PDL::Indexingp - Online di Cloud

Ini adalah perintah PDL::Indexingp yang dapat dijalankan di penyedia hosting gratis OnWorks menggunakan salah satu dari beberapa workstation online gratis kami seperti Ubuntu Online, Fedora Online, emulator online Windows atau emulator online MAC OS

PROGRAM:

NAMA


PDL::Indexing - Pengantar pengindeksan dan slicing piddles.

GAMBARAN


Halaman manual ini harus berfungsi sebagai tutorial pertama tentang fitur pengindeksan dan threading dari
PDL.

Seperti semua bahasa vektor, PDL mengotomatiskan perulangan array menggunakan varian dari
notasi vektor matematika. Pengulangan otomatis disebut "threading", sebagian
karena pada akhirnya PDL akan menerapkan pemrosesan paralel untuk mempercepat loop.

Banyak fleksibilitas dan kekuatan PDL bergantung pada fitur pengindeksan dan threading dari
ekstensi Perl. Pengindeksan memungkinkan akses ke data piddle dengan cara yang sangat fleksibel
cara. Threading menyediakan vektorisasi yang efisien dari operasi sederhana.

Nilai piddle disimpan secara kompak sebagai nilai yang diketik dalam satu blok memori,
tidak (seperti dalam daftar-daftar Perl normal) sebagai skalar Perl individual.

Di bagian yang mengikuti banyak "metode" dipanggil -- ini adalah operator Perl yang
berlaku untuk PDL. Dari shell perldl (atau pdl2), Anda dapat mengetahui lebih lanjut tentang setiap metode
dengan mengetik "?" diikuti dengan nama metode.

Dimensi daftar
Piddle (variabel PDL), secara umum, adalah array berdimensi-N di mana N dapat bernilai 0 (untuk a
skalar), 1 (misalnya untuk sampel suara), atau nilai yang lebih tinggi untuk gambar dan lebih kompleks
struktur. Setiap dimensi piddle memiliki ukuran bilangan bulat positif. "perl"
interpreter memperlakukan setiap piddle sebagai jenis skalar Perl khusus (objek Perl yang diberkati,
sebenarnya -- tetapi Anda tidak perlu mengetahuinya untuk menggunakannya) yang dapat digunakan di mana pun Anda bisa
menempatkan skalar normal.

Anda dapat mengakses dimensi piddle sebagai daftar Perl dan menentukan ukurannya
dari piddle dengan beberapa metode. Yang penting adalah:

nelem - jumlah total elemen dalam PDL
ndims - mengembalikan jumlah dimensi dalam PDL
dims - mengembalikan daftar dimensi PDL sebagai daftar Perl
redup - mengembalikan ukuran dimensi tertentu dari PDL

Pengindeksan dan Aliran data
PDL mempertahankan gagasan "aliran data" antara piddle dan subbidang yang diindeks dari itu
kencing. Saat Anda menghasilkan subbidang yang diindeks atau elemen tunggal dari piddle induk,
anak dan orang tua tetap terikat sampai Anda memutuskannya secara manual. Ini memungkinkan Anda
mewakili data yang sama dengan cara yang berbeda dalam kode Anda -- misalnya, Anda dapat mempertimbangkan
gambar RGB secara bersamaan sebagai kumpulan nilai (R,G,B) dalam gambar 3 x 1000 x 1000,
dan sebagai tiga bidang warna 1000 x 1000 terpisah yang disimpan dalam variabel yang berbeda. Memodifikasi
salah satu variabel mengubah memori yang mendasarinya, dan perubahan tersebut tercermin dalam semua
representasi dari data.

Ada dua metode penting yang memungkinkan Anda mengontrol koneksi aliran data antara anak
dan PDL induk:

copy - memaksa salinan eksplisit dari PDL
sever - memutuskan koneksi aliran data antara PDL dan induknya (jika ada)

threading dan Dimensi Memesan
Kebanyakan operasi PDL bertindak pada beberapa dimensi pertama dari argumen piddle mereka. Untuk
contoh, "sumover" menjumlahkan semua elemen di sepanjang dimensi pertama dalam daftar (dimensi 0).
Jika Anda memberi makan dalam genangan tiga dimensi, maka dimensi pertama dianggap sebagai
dimensi "aktif" dan dimensi selanjutnya adalah dimensi "benang" karena mereka
hanya dilingkari. Ada beberapa cara untuk mengubah urutan atau menyusun ulang daftar dimensi
sebuah PDL. Teknik-teknik itu sangat cepat karena tidak menyentuh data yang mendasarinya, hanya
mengubah cara PDL mengakses data. Fungsi pemesanan dimensi utama adalah:

mv - memindahkan dimensi tertentu ke tempat lain dalam daftar dimensi
xchg - menukar dua dimensi dalam daftar dimensi, meninggalkan sisanya sendiri
menyusun ulang - memungkinkan pencampuran dimensi secara grosir
clump - menggumpal bersama-sama dua atau lebih dimensi kecil menjadi satu yang lebih besar
pemerasan - menghilangkan dimensi ukuran 1

Fisik dan tiruan Ukuran
· dokumen threading tingkat Perl

· threadid

· perbarui dan deskripsi irisan yang benar

· fungsi baru di slice.pd (affine, lag, splitdim)

· pengerjaan ulang paragraf pada threading eksplisit

Pengindeksan dan threading dengan PDL


Banyak fleksibilitas dan kekuatan PDL bergantung pada fitur pengindeksan dan pengulangan dari
ekstensi Perl. Pengindeksan memungkinkan akses ke data objek pdl dengan cara yang sangat fleksibel
jalan. Threading menyediakan fungsionalitas perulangan implisit yang efisien (karena perulangan adalah
diimplementasikan sebagai kode C yang dioptimalkan).

Objek Pdl (kemudian sering disebut "pdls") adalah objek Perl yang mewakili multidimensi
array dan operasi pada mereka. Berbeda dengan gaya Perl @x sederhana yang mencantumkan data array
disimpan secara kompak dalam satu blok memori sehingga menggunakan lebih sedikit memori dan
memungkinkan penggunaan kode C cepat untuk mengimplementasikan operasi (misalnya penambahan, dll) pada pdls.

pdls bisa memiliki anak-anak
Inti dari banyak kemampuan pengindeksan PDL adalah hubungan "induk" dan
"anak" di antara pdls. Banyak dari perintah pengindeksan membuat pdl baru dari pdl yang ada.
Pdl baru adalah "anak" dan yang lama adalah "orang tua". Data pdl baru adalah
didefinisikan oleh transformasi yang menentukan cara menghasilkan (menghitung) datanya dari
data orang tua. Hubungan antara pdl anak dan orang tuanya sering dua arah,
artinya perubahan pada data anak disebarkan kembali ke induknya. (Catatan: Anda
lihat, kami bertujuan dalam terminologi kami sudah menuju fitur aliran data baru. Jenis
aliran data yang digunakan oleh perintah pengindeksan (yang akan Anda pelajari sebentar lagi)
selalu beroperasi, tidak hanya ketika Anda secara eksplisit mengaktifkan aliran data di pdl
dengan mengatakan "$a->doflow". Untuk informasi lebih lanjut tentang aliran data, periksa man dataflow
Halaman.)

Cara lain untuk menafsirkan pdls yang dibuat oleh perintah pengindeksan kami adalah dengan melihatnya sebagai
jenis pointer cerdas yang menunjuk kembali ke beberapa bagian atau semua data induknya.
Oleh karena itu, tidak mengherankan jika data induk (atau sebagian darinya) berubah ketika
dimanipulasi melalui "penunjuk" ini. Setelah kata pengantar ini semoga
mempersiapkan Anda untuk apa yang akan datang (daripada membingungkan Anda terlalu banyak) kami akan menyelam
langsung dan mulai dengan deskripsi perintah pengindeksan dan beberapa contoh tipikal
bagaimana mereka dapat digunakan dalam program PDL. Kami selanjutnya akan mengilustrasikan pointer/aliran data
analogi dalam konteks beberapa contoh nanti.

Ada dua implementasi berbeda dari hubungan ``smart pointer'' ini: yang pertama
satu, yang sedikit lebih lambat tetapi berfungsi untuk transformasi apa pun hanyalah dengan melakukan
transformasi maju dan mundur yang diperlukan. Yang lainnya adalah untuk mempertimbangkan anak
piddle piddle ``virtual'', yang hanya menyimpan pointer ke parent dan akses
informasi sehingga rutinitas yang menggunakan piddle anak benar-benar langsung mengakses data
di induk. Jika piddle virtual diberikan ke rutin yang tidak dapat menggunakannya, PDL
secara transparan membuat piddle virtual sebelum membiarkan rutinitas menggunakannya.

Saat ini (1.94_01) semua transformasi yang ``affine'', yaitu indeks data
item dalam piddle induk ditentukan oleh transformasi linier (+ konstan) dari
indeks hasil piddle anak di piddle virtual. Semua rutinitas pengindeksan lainnya (mis
"->index(...)") menghasilkan piddle fisik. Semua rutinitas yang dikompilasi oleh PP dapat menerima affine
piddles (kecuali rutinitas yang meneruskan pointer ke fungsi perpustakaan eksternal).

Perhatikan bahwa apakah sesuatu itu cocok atau tidak, tidak memengaruhi semantik dari apa yang Anda lakukan
dengan cara apa pun: keduanya

$a->indeks(...) .= 5;
$a->slice(...) .= 5;

ubah data di $a. Namun, afinitas memiliki dampak signifikan pada memori
penggunaan dan kinerja.

Mengiris pdls
Mungkin aplikasi paling penting dari konsep parent/child pdls adalah
representasi irisan persegi panjang dari pdl fisik oleh pdl virtual. Setelah berbicara
cukup lama tentang konsep mari kita lebih spesifik. Misalkan kita bekerja dengan pdl 2D
mewakili gambar 5x5 (sangat kecil sehingga kami dapat mencetaknya tanpa mengisi
beberapa layar penuh dengan angka ;).

