【问题标题】:While loop adding extra [] on every stepWhile 循环在每一步添加额外的 []
【发布时间】:2021-02-03 14:30:42
【问题描述】:

我已将函数 newton 定义为实现 Newton 方法以求实值函数和向量值函数的根。

问题在于,创建的序列在每一步都包含在一个额外的 [] 中。

为什么会发生这种情况,如何通过更改牛顿函数定义来避免这种情况?

这是我的输出序列:

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

这是我的代码:

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)

非常感谢任何帮助或 cmets。谢谢!

【问题讨论】:

  • 这必须是调用norm(F(x))np.linalg.inv(DF(x))*F(x) 的结果。给每个样本数据提供一些样本数据,看看哪个导致了额外的嵌套(向数据添加另一个维度),然后阅读文档并了解它为什么这样做(或先阅读每个函数的文档)。
  • x = x - (np.linalg.inv(DF(x))*F(x)).reshape((1,1))
  • 您可以使用f-string 以更易读的方式打印输出,而不是使用一系列print 语句
  • 这不会使我的实现对向量值函数 F 无用吗? @Epsi95

标签: python numeric newtons-method


【解决方案1】:

问题在于 DF 函数,它总是将参数返回到数组中。因此,您正在传递数组,它将在另一个数组中返回该数组。如果我理解您的代码,您可以删除该数组以用于 DF 函数和 linalg.inv 调用,然后操作您的 lambda 函数以接受来自数组的参数:

看看这是否符合你的要求:

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)

【讨论】:

  • 回溯(最近一次调用最后):文件“q2.py”,第 35 行,在 x,k = newton(F, DF, array([1.]), 1e- 8, 100) 文件“q2.py”,第 8 行,单位为牛顿 x = x0 - np.linalg.inv(DF(x0))*F(x0) 文件“<__array_function__ internals>”,第 5 行,inv 文件“/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/numpy/linalg/linalg.py”,第 540 行,inv _assert_stacked_2d(a)
  • 文件 "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/numpy/linalg/linalg.py",第 197 行,在 _assert_stacked_2d 中引发 LinAlgError( '%d 维数组给定。数组必须是 'numpy.linalg.LinAlgError: 1 维数组给定。数组必须至少是二维的
  • 由于某种原因,DF 参数必须是一个数组。我应该执行 newton 实现,而 x,k = newton(...) 是给我的部分,用于测试我的实现。
  • 在我的建议中,我也删除了 np.linalg.inv。
  • 我认为应该是 F/DF 而不是 F*DF?
猜你喜欢
  • 2017-08-08
  • 2020-11-03
  • 1970-01-01
  • 1970-01-01
  • 2016-10-09
  • 2016-08-06
  • 1970-01-01
  • 1970-01-01
  • 2017-11-26
相关资源
最近更新 更多