Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Towards #12251 and #12153, reimplement all full(X) method defs. as convert(Array, X) and add convert(AbstractArray, X) methods for Factorizations #17066

Merged
merged 16 commits into from
Jul 10, 2016

Conversation

Sacha0
Copy link
Member

@Sacha0 Sacha0 commented Jun 22, 2016

First step towards #12251 (edit: and now #12153 as well) (edit: explanation and plan now described in #17066 (comment)). This pull request reduces every full(X) method definition to convert(Array, X) (apart from the AbstractArray no-op fallback and the approx_full methods in test.jl):

~/pkg/julia$ grep -rn -e 'function full[{(]' -e 'full\({.*}\)\?(.*).* =' base/
base//abstractarray.jl:663:full(x::AbstractArray) = x
base//linalg/bidiag.jl:107:full(A::Bidiagonal) = convert(Array, A)
base//linalg/cholesky.jl:329:full(C::Cholesky) = convert(Array, C)
base//linalg/cholesky.jl:333:full(F::CholeskyPivoted) = convert(Array, F)
base//linalg/diagonal.jl:28:full(D::Diagonal) = convert(Array, D)
base//linalg/eigen.jl:190:full(F::Eigen) = convert(Array, F)
base//linalg/hessenberg.jl:58:full(A::HessenbergQ) = convert(Array, A)
base//linalg/hessenberg.jl:61:full(F::Hessenberg) = convert(Array, F)
base//linalg/ldlt.jl:91:full(F::LDLt) = convert(Array, F)
base//linalg/lq.jl:93:full(A::LQ) = convert(Array, A)
base//linalg/lq.jl:109:full(A::LQPackedQ; thin::Bool = true) = convert(Array, A, thin = thin)
base//linalg/lu.jl:438:full(F::LU) = convert(Array, F)
base//linalg/lu.jl:478:full{T}(F::Base.LinAlg.LU{T,Tridiagonal{T}}) = convert(Array, F)
base//linalg/qr.jl:179:full(F::Union{QR,QRCompactWY}) = convert(Array, F)
base//linalg/qr.jl:184:full(F::QRPivoted) = convert(Array, F)
base//linalg/qr.jl:252:full(A::Union{QRPackedQ,QRCompactWYQ}; thin::Bool = true) = convert(Array, A, thin = thin)
base//linalg/schur.jl:212:full(F::Schur) = convert(Array, F)
base//linalg/svd.jl:242:full(F::SVD) = convert(Array, F)
base//linalg/symmetric.jl:87:full(A::Union{Symmetric,Hermitian}) = convert(Array, A)
base//linalg/triangular.jl:52:full(A::AbstractTriangular) = convert(Array, A)
base//linalg/tridiag.jl:58:full(M::SymTridiagonal) = convert(Array, M)
base//linalg/tridiag.jl:382:full(M::Tridiagonal) = convert(Array, M)
base//sparse/sparsematrix.jl:293:full(S::SparseMatrixCSC) = convert(Array, S)
base//sparse/sparsevector.jl:679:full(x::AbstractSparseVector) = convert(Array, x)
base//test.jl:821:approx_full(x::AbstractArray) = x
base//test.jl:822:approx_full(x::Number) = x
base//test.jl:823:approx_full(x) = full(x)

This change should enable drop-in replacement of full(X) calls with convert(Array, X) throughout base/, the next step towards #12251. Some notes:

For non-Factorization types, each full(X) method is now part of a block like

convert(::Type{Matrix}, A::SparseMatrixCSC) = ...
convert(::Type{Array}, A::SparseMatrixCSC) = convert(Matrix, A)
full(A::SparseMatrixCSC) = convert(Array, A)

or

convert(::Type{Vector}, x::AbstractSparseVector) = ...
convert(::Type{Array}, x::AbstractSparseVector) = convert(Vector, x)
full(x::AbstractSparseVector) = convert(Array, x)

such that generic methods may call convert(Array, foo) for arbitrary presently-full-able foo, and hence don't need to know whether foo naturally converts to a Matrix, Vector, etc. In some cases parametric convert{T}(::Type{Matrix{T}}, X) methods already existed; this pull request preserves those methods and implements the convert(::Type{Matrix}, X) and convert(::Type{Array}, X) methods as children thereof. But it does not introduce such parametric definitions where they did not previously exist.

