src/AlgorithmProximal.jl

changeset 5
843e7611b068
equal deleted inserted replaced
4:a64766c44642 5:843e7611b068
1 ####################################################################
2 # Predictive online PDPS for optical flow with known velocity field
3 ####################################################################
4
5 __precompile__()
6
7 module AlgorithmProximal
8
9 identifier = "pdps_known_proximal"
10
11 using Printf
12
13 using AlgTools.Util
14 import AlgTools.Iterate
15 using ImageTools.Gradient
16
17 using ..OpticalFlow: ImageSize,
18 Image,
19 pdflow!
20
21 #########################
22 # Iterate initialisation
23 #########################
24
25 function init_rest(x::Image)
26 imdim=size(x)
27
28 y = zeros(2, imdim...)
29 Δx = copy(x)
30 Δy = copy(y)
31 x̄ = copy(x)
32
33 return x, y, Δx, Δy, x̄
34 end
35
36 function init_iterates(xinit::Image)
37 return init_rest(copy(xinit))
38 end
39
40 function init_iterates(dim::ImageSize)
41 return init_rest(zeros(dim...))
42 end
43
44 ############
45 # Algorithm
46 ############
47
48 function step_lengths(params, γ, R_K²)
49 ρ̃₀, τ₀, σ₀, σ̃₀ = params.ρ̃₀, params.τ₀, params.σ₀, params.σ̃₀
50 δ = params.δ
51 ρ = isdefined(params, :phantom_ρ) ? params.phantom_ρ : params.ρ
52 Λ = params.Λ
53 Θ = params.dual_flow ? Λ : 1
54
55 τ = τ₀/γ
56 @assert(1+γ*τ ≥ Λ)
57 σ = σ₀*min(1/(τ*R_K²), 1/max(0, τ*R_K²/((1+γ*τ-Λ)*(1-δ))-ρ))
58 q = δ*(1+σ*ρ)/Θ
59 if 1 ≥ q
60 σ̃ = σ̃₀*σ/q
61 #ρ̃ = ρ̃₀*max(0, ((Θ*σ)/(2*δ*σ̃^2*(1+σ*ρ))+1/(2σ)-1/σ̃))
62 ρ̃ = max(0, (1-q)/(2*σ))
63 else
64 σ̃ = σ̃₀*σ/(q*(1-√(1-1/q)))
65 ρ̃ = 0
66 end
67
68 println("Step length parameters: τ=$(τ), σ=$(σ), σ̃=$(σ̃), ρ̃=$(ρ̃)")
69
70 return τ, σ, σ̃, ρ̃
71 end
72
73 function solve( :: Type{DisplacementT};
74 dim :: ImageSize,
75 iterate = AlgTools.simple_iterate,
76 params::NamedTuple) where DisplacementT
77
78 ################################
79 # Extract and set up parameters
80 ################################
81
82 α, ρ = params.α, params.ρ
83 R_K² = ∇₂_norm₂₂_est²
84 γ = 1
85 τ, σ, σ̃, ρ̃ = step_lengths(params, γ, R_K²)
86
87 ######################
88 # Initialise iterates
89 ######################
90
91 x, y, Δx, Δy, x̄ = init_iterates(dim)
92 init_data = (params.init == :data)
93
94 ####################
95 # Run the algorithm
96 ####################
97
98 v = iterate(params) do verbose :: Function,
99 b :: Image,
100 v_known :: DisplacementT,
101 🚫unused_b_next :: Image
102
103 ##################
104 # Prediction step
105 ##################
106 if init_data
107 x .= b
108 init_data = false
109 end
110
111 pdflow!(x, Δx, y, Δy, v_known, params.dual_flow)
112
113 # Proximal step
114 ∇₂!(Δy, x)
115 @. y = (y + σ̃*Δy)/(1 + σ̃*(ρ̃+ρ/α))
116 proj_norm₂₁ball!(y, α)
117
118
119 ############
120 # PDPS step
121 ############
122
123 ∇₂ᵀ!(Δx, y) # primal step:
124 @. x̄ = x # | save old x for over-relax
125 @. x = (x-τ*(Δx-b))/(1+τ) # | prox
126 @. x̄ = 2x - x̄ # over-relax
127 ∇₂!(Δy, x̄) # dual step: y
128 @. y = (y + σ*Δy)/(1 + σ*ρ/α) # |
129 proj_norm₂₁ball!(y, α) # | prox
130
131 ################################
132 # Give function value if needed
133 ################################
134 v = verbose() do
135 ∇₂!(Δy, x)
136 value = norm₂²(b-x)/2 + params.α*γnorm₂₁(Δy, params.ρ)
137 value, x, [NaN, NaN], nothing
138 end
139
140 v
141 end
142
143 return x, y, v
144 end
145
146 end # Module
147
148

mercurial