|
3 | 3 | # givensAlgorithm functions are derived from LAPACK, see below
|
4 | 4 |
|
5 | 5 | abstract type AbstractRotation{T} end
|
| 6 | +struct AdjointRotation{T,S<:AbstractRotation{T}} <: AbstractRotation{T} |
| 7 | + R::S |
| 8 | +end |
6 | 9 |
|
7 | 10 | transpose(R::AbstractRotation) = error("transpose not implemented for $(typeof(R)). Consider using adjoint instead of transpose.")
|
8 | 11 |
|
9 | 12 | function (*)(R::AbstractRotation{T}, A::AbstractVecOrMat{S}) where {T,S}
|
10 | 13 | TS = typeof(zero(T)*zero(S) + zero(T)*zero(S))
|
11 | 14 | lmul!(convert(AbstractRotation{TS}, R), copy_similar(A, TS))
|
12 | 15 | end
|
13 |
| -(*)(A::AbstractVector, adjR::Adjoint{<:Any,<:AbstractRotation}) = _absvecormat_mul_adjrot(A, adjR) |
14 |
| -(*)(A::AbstractMatrix, adjR::Adjoint{<:Any,<:AbstractRotation}) = _absvecormat_mul_adjrot(A, adjR) |
15 |
| -function _absvecormat_mul_adjrot(A::AbstractVecOrMat{T}, adjR::Adjoint{<:Any,<:AbstractRotation{S}}) where {T,S} |
16 |
| - R = adjR.parent |
| 16 | +function (*)(adjR::AdjointRotation{T}, A::AbstractVecOrMat{S}) where {T,S} |
| 17 | + TS = typeof(zero(T)*zero(S) + zero(T)*zero(S)) |
| 18 | + lmul!(convert(AbstractRotation{TS}, adjR.R)', copy_similar(A, TS)) |
| 19 | +end |
| 20 | +(*)(A::AbstractVector, adjR::AdjointRotation) = _absvecormat_mul_adjrot(A, adjR) |
| 21 | +(*)(A::AbstractMatrix, adjR::AdjointRotation) = _absvecormat_mul_adjrot(A, adjR) |
| 22 | +function _absvecormat_mul_adjrot(A::AbstractVecOrMat{T}, adjR::AdjointRotation{S}) where {T,S} |
17 | 23 | TS = typeof(zero(T)*zero(S) + zero(T)*zero(S))
|
18 |
| - rmul!(TS.(A), convert(AbstractRotation{TS}, R)') |
| 24 | + rmul!(copy_similar(A, TS), convert(AbstractRotation{TS}, adjR.R)') |
19 | 25 | end
|
20 | 26 | function(*)(A::AbstractMatrix{T}, R::AbstractRotation{S}) where {T,S}
|
21 | 27 | TS = typeof(zero(T)*zero(S) + zero(T)*zero(S))
|
22 |
| - rmul!(TS.(A), convert(AbstractRotation{TS}, R)) |
| 28 | + rmul!(copy_similar(A, TS), convert(AbstractRotation{TS}, R)) |
23 | 29 | end
|
24 | 30 |
|
25 | 31 | """
|
@@ -55,12 +61,11 @@ AbstractRotation{T}(G::Givens) where {T} = Givens{T}(G)
|
55 | 61 | AbstractRotation{T}(R::Rotation) where {T} = Rotation{T}(R)
|
56 | 62 |
|
57 | 63 | adjoint(G::Givens) = Givens(G.i1, G.i2, G.c', -G.s)
|
58 |
| -adjoint(R::Rotation) = Adjoint(R) |
59 |
| -function Base.copy(aG::Adjoint{<:Any,<:Givens}) |
60 |
| - G = aG.parent |
61 |
| - return Givens(G.i1, G.i2, conj(G.c), -G.s) |
62 |
| -end |
63 |
| -Base.copy(aR::Adjoint{<:Any,Rotation{T}}) where {T} = Rotation{T}(reverse!([r' for r in aR.parent.rotations])) |
| 64 | +adjoint(R::AbstractRotation) = AdjointRotation(R) |
| 65 | +adjoint(adjR::AdjointRotation) = adjR.R |
| 66 | + |
| 67 | +Base.copy(aR::AdjointRotation{T,Rotation{T}}) where {T} = |
| 68 | + Rotation{T}([r' for r in Iterators.reverse(aR.R.rotations)]) |
64 | 69 |
|
65 | 70 | floatmin2(::Type{Float32}) = reinterpret(Float32, 0x26000000)
|
66 | 71 | floatmin2(::Type{Float64}) = reinterpret(Float64, 0x21a0000000000000)
|
@@ -291,7 +296,7 @@ function givens(f::T, g::T, i1::Integer, i2::Integer) where T
|
291 | 296 | c, s, r = givensAlgorithm(f, g)
|
292 | 297 | if i1 > i2
|
293 | 298 | s = -conj(s)
|
294 |
| - i1,i2 = i2,i1 |
| 299 | + i1, i2 = i2, i1 |
295 | 300 | end
|
296 | 301 | Givens(i1, i2, c, s), r
|
297 | 302 | end
|
@@ -329,9 +334,7 @@ B[i2] = 0
|
329 | 334 |
|
330 | 335 | See also [`LinearAlgebra.Givens`](@ref).
|
331 | 336 | """
|
332 |
| -givens(x::AbstractVector, i1::Integer, i2::Integer) = |
333 |
| - givens(x[i1], x[i2], i1, i2) |
334 |
| - |
| 337 | +givens(x::AbstractVector, i1::Integer, i2::Integer) = givens(x[i1], x[i2], i1, i2) |
335 | 338 |
|
336 | 339 | function getindex(G::Givens, i::Integer, j::Integer)
|
337 | 340 | if i == j
|
@@ -386,23 +389,24 @@ function lmul!(R::Rotation, A::AbstractMatrix)
|
386 | 389 | end
|
387 | 390 | return A
|
388 | 391 | end
|
389 |
| -function rmul!(A::AbstractMatrix, adjR::Adjoint{<:Any,<:Rotation}) |
390 |
| - R = adjR.parent |
| 392 | +function rmul!(A::AbstractMatrix, R::Rotation) |
| 393 | + @inbounds for i = 1:length(R.rotations) |
| 394 | + rmul!(A, R.rotations[i]) |
| 395 | + end |
| 396 | + return A |
| 397 | +end |
| 398 | +function lmul!(adjR::AdjointRotation{<:Any,<:Rotation}, A::AbstractMatrix) |
| 399 | + R = adjR.R |
| 400 | + @inbounds for i = 1:length(R.rotations) |
| 401 | + lmul!(adjoint(R.rotations[i]), A) |
| 402 | + end |
| 403 | + return A |
| 404 | +end |
| 405 | +function rmul!(A::AbstractMatrix, adjR::AdjointRotation{<:Any,<:Rotation}) |
| 406 | + R = adjR.R |
391 | 407 | @inbounds for i = 1:length(R.rotations)
|
392 | 408 | rmul!(A, adjoint(R.rotations[i]))
|
393 | 409 | end
|
394 | 410 | return A
|
395 | 411 | end
|
396 |
| -*(G1::Givens{T}, G2::Givens{T}) where {T} = Rotation(push!(push!(Givens{T}[], G2), G1)) |
397 |
| - |
398 |
| -# TODO: None of the following disambiguation methods are great. They should perhaps |
399 |
| -# instead be MethodErrors, or revised. |
400 |
| -# |
401 |
| -# disambiguation methods: *(Adj/Trans of AbsVec or AbsMat, Adj of AbstractRotation) |
402 |
| -*(A::Adjoint{<:Any,<:AbstractVector}, B::Adjoint{<:Any,<:AbstractRotation}) = copy(A) * B |
403 |
| -*(A::Adjoint{<:Any,<:AbstractMatrix}, B::Adjoint{<:Any,<:AbstractRotation}) = copy(A) * B |
404 |
| -*(A::Transpose{<:Any,<:AbstractVector}, B::Adjoint{<:Any,<:AbstractRotation}) = copy(A) * B |
405 |
| -*(A::Transpose{<:Any,<:AbstractMatrix}, B::Adjoint{<:Any,<:AbstractRotation}) = copy(A) * B |
406 |
| -# disambiguation methods: *(Diag/AbsTri, Adj of AbstractRotation) |
407 |
| -*(A::Diagonal, B::Adjoint{<:Any,<:AbstractRotation}) = A * copy(B) |
408 |
| -*(A::AbstractTriangular, B::Adjoint{<:Any,<:AbstractRotation}) = A * copy(B) |
| 412 | +*(G1::Givens{T}, G2::Givens{T}) where {T} = Rotation([G2, G1]) |
0 commit comments