使用numpy和lstsq来解决3维系统

时间:2017-06-10 20:40:15

标签: python numpy

我正在尝试将 x,y,z 真实世界坐标转换为我自己的 x,y,z 虚拟世界坐标。由于在获得真实世界坐标时存在噪音,我需要使用最小二乘法。我有3个变量作为输入: r_x,r_y,r_z ,我需要输出3个变量 v_x,v_y,v_z 。我知道我需要的只是一个矩阵 A 所以 [r_x,r_y,r_z] A = [v_x,v_y,v_z]

这是我的代码:

>>> import numpy as np
>>> x = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> y = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> A = np.vstack([x, np.ones(len(x))]).T
>>> c, resid, rank,  sigma =np.linalg.lstsq(A,y)
>>> c,m = c[0:3], c[-1]
>>> x1 = np.array([1,2,3])
>>> np.dot(x1,c) + m
array([ 1.94736842,  2.31578947,  2.68421053])

可以看出,答案是错误的,因为初始系统有一个独特的解决方案,最小二乘结果是一个非常糟糕的近似值。有谁知道我做错了什么?

1 个答案:

答案 0 :(得分:1)

主要问题是输入数据的排名不足以准确反转您的A矩阵。请考虑以下事项:

测试代码:

import numpy as np

def build_a(x_data):
    return np.column_stack((x_data, np.ones(len(x_data))))

def lstsq(x_data, y_data):
    return np.linalg.lstsq(build_a(x_data), y_data)

def show_rank(x_data):
    print(lstsq(x_data, x_data)[2])

show_rank([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
show_rank([[1, 2, 3], [4, 6, 6], [7, 8, 9]])
show_rank([[1, 2, 3], [4, 6, 6], [7, 7, 9]])
show_rank([[1, 2, 3], [4, 6, 6], [7, 7, 9], [7, 8, 10]])
show_rank(np.random.rand(10, 3))

矩阵排名:

2
3
3
4
4

这个问题是[1,2,3]和[4,5,6]在同一个向量上,并且不再提供信息,因此通过稍微混合对,可以增加等级。但是我们需要等级4因为我们也得到了偏移量,所以我们需要至少4个样本才能获得秩4矩阵。

实施例

x = np.array([[1, 2, 3], [4, 5, 16], [17, 8, 9], [7, 8, 19]])
C, resid, rank, sigma = lstsq(x, x + 1)

c, m = C[0:3], C[-1]
x1 = np.array([1, 2, 4])
print(np.dot(x1, c) + m)
print(rank)

结果:

[ 2.  3.  5.]
4