比较Google Test或Google Mock中的Eigen矩阵

Lem*_*ing 7 c++ unit-testing googletest eigen gmock

我想知道是否有一种很好的方法可以使用Google TestGoogle Mock测试两个Eigen矩阵的近似相等性.

采取以下测试用例作为一个简化的例子:我乘以2点复数值矩阵A,和B,并期望一个确定的结果C_expect.我C_actual = A * B使用Eigen 计算数值结果.现在,我想比较C_expect,和C_actual.现在,相应的代码如下所示:

#include <complex>
#include <Eigen/Dense>
#include <gtest/gtest.h>
#include <gmock/gmock.h>

typedef std::complex<double> Complex;
typedef Eigen::Matrix2cd Matrix;

TEST(Eigen, MatrixMultiplication) {
    Matrix A, B, C_expect, C_actual;

    A << Complex(1, 1), Complex(2, 3),
         Complex(3, 2), Complex(4, 4);
    B << Complex(4, 4), Complex(3, 2),
         Complex(2, 3), Complex(1, 1);
    C_expect << Complex(-5, 20), Complex(0, 10),
                Complex(0, 40), Complex(5, 20);

    C_actual = A * B;

    // !!! These are the lines that bother me.
    for (int j = 0; j < C_actual.cols(); ++j) {
        for (int i = 0; i < C_actual.rows(); ++i) {
            EXPECT_NEAR(C_expect(i, j).real(), C_actual(i, j).real(), 1e-7)
                << "Re(" << i << "," << j << ")";
            EXPECT_NEAR(C_expect(i, j).imag(), C_actual(i, j).imag(), 1e-7)
                << "Im(" << i << "," << j << ")";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这有什么问题?好吧,我必须手动迭代矩阵的所有索引,然后分别比较实部和虚部.我更喜欢Google Mock的ElementsAreArray匹配器.例如

EXPECT_THAT(C_actual, ElementsAreArray(C_expect));
// or
EXPECT_THAT(C_actual, Pointwise(MyComplexNear(1e-7), C_expect));
Run Code Online (Sandbox Code Playgroud)

不幸的是,Google Mock的内置功能似乎只适用于一维C风格或STL类型的容器.此外,我需要对矩阵的复数值进行近似比较.

我的问题:你知道是否(以及如何)教导Google Mock迭代多维度,并将复杂的浮点数与近似相等进行比较?

请注意,我不能只将数据指针作为C风格的数组处理,因为存储布局可能会有所不同C_expect,和C_actual.而且,实际上,矩阵大于2×2矩阵.即某种循环肯定是必要的.

iNF*_*TEi 14

为什么不使用Eigen Matrix类型的isApproxisMuchSmallerThan成员函数?

这些功能的文档可在此处获得

所以对大多数情况ASSERT_TRUE(C_actual.isApprox(C_expect));来说就是你需要的.您也可以提供精确的参数作为第二arguement到isApprox.


Una*_*dra 5

EXPECT_PRED2 从 GoogleTest 可以用于此。

在 C++11 下使用 lambda 工作正常,但看起来不合时宜:

  ASSERT_PRED2([](const MatrixXf &lhs, const MatrixXf &rhs) {
                  return lhs.isApprox(rhs, 1e-4);
               },
               C_expect, C_actual);
Run Code Online (Sandbox Code Playgroud)

如果失败,您会得到输入参数的打印输出。

可以像这样定义普通谓词函数,而不是使用 lambda:

bool MatrixEquality(const MatrixXf &lhs, const MatrixXf &rhs) {
  return lhs.isApprox(rhs, 1e-4);
}

TEST(Eigen, MatrixMultiplication) {
  ...

  ASSERT_PRED2(MatrixEquality, C_expected, C_actual);
}
Run Code Online (Sandbox Code Playgroud)

更高版本也适用于 C++11 之前的版本。