Download as pdf or txt
Download as pdf or txt
You are on page 1of 26

HOMOTOPY CONTINUATION METHODS:

An Algorithm for the Fixed Point and Newton Homotopy Methods with Some Examples

Francesco Decarolis fdc@uchicago.edu

Ricardo Mayer ricardom@uchicago.edu

Martin Santamaria msantama@uchicago.edu

ABSTRACT Homotopy Continuation Methods provide a useful approach to find the zeros of f : Rn Rn in a globally convergent way. Homotopy Methods transform a hard problem into a simpler one whit easily calculated zeros and then gradually deform this simpler problem into the original one computing the zeros of the intervening problems and eventually ending with a zero of the original problem. This paper presents a description of a Matlab code that can implement the Fixed Point Homotopy and the Newton Homotopy methods to find the zeros of any function f : Rn Rn. Four examples are also provided for illustrative purposes. Two univariate examples, one of which regarding a General Equilibrium problem, and two multivariate ones show how the Matlab code can be easily applied to different problems. You will need Matlab's Symbolic Math Toolbox to run this code.

1. INTRODUCTION: the Homotopy Continuation Methods in General This paper accompanies a code that can implement the Fixed Point Homotopy and the Newton Homotopy methods to find the zeros of any function f : Rn Rn. Homotopy methods belong to the family of continuation methods and like all these methods they represent a way to find a solution to a problem by constructing a new problem, simpler than the original one, and then gradually deforming this simpler problem into the original one keeping track of the series of zeros that connect the solution of the simpler problem to that of the original, harder one. The greatest advantage of the Homotopy Methods is that, under some conditions, they offer a way to have a globally convergent method to find the zeros of any function f : Rn Rn. Judd (1998), chapter 5, contains a detailed description of the computational issues involved in the use of these Homotopy Continuation Methods. In this paper we follow the discussion in Judd (1998) to construct a simple code that allows to use the Fixed Point Homotopy (FPH) and the Newton Homotopy (NH) to find the zeros of f : Rn Rn. All the Homotopy methods are based on the construction of a function, H(x,t), H: Rn+1 Rn, HC0(Rn+1). This function H , which is called the Homotopy function, serves the objective of continuously deforming a function g into f and can be any continuous function such that: H(x,0)=g(x) and H(x,1)=f(x). Hence we construct H(x,0) in such a way that its zeros are easily found while we also require that, once the parameter t is equal to 1, then H coincides with the original function f . Among the various Homotopy functions that are generally used the Fixed Point Homotopy and the Newton Homotopy are simple and powerful methods that can be successfully applied to several different problems. In the next sections we describe how these two Homotopy functions are constructed and we illustrate how the Matlab code that we wrote applies these methods in an algorithm to find the zeros of f : Rn Rn. Finally we illustrate how to actually use the Matlab code we wrote through four examples, both univariate and multivariate.

2. FIXED POINT HOMOTOPY, NEWTON HOMOTOPY AND THEIR IMPLEMENTATION The code described in the next section is an algorithm that finds zeros of f : Rn Rn through an Homotopy method. The two Homotopy methods between which our code allows to chose are the following: (a) Fixed Point Homotopy: (b) Newton Homotopy: H(x,t)=(1-t) (x-x0)+tf(x) H(x,t)= f(x) - (1-t) f(x0) for some x0. for some x0.

The first Homotopy function gradually deforms the function (x-x0) into f(x), while the second one is a function that for t=0 has its zero at x=x0 while at t=1 it is f(x). The idea of our code will be to follow the path connecting the zeros of H(x,t) from t=0, where they are as described above, until t=1, where we will have found the zeros of the original problem. If H(x,0) and H(x,1) have zeros we will try to develop a way to follow a continuous path, which we indicate as H-1(0), H-1(0)={(x,t)H(x,t)=0}, that connects one to the other. The procedure we follow in order to create a code that traces the path H-1(0) is based on the parametric approach described in Judd (1998). Hence we view x and t as both functions of the same parameter s and we require that a parametric path satisfies H(x(s),t(s))=0 for all s. Being on the path thus implies that we have an y(s)=(x(s),t(s)) such that H is equal to zero hence for changes in x and t it must be that y obeys the following system differential equations (see Garcia and Zangwill (1981)):

dyi ds

1i det H yi, i 1,...,n1 y

