私はSWIGで美しく動作する小さなプロジェクトを持っています。特に、私の関数のいくつかはstd::vector
を返します。これはPythonのタプルに変換されます。さて、私は多くの数値を扱うので、SWIGはこれらをC++コードから返された後にnumpy配列に変換します。これを行うために、私はSWIGで次のようなものを使用します。SWIGの新しい組み込み機能でpythonappendを使う方法はありますか?
%feature("pythonappend") My::Cool::Namespace::Data() const %{ if isinstance(val, tuple) : val = numpy.array(val) %}
(実際には、浮動小数点数を返すそのうちのいくつかは、データという名前のいくつかの機能は、私はval
が実際にタプルであることを確認してください理由である、があります。)これはただ美しく動作します。
でも、現在利用可能な-builtin
フラグを使用したいと思います。これらのデータ関数への呼び出しは稀で、ほとんどインタラクティブであるため、遅さは問題ではありませんが、組み込みオプションで大幅に高速化する他の低速ループもあります。
問題は、私がそのフラグを使用すると、pythonappend機能が静かに無視されることです。さて、データはタプルをもう一度返します。私はまだnumpy配列を返すことができる方法はありますか?私はタイプマップを使ってみたが、それは巨大な混乱に変わった。
編集:
Borealidは非常にうまく質問に答えました。完全性のために、私はconst参照によって返され、私はベクトルのベクトルを使用するので(開始しないでください!)、私が必要とする微妙に異なるタイプマップをいくつか含んでいます。これらは十分に異なっているので、他の誰かが微妙な違いを見つけようとしているのではありません。
%typemap(out) std::vector<int>& {
npy_intp result_size = $1->size();
npy_intp dims[1] = { result_size };
PyArrayObject* npy_arr = (PyArrayObject*)PyArray_SimpleNew(1, dims, NPY_INT);
int* dat = (int*) PyArray_DATA(npy_arr);
for (size_t i = 0; i < result_size; ++i) { dat[i] = (*$1)[i]; }
$result = PyArray_Return(npy_arr);
}
%typemap(out) std::vector<std::vector<int> >& {
npy_intp result_size = $1->size();
npy_intp result_size2 = (result_size>0 ? (*$1)[0].size() : 0);
npy_intp dims[2] = { result_size, result_size2 };
PyArrayObject* npy_arr = (PyArrayObject*)PyArray_SimpleNew(2, dims, NPY_INT);
int* dat = (int*) PyArray_DATA(npy_arr);
for (size_t i = 0; i < result_size; ++i) { for (size_t j = 0; j < result_size2; ++j) { dat[i*result_size2+j] = (*$1)[i][j]; } }
$result = PyArray_Return(npy_arr);
}
編集2:
なく、かなり私が探していたものを、同様の問題がまたMONKのアプローチ(explained here)@使用して解決することができるけれども。
typemapを書かずにCサイドでやっていないと、-builtinがpythonappendが普通に置かれているコードを取り除いてしまっているとは思いません。あなたはビルドインの方がはるかに高速です(つまり、プロファイリングで使用するように誘導しましたか?)私は2つのモジュールを使用するように誘惑されます。 – Flexo
'-builtin'がpythonappendを無視するという警告はありません。私はnumpy配列に 'std :: vector'を型付けすることに挑戦するつもりはありません。私はプロフィールを作成し、インターフェイスで最も迷惑なループを大幅にスピードアップしました(休憩を取るのに十分な長さではなく、頻繁に待つのは長すぎます)。しかし、私はまた、私はこのループを私のC++コードに移すことができることを認識しました。だから私は行くつもりです。それでも、あなたの「2つのモジュール」の提案は面白く、他の場合には有用かもしれません。 – Mike
-WallでSWIGに電話しましたか?私はその場合警告すると仮定した。 – Flexo