src/PET/AlgorithmZeroDual.jl

changeset 36
e4a8f662a1ac
parent 35
74b1a9f0c35e
child 37
bba159cf1636
equal deleted inserted replaced
35:74b1a9f0c35e 36:e4a8f662a1ac
1 ####################################################################
2 # Predictive online PDPS for optical flow with known velocity field
3 ####################################################################
4
5 __precompile__()
6
7 module AlgorithmZeroDual
8
9 identifier = "pdps_known_zerodual"
10
11 using Printf
12
13 using AlgTools.Util
14 import AlgTools.Iterate
15 using ImageTools.Gradient
16 using ImageTools.Translate
17
18 using ..Radon
19 using ImageTransformations
20 using Images, CoordinateTransformations, Rotations, OffsetArrays
21 using ImageCore, Interpolations
22
23 using ..OpticalFlow: ImageSize,
24 Image,
25 petpdflow!
26
27 #########################
28 # Iterate initialisation
29 #########################
30
31 function init_rest(x::Image)
32 imdim=size(x)
33 y = zeros(2, imdim...)
34 Δx = copy(x)
35 Δy = copy(y)
36 x̄ = copy(x)
37 radonx = copy(x)
38 return x, y, Δx, Δy, x̄, radonx
39 end
40
41 function init_iterates(xinit::Image)
42 return init_rest(copy(xinit))
43 end
44
45 function init_iterates(dim::ImageSize)
46 return init_rest(zeros(dim...))
47 end
48
49 #########################
50 # PETscan related
51 #########################
52 function petvalue(x, b, c)
53 tmp = similar(b)
54 radon!(tmp, x)
55 return sum(@. tmp - b*log(tmp+c))
56 end
57
58 function petgrad!(res, x, b, c, S)
59 tmp = similar(b)
60 radon!(tmp, x)
61 @. tmp = S .- b/(tmp+c)
62 backproject!(res, S.*tmp)
63 end
64
65 function proj_nonneg!(y)
66 @inbounds @simd for i=1:length(y)
67 if y[i] < 0
68 y[i] = 0
69 end
70 end
71 return y
72 end
73
74 ############
75 # Algorithm
76 ############
77
78 function solve( :: Type{DisplacementT};
79 dim :: ImageSize,
80 iterate = AlgTools.simple_iterate,
81 params::NamedTuple) where DisplacementT
82
83 ################################
84 # Extract and set up parameters
85 ################################
86 α, ρ = params.α, params.ρ
87 R_K² = ∇₂_norm₂₂_est²
88 γ = 1
89 L = params.L
90 τ₀, σ₀ = params.τ₀, params.σ₀
91 τ = τ₀/L
92 σ = σ₀*(1-τ₀)/(R_K²*τ)
93
94 println("Step length parameters: τ=$(τ), σ=$(σ)")
95
96 λ = params.λ
97 c = params.c*ones(params.radondims...)
98
99
100 ######################
101 # Initialise iterates
102 ######################
103
104 x, y, Δx, Δy, x̄, r∇ = init_iterates(dim)
105
106 if params.L_experiment
107 oldpetgradx = zeros(size(x)...)
108 petgradx = zeros(size(x))
109 oldx = ones(size(x))
110 end
111
112 ####################
113 # Run the algorithm
114 ####################
115
116 v = iterate(params) do verbose :: Function,
117 b :: Image, # noisy_sinogram
118 v_known :: DisplacementT,
119 theta_known :: DisplacementT,
120 b_true :: Image,
121 S :: Image
122
123 ###################
124 # Prediction steps
125 ###################
126
127 petpdflow!(x, Δx, y, Δy, v_known, theta_known, false)
128 y .= zeros(size(y)...)
129
130 if params.L_experiment
131 @. oldx = x
132 end
133
134 ############
135 # PDPS step
136 ############
137
138 ∇₂ᵀ!(Δx, y) # primal step:
139 @. x̄ = x # | save old x for over-relax
140 petgrad!(r∇, x, b, c, S) # | Calculate gradient of fidelity term
141
142 @. x = x-(τ*λ)*r∇-τ*Δx # |
143 proj_nonneg!(x) # | non-negativity constaint prox
144 @. x̄ = 2x - x̄ # over-relax: x̄ = 2x-x_old
145 ∇₂!(Δy, x̄) # dual step:
146 @. y = y + σ*Δy # |
147 proj_norm₂₁ball!(y, α) # | prox
148
149 #####################
150 # L update if needed
151 #####################
152 if params.L_experiment
153 petgrad!(petgradx, x, b, c, S)
154 petgrad!(oldpetgradx, oldx, b, c, S)
155 if norm₂(x-oldx)>1e-12
156 L = max(0.9*norm₂(petgradx - oldpetgradx)/norm₂(x-oldx),L)
157 println("Step length parameters: L=$(L)")
158 τ = τ₀/L
159 σ = σ₀*(1-τ₀)/(R_K²*τ)
160 end
161 end
162
163 ################################
164 # Give function value if needed
165 ################################
166
167 v = verbose() do
168 ∇₂!(Δy, x)
169 value = λ*petvalue(x, b, c) + params.α*norm₂₁(Δy)
170 value, x, [NaN, NaN], nothing, τ, σ
171 end
172
173 v
174 end
175
176 return x, y, v
177 end
178
179 end # Module
180
181

mercurial