C++ 犰狳:矩阵乘法精度损失

C++ 犰狳:矩阵乘法精度损失,c++,matlab,precision,armadillo,C++,Matlab,Precision,Armadillo,我在执行矩阵乘法时似乎遇到了精度损失,我想知道如何防止这种情况。例如,假设专长和beta的大小合适 Y = feat*beta.rows(0,N); 我正在使用的数字值较小,大多数数字都小于1e-3,因此我尝试实现的目标可能是不可能的。我还应该注意,这是一个调用C++函数的Matlab函数,因此涉及MEX编译器。当数字到达时,我会检查mex函数中的数字,它们是正确的,只有在上面这一行之后,我才会得到错误的答案 编辑:我认为给出程序的完整上下文不会有什么坏处。这是我到目前为止所拥有的。我有一行,

我在执行矩阵乘法时似乎遇到了精度损失,我想知道如何防止这种情况。例如,假设专长和beta的大小合适

Y = feat*beta.rows(0,N);
我正在使用的数字值较小,大多数数字都小于1e-3,因此我尝试实现的目标可能是不可能的。我还应该注意,这是一个调用C++函数的Matlab函数,因此涉及MEX编译器。当数字到达时,我会检查mex函数中的数字,它们是正确的,只有在上面这一行之后,我才会得到错误的答案

编辑:我认为给出程序的完整上下文不会有什么坏处。这是我到目前为止所拥有的。我有一行,在这行中,精确性的损失被加上了注释

编辑2:这里有一些有关矩阵的例子。
专长2d是5x4608

     0         0         0         0         0
     0         0         0         0         0
     0         0         0         0    4.8146
     0         0   19.0266         0         0
     0         0         0         0         0
Beta_2d为4609x4。我把最后一行放在feat*Beta_2d的乘法中

 -7.1486e-05  -1.6801e-04   1.0970e-05   3.7837e-04
 -8.7524e-05   1.8275e-04  -6.7857e-04   2.6267e-04
 -9.1812e-05  -6.5495e-05  -1.7687e-03  -3.2168e-04
  0e+00        0e+00        0e+00        0e+00
 -4.5089e-04  -5.6013e-05   1.4841e-04   2.4912e-04
Y=

这是来自EDIT1的代码

#include <mex.h>
#include <iostream>
#include <armadillo>

using namespace arma;

