How to use map to multiply two vectors

Given these two vectors,

x = [1,2,3]; y=[4,5,6]

I understand why this is true:

x * y' == *(x, y')

But I do not understand why this is true or, better, why * does not multiply the two vectors the same way. How can I use map to multiply the two vectors?

C0 = map(*, x, y')

C1 = map((a,b) -> a * b, x, y')

C2 = map((a,b) -> a * b, x, y)

C0 == C1 == C2

map is element-wise, x * y' is not element-wise, it’s a column vector * a row vector, so an outer product

This is where you use broadcasting instead of map. It broadcasts across singleton dimensions, and in this particular case, it is trivial to express it as

x .* y'

There’s not all that much point to change from x * y' to x .* y' in and of itself. But you can fuse it with other operations, or do it in-place, like this

A .= x .* y'

x .* y' == map.(*, x, y')

This gives an error: A is not defined.

So the answer to my question is:

map.(*, x, y')

It’s for when you have predefined an output array, which I called A as an example.

I think this was probably intended as a joke. Combining map and broadcast like that is pointless (but fun).

Just use broadcast.

OK. Just like this:

A = zeros(Int, (3, 3))

A .= x .* y'

that’s not helpful for OP I think.

By definition, map.() is doing map for individual element, if you’re writing this you might as well do

x .* y'

julia> x .* y' == x * y'
true

but THIS IS AN COINCIDENCE,

julia> x' .* y == x' * y
false

like, the point shouldn’t be literally use “map” somewhere in the code, the point is map is doing element operation and the * inside x * y' is conceptually not an element-wise operation

x' * y == mapreduce(*, +, x, y)

I still don’t understand why you are insisting on showing simple linear algebra concepts like “dot product” and “outer product” can be expressed using something containing the word “map” – how is this helpful for a beginner like OP?

I was only trying to find a Julia function similar to the R outer function, where outer(x, y, FUN = "*") == x %*% t(y). FUN is a vectorized function like + or +. That is why I was trying to use map in Julia.

And this mapping horror:

using LinearAlgebra
cross(x,y) == map(.*, circshift(x,2), circshift(y,1)) - map(.*, circshift(x,1), circshift(y,2))

In Julia you don’t use any special function for this, you just broadcast whatever operator you want, like x .* y', x .+ y', x .< y', x .% y', etc etc etc.

OK. But how could you do in Julia something like this in R:

f <- outer(x, y , function(x, y) cos(y) / (1 + x^2))

cos.(y') ./ (1 .+ x.^2), or more simply @. cos(y') / (1+x^2)

I got a different result using R:

> f
            [,1]       [,2]       [,3]
[1,] -0.32682181 0.14183109 0.48008514
[2,] -0.13072872 0.05673244 0.19203406
[3,] -0.06536436 0.02836622 0.09601703

and in Julia

julia> @. cos(y') / (1+x^2)
3Ă—1 Matrix{Float64}:
 -0.32682181043180597
  0.05673243709264525
  0.0960170286650366

Up to rounding error, that’s what I get in Julia also.

julia> x = [1,2,3]; y=[4,5,6];

julia> @. cos(y') / (1+x^2)
3Ă—3 Matrix{Float64}:
 -0.326822   0.141831   0.480085
 -0.130729   0.0567324  0.192034
 -0.0653644  0.0283662  0.096017