424
421
function inv(C::CholeskyDense)
425
422
Ci, info = LAPACK.potri!(C.UL, copy(C.LR))
426
if info != 0 error("Matrix singular") end
423
if info != 0; throw(LAPACK.SingularException(info)); end
427
424
symmetrize!(Ci, C.UL)
430
427
## Should these functions check that the matrix is Hermitian?
431
chold!{T<:BlasFloat}(A::Matrix{T}, UL::BlasChar) = CholeskyDense{T}(A, UL)
432
chold!{T<:BlasFloat}(A::Matrix{T}) = chold!(A, 'U')
433
chold{T<:BlasFloat}(A::Matrix{T}, UL::BlasChar) = chold!(copy(A), UL)
434
chold{T<:Number}(A::Matrix{T}, UL::BlasChar) = chold(float64(A), UL)
435
chold{T<:Number}(A::Matrix{T}) = chold(A, 'U')
428
cholfact!{T<:BlasFloat}(A::Matrix{T}, UL::BlasChar) = CholeskyDense{T}(A, UL)
429
cholfact!{T<:BlasFloat}(A::Matrix{T}) = cholfact!(A, 'U')
430
cholfact{T<:BlasFloat}(A::Matrix{T}, UL::BlasChar) = cholfact!(copy(A), UL)
431
cholfact{T<:Number}(A::Matrix{T}, UL::BlasChar) = cholfact(float64(A), UL)
432
cholfact{T<:Number}(A::Matrix{T}) = cholfact(A, 'U')
437
434
## Matlab (and R) compatible
438
chol(A::Matrix, UL::BlasChar) = factors(chold(A, UL))
435
chol(A::Matrix, UL::BlasChar) = factors(cholfact(A, UL))
439
436
chol(A::Matrix) = chol(A, 'U')
440
437
chol(x::Number) = imag(x) == 0 && real(x) > 0 ? sqrt(x) : error("Argument not positive-definite")
442
type CholeskyDensePivoted{T<:BlasFloat} <: Factorization{T}
439
type CholeskyPivotedDense{T<:BlasFloat} <: Factorization{T}
445
442
piv::Vector{BlasInt}
448
function CholeskyDensePivoted(A::Matrix{T}, UL::BlasChar, tol::Real)
445
function CholeskyPivotedDense(A::Matrix{T}, UL::BlasChar, tol::Real)
449
446
A, piv, rank, info = LAPACK.pstrf!(UL, A, tol)
447
if info != 0; throw(LAPACK.RankDeficientException(info)); end
451
449
new(triu!(A), UL, piv, rank, tol)
460
size(C::CholeskyDensePivoted) = size(C.LR)
461
size(C::CholeskyDensePivoted,d::Integer) = size(C.LR,d)
463
factors(C::CholeskyDensePivoted) = C.LR, C.piv
465
function \{T<:BlasFloat}(C::CholeskyDensePivoted{T}, B::StridedVector{T})
466
if C.rank < size(C.LR, 1) error("Matrix is not positive-definite") end
458
size(C::CholeskyPivotedDense) = size(C.LR)
459
size(C::CholeskyPivotedDense,d::Integer) = size(C.LR,d)
461
factors(C::CholeskyPivotedDense) = C.LR, C.piv
463
function \{T<:BlasFloat}(C::CholeskyPivotedDense{T}, B::StridedVector{T})
464
if C.rank < size(C.LR, 1); throw(LAPACK.RankDeficientException(info)); end
467
465
LAPACK.potrs!(C.UL, C.LR, copy(B)[C.piv])[invperm(C.piv)]
469
function \{T<:BlasFloat}(C::CholeskyDensePivoted{T}, B::StridedMatrix{T})
470
if C.rank < size(C.LR, 1) error("Matrix is not positive-definite") end
468
function \{T<:BlasFloat}(C::CholeskyPivotedDense{T}, B::StridedMatrix{T})
469
if C.rank < size(C.LR, 1); throw(LAPACK.RankDeficientException(info)); end
471
470
LAPACK.potrs!(C.UL, C.LR, copy(B)[C.piv,:])[invperm(C.piv),:]
474
rank(C::CholeskyDensePivoted) = C.rank
473
rank(C::CholeskyPivotedDense) = C.rank
476
function det{T}(C::CholeskyDensePivoted{T})
475
function det{T}(C::CholeskyPivotedDense{T})
477
476
if C.rank < size(C.LR, 1)
478
477
return real(zero(T))
492
491
## Should these functions check that the matrix is Hermitian?
493
cholpd!{T<:BlasFloat}(A::Matrix{T}, UL::BlasChar, tol::Real) = CholeskyDensePivoted{T}(A, UL, tol)
494
cholpd!{T<:BlasFloat}(A::Matrix{T}, UL::BlasChar) = cholpd!(A, UL, -1.)
495
cholpd!{T<:BlasFloat}(A::Matrix{T}, tol::Real) = cholpd!(A, 'U', tol)
496
cholpd!{T<:BlasFloat}(A::Matrix{T}) = cholpd!(A, 'U', -1.)
497
cholpd{T<:Number}(A::Matrix{T}, UL::BlasChar, tol::Real) = cholpd(float64(A), UL, tol)
498
cholpd{T<:Number}(A::Matrix{T}, UL::BlasChar) = cholpd(float64(A), UL, -1.)
499
cholpd{T<:Number}(A::Matrix{T}, tol::Real) = cholpd(float64(A), true, tol)
500
cholpd{T<:Number}(A::Matrix{T}) = cholpd(float64(A), 'U', -1.)
501
cholpd{T<:BlasFloat}(A::Matrix{T}, UL::BlasChar, tol::Real) = cholpd!(copy(A), UL, tol)
502
cholpd{T<:BlasFloat}(A::Matrix{T}, UL::BlasChar) = cholpd!(copy(A), UL, -1.)
503
cholpd{T<:BlasFloat}(A::Matrix{T}, tol::Real) = cholpd!(copy(A), 'U', tol)
504
cholpd{T<:BlasFloat}(A::Matrix{T}) = cholpd!(copy(A), 'U', -1.)
492
cholpfact!{T<:BlasFloat}(A::Matrix{T}, UL::BlasChar, tol::Real) = CholeskyPivotedDense{T}(A, UL, tol)
493
cholpfact!{T<:BlasFloat}(A::Matrix{T}, UL::BlasChar) = cholpfact!(A, UL, -1.)
494
cholpfact!{T<:BlasFloat}(A::Matrix{T}, tol::Real) = cholpfact!(A, 'U', tol)
495
cholpfact!{T<:BlasFloat}(A::Matrix{T}) = cholpfact!(A, 'U', -1.)
496
cholpfact{T<:Number}(A::Matrix{T}, UL::BlasChar, tol::Real) = cholpfact(float64(A), UL, tol)
497
cholpfact{T<:Number}(A::Matrix{T}, UL::BlasChar) = cholpfact(float64(A), UL, -1.)
498
cholpfact{T<:Number}(A::Matrix{T}, tol::Real) = cholpfact(float64(A), true, tol)
499
cholpfact{T<:Number}(A::Matrix{T}) = cholpfact(float64(A), 'U', -1.)
500
cholpfact{T<:BlasFloat}(A::Matrix{T}, UL::BlasChar, tol::Real) = cholpfact!(copy(A), UL, tol)
501
cholpfact{T<:BlasFloat}(A::Matrix{T}, UL::BlasChar) = cholpfact!(copy(A), UL, -1.)
502
cholpfact{T<:BlasFloat}(A::Matrix{T}, tol::Real) = cholpfact!(copy(A), 'U', tol)
503
cholpfact{T<:BlasFloat}(A::Matrix{T}) = cholpfact!(copy(A), 'U', -1.)
506
505
type LUDense{T} <: Factorization{T}
572
571
size(A::QRDense) = size(A.hh)
573
572
size(A::QRDense,n) = size(A.hh,n)
575
qrd!{T<:BlasFloat}(A::StridedMatrix{T}) = QRDense{T}(LAPACK.geqrf!(A)...)
576
qrd{T<:BlasFloat}(A::StridedMatrix{T}) = qrd!(copy(A))
577
qrd{T<:Real}(A::StridedMatrix{T}) = qrd(float64(A))
574
qrfact!{T<:BlasFloat}(A::StridedMatrix{T}) = QRDense{T}(LAPACK.geqrf!(A)...)
575
qrfact{T<:BlasFloat}(A::StridedMatrix{T}) = qrfact!(copy(A))
576
qrfact{T<:Real}(A::StridedMatrix{T}) = qrfact(float64(A))
579
function factors{T<:BlasFloat}(qrd::QRDense{T})
578
function factors{T<:BlasFloat}(qrfact::QRDense{T})
581
580
R = triu(aa[1:min(size(aa)),:]) # must be *before* call to orgqr!
582
LAPACK.orgqr!(aa, qrd.tau, size(aa,2)), R
581
LAPACK.orgqr!(aa, qrfact.tau, size(aa,2)), R
585
qr{T<:Number}(x::StridedMatrix{T}) = factors(qrd(x))
584
qr{T<:Number}(x::StridedMatrix{T}) = factors(qrfact(x))
586
585
qr(x::Number) = (one(x), x)
588
587
## Multiplication by Q from the QR decomposition
589
(*){T<:BlasFloat}(A::QRDense{T}, B::StridedVecOrMat{T}) =
588
qmulQR{T<:BlasFloat}(A::QRDense{T}, B::StridedVecOrMat{T}) =
590
589
LAPACK.ormqr!('L', 'N', A.hh, size(A.hh,2), A.tau, copy(B))
592
591
## Multiplication by Q' from the QR decomposition
593
Ac_mul_B{T<:BlasFloat}(A::QRDense{T}, B::StridedVecOrMat{T}) =
592
qTmulQR{T<:BlasFloat}(A::QRDense{T}, B::StridedVecOrMat{T}) =
594
593
LAPACK.ormqr!('L', iscomplex(A.tau)?'C':'T', A.hh, size(A.hh,2), A.tau, copy(B))
596
595
## Least squares solution. Should be more careful about cases with m < n
597
596
function (\){T<:BlasFloat}(A::QRDense{T}, B::StridedVecOrMat{T})
598
597
n = length(A.tau)
599
ans, info = LAPACK.trtrs!('U','N','N',A.hh[1:n,:],(A'*B)[1:n,:])
598
ans, info = LAPACK.trtrs!('U','N','N',A.hh[1:n,:],(qTmulQR(A,B))[1:n,:])
600
599
if info > 0; throw(LAPACK.SingularException(info)); end
604
type QRPDense{T} <: Factorization{T}
603
type QRPivotedDense{T} <: Factorization{T}
607
606
jpvt::Vector{BlasInt}
608
function QRPDense(hh::Matrix{T}, tau::Vector{T}, jpvt::Vector{BlasInt})
607
function QRPivotedDense(hh::Matrix{T}, tau::Vector{T}, jpvt::Vector{BlasInt})
610
609
if length(tau) != min(m,n) || length(jpvt) != n
611
error("QRPDense: mismatched dimensions")
610
error("QRPivotedDense: mismatched dimensions")
616
size(x::QRPDense) = size(x.hh)
617
size(x::QRPDense,d) = size(x.hh,d)
615
size(x::QRPivotedDense) = size(x.hh)
616
size(x::QRPivotedDense,d) = size(x.hh,d)
618
617
## Multiplication by Q from the QR decomposition
619
(*){T<:BlasFloat}(A::QRPDense{T}, B::StridedVecOrMat{T}) =
618
qmulQR{T<:BlasFloat}(A::QRPivotedDense{T}, B::StridedVecOrMat{T}) =
620
619
LAPACK.ormqr!('L', 'N', A.hh, size(A,2), A.tau, copy(B))
621
620
## Multiplication by Q' from the QR decomposition
622
Ac_mul_B{T<:BlasFloat}(A::QRPDense{T}, B::StridedVecOrMat{T}) =
621
qTmulQR{T<:BlasFloat}(A::QRPivotedDense{T}, B::StridedVecOrMat{T}) =
623
622
LAPACK.ormqr!('L', iscomplex(A.tau)?'C':'T', A.hh, size(A,2), A.tau, copy(B))
625
qrpd!{T<:BlasFloat}(A::StridedMatrix{T}) = QRPDense{T}(LAPACK.geqp3!(A)...)
626
qrpd{T<:BlasFloat}(A::StridedMatrix{T}) = qrpd!(copy(A))
627
qrpd{T<:Real}(x::StridedMatrix{T}) = qrpd(float64(x))
624
qrpfact!{T<:BlasFloat}(A::StridedMatrix{T}) = QRPivotedDense{T}(LAPACK.geqp3!(A)...)
625
qrpfact{T<:BlasFloat}(A::StridedMatrix{T}) = qrpfact!(copy(A))
626
qrpfact{T<:Real}(x::StridedMatrix{T}) = qrpfact(float64(x))
629
function factors{T<:BlasFloat}(x::QRPDense{T})
628
function factors{T<:BlasFloat}(x::QRPivotedDense{T})
631
630
R = triu(aa[1:min(size(aa)),:])
632
631
LAPACK.orgqr!(aa, x.tau, size(aa,2)), R, x.jpvt
635
qrp{T<:BlasFloat}(x::StridedMatrix{T}) = factors(qrpd(x))
634
qrp{T<:BlasFloat}(x::StridedMatrix{T}) = factors(qrpfact(x))
636
635
qrp{T<:Real}(x::StridedMatrix{T}) = qrp(float64(x))
638
function (\){T<:BlasFloat}(A::QRPDense{T}, B::StridedVecOrMat{T})
637
function (\){T<:BlasFloat}(A::QRPivotedDense{T}, B::StridedVecOrMat{T})
639
638
n = length(A.tau)
640
x, info = LAPACK.trtrs!('U','N','N',A.hh[1:n,:],(A'*B)[1:n,:])
639
x, info = LAPACK.trtrs!('U','N','N',A.hh[1:n,:],(qTmulQR(A,B))[1:n,:])
641
640
if info > 0; throw(LAPACK.SingularException(info)); end
642
641
isa(B, Vector) ? x[invperm(A.jpvt)] : x[:,invperm(A.jpvt)]
728
727
eig(x) = eig(x, true)
729
728
eigvals(x) = eig(x, false)
731
# This is the svd based on the LAPACK GESVD, which is slower, but takes
732
# lesser memory. It should be made available through a keyword argument
735
# function svd{T<:BlasFloat}(A::StridedMatrix{T},vecs::Bool,thin::Bool)
737
# if m == 0 || n == 0
738
# if vecs; return (eye(m, thin ? n : m), zeros(0), eye(n,n)); end
739
# return (zeros(T, 0, 0), zeros(T, 0), zeros(T, 0, 0))
741
# if vecs; return LAPACK.gesvd!(thin ? 'S' : 'A', thin ? 'S' : 'A', copy(A)); end
742
# LAPACK.gesvd!('N', 'N', copy(A))
745
# svd{T<:Integer}(x::StridedMatrix{T},vecs,thin) = svd(float64(x),vecs,thin)
746
# svd(A::StridedMatrix) = svd(A,true,false)
747
# svd(A::StridedMatrix, thin::Bool) = svd(A,true,thin)
748
# svdvals(A) = svd(A,false,true)[2]
750
svdt(x::Number,vecs::Bool,thin::Bool) = vecs ? (x==0?one(x):x/abs(x),abs(x),one(x)) : ([],abs(x),[])
751
svdt(x::Number,vecs::Bool,thin::Bool) = svdt(x, vecs, thin)
753
function svdt{T<:BlasFloat}(A::StridedMatrix{T},vecs::Bool,thin::Bool)
756
if vecs; return (eye(m, thin ? n : m), zeros(0), eye(n,n)); end
731
type SVDDense{T,Tr} <: Factorization{T}
737
factors(F::SVDDense) = (F.U, F.S, F.V)
739
function svdfact!{T<:BlasFloat}(A::StridedMatrix{T}, thin::Bool)
742
u,s,v = (eye(m, thin ? n : m), zeros(0), eye(n,n))
744
u,s,v = LAPACK.gesdd!(thin ? 'S' : 'A', A)
746
return SVDDense(u,s,v)
749
svdfact!(A::StridedMatrix) = svdfact(A, false)
751
svdfact(A::StridedMatrix, thin::Bool) = svdfact!(copy(A), thin)
752
svdfact(A::StridedMatrix) = svdfact(A, false)
754
function svdvals!(A::StridedMatrix)
757
757
return (zeros(T, 0, 0), zeros(T, 0), zeros(T, 0, 0))
759
if vecs; return LAPACK.gesdd!(thin ? 'S' : 'A', copy(A)); end
760
LAPACK.gesdd!('N', copy(A))
763
svdt{T<:Integer}(x::StridedMatrix{T},vecs,thin) = svdt(float64(x),vecs,thin)
764
svdt(A) = svdt(A,true,false)
765
svdt(A, thin::Bool) = svdt(A,true,thin)
767
svdt(x::Number,vecs::Bool,thin::Bool) = vecs ? (x==0?one(x):x/abs(x),abs(x),one(x)) : ([],abs(x),[])
769
function svd(x::StridedMatrix,vecs::Bool,thin::Bool)
770
(u, s, vt) = svdt(x,vecs,thin)
774
svd(A) = svd(A,true,false)
775
svd(A, thin::Bool) = svd(A,true,thin)
777
svdvals(A) = svdt(A,false,true)[2]
759
U, S, V = LAPACK.gesdd!('N', A)
763
svdvals(A) = svdvals!(copy(A))
765
svdt(A::StridedMatrix, thin::Bool) = factors(svdfact(A, thin))
766
svdt(A::StridedMatrix) = svdt(A, false)
767
svdt(x::Number, thin::Bool) = (x==0?one(x):x/abs(x),abs(x),one(x))
769
function svd(A::StridedMatrix, thin::Bool)
770
u,s,v = factors(svdfact(A, thin))
774
svd(A::StridedMatrix) = svd(A, false)
775
svd(x::Number, thin::Bool) = (x==0?one(x):x/abs(x),abs(x),one(x))
779
type GSVDDense{T} <: Factorization{T}
783
a::Vector #{eltype(real(one(T)))}
784
b::Vector #{eltype(real(one(T)))}
790
function svdfact(A::StridedMatrix, B::StridedMatrix)
791
U, V, Q, a, b, k, l, R = LAPACK.ggsvd!('U', 'V', 'Q', copy(A), copy(B))
792
return GSVDDense(U, V, Q, a, b, int(k), int(l), R)
795
svd(A::StridedMatrix, B::StridedMatrix) = factors(svdfact(A, B))
797
function factors{T}(obj::GSVDDense{T})
801
if m - obj.k - obj.l >= 0
802
D1 = [eye(T, obj.k) zeros(T, obj.k, obj.l); zeros(T, obj.l, obj.k) diagm(obj.a[obj.k + 1:obj.k + obj.l]); zeros(T, m - obj.k - obj.l, obj.k + obj.l)]
803
D2 = [zeros(T, obj.l, obj.k) diagm(obj.b[obj.k + 1:obj.k + obj.l]); zeros(T, p - obj.l, obj.k + obj.l)]
804
R0 = [zeros(T, obj.k + obj.l, n - obj.k - obj.l) obj.R]
806
D1 = [eye(T, m, obj.k) [zeros(T, obj.k, m - obj.k); diagm(a[obj.k + 1:m])] zeros(T, m, obj.k + obj.l - m)]
807
D2 = [zeros(T, p, obj.k) [diagm(b[obj.k + 1:m]); zeros(T, obj.k + p - m, m - obj.k)] [zeros(T, m - obj.k, obj.k + obj.l - m); eye(T, obj.k + p - m, obj.k + obj.l - m)]]
808
R0 = [zeros(T, obj.k + obj.l, n - obj.k - obj.l) obj.R]
810
return obj.U, obj.V, obj.Q, D1, D2, R0
813
svdvals(A::StridedMatrix, B::StridedMatrix) = LAPACK.ggsvd!('N', 'N', 'N', copy(A), copy(B))[4:5]
779
815
schur{T<:BlasFloat}(A::StridedMatrix{T}) = LAPACK.gees!('V', copy(A))