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