Skip to content

Commit 91d7023

Browse files
authored
Merge pull request #24969 from Sacha0/lazyjazz
[WIP] lazier, less-jazzy linalg internals
2 parents f24e4c1 + a05e85f commit 91d7023

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+3076
-1314
lines changed

base/deprecated.jl

Lines changed: 790 additions & 4 deletions
Large diffs are not rendered by default.

base/linalg/adjtrans.jl

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# This file is a part of Julia. License is MIT: https://julialang.org/license
2+
3+
using Base: @pure, @propagate_inbounds, _return_type, _default_type, _isleaftype, @_inline_meta
4+
import Base: length, size, indices, IndexStyle, getindex, setindex!, parent, vec, convert, similar
5+
6+
### basic definitions (types, aliases, constructors, abstractarray interface, sundry similar)
7+
8+
# note that Adjoint and Transpose must be able to wrap not only vectors and matrices
9+
# but also factorizations, rotations, and other linear algebra objects, including
10+
# user-defined such objects. so do not restrict the wrapped type.
11+
struct Adjoint{T,S} <: AbstractMatrix{T}
12+
parent::S
13+
function Adjoint{T,S}(A::S) where {T,S}
14+
checkeltype(Adjoint, T, eltype(A))
15+
new(A)
16+
end
17+
end
18+
struct Transpose{T,S} <: AbstractMatrix{T}
19+
parent::S
20+
function Transpose{T,S}(A::S) where {T,S}
21+
checkeltype(Transpose, T, eltype(A))
22+
new(A)
23+
end
24+
end
25+
26+
@pure function checkeltype(::Type{Transform}, ::Type{ResultEltype}, ::Type{ParentEltype}) where {Transform, ResultEltype, ParentEltype}
27+
if ResultEltype !== transformtype(Transform, ParentEltype)
28+
error(string("Element type mismatch. Tried to create an `$Transform{$ResultEltype}` ",
29+
"from an object with eltype `$ParentEltype`, but the element type of the ",
30+
"`$Transform` of an object with eltype `$ParentEltype` must be ",
31+
"`$(transformtype(Transform, ParentEltype))`"))
32+
end
33+
return nothing
34+
end
35+
function transformtype(::Type{O}, ::Type{S}) where {O,S}
36+
# similar to promote_op(::Any, ::Type)
37+
@_inline_meta
38+
T = _return_type(O, Tuple{_default_type(S)})
39+
_isleaftype(S) && return _isleaftype(T) ? T : Any
40+
return typejoin(S, T)
41+
end
42+
43+
# basic outer constructors
44+
Adjoint(A) = Adjoint{transformtype(Adjoint,eltype(A)),typeof(A)}(A)
45+
Transpose(A) = Transpose{transformtype(Transpose,eltype(A)),typeof(A)}(A)
46+
47+
# numbers are the end of the line
48+
Adjoint(x::Number) = adjoint(x)
49+
Transpose(x::Number) = transpose(x)
50+
51+
# unwrapping constructors
52+
# perhaps slightly odd, but necessary (at least till adjoint and transpose names are free)
53+
Adjoint(A::Adjoint) = A.parent
54+
Transpose(A::Transpose) = A.parent
55+
56+
# some aliases for internal convenience use
57+
const AdjOrTrans{T,S} = Union{Adjoint{T,S},Transpose{T,S}} where {T,S}
58+
const AdjOrTransAbsVec{T} = AdjOrTrans{T,<:AbstractVector}
59+
const AdjOrTransAbsMat{T} = AdjOrTrans{T,<:AbstractMatrix}
60+
61+
# for internal use below
62+
wrappertype(A::Adjoint) = Adjoint
63+
wrappertype(A::Transpose) = Transpose
64+
wrappertype(::Type{<:Adjoint}) = Adjoint
65+
wrappertype(::Type{<:Transpose}) = Transpose
66+
67+
# AbstractArray interface, basic definitions
68+
length(A::AdjOrTrans) = length(A.parent)
69+
size(v::AdjOrTransAbsVec) = (1, length(v.parent))
70+
size(A::AdjOrTransAbsMat) = reverse(size(A.parent))
71+
indices(v::AdjOrTransAbsVec) = (Base.OneTo(1), indices(v.parent)...)
72+
indices(A::AdjOrTransAbsMat) = reverse(indices(A.parent))
73+
IndexStyle(::Type{<:AdjOrTransAbsVec}) = IndexLinear()
74+
IndexStyle(::Type{<:AdjOrTransAbsMat}) = IndexCartesian()
75+
@propagate_inbounds getindex(v::AdjOrTransAbsVec, i::Int) = wrappertype(v)(v.parent[i])
76+
@propagate_inbounds getindex(A::AdjOrTransAbsMat, i::Int, j::Int) = wrappertype(A)(A.parent[j, i])
77+
@propagate_inbounds setindex!(v::AdjOrTransAbsVec, x, i::Int) = (setindex!(v.parent, wrappertype(v)(x), i); v)
78+
@propagate_inbounds setindex!(A::AdjOrTransAbsMat, x, i::Int, j::Int) = (setindex!(A.parent, wrappertype(A)(x), j, i); A)
79+
# AbstractArray interface, additional definitions to retain wrapper over vectors where appropriate
80+
@propagate_inbounds getindex(v::AdjOrTransAbsVec, ::Colon, is::AbstractArray{Int}) = wrappertype(v)(v.parent[is])
81+
@propagate_inbounds getindex(v::AdjOrTransAbsVec, ::Colon, ::Colon) = wrappertype(v)(v.parent[:])
82+
83+
# conversion of underlying storage
84+
convert(::Type{Adjoint{T,S}}, A::Adjoint) where {T,S} = Adjoint{T,S}(convert(S, A.parent))
85+
convert(::Type{Transpose{T,S}}, A::Transpose) where {T,S} = Transpose{T,S}(convert(S, A.parent))
86+
87+
# for vectors, the semantics of the wrapped and unwrapped types differ
88+
# so attempt to maintain both the parent and wrapper type insofar as possible
89+
similar(A::AdjOrTransAbsVec) = wrappertype(A)(similar(A.parent))
90+
similar(A::AdjOrTransAbsVec, ::Type{T}) where {T} = wrappertype(A)(similar(A.parent, transformtype(wrappertype(A), T)))
91+
# for matrices, the semantics of the wrapped and unwrapped types are generally the same
92+
# and as you are allocating with similar anyway, you might as well get something unwrapped
93+
similar(A::AdjOrTrans) = similar(A.parent, eltype(A), size(A))
94+
similar(A::AdjOrTrans, ::Type{T}) where {T} = similar(A.parent, T, size(A))
95+
similar(A::AdjOrTrans, ::Type{T}, dims::Dims{N}) where {T,N} = similar(A.parent, T, dims)
96+
97+
# sundry basic definitions
98+
parent(A::AdjOrTrans) = A.parent
99+
vec(v::AdjOrTransAbsVec) = v.parent
100+
101+
102+
### linear algebra
103+
104+
# definitions necessary for test/linalg/rowvector.jl to pass
105+
# should be cleaned up / revised as necessary in the future
106+
/(A::Transpose{<:Any,<:Vector}, B::Matrix) = /(transpose(A.parent), B)
107+
/(A::Transpose{<:Any,<:Vector}, B::Transpose{<:Any,<:Matrix}) = /(transpose(A.parent), B)
108+
*(A::Adjoint{<:Any,<:Matrix}, B::Adjoint{<:Any,<:Vector}) = *(adjoint(A.parent), adjoint(B.parent))
109+
110+
111+
# dismabiguation methods
112+
*(A::Transpose{<:Any,<:AbstractVector}, B::Adjoint{<:Any,<:AbstractVector}) = transpose(A.parent) * B
113+
*(A::Transpose{<:Any,<:AbstractVector}, B::Adjoint{<:Any,<:AbstractMatrix}) = transpose(A.parent) * B
114+
*(A::Transpose{<:Any,<:AbstractMatrix}, B::Adjoint{<:Any,<:AbstractVector}) = A * adjoint(B.parent)
115+
*(A::Transpose{<:Any,<:AbstractMatrix}, B::Adjoint{<:Any,<:AbstractMatrix}) = transpose(A.parent) * B
116+
*(A::Adjoint{<:Any,<:AbstractVector}, B::Transpose{<:Any,<:AbstractVector}) = adjoint(A.parent) * B
117+
*(A::Adjoint{<:Any,<:AbstractVector}, B::Transpose{<:Any,<:AbstractMatrix}) = adjoint(A.parent) * B
118+
*(A::Adjoint{<:Any,<:AbstractMatrix}, B::Adjoint{<:Any,<:AbstractVector}) = A * adjoint(B.parent)
119+
*(A::Adjoint{<:Any,<:AbstractMatrix}, B::Transpose{<:Any,<:AbstractVector}) = A * transpose(B.parent)
120+
*(A::Adjoint{<:Any,<:AbstractMatrix}, B::Transpose{<:Any,<:AbstractMatrix}) = adjoint(A.parent) * B

