# Higher dimensional cross product in LinearAlgebra

**URL:** <https://discourse.julialang.org/t/higher-dimensional-cross-product-in-linearalgebra/47919>\
**Category:** Internals & Design\
**Tags:** question, linearalgebra, math\
**Created:** [October 7, 2020, 10:53am UTC](https://discourse.julialang.org/t/higher-dimensional-cross-product-in-linearalgebra/47919 "2020-10-07T10:53:45Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![akshu3398](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/akshu3398/32/14215_2.png) [@akshu3398](https://discourse.julialang.org/u/akshu3398)\
**Post date:** [October 7, 2020, 10:53am UTC](https://discourse.julialang.org/t/higher-dimensional-cross-product-in-linearalgebra/47919/1 "2020-10-07T10:53:45Z")

</div>

Is there any function (specifically in `LineaAlgebra` or `Base` Julia) similar to `cross`, but one that works(gives cross product) on (mathematically speaking) [higher dimensional](https://math.stackexchange.com/questions/2371022/cross-product-in-higher-dimensions/2371039#:~:text=is%20linear.,orthogonal%20to%20the%20first%20two.)(`length`) `Vector`s??? As `cross` currently only supports 3 dimensional(`length`) `Vector`s (see [this](https://github.com/JuliaLang/julia/blob/539f3ce943f59dec8aff3f2238b083f1b27f41e5/stdlib/LinearAlgebra/src/generic.jl#L263-L289)).

The reason I am asking this is that, this might be a cool(& easy) feature to contribute to as a newcomer(to open source and julia). But, I first want to check if it is possible to open up an issue for this(& work on it). I have already searched through issues in Julia’s github repo but, found none related. Hence, I am asking here to know whether(if yes, then where) this topic was discussed in the past(specifically in [julia](https://github.com/JuliaLang/julia/issues?q=)), so I can determine whether to open up a PR for this(if possible).

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [October 7, 2020, 11:16am UTC](https://discourse.julialang.org/t/higher-dimensional-cross-product-in-linearalgebra/47919/2 "2020-10-07T11:16:36Z")

</div>

The cross product is an intrinsically 3-dimensional idea.

In the SO thread, “What you are looking for is the wedge or exterior product” is the right idea, but maybe not so readable. Instead of a map from two vectors to another vector, the general object is a map from two 1-forms to a 2-form, but in 3 dimensions, this 2-form is hodge dual to another 1-form, and that’s what the cross product gives you. (That’s also why you can think of area elements in 3D as being their normal vectors.) In more, or fewer, dimensions, the 2-form isn’t dual to a 1-form.

There are quite a few Julia packages playing with related ideas, with varying goals & levels of abstraction. In no particular order: [https://github.com/Jutho/TensorKit.jl](https://github.com/Jutho/TensorKit.jl), [https://github.com/simeonschaub/CoolTensors.jl](https://github.com/simeonschaub/CoolTensors.jl), [https://github.com/EricForgy/TensorAlgebra.jl](https://github.com/EricForgy/TensorAlgebra.jl), [https://github.com/chakravala/Grassmann.jl](https://github.com/chakravala/Grassmann.jl).

---

<div class="post-metadata">

**Author:** ![akshu3398](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/akshu3398/32/14215_2.png) [@akshu3398](https://discourse.julialang.org/u/akshu3398)\
**Post date:** [October 7, 2020, 12:43pm UTC](https://discourse.julialang.org/t/higher-dimensional-cross-product-in-linearalgebra/47919/3 "2020-10-07T12:43:28Z")

</div>

> [@mcabbott](#):
>
> wedge or exterior product

Forgive me for not clearing this up earlier. But yeah, by cross product, I meant like [“wedge” or “exterior” product](https://en.wikipedia.org/wiki/Exterior_algebra#:~:text=In%20mathematics%2C%20the%20exterior%20product,and%20their%20higher%2Ddimensional%20analogues.&text=More%20generally%2C%20the%20exterior%20product,sometimes%20called%20a%20k%2Dblade.)(as suggested) and not an outer vector product. But, I think in general, [the idea](https://en.wikipedia.org/wiki/Cross_product#Matrix_notation) is similar(for 3 dimension case). I just want to (slightly)extend that idea([if you look at the code](https://github.com/JuliaLang/julia/blob/539f3ce943f59dec8aff3f2238b083f1b27f41e5/stdlib/LinearAlgebra/src/generic.jl#L263-L289)) of `LinearAlgebra`’s `cross` product to higher dimensional `Vector`s.

I also looked at the packages you mentioned. But, [some of them](https://ericforgy.github.io/TensorAlgebra.jl/dev/#Tensor-Spaces) uses (`Vector`)outer product in place of cross(wedge/exterior) product, [some of them](https://simeonschaub.github.io/CoolTensors.jl/dev/) don’t have definition to cross product because of the package infancy, and [some of the major packages](https://github.com/chakravala/Grassmann.jl/blob/473b3488cb76119de30333e83cac9fb7392d4b4c/src/algebra.jl#L194-L198) still uses the same definition in `LinearAlgebra` library for their own `cross` products(may be they were thinking that someone might someday extend that definition).

P.S. Apoligies if this sounds dumb.

---

<div class="post-metadata">

**Author:** ![Syx\_Pek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/syx_pek/32/6364_2.png) [@Syx\_Pek](https://discourse.julialang.org/u/Syx_Pek)\
**Post date:** [October 7, 2020, 1:51pm UTC](https://discourse.julialang.org/t/higher-dimensional-cross-product-in-linearalgebra/47919/4 "2020-10-07T13:51:38Z")

</div>

Here is perhaps an implementation matching what you want? [https://github.com/eschnett/DifferentialForms.jl](https://github.com/eschnett/DifferentialForms.jl)

---

<div class="post-metadata">

**Author:** ![akshu3398](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/akshu3398/32/14215_2.png) [@akshu3398](https://discourse.julialang.org/u/akshu3398)\
**Post date:** [October 7, 2020, 2:52pm UTC](https://discourse.julialang.org/t/higher-dimensional-cross-product-in-linearalgebra/47919/5 "2020-10-07T14:52:20Z")

</div>

Nope, it’s not that either.

let me explain by example:

1. we get `zero` `Vector` when we `cross` two vectors that are in the same direction.  
e.x. `LinearAlgebra.cross([1,1,1], [2,2,2]) .|> iszero |> all` this gives `true`  
similarly I want to implement in julia(I have the code just to make a pr) something like,  
`cross([1,1,1,1], [2,2,2,2], [3,3,3,3]) .|> iszero |> all` again `true`

2. by `cross`ing(applying `cross` product to) N-1 orthogonal `Vector`s(of N dimensions) we get another vector(in same dimensional space) that is also orthogonal to the `Vector`s used in the `cross` product.  
e.x. `LinearAlgebra.cross([0,1,0], [0,0,1]) == [1,0,0] # true`  
similarly,  
`cross([0,1,0,0], [0,0,1,0], [0,0,0,1]) == [1, 0, 0, 0] # true`

3. And for any vector,:  
e.x. `LinearAlgebra.cross([1,2,3], [3,5,-1]) == [-17, 10, -1] # true`  
similarly,  
`cross([1,1,0,2,4], [3,0,1,-5,3], [3,3,3,1,2], [-4,2,0,7,1]) == [-13.0, -221.0, 195.0, 51.0, 33.0] # true`

---

<div class="post-metadata">

**Author:** ![Syx\_Pek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/syx_pek/32/6364_2.png) [@Syx\_Pek](https://discourse.julialang.org/u/Syx_Pek)\
**Post date:** [October 7, 2020, 3:03pm UTC](https://discourse.julialang.org/t/higher-dimensional-cross-product-in-linearalgebra/47919/6 "2020-10-07T15:03:18Z")

</div>

```julia
julia> A = [1 1 0 2 4
       3 0 1 -5 3
       3 3 3 1 2
       -4 2 0 7 1
       1 1 1 1 1]

julia> det(A)*(A\[0,0,0,0,1])
5-element Array{Float64,1}:
  -12.999999999999991
 -220.99999999999997
  195.0
   51.0
   32.99999999999999

```

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [October 7, 2020, 3:10pm UTC](https://discourse.julialang.org/t/higher-dimensional-cross-product-in-linearalgebra/47919/7 "2020-10-07T15:10:20Z")

</div>

```julia
julia> using DifferentialForms

julia> v = Form{3,1}((0,1,0)); w = Form{3,1}((0,0,1));

julia> hodge(wedge(v,w)) # the cross product
Int64⟦[1]:1, [2]:0, [3]:0⟧{3,1}

julia> v = Form{4,1}((0,1,0,0)); w = Form{4,1}((0,0,1,0)); u = Form{4,1}((0,0,0,1));

julia> hodge(wedge(v,w,u)) # notice the orientation 
Int64⟦[1]:-1, [2]:0, [3]:0, [4]:0⟧{4,1}

julia> v = Form{5,1}((1,1,0,2,4)); w = Form{5,1}((3,0,1,-5,3)); u = Form{5,1}((3,3,3,1,2)); x = Form{5,1}((-4,2,0,7,1));

julia> hodge(wedge(v,w,u,x))
Int64⟦[1]:-13, [2]:-221, [3]:195, [4]:51, [5]:33⟧{5,1}

```

---

<div class="post-metadata">

**Author:** ![akshu3398](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/akshu3398/32/14215_2.png) [@akshu3398](https://discourse.julialang.org/u/akshu3398)\
**Post date:** [October 7, 2020, 3:59pm UTC](https://discourse.julialang.org/t/higher-dimensional-cross-product-in-linearalgebra/47919/9 "2020-10-07T15:59:49Z")

</div>

Yup, that’s what i was asking for(& this was exactly what i did in my definition of `cross`). A simple solution to a simple problem.

---

<div class="post-metadata">

**Author:** ![akshu3398](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/akshu3398/32/14215_2.png) [@akshu3398](https://discourse.julialang.org/u/akshu3398)\
**Post date:** [October 7, 2020, 4:04pm UTC](https://discourse.julialang.org/t/higher-dimensional-cross-product-in-linearalgebra/47919/10 "2020-10-07T16:04:52Z")

</div>

Oh yeah, my bad for skimming through docs.

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [October 7, 2020, 4:06pm UTC](https://discourse.julialang.org/t/higher-dimensional-cross-product-in-linearalgebra/47919/11 "2020-10-07T16:06:08Z")

</div>

There was a PR previously for the cross product in 7 dimensions, which was declined since it wasn’t clear which definition to choose: [https://github.com/JuliaLang/julia/pull/32107](https://github.com/JuliaLang/julia/pull/32107). The conclusion there was that the definition was better in a package so that Base Julia isn’t locked into a particular definition forever.

---

<div class="post-metadata">

**Author:** ![akshu3398](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/akshu3398/32/14215_2.png) [@akshu3398](https://discourse.julialang.org/u/akshu3398)\
**Post date:** [October 7, 2020, 4:08pm UTC](https://discourse.julialang.org/t/higher-dimensional-cross-product-in-linearalgebra/47919/12 "2020-10-07T16:08:11Z")

</div>

Thnx, that answers this thread 👍

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [October 7, 2020, 11:34pm UTC](https://discourse.julialang.org/t/higher-dimensional-cross-product-in-linearalgebra/47919/13 "2020-10-07T23:34:10Z")

</div>

It seems unfortunate that Base exports the `cross` function and `\times` symbol for something that is actually pretty rare.

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [October 8, 2020, 12:17am UTC](https://discourse.julialang.org/t/higher-dimensional-cross-product-in-linearalgebra/47919/14 "2020-10-08T00:17:39Z")

</div>

Just a pedantic note, they’re exported by `LinearAlgebra`, not `Base`.

---

<div class="post-metadata">

**Author:** ![akshu3398](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/akshu3398/32/14215_2.png) [@akshu3398](https://discourse.julialang.org/u/akshu3398)\
**Post date:** [October 8, 2020, 12:25am UTC](https://discourse.julialang.org/t/higher-dimensional-cross-product-in-linearalgebra/47919/15 "2020-10-08T00:25:34Z")

</div>

I am using version 1.5.1 of julia & `Base` doesn’t export `cross` not `\times` symbol.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [October 8, 2020, 1:12am UTC](https://discourse.julialang.org/t/higher-dimensional-cross-product-in-linearalgebra/47919/16 "2020-10-08T01:12:29Z")

</div>

Very good point, thanks! I guess this was a memory from \>2 years ago.

---

<div class="post-metadata">

**Author:** ![Olof\_Salberger](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/olof_salberger/32/4850_2.png) [@Olof\_Salberger](https://discourse.julialang.org/u/Olof_Salberger)\
**Post date:** [October 8, 2020, 4:03am UTC](https://discourse.julialang.org/t/higher-dimensional-cross-product-in-linearalgebra/47919/17 "2020-10-08T04:03:03Z")

</div>

Tbh, I think there is a decent case for including the wedge product in the base linear algebra package since it is extremely useful in a wide range of situations, and exporting it from LinearAlgebra would mean wider ecosystem support for it just like with the tensor/kronecker product.

The 7-dimensional cross product on the other hand is a fairly weird constuction that involves fixing a particular trivector (3-form), so unlike in the 3d case where there is only one trivector up to scalar multiplication (with sign giving chirality), the 7-dimensional cross product does not transform in the same way as its factors under rotations for example. It is only does that for a G\_2 factor of SO(7) (though it behaves more nicely for 7d vectors over finite fields). As opposed to the wedge product which is completely unique and depends on nothing, just like the tensor product.

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [October 8, 2020, 8:47am UTC](https://discourse.julialang.org/t/higher-dimensional-cross-product-in-linearalgebra/47919/18 "2020-10-08T08:47:11Z")

</div>

> [@Olof\_Salberger](#):
>
> there is a decent case for including the wedge product in the base linear algebra package

Would `∧(::Vector, ::Vector)` return a `Matrix`?

The loudest objection to putting `⊗` into LinearAlgebra was that it was also going to return a matrix for something which really has two of the same indices, while most other parts of the package assume a Matrix has one upstairs & one downstairs. So we got TensorCore.jl, but ideally this will be folded back in at some point.

---

<div class="post-metadata">

**Author:** ![Orbots](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/orbots/32/3392_2.png) [@Orbots](https://discourse.julialang.org/u/Orbots)\
**Post date:** [October 9, 2020, 7:19pm UTC](https://discourse.julialang.org/t/higher-dimensional-cross-product-in-linearalgebra/47919/19 "2020-10-09T19:19:48Z")

</div>

> [@mcabbott](#):
>
> Would `∧(::Vector, ::Vector)` return a `Matrix` ?

I would say yes since both argument types are Vectors. `∧(::Form{N}, ::Form{M})` would return `Form{N+M}` for a hypothetical Form ( or Covector ) type.  
Like ⊗ I think wedge would be a good one to include in base if/when covariance is taken seriously.

---

<div class="post-metadata">

**Author:** ![Olof\_Salberger](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/olof_salberger/32/4850_2.png) [@Olof\_Salberger](https://discourse.julialang.org/u/Olof_Salberger)\
**Post date:** [October 10, 2020, 4:48am UTC](https://discourse.julialang.org/t/higher-dimensional-cross-product-in-linearalgebra/47919/20 "2020-10-10T04:48:13Z")

</div>

Right, the issue here regarding index types is the lack of distinction between vectors and dual vectors. The tensor product of a vector with a dual vector is basically a matrix, just like the wedge product. Julia doesn’t quite distinguish between vectors and their duals though.

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [October 10, 2020, 5:17am UTC](https://discourse.julialang.org/t/higher-dimensional-cross-product-in-linearalgebra/47919/21 "2020-10-10T05:17:01Z")

</div>

Julia does indeed distinguish between vectors and dual vectors though `adjoint`. It’s just that it doesn’t generalize well to higher rank objects.

Something with two contravriant or two covariant or one covariant and one contra variant index are all `Matrix`es.

[Next page](https://discourse.julialang.org/t/higher-dimensional-cross-product-in-linearalgebra/47919.md?page=2)
