代码之家  ›  专栏  ›  技术社区  ›  KcFnMi

如何检查两个矩阵是否相同?

  •  1
  • KcFnMi  · 技术社区  · 8 年前

    想法是把两个矩阵相乘。用本征做同样的乘法,然后检查结果是否相同。

    在下面的制作过程中 N = 2 退货 same thing 但是 N = 1000 退货 NOT same thing . 为什么?

    #include <cstdlib>
    #include <iostream>
    #include <Eigen/Dense>
    
    using namespace std;
    using namespace Eigen;
    
    const int N = 1000;
    
    void mult_matrix(double x[N][N], double y[N][N], double z[N][N]) {
        int rows = N;
        int cols = N;
        for (int i = 0; i < rows; i++)
            for (int j = 0; j < cols; j++)
                for (int k = 0; k < cols; k++)
                    z[i][j] += x[i][k] * y[k][j];
    }
    
    void check(double *x, double *y, double *z) {
    
        Matrix<double, Dynamic, Dynamic, RowMajor> m = 
                Matrix<double, Dynamic, Dynamic, RowMajor>::Map(x, N, N) * 
                Matrix<double, Dynamic, Dynamic, RowMajor>::Map(y, N, N);
    
        cout << m(0, 0) << endl;
        cout << Matrix<double, Dynamic, Dynamic, RowMajor>::Map(z, N, N)(0, 0) << endl;
    
        if (m == Matrix<double, Dynamic, Dynamic, RowMajor>::Map(z, N, N))
            cout << "same thing" << endl;
        else
            cout << "NOT same thing" << endl;
    }
    
    int main() {
        double *a = (double*)malloc(N*N*sizeof(double));
        double *b = (double*)malloc(N*N*sizeof(double));
        double *c = (double*)malloc(N*N*sizeof(double));
    
        Matrix<double, Dynamic, Dynamic, RowMajor>::Map(a, N, N).setRandom();
        Matrix<double, Dynamic, Dynamic, RowMajor>::Map(b, N, N).setRandom();
        Matrix<double, Dynamic, Dynamic, RowMajor>::Map(c, N, N).setZero();
    
        mult_matrix((double (*)[N])a, (double (*)[N])b, (double (*)[N])c);
        check(a, b, c);
    }
    
    4 回复  |  直到 8 年前
        1
  •  4
  •   RHertel    8 年前

    isApprox()

    ==

    if (m.isApprox(Matrix<double, Dynamic, Dynamic, RowMajor>::Map(z, N, N)))
      cout << "same thing" << endl;
    else
      cout << "NOT same thing" << endl;
    

    isMuchSmallerThan()

        2
  •  3
  •   Daniel Heilper    8 年前

    == N=2 N

    bool double_equals(double a, double b, double epsilon = 0.001)
    {
        return std::abs(a - b) < epsilon;
    }
    

    double reldiff(double a, double b) {
        double divisor = fmax(fabs(a), fabs(b)); /* If divisor is zero, both x and y are zero, so the difference between them is zero */
        if (divisor == 0.0) return 0.0; return fabs(a - b) / divisor; 
    }
    
    bool double_equals(double a, double b, double rel_diff)
    {
        return reldiff(a, b) < rel_diff;
    }
    
        3
  •  2
  •   Yves Daoust    8 年前

    0.1 0.99999999999993 0.100000000000002

    |a - b| < max(|a|, |b|).ε
    

    ε 10^-7

    (sin(1.000001) - sin(1)) / 0.000001 = (0.84147104 - 0.84147100) / 0.0000001 = 0.40000000 0.5403023

        4
  •  1
  •   Yves Daoust    8 年前

    u = 2^-t t n n u < 0.01 xTy

    1.01 n u |x|T |y|


    xTy = 0