MatlabTips
892 subscribers
463 photos
73 videos
54 files
304 links
آموزش MATLAB با "استفاده از ویدئو و متن" در سطوح مبتدی تا پیشرفته
پاسخ به سوالات تخصصی:
@roholazandie
Download Telegram
@MatlabTips
image
این easter egg تصویر یک پسر بچه را نمایش می‌دهد.
Forwarded from Deleted Account
@MatlabTips
spy
این دستور در بعضی از نسخه ها تصویر یک جاسوس کلاسیک یا سگ کارآگاه را نشان می دهد.
@MatlabTips
fifteen
با وارد کردن این دستور در پنجره matlab یک بازی کامپیوتری ظاهر می شود که هدف آن مرتب کردن اعداد 1 تا 15 می باشد.
@MatlabTips
خطای گرد کردن(Rounding error)
در MATLAB نیز مانند تمام زبان های برنامه نویسی دیگر، اعداد بسته به نوع (double, int16 ,…) بصورت دنباله‌ ای از 0 و 1 نمایش داده می شود. هر نوع ذاتا برای یک دقت خاص استفاده می شود. به همین خاطر، عملیات ریاضی بر روی این اعداد ممکن است منجر به نتایجی شود که به دور از انتظار ما باشد. در این پست این رفتارها را شناسایی خواهیم کرد تا از مشکلات بالقوه آنها دوری کنیم:
@MatlabTips
مثال:
x = 1; %initial value
cnt = 0; %counter
while x ~= 2
x = x + 0.1;
cnt = cnt + 1; %count up
end

انتظار داریم بعد از پایان برنامه مقدار cnt برابر 10 شود، اما این برنامه تا ابد ادامه می‌یابد. عدد 0.1 با یک دقت مشخصی گرد می‌شود و از آنجایی که این عدد هنگامی که به زبان ماشین تبدیل می‌شود دقیقا برابر 0.1 نیست بنابراین هیچ وقت شرط حلقه برقرار نمی شود.
برای اجتناب از چنین حالت‌هایی باید معیار شرط را مناسب انتخاب کرد. مثلا در مثال بالا " while x <2 " می‌تواند مناسب تر باشد.
در مثال بالا به جای "0.1" از "0.25" استفاده کنید. دقت کنید که عدد "0.25" بطور دقیق با دقت ماشین های امروزی قابل نمایش است.
@MatlabTips
#SpeedUp
@MatlabTips
برای تسریع در عملکرد کدهایتان، نکات زیر را لحاظ کنید:
1⃣محیط

هنگام اجرای برنامه در MATLAB دقت داشته باشید که همزمان برنامه دیگری در حال اجرا نباشد که از منابع پردازشی زیادی استفاده کند.
2⃣ساختار کد

به جای اسکریپت از تابع استفاده کنید. به طور کلی توابع سریع‌تر هستند.
✔️از توابع تو در تو استفاده نکنید و به جای آن از توابع محلی استفاده کنید.(مخصوصا زمانی که توابع نیازی به دسترسی به متغیرهای درون تابع اصلی ندارند).
✔️از برنامه‌نویسی ماژولار استفاده کنید. کد خود را به فایل‌های ریزتر تقسیم کنید.
@MatlabTips
3⃣تمرین‌های برنامه‌نویسی برای بهبود عملکرد
از تکنیک‌های زیر برای بهبود عملکرد کد خود استفاده کنید:
✔️پیش‌تخصیص(preallocate):
به جای اینکه دائما اندازه آرایه‌ها تغییر کند، یک مقدار ثابت برای اندازه آرایه مورد نظر در نظر گرفته که مدام در حافظه عملیات تخصیص صورت نگیرد.
✔️بردارسازی:
به جای استفاده از حلقه‌ها سعی کنید تا جایی که ممکن است از عملیات برداری و ماتریسی استفاده کنید.
✔️عملیات مستقل را بیرون از حلقه قرار دهید:
در صورتی که با تکرارهای حلقه بخشی از کد دچار تغییر نمی‌شود، آن قسمت را از حلقه بیرون بیاورید.
✔️از متغیرهای global استفاده نکیند:
حداقل کردن استفاده از این متغیرها توصیه می‌شود. متغیرهای global عملکرد کد MATLAB را کاهش می‌دهد.
@MatlabTips
Channel photo updated
%% we want to show how "preallocation" speed up the code!!
%dynamic array growth:
tic
fibonacci = [0,1];
for idx = 3 : 40000
fibonacci(idx) = fibonacci(idx-1) + fibonacci(idx-2); %dynamically changes size
end
toc
%@MatlabTips
% use preallocation – 9x faster in my machine(dual_core)
tic
fibonacci = zeros(40000,1); %preallocation
fibonacci(1)=0; fibonacci(2)=1;
for idx = 3 : 40000,
fibonacci(idx) = fibonacci(idx-1) + fibonacci(idx-2);
end
toc
هدف از کد بالا نشان دادن تاثیر پیش‌تخصیص (preallocation) در افزایش سرعت کد است. کد اول 40000 جمله اول از دنباله فیبوناچی را تولید می‌کند، در صورتی که بردار Fibonacci بصورت دینامیکی در حال رشد است. با تغییر اندازه این بردار پردازنده مدام به حافظه (ram) سر می‌زند و یک بلوک متناسب با آن را تخصیص می‌دهد. این سر زدن متوالی به حافظه باعث کند شدن برنامه می‌شود. در حالی که در برنامه دوم با پیش‌تخصیص توانسته‌ایم سرعت برنامه را 9 برابر (این عدد از یک سیستم به سیستم دیگر ممکن است تغییر کند) سریع‌تر کنیم.
@MatlabTips
#SpeedUp
پیش نیاز: آشنایی مقدماتی با کدنویسی در MATLAB
@MatlabTips
بردارها و ماتریس‌ها قلب هر برنامه MATLAB را تشکیل می‌دهند. هنگامی که عملیات MATLAB بصورت برداری و ماتریسی انجام شود، عملکرد آن به شدت بهینه می‌شود. "برداری‌سازی" هنر تبدیل محاسبات بصورت عنصر به عنصر (همان‌گونه که در حلقه‌ها می‌بینیم) به عملیاتی برداری است.