Edit: For Factorization types, as a simultaneous attack on #12153, each full(X) method is now part of a block like

convert(::Type{AbstractMatrix}, F::Cholesky) = ...
convert(::Type{AbstractArray}, F::Cholesky) = convert(AbstractMatrix, F)
convert(::Type{Matrix}, F::Cholesky) = convert(Array, convert(AbstractArray, F))
convert(::Type{Array}, F::Cholesky) = convert(Matrix, F)
full(F::Cholesky) = convert(Array, F)

where convert(::Type{AbstractMatrix}, F::Cholesky) recovers the original matrix, not necessarily as an Array.

For Symmetric/Hermitian types, the former full semantics also differed from the norm:

full(A::Symmetric) = copytri!(copy(A.data), A.uplo)

which does not necessarily return an Array. This pull request effectively changes the behavior to

full(A::Symmetric) = copytri!(convert(Array, copy(A.data)), A.uplo)

This change leaves a void where the (potentially useful) former behavior lived. Perhaps this behavior needs a separate name, and perhaps unification with the conceptually similar full! methods for XTriangular types, all of which return a copy of the underlying data modified such that it matches (in the AbstractArray comparison sense) the Symmetric/Hermitian/XTriangular-wrapped object. Thoughts?

Best!

@Sacha0 Sacha0 changed the title Towards #12251, reimplement all full(X) methods as convert(Array, X) Towards #12251, reimplement all full(X) method defs. as convert(Array, X) Jun 22, 2016
full(A::LQ) = convert(Array, A)

function convert{T}(::Type{Matrix}, A::LQPackedQ{T}; thin::Bool = true)
#= We construct the full eye here, even though it seems ineffecient, because
Copy link
Member

Choose a reason for hiding this comment

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

inefficient

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed. Thanks!

@nalimilan
Copy link
Member

Cool. Could you add tests for the new convert methods too?

@Sacha0
Copy link
Member Author

Sacha0 commented Jun 23, 2016

Thanks for the review!

Should we deprecate full while you're at it?

Apologies for not clearly explaining this pull request's purpose above. Deprecating full is #12251's conclusion, so yes. Overall plan:

  1. Silently reimplement all full(X) method definitions as convert(Array, X), enabling drop-in replacement of full(X) with convert(Array, X) throughout base.
  2. Replace full(X) calls with convert(Array, X) throughout base, and migrate existing tests of full to the now-directly-called convert methods.
  3. Deprecate all full methods.

Rationale for this partitioning: Completing (1) upstream of (2) upstream of (3): significantly eases (2); minimizes commit-to-commit discontinuities in functionality and testing, helping to avoid introducing regressions in existing functionality; and hopefully simplifies review by separating logically disjoint transformations.

Could you add tests for the new convert methods too?

If migrating the full tests to the underlying convert methods at this stage would be better than doing so in step (2) as described above, I would be happy to do so. Thoughts? Thanks, and best!

@nalimilan
Copy link
Member

If migrating the full tests to the underlying convert methods at this stage would be better than doing so in step (2) as described above, I would be happy to do so. Thoughts? Thanks, and best!

Adding untested features isn't generally a good idea. I guess you could copy the existing tests for full to make them exercize convert immediately, and then remove the old ones testing full as part of (2).

@Sacha0
Copy link
Member Author

Sacha0 commented Jun 23, 2016

Adding untested features isn't generally a good idea.

Agreed. The added convert methods should be exercised by way of full as it stands though, full calls now calling the added convert chains?

Edit: Thought this through while migrating the tests in #17079. All convert chains introduced here should indeed be as well exercised as corresponding/child full methods, by nature of the former becoming the latter's implementation in this PR. Hence replicating the tests as in

I guess you could copy the existing tests for full to make them exercize convert immediately, and then remove the old ones testing full as part of (2).

would not impact coverage, only increase code churn unfortunately. As such keeping test migration in #17079 alongside the other full to convert usage changes in base/ still strikes me as the best approach. If the full/convert infrastructure should be more thoroughly tested, let's make those changes in PRs separate from the #12251-related PR series, that being an orthogonal issue? Thanks again!

ip = invperm(F[:p])
return (F[:L] * F[:U])[ip,ip]
end
convert(::Type{Matrix}, C::Cholesky) = C.uplo == 'U' ? C[:U]'C[:U] : C[:L]*C[:L]'
Copy link
Member

