JuliaLang / julia

The Julia Programming Language
https://julialang.org/
MIT License
45.84k stars 5.49k forks source link

Degenerate arrays get all dimensions squeeze()d out #573

Closed pao closed 12 years ago

pao commented 12 years ago

This shouldn't come up as much now with the changes made to the treatment of singleton dimensions, but using squeeze() on a single-element array leaves you with a zero-dimensional array which interacts with scalars, rather than with arrays:

julia> degen = squeeze([1])
0-dimensional Int64 Array:
1

julia> size(degen)
()

julia> degen*[1]
no method *(Array{Int64,0},Array{Int64,1})
 in method_missing at /home/patrick/julia/jl/base.jl:60

julia> degen*1
0-dimensional Int64 Array:
1

Would it be better to leave such single-element arrays one-dimensional, or should the singular dimension rules extend to zero-dim arrays? (Or none of the above?)

StefanKarpinski commented 12 years ago

I dunno. This seems like the only consistent possible behavior to me.

JeffBezanson commented 12 years ago

The 0-d array actually works:

julia> degen = squeeze([1])
0-dimensional Int64 Array:
1

julia> degen.*[1]
[1]

julia> degen+[1]
[2]

It works with .* and +. The problem above is that matrix multiply isn't defined for 0-d * 1-d. 1-d * 1-d doesn't work either:

julia> [1]*[1]
no method *(Array{Int64,1},Array{Int64,1})
 in method_missing at /home/jeff/src/julia/jl/base.jl:60
pao commented 12 years ago

Where I see this potentially coming up, it's because some input size may vary and happen to be (1,), so I don't think that [1]*[1] is a good comparison--x*x.' is what you would write (expecting longer vectors), and in my hypothetical it just so happens x==squeeze([1]).

This type just seems like an oddity in the bestiary, but there are many things that are useful that I don't understand.

JeffBezanson commented 12 years ago

I think the real problem here might be that squeeze is just not a very good function. If you want to squeeze something to a vector (for example, a 1x1xNx1x1 thing), you can use reshape instead and be sure to get a vector like you expect.

pao commented 12 years ago

Sounds like a reasonable answer.

StefanKarpinski commented 12 years ago

How about a version of squeeze where you tell it which dimensions you expect to have left in the end — both how many and which ones. Then it can throw an exception if any other dimensions are non-singleton.