gpt4 book ai didi

c++ - 混合三元运算和特征数组

转载 作者:行者123 更新时间:2023-11-30 05:12:33 24 4
gpt4 key购买 nike

我在 Eigen 文档 ( http://eigen.tuxfamily.org/index.php?title=Pit_Falls#Ternary_operator ) 中读到 Eigen 不能很好地处理三元运算;这当然是我的经验。

我想做的是根据几个 bool 标志构造一个数组,下面代码段中的 use_XXX 标志。我知道至少有一个标志从之前的检查中是正确的,但我无法编译这个 block 。以下是我尝试过但不起作用的其他选项:

  1. 使用位掩码之类的东西为 umat 构造 2^4 = 16 个逻辑选项 - 代码最终变得冗长且难以维护;呸……

  2. umat 初始化为零,然后遍历条件,进行就地减法 - 这比我手动注释掉术语时的单个求和要慢很多

另一个想法是尝试用标志乘以表达式,希望 Eigen 会使用它的模板魔法来弄清楚要做什么,但这也没有用,因为在我的例子中我没有初始化数组,如果我不使用它(这个循环中的性能非常关键的代码)

umat = (
(use_gauss_delta ? -coeffs.eta*delta_minus_epsilon.square() : 0)
+
(use_delta_ld ? -coeffs.cd*delta_to_ld : 0)
+
(use_gauss_tau ? -coeffs.beta*tau_minus_gamma.square() : 0)
+
(use_tau_lt ? -coeffs.ct*tau_to_lt : 0)
)
);

编辑

我还尝试了 select 函数,它可以工作,但是速度很慢。每个 mask_XXX 都是 Eigen::ArrayXi,所有其他的都是 Eigen::ArrayXd

umat = (
mask_gauss_delta.select(-coeffs.eta*delta_minus_epsilon.square(),0)
+
mask_delta_ld.select(-coeffs.cd*delta_to_ld,0)
+
mask_gauss_tau.select(-coeffs.beta*tau_minus_gamma.square(),0)
+
mask_tau_lt.select(-coeffs.ct*tau_to_lt,0)
);

最佳答案

您可以通过添加 .eval() 到一个条件。请参见下面的示例:

#include <Eigen/Core>
#include <iostream>

using Eigen::ArrayXd;
int main(int argc, char** argv)
{
ArrayXd aa, res;
int size = 6;
aa.setLinSpaced(size, 0, 5);
double d = 345.5;

res = (true ? (d * aa.square()).eval() : ArrayXd::Zero(size));
std::cout << res << std::endl;
res = (false ? (d * aa.square()).eval() : ArrayXd::Zero(size));
std::cout << res << std::endl;


return 0;
}

d * aa.square() 是一个 CwiseBinaryOp,其中 ArrayXd::Zero(size) 是一个 CwiseNullaryOp,两者都不能转换为另一个。将 .eval() 添加到其中一个使其成为 ArrayXd(并将创建一个您似乎不想要的临时对象)并使三元运算起作用。然而,

whatever = 
(true ? (d * aa.square()).eval() : ArrayXd::Zero(size)) +
(false ? (d * aa.square()).eval() : ArrayXd::Zero(size));

仍会导致 ArrayXd::Zero(size) 被评估为临时的,从而降低性能。性能最好的选项可能是

if(use_gauss_delta) umat += -coeffs.eta*delta_minus_epsilon.square();
if(use_delta_ld) umat += -coeffs.cd*delta_to_ld;
if(use_gauss_tau) umat += -coeffs.beta*tau_minus_gamma.square();
if(use_tau_lt) umat += -coeffs.ct*tau_to_lt;

主要缺点是评估最多会发生四次,但如果不构建您提到的 2^4 选项,我想不出避免这种情况的方法。

关于c++ - 混合三元运算和特征数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44479142/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com