@@ -189,10 +189,20 @@ end
189189# Converting from Bidiagonal to dense Matrix
190190function Matrix {T} (A:: Bidiagonal ) where T
191191 B = Matrix {T} (undef, size (A))
192+ iszero (size (B,1 )) && return B
192193 if haszero (T) # optimized path for types with zero(T) defined
193194 size (B,1 ) > 1 && fill! (B, zero (T))
194- copyto! (diagview (B), A. dv)
195- copyto! (diagview (B, _offdiagind (A. uplo)), A. ev)
195+ isupper = A. uplo == ' U'
196+ if isupper
197+ B[1 ,1 ] = A. dv[1 ]
198+ end
199+ for col in axes (A. ev,1 )
200+ B[col+ ! isupper, col+ isupper] = A. ev[col]
201+ B[col+ isupper, col+ isupper] = A. dv[col+ isupper]
202+ end
203+ if ! isupper
204+ B[end ,end ] = A. dv[end ]
205+ end
196206 else
197207 copyto! (B, A)
198208 end
@@ -286,6 +296,7 @@ axes(M::Bidiagonal) = (ax = axes(M.dv, 1); (ax, ax))
286296for func in (:conj , :copy , :real , :imag )
287297 @eval ($ func)(M:: Bidiagonal ) = Bidiagonal (($ func)(M. dv), ($ func)(M. ev), M. uplo)
288298end
299+ isreal (M:: Bidiagonal ) = isreal (M. dv) && isreal (M. ev)
289300
290301adjoint (B:: Bidiagonal{<:Number} ) = Bidiagonal (vec (adjoint (B. dv)), vec (adjoint (B. ev)), B. uplo == ' U' ? :L : :U )
291302adjoint (B:: Bidiagonal{<:Number, <:Base.ReshapedArray{<:Number,1,<:Adjoint}} ) =
@@ -454,8 +465,8 @@ function rmul!(B::Bidiagonal, x::Number)
454465 iszero (y) || throw (ArgumentError (LazyString (lazy " cannot set index ($row, $col) off " ,
455466 lazy " the tridiagonal band to a nonzero value ($y)" )))
456467 end
457- @. B. dv *= x
458- @. B. ev *= x
468+ rmul! ( B. dv, x)
469+ rmul! ( B. ev, x)
459470 return B
460471end
461472function lmul! (x:: Number , B:: Bidiagonal )
@@ -467,8 +478,8 @@ function lmul!(x::Number, B::Bidiagonal)
467478 iszero (y) || throw (ArgumentError (LazyString (lazy " cannot set index ($row, $col) off " ,
468479 lazy " the tridiagonal band to a nonzero value ($y)" )))
469480 end
470- @. B . dv = x * B. dv
471- @. B . ev = x * B. ev
481+ lmul! (x, B. dv)
482+ lmul! (x, B. ev)
472483 return B
473484end
474485/ (A:: Bidiagonal , B:: Number ) = Bidiagonal (A. dv/ B, A. ev/ B, A. uplo)
@@ -583,7 +594,7 @@ function _diag(A::Bidiagonal, k)
583594 elseif k == _offdiagind (A. uplo)
584595 return A. ev
585596 else
586- return diag (A, k)
597+ return diagview (A, k)
587598 end
588599end
589600
@@ -952,11 +963,10 @@ function _mul!(C::AbstractVecOrMat, A::BiTriSym, B::AbstractVecOrMat, _add::MulA
952963 nB = size (B,2 )
953964 (iszero (nA) || iszero (nB)) && return C
954965 iszero (_add. alpha) && return _rmul_or_fill! (C, _add. beta)
955- if nA <= 3
956- # naive multiplication
957- for I in CartesianIndices (C)
958- col = Base. tail (Tuple (I))
959- _modify! (_add, sum (A[I[1 ], k] * B[k, col... ] for k in axes (A,2 )), C, I)
966+ if nA == 1
967+ A11 = @inbounds A[1 ,1 ]
968+ for i in axes (B, 2 )
969+ @inbounds _modify! (_add, A11 * B[1 ,i], C, (1 ,i))
960970 end
961971 return C
962972 end
@@ -1189,25 +1199,25 @@ function _dibimul!(C::Bidiagonal, A::Diagonal, B::Bidiagonal, _add)
11891199 C
11901200end
11911201
1192- function * (A:: UpperOrUnitUpperTriangular , B:: Bidiagonal )
1202+ function mul (A:: UpperOrUnitUpperTriangular , B:: Bidiagonal )
11931203 TS = promote_op (matprod, eltype (A), eltype (B))
11941204 C = mul! (similar (A, TS, size (A)), A, B)
11951205 return B. uplo == ' U' ? UpperTriangular (C) : C
11961206end
11971207
1198- function * (A:: LowerOrUnitLowerTriangular , B:: Bidiagonal )
1208+ function mul (A:: LowerOrUnitLowerTriangular , B:: Bidiagonal )
11991209 TS = promote_op (matprod, eltype (A), eltype (B))
12001210 C = mul! (similar (A, TS, size (A)), A, B)
12011211 return B. uplo == ' L' ? LowerTriangular (C) : C
12021212end
12031213
1204- function * (A:: Bidiagonal , B:: UpperOrUnitUpperTriangular )
1214+ function mul (A:: Bidiagonal , B:: UpperOrUnitUpperTriangular )
12051215 TS = promote_op (matprod, eltype (A), eltype (B))
12061216 C = mul! (similar (B, TS, size (B)), A, B)
12071217 return A. uplo == ' U' ? UpperTriangular (C) : C
12081218end
12091219
1210- function * (A:: Bidiagonal , B:: LowerOrUnitLowerTriangular )
1220+ function mul (A:: Bidiagonal , B:: LowerOrUnitLowerTriangular )
12111221 TS = promote_op (matprod, eltype (A), eltype (B))
12121222 C = mul! (similar (B, TS, size (B)), A, B)
12131223 return A. uplo == ' L' ? LowerTriangular (C) : C
@@ -1249,19 +1259,19 @@ end
12491259ldiv! (A:: Bidiagonal , b:: AbstractVecOrMat ) = @inline ldiv! (b, A, b)
12501260function ldiv! (c:: AbstractVecOrMat , A:: Bidiagonal , b:: AbstractVecOrMat )
12511261 require_one_based_indexing (c, A, b)
1252- N = size (A, 2 )
1262+ N = size (A, 1 )
12531263 mb, nb = size (b, 1 ), size (b, 2 )
12541264 if N != mb
1255- throw (DimensionMismatch (lazy " second dimension of A, $N, does not match first dimension of b, $mb" ))
1265+ dimstr = b isa AbstractVector ? " length" : " first dimension"
1266+ throw (DimensionMismatch (LazyString (lazy " the first dimension of the Bidiagonal matrix, $N, " ,
1267+ lazy " does not match the $dimstr of the right-hand-side, $mb" )))
12561268 end
12571269 mc, nc = size (c, 1 ), size (c, 2 )
12581270 if mc != mb || nc != nb
1259- throw (DimensionMismatch (lazy " size of result, ($mc, $nc) , does not match the size of b, ($mb, $nb )" ))
1271+ throw (DimensionMismatch (lazy " size of result, $(size(c)) , does not match the size of b, $(size(b) )" ))
12601272 end
12611273
1262- if N == 0
1263- return copyto! (c, b)
1264- end
1274+ N == 0 && return c # in this case c and b are also empty
12651275
12661276 zi = findfirst (iszero, A. dv)
12671277 isnothing (zi) || throw (SingularException (zi))
@@ -1333,27 +1343,27 @@ function _rdiv!(C::AbstractMatrix, A::AbstractMatrix, B::Bidiagonal)
13331343 isnothing (zi) || throw (SingularException (zi))
13341344
13351345 if B. uplo == ' L'
1336- diagB = B. dv[n]
1337- for i in 1 : m
1338- C[i,n] = A[i,n] / diagB
1346+ diagB = @inbounds B. dv[n]
1347+ for i in axes (A, 1 )
1348+ @inbounds C[i,n] = A[i,n] / diagB
13391349 end
1340- for j in n- 1 : - 1 : 1
1341- diagB = B. dv[j]
1342- offdiagB = B. ev[j]
1343- for i in 1 : m
1344- C[i,j] = (A[i,j] - C[i,j+ 1 ]* offdiagB)/ diagB
1350+ for j in reverse ( axes (A, 2 )[ 1 : end - 1 ]) # n-1:-1:1
1351+ diagB = @inbounds B. dv[j]
1352+ offdiagB = @inbounds B. ev[j]
1353+ for i in axes (A, 1 )
1354+ @inbounds C[i,j] = (A[i,j] - C[i,j+ 1 ]* offdiagB)/ diagB
13451355 end
13461356 end
13471357 else
1348- diagB = B. dv[1 ]
1349- for i in 1 : m
1350- C[i,1 ] = A[i,1 ] / diagB
1358+ diagB = @inbounds B. dv[1 ]
1359+ for i in axes (A, 1 )
1360+ @inbounds C[i,1 ] = A[i,1 ] / diagB
13511361 end
1352- for j in 2 : n
1353- diagB = B. dv[j]
1354- offdiagB = B. ev[j- 1 ]
1355- for i = 1 : m
1356- C[i,j] = (A[i,j] - C[i,j- 1 ]* offdiagB)/ diagB
1362+ for j in axes (A, 2 )[ 2 : end ]
1363+ diagB = @inbounds B. dv[j]
1364+ offdiagB = @inbounds B. ev[j- 1 ]
1365+ for i in axes (A, 1 )
1366+ @inbounds C[i,j] = (A[i,j] - C[i,j- 1 ]* offdiagB)/ diagB
13571367 end
13581368 end
13591369 end
0 commit comments