【问题标题】:Armadillo subview issue犰狳子视图问题
【发布时间】:2022-01-12 14:51:54
【问题描述】:

以下片段产生编译错误:

arma::Mat<double> a(10,10,arma::fill::zeros);
arma::ucolvec w = whatever1;
whatever2 = a.rows(w).each_col() + another-col-vector;

错误是 arma::subview_elem2 没有名为 each_col 的成员。

在 Armadillo 的许多情况下,标准数组函数并不总是可用于其他函数调用的表达式或结果。显然 rows() 函数不返回一个 Mat 对象,而是一个 subview_elem2 对象,大概是为了优化。另一种方法是在 Mat 和其他内部类(例如子视图)实现的接口/纯抽象类中声明所有数组函数。除了只生成 r 值的表达式的写操作之外,似乎应该可以使所有 Armadillo 数组表达式与数组对象互换。

所以...我希望得到以下结果

a) 说明哪些方法不适用于哪些结果。 b) 最好启用所有有意义的数组方法组合。

如果没有上述,如何才能达到想要的结果,也就是对表达式求值:

a.rows(w).each_col()

??

【问题讨论】:

    标签: armadillo


    【解决方案1】:

    一些关于犰狳的先验信息

    犰狳库大量使用模板,大多数操作返回expression templates。只有当您将结果分配给变量时,才会执行实际计算。这就是为什么你不应该使用 auto 存储犰狳计算的结果。

    例如,给定一些矩阵ABC,类似于

    auto D = A * B + C;
    

    不会执行计算,只有表达式模板存储在D 中。另一方面,使用

    arma::mat D = A * B + C;
    

    将强制进行计算并将结果存储在D

    解决您的问题

    特别是对于您的问题,a.rows(w) 之类的内容会返回 subview_elem2 类型的表达式模板(此文件在源代码 armadillo_bits/subview_elem2_bones.hpp 中定义)。这种“临时类型”没有.each_col 方法,这会导致您得到错误。一种解决方法是将a.rows(w) 的结果存储在一个变量中,但由于您对该变量不感兴趣,您可以使用.eval() 方法。 .eval() 方法强制表达式模板执行到该点的实际计算,因此随后对 .each_col 的调用将起作用。也就是替换

    a.rows(w).each_col() + another-col-vector;
    

    a.rows(w).eval().each_col() + another-col-vector;
    

    【讨论】:

    • .eval() 函数在这种情况下工作得很好,但通常我们应该小心使用它。文档说:“此功能应谨慎使用,仅在绝对必要的情况下使用;不加选择地使用会降低性能”
    • 是的,我同意。使用模板表达式是有原因的。他们可以在实际需要值时优化操作(当您分配给变量时)。当您使用 eval 时,您正在消除这种可能性,但在这种情况下,它似乎是必要的。 Armadillo 是一个非常成熟的库,我猜想 subview_elem2 中缺少 each_col 方法可能是因为这要么是不可能的,要么在效率方面与那里有一个 eval 相同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-16
    相关资源
    最近更新 更多