این دستور PDL::Indexingp است که می تواند در ارائه دهنده هاست رایگان OnWorks با استفاده از یکی از چندین ایستگاه کاری آنلاین رایگان ما مانند Ubuntu Online، Fedora Online، شبیه ساز آنلاین ویندوز یا شبیه ساز آنلاین MAC OS اجرا شود.
برنامه:
نام
PDL::Indexing - مقدمه ای بر نمایه سازی و برش پیدل ها.
بررسی اجمالی
این صفحه مرد باید بهعنوان اولین آموزش در مورد ویژگیهای نمایهسازی و رشتهسازی باشد
PDL.
مانند همه زبانهای برداری، PDL با استفاده از یک نوع از آرایهها را خودکار میکند
نماد برداری ریاضی حلقه خودکار تا حدی "threading" نامیده می شود
زیرا در نهایت PDL پردازش موازی را برای سرعت بخشیدن به حلقه ها پیاده سازی می کند.
بسیاری از انعطافپذیری و قدرت PDL به ویژگیهای نمایهسازی و رشتهسازی متکی است.
پسوند پرل نمایه سازی امکان دسترسی به داده های یک piddle را به صورت بسیار انعطاف پذیر می دهد
مسیر. Threading بردارسازی کارآمد عملیات ساده را فراهم می کند.
مقادیر یک piddle به صورت فشرده به عنوان مقادیر تایپ شده در یک بلوک از حافظه ذخیره می شوند.
نه (مثل یک لیست معمولی پرل) به عنوان اسکالرهای پرل.
در بخشهایی که دنبال میشوند بسیاری از "روشها" فراخوانی میشوند -- اینها عملگرهای Perl هستند که
برای PDL ها اعمال شود. از پوسته perldl (یا pdl2)، می توانید در مورد هر روش اطلاعات بیشتری کسب کنید
با تایپ "?" به دنبال آن نام روش.
بعد liste
یک piddle (متغیر PDL)، به طور کلی، یک آرایه N بعدی است که در آن N می تواند 0 باشد (برای یک
اسکالر)، 1 (مثلاً برای نمونه صدا)، یا مقادیر بالاتر برای تصاویر و پیچیده تر
سازه های. هر بعد از piddle دارای یک اندازه صحیح مثبت است. "پرل"
مفسر هر پیدل را به عنوان نوع خاصی از اسکالر پرل (یک شی پرل مبارک،
در واقع -- اما برای استفاده از آنها لازم نیست این را بدانید) که می توانند در هر جایی که بتوانید استفاده کنید
یک اسکالر معمولی قرار دهید
شما می توانید به ابعاد یک piddle به عنوان یک لیست پرل دسترسی داشته باشید و در غیر این صورت اندازه را تعیین کنید
یک پیدل با چندین روش موارد مهم عبارتند از:
nelem - تعداد کل عناصر در یک PDL
ndims - تعداد ابعاد یک PDL را برمی گرداند
dims - لیست ابعاد یک PDL را به عنوان لیست پرل برمی گرداند
dim - اندازه یک بعد خاص از یک PDL را برمی گرداند
نمایه سازی و گردش داده ها
PDL مفهوم "جریان داده" را بین یک piddle و زیر فیلدهای نمایه شده آن حفظ می کند
چاک زدن هنگامی که یک زیرفیلد نمایه شده یا عنصر واحد از یک piddle والد را تولید می کنید،
فرزند و والدین تا زمانی که آنها را به صورت دستی جدا نکنید، متصل می مانند. این به شما اجازه می دهد
همان داده ها را به روش های مختلف در کد خود نشان دهید -- برای مثال، می توانید در نظر بگیرید
یک تصویر RGB به طور همزمان به عنوان مجموعه ای از مقادیر (R,G,B) در یک تصویر 3×1000×1000،
و به صورت سه صفحه رنگی 1000×1000 جداگانه که در متغیرهای مختلف ذخیره می شوند. در حال اصلاح
هر یک از متغیرها حافظه اصلی را تغییر می دهد و تغییرات در همه آنها منعکس می شود
نمایش داده ها
دو روش مهم وجود دارد که به شما امکان می دهد اتصالات جریان داده بین یک کودک را کنترل کنید
و PDL والد:
کپی - یک کپی صریح از یک PDL را مجبور می کند
Server - اتصال جریان داده بین یک PDL و والدین آن را قطع می کند (در صورت وجود)
نخ کشی و بعد سفارش
اکثر عملیات PDL بر روی چند بعد اول آرگومان های piddle خود عمل می کنند. برای
به عنوان مثال، "sumover" تمام عناصر را در امتداد بعد اول در لیست (بعد 0) جمع می کند.
اگر در یک پیدل سه بعدی تغذیه کنید، بعد اول در نظر گرفته می شود
بعد "فعال" و ابعاد بعدی، ابعاد "نخ" هستند زیرا هستند
به سادگی حلقه شد راه های مختلفی برای جابجایی یا ترتیب مجدد لیست ابعاد وجود دارد
یک PDL این تکنیکها بسیار سریع هستند، زیرا فقط به دادههای زیربنایی دست نمیزنند
نحوه دسترسی PDL به داده ها را تغییر دهید. توابع سفارش ابعاد اصلی عبارتند از:
mv - یک بعد خاص را به جای دیگری در لیست ابعاد منتقل می کند
xchg - دو بعد را در لیست ابعاد رد و بدل می کند و بقیه را به حال خود رها می کند
سفارش مجدد - امکان اختلاط عمده ابعاد را فراهم می کند
clump - دو یا چند بعد کوچک را به هم متصل می کند و به یک بعد بزرگتر تبدیل می کند
فشار دادن - هر ابعادی از اندازه 1 را حذف می کند
فیزیکی و ساختگی ابعاد
· سند رشته سطح پرل
· رشته ها
· به روز رسانی و شرح صحیح از برش
· توابع جدید در slice.pd (affine، lag، splitdim)
· بازکاری پاراگراف در مورد نخ صریح
نمایه سازی و نخ با PDL
بسیاری از انعطافپذیری و قدرت PDL به ویژگیهای نمایهسازی و حلقهای بستگی دارد
پسوند پرل نمایه سازی امکان دسترسی به داده های یک شی pdl را به صورت بسیار انعطاف پذیر می دهد
مسیر. Threading عملکرد حلقه ضمنی کارآمد را فراهم می کند (از آنجایی که حلقه ها هستند
به عنوان کد C بهینه سازی شده پیاده سازی شده است).
اشیاء Pdl (که بعداً اغلب "pdls" نامیده می شوند) اشیاء پرل هستند که چند بعدی را نشان می دهند.
آرایه ها و عملیات روی آن ها بر خلاف ساده Perl @x استایل داده های آرایه را فهرست می کند
به طور فشرده در یک بلوک حافظه ذخیره می شود و بنابراین حافظه بسیار کمتری را اشغال می کند
امکان استفاده از کد C سریع برای اجرای عملیات (به عنوان مثال افزودن، و غیره) در pdls.
pdls می توان داشته باشد فرزندان
در بسیاری از قابلیت های نمایه سازی PDL، رابطه "والد" و
"کودک" بین pdls. بسیاری از دستورات نمایه سازی یک pdl جدید از یک pdl موجود ایجاد می کنند.
pdl جدید «فرزند» و قدیم «والد» است. داده های pdl جدید است
با تبدیلی تعریف می شود که نحوه تولید (محاسبه) داده های آن را مشخص می کند
داده های والدین رابطه بین pdl فرزند و والد آن اغلب دو طرفه است،
به این معنی که تغییرات در داده های کودک به والدین منتقل می شود. (توجه: شما
ببینید، ما در اصطلاح خود از قبل به سمت ویژگیهای جدید جریان داده میرویم. نوع
جریان داده ای که توسط دستورات نمایه سازی استفاده می شود (که در عرض یک دقیقه در مورد آن خواهید آموخت)
همیشه فعال است، نه تنها زمانی که شما به صراحت جریان داده را در pdf خود روشن کرده باشید
با گفتن "$a->doflow". برای اطلاعات بیشتر در مورد جریان داده ها، داده ها را بررسی کنید
صفحه.)
راه دیگری برای تفسیر pdl های ایجاد شده توسط دستورات نمایه سازی ما این است که آنها را به صورت a مشاهده کنیم
نوعی اشاره گر هوشمند که به بخشی یا تمام داده های والد خود اشاره می کند.
بنابراین، جای تعجب نیست که دادههای والدین (یا بخشی از آن) در زمانی تغییر کند
از طریق این "اشاره گر" دستکاری می شود. پس از این سخنان مقدماتی که امیدوارم
شما را برای چیزی که در راه است آماده کردیم (به جای اینکه بیش از حد شما را گیج کنیم) ما قصد داریم شیرجه بزنیم
درست در و با شرح دستورات نمایه سازی و چند مثال معمولی شروع کنید
چگونه می توان از آنها در برنامه های PDL استفاده کرد. اشاره گر/جریان داده را بیشتر توضیح خواهیم داد
قیاس در زمینه برخی از مثال های بعدی.
دو پیاده سازی متفاوت از این رابطه «اشاره گر هوشمند» وجود دارد: اولی
یکی، که کمی کندتر است اما برای هر تغییری کار می کند، به سادگی انجام آن است
تغییر شکل به جلو و عقب در صورت لزوم. دیگر این است که کودک را در نظر بگیرید
piddle یک piddle "مجازی"، که فقط یک اشاره گر به والد و دسترسی را ذخیره می کند
اطلاعات به طوری که روتین هایی که از کودک piddle استفاده می کنند در واقع به طور مستقیم به داده ها دسترسی دارند
در پدر و مادر اگر پیدل مجازی به روتینی داده شود که نمی تواند از آن استفاده کند، PDL
قبل از اینکه به روتین اجازه استفاده از آن را بدهد، به طور شفاف پیدل مجازی را فیزیکی می کند.
در حال حاضر (1.94_01) همه تبدیلهایی که «مرتبط» هستند، یعنی شاخصهای دادهها
آیتم در piddle والد توسط یک تبدیل خطی (+ ثابت) از تعیین می شود
شاخصهای ردپای فرزند منجر به ایجاد شکافهای مجازی میشوند. سایر روال های نمایه سازی (مثلاً
"-> index(...)") منجر به خلل های فیزیکی می شود. همه روتین های کامپایل شده توسط PP می توانند affine را بپذیرند
piddle ها (به جز آن دسته از روتین هایی که نشانگرها را به توابع کتابخانه خارجی ارسال می کنند).
توجه داشته باشید که مرتبط بودن یا نبودن چیزی بر معنایی کاری که انجام می دهید تأثیر نمی گذارد
به هر نحو: هر دو
$a->index(...) .= 5;
$a->slice(...) .= 5;
داده ها را در $a تغییر دهید. با این حال، این تمایل تأثیر قابل توجهی بر حافظه دارد
استفاده و عملکرد
برش pdls
احتمالاً مهمترین کاربرد مفهوم pdls والد/فرزند همان است
نمایش برش های مستطیلی یک pdl فیزیکی توسط یک pdl مجازی. صحبت کردن
در مورد مفاهیم به اندازه کافی طولانی است، اجازه دهید دقیق تر شویم. فرض کنید ما با یک pdl دو بعدی کار می کنیم
نشان دهنده یک تصویر 5x5 (به طور غیرعادی کوچک است به طوری که می توانیم آن را بدون پر کردن چاپ کنیم
چندین صفحه پر از رقم ؛).
pdl> $im = دنباله (5,5،XNUMX)
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> help vars
متغیرهای PDL در بسته اصلی::
نوع نام ابعاد وضعیت جریان مم
-------------------------------------------------- --------------
$im Double D [5,5] P 0.20Kb
[ در اینجا ممکن است مناسب باشد که به سرعت در مورد فرمان "help vars" که ارائه می دهد صحبت کنیم
اطلاعات مربوط به pdls در پوسته تعاملی "perldl" یا "pdl2" همراه با PDL. ]
حالا فرض کنید میخواهیم یک pdl 1 بعدی بسازیم که فقط به یک خط از تصویر اشاره میکند
خط 2؛ یا یک pdl که تمام خطوط زوج تصویر را نشان می دهد (تصور کنید باید با آن سر و کار داشته باشیم
فریم های زوج و فرد از یک تصویر درهم آمیخته به دلیل برخی رفتارهای عجیب قاب ما
گیر). به عنوان یکی دیگر از کاربردهای مکرر برش ها، ممکن است بخواهیم یک pdl ایجاد کنیم که
یک ناحیه مستطیلی از تصویر را با بالا و پایین معکوس نشان می دهد. همه این
افکت ها (و بسیاری موارد دیگر) را می توان به راحتی با عملکرد قدرتمند برش بدست آورد:
pdl> $line = $im->slice(':,(2)')
pdl> $even = $im->slice(':,1:-1:2')
pdl> $area = $im->slice('3:4,3:1')
pdl> help vars # یا فقط PDL->vars
متغیرهای PDL در بسته اصلی::
نوع نام ابعاد وضعیت جریان مم
-------------------------------------------------- --------------
$ even Double D [5,2] -C 0.00Kb
$im Double D [5,5] P 0.20Kb
$line Double D [5] -C 0.00Kb
$area Double D [2,3] -C 0.00Kb
هر سه pdl "کودک" فرزندان $im یا در دیگری هستند (تا حد زیادی معادل)
اشاره گرهای تفسیری به داده های $im. عملیات روی آن pdls مجازی فقط دسترسی دارند
آن بخش از داده ها که توسط آرگومان برش مشخص شده است. بنابراین ما فقط می توانیم چاپ کنیم
خط 2:
pdl> p $line
[10 11 12 13 14 ]
همچنین به تفاوت "وضعیت جریان" $area در بالا و پایین توجه کنید:
pdl> p $area
pdl> help $area
این متغیر Double D [2,3] VC 0.00Kb است
موارد زیر نشان می دهد که $im و $line واقعاً همانطور که از a انتظار دارید رفتار می کنند
شی نشانگر مانند (یا در تصویر جریان داده: تغییرات در داده های $line است
به $im منتشر شد):
pdl> $im++
pdl> p $line
[11 12 13 14 15 ]
pdl> $line += 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 ]
]
توجه داشته باشید که چگونه عملیات انتساب در pdl مجازی فرزند، pdl فیزیکی والد را تغییر می دهد
و بالعکس (اما، تخصیص اولیه "=" ندارد، از ".=" برای به دست آوردن آن اثر استفاده کنید.
دلایل زیر را ببینید). pdlهای فرزند مجازی چیزی شبیه "پیوندهای زنده" هستند
pdl والد "اصلی". همانطور که قبلاً گفته شد، می توان تصور کرد که آنها مشابه a کار می کنند
C-pointer. اما برخلاف C-pointer، اطلاعات بسیار بیشتری را در خود جای می دهند. اولا آنها
ساختار داده هایی را که نشان می دهند (بعدی pdl جدید) مشخص کنید و
در مرحله دوم، نحوه ایجاد این ساختار را از دادههای والدینش مشخص کنید (روشی که این کار میکند
در داخل PDL مدفون است و به هر حال برای شما مهم نیست که بدانید (مگر اینکه شما
می خواهید در آینده هسته اصلی را هک کنید یا به طور کلی می خواهید یک گورو PDL شوید (برای یک
تعریف این موجود عجیب را ببینید PDL::Internals)).
مثال های قبلی استفاده معمولی از تابع slice را نشان داده اند. از آنجا که
عملکرد برش بسیار مهم است در اینجا توضیحی در مورد نحو برای رشته است
آرگومان برای برش:
$vpdl = $a->slice('ind0,ind1...')
که در آن "ind0" مشخص می کند که با شاخص شماره 0 از pdl $a و غیره چه باید کرد. هر عنصر از
لیست جدا شده با کاما می تواند یکی از اشکال زیر را داشته باشد:
':' از کل بعد استفاده کنید
'n' فقط از نمایه "n" استفاده کنید. بعد این شاخص در pdl مجازی حاصل 1 است.
یک مثال شامل آن دو فرمت فهرست اول:
pdl> $column = $im->slice('2,:')
pdl> $row = $im->slice(':,0')
pdl> p $ ستون
[
[3]
[8]
[15]
[18]
[23]
]
pdl> p $row
[
[1 2 3 4 5 ]
]
pdl> help $column
این متغیر Double D [1,5] VC 0.00Kb است
pdl> help $row
این متغیر Double D [5,1] VC 0.00Kb است
'(n)' فقط از نمایه "n" استفاده کنید. این بعد از pdl حاصل حذف می شود (با تکیه بر
این واقعیت که یک بعد از اندازه 1 همیشه قابل حذف است). تمایز بین این
مورد و مورد قبلی در تکالیفی که دست چپ و راست است مهم می شود
طرف باید دارای ابعاد مناسب باشد.
pdl> $line = $im->slice(':,(0)')
pdl> help $line
این متغیر Double D [5] -C 0.00Kb است
pdl> p $line
[1 2 3 4 5 ]
تفاوت را با مثال قبلی ببینید؟
'n1:n2' or 'n1:n2:n3'
محدوده شاخص ها را از "n1" تا "n2" یا (شکل دوم) محدوده
شاخص از "n1" به "n2" با مرحله "n3". مثالی برای استفاده از این فرمت می باشد
تعریف قبلی تصویر فرعی که از خطوط زوج تشکیل شده است.
pdl> $even = $im->slice(':,1:-1:2')
این مثال همچنین نشان می دهد که شاخص های منفی مانند حالت عادی کار می کنند
آرایه های سبک پرل با شمارش معکوس از انتهای بعد. اگر "n2" باشد
کوچکتر از "n1" (در مثال -1 معادل شاخص 4 است) عناصر موجود در
pdl مجازی به طور موثر با توجه به والد خود برگردانده می شوند.
'*[n]'
یک بعد ساختگی اضافه کنید. اندازه این بعد به طور پیش فرض 1 یا برابر خواهد بود
"n" اگر آرگومان عددی اختیاری داده شود.
حالا، این واقعاً در نگاه اول کمی عجیب است. ساختگی چیست
بعد، ابعاد، اندازه؟ بعد ساختگی ابعادی را درج می کند که قبلاً وجود نداشت. چگونه
آیا آن کار انجام شده است؟ خوب، در مورد ابعاد جدید با اندازه 1 می توان آن را به راحتی انجام داد
با روشی که می توانید یک بردار (با عناصر "m") را با an شناسایی کنید توضیح داده شده است
ماتریس "(1،m)" یا "(m،1)". واضح است که همین امر برای اجسام با ابعاد بالاتر صدق می کند.
جالب تر، مورد ابعاد ساختگی با اندازه بزرگتر از یک است (به عنوان مثال
"Slice('*5,:')"). این به همان روشی عمل می کند که فراخوانی به تابع ساختگی ایجاد می کند
یک بعد ساختگی جدید پس ادامه مطلب را بخوانید و توضیح آن را در زیر بررسی کنید.
'([n1:n2[:n3]]=i)'
[هنوز اجرا نشده ??????] با استدلالی از این دست شما می کنید به طور کلی
مورب. قطری بعد شماره خواهد بود. "i" از خروجی جدید pdl و (اگر
قسمت اختیاری در پرانتز مشخص شده) در امتداد دامنه شاخص ها گسترش می یابد
مشخص شده از بعد pdl والد مربوطه. به طور کلی یک استدلال مانند این
تنها زمانی منطقی است که استدلال های دیگری مانند این در همان فراخوانی برای برش وجود داشته باشد.
قسمت داخل پرانتز برای این نوع آرگومان اختیاری است. همه استدلال های این
نوعی که همان بعد هدف "i" را مشخص می کند باید به همان تعداد مربوط باشد
شاخص ها در بعد والد خود. بهترین راه برای توضیح آن احتمالاً دادن یک است
به عنوان مثال، در اینجا ما یک pdl می سازیم که به عناصر در امتداد قطر فضایی اشاره دارد
pdl والد آن (یک مکعب):
مکعب $ = صفر (5,5,5،XNUMX،XNUMX)؛
$sdiag = $cube->slice('(=0),(=0),(=0)');
دستور بالا یک pdl مجازی ایجاد می کند که مورب را در امتداد نشان می دهد
بعد والدین شماره 0، 1 و 2 و بعد آن را 0 (تنها بعد) از
آی تی. اگر اندازه ابعاد والد شما را تعیین می کند، از نحو توسعه یافته استفاده می کنید
می خواهید مورب را از اندازه های مختلف بسازید یا می خواهید آن را برعکس کنید
دنباله ای از عناصر در مورب، به عنوان مثال
$rect = صفر (12,3,5,6,2);
$vpdl = $rect->slice('2:7,(0:1=1),(4),(5:4=1),(=1)');
بنابراین، عناصر $vpdl به روشی که میتوانیم به عناصر والد آن مرتبط میشوند
بیان به صورت:
vpdl(i,j) = rect(i+2,j,4,5-j,j) 0<=i<5, 0<=j<2
[ در تابع نمایه جدید کار کنید: "$b = $a->index($c);" ???? ]
آنجا هستند مختلف انواع of تکالیف in PDL
مثالهای قبلی قبلاً نشان دادهاند که از pdls مجازی میتوان برای کار بر روی یا استفاده کرد
دسترسی به بخش هایی از داده های یک pdl والد. آنها همچنین می توانند به عنوان lvalues در تکالیف استفاده شوند
(همانطور که استفاده از "++" در برخی از مثال های بالا قبلا نشان داده است). برای صریح
انتساب به داده های ارائه شده توسط یک pdl مجازی شما باید از ".=" بیش از حد بارگذاری شده استفاده کنید.
عملگر (که در این زمینه به آن می گوییم تکثیر واگذاری). چرا نمی توانید از آن استفاده کنید
عملگر انتساب عادی "="؟
خوب، شما قطعا هنوز هم می توانید از عملگر '=' استفاده کنید اما آن چیزی که شما می خواهید را انجام نمی دهد. این
به دلیل این واقعیت است که عملگر '=' را نمی توان به همان روش دیگر بارگذاری کرد
اپراتورهای واگذاری اگر سعی کردیم از '=' برای اختصاص داده به بخشی از a استفاده کنیم
pdl فیزیکی از طریق یک pdl مجازی، ما به اثر دلخواه نخواهیم رسید (در عوض
متغیر نشان دهنده pdf مجازی (اشاره به یک چیز مبارک) بعد از
تکلیف فقط شامل ارجاع به چیز مبارک دیگری است که می تواند رفتار کند
تکالیف آینده به عنوان یک کپی «فیزیکی» از rvalue اصلی [این در واقع هنوز نیست
واضح و موضوع بحث در لیست پستی توسعه دهندگان PDL]. از این نظر
اتصال pdl به والد را قطع می کند [ آیا این رفتار به یک معنا نیست
برخلاف آنچه در جریان داده اتفاق می افتد، جایی که ".=" ارتباط با والد را قطع می کند؟ ].
به عنوان مثال
pdl> $line = $im->slice(':,(2)')
pdl> $line = صفر(5)؛
pdl> $line++;
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 $line
[1 1 1 1 1 ]
اما با استفاده از ".="
pdl> $line = $im->slice(':,(2)')
pdl> $line .= صفر(5)
pdl> $line++
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> $line را چاپ کنید
[1 1 1 1 1 ]
همچنین، می توانید جایگزین کنید
pdl> $line .= 0;
برای تخصیص بالا (صفر به یک پیدل اسکالر تبدیل می شود، بدون هیچ ابعادی
می توان آن را به هر پیدلی اختصاص داد).
یکی از ویژگی های خوب در نسخه های اخیر پرل، زیرروال های lvalue است (یعنی نسخه های 5.6.x و
بالاتر از جمله تمام پرل هایی که در حال حاضر توسط PDL پشتیبانی می شوند). که به شخص اجازه می دهد از آن استفاده کند
برش نحو در هر دو طرف تکلیف:
pdl> $im->slice(':,(2)') .= صفر(5)->xvals-> شناور
مربوط به ویژگی انتساب فرعی lvalue یک تله کوچک برای افراد بی احتیاط است: پرل های اخیر
یک "ویژگی" را معرفی کرد که استفاده PDL از lvalue subs را برای تکالیف برش قطع می کند.
در حال اجرا تحت دیباگر perl، "perl -d". در زیر دیباگر، استفاده بالا یک نشان می دهد
خطای مانند: "نمی توان یک زیربرنامه موقت از lvalue را برگرداند..." بنابراین باید از نحو استفاده کنید
مثل این:
pdl> ($pdl = $im->slice(':,(2)')) .= صفر(5)->xvals-> شناور
که هم با و هم بدون دیباگر کار می کند، اما احتمالاً خواندن آن ناشیانه و ناخوشایند است.
توجه داشته باشید که وقتی lvalue و rvalue pdls هستند، ممکن است با انتساب هایی مانند این مشکل وجود داشته باشد
به بخش های همپوشانی داده ها در pdl والد مراجعه کنید:
# عناصر خط اول $a را برگردانید
($tmp = $a->slice(':,(1)')) .= $a->slice('-1:0,(1)');
در حال حاضر، دادههای والد در سمت راست تکالیف قبل از کپی نمیشوند
(داخلی) حلقه تخصیص حاصل می شود. بنابراین، نتیجه این تکلیف بستگی دارد
در ترتیبی که عناصر در آن تخصیص داده می شوند و تقریباً به طور قطع نه کاری که تو
تحت تعقیب. بنابراین معناشناسی در حال حاضر است تعریف نشده در حال حاضر و در هر زمان ممکن است تغییر کند. به
به دست آوردن رفتار مطلوب، استفاده
($tmp = $a->slice(':,(1)')) .= $a->slice('-1:0,(1)')->کپی;
که یک کپی فیزیکی از برش یا
($tmp = $a->slice(':,(1)')) .= $a->slice('-1:0,(1)')->sever;
که همان برش را برمی گرداند اما ارتباط برش را به والد خود قطع می کند.
دیگر توابع که دستکاری ابعاد
پس از صحبت گسترده در مورد عملکرد برش، باید توجه داشت که این چنین نیست
فقط تابع نمایه سازی PDL. توابع نمایه سازی اضافی نیز وجود دارد که مفید هستند
(مخصوصاً در زمینه threading که بعداً در مورد آن صحبت خواهیم کرد). در اینجا یک لیست است
و چند مثال نحوه استفاده از آنها
"ساختگی"
یک بعد ساختگی به اندازه ای که شما مشخص کرده اید (پیش فرض 1) را در مکان انتخابی درج می کند.
شما نمی توانید صبر کنید تا بشنوید که چگونه به دست می آید؟ خوب، همه عناصر با شاخص "(X,x,Y)"
("0<=x
pdl (که در آن "X" و "Y" به گروه شاخص های قبل و بعد از مکان اشاره دارد
جایی که بعد ساختگی درج شده است.)
این مثال مختصات x مرکز یک تصویر را محاسبه می کند (بعداً خواهیم گفت
یاد بگیرید که ما واقعاً به لطف جادوی ضمنی به بعد ساختگی نیاز نداشتیم
نخ زنی اما با استفاده از ابعاد ساختگی، کد در دنیای بدون رشته نیز کار می کند.
اگر چه زمانی که با موضوعات PDL کار کردید، نمی خواهید بدون آنها زندگی کنید
از نو).
# نقطه مرکزی
($xd,$yd) = $im->dims;
$xc = sum($im*xvals(zeroes($xd))-> dummy(1,$yd))/sum($im);
بیایید با کمی جزئیات بیشتر توضیح دهیم که چگونه کار می کند. ابتدا محصول:
xvs $ = xvals (صفر ($xd));
print $xvs->dummy(1,$yd); # خط $yd را بارها تکرار کنید
$prod = $im*xvs->dummy(1,$yd); # محصول مبتنی بر پیکسل را با
# خط مکرر x-value
سپس بقیه نتایج حاصل از محصول پیکسلی را با هم جمع می کند و
نرمال سازی با مجموع تمام مقادیر پیکسل در تصویر اصلی و بدین ترتیب محاسبه می شود
مختصات x "مرکز جرم" تصویر (تفسیر مقادیر پیکسل به صورت
جرم محلی) که به عنوان مرکز تصویر شناخته می شود.
بعد یک تبدیل (از نظر مصرف حافظه) بسیار ارزان از
مقیاس خاکستری تا RGB، یعنی هر پیکسل به جای یک اسکالر، اکنون یک مقدار سه برابری دارد.
خوشبختانه، سه مقدار در سهگانه برای یک تصویر خاکستری یکسان هستند، بنابراین
که ترفند ما به خوبی کار می کند زیرا هر سه عضو سه گانه را به نگاشت می کند
همان عنصر منبع:
# تبدیل ارزان مقیاس خاکستری به RGB
$rgb = $grey->Dummy(0,3)
متأسفانه از این ترفند نمی توان برای تبدیل عکس های قدیمی B/W به رنگی استفاده کرد
به روشی که شما دوست دارید :(
توجه داشته باشید که استفاده از حافظه از piddle ها با ابعاد ساختگی بسیار حساس است
نمایندگی داخلی اگر piddle را می توان به عنوان یک پیوند مجازی نشان داد
("vaffine") piddle، فقط ساختارهای کنترل ذخیره می شوند. اما اگر $b در
$a = صفر(10000)؛
$b = $a->Dummy(1,10000);
توسط برخی از روال فیزیکی ساخته شده است، شما متوجه خواهید شد که استفاده از حافظه برنامه شما
به طور ناگهانی 100 مگابایت افزایش یافته است.
"مورب"
دو بعد را (که باید هم اندازه باشند) با یک بعد جایگزین می کند
به تمام عناصر در امتداد "مورب" در امتداد آن دو بعد اشاره می کند. ما اینجاییم
دو مثال داشته باشید که باید برای هر کسی که تا به حال کارهای خطی انجام داده است آشنا به نظر برسد
جبر ابتدا یک ماتریس وحدت بسازید:
# ماتریس وحدت
$e = صفر (float, 3, 3); # همه چیز را صفر کنید
($tmp = $e->مورب(0,1)) .= 1; # عناصر در امتداد مورب را روی 1 قرار دهید
چاپ $e;
یا مورب دیگر:
($tmp = $e->slice(':-1:0')->مورب(0,1)) .= 2;
چاپ $e;
(آیا متوجه شده اید که چگونه از تابع slice برای برگرداندن دنباله خطوط قبل استفاده کردیم
تنظیم مورب فرزند جدید، در نتیجه تعیین مورب متقاطع از
والد؟) یا نقشه برداری از فضای ماتریس های مورب به میدانی که روی آن
ماتریس ها تعریف می شوند، ردیابی یک ماتریس:
# ردی از یک ماتریس
$trace = sum($mat->مورب(0,1)); # مجموع تمام عناصر مورب
"xchg" و "mv"
xchg دو بعد مشخص شده را مبادله یا "تبدیل" می کند. یک سرراست
مثال:
# انتقال یک ماتریس (بدون تغییر صریح داده ها و
# کپی کردن)
$prod = $ax $a->xchg(0,1);
اگر $a یک ماتریس متعامد باشد، اکنون $prod باید بسیار نزدیک به ماتریس وحدت باشد.
اغلب "xchg" در زمینه نخ استفاده می شود، اما بعداً بیشتر در مورد آن استفاده می شود.
mv به روشی مشابه کار می کند. یک بعد را حرکت می دهد (مشخص شده با شماره آن در
والدین) به یک موقعیت جدید در pdl فرزند جدید:
$b = $a->mv(4,0); # بعد پنجم $a را به اولین بعد تبدیل کنید
# فرزند جدید $b
تفاوت بین "xchg" و "mv" در این است که "xchg" فقط موقعیت دو را تغییر می دهد
ابعاد با یکدیگر، در حالی که "mv" بعد اول را به محل قرار می دهد
دوم، جابجایی ابعاد دیگر بر این اساس.
"توده"
چندین بعد را در یک بعد جمع می کند. تنها آرگومان آن چند بعد را مشخص می کند
pdl منبع باید جمع شود (از اول شروع می شود). یک ( مسلما
غیر واقعی) به عنوان مثال یک Pdl سه بعدی است که داده ها را از پشته ای از فایل های تصویری که شما در اختیار دارید نگه می دارد
با این حال، داده های هر تصویر واقعاً یک زمان 1 بعدی را نشان می دهد
سری و فقط به این دلیل تنظیم شده است که با یک قاب دیجیتالی شده است
غارتگر بنابراین برای داشتن آن دوباره به عنوان یک آرایه از توالی زمانی شما می گویید
pdl> $seqs = $stack->توده(2)
pdl> help vars
متغیرهای PDL در بسته اصلی::
نوع نام ابعاد وضعیت جریان مم
-------------------------------------------------- --------------
$seqs Double D [8000,50] -C 0.00Kb
$stack Double D [100,80,50،3.05،XNUMX] P XNUMX مگابایت
اگرچه غیرواقعی به نظر می رسد، نرم افزار میکروسکوپ کانفوکال ما داده ها را می نویسد (گاهی اوقات)
بدین ترتیب. اما بیشتر اوقات برای دستیابی به یک اثر خاص هنگام استفاده ضمنی از کلوخ استفاده می کنید
یا threading صریح.
تماس ها به نمایه سازی توابع می توان be زنجیر شده
همانطور که ممکن است در برخی از مثال های بالا متوجه شده باشید که توابع نمایه سازی را فراخوانی می کند
را می توان به خوبی زنجیر کرد زیرا همه این توابع یک شی فرزند جدید ایجاد شده را برمی گرداند.
با این حال، هنگام انجام دستکاری های گسترده شاخص در یک زنجیره، مطمئن شوید که چه چیزی را دنبال می کنید
شما انجام می دهید، به عنوان مثال
$a->xchg(0,1)->mv(0,4)
بعد 1 $a را به موقعیت 4 منتقل می کند از زمانی که فرمان دوم اجرا می شود
بعد اصلی 1 به موقعیت 0 فرزند جدید منتقل شده است که "mv" را صدا می کند.
عملکرد. فکر می کنم شما این ایده را دریافت کرده اید (علی رغم توضیحات پیچیده من).
تکثیر شد تکالیف ('.=') و ساختگی ابعاد
یک ویژگی فرعی مربوط به نمایه سازی، انتساب به pdls حاوی ابعاد ساختگی است
اندازه بزرگتر از 1. این تخصیص ها (با استفاده از ".=") به دلیل چندین عنصر ممنوع هستند
از lvalue pdl به همان عنصر والد اشاره می کند. در نتیجه ارزش
آن عناصر والد به طور بالقوه مبهم هستند و به ترتیبی که در آن وجود دارد بستگی دارد
پیاده سازی به عناصر تخصیص می دهد. بنابراین، یک تکلیف مانند این:
$a = pdl [1,2,3،XNUMX،XNUMX];
$b = $a->Dummy(1,4);
$b .= yvals(zeroes(3,4));
می تواند نتایج غیرمنتظره ای ایجاد کند و نتایج به صراحت می باشد تعریف نشده توسط PDL زیرا
هنگامی که PDL ویژگی های محاسباتی موازی را دریافت می کند، نتیجه فعلی ممکن است تغییر کند.
از نقطه نظر جریان داده، معرفی ساختگی با اندازه بزرگتر از یک
ابعاد به عنوان یک دگرگونی برگشت ناپذیر در نظر گرفته می شود (مشابه اصطلاحات در
ترمودینامیک) که مانع از انتشار معکوس انتساب به والدین (که شما
صراحتاً با استفاده از تخصیص ".=" درخواست کرده بود. مشکل مشابهی که باید مراقب آن بود
در زمینه threading رخ می دهد که گاهی اوقات ابعاد ساختگی به طور ضمنی ایجاد می شود
در طول حلقه نخ (به زیر مراجعه کنید).
دلایل برای la والد / فرزند (و یا "نشانگر") مفهوم
[این باید کمی صبر کرد]
XXXXX حافظه کارآمد است
XXXXX در زمینه نخ زنی
XXXXX روش بسیار منعطف و قدرتمند برای دسترسی به بخش هایی از داده های pdl
(به روشی بسیار کلی تر از ثانیه و غیره اجازه می دهد)
XXXXX پیاده سازی کارآمد
XXXXX تفاوت با بخش/در و غیره
چگونه به ساخت اشیاء فیزیکی از نو
[XXXX بعداً وقتی همه چیز کمی حل شد آن را پر کنید]
** در صورت نیاز (عملکرد رابط معمول xsub C lib)
** چگونه به دست آمد (-> فیزیکی)
** نحوه آزمایش (فیزیکی است (در حال حاضر نحوه عملکرد آن را توضیح دهید)
** ->کپی و -> سرور
نخ کشی
در پاراگراف قبلی در مورد نمایه سازی، قبلاً به اصطلاح گاهی اوقات اما اشاره کردیم
اکنون واقعاً زمان آن رسیده است که به صراحت در مورد "نخ زدن" با pdls صحبت کنیم. اصطلاح threading دارد
معانی مختلف در زمینه های مختلف محاسبات. در چارچوب PDL آن
احتمالاً میتواند بهصورت آزادانه به عنوان یک تسهیلات حلقهای ضمنی تعریف شود. ضمنی است زیرا
شما چیزی مانند محصور کردن حلقه های for را مشخص نمی کنید، بلکه حلقه ها به طور خودکار هستند
(یا به صورت جادویی) که توسط PDL بر اساس ابعاد pdls درگیر ایجاد می شود. این
باید به شما یک ایده اولیه بدهد که چرا توابع دستکاری شاخص/بعدی را که ملاقات کرده اید
در پاراگراف های قبلی به ویژه در زمینه مهم و مفید هستند
نخ زنی ماده دیگر برای threading (به غیر از pdls مربوطه) a
تابعی که threading آگاه است (به طور کلی، اینها توابع کامپایل شده PDL::PP هستند) و
که pdls ها روی آن "رشته" شده اند. در مورد اصطلاحات بسیار زیاد است و اکنون بیایید سعی کنیم
مقداری به معنای همه آن روشن کنید.
ضمنی نخ - a اول مثال
دو نوع کمی متفاوت از نخ وجود دارد. ما با چیزی که می نامیم شروع می کنیم
"نخ زدن ضمنی". بیایید یک مثال عملی را انتخاب کنیم که شامل حلقه کردن یک تابع است
بیش از بسیاری از عناصر یک pdf. فرض کنید یک تصویر RGB داریم که می خواهیم آن را به خاکستری تبدیل کنیم-
مقیاس تصویر RGB با یک pdl 3 کم نور "im(3,x,y)" نشان داده می شود که در آن بعد اول
شامل سه جزء رنگی هر پیکسل است و "x" و "y" عرض و ارتفاع هستند
تصویر به ترتیب بعد باید نحوه تبدیل یک رنگ سه گانه را در یک داده مشخص کنیم
پیکسل را به یک مقدار خاکستری تبدیل می کند (برای اینکه یک مثال واقعی باشد باید مقدار نسبی را نشان دهد
شدتی که سلول های چشم غیر حساس به رنگ ما برای رسیدن به آن رنگ را تشخیص می دهند
چیزی که ما آن را تبدیل طبیعی از رنگ به مقیاس خاکستری می نامیم). تقریبی که
به خوبی کار می کند این است که شدت خاکستری را از هر سه گانه RGB (r,g,b) به عنوان یک محاسبه کنیم.
جمع وزنی
مقدار خاکستری = 77/256*r + 150/256*g + 29/256*b =
داخلی([77,150,29]/256, [r,g,b])
که در آن شکل آخر نشان می دهد که می توانیم این را به عنوان یک حاصل ضرب درونی بردار 3 بنویسیم
شامل وزن مولفه های قرمز، سبز و آبی با بردار 3 شامل
اجزای رنگ به طور سنتی، ما ممکن است تابعی مانند زیر را بنویسیم
کل تصویر را پردازش کنید:
my @dims=$im->dims;
# در اینجا معمولاً بررسی کنید که اولین dim دارای اندازه صحیح (3) و غیره باشد
$grey=zeroes(@dims[1,2]); # pdl را برای تصویر خاکستری حاصل بسازید
$w = pdl [77,150,29] / 256; # بردار اوزان
برای ($j=0;$j
برای ($i=0;$i
# مقدار پیکسل را محاسبه کنید
$tmp = inner($w,$im->slice(':,(i),(j)'));
set($خاکستری،$i،$j،$tmp)؛ # و آن را در تصویر در مقیاس خاکستری تنظیم کنید
}
}
اکنون همان را با استفاده از threading می نویسیم (توجه داشته باشید که "inner" یک تابع آگاه از threading است
تعریف شده در بسته PDL::Primitive)
خاکستری $ = داخلی($im,pdl([77,150,29]/256));
ما به یک خط یک خطی رسیدیم که به طور خودکار pdl $grey را با سمت راست ایجاد می کند
تعداد و اندازه ابعاد و انجام حلقه ها به صورت خودکار (این حلقه ها هستند
به عنوان کد C سریع در قسمت داخلی PDL پیاده سازی شده است). خب ما هنوز به شما مدیونیم
توضیح دهید که چگونه این "جادو" به دست می آید.
چگونه میکند la مثال کار ?
اولین چیزی که باید توجه داشت این است که هر تابعی که threading آگاه است (اینها بدون
توابع استثنایی که از توضیحات مختصر توسط PDL::PP گردآوری شده است، که بعداً PP- نامیده شد.
توابع) تعداد مشخصی (حداقل) ابعاد را انتظار دارد (ما آنها را ابعاد اصلی می نامیم)
از هر یک از آرگومان های pdl آن. تابع داخلی دو تک بعدی انتظار دارد (ورودی)
پارامترهایی که از آنها یک پارامتر صفر بعدی (خروجی) محاسبه می کند. ما آن را می نویسیم
به طور نمادین به عنوان "inner((n)،(n)،[o]())" و آن را "inner" می نامند. امضا، جایی که n نشان دهنده است
اندازه آن بعد برابر بودن n در پارامتر اول و دوم به این معنی است
این ابعاد باید در هر تماسی از اندازه یکسان باشند. به عنوان یک مثال متفاوت، را در نظر بگیرید
محصول بیرونی که دو بردار 1 بعدی را برای تولید یک ماتریس دو بعدی می گیرد که به طور نمادین به صورت نوشته شده است
بیرونی((n)،(m)،[o](n،m))". "[o]" در هر دو مثال نشان می دهد که این (در اینجا سوم)
آرگومان یک آرگومان خروجی است. در مثال اخیر ابعاد اول و دوم
استدلال لازم نیست موافق باشد، اما می بینید که چگونه اندازه دو بعد را تعیین می کنند
از خروجی pdf.
نکته ای که بالاخره threading وارد بازی می شود اینجاست. اگر با توابع PP تماس بگیرید
pdf هایی که دارند بیش از ابعاد هسته مورد نیاز، اولین ابعاد pdl
آرگومان ها به عنوان ابعاد اصلی استفاده می شوند و ابعاد اضافی اضافی رشته می شوند
بر فراز. اجازه دهید این را ابتدا با مثال بالا نشان دهیم
خاکستری $ = داخلی ($im,$w); # w بردار وزن از بالا است
در این مورد $w 1D است و بنابراین فقط بعد اصلی ارائه شده است، $im 3D است، بیشتر
به طور خاص "(3، x، y)". بعد اول (سایز 3) بعد هسته مورد نیاز است
که با اولین (و تنها) بعد $w مطابقت دارد (بر اساس نیاز داخلی). دومین
بعد اولین بعد نخ است (به اندازه "x") و سومی در اینجا دومین است
بعد نخ (به اندازه "y"). خروجی pdl به طور خودکار ایجاد می شود (طبق درخواست
قبل از فراخوانی، $grey را روی "null" قرار دهید). ابعاد خروجی توسط
ضمیمه کردن حلقه ابعاد (در اینجا "(x,y)") به ابعاد خروجی هسته (در اینجا 0D) به
ابعاد نهایی pdl ایجاد شده خودکار (در اینجا "0D+2D=2D" برای ایجاد یک خروجی 2 بعدی
اندازه "(x,y)").
بنابراین دستور بالا عملکرد اصلی را فراخوانی می کند که حاصل ضرب داخلی دو را محاسبه می کند
بردارهای 1 بعدی "x*y" بار با $w و همه برش های 1 بعدی به شکل "(':,(i),(j)')" از $im و
عناصر مربوطه از خروجی pdl "$grey(i,j)" را به نتیجه هر یک تنظیم می کند.
محاسبه ما می توانیم آن را به صورت نمادین بنویسیم
$خاکستری(0,0) = f($w,$im(:,(0),(0)))
$خاکستری(1,0) = f($w,$im(:,(1),(0)))
.
.
.
خاکستری $(x-2,y-1) = f($w,$im(:,(x-2),(y-1)))
خاکستری $(x-1,y-1) = f($w,$im(:,(x-1),(y-1)))
اما این به طور خودکار توسط PDL بدون نوشتن هیچ گونه حلقه پرل صریح انجام می شود. می بینیم
که دستور واقعاً یک خروجی pdl با ابعاد مناسب ایجاد می کند و مقدار را تنظیم می کند
عناصر در واقع به نتیجه محاسبه برای هر پیکسل از تصویر ورودی.
هنگامی که pdf و ابعاد اضافی بیشتر درگیر می شوند، همه چیز کمی پیچیده تر می شود.
ابتدا قوانین کلی را بیان می کنیم که چگونه ابعاد نخ به ابعاد بستگی دارد
Pdl ورودی که شما را قادر می سازد ابعاد یک خروجی Pdl ایجاد شده خودکار را بفهمید
(برای هر مجموعه معینی از pdlهای ورودی و ابعاد اصلی تابع PP مورد نظر). در
قوانین کلی به احتمال زیاد در نگاه اول کمی گیج کننده به نظر می رسند، بنابراین ما شروع می کنیم
برای نشان دادن استفاده با مجموعه ای از مثال های بیشتر (که امیدواریم همینطور باشد
نشان می دهد که در واقع موقعیت های عملی زیادی وجود دارد که در آن نخ ها وارد می شوند
بسیار مفید).
A صدا برای برنامه نویسی انضباط
قبل از اینکه به سایر جزئیات فنی نخ زنی اشاره کنیم، لطفاً به این فراخوان توجه کنید
رشته برنامه نویسی هنگام استفاده از Threading:
به منظور حفظ خوانایی انسان، لطفا هر عبارت غیر بی اهمیتی را در خود کامنت کنید
کد شامل رشته مهمتر از همه، برای هر زیربرنامه، اطلاعات را در
شروع در مورد آنچه انتظار دارید که ابعاد نشان دهند (یا محدوده ابعاد).
به عنوان یک هشدار، به این تابع غیرمستند نگاه کنید و سعی کنید حدس بزنید چه چیزی ممکن است اتفاق بیفتد:
جستجوی فرعی {
my ($im,$palette) = @_;
$res من;
index($palette->xchg(0,1)
$im->long->dummy(0,($palette->dim)[0]),
($res=null));
بازگشت $res;
}
آیا موافق هستید که تشخیص ابعاد مورد انتظار و هدف ممکن است دشوار باشد
روال و غیره؟ (اگر می خواهید بدانید که این قطعه کد چه کاری انجام می دهد، به زیر مراجعه کنید)
چگونه به شکل خارج la حلقه ابعاد
چند قانون وجود دارد که به شما امکان می دهد تعداد و اندازه حلقه را بفهمید
ابعاد (و اگر اندازه pdl های ورودی شما مطابق با قوانین نخ یابی باشد).
ابعاد هر آرگومان pdl به دو گروه زیر تقسیم می شود: Core
ابعاد (همانطور که توسط تابع PP تعریف شده است، ببینید ضمیمه B برای لیستی از PDL های اولیه)
و ابعاد اضافی که شامل تمام ابعاد باقی مانده از آن pdl است. مثلا
فراخوانی یک تابع "func" با امضای "func((n,m),[o](n))" با یک pdl
"a(2,4,7,1,3،XNUMX،XNUMX،XNUMX،XNUMX)" به عنوان "f($a,($o = null))" منجر به تقسیم معنایی ابعاد a می شود.
به: ابعاد هسته "(2,4،7,1,3)" و ابعاد اضافی "(XNUMX،XNUMX،XNUMX)".
ابعاد هسته R0 با اولین ابعاد N از pdl مربوطه مشخص می شود
استدلال (و مورد نیاز است). هر ابعاد دیگری ابعاد اضافی هستند و استفاده می شود
تعیین ابعاد حلقه
R1 تعداد ابعاد حلقه (ضمنی) برابر با حداکثر تعداد اضافی است
ابعاد بر روی مجموعه آرگومان های pdl گرفته شده است.
R2 اندازه هر یک از ابعاد حلقه از اندازه مربوطه به دست می آید
ابعاد آرگومان های pdl. اندازه یک بعد حلقه توسط نشان داده می شود
حداکثر اندازه موجود در هر یک از pdlهایی که این بعد اضافی را دارند.
R3 برای تمام pdlهایی که دارای یک بعد اضافی مشخص هستند، اندازه باید برابر با اندازه باشد
بعد حلقه (همانطور که توسط قانون قبلی تعیین شده است) یا 1؛ در غیر این صورت شما یک را مطرح می کنید
استثنا در زمان اجرا اگر اندازه بعد اضافی در یک pdl یک باشد، این است
به طور ضمنی به عنوان یک بعد ساختگی از اندازه برابر با اندازه کم نور حلقه زمانی که
اجرای حلقه نخ
R4 اگر یک pdl بعد حلقه نداشته باشد، در حلقه thread با این pdl به گونه ای رفتار می شود که انگار
داشتن یک بعد ساختگی به اندازه اندازه آن بعد حلقه.
R5 اگر از ایجاد خودکار خروجی استفاده شود (با تنظیم pdl مربوطه روی "PDL->null" قبل از
invocation) تعداد ابعاد pdl ایجاد شده برابر است با مجموع
تعداد ابعاد خروجی هسته + تعداد ابعاد حلقه. اندازه هسته
ابعاد خروجی از بعد مربوطه pdls ورودی (همانطور که مشخص شده است
در تعریف تابع) و اندازه سایر ابعاد برابر است
اندازه بعد حلقه که از آن مشتق شده است. pdf ایجاد شده به صورت خودکار خواهد بود
فیزیکی (مگر اینکه جریان داده در حال کار باشد).
در این زمینه، توجه داشته باشید که می توانید با انتساب به pdls حاوی مشکل مواجه شوید
ابعاد ساختگی بزرگتر از یک (به بالا مراجعه کنید). اگرچه خروجی pdf(های) شما حاوی نبود
هر ابعاد ساختگی در وهله اول ممکن است به ساختگی به طور ضمنی ختم شود
ابعاد با توجه به R4.
به عنوان مثال، فرض کنید ما یک تابع PP (در اینجا نامشخص) با امضا داریم:
func((m،n)،(m،n،o)،(m)،[o](m،o))
و شما آن را با 3 pdls "a(5,3,10,11،5,3,2,10,1,12،5,1,11,12،XNUMX)، "b(XNUMX،XNUMX،XNUMX،XNUMX،XNUMX،XNUMX)، و "c(XNUMX،XNUMX،XNUMX،XNUMX)" صدا میزنید. مانند
func($a،$b،$c،($d=null))
سپس تعداد ابعاد حلقه 3 است (با "R0+R1" از $b و $c) با اندازه
"(10,11,12،2،5,2)" (توسط RXNUMX)؛ دو بعد هسته خروجی "(XNUMX،XNUMX)" هستند (از امضای
func) منجر به یک خروجی 5 بعدی pdl $c با اندازه "(5,2,10,11,12،5،XNUMX،XNUMX،XNUMX)" (به RXNUMX مراجعه کنید) و
(به طور خودکار ایجاد شده) $d از "($a,$b,$c)" مشتق شده است به نحوی که می تواند بیان شود
در شبه کد pdl به عنوان
$d(:,:,i,j,k) .= func($a(:,:,i,j),$b(:,:,:,i,0,k),$c(:, 0,j,k))
با 0<=i<10، 0<=j<=11، 0<=k<12
اگر دوباره با در نظر گرفتن این قوانین تبدیل رنگ به مقیاس خاکستری را تجزیه و تحلیل کنیم، توجه می کنیم
یکی دیگر از مزایای بزرگ نخ ضمنی. می توانیم تبدیل را با یک pdf فراخوانی کنیم
نشان دهنده یک پیکسل (im(3))، یک خط پیکسل rgb ("im(3,x)")، یک تصویر رنگی مناسب
("im(3,x,y)") یا یک پشته کامل از تصاویر RGB ("im(3,x,y,z)"). تا زمانی که $im از آن باشد
از فرم "(3،...)" خروجی pdf ایجاد شده به طور خودکار حاوی تعداد مناسبی خواهد بود
ابعاد و حاوی دادههای شدتی است که از زمانی که حلقهها بودهاند انتظار داریم
به طور ضمنی به لطف انجام شده است ضمنی نخ. شما به راحتی می توانید خود را متقاعد کنید
فراخوانی با پیکسل رنگی خاکستری $ 0D است، با یک خط یک بعدی خاکستری (x) می شود، با یک تصویر
"خاکستری(x,y)" و در نهایت یک پشته تصویر تبدیل شده "خاکستری(x,y,z)" دریافت می کنیم.
بیایید این قوانین کلی را با چند مورد بیشتر با زندگی بیشتری پر کنیم
مثال ها. خواننده ممکن است سعی کند فرمول بندی های معادل را با فرمول های صریح بیابد:
حلقه زدن و مقایسه انعطاف پذیری آن روال ها با استفاده از نخ ضمنی به
فرمول صریح بعلاوه، به ویژه هنگام استفاده از چندین بعد نخ، a
تمرین مفید برای بررسی سرعت نسبی با انجام برخی تستهای معیار (که هنوز هم
باید انجام داد).
ابتدا در ردیف یک نمونه سانتروئید کمی بازسازی شده است که اکنون با threading in کدگذاری شده است
ذهن
# مولتی رشتهای برای محاسبه ضرایب مرکز، برای پشتهها نیز کار میکند
$xc = sumover(($im*xvals(($im->dims)[0]))->توده(2)) /
sumover($im->توده(2))؛
بیایید گام به گام آنچه را که در حال وقوع است تجزیه و تحلیل کنیم. ابتدا محصول:
$prod = $im*xvals(صفر(($im->dims)[0]))
این در واقع برای $im که یک، دو، سه و ابعاد بالاتر است کار می کند. اگر $im باشد
تک بعدی فقط یک محصول معمولی است (به این معنا که هر عنصر $im است
اگر $im ابعاد بیشتری داشته باشد، با عنصر مربوطه "xvals(...)" ضرب می شود
threading بیشتر با افزودن ابعاد ساختگی مناسب به "xvals(...)" انجام می شود.
طبق R4. مهمتر از آن، دو عملیات sumover اولین نمونه از چگونگی را نشان می دهد
برای استفاده از دستورات دستکاری ابعاد. نگاهی گذرا به امضای سامور
به شما یادآوری میکند که فقط بعد اول یک pdf ورودی داده شده را «بلع» میکند.
اما اگر بخواهیم واقعاً مجموع همه عناصر دو عنصر اول را محاسبه کنیم، چه؟
ابعاد؟ خوب، هیچ چیز ما را از ارسال یک pdl مجازی به sumover باز می دارد که در این مورد
مورد با جمع کردن دو بعد اول "pdl والد" در یکی تشکیل می شود. از
از دیدگاه pdl والد، مجموع اکنون در دو بعد اول محاسبه می شود.
همانطور که می خواستیم، هر چند sumover به تازگی کار را همانطور که در امضای آن مشخص شده انجام داده است. بدست آورد
آی تی ؟
یکی دیگر از ظرافت های کوچک نوشتن کد به این صورت: ما عمدا استفاده کردیم
"sumover($pdl->توده(2))" به جای "sum($pdl)" تا بتوانیم فقط یک تصویر را ارسال کنیم
"(x,y)" یا یک پشته از تصاویر "(x,y,t)" را در این روال وارد کنید و فقط یکی را دریافت کنید
x-coordiante یا بردار مختصات x (به اندازه t) در برگشت.
مجموعه دیگری از عملیات رایج همان چیزی است که می توان آن را "عملیات طرح ریزی" نامید. اینها
عملیات یک pdl ND را به عنوان ورودی دریافت می کند و یک pdl (N-1)-D "پیش بینی شده" را برمی گرداند. این عملیات ها
اغلب با عملکردهایی مانند sumover، prodover، minimum و حداکثر انجام می شوند. استفاده كردن
دوباره تصاویر به عنوان مثال ممکن است بخواهیم حداکثر مقدار پیکسل را برای هر خط محاسبه کنیم
از یک تصویر یا پشته تصویر. ما می دانیم که چگونه این کار را انجام دهیم
# حداکثر خطوط (به عنوان تابعی از تعداد خط و زمان)
حداکثر($stack,($ret=null));
اما اگر بخواهید ماکزیمم را در هر ستون محاسبه کنید، زمانی که نخسازی ضمنی همیشه اعمال میشود، چه میشود
عملکرد اصلی به بعد اول و موضوعات بیش از بقیه؟ ما چطور می تونیم
دستیابی به اینکه در عوض عملکرد اصلی در بعد دوم اعمال شود و
نخ روی بقیه انجام می شود. آیا می توانید آن را حدس بزنید؟ بله، ما یک pdl مجازی می سازیم که دارد
بعد دوم "pdl والد" به عنوان بعد اول آن با استفاده از دستور "mv".
# حداکثر ستون (به عنوان تابعی از تعداد ستون و زمان)
حداکثر($stack->mv(1,0),($ret=null));
و محاسبه تمام مجموع برش های فرعی در بعد سوم اکنون تقریباً بسیار آسان است
# مجموع پیکسل ها در زمان (با فرض اینکه زمان سومین کم نور باشد)
sumover($stack->mv(2,0),($ret=null));
در نهایت، اگر میخواهید این عملیات را روی همه عناصر اعمال کنید (مانند حداکثر روی همه عناصر یا
مجموع تمام عناصر) بدون در نظر گرفتن ابعاد pdl مورد نظر "کلبه" می آید
مفید است. به عنوان مثال به تعریف "sum" نگاه کنید (همانطور که در "Ufunc.pm" تعریف شده است):
جمع فرعی {
PDL::Ufunc::sumover($name->clump(-1)،($tmp=null));
بازگشت $tmp->at(); # یک عدد Perl برگردانید، نه یک pdl 0D
}
قبلاً اشاره کردیم که تمام عملیات پایه پشتیبانی از threading و انتساب ندارد
استثنا. بنابراین در اینجا چند تکلیف رشته ای وجود دارد
pdl> $im = صفر (بایت، 10,20،XNUMX)
pdl> $line = exp(-rvals(10)**2/9)
# تکلیف رشته ای
pdl> $im .= $line # هر خط $im را روی $line قرار دهید
pdl> $im2 .= 5 # هر عنصر $im2 را روی 5 تنظیم کنید
تا به حال احتمالاً می بینید که چگونه کار می کند و چه کاری انجام می دهد، اینطور نیست؟
برای تکمیل مثالهای این پاراگراف، در اینجا تابعی برای ایجاد یک تصویر RGB وجود دارد
چیزی که تصویر پالت نامیده می شود. تصویر پالت از دو بخش تشکیل شده است: یک تصویر از
شاخص ها را در جدول جستجوی رنگ و خود جدول جستجوی رنگ قرار می دهد. [ چگونگی آن را شرح دهید
کار می کند ] ما می خواهیم از یک تابع PP استفاده کنیم که هنوز در گذشته با آن مواجه نشده ایم.
مثال ها. این تابع شاخص با نام مناسب، امضای "((n),(),[o]())" است (نگاه کنید به ضمیمه
B) با عملکرد اصلی که "index(pdl (0,2,4,5),2,($ret=null))" را برمی گرداند
عنصر با اندیس 2 از اولین ورودی pdl. در این حالت $ret حاوی مقدار 4 خواهد بود.
بنابراین این مثال است:
# جستجوی فهرست رشته ای برای تولید یک تصویر RGB، یا RGBA یا YMCK
# از یک تصویر پالت (که توسط یک جدول جستجوی $palette و
# یک تصویر با شاخص رنگ $im)
#میتونی بگی فقط ساختگی(0) زیرا قوانین نخ آن را مناسب می کند
pdl> index($palette->xchg(0,1)
$im->long->dummy(0,($palette->dim)[0]),
($res=null));
بیایید آن را مرور کنیم و مراحل مربوط به آن را توضیح دهیم. با فرض اینکه با یک RGB سروکار داریم
پالت $ lookup-table اندازه "(3،x)" است. ابتدا ابعاد پالت را رد و بدل می کنیم
به طوری که حلقه کردن روی بعد اول پالت $ (با اندازه 3 که نشان دهنده r است، انجام می شود،
اجزای g و b). اکنون به $im نگاه می کنیم، یک بعد ساختگی به اندازه اضافه می کنیم
طول تعداد مؤلفه ها (در موردی که در اینجا بحث می کنیم، می توانیم فقط داشته باشیم
از عدد 3 استفاده کرد زیرا ما 3 جزء رنگی داریم). ما می توانیم از یک بعد ساختگی استفاده کنیم
برای اجزای رنگ قرمز، سبز و آبی از همان شاخص تصویر اصلی استفاده می کنیم.
به عنوان مثال، با فرض اینکه یک پیکسل معین $im دارای مقدار 4 باشد، جستجو باید آن را تولید کند
سه گانه
[پالت (0,4،1,4)، پالت (2,4،XNUMX)، پالت (XNUMX،XNUMX)]
برای اجزای جدید قرمز، سبز و آبی تصویر خروجی. امیدوارم تا الان داشته باشید
نوعی ایده که قطعه کد بالا قرار است چه کاری انجام دهد (اغلب در واقع اینطور است
بسیار پیچیده برای توصیف جزئیات نحوه کار یک قطعه کد رشته. فقط برو جلو
و کمی آزمایش کنید تا احساس بهتری نسبت به آن داشته باشید).
اگر قوانین threading را به دقت خوانده باشید، شاید متوجه شده باشید که ما این کار را نکرده ایم
باید به صراحت اندازه بعد ساختگی را که برای $im ایجاد کردیم، بیان کنیم. زمانی که ما
آن را با اندازه 1 ایجاد کنید (پیشفرض) قوانین رشتهبندی آن را به طور خودکار متناسب میکند
اندازه مورد نظر (طبق قانون R3، در مثال ما اندازه با فرض پالت 3 خواهد بود
اندازه "(3، x)"). از آنجایی که موقعیتهایی مانند این اغلب در عمل اتفاق میافتد، در واقع به همین دلیل است
قانون R3 معرفی شده است (قسمتی که ابعاد سایز 1 را با نخ متناسب می کند
اندازه کم نور حلقه). پس فقط می توانیم بگوییم
pdl> index($palette->xchg(0,1)،$im->long->ساختگی(0)، ($res=null));
باز هم می توانید خود را متقاعد کنید که این روال در صورت فراخوانی خروجی مناسبی ایجاد می کند
با یک پیکسل ($im 0D است)، یک خط ($im 1D است)، یک تصویر ($im 2D است)، ...، یک جستجوی RGB
جدول (پالت "(3،x)") و جدول جستجوی RGBA (پالت "(4،x)" است، به عنوان مثال OpenGL را ببینید).
این انعطاف پذیری با قوانین نخ زنی که برای انجام درست ساخته شده اند به دست می آید
چیزی در بیشتر موقعیت ها
برای جمع بندی مجدد همه چیز، ایده کلی به شرح زیر است. اگر می خواهید به دست آورید
حلقه کردن بر روی ابعاد خاص و داشتن هسته قابلیت به دیگری اعمال شود
مجموعه مشخصی از ابعاد شما از دستورات دستکاری ابعاد برای ایجاد (یا
چندین) مجازی pdl(s) به طوری که از نقطه نظر پدر یا مادر pdl(s) شما چه چیزی را دریافت می کنید
می خواهید (همیشه امضای تابع مورد نظر و R1-R5 را در ذهن داشته باشید!).
آسان است، اینطور نیست؟
تولید ایجاد خودکار و تابع PP فراخوانی کنوانسیون
در این مرحله ما باید به برخی از جزئیات فنی که به کلیات مربوط می شود منحرف شویم
فراخوانی قراردادهای توابع PP و ایجاد خودکار آرگومان های خروجی.
اساساً دو راه برای فراخوانی روالهای pdl وجود دارد، یعنی
$result = func($a,$b);
و
func($a,$b,$result);
اگر فقط از threading ضمنی استفاده می کنید، متغیر خروجی می تواند به طور خودکار باشد
ایجاد شده توسط PDL. با تنظیم آرگومان خروجی روی a، آن را به تابع PP علامت گذاری می کنید
نوع خاصی از pdl که از فراخوانی به تابع "PDL->null" که برمیگرداند برمیگردد
یک pdl اساساً "خالی" (برای کسانی که به جزئیات علاقه دارند یک پرچم در C pdl وجود دارد
ساختار برای این). ابعاد pdl ایجاد شده توسط قوانین تعیین می شود
threading ضمنی: اولین ابعاد همان ابعاد خروجی هسته هستند که به آنها
ابعاد نخ اضافه شده است (که به نوبه خود توسط ابعاد تعیین می شود
pdls ورودی همانطور که در بالا توضیح داده شد). بنابراین می توانید بگویید
func($a,$b,($result=PDL->null));
or
$result = func($a,$b)
که هستند کاملا معادل.
هشدار داده شود که می توانید نه از ایجاد خودکار خروجی هنگام استفاده از threading صریح (برای
دلایل در بخش زیر توضیح داده شده است صریح نخ، دومین نوع
نخ زنی).
در حلقههای «تنگ» احتمالاً میخواهید از ایجاد ضمنی یک pdl موقت در آن اجتناب کنید
هر مرحله از حلقه که همراه با سبک "عملکردی" است، بلکه می گویند
# فقط در اولین فراخوانی pdf خروجی با اندازه مناسب ایجاد کنید
$نتیجه = null;
برای (0...$n) {
func($a,$b,$result); # در همه فراخوانی $result به جز اولین فراخوانی
func2 ($b); # تعریف شده است و اندازه مناسبی دارد
# خروجی را بگیرید مشروط بر اینکه کم نورهای $b تغییر نکنند
twiddle($result,$a); # کاری از $result تا $a برای تکرار انجام دهید
}
پیام اصلی این بخش یک بار دیگر: از محدودیت در خروجی آگاه باشید
ایجاد در هنگام استفاده صریح نخ.
صریح نخ
با توجه به اینکه تا کنون فقط در مورد اولین طعم نخ زنی صحبت کرده ایم، اکنون زمان آن فرا رسیده است
نوع دوم را معرفی کنید به جای این که دائماً ابعاد را به هم بزنید و
با تکیه بر قوانین نخ زنی ضمنی برای درست کردن همه چیز ممکن است گاهی اوقات بخواهید
نحوه اجرای حلقه thread را به روشی واضح تر مشخص کنید. احتمالاً اینطور نیست
جای تعجب است که این نوع بازی نامیده می شود صریح نخ. حالا قبل از ما
تصور اشتباه ایجاد کنید: این هم نیست ضمنی or صریح; این دو طعم انجام می دهند
مخلوط کردن. اما بیشتر در مورد آن بعدا.
دو تابعی که بیشترین استفاده را دارند با threading واضح، thread و unthread هستند. ما شروع
با مثالی که کاربرد معمولی اولی را نشان می دهد:
[# ** این بدترین مثال ممکن برای شروع است]
# اما می تواند برای نشان دادن تفاوت $mat += $line با
# $mat->موضوع(0) += $line
# threading صریح برای افزودن یک بردار به هر ستون از یک ماتریس
pdl> $mat = صفر (4,3،XNUMX)
pdl> $line = pdl (3.1416,2,-2)
pdl> ($tmp = $mat->موضوع(0)) += $line
در این مثال، "$mat->موضوع(0)" به PDL می گوید که شما بعد دوم این را می خواهید
pdl که ابتدا به یک حلقه نخ کشیده می شود که می تواند به صورت بیان شود
برای (j=0; j<3; j++) {
برای (i=0; i<4; i++) {
mat(i,j) += src(j);
}
}
"thread" لیستی از اعداد را به عنوان آرگومان می گیرد که به صراحت مشخص می کند که کدام ابعاد
ابتدا نخ را بکشید با معرفی threading صریح ابعاد یک pdl می باشد
از نظر مفهومی به سه گروه مختلف تقسیم می شود که دو گروه آخر را قبلاً انجام داده ایم
مواجه شده: ابعاد نخ، ابعاد هسته و ابعاد اضافی.
از نظر مفهومی، بهتر است به ابعادی از یک pdl فکر کنید که در آن مشخص شده است
فراخوانی به "نخ" به عنوان از مجموعه ابعاد عادی جدا شده و روی الف قرار می گیرد
پشته جداگانه بنابراین با فرض اینکه یک PDL "a(4,7,2,8)" داریم
$b = $a->thread(2,1)
یک pdl مجازی جدید با بعد "b(4,8)" ایجاد می کند (که ما آن را کم رنگ باقی مانده می نامیم) که
همچنین دارای 2 بعد نخ به اندازه "(2,7،XNUMX)" است. برای اهداف این سند می نویسیم
که به طور نمادین به عنوان "b(4,8،2,7){XNUMX،XNUMX}". یک تفاوت مهم با مثال های قبلی که در آن
فقط از threading ضمنی استفاده شد این واقعیت است که ابعاد هسته با آن مطابقت دارند
la باقی مانده ابعاد که لزوماً اولین ابعاد pdl نیستند. ما
اکنون مشخص خواهد شد که چگونه وجود ابعاد نخ، قوانین R1-R5 را برای نخ تغییر می دهد.
حلقه ها (که در مورد خاصی اعمال می شود که در آن هیچ یک از آرگومان های pdl هیچ رشته ای ندارد.
ابعاد).
ابعاد هسته T0 با n اول مطابقت دارد باقی مانده ابعاد از pdl
آرگومان (به تفاوت R1 توجه کنید). هر چه بیشتر باقی مانده ابعاد هستند اضافی
ابعاد و برای تعیین استفاده می شوند ضمنی حلقه ابعاد.
T1a تعداد ضمنی حلقه ابعاد برابر است با حداکثر تعداد اضافی
ابعاد بر روی مجموعه آرگومان های pdl گرفته شده است.
T1b تعداد صریح حلقه ابعاد برابر با حداکثر تعداد نخ است
ابعاد بر روی مجموعه آرگومان های pdl گرفته شده است.
T1c تعداد کل حلقه ابعاد برابر است با مجموع صریح حلقه ابعاد
و ضمنی حلقه ابعاد. در حلقه نخ، صریح حلقه ابعاد هستند
نخ روی اول و به دنبال آن ضمنی حلقه ابعاد.
T2 اندازه هر یک از حلقه ابعاد از اندازه مربوطه مشتق شده است
ابعاد آرگومان های pdl. با حداکثر اندازه موجود در هر pdls داده می شود
داشتن این بعد رشته (برای صریح حلقه ابعاد) یا بعد اضافی (برای
ضمنی حلقه ابعاد).
T3 این قانون در مورد هر کدام صدق می کند صریح حلقه بعد و همچنین هر کدام ضمنی حلقه
بعد. برای تمام pdl هایی که داده شده اند نخ / اضافی بعد اندازه باید باشد
برابر با اندازه مربوطه صریح / ضمنی حلقه بعد یا 1; در غیر این صورت
شما یک استثنا در زمان اجرا ایجاد می کنید. اگر اندازه a نخ / اضافی بعد از یک pdl یکی است
به طور ضمنی به عنوان یک بعد ساختگی با اندازه برابر با تلقی می شود صریح / ضمنی
حلقه بعد.
T4 اگر یک pdl a ندارد نخ / اضافی بعد که مطابق با یک
صریح / ضمنی حلقه بعد، در حلقه thread با این pdl به گونه ای رفتار می شود که گویی دارد
یک بعد ساختگی از اندازه برابر با اندازه آن بعد حلقه.
T4a همه pdlهایی که دارند موضوع ابعاد باید تعداد نخ یکسانی داشته باشد
ابعاد
اگر هر یک از آرگومانهای pdl وجود داشته باشد، نمیتوان از ایجاد خودکار خروجی T5 استفاده کرد موضوع
ابعاد. در غیر این صورت R5 اعمال می شود.
همین محدودیت ها در مورد ابعاد ساختگی ضمنی (ایجاد شده توسط
استفاده از T4) همانطور که قبلاً در بخش threading ضمنی ذکر شد: در صورت وجود
pdls خروجی یک بعد ساختگی بزرگتر از یک (به صورت صریح یا ضمنی ایجاد شده) دارد a
استثنا زمان اجرا مطرح خواهد شد.
اجازه دهید این قوانین را در کار در یک مورد عمومی نشان دهیم. فرض کنید ما یک (اینجا
نامشخص) تابع PP با امضا:
func((m،n)،(m)،()،[o](m))
و شما آن را با 3 pdls "a(5,3,10,11)", "b(3,5,10,1,12)" و "c(10)" و خروجی pdl
"d(3,11,5,10,12،XNUMX،XNUMX،XNUMX،XNUMX)" (که در اینجا می توانید نه به طور خودکار ایجاد شود) به عنوان
func($a->thread(1,3)،$b->thread(0,3)،$c,$d->thread(0,1))
از امضای func و فراخوانی بالا، pdls به گروه های زیر تقسیم می شود
ابعاد هسته، اضافی و thread (نوشته شده به شکل "pdl(core dims){thread dims}[extra
کم نور]"):
a (5,10،3,11){XNUMX،XNUMX}[] b(5){3,1}[10,12] c(){}[10] d(5){3,11،10,12}[XNUMX،XNUMX]
با این کار برای کمک به ما (به طور کلی نوشتن استدلال ها به این صورت مفید است
هنگامی که شما شروع به بازی با نخ می کنید و می خواهید آنچه را که در جریان است پیگیری کنید) ما
بیشتر استنباط کنید که تعداد ابعاد حلقه صریح 2 است (توسط T1b از $a و $b)
با اندازه های "(3,11،2)" (توسط T2)؛ 1 بعد حلقه ضمنی (توسط TXNUMXa از $b و $d) اندازه
"(10,12)" (توسط T2) و عناصر از pdls ورودی به گونه ای محاسبه می شوند که می تواند
به صورت شبه کد pdl بیان شود
برای (l=0;l<12;l++)
برای (k=0;k<10;k++)
برای (j=0;j<11;j++) اثر تلقی آن به عنوان کم نور ساختگی (شاخص j)
برای (i=0;i<3;i++) |
d(i,j,:,k,l) = func(a(:,i,:,j),b(i,:,k,0,l),c(k))
اوه، این مثال واقعاً از نظر حسابداری آسان نبود. این بیشتر به عنوان یک
به عنوان مثال چگونه متوجه شوید که چه اتفاقی در حال رخ دادن است، زمانی که با یک ظاهر پیچیده روبرو می شوید
اصطلاح. اما اکنون واقعاً زمان آن است که با دادن مقداری بیشتر نشان دهیم که threading مفید است
از نمونه های به اصطلاح "عملی" ما.
[ مثال های زیر در آینده نیاز به توضیح بیشتری خواهند داشت. برای
لحظه لطفا سعی کنید با نظرات در قطعات کد زندگی کنید. ]
به عنوان مثال 1:
*** معکوس ماتریس نشان داده شده توسط eigvecs و eigvals
** با یک ماتریس متقارن M = A^T x diag(lambda_i) x A
** => معکوس M^-1 = A^T x diag(1/lambda_i) x A
** اول $tmp = diag(1/lambda_i)*A
** سپس A^T * $tmp توسط محصول داخلی رشته ای
# مدیریت ایندکس به طوری که ماتریس ها در زیر pdl درست چاپ شوند
$inv .= $evecs*0; # فقط کپی کنید تا خروجی با اندازه مناسب دریافت کنید
$tmp .= $evecs; # مقداردهی اولیه، بدون پس انتشار
($tmp2 = $tmp->موضوع(0)) /= $evals; # تقسیم رزوه ای
# و در حال حاضر ضرب ماتریس در مبدل
PDL::Primitive::inner($evecs->xchg(0,1)->thread(-1,1),
$tmp->thread(0,-1)،
$inv->thread(0,1));
# جایگزین برای مولتی ماتریس با استفاده از نخ ضمنی،
# اولین xchg فقط برای انتقال
PDL::Primitive::inner($evecs->xchg(0,1)->ساختگی(1)
$tmp->xchg(0,1)->ساختگی(2)
($inv=null));
به عنوان مثال 2:
# حاصلضرب بیرونی با ضرب رشته ای
# تاکید کنید که باید این کار را با تماس صریح به my_biop1 انجام دهیم
# هنگام استفاده از threading واضح
$res=zeroes(($a->dims)[0],($b->dims)[0]);
my_biop1($a->thread(0,-1),$b->thread(-1,0),$res->(0,1),"*");
# چیز مشابه با نخ زنی ضمنی با pdf ایجاد شده خودکار
$res = $a->ساختگی(1) * $b->ساختگی(0)؛
به عنوان مثال 3:
# استفاده متفاوت از نخ و بدون نخ برای به هم زدن تعدادی از
# ابعاد در یک حرکت بدون تماس های زیاد به ->xchg و ->mv
# از thread/unthread برای به هم زدن ابعاد اطراف استفاده کنید
# فقط آن را امتحان کنید و pdl کودک را با والدینش مقایسه کنید
$trans = $a->thread(4,1,0,3,2)->unthread;
به عنوان مثال 4:
# چند جعبه محدود کننده را محاسبه کنید
# $bb BB را به صورت [xmin,xmax]،[ymin,ymax]،[zmin,zmax] نگه میدارد
# ما دوباره از thread و unthread برای به هم زدن ابعاد در اطراف استفاده می کنیم
pdl> $bb = صفر (دو برابر، 2,3،XNUMX)؛
pdl> حداقل ($vertices->موضوع(0)-> clump->بدون نخ(1)، $bb->slice('(0),:'));
pdl> حداکثر ($vertices->موضوع(0)-> clump->بدون نخ(1)، $bb->slice('(1),:'));
به عنوان مثال 5:
# یک توالی از تصاویر خود سهمیه بندی شده (یعنی خود عادی سازی شده) را محاسبه کنید
# از threading صریح و یک تقسیم threaded ضمنی استفاده می کند
$stack = read_image_stack();
# میانگین (میانگین در هر پیکسل) اولین $n+1 تصاویر را محاسبه کنید
$aver = zeroes([stack->dims]->[0,1]); # خروجی را pdf بسازید
sumover($stack->slice(":,:,0:$n")->thread(0,1),$aver);
$aver /= ($n+1);
$stack /= $aver; # با انجام یک تقسیم رشته ای پشته را عادی کنید
# ضمنی در مقابل صریح
# به طور متناوب، $aver را با threading ضمنی و ایجاد خودکار محاسبه کنید
sumover($stack->slice(":,:,0:$n")->mv(2,0),($aver=null));
$aver /= ($n+1);
#
ضمنی در مقابل صریح نخ
در این پاراگراف ما قصد داریم نشان دهیم که چه زمانی threading واضح بر آن ترجیح داده می شود
threading ضمنی و بالعکس. اما باز هم، این احتمالا بهترین راه نیست
از آنجایی که قبلاً می دانید: این دو طعم با هم مخلوط می شوند. بنابراین، بیشتر در مورد چگونگی آن است
برای به دست آوردن بهترین های هر دو دنیا و به هر حال در بهترین سنت های پرل: TIMTOWTDI!
[ با عرض پوزش، این هنوز باید در نسخه بعدی پر شود. یا به نمونه های بالا مراجعه کنید
یا موارد جدید را انتخاب کنید]
در نهایت، این ممکن است مکان خوبی برای توجیه تمام جزئیات فنی باشد که به آن پرداختهایم
در مورد برای چند صفحه: چرا نخ زنی؟
خوب، کدی که از threading استفاده می کند باید (به طور قابل توجهی) سریعتر از کدی باشد که استفاده می کند
حلقههای for صریح (یا ساختارهای مشابه Perl) برای دستیابی به عملکرد یکسان.
به خصوص در ابر رایانه ها (با امکانات محاسبات برداری/پردازش موازی) PDL
نخ زنی به گونه ای اجرا می شود که از امکانات اضافی بهره مند شود
از این ماشین ها علاوه بر این، از نظر مفهومی یک ساختار ساده است (هر چند فنی
جزئیات ممکن است گاهی درگیر شوند) و می توانند تا حد زیادی کاهش پیچیدگی نحوی
کد PDL (اما توصیه اسناد را در ذهن داشته باشید). وقتی راحت شدی
با نخ طرز تفکر (و کدنویسی) نباید خیلی سخت باشد
کدهایی را که شخص دیگری نوشته است را درک کنید (به شرطی که به شما ایده بدهد
ابعاد ورودی مورد انتظار هستند و غیره). به عنوان یک نکته کلی برای افزایش عملکرد شما
کد: اگر باید یک حلقه در کد خود وارد کنید، سعی کنید مشکل را دوباره فرموله کنید
که می توانید از threading برای اجرای حلقه استفاده کنید (مانند هر چیز دیگری استثناهایی وجود دارد
این قانون سرانگشتی؛ اما نویسندگان این سند تمایل دارند فکر کنند که این موارد نادر هستند
موارد ;).
PDL::PP
An ساده راه به تعريف كردن توابع که هستند مطلع of نمایه سازی و نخ (و la جهان و
همه چیز)
PDL:PP بخشی از توزیع PDL است. برای تولید توابعی که از آن آگاه هستند استفاده می شود
قوانین نمایه سازی و رشته بندی از توضیحات بسیار مختصر. می تواند برای شما مفید باشد اگر
شما میخواهید توابع خود را بنویسید یا اگر میخواهید توابع را از یک واسط استفاده کنید
کتابخانه خارجی به طوری که آنها از نمایه سازی و رشته گذاری پشتیبانی می کنند (و شاید جریان داده نیز،
به PDL::Dataflow مراجعه کنید. برای جزئیات بیشتر PDL::PP را بررسی کنید.
ضمیمه A
افیون تحولات - a ویژه کلاس of ساده و قوی تحولات
[ این نیز چیزی است که باید در نسخه های بعدی اضافه شود. آیا ما در حال حاضر ژنرال
روتین make_affine در PDL؟ ممکن است به مرد مناسب دیگری مراجعه کنیم
صفحه از اینجا ]
ضمیمه B
امضا of استاندارد PDL::PP وارد توابع
مجموعه ای از امضاهای اولیه PDL برای نشان دادن چند بعد PP کامپایل شده است
توابع غوطه ور می شوند (و بنابراین می توانید بفهمید که چه چیزی روی آن قرار می گیرد). بیشتر
این توابع، توابع اولیه تعریف شده در "primitive.pd" هستند.
# توابع در primitive.pd
#
sumover ((n)،[o]())
ارائه دهنده ((n)،[o]())
مقادیر محوری ((n)) در جای خود
درونی ((n)،(n)،[o]())
بیرونی ((n)،(m)،[o](n،m))
innerwt ((n)،(n)،(n)،[o]())
درونی2 ((m)، (m،n)، (n)، [o]())
inner2t ((j،n)،(n،m)،(m،k)،[o]())
شاخص (1D,0D,[o])
حداقل (1D,[o])
حداکثر (1D،[o])
wstat ((n)،(n)،()،[o]،())
اختصاص دادن (()،())
# عملیات اساسی
عملیات باینری (()،()،[o]())
عملیات واحد (()،[o]())
نویسنده & کپی رایت
حق چاپ (C) 1997 کریستین سولر (c.soeller@auckland.ac.nz) & Tuomas J. Lukka
(lukka@fas.harvard.edu). تمامی حقوق محفوظ است. اگر چه برای انتشار به عنوان صفحه مرد
با توزیع استاندارد PDL، مالکیت عمومی نیست. مجوز داده می شود
آزادانه نسخه های کلمه به کلمه این سند را به شرط عدم تغییر در خارج توزیع کنید
قالب بندی انجام شود و این اطلاعیه دست نخورده باقی بماند. شما مجاز هستید و
تشویق به استفاده از کد آن و مشتقات آن در کد منبع خود برای سرگرمی یا برای
هر طور که صلاح می دانید سود کنید
از PDL::Indexingp به صورت آنلاین با استفاده از خدمات onworks.net استفاده کنید