# Why does Julia support \`::Vector \* ::Matrix\`?

**URL:** <https://discourse.julialang.org/t/why-does-julia-support-vector-matrix/107330>\
**Category:** General Usage\
**Tags:** question, linearalgebra\
**Created:** [December 8, 2023, 2:19pm UTC](https://discourse.julialang.org/t/why-does-julia-support-vector-matrix/107330 "2023-12-08T14:19:08Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)\
**Post date:** [December 8, 2023, 2:19pm UTC](https://discourse.julialang.org/t/why-does-julia-support-vector-matrix/107330/1 "2023-12-08T14:19:08Z")

</div>

For example,

```julia
julia> [1,2] * [2;;]
2×1 Matrix{Int64}:
 2
 4

```

This reshapes the vector as a `n x 1` matrix and multiplies it with the `1 x 1` matrix. This seems to go against the general idea of treating `Vector`s and `Matrices` as separate entities.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [December 8, 2023, 2:34pm UTC](https://discourse.julialang.org/t/why-does-julia-support-vector-matrix/107330/2 "2023-12-08T14:34:02Z")

</div>

In short, it’s because it’s convenient to have vectors participate in the algebra of matrices as though they are Nx1 columns and because — with transposed “row vectors” — there’s a comprehensive and consistent set of behaviors that allow it to do so sensibly. See Julia#4774 for the in-depth design discussion.

---

<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:** [December 8, 2023, 3:13pm UTC](https://discourse.julialang.org/t/why-does-julia-support-vector-matrix/107330/3 "2023-12-08T15:13:57Z")

</div>

More generally, we treat `AbstractArray`s as having an infinite amount of length-1 trailing dimensions:

```julia-repl
julia> size([1,2], 1)
2

julia> size([1,2], 2)
1

julia> size([1,2], 3)
1

julia> size([1,2], 4)
1

julia> [1, 2][2, 1, 1, 1, 1, 1, 1, 1]
2

```

---

<div class="post-metadata">

**Author:** ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)\
**Post date:** [December 8, 2023, 3:25pm UTC](https://discourse.julialang.org/t/why-does-julia-support-vector-matrix/107330/4 "2023-12-08T15:25:39Z")

</div>

To be honest, I’m a bit surprised by vector-matrix multiply being accepted with “compatible inferred dimensions.” I suppose the reason it’s a thing is that it’s mostly harmless – i.e., there isn’t something else we would do with it.

Although it does give rise to an inconsistency with respect to vector-vector multiplication:

```julia-repl
julia> [1;] * [1;;]
1×1 Matrix{Int64}:
 1

julia> [1;] * [1;] # why not return a 1-vector?
ERROR: MethodError: no method matching *(::Vector{Int64}, ::Vector{Int64})

```

An inferred-dimension interpretation (like justifies vector-matrix) would have accepted this vector-vector multiplication and returned a 1-vector. A justification against is that `x * y` was probably a typo of `x' * y` or `x * y'`, so this is a nice backstop.

If I were Czar I would probably have left vector-matrix multiplication as an error at any size. Alas, to make it so now would be breaking (even if it’s likely uncommon).

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [December 8, 2023, 5:55pm UTC](https://discourse.julialang.org/t/why-does-julia-support-vector-matrix/107330/5 "2023-12-08T17:55:23Z")

</div>

Right, it’s not _exactly_ like they’re Nx1 matrices. Again, I really encourage you to read through Julia#4774 or at least watch Jiahao’s :4774: JuliaCon presentation for more on the rationale here.

[![](https://global.discourse-cdn.com/julialang/original/3X/e/5/e55a2a411b08eba0d6e2cdb7b9392b0f4a8a5eee.jpeg "JuliaCon 2017 | Taking Vector Transposes Seriously | Jiahao Chen") ](https://www.youtube.com/watch?v=C2RO34b_oPM)

For Vector \* Matrix specifically, see Julia#20389.

---

<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:** [December 9, 2023, 11:20am UTC](https://discourse.julialang.org/t/why-does-julia-support-vector-matrix/107330/6 "2023-12-09T11:20:15Z")

</div>

> [@mikmoore](#):
>
> If I were Czar I would probably have left vector-matrix multiplication as an error at any size. Alas, to make it so now would be breaking (even if it’s likely uncommon).

I’d revolt for sure. Being able to write `v1 * v2'` to quickly create a rank-1 matrix is incredibly useful and nice. Having to turn that into `reshape(v1, length(v1), 1) * v2'` is so much worse, especially when v\_1 \, v\_2^\dagger is already pretty common mathematical notation for the outer product of two vectors.

> [@mikmoore](#):
>
> ```julia
> julia> [1;] * [1;] # why not return a 1-vector?
> ERROR: MethodError: no method matching *(::Vector{Int64}, ::Vector{Int64})
> 
> ```

I’d say that the reason there’s no method for this is probably just that it’s not useful since it only comes up if the vectors are both of length 1, whereas multiplying a vector by a covector is suuuper common.

---

<div class="post-metadata">

**Author:** ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)\
**Post date:** [December 9, 2023, 3:05pm UTC](https://discourse.julialang.org/t/why-does-julia-support-vector-matrix/107330/7 "2023-12-09T15:05:53Z")

</div>

Fear not – I would revolt, too. Even I never imagined to remove `x * y'` for outer products. But `y'` is a `Adjoint{<:Any,<:AbstractVector}`, which we can (and do) specialize beyond what we do for general `AbstractMatrix`. There isn’t an incompatibility here.

But like I said: there’s little harm in the current behavior, no possibility to change it in v1.x, and still almost no reason to change it beyond that.

---

<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:** [December 9, 2023, 3:46pm UTC](https://discourse.julialang.org/t/why-does-julia-support-vector-matrix/107330/8 "2023-12-09T15:46:41Z")

</div>

But then if you did `collect(v2’)` it’d just suddenly stop working. It seems quite weird and pointless to try and omit this method to me.
