1+ export ProdOp
2+ """
3+ `mutable struct ProdOp{T}`
4+
5+ struct describing the result of a composition/product of operators.
6+ Describing the composition using a dedicated type has the advantage
7+ that the latter can be made copyable. This is particularly relevant for
8+ multi-threaded code
9+ """
10+ mutable struct ProdOp{T,U,V} <: AbstractLinearOperatorFromCollection{T}
11+ nrow :: Int
12+ ncol :: Int
13+ symmetric :: Bool
14+ hermitian :: Bool
15+ prod! :: Function
16+ tprod! :: Function
17+ ctprod! :: Function
18+ nprod :: Int
19+ ntprod :: Int
20+ nctprod :: Int
21+ args5 :: Bool
22+ use_prod5! :: Bool
23+ allocated5 :: Bool
24+ Mv5 :: Vector{T}
25+ Mtu5 :: Vector{T}
26+ A:: U
27+ B:: V
28+ tmp:: Vector{T}
29+ end
30+
31+ """
32+ ProdOp(A,B)
33+
34+ composition/product of two Operators. Differs with * since it can handle normal operator
35+ """
36+ function ProdOp (A,B)
37+ nrow = size (A, 1 )
38+ ncol = size (B, 2 )
39+ S = promote_type (eltype (A), eltype (B))
40+ tmp_ = Vector {S} (undef, size (B, 1 ))
41+
42+ function produ! (res, x:: AbstractVector{T} , tmp) where T<: Union{Real,Complex}
43+ mul! (tmp, B, x)
44+ return mul! (res, A, tmp)
45+ end
46+
47+ function tprodu! (res, y:: AbstractVector{T} , tmp) where T<: Union{Real,Complex}
48+ mul! (tmp, transpose (A), y)
49+ return mul! (res, transpose (B), tmp)
50+ end
51+
52+ function ctprodu! (res, y:: AbstractVector{T} , tmp) where T<: Union{Real,Complex}
53+ mul! (tmp, adjoint (A), y)
54+ return mul! (res, adjoint (B), tmp)
55+ end
56+
57+ Op = ProdOp ( nrow, ncol, false , false ,
58+ (res,x) -> produ! (res,x,tmp_),
59+ (res,y) -> tprodu! (res,y,tmp_),
60+ (res,y) -> ctprodu! (res,y,tmp_),
61+ 0 , 0 , 0 , false , false , false , S[], S[],
62+ A, B, tmp_)
63+
64+ return Op
65+ end
66+
67+ function Base. copy (S:: ProdOp{T} ) where T
68+ A = copy (S. A)
69+ B = copy (S. B)
70+ return ProdOp (A,B)
71+ end
72+
73+ Base.:* (:: Type{<:ProdOp} , A, B) = ProdOp (A, B)
74+ Base.:* (:: Type{<:ProdOp} , A, args... ) = ProdOp (A, * (ProdOp, args... ))
75+
76+ storage_type (op:: ProdOp ) = typeof (op. Mv5)
0 commit comments