0

我正在尝试出于三边测量的目的执行非线性最小二乘拟合 LMFIT:

  • LMFIT
  • 信标包括信标位置 x,y,z
  • Parameters()包括Xinit要估计的位置。
  • tag_distances[i]包括测量值(从标签到 的距离beacon[i]

我收到此错误:

raise TypeError('Improper input: N=%s must not超过 M=%s' % (n, m)) TypeError: Improper input: N=3 must not超过 M=1

import numpy as np
from math import pow
from lmfit import minimize, Parameters

beacons=np.array([[0.,0.,5.],
              [0.,15.,5.],
              [15.,0.,5.],
              [15.,15.,5.]])

tag=np.array([0,15,0])  
tag_distances=np.arange(float(beacons.shape[0]))

xinit=np.array([5.,5.,2.])

def distance (p1, p2):
    s=0
    for i in range (0,3):
    s+=(p1[i]-p2[i])**2
    return s**.5

for i in range (0,beacons.shape[0]): 
  tag_distances[i]=distance(beacons[i,:],tag)
tag_distances= tag_distances.reshape(beacons.shape[0], 1)

def residual(params, measures , beacons, eps_data):
    x=np.array([ params['x'].value,
               params['y'].value,
               params['z'].value])
    s=0
    for i in range (0,beacons.shape[0]): 
       s+=(measures[i,0]-distance(beacons[i,:],x))**2
 return s 

params = Parameters()
params.add('x', value=xinit[0])
params.add('y', value=xinit[1])
params.add('z', value=xinit[2])

eps_data=np.array([1.0,1.0,1.0,1.0])

out = minimize(residual, params, args=(tag_distances, beacons, eps_data))
4

1 回答 1

1

m使用任何最小二乘算法(线性或非线性)将函数拟合到数据时,曲线上的数据点 ( ) 至少需要与模型中的参数 ( n) 一样多。如果你的参数多于点,你的算法将不会收敛到一个单一的解决方案(实际上会有无数个同样好的解决方案)。

该错误TypeError('Improper input: N=%s must not exceed M=%s' % (n, m))是由 scipy 引发的,因为您的代码当前已实现,它n的大小大于m.

lmfitminimize要求您的函数residual返回一个值数组,到目前为止,它只返回一个浮点数。您可以residual在以下内容中进行编辑,以便它返回残差数组:

def residual(params, measures , beacons, eps_data):
    x=np.array([ params['x'].value,
                 params['y'].value,
                 params['z'].value])
    s= np.empty(beacons.shape[0])   # Make s an np.array beforehand
    for i in range (0,beacons.shape[0]): 
        s[i] =(measures[i,0]-distance(beacons[i,:],x))**2 # Store each residual
    return s 

out = minimize(residual, params, args=(tag_distances, beacons, eps_data))
# Print results
print out.params['x'].value
print out.params['y'].value
print out.params['z'].value

现在您的脚本将起作用,因为它将返回参数 x,y,z 以最小化从residual.

但是,对于您拥有的残差函数,最小化此残差函数的参数 x,y,z 将始终等于tag。因此,这不是一个非常有用的最小化过程。我想你打算写一个不同的残差函数,它实际上取决于eps_data.

于 2016-11-11T02:42:23.607 回答