0

I have defined the function newton to be the implementation of the Newton method to find roots of real-valued and vector-valued functions.

The problem is that, the sequence created is being included into an extra [] at every step.

Why is this happening and how can I avoid it by making changes on the newton function definition?

This is my output sequence:

x_1 = [[4.66097544]]
x_2 = [[[2.76124695]]]
x_3 = [[[[3.14624513]]]]
x_4 = [[[[[3.14159265]]]]]

This is my code:

from math import exp
import numpy as np
from numpy import array
from numpy.linalg import norm
from numpy import sin,cos,pi

def newton (F, DF, x0, eps, K):
    x = x0 - np.linalg.inv(DF(x0))*F(x0)
    k=1
    print("x_", end="")
    print(k, end="")
    print(" = ", end="")
    print(x)
    print("( ||F(x)|| = ", end="")
    print(norm(F(x)), end=" )\n")
    while (norm(F(x)) > eps) and (k<=K):
        x = x - np.linalg.inv(DF(x))*F(x)
        k += 1
        print("x_", end="")
        print(k, end="")
        print(" = ", end="")
        print(x)
        print("( ||F(x)|| = ", end="")
        print(norm(F(x)), end=" )\n")
    return x,k

F = lambda y: cos(y/2)
DF = lambda y: array([-sin(y/2)/2])
x,k = newton(F, DF, array([1.]), 1e-8, 100)

Any help or comments are highly appreciated. Thanks!

  • This would have to be a result of calling `norm(F(x))` or `np.linalg.inv(DF(x))*F(x)`. Feed each some sample data, see which is causing the extra nesting (adding another dimension to the data), then read the docs and see why it's doing that (or read the docs for each function first). – Carcigenicate Feb 03 '21 at 14:34
  • `x = x - (np.linalg.inv(DF(x))*F(x)).reshape((1,1))` – Epsi95 Feb 03 '21 at 14:38
  • You can use `f-string` to print output in a more readable manner instead of series of `print` statements – Epsi95 Feb 03 '21 at 14:39
  • Wouldn't that make my implementation useless for a vector valued function F? @Epsi95 – Jena Rayner Feb 03 '21 at 14:43

1 Answers1

0

The problem is that DF function, that always return the argument into a array. So you are passing arrays and it will return that array inside another array. If i understood your code, you can drop that array for the DF function and the linalg.inv call, and just manipulate your lambda functions to accept arguments from a array:

See if this do what you want:

from math import exp
import numpy as np
from numpy import array
from numpy.linalg import norm
from numpy import sin,cos,pi

def newton (F, DF, x0, eps, K):
    x = x0 - F(x0)/DF(x0)
    k=1
    print("x_", end="")
    print(k, end="")
    print(" = ", end="")
    print(x)
    print("( ||F(x)|| = ", end="")
    print(norm(F(x)), end=" )\n")
    while (norm(F(x)) > eps) and (k<=K):
        x = x - DF(x)*F(x)
        k += 1
        print("x_", end="")
        print(k, end="")
        print(" = ", end="")
        print(x)
        print("( ||F(x)|| = ", end="")
        print(norm(F(x)), end=" )\n")
    return x,k

F = lambda y: cos(y[0]/2)
DF = lambda y: -sin(y[0]/2)/2 
x,k = newton(F, DF, array([1]), 1e-8, 100)
Filipe
  • 169
  • 5
  • Traceback (most recent call last): File "q2.py", line 35, in x,k = newton(F, DF, array([1.]), 1e-8, 100) File "q2.py", line 8, in newton x = x0 - np.linalg.inv(DF(x0))*F(x0) File "<__array_function__ internals>", line 5, in inv File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/numpy/linalg/linalg.py", line 540, in inv _assert_stacked_2d(a) – Jena Rayner Feb 03 '21 at 15:22
  • File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/numpy/linalg/linalg.py", line 197, in _assert_stacked_2d raise LinAlgError('%d-dimensional array given. Array must be ' numpy.linalg.LinAlgError: 1-dimensional array given. Array must be at least two-dimensional – Jena Rayner Feb 03 '21 at 15:22
  • For some reason the DF argument has to be an array. I am supposed to do the newton implementation while the x,k = newton(...) is the part given to me to test my implementation. – Jena Rayner Feb 03 '21 at 15:23
  • In my sugestion i removed that np.linalg.inv also. – Filipe Feb 03 '21 at 15:41
  • And i think it should be F/DF and not F*DF? – Filipe Feb 03 '21 at 15:54