From: Tamas
Subject: map and reduce
Date: 
Message-ID: <acc442eb-8178-4b08-9204-f20dd4d73557@m3g2000hsc.googlegroups.com>
Consider n vectors (or lists) v1, ..., vn of equal length, an n-
variate function f, and a bivariate function g.

I want to calculate (reduce g (map 'vector f v1 v2 ... vn)), eg

(reduce #'+ (map 'vector #'* '(1 2 3) '(4 5 6)))  ; => 32

but without the intermediate vector (my vectors are long).  I can of
course write a function to do this, but I am wondering if there is a
clever way to do it with CL library functions.

Thanks,

Tamas

From: Brian
Subject: Re: map and reduce
Date: 
Message-ID: <5fefcc23-c02e-4cea-9bfd-12470f402560@b1g2000hsg.googlegroups.com>
Tamas wrote:
> Consider n vectors (or lists) v1, ..., vn of equal length, an n-
> variate function f, and a bivariate function g.
>
> I want to calculate (reduce g (map 'vector f v1 v2 ... vn)), eg
>
> (reduce #'+ (map 'vector #'* '(1 2 3) '(4 5 6)))  ; => 32
>
> but without the intermediate vector (my vectors are long).  I can of
> course write a function to do this, but I am wondering if there is a
> clever way to do it with CL library functions.
>
> Thanks,
>
> Tamas
For that simple example:
(loop for a across #(1 2 3)
      for b across #(4 5 6)
      sum (* a b))
=> 32
From: Scott Burson
Subject: Re: map and reduce
Date: 
Message-ID: <13d34af0-b58e-46af-85a0-b07513a230ed@w5g2000prd.googlegroups.com>
On May 23, 9:23 am, Tamas <······@gmail.com> wrote:
> Consider n vectors (or lists) v1, ..., vn of equal length, an n-
> variate function f, and a bivariate function g.
>
> I want to calculate (reduce g (map 'vector f v1 v2 ... vn)), eg
>
> (reduce #'+ (map 'vector #'* '(1 2 3) '(4 5 6)))  ; => 32
>
> but without the intermediate vector (my vectors are long).  I can of
> course write a function to do this, but I am wondering if there is a
> clever way to do it with CL library functions.

My GMAP macro is good for this kind of thing:

  (gmap :sum #'* (:list '(1 2 3)) (:list 4 5 6))

You can find it at

  http://common-lisp.net/project/misc-extensions/

-- Scott
From: Marco Antoniotti
Subject: Re: map and reduce
Date: 
Message-ID: <9feb7a07-38c8-43a1-b711-9794ef4a318b@z72g2000hsb.googlegroups.com>
On May 23, 11:57 pm, Scott Burson <········@gmail.com> wrote:
> On May 23, 9:23 am, Tamas <······@gmail.com> wrote:
>
> > Consider n vectors (or lists) v1, ..., vn of equal length, an n-
> > variate function f, and a bivariate function g.
>
> > I want to calculate (reduce g (map 'vector f v1 v2 ... vn)), eg
>
> > (reduce #'+ (map 'vector #'* '(1 2 3) '(4 5 6)))  ; => 32
>
> > but without the intermediate vector (my vectors are long).  I can of
> > course write a function to do this, but I am wondering if there is a
> > clever way to do it with CL library functions.
>
> My GMAP macro is good for this kind of thing:
>
>   (gmap :sum #'* (:list '(1 2 3)) (:list 4 5 6))
>
> You can find it at
>
>  http://common-lisp.net/project/misc-extensions/
>
> -- Scott

... and SERIES should do it as well.

Cheers

Marco
From: Tamas
Subject: Re: map and reduce
Date: 
Message-ID: <922ad87d-8c3b-4c9c-909a-b0dc150f62cd@l42g2000hsc.googlegroups.com>
On May 24, 2:44 pm, Marco Antoniotti <·······@gmail.com> wrote:
> On May 23, 11:57 pm, Scott Burson <········@gmail.com> wrote:
>
>
>
> > On May 23, 9:23 am, Tamas <······@gmail.com> wrote:
>
> > > Consider n vectors (or lists) v1, ..., vn of equal length, an n-
> > > variate function f, and a bivariate function g.
>
> > > I want to calculate (reduce g (map 'vector f v1 v2 ... vn)), eg
>
> > > (reduce #'+ (map 'vector #'* '(1 2 3) '(4 5 6)))  ; => 32
>
> > > but without the intermediate vector (my vectors are long).  I can of
> > > course write a function to do this, but I am wondering if there is a
> > > clever way to do it with CL library functions.
>
> > My GMAP macro is good for this kind of thing:
>
> >   (gmap :sum #'* (:list '(1 2 3)) (:list 4 5 6))
>
> > You can find it at
>
> >  http://common-lisp.net/project/misc-extensions/
>
> > -- Scott
>
> ... and SERIES should do it as well.
>
> Cheers
>
> Marco

Thanks Marco (and others),

I ended up using SERIES, as I need general functions (summing was just
an example, but I guess that wasn't clear from my post).

Tamas
From: Rainer Joswig
Subject: Re: map and reduce
Date: 
Message-ID: <joswig-042D18.19460023052008@news-europe.giganews.com>
In article 
<····································@m3g2000hsc.googlegroups.com>,
 Tamas <······@gmail.com> wrote:

> Consider n vectors (or lists) v1, ..., vn of equal length, an n-
> variate function f, and a bivariate function g.
> 
> I want to calculate (reduce g (map 'vector f v1 v2 ... vn)), eg
> 
> (reduce #'+ (map 'vector #'* '(1 2 3) '(4 5 6)))  ; => 32
> 
> but without the intermediate vector (my vectors are long).  I can of
> course write a function to do this, but I am wondering if there is a
> clever way to do it with CL library functions.
> 
> Thanks,
> 
> Tamas

(let ((sum 0))
    (map nil
         (lambda (a b)
            (incf sum (* a b)))
         '(1 2 3) '(4 5 6))
   sum)

-- 
http://lispm.dyndns.org/
From: Mark Wooding
Subject: Re: map and reduce
Date: 
Message-ID: <slrng3edme.ihm.mdw@metalzone.distorted.org.uk>
Tamas <······@gmail.com> wrote:

> Consider n vectors (or lists) v1, ..., vn of equal length, an n-
> variate function f, and a bivariate function g.
>
> I want to calculate (reduce g (map 'vector f v1 v2 ... vn)), eg
>
> (reduce #'+ (map 'vector #'* '(1 2 3) '(4 5 6)))  ; => 32
>
> but without the intermediate vector (my vectors are long).  I can of
> course write a function to do this, but I am wondering if there is a
> clever way to do it with CL library functions.

I don't think there is a way to do this sort of thing directly.  It's
not difficult (or even particularly ugly) to do using LOOP, though.  For
the case G = #'+, it's particularly nice:

  (loop for x across first-vector
        for y across second-vector
        sum (funcall f x y))

but for general G, you need

  (loop for x across first-vector
        for y across second-vector
	for temp = (funcall f x y)
        for result = temp then (funcall result temp)
	finally (return result))

(This only works if the input vectors are non-empty; you need to do
something a little messier otherwise.)

-- [mdw]
From: Joshua Taylor
Subject: Re: map and reduce
Date: 
Message-ID: <53405043-f303-4888-95f1-a607161b4d42@2g2000hsn.googlegroups.com>
On May 23, 12:23 pm, Tamas <······@gmail.com> wrote:
> Consider n vectors (or lists) v1, ..., vn of equal length, an n-
> variate function f, and a bivariate function g.
>
> I want to calculate (reduce g (map 'vector f v1 v2 ... vn)), eg
>
> (reduce #'+ (map 'vector #'* '(1 2 3) '(4 5 6)))  ; => 32
>
> but without the intermediate vector (my vectors are long).  I can of
> course write a function to do this, but I am wondering if there is a
> clever way to do it with CL library functions.
>
> Thanks,
>
> Tamas

If any of the input vectors are modifiable (that is, you're willing to
change their entries), you can use map-into to avoid making a new
vector:

(let ((v1 #(1 2 3))
      (v2 #(4 5 6))) ; v2 can be modified
  (reduce #'+ (map-into v2 #'* v1 v2)))

=> 32
From: Rainer Joswig
Subject: Re: map and reduce
Date: 
Message-ID: <joswig-7DD3CF.16455924052008@news-europe.giganews.com>
In article 
<····································@2g2000hsn.googlegroups.com>,
 Joshua Taylor <···········@gmail.com> wrote:

> On May 23, 12:23�pm, Tamas <······@gmail.com> wrote:
> > Consider n vectors (or lists) v1, ..., vn of equal length, an n-
> > variate function f, and a bivariate function g.
> >
> > I want to calculate (reduce g (map 'vector f v1 v2 ... vn)), eg
> >
> > (reduce #'+ (map 'vector #'* '(1 2 3) '(4 5 6))) �; => 32
> >
> > but without the intermediate vector (my vectors are long). �I can of
> > course write a function to do this, but I am wondering if there is a
> > clever way to do it with CL library functions.
> >
> > Thanks,
> >
> > Tamas
> 
> If any of the input vectors are modifiable (that is, you're willing to
> change their entries), you can use map-into to avoid making a new
> vector:
> 
> (let ((v1 #(1 2 3))
>       (v2 #(4 5 6))) ; v2 can be modified
>   (reduce #'+ (map-into v2 #'* v1 v2)))
> 
> => 32

Generally that's right. But I fear in this specific example
#(4 5 6) is constant data and you are not allowed to modify
it according to ANSI CL. #(4 5 6) is contant data and
'#(4 5 6) is also constant data.

Whenever you are using direct syntax for the data in the source
you'll end up with 'constant data'. One should not modify it
in portable programs.

You get a modifiable vector from calling (VECTOR 4 5 6).

-- 
http://lispm.dyndns.org/