commons math3 和 ojalgo 库的 SVD 解输出之间的巨大差异
Huge difference between SVD solution output of commons math3 and ojalgo libraries
commons-math3 和 ojalgo 库之间的 SVD 解差异很大。有什么方法可以根据任何输入参数减少差异。
double[][] olsColumns = { { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 } };
double[] observationVector = { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
//Ojalgo
final PrimitiveDenseStore tmpOriginal = PrimitiveDenseStore.FACTORY.rows(olsColumns);
SingularValue<Double> tmpSVD = SingularValue.make(tmpOriginal);
tmpSVD.decompose(tmpOriginal);
double[] singularValues = tmpSVD.getSingularValues().toRawCopy1D();
double[][] V = tmpSVD.getQ2().toRawCopy2D();
System.out.println("V" + Arrays.deepToString(V));
System.out.println("Singular values" + Arrays.toString(singularValues));
try {
// MatrixStore<Double> doubleMat = tmpSVD.solve(tmpOriginal,
// PrimitiveDenseStore.FACTORY.column(Utils.prepareObservationVector()));
MatrixStore<Double> solution = tmpSVD.getSolution(PrimitiveDenseStore.FACTORY.column(observationVector),
tmpSVD.preallocate(tmpOriginal));
System.out.println("Solution " + Arrays.toString(solution.toRawCopy1D()));
} catch (Exception e) {
e.printStackTrace();
}
//Commons-Math3
RealMatrix newPredM = new Array2DRowRealMatrix(olsColumns);
SingularValueDecomposition svd = new SingularValueDecomposition(newPredM);
// RealMatrix covariance = svd.getCovariance(0);
// System.out.println("covariance"+Arrays.deepToString(covariance.getData()));
System.out.println("V" + Arrays.deepToString(svd.getV().getData()));
System.out.println("Singular values" + Arrays.toString(svd.getSingularValues()));
double[] solution = svd.getSolver().solve(new ArrayRealVector(observationVector)).toArray();
System.out.println("Solution" + Arrays.toString(solution));
Commons Math3 解决方案:[0.01612903225806451, 0.016129032258064502]
OjAlgo解决方案解决方案:[7.614155324982286E13, -7.614155324982295E13]
您使用的是哪个版本的 ojAlgo?
当我尝试该代码时出现异常,因为您提供给 tmpSVD.getSolution(...) 方法的 "preallocated" 矩阵是错误的 size/shape。如果您简单地删除第二个参数,分配就会为您完成并且代码可以工作。我得到这个结果:
V[[0.707106781186548, -0.707106781186547], [0.707106781186547, 0.707106781186548]]
Singular values[13.638181696985853, 9.035878689445474E-15]
Solution [0.016129032258064484, 0.01612903225806446]
commons-math3 和 ojalgo 库之间的 SVD 解差异很大。有什么方法可以根据任何输入参数减少差异。
double[][] olsColumns = { { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 1.0 } };
double[] observationVector = { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
//Ojalgo
final PrimitiveDenseStore tmpOriginal = PrimitiveDenseStore.FACTORY.rows(olsColumns);
SingularValue<Double> tmpSVD = SingularValue.make(tmpOriginal);
tmpSVD.decompose(tmpOriginal);
double[] singularValues = tmpSVD.getSingularValues().toRawCopy1D();
double[][] V = tmpSVD.getQ2().toRawCopy2D();
System.out.println("V" + Arrays.deepToString(V));
System.out.println("Singular values" + Arrays.toString(singularValues));
try {
// MatrixStore<Double> doubleMat = tmpSVD.solve(tmpOriginal,
// PrimitiveDenseStore.FACTORY.column(Utils.prepareObservationVector()));
MatrixStore<Double> solution = tmpSVD.getSolution(PrimitiveDenseStore.FACTORY.column(observationVector),
tmpSVD.preallocate(tmpOriginal));
System.out.println("Solution " + Arrays.toString(solution.toRawCopy1D()));
} catch (Exception e) {
e.printStackTrace();
}
//Commons-Math3
RealMatrix newPredM = new Array2DRowRealMatrix(olsColumns);
SingularValueDecomposition svd = new SingularValueDecomposition(newPredM);
// RealMatrix covariance = svd.getCovariance(0);
// System.out.println("covariance"+Arrays.deepToString(covariance.getData()));
System.out.println("V" + Arrays.deepToString(svd.getV().getData()));
System.out.println("Singular values" + Arrays.toString(svd.getSingularValues()));
double[] solution = svd.getSolver().solve(new ArrayRealVector(observationVector)).toArray();
System.out.println("Solution" + Arrays.toString(solution));
Commons Math3 解决方案:[0.01612903225806451, 0.016129032258064502]
OjAlgo解决方案解决方案:[7.614155324982286E13, -7.614155324982295E13]
您使用的是哪个版本的 ojAlgo?
当我尝试该代码时出现异常,因为您提供给 tmpSVD.getSolution(...) 方法的 "preallocated" 矩阵是错误的 size/shape。如果您简单地删除第二个参数,分配就会为您完成并且代码可以工作。我得到这个结果:
V[[0.707106781186548, -0.707106781186547], [0.707106781186547, 0.707106781186548]]
Singular values[13.638181696985853, 9.035878689445474E-15]
Solution [0.016129032258064484, 0.01612903225806446]