base/linalg/bidiag.jl

Lines changed: 87 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -329,25 +329,33 @@ end
329329

330330
const BiTriSym = Union{Bidiagonal,Tridiagonal,SymTridiagonal}
331331
const BiTri = Union{Bidiagonal,Tridiagonal}
332-
A_mul_B!(C::AbstractMatrix, A::SymTridiagonal, B::BiTriSym) = A_mul_B_td!(C, A, B)
333-
A_mul_B!(C::AbstractMatrix, A::BiTri, B::BiTriSym) = A_mul_B_td!(C, A, B)
334-
A_mul_B!(C::AbstractMatrix, A::BiTriSym, B::BiTriSym) = A_mul_B_td!(C, A, B)
335-
A_mul_B!(C::AbstractMatrix, A::AbstractTriangular, B::BiTriSym) = A_mul_B_td!(C, A, B)
336-
A_mul_B!(C::AbstractMatrix, A::AbstractMatrix, B::BiTriSym) = A_mul_B_td!(C, A, B)
337-
A_mul_B!(C::AbstractMatrix, A::Diagonal, B::BiTriSym) = A_mul_B_td!(C, A, B)
338-
A_mul_B!(C::AbstractVector, A::BiTri, B::AbstractVector) = A_mul_B_td!(C, A, B)
339-
A_mul_B!(C::AbstractMatrix, A::BiTri, B::AbstractVecOrMat) = A_mul_B_td!(C, A, B)
340-
A_mul_B!(C::AbstractVecOrMat, A::BiTri, B::AbstractVecOrMat) = A_mul_B_td!(C, A, B)
341-
342-
\(::Diagonal, ::RowVector) = throw(DimensionMismatch("Cannot left-divide matrix by transposed vector"))
343-
\(::Bidiagonal, ::RowVector) = throw(DimensionMismatch("Cannot left-divide matrix by transposed vector"))
344-
\(::Bidiagonal{<:Number}, ::RowVector{<:Number}) = throw(DimensionMismatch("Cannot left-divide matrix by transposed vector"))
345-
346-
At_ldiv_B(::Bidiagonal, ::RowVector) = throw(DimensionMismatch("Cannot left-divide matrix by transposed vector"))
347-
At_ldiv_B(::Bidiagonal{<:Number}, ::RowVector{<:Number}) = throw(DimensionMismatch("Cannot left-divide matrix by transposed vector"))
348-
349-
Ac_ldiv_B(::Bidiagonal, ::RowVector) = throw(DimensionMismatch("Cannot left-divide matrix by transposed vector"))
350-
Ac_ldiv_B(::Bidiagonal{<:Number}, ::RowVector{<:Number}) = throw(DimensionMismatch("Cannot left-divide matrix by transposed vector"))
332+
mul!(C::AbstractMatrix, A::SymTridiagonal, B::BiTriSym) = A_mul_B_td!(C, A, B)
333+
mul!(C::AbstractMatrix, A::BiTri, B::BiTriSym) = A_mul_B_td!(C, A, B)
334+
mul!(C::AbstractMatrix, A::BiTriSym, B::BiTriSym) = A_mul_B_td!(C, A, B)
335+
mul!(C::AbstractMatrix, A::AbstractTriangular, B::BiTriSym) = A_mul_B_td!(C, A, B)
336+
mul!(C::AbstractMatrix, A::AbstractMatrix, B::BiTriSym) = A_mul_B_td!(C, A, B)
337+
mul!(C::AbstractMatrix, A::Diagonal, B::BiTriSym) = A_mul_B_td!(C, A, B)
338+
mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:Diagonal}, B::BiTriSym) = A_mul_B_td!(C, A, B)
339+
mul!(C::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, B::BiTriSym) = A_mul_B_td!(C, A, B)
340+
mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:AbstractTriangular}, B::BiTriSym) = A_mul_B_td!(C, A, B)
341+
mul!(C::AbstractMatrix, A::Transpose{<:Any,<:AbstractTriangular}, B::BiTriSym) = A_mul_B_td!(C, A, B)
342+
mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:AbstractVecOrMat}, B::BiTriSym) = A_mul_B_td!(C, A, B)
343+
mul!(C::AbstractMatrix, A::Transpose{<:Any,<:AbstractVecOrMat}, B::BiTriSym) = A_mul_B_td!(C, A, B)
344+
mul!(C::AbstractVector, A::BiTri, B::AbstractVector) = A_mul_B_td!(C, A, B)
345+
mul!(C::AbstractMatrix, A::BiTri, B::AbstractVecOrMat) = A_mul_B_td!(C, A, B)
346+
mul!(C::AbstractVecOrMat, A::BiTri, B::AbstractVecOrMat) = A_mul_B_td!(C, A, B)
347+
mul!(C::AbstractMatrix, A::BiTri, B::Transpose{<:Any,<:AbstractVecOrMat}) = A_mul_B_td!(C, A, B) # around bidiag line 330
348+
mul!(C::AbstractMatrix, A::BiTri, B::Adjoint{<:Any,<:AbstractVecOrMat}) = A_mul_B_td!(C, A, B)
349+
mul!(C::AbstractVector, A::BiTri, B::Transpose{<:Any,<:AbstractVecOrMat}) = throw(MethodError(mul!, (C, A, B)))
350+
351+
\(::Diagonal, ::RowVector) = _mat_ldiv_rowvec_error()
352+
\(::Bidiagonal, ::RowVector) = _mat_ldiv_rowvec_error()
353+
\(::Bidiagonal{<:Number}, ::RowVector{<:Number}) = _mat_ldiv_rowvec_error()
354+
\(::Adjoint{<:Any,<:Bidiagonal}, ::RowVector) = _mat_ldiv_rowvec_error()
355+
\(::Transpose{<:Any,<:Bidiagonal}, ::RowVector) = _mat_ldiv_rowvec_error()
356+
\(::Adjoint{<:Number,<:Bidiagonal{<:Number}}, ::RowVector{<:Number}) = _mat_ldiv_rowvec_error()
357+
\(::Transpose{<:Number,<:Bidiagonal{<:Number}}, ::RowVector{<:Number}) = _mat_ldiv_rowvec_error()
358+
_mat_ldiv_rowvec_error() = throw(DimensionMismatch("Cannot left-divide matrix by transposed vector"))
351359

