Skip to content

Commit 5c5fe34

Browse files
authored
Add options and plan to Afft and Asense (#124)
* Add return x,y * for in * Use plan in Afft * Test new Afft * Add fft_forward option * Use plan * Test plan * Plain Afft * Refine Afft * Test Afft * Add unitary option * Test unitary Asense * v0.17 * Test fft_forward * Check 1-based
1 parent f13a591 commit 5c5fe34

File tree

9 files changed

+398
-88
lines changed

9 files changed

+398
-88
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "MIRT"
22
uuid = "7035ae7a-3787-11e9-139a-5545ed3dc201"
33
authors = ["fessler <[email protected]>"]
4-
version = "0.16.0"
4+
version = "0.17.0"
55

66
[deps]
77
AVSfldIO = "b6189060-daf9-4c28-845a-cc0984b81781"

src/algorithm/general/ncg.jl

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ where ``C_j(u)`` is diagonal matrix of curvatures.
2727
This CG method uses a majorize-minimize (MM) line search.
2828
2929
in
30-
- `B` array of ``J`` blocks ``B_1,...,B_J``
31-
- `gradf` array of ``J`` functions return gradients of ``f_1,...,f_J``
32-
- `curvf` array of ``J`` functions `z -> curv(z)` that return a scalar
30+
- `B` vector of ``J`` blocks ``B_1,...,B_J``
31+
- `gradf` vector of ``J`` functions return gradients of ``f_1,...,f_J``
32+
- `curvf` vector of ``J`` functions `z -> curv(z)` that return a scalar
3333
or a vector of curvature values for each element of ``z``
3434
- `x0` initial guess; need `length(x) == size(B[j],2)` for ``j=1...J``
3535
@@ -58,10 +58,12 @@ function ncg(
5858
niter::Int = 50,
5959
ninner::Int = 5,
6060
P = I, # trick: this is an overloaded I (by LinearMapsAA)
61-
betahow::Symbol=:dai_yuan,
61+
betahow::Symbol = :dai_yuan,
6262
fun::Function = (x,iter) -> 0,
6363
)
6464

65+
Base.require_one_based_indexing(B, gradf, curvf)
66+
6567
out = Array{Any}(undef, niter+1)
6668
out[1] = fun(x0, 0)
6769

@@ -72,10 +74,10 @@ function ncg(
7274
grad_old = []
7375
grad_new = []
7476

75-
Bx = [B[j] * x for j=1:J] # u_j in course notes
76-
grad = (Bx) -> sum([B[j]' * gradf[j](Bx[j]) for j=1:J])
77+
Bx = [B[j] * x for j in 1:J] # u_j in course notes
78+
grad = (Bx) -> sum([B[j]' * gradf[j](Bx[j]) for j in 1:J])
7779

78-
for iter = 1:niter
80+
for iter in 1:niter
7981
grad_new = grad(Bx) # gradient
8082
npgrad = -(P * grad_new)
8183
if iter == 1
@@ -97,14 +99,14 @@ for iter = 1:niter
9799

98100
# MM-based line search for step size alpha
99101
# using h(a) = sum_j f_j(uj + a vj)
100-
Bd = [B[j] * dir for j=1:J] # v_j in course notes
102+
Bd = [B[j] * dir for j in 1:J] # v_j in course notes
101103

102104
alf = 0
103-
for ii=1:ninner
104-
# derh = alf -> sum([Bd[j]' * gradf[j](Bx[j] + alf * Bd[j]) for j=1:J])
105+
for ii in 1:ninner
106+
# derh = alf -> sum([Bd[j]' * gradf[j](Bx[j] + alf * Bd[j]) for j in 1:J])
105107
derh = 0 # derivative of h(a)
106108
curv = 0
107-
for j=1:J
109+
for j in 1:J
108110
tmp = Bx[j] + alf * Bd[j]
109111
derh += real(dot(Bd[j], gradf[j](tmp)))
110112
curv += sum(curvf[j](tmp) .* abs2.(Bd[j]))
@@ -119,7 +121,7 @@ for iter = 1:niter
119121
end
120122

121123
x += alf * dir
122-
for j=1:J # update Bj * x
124+
for j in 1:J # update Bj * x
123125
Bx[j] += alf * Bd[j]
124126
end
125127
out[iter+1] = fun(x, iter)

src/algorithm/general/ogm_ls.jl

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,23 @@ where ``C_j(u)`` is diagonal matrix of curvatures.
2424
2525
This OGM method uses a majorize-minimize (MM) line search.
2626
27-
in
28-
- `B` array of ``J`` blocks ``B_1,...,B_J``
29-
- `gradf` array of ``J`` functions return gradients of ``f_1,...,f_J``
30-
- `curvf` array of ``J`` functions `z -> curv(z)` that return a scalar
31-
or a vector of curvature values for each element of ``z``
32-
- `x0` initial guess; need `length(x) == size(B[j],2)` for ``j=1...J``
33-
34-
option
35-
- `niter` # number of outer iterations; default 50
36-
- `ninner` # number of inner iterations of MM line search; default 5
37-
- `fun` User-defined function to be evaluated with two arguments (x,iter).
27+
# in
28+
- `B` vector of ``J`` blocks ``B_1,...,B_J``
29+
- `gradf` vector of ``J`` functions return gradients of ``f_1,...,f_J``
30+
- `curvf` vector of ``J`` functions `z -> curv(z)` that return a scalar
31+
or a vector of curvature values for each element of ``z``
32+
- `x0` initial guess; need `length(x) == size(B[j],2)` for ``j=1...J``
33+
34+
# option
35+
- `niter` # number of outer iterations; default 50
36+
- `ninner` # number of inner iterations of MM line search; default 5
37+
- `fun` User-defined function to be evaluated with two arguments (x,iter).
3838
* It is evaluated at (x0,0) and then after each iteration.
3939
40-
output
41-
- `x` final iterate
42-
- `out` `[niter+1] (fun(x0,0), fun(x1,1), ..., fun(x_niter,niter))`
43-
* (all 0 by default). This is an array of length `niter+1`
40+
# output
41+
- `x` final iterate
42+
- `out (niter+1) (fun(x0,0), fun(x1,1), ..., fun(x_niter,niter))`
43+
* (all 0 by default). This is a vector of length `niter+1`.
4444
"""
4545
function ogm_ls(
4646
B::AbstractVector{<:Any},
@@ -52,6 +52,8 @@ function ogm_ls(
5252
fun::Function = (x,iter) -> 0,
5353
)
5454

55+
Base.require_one_based_indexing(B, gradf, curvf)
56+
5557
out = Array{Any}(undef, niter+1)
5658
out[1] = fun(x0, 0)
5759

@@ -65,12 +67,12 @@ grad_sum = zeros(size(x0))
6567
ti = 1
6668
thetai = 1
6769

68-
B0 = [B[j] * x for j=1:J]
70+
B0 = [B[j] * x for j in 1:J]
6971
Bx = copy(B0)
7072
By = copy(B0)
71-
grad = (Bx) -> sum([B[j]' * gradf[j](Bx[j]) for j=1:J])
73+
grad = (Bx) -> sum([B[j]' * gradf[j](Bx[j]) for j in 1:J])
7274

73-
for iter = 1:niter
75+
for iter in 1:niter
7476
grad_new = grad(Bx) # gradient of x_{iter-1}
7577
grad_sum += ti * grad_new # sum_{j=0}^{iter-1} t_j * gradient_j
7678

@@ -80,21 +82,21 @@ for iter = 1:niter
8082
tt = (iter < niter) ? ti : thetai # use theta_i factor for last iteration
8183
yi = (1 - 1/tt) * x + (1/tt) * x0
8284

83-
for j=1:J # update Bj * yi
85+
for j in 1:J # update Bj * yi
8486
By[j] = (1 - 1/tt) * Bx[j] + (1/tt) * B0[j]
8587
end
8688

8789
dir = -(1 - 1/tt) * grad_new - (2/tt) * grad_sum # -d_i
8890

8991
# MM-based line search for step size alpha
9092
# using h(a) = sum_j f_j(By_j + a * Bd_j)
91-
Bd = [B[j] * dir for j=1:J]
93+
Bd = [B[j] * dir for j in 1:J]
9294

9395
alf = 0
94-
for ii=1:ninner
96+
for ii in 1:ninner
9597
derh = 0 # derivative of h(a)
9698
curv = 0
97-
for j=1:J
99+
for j in 1:J
98100
tmp = By[j] + alf * Bd[j]
99101
derh += real(dot(Bd[j], gradf[j](tmp)))
100102
curv += sum(curvf[j](tmp) .* abs2.(Bd[j]))
@@ -109,20 +111,20 @@ for iter = 1:niter
109111
end
110112

111113
# # derivative of h(a) = cost(x + a * dir) where \alpha is real
112-
# dh = alf -> real(sum([Bd[j]' * gradf[j](By[j] + alf * Bd[j]) for j=1:J]))
113-
# Ldh = sum([Lgf[j] * norm(Bd[j])^2 for j=1:J]) # Lipschitz constant for dh
114+
# dh = alf -> real(sum([Bd[j]' * gradf[j](By[j] + alf * Bd[j]) for j in 1:J]))
115+
# Ldh = sum([Lgf[j] * norm(Bd[j])^2 for j in 1:J]) # Lipschitz constant for dh
114116
# (alf, ) = gd(dh, Ldh, 0, niter=ninner) # GD-based line search
115117
# todo
116118

117119
x = yi + alf * dir
118120

119121
if iter < niter
120-
for j=1:J # update Bj * x
122+
for j in 1:J # update Bj * x
121123
Bx[j] = By[j] + alf * Bd[j]
122124
end
123125
end
124126

125-
# for j=1:J # recursive update Bj * yi ???
127+
# for j in 1:J # recursive update Bj * yi ???
126128
# By[j] = (1 - 1/ti) * (By[j] + alf * Bd[j]) + (1/ti) * B0[j]
127129
# end
128130

@@ -136,10 +138,11 @@ end
136138
"""
137139
(x,out) = ogm_ls(grad, curv, x0, ...)
138140
139-
special case of `ogm_ls` (OGM with line search) for minimizing a cost function
141+
Special case of `ogm_ls` (OGM with line search)
142+
for minimizing a cost function
140143
whose gradient is `grad(x)`
141144
and that has a quadratic majorizer with diagonal Hessian given by `curv(x)`.
142-
Typically `curv = (x) -> L` where `L` is the Lipschitz constant of `grad`
145+
Typically `curv = (x) -> L` where `L` is the Lipschitz constant of `grad`.
143146
"""
144147
function ogm_ls(
145148
grad::Function,

src/algorithm/general/pogm_restart.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ function pogm_restart(
148148
ynew = []
149149

150150
# iterations
151-
for iter=1:niter
151+
for iter in 1:niter
152152

153153
# proximal gradient (PGM) update
154154
if mom === :pgm && mu != 0

src/algorithm/general/poweriter.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ function poweriter(
3838

3939
x = copy(x0)
4040
ratio_old = Inf
41-
for iter=1:niter
41+
for iter in 1:niter
4242
Ax = A * x
4343
ratio = norm(Ax) / norm(x)
4444
if abs(ratio - ratio_old) / ratio < tol

0 commit comments

Comments
 (0)