I’m porting some projective geometric algebra (PGA) applications from ganja.js (JavaScript) to Julia+Makie. In the applications I’m porting (and I suspect in many other PGA applications) it would be convenient to be able to broadcast the overloaded vector operators to each column of a matrix (e.g., to rotate multiple polygon vertices, each stored in its own column, by multiplying the whole matrix by a PGA rotor vector).

However, when I try to do that, the operation reverts back to an element by element operation instead of the column by column overloaded operation I’m seeking. Any suggestions on how to specify to Julia to perform the column by column overloaded vector operations?

```
julia> include("ripga2d.jl")
utest (generic function with 4 methods)
julia> X = rand(Float32,8,3)
8×3 Matrix{Float32}:
0.116556 0.36722 0.517178
0.659318 0.469833 0.464139
0.4231 0.0838702 0.530423
0.213568 0.119756 0.326653
0.71594 0.199458 0.411434
0.944089 0.799287 0.350504
0.935295 0.461366 0.207585
0.104116 0.171554 0.507419
julia> Y = ones(Float32,8);
julia> X[:,1] * Y # correct geometric product
8-element Vector{Float32}:
-0.18207103
-0.7012192
1.261383
-0.18207103
1.3951917
1.3614659
1.2613833
4.1119814
julia> X .* Y # no longer a geometric product
8×3 Matrix{Float32}:
0.116556 0.36722 0.517178
0.659318 0.469833 0.464139
0.4231 0.0838702 0.530423
0.213568 0.119756 0.326653
0.71594 0.199458 0.411434
0.944089 0.799287 0.350504
0.935295 0.461366 0.207585
0.104116 0.171554 0.507419
julia>
```

Just in case it is relevant, I’ve implemented the following overloaded geometric product operator as suggested in the bivector.net C++ reference implementation of PGA. (Although the code may look dreadful, it is a straightforward and fast implementation of the geometric product’s Caley Table, which is trivial to derive.)

```
function Base.:*(a::Vector{Float32},b::Vector{Float32})::Vector{Float32}
res = Vector{Float32}(undef,length(a))
res[1]=a[1]*b[1]+a[3]*b[3]+a[4]*b[4]-a[7]*b[7]
res[2]=a[1]*b[2]+a[2]*b[1]+a[5]*b[3]-a[3]*b[5]+a[4]*b[6]-a[6]*b[4]-a[7]*b[8]-a[8]*b[7]
res[3]=a[1]*b[3]+a[3]*b[1]-a[4]*b[7]+a[7]*b[4]
res[4]=a[1]*b[4]+a[4]*b[1]+a[3]*b[7]-a[7]*b[3]
res[5]=a[1]*b[5]+a[5]*b[1]+a[2]*b[3]-a[3]*b[2]+a[4]*b[8]+a[8]*b[4]+a[6]*b[7]-a[7]*b[6]
res[6]=a[1]*b[6]+a[6]*b[1]-a[2]*b[4]+a[4]*b[2]+a[3]*b[8]+a[8]*b[3]-a[5]*b[7]+a[7]*b[5]
res[7]=a[1]*b[7]+a[7]*b[1]+a[3]*b[4]-a[4]*b[3]
res[8]=a[1]*b[8]+a[8]*b[1]+a[2]*b[7]+a[7]*b[2]+a[3]*b[6]+a[6]*b[3]+a[4]*b[5]+a[5]*b[4]
return res
end
```