352360
function check_A_mul_B!_sizes(C, A, B)
353361
nA, mA = size(A)
@@ -379,7 +387,7 @@ end
379387
function A_mul_B_td!(C::AbstractMatrix, A::BiTriSym, B::BiTriSym)
380388
check_A_mul_B!_sizes(C, A, B)
381389
n = size(A,1)
382-
n <= 3 && return A_mul_B!(C, Array(A), Array(B))
390+
n <= 3 && return mul!(C, Array(A), Array(B))
383391
fill!(C, zero(eltype(C)))
384392
Al = _diag(A, -1)
385393
Ad = _diag(A, 0)
@@ -438,7 +446,7 @@ function A_mul_B_td!(C::AbstractVecOrMat, A::BiTriSym, B::AbstractVecOrMat)
438446
if size(C,2) != nB
439447
throw(DimensionMismatch("A has second dimension $nA, B has $(size(B,2)), C has $(size(C,2)) but all must match"))
440448
end
441-
nA <= 3 && return A_mul_B!(C, Array(A), Array(B))
449+
nA <= 3 && return mul!(C, Array(A), Array(B))
442450
l = _diag(A, -1)
443451
d = _diag(A, 0)
444452
u = _diag(A, 1)
@@ -459,7 +467,7 @@ end
459467
function A_mul_B_td!(C::AbstractMatrix, A::AbstractMatrix, B::BiTriSym)
460468
check_A_mul_B!_sizes(C, A, B)
461469
n = size(A,1)
462-
n <= 3 && return A_mul_B!(C, Array(A), Array(B))
470+
n <= 3 && return mul!(C, Array(A), Array(B))
463471
m = size(B,2)
464472
Bl = _diag(B, -1)
465473
Bd = _diag(B, 0)
@@ -493,15 +501,17 @@ const SpecialMatrix = Union{Bidiagonal,SymTridiagonal,Tridiagonal}
493501
*(A::SpecialMatrix, B::SpecialMatrix) = Array(A) * Array(B)
494502