where ( )-i means that we remove the ith column. For the system defined by the above equation to arrive to t(s)=1 it must be that we never find any singular matrix (((H)/(y))(y)-i) before that. The condition that insures that this is the case is that the Homotopy function H is regular, where we define H to be regular whenever Hy=(Hx,Ht) is of full rank (i.e. rank n) at all points in H-1(0) and y(x,t). The code that we present in the next section builds on this parametric approach to describe a path in the (x,t) space that connects the zeros of H(x,0) to those of H(x,1).

3. THE CODE The code involves using only 2 m-files, only one of them written by the user. These are:

A User's Script (US) : this is the only file a user will need to run. Here the user must write the equations he wants to solve (it may be only one equation) as long with the other inputs needed by htopy.m. This program calls the function htopy, get's the results and further calls fsolve to refine the solution delivered by htopy. We suggest the user first read carefully and understand well the example file called 'examplebook.m' . This example show how to solve an univariate problem and contains extensive comments. Later, the reader should take a look at any other example just to see the small changes needed to solve a multivariate problem. Note that there is the freedom to choose any letter (like x, q, z, etc., or even multi-characters expressions like x1, x2, xx1, xx2, etc.) for the independent variables with the exception of y and t , because those will be names used internally by htopy. The order in which the user inputs these variables will be the one in which the plots and of the elements in the Homotopy solution vector, hopt, will appear.

The m-file function htopy.m. The function is relatively well-documented and we encourage the user to have a glance of at least the first comments included in the file: it provides a description of the inputs needed to call the function, the output it gives, describes the organization of the whole algorithm and the choices made during the execution of the program. Is short, htopy has two main parts: (a) The first uses the Symbolic Math Toolbox's capabilities to construct the system of ODEs defining the solution's path. This is, the user only have to know his initial system of equation and not the possibly quite different system of ODEs: this is computed on-the-fly by htopy. In particuar it will compute a symbolic Jacobian of the system and symbolic Determinants of parts of the Jacobian. It never writes a new mfile: it will store the system of ODEs as an inline function to feed the ODE-solver later. Some work inside the function is spent in converting symbolic object into string objects suitable for inline functions. (b) The second part takes such system of ODEs -now in form an inline function- and calls the ODE-solver specified by the user. It does the path-tracking and explores whether we have reached a solution and whether the solution is an acceptable one.

Conditional on success, returns the value of the candidate solution. If something fails it gives an appropriate warning and information to the User so she can decide how to proceed next.

4. FOUR APPLICATIONS OF THE HOMOTOPY CODE Here we present four examples that will illustrate how to use the code described above. The first two examples are univariate. In particular the first one is the same used in Judd (1998), chapter 5, to present the Homotopy methods. Here it will be particularly useful to exemplify the differences between the Fixed Point and the Newton Homotopy. The second one, instead, is a simple General Equilibrium and we show how the code is used to find the equilibrium prices. Then, finally, the third and fourth examples illustrate how to apply the htopy.m code to multivariate problems. 4.1 Example1 (Taken from Judd (1998)). The problem is to find the value of x for which f(x)=0, where f(x) is given by: f(x)=2*x - 4 + sin(2*pi*x) The unique solution of this problem is x=2. Below we show the results that we get from the code reported in the Appendix at the end of this paper. We pick as our initial guess for x, x0=0. We further choose to have 70 checks and UpS equal to 2.5. For the two Homotopy methods that our htopy.m function can compute we get the following results: (a) Fixed Point Homotopy

Computed Solutions
Homotopy Solution: Gauss-Newton Solution: 2.0008e+000 2.0000e+000

The solution, hsol, is found in the 20th chunk in which the interval [0, uppers] has been partitioned. The code also reports the value of H at the end of each of the previous 19 chunks and these values are always close enough to zero (according to the Htol parameter defined in htopy.m) so that the code never uses the Gauss-Newton solver to generate the initial guess for the ODE solver. The figure below shows the path connecting the zero of H(x,0) to that of H(x,1). This last zero is found at x=2.0008e+000 by our Fixed Point Homotopy method. When this value of x is used as an initial guess for the Matlab Gauss-Newton solver (fsolve) we get that the solution is x=2.0000e+000. This illustrates one of the key aspect of the parametric Homotopy approach that we implement: although it does not produce by itself particularly accurate solutions, still its outcome is accurate enough to be a good initial guess for more refined, possibly local, methods to find the solution of the problem at hand. Figure 1: the Fixed Point Homotopy
1 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1 t

0.2

0.4

0.6

0.8 1 1.2 independent variable

1.4

1.6

1.8

(b) Newton Homotopy

Computed Solutions
Homotopy Solution: Gauss-Newton Solution: 2.0000e+000 2.0000e+000