با یک مثال ساده شروع می‌کنیم:
1⃣فرض کنید دو ماتریس A و B و هم اندازه داریم. دو روش برای ضرب آنها وجود دارد: ✔️عنصر به عنصر
A=rand(100,1);
B=rand(100,1);
for i=1:100
C(i)=A(i)*B(i);
end

✔️یا بصورت برداری عناصر آن را با عملگر ضرب آرایه‌ای در هم ضرب کنیم.
A=rand(100,1);
B=rand(100,1);
C=A.*B;

@MatlabTips
یک مثال دیگر:
2⃣فرض کنید می‌خواهیم تمام حجم‌های ممکن برای استوانه‌هایی با شعاع R و ارتفاع H رامحاسبه کنیم.
✔️روش عنصر به عنصر:
R = 1:10000;        %radious 
H = 1:400; %Height
V = zeros(10000,4000); %preallocate V(volume) to speed up

for i = 1:numel(H)
for j = 1:numel(R)
V(j,i) = pi * R(j).^2 * H(i);
end
end


✔️روش برداری:
R = 1:10000;
H = 1:400;
[matR, matH] = meshgrid(R,H);
V = pi.*matR.^2.*matH;


@MatlabTips
%@MatlabTips
% Using a loop(element by element)
tic
R = 1:10000; %radious
H = 1:400; %Height
V = zeros(10000,4000); %preallocate V(volume) to speed up

for i = 1:numel(H)
for j = 1:numel(R)
V(j,i) = pi * R(j).^2 * H(i);
end
end
toc
clear all
%@MatlabTips
% Vectorized code , 6x faster in my machine

tic
R = 1:10000;
H = 1:400;
[matR, matH] = meshgrid(R,H);
V = pi.*matR.^2.*matH;
toc

✔️کدهای مربوط به مثال بالا و مقایسه سرعت آن ها
🔵تجاربی از کاربا MATLAB که سال ها طول می کشد یاد بگیرید🔵
(پیش نیاز: بدون پیش نیاز)
@MatlabTips

این نکات با این که در نگاه اول ساده به نظر می رسند، در دراز مدت اگر با آنها آشنایی نداشته باشید شما را با زحمت روبرو می کنند و لذت کد زدن با MATLAB را به سختی تبدیل میکند.
1⃣ اعداد اعشاری را درست بنویسید:
این نکته شاید ساده به نظر برسد ولی وقتی چند صد خط کد متلب بنویسید و این نکته ساده را فراموش کنید پیدا کردن خطا مثل پیدا کردن سوزن در انبار کاه به نظر می رسد. خیلی ساده است که .5 را با 5. اشتباه بگیرید و یافتن آن میان آن همه کد کار سختی است. پس بهتر است از اول خودتان را عادت بدهید به جای 5. بنویسید: 0.5
2⃣ از توابع و اسامی خود متلب برای نام گذاریی کدهایتان استفاده نکنید:
متاسفانه MATLAB زبان بسیار آسان گیری است و اگر از اسامی تابع هایش برای تابع های خودتان استفاده کنید اشکالی نمی گیرد. اما همین ممکن است به مشکلاتی منجر شود که حل کردنشان بسیار دشواراست چون برنامه تان را می نویسید و با هیچ خطایی مواجه نمی شوید اما نتایجتان را نمی گیرید! مثلا وقتی از کلماتی مانند ans ، filter، mean استفاده کنید به مشکل بر میخورید. برای اینکه مطمئن شوید اسم تابع تان قبلا درMATLAB ثبت نشده کافیست در خط فرمان متلب بنویسید:
»which myname

