I implemented the gm for quadratic function in Mathematica, but it looks like more in an OOP style, as the pic shows.
How to rewrite it in Mathematica style? I tried with following code:
gmQuadraticF[A_, b_, x0_, eps_, iter_] :=Module[{x, temp, path},(*g[k] = x[k]+b*)
temp = RecurrenceTable[
{x[k + 1] == x[k] - N[Norm[A.x[k] + b]^2/(A.x[k] + b).A.(A.x[k] + b)]*(A.x[k] + b),
x[0] = x0 }, x, {k, 0, iter_}];(* with other codes ommitted*)];
I came across two problems. The first is flow control with recurrencetable. I want to stop the iteration when Norm[A.x[k]+b] is less than eps (tolerence rate). I tried to calculate the whole list first than apply TakeWhile to select but didn't work Second, the "b" caused the recuurencetable return a numerical exception. Any hint? Or any function should I apply instead?
-------------------------Update-----------------------------------------------
Thanks to Thies Heidecke. I've partially get it done. Two implementations return same result in first several steps. However, the implementation in functional way always stops earlier than OOP style. How to solve that?
gmQuadraticF[A_, b_, x0_, eps_, iter_] :=
Module[
{x, g, \[Alpha], NormG, f, v, path},
x = x0;
g = A.x + b;
v = 1/2 x0.A.x0 + b.x0;
\[Alpha] = N[ (Norm[g]^2)/g.A.g];
NormG = Norm[g];
f[step_, \[Alpha]_, x_, g_, sqaureNormG_, v_] := {
step + 1,(*update Iteration counts*)
N[Norm[g]^2/g.A.g],(*\[Alpha] step size*)
x - N[Norm[g]^2/g.A.g]*g,(*update x*)
A.(x - N[Norm[g]^2/g.A.g]*g) + b, (*update gradient*)
Norm[A.(x - N[Norm[g]^2/g.A.g]*g) + b],(*update gradient norm*)
1/2 (x - N[Norm[g]^2/g.A.g]*g).A.(x - N[Norm[g]^2/g.A.g]*g) +
b.(x - N[Norm[g]^2/g.A.g]*g)(*object function value*)};
path = NestWhileList[
f[#[[1]], #[[2]], #[[3]], #[[4]], #[[5]], #[[6]]] &, {0, \[Alpha],
x, g, NormG, v}, #[[1]] <= iter && #[[5]]^2 >= eps &];
Prepend[
path, {"Iteration", "Step Size", "X", "Gradient", "Gradient Norm",
"Object Value"}] // TableForm
]
NestList
/NestWhileList
. You can encode all the variables that change with each step as a list, e.g.{x,g,steps}
. $\endgroup$NestWhileList
. It should be#[[5]]
not#[[5]]^2
. $\endgroup$