maxsteps = 200; % max timesteps
p = 0.5; % starting rate
dec = 1; % decrease rate by this fraction each step
Mest = zeros(6,1); % initialize
dM = zeros(6,8); % initialize
% known input coefficients (M)
M = [32.5; 3.65384615384615; 3.65384615384615; 3.65384615384615; 3.65384615384615; 2.5];
% M = [4.975388788; 0.083993056; 0.013540861; 0.082389867; 0.013327759; 0.013806649];
% min/max/avg unknowns (a,b,c,d,e,f,g,h)
lo = min(1./M)./1000; % min coefficient value
hi = max(1./M).*1000; % max coefficient value
avg = mean(1./M); % avg coefficient value
% unknown ouput coefficients (a,b,c,d,e,f,g,h)
[a,b,c,d,e,f,g,h] = deal(avg); % average 1/M to starting guess
% recording
Crecs = zeros(maxsteps,8);
Mrecs = zeros(maxsteps,6);
Crecs(1,:) = [a b c d e f g h];
for t=1:maxsteps
% current M estimates
Mest(1) = 1/(a+b)+1/(e+f);
Mest(2) = 1/(a+c)+1/(e+g);
Mest(3) = 1/(a+d)+1/(e+h);
Mest(4) = 1/(b+c)+1/(f+g);
Mest(5) = 1/(b+d)+1/(f+h);
Mest(6) = 1/(c+d)+1/(g+h);
% distance to correct M
deltaM = abs(Mest-M);
% average distance to correct M, for change in a coefficient value
f0(1) = (deltaM(1)+deltaM(2)+deltaM(3))/3; % average distance at new a
f0(2) = (deltaM(1)+deltaM(4)+deltaM(5))/3; % average distance at new b
f0(3) = (deltaM(2)+deltaM(4)+deltaM(6))/3; % average distance at new c
f0(4) = (deltaM(3)+deltaM(5)+deltaM(6))/3; % average distance at new d
f0(5) = (deltaM(1)+deltaM(2)+deltaM(3))/3; % average distance at new e
f0(6) = (deltaM(1)+deltaM(4)+deltaM(5))/3; % average distance at new f
f0(7) = (deltaM(2)+deltaM(4)+deltaM(6))/3; % average distance at new g
f0(8) = (deltaM(3)+deltaM(5)+deltaM(6))/3; % average distance at new h
% M derivatives for each coefficient
% a b c d e f g h
dM(1,1) = -1/(a+b)^2; dM(1,2) = -1/(a+b)^2; dM(1,3) = 0; dM(1,4) = 0; dM(1,5) = -1/(e+f)^2; dM(1,6) = -1/(e+f)^2; dM(1,7) = 0; dM(1,8) = 0;
dM(2,1) = -1/(a+c)^2; dM(2,2) = 0; dM(2,3) = -1/(a+c)^2; dM(2,4) = 0; dM(2,5) = -1/(e+g)^2; dM(2,6) = 0; dM(2,7) = -1/(e+g)^2; dM(2,8) = 0;
dM(3,1) = -1/(a+d)^2; dM(3,2) = 0; dM(3,3) = 0; dM(3,4) = -1/(a+d)^2; dM(3,5) = -1/(e+h)^2; dM(3,6) = 0; dM(3,7) = 0; dM(3,8) = -1/(e+h)^2;
dM(4,1) = 0; dM(4,2) = -1/(b+c)^2; dM(4,3) = -1/(b+c)^2; dM(4,4) = 0; dM(4,5) = 0; dM(4,6) = -1/(f+g)^2; dM(4,7) = -1/(f+g)^2; dM(4,8) = 0;
dM(5,1) = 0; dM(5,2) = -1/(b+d)^2; dM(5,3) = 0; dM(5,4) = -1/(b+d)^2; dM(5,5) = 0; dM(5,6) = -1/(f+h)^2; dM(5,7) = 0; dM(5,8) = -1/(f+h)^2;
dM(6,1) = 0; dM(6,2) = 0; dM(6,3) = -1/(c+d)^2; dM(6,4) = -1/(c+d)^2; dM(6,5) = 0; dM(6,6) = 0; dM(6,7) = -1/(g+h)^2; dM(6,8) = -1/(g+h)^2;
% positive on negative side is the direction of the root (0)
for i=1:6
if Mest(i)<M(i)
dM(i,:) = -dM(i,:);
end
end
% net derivative
df = sum(dM);
% Newton-Raphson step
an = a-p*f0(1)/df(1);
bn = b-p*f0(2)/df(2);
cn = c-p*f0(3)/df(3);
dn = d-p*f0(4)/df(4);
en = e-p*f0(5)/df(5);
fn = f-p*f0(6)/df(6);
gn = g-p*f0(7)/df(7);
hn = h-p*f0(8)/df(8);
% bound results: do not allow steps to very high or very low values
if an<lo; a = (a+lo)/2; elseif an>hi; a = (a+hi)/2; else; a = an; end
if bn<lo; b = (b+lo)/2; elseif bn>hi; b = (b+hi)/2; else; b = bn; end
if cn<lo; c = (c+lo)/2; elseif cn>hi; c = (c+hi)/2; else; c = cn; end
if dn<lo; d = (d+lo)/2; elseif dn>hi; d = (d+hi)/2; else; d = dn; end
if en<lo; e = (e+lo)/2; elseif en>hi; e = (e+hi)/2; else; e = en; end
if fn<lo; f = (f+lo)/2; elseif fn>hi; f = (f+hi)/2; else; f = fn; end
if gn<lo; g = (g+lo)/2; elseif gn>hi; g = (g+hi)/2; else; g = gn; end
if hn<lo; h = (h+lo)/2; elseif hn>hi; h = (h+hi)/2; else; h = hn; end
% decrease convergence rate
p = p.*dec;
% record
Crecs(t+1,:) = [a b c d e f g h];
Mrecs(t,:) = Mest;
end
fprintf('residual: %f',Mest./M-1)
for i=1:8
figure(1); plot(1:maxsteps+1,Crecs(:,i)); hold on;
end
title('a, b, c, d, e, f, g, h'); xlabel('steps'); hold off;
for i=1:6
figure(2); plot(1:maxsteps,Mrecs(:,i)./M(i)); hold on;
end
title('M_{est}/M_{actual}'); xlabel('steps'); hold off;