که در آن myname اسم تابع یا متغیر شماست. اگر قبلا در متلب این اسم ثبت نشده باشد با خطای
 ‘myname’ not found.

روبرو می شوید که به این معنی است که شما آزادید از آن نام استفاده کنید در غیر این صورت بهتر است اسم دیگری انتخاب کنید.
3⃣ تا جایی که می توانید از فاصله و semicolonاستفاده کنید:
کدی که بخش بندی شده و از فاصله بین متغیرها و عملگر ها استفاده می کند راحتتر قابل خواندن است و دیرتر از کد زدن خسته یا زده می شوید. پس سعی کنید تا جایی که می توانید تمیز بنویسید.
@MatlabTips
4⃣ اسم های با مسما برای متغیر هایتان استفاده کنید:
اگر از اسم های با معنی تری در کد هایتان استفاده کنید خواندن دوباره کدها برایتان ساده تر می شود. بنابراین از اسم های ناشیانه ای مثل aaa، temp، r1 وغیره که فقط باعث سردرگمی بیشتر می شوند خودداری کنید. اسم هایی مثل centroidX ، fidCurrentFile و غیره بسیار مناسب تر هستند. اگر برای اسمی به نظرتان نمی رسد احتمالا آن قسمت از کد را درست متوجه نشده اید! فراموش نکنید که برنامه نویسی فراتر از خروجی گرفتن است، کدهای شما می بایست مانند یک داستان روایت مناسبی از آنچه الگوریتم انجام می دهد باشد: بسیار شبیه به آنچه برای دوستتان تعریف می کنید.
✔️ به نمونه کد های زیر دقت کنید و هر دو یک کار را انجام می دهند اما...
(A-2)
(ادامه دارد)
🔵تجاربی از کار با MATLAB که سال ها طول می کشد یاد بگیرید(ادامه)🔵
(پیش نیاز: بدون پیش نیاز)
@MatlabTips
5⃣ متغیر هایتان را هارد کد(Hardcode) نکنید:
اگر اندازه متغیری که استفاده می کنید در حدود یک ماتریس 3 در 3 باشد مشکلی برای نوشتن آن در فایل کد( با پسوند .m) نیست. اما اگر متغیری که دارید بزرگتر از اندازه معمول( بالاتر از چند مگابایت) بود بهتر است آن را در یک فایل جداگانه بگذارید و آن را بخوانید تا هم قابلیت استفاده دوباره کد خود را بالا ببرید و هم بهتر قابل خواندن باشد.(بعدا در این مورد مطالبی قرار خواهیم داد.)

6⃣ فایل هایِ کد بزرگ نسازید:
یکی از مواردی که بسیاری از برنامه نویسان مبتدی را زود از کار خسته می کند نوشتن برنامه های بزرگ در یک فایل است. این البته ربطی به ذهن آن ها ندارد حتی یک برنامه نویس حرفه ای هم با دیدن یک فایل بسیار بزرگ شامل چند صد خط کد، گیج و سردر گم می شود. برای شکستن برنامه تان می توانید از برنامه نویسی شی گرا استفاده کنید یا اگر با مفاهیم شی گرایی آشنا نیستید حداقل از توابع استفاده کنید. یک راه خوب این است که با خودتان قرار بگذارید که هر تابعی که می نویسید حداکثر در یک صفحه (بدون اسکرول کردن) قابل دیدن باشد. این کار شاید همیشه ممکن نباشد. اما حداقل با استفاده از کامنت قسمت های کد را به صورت منطقی از هم جدا کنید. با %% می توان برنامه را بخش بندی کرد. در شکل زیر یک نمونه از بخش بندی برنامه با استفاده از همین روش میبینید. در هر قسمت که کلیک میکنید آن قسمت به صورت زرد رنگ(در ادیتور MATLAB) نمایش داده می شود.

