Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Newton';在Python中求解非线性方程组;s法_Python_Numerical Methods_Equation Solving_Newtons Method - Fatal编程技术网

使用Newton';在Python中求解非线性方程组;s法

使用Newton';在Python中求解非线性方程组;s法,python,numerical-methods,equation-solving,newtons-method,Python,Numerical Methods,Equation Solving,Newtons Method,我正在努力为大学解决这个问题。我已经提交了下面的代码。然而,我并不完全满意 任务是建立牛顿方法的实现,以解决以下非线性方程组: 为了学习牛顿法,除了上课,我还观看了以下YouTube视频: 视频中的那个家伙解释了牛顿方法背后的数学过程,并手动进行了两次迭代 我为此做了一个Python实现,视频中的示例代码运行良好。尽管如此,视频中的例子涉及2个变量,我的家庭作业涉及3个变量。因此,我修改了它 这就是代码: import numpy as np #### example from youtub

我正在努力为大学解决这个问题。我已经提交了下面的代码。然而,我并不完全满意

任务是建立牛顿方法的实现,以解决以下非线性方程组:

为了学习牛顿法,除了上课,我还观看了以下YouTube视频:

视频中的那个家伙解释了牛顿方法背后的数学过程,并手动进行了两次迭代

我为此做了一个Python实现,视频中的示例代码运行良好。尽管如此,视频中的例子涉及2个变量,我的家庭作业涉及3个变量。因此,我修改了它

这就是代码:

import numpy as np

#### example from youtube https://www.youtube.com/watch?v=zPDp_ewoyhM

def jacobian_example(x,y):

    return [[1,2],[2*x,8*y]]

def function_example(x,y):

    return [(-1)*(x+(2*y)-2),(-1)*((x**2)+(4*(y**2))-4)]
####################################################################


### agora com os dados do exercício

def jacobian_exercise(x,y,z):

    return [[1,1,1],[2*x,2*y,2*z],[np.exp(x),x,-x]]

#print (jacobian_exercise(1,2,3))
jotinha  = (jacobian_exercise(1,2,3))

def function_exercise(x,y,z):

    return [x+y+z-3, (x**2)+(y**2)+(z**2)-5,(np.exp(x))+(x*y)-(x*z)-1]

#print (function_exercise(1,2,3))
bezao = (function_exercise(1,2,3))

def x_delta_by_gauss(J,b):

    return np.linalg.solve(J,b)

print (x_delta_by_gauss(jotinha, bezao))
x_delta_test = x_delta_by_gauss(jotinha,bezao)

def x_plus_1(x_delta,x_previous):

    x_next = x_previous + x_delta

    return x_next

print (x_plus_1(x_delta_test,[1,2,3]))

def newton_method(x_init):

    first = x_init[0]

    second = x_init[1]

    third = x_init[2]

    jacobian = jacobian_exercise(first, second, third)

    vector_b_f_output = function_exercise(first, second, third)

    x_delta = x_delta_by_gauss(jacobian, vector_b_f_output)

    x_plus_1 = x_delta + x_init

    return x_plus_1

def iterative_newton(x_init):

    counter = 0

    x_old = x_init
    print ("x_old", x_old)

    x_new = newton_method(x_old)
    print ("x_new", x_new)

    diff = np.linalg.norm(x_old-x_new)
    print (diff)

    while diff>0.000000000000000000000000000000000001:

        counter += 1

        print ("x_old", x_old)
        x_new = newton_method(x_old)
        print ("x_new", x_new)

        diff = np.linalg.norm(x_old-x_new)
        print (diff)

        x_old = x_new

    convergent_val = x_new
    print (counter)

    return convergent_val

#print (iterative_newton([1,2]))
print (iterative_newton([0,1,2]))
我很确定这段代码绝对不是完全错误。 如果将初始值作为向量[0,1,2]输入,则代码将作为输出[0,1,2]返回。这是一个正确的答案,它解决了上述三个方程

此外,如果输入[0,2,1]与输入稍有不同,代码也会工作,并且返回的答案也是正确的

但是,如果我将初始值改为[1,2,3]之类的值,我会得到一个奇怪的结果:527.7482,-1.63和2.14

这个结果毫无意义。看看第一个方程,如果你输入这些值,你可以很容易地看到(527)+(-1.63)+(2.14)不等于3。这是错误的

如果我将输入值更改为接近正确的解决方案,如[0.1,1.1,2.1],它也会崩溃

