YUDUM'ın yeni yerleşik özelliği ile pythonappend kullanmak için herhangi bir yolu var mı? | Netgez.com
SORU
14 ŞUBAT 2012, Salı


YUDUM'ın yeni yerleşik özelliği ile pythonappend kullanmak için herhangi bir yolu var mı?

Güzel YUDUM ile çalışan küçük bir projem var. Özellikle benim bazı fonksiyonları Python dizilerini çevrilmiş olsun std::vectorler, dönüş. Şimdi, rakamsal bir sürü iş yaptım, ben sadece YUDUM döndükten sonra c kodundan numpy diziler için bu dönüştürmek. Bunu yapmak için, YUDUM aşağıdaki gibi bir şey kullanıyorum.

þature("pythonappend") My::Cool::Namespace::Data() const %{ if isinstance(val, tuple) : val = numpy.array(val) %}

(Aslında, çeşitli fonksiyonları val aslında bir başlığın olduğunu kontrol ediliyor Veri, geri yüzer bazıları olarak sayılabilir.) Bu sadece çok güzel çalışıyor.

Ama aynı zamanda şu anda mevcut olan -builtin bayrağı kullanmak istiyorum. Bu Veriler işlevleri için çağrılar nadir ve çoğunlukla etkileşimli, yavaşlık bir sorun değil, ancak önemli ölçüde yerleşik seçeneği ile hızlandıran diğer yavaş döngüler vardır.

Sorun bu bayrağı kullanırken, pythonappend özelliği sessizce göz ardı edilir. Şimdi, Veri yine bir demet verir. Hala numpy diziler dönüş şansım var mı? Overview kullanarak denedim, ama içine dev bir karışıklık çıktı.

Düzenleme:

Borealid çok güzel bir soru cevap. Sadece bütünlüğü için, sabit referans ile döneceğim çünkü ihtiyacım var ilgili ama kurnazca bir kaç farklı Overview dahil ettim ve vektörler (başlama!) vektörleri kullanıyorum. Bu başkasının küçük farkları anlamaya çalışıyorum uğraşmayı istemem yeterince farklı.

%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);
}

Edit 2:

Gerçi arıyordum çok, benzer sorunlar da kullanılarak çözülebilir @MONK yaklaşımı (explained here).

CEVAP
10 Ocak 2013, PERÅžEMBE


typemap kullanarak biraz karmaşık bir hal alır, sana katılıyorum, ama bu görevi yerine getirmek için doğru bir yöntemdir. Ayrıca YUDUM belgelere doğrudan %pythonappend -builtin ile uyumlu değil ama kuvvetle ima olduğunu söylemek değil, haklısınız: %pythonappendPython proxy sınıfı eklerve -builtin bayrağı ile birlikte Python proxy sınıfı Hiç Yok.

Önce, ne yaptığını YUDUM Python dizilerini içine std::vector nesneleri C dönüştürmek ve yeniden dönüştürülmüş nerede numpy - geri aşağı o dizilerini geçen geçiriyordu.

Sen gerçekten ne yapmak istediğini bir kez, C düzeyinde dönüştürmek.

İşte NumPy tamsayı diziler std::vector<int> tüm nesneler dönecek kodu:

%{
#include "numpy/arrayobject.h"
%}

%init %{
    import_array();
%}

%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);
}

Bu C-düzey numpy fonksiyonları ve bir dizi inşa döndürmek için kullanır. Sırayla:

  • NumPy arrayobject.h C bulunan bir dosya çıktı dosyası saÄŸlar
  • import_array Python modülü zaman çaÄŸrılmasına neden olur (aksi halde, tüm NumPy yöntemleri segfault) yüklenir
  • Haritalar typemap ile NumPy diziler std::vector<int> herhangi döndürür

Bu kod konulmalıdırönce21 ** işlevleri std::vector<int> dönen içeren başlıkları. Kısıtlama, tamamen eklemek gerekir; bu nedenle, kendi kendine yeten, daha başka öznel çok fazla "karmaşa" kod temeli.

Eğer diğer vektör türleri ihtiyacın olursa, sadece NPY_INT int* int tüm parçaları, aksi halde yukarıdaki fonksiyonu çoğaltarak değiştirebilirsiniz.

Bunu PaylaÅŸ:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VÄ°DEO

Rastgele Yazarlar

  • BaaaStuds's channel

    BaaaStuds's

    10 Mart 2009
  • Cartoonium

    Cartoonium

    11 NÄ°SAN 2011
  • Whizzpopping

    Whizzpopping

    10 Kasım 2005