Choose a reason for hiding this comment

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

The issue here is that the result might not be a Matrix since Cholesky is parametric on the array type.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch! What would you suggest? I could wrap the result in another convert(Array, ) call?

Copy link
Member Author

@Sacha0 Sacha0 Jun 24, 2016

Choose a reason for hiding this comment

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

For each array-parametic type that originally had a full definition not necessarily returning an Array (e.g. that you highlighted, and the array-parametric factorization types generally), I've added a wrapping convert(Array, ) to ensure the return will now be an Array.

The pattern for LDLt

convert(::Type{SymTridiagonal}, F::LDLt) = ...
convert(::Type{AbstractMatrix}, F::LDLt) = convert(SymTridiagonal, F)
convert(::Type{AbstractArray}, F::LDLt) = convert(AbstractMatrix, F)
convert(::Type{Matrix}, F::LDLt) = convert(Array, convert(AbstractArray, F))
convert(::Type{Array}, F::LDLt) = convert(Matrix, F)
full(F::LDLt) = convert(Array, F) 

is where the methods for these cases should ultimately go I think, solving #12153. Another PR though. Thanks!

Copy link
Member

@andreasnoack andreasnoack Jun 24, 2016

Choose a reason for hiding this comment

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

I think something like this is the right approach. Basically, the convert(::Type{AbstractMatrix}, F::<:Factorization) should be what full(F::Factorization) is now. The version for Matrix could then probably be defined once with

convert(::Type{Matrix}, F::Factorization) = convert(Matrix, convert(AbstractMatrix, F))

Copy link
Member Author

Choose a reason for hiding this comment

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

Cheers, we're on the same page then. Are you advocating for additionally making those changes (i.e. attacking #12153 simultaneously) in this PR, rather than in a later PR? Thanks!

Copy link
Member Author

Choose a reason for hiding this comment

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

I've reworked the PR to simultaneously address #12153 as discussed just above. Thanks! I hope JuliaCon is going well!

convert(::Type{Array}, C::Cholesky) = convert(Matrix, C)
full(C::Cholesky) = convert(Array, C)

convert(::Type{Matrix}, F::CholeskyPivoted) = (ip = invperm(F[:p]); convert(Array, (F[:L] * F[:U])[ip,ip]))
Copy link
Contributor

Choose a reason for hiding this comment

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

I liked this better in the multi-line form

Copy link
Member Author

Choose a reason for hiding this comment

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

That line is simplified / shortened in the most recent version. Do you still prefer the multiline form? If so I'll break it down. Thanks!

Copy link
Contributor

Choose a reason for hiding this comment

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

it's still multiple statements, assigning a temporary variable then using it - worth doing those on separate lines IMO

Copy link
Member Author

Choose a reason for hiding this comment

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

Multiline it is, and done! :)

@Sacha0 Sacha0 changed the title Towards #12251, reimplement all full(X) method defs. as convert(Array, X) Towards #12251 and #12153, reimplement all full(X) method defs. as convert(Array, X) and add convert(AbstractArray, X) methods for Factorizations Jun 24, 2016
"""
full(S)

Convert a sparse matrix or vector `S` into a dense matrix or vector.
"""
full

function full{Tv}(S::SparseMatrixCSC{Tv})
# Handle cases where zero(Tv) is not defined but the array is dense.
# (Should we really worry about this?)
Copy link
Contributor

Choose a reason for hiding this comment

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

this is kind of useful to keep

Copy link
Member Author

Choose a reason for hiding this comment

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

Good call. Reintroduced. Thanks!