495503
#Generic multiplication
496-
for func in (:*, :Ac_mul_B, :A_mul_Bc, :/, :A_rdiv_Bc)
497-
@eval ($func)(A::Bidiagonal{T}, B::AbstractVector{T}) where {T} = ($func)(Array(A), B)
498-
end
504+
*(A::Bidiagonal{T}, B::AbstractVector{T}) where {T} = *(Array(A), B)
505+
*(adjA::Adjoint{<:Any,<:Bidiagonal{T}}, B::AbstractVector{T}) where {T} = *(Adjoint(Array(adjA.parent)), B)
506+
*(A::Bidiagonal{T}, adjB::Adjoint{<:Any,<:AbstractVector{T}}) where {T} = *(Array(A), Adjoint(adjB.parent))
507+
/(A::Bidiagonal{T}, B::AbstractVector{T}) where {T} = /(Array(A), B)
508+
/(A::Bidiagonal{T}, adjB::Adjoint{<:Any,<:AbstractVector{T}}) where {T} = /(Array(A), Adjoint(adjB.parent))
499509

500510
#Linear solvers
501-
A_ldiv_B!(A::Union{Bidiagonal, AbstractTriangular}, b::AbstractVector) = naivesub!(A, b)
502-
At_ldiv_B!(A::Bidiagonal, b::AbstractVector) = A_ldiv_B!(transpose(A), b)
503-
Ac_ldiv_B!(A::Bidiagonal, b::AbstractVector) = A_ldiv_B!(adjoint(A), b)
504-
function A_ldiv_B!(A::Union{Bidiagonal,AbstractTriangular}, B::AbstractMatrix)
511+
ldiv!(A::Union{Bidiagonal, AbstractTriangular}, b::AbstractVector) = naivesub!(A, b)
512+
ldiv!(transA::Transpose{<:Any,<:Bidiagonal}, b::AbstractVector) = ldiv!(transpose(transA.parent), b)
513+
ldiv!(adjA::Adjoint{<:Any,<:Bidiagonal}, b::AbstractVector) = ldiv!(adjoint(adjA.parent), b)
514+
function ldiv!(A::Union{Bidiagonal,AbstractTriangular}, B::AbstractMatrix)
505515
nA,mA = size(A)
506516
tmp = similar(B,size(B,1))
507517
n = size(B, 1)
@@ -510,26 +520,40 @@ function A_ldiv_B!(A::Union{Bidiagonal,AbstractTriangular}, B::AbstractMatrix)
510520
end
511521
for i = 1:size(B,2)
512522
copy!(tmp, 1, B, (i - 1)*n + 1, n)
513-
A_ldiv_B!(A, tmp)
523+
ldiv!(A, tmp)
514524
copy!(B, (i - 1)*n + 1, tmp, 1, n) # Modify this when array view are implemented.
515525
end
516526
B
517527
end
518-
for func in (:Ac_ldiv_B!, :At_ldiv_B!)
519-
@eval function ($func)(A::Union{Bidiagonal,AbstractTriangular}, B::AbstractMatrix)
520-
nA,mA = size(A)
521-
tmp = similar(B,size(B,1))
522-
n = size(B, 1)
523-
if mA != n
524-
throw(DimensionMismatch("size of A' is ($mA,$nA), corresponding dimension of B is $n"))
525-
end
526-
for i = 1:size(B,2)
527-
copy!(tmp, 1, B, (i - 1)*n + 1, n)
528-
($func)(A, tmp)
529-
copy!(B, (i - 1)*n + 1, tmp, 1, n) # Modify this when array view are implemented.
530-
end
531-
B
528+
function ldiv!(adjA::Adjoint{<:Any,<:Union{Bidiagonal,AbstractTriangular}}, B::AbstractMatrix)
529+
A = adjA.parent
530+
nA,mA = size(A)
531+
tmp = similar(B,size(B,1))
532+
n = size(B, 1)
533+
if mA != n
534+
throw(DimensionMismatch("size of A' is ($mA,$nA), corresponding dimension of B is $n"))
532535
end
536+
for i = 1:size(B,2)
537+
copy!(tmp, 1, B, (i - 1)*n + 1, n)
538+
ldiv!(Adjoint(A), tmp)
539+
copy!(B, (i - 1)*n + 1, tmp, 1, n) # Modify this when array view are implemented.
540+
end
541+
B
542+
end
543+
function ldiv!(transA::Transpose{<:Any,<:Union{Bidiagonal,AbstractTriangular}}, B::AbstractMatrix)
544+
A = transA.parent
545+
nA,mA = size(A)
546+
tmp = similar(B,size(B,1))
547+
n = size(B, 1)
548+
if mA != n
549+
throw(DimensionMismatch("size of A' is ($mA,$nA), corresponding dimension of B is $n"))
550+
end
551+
for i = 1:size(B,2)
552+
copy!(tmp, 1, B, (i - 1)*n + 1, n)
553+
ldiv!(Transpose(A), tmp)
554+
copy!(B, (i - 1)*n + 1, tmp, 1, n) # Modify this when array view are implemented.
555+
end
556+
B
533557
end
534558
#Generic solver using naive substitution
535559
function naivesub!(A::Bidiagonal{T}, b::AbstractVector, x::AbstractVector = b) where T
@@ -554,15 +578,26 @@ function naivesub!(A::Bidiagonal{T}, b::AbstractVector, x::AbstractVector = b) w
554578
end
555579

