# How to prevent matrices decaying into vectors?

**URL:** <https://discourse.julialang.org/t/how-to-prevent-matrices-decaying-into-vectors/21260>\
**Category:** New to Julia\
**Created:** [February 27, 2019, 11:57am UTC](https://discourse.julialang.org/t/how-to-prevent-matrices-decaying-into-vectors/21260 "2019-02-27T11:57:23Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![HenrikM](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrikm/32/17975_2.png) [@HenrikM](https://discourse.julialang.org/u/HenrikM)\
**Post date:** [February 27, 2019, 11:57am UTC](https://discourse.julialang.org/t/how-to-prevent-matrices-decaying-into-vectors/21260/1 "2019-02-27T11:57:23Z")

</div>

I have a function `f` that can take matrices of various sizes as inputs. When I try to call it with matrices of size d \times 1, produced by `m[:, k]` where `k` is an integer, they get converted to vectors of size d. How to prevent this? This must have been discussed many times but I could not find any solutions. Below is an MWE:

```julia
function f(x1, x2)
    d, n1 = size(x1)
    d, n2 = size(x2)

    out = zeros(d, n1 * n2)
end

function test()
    x1 = randn(2, 3)
    x2 = randn(2, 5)

    # Works fine
    y = f(x1, x2[:, 1:2])

    # Does not work
    y = f(x1, x2[:, 1])

    display(y)
end

test()

```

---

<div class="post-metadata">

**Author:** ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)\
**Post date:** [February 27, 2019, 12:05pm UTC](https://discourse.julialang.org/t/how-to-prevent-matrices-decaying-into-vectors/21260/2 "2019-02-27T12:05:22Z")

</div>

Like this:

```julia
julia> A = randn(2,2)
2×2 Array{Float64,2}:
  2.66127 0.568908
 -1.40935 0.118752

julia> A[:,1]
2-element Array{Float64,1}:
  2.6612671809730895
 -1.409351022092897 

julia> A[:,1:1]
2×1 Array{Float64,2}:
  2.6612671809730895
 -1.409351022092897 

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [February 27, 2019, 2:03pm UTC](https://discourse.julialang.org/t/how-to-prevent-matrices-decaying-into-vectors/21260/3 "2019-02-27T14:03:23Z")

</div>

> [@HenrikM](#):
>
> I have a function `f` that can take matrices of various sizes as inputs. When I try to call it with matrices of size d×1d \times 1, produced by `m[:, k]` where `k` is an integer, they get converted to vectors of size dd.

Many routines in Base accept either a matrix or a vector, where the latter is treated as a matrix with one column. This is a pretty convenient pattern for linear-algebra code.

The way to do this is to simply pass dimension arguments to `size`, for example changing your code above to:

```julia
d, n1 = size(x1,1), size(x1,2)

```

The `size` function returns `1` for dimensions after the last one, so `size(x1,2)` will be `1` if `x1` is a vector (1d array). Note if `x1` is a vector, you are also allowed to index it as `x1[i,1]`, i.e. you can pass `1` for “extra” dimensions, to treat it as a matrix with one column.

You can even declare this explicitly in your argument signature as `function f(x1::AbstractVecOrMat, x2::AbstractVecOrMat)`, where `AbstractVecOrMat{T}` is a built-in type alias for `Union{AbstractVector{T},AbstractMatrix{T}}`.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [February 27, 2019, 2:34pm UTC](https://discourse.julialang.org/t/how-to-prevent-matrices-decaying-into-vectors/21260/4 "2019-02-27T14:34:45Z")

</div>

I just tried this and was a little surprised that we throw an error:

```julia
julia> v = rand(5);

julia> d1, d2 = size(v)
ERROR: BoundsError: attempt to access (5,)
  at index [2]

```

We could potentially allow it and just keep returning 1 as long as someone’s asking.

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [February 27, 2019, 2:59pm UTC](https://discourse.julialang.org/t/how-to-prevent-matrices-decaying-into-vectors/21260/5 "2019-02-27T14:59:07Z")

</div>

Specifically for `size`? How would that generalize?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [February 27, 2019, 3:40pm UTC](https://discourse.julialang.org/t/how-to-prevent-matrices-decaying-into-vectors/21260/6 "2019-02-27T15:40:37Z")

</div>

> [@StefanKarpinski](#):
>
> We could potentially allow it and just keep returning 1 as long as someone’s asking.

I have the same question as @tkoolen : `size(v)` is an expression that has a value regardless of the LHS, how could it know how long to run?

I consider _automatic_ expansion by `1`s a wart in the linear algebra design, but I am fine with it _on demand_. Eg `expandedsize(v, n)` could

1. expand with `1`s whenever `ndims(v) <= n`,
2. error otherwise.

This would still allow combining code for vectors and matrices.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [February 27, 2019, 3:47pm UTC](https://discourse.julialang.org/t/how-to-prevent-matrices-decaying-into-vectors/21260/7 "2019-02-27T15:47:33Z")

</div>

Yeah, it’s probably a bad idea now that I think about it a bit more. It would require returning a special `Dims` object that acts like an infinite tuple.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [February 27, 2019, 3:48pm UTC](https://discourse.julialang.org/t/how-to-prevent-matrices-decaying-into-vectors/21260/8 "2019-02-27T15:48:39Z")

</div>

We need to be able to dispatch on the number of return values.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [February 27, 2019, 3:50pm UTC](https://discourse.julialang.org/t/how-to-prevent-matrices-decaying-into-vectors/21260/9 "2019-02-27T15:50:43Z")

</div>

As I understand it, multiple return values are basically returned as a Tuple - do you mean dispatching on the return type?

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [February 27, 2019, 3:51pm UTC](https://discourse.julialang.org/t/how-to-prevent-matrices-decaying-into-vectors/21260/10 "2019-02-27T15:51:53Z")

</div>

It was mostly a joke ([Number of function output arguments - MATLAB nargout - MathWorks Nordic](https://se.mathworks.com/help/matlab/ref/nargout.html)).