Sacha0 added 11 commits June 27, 2016 12:13
…trixCSC) chain, and reimplement full(SparseMatrixCSC) as a synonymous child of convert(Array, SparseMatrixCSC).
…tractSparseVector) chain, and reimplement full(AbstractSparseVector) as a synonymous child of convert(Array, AbstractSparseVector).
…hain, and reimplement full(Bidiagonal) as a synonymous child of convert(Array, Bidiagonal).
…convert(Matrix, X) <- convert(Array, X) chains for Cholesky and CholeskyPivoted types, and reimplement full(X) for both types as synonymous children of convert(Array, X).
…, and reimplement full(Diagonal) as a synonymous child of convert(Array, Diagonal).
…gen) <- convert(Matrix, Eigen) <- convert(Array, Eigen) chain, and reimplement full(Eigen) as synonymous child of convert(Array, Eigen).
…y, Hessenberg) <- convert(Matrix, Hessenberg) <- convert(Array, Hessenberg) and convert(Matrix, HessenbergQ) <- convert(Array, HessenbergQ )chains, and reimplement full(X) for both types as synonmous children of convert(Array, X).
…Lt) <- convert(AbstractArray, LDLt) <- convert(Matrix, LDLt) <- convert(Array, LDLt) chain, and reimplement full(LDLt) as a synonymous child of convert(Array, LDLt).
…- convert(Matrix, LQ) <- convert(Array, LQ) and convert(Matrix, LQPackedQ) <- convert(Array, LQPackedQ) chains, and reimplement full(X) for both types as a synonymous child of convert(Array, X).
…onvert(Matrix, X) <- convert(Array, X) chains for LU and LU{T,Tridiagonal{T}} types, and reimplement full(X) for both types as synonymous children of convert(Array, X).
…stractMatrix, Union{QR,QRCompactWY}) <- convert(Matrix, Union{QR,QRCompactWY}) <- convert(Array, Union{QR,QRCompactWY}) and convert(Matrix, Union{QRPackedQ,QRCompactWYQ}) <- convert(Array, Union{QRPackedQ,QRCompactWYQ}) chains, and reimplement full(Union{QR,QRCompactWY}) and full(Union{QRPackedQ,QRCompactWYQ}) as synonymous children of convert(Array, Union{QR,QRCompactWY}) and convert(Array, Union{QRPackedQ,QRCompactWYQ}) respectively.
… Implements convert(Array, Union{Symmetric,Hermitian}) as a short child of the two preceding methods, and reimplements full(Union{Symmetric,Hermitian}) likewise.
…vert(Matrix, AbstractTriangular), and reimplements full(AbstractTriangular) as a short child of convert(Array, AbstractTriangular).
…nal) as synonymous children of convert(Matrix, Tridiagonal) and convert(Matrix, SymTridiagonal) respectively, and reimplements full(Tridiagonal) and full(SymTridiagonal) as short children of convert(Array, Tridiagonal) and convert(Array, SymTridiagonal) respectively.
@tkelman
Copy link
Contributor

tkelman commented Jun 29, 2016

just being paranoid - @nanosoldier runbenchmarks(ALL, vs=":master")

@nanosoldier
Copy link
Collaborator

Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @jrevels

@tkelman
Copy link
Contributor

tkelman commented Jun 29, 2016

I suspect those two might be noise...

@Sacha0
Copy link
Member Author

Sacha0 commented Jun 29, 2016

I suspect those two might be noise...

Concur. Is this in good shape now, or have I missed anything? Thanks and best!

@andreasnoack andreasnoack added the domain:linear algebra Linear algebra label Jul 10, 2016
@andreasnoack andreasnoack merged commit f8d67f7 into JuliaLang:master Jul 10, 2016
@andreasnoack
Copy link
Member

Unfortunately, I've just realized that we still need to come up with a good solution for what used to be e.g. full(Hermitian) and full(XTriangular). We cannot meaningfully use convert(AbstractMatrix, XTriangular/Hermitian) because XTriangular and Hermitian are already AbstractMatrix and we cannot use Martrix/Array because they are parametric on the array type. We could define a function for this but then we might as well just rename full instead of using convert. Maybe we could introduce a parenttype similarly to eltype and then we write parenttype(A)(A) and define

parenttype{T,S}(A::Hermitian{T,S}) = S
convert{T,S}(S,A::Hermitian{T,S}) = ...blablabla...

@tkelman
Copy link
Contributor

tkelman commented Jul 10, 2016

It's not really the parent, it's the wrapped type.

@andreasnoack
Copy link
Member

Can you elaborate? Don't you think that A.data of a A::LowerTriangular is a parent in the same way that A.parent is the parent of A::SubArray?

@tkelman
Copy link
Contributor

tkelman commented Jul 10, 2016

I guess it's the underlying array that the "view" is being taken of, though I think with triangular or symmetric matrices it would be more common (than with SubArray) to have situations where the internal array is never referenced as its own separate object.

@andreasnoack
Copy link
Member

I see. This made me this a little more about this and I don't think the parenttype works either. E.g. if we have

A = randn(4,4)
B = view(A,1:3,1:3)
C = Symmetric(B)