556580
### Generic promotion methods and fallbacks
557-
for (f,g) in ((:\, :A_ldiv_B!), (:At_ldiv_B, :At_ldiv_B!), (:Ac_ldiv_B, :Ac_ldiv_B!))
558-
@eval begin
559-
function ($f)(A::Bidiagonal{TA}, B::AbstractVecOrMat{TB}) where {TA<:Number,TB<:Number}
560-
TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA))
561-
($g)(convert(AbstractArray{TAB}, A), copy_oftype(B, TAB))
562-
end
563-
($f)(A::Bidiagonal, B::AbstractVecOrMat) = ($g)(A, copy(B))
564-
end
581+
function \(A::Bidiagonal{<:Number}, B::AbstractVecOrMat{<:Number})
582+
TA, TB = eltype(A), eltype(B)
583+
TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA))
584+
ldiv!(convert(AbstractArray{TAB}, A), copy_oftype(B, TAB))
585+
end
586+
\(A::Bidiagonal, B::AbstractVecOrMat) = ldiv!(A, copy(B))
587+
function \(transA::Transpose{<:Number,<:Bidiagonal{<:Number}}, B::AbstractVecOrMat{<:Number})
588+
A = transA.parent
589+
TA, TB = eltype(A), eltype(B)
590+
TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA))
591+
ldiv!(Transpose(convert(AbstractArray{TAB}, A)), copy_oftype(B, TAB))
592+
end
593+
\(transA::Transpose{<:Any,<:Bidiagonal}, B::AbstractVecOrMat) = ldiv!(Transpose(transA.parent), copy(B))
594+
function \(adjA::Adjoint{<:Number,<:Bidiagonal{<:Number}}, B::AbstractVecOrMat{<:Number})
595+
A = adjA.parent
596+
TA, TB = eltype(A), eltype(B)
597+
TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA))
598+
ldiv!(Adjoint(convert(AbstractArray{TAB}, A)), copy_oftype(B, TAB))
565599
end
600+
\(adjA::Adjoint{<:Any,<:Bidiagonal}, B::AbstractVecOrMat) = ldiv!(Adjoint(adjA.parent), copy(B))
566601

