C++犰狳稀疏矩阵类型转换

C++ armadillo sparse matrix type conversion

我想用 operator+ 添加两个任意(不同)类型的稀疏犰狳矩阵,例如

SpMat<double> M1(2,2);
SpMat<cx_double> M2(2,2);

// ..fill both matrices

cout<<M1 + M2<<endl;

编译时,编译器抱怨没有为这些类型定义 operator+

当对 DENSE 矩阵执行相同操作时,犰狳会自动将双矩阵提升为复矩阵,执行加法并打印复矩阵结果。

include 目录中的 operator_plus.hpp 中有此运算符的相应模板,用于添加两个可能不同类型的稀疏对象(至少模板定义表明如此),但它似乎仅在以下情况下有效两个操作数的类型相同。上述代码的实际编译器消息如下

operator_plus.hpp:164:1: note: template<class T1, class T2> typename arma::enable_if2<((arma::is_arma_sparse_type<T1>::value && arma::is_arma_sparse_type<T2>::value) && arma::is_same_type<typename T1::elem_type, typename T2::elem_type>::value), arma::SpGlue<T1, T2, arma::spglue_plus> >::result arma::operator+(const T1&, const T2&)
operator_plus.hpp:164:1: note:   template argument deduction/substitution failed:
operator_plus.hpp:164:1: error: no type named ‘result’ in ‘struct arma::enable_if2<false, arma::SpGlue<arma::SpMat<double>, arma::SpMat<std::complex<double> >, arma::spglue_plus> >’

有什么想法吗?有没有可能这个功能还没有实现? 谢谢!

似乎还没有实现添加两个不同类型的稀疏矩阵(使用当前最新版本 6.400.3)。我估计下面也回答了 this question.

Armadillo 使用 SFINAE 技术从 operator+(以及许多其他 functions/operators)的可能重载候选列表中排除不适合的函数模板,以便评估模板参数后只剩下所需的候选人。

这里我们要的候选是两个稀疏矩阵相加的那个。它具有以下签名

template<typename T1, typename T2>
inline arma_hot
typename enable_if2
<
(is_arma_sparse_type<T1>::value && is_arma_sparse_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
 SpGlue<T1,T2,spglue_plus>
>::result
operator+(const T1& x,const T2& y)

enable_if2 是在 restrictors.hpp 中定义的模板结构,其工作方式与 std::enable_if 非常相似:如果 enable_if 的第一个模板参数(在上面声明长布尔表达式)的计算结果为真,enable_if 具有与第二个模板参数相同类型的成员(在本例中为 SpGlue<T1,T2,spglue_plus>)。

这意味着只有当布尔表达式的计算结果为真时,这个候选项才有效,否则它也会从可能的候选项列表中被丢弃。如您所见,布尔表达式还包含

部分
is_same_type<typename T1::elem_type, typename T2::elem_type>::value

如果 T1T2 不相同,

当然会计算为 false,因此 enable_if2 没有成员 enable_if2::result 并且函数从候选中删除列表。