我试图使用Eigen中的函数来压缩一些代码,特别是那些允许你做数组的系数方面产品的代码,但是我可能错误地使用它们。基本思想包含在这个扩展的for循环中:
for (int dir = 0; dir < NDIM; dir++)
{
for (int i = 0; i < nlocal; i++)
{
for (int qp = 0; qp < nVolQuad; qp++)
qNewPtr[i] +=
volQuad.weights(qp)*bigStoredVolMatrices[dir](i,qp)*alpha(dir,qp)*fAtQuad(qp);
}
}
我想凝结成:
for (int dir = 0; dir < NDIM; dir++)
{
resultVectorDir[dir].noalias() = bigStoredVolMatrices[dir]*
(volQuad.weights.array()*fAtQuad.array()*alpha.row(dir).array()).matrix();
}
for (int i = 0; i < nlocal; i++)
{
for (int dir = 0; dir < NDIM; dir++)
qNewPtr[i] += resultVectorDir[dir](i);
}
或不在数组和矩阵之间切换,使用类似:
for (int dir = 0; dir < NDIM; dir++)
{
resultVectorDir[dir].noalias() = bigStoredVolMatrices[dir]*
(volQuad.weights.cwiseProduct(fAtQuad.cwiseProduct(alpha.row(dir))));
}
for (int i = 0; i < nlocal; i++)
{
for (int dir = 0; dir < NDIM; dir++)
qNewPtr[i] += resultVectorDir[dir](i);
}
对我来说奇怪的是有时这是有效的。代码有时会产生所需的输出,但有时也会产生NaN。我以为我可能需要在精简版本中明确地将resultVectorDir归零,但这并没有解决问题。我认为执行这个操作顺序可能只有一些微妙之处?我们将非常感谢您提供的任何帮助。
作为这个问题的附录,我用旧的老式印刷语句攻击了这个问题,发现我一定不能正确使用数组函数的系数明智的产品。例如,在nVolQuad = 9的情况下,我运行了这段代码:
for (int dir = 0; dir < NDIM; dir++)
{
tempArray = volQuad.weights.cwiseProduct(fAtQuad.cwiseProduct(alpha.row(dir)));
for (int qp = 0; qp < nVolQuad; qp++)
{
std::cout << std::endl;
std::cout << tempArray(qp) << " ";
std::cout << volQuad.weights(qp)*alpha(dir,qp)*fAtQuad(qp) << " ";
std::cout << std::endl;
}
std::cout << std::endl;
std::cout << std::endl;
}
输出的一块看起来像这样:
-2.23064e-05 -2.23064e-05
1.49458e-154 -3.56902e-05
6.94729e-310 -2.23064e-05
-2.68156e + 154 -2.0672e-05
6.94729e-310 -3.30752e-05
6.94729e-310 -2.0672e-05
2.13645e-314 -2.99114e-06
6.94729e-310 -4.78582e-06
6.94729e-310 -2.99114e-06
输出的其他部分类似。第一个条目是正确的,但tempArray的其他8个条目都是无意义的。 tempArray在循环之前被初始化为0.0,所以我有点不知所措。我将继续深入研究Eigen的文档,以确保我在使用此函数时没有做过极其愚蠢的事情。
答案 0 :(得分:1)
关键错误是假设当扩展循环访问不同大小的数据时,您可以立即从扩展循环转到系数明智产品。这里:
volQuad.weights.cwiseProduct(fAtQuad.cwiseProduct(alpha.row(dir)))
由于volQuad.weights和fAtQuad用Eigen :: VectorXd初始化,它们是列向量,但是通过使用alpha.row(dir),该特定数据结构是行向量。因此,系数明智的产品没有意义,你只能得到第一个条目正确。通过将语法更改为:
,可以轻松解决此问题volQuad.weights.cwiseProduct(fAtQuad.cwiseProduct(alpha.row(dir).transpose()))