好的,牛顿方法不能保证正确的收敛性。我知道。这取决于初始值以及其他因素

我的实现在任何方面都是错误的吗?或者向量[1,2,3]只是一个“坏”的初始值


谢谢。

为了使代码更具可读性,我建议减少函数定义的数量。它们掩盖了正在进行的相对简单的计算

我重写了自己的版本:

def iter_newton(X,function,jacobian,imax = 1e6,tol = 1e-5):
    for i in range(int(imax)):
        J = jacobian(X) # calculate jacobian J = df(X)/dY(X) 
        Y = function(X) # calculate function Y = f(X)
        dX = np.linalg.solve(J,Y) # solve for increment from JdX = Y 
        X -= dX # step X by dX 
        if np.linalg.norm(dX)<tol: # break if converged
            print('converged.')
            break
    return X
甚至对更糟糕的猜测也有效

>>>X_0 = np.array([13.4,-2,31],dtype=float)
>>>iter_newton(X_0,function_exercise,jacobian_exercise)
converged.
array([1.59654153e-18, 2.00000000e+00, 1.00000000e+00])

我试着用一种更通俗的方式重写你的代码。我希望有帮助。可能错误是高斯(雅可比矩阵,向量输出)中的
向量输出的符号?或者雅可比矩阵中缺少的项

import numpy as np

# Example from the video:
# from youtube https://www.youtube.com/watch?v=zPDp_ewoyhM
def jacobian_example(xy):
    x, y = xy
    return [[1, 2],
            [2*x, 8*y]]

def function_example(xy):
    x, y = xy
    return [x + 2*y - 2, x**2 + 4*y**2 - 4]

# From the exercise:
def function_exercise(xyz):
    x, y, z = xyz
    return [x + y + z - 3,
            x**2 + y**2 + z**2 - 5,
            np.exp(x) + x*y - x*z - 1]

def jacobian_exercise(xyz):
    x, y, z = xyz
    return [[1, 1, 1],
            [2*x, 2*y, 2*z],
            [np.exp(x) + y - z, x, -x]]



def iterative_newton(fun, x_init, jacobian):
    max_iter = 50
    epsilon = 1e-8

    x_last = x_init

    for k in range(max_iter):
        # Solve J(xn)*( xn+1 - xn ) = -F(xn):
        J = np.array(jacobian(x_last))
        F = np.array(fun(x_last))

        diff = np.linalg.solve( J, -F )
        x_last = x_last + diff

        # Stop condition:
        if np.linalg.norm(diff) < epsilon:
            print('convergence!, nre iter:', k )
            break

    else: # only if the for loop end 'naturally'
        print('not converged')

    return x_last

# For the exercice:
x_sol = iterative_newton(function_exercise, [2.0,1.0,2.0], jacobian_exercise)
print('solution exercice:', x_sol )
print('F(sol)', function_exercise(x_sol) )

# For the example:
x_sol = iterative_newton(function_example, [1.0,2.0], jacobian_example)
print('solution example:', x_sol )
print( function_example(x_sol) )

回答这个问题的人帮了我。然而,修改一行代码使我的实现中的一切工作正常

因为我使用的是我提到的YouTube视频中描述的方法,所以我需要将向量值函数乘以(-1),这会修改向量中每个元素的值

我这样做是为了
函数\u示例
。然而,当我编写
函数\u练习时,
,我需要在没有负号的情况下为我的家庭作业解决的问题。我错过了

现在,它是固定的,并且可以完全工作,即使有非常不同的起始向量

import numpy as np

#### example from youtube https://www.youtube.com/watch?v=zPDp_ewoyhM

def jacobian_example(x,y):

    return [[1,2],[2*x,8*y]]

def function_example(x,y):

    return [(-1)*(x+(2*y)-2),(-1)*((x**2)+(4*(y**2))-4)]
####################################################################


### agora com os dados do exercício

def jacobian_exercise(x,y,z):

    return [[1,1,1],[2*x,2*y,2*z],[np.exp(x),x,-x]]

#print (jacobian_exercise(1,2,3))
jotinha  = (jacobian_exercise(1,2,3))

def function_exercise(x,y,z):

    return [(-1)*(x+y+z-3),(-1)*((x**2)+(y**2)+(z**2)-5),(-1)*((np.exp(x))+(x*y)-(x*z)-1)]

#print (function_exercise(1,2,3))
bezao = (function_exercise(1,2,3))