Right now, full(C) will give you a 3x3 Matrix{Float64} which I think is the useful output to get regardless of the name of the function producing it. However, parenttype(C) is a SubMatrix so convert or parenttype(C)(C) couldn't be right.

@andreasnoack
Copy link
Member

@Sacha0 What are your current thoughts here?

@Sacha0
Copy link
Member Author

Sacha0 commented Jul 12, 2016

My thoughts echo yours. Something along the lines of convert with

julia> parenttype(A) = typeof(A) == typeof(parent(A)) ? typeof(A) : parenttype(parent(A))
parenttype (generic function with 1 method)

julia> foo = rand(3,3)
3×3 Array{Float64,2}:
 0.645174   0.500884  0.85511
 0.0901531  0.753874  0.346687
 0.975905   0.920539  0.797743

julia> parenttype(Hermitian(foo))
Array{Float64,2}

julia> bar = view(foo, 1:2, 1:2)
2×2 SubArray{Float64,2,Array{Float64,2},Tuple{UnitRange{Int64},UnitRange{Int64}},false}:
 0.645174   0.500884
 0.0901531  0.753874

julia> parenttype(Hermitian(bar))
Array{Float64,2}

julia> baz = reshape(bar, 2, 2)
2×2 Base.ReshapedArray{Float64,2,SubArray{Float64,2,Array{Float64,2},Tuple{UnitRange{Int64},UnitRange{Int64}},false},Tuple{Base.MultiplicativeInverses.SignedMultiplicativeInverse{Int64}}}:
 0.645174   0.500884
 0.0901531  0.753874

julia> parenttype(Hermitian(baz))
Array{Float64,2}

julia> qux = reshape(UpperTriangular(view(Hermitian(baz),1:2,1:2)),2,2)
2×2 Base.ReshapedArray{Float64,2,UpperTriangular{Float64,SubArray{Float64,2,Hermitian{Float64,Base.ReshapedArray{Float64,2,SubArray{Float64,2,Array{Float64,2},Tuple{UnitRange{Int64},UnitRange{Int64}},false},Tuple{Base.MultiplicativeInverses.SignedMultiplicativeInverse{Int64}}}},Tuple{UnitRange{Int64},UnitRange{Int64}},false}},Tuple{Base.MultiplicativeInverses.SignedMultiplicativeInverse{Int64}}}:
 0.645174  0.500884
 0.0       0.753874

julia> parenttype(qux)
Array{Float64,2}

Edit: Maybe backingtype or underlyingtype would be a better name, reflecting that we're interested in the 'backing' or 'underlying' array type rather than the 'parent' type?

@Sacha0
Copy link
Member Author

Sacha0 commented Jul 12, 2016

Also, thanks for the review and merge! Best!

@Sacha0 Sacha0 deleted the remfull branch July 12, 2016 05:14
nalimilan pushed a commit that referenced this pull request Aug 29, 2016
…7848)

This commit will allow a user to call:
convert(Vector, my_abstractvector_of_eltype_Foo)
convert(Matrix, my_abstractmatrix_of_eltype_Foo)

which is useful because
- for the case that the variable is a subarray of the same dimensionality
- for consistency with PR #17066
tkelman pushed a commit that referenced this pull request Aug 29, 2016
…7848)

This commit will allow a user to call:
convert(Vector, my_abstractvector_of_eltype_Foo)
convert(Matrix, my_abstractmatrix_of_eltype_Foo)

