7

ブースト行列とベクトル型で要素単位の関数を実行したい。たとえば、各要素の対数をとり、各要素を累乗し、ガンマやディガンマなどの特別な関数を適用するなど (適用されたこれらの関数の matlab の処理と同様)行列とベクトルに。)

必要な関数ごとにこれをブルートフォースするヘルパー関数を書くだけで十分だと思いますが、これは無駄に思えます。

同様に、boost wiki は標準関数をベクトル化するコードを提供していますが、これは非常に複雑に思えます。

valarray が提案されていますが、他の操作 (行列積、疎行列など) には ublas データ型が必要なので、データ型間の変換は避けたいと思います。

どんな助けでも大歓迎です。

4

2 に答える 2

10

begin1()/を使用するとend1()、デフォルトの列位置(0)の要素にアクセスできるため、機能しません。したがって、最初の列のすべての要素にアクセスするだけです。(期待される動作が得られるという意味で)次の方法でシーケンシャルアクセスを取得することをお勧めします。

std::transform(mat.data().begin(), mat.data().end(),
               mat.data().begin(), boost::math::tgamma) ;

これは、実装が完全ではない場合だと思います。

楽しみ!

于 2010-10-15T16:31:45.907 に答える
3

警告

次の答えは正しくありません。下部の編集を参照してください。エラーを指摘した人たちに文脈と信用を与えるために、私は元の答えをそのままにしました。


私はBoostライブラリに特に精通していないので、これを行うためのより標準的な方法があるかもしれませんが、イテレータとSTL変換関数テンプレートを使用して必要なことを実行できると思います。uBLASライブラリのドキュメントの概要では、そのクラスはSTLで使用されているのと同じイテレータの動作と互換性があるように設計されていると述べています。ブースト行列とベクトルテンプレートにはすべて、個々の要素にアクセスするために使用できるイテレーターがあります。ベクトルにはとがbegin()あり、end()行列には​​、、、、、があります。種類は列単位のイテレーターであり、種類は行単位の反復子です。VectorExpressionのブーストドキュメントを参照してくださいbegin1()end1()begin2()end2()12詳細については、MatrixExpressionを参照してください。

STLtransformアルゴリズムを使用すると、反復可能シーケンスの各要素に関数を適用し、その結果を同じ長さまたは同じシーケンスの異なる反復可能シーケンスに割り当てることができます。したがって、これをブーストuBLASベクトルで使用するには、次のようにします。

using namespace boost::numeric::ublas;

// Create a 30 element vector of doubles
vector<double> vec(30);

// Assign 8.0 to each element.
std::fill(vec.begin(), vec.end(), 8.0);

// Perform the "Gamma" function on each element and assign the result back
// to the original element in the vector.
std::transform(vec.begin(), vec.end(), vec.begin(), boost::math::tgamma);

行列の場合、基本的に同じものであり、イテレータまたはイテレータのファミリのいずれかを使用し1ます2。どちらを使用するかは、行列のメモリレイアウトが行メジャーか列メジャーかによって異なります。uBLASのドキュメントをざっとスキャンすると、どちらかである可能性があると思います。そのため、コードを調べて、どちらが使用されているかを判断し、最も効率的な反復順序を選択する必要があります。

matrix<double> mat(30, 30);
.
.
.

std::transform(mat.begin1(), mat.end1(), mat.begin1(), boost::math::tgamma);

最後の引数として渡す関数は、単一のdouble引数を取り、double値を返す関数にすることができます。ファンクターになることもできます。

これは、引用したベクトル化の例とまったく同じではありませんが、必要なものにかなり近いはずです。


編集

推奨事項を作成する前にテストする必要があったようです。他の人が指摘しているように、「1」と「2」のイテレータは、行列の単一の行/列に沿ってのみ反復します。Boostの概要ドキュメントは、これに関して深刻な誤解を招きます。begin1()「行列の先頭を指すiterator1をend1()返す」と「行列の終わりを指すiterator1を返す」と主張しています。「マトリックス」の代わりに「マトリックスの列」と言うことは彼らを殺したでしょうか?iterator1anは、行列全体を反復処理する列単位の反復子であると想定しました。これを行う正しい方法については、LanternRougeの回答を参照してください。

于 2009-05-16T05:51:33.827 に答える