This second method finds a even more refined solution that the previous one. Interestingly we can see from the picture below how the path described by this Homotopy method differs from the Fixed Point one used above.

Figure 2: the Newton Homotopy

0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1 t

0.2

0.4

0.6

0.8 1 1.2 independent variable

1.4

1.6

1.8

4.2 Example2. (General Equilibrium). Assume a two good economy populated by only one type of individuals with CES utility function given by:

Ux1,x2 x1 1 x2
Then it is a simple exercise of calculus to show that the excess demand of good one as a function of the relative price p and the endowment vector e is given by:

z1p,p e

pe
1

e1

The excess demand is shown below for =0.2, =0.5 and endowment vector e=(0.1 , 0.3). As can be seen from the picture there are at least two equilibria. Figure 3: the Excess Demand Function
0.01 0.008 0.006 0.004 0.002 0 -0.002 -0.004 -0.006 -0.008 -0.01

10

20

30

40

50

60

70

80

90

100

Finding the zeros of the excess demand using Homotopy continuation methods First we start with two figures that illustrate how the Homotopy method works for this simple case. In both cases we use the Newton Homotopy, defined by:

H p,t z1p,p et 1 tz1p,p e z1p0,p0 e


Intuitively, to get to the solution we start by solving the equation z1(p,pe) z1(p0, p0e) which has a solution at p0. And then we continuously deform this equation (of which we know the solution) into the original excess demand function. The first figure illustrates the case where p0 is smaller than the equilibrium price. As we can see from the figure as we continuously change t from 0 to 1 the zeros of the Homotopy function converge to the zero of the excess demand function monotonically from below. Figure 4: Newton Homotopy for the GE with p0=1.
0.02 0.015 0.01 0.005 0 -0.005 -0.01 -0.015 -0.02 t=0 t=1 t=0.5 t=.7 t=.8 t=.9

The next picture, instead, depicts the opposite situation . In this case the convergence to the solution is from above. Figure 5: Newton Homotopy for the GE with p0=5.
0.02 0.015 0.01 0.005 0 -0.005 -0.01 -0.015 -0.02 t=0 t=1 t=0.5 t=.7 t=.8 t=.9

Now we show the results that we get once we use the htopy.m function to find a solution to the problem at hand. These codes are reported at the end of this paper in the appendix.

Computed Solutions
Newton Homotopy Solution (p0=1): Newton Homotopy Solution (p0=5): 2.1429e+000 2.3357e+000

The following figures show the set {(x,t):H(x,t)=0} found by our code respectively with the initial guess p0=1 and p0=5. Figura 6: Newton Homotopy for the GE with p0=1: the parametric path.

0.9 0.8 0.7 0.6 0.5 t 0.4 0.3 0.2 0.1

1.1

1.2

1.3

1.4 1.5 1.6 1.7 in d e p e n d e n t va ria b le

1.8

1.9

2.1

Figura 7: Newton Homotopy for the GE with p0=5: the parametric path.
0.9 0.8 0.7 0.6 0.5 t 0.4 0.3 0.2 0.1

2.5

3.5 4 in d e p e n d e n t va ria b le

4.5

4.3 Example3. (Bivariate Case). The problem is to find the value of x,q,z for which f(x,q)=0, where f(x,q) is given by: f1(x,q)= x^2 + q^2-1 f2(x,q)= sin(x)-q The system has two symmetric solutions. Below we show the results that we get from the code reported in the Appendix at the end of this paper. We pick as our initial guess (0,0). We further choose to have 70 checks and UpS equal to 10. For the first one of the Homotopy methods that our htopy.m function can compute we get the following results:

(a) Fixed Point Homotopy

Computed Solutions
x Homotopy Solutions: Gauss-Newton Solutions: -7.388530437289927e-001 -7.390851332165159e-001 q -6.756862152576728e-001 -6.736120291852369e-001

Functions Evaluation at the Computed Solutions


x^2 + q^2-1 At Homotopy Solutions At Gauss-Newton Solutions 1.227087985954902e-003 2.363775841726627e-012 sin(x)-q 1.122180544844956e-003 5.102029909658878e-013

The code also reports the results of H evaluated at the end of each subinterval and we have that these values are always close enough to zero so that the code does not call the Gauss-Newton solver to be set back on track.

The pictures below show the path that our code finds.

Figure 8: variable by variable. x in the upper subplot and q in the lower one
1 0.8 0.6 t 0.4 0.2 -0.7 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1 0 independent variable 0.1 0.2 0.3 1 0.8 0.6 t 0.4 0.2 -1 -0.9 -0.8 -0.7 -0.6 -0.5 -0.4 independent variable -0.3 -0.2 -0.1

