Matrix versus matrix transpose


#1

I’m a bit confused: how is the matrix transpose expected to work?

Let’s say I form a transpose:

julia> a = rand(3,3)
3×3 Array{Float64,2}:
 0.138434  0.0714774  0.570142
 0.169383  0.0834496  0.1411
 0.704381  0.0703364  0.0379085

julia> transpose(a)
3×3 Transpose{Float64,Array{Float64,2}}:
 0.138434   0.169383   0.704381
 0.0714774  0.0834496  0.0703364
 0.570142   0.1411     0.0379085

But in my mind that transpose IS an ARRAY, so I should be able to pass it to a function that expects an Array{Float64,2}. However that function is not going to accept that as an argument, because now I’m going to pass a Transpose{Float64,Array{Float64,2}} instead of a Array{Float64,2}.

Am I missing something?

(Sorry, I forgot to say that I’m talking about 0.7.)


#2

A Transpose is still an AbstractArray, so you can pass it to any function that expects an AbstractArray. If a function expects exactly an Array{Float64, 2} then either (1) that function is doing something that relies on the exact internal representation of an Array{Float64, 2}, in which case you can copy() the transpose to get a “plain” array, or (2) that function’s input type signatures are too restrictive, in which case the function’s input types should be updated.


#3

OK, that makes sense. Thanks.


#4

Don’t type your functions to ::Array. Instead type them to ::AbstractArray. And make your types have type parameters instead of ::Array. It makes this all a non-issue without changing performance, and gives you a lot of new features for free.


#5

That is good advice.


#6

As I understand this is a version 0.7 behaviour,
because for version 0.6 transpose(a) returns a 3×3 Array{Float64,2}

I do not find any trace of this change in the release notes for the master.
Could you point me where the change happened.


#7

Transposes are lazy now.


#8

The PR is here: https://github.com/JuliaLang/julia/pull/25364

I just flagged it as needing a NEWS update.