Armadillo调用rows返回subview_elem2无each_col成员的问题问询
报错原因
你遇到的arma::subview_elem2 has no member named each_col报错,是Armadillo的性能优化设计导致的:当调用rows()传入非连续索引(这里是ucolvec类型的w)时,返回的是无内存拷贝的轻量代理对象subview_elem2,该类型为了控制编译开销和二进制体积,没有实现each_col这类迭代类方法。
等效实现方案
- 方案1:利用自动广播特性(性能最优,无额外内存拷贝)
Armadillo默认支持矩阵与列向量的广播运算,直接相加即可实现所有列逐一加上目标列向量的效果,不需要显式调用each_col:
arma::Mat<double> a(10,10,arma::fill::zeros); arma::ucolvec w = whatever1; arma::vec another_col_vector = ...; // 直接相加即可,默认按列广播 whatever2 = a.rows(w) + another_col_vector;
- 方案2:显式转换为Mat对象(通用适配所有Mat方法)
如果确实需要调用each_col做更复杂的逐列操作,可先将代理对象显式转为完整的Mat类型,再调用对应方法:
// 显式转换后即可调用所有Mat类支持的方法 whatever2 = arma::mat(a.rows(w)).each_col() + another_col_vector;
相关诉求回应
a) 代理类不可用的方法说明
Armadillo所有表达式返回的代理类(包括subview_mat、subview_elem2、各类Op/Glue表达式对象),仅实现了基础的算术运算符重载,以下类型的方法仅在完整的Mat/Col/Row容器类上可用:
- 逐元素/逐行/逐列迭代类方法:
each_col()、each_row()、for_each()等 - IO类方法:
save()、load()等 - 尺寸修改类方法:
reshape()、resize()、insert_rows()等
如果不确定当前返回值类型,直接显式转换为对应容器类即可规避方法缺失问题。
b) 全量方法支持的说明
Armadillo的核心设计目标是优先保障数值计算的性能和编译速度,给所有轻量代理类实现全量容器方法会大幅提升编译耗时和二进制体积,目前官方没有相关迭代计划。
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

