% This file is part of the SPLINTER library.
% Copyright (C) 2012 Bjarne Grimstad (bjarne.grimstad@gmail.com).
%
% This Source Code Form is subject to the terms of the Mozilla Public
% License, v. 2.0. If a copy of the MPL was not distributed with this
% file, You can obtain one at http://mozilla.org/MPL/2.0/.

% Example where the Rosenbrock function is approximated
close all, clear variables
clc

% Definition of the current path folder
FileName = mfilename('fullpath');
[directory,~,~] = fileparts(FileName);
[dirmain,~,~] = fileparts(fileparts(directory));
addpath(genpath(dirmain)) 

% Rosenbrock function
funct = @(x,y) (1-x).^2 + 100*(y-x.^2).^2;
maxx =  2;      minx = -2;
maxy =  1;      miny = -1;
maxz =  3000;	  minz =  0;

% % 6-hump camelback function
% funct = @(x,y) (4 - 2.1*x.^2 + 1/3.*x.^4).*x.^2 + x.*y + (-4 + 4*y.^2).*y.^2; 
% maxx =  2; minx =  0;
% maxy =  2; miny =  0;
% maxz =  4; minz = -1;

range = 10:10:100;
time.sum = zeros(numel(range),1);
n_var = time.sum;

for k = 1:numel(range)

% Coarse grid for with sample points
% N = 10;
N = range(k);
x = linspace(-2,2,N);
y = linspace(-1,1,N);
[X,Y] = meshgrid(x,y);
Z = funct(X,Y);
% Fine grid for plotting and evaluation of errors
Nd = 10*N;
xd = linspace(min(x),max(x),Nd);
yd = linspace(min(y),max(y),Nd);
[Xd,Yd] = meshgrid(xd,yd);

time.in.exact = tic;
res.exact = funct(Xd,Yd);
time.eval.exact = toc(time.in.exact);

% Plot function and sample points
% figure
% surf(Xd,Yd,res.exact, 'EdgeColor','none','LineStyle','none')
% hold on
% stem3(X,Y,Z, 'color', 'black', 'MarkerSize', 6, 'MarkerEdgeColor', 'black', 'MarkerFaceColor','black')
% hold off
% zlim([minz,maxz]);
% view(210, 30);

% Definition of the vectors for BSplinebuilder
xs = [X(:) Y(:)];
zs = Z(:);

% % Build approximations
% time.in.Linear          = tic;
% approx.Linear           = BSplineBuilder(xs, zs, 1).build();
% time.approx.Linear      = toc(time.in.Linear);
% 
% time.in.Quadratic       = tic;
% approx.Quadratic        = BSplineBuilder(xs, zs, 2).build();
% time.approx.Quadratic   = toc(time.in.Quadratic);
% 
% time.in.Cubic           = tic;
% approx.Cubic            = BSplineBuilder(xs, zs, 3).build();
% time.approx.Cubic       = toc(time.in.Cubic);

time.in.Quartic         = tic;
approx.Quartic          = BSplineBuilder(xs, zs, 4).build();
time.approx.Quartic     = toc(time.in.Quartic);

n_var(k) = N^2;
time.sum(k) = time.approx.Quartic;

