-
Notifications
You must be signed in to change notification settings - Fork 41
/
Copy pathChambollePock.md
115 lines (90 loc) · 3.2 KB
/
ChambollePock.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# [The Riemannian Chambolle-Pock Algorithm](@id ChambollePockSolver)
The Riemannian Chambolle–Pock is a generalization of the Chambolle–Pock algorithm [ChambollePock:2011](@citet*)
It is also known as primal-dual hybrid gradient (PDHG) or primal-dual proximal splitting (PDPS) algorithm.
In order to minimize over $p∈\mathcal M§ the cost function consisting of
```math
F(p) + G(Λ(p)),
```
where $F:\mathcal M → \overline{ℝ}$, $G:\mathcal N → \overline{ℝ}$, and
$Λ:\mathcal M →\mathcal N$.
If the manifolds $\mathcal M$ or $\mathcal N$ are not Hadamard, it has to be considered locally,
i.e. on geodesically convex sets $\mathcal C \subset \mathcal M$ and $\mathcal D \subset\mathcal N$
such that $Λ(\mathcal C) \subset \mathcal D$.
The algorithm is available in four variants: exact versus linearized (see `variant`)
as well as with primal versus dual relaxation (see `relax`). For more details, see
[BergmannHerzogSilvaLouzeiroTenbrinckVidalNunez:2021](@citet*).
In the following we note the case of the exact, primal relaxed Riemannian Chambolle–Pock algorithm.
Given base points $m∈\mathcal C$, $n=Λ(m)∈\mathcal D$,
initial primal and dual values $p^{(0)} ∈\mathcal C$, $ξ_n^{(0)} ∈T_n^*\mathcal N$,
and primal and dual step sizes $\sigma_0$, $\tau_0$, relaxation $\theta_0$,
as well as acceleration $\gamma$.
As an initialization, perform $\bar p^{(0)} \gets p^{(0)}$.
The algorithms performs the steps $k=1,…,$ (until a [`StoppingCriterion`](@ref) is fulfilled with)
1. ```math
ξ^{(k+1)}_n = \operatorname{prox}_{\tau_k G_n^*}\Bigl(ξ_n^{(k)} + \tau_k \bigl(\log_n Λ (\bar p^{(k)})\bigr)^\flat\Bigr)
```
2. ```math
p^{(k+1)} = \operatorname{prox}_{\sigma_k F}\biggl(\exp_{p^{(k)}}\Bigl( \operatorname{PT}_{p^{(k)}\gets m}\bigl(-\sigma_k DΛ(m)^*[ξ_n^{(k+1)}]\bigr)^\sharp\Bigr)\biggr)
```
3. Update
* ``\theta_k = (1+2\gamma\sigma_k)^{-\frac{1}{2}}``
* ``\sigma_{k+1} = \sigma_k\theta_k``
* ``\tau_{k+1} = \frac{\tau_k}{\theta_k}``
4. ```math
\bar p^{(k+1)} = \exp_{p^{(k+1)}}\bigl(-\theta_k \log_{p^{(k+1)}} p^{(k)}\bigr)
```
Furthermore you can exchange the exponential map, the logarithmic map, and the parallel transport
by a retraction, an inverse retraction, and a vector transport.
Finally you can also update the base points $m$ and $n$ during the iterations.
This introduces a few additional vector transports. The same holds for the case
$Λ(m^{(k)})\neq n^{(k)}$ at some point. All these cases are covered in the algorithm.
```@meta
CurrentModule = Manopt
```
```@docs
ChambollePock
ChambollePock!
```
## State
```@docs
ChambollePockState
```
## Useful Terms
```@docs
primal_residual
dual_residual
```
## Debug
```@docs
DebugDualBaseIterate
DebugDualBaseChange
DebugPrimalBaseIterate
DebugPrimalBaseChange
DebugDualChange
DebugDualIterate
DebugDualResidual
DebugPrimalChange
DebugPrimalIterate
DebugPrimalResidual
DebugPrimalDualResidual
```
## Record
```@docs
RecordDualBaseIterate
RecordDualBaseChange
RecordDualChange
RecordDualIterate
RecordPrimalBaseIterate
RecordPrimalBaseChange
RecordPrimalChange
RecordPrimalIterate
```
## Internals
```@docs
Manopt.update_prox_parameters!
```
## Literature
```@bibliography
Pages = ["solvers/ChambollePock.md"]
Canonical=false
```