567602
factorize(A::Bidiagonal) = A
568603

base/linalg/bunchkaufman.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ function inv(B::BunchKaufman{<:BlasComplex})
254254
end
255255
end
256256

257-
function A_ldiv_B!(B::BunchKaufman{T}, R::StridedVecOrMat{T}) where T<:BlasReal
257+
function ldiv!(B::BunchKaufman{T}, R::StridedVecOrMat{T}) where T<:BlasReal
258258
if !issuccess(B)
259259
throw(SingularException(B.info))
260260
end
@@ -265,7 +265,7 @@ function A_ldiv_B!(B::BunchKaufman{T}, R::StridedVecOrMat{T}) where T<:BlasReal
265265
LAPACK.sytrs!(B.uplo, B.LD, B.ipiv, R)
266266
end
267267
end
268-
function A_ldiv_B!(B::BunchKaufman{T}, R::StridedVecOrMat{T}) where T<:BlasComplex
268+
function ldiv!(B::BunchKaufman{T}, R::StridedVecOrMat{T}) where T<:BlasComplex
269269
if !issuccess(B)
270270
throw(SingularException(B.info))
271271
end
@@ -285,9 +285,9 @@ function A_ldiv_B!(B::BunchKaufman{T}, R::StridedVecOrMat{T}) where T<:BlasCompl
285285
end
286286
end
287287
# There is no fallback solver for Bunch-Kaufman so we'll have to promote to same element type
288-
function A_ldiv_B!(B::BunchKaufman{T}, R::StridedVecOrMat{S}) where {T,S}
288+
function ldiv!(B::BunchKaufman{T}, R::StridedVecOrMat{S}) where {T,S}
289289
TS = promote_type(T,S)
290-
return A_ldiv_B!(convert(BunchKaufman{TS}, B), convert(AbstractArray{TS}, R))
290+
return ldiv!(convert(BunchKaufman{TS}, B), convert(AbstractArray{TS}, R))
291291
end
292292

293293
function logabsdet(F::BunchKaufman)

0 commit comments

Comments
 (0)