Newton’s Method in Multidimensions MATH2070 Lab #5 solution

$25.00

Original Work ?
Category: You will Instantly receive a download link for .ZIP solution file upon Payment

Description

5/5 - (4 votes)

1 Introduction
Last time we discussed Newton’s method for nonlinear equations in one real or complex variable. In this
lab, we will extend the discussion to two or more dimensions. We will consider a common application of
Newton’s method to nonlinear least squares fitting of a function to given data.
2 A vector function
In many cases, the nonlinear problem we are facing involves vectors. For example, X and F may represent
vectors of length 2, and we are asked to solve the system:
F0(X) = 1 − x0
F1(X) = 10(x1 − x
2
0
)
When we are working on a vector problem like this, the derivative information that we need is known as the
Jacobian, which is often symbolized by J. For this problem, we will have
J =

∂F0
∂x0
∂F0
∂x1
∂F1
∂x0
∂F1
∂x1
!
=

−1 0
−20×0 10 
It would be nice to think that our old Newton code would work with this problem. That’s almost true, but
we need to make several modifications in order to adjust to the fact that vectors are involved.
After we get an initial vector version of Newton’s method working, we will explore some of the new issues
that arise when working with vector problems.
3 A Newton code for vector problems
Suppose x is a vector in R
n, x = (x1, x2, . . . , xn), and F(x) a differentiable vector function of x:
F = (Fi(x1, x2, . . . , xN )), for i = 1, 2, . . . , n,
with Jacobian matrix J,
Jij =
∂Fi
∂xj
.
Recall that Newton’s method can be written
x
(k+1) − x
(k) = −J(x
(k)
)
−1F(x
(k)
). (1)
The superscript indicates iteration number, rather than vector index.
As an implementation note, the inverse of J should not be computed. Instead, the system
J(x
(k)
)(x
(k+1) − x
(k)
) = −F(x
(k)
).
1
should be solved. As you will see later in this course, this will save about a factor of three in computing
time over computing the inverse. numpy.linalg provides the x=np.linalg.solve(A,b) function for this
solution. If you wish to solve the system
J dx = −F
then the solution can be written as
import numpy a s np
dx = np . l i n a l g . s o l v e ( J , −F )
4 Exercise 1
1. Make a copy of the file newton3.py from Lab 4, changing its name to vnewton1.py
2. Change the signature to
def vnewton1 ( func , d func , x0 , maxIts = 100 ) :
”””x , numIts = vnewton1 ( func , d func , x0 , maxI ts = 100 )
func : e v a l u a t e s t h e f u n c t i o n .
d func : e v a l u a t e s t h e Jacob ian .
x0 : t h e i n i t i a l s o l u t i o n e s t im a t e .
maxI ts : maximum number o f i t e r a t i o n s , d e f a u l t i n g t o 1 0 0 .
”””
. . . Old t e x t o f newton3 ( ) al g o ri t hm . . .
return x , numIts
and modify it so that it:
• sets the function vector F using func();
• sets the Jacobian matrix J using dfunc();
• uses the numpy.linalg function solve() instead of scalar division;
• uses the numpy.linalg function norm() instead of abs();
• has no print statements;
3. Create a new problem file v1.py, in which v1F() defines the function vector F and v1J() defines the
jacobian matrix J, for the problem whose function is:
f0(x) = 1 − x0
f1(x) = 10(x1 − x
2
0
)
Both F and J are numpy arrays, so you need to declare them first as arrays of zeros before using them.
For instance, inside the v1.py file, the definition of v1F() might look like this:
def v1F ( x ) :
import numpy a s np
F = np . z e r o s ( 2 )
F [ 0 ] = 1. 0 − x [ 0 ]
F [ 1 ] = 1 0. 0 ∗ ( x [ 1 ] − x [ 0 ] ∗ ∗ 2 )
return F
4. Test vnewton1() on problem v1, using the starting point x0=np.array([-1.2,2.0]). In order to
access the function and jacobian information from v1, you will need a statement like
from v1 import v1F , v1J
5. Check your result by printing the norm of the function, which should be very small.
2
5 A complex function revisited
It is possible to rewrite a complex function of a complex variable as twice as many real vector functions of
twice as many real vector variables. This is done by equating the real part of a complex number with the
first component of a vector and the imaginary part of a complex number with the second component of a
vector.
Previously, we used Newton’s method to find complex roots of f(z) = z
2 + 9. Let us replace the complex
argument z by the real vector x = [x0, x1] where z = x0 + x1j, and similarly f(z) = f0 + f1j. Here Python
understands an expression like 2j to be the imaginary quantity we would mathematically represent as 2i.
Plugging these variables in yields
f0 + f1j = (x
2
0 − x
2
1 + 9) + (2×0 x1)j.
This can be written in an equivalent real vector form as