void predict_bbox_reg(double *beta, int beta_dim[2], double *t_inv, int tinv_dim[2], double mu, double *feat, int feat_dim[2], double *boxes, int box_dim[2]){


    //convert pointers 
    //beta
    arma::mat beta_2d = mat(beta_dim[0], beta_dim[1]);
    for(int i = 0; i<beta_dim[0]; i++){
        for(int j = 0; j<beta_dim[1]; j++){
            beta_2d(i, j) = beta[i+beta_dim[0]*j];
        }
    }

    //t_inv
    arma::mat tinv_2d = mat(tinv_dim[0], tinv_dim[1]);
    for(int i = 0; i<tinv_dim[0]; i++){
        for(int j = 0; j<tinv_dim[1]; j++){
            tinv_2d(i, j) = t_inv[i+tinv_dim[0]*j];
        }
    }
    //feadoublet_2d
    arma::mat feat_2d = mat(feat_dim[0], feat_dim[1]);
    for(int i = 0; i<feat_dim[0]; i++){
        for(int j = 0; j<feat_dim[1]; j++){
            feat_2d(i, j) = feat[i+feat_dim[0]*j];
        }
    }

    //boxes
    arma::mat box_2d = mat(box_dim[0], box_dim[1]);
    for(int i = 0; i<box_dim[0]; i++){
        for(int j = 0; j<box_dim[1]; j++){
            box_2d(i, j) = boxes[i+box_dim[0]*j];
        }
    }


    arma::mat Y = mat(feat_dim[0], beta_dim[1]);

    Y = feat_2d*beta_2d.rows(0,beta_dim[0]-2);// this is the precision loss

    arma::mat y1 = beta_2d.row(beta_2d.n_rows-1);
    Y.each_row() += y1.row(0);

    //RETURNS SOMETHING


}        

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {

    int M = mxGetM(prhs[0]);
    int N = mxGetN(prhs[0]);

    int beta_dim[2] = {M,N}; 
    double *beta = mxGetPr(prhs[0]);


    M = mxGetM(prhs[1]);
    N = mxGetN(prhs[1]);
    int tinv_dim[2] = {M,N};
    double *t_inv = mxGetPr(prhs[1]);


    double mu = *mxGetPr(prhs[2]);    

    M = mxGetM(prhs[3]);
    N = mxGetN(prhs[3]);

    int feat_dim[2] = {M,N};
    double *feat = mxGetPr(prhs[3]);

    M = mxGetM(prhs[4]);
    N = mxGetN(prhs[4]);

    int box_dim[2] = {M,N};
    double *ex_boxes = mxGetPr(prhs[4]);

    predict_bbox_reg(beta, beta_dim, t_inv, tinv_dim,
            mu, feat, feat_dim, ex_boxes, box_dim);

    //RETURNS results to matlab
}
#包括
#包括
#包括
使用arma;
无效预测\u bbox\u注册表(双*贝塔,整数贝塔尺寸[2],双*t\u inv,整数tinv\u尺寸[2],双mu,双*专长,整数专长尺寸[2],双*盒子,整数盒子尺寸[2]){
//转换指针
//贝塔
arma::mat beta_2d=mat(beta_dim[0],beta_dim[1]);

对于(int i=0;i我在代码中看不到任何直接错误,但我怀疑Armadillo存在精度问题。我怀疑这可能是指向mat转换的指针中的问题。我将使用Armadillo在
../mex\u interface/armaMex.hpp
文件中提供的函数

矩阵乘法的一个简单示例(mult_test.cpp):

给出输出

Matlab:
1.0e-06 *

0.240798243020273   0.410716970485213
0.559953800808707   0.974915983937571

Armadillo:
1.0e-06 *

0.240798243020273   0.410716970485213
0.559953800808707   0.974915983937571

我们需要更多的信息。你能展示一些矩阵的最小示例吗?另外,你如何定义“精度损失”?你怎么知道你实际上正在失去精度?如果你做得很好,你就无法将它与计算机进行比较……因为你的比较矩阵可能不好,而不是你自己的。@AnderBiguri我对一些矩阵进行了一些编辑,显示了一些矩阵,似乎有一个问题,Y导致基本上为零的运算。当我进行运算时在matlab中,结果是不一样的。我可以问一下!正如doc!犰狳被限制为本地类型的两倍或可能是最大精度的两倍!如果这还不够呢!我搜索了,但没有找到如何使用其他类型,如一些大num库!任何关于这方面的想法!当然性能会受到影响完成了!非常感谢!正如您所说,Armadillo只支持“float、double、std::complex、std::complex、short、int、long和short、int、long的无符号版本”据我所知。谢谢你。我确实在帮助一位朋友。最终我们没有出现精度问题。当我有时间时,我会检查混合一个大的num lib和运算符重载。这可能有效。
#include <armadillo>
#include "armaMex.hpp"

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{     
    // Convert to Armadillo
    mat x1 = conv_to<mat>::from(armaGetPr(prhs[0],true));
    mat x2 = conv_to<mat>::from(armaGetPr(prhs[1],true));
    mat y(x1.n_rows,x2.n_cols);

    // Do your stuff here:
    y = x1*x2;

    // Convert back to Matlab
    plhs[0] = armaCreateMxMatrix(y.n_rows, y.n_cols, mxDOUBLE_CLASS, mxREAL); 
    armaSetPr(plhs[0], conv_to<mat>::from(y));
    return;
}
X1 = [1 2 3 ; 4 5 6];
X2 = 1e-7*rand(3,2);

Y = mult_test(X1,X2);

disp('Matlab:')
disp(X1*X2)
disp('Armadillo:')
disp(Y)
Matlab:
1.0e-06 *

0.240798243020273   0.410716970485213
0.559953800808707   0.974915983937571

Armadillo:
1.0e-06 *

0.240798243020273   0.410716970485213
0.559953800808707   0.974915983937571