Skip to content

Conversation

@fredrikekre
Copy link
Member

@fredrikekre fredrikekre commented Oct 25, 2017

My take on JuliaLang/LinearAlgebra.jl#478
Changes:

  • diag(A::StructuredMatrix[, k=0]) now return a new vector, such that it does not alias the wrapped vector. This now behaves the same for eg Matrix, where we get a new vector. It is also consistent with getindex (diag is essentially a special case of getindex).
  • diag(A::StructuredMatrix{T,VectorType}[, k=0]) always return a vector of type VectorType, i.e. the same type which the diagonals are stored as (actually we return similar(::VectorType, k::Int), but that is usually of type VectorType). This is problematic for wrapped UnitRanges but that is already pretty broken for this case. EDIT: The latest revision does actually work for UnitRanges also, since similar(1:4) return an Vector{Int} 🎉

fix JuliaLang/LinearAlgebra.jl#478

@fredrikekre fredrikekre requested a review from Sacha0 October 25, 2017 06:15
@fredrikekre fredrikekre added the linear algebra Linear algebra label Oct 25, 2017
return M.uplo == 'U' ? M.ev : zeros(T, size(M,1)-1)
elseif n == -1
return M.uplo == 'L' ? M.ev : zeros(T, size(M,1)-1)
return copy(M.dv)
Copy link
Member Author

Choose a reason for hiding this comment

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

Should change this to copy!(similar(M.dv, length(M.dv)), M.dv) to make certain we return the same type, since we then call the same similar method no matter what n is.

return M.uplo == 'U' ? M.ev : zeros(T, size(M,1)-1)
elseif n == -1
return M.uplo == 'L' ? M.ev : zeros(T, size(M,1)-1)
return copy!(similar(M.dv, length(M.dv)), M.dv)
Copy link
Member

@Sacha0 Sacha0 Oct 26, 2017

Choose a reason for hiding this comment

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

Could the length(M.dv) be omitted? (Edit: Guarding against the length specification modifying the return type?)

Copy link
Member

@Sacha0 Sacha0 Oct 26, 2017

Choose a reason for hiding this comment

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

Moreover, why not simply copy(... rather than copy!(similar(M.dv, length(M.dv)), M.dv)? Does the return type otherwise depend upon k in some cases (e.g. for ranges)?

Copy link
Member Author

Choose a reason for hiding this comment

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

Guarding against the length specification modifying the return type?

Yes, that was the idea, to guarantee that we take the same path no matter which diagonal was requested.

Moreover, why not simply copy(... rather than copy!(similar(M.dv, length(M.dv)), M.dv)? Does the return type otherwise depend upon k in some cases (e.g. for ranges)?

Same comment applies; guarantee the same code path. Also copy(r::AbstractRange) = r so that will not yield a Vector{Int} as similar does.

julia> copy(1:4)
1:4

I don't think the copy!(similar(...), ...) uses are that terrible -- it is pretty clear what is going on IMO.

Copy link
Member

Choose a reason for hiding this comment

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

Sounds good then! I might consider adding comments to make the intention clear for future readers; to someone not acquainted with the subtleties involved, the intention may be far from clear :).

Copy link
Member Author

Choose a reason for hiding this comment

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

Yea, Ill add that

Copy link
Member

@Sacha0 Sacha0 left a comment

Choose a reason for hiding this comment

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

If my guesses above at the reasons for the particular copy!(similar(... invocations are correct, then lgtm! :)

 - diag(A::StructuredMatrix[, k=0]) now return a new vector,
   such that it does not alias the wrapped vector. This now
   behaves the same for eg Matrix, where we get a new vector.
   It is also consistent with getindex (diag is essentially a
   special case of getindex).

 - diag(A::StructuredMatrix{T,VectorType}[, k=0]) now call
   similar(..., ::Int) on every branch to make sure the same
   vector type is always returned, this is usually of type
   VectorType.
function diag(M::Bidiagonal{T}, n::Integer=0) where T
function diag(M::Bidiagonal, n::Integer=0)
# every branch call similar(..., ::Int) to make sure the
# same vector type is returned independent of n
Copy link
Member

Choose a reason for hiding this comment

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

👍 :)

Copy link
Member

@Sacha0 Sacha0 left a comment

Choose a reason for hiding this comment

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

Thanks @fredrikekre! :)

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.

diag specializations for structured matrices yield dense vectors

3 participants