f0(x0, x1)
f1(x0, x1)

=

x
2
0 − x
2
1 + 9
2 x0 x1

(2)
6 Exercise 2
1. Create a file v2.py containing v2F and v2J, defining the values of the function F and Jacobian J of this
problem as real-valued vector and matrix quantities, respectively. The definitions might look like this;
def v2F ( x ) :
. . . set up and c a l c u l a t e F . . .
return F
def v2J ( x ) :
. . . set up and c a l c u l a t e J . . .
return J
2. Test vnewton1() on the vector problem defined in v2.py starting from [1,1]. Compare this result with
what you obtained in the previous lab, where newton3() used complex arithmetic on f8.py, starting
from 1+1j.
3. Fill in the table below. One approach to these four calculations is simply to repeat the full set of
commands four times. But you may be interested to try using the for loop to simplify things like this:
x 0 a r r a y = np . a r r a y ( [ [ 1 . 0 , 1 . 0 ] , [ 1 . 0 , −1. 0] , [ 1 0 . 0 , 5 . 0 ] , [ 1 0 . 0 , 1. 0E−25] ] )
fo r x0 in x 0 a r r a y :
x , numits = vnewton1 ( v2F , v2J , x0 )
. . . compute e r r o r . . .
. . . print numIts and e r r o r norm . . .
Initial guess numIts norm(error)
[1,1] _______ _________
[1,-1] _______ _________
[10,5] _______ _________
[10,1.e-25] _______ _________
7 Exercise 3
At this point, you should be confident that vnewton1() is correctly programmed and yields the same results
as newton3() from the previous lab. In this exercise, you will apply vnewton1() to a simple nonlinear
problem.
3
Use Newton’s method to find the two intersection points of the parabola y = x
2 − x and the ellipse
x
2/16 + y
2 = 1.
1. Plot the parabola and ellipse together over the range −4 ≤ x ≤ 4. To do this, you have to rewrite the
ellipse as a formula for y; because you are taking the square root to do this, there will be two formulas,
one for the upper half of the ellipse, and one for the lower half. Thus you will need to make three
plt.plot() statements to show the whole picture. Please include this plot when you send me your
work.
2. In order to work with Newton’s method, it is necessary to think of x and y as x[0] and x[1], and to
write both equations as functions. Thus, you should now think of the first equation as
F [ 0 ] = x [ 0 ] ∗ ∗ 2 − x [ 0 ] − x [ 1 ]
with a similar reformulation of the second equation.
3. Write a file v3.py to compute the vector function F and its jacobian J.
def v3F ( x ) :
. . . compute F . . .
return F
def v3J ( x ) :
. . . compute J . . .
return J
If we can solve F(x) = 0, then we have found a pair of values corresponding to an intersection of the
parabola and the ellipse.
4. Starting from the initial vector guess [2,1], what is the intersection point that vnewton1() finds, and
how many iterations does it take?
5. Find the other intersection point by choosing a different initial guess. What initial guess did you use,
what is the intersection point, and how many iterations did it take?
8 Exercise 4
In Exercise 2, you saw that the guess [10,1.e-25] resulted in a relatively large number of iterations. While
not a failure, a large number of iterations is unusual.
In this exercise, we will look more carefully at the iterates in the poorly-converging case from Exercise 2.
Because we are interested in the sequence of iterates, we will generate a special version of vnewton1.py that
returns the full sequence of iterates. It will return the iterates as a matrix whose rows are the iterates. (One
would not normally return so much data from a function call, but we have a special need for this exercise.)
1. Make a copy of vnewton1.py and call it vnewton2.py. Change its signature line to the following
def vnewton2 ( func , d func , x0 , maxIts ) :
”””x , numIts , i t e r a t e s = vnewton2 ( func , d func , x0 , maxI ts )
. . . comments
”””
x = ? ? ?
numIts = ? ? ?
i t e r a t e s = ? ? ?
return x , numIts , i t e r a t e s
2. Just before the loop, add the following statement
n = len ( x )
i t e r a t e s = np . z e r o s ( [ 1 , n ] )
i t e r a t e s [ 0 , : ] = x
4
to initialize the variable iterates.
3. Add the following just after the new value of x has been computed.
x = x + dx
i t e r a t e s = np . i n s e r t ( i t e r a t e s , numIts , x , a x i s = 0 )
This statement appends x as a new row to the array iterates.
4. Test your modified function vnewton2() using the same v2.py from above, starting from the vector
[1,1]. You should get the same results as before for solution and number of iterations. Check that
the size of the matrix of iterates is (iterations+1)×2, that is, it has (numIts+1) rows and 2 columns.
9 Exercise 5
The study of the poorly-converging case continues with this exercise. The objective is to try to understand
what is happening.
1. Apply vnewton2() to the function defined in v2.py starting from the vector [10,1.e-25]. This is the
poorly-converging case.
2. Plot the sequence of iterates on the plane using the command
p l t . pl o t ( i t e r a t e s [ : , 0 ] , i t e r a t e s [ : , 1 ] , ’∗− ’ )
p l t . show ( )
It is hard to interpret this plot, but it is a place to start. You do not have to send me a copy of your
plot. Note that most of the iterates lie along the x-axis, with some quite large.
3. If it’s available to you, use the zoom feature to focus on the portion of the plot with horizontal extent
around [-20,20]. It is clear that most of the iterates appear to be on the x-axis. Please send me a copy
of this plot.
4. Look at the formula you used for the Jacobian in v2.py. Explain why, if the initial guess starts with
x1 = 0 exactly, then all subsequent iterates also have x1 = 0. You have used computation to help
formulate a hypothesis that can be proved.
5. You should be able to see what is happening. We used an initial guess with x1 ≈ 0, so for a long time,
the subsequent iterates stayed near the horizontal-axis. Since the root is at x1 = 3, it takes many
iterates before the x1 component of the iterate pulls away from the horizontal axis and approaches the
region of quadratic convergence near the root at (0, 3).
6. Use a semilog plot to see how the second component of the iterates grows in the vertical direction:
p l t . s emil o g y ( np . abs ( i t e r a t e s [ : , 1 ] ) )
p l t . show ( )
The plot shows the x1 component seems to grow exponentially (linearly on the semilog plot) with
seemingly random jumps superimposed. Please send me a copy of this plot.
You now have a rough idea of how this problem is behaving. It converges slowly because the initial guess
is not close enough to the root for quadratic convergence to be exhibited. The second component grows
exponentially, however, and eventually the iterates become close enough to the root to exhibit quadratic
convergence.
10 Nonlinear least squares
A common application of Newton’s method for vector functions is fitting a nonlinear curve by the method
of least squares. This application falls into the general topic of optimization where the extremum of some
function D : R
n → R is sought. If D is differentiable, then its extrema are given by the solution of the system
5
of equations ∂D/∂xk = 0 for k = 0, 1, . . . , n − 1, which we can regard as the vector equation F(x) = 0. The
value x which zeroes out the vector equation is the same value which will minimize the scalar function D.
The differential equation describing the motion of a weight attached to a damped spring without forcing
is
m
d
2v
dt2
+ c
dv
dt + k v = 0,
where v is the displacement of the weight from equilibrium, m is the mass of the weight, c is a constant
related to the damping of the spring, and k is the spring stiffness constant. The physics of the situation
indicate that m, c and k should be positive. Solutions to this differential equation are of the form
v(t) = e
−x0t
(x2 sin x1t + x3 cos x1t),
where x0 = c/(2m), x1 =
p
k − c
2/(4m2), and x2 and x3 are values depending on the position and velocity
of the weight at t = 0. One common practical problem (called the parameter identification problem) is to
estimate the values x0 . . . x3 by observing the motion of the spring at many instants of time.
After the observations have progressed for some time, you have a large number of pairs of values (tn, vn) for
n = 0, . . . , N−1. The question to be answered is, “What values of xk would best reproduce the observations?”
In other words, find the values of x = [x0, x1, x2, x3] that minimize the norm of the differences between the
formula and observations. Define
D(x) =
N
X−1
n=0
(vn − e
−x0tn (x2 sin x1tn + x3 cos x1tn))2
(3)
and we seek the minimum of D.
In order to solve this problem, it is best to note that when the minimum is achieved, the gradient vector
F = ∇D must be zero. The components Fk of the gradient can be written as
F0 =
∂D
∂x0
= 2
K
X−1
k=0
(vk − e
−x0tk
(x2 sin x1tk + x3 cos x1tk)) tke
−x0tk
(x2 sin x1tk + x3 cos x1tk)
F1 =
∂D
∂x1
= −2
K
X−1
k=0
(vk − e
−x0tk
(x2 sin x1tk + x3 cos x1tk)) e
−x0tk
(x2 cos x1tktk − x3 sin x1tktk) (4)
F2 =
∂D
∂x2
= −2
K
X−1
k=0
(vk − e
−x0tk
(x2 sin x1tk + x3 cos x1tk)) e
−x0tk
sin(x1tk)
F3 =
∂D
∂x3
= −2
K
X−1
k=0
(vk − e
−x0tk
(x2 sin x1tk + x3 cos x1tk)) e
−x0tk cos(x1tk)
To minimize D, we want the components of F to be zero. So we want to apply Newton’s method to
F (and not to D!). Thus, we will also need the derivatives of F. The function D is a scalar function of a
vector. Its gradient, F = ∇D, is a vector function. The gradient of F is the Jacobian matrix, and is actually
the second derivative of D. In the least squares context, J is called the “Hessian” matrix of D, but for our
Newton application, we think of J as the Jacobian of F.
11 Exercise 6
1. Download the file objective.py which defines a function objectiveF() and jacobian objectiveJ() for
the least squares problem.
6
2. For this exercise, set x to the vector that actually minimizes the objective function:
x = np . a r r a y ( [ 0. 1 5 , 2 . 0 , 1 . 0 , 3 . 0 ] )
3. At the minimizer, F(x) should be zero. Verify this by calling objectiveF(x).
4. Compute the Jacobian by calling objectiveJ(x).
5. Compute the determinant of J(x) to see that it is nonsingular there:
v al u e = np . l i n a l g . de t ( J )
6. Since the matrix J is the second derivative of the underlying scalar function D, it must be positive
definite and symmetric. Check that J(x) is symmetric or very nearly so, using a command like
e r r = np . l i n a l g . norm ( J − np . t r a n s p o s e ( J ) )
7. Check that J is positive definite by computing its eigenvalues, which should all be positive real values,
using the command
val , vec = np . l i n a l g . e i g ( J )
which returns the eigenvalues (a vector) and eigenvectors (in a matrix).
12 Exercise 7
In this exercise, you will see that Newton’s method applied to this system can require the convergence
neighborhood to be quite small.
The point of this exercise is to see how sensitive Newton’s method can be when the initial guess is
changed. Fill in the following table with either the number of iterations required or the word “failed,” using
vnewton1() and the indicated initial guess. Note that the first line is the correct solution. For this exercise,
restrict the number of iterations to be no more than 100.
Initial guess Number of iterations
[0.15, 2.0, 1.0, 3] ______________
[0.15, 2.0, 0.9, 3] ______________
[0.15, 2.0, 0.0, 3] ______________
[0.15, 2.0,-0.1, 3] ______________
[0.15, 2.0,-0.3, 3] ______________
[0.15, 2.0,-0.5, 3] ______________
[0.15, 2.0, 1.0, 4] ______________
[0.15, 2.0, 1.0, 5] ______________
[0.15, 2.0, 1.0, 6] ______________
[0.15, 2.0, 1.0, 7] ______________
[0.15, 1.99, 1.0, 3] ______________
[0.15, 1.97, 1.0, 3] ______________
[0.15, 1.95, 1.0, 3] ______________
[0.15, 1.93, 1.0, 3] ______________
[0.15, 1.91, 1.0, 3] ______________
[0.17, 2.0, 1.0, 3] ______________
[0.19, 2.0, 1.0, 3] ______________
[0.20, 2.0, 1.0, 3] ______________
7
You can see from the previous exercise that Newton can require a precise guess before it will converge.
Sometimes some iterate is not far from the ball of convergence, but the Newton step is so large that the next
iterate is ridiculous. In cases where the Newton step is too large, reducing the size of the step might make
it possible to get inside the ball of convergence, even with initial guesses far from the exact solution. This is
the strategy examined in the following section.
13 Damping
The exercise in the previous section suggests that Newton gets in trouble when its increment is too large.
One way to mitigate this problem is to “dampen” the iteration by putting a fractional factor on the iterate.
x
(n+1) = x
(k) − αJ(x
(k)
)
−1F(x
(k)
) (5)
where α is a number smaller than one. It should be clear from the convergence proofs you have seen for
Newton’s method that introducing the damping factor α destroys the quadratic convergence of the method.
This raises the question of stopping. In the current version of vnewton1(), you stop when norm(increment)
gets small enough, but if increment has been multiplied by alpha, then convergence could happen immediately if alpha is very small. It is important to make sure norm(increment) is not multiplied by alpha
before the test is done.
14 Exercise 8
In this exercise, we experiment with damping.
1. Starting from your vnewton1.py file, copy it to a new file named vnewton3.py, change its signature to
def vnewton3 ( func , d func , x0 , maxIts ) :
”””x , numIts = vnewton3 ( func , d func , x0 , maxI ts )
. . . comments
”””
return x , numIts
and change it to conform with Equation (5) with the fixed value α = 1/2. Don’t forget to change the
comments and the convergence criterion.
2. Apply vnewton3() to the objectiveF function. First solve the problem for the exact solution [ 0.15,
2.0, 1.0, 3.0 ]. Then increase the first component of x0 by 0.01 and solve again. Keep increasing x0
by 0.01 and solving, until the iteration diverges. What is the largest value of x0 for which vnewton3()
still converges? Your code might look something like this:
x0 = np . a r r a y ( [ 0. 1 5 , 2 . 0 , 1 . 0 , 3. 0 ] )
while ( True ) :
try :
x , numits = vnewton3 ( o b j e c ti v eF , o b j e c ti v e J , x0 )
print ( ” vnewton3 : x0 =” , x0 , ” numits =” , numits )
x0 [ 0 ] = x0 [ 0 ] + 0. 0 1
except Excep ti on :
print ( ” vnewton3 : x0 =” , x0 , ” ( Did not c on v e r ge ! ) ” )
break
Damping by a constant factor can improve the initial behavior of the iterates, but it destroys the quadratic
convergence of the method. Further, it is hard to guess what the damping factor should be. There are tricks
to dampen the iteration in such a way that when it starts to converge, the damping goes away (α → 1).
8
One such trick is to compute
∆x = −J(x
(k)
)
−1
f(x
(k)
)
α =
1
1 + βk∆xk
(6)
x
(k+1) = x
(k) + α∆x
where the value β = 10 is a conveniently chosen constant. You should be able to see how you might prove
that this damping strategy does not destroy the quadratic convergence rate, or, at least, allows a superlinear
rate.
Note that the expression in (6) is designed to keep the largest step below one tenth of the Newton step.
This is a very conservative strategy. Note also that another quantity could be placed in the denominator,
such as kfk, so long as it becomes zero at the solution.
15 Exercise 9
1. Make a copy of your vnewton3.py file as the new file vnewton4.py, and change it so that α is not the
constant 1/2, but is determined from Equation (6). Don’t forget to change the comments.
2. Apply vnewton4() to the objectiveF function. for the initial guess x0 set to [ 0.20, 2.0, 1.0,
3.0 ]. You should see that vnewton4() has a slightly larger ball of convergence than vnewton3(),
and converges much faster.
3. Using vnewton4(), repeatedly increase the first component of the starting point x0 by increments of
0.01, until the iteration diverges. What is the largest such value for which vnewton4() is still able to
solve the problem?
Another strategy is to choose α so that the objective function almost always decreases on each iteration.
This strategy can be useful when the the previous approach is too slow. One way to implement this strategy
is to add an additional loop inside the Newton iteration loop. Begin with a full Newton step, but check that
this step reduces the objective function. If it does not, halve the step size and try again. Keep halving the
step size until either the objective function is reduced or some fixed maximum number of halvings (10, for
example) have been tried. This can be written as an algorithm:
1. On Newton iteration k + 1, start with α = 1.
2. Compute a trial update:

