我想使用 Eigen 求解系数在 Z_2 中的大型稀疏线性方程组。首先,我们尝试了 Boolean 类型,它不起作用,因为在 Boolean 中 1+1=1,但我希望 1+1=0。因此,解决方案可能是一种新的定制标量类型。但它究竟是如何工作的呢?也欢迎其他软件包或软件的一些建议。
问问题
161 次
1 回答
0
由于基本类型的运算符不能重载。您需要一个自定义的标量类型。这是告诉您如何执行此操作的基本文档。
http://eigen.tuxfamily.org/dox/TopicCustomizingEigen.html#CustomScalarType
基本上你需要做3件事。
- 确保类型 T 支持通用运算符(+、-、*、/ 等)
- 添加 struct Eigen::NumTraits 的特化
- 定义对您的类型有意义的数学函数。这包括标准的,如 sqrt、pow、sin、tan、conj、real、imag 等,以及特定于 Eigen 的 abs2。(参见文件 Eigen/src/Core/MathFunctions.h)
实际上,您只能定义方程求解所需的那些运算符和数学函数。
上面的链接提供了一个简单的 type 示例adtl::adouble
。代码很短,因为大部分操作已经定义好。在 Eigen source dirunsupported/
中,还有另一个 3rd-party 类型mpfr::mpreal
支持。你可以从这个链接开始。
https://eigen.tuxfamily.org/dox/unsupported/group__MPRealSupport__Module.html
在 Eigen 源目录中,这些文件与mpfr::mpreal
支持有关。它们可能有用。
./unsupported/Eigen/MPRealSupport ./unsupported/test/mpreal/mpreal.h ./unsupported/test/mpreal_support.cpp
这是 Z_2 中支持矩阵乘法的最小工作示例:
#include <iostream>
#include <Eigen/Eigen>
namespace Z2 {
struct Scalar {
Scalar() :
data(0) {
}
Scalar(bool x) :
data(x) {
}
bool data;
inline Scalar operator+=(const Scalar& a) {
return data ^= a.data;
}
};
inline Scalar abs(const Scalar& a) {
return a;
}
inline Scalar operator+(const Scalar& a, const Scalar& b) {
return a.data ^ b.data;
}
inline Scalar operator*(const Scalar& a, const Scalar& b) {
return a.data & b.data;
}
template<class E, class CT>
std::basic_ostream<E, CT> &operator <<(std::basic_ostream<E, CT> &os,
const Z2::Scalar &m) {
return os << m.data;
}
}
namespace Eigen {
// follow all other traits of bool
template<> struct NumTraits<Z2::Scalar> : NumTraits<bool> {
typedef Z2::Scalar Real;
typedef typename internal::conditional<sizeof(Z2::Scalar) <= 2, float, double>::type NonInteger;
typedef Z2::Scalar Nested;
};
}
int main(void) {
using namespace Eigen;
Matrix<Z2::Scalar, Dynamic, Dynamic> x(2, 2), y(2, 2), i(2, 2), j(2, 2);
x.row(0) << 1, 1;
y.col(0) << 1, 1;
i.setIdentity();
j = i.array() + 1;
std::cout << "x=\n" << x << std::endl;
std::cout << "y=\n" << y << std::endl;
std::cout << "i=\n" << i << std::endl;
std::cout << "j=\n" << j << std::endl;
std::cout << "x+y=\n" << x + y << std::endl;
std::cout << "x.*y=\n" << x.array() * y.array() << std::endl;
std::cout << "y*j=\n" << y * j << std::endl;
std::cout << "abs(x)=\n" << x.array().abs() << std::endl;
return 0;
}
结果:
x=
1 1
0 0
y=
1 0
1 0
i=
1 0
0 1
j=
0 1
1 0
x+y=
0 1
1 0
x.*y=
1 0
0 0
y*j=
0 1
0 1
abs(x)=
1 1
0 0
于 2016-06-22T18:57:47.303 回答