fprintf('It took %4.4i s to solve the problem. with %6.0i elements \n',time.sum(k),n_var(k))
end
%%
% % Evaluate approximations and compute errors
% time.in.Linear = tic;
% res.Linear = reshape(approx.Linear.eval([Xd(:) Yd(:)]),Nd,Nd);
% time.eval.Linear = toc(time.in.Linear);
% err.nom.Linear = res.Linear - res.exact;
% 
% time.in.Quadratic = tic;
% res.Quadratic = reshape(approx.Quadratic.eval([Xd(:) Yd(:)]),Nd,Nd);
% time.eval.Quadratic = toc(time.in.Quadratic);
% err.nom.Quadratic = res.Quadratic - res.exact;
% 
% time.in.Cubic = tic;
% res.Cubic = reshape(approx.Cubic.eval([Xd(:) Yd(:)]),Nd,Nd);
% time.eval.Cubic = toc(time.in.Cubic);
% err.nom.Cubic = res.Cubic - res.exact;
% 
% time.in.Quartic = tic;
% res.Quartic = reshape(approx.Quartic.eval([Xd(:) Yd(:)]),Nd,Nd);
% time.eval.Quartic = toc(time.in.Quartic);
% err.nom.Quartic = res.Quartic - res.exact;
% 
% % Plot approximations
% figure
% subplot(2,2,1);
% surf(xd, yd, res.Linear, 'EdgeColor','none','LineStyle','none')
% zlim([minz,maxz]);
% view(210, 30);
% title('Linear');
% 
% subplot(2,2,2);
% surf(xd, yd, res.Quadratic, 'EdgeColor','none','LineStyle','none')
% zlim([minz,maxz]);
% view(210, 30);
% title('Quadratic');
% 
% subplot(2,2,3);
% surf(xd, yd, res.Cubic, 'EdgeColor','none','LineStyle','none')
% zlim([minz,maxz]);
% view(210, 30);
% title('Cubic');
% 
% subplot(2,2,4);
% surf(xd, yd, res.Quartic, 'EdgeColor','none','LineStyle','none')
% zlim([minz,maxz]);
% view(210, 30);
% title('Quartic');
% 
% % Plot errors
% figure
% subplot(2,2,1);
% surf(xd, yd, abs(err.nom.Linear), 'EdgeColor','none','LineStyle','none')
% %zlim([minz,maxz]);
% view(210, 30);
% title('Linear');
% 
% subplot(2,2,2);
% surf(xd, yd, abs(err.nom.Quadratic), 'EdgeColor','none','LineStyle','none')
% %zlim([minz,maxz]);
% view(210, 30);
% title('Quadratic');
% 
% subplot(2,2,3);
% surf(xd, yd, abs(err.nom.Cubic), 'EdgeColor','none','LineStyle','none')
% %zlim([minz,maxz]);
% view(210, 30);
% title('Cubic');
% 
% subplot(2,2,4);
% surf(xd, yd, abs(err.nom.Quartic), 'EdgeColor','none','LineStyle','none')
% %zlim([minz,maxz]);
% view(210, 30);
% title('Quartic');
% 
% % Compute absolute errors
% err.abs.Linear = max(max(abs(err.nom.Linear)));
% fprintf('The maximum absolute error with a    linear spline is given by: %2.2f \n',err.abs.Linear) 
% 
% err.abs.Quadratic = max(max(abs(err.nom.Quadratic)));
% fprintf('The maximum absolute error with a quadratic spline is given by: %2.2f \n',err.abs.Quadratic) 
% 
% err.abs.Cubic = max(max(abs(err.nom.Cubic)));
% fprintf('The maximum absolute error with a     cubic spline is given by: %2.2f \n',err.abs.Cubic) 
% 
% err.abs.Quartic = max(max(abs(err.nom.Quartic)));
% fprintf('The maximum absolute error with a   quartic spline is given by: %2.2f \n\n',err.abs.Quartic) 
% 
% % Compute relative errors
% frange = max(max(res.exact))-min(min(res.exact));
% err.rel.Linear = max(max(abs(err.nom.Linear./frange)))*100;
% fprintf('The maximum relative error with a    linear spline in [%%] is given by: %2.2f \n',err.rel.Linear) 
% 
% err.rel.Quadratic = max(max(abs(err.nom.Quadratic./frange)))*100;
% fprintf('The maximum relative error with a quadratic spline in [%%] is given by: %2.2f \n',err.rel.Quadratic) 
% 
% err.rel.Cubic = max(max(abs(err.nom.Cubic./frange)))*100;
% fprintf('The maximum relative error with a     cubic spline in [%%] is given by: %2.2f \n',err.rel.Cubic) 
% 
% err.rel.Quartic = max(max(abs(err.nom.Quartic./frange)))*100;
% fprintf('The maximum relative error with a   quartic spline in [%%] is given by: %2.2f \n',err.rel.Quartic) 