pdl> $im = urutan(5,5)
pdl> p $im

[
[0 1 2 3 4]
[5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]
[20 21 22 23 24]
]

pdl> bantuan vars
Variabel PDL dalam paket utama::

Nama Tipe Dimensi Aliran Status Mem
-------------------------------------------------- --------------
$im Ganda D [5,5] P 0.20Kb

[ di sini mungkin tepat untuk berbicara cepat tentang perintah "help vars" yang menyediakan
informasi tentang pdls di shell "perldl" atau "pdl2" interaktif yang disertakan dengan PDL. ]

Sekarang misalkan kita ingin membuat pdl 1-D yang hanya mereferensikan satu baris gambar, katakan
baris 2; atau pdl yang mewakili semua garis genap dari gambar (bayangkan kita harus berurusan dengan
bingkai genap dan ganjil dari gambar interlaced karena beberapa perilaku aneh dari bingkai kami
orang bakhil). Sebagai aplikasi irisan lain yang sering, kami mungkin ingin membuat pdl yang
mewakili wilayah persegi panjang dari gambar dengan bagian atas dan bawah terbalik. Semua ini
efek (dan banyak lagi) dapat dengan mudah dicapai dengan fungsi irisan yang kuat:

pdl> $line = $im->slice(':,(2)')
pdl> $genap = $im->slice(':,1:-1:2')
pdl> $area = $im->slice('3:4,3:1')
pdl> help vars # atau hanya PDL->vars
Variabel PDL dalam paket utama::

Nama Tipe Dimensi Aliran Status Mem
-------------------------------------------------- --------------
$bahkan Double D [5,2] -C 0.00Kb
$im Ganda D [5,5] P 0.20Kb
$baris Ganda D [5] -C 0.00Kb
$area Ganda D [2,3] -C 0.00Kb

Ketiga pdl "anak" adalah anak-anak dari $im atau yang lainnya (sebagian besar setara)
interpretasi pointer ke data $im. Operasi pada akses pdls virtual itu saja
bagian-bagian dari data seperti yang ditentukan oleh argumen untuk diiris. Jadi kita hanya bisa mencetak
baris 2:

pdl> p $baris
[10 11 12 13 14]

Perhatikan juga perbedaan "Keadaan Aliran" $area di atas dan di bawah:

pdl> p $area
pdl> bantu $area
Variabel ini adalah Double D [2,3] VC 0.00Kb

Berikut ini menunjukkan bahwa $im dan $line benar-benar berperilaku seperti yang Anda harapkan dari a
objek seperti pointer (atau dalam gambar aliran data: perubahan pada data $line adalah
disebarkan kembali ke $im):

pdl> $im++
pdl> p $baris
[11 12 13 14 15]
pdl> $baris += 2
pdl> p $im

[
[1 2 3 4 5]
[6 7 8 9 10]
[13 14 15 16 17]
[16 17 18 19 20]
[21 22 23 24 25]
]

