警告
次の答えは正しくありません。下部の編集を参照してください。エラーを指摘した人たちに文脈と信用を与えるために、私は元の答えをそのままにしました。
私はBoostライブラリに特に精通していないので、これを行うためのより標準的な方法があるかもしれませんが、イテレータとSTL変換関数テンプレートを使用して必要なことを実行できると思います。uBLASライブラリのドキュメントの概要では、そのクラスはSTLで使用されているのと同じイテレータの動作と互換性があるように設計されていると述べています。ブースト行列とベクトルテンプレートにはすべて、個々の要素にアクセスするために使用できるイテレーターがあります。ベクトルにはとがbegin()
あり、end()
行列には、、、、、があります。種類は列単位のイテレーターであり、種類は行単位の反復子です。VectorExpressionのブーストドキュメントを参照してくださいbegin1()
end1()
begin2()
end2()
1
2
詳細については、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を返す」と主張しています。「マトリックス」の代わりに「マトリックスの列」と言うことは彼らを殺したでしょうか?iterator1
anは、行列全体を反復処理する列単位の反復子であると想定しました。これを行う正しい方法については、LanternRougeの回答を参照してください。