which is useful because
- for the case that the variable is a subarray of the same dimensionality
- for consistency with PR #17066
(cherry picked from commit bffeedb)
mfasi pushed a commit to mfasi/julia that referenced this pull request Sep 5, 2016
…method defs. as convert(Array, X) and add convert(AbstractArray, X) methods for Factorizations (JuliaLang#17066)

* Implement convert(Matrix, SparseMatrixCSC) <- convert(Array, SparseMatrixCSC) chain, and reimplement full(SparseMatrixCSC) as a synonymous child of convert(Array, SparseMatrixCSC).

* Implement convert(Vector, AbstractSparseVector) <- convert(Array, AbstractSparseVector) chain, and reimplement full(AbstractSparseVector) as a synonymous child of convert(Array, AbstractSparseVector).

* Implement convert(Matrix, Bidiagonal) <- convert(Array, Bidiagonal) chain, and reimplement full(Bidiagonal) as a synonymous child of convert(Array, Bidiagonal).

* Implement convert(AbstractMatrix, X) <- convert(AbstractArray, X) <- convert(Matrix, X) <- convert(Array, X) chains for Cholesky and CholeskyPivoted types, and reimplement full(X) for both types as synonymous children of convert(Array, X).

* Implement convert(Matrix, Diagonal) <- convert(Array, Diagonal) chain, and reimplement full(Diagonal) as a synonymous child of convert(Array, Diagonal).

* Implement convert(AbstractMatrix, Eigen) <- convert(AbstractArray, Eigen) <- convert(Matrix, Eigen) <- convert(Array, Eigen) chain, and reimplement full(Eigen) as synonymous child of convert(Array, Eigen).

* Implement convert(AbstractMatrix, Hessenberg) <- convert(AbstractArray, Hessenberg) <- convert(Matrix, Hessenberg) <- convert(Array, Hessenberg) and convert(Matrix, HessenbergQ) <- convert(Array, HessenbergQ )chains, and reimplement full(X) for both types as synonmous children of convert(Array, X).

* Implement convert(SymTridiagonal, LDLt) <- convert(AbstractMatrix, LDLt) <- convert(AbstractArray, LDLt) <- convert(Matrix, LDLt) <- convert(Array, LDLt) chain, and reimplement full(LDLt) as a synonymous child of convert(Array, LDLt).

* Implement convert(AbstractMatrix, LQ) <- convert(AbstractArray, LQ) <- convert(Matrix, LQ) <- convert(Array, LQ) and convert(Matrix, LQPackedQ) <- convert(Array, LQPackedQ) chains, and reimplement full(X) for both types as a synonymous child of convert(Array, X).

* Implement convert(AbstractMatrix, X) < convert(AbstractArray, X) <- convert(Matrix, X) <- convert(Array, X) chains for LU and LU{T,Tridiagonal{T}} types, and reimplement full(X) for both types as synonymous children of convert(Array, X).

* Implement convert(AbstractArray, Union{QR,QRCompactWY}) <- convert(AbstractMatrix, Union{QR,QRCompactWY}) <- convert(Matrix, Union{QR,QRCompactWY}) <- convert(Array, Union{QR,QRCompactWY}) and convert(Matrix, Union{QRPackedQ,QRCompactWYQ}) <- convert(Array, Union{QRPackedQ,QRCompactWYQ}) chains, and reimplement full(Union{QR,QRCompactWY}) and full(Union{QRPackedQ,QRCompactWYQ}) as synonymous children of convert(Array, Union{QR,QRCompactWY}) and convert(Array, Union{QRPackedQ,QRCompactWYQ}) respectively.

* Implement convert(AbstractMatrix, Schur) <- convert(AbstractArray, Schur) <- convert(Matrix, Schur) <- convert(Array, Schur) chain, and reimplement full(Schur) as a synonymous child of convert(Array, Schur).

* Implement convert(AbstractMatrix, SVD) <- convert(AbstractArray, SVD) <- convert(Matrix, SVD) <- convert(Array, SVD) chain, and reimplement full(SVD) as a synonymous child of convert(Array, SVD).

* Implements convert(Matrix, Symmetric) and convert(Matrix, Hermitian). Implements convert(Array, Union{Symmetric,Hermitian}) as a short child of the two preceding methods, and reimplements full(Union{Symmetric,Hermitian}) likewise.

* Implements convert(Array, AbstractTriangular) as a short child of convert(Matrix, AbstractTriangular), and reimplements full(AbstractTriangular) as a short child of convert(Array, AbstractTriangular).

* Implements convert(Array, Tridiagonal) and convert(Array, SymTridiagonal) as synonymous children of convert(Matrix, Tridiagonal) and convert(Matrix, SymTridiagonal) respectively, and reimplements full(Tridiagonal) and full(SymTridiagonal) as short children of convert(Array, Tridiagonal) and convert(Array, SymTridiagonal) respectively.
mfasi pushed a commit to mfasi/julia that referenced this pull request Sep 5, 2016
…liaLang#17848)

This commit will allow a user to call:
convert(Vector, my_abstractvector_of_eltype_Foo)
convert(Matrix, my_abstractmatrix_of_eltype_Foo)

which is useful because
- for the case that the variable is a subarray of the same dimensionality
- for consistency with PR JuliaLang#17066
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants