

%% Problem 1
clc
fprintf('Problem 1\n\n')

% The set of equations can be writen as:
% A*X=b
% so X is:
% X = A^-1 * b
% where A^-1 is the matrix inverse of A

% Setup A and b
A=[4,3,3;1 10 4;8 0 3]; % The coefficient matrix
b=[6; 0; 6];

Inv_A=inv(A);   %Matrix inverse

% Find X
X=Inv_A*b;

fprintf('The solution for these equations are\n x = %g\n y = %g \n z = %g \n ',...
    X(1),X(2),X(3))

% Check the solution by pluggeing back into oringal set of equations:
x=X(1);y=X(2);z=X(3);
C1=4*x+3*y+3*z;
C2=x+10*y+4*z;
C3=8*x+3*z;

% Our solution:
CheckSol =[C1; C2; C3]

%From the set of eqations should be:
b


%% Problem 2
clc
fprintf('Problem 2\n\n')

% Make function handle for the J0 function
f=@(X) besselj(0,X);

%Create object of class 'HW6_Solution_RootFinding'
BF=HW6_Solution_RootFinding;

%Setup properties 
BF.F=f;     %Function handle
BF.X0=0;    %First initial point
BF.X1=3;    %Second intial point needed for secant method: 
% Note:     If you look at the plot you can choose a good number for X1

%Call the method that performs the Secant update method
BF.secantMethod();

%Call the method that makes the plot showing the search history
BF.plotUpdates() % This part is arbitary

%Report Final Answer to the command window. 
fprintf('The first positive root for bessel function of the first kind is %d \n',BF.X_root)


%% Problem 3
clc
fprintf('Problem 3\n\n')

%Create function handles for the function and first derivative
f=@(X) besselj(0,X);
fprime=@(x) -besselj(1,x)

%Create object of class 'HW6_Solution_RootFinding'
BF=HW6_Solution_RootFinding;

% Setup object
BF.F=f;
BF.F_p=fprime;
BF.X0=1;

%Call the method that performs Newton's method updates
BF.newtonMethod()

%Plot the search progress and result 
BF.plotUpdates()

fprintf('The first positive root for bessel function of the first kind is %d \n',BF.X_root)


%% Problem 4
clc
fprintf('Problem 4\n\n')

%To find the minimum we need to find where f'(x) crosses 0

%The function for which we are finding the root is then:
f=@(X) -besselj(1,X);

%Since we don't know f'(x) we use secant method. 

%Create object setup for secant method 
BF=HW6_Solution_RootFinding;
BF.F=f;
BF.X0=1;
BF.X1=5;

%Run method
BF.secantMethod()

%Plot the search
BF.plotUpdates()


%Now lets check if our root of -J1 is really minimum of J0
X=linspace(0,10,100);
figure
hold on

%plot -J1
plot(X,f(X));

%plot J0
plot(X,besselj(0,X));

% A dashed horizontal line at Y=0
plot([0 10],[0 0],'k--')

% A vertical dashed line at our zero
plot([BF.X_root,BF.X_root],[-.5,1],'k--')  

% Marking our zero with a star
plot(BF.X_root,BF.F(BF.X_root),'p',...         
    'MarkerFaceColor',[0,0.25,0.5],...
    'MarkerEdgeColor','y',...
    'MarkerSize',12)

%legend, title and labels...
legend('J0(x)','Secant')
title('Bessel function of the first kind')
xlabel=('X')
ylabel=('J0(X)')

%print result to command window
Fmin=besselj(0,BF.X_root);
fprintf('The first minimum of J_0(X) is at %g with the value of %d\n',BF.X_root,Fmin)
