% 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)
ans =

    -5


ans =

   -13


ans =

   -7.7236


Equation solved.

fsolve completed because the vector of function values is near zero
as measured by the default value of the function tolerance, and
the problem appears regular as measured by the gradient.




ans =

    1.4918


Equation solved.

fsolve completed because the vector of function values is near zero
as measured by the default value of the function tolerance, and
the problem appears regular as measured by the gradient.




x =

    1.4918


fcnVal =

   3.8543e-09


ans =

   12.7447


Equation solved.

fsolve completed because the vector of function values is near zero
as measured by the default value of the function tolerance, and
the problem appears regular as measured by the gradient.




x =

   -0.3144


fcnVal =

  -2.2604e-12


ans =

   -3.1805


ans =

   -3.1805


ans =

    -7
    -9
     1


Equation solved.

fsolve completed because the vector of function values is near zero
as measured by the default value of the function tolerance, and
the problem appears regular as measured by the gradient.




x =

    2.1010
    1.6983
    2.4026


fcnVal =

   1.0e-14 *

   -0.1776
         0
   -0.0444