Python:Gauss-Newton方法仅适用于第一次迭代

时间:2017-04-21 02:44:03

标签: python numpy scipy numerical-methods

我试图使用Gauss-Newton方法在Python中找到 n 圆的近交点。这里的目标是给定点(x1,y1),(x2,y2),...,(xn,yn)和半径 R1,R2,...,Rn < / em>,Gauss-Newton方法用于找到与 n 圆的平方距离之和最小的点。

这是一种迭代方法,我们从初始向量 v0 = [0,0] 开始。第一次迭代完全正确,但后续迭代不正确。我在代码中找不到错误:

solutions = []
rmse = []

vk = [[0], [0]] # initial is set here
x = [0, 1, 0]
y = [1, 1, -1]
radii = [1, 1, 1]

iterations = 3

base_str_x = "(x _xi) / sqrt((x xi)^2 + (y yi)^2)"
base_str_y = "(y _yi) / sqrt((x xi)^2 + (y yi)^2)"
base_str_rk = "sqrt((x xi)^2 + (y yi)^2) Ri K"


it = 0
while it < iterations:
    i = 0
    A = []
    while i < len(x):
        A.append(["", ""])
        A0_str = base_str_x.replace(" xi", "%+f" % (x[i]))
        A0_str = A0_str.replace(" yi", "%+f" % (y[i]))
        A0_str = A0_str.replace("_xi", "%+f" % (x[i] * -1))
        A[i][0] = float(f(vk[0][0], A0_str, vk[1][0]))
        A1_str = base_str_y.replace(" xi", "%+f" % (x[i]))
        A1_str = A1_str.replace(" yi", "%+f" % (y[i]))
        A1_str = A1_str.replace("_yi", "%+f" % (y[i] * -1))
        A[i][1] = float(f(vk[0][0], A1_str, vk[1][0]))
        i += 1

    i = 0
    rk = []
    while i < len(x):
        rk.append([""])
        r0_str = base_str_rk.replace(" xi", "%+f" % (x[i]))
        r0_str = r0_str.replace(" yi", "%+f" % (y[i]))
        r0_str = r0_str.replace("Ri", "%+f" % (radii[i] * -1))
        rk[i][0] = float(f(vk[0][0], r0_str, vk[1][0]))
        i += 1

    lhs = np.matmul(map(list, zip(*A)), A)
    rhs = -np.matmul(map(list, zip(*A)), rk)
    vk = np.matmul(np.linalg.inv(lhs), rhs)
    solutions.append(vk)

此代码计算 A = Dr(x,y),其定义为:

enter image description here

然后它解决了等式:

enter image description here

代表vk

函数f是一个&#34;通用函数&#34;用于计算A的每个元素。任何帮助找到为什么后面的迭代不正确的原因将不胜感激。

1 个答案:

答案 0 :(得分:0)

发生这种情况有两个原因:

  1. 括号内的符号是错误的。为了解决这个问题,请在每个字词内将x[1]乘以-1。例如A0_str = A0_str.replace(" yi", "%+f" % (y[i] * -1))
  2. 错误传播。结果矩阵给出的结果精确到小于后续迭代中转换为float的小数位数。
  3. 虽然第一个问题可以轻松解决,但第二个问题却不能解决。 Decimal不支持使用matmul并提供TypeError。未显示float64float128数据类型会增加精度。