17

プログラムの線形代数エンジンとしてEigen行列ライブラリを使用したいと思います。Eigenは、式テンプレートを使用して遅延評価を実装し、ループと計算を簡素化します。

例えば:

#include<Eigen/Core>

int main()
{
  int size = 40;
  // VectorXf is a vector of floats, with dynamic size.
  Eigen::VectorXf u(size), v(size), w(size), z(size);
  u = 2*v + w + 0.2*z;
}

Eigenは式テンプレートを使用するため、次のようなコードを使用します

u = 2*v + w + 0.2*z;

上記のサンプルでは、​​一時的なものを作成せずに、長さ10の単一ループに縮小されます(40ではなく、フロートは4のチャンクによってレジストラに入れられます)。それはどれくらいクールですか?

しかし、このようにライブラリを統合すると、次のようになります。

class UsingEigen
{
    public:  
        UsingEigen(const Eigen::VectorXf& data):
            data_(data)
        {}

        UsingEigen operator + (const UsingEigen& adee)const
        {
            return UsingEigen(data_ + adee.data_);
        }

        ...
    private:
        Eigen::VectorXf data_;
}

次に、次のような式:

UsingEigen a, b, c, d;
a = b + c + d;

Eigenの実装方法を利用することはできません。そして、これが最後ではありません。Eigenで式テンプレートが使用されている例は他にもたくさんあります。

簡単な解決策は、演算子を自分で定義せずにdata_公開し、次のような式を記述することです。

UsingEigen a, b, c, d;
a.data_ = b.data_ + c.data_ + d.data_;

これはカプセル化を破りますが、Eigenの効率を維持します。

他の方法は、独自の演算子を作成することですが、式テンプレートを返すようにします。しかし、私はC ++の初心者なので、これが正しい方法かどうかはわかりません。

質問が一般的すぎる場合は申し訳ありません。私は初心者で、誰にも尋ねることはありません。今まではstd::vector<float>どこでも使っていましたが、今は行列も使う必要があります。プロジェクト全体でEigenに切り替えることstd::vector<float>は大きな一歩であり、最初から間違った電話をかけることを恐れています。どんなアドバイスも歓迎します!

4

4 に答える 4

5

公開data_するとカプセル化が破られるのはなぜですか? カプセル化とは、実装の詳細を隠し、インターフェースのみを公開することを意味します。ラッパー クラスがネイティブライブラリにUsingEigen動作または状態を追加しない場合、インターフェイスは変更されません。Eigenこの場合、このラッパーを完全に削除し、Eigenデータ構造を使用してプログラムを作成する必要があります。

行列またはベクトルを公開しても、カプセル化は解除されません。行列またはベクトルの実装を公開するだけで、カプセル化が解除されます。Eigenライブラリは算術演算子を公開しますが、その実装は公開しません。

式テンプレート ライブラリを使用して、ユーザーがライブラリ機能を拡張する最も一般的な方法は、状態を追加して追加するのではなく、動作を追加することです。また、動作を追加するために、ラッパー クラスを記述する必要はありません。クラス メンバー関数に関して実装される非メンバー関数を追加することもできEigenます。Scott Meyers によるこのコラム「非メンバー関数がカプセル化を改善する方法」を参照してください。

現在のプログラムをEigen機能を明示的に使用するバージョンに変換することに関する懸念については、変更を段階的に実行し、毎回プログラムの小さな部分を変更して、ユニットテストを確認します (ユニットがあることを確認します)。テストですよね?) 途中で壊れません。

于 2012-06-11T08:21:04.793 に答える
-2

私はあなたの質問をすべて理解しているわけではありません。ほとんどの質問に答えようとします。この文では:

 UsingEigen operator + (const UsingEigen& adee)const
    {
        return UsingEigen(data_ + adee.data_);
    }

オーバーロード演算子があります (申し訳ありませんが、これが英語での正しい書き方かどうかはわかりません)。このため、次のように書くことができます。

a = b + c + d;

それ以外の:

a.data_ = b.data_ + c.data_ + d.data_;

問題はありません。プログラムの費用は同じです。さらに、カプセル化と効率性が得られます。

一方、独自のオペレーターを定義したい場合は、テンプレートのように行うことができます。「オーバーロード演算子」を検索する Web で情報を見つけることができますが、次のようなものです。

UsingEigen operator + (const UsingEigen& adee)const
    {
        return UsingEigen(data_ + adee.data_);
    }

「+」の代わりに演算子を入れて、必要な操作を行うことができます。

マトリックスを作成したい場合は簡単です。配列の配列またはベクトルのベクトルを作成するだけです。

私は次のようなものだと思います:

std::vector<vector<float>>

よくわかりませんが、簡単ですが、この方法で単純なマトリックスを使用できます。

float YourMatrix [サイズ][サイズ];

お役に立てば幸いです。私はあなたの質問をすべて理解していません.さらに何か必要な場合は、Google+に私を追加してください.

私の英語で申し訳ありませんが、すべてを理解していただければ幸いです。

于 2012-06-11T08:23:10.743 に答える