@@ -516,12 +516,18 @@ Base.propertynames(F::QRPivoted, private::Bool=false) =
516
516
517
517
adjoint (F:: Union{QR,QRPivoted,QRCompactWY} ) = Adjoint (F)
518
518
519
- abstract type AbstractQ{T} <: AbstractMatrix{T} end
519
+ abstract type AbstractQ{T} end
520
+ struct AdjointQ{T,S<: AbstractQ{T} } <: AbstractQ{T}
521
+ Q:: S
522
+ end
520
523
521
524
inv (Q:: AbstractQ ) = Q'
525
+ adjoint (Q:: AbstractQ ) = AdjointQ (Q)
526
+ adjoint (adjQ:: AdjointQ ) = adjQ. Q
527
+ eltype (:: AbstractQ{T} ) where {T} = T
522
528
523
529
"""
524
- QRPackedQ <: AbstractMatrix
530
+ QRPackedQ <: LinearAlgebra.AbstractQ
525
531
526
532
The orthogonal/unitary ``Q`` matrix of a QR factorization stored in [`QR`](@ref) or
527
533
[`QRPivoted`](@ref) format.
@@ -544,7 +550,7 @@ QRPackedQ{T}(factors::AbstractMatrix, τ::AbstractVector) where {T} =
544
550
QRPackedQ {T,S,typeof(τ)} (factors, τ), false )
545
551
546
552
"""
547
- QRCompactWYQ <: AbstractMatrix
553
+ QRCompactWYQ <: LinearAlgebra.AbstractQ
548
554
549
555
The orthogonal/unitary ``Q`` matrix of a QR factorization stored in [`QRCompactWY`](@ref)
550
556
format.
@@ -572,16 +578,25 @@ AbstractMatrix{T}(Q::QRPackedQ) where {T} = QRPackedQ{T}(Q)
572
578
QRCompactWYQ {S} (Q:: QRCompactWYQ ) where {S} = QRCompactWYQ (convert (AbstractMatrix{S}, Q. factors), convert (AbstractMatrix{S}, Q. T))
573
579
AbstractMatrix {S} (Q:: QRCompactWYQ{S} ) where {S} = Q
574
580
AbstractMatrix {S} (Q:: QRCompactWYQ ) where {S} = QRCompactWYQ {S} (Q)
575
- Matrix {T} (Q:: AbstractQ{S} ) where {T,S} = Matrix {T} ( lmul! (Q, Matrix {S} (I, size (Q, 1 ), min (size (Q. factors)... ))))
581
+ Matrix {T} (Q:: AbstractQ{S} ) where {T,S} = convert ( Matrix{T}, lmul! (Q, Matrix {S} (I, size (Q, 1 ), min (size (Q. factors)... ))))
576
582
Matrix (Q:: AbstractQ{T} ) where {T} = Matrix {T} (Q)
577
583
Array {T} (Q:: AbstractQ ) where {T} = Matrix {T} (Q)
578
584
Array (Q:: AbstractQ ) = Matrix (Q)
585
+ convert (:: Type{Array} , Q:: AbstractQ ) = Matrix (Q)
586
+ convert (:: Type{Matrix} , Q:: AbstractQ ) = Matrix (Q)
587
+ # legacy
588
+ @deprecate (convert (:: Type{AbstractMatrix{T}} , Q:: AbstractQ ) where {T},
589
+ convert (LinearAlgebra. AbstractQ{T}, Q))
590
+ convert (:: Type{AbstractQ{T}} , Q:: QRPackedQ ) where {T} = QRPackedQ {T} (Q)
591
+ convert (:: Type{AbstractQ{T}} , Q:: QRCompactWYQ ) where {T} = QRCompactWYQ {T} (Q)
592
+ convert (:: Type{AbstractQ{T}} , adjQ:: AdjointQ ) where {T} = adjoint (convert (AbstractQ{T}, adjQ. Q))
579
593
580
594
size (F:: Union{QR,QRCompactWY,QRPivoted} , dim:: Integer ) = size (getfield (F, :factors ), dim)
581
595
size (F:: Union{QR,QRCompactWY,QRPivoted} ) = size (getfield (F, :factors ))
582
596
size (Q:: Union{QRCompactWYQ,QRPackedQ} , dim:: Integer ) =
583
597
size (getfield (Q, :factors ), dim == 2 ? 1 : dim)
584
598
size (Q:: Union{QRCompactWYQ,QRPackedQ} ) = size (Q, 1 ), size (Q, 2 )
599
+ size (adjQ:: AdjointQ ) = size (adjQ. Q, 2 ), size (adjQ. Q, 1 )
585
600
586
601
copymutable (Q:: AbstractQ{T} ) where {T} = lmul! (Q, Matrix {T} (I, size (Q)))
587
602
copy (Q:: AbstractQ ) = copymutable (Q)
596
611
597
612
getindex (Q:: AbstractQ , i:: Int , j:: Int ) = Q[:, j][i]
598
613
614
+ # needed because AbstractQ does not subtype AbstractMatrix
615
+ qr (Q:: AbstractQ , arg... ; kwargs... ) = qr! (Matrix (Q), arg... ; kwargs... )
616
+
599
617
# specialization avoiding the fallback using slow `getindex`
600
618
function copyto! (dest:: AbstractMatrix , src:: AbstractQ )
601
619
copyto! (dest, I)
@@ -653,50 +671,49 @@ function lmul!(A::QRPackedQ, B::AbstractVecOrMat)
653
671
B
654
672
end
655
673
656
- function (* )(A :: AbstractQ , b:: StridedVector )
657
- TAb = promote_type (eltype (A ), eltype (b))
658
- Anew = convert (AbstractMatrix{TAb }, A )
659
- if size (A . factors, 1 ) == length (b)
660
- bnew = copymutable_oftype (b, TAb )
661
- elseif size (A . factors, 2 ) == length (b)
662
- bnew = [b; zeros (TAb , size (A . factors, 1 ) - length (b))]
674
+ function (* )(Q :: AbstractQ , b:: AbstractVector )
675
+ TQb = promote_type (eltype (Q ), eltype (b))
676
+ QQ = convert (AbstractQ{TQb }, Q )
677
+ if size (Q . factors, 1 ) == length (b)
678
+ bnew = copy_similar (b, TQb )
679
+ elseif size (Q . factors, 2 ) == length (b)
680
+ bnew = [b; zeros (TQb , size (Q . factors, 1 ) - length (b))]
663
681
else
664
- throw (DimensionMismatch (" vector must have length either $(size (A . factors, 1 )) or $(size (A . factors, 2 )) " ))
682
+ throw (DimensionMismatch (" vector must have length either $(size (Q . factors, 1 )) or $(size (Q . factors, 2 )) " ))
665
683
end
666
- lmul! (Anew , bnew)
684
+ lmul! (QQ , bnew)
667
685
end
668
- function (* )(A :: AbstractQ , B:: StridedMatrix )
669
- TAB = promote_type (eltype (A ), eltype (B))
670
- Anew = convert (AbstractMatrix{TAB }, A )
671
- if size (A . factors, 1 ) == size (B, 1 )
672
- Bnew = copymutable_oftype (B, TAB )
673
- elseif size (A . factors, 2 ) == size (B, 1 )
674
- Bnew = [B; zeros (TAB , size (A . factors, 1 ) - size (B,1 ), size (B, 2 ))]
686
+ function (* )(Q :: AbstractQ , B:: AbstractMatrix )
687
+ TQB = promote_type (eltype (Q ), eltype (B))
688
+ QQ = convert (AbstractQ{TQB }, Q )
689
+ if size (Q . factors, 1 ) == size (B, 1 )
690
+ Bnew = copy_similar (B, TQB )
691
+ elseif size (Q . factors, 2 ) == size (B, 1 )
692
+ Bnew = [B; zeros (TQB , size (Q . factors, 1 ) - size (B,1 ), size (B, 2 ))]
675
693
else
676
- throw (DimensionMismatch (" first dimension of matrix must have size either $(size (A . factors, 1 )) or $(size (A . factors, 2 )) " ))
694
+ throw (DimensionMismatch (" first dimension of matrix must have size either $(size (Q . factors, 1 )) or $(size (Q . factors, 2 )) " ))
677
695
end
678
- lmul! (Anew , Bnew)
696
+ lmul! (QQ , Bnew)
679
697
end
680
698
681
- function (* )(A:: AbstractQ , b:: Number )
682
- TAb = promote_type (eltype (A), typeof (b))
683
- dest = similar (A, TAb)
684
- copyto! (dest, b* I)
685
- lmul! (A, dest)
699
+ function (* )(Q:: AbstractQ , b:: Number )
700
+ TQb = promote_type (eltype (Q), typeof (b))
701
+ dest = Matrix {TQb} (b* I, size (Q))
702
+ lmul! (convert (AbstractQ{TQb}, Q), dest)
686
703
end
687
704
688
705
# ## QcB
689
- lmul! (adjA :: Adjoint {<:Any,<:QRCompactWYQ{T,S}} , B:: StridedVecOrMat{T} ) where {T<: BlasReal ,S<: StridedMatrix } =
690
- (A = adjA . parent ; LAPACK. gemqrt! (' L' , ' T' , A . factors, A . T, B))
691
- lmul! (adjA :: Adjoint {<:Any,<:QRCompactWYQ{T,S}} , B:: StridedVecOrMat{T} ) where {T<: BlasComplex ,S<: StridedMatrix } =
692
- (A = adjA . parent ; LAPACK. gemqrt! (' L' , ' C' , A . factors, A . T, B))
693
- lmul! (adjA :: Adjoint {<:Any,<:QRPackedQ{T,S}} , B:: StridedVecOrMat{T} ) where {T<: BlasReal ,S<: StridedMatrix } =
694
- (A = adjA . parent ; LAPACK. ormqr! (' L' , ' T' , A . factors, A . τ, B))
695
- lmul! (adjA :: Adjoint {<:Any,<:QRPackedQ{T,S}} , B:: StridedVecOrMat{T} ) where {T<: BlasComplex ,S<: StridedMatrix } =
696
- (A = adjA . parent ; LAPACK. ormqr! (' L' , ' C' , A . factors, A . τ, B))
697
- function lmul! (adjA:: Adjoint {<:Any,<:QRPackedQ} , B:: AbstractVecOrMat )
706
+ lmul! (adjQ :: AdjointQ {<:Any,<:QRCompactWYQ{T,S}} , B:: StridedVecOrMat{T} ) where {T<: BlasReal ,S<: StridedMatrix } =
707
+ (Q = adjQ . Q ; LAPACK. gemqrt! (' L' , ' T' , Q . factors, Q . T, B))
708
+ lmul! (adjQ :: AdjointQ {<:Any,<:QRCompactWYQ{T,S}} , B:: StridedVecOrMat{T} ) where {T<: BlasComplex ,S<: StridedMatrix } =
709
+ (Q = adjQ . Q ; LAPACK. gemqrt! (' L' , ' C' , Q . factors, Q . T, B))
710
+ lmul! (adjQ :: AdjointQ {<:Any,<:QRPackedQ{T,S}} , B:: StridedVecOrMat{T} ) where {T<: BlasReal ,S<: StridedMatrix } =
711
+ (Q = adjQ . Q ; LAPACK. ormqr! (' L' , ' T' , Q . factors, Q . τ, B))
712
+ lmul! (adjQ :: AdjointQ {<:Any,<:QRPackedQ{T,S}} , B:: StridedVecOrMat{T} ) where {T<: BlasComplex ,S<: StridedMatrix } =
713
+ (Q = adjQ . Q ; LAPACK. ormqr! (' L' , ' C' , Q . factors, Q . τ, B))
714
+ function lmul! (adjA:: AdjointQ {<:Any,<:QRPackedQ} , B:: AbstractVecOrMat )
698
715
require_one_based_indexing (B)
699
- A = adjA. parent
716
+ A = adjA. Q
700
717
mA, nA = size (A. factors)
701
718
mB, nB = size (B,1 ), size (B,2 )
702
719
if mA != mB
@@ -720,26 +737,26 @@ function lmul!(adjA::Adjoint{<:Any,<:QRPackedQ}, B::AbstractVecOrMat)
720
737
end
721
738
B
722
739
end
723
- function * (adjQ:: Adjoint{<:Any,<:AbstractQ} , B:: StridedVecOrMat )
724
- Q = adjQ. parent
725
- TQB = promote_type (eltype (Q), eltype (B))
726
- return lmul! (adjoint (convert (AbstractMatrix{TQB}, Q)), copymutable_oftype (B, TQB))
740
+ function * (adjQ:: AdjointQ , B:: AbstractMatrix )
741
+ TQB = promote_type (eltype (adjQ), eltype (B))
742
+ return lmul! (convert (AbstractQ{TQB}, adjQ), copy_similar (B, TQB))
727
743
end
728
744
729
745
# ## QBc/QcBc
730
- function * (Q:: AbstractQ , adjB:: Adjoint{<:Any,<:StridedVecOrMat } )
746
+ function * (Q:: AbstractQ , adjB:: Adjoint{<:Any,<:AbstractVecOrMat } )
731
747
B = adjB. parent
732
748
TQB = promote_type (eltype (Q), eltype (B))
733
749
Bc = similar (B, TQB, (size (B, 2 ), size (B, 1 )))
734
750
adjoint! (Bc, B)
735
- return lmul! (convert (AbstractMatrix {TQB}, Q), Bc)
751
+ return lmul! (convert (AbstractQ {TQB}, Q), Bc)
736
752
end
737
- function * (adjQ:: Adjoint{<:Any,<:AbstractQ} , adjB:: Adjoint{<:Any,<:StridedVecOrMat} )
738
- Q, B = adjQ. parent, adjB. parent
739
- TQB = promote_type (eltype (Q), eltype (B))
753
+ # disambiguation
754
+ function * (adjQ:: AdjointQ , adjB:: Adjoint{<:Any,<:AbstractVecOrMat} )
755
+ B = adjB. parent
756
+ TQB = promote_type (eltype (adjQ), eltype (B))
740
757
Bc = similar (B, TQB, (size (B, 2 ), size (B, 1 )))
741
758
adjoint! (Bc, B)
742
- return lmul! (adjoint ( convert (AbstractMatrix {TQB}, Q) ), Bc)
759
+ return lmul! (convert (AbstractQ {TQB}, adjQ ), Bc)
743
760
end
744
761
745
762
# ## AQ
@@ -772,30 +789,27 @@ function rmul!(A::StridedMatrix,Q::QRPackedQ)
772
789
A
773
790
end
774
791
775
- function (* )(A:: StridedMatrix , Q:: AbstractQ )
792
+ function (* )(A:: AbstractMatrix , Q:: AbstractQ )
776
793
TAQ = promote_type (eltype (A), eltype (Q))
777
-
778
- return rmul! (copymutable_oftype (A, TAQ), convert (AbstractMatrix{TAQ}, Q))
794
+ return rmul! (copy_similar (A, TAQ), convert (AbstractQ{TAQ}, Q))
779
795
end
780
-
781
- function (* )(a:: Number , B:: AbstractQ )
782
- TaB = promote_type (typeof (a), eltype (B))
783
- dest = similar (B, TaB)
784
- copyto! (dest, a* I)
785
- rmul! (dest, B)
796
+ function (* )(a:: Number , Q:: AbstractQ )
797
+ TaQ = promote_type (typeof (a), eltype (Q))
798
+ dest = Matrix {TaQ} (a* I, size (Q))
799
+ rmul! (dest, convert (AbstractQ{TaQ}, Q))
786
800
end
787
801
788
802
# ## AQc
789
- rmul! (A:: StridedVecOrMat{T} , adjB :: Adjoint {<:Any,<:QRCompactWYQ{T}} ) where {T<: BlasReal } =
790
- (B = adjB . parent ; LAPACK. gemqrt! (' R' , ' T' , B . factors, B . T, A))
791
- rmul! (A:: StridedVecOrMat{T} , adjB :: Adjoint {<:Any,<:QRCompactWYQ{T}} ) where {T<: BlasComplex } =
792
- (B = adjB . parent ; LAPACK. gemqrt! (' R' , ' C' , B . factors, B . T, A))
793
- rmul! (A:: StridedVecOrMat{T} , adjB :: Adjoint {<:Any,<:QRPackedQ{T}} ) where {T<: BlasReal } =
794
- (B = adjB . parent ; LAPACK. ormqr! (' R' , ' T' , B . factors, B . τ, A))
795
- rmul! (A:: StridedVecOrMat{T} , adjB :: Adjoint {<:Any,<:QRPackedQ{T}} ) where {T<: BlasComplex } =
796
- (B = adjB . parent ; LAPACK. ormqr! (' R' , ' C' , B . factors, B . τ, A))
797
- function rmul! (A:: StridedMatrix , adjQ:: Adjoint {<:Any,<:QRPackedQ} )
798
- Q = adjQ. parent
803
+ rmul! (A:: StridedVecOrMat{T} , adjQ :: AdjointQ {<:Any,<:QRCompactWYQ{T}} ) where {T<: BlasReal } =
804
+ (Q = adjQ . Q ; LAPACK. gemqrt! (' R' , ' T' , Q . factors, Q . T, A))
805
+ rmul! (A:: StridedVecOrMat{T} , adjQ :: AdjointQ {<:Any,<:QRCompactWYQ{T}} ) where {T<: BlasComplex } =
806
+ (Q = adjQ . Q ; LAPACK. gemqrt! (' R' , ' C' , Q . factors, Q . T, A))
807
+ rmul! (A:: StridedVecOrMat{T} , adjQ :: AdjointQ {<:Any,<:QRPackedQ{T}} ) where {T<: BlasReal } =
808
+ (Q = adjQ . Q ; LAPACK. ormqr! (' R' , ' T' , Q . factors, Q . τ, A))
809
+ rmul! (A:: StridedVecOrMat{T} , adjQ :: AdjointQ {<:Any,<:QRPackedQ{T}} ) where {T<: BlasComplex } =
810
+ (Q = adjQ . Q ; LAPACK. ormqr! (' R' , ' C' , Q . factors, Q . τ, A))
811
+ function rmul! (A:: StridedMatrix , adjQ:: AdjointQ {<:Any,<:QRPackedQ} )
812
+ Q = adjQ. Q
799
813
mQ, nQ = size (Q. factors)
800
814
mA, nA = size (A,1 ), size (A,2 )
801
815
if nA != mQ
@@ -819,40 +833,41 @@ function rmul!(A::StridedMatrix, adjQ::Adjoint{<:Any,<:QRPackedQ})
819
833
end
820
834
A
821
835
end
822
- function * (A:: StridedMatrix , adjB :: Adjoint{<:Any,<:AbstractQ} )
823
- B = adjB . parent
824
- TAB = promote_type (eltype (A),eltype (B ))
825
- BB = convert (AbstractMatrix{TAB }, B )
826
- if size (A,2 ) == size (B . factors, 1 )
827
- AA = copy_similar (A, TAB )
828
- return rmul! (AA, adjoint (BB ))
829
- elseif size (A,2 ) == size (B . factors,2 )
830
- return rmul! ([A zeros (TAB , size (A, 1 ), size (B . factors, 1 ) - size (B . factors, 2 ))], adjoint (BB ))
836
+ function * (A:: AbstractMatrix , adjQ :: AdjointQ )
837
+ Q = adjQ . Q
838
+ TAQ = promote_type (eltype (A),eltype (Q ))
839
+ QQ = convert (AbstractQ{TAQ }, Q )
840
+ if size (A,2 ) == size (Q . factors, 1 )
841
+ AA = copy_similar (A, TAQ )
842
+ return rmul! (AA, adjoint (QQ ))
843
+ elseif size (A,2 ) == size (Q . factors,2 )
844
+ return rmul! ([A zeros (TAQ , size (A, 1 ), size (Q . factors, 1 ) - size (Q . factors, 2 ))], adjoint (QQ ))
831
845
else
832
- throw (DimensionMismatch (" matrix A has dimensions $(size (A)) but matrix B has dimensions $(size (B )) " ))
846
+ throw (DimensionMismatch (" matrix A has dimensions $(size (A)) but matrix B has dimensions $(size (Q )) " ))
833
847
end
834
848
end
835
- * (u:: AdjointAbsVec , A :: Adjoint{<:Any,<:AbstractQ} ) = adjoint (A . parent * u. parent)
836
-
849
+ * (u:: AdjointAbsVec , adjQ :: AdjointQ ) = adjoint (adjQ . Q * u. parent)
850
+ * (a :: AbstractVector , adjQ :: AdjointQ ) = reshape (a, length (a), 1 ) * adjQ
837
851
838
852
# ## AcQ/AcQc
839
- function * (adjA:: Adjoint{<:Any,<:StridedVecOrMat } , Q:: AbstractQ )
853
+ function * (adjA:: Adjoint{<:Any,<:AbstractVecOrMat } , Q:: AbstractQ )
840
854
A = adjA. parent
841
855
TAQ = promote_type (eltype (A), eltype (Q))
842
856
Ac = similar (A, TAQ, (size (A, 2 ), size (A, 1 )))
843
857
adjoint! (Ac, A)
844
- return rmul! (Ac, convert (AbstractMatrix {TAQ}, Q))
858
+ return rmul! (Ac, convert (AbstractQ {TAQ}, Q))
845
859
end
846
- function * (adjA:: Adjoint{<:Any,<:StridedVecOrMat} , adjQ:: Adjoint{<:Any,<:AbstractQ} )
847
- A, Q = adjA. parent, adjQ. parent
848
- TAQ = promote_type (eltype (A), eltype (Q))
860
+ # disambiguation
861
+ function * (adjA:: Adjoint{<:Any,<:AbstractVecOrMat} , adjQ:: AdjointQ )
862
+ A = adjA. parent
863
+ TAQ = promote_type (eltype (A), eltype (adjQ))
849
864
Ac = similar (A, TAQ, (size (A, 2 ), size (A, 1 )))
850
865
adjoint! (Ac, A)
851
- return rmul! (Ac, adjoint ( convert (AbstractMatrix {TAQ}, Q) ))
866
+ return rmul! (Ac, convert (AbstractQ {TAQ}, adjQ ))
852
867
end
853
868
854
869
# ## mul!
855
- function mul! (C:: StridedVecOrMat{T} , Q:: AbstractQ{T} , B:: StridedVecOrMat {T} ) where {T}
870
+ function mul! (C:: StridedVecOrMat{T} , Q:: AbstractQ{T} , B:: AbstractVecOrMat {T} ) where {T}
856
871
require_one_based_indexing (C, B)
857
872
mB = size (B, 1 )
858
873
mC = size (C, 1 )
@@ -865,9 +880,9 @@ function mul!(C::StridedVecOrMat{T}, Q::AbstractQ{T}, B::StridedVecOrMat{T}) whe
865
880
return lmul! (Q, copyto! (C, B))
866
881
end
867
882
end
868
- mul! (C:: StridedVecOrMat{T} , A:: StridedVecOrMat {T} , Q:: AbstractQ{T} ) where {T} = rmul! (copyto! (C, A), Q)
869
- mul! (C:: StridedVecOrMat{T} , adjQ:: Adjoint {<:Any,<:AbstractQ{T}} , B:: StridedVecOrMat {T} ) where {T} = lmul! (adjQ, copyto! (C, B))
870
- mul! (C:: StridedVecOrMat{T} , A:: StridedVecOrMat {T} , adjQ:: Adjoint {<:Any,<:AbstractQ{T}} ) where {T} = rmul! (copyto! (C, A), adjQ)
883
+ mul! (C:: StridedVecOrMat{T} , A:: AbstractVecOrMat {T} , Q:: AbstractQ{T} ) where {T} = rmul! (copyto! (C, A), Q)
884
+ mul! (C:: StridedVecOrMat{T} , adjQ:: AdjointQ {<:Any,<:AbstractQ{T}} , B:: AbstractVecOrMat {T} ) where {T} = lmul! (adjQ, copyto! (C, B))
885
+ mul! (C:: StridedVecOrMat{T} , A:: AbstractVecOrMat {T} , adjQ:: AdjointQ {<:Any,<:AbstractQ{T}} ) where {T} = rmul! (copyto! (C, A), adjQ)
871
886
872
887
function ldiv! (A:: QRCompactWY{T} , b:: StridedVector{T} ) where {T<: BlasFloat }
873
888
m,n = size (A)
0 commit comments