Skip to content

Concatenation with I (UniformScaling) and numbers#33363

Closed
dkarrasch wants to merge 7 commits intoJuliaLang:masterfrom
dkarrasch:hvcat_scaling_number
Closed

Concatenation with I (UniformScaling) and numbers#33363
dkarrasch wants to merge 7 commits intoJuliaLang:masterfrom
dkarrasch:hvcat_scaling_number

Conversation

@dkarrasch
Copy link
Copy Markdown
Member

@dkarrasch dkarrasch commented Sep 23, 2019

Fixes JuliaLang/LinearAlgebra.jl#666.

The hvcat method used to error (see JuliaLang/LinearAlgebra.jl#666), so this is kind of a bugfix, but one could also say a new feature. The hcat/vcat is not a new feature since it currently returns an array of Any when concatenating matrices, uniform scalings and numbers:

julia> C = [[1 2] I 3]
1×4 Array{Any,2}:
 1  2  UniformScaling{Bool}(true)  3

So probably this part is breaking (and could be removed from this PR or even altogether if people see some conflict).

EDIT: I think it's technically breaking, but hard to imagine that people have specifically used this with the above behavior.

@dkarrasch
Copy link
Copy Markdown
Member Author

dkarrasch commented Sep 23, 2019

Hm, the vcat modifications also kick in when there is no UniformScaling around, and then a column matrix is returned instead of a simple vector. hcat is fine though. I'm not sure if there is a simple fix to that, other than reverting that change.

EDIT: I think that's fixed now.

@mbauman mbauman added the linear algebra Linear algebra label Sep 23, 2019
@mbauman mbauman requested a review from stevengj September 23, 2019 15:04
# so that the same promotion code can be used for hvcat. We pass the type T
# so that we can re-use this code for sparse-matrix hcat etcetera.
promote_to_arrays_(n::Int, ::Type{Matrix}, J::UniformScaling{T}) where {T} = copyto!(Matrix{T}(undef, n,n), J)
promote_to_arrays_(n::Int, ::Type, a::T) where {T<:Number} = copyto!(Vector{T}(undef, 1), a)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A little unfortunate that for every scalar it will now allocate a Vector first … seems like it would be better to change the logic elsewhere.

@dkarrasch
Copy link
Copy Markdown
Member Author

@stevengj Thanks for the comment. I made a second attempt without allocating vectors. The resulting method is more special than the generic hv/h/vcat, so at the end we need to call a function with a different name.

@dkarrasch
Copy link
Copy Markdown
Member Author

I'm running out of ideas... I had added Number to the signature of hvcat and "promoted" numbers to numbers. Without Numbers in the signature, we have only abstract matrices, so when we call hvcat again it's calling a different method, with homogeneous argument types. With Numbers, we can't call hvcat on the promoted arguments again, because the method calls itself indefinitely.

I was trying to circumvent this by calling typed_hvcat after the promotion, but that doesn't get the dense/sparse logic right (one of my own tests gets it wrong, all other existing tests pass!). The reason seems to be that the sparse concatenation routines don't run by typed_*cat methods, which are called within typed_hvcat. Those don't even return a sparse matrix when you hcat a number with a sparse row vector...

To resolve this, we would need to call straigt *cat, and so the cat bites itself.

@dkarrasch
Copy link
Copy Markdown
Member Author

So I couldn't get this working without the allocation @stevengj rightly found unfortunate. So I'm fine with closing this, unless fixing the original issue by c4dd694 weighs more than the price we would pay with the allocations. @stevengj @mbauman

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

linear algebra Linear algebra

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Concatenation with I (UniformScaling) fails with numbers

3 participants