Skip to main content
added 1472 characters in body
Source Link

-------------------------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
  ]

enter image description here

enter image description here

-------------------------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
  ]

enter image description here

enter image description here

Source Link

Implement gradient method in functional programming style

I implemented the gm for quadratic function in Mathematica, but it looks like more in an OOP style, as the pic shows. enter image description here

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?