Example for Gauss-Newton method

Contents

Define function f(x) and Jacobian f'(x)

Here we use @-functions in Matlab. For more complicated functions one can define the functions in separate m-files f.m and fp.m .

f = @(x) [x(1)-1; x(2)-2 ; x(1)^2+x(2)^2-3];
fp = @(x) [ 1, 0 ; 0, 1; 2*x(1), 2*x(2) ];

Plot zero contours of the functions f1, f2, f3

h = ezplot('1*x1+0*x2-1',[-3 3 -3 3]); hold on  % plot curves where f1=0
set(h,'LineColor','r');                         % and make this red
h = ezplot('0*x1+1*x2-2',[-3 3 -3 3]);          % plot curves where f2=0
set(h,'LineColor','g');                         % and make this green
h = ezplot('x1^2+x2^2-3',[-3 3 -3 3]);          % plot curves where f3=0
set(h,'LineColor','b');                         % and make this blue
title('zero contours of f1,f2,f3')
axis equal
legend('f1=0','f2=0','f3=0')

Perform 10 Gauss-Newton steps starting with [0;0]

x = [0;0];           % initial guess
for i=1:10
  b = f(x);          % evaluate f
  fprintf('x=[%20.17g,%20.17g], ||f(x)||=%20.17g\n',x,norm(b))
  A = fp(x);         % evaluate Jacobian
  d = -A\b;          % solve norm(A*d+b)=min
  x = x + d;
end

plot(x(1),x(2),'ko'); hold off %    mark solution point with 'o'
title('zero contours of f1,f2,f3 and solution point')
x=[                   0,                   0], ||f(x)||=  3.7416573867739409
x=[                   1,                   2], ||f(x)||=                   2
x=[ 0.80952380952380942,  1.6190476190476191], ||f(x)||= 0.50787576572339488
x=[ 0.79127532704128101,  1.5825506540825622], ||f(x)||= 0.48464618206378557
x=[ 0.79142841595063729,  1.5828568319012746], ||f(x)||= 0.48464457916624887
x=[ 0.79142541916499731,  1.5828508383299948], ||f(x)||=  0.4846445785517931
x=[ 0.79142547754473658,  1.5828509550894729], ||f(x)||=  0.4846445785515599
x=[ 0.79142547640734506,  1.5828509528146903], ||f(x)||= 0.48464457855155979
x=[ 0.79142547642950456,  1.5828509528590089], ||f(x)||=  0.4846445785515599
x=[ 0.79142547642907268,  1.5828509528581454], ||f(x)||= 0.48464457855155973

Find errors

We see that we have convergence of order 1: the error gets multiplied by about .02 with each iteration.

xs = x;              % xs is exact solution which we just found
x = [0;0];           % initial guess
olderr = NaN;
for i=1:10
  b = f(x);          % evaluate f
  A = fp(x);         % evaluate Jacobian
  d = -A\b;          % solve norm(A*d+b)=min
  x = x + d;
  err = norm(x-xs);
  fprintf('||x-xs||=%8.2e, ratio=%g\n',err,err/olderr)
  olderr = err;
end
||x-xs||=4.66e-01, ratio=NaN
||x-xs||=4.05e-02, ratio=0.0867715
||x-xs||=3.36e-04, ratio=0.00829631
||x-xs||=6.57e-06, ratio=0.0195773
||x-xs||=1.28e-07, ratio=0.0194807
||x-xs||=2.49e-09, ratio=0.0194826
||x-xs||=4.86e-11, ratio=0.0194828
||x-xs||=9.46e-13, ratio=0.0194728
||x-xs||=1.91e-14, ratio=0.0201451
||x-xs||=0.00e+00, ratio=0