% Jake Bobowski
% July 24, 2017
% Created using MATLAB R2014a

% This tutorial is based off of code written and published online by
% Vaughan R. Voller.  Here is a link to Dr. Voller's website:
% http://personal.cege.umn.edu/~voller/ and a link to source of the code
% presented in this tutorial: http://personal.cege.umn.edu/~voller/ce3101_2009/matlab_solver.pdf

% You can clear all previous variable assignments using 'clearvars':
clearvars

% The goal is to use fsolve solve a nonlinear equation and a system of
% nonlinear equations.  However, fsolve calls a function when it is
% exectued, so we have to define and save the appropriate functions.

% In the first example we attempt to solve a single nonlinear function.
% Take for example, 3x^3 - 3x^2 + x -7 = 0.  We want to know the value of x
% that satifies this equality. 

% The first step is to define the function as follows:
% function F = nonlinfcn1(x)
% F = 3*x^3 - 2*x^2 + x -7;

% You must enter the two lines of coded into the MATLAB editor and save
% it as nonlinfcn1.m and keep this file in the same directory as this
% script (nonlinear.m)

% Once the above function has been created and saved, we can call it as
% follows:
nonlinfcn1(1)
nonlinfcn1(-1)
nonlinfcn1(-0.35)

% Now we can use fsolve to call this function and solve it for the value of
% x that makes the nonlinear expression equal to zero.  fsolve requires
% that we provide a starting value for x.  We will use as our intial guess
% the value x0 = 1.
x0 = 1;
fsolve(@nonlinfcn1,x0)

% fsolve has determined that x = 1.4918 causes the nonlinear function to
% evaluate to a number that is close to zero.  We can force fsolve to tell
% us what the function actually evaluates to using:
[x, fcnVal] = fsolve(@nonlinfcn1,x0)

% Here's another nonlinear function of a single variable: tan(exp(-2*x^4))
% = 1/x.  To find the value of x and satisfies this expression, create the
% following function:
% function F = nonlinfcn2(x)
% F = tan(exp(-2*x)) - 1/x;

% Enter the above two lines in the script editor and save it as
% nonlinfcn2.m.  When fsolve is called, it will set the function we entered
% equal to zero and find the value of x that satifies that condition.

% We can test that nonlinfcn2 works properly
nonlinfcn2(-0.1)

% And then we can implement fsolve.
x0 = -0.1;
[x, fcnVal] = fsolve(@nonlinfcn2,x0)

% To test if the solution seems reasoable...
tan(exp(-2*x))
1/x

% In this next, and final, example, we solve a system of nonlinear
% equations using the same method used above.  The system of equations we
% consider are:
% 3*x*y + y - z = 10
% x + x^2*y + z = 12
% x - y - z = -2
% and the goal is to determine the values of x, y, and z.

% In a MATLAB script enter the following lines and save it as nonlinsys.m
% function F = nonlinsys(x)
% F = [3*x(1)*x(2) + x(2) - x(3) - 10;
% x(1) + x(1)^2*x(2) + x(3) - 12;
% x(1) - x(2) - x(3) + 2];

% The semicolons between the three expressions ensures that the result is a
% column vector of the three expressions.

% We can call the function as follows:
x0 = [1; 1; 1];
nonlinsys(x0)
% whcih evaluates the function at x = 1, y = 1, and z = 1.

% Finally, using fsolve we can get the solution.
[x, fcnVal] = fsolve(@nonlinsys, x0)