Fri, 03 May 2024 13:06:24 -0500
merge
47
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
1 | ######################################################## |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
2 | # TV reconstruction via primal–dual proximal splitting |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
3 | ######################################################## |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
4 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
5 | __precompile__() |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
6 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
7 | module TVRecon |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
8 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
9 | using AlgTools.Util |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
10 | using AlgTools.LinOps |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
11 | import AlgTools.Iterate |
53
f8a3bc920f6a
Fix some `using` to be relative.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
12 | using ..Gradient |
47
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
13 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
14 | ############## |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
15 | # Our exports |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
16 | ############## |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
17 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
18 | export recon_pdps |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
19 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
20 | ############# |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
21 | # Data types |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
22 | ############# |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
23 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
24 | ImageSize = Tuple{Integer,Integer} |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
25 | Image = Array{Float64,2} |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
26 | Primal = Image |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
27 | Dual = Array{Float64,3} |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
28 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
29 | ######################### |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
30 | # Iterate initialisation |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
31 | ######################### |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
32 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
33 | function init_rest(x::Primal, b::Array{Float64, N}) where N |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
34 | imdim=size(x) |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
35 | datadim=size(b) |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
36 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
37 | y = zeros(2, imdim...) |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
38 | λ = zeros(datadim...) |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
39 | Δx₁ = copy(x) |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
40 | Δx₂ = copy(x) |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
41 | Δy = copy(y) |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
42 | Δλ = copy(λ) |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
43 | x̄ = copy(x) |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
44 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
45 | return x, y, λ, Δx₁, Δx₂, Δy, Δλ, x̄ |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
46 | end |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
47 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
48 | function init_primal(xinit::Image) |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
49 | return copy(xinit) |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
50 | end |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
51 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
52 | ############ |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
53 | # Algorithm |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
54 | ############ |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
55 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
56 | function recon_pdps(b :: Data, op :: LinOp{Image, Data}; |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
57 | xinit :: Union{Image, Nothing} = nothing, |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
58 | iterate = Iterate.simple_iterate, |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
59 | params::NamedTuple) where Data |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
60 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
61 | ################################ |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
62 | # Extract and set up parameters |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
63 | ################################ |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
64 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
65 | α, ρ = params.α, params.ρ |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
66 | τ₀, σ₀ = params.τ₀, params.σ₀ |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
67 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
68 | R_K = √(∇₂_norm₂₂_est^2+opnorm_estimate(op)^2) |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
69 | γ = 1 |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
70 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
71 | @assert(τ₀*σ₀ < 1) |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
72 | σ = σ₀/R_K |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
73 | τ = τ₀/R_K |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
74 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
75 | ###################### |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
76 | # Initialise iterates |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
77 | ###################### |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
78 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
79 | x, y, λ, Δx₁, Δx₂, Δy, Δλ, x̄ = init_rest(copy(xinit), b) |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
80 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
81 | #################### |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
82 | # Run the algorithm |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
83 | #################### |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
84 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
85 | v = iterate(params) do verbose :: Function |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
86 | ω = params.accel ? 1/√(1+2*γ*τ) : 1 |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
87 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
88 | ∇₂ᵀ!(Δx₁, y) # primal step: x |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
89 | inplace!(Δx₂, op', λ) # | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
90 | @. x̄ = x # | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
91 | @. x = x-τ*(Δx₁+Δx₂) # | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
92 | @. x̄ = (1+ω)*x - ω*x̄ # over-relax: x̄ = 2x-x_old |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
93 | ∇₂!(Δy, x̄) # dual step: y, λ |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
94 | inplace!(Δλ, op, x̄) # | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
95 | @. y = (y + σ*Δy)/(1 + σ*ρ/α) # | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
96 | proj_norm₂₁ball!(y, α) # | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
97 | @. λ = (λ + σ*(Δλ-b))/(1 + σ) # | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
98 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
99 | if params.accel |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
100 | τ, σ = τ*ω, σ/ω |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
101 | end |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
102 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
103 | ################################ |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
104 | # Give function value if needed |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
105 | ################################ |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
106 | v = verbose() do |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
107 | ∇₂!(Δy, x) |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
108 | inplace!(Δλ, op, x) |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
109 | value = norm₂²(Δλ-b)/2 + params.α*γnorm₂₁(Δy, params.ρ) |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
110 | value, x |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
111 | end |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
112 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
113 | v |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
114 | end |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
115 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
116 | return x, y, v |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
117 | end |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
118 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
119 | end # Module |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
120 | |
b32ced049cbd
Add TV reconstruction code for abstract linear operators
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
121 |