Julia type displaying change between versions

It is kind of annoying:

I saw this on the internet:

julia> Array(ones(2,2))
2×2 Array{Float64,2}:
 1.0  1.0
 1.0  1.0

but when I do it in my terminal I get:

julia> Array(ones(2,2))
2×2 Matrix{Float64}:
 1.0  1.0
 1.0  1.0

It is the same thing Array{Float64, 2} === Matrix{Float64}, the printing just changed. Supported Julia version (i.e. > 1.6) points this out when printing the type:

julia> Matrix{Float64}
Matrix{Float64} (alias for Array{Float64, 2})
8 Likes

So Julia is not backwards compatible.

All the tutorials on the net are broken now.

It is backwards compatible – the code Array(ones(2,2)) worked in both versions, and produced the exact same thing.

5 Likes

I get it but it is just not professional for a (compiled) programming language that the type information changes.

And version 1.6 was a long time after the inception of Julia.

It didn’t.

10 Likes

To be clear, Matrix{Float64} is an alias for Array{Float64,2} and has been since Julia 1.0. The only thing different in Julia 1.7 is how the type is printed.

Julia 1.0.5:

   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.0.5 (2019-09-09)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |


julia> Array{Float64,2} == Matrix{Float64}
true

julia> Array{Float64,2}
Array{Float64,2}

julia> Matrix{Float64}
Array{Float64,2}

julia> versioninfo()
Julia Version 1.0.5
Commit 3af96bcefc (2019-09-09 19:06 UTC)

Julia 1.7.1:

   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.7.1 (2021-12-22)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

julia> Array{Float64,2}
Matrix{Float64} (alias for Array{Float64, 2})

julia> Matrix{Float64}
Matrix{Float64} (alias for Array{Float64, 2})

julia> Array{Float64,2} == Matrix{Float64}
true
5 Likes
 [0:10...]
11-element Vector{Int64}:
  0  1 2 3 4 5 6 7 8 9  10
julia> [0:10...] 
11-element Array{Int64,1}: 
0 1 2 3 4 5 6 7 8 9 10

You may argue a vector is a subset of a 1D array (maybe a linear algebra expert has got the exact definition of a vector).

If there is no difference between a vector and an Array why change the type message with version 1.6.

it’s just the display because Vector{} is more readable?, Vector{T} is exactly the same thing as Array{T, 1}, nothing changed

4 Likes

Here’s the history of the change if you are interested:
https://github.com/JuliaLang/julia/pull/36032
https://github.com/JuliaLang/julia/pull/36107

1 Like

And exactly this is the problem. It leads to confusion.

Same with numpy: I have no idea if numpy has vectors. I often think I use a vector but then it turns out when I pass ‘my vector’ to a numpy function it expects kind of (1,n) array or matrix. And often the other way round I have no idea if numpy thinks a (1,n) matrix is a 1D vector.

And also numpy changes things at random. The numpy claims it doesn’t know what to do with np.float anymore and I have to change everything from np.float to np.float32 or np.float64 to avoid those nagging warning. Now, I expect no better from numpy that they change things at random because numpy is total mess (I would call it a rats nest even).

I also find a vector easier to imagine than a row of an array or matrix.

But I am not certain it should be done in array language.

Maybe a linear algebra expert can comment on it.

The printing is just a visual thing, it does not affect your code, so no, this is NOT LIKE your complaint about NumPy.

This is literally just a type alias and Julia tells you that:

julia> Vector{Int}
Vector{Int64} (alias for Array{Int64, 1})

I don’t understand what this fuss is about tbh


it’s also mentioned in docs:
https://docs.julialang.org/en/v1/base/arrays/#Base.Vector

and manual Single- and multi-dimensional Arrays · The Julia Language

The Array type is a specific instance of DenseArray; Vector and Matrix are aliases for the 1-d and 2-d cases.

11 Likes

There are “row” and “column” vectors:

In Julia, row and column vectors are best represented as follows:

julia> [1,2,3,4] # column vector
4-element Vector{Int64}:
 1
 2
 3
 4

julia> [1,2,3,4]' # row vector
1×4 adjoint(::Vector{Int64}) with eltype Int64:
 1  2  3  4

julia> typeof(ans)
LinearAlgebra.Adjoint{Int64, Vector{Int64}}

julia> transpose([1,2,3,4]) # also a row vector
1×4 transpose(::Vector{Int64}) with eltype Int64:
 1  2  3  4

julia> typeof(ans)
LinearAlgebra.Transpose{Int64, Vector{Int64}}

I have degrees in Mathematics and Biophysics. This is one of the best representations of linear algebra that I have seen in a programming language. Does that count as a comment from a linear algebra expert?

11 Likes

I know that there are row and column vectors.

When you read physics papers with heavy math in it careful authors always point out that v.T now is a row vector.

I am more sloppy to be honest.

Although: Coming back to your demonstration. Why is 1 column vector not a (n,1) matrix vector? What is the exact definition here?

why is it not a (n, 1, 1, 1, 1, 1) tensor? in fact, behavior wise, this, mental model works:

julia> a = [1,2,3];

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

but Julia’s typing system is designed to be able to distinguish dimension of array, if you like everything being Matrix, maybe you should use MATLAB, where a scalar is a 1x1 Matrix

4 Likes

I do not use Matlab (okay I must have used it 20 years ago when I was PhD student in physics).

And I do not wanna know what NumPy thinks a scalar should be.

But I have heard people loathing the 1x1 matrix Matlab scalar representation thing.

1 Like

One thing that I don’t think I saw mentioned that confused me when I started is that there IS a difference between a Vector (that is, a 1D array), and Matrix (that is, a 2D array) with a single column.

I gather this distinction is important to the linear algebra folks, but I find it a bit awkward. then again, it rarely comes up in practice, and I assure you that the behavior hasn’t changed (aside from the printing, that is).

Me too. But I have found that anything that seems sloppy, weird, or wrong in Julia’s implementation of linear algebra is almost certainly a misunderstanding on my part, or there’s a very good reason.

2 Likes

Also this is pretty confusing:

**julia>** Array[[5,6],[9,78]]

2-element Vector{Array}:

[5, 6]

[9, 78]

It shouldn’t rather be expressed as:

**julia>** Vector[[5,6],[9,78]]

Because an array normally is thought of as a vector of vectors and each element again can represent a vectors. Maybe I am losing money on that bet but that is how most languages would implement an array (I did it in the past with Scheme which only knows vectors but not multi dimensional arrays or 2D matrices for that matter). Why overcomplicate things.

People will argue does it really matter if you type ‘Array’ versus ‘Vector’ because the end result is practically the same.

The reason for an explicit multidimensional array type is to have 1) static guarantee that each inner slice has the same length and 2) to have all memory occupied by the matrix be contiguous. Both of these make better use of caching effects. If you have a vector of vectors as your “Matrix” type, you don’t get those guarantees.

It is not the same - having a Vector{Array} can hold arbitrary arrays, not even necessarily having the same shape or containing the same element type. A Vector{Vector} at least guarantees you the shape (i.e. dimensionality) to be the same, though still allows them to contain different elements typewise.