'How to implement outer product of two vectors in Scheme?

I want to define a function in Scheme that will compute the outer product of two vectors.

for example:

(outerProduct '(1 2 3) '(4 5))

the output is supposed to be the following matrix:

((4 5) (8 10) (12 15))

How can I achieve that?



Solution 1:[1]

Note that collections used in your example aren't vectors, but lists. But this code with two nested for/lists will work for both:

(define (outer-product v1 v2)
  (for/list ((e1 v1))
    (for/list ((e2 v2))
      (* e1 e2))))

Examples:

> (outer-product '(1 2 3) '(4 5))
'((4 5) (8 10) (12 15))

> (outer-product (vector 1 2 3) (vector 4 5))
'((4 5) (8 10) (12 15))

Solution 2:[2]

You can also do it with map if you don't want to use Racket-specific constructs (Assuming you're working with lists like in your code and not vectors like the subject line (Maybe you're thinking of vectors in the math sense, not the scheme sense?); though Racket has a vector-map too so it's easy to adapt:

(define (outerProduct l1 l2)
  (map (lambda (x) (map (lambda (y) (* x y)) l2)) l1))

Example:

> (outerProduct '(1 2 3) '(4 5))
'((4 5) (8 10) (12 15))

Or using the math/matrix library that comes with Racket:

(require math/matrix)
(define (outerProduct l1 l2)
  (let ((m1 (->col-matrix l1))
        (m2 (->row-matrix l2)))
    (matrix->list* (matrix* m1 m2))))

(This is a better option if you use its matrix type directly instead of converting to and from lists and are also doing other stuff with the values; also the docs suggest using typed Racket for best performance)

Solution 3:[3]

(define outerprod
  (lambda (a b)
    (map (lambda (a)
           (map (lambda(b) (* a b))
                b))
         a )))


1 ]=> (outerprod '(1 2 3) '(4 5))
;Value: ((4 5) (8 10) (12 15))

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Martin Půda
Solution 2 Shawn
Solution 3 alinsoar