Perhatikan bagaimana operasi penugasan pada pdl virtual anak mengubah pdl fisik induk
dan sebaliknya (namun, tugas dasar "=" tidak, gunakan ".=" untuk mendapatkan efek itu.
Lihat di bawah untuk alasan). Pdls anak virtual adalah sesuatu seperti "tautan langsung" ke
pdl induk "asli". Seperti yang dikatakan sebelumnya, mereka dapat dianggap bekerja mirip dengan
C-pointer. Tetapi berbeda dengan C-pointer mereka membawa lebih banyak informasi. Pertama, mereka
tentukan struktur data yang mereka wakili (dimensi pdl baru) dan
kedua, tentukan cara membuat struktur ini dari data induknya (cara kerjanya
terkubur di internal PDL dan tidak penting untuk Anda ketahui (kecuali Anda
ingin meretas inti di masa depan atau ingin menjadi guru PDL secara umum (untuk a
definisi makhluk aneh ini lihat PDL::Internals)).

Contoh sebelumnya telah menunjukkan penggunaan khas dari fungsi irisan. Sejak
fungsi slicing sangat penting di sini adalah penjelasan tentang sintaks untuk string
argumen untuk mengiris:

$vpdl = $a->slice('ind0,ind1...')

di mana "ind0" menentukan apa yang harus dilakukan dengan indeks No 0 dari pdl $a, dll. Setiap elemen dari
daftar yang dipisahkan koma dapat memiliki salah satu bentuk berikut:

':' Gunakan seluruh dimensi

'n' Gunakan hanya indeks "n". Dimensi indeks ini dalam pdl virtual yang dihasilkan adalah 1.
Contoh yang melibatkan dua format indeks pertama:

pdl> $column = $im->slice('2,:')
pdl> $baris = $im->slice(':,0')
pdl> p $kolom

[
[3]
[8]
[15]
[18]
[23]
]

pdl> p $baris

[
[1 2 3 4 5]
]

pdl> bantu $kolom
Variabel ini adalah Double D [1,5] VC 0.00Kb

pdl> bantu $baris
Variabel ini adalah Double D [5,1] VC 0.00Kb

'(n)' Gunakan hanya indeks "n". Dimensi ini dihapus dari pdl yang dihasilkan (bergantung pada
fakta bahwa dimensi ukuran 1 selalu dapat dihilangkan). Perbedaan antara ini
kasus dan yang sebelumnya menjadi penting dalam tugas di mana tangan kiri dan kanan
sisi harus memiliki dimensi yang sesuai.

pdl> $line = $im->slice(':,(0)')
pdl> bantu $line
Variabel ini adalah Double D [5] -C 0.00Kb

pdl> p $baris
[1 2 3 4 5]

Temukan perbedaannya dengan contoh sebelumnya?

'n1:n2' or 'n1:n2:n3'
Ambil rentang indeks dari "n1" hingga "n2" atau (bentuk kedua) ambil rentang
indeks dari "n1" ke "n2" dengan langkah "n3". Contoh penggunaan format ini adalah
definisi sub-gambar sebelumnya yang terdiri dari garis-garis genap.

pdl> $genap = $im->slice(':,1:-1:2')

Contoh ini juga menunjukkan bahwa indeks negatif bekerja seperti yang mereka lakukan untuk normal
Array gaya Perl dengan menghitung mundur dari akhir dimensi. Jika "n2" adalah
lebih kecil dari "n1" (dalam contoh -1 setara dengan indeks 4) elemen dalam
pdl virtual secara efektif dikembalikan sehubungan dengan induknya.

'*[n]'
Tambahkan dimensi boneka. Ukuran dimensi ini akan menjadi 1 secara default atau sama dengan
"n" jika argumen numerik opsional diberikan.

Sekarang, ini benar-benar sesuatu yang agak aneh pada pandangan pertama. Apa itu boneka?
dimensi? Dimensi dummy menyisipkan dimensi yang sebelumnya tidak ada. Bagaimana
apakah itu sudah selesai? Nah, dalam kasus dimensi baru yang memiliki ukuran 1 itu bisa dengan mudah
dijelaskan dengan cara Anda dapat mengidentifikasi vektor (dengan elemen "m") dengan
matriks "(1,m)" atau "(m,1)". Hal yang sama berlaku jelas untuk objek dimensi yang lebih tinggi.
Yang lebih menarik adalah kasus dimensi dummy dengan ukuran lebih besar dari satu (mis
"irisan('*5,:')"). Ini bekerja dengan cara yang sama seperti panggilan ke fungsi dummy yang dibuat
dimensi boneka baru. Jadi baca terus dan cek penjelasannya di bawah ini.

'([n1:n2[:n3]]=i)'
[Belum dilaksanakan ???????] Dengan argumen seperti ini kamu buat digeneralisasikan
diagonal. itu diagonal akan menjadi dimensi no. "i" dari pdl keluaran baru dan (jika
bagian opsional dalam tanda kurung yang ditentukan) akan diperpanjang di sepanjang kisaran indeks
ditentukan dari dimensi pdl induk masing-masing. Secara umum argumen seperti ini
hanya masuk akal jika ada argumen lain seperti ini dalam panggilan yang sama untuk mengiris.
Bagian dalam tanda kurung adalah opsional untuk jenis argumen ini. Semua argumen ini
jenis yang menentukan dimensi target yang sama "i" harus berhubungan dengan jumlah yang sama dari
indeks dalam dimensi induknya. Cara terbaik untuk menjelaskannya mungkin dengan memberikan
contoh, di sini kita membuat pdl yang mengacu pada elemen di sepanjang diagonal ruang dari
pdl induknya (sebuah kubus):

$kubus = nol(5,5,5);
$sdiag = $cube->slice('(=0),(=0),(=0)');

Perintah di atas membuat pdl virtual yang mewakili diagonal di sepanjang
dimensi orang tua no. 0, 1 dan 2 dan menjadikan dimensinya 0 (satu-satunya dimensi) dari
dia. Anda menggunakan sintaks diperpanjang jika ukuran dimensi dari dimensi induk Anda
ingin membangun diagonal dari memiliki ukuran yang berbeda atau Anda ingin membalikkan
urutan elemen dalam diagonal, mis

$rect = nol(12,3,5,6,2);
$vpdl = $rect->slice('2:7,(0:1=1),(4),(5:4=1),(=1)');

Jadi elemen $vpdl kemudian akan dikaitkan dengan elemen induknya seperti yang kita bisa
nyatakan sebagai:

vpdl(i,j) = rect(i+2,j,4,5-j,j) 0<=i<5, 0<=j<2

[ bekerja di fungsi indeks baru: "$b = $a->index($c);" ???? ]

Sana adalah berbeda jenis of tugas in PDL
Contoh sebelumnya telah menunjukkan bahwa pdls virtual dapat digunakan untuk beroperasi pada atau
mengakses bagian data dari pdl induk. Mereka juga dapat digunakan sebagai nilai dalam tugas
(seperti penggunaan "++" dalam beberapa contoh di atas telah ditunjukkan). Untuk eksplisit
tugas ke data yang diwakili oleh pdl virtual Anda harus menggunakan ".=" yang kelebihan beban
operator (yang dalam konteks ini kita sebut diperbanyak tugas). Mengapa Anda tidak dapat menggunakan
operator penugasan normal "="?

Yah, Anda pasti masih dapat menggunakan operator '=' tetapi itu tidak akan melakukan apa yang Anda inginkan. Ini
adalah karena fakta bahwa operator '=' tidak dapat kelebihan beban dengan cara yang sama seperti yang lain
operator penugasan. Jika kami mencoba menggunakan '=' untuk mencoba menetapkan data ke sebagian dari a
pdl fisik melalui pdl virtual kami tidak akan mencapai efek yang diinginkan (sebagai gantinya
variabel yang mewakili pdl virtual (referensi ke benda yang diberkati) akan setelah
tugas hanya berisi referensi ke hal lain yang diberkati yang akan berperilaku
tugas masa depan sebagai salinan "fisik" dari nilai asli [ini sebenarnya belum
jelas dan subjek diskusi di milis pengembang PDL]. Dalam arti itu
akan memutuskan koneksi pdl ke induk [ bukankah perilaku ini dalam arti
kebalikan dari apa yang terjadi di aliran data, di mana ".=" memutuskan koneksi ke induk? ].

Misalnya

pdl> $line = $im->slice(':,(2)')
pdl> $baris = nol(5);
pdl> $baris++;
pdl> p $im

[
[1 2 3 4 5]
[6 7 8 9 10]
[13 14 15 16 17]
[16 17 18 19 20]
[21 22 23 24 25]
]

pdl> p $baris
[1 1 1 1 1]

Tapi menggunakan ".="

pdl> $line = $im->slice(':,(2)')
pdl> $baris .= nol(5)
pdl> $baris++
pdl> p $im

[
[1 2 3 4 5]
[6 7 8 9 10]
[1 1 1 1 1]
[16 17 18 19 20]
[21 22 23 24 25]
]

pdl> cetak $baris
[1 1 1 1 1]

Juga, Anda dapat mengganti

pdl> $baris .= 0;

untuk tugas di atas (nol diubah menjadi piddle skalar, tanpa dimensi jadi
itu dapat ditugaskan ke piddle apa pun).

Sebuah fitur bagus dalam versi perl terbaru adalah lvalue subrutin (yaitu, versi 5.6.x dan
lebih tinggi termasuk semua perl yang saat ini didukung oleh PDL). Itu memungkinkan seseorang untuk menggunakan
mengiris sintaks di kedua sisi tugas:

pdl> $im->slice(':,(2)') .= nol(5)->xvals->float

Terkait dengan fitur subtugas nilai adalah jebakan kecil untuk yang tidak waspada: perls terbaru
memperkenalkan "fitur" yang menghentikan penggunaan PDL dari subs lvalue untuk penugasan irisan ketika
berjalan di bawah perl debugger, "perl -d". Di bawah debugger, penggunaan di atas memberikan
kesalahan seperti: "Tidak dapat mengembalikan sementara dari lvalue subrutin..." Jadi, Anda harus menggunakan sintaks
seperti ini:

pdl> ($pdl = $im->slice(':,(2)')) .= nol(5)->xvals->float

yang bekerja baik dengan dan tanpa debugger tetapi bisa dibilang canggung dan canggung untuk dibaca.

Perhatikan bahwa mungkin ada masalah dengan tugas seperti ini ketika lvalue dan rvalue pdls
lihat bagian data yang tumpang tindih di pdl induk:

# mengembalikan elemen dari baris pertama $a
($tmp = $a->slice(':,(1)')) .= $a->slice('-1:0,(1)');

Saat ini, data induk di sisi kanan tugas tidak disalin sebelum
(internal) penugasan loop berlangsung. Oleh karena itu, hasil dari tugas ini akan tergantung
pada urutan di mana elemen ditugaskan dan hampir pasti tidak lakukan apa yang kamu
diinginkan. Jadi semantiknya saat ini tidak terdefinisi untuk saat ini dan dapat berubah sewaktu-waktu. Ke
mendapatkan perilaku yang diinginkan, gunakan

($tmp = $a->slice(':,(1)')) .= $a->slice('-1:0,(1)')->copy;

yang membuat salinan fisik dari irisan atau

($tmp = $a->slice(':,(1)')) .= $a->slice('-1:0,(1)')->sever;

yang mengembalikan irisan yang sama tetapi memutuskan koneksi irisan ke induknya.

Lainnya fungsi bahwa memanipulasi ukuran
Setelah berbicara panjang lebar tentang fungsi irisan, perlu dicatat bahwa ini bukan
hanya fungsi pengindeksan PDL. Ada fungsi pengindeksan tambahan yang juga berguna
(terutama dalam konteks threading yang akan kita bicarakan nanti). Berikut adalah daftarnya
dan beberapa contoh cara menggunakannya.

"dummy"
menyisipkan dimensi dummy dari ukuran yang Anda tentukan (default 1) di lokasi yang dipilih.
Anda tidak sabar untuk mendengar bagaimana hal itu dicapai? Nah, semua elemen dengan indeks "(X,x,Y)"
("0<=x
pdl (di mana "X" dan "Y" merujuk ke grup indeks sebelum dan sesudah lokasi
di mana dimensi dummy dimasukkan.)

Contoh ini menghitung koordinat x dari centroid suatu gambar (nanti kita akan
pelajari bahwa kita sebenarnya tidak membutuhkan dimensi dummy berkat keajaiban implisit
threading; tetapi menggunakan dimensi dummy, kode tersebut juga akan berfungsi di dunia tanpa utas;
meskipun begitu Anda telah bekerja dengan utas PDL, Anda tidak ingin hidup tanpanya
lagi).

# pusat
($xd,$yd) = $im->redup;
$xc = sum($im*xvals(zeroes($xd))->dummy(1,$yd))/sum($im);

Mari kita jelaskan cara kerjanya dengan sedikit lebih detail. Pertama, produk:

$xvs = xvals(nol($xd));
print $xvs->dummy(1,$yd); # ulangi baris $yd kali
$prod = $im*xvs->dummy(1,$yd); # bentuk produk piksel dengan
# garis berulang dari nilai-x

Sisanya kemudian menjumlahkan hasil produk piksel-bijaksana bersama-sama dan
normalisasi dengan jumlah semua nilai piksel dalam gambar asli sehingga menghitung
koordinat x dari "pusat massa" gambar (menafsirkan nilai piksel sebagai
massa lokal) yang dikenal sebagai pusat massa dari suatu gambar.

Berikutnya adalah (dari sudut pandang konsumsi memori) konversi yang sangat murah dari
skala abu-abu ke RGB, yaitu setiap piksel sekarang memiliki nilai tiga kali lipat, bukan skalar.
Tiga nilai dalam rangkap tiga, untungnya, semuanya sama untuk gambar abu-abu, jadi
bahwa trik kami bekerja dengan baik karena memetakan ketiga anggota triple ke
elemen sumber yang sama:

# konversi skala abu-abu ke RGB yang murah
$rgb = $abu-abu->dummy(0,3)

Sayangnya trik ini tidak dapat digunakan untuk mengonversi foto B/W lama Anda menjadi foto berwarna
dengan cara yang Anda inginkan. :(

Perhatikan bahwa penggunaan memori piddle dengan dimensi dummy sangat sensitif terhadap
representasi internal. Jika piddle dapat direpresentasikan sebagai affine virtual
(``vaffine''), hanya struktur kontrol yang disimpan. Tetapi jika $b masuk

$a = nol(10000);
$b = $a->dummy(1,10000);

dibuat fisik oleh beberapa rutinitas, Anda akan menemukan bahwa penggunaan memori program Anda
tiba-tiba tumbuh sebesar 100Mb.

"diagonal"
menggantikan dua dimensi (yang harus berukuran sama) dengan satu dimensi yang
referensi semua elemen sepanjang "diagonal" sepanjang dua dimensi. Disini kita
memiliki dua contoh yang seharusnya tampak akrab bagi siapa saja yang pernah melakukan linier
aljabar. Pertama, buat matriks kesatuan:

# matriks kesatuan
$e = nol(mengambang, 3, 3); #jadikan semuanya nol
($tmp = $e->diagonal(0,1)) .= 1; # atur elemen di sepanjang diagonal ke 1
cetak $e;

Atau diagonal lainnya:

($tmp = $e->slice(':-1:0')->diagonal(0,1)) .= 2;
cetak $e;

(Apakah Anda memperhatikan bagaimana kami menggunakan fungsi irisan untuk mengembalikan urutan garis sebelumnya
mengatur diagonal anak baru, sehingga mengatur diagonal silang dari
induk ?) Atau pemetaan dari ruang matriks diagonal ke bidang di mana
matriks didefinisikan, jejak matriks:

# jejak matriks
$trace = sum($mat->diagonal(0,1)); # jumlahkan semua elemen diagonal

"xchg" dan "mv"
xchg menukar atau "mengubah posisi" dua dimensi yang ditentukan. Langsung
contoh:

# mengubah posisi matriks (tanpa secara eksplisit mengubah data dan
# membuat salinan)
$prod = $ax $a->xchg(0,1);

$prod sekarang seharusnya cukup dekat dengan matriks kesatuan jika $a adalah matriks ortogonal.
Seringkali "xchg" akan digunakan dalam konteks threading tetapi lebih lanjut tentang itu nanti.

mv bekerja dengan cara yang sama. Ini memindahkan dimensi (ditentukan oleh nomornya di
induk) ke posisi baru di pdl anak baru:

$b = $a->mv(4,0); # Jadikan dimensi ke-5 dari $a yang pertama di
# anak baru $b

Perbedaan antara "xchg" dan "mv" adalah bahwa "xchg" hanya mengubah posisi dua
dimensi satu sama lain, sedangkan "mv" menyisipkan dimensi pertama ke tempat
kedua, memindahkan dimensi lain di sekitar yang sesuai.

"rumpun"
meruntuhkan beberapa dimensi menjadi satu. Satu-satunya argumennya menentukan berapa banyak dimensi
dari pdl sumber harus diciutkan (mulai dari yang pertama). Sebuah (diakui
tidak realistis) contohnya adalah pdl 3D yang menyimpan data dari tumpukan file gambar yang Anda
baru saja membaca. Namun, data dari setiap gambar benar-benar mewakili waktu 1D
seri dan hanya diatur seperti itu karena didigitalkan dengan bingkai
orang bakhil. Jadi untuk memilikinya lagi sebagai rangkaian urutan waktu, Anda mengatakan

pdl> $seqs = $stack->rumpun(2)
pdl> bantuan vars
Variabel PDL dalam paket utama::

Nama Tipe Dimensi Aliran Status Mem
-------------------------------------------------- --------------
$seqs Ganda D [8000,50] -C 0.00Kb
$tumpukan Ganda D [100,80,50] P 3.05Mb

Tampaknya tidak realistis, perangkat lunak mikroskop confocal kami menulis data (terkadang)
cara ini. Tetapi lebih sering Anda menggunakan rumpun untuk mencapai efek tertentu saat menggunakan implisit
atau threading eksplisit.

Panggilan untuk Indeksasi fungsi bisa be dirantai
Seperti yang mungkin Anda perhatikan dalam beberapa contoh di atas, panggilan ke fungsi pengindeksan
dapat dirantai dengan baik karena semua fungsi ini mengembalikan objek anak yang baru dibuat.
Namun, ketika melakukan manipulasi indeks ekstensif dalam sebuah rantai, pastikan untuk melacak apa yang
Anda lakukan, misalnya

$a->xchg(0,1)->mv(0,4)

memindahkan dimensi 1 dari $a ke posisi 4 sejak perintah kedua dijalankan
dimensi asli 1 telah dipindahkan ke posisi 0 dari anak baru yang memanggil "mv"
fungsi. Saya pikir Anda mendapatkan idenya (terlepas dari penjelasan saya yang berbelit-belit).

disebarkan tugas ('.=') dan boneka ukuran
Sublety yang terkait dengan pengindeksan adalah penugasan ke pdls yang berisi dimensi dummy dari
ukuran lebih besar dari 1. Tugas ini (menggunakan ".=") dilarang karena beberapa elemen
dari lvalue pdl menunjuk ke elemen yang sama dari induknya. Akibatnya nilai
elemen induk tersebut berpotensi ambigu dan akan bergantung pada urutan di mana
implementasi membuat penugasan ke elemen. Oleh karena itu, tugas seperti ini:

$a = pdl[1,2,3];
$b = $a->dummy(1,4);
$b .= yvals(nol(3,4));

dapat menghasilkan hasil yang tidak terduga dan hasilnya secara eksplisit tidak terdefinisi oleh PDL karena
ketika PDL mendapatkan fitur komputasi paralel, hasil saat ini mungkin berubah.

Dari sudut pandang aliran data, pengenalan boneka berukuran lebih besar dari satu
dimensi dianggap sebagai transformasi ireversibel (mirip dengan terminologi dalam
termodinamika) yang menghalangi propagasi mundur penugasan ke induk (yang Anda
telah secara eksplisit meminta menggunakan ".=" tugas). Masalah serupa yang harus diwaspadai
terjadi dalam konteks threading di mana terkadang dimensi dummy dibuat secara implisit
selama loop utas (lihat di bawah).

Alasan untuk itu orang tua/anak (Atau "penunjuk") konsep
[ini harus menunggu sebentar]

XXXXX hemat memori
XXXXX dalam konteks threading
XXXXX cara yang sangat fleksibel dan kuat untuk mengakses sebagian data pdl
(dengan cara yang jauh lebih umum daripada detik, dll.)
XXXXX implementasi yang efisien
Perbedaan XXXXX untuk bagian/at, dll.

Seterpercayaapakah Olymp Trade? Kesimpulan untuk membuat hal fisik lagi
[ XXXXX isi nanti ketika semuanya sudah beres sedikit lagi ]

** Saat dibutuhkan (xsub rutin menghubungkan fungsi C lib)
** Bagaimana dicapai (->fisik)
** Cara menguji (isfisik (jelaskan cara kerjanya saat ini))
** -> salin dan -> putuskan

threading


Di paragraf sebelumnya tentang pengindeksan, kami telah menyebutkan istilah itu sesekali tetapi
sekarang benar-benar waktu untuk berbicara secara eksplisit tentang "threading" dengan pdls. Istilah threading memiliki
banyak arti yang berbeda dalam berbagai bidang komputasi. Dalam kerangka PDL itu
mungkin bisa secara longgar didefinisikan sebagai fasilitas perulangan implisit. Hal ini tersirat karena
anda tidak menentukan apa pun seperti melampirkan for-loop melainkan loop secara otomatis
(atau 'ajaib') yang dihasilkan oleh PDL berdasarkan dimensi pdl yang terlibat. Ini
seharusnya memberi Anda ide pertama mengapa fungsi manipulasi indeks/dimensi yang Anda temui
dalam paragraf sebelumnya sangat penting dan berguna dalam konteks
threading. Bahan lain untuk threading (selain dari pdls yang terlibat) adalah a
fungsi yang sadar akan threading (umumnya, ini adalah fungsi yang dikompilasi PDL::PP) dan
bahwa pdls sudah "berulir". Begitu banyak tentang terminologi dan sekarang mari kita coba
menjelaskan apa arti semua itu.

Implisit threading - a pertama contoh
Ada dua varian threading yang sedikit berbeda. Kita mulai dengan apa yang kita sebut
"pengikatan implisit". Mari kita pilih contoh praktis yang melibatkan perulangan fungsi
atas banyak elemen pdl. Misalkan kita memiliki gambar RGB yang ingin kita ubah menjadi abu-abu-
skala. Gambar RGB diwakili oleh 3-dim pdl "im(3,x,y)" di mana dimensi pertama
berisi tiga komponen warna setiap piksel dan "x" dan "y" adalah lebar dan tinggi
gambar, masing-masing. Selanjutnya kita perlu menentukan cara mengonversi warna-tiga pada yang diberikan
piksel menjadi nilai abu-abu (untuk menjadi contoh realistis itu harus mewakili relatif
intensitas yang dengannya sel-sel mata kita yang tidak peka warna akan mendeteksi warna itu untuk dicapai
apa yang kita sebut konversi alami dari warna ke skala abu-abu). Sebuah perkiraan bahwa
bekerja cukup baik adalah menghitung intensitas abu-abu dari setiap triplet RGB (r,g,b) sebagai a
jumlah tertimbang

nilai abu-abu = 77/256*r + 150/256*g + 29/256*b =
batin([77,150,29]/256, [r,g,b])

di mana bentuk terakhir menunjukkan bahwa kita dapat menulis ini sebagai produk dalam dari 3-vektor
yang terdiri dari bobot untuk komponen merah, hijau dan biru dengan 3-vektor yang mengandung
komponen warna. Secara tradisional, kami mungkin telah menulis fungsi seperti berikut ini untuk
memproses seluruh gambar:

saya @redup=$im->redup;
# di sini biasanya periksa bahwa redup pertama memiliki ukuran yang benar (3), dll
$abu-abu=nol(@redup[1,2]); # buat pdl untuk gambar abu-abu yang dihasilkan
$w = pdl [77,150,29] / 256; #vektor bobot
untuk ($j=0;$j
untuk ($i=0;$i
# menghitung nilai piksel
$tmp = inner($w,$im->slice(':,(i),(j)'));
set($abu-abu,$i,$j,$tmp); # dan atur dalam gambar skala abu-abu
}
}

Sekarang kita menulis hal yang sama menggunakan threading (perhatikan bahwa "batin" adalah fungsi sadar threading
didefinisikan dalam PDL::Paket primitif)

$abu-abu = batin($im,pdl([77,150,29]/256));

Kami telah berakhir dengan satu baris yang secara otomatis membuat pdl $abu-abu dengan hak
jumlah dan ukuran dimensi dan melakukan loop secara otomatis (loop ini adalah
diimplementasikan sebagai kode C cepat di internal PDL). Yah, kami masih berutang padamu
penjelasan bagaimana 'keajaiban' ini dicapai.

Seterpercayaapakah Olymp Trade? Kesimpulan tidak itu contoh kerja ?
Hal pertama yang perlu diperhatikan adalah bahwa setiap fungsi yang sadar threading (ini tanpa
fungsi pengecualian dikompilasi dari deskripsi singkat oleh PDL::PP, kemudian disebut PP-
fungsi) mengharapkan jumlah dimensi yang ditentukan (minimum) (kami menyebutnya dimensi inti)
dari masing-masing argumen pdl-nya. Fungsi dalam mengharapkan dua satu dimensi (input)
parameter dari mana ia menghitung parameter nol-dimensi (output). Kami menulis itu
secara simbolis sebagai "batin((n),(n),[o]())" dan menyebutnya "batin" tanda tangan, di mana n mewakili
ukuran dimensi itu. n sama pada parameter pertama dan kedua berarti bahwa
dimensi tersebut harus memiliki ukuran yang sama dalam panggilan apa pun. Sebagai contoh yang berbeda ambil
produk luar yang mengambil dua vektor 1D untuk menghasilkan matriks 2D, secara simbolis ditulis sebagai
"luar((n),(m),[o](n,m))". The "[o]" di kedua contoh menunjukkan bahwa ini (di sini ketiga)
argumen adalah argumen keluaran. Dalam contoh terakhir dimensi pertama dan kedua
argumen tidak harus setuju tetapi Anda melihat bagaimana mereka menentukan ukuran dua dimensi
dari keluaran pdl.

Di sinilah titik ketika threading akhirnya memasuki permainan. Jika Anda memanggil fungsi PP dengan
pdls yang punya lebih dari dimensi inti yang diperlukan, dimensi pertama pdl
argumen digunakan sebagai dimensi inti dan dimensi tambahan tambahan diulir
lebih. Mari kita tunjukkan ini dulu dengan contoh kita di atas

$abu-abu = dalam($im,$w); # w adalah vektor berat dari atas

Dalam hal ini $w adalah 1D dan hanya menyediakan dimensi inti, $im adalah 3D, lebih banyak
khususnya "(3,x,y)". Dimensi pertama (ukuran 3) adalah dimensi inti yang diperlukan
yang cocok (seperti yang dipersyaratkan oleh bagian dalam) dimensi pertama (dan satu-satunya) dari $w. Kedua
dimensi adalah dimensi utas pertama (dengan ukuran "x") dan yang ketiga ada di sini yang kedua
dimensi benang (ukuran "y"). Pdl keluaran dibuat secara otomatis (seperti yang diminta oleh
pengaturan $abu-abu ke "null" sebelum doa). Dimensi keluaran diperoleh dengan
menambahkan lingkaran ukuran (di sini "(x,y)") ke dimensi keluaran inti (di sini 0D) ke
menghasilkan dimensi akhir dari pdl yang dibuat secara otomatis (di sini "0D+2D=2D" untuk menghasilkan output 2D
ukuran "(x,y)").

Jadi perintah di atas memanggil fungsionalitas inti yang menghitung produk dalam dua
Vektor 1D "x*y" kali dengan $w dan semua irisan 1D berbentuk "(':,(i),(j)')" dari $im dan
set elemen masing-masing dari output pdl "$grey(i,j)" ke hasil masing-masing
komputasi. Kita bisa menulisnya secara simbolis sebagai

$abu-abu(0,0) = f($w,$im(:,(0),(0)))
$abu-abu(1,0) = f($w,$im(:,(1),(0)))
.
.
.
$abu-abu(x-2,y-1) = f($w,$im(:,(x-2),(y-1)))
$abu-abu(x-1,y-1) = f($w,$im(:,(x-1),(y-1)))

Tapi ini dilakukan secara otomatis oleh PDL tanpa menulis loop Perl eksplisit. Kami melihat
bahwa perintah tersebut benar-benar membuat output pdl dengan dimensi yang tepat dan menetapkan
elemen memang untuk hasil perhitungan untuk setiap piksel dari gambar input.

Ketika lebih banyak pdls dan dimensi ekstra terlibat, semuanya menjadi sedikit lebih rumit.
Kami pertama-tama akan memberikan aturan umum bagaimana dimensi utas bergantung pada dimensi
input pdls memungkinkan Anda untuk mengetahui dimensi pdl output yang dibuat secara otomatis
(untuk setiap set input pdl dan dimensi inti dari fungsi PP yang bersangkutan). Itu
aturan umum kemungkinan besar akan tampak sedikit membingungkan pada pandangan pertama sehingga kami akan berangkat
untuk mengilustrasikan penggunaan dengan serangkaian contoh lebih lanjut (yang semoga juga
menunjukkan bahwa memang ada banyak situasi praktis di mana threading masuk
sangat berguna).

A panggilan untuk coding disiplin
Sebelum kami menunjukkan detail teknis threading lainnya, harap perhatikan panggilan ini untuk
disiplin pemrograman saat menggunakan threading:

Untuk menjaga keterbacaan manusia, HARAP komentari ekspresi nontrivial apa pun di Anda
kode yang melibatkan threading. Yang terpenting, untuk setiap subrutin, sertakan informasi di
awal tentang apa yang Anda harapkan dari dimensi untuk mewakili (atau rentang dimensi).

Sebagai peringatan, lihat fungsi tidak berdokumen ini dan coba tebak apa yang mungkin terjadi:

sub pencarian {
saya ($im,$palet) = @_;
$res saya;
indeks($palette->xchg(0,1),
$im->long->dummy(0,($palette->dim)[0]),
($res=null));
kembali $res;
}

Apakah Anda setuju bahwa mungkin sulit untuk mengetahui dimensi yang diharapkan, tujuan dari
rutinitas, dll? (Jika Anda ingin mengetahui apa yang dilakukan bagian kode ini, lihat di bawah)

Seterpercayaapakah Olymp Trade? Kesimpulan untuk mencari di luar itu lingkaran ukuran
Ada beberapa aturan yang memungkinkan Anda untuk mengetahui jumlah dan ukuran loop
dimensi (dan jika ukuran pdls input Anda sesuai dengan aturan threading).
Dimensi argumen pdl apa pun dipecah menjadi dua kelompok sebagai berikut: Inti
dimensi (sebagaimana didefinisikan oleh fungsi PP, lihat Lampiran B untuk daftar primitif PDL)
dan dimensi tambahan yang terdiri dari semua dimensi yang tersisa dari pdl itu. Sebagai contoh
memanggil fungsi "func" dengan tanda tangan "func((n,m),[o](n))" dengan pdl
"a(2,4,7,1,3)" sebagai "f($a,($o = null))" menghasilkan pemisahan semantik dari dimensi a
menjadi: dimensi inti "(2,4)" dan dimensi tambahan "(7,1,3)".

R0 Dimensi inti diidentifikasi dengan dimensi N pertama dari masing-masing pdl
argumen (dan diperlukan). Dimensi lebih lanjut adalah dimensi ekstra dan digunakan untuk
menentukan dimensi lingkaran.

R1 Jumlah dimensi loop (implisit) sama dengan jumlah maksimum ekstra
dimensi diambil alih set argumen pdl.

R2 Ukuran masing-masing dimensi loop diturunkan dari ukuran masing-masing
dimensi argumen pdl. Ukuran dimensi loop diberikan oleh
ukuran maksimal ditemukan di salah satu pdl yang memiliki dimensi ekstra ini.

R3 Untuk semua pdls yang memiliki dimensi ekstra yang diberikan, ukurannya harus sama dengan ukuran
dimensi loop (sebagaimana ditentukan oleh aturan sebelumnya) atau 1; jika tidak, Anda menaikkan
pengecualian waktu proses. Jika ukuran dimensi ekstra dalam pdl adalah satu, itu adalah
secara implisit diperlakukan sebagai dimensi dummy dengan ukuran yang sama dengan ukuran redup loop itu ketika
melakukan loop benang.

R4 Jika pdl tidak memiliki dimensi loop, dalam loop thread pdl ini diperlakukan seolah-olah
memiliki dimensi dummy dengan ukuran yang sama dengan ukuran dimensi loop itu.

R5 Jika output auto-creation digunakan (dengan mengatur pdl yang relevan ke "PDL->null" sebelum
doa) jumlah dimensi pdl yang dibuat sama dengan jumlah dari
jumlah dimensi output inti + jumlah dimensi loop. Ukuran inti
dimensi output berasal dari dimensi yang relevan dari input pdls (seperti yang ditentukan
dalam definisi fungsi) dan ukuran dimensi lain sama dengan
ukuran dimensi loop itu berasal dari. Pdl yang dibuat secara otomatis adalah
fisik (kecuali aliran data sedang beroperasi).

Dalam konteks ini, perhatikan bahwa Anda dapat mengalami masalah dengan penugasan ke pdls yang mengandung
lebih besar dari satu dimensi dummy (lihat di atas). Meskipun pdl keluaran Anda tidak mengandung
dimensi dummy apa pun di tempat pertama mereka mungkin berakhir dengan dummy yang dibuat secara implisit
dimensi menurut R4.

Sebagai contoh, misalkan kita memiliki fungsi PP (di sini tidak ditentukan) dengan tanda tangan:

fungsi((m,n),(m,n,o),(m),[o](m,o))

dan Anda menyebutnya dengan 3 pdls "a(5,3,10,11)", "b(5,3,2,10,1,12)", dan "c(5,1,11,12)" sebagai

fungsi($a,$b,$c,($d=null))

maka jumlah dimensi loop adalah 3 (dengan "R0+R1" dari $b dan $c) dengan ukuran
"(10,11,12)" (oleh R2); dua dimensi inti keluaran adalah "(5,2)" (dari tanda tangan
func) menghasilkan keluaran 5 dimensi pdl $c dengan ukuran "(5,2,10,11,12)" (lihat R5) dan
(yang dibuat secara otomatis) $d diturunkan dari "($a,$b,$c)" dengan cara yang dapat diekspresikan
dalam kode semu pdl sebagai

$d(:,:,i,j,k) .= func($a(:,:,i,j),$b(:,:,:,i,0,k),$c(:, 0,j,k))
dengan 0<=i<10, 0<=j<=11, 0<=k<12

Jika kami menganalisis konversi warna ke skala abu-abu lagi dengan mempertimbangkan aturan ini, kami mencatat
keuntungan besar lain dari threading implisit. Kita dapat memanggil konversi dengan pdl
mewakili piksel (im(3)), garis piksel rgb ("im(3,x)"), gambar berwarna yang tepat
("im(3,x,y)") atau seluruh tumpukan gambar RGB ("im(3,x,y,z)"). Selama $im adalah dari
bentuk "(3,...)" output pdl yang dibuat secara otomatis akan berisi jumlah yang tepat dari
dimensi dan berisi data intensitas seperti yang kita harapkan sejak loop telah
dilakukan secara implisit berkat implisit threading. Anda dapat dengan mudah meyakinkan diri sendiri bahwa
memanggil dengan piksel warna $abu-abu adalah 0D, dengan garis ternyata 1D abu-abu(x), dengan gambar
kami mendapatkan "abu-abu(x,y)" dan akhirnya kami mendapatkan tumpukan gambar yang dikonversi "abu-abu(x,y,z)".

Mari kita isi aturan umum ini dengan lebih banyak kehidupan dengan melewati beberapa langkah lebih lanjut
contoh. Pembaca dapat mencoba untuk mencari tahu formulasi setara dengan eksplisit for-
perulangan dan bandingkan fleksibilitas rutinitas tersebut menggunakan threading implisit ke
formulasi eksplisit. Selain itu, terutama saat menggunakan beberapa dimensi utas, ini adalah
latihan yang berguna untuk memeriksa kecepatan relatif dengan melakukan beberapa tes benchmark (yang masih kami lakukan
harus dilakukan).

Pertama di baris adalah contoh centroid yang sedikit dikerjakan ulang, sekarang dikodekan dengan threading in
pikiran.

# mult berulir untuk menghitung koordinat centroid, berfungsi untuk tumpukan juga
$xc = sumover(($im*xvals(($im->dims)[0]))->rumpun(2)) /
sumover($im->rumpun(2));

Mari kita menganalisis apa yang terjadi langkah demi langkah. Pertama produk:

$prod = $im*xvals(nol(($im->redup)[0]))

Ini benar-benar akan bekerja untuk $im menjadi satu, dua, tiga, dan dimensi yang lebih tinggi. Jika $im adalah
satu dimensi itu hanya produk biasa (dalam arti bahwa setiap elemen $im adalah
dikalikan dengan masing-masing elemen "xvals(...)"), jika $im memiliki lebih banyak dimensi
threading lebih lanjut dilakukan dengan menambahkan dimensi dummy yang sesuai ke "xvals(...)"
sesuai R4. Lebih penting lagi, dua operasi sumover menunjukkan contoh pertama bagaimana
untuk menggunakan perintah manipulasi dimensi. Sekilas tentang tanda tangan sumover
akan mengingatkan Anda bahwa itu hanya akan "melahap" dimensi pertama dari pdl input yang diberikan.
Tetapi bagaimana jika kita ingin benar-benar menghitung jumlah semua elemen dari dua yang pertama?
ukuran? Yah, tidak ada yang menghalangi kita untuk melewati pdl virtual ke sumover yang dalam hal ini
case dibentuk dengan mengelompokkan dua dimensi pertama dari "pdl induk" menjadi satu. Dari
sudut pandang pdl induk, jumlah sekarang dihitung selama dua dimensi pertama,
seperti yang kita inginkan, meskipun sumover baru saja melakukan pekerjaan seperti yang ditentukan oleh tanda tangannya. Telah mendapatkan
dia ?

Kemahiran kecil lain menulis kode seperti itu: kami sengaja menggunakan
"sumover($pdl->rumpun(2))" alih-alih "sum($pdl)" sehingga kita hanya dapat melewatkan sebuah gambar
"(x,y)" atau setumpuk gambar "(x,y,t)" ke dalam rutinitas ini dan dapatkan salah satunya
koordinat-x atau vektor koordinat-x (berukuran t) sebagai gantinya.

Serangkaian operasi umum lainnya adalah apa yang bisa disebut "operasi proyeksi". Ini
operasi mengambil pdl ND sebagai input dan mengembalikan pdl "yang diproyeksikan" (N-1)-D. Operasi ini
sering dilakukan dengan fungsi seperti sumover, prodover, minimum dan maksimum. Menggunakan
lagi gambar sebagai contoh kami mungkin ingin menghitung nilai piksel maksimum untuk setiap baris
dari gambar atau tumpukan gambar. Kami tahu bagaimana melakukannya

# maxima baris (sebagai fungsi dari nomor baris dan waktu)
maksimum($tumpukan,($ret=null));

Tetapi bagaimana jika Anda ingin menghitung maxima per kolom ketika threading implisit selalu berlaku?
fungsionalitas inti ke dimensi pertama dan utas di atas semua yang lain? Bagaimana kita bisa
mencapai itu alih-alih fungsionalitas inti diterapkan ke dimensi kedua dan
threading dilakukan di atas yang lain. Bisakah Anda menebaknya? Ya, kami membuat pdl virtual yang memiliki
dimensi kedua dari "pdl induk" sebagai dimensi pertama menggunakan perintah "mv".

# maxima kolom (sebagai fungsi dari jumlah kolom dan waktu)
maksimum($stack->mv(1,0),($ret=null));

dan menghitung semua jumlah sub-irisan pada dimensi ketiga sekarang hampir terlalu mudah

# jumlah piksel dalam waktu (dengan asumsi waktu adalah redup ketiga)
sumover($stack->mv(2,0),($ret=null));

Terakhir, jika Anda ingin menerapkan operasi ke semua elemen (seperti maks di semua elemen atau
jumlah semua elemen) terlepas dari dimensi pdl yang dimaksud "rumpun" datang
berguna. Sebagai contoh lihat definisi "jumlah" (sebagaimana didefinisikan dalam "Ufunc.pm"):

jumlah tambahan {
PDL::Ufunc::sumover($name->clump(-1),($tmp=null));
kembali $tmp->at(); # kembalikan nomor Perl, bukan pdl 0D
}

Kami telah menyebutkan bahwa semua operasi dasar mendukung threading dan penugasan tidak
pengecualian. Jadi, inilah beberapa tugas berulir

pdl> $im = nol(byte, 10,20)
pdl> $baris = exp(-rval(10)**2/9)
# tugas berulir
pdl> $im .= $line # atur setiap baris $im ke $line
pdl> $im2 .= 5 # setel setiap elemen $im2 ke 5

Sekarang Anda mungkin melihat cara kerjanya dan apa fungsinya, bukan?

Untuk menyelesaikan contoh dalam paragraf ini di sini adalah fungsi untuk membuat gambar RGB dari
apa yang disebut gambar palet. Gambar palet terdiri dari dua bagian: gambar
indeks ke dalam tabel pencarian warna dan tabel pencarian warna itu sendiri. [jelaskan caranya
bekerja ] Kami akan menggunakan fungsi PP yang belum kami temukan sebelumnya
contoh. Ini adalah fungsi indeks bernama tepat, tanda tangan "((n),(),[o]())" (lihat Lampiran
B) dengan fungsionalitas inti bahwa "index(pdl (0,2,4,5),2,($ret=null))" akan mengembalikan
elemen dengan indeks 2 pdl input pertama. Dalam hal ini, $ret akan berisi nilai 4.
Jadi inilah contohnya:

# pencarian indeks berulir untuk menghasilkan gambar RGB, atau RGBA atau YMCK
# dari gambar palet (diwakili oleh tabel pencarian $palette dan
# gambar indeks warna $im)
#bisa dibilang adil boneka(0) karena aturan threading membuatnya cocok
pdl> indeks($palette->xchg(0,1),
$im->long->dummy(0,($palette->dim)[0]),
($res=null));

Mari kita membahasnya dan menjelaskan langkah-langkah yang terlibat. Dengan asumsi kita berhadapan dengan RGB
tabel pencarian $palette berukuran "(3,x)". Pertama kita bertukar dimensi palet
sehingga perulangan dilakukan pada dimensi pertama $palette (ukuran 3 yang mewakili r,
komponen g, dan b). Sekarang melihat $im, kami menambahkan dimensi dummy dengan ukuran yang sama dengan
panjang jumlah komponen (dalam kasus yang kita bahas di sini kita bisa saja
menggunakan nomor 3 karena kami memiliki 3 komponen warna). Kita bisa menggunakan dimensi dummy karena
untuk komponen warna merah, hijau dan biru kami menggunakan indeks yang sama dari gambar aslinya,
misalnya dengan asumsi piksel tertentu $im memiliki nilai 4 maka pencarian harus menghasilkan
rangkap tiga

[palet(0,4),palet(1,4),palet(2,4)]

untuk komponen merah, hijau dan biru baru dari gambar keluaran. Semoga saat ini kamu sudah
semacam ide apa yang seharusnya dilakukan oleh potongan kode di atas (seringkali sebenarnya
cukup rumit untuk menjelaskan secara rinci bagaimana sepotong kode threading bekerja; lanjutkan saja
dan bereksperimen sedikit untuk mendapatkan perasaan yang lebih baik untuk itu).

Jika Anda telah membaca aturan threading dengan cermat, maka Anda mungkin telah memperhatikan bahwa kami tidak melakukannya
harus secara eksplisit menyatakan ukuran dimensi dummy yang kita buat untuk $im; ketika kita
buat dengan ukuran 1 (default) aturan threading membuatnya otomatis sesuai
ukuran yang diinginkan (dengan aturan R3, dalam contoh kita ukurannya adalah 3 dengan asumsi palet dari
ukuran "(3,x)"). Karena situasi seperti ini sering terjadi dalam praktik, inilah alasannya
aturan R3 telah diperkenalkan (bagian yang membuat dimensi ukuran 1 pas dengan utas
lingkaran ukuran redup). Jadi kita hanya bisa mengatakan

pdl> index($palette->xchg(0,1),$im->long->boneka(0),($res=null));

Sekali lagi, Anda dapat meyakinkan diri sendiri bahwa rutinitas ini akan menghasilkan output yang tepat jika dipanggil
dengan piksel ($im adalah 0D), garis ($im adalah 1D), gambar ($im adalah 2D), ..., pencarian RGB
tabel (palet adalah "(3,x)") dan tabel pencarian RGBA (palet adalah "(4,x)", lihat misalnya OpenGL).
Fleksibilitas ini dicapai dengan aturan threading yang dibuat untuk melakukan yang benar
hal dalam kebanyakan situasi.

Untuk membungkus semuanya sekali lagi, ide umumnya adalah sebagai berikut. Jika Anda ingin mencapai
perulangan di atas dimensi tertentu dan memiliki inti fungsi diterapkan ke yang lain
set dimensi tertentu Anda menggunakan perintah manipulasi dimensi untuk membuat (atau
beberapa) maya pdl(s) sehingga dari sudut pandang induk pdl (s) Anda mendapatkan apa
yang Anda inginkan (selalu memiliki tanda tangan dari fungsi yang bersangkutan dan mempertimbangkan R1-R5!).
Mudah, bukan?

Keluaran pembuatan otomatis dan PP-fungsi panggilan konvensi
Pada titik ini kita harus mengalihkan ke beberapa detail teknis yang berkaitan dengan jenderal
konvensi pemanggilan fungsi-PP dan pembuatan argumen keluaran secara otomatis.
Pada dasarnya, ada dua cara untuk memanggil rutin pdl, yaitu

$hasil = func($a,$b);

dan

func($a,$b,$hasil);

Jika Anda hanya menggunakan threading implisit maka variabel output dapat secara otomatis
dibuat oleh PDL. Anda menandainya ke fungsi PP dengan mengatur argumen output ke a
jenis khusus pdl yang dikembalikan dari panggilan ke fungsi "PDL->null" yang mengembalikan
pdl yang pada dasarnya "kosong" (bagi mereka yang tertarik dengan detail ada tanda di C pdl
struktur untuk ini). Dimensi pdl yang dibuat ditentukan oleh aturan
threading implisit: dimensi pertama adalah dimensi keluaran inti yang
dimensi ulir ditambahkan (yang pada gilirannya ditentukan oleh dimensi
masukan pdls seperti dijelaskan di atas). Jadi kamu bisa bilang

func($a,$b,($result=PDL->null));

or

$hasil = fungsi($a,$b)

yang mana persis setara.

Diperingatkan bahwa Anda bisa tidak gunakan pembuatan otomatis keluaran saat menggunakan threading eksplisit (untuk
alasan yang dijelaskan di bagian berikut tentang eksplisit threading, varian kedua dari
benang).

Dalam loop "ketat" Anda mungkin ingin menghindari pembuatan implisit dari pdl sementara di
setiap langkah loop yang datang bersama dengan gaya "fungsional" melainkan katakan

# buat output pdl dengan ukuran yang sesuai hanya pada permintaan pertama
$hasil = nol;
untuk (0...$n) {
func($a,$b,$hasil); # semuanya kecuali permintaan pertama $result
fungsi2($b); # didefinisikan dan memiliki ukuran yang tepat untuk
# ambil output asalkan redup $b tidak berubah
twiddle($hasil,$a); # lakukan sesuatu dari $result hingga $a untuk iterasi
}

Pesan yang dapat dibawa pulang dari bagian ini sekali lagi: waspadai keterbatasan output
kreasi saat menggunakan eksplisit threading.

Eksplisit threading
Sejauh ini hanya berbicara tentang rasa pertama dari threading, sekarang saatnya untuk
memperkenalkan varian kedua. Alih-alih mengacak-acak dimensi sepanjang waktu dan
mengandalkan aturan threading implisit untuk menyelesaikannya dengan baik, terkadang Anda mungkin ingin
tentukan dengan cara yang lebih eksplisit bagaimana melakukan loop utas. Mungkin tidak terlalu
mengejutkan bahwa varian game ini disebut eksplisit threading. Sekarang, sebelum kita
buat kesan yang salah: tidak juga implisit or eksplisit; dua rasa itu
mencampur. Selengkapnya lain waktu.

Dua fungsi yang paling sering digunakan dengan threading eksplisit adalah thread dan unthread. Kami mulai
dengan contoh yang menggambarkan penggunaan tipikal dari yang pertama:

[ # ** ini adalah contoh terburuk yang mungkin untuk memulai ]
# tetapi dapat digunakan untuk menunjukkan bahwa $mat += $line berbeda dari
# $mat->benang(0) += $baris
# threading eksplisit untuk menambahkan vektor ke setiap kolom matriks
pdl> $mat = nol(4,3)
pdl> $baris = pdl (3.1416,2,-2)
pdl> ($tmp = $mat->benang(0)) += $baris

Dalam contoh ini, "$mat->benang(0)" memberi tahu PDL bahwa Anda menginginkan dimensi kedua ini
pdl untuk diulir terlebih dahulu yang mengarah ke loop utas yang dapat dinyatakan sebagai

untuk (j=0; j<3; j++) {
untuk (i=0; i<4; i++) {
mat(i,j) += src(j);
}
}

"utas" mengambil daftar angka sebagai argumen yang secara eksplisit menentukan dimensi mana yang akan
benang lebih dulu. Dengan diperkenalkannya threading eksplisit, dimensi pdl adalah:
secara konseptual dibagi menjadi tiga kelompok yang berbeda, dua yang terakhir telah kita miliki
ditemui: dimensi ulir, dimensi inti, dan dimensi ekstra.

Secara konseptual, yang terbaik adalah memikirkan dimensi pdl yang telah ditentukan dalam
panggilan ke "utas" sebagai diambil dari himpunan dimensi normal dan memakai a
tumpukan terpisah. Jadi dengan asumsi kita memiliki pdl "a(4,7,2,8)" mengatakan

$b = $a->utas(2,1)

membuat pdl virtual baru dengan dimensi "b(4,8)" (yang kami sebut sisa redup) yang
juga memiliki 2 dimensi benang ukuran "(2,7)". Untuk keperluan dokumen ini kami menulis
yang secara simbolis sebagai "b(4,8){2,7}". Perbedaan penting dengan contoh sebelumnya di mana
hanya threading implisit yang digunakan adalah fakta bahwa dimensi inti dicocokkan
itu yang tersisa ukuran yang belum tentu merupakan dimensi pertama dari pdl. Kami
sekarang akan menentukan bagaimana kehadiran dimensi utas mengubah aturan R1-R5 untuk utas
loop (yang berlaku untuk kasus khusus di mana tidak ada argumen pdl yang memiliki utas
ukuran).

Dimensi inti T0 dicocokkan dengan n pertama yang tersisa ukuran dari pdl
argumen (perhatikan perbedaannya dengan R1). Lebih jauh yang tersisa ukuran adalah tambahan
ukuran dan digunakan untuk menentukan implisit lingkaran ukuran.

T1a Banyaknya implisit lingkaran ukuran sama dengan jumlah maksimum ekstra
dimensi diambil alih set argumen pdl.

T1b Banyaknya eksplisit lingkaran ukuran sama dengan jumlah maksimum utas
dimensi diambil alih set argumen pdl.

T1c Jumlah total lingkaran ukuran sama dengan jumlah eksplisit lingkaran ukuran
dan implisit lingkaran ukuran. Dalam lingkaran benang, eksplisit lingkaran ukuran adalah
diulir terlebih dahulu diikuti oleh implisit lingkaran ukuran.

T2 Ukuran masing-masing lingkaran ukuran diturunkan dari ukuran masing-masing
dimensi argumen pdl. Itu diberikan oleh ukuran maksimal yang ditemukan di setiap pdls
memiliki dimensi utas ini (untuk eksplisit lingkaran ukuran) atau dimensi ekstra (untuk
implisit lingkaran ukuran).

T3 Aturan ini berlaku untuk semua eksplisit lingkaran dimensi serta apapun implisit lingkaran
dimensi. Untuk semua pdls yang telah diberikan benang/tambahan dimensi ukurannya harus
sama dengan ukuran masing-masing eksplisit/implisit lingkaran dimensi atau 1; jika tidak
Anda meningkatkan pengecualian runtime. Jika ukuran benang/tambahan dimensi dari pdl adalah satu
itu secara implisit diperlakukan sebagai dimensi dummy dengan ukuran yang sama dengan eksplisit/implisit
lingkaran dimensi.

T4 Jika pdl tidak memiliki benang/tambahan dimensi yang sesuai dengan
eksplisit/implisit lingkaran dimensi, dalam loop utas pdl ini diperlakukan seolah-olah memiliki
dimensi dummy dengan ukuran yang sama dengan ukuran dimensi loop itu.

T4a Semua pdls yang memiliki benang ukuran harus memiliki jumlah utas yang sama
ukuran.

T5 Output auto-creation tidak dapat digunakan jika ada argumen pdl yang memiliki benang
ukuran. Jika tidak, R5 berlaku.

Pembatasan yang sama berlaku sehubungan dengan dimensi dummy implisit (dibuat oleh
penerapan T4) sebagaimana telah disebutkan pada bagian threading implisit: jika ada
output pdls memiliki (eksplisit atau implisit dibuat) lebih besar dari satu dimensi dummy a
pengecualian runtime akan dimunculkan.

Mari kita tunjukkan aturan-aturan ini di tempat kerja dalam kasus umum. Misalkan kita memiliki (di sini
tidak ditentukan) PP-fungsi dengan tanda tangan:

fungsi((m,n),(m),(),[o](m))

dan Anda menyebutnya dengan 3 pdls "a(5,3,10,11)", "b(3,5,10,1,12)", "c(10)" dan output pdl
"d(3,11,5,10,12)" (yang bisa di sini tidak dibuat secara otomatis) sebagai

func($a->utas(1,3),$b->utas(0,3),$c,$d->utas(0,1))

Dari tanda tangan fungsi dan panggilan di atas, pdls dibagi menjadi grup berikut:
dimensi inti, ekstra dan utas (ditulis dalam bentuk "pdl(core redup){thread redup}[extra
redup]"):

a(5,10){3,11}[] b(5){3,1}[10,12] c(){}[10] d(5){3,11}[10,12]

Dengan ini untuk membantu kita (secara umum membantu untuk menuliskan argumen seperti ini
ketika Anda mulai bermain dengan threading dan ingin melacak apa yang sedang terjadi) kami
selanjutnya menyimpulkan bahwa jumlah dimensi loop eksplisit adalah 2 (dengan T1b dari $a dan $b)
dengan ukuran "(3,11)" (oleh T2); 2 dimensi loop implisit (dengan T1a dari $b dan $d) dari ukuran
"(10,12)" (oleh T2) dan elemen dihitung dari input pdls dengan cara yang dapat
diekspresikan dalam kode semu pdl sebagai

untuk (l=0;l<12;l++)
untuk (k=0;k<10;k++)
untuk (j=0;j<11;j++) efek memperlakukannya sebagai dummy redup (indeks j)
untuk (i=0;i<3;i++) |
d(i,j,:,k,l) ​​= func(a(:,i,:,j),b(i,:,k,0,l),c(k))

Ugh, contoh ini benar-benar tidak mudah dalam hal pembukuan. Ini berfungsi sebagian besar sebagai
contoh bagaimana mencari tahu apa yang terjadi ketika Anda menemukan tampilan yang rumit
ekspresi. Tapi sekarang saatnya untuk menunjukkan bahwa threading berguna dengan memberi lebih banyak
dari apa yang disebut contoh "praktis" kami.

[ Contoh berikut akan membutuhkan beberapa penjelasan tambahan di masa mendatang. Untuk
saat silakan coba hidup dengan komentar di fragmen kode. ]

Contoh 1:

*** kebalikan dari matriks yang diwakili oleh eigvec dan eigvals
** diberikan matriks simetris M = A^T x diag(lambda_i) x A
** => invers M^-1 = A^T x diag(1/lambda_i) x A
** $tmp pertama = diag(1/lambda_i)*A
** lalu A^T * $tmp dengan produk dalam berulir
# penanganan indeks sehingga matriks dicetak dengan benar di bawah pdl
$inv .= $evecs*0; # cukup salin untuk mendapatkan hasil dengan ukuran yang sesuai
$tmp .= $evecs; # inisialisasi, tidak ada propagasi balik
($tmp2 = $tmp->benang(0)) /= $evals; # divisi berulir
# dan sekarang perkalian matriks yang menyamar
PDL::Primitif::dalam($evecs->xchg(0,1)->utas(-1,1),
$tmp->utas(0,-1),
$inv->utas(0,1));
# alternatif untuk mult matriks menggunakan threading implisit,
# xchg pertama hanya untuk transpos
PDL::Primitif::inner($evecs->xchg(0,1)->boneka(1)
$tmp->xchg(0,1)->boneka(2)
($inv=null));

Contoh 2:

# produk luar dengan perkalian berulir
# tekankan bahwa kita perlu melakukannya dengan panggilan eksplisit ke my_biop1
# saat menggunakan threading eksplisit
$res=zeroes(($a->redup)[0],($b->redup)[0]);
my_biop1($a->thread(0,-1),$b->thread(-1,0),$res->(0,1),"*");
# hal serupa dengan threading implisit dengan pdl yang dibuat secara otomatis
$res = $a->boneka(1) * $b->boneka(0);

Contoh 3:

# perbedaan penggunaan utas dan utas untuk mengacak sejumlah
# dimensi sekaligus tanpa banyak panggilan ke ->xchg dan ->mv

# gunakan utas/unthread untuk mengacak dimensi
# coba saja dan bandingkan pdl anak dengan induknya
$trans = $a->thread(4,1,0,3,2)->unthread;

Contoh 4:

# menghitung beberapa kotak pembatas
# $bb akan menahan BB sebagai [xmin,xmax],[ymin,ymax],[zmin,zmax]
# kami menggunakan lagi utas dan utas untuk mengacak dimensi di sekitar
pdl> $bb = nol(ganda, 2,3 );
pdl> minimum($vertices->benang(0)->rumpun->lepaskan benangnya(1), $bb->slice('(0),:'));
pdl> maksimum($simpul->benang(0)->rumpun->lepaskan benangnya(1), $bb->slice('(1),:'));

Contoh 5:

# menghitung urutan gambar yang dijatah sendiri (yaitu dinormalisasi sendiri)
# menggunakan threading eksplisit dan divisi threaded secara implisit
$tumpukan = read_image_stack();
# hitung rata-rata (rata-rata per piksel) dari $n+1 gambar pertama
$aver = nol([tumpukan->redup]->[0,1]); # buat outputnya pdl
sumover($stack->slice(":,:,0:$n")->thread(0,1),$aver);
$rata /= ($n+1);
$tumpukan /= $aver; # normalkan tumpukan dengan melakukan pembagian berulir
# implisit versus eksplisit
# sebagai alternatif hitung $aver dengan threading implisit dan pembuatan otomatis
sumover($stack->slice(":,:,0:$n")->mv(2,0),($aver=null));
$rata /= ($n+1);
#

Implisit lawan eksplisit threading
Dalam paragraf ini kita akan mengilustrasikan kapan threading eksplisit lebih disukai daripada
threading implisit dan sebaliknya. Tapi sekali lagi, ini mungkin bukan cara terbaik
letakkan kasusnya karena Anda sudah tahu: kedua rasa itu bercampur. Jadi, ini lebih tentang bagaimana
untuk mendapatkan yang terbaik dari kedua dunia dan, bagaimanapun, dalam tradisi Perl terbaik: TIMTOWTDI !

[ Maaf, ini masih harus diisi di rilis berikutnya; baik merujuk ke contoh di atas
atau pilih yang baru ]

Akhirnya, ini mungkin tempat yang baik untuk membenarkan semua detail teknis yang telah kita lalui
tentang untuk beberapa halaman: mengapa threading ?

Nah, kode yang menggunakan threading harus (jauh) lebih cepat daripada kode yang menggunakan
for-loop eksplisit (atau konstruksi Perl serupa) untuk mencapai fungsionalitas yang sama.
Terutama pada superkomputer (dengan fasilitas komputasi vektor/pemrosesan paralel) PDL
threading akan diimplementasikan dengan memanfaatkan fasilitas tambahan
dari mesin-mesin ini. Selain itu, ini adalah konstruksi yang secara konseptual sederhana (meskipun teknis)
detail mungkin terlibat di kali) dan dapat sangat mengurangi kompleksitas sintaksis dari
Kode PDL (tetapi ingatlah peringatan untuk dokumentasi). Setelah Anda merasa nyaman
pada pengatur terkenal. Pengatur ini menawarkan bantuan hukum kepada traderapabila trader berselisih dengan broker yang terdaftar dengan mereka. threading cara berpikir (dan coding) seharusnya tidak terlalu sulit untuk
memahami kode yang telah ditulis orang lain (asalkan dia memberi Anda gambaran tentang apa?
dimensi input yang diharapkan adalah, dll.). Sebagai tip umum untuk meningkatkan kinerja Anda
kode: jika Anda harus memasukkan loop ke dalam kode Anda, coba rumuskan ulang masalahnya, jadi
bahwa Anda dapat menggunakan threading untuk melakukan loop (seperti apa pun ada pengecualian untuk
aturan praktis ini; tetapi penulis dokumen ini cenderung berpikir bahwa ini jarang terjadi
kasus ;).

PDL::PP


An Mudah cara untuk menetapkan fungsi bahwa adalah sadar of Indeksasi dan threading (Dan itu alam semesta dan
semuanya)
PDL:PP adalah bagian dari distribusi PDL. Hal ini digunakan untuk menghasilkan fungsi yang menyadari
pengindeksan dan aturan threading dari deskripsi yang sangat ringkas. Ini dapat berguna bagi Anda jika
Anda ingin menulis fungsi Anda sendiri atau jika Anda ingin antarmuka fungsi dari
perpustakaan eksternal sehingga mereka mendukung pengindeksan dan threading (dan mungkin aliran data juga,
lihat PDL::Dataflow). Untuk detail lebih lanjut, periksa PDL::PP.

Lampiran A


affine transformasi - a khusus kelas of sederhana dan kuat transformasi
[ Ini juga sesuatu yang akan ditambahkan dalam rilis mendatang. Apakah kita sudah memiliki jenderal?
make_affine rutin di PDL ? Mungkin saja kami akan merujuk pria lain yang sesuai
halaman dari sini]

Lampiran B


tanda tangan of standard PDL::PP dikompilasi fungsi
Pilihan tanda tangan primitif PDL untuk menunjukkan berapa banyak dimensi yang dikompilasi PP
fungsi melahap (dan karena itu Anda dapat mengetahui apa yang akan diulir). Kebanyakan
fungsi-fungsi itu adalah fungsi dasar yang didefinisikan dalam "primitive.pd"

# fungsi di primitif.pd
#
sumover ((n),[o]())
kelebihan ((n),[o]())
nilai sumbu ((n)) di tempat
dalam ((n),(n),[o]())
luar ((n),(m),[o](n,m))
bagian dalam ((n),(n),(n),[o]())
batin2 ((m),(m,n),(n),[o]())
batin2t ((j,n),(n,m),(m,k),[o]())
indeks (1D,0D,[o])
minimal (1D,[o])
maksimum (1D,[o])
wstat ((n),(n),(),[o],())
tugas ((),())

# operasi dasar
operasi biner ((),(),[o]())
operasi unary ((),[o]())

PENULIS & HAK CIPTA


Hak Cipta (C) 1997 Christian Soeller (c.soeller@auckland.ac.nz) & Tuomas J. Lukka
(lukka@fas.harvard.edu). Seluruh hak cipta. Meskipun ditakdirkan untuk dirilis sebagai halaman manual
dengan distribusi PDL standar, itu bukan domain publik. Izin diberikan kepada
mendistribusikan secara bebas salinan kata demi kata dari dokumen ini asalkan tidak ada modifikasi di luar
pemformatan dibuat, dan bahwa pemberitahuan ini tetap utuh. Anda diizinkan dan
didorong untuk menggunakan kode dan turunannya dalam kode sumber Anda sendiri untuk bersenang-senang atau untuk
keuntungan sesuai keinginan Anda.

Gunakan PDL::Indexingp online menggunakan layanan onworks.net



Program online Linux & Windows terbaru