Figure 9: 3D plot of the path


3D P lot of the s olution

1 0.8 0.6 t 0.4 0.2 0 0 -0.5 -1 q -1.5 -1 -0.5 x 0

0.5

4.4 Example4. (Trivariate Case). The problem is to find the value of x,q,z for which f(x,q,z)=0, where f(x,q,z) is given by: f1(x,q)= x + 0.5*q + 0.3*z-5 f2(x,q)= 0.6*x + q + z*0.1-7 f3(x,q)= 0.2*x + 0.4*q + z-4 The system above is linear, the solutions given by Mathematica is x=1.67155, q=5.8651 and z=1.31965. Below we show the results that we get from the code reported in the Appendix at the end of this paper. We pick as our initial guess (0,0,0). We further choose to have 50 checks and UpS equal to 30. For the for the first one of the Homotopy methods that our htopy.m function can compute we get the following results: (a) Fixed Point Homotopy

Computed Solutions
x
Homotopy Solutions: Gauss-Newton Solutions 1.6731e+000 1.6716e+000

q
5.8575e+000 5.8651e+000

z
1.3209e+000 1.3196e+000

Functions Evaluation at the Computed Solutions


x + 0.5*q + 0.3*z-5 0.6*x + q + z*0.1-7 0.2*x + 0.4*q + z-4

At Homotopy Solut. At Gauss-Newton Solut.

-2.5918e-004 2.6838e-012

-9.0738e-004 -1.3749e-012

-2.0462e-004 4.3367e-012

The three dimensional graph of the solution (just the values of x, q and z, not t) is:
3 D P lo t o f t h e s o lu t io n

1 .5

z 0 .5

0 6 5 4 1 3 q 2 1 0 x

Instead the figure below plots how each of the original independent variables changes along the path as t increases from zero to one. Figure 10: variable by variable. x in the upper subplot, q in the middle one and z in the lower one.

1 0.8 0.6 t 0.4 0.2 0.2 0.4 0.6 0.8 1 independent variable 1.2 1.4 1.6 1.8 1 0.8 0.6 t 0.4 0.2 0.5 1 1.5 2 2.5 3 3.5 independent variable 4 4.5 5 5.5 1 0.8 0.6 t 0.4 0.2 0.2 0.4 0.6 0.8 independent variable 1 1.2 1.4

5. BIBLIOGRAPHY - Judd, K. L. (1998). Numerical Methods in Economics. MIT Press, Cambridge, MA. - Garcia, C. B. and W. I. Zangwill (1981). Pathways to Solutions, Fixed Points and Equilibria. Prentice Hall, Englewood Cliffs, NJ.

Appendix Example 1. One equation in one unknown, taken from Judd (1998), chapter 5.
clear; clc; %EXAMPLE-BOOK. %(FROM JUDD (1998) CHAPTER 5)

%%%%%%%%%% Step 1: write down your system and variables as strings fstring = [{'2*x - 4 + sin(2*pi*x)'}]; varlist = [{'x'}];

%%%%%%%%%% Step 2: Make some choices for your problem: %%% choose the initial values for your variable initialval = [0]; %%% choose the limits for your solutions aboxa = [-100,100] ; %%% choose an upper value for s (in the ode system) upS =2.5; %%% choose the number of intermediate checks for [0, upperS] checks = 70; %%% choose an homotopy : FP or N homoto = 'FP'; %homoto = 'N'; %%% choose an ODE solver % odesol = 'ode15'; %% it actually the ode15s solver odesol = 'ode45';

%%%%%%%%%%%%%%% Step 3: call the homotopy function


[hsol, ff] = htopy(fstring,varlist,initialval, upS,checks, aboxa, homoto, odesol)

%%%%%%%%%%%%%%% Step 4: refine the solution calling fsolve if ff == 1 nsol=fsolve(inline('[2*x(1) - 4 + sin(2*pi*x(1))]','x'),hsol) end

Example 2. Codes for the General Equilibrium Example.


clear; clc; format short e; %%%%%%%%%%%%%%%%%% %Parameter Values% %%%%%%%%%%%%%%%%%% a = 0.2; %alpha s=0.5; %rho %%%%%%%%%%%%%%%%%% %Endowment Vector% %%%%%%%%%%%%%%%%%% e = [.1 .3]; %%%%%%%%%%%%%%%%%% %Initial Guess % %%%%%%%%%%%%%%%%%% x0=5; %%%%%%%%%%%%%%%%%% %Main Routine % %%%%%%%%%%%%%%%%%% syms x1 syms f1
f1=-(((a/x1)^(s))*(((x1*e(1,1)+e(1,2))/((a^s)*(x1^(1-s))+(1-a)^s)))-e(1));

