【问题标题】:How to use cwise operations over specific indexes of a vector? (Eigen)如何对向量的特定索引使用 cwise 操作? (本征)
【发布时间】:2018-10-21 14:18:30
【问题描述】:

我正在尝试将以下 Matlab 代码转换为 C/C++。

indl = find(dlamu1 < 0);  indu = find(dlamu2 < 0);
s = min([1; -lamu1(indl)./dlamu1(indl); -lamu2(indu)./dlamu2(indu)]);

我在另一个线程上读到,Eigen 库中还没有与 find() 函数等效的东西,我对此很平静,并且已经蛮力解决了它。

现在,如果我想对lamu1dlamu1 进行系数除法,我会选择lamu1.cwiseQuotient(dlamu1),但我该怎么做呢?由indl的系数指定?我在文档中没有找到任何关于此的内容,但也许我没有使用正确的搜索词。

【问题讨论】:

    标签: eigen eigen3


    【解决方案1】:

    使用默认分支,您只需编写 lamu1(indl)indlstd::vector&lt;int&gt;Eigen::VectorXi 或任何您喜欢的支持通过 operator[] 进行随机访问的内容。

    【讨论】:

    • 你是在建议类似 lamu1(indl).cwiseQuotient(dlamu1(indl)) 的东西吗?
    • 没错,为了让我的评论足够长,我也会写下变体:lamu1(indl).array() / dlamu1(indl).array()
    【解决方案2】:

    即使在默认分支中,也没有 find 的等价物。但是,您的函数可以使用 select 方法来表达(也适用于 Eigen 3.3.x):

    double ret1 = (dlamu1.array()<0).select(-lamu1.cwiseQuotient(dlamu1), 1.0).minCoeff();
    return std::min(1.0,ret1); // not necessary, if dlamu1.array()<0 at least once
    

    select 懒惰地计算,即只有当条件为真时,才会计算商。另一方面,上面的代码会与 1.0 进行很多不必要的比较。

    如果[d]lamu 存储在Eigen::ArrayXd 而不是Eigen::VectorXd,则可以这样写:

    double ret1 = (dlamu1<0).select(-lamu1/dlamu1, 1.0).minCoeff();
    

    如果你还是强行使用indl,你可以按照ggael的建议写:

    lamu1(indl).cwiseQuotient(dlamu1(indl)).minCoeff();
    

    (如果indl.size()==0,这是未定义/崩溃)

    【讨论】:

    • 第一个和第二个建议都会导致 seg.fault。至于 ggael 的建议,编译器似乎对此有异议;我尝试将 indl 的类型从 VectorXi 替换为 Index,但是一旦完成,编译器就会抱怨“array()”的使用。
    • 代码编译并运行良好。在您的情况下,dlamu1lamu1 的类型是什么?您使用的是什么 Eigen 版本?您使用什么编译器和编译选项?换句话说:提供minimal reproducible example!
    • 两者都是 VectorXd。我正在使用 Eigen 3.3.5 并使用 g++ -std=c++11 进行编译
    猜你喜欢
    • 2020-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-02
    • 2012-08-10
    • 1970-01-01
    • 2016-08-27
    相关资源
    最近更新 更多