我正在为一个函数编写一个单元测试,该函数计算一个由4个大小为2的行向量组成的特征数组。我想检查它是否近似等于预期的结果,但行不一定必须以相同的顺序出现。因此,对于实际输出中的每一行,我想看看它是否与预期输出中的 some 行匹配。
所以这是我现在的测试
Eigen::Array<float, 4, 2> expectedResult {{-14.1421356F, -14.1421356F},
{-28.2842712F, 28.2841712F},
{14.1421356F, 14.1421356F},
{28.2842712F, -28.284172F}};
Eigen::Array<float, 4, 2> result = myFunction();
for (int rowIndex = 0; rowIndex < 4; rowIndex++)
{
// Check whether each row of result matches some other row of expectedResult,
// not necessarily in order.
// @todo find less clumsy way
bool foundMatch = false;
for (int comparisonRowIndex = 0; comparisonRowIndex < 4; comparisonRowIndex++)
{
if (result.row(rowIndex).isApprox(expectedResult.row(comparisonRowIndex), TOLERANCE))
{
foundMatch = true;
}
}
EXPECT_TRUE(foundMatch);
}
字符串
这感觉并不令人满意,我想我肯定能够以某种方式使用Eigen的any()
结构,但我仍然没有找到原因。
for (int rowIndex = 0; rowIndex < 4; rowIndex++)
{
EXPECT_TRUE(expectedResult.rowwise().isApprox(result.row(rowIndex), TOLERANCE).any()); // WRONG
}
型
1条答案
按热度按时间hjqgdpho1#
你的代码不能编译的原因是因为
expectedResult.rowwise
的返回值不是一个数组,因此没有成员isApprox
。它是一个VectorwiseOp
,参见rowwise
的文档 (下次,请在你的问题中包括你的编译器错误)。我不是Eigen方面的Maven,但你的问题似乎是如此具体,我有一种预感,在Eigen中没有专门的功能来解决你的问题。
你没有说明为什么你认为你的方法是“笨拙的”。我认为你的方法总体上是好的,你需要检查源数组中的每一行与目标数组中的每一行,没有办法绕过它。如果你可以为行提供一个部分排序比较器函数,情况就会有所不同:然后你可以手动排序行,或者潜在地使用
std::set
。但是,您可以通过减少比较次数来提高效率:
1.如果源数组中的一行在目标数组中找不到匹配的行,可以停止函数并返回false。
1.如果对于源数组中的一行,您在目标数组中找到了匹配的行,则可以停止在源数组中搜索与该行匹配的行:您已经找到了匹配项。
1.如果对于源数组中的一行,您在目标数组中找到了匹配的行,则在对源数组行的后续迭代中不必考虑此目标行。
字符串
Godbolt链接:https://godbolt.org/z/6oTacj87j
附录
正如@chtz在他的评论中指出的那样,可能会有这种检查失败的情况。原因是“近似相等”不是等价关系。更具体地说,它不是传递的,即
x.isApprox(y,tol)
和y.isApprox(z,tol)
并不意味着x.isApprox(z,tol)
。作为一个例子,让我们考虑你的问题的简化版本,我们想比较两个长度为1的行的数组,即两个二元向量s和t。
| S|不|
| --|--|
| 1.0 |1.0版|
| 0.91 |一点零九|
规则2和规则3将
s[0]
与t[0]
匹配,由于t[0]
将从候选行集合中删除,因此s[1]
没有匹配对象,函数将返回false
,这可能是意外的。那么,不排除任何比较是否更安全呢?
不,不是这样的。让我们放弃规则1,2和3,并严格比较以下输入的每个源行和每个目标行:
| S|不|
| --|--|
| 1.0 |1.0版|
| 0.91 |42.0|
然后,给定0.1的容差,您提出的算法将
s[0]
和s[1]
与t[0]
匹配,并且由于每个源行在目标数组中都有匹配,因此您的算法将返回true
,这可能也不是您所期望的。长话短说,浮点比较有复杂的陷阱,如果可能的话,拥有一个尊重所有边缘情况的比较函数并不是一个微不足道的任务。