x=[x1]; f=[f1]; fstring = char([]); varlist = char([]); for i=1:1 fstring = [fstring, {char(f(i))}]; varlist = [varlist, {char(x(i))}]; end %%%%%%%%%%%%%%%%%%%%%% %Homotopy Parameters % %%%%%%%%%%%%%%%%%%%%%% upS =300; checks=70; aboxa=[0.1,10]; initialval = x0; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %Choose an homotopy : FP or N % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %homoto = 'FP'; homoto = 'N'; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %Choose an ODE solver : ode15 or ode45 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % odesol = 'ode15'; %% it actually the ode15s solver odesol = 'ode45'; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %Step 3: Call the homotopy function % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[hsol, ff] = htopy(fstring,varlist,initialval, upS,checks, aboxa, homoto, odesol)

Example 3. Two equations in two unknowns.


clear; clc; %Bivariate Example format long e; %%%%%%%%%% Step 1: write down your system and variables as strings fstring1 = 'x^2 + q^2-1'; fstring2='sin(x)-q'; varlist = [{'x'},{'q'}]; fstring = [{fstring1},{fstring2}];

%%%%%%%%%% Step 2: Make some choices for your problem: %%% choose the initial values for the variables initialval = [0,0]; %%% choose the limits for your solutions aboxa=[-100,100 ; -100, 100]; %%% choose an upper value for s (in the ode system) upS =20; %%% choose the number of intermediate checks for [0, upperS] checks=70; %%% choose an homotopy : FP or N homoto = 'FP'; %homoto = 'N'; %%% choose an ODE solver % odesol = 'ode15'; %% it is ctually the ode15s solver odesol = 'ode45';

%%%%%%%%%%%%%%% Step 3: call the homotopy function


[hsol, ff] = htopy(fstring,varlist,initialval, upS,checks, aboxa, homoto, odesol)

%%%%%%%%%%%% %%%%%%%%%%%% %%%%%%%%%%%% %%%%%%%%%%%% %%%%%%%%%%%% %%%%%%%%%%%% if ff == 1

Step 4:in case the Homotopy finds a solution then ff=1 and the solution found by the Homotopy, hsol, is reported. The hsol is then used as an initial guess for fsolve and finally both the original solution of the Homotopy, hsol, and that of the Gauss-Newton solver, nsol, are used to evaluate the equations of the original system.

nsol=fsolve(inline('[x(1)^2 + x(2)^2-1;sin(x(1))-x(2)]','x'),hsol) fhom=(feval(inline('[x(1)^2 + x(2)^2-1;sin(x(1))-x(2)]','x'),hsol))./(1+norm(hsol)) fnew=(feval(inline('[x(1)^2 + x(2)^2-1;sin(x(1))-x(2)]','x'),nsol))./(1+norm(nsol))

end

Example 4. Three equations in three unknowns.


clear; clc; %Trivariate Example format short e;

%%%%%%%%%% Step 1: write down your system and variables as strings fstring1 = 'x + 0.5*q + 0.3*z-5'; fstring2='0.6*x + q + z*0.1-7'; fstring3='0.2*x + 0.4*q + z-4'; varlist = [{'x'},{'q'},{'z'}]; fstring = [{fstring1},{fstring2},{fstring3}];

%%%%%%%%%% Step 2: Make some choices for your problem: %%% choose the initial values for the variables initialval = [0, 0, 0]; %%% choose the limits for your solutions aboxa=[-100,100 ;-100,100;-100, 100]; %%% choose an upper value for s (in the ode system) upS =30; %%% choose the number of intermediate checks for [0, upperS] checks=50; %%% choose an homotopy : FP or N homoto = 'FP'; %homoto = 'N'; %%% choose an ODE solver % odesol = 'ode15'; %% it is actually the ode15s solver odesol = 'ode45';

%%%%%%%%%%%%%%% Step 3: call the homotopy function


[hsol, ff] = htopy(fstring,varlist,initialval, upS,checks, aboxa, homoto, odesol)

%%%%%%%%%%%% %%%%%%%%%%%% %%%%%%%%%%%% %%%%%%%%%%%% %%%%%%%%%%%% %%%%%%%%%%%% if ff == 1

Step 4:in case the Homotopy finds a solution then ff=1 and the solution found by the Homotopy, hsol, is reported. The hsol is then used as an initial guess for fsolve and finally both the original solution of the Homotopy, hsol, and that of the Gauss-Newton solver, nsol, are used to evaluate the equations of the original system.

