Java 最小二乘意义下求解A*w=b的QR分解

Java 最小二乘意义下求解A*w=b的QR分解,java,math,least-squares,apache-commons-math,Java,Math,Least Squares,Apache Commons Math,我正试图实现QR24算法来校准法兰/工具和机器人/世界,Floris Ernst(2012) 我需要解一个方程M_I*X-Y*N_I=0,其中M_I和N_I是已知的,I从1到测量数,X和Y是未知矩阵 在论文中,他们将这个方程组合成一个线性方程组a*w=b,其中a由12*个测量行和24列组成,因此我有一个具有24个参数的线性方程组,其中我需要至少2个测量来解这个系统 为了解这个方程,我需要使用最小二乘意义上的QR分解,因为随着测量的增加,这个系统的方程比参数更多 我正在使用Apache Commo

我正试图实现QR24算法来校准法兰/工具和机器人/世界,Floris Ernst(2012)

我需要解一个方程
M_I*X-Y*N_I=0
,其中
M_I
N_I
是已知的,I从1到测量数,
X
Y
是未知矩阵

在论文中,他们将这个方程组合成一个线性方程组
a*w=b
,其中a由12*个测量行和24列组成,因此我有一个具有24个参数的线性方程组,其中我需要至少2个测量来解这个系统

为了解这个方程,我需要使用最小二乘意义上的QR分解,因为随着测量的增加,这个系统的方程比参数更多

我正在使用Apache Commons数学库中的
OLSMultipleLinearRegression
来求解方程组:

OLSMultipleLinearRegression回归=新的OLSMultipleLinearRegression();
回归。setNoIntercept(真);
newSampleData(B.toArray(),A.getData());
RealVector w=新的ArrayRealVector(regression.estimateRegressionParameters());
实向量w
现在应该包含未知矩阵X和Y的条目(没有最后一行,它总是
[0 0 1]
,因为这些矩阵是齐次变换矩阵)

我使用Denavit Hartenberg在纸上手工生成了一些测试数据,因为我目前无法访问我想要使用的机器人和跟踪系统,因为电晕

然而,我得到的结果X和Y矩阵(向量w)总是非常荒谬,与我期望的结果相差甚远。例如,当我使用没有任何平移或旋转误差的精确变换矩阵时(除了计算机的计算误差),我得到的矩阵旋转部分的值超过10^14(这显然不可能是真的),平移部分的值超过10^17,而不是预期的100左右

当我向矩阵中添加一些测量误差时(例如旋转时为+-0.01°,平移部分为+-0.01),我没有得到那些超高的值,但旋转部分的值却不可能为真

你知道为什么这些值是如此的错误吗?或者你知道如何在这个库中使用最小二乘意义上的QR分解吗

下面是我使用M_i和N_i度量创建A的每个条目/子矩阵Ai的代码:

私有RealMatrix createAi(RealMatrix m、RealMatrix n、布尔逆变){
实矩阵M=新的Array2DroArralMatrix();
如果(反转){
M=新的QR分解(M).getSolver().GetReverse();
}否则{
M=M.copy();
}
//getRot是我编写的一个方法,用于获取矩阵的旋转部分
RealMatrix RM=getRot(M);
RealMatrix N=N.copy();
//每个测量有12个方程和24个参数需要求解
实矩阵Ai=新的Array2DroArralMatrix(12,24);
实矩阵零=新的Array2DroArralMatrix(3,3);
RealMatrix Identity12=MatrixUtils.createRealIdentityMatrix(12);
//第一列
Ai.setSubMatrix(RM.scalarMultiply(N.getEntry(0,0)).getData(),0,0);
Ai.setSubMatrix(RM.scalarMultiply(N.getEntry(0,1)).getData(),3,0);
Ai.setSubMatrix(RM.scalarMultiply(N.getEntry(0,2)).getData(),6,0);
Ai.setSubMatrix(RM.scalarMultiply(N.getEntry(0,3)).getData(),9,0);
//第二列
Ai.setSubMatrix(RM.scalarMultiply(N.getEntry(1,0)).getData(),0,3);
Ai.setSubMatrix(RM.scalarMultiply(N.getEntry(1,1)).getData(),3,3);
Ai.setSubMatrix(RM.scalarMultiply(N.getEntry(1,2)).getData(),6,3);
Ai.setSubMatrix(RM.scalarMultiply(N.getEntry(1,3)).getData(),9,3);
//第三纵队
Ai.setSubMatrix(RM.scalarMultiply(N.getEntry(2,0)).getData(),0,6);
Ai.setSubMatrix(RM.scalarMultiply(N.getEntry(2,1)).getData(),3,6);
Ai.setSubMatrix(RM.scalarMultiply(N.getEntry(2,2)).getData(),6,6);
Ai.setSubMatrix(RM.scalarMultiply(N.getEntry(2,3)).getData(),9,6);
//第四栏
Ai.setSubMatrix(Zero.getData(),0,9);
Ai.setSubMatrix(Zero.getData(),3,9);
Ai.setSubMatrix(Zero.getData(),6,9);
Ai.setSubMatrix(RM.getData(),9,9);
//第五纵队
Ai.setSubMatrix(Identity12.scalarMultiply(-1d).getData(),0,12);
返回Ai;
}
下面是我使用M_i度量创建b的每个条目/子向量bi的代码:

私有RealVector createBEntry(RealMatrix m,布尔反转){
实矩阵bi=新的Array2DroArralMatrix(1,12);
RealMatrix negative_M=新的ARRAY2DROREALMATRIX();
//getTrans是我编写的一种方法,用于获取矩阵的平移部分
如果(反转){
负μM=getTrans(新的QR分解(M).getSolver().getInverse()).scalarMultiply(-1d);
}否则{
负μM=getTrans(M).scalarMultiply(-1d);
}       
bi.setSubMatrix(负的_M.getData(),0,9);
返回bi.getRowVector(0);
}

我找到了解决问题的方法,我想与大家分享。 这个问题不是编程错误,但本文提供了一个不正确的矩阵(Ai矩阵),这是求解线性方程组所需要的。 我试图利用齐次变换矩阵和旋转矩阵的特性,从
M*X-Y*N=0
中提取一个线性方程组。我想出了以下解决方案:


哪里

文中提供的向量bi很好


由于Ernst教授在我的大学任教,我将与他一起学习一门课程,我将努力让他意识到这个错误。

我能够找到解决问题的方法,我想与大家分享。 问题不是编程错误,但该论文提供了一个