% eda11_14
% a network that implements the linear function y=cx+d
% for small w112 and w113 so that the approximation
% is reasonably accurate in the range -1<x<+1
% (when c, d, are both or order 1)

c = 0.5; % true slope
d = 2.0; % true intercept

% standard x axis setup
Nx = 101;
xmin = -1;
xmax = 1;
x = xmin + (xmax-xmin)*[0:Nx-1]'/(Nx-1);

% the function we are trying o approximate
ytrue = c*x+d;

% ---Neural Net definitions---

% Nmax: number of layers;
Lmax = 4;

% Lmax: maximum number of neurons in any layer
Nmax = 1;

[N,w,b,a] = eda_net_init(Lmax,Nmax);

N = [1, 1, 1, 1]';

% these two slopes are arbitrary, as long as they are small
slope1 = 0.01;
slope2 = 0.02;
w(1,1,2) = 4*slope1;
w(1,1,3) = 4*slope2;
w2w3 = w(1,1,2)*w(1,1,3);
b(1,2) = 0;

% the details:
% near x=0, sigma(wx) = (w/4)*x + (1/2)
% z2 = w2*x + b2 = w2*x + 0
% a2 = sigma(z2) = w2/4+(1/2)
% z3 = w3*a2 + b3 = w3*(w2/4+(1/2)+b3 = (w2*w3/4)*x + w3/2 + b3
% so with choice b3 = -w3/2
% z3 = (w2*w3/4)*x
% a3 = sigma(z3) = (w2*w3/16)*x + (1/2)
% z4 = w4*a3+b4
% so with choices w4=16c/(w2*w3) and b4=d-8c(w2*w3)
% a4 = c*x + d

w(1,1,4) = 16*c/w2w3;

b(1,2) = 0;
b(1,3) = -w(1,1,3)/2;
b(1,4) = d-8*c/w2w3;

figure(1);
clf;
eda_net_view(N,w,b);

% forward propagate the network for each value fo x
yest = zeros(Nx,1);
for kx=[1:Nx]
    a(1,1) = x(kx); 
    a = eda_net_eval( N,w,b,a);
    yest(kx)=a(1,4);
end

% plot the results
figure(2);
clf;
set(gca,'LineWidth',2);
hold on;
axis( [xmin, xmax, d+c*xmin, d+c*xmax] );
plot( x, ytrue, '-', 'LineWidth', 7, 'Color', [0.8,0.8,0.8]);
plot( x, yest, 'k-', 'LineWidth', 2);
xlabel('x');
ylabel('y(x)');