nsol=fsolve(inline('[x(1) + ;0.2*x(1) + 0.4*x(2) + x(3) fhom=(feval(inline('[x(1) + ;0.2*x(1) + 0.4*x(2) + x(3) fnew=(feval(inline('[x(1) + ;0.2*x(1) + 0.4*x(2) + x(3)

0.5*x(2) + 0.3*x(3)-5 ; 0.6*x(1) + x(2) + x(3)*0.1-7 - 4]','x'),hsol) 0.5*x(2) + 0.3*x(3)-5 ; 0.6*x(1) + x(2) + x(3)*0.1-7 - 4]','x'),hsol))./(1+norm(hsol)) 0.5*x(2) + 0.3*x(3)-5 ; 0.6*x(1) + x(2) + x(3)*0.1-7 - 4]','x'),nsol))./(1+norm(nsol))

end

THE HOMOTOPY ROUTINE: HTOPY.M

function

[opt,fall] = htopy(fu,svars, prex0, upperS, numchecks, box, Hchoice, ODEchoice)

% htopy2 computes an approximate solution to the system of equations fu(x)=0. % It uses an homotopy represented by H(x,t)=0, with known solution for x at t=0, and % with H(x,1)=fu(x)=0, so any x satisfying (approx) H(x,1) is an (approx) solution to % fu(x), the system of interest. % This implementation continously deforms H(x,0) into a sequence of H(x,t) by making % x and t functions of another variable 's' (thus, x becomes x(s) and t becomes t(s)), % and solves a sequence of systems of ODE in order to 'track' the path defined by H(x,t). % For more explanations about this procedure and formulas involved, see Judd 1998, pages % 179 to 187) % % OUTPUT: % % fall: fall = 1 only if the function succeeds. Success means: 1) a candidate solution was found % (i.e. a t close enough to 1 is found), AND 2) the candidate solution lies inside the % bounds for x specified by the user (in 'box'). In any other case the function fails % and fall = 0. This is useful to instruct other functions not to use the value in opt % if fall is not 1. % % opt: if the function succeeds, opt is a vector of values x % that makes fu(x) approx. zero. If fails because the candidate solution lies % outside the box, then it returns and empty array []. If it fails because no % candidate solution was found it ret)urns the values of x and t for the last % iteration. % % INPUTS: % % fu: a cell array of strings representing a system of equations % (it can be just a single equation) in the form f(x)=0 % % svars : a cell array of strings containig the names of the variables included % in fu (in particular, do not include t or s here) % % prex0 : a vector with the initial conditions for variables in svars % % upperS : this scalar is the upper bound used in the ODE part for s. You can set upperS % relatively large and insert many check points between 0 and upperS. The function % will exit as soon as one candidate solution has been found in any of the % intervals defined by the checkpoints [0,s1,s2....upperS]. That can happen well % before s is close to upperS. % % numchecks: A scalar. Is the number of intermediate checks s1,s2,s3... between 0 % and upperS. The fucntion will divide [0,upperS] in (numchecks+1) intervals of equal % length % % box: an nx2 matrix. Each rows represent one variable in svars. The first column % holds the lower bound for that variable and the second column contains the upper bound. % % Hchoice: a string. If it takes the value 'FP' then the (1-t)(x-x0) is % done. If it takes the value 'N', it implements a Newton type homotopy (see page 179) % % ODEchoice: a string. If it takes the value 'ode45' then the solver ode45 % (runge-kutta, recommended choice for nonstiff problems) is used. If it takes the % value 'ode15s', a BDF-type solver is used. This appropiate for stiff % problem and when precision is less of a concern

