echo on
1==1;

%we create 3diag matrix with 2 on the main diagonal and -1 on super subdiaonal
%loop:

function L=tridiag1(N)
for k=1:N-1,
  L(k:k+1,k:k+1)=[2,-1;-1,2];
endfor
endfunction

%we check if itw works...
tridiag1(5)

tic;tridiag1(1000);t1=toc
%this time can be easily reduced by allocating memory i.e. defining
%A once then assigning its values

function L=tridiag2(N)
 L=zeros(N,N); 
for k=1:N-1,
  L(k:k+1,k:k+1)=[2,-1;-1,2];
endfor
endfunction

%we check if itw works...
tridiag2(5)

tic;tridiag2(1000);t2=toc

%using diag() function


function L=tridiag3(N)
 x=ones(N,1); 
 L=2*diag(x)-diag(x(1:N-1),1)-diag(x(1:N-1),-1);
endfunction

%we check if it works...
tridiag3(5)

tic;tridiag3(1000);t3=toc

%using diag() and sparse() functions i.e. A in sparse format


function L=tridiag4(N)
 x=ones(N,1); 
 L=sparse(2*diag(x)-diag(x(1:N-1),1)-diag(x(1:N-1),-1));
endfunction

%we check if it works...
tridiag4(5)

tic;tridiag4(1000);t4=toc

%directly as a sparse matrix using only sparse
function L=tridiag5(N)
  
 V=[2*ones(N,1);-ones(2*N-2,1)];
 I=[1:N,1:N-1,2:N]; %rows
 J=[1:N,2:N,1:N-1];%columns
 L=sparse(I,J,V,N,N);
endfunction

%we check if it works...
A=tridiag5(5)
full(A)
tic;tridiag5(1000);t5=toc
t=[t1,t2,t3,t4,t5]
disp("how many tmes the last method is faster...");
t/t5


%prolem no 2: let's compare time solving the system with L
clear t
N=100;
for k=1:5
 L=tridiag5(N);
 L1=full(L);
 iL=inv(L);
 b=ones(N,1);
 tic;L\b;t(k,1)=toc;
 tic;L1\b;t(k,2)=toc;
 tic;iL*b;t(k,3)=toc;
 N*=2;
end 

t
disp("we see that sparse solver is almost 500 times faster then multiplying by the exact inverse..")
[t(:,2)./t(:,1),t(:,3)./t(:,1)]
%naturally tridiagonal matrices are extremely easy for solving by a suitable solver...

%problem no 3: hat function f(x)=1-|x| on [-1,1] and zero otherwise - no loops!

function y=hat(x)
  mxl1=(x>-1)&(x<1);
  y=mxl1.*(1-abs(x));
endfunction

hat(x=[-2,-0.5,0.3,4])
x=linspace(-2,3,300);
plot(x,hat(x));


%prob 4 solving a simple scalar equation

x1=fzero(f=@(x) x*x-2,[1,2])
x2=fsolve(f,2)
sqrt(2)-[x1,x2]
disp("fzro gives higher precision result");

%prob 5:
%fzero will not work try yourself (uncomment) 
%[x,info]=fzero(f1=@(x) (x-2)*(x-2), 2.1)
%we check fsolve
x1=fsolve(f1,3)
%low precision...
%try very close x0=2.01
x=fsolve(f1,2.01)
fsolve(f1,x)

%prob 6 
%implicit function 
F=@(x,y) x*x+y*y-1;
%Let's compute f(0.5) fir f defined as a nimolicit f:
%F(x,f(x))=0
%we have to solve equation g(y):=F(x,y)=0
y=fsolve(g=@(s) F(0.5,s),0.5)
y1=fzero(g,[0,1])
[y,y1]-sqrt(1-0.5*0.5)
x=linspace(0,1-1e-4);%mesh on  [0,1) 
y=size(x);
function  y=g(s)
  global FF xx
  y=FF(xx,s);
endfunction
global xx FF
FF=F;  
y(1)=1.0;
echo off
for k=2:100
  xx=x(k);
  y(k)=fzero(@g,[0,1]);
endfor
plot(x,y);pause(2);
er=y-sqrt(1-x.*x);
norm(er,"inf")
plot(x,er,";error;")

%computing an iverse we leave as a homework or next lab...