7⃣ از متغیر های Global دوری کنید:
نمی توان کدی که شامل متغیر های Global هست را یک کد خوب دانست. دلیل ساده آن این است که وقتی از متغیر Global استفاده می کنید خودتان هم نمی دانید که بازه(scope) متغیرتان کجاست.(تنها یک استثنا برای آن وجود دارد و آن هم توابع tic و toc است)
@MatlabTips
(A-2)
🔵دسترسی بهینه به عناصر ماتریس‌ها در MATLAB🔵
پیش‌نیاز: آشنایی مقدماتی با کد نویسی در MATLAB

یک راه ساده برای بهبود عملکرد کد MATLAB دسترسی به عناصر ماتریس‌های چندبعدی به شیوه‌ای است که خود MATLAB آنها را درون حافظه ذخیره‌سازی می‌کند.
ماتریس A را در نظر بگیرید:
| a11 a12 a13 |
A =| a21 a22 a23 |
| a31 a32 a33 |

اگرچه این یک ماتریس دو بعدی است، داده‌های آن بصورت ترتیبی در حافظه کامپیوتر ذخیره می‌شود. برای تبدیل ماتریس‌های چندبعدی به نمایش آرایه‌های ترتیبی، MATLAB از فرمت بر اساس ستون‌ (column-major) استفاده می‌کند. در این فرمت عناصر یک ستون ابتدا ذخیره شده و سپس عناصر ستون کناری به دنبال آن ذخیره می‌شود. در حالت ستون بیس، ماتریس A بصورت زیر ذخیره می شود.


[a11 a21 a31 a12 a22 a32 a13 a23 a33]
مثال:
این کد بر اساس ردیف (row-major) عناصر ماتریس را می‌خواند.
X = randn(N);
Y = zeros(N);
for row = 1:N % Row
for col = 1:N % Column
if X(row,col) >= 0
Y(row,col) = X(row,col);
end
end
end

این کد بر اساس ستون به عناصر ماتریس دسترسی دارد و 1.7 برابر (در ماشین من) سریعتر است.
N = 5e3;
X = randn(N);
Y = zeros(N);
for col = 1:N % Column
for row = 1:N % Row
if X(row,col) >= 0
Y(row,col) = X(row,col);
end
end
end

@MatlabTips
🔵آزمون محک در Matlab🔵
پیش‌نیاز : (پیش‌نیاز ندارد)

فرمان bench شش کار متفاوت در Matlab اعم از (LU, FFT,ODE, …) را برای آزمون محک (test bench) در نظر می‌گیرد. سرعت اجرای این کارها بر روی سیستم شما با سرعت اجرای آنها بر روی چندین کامپیوتر دیگر مقایسه می‌شود.
نمودرا میله‌ای که در پایان ظاهر می‌شود، سرعت را نمایش می‌دهد. میله‌های بزرگتر بیانگر ماشین‌های سریع‌تر هستند و میله‌های کوچکتر بیانگر ماشین‌های کندتر.
✔️مثال:
دستور زیر را در پنجره فرمان (command window) وارد کرده تا قدرت سیستم خود را با سیستم های موجود مقایسه کنید.
>> bench

@MatlabTips
(A-1)
🔵کاهش پیچیدگی محاسباتی🔵
#SpeedUp
پیش نیاز: (آشنایی مقدماتی با کدنویسی)
سطح پیچیدگی:🌕🌓🌑🌑🌑

در هنگام اجرای هر نوع پردازش روابط ریاضی بهتر است معادل‌های ساده‌تر آن را یافته و در کد استفاده کنیم. در این موارد حتی اگر کد کاملا برداری‌شده باشد استفاده از این روش می‌تواند کد را سریع‌تر کند. دو عملگر + و – از عملگرهای * و / سریع‌تر هستند و این دو عملگر از توان سریع‌تر عمل می‌کنند.
✔️به مثال زیر توجه کنید که چگونه عملگرها را به لحاظ عملکرد با یکدیگر مقایسه می‌کند. دقت کنید که کد اول که از عملگر توان استفاده می کند چندین برابر کندتر از معادل های دیگر خود می باشد.

%% slow approach using a.^n
a = 0.9999; n = 10000;
for idx=1:1000
y=a.^(1:n);
end

%% Using exp(log(a)*n) - 8x faster
for idx=1:1000
y=exp(log(a)*(1:n));
end

%% Using cumprod(a) - 40x faster
for idx=1:1000
y=cumprod(zeros(1,n)+a);
end


@MatlabTips
(A-1)