%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% %%% Step 0: set tolerance parameters and default values %%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% this is our max acceptable deviation from H(x,t) = 0, we make this check %%% at the end of each subinterval [s_{i} , s_{i+1}] Htol = 1e-4; %%% we accept t as close enough to 1 if t \in (1-epsilont , 1+epsilont) epsilont=1e-1; %% set the failure flag to 0, do not change to success unless on sol is found fall=0; %% set a void value for the solution as the default in case of failure opt=[];

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% %%% Step 1: symbolize relevant variables and set the homotopy H %%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% simbolize s and t and some otehr symbols we may need syms t s pi e a; %%% augment the vector of initial conditions -prex0- adding the initial condition for t %%% (zero) at the end. The augmented vector is x0 x0= [prex0, 0]; numvar = size(svars,2); numfun = size(fu,2); %% check your system is square if numfun ~= numvar 'the number of variables is not equal to the number of equations' return; end %% initialize these to be symbolic but empty allvars = sym([]); allfun = sym([]); for i=1:numvar allvars = [allvars, sym(svars{i})]; allfun = [allfun, sym(fu{i})]; end %% now allvars contains all variables in symbolic form %% and allfun has all equations in fu but with symbolic status %%% Define your Homotopy if Hchoice=='FP' % this is the fixed point homotopy H = (1-t)*(allvars-prex0) + t*allfun elseif Hchoice=='N' % Newton's homotopy f0=allfun; allfun x0 for a=1:size(allvars,2) f0=subs(f0,{allvars(a)},{x0(a)}); end f0 H=allfun-(1-t)*f0 else display('Error: no Homotopy was selected or you typed an incorrect name') return; end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% %%% Step 2: Construct the system of ODEs (see eq. 5.9.4 , page 182) %%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%% Step 2.1: obtaing the RHS of the system %% append symbolic t to end of list of symbolic x allvars = [allvars, t]; %% compute the symbolic Jacobian of H w.r.t. x and t J=jacobian(H,allvars); %% form the Right Hand Side of the ODE system allRHS = []; for i = 1:numvar+1 subJ = J; %% exclude the i-th column of the Jacobian before taking Determinant subJ(:,i)=[]; %% concatenate each eq vertically, do the sign switch allRHS=[allRHS; (-1)^i * (det(subJ))]; end %% display the RHS of the ODE system if mod(numvar,2)==0 allRHS=(-1)*allRHS; end

%% %% %% %%

now we change the notation of the symbolic expressions that appear in allRHS. The reason is to get an expression that, once transformed into a string (see step 2.2) will be usable as an inline function accepted as input by fsolve (see step 2.3).

%% the first step to change the notation of allRHS is to create a row %% vector y=[y(1), y(2), ..., y(numvar+1)], where numvar was defined in %% step zero and corresponds to allvars-1. yy=sym([]); for j=1:size(allvars,2) sj = num2str(j); name = strcat('y(',sj,')'); yy(j)=name; end y=yy; %% the second step in changing the notation is to sobstitute the original %% variables given in allvars with the y(i) ones we constructed above. [m1,n1]=size(allRHS); B=jacobian(allRHS,allvars); for j=1:m1 for i=1:m1 if B(j,i)==0 allRHSs(j)=allRHS(j); else allRHSs(j)=subs(allRHS(j),{allvars(i)},{y(i)}); end allRHS(j)=allRHSs(j); end end allRHS %%%%%%% Step 2.2 %%%%%%% change the symbolic object to string object, so you can use inline functions newstring = '['; for i=1:size(allRHS,1) for j=1:1

newstring = [newstring char(allRHS(i,j)) ' ']; end newstring = [newstring ' ; '];

end newstring = newstring(1:end-3); %remove trailing punctuation newstring = strcat(newstring, ']');

%%%%%%% Step 2.3 : %%%%%%% create an inline function to make RHS usable with Matlab's ODE-functions f=inline(newstring,'s','y');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% %%% Step 3: Do the path-tracking via ODE-solving %%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% these points define a uniform grid on [0,upperS] checkpoints = linspace(0,1,numchecks+1)*upperS; %% container for solutions passed by the ODE solver pastedvalues = []; pastedtime =[]; %% Htest will be used to asses value of H at the checkpoints. For now %% it is a symbolic object but it will be converted to a number once we %% have computed the values of t and the svars at which we want to compute %% the value of H. Htest = H; k=0; for j=1:numchecks j if (ODEchoice=='ode45') [timepoints, varvalues] = ode45(f,[checkpoints(j),checkpoints(j+1)],x0); elseif (ODEchoice=='ode15') [timepoints, varvalues] = ode15s(f,[checkpoints(j),checkpoints(j+1)],x0); else H=h; display('Error: no ode-solver is being called or you typed an incorrect name') return; end %% store the last chunk of x's t and s pastedvalues = [pastedvalues; varvalues(2:end,:)]; pastedtime = [pastedtime; timepoints(2:end)]; %% update the initial conditions for x and t, to be used in the next iteration x0 = varvalues(end,:); %% find the value of t closest to 1 for this [s_i,s_{i+1}] interval testvec =abs(varvalues(:,end) -1); mintestvec= min(testvec); k = k+size(testvec,1)-1; %% test if our 'best' t is close enough to 1, if it's not, just go on if (abs(mintestvec) < epsilont) %% if t is accepted then report a candidate solution z = min(testvec); i=1; while (testvec(i) ~= z) i = i+1; end %% opt does not include tH=h; %% set opt equal to your candidate solution opt = varvalues(i,1:end-1);

