@@ -1659,6 +1659,115 @@ for (syconv, syev, sysv, sytrf, sytri, sytrs, elty, relty) in
1659
1659
end
1660
1660
end
1661
1661
1662
+
1663
+
1664
+ # Find the leading dimension
1665
+ ld = x-> max (1 ,stride (x,2 ))
1666
+ function validate (uplo)
1667
+ if ! (uplo== ' U' || uplo== ' L' )
1668
+ error (string (" Invalid UPLO: must be 'U' or 'L' but you said" , uplo))
1669
+ end
1670
+ end
1671
+ # # (BD) Bidiagonal matrices - singular value decomposition
1672
+ for (bdsqr, relty, elty) in
1673
+ ((:dbdsqr_ ,:Float64 ,:Float64 ),
1674
+ (:sbdsqr_ ,:Float32 ,:Float32 ),
1675
+ (:zbdsqr_ ,:Float64 ,:Complex128 ),
1676
+ (:cbdsqr_ ,:Float32 ,:Complex64 ))
1677
+ @eval begin
1678
+ # *> DBDSQR computes the singular values and, optionally, the right and/or
1679
+ # *> left singular vectors from the singular value decomposition (SVD) of
1680
+ # *> a real N-by-N (upper or lower) bidiagonal matrix B using the implicit
1681
+ # *> zero-shift QR algorithm.
1682
+ function bdsqr! (uplo:: BlasChar , d:: Vector{$relty} , e_:: Vector{$relty} ,
1683
+ vt:: StridedMatrix{$elty} , u:: StridedMatrix{$elty} , c:: StridedMatrix{$elty} )
1684
+
1685
+ validate (uplo)
1686
+ n = length (d)
1687
+ if length (e_) != n- 1 throw (DimensionMismatch (" bdsqr!" )) end
1688
+ ncvt, nru, ncc = size (vt)[2 ], size (u)[1 ], size (c)[2 ]
1689
+ ldvt, ldu, ldc = ld (vt), ld (u), ld (c)
1690
+ work= Array ($ elty, 4 n)
1691
+ info= Array (BlasInt,1 )
1692
+
1693
+ ccall (($ (string (bdsqr)),liblapack), Void,
1694
+ (Ptr{BlasChar}, Ptr{BlasInt}, Ptr{BlasInt}, Ptr{BlasInt}, Ptr{BlasInt},
1695
+ Ptr{$ elty}, Ptr{$ elty}, Ptr{$ elty}, Ptr{BlasInt}, Ptr{$ elty},
1696
+ Ptr{BlasInt}, Ptr{$ elty}, Ptr{BlasInt}, Ptr{$ elty}, Ptr{BlasInt}),
1697
+ & uplo, & n, ncvt, & nru, & ncc,
1698
+ d, e_, vt, & ldvt, u,
1699
+ & ldu, c, & ldc, work, info)
1700
+
1701
+ if info[1 ] != 0 throw (LAPACKException (info[1 ])) end
1702
+ d, vt, u, c # singular values in descending order, P**T * VT, U * Q, Q**T * C
1703
+ end
1704
+ end
1705
+ end
1706
+
1707
+ # Defined only for real types
1708
+ for (bdsdc, elty) in
1709
+ ((:dbdsdc_ ,:Float64 ),
1710
+ (:sbdsdc_ ,:Float32 ))
1711
+ @eval begin
1712
+ # * DBDSDC computes the singular value decomposition (SVD) of a real
1713
+ # * N-by-N (upper or lower) bidiagonal matrix B: B = U * S * VT,
1714
+ # * using a divide and conquer method
1715
+ # * .. Scalar Arguments ..
1716
+ # CHARACTER COMPQ, UPLO
1717
+ # INTEGER INFO, LDU, LDVT, N
1718
+ # * ..
1719
+ # * .. Array Arguments ..
1720
+ # INTEGER IQ( * ), IWORK( * )
1721
+ # DOUBLE PRECISION D( * ), E( * ), Q( * ), U( LDU, * ),
1722
+ # $ VT( LDVT, * ), WORK( * )
1723
+ function bdsdc! (uplo:: BlasChar , compq:: BlasChar , d:: Vector{$elty} , e_:: Vector{$elty} )
1724
+ validate (uplo)
1725
+ n, ldiq, ldq, ldu, ldvt = length (d), 1 , 1 , 1 , 1
1726
+ if compq == ' N'
1727
+ lwork = 4 n
1728
+ elseif compq == ' P'
1729
+ warn (" COMPQ='P' is not tested" )
1730
+ # TODO turn this into an actual LAPACK call
1731
+ # smlsiz=ilaenv(9, $elty==:Float64 ? 'dbdsqr' : 'sbdsqr', string(uplo, compq), n,n,n,n)
1732
+ smlsiz= 100 # For now, completely overkill
1733
+ ldq = n* (11 + 2 * smlsiz+ 8 * int (log ((n/ (smlsiz+ 1 )))/ log (2 )))
1734
+ ldiq = n* (3 + 3 * int (log (n/ (smlsiz+ 1 ))/ log (2 )))
1735
+ lwork = 6 n
1736
+ elseif compq == ' I'
1737
+ ldvt= ldu= max (1 , n)
1738
+ lwork= 3 * n^ 2 + 4 n
1739
+ else
1740
+ error (string (" Invalid COMPQ. Valid choices are 'N', 'P' or 'I' but you said '" ,compq," '" ))
1741
+ end
1742
+ u = Array ($ elty, (ldu, n))
1743
+ vt= Array ($ elty, (ldvt, n))
1744
+ q = Array ($ elty, ldq)
1745
+ iq= Array (BlasInt, ldiq)
1746
+ work = Array ($ elty, lwork)
1747
+ iwork= Array (BlasInt, 7 n)
1748
+ info = Array (BlasInt, 1 )
1749
+ ccall (($ (string (bdsdc)),liblapack), Void,
1750
+ (Ptr{BlasChar}, Ptr{BlasChar}, Ptr{BlasInt}, Ptr{$ elty}, Ptr{$ elty},
1751
+ Ptr{$ elty}, Ptr{BlasInt}, Ptr{$ elty}, Ptr{BlasInt},
1752
+ Ptr{$ elty}, Ptr{BlasInt}, Ptr{$ elty}, Ptr{BlasInt}, Ptr{BlasInt}),
1753
+ & uplo, & compq, & n, d, e_,
1754
+ u, & ldu, vt, & ldvt,
1755
+ q, iq, work, iwork, info)
1756
+
1757
+ if info[1 ] != 0 throw (LAPACKException (info[1 ])) end
1758
+ if compq == ' N'
1759
+ d
1760
+ elseif compq == ' P'
1761
+ d, q, iq
1762
+ else # compq == 'I'
1763
+ u, d, vt'
1764
+ end
1765
+ end
1766
+ end
1767
+ end
1768
+
1769
+
1770
+
1662
1771
# New symmetric eigen solver
1663
1772
for (syevr, elty) in
1664
1773
((:dsyevr_ ,:Float64 ),
0 commit comments