From: Andrea Taverna on
Hi,

I need to implement an argmax-like function that works this way:
(i*,j*) = argmax{f(i,j) | i,j in C}, i.e. I have to find the optimal
couple (i*,j*) for function f where i,j are variables varying on a
finite discrete set C=0..n-1.

Using iterate I came up with the following solution
(iter (for i from 0 below n)
(for result =
(iter (for j from 0 below n)
(for c = (list i j))
(finding c maximizing (apply #'f c) into c*)
(finally (return c*))))
(finally (return result)))

But I don't like it much, I'd prefer not to have to express how the
couple (i,j) is implemented, I'd like to write something like this:
(multiple-value-bind (i* j*)
(iter (for i from 0 below n)
(iter (for j from 0 below n)
(finding (i . j) maximizing (f i j) into (i^ . j^))
(finally (return (values i^ j^)))))
...)

Apart from "elegance", is there something I should look out
performance-wise?

TIA

Andrea
From: Andrea Taverna on
Noticed I missed one piece, it should be

(iter (for i from 0 below n)
   (for result =
       (iter (for j from 0 below n)
         (for c = (list i j))
         (finding c  maximizing (apply #'f c) into c*)
      (finally (return c*))))
(finding result maximizing (apply #'f result) into result*)
   (finally (return result*)))

which adds another evaluation for f
From: Tamas K Papp on
On Mon, 19 Apr 2010 09:18:13 -0700, Andrea Taverna wrote:

> Hi,
>
> I need to implement an argmax-like function that works this way: (i*,j*)
> = argmax{f(i,j) | i,j in C}, i.e. I have to find the optimal couple
> (i*,j*) for function f where i,j are variables varying on a finite
> discrete set C=0..n-1.
>
> Using iterate I came up with the following solution (iter (for i from 0
> below n)
> (for result =
> (iter (for j from 0 below n)
> (for c = (list i j))
> (finding c maximizing (apply #'f c) into c*)
> (finally (return c*))))
> (finally (return result)))
>
> But I don't like it much, I'd prefer not to have to express how the
> couple (i,j) is implemented, I'd like to write something like this:
> (multiple-value-bind (i* j*)
> (iter (for i from 0 below n)
> (iter (for j from 0 below n)
> (finding (i . j) maximizing (f i j) into (i^ .
j^)) (finally
> (return (values i^ j^)))))
> ...)
>
> Apart from "elegance", is there something I should look out
> performance-wise?

I would be very surprised if the performance difference between the
alternatives was even measurable. Don't worry about it. Use the form
that comes most naturally.

BTW, it seems to me that the inner loop would just return the best
(values i j) for a given i, which would then be ignored. I doubt that
this is the intention. In iterate, you can name your loop levels, and
collect/gather/etc in another (outer level). See the manual.

Best,

Tamas
From: grucidipo on
On 19 abr, 18:18, Andrea Taverna <a.t...(a)hotmail.it> wrote:
> Hi,
>
> I need to implement an argmax-like function that works this way:
> (i*,j*) = argmax{f(i,j) | i,j in C}, i.e. I have to find the optimal
> couple (i*,j*) for function f where i,j are variables varying on a
> finite discrete set C=0..n-1.
>
> Using iterate I came up with the following solution
> (iter (for i from 0 below n)
>    (for result =
>        (iter (for j from 0 below n)
>          (for c = (list i j))
>          (finding c  maximizing (apply #'f c) into c*)
>       (finally (return c*))))
>    (finally (return result)))
>
> But I don't like it much, I'd prefer not to have to express how the
> couple (i,j) is implemented, I'd like to write something like this:
> (multiple-value-bind (i* j*)
>              (iter  (for i from 0 below n)
>                     (iter (for j from 0 below n)
>                           (finding (i . j)  maximizing (f i j) into (i^ . j^))
>                           (finally (return (values i^ j^)))))
>            ...)
>
> Apart from "elegance", is there something I should look out
> performance-wise?
>
> TIA
>
> Andrea


What about this one?

;; for testing (defun f(x y)(- (* x x) (* x y)))

(defun argmax-like (f n)
(loop with argmax = '(0 0)
with maxf = (funcall f 0 0)
for i below n do
(loop for j below n do
(when (> (funcall f i j) maxf)
(setq argmax (list i j)
maxf (funcall f i j))))
finally (return (list argmax maxf))))

;; example (argmax-like #'f 10) => ((9 0) 81)
From: Rob Warnock on
Alberto Riva <alb(a)nospam.ufl.edu> wrote:
+---------------
| I would change it to:
|
| (defun argmax-like (f n)
| (loop with argmax = (cons 0 0)
| with maxf = (funcall f 0 0)
| for i below n do
| (loop for j below n do
| (let ((v (funcall f i j)))
| (when (> v maxf)
| (setf (car argmax) i
| (cdr argmax) j
| maxf v))))
| finally (return (list argmax maxf))))
|
| Advantages:
| 1. You use a single cons to store argmax, instead of creating a new list
| every time;
| 2. You avoid repeated evaluations of f.
+---------------

Or even get rid of the ARGMAX cons and the consing of results
and let everything be stack-allocated:

(defun argmax-like (f n)
(loop with max-i = 0
and max-j = 0
and max-f = (funcall f 0 0)
for i below n do
(loop for j below n
for v = (funcall f i j)
when (> v max-f)
do (setf max-i i
max-j j
max-f v))
finally (return (values max-i max-j max-f))))

Or (return (list (list max-i max-j) max-f)) if the original API
was really important...


-Rob

p.s. If the limit N -- or rather, (EXPT N 2) -- is fairly small and
the cost of calling F is very large [or has unwanted side-effects], one
might even want to get rid of the initializing call of (FUNCALL F 0 0),
like so:

(defun argmax-like (f n)
(loop with max-i = 0
and max-j = 0
and max-f = nil
and first-time = t
for i below n do
(loop for j below n
for v = (funcall f i j)
when (or first-time (> v max-f))
do (setf max-i i
max-j j
max-f v
first-time nil))
finally (return (values max-i max-j max-f))))

-----
Rob Warnock <rpw3(a)rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607