%% test if your candidate solution lies inside the box for x or not if (opt >= box(:,2)') | (opt <= box(:,1)') display ('Out of bounds') out_of_bound_guess=opt %% your solution is out of the permisible region %% exit the function, do not report fall=1 return; end %% your solution passed the test, report success fall=1;

in the case of success the program will create plots for each of the original variables. Each plot has t on the vertical axis and one of the independent variables on the orizontal axis. m1 == 3 X1=pastedvalues(1:(k-size(testvec,1)+i),1); Y1=pastedvalues(1:(k-size(testvec,1)+i),2); Z1=pastedvalues(1:(k-size(testvec,1)+i),3); plot3(X1,Y1,Z1) grid on xlabel('x') ylabel('q') zlabel('t') title('3D Plot of the solution') else for l=1:m1-1 h(l)=subplot(m1-1,1,l); plot(pastedvalues(1:(ksize(testvec,1)+i),l)',pastedvalues(1:(k-size(testvec,1)+i),end)') xlabel('independent variable') ylabel('t') axis([h(l)],'tight') end end return end

%% %% %% if

%% A cnadidate solution was not found on this subinterval. Before %% checking the next subinterval (that is, going to the next j) we %% assess if our new guess is such to satisfy the requirement that %% H is equal to zero along all the path. %% Tah is, we check taht H(x0,t)=0, where x0 is the last value of %% varvalues. for a=1:size(allvars,2) Htest=subs(Htest,{allvars(a)},{x0(a)}); end Htest if (abs(Htest)/(1+norm(x0)) > Htol) %% if we are off-path then use a solver to correct x, fixing t display('Warning: off-the path. The Htol loop has been activated to correct the initial guess for the next subinterval');

% % % %

Now the program uses fsolve to produce a new vector of initial guesses for the original independent variables, given of t which we get at the end of the subinterval. To produce the new guess we proceed in three parts:

%% PART I: H is evaluated at the last value of t and then the %% notation is changed so to get an expression that, once %% transformed into a string (see PART II) will be usable as an %% inline function accepted as input by fsolve (see PART III). [m2,n2]=size(H); y(n2+1)=x0(n2+1); B2=jacobian(H,allvars); H2=H; for u=1:n2 for v=1:m1 if J(u,v)==0 newHs(u)=H2(u); else newHs(u)=subs(H2(u),{allvars(v)},{y(v)}); end H2(u)=newHs(u); end end newH=sym([]); r0=zeros(n2,1); for r=1:n2 newH=[newH;H2(r)]; r0(r)=x0(r); end newH % shows H(y(1),...,y(numvar),t*). Where t* is the last value % of t computed by the ODE solver for the subinterval at hand. % PART II: then we need to make newH usable with fsolve. We make it a % string. newstring2 = '['; for c=1:size(newH,1) for w=1:1 newstring2 = [newstring2 char(newH(c,w)) ' ']; end newstring2 = [newstring2 ' ; ']; end newstring2 = newstring2(1:end-3); %remove trailing punctuation newstring2 = strcat(newstring2, ']'); %% PART III: we use the above string into an inline function %% that becomes the input of fsolve together with an initial %% guess for the original independent variables given by the last %% values generated for them by the ODE solver. %% The new guess we generate through fsolve is called "newx". f2=inline(newstring2,'y') newx=fsolve(f2,r0) %% Then we also implement a check to see how well we are on the path %% with this new values of the independent variables and the value %% of that ends the subinterval. That is we evaluate H at %% (newx,t*). We call "newHtest" the value that we compute and that %% we will compare to Htol. x02=[(newx)',x0(n2+1)] newHtest=H; for a=1:size(allvars,2) newHtest=subs(newHtest,{allvars(a)},{x02(a)}); end newHtest if abs(Htest)<abs(newHtest) display('Matlab equation solver gave a worse x than the ODE solver') return; elseif (abs(newHtest)/(1+norm(x0)) > Htol) display('Matlab equation solver gave a result such that H is far from zero. Check Htol') return; else x0=x02

end % so either we start the check on the next subinterval with an % initial guess so that H is close enough to zero or we get one % of the two error messages above and the program stops. end %% this complete the loop for a single subinterval end %% all the subintervals in [0, upperS] have been examined %% if you made it up to this point without exit the function, it means that you never found %% a candidate solution display ('Warning: t did not get close enough to 1: increase upperS or refine stepsize for t')

You might also like