src/LinOps.jl

Wed, 22 Dec 2021 11:14:38 +0200

author
Tuomo Valkonen <tuomov@iki.fi>
date
Wed, 22 Dec 2021 11:14:38 +0200
changeset 35
d881275c6564
parent 26
f075aca8485b
permissions
-rw-r--r--

Add metaprogramming tools and fast multidimensional loops.

20
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1 ########################################################
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
2 # Abstract Hilbert space linear operators. Does not set
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
3 # any limits on the input and output data types unlike
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
4 # the package LinearOperators.
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
5 ########################################################
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
6
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
7 __precompile__()
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
8
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
9 module LinOps
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
10
23
4399bf266660 Improve MatrixOp parametrisation
Tuomo Valkonen <tuomov@iki.fi>
parents: 20
diff changeset
11 export LinOp, IdOp, AdjointOp, AdjointableOp, MatrixOp,
20
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
12 calc_adjoint, calc_adjoint!, inplace!,
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
13 opnorm_estimate
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
14
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
15 # General type
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
16
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
17 abstract type LinOp{X, Y} end
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
18
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
19 function inplace!(y::Y, op::LinOp{X,Y}, x::X) where {X, Y}
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
20 y .= op(x)
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
21 end
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
22
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
23 # Adjoint operator for operators that define calc_adjoint and calc_adjoint!
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
24
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
25 abstract type AdjointableOp{X, Y} <: LinOp{X,Y} end
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
26
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
27 struct AdjointOp{X,Y,T<:AdjointableOp{X,Y}} <: LinOp{Y,X}
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
28 op :: T
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
29 end
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
30
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
31 function Base.adjoint(op::T) where {X, Y, T<:AdjointableOp{X,Y}}
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
32 return AdjointOp{X,Y,T}(op)
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
33 end
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
34
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
35 function Base.adjoint(adj::AdjointOp{X,Y,T}) where {X, Y, T<:AdjointableOp{X,Y}}
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
36 return adj.op
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
37 end
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
38
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
39 function (adj::AdjointOp{X,Y,T})(y::Y) where {X, Y, T<:AdjointableOp{X,Y}}
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
40 calc_adjoint(adj, y)
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
41 end
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
42
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
43 function inplace!(x::X, adj::AdjointOp{X,Y,T}, y::Y) where {X, Y, T<:AdjointableOp{X,Y}}
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
44 calc_adjoint!(x, adj.op, y)
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
45 end
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
46
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
47 function calc_adjoint(op::T, y::Y) where {X, Y, T<:AdjointableOp{X,Y}}
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
48 @error "unimplemented"
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
49 end
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
50
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
51 function calc_adjoint!(x::X, adj::T, y::Y) where {X, Y, T<:AdjointableOp{X,Y}}
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
52 x .= calc_adjoint(adj, y)
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
53 end
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
54
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
55 function opnorm_estimate(adj::AdjointOp{X,Y,T}) where {X, Y, T<:AdjointableOp{X,Y}}
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
56 return opnorm_estimate(adj.op)
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
57 end
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
58
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
59 # Identity operator
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
60
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
61 struct IdOp{X} <: LinOp{X,X}
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
62 end
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
63
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
64 function (op::IdOp{X})(x::X) where X
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
65 return x
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
66 end
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
67
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
68 function Base.adjoint(op::IdOp{X}) where X
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
69 return op
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
70 end
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
71
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
72 function opnorm_estimate(op::IdOp{X}) where X
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
73 return 1
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
74 end
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
75
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
76 # Matrix operator
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
77
23
4399bf266660 Improve MatrixOp parametrisation
Tuomo Valkonen <tuomov@iki.fi>
parents: 20
diff changeset
78 struct MatrixOp{T<:Real} <: LinOp{Vector{T}, Vector{T}}
26
f075aca8485b Fix Linops to use AbstractMatrix instead of Matrix
Tuomo Valkonen <tuomov@iki.fi>
parents: 24
diff changeset
79 m :: AbstractMatrix{T}
20
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
80 end
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
81
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
82 function (op::MatrixOp{T})(v::Vector{T}) where T
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
83 return op.m*v
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
84 end
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
85
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
86 function Base.adjoint(op::MatrixOp{T}) where T
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
87 return MatrixOp(op.m')
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
88 end
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
89
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
90 function opnorm_estimate(op::MatrixOp{T}) where T
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
91 return opnorm(op.m, 2)
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
92 end
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
93
24
da6c7475dd0e Define some basic operations for MatrixOps
Tuomo Valkonen <tuomov@iki.fi>
parents: 23
diff changeset
94 function Base.:+(a::MatrixOp{T}, b::MatrixOp{T}) where T
da6c7475dd0e Define some basic operations for MatrixOps
Tuomo Valkonen <tuomov@iki.fi>
parents: 23
diff changeset
95 return MatrixOp(a.m+b.m)
20
8b80aa64adec Add abstract LinOps
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
96 end
24
da6c7475dd0e Define some basic operations for MatrixOps
Tuomo Valkonen <tuomov@iki.fi>
parents: 23
diff changeset
97
da6c7475dd0e Define some basic operations for MatrixOps
Tuomo Valkonen <tuomov@iki.fi>
parents: 23
diff changeset
98 function Base.:-(a::MatrixOp{T}, b::MatrixOp{T}) where T
da6c7475dd0e Define some basic operations for MatrixOps
Tuomo Valkonen <tuomov@iki.fi>
parents: 23
diff changeset
99 return MatrixOp(a.m-b.m)
da6c7475dd0e Define some basic operations for MatrixOps
Tuomo Valkonen <tuomov@iki.fi>
parents: 23
diff changeset
100 end
da6c7475dd0e Define some basic operations for MatrixOps
Tuomo Valkonen <tuomov@iki.fi>
parents: 23
diff changeset
101
da6c7475dd0e Define some basic operations for MatrixOps
Tuomo Valkonen <tuomov@iki.fi>
parents: 23
diff changeset
102 function Base.:*(a::MatrixOp{T}, b::MatrixOp{T}) where T
da6c7475dd0e Define some basic operations for MatrixOps
Tuomo Valkonen <tuomov@iki.fi>
parents: 23
diff changeset
103 return MatrixOp(a.m*b.m)
da6c7475dd0e Define some basic operations for MatrixOps
Tuomo Valkonen <tuomov@iki.fi>
parents: 23
diff changeset
104 end
da6c7475dd0e Define some basic operations for MatrixOps
Tuomo Valkonen <tuomov@iki.fi>
parents: 23
diff changeset
105
da6c7475dd0e Define some basic operations for MatrixOps
Tuomo Valkonen <tuomov@iki.fi>
parents: 23
diff changeset
106 end

mercurial