2016-06-22 9 views
1

私はEigenを使ってZ_2の係数を持つ大規模な疎線形方程式系を解きたい。最初に、ブール型で1 + 1 = 1なので、動作しないブール型を試しましたが、1 + 1 = 0が必要です。したがって、ソリューションは新しいカスタマイズされたスカラー型かもしれません。しかし、どのように正確に動作するのですか?他のパッケージやソフトウェアの提案も歓迎します。どのようにZ_2の係数で疎線形システムを解くことができますか?

+1

使用演算子^代わりに演算子+? – lorro

+0

@lorroなぜですか? 1^1 = 1である。 –

+0

'^'はビットXORです。 – kangshiyin

答えて

0

基本型の演算子はオーバーロードできないためです。カスタマイズされたスカラー型が必要です。これを行う方法を説明する基本的な文書があります。

http://eigen.tuxfamily.org/dox/TopicCustomizingEigen.html#CustomScalarType

は、基本的には3つの事を行う必要があります。

  1. 共通オペレータを確認してください - 構造体固有の特殊化を追加するタイプのT
  2. によってサポートされています(+、*、/、など。):: NumTraits
  3. は数学関数を定義しますそれはあなたのタイプに合っています。これには、sqrt、pow、sin、tan、conj、real、imagなどの標準的なものだけでなく、Eigen固有のabs2も含まれます。実際にあなただけの方程式を解くために必要とされるそれらの演算子や数学関数を定義することができ

(ファイル固有/ SRC /コア/ MathFunctions.hを参照してください)。

上記のリンクは、タイプadtl::adoubleの簡単な例です。ほとんどの操作が既に明確に定義されているため、コードは非常に短いです。 Eigenソースディレクトリunsupported/には、別の第三者タイプのmpfr::mprealがサポートされています。このリンクから始めることができます。固有のソースディレクトリで

https://eigen.tuxfamily.org/dox/unsupported/group__MPRealSupport__Module.html

、これらのファイルは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 
+0

はい、今私は知っている^は正しい演算子です。しかし私が言及したように、私はパッケージEigenを使って疎線形システムを解きたい。実際にはまずEigen :: Matrix(m、n、BOOL)のようなブール値の行列を定義したいと思います。このBOOLはあなたが言ったように、変更された演算子を持つブール型です。私はそれを実現する方法を知らない。 –

+0

@Misery私は見る。そのため、オーバーロードが必要です。 – kangshiyin

+0

それは素晴らしいです。私は本当に感謝しています。しかし、線形システムを解くためには、 - 、>、...のような多くの演算子に負担をかける必要があります。そのほとんどはうまくいきます。1. sqrt、absのような関数をオーバーロードする必要があります。それは次のようになります: 'namespace std {Z2 :: Scalar abs(Z2 :: Scalar&a){return a.data; } Z2 ::スカラーsqrt(Z2 ::スカラー&a){戻ります。データ; }} 'しかし、それはまだ動作しなかったし、一致する関数がないと言った。あなたは何か考えていますか? –

関連する問題