def x_delta_by_gauss(J,b):

    return np.linalg.solve(J,b)

print (x_delta_by_gauss(jotinha, bezao))
x_delta_test = x_delta_by_gauss(jotinha,bezao)

def x_plus_1(x_delta,x_previous):

    x_next = x_previous + x_delta

    return x_next

print (x_plus_1(x_delta_test,[1,2,3]))

def newton_method(x_init):

    first = x_init[0]

    second = x_init[1]

    third = x_init[2]

    jacobian = jacobian_exercise(first, second, third)

    vector_b_f_output = function_exercise(first, second, third)

    x_delta = x_delta_by_gauss(jacobian, vector_b_f_output)

    x_plus_1 = x_delta + x_init

    return x_plus_1

def iterative_newton(x_init):

    counter = 0

    x_old = x_init
   #print ("x_old", x_old)

    x_new = newton_method(x_old)
   #print ("x_new", x_new)

    diff = np.linalg.norm(x_old-x_new)
   #print (diff)

    while diff>0.0000000000001:

        counter += 1

       #print ("x_old", x_old)
        x_new = newton_method(x_old)
       #print ("x_new", x_new)

        diff = np.linalg.norm(x_old-x_new)
       #print (diff)

        x_old = x_new

    convergent_val = x_new
   #print (counter)

    return convergent_val

#print (iterative_newton([1,2]))
print (list(map(float,(iterative_newton([100,200,3])))))

很难检查代码,但如果您有时间玩,您可以尝试绘制由三条曲线定义的曲面,然后可以制作解点(x,y,z)在空间中移动的动画,如牛顿方法iterates@kevinkayaks谢谢我能做些什么使代码更可读吗?在函数
雅可比函数(x,y,z)
中,第三个方程对
x
的导数缺少一些项。
# Verification using fsvole from Scipy
from scipy.optimize import fsolve

x0 = [2, 2, 2]
sol = fsolve(function_exercise, x0, fprime=jacobian_exercise, full_output=1)
print('solution exercice fsolve:', sol)
import numpy as np

#### example from youtube https://www.youtube.com/watch?v=zPDp_ewoyhM

def jacobian_example(x,y):

    return [[1,2],[2*x,8*y]]

def function_example(x,y):

    return [(-1)*(x+(2*y)-2),(-1)*((x**2)+(4*(y**2))-4)]
####################################################################


### agora com os dados do exercício

def jacobian_exercise(x,y,z):

    return [[1,1,1],[2*x,2*y,2*z],[np.exp(x),x,-x]]

#print (jacobian_exercise(1,2,3))
jotinha  = (jacobian_exercise(1,2,3))

def function_exercise(x,y,z):

    return [(-1)*(x+y+z-3),(-1)*((x**2)+(y**2)+(z**2)-5),(-1)*((np.exp(x))+(x*y)-(x*z)-1)]

#print (function_exercise(1,2,3))
bezao = (function_exercise(1,2,3))

def x_delta_by_gauss(J,b):

    return np.linalg.solve(J,b)

print (x_delta_by_gauss(jotinha, bezao))
x_delta_test = x_delta_by_gauss(jotinha,bezao)

def x_plus_1(x_delta,x_previous):

    x_next = x_previous + x_delta

    return x_next

print (x_plus_1(x_delta_test,[1,2,3]))

def newton_method(x_init):

    first = x_init[0]

    second = x_init[1]

    third = x_init[2]

    jacobian = jacobian_exercise(first, second, third)

    vector_b_f_output = function_exercise(first, second, third)

    x_delta = x_delta_by_gauss(jacobian, vector_b_f_output)

    x_plus_1 = x_delta + x_init

    return x_plus_1

def iterative_newton(x_init):

    counter = 0

    x_old = x_init
   #print ("x_old", x_old)

    x_new = newton_method(x_old)
   #print ("x_new", x_new)

    diff = np.linalg.norm(x_old-x_new)
   #print (diff)

    while diff>0.0000000000001:

        counter += 1

       #print ("x_old", x_old)
        x_new = newton_method(x_old)
       #print ("x_new", x_new)

        diff = np.linalg.norm(x_old-x_new)
       #print (diff)

        x_old = x_new

    convergent_val = x_new
   #print (counter)

    return convergent_val

#print (iterative_newton([1,2]))
print (list(map(float,(iterative_newton([100,200,3])))))