(`) = x
(k) − αJ(x
(k)
)
−1
f(x
(k)
)
3. If |f(x˜
(`)
)| ≤ |f(x
(k)
)| or if α < 1/1024, then set x
(k+1) = x˜
(`) and continue with the next Newton
iteration,
otherwise replace α with α/2 and return to Step 2.
The limit α < 1/1024 represents the (arbitrary) choice of a maximum of 10 halvings.
16 Exercise 10
Here is the outline of a revised Newton code that we will need for the next exercise.
def vnewton5 ( func , d func , x0 , maxIts ) :
”””x , numIts = vnewton5 ( func , d func , x0 , maxI ts )
. . . comments
”””
import numpy a s np
9
EPSILON = 5. 0 e−05
x = x0 . copy ( )
fo r numIts in range ( 1 , maxIts + 1 ) :
f = func ( x )
fnrm = np . l i n a l g . norm ( f ) # Need t h i s now f o r compar ison
J = d func ( x )
dx = − np . l i n a l g . s o l v e ( J , f )
alph a = 1. 0 # i n i t i a l i z e al p h a
while ( True ) : # Loop s e a r c h i n g f o r good al p h a
x2 = ? ? ?
f 2 = ? ? ?
f2nrm = ? ? ?
i f ( f2nrm < fnrm ) :
x = np . copy ( x2 ) # x = x2 doesn ’ t work f o r py thon v e c t o r s !
break # s u c c e s s !
alph a = alph a / 2. 0 # maybe t r y sm a l l e r al p h a ?
i f ( alph a <= 1. 0 / 1 0 2 4. 0 ) :
ra is e Excep ti on ( ” vnewton5 : damping f a i l e d . ” )
e r r = np . l i n a l g . norm ( dx )
i f ( e r r <= EPSILON ) :
return x , numIts
ra is e Excep ti on ( ” vnewton5 : i t e r a t i o n did not c on ve r ge . ” )
Of course, it is necessary for you to replace the ”???” text by the appropriate formulas.
1. Using vnewton5(), to the nearest 0.01, how large can the first component of the initial guess get before
the iteration diverges? (Leave the other three values at their correct values.)
Warning: You may find this strategy is not better than the previous one!
17 Continuation or homotopy methods
As can be seen in the previous few exercises, there are ways to improve the radius of convergence of Newton’s
method. For some problems, such as the curve-fitting problem above, they just don’t help enough. There
is a class of methods called continuation or homotopy methods that can be used to find good initial guesses
for Newton’s method.
In the previous section, we were concerned with finding the value x which minimizes a scalar objective
D1(x). Suppose there is another, much simpler, objective D2(x), whose minimizer z is easy to find using
Newton’s method. One possible choice would be D2(x) = kx − zk
2
, where z might be arbitrary, or better,
chosen as any approximate guess for the minimizer of D1(x) . For 0 ≤ p ≤ 1, consider the new objective
function
G(x, p) = pD1(x) + (1 − p)D2(x). (7)
When p = 0, the function G reduces to D2 and the corresponding vector equation F2(x) = ∂D2
∂x is easy
for Newton’s method to solve with any initial guess. (Naturally, our starting guess here will be z!). When
p = 1, G is equal to D1, and we are back to solving F(x) = ∂D1
∂x . The only new thing is that our starting
guess for this iteration is likely to be much better than z, or any other guess we might make in advance.
That’s because we plan to solve a sequence of problems, turning up the value of p gradually, so that Newton
starts on the easy problem, and works its way towards the hard problem, each time using the solution of the
previous step as its starting point.
10
18 Exercise 11
1. We suppose that z is a fixed vector of size 4, which is a rough approximate minimizer of D1(x). Define
D2(x) = X
4
k=1
(xk − zk)
2
.
Its gradient is
F2k =
∂D2
∂xk
and the Jacobian matrix is given by
J2k,` =
∂F2
∂x`
The following code, easy objective.py, computes these quantities: similar to objective.py.
def e a s y o b j e c ti v e D ( x , z ) :
import numpy a s np
D2 = np .sum ( ( x − z ) ∗∗2 )
return D2
def e a s y o b j e c t i v e F ( x , z ) :
import numpy a s np
n = len ( x )
F2 = np . z e r o s ( n )
F2 = ? ? ?
return F2
def e a s y o b j e c t i v e J ( x , z ) :
import numpy a s np
n = len ( x )
J2 = np . z e r o s ( ( n , n ) )
fo r k in range ( 0 , n ) :
J2 [ k , k ] = 2. 0
return J2
Make a copy of this file, and fill in the missing calculations for F2.
The chosen value for z is problem-related and amounts to a vague approximation to the final solution.
2. Copy the following text to a file named homotopy.py, and fill in the missing details indicated by
question marks:
def homotopyD ( x , p , z ) :
from e a s y o b j e c t i v e import e a s y o b j e c ti v e D
from o b j e c t i v e import o b j e c ti v eD
D1 = o b j e c ti v eD ( x )
D2 = e a s y o b j e c ti v e D ( x , z )
D = p ∗ D1 + ( 1. 0 − p ) ∗ D2
return D
def homotopyF ( x , p , z ) :
from e a s y o b j e c t i v e import e a s y o b j e c t i v e F
from o b j e c t i v e import o b j e c ti v e F
F1 = ?
F2 = ?
F = ?
return F
def homotopyJ ( x , p , z ) :
?
return J
11
3. Create the following code named homotopy run.py.
def homotopy run ( z )
from homotopy import homotopyF , homotopyJ
from vnewton1 import vnewton1
import numpy a s np
x0 = z
STEPS = 1000
MAX ITERS = 100
p = 0. 0
print ( ” p n x [ 0 ] x [ 1 ] x [ 2 ] x [ 3 ] ” )
fo r k in range ( 0 , STEPS + 1 ) :
p = k / STEPS
x , n = vnewton1 ( lambda X: homotopyF ( X, p , z ) , \
lambda X: homotopyJ ( X, p , z ) , x0 , MAX ITERS )
i f ( k == STEPS or ( k % 50 ) == 0 ) :
print ( p , n , x )
x0 = np . copy ( x ) # Here i s our s t a r t i n g p o i n t f o r nex t Newton i t e r a t i o n .
4. Explain why the expression
lambda X: homotopyF ( X, p , z )
is necessary for this problem, in order to successfully call vnewton1(). You can look up the term
python lambda for information. Why must this construct be used instead of simply using homotopyF?
5. Can you start from z=[0.24, 2, 1, 3] and reach the solution at p=1? Do you get the same solution
as in Exercises 5, 6, 8 and 9?
6. Can you start from z=[0,2,1,3] and reach the solution?
7. Can you start from z=[-0.5,2,1,3] and reach the solution?
8. Start from z=[.25,2,1,3] and solve the problem. Repeatedly increase the first component of z by
0.05 and solve the problem. At what value of the first component of z does this process fail? You
could automate this experiment as follows:
z = np . a r r a y ( [ 0. 2 5 , 2 . 0 , 1 . 0 , 3. 0 ] )
try :
while ( True ) :
homotopy run ( z )
z [ 0 ] = z [ 0 ] + 0. 0 5
except :
print ( ” homotopy run f a i l e d f o r z [ 0 ] = ” , z [ 0 ] )
12