آشنایی با متغیرها و انواع داده در متلب (همراه با مثال کدی)

فهرست مطالب

متلب (MATLAB)، مخفف “Matrix Laboratory”، یک محیط قدرتمند برنامه‌نویسی برای محاسبات عددی، تحلیل داده‌ها، توسعه الگوریتم‌ها، و مدل‌سازی سیستم‌ها است. این ابزار به دلیل رویکرد ماتریس‌محور خود، به ویژه در حوزه‌های مهندسی، علوم، و تحقیقات دانشگاهی، محبوبیت چشمگیری دارد. یکی از اساسی‌ترین مفاهیم در هر زبان برنامه‌نویسی، از جمله متلب، درک متغیرها و انواع داده است. متغیرها به عنوان ظروفی برای ذخیره اطلاعات عمل می‌کنند، در حالی که انواع داده، ماهیت این اطلاعات (عدد، متن، منطقی و غیره) و نحوه ذخیره و پردازش آن‌ها توسط متلب را تعیین می‌کنند.

برای کاربران متخصص متلب، درک عمیق از متغیرها و انواع داده فراتر از صرفاً دانستن نحوه تعریف آن‌ها است. این شامل شناخت تفاوت‌های ظریف بین انواع داده مختلف، انتخاب نوع داده مناسب برای بهینه‌سازی عملکرد و مصرف حافظه، و آگاهی از نحوه تعامل آن‌ها در عملیات‌های پیچیده ماتریسی و آرایه‌ای می‌شود. این پست وبلاگ به بررسی جامع و تخصصی متغیرها و انواع داده در متلب می‌پردازد و با ارائه مثال‌های کدی متعدد، به شما کمک می‌کند تا درک خود را از این مفاهیم بنیادی ارتقا بخشید و کدهای کارآمدتر و قابل اعتمادتری بنویسید.

از معرفی اصول اولیه تعریف متغیرها و قواعد نام‌گذاری آن‌ها گرفته تا غواصی عمیق در انواع داده عددی، غیرعددی، و ساختارهای داده پیشرفته مانند سلول‌ها، ساختارها و جداول، هر جنبه‌ای با جزئیات بررسی خواهد شد. همچنین، به اهمیت مدیریت حافظه و توابع کاربردی برای تشخیص و تبدیل انواع داده اشاره خواهیم کرد. هدف نهایی این است که شما را به دانش و ابزارهای لازم برای استفاده حداکثری از قابلیت‌های متلب در پروژه‌های پیچیده خود مجهز کنیم.

مقدمه: چرا درک متغیرها و انواع داده در متلب حیاتی است؟

در قلب هر برنامه متلب، متغیرها و انواع داده قرار دارند. این دو مفهوم نه تنها سنگ بنای هرگونه عملیات محاسباتی هستند، بلکه نقش حیاتی در کارایی، خوانایی و صحت کدهای شما ایفا می‌کنند. شاید در نگاه اول، متغیرها تنها مکانی برای ذخیره اعداد یا متن به نظر برسند، اما در محیط پویای متلب، پیچیدگی‌ها و ظرافت‌هایی وجود دارد که درک آن‌ها برای هر توسعه‌دهنده یا محقق متخصص، ضروری است.

یکی از دلایل اصلی اهمیت این موضوع، طبیعت دینامیک متلب در مدیریت انواع داده است. برخلاف بسیاری از زبان‌های برنامه‌نویسی استاتیک مانند C++ یا جاوا که در آن‌ها باید نوع داده یک متغیر را هنگام تعریف آن به صراحت اعلام کنید، متلب به صورت خودکار نوع داده را بر اساس مقداری که به متغیر تخصیص می‌دهید، تعیین می‌کند. این ویژگی، انعطاف‌پذیری زیادی به کاربر می‌دهد، اما در عین حال می‌تواند منجر به چالش‌هایی در مدیریت حافظه، دقت محاسبات و حتی عملکرد برنامه شود، به خصوص زمانی که با مجموعه‌های داده بزرگ یا عملیات‌های پیچیده سروکار دارید. به عنوان مثال، اگر بدون توجه به ماهیت داده‌های خود، همه اعداد را به صورت پیش‌فرض double نگه دارید، ممکن است به طور غیرضروری حافظه زیادی را اشغال کنید یا در برخی موارد، دقت کافی برای محاسبات خاص را نداشته باشید.

درک اینکه چگونه متلب داده‌ها را در حافظه ذخیره می‌کند و چگونه عملیات مختلف بر روی انواع داده‌های متفاوت انجام می‌شوند، به شما امکان می‌دهد تا کدهای بهینه‌تری بنویسید. برای مثال، استفاده از انواع داده صحیح (integer) به جای اعداد ممیز شناور (floating-point) در مواردی که نیاز به دقت اعشاری نیست (مانند شمارش‌ها یا اندیس‌گذاری)، می‌تواند منجر به صرفه‌جویی قابل توجهی در حافظه و افزایش سرعت اجرا شود. همچنین، زمانی که با داده‌های بزرگ مانند تصاویر (که معمولاً به صورت uint8 ذخیره می‌شوند) یا سیگنال‌ها سروکار دارید، انتخاب نوع داده مناسب حیاتی است.

علاوه بر این، درک انواع داده به شما کمک می‌کند تا خطاهای رایج را شناسایی کرده و از آن‌ها اجتناب کنید. خطاهایی مانند ناسازگاری انواع داده در عملیات‌ها، از دست دادن دقت در تبدیل‌ها، یا استفاده نادرست از آرایه‌های سلولی و ساختارها، می‌توانند منجر به نتایج غیرمنتظره و اشکال‌زدایی دشوار شوند. با شناخت دقیق ویژگی‌های هر نوع داده، می‌توانید از همان ابتدا ساختار داده‌ای مناسب را انتخاب کرده و از بروز چنین مشکلاتی جلوگیری کنید.

در نهایت، برای هر متخصصی که با متلب کار می‌کند، تسلط بر متغیرها و انواع داده به معنای نوشتن کدی است که نه تنها کار می‌کند، بلکه کارآمد، مقیاس‌پذیر، و قابل نگهداری نیز هست. این پایه و اساس برای حرکت به سمت مفاهیم پیشرفته‌تر مانند برنامه‌نویسی شیءگرا، توسعه ابزارهای سفارشی، و پیاده‌سازی الگوریتم‌های پیچیده است. در بخش‌های بعدی، به تفصیل به این مفاهیم خواهیم پرداخت و با مثال‌های عملی، این نکات را روشن خواهیم ساخت.

اساس متغیرها در متلب: تعریف، نام‌گذاری و تخصیص مقادیر

متغیر در متلب، یک نام نمادین برای یک مکان در حافظه کامپیوتر است که مقداری از داده را ذخیره می‌کند. هر بار که شما یک متغیر را در متلب تعریف می‌کنید و مقداری به آن اختصاص می‌دهید، متلب یک بخش از حافظه را برای ذخیره آن مقدار رزرو کرده و آن نام را به آن مکان پیوند می‌دهد. در ادامه به جزئیات این فرآیند می‌پردازیم.

نام‌گذاری متغیرها در متلب

انتخاب نام مناسب برای متغیرها نه تنها به خوانایی کد کمک می‌کند، بلکه از بروز خطاهای احتمالی نیز جلوگیری می‌کند. متلب برای نام‌گذاری متغیرها قواعد خاصی دارد:

  • شروع با حرف: نام متغیرها باید با یک حرف (انگلیسی) شروع شوند.
  • کاراکترهای مجاز: پس از حرف اول، می‌توانند شامل حروف (بزرگ و کوچک)، اعداد و خط زیر (underscore `_`) باشند.
  • حساس به بزرگی و کوچکی حروف (Case-Sensitive): متلب به بزرگی و کوچکی حروف حساس است. بنابراین، `myVar` و `myvar` دو متغیر مجزا محسوب می‌شوند.
  • حداکثر طول: طول نام متغیرها می‌تواند تا ۶۳ کاراکتر باشد. اگرچه، برای خوانایی بهتر، استفاده از نام‌های کوتاه‌تر و معنادار توصیه می‌شود.
  • کلمات کلیدی رزرو شده: نمی‌توانید از کلمات کلیدی رزرو شده متلب (مانند `for`, `if`, `while`, `function`, `end`, `clear` و…) به عنوان نام متغیر استفاده کنید. متلب به صورت خودکار این کلمات را تشخیص می‌دهد.
  • توصیه: از نام‌هایی استفاده کنید که ماهیت داده‌ای که ذخیره می‌کنند را منعکس کنند (مانند `temperature_celsius`، `sensor_data_matrix`).

مثال‌هایی از نام‌گذاری متغیرها:

% نام‌گذاری صحیح
myVariable = 10;
another_Variable = 'Hello';
Data_2023 = [1 2 3];
Result_Final = true;

% نام‌گذاری نادرست (که متلب خطا می‌دهد یا اخطار)
% 1variable = 5; % شروع با عدد
% my-variable = 12; % استفاده از خط تیره (-)
% for = 100; % کلمه کلیدی رزرو شده

تخصیص و نمایش مقادیر

تخصیص مقدار به یک متغیر در متلب با استفاده از عملگر انتساب (`=`) انجام می‌شود. متلب به صورت پیش‌فرض، مقدار تخصیص یافته را در خط فرمان نمایش می‌دهد، مگر اینکه خط با یک نقطه ویرگول (`;`) به پایان برسد. نقطه ویرگول برای سرکوب نمایش خروجی در خط فرمان استفاده می‌شود که در اسکریپت‌ها و توابع برای جلوگیری از حجم زیاد خروجی، بسیار مفید است.

مثال تخصیص و نمایش:

% تخصیص و نمایش مقدار (بدون نقطه ویرگول)
x = 5
% خروجی:
% x =
%      5

% تخصیص مقدار بدون نمایش خروجی (با نقطه ویرگول)
y = 10;

% انجام عملیات و تخصیص به متغیر جدید
z = x + y; % z برابر با 15 خواهد بود

% نمایش مقدار متغیرها به روش‌های مختلف
z % نمایش مقدار z (فقط در خط فرمان)
disp(z); % نمایش مقدار z با تابع disp
disp('مقدار z برابر است با:');
disp(z);

% استفاده از fprintf برای نمایش فرمت‌بندی شده
fprintf('مقدار x برابر است با: %d و مقدار y برابر است با: %d\n', x, y);
fprintf('حاصل جمع x و y برابر است با: %d\n', z);

فضای کاری متلب (Workspace)

فضای کاری (Workspace) متلب، جایی است که تمام متغیرهایی که در طول یک نشست متلب ایجاد می‌کنید، ذخیره می‌شوند. می‌توانید با دستورات مختلفی این فضا را مدیریت کنید:

  • `who`: لیستی از نام تمام متغیرهای موجود در فضای کاری را نمایش می‌دهد.
  • `whos`: اطلاعات جزئی‌تری شامل نام، اندازه (Size)، تعداد عناصر (Bytes)، نوع داده (Class) و ویژگی‌ها (Attributes) را برای هر متغیر نمایش می‌دهد. این دستور برای مدیریت حافظه بسیار مفید است.
  • `clear`: یک یا چند متغیر خاص را از فضای کاری حذف می‌کند.
  • `clear all`: تمامی متغیرها، توابع و MEX-فایل‌ها را از فضای کاری پاک می‌کند.
  • `save`: متغیرهای فضای کاری را در یک فایل `.mat` ذخیره می‌کند.
  • `load`: متغیرها را از یک فایل `.mat` به فضای کاری بارگذاری می‌کند.

مثال مدیریت فضای کاری:

% ایجاد چند متغیر
a = 10;
b = 'hello';
c = [1 2 3];

% مشاهده متغیرها
who
% خروجی:
% Your variables are:
%
% a  b  c

whos
% خروجی مشابه زیر خواهد بود (جزئیات مربوط به حجم و ابعاد)
%   Name      Size            Bytes  Class    Attributes
%
%   a         1x1                 8  double
%   b         1x5                10  char
%   c         1x3                24  double

% پاک کردن متغیر 'b'
clear b

% مشاهده مجدد فضای کاری
who
% خروجی:
% Your variables are:
%
% a  c

% پاک کردن تمامی متغیرها
clear all
who % خروجی خالی خواهد بود

متغیرهای از پیش تعریف شده

متلب دارای مجموعه‌ای از متغیرهای از پیش تعریف شده است که کاربر می‌تواند از آن‌ها استفاده کند:

  • `ans`: اگر نتیجه یک عبارت را به هیچ متغیری تخصیص ندهید، متلب به طور خودکار آن را در متغیر `ans` (answer) ذخیره می‌کند.
  • `pi`: مقدار π (عدد پی) با دقت double.
  • `i` یا `j`: واحد موهومی برای اعداد مختلط (√-1).
  • `eps`: کوچکرین عدد ممیز شناور مثبت که وقتی به عدد ۱ اضافه شود، نتیجه‌ای بزرگتر از ۱ تولید کند. این مقدار نشان‌دهنده دقت محاسبات ممیز شناور است.
  • `inf`: نشان‌دهنده بی‌نهایت (مانند نتیجه تقسیم یک عدد مثبت بر صفر).
  • `NaN`: مخفف “Not-a-Number”، نشان‌دهنده یک مقدار عددی تعریف نشده (مانند نتیجه تقسیم صفر بر صفر یا بی‌نهایت منهای بی‌نهایت).

مثال متغیرهای از پیش تعریف شده:

% مثال استفاده از ans
5 + 3
% ans = 8
ans * 2
% ans = 16

% استفاده از pi
circumference = 2 * pi * 5; % محیط دایره با شعاع 5
disp(circumference);

% اعداد مختلط
complex_num = 3 + 4i;
complex_num_j = 5 + 6j;
disp(complex_num);
disp(complex_num_j);

% eps
double_precision_epsilon = eps;
disp(['Epsilon for double: ', num2str(double_precision_epsilon)]);

% inf و NaN
result_inf = 10 / 0;
disp(result_inf);
result_nan = 0 / 0;
disp(result_nan);

با درک این مفاهیم بنیادی، شما آماده هستید تا به دنیای انواع داده در متلب قدم بگذارید و ببینید چگونه متلب انواع مختلف اطلاعات را مدیریت و پردازش می‌کند.

انواع داده عددی در متلب: از اعداد صحیح تا ممیز شناور و مختلط

متلب به طور پیش‌فرض، همه اعداد را به عنوان نوع داده `double` (ممیز شناور با دقت مضاعف) ذخیره می‌کند. با این حال، طیف وسیعی از انواع داده عددی دیگر را نیز پشتیبانی می‌کند که هر یک دارای محدودیت‌ها و کاربردهای خاص خود هستند. انتخاب صحیح نوع داده عددی می‌تواند به بهینه‌سازی حافظه و افزایش سرعت محاسبات کمک کند.

اعداد ممیز شناور (Floating-Point Numbers)

اعداد ممیز شناور برای نمایش اعداد حقیقی (با قسمت اعشاری) استفاده می‌شوند. دو نوع اصلی از این داده‌ها در متلب وجود دارد:

Double Precision (دقت مضاعف)

این نوع داده، پیش‌فرض متلب برای اعداد است. اعداد `double` ۶۴ بیتی هستند و می‌توانند اعداد بسیار بزرگ یا بسیار کوچک را با دقت بالا (تقریباً ۱۵ تا ۱۷ رقم اعشار) نمایش دهند. این دقت برای اکثر کاربردهای علمی و مهندسی کافی است.

  • حافظه: ۸ بایت (۶۴ بیت) برای هر عدد.
  • محدوده: از حدود 10-308 تا 10308.
% مثال Double Precision
a = 3.1415926535; % به صورت پیش‌فرض double است
class(a) % خروجی: 'double'

b = 1/3;
sprintf('%.16f', b) % نمایش با 16 رقم اعشار: '0.3333333333333333'

large_num = 1.2345e+200; % عدد بسیار بزرگ
small_num = 6.789e-250;  % عدد بسیار کوچک

Single Precision (دقت تنها)

اعداد `single` ۳۲ بیتی هستند و دقت کمتری (تقریباً ۷ تا ۸ رقم اعشار) نسبت به `double` دارند، اما حافظه کمتری نیز اشغال می‌کنند. زمانی که نیاز به دقت بالا نیست یا برای کار با داده‌های بسیار بزرگ که حافظه عامل محدودکننده است (مثلاً در پردازش تصویر)، `single` می‌تواند انتخاب مناسبی باشد.

  • حافظه: ۴ بایت (۳۲ بیت) برای هر عدد.
  • محدوده: از حدود 10-38 تا 1038.
% مثال Single Precision
s = single(3.14159265); % تبدیل صریح به single
class(s) % خروجی: 'single'

s_result = single(1) / single(3);
sprintf('%.8f', s_result) % نمایش با 8 رقم اعشار: '0.33333334' (دقت کمتر)

% تفاوت در دقت
d_val = 123456789.123456789;
s_val = single(d_val);
fprintf('Double: %.15f\n', d_val);
fprintf('Single: %.15f\n', s_val);
% خروجی نشان می‌دهد که single ارقام اعشار کمتری را حفظ می‌کند.

نکته: در محاسبات با `single` و `double`، اگر یکی از عملوندها `single` و دیگری `double` باشد، متلب معمولاً عملوند `single` را به `double` تبدیل کرده و نتیجه را به صورت `double` برمی‌گرداند تا از از دست رفتن دقت جلوگیری کند.

اعداد صحیح (Integers)

اعداد صحیح برای نمایش اعداد کامل (بدون قسمت اعشاری) استفاده می‌شوند. این انواع داده زمانی مفید هستند که نیاز به دقت اعشاری نباشد (مانند اندیس‌ها، شمارنده‌ها، مقادیر پیکسل در تصاویر) و می‌توانند حافظه را به طور قابل توجهی بهینه کنند. متلب چندین نوع داده صحیح را ارائه می‌دهد که بر اساس تعداد بیت‌ها و علامت‌دار بودن (signed/unsigned) دسته‌بندی می‌شوند.

اعداد صحیح علامت‌دار (Signed Integers)

این اعداد می‌توانند مقادیر مثبت و منفی را ذخیره کنند. هر چه تعداد بیت‌ها بیشتر باشد، محدوده اعداد قابل ذخیره نیز بزرگ‌تر است.

  • `int8`: ۸ بیت، محدوده از -۱۲۸ تا ۱۲۷.
  • `int16`: ۱۶ بیت، محدوده از -۳۲۷۶۸ تا ۳۲۷۶۷.
  • `int32`: ۳۲ بیت، محدوده از حدود 2×109– تا 2×109.
  • `int64`: ۶۴ بیت، محدوده از حدود 9×1018– تا 9×1018.
% مثال Signed Integers
i8 = int8(120);
class(i8) % خروجی: 'int8'
intmax('int8') % نمایش حداکثر مقدار: 127
intmin('int8') % نمایش حداقل مقدار: -128

i16 = int16(32000);
class(i16) % خروجی: 'int16'

% سرریز (Overflow): اگر مقداری خارج از محدوده ذخیره کنید، متلب آن را به نزدیکترین مقدار مجاز گرد می‌کند.
over_i8 = int8(150); % 150 > 127, پس over_i8 برابر با 127 خواهد شد
disp(over_i8);

اعداد صحیح بدون علامت (Unsigned Integers)

این اعداد فقط می‌توانند مقادیر صفر یا مثبت را ذخیره کنند. با استفاده از تمام بیت‌ها برای نمایش اندازه، محدوده مثبت بزرگ‌تری نسبت به نوع علامت‌دار معادل دارند.

  • `uint8`: ۸ بیت، محدوده از ۰ تا ۲۵۵. (بسیار رایج برای تصاویر خاکستری)
  • `uint16`: ۱۶ بیت، محدوده از ۰ تا ۶۵۵۳۵.
  • `uint32`: ۳۲ بیت، محدوده از ۰ تا حدود 4×109.
  • `uint64`: ۶۴ بیت، محدوده از ۰ تا حدود 1.8×1019.
% مثال Unsigned Integers
u8 = uint8(250);
class(u8) % خروجی: 'uint8'
uintmax('uint8') % نمایش حداکثر مقدار: 255
uintmin('uint8') % نمایش حداقل مقدار: 0

% مثال رایج در پردازش تصویر
pixel_value = uint8(150);
another_pixel = uint8(200);
sum_pixels = pixel_value + another_pixel; % 150 + 200 = 350. اما uint8 حداکثر 255 است.
disp(sum_pixels); % خروجی: 255 (سرریز)

تبدیل انواع عددی

می‌توانید انواع داده عددی را به یکدیگر تبدیل کنید. این کار با استفاده از توابع همنام با نوع داده مقصد (مانند `double()`, `single()`, `int8()`, `uint16()`) انجام می‌شود. در هنگام تبدیل از ممیز شناور به صحیح، قسمت اعشاری به سمت صفر گرد می‌شود.

% مثال تبدیل انواع عددی
x_double = 10.75;
x_int = int32(x_double); % تبدیل به عدد صحیح 32 بیتی: 10
disp(['Double: ', num2str(x_double), ', Int32: ', num2str(x_int)]);

x_single = single(x_int); % تبدیل به single: 10.0
disp(['Int32: ', num2str(x_int), ', Single: ', num2str(x_single)]);

% تبدیل از int به double
y_int = int16(500);
y_double = double(y_int);
disp(['Int16: ', num2str(y_int), ', Double: ', num2str(y_double)]);

اعداد مختلط (Complex Numbers)

متلب به طور کامل از اعداد مختلط پشتیبانی می‌کند، که شامل یک قسمت حقیقی و یک قسمت موهومی هستند. واحد موهومی با `i` یا `j` نمایش داده می‌شود (√-1).

  • اعداد مختلط به طور پیش‌فرض از نوع `double` هستند.
  • می‌توانید آن‌ها را با قسمت حقیقی و موهومی مستقیماً تعریف کنید.
% مثال اعداد مختلط
z1 = 2 + 3i;  % 2 قسمت حقیقی، 3 قسمت موهومی
z2 = 4 - 5j;  % همچنین می‌توانید از j استفاده کنید
class(z1) % خروجی: 'double' (اگرچه مختلط است)

% عملیات با اعداد مختلط
sum_z = z1 + z2;     % جمع
prod_z = z1 * z2;    % ضرب
div_z = z1 / z2;     % تقسیم

% توابع برای کار با اعداد مختلط
real_part = real(z1);     % قسمت حقیقی: 2
imag_part = imag(z1);     % قسمت موهومی: 3
magnitude = abs(z1);      % قدر مطلق (اندازه): sqrt(2^2 + 3^2) = 3.6056
angle_rad = angle(z1);    % زاویه (فاز) در رادیان: 0.9828
conjugate = conj(z1);     % مزدوج مختلط: 2 - 3i

disp(['z1: ', num2str(z1)]);
disp(['Magnitude of z1: ', num2str(magnitude)]);
disp(['Angle of z1 (rad): ', num2str(angle_rad)]);
disp(['Conjugate of z1: ', num2str(conjugate)]);

درک این انواع داده عددی و محدودیت‌های آن‌ها برای نوشتن کدهای متلب کارآمد، دقیق و بهینه ضروری است، به ویژه در کاربردهایی که با حجم زیادی از داده‌ها یا محاسبات حساس به دقت سروکار دارند.

انواع داده غیر عددی اساسی: کاراکترها، رشته‌ها و آرایه‌های منطقی

متلب علاوه بر اعداد، از انواع داده‌ای برای ذخیره اطلاعات غیر عددی مانند متن و مقادیر منطقی (درست/غلط) نیز پشتیبانی می‌کند. این انواع داده در کارهای روزمره، از نمایش نتایج تا کنترل جریان برنامه، نقش حیاتی دارند.

آرایه‌های کاراکتری (Character Arrays)

آرایه‌های کاراکتری (char arrays) برای ذخیره متن استفاده می‌شوند و به صورت بردارهایی از کاراکترها در نظر گرفته می‌شوند. هر کاراکتر در متلب به صورت یک عدد صحیح بدون علامت ۱۶ بیتی (uint16) ذخیره می‌شود که کد یونیکد آن کاراکتر را نشان می‌دهد. آرایه‌های کاراکتری با استفاده از علامت نقل قول تکی (`’`) تعریف می‌شوند.

  • ماهیت برداری: یک آرایه کاراکتری در واقع یک بردار ردیفی است که هر عنصر آن یک کاراکتر است.
  • اندازه: برای ذخیره چندین خط متن، می‌توانید از یک ماتریس کاراکتری استفاده کنید که در آن هر ردیف یک خط متن را نشان می‌دهد. در این حالت، تمام ردیف‌ها باید طول یکسانی داشته باشند، که در صورت لزوم با فضاهای خالی (` `) تکمیل می‌شوند.
% مثال آرایه‌های کاراکتری
char_array = 'Hello, MATLAB!';
class(char_array) % خروجی: 'char'
size(char_array)  % خروجی: 1 14 (بردار ردیفی با 14 کاراکتر)
length(char_array) % خروجی: 14

% ماتریس کاراکتری (برای چندین خط متن)
multi_line_char = ['First Line '; 'Second Line']; % ' ' برای تراز کردن طول ردیف‌ها
size(multi_line_char) % خروجی: 2 12 (دو ردیف، هر ردیف 12 کاراکتر)

% دسترسی به عناصر
first_char = char_array(1); % 'H'
fifth_char = char_array(5); % 'o'

آرایه‌های رشته‌ای (String Arrays)

آرایه‌های رشته‌ای (string arrays) که از MATLAB R2016b به بعد معرفی شدند، یک راهکار مدرن‌تر و انعطاف‌پذیرتر برای کار با متن در متلب ارائه می‌دهند. رشته‌ها با استفاده از علامت نقل قول دوتایی (`”`) تعریف می‌شوند.

  • انعطاف‌پذیری: بر خلاف آرایه‌های کاراکتری، آرایه‌های رشته‌ای می‌توانند شامل رشته‌هایی با طول‌های متفاوت باشند.
  • نوع داده: هر عنصر یک آرایه رشته‌ای، خودش یک شیء از نوع `string` است.
  • عملیات ساده‌تر: بسیاری از توابع دستکاری رشته‌ها با آرایه‌های رشته‌ای به صورت بصری‌تر و ساده‌تر کار می‌کنند.
% مثال آرایه‌های رشته‌ای
str_array = "Hello, World!";
class(str_array) % خروجی: 'string'
size(str_array)  % خروجی: 1 1 (یک رشته اسکالر)

% آرایه رشته‌ای با چندین عنصر (طول‌های متفاوت مجاز است)
str_multiple = ["apple", "banana", "cherry"];
size(str_multiple) % خروجی: 1 3 (یک بردار ردیفی از 3 رشته)

% دسترسی به عناصر
first_str = str_multiple(1); % "apple"
second_str = str_multiple(2); % "banana"

% اتصال رشته‌ها
greeting = "Hi" + " " + "there!"; % "Hi there!"
combined_str = [str_multiple, "date"]; % ["apple", "banana", "cherry", "date"]

توابع دستکاری رشته‌ها

متلب مجموعه‌ای غنی از توابع برای کار با متن ارائه می‌دهد که هم برای `char arrays` و هم برای `string arrays` قابل استفاده هستند، اگرچه برخی توابع برای `string arrays` ساده‌تر هستند. برخی از این توابع عبارتند از:

  • `strcat`, `plus (+) `: برای اتصال (concatenation) رشته‌ها. (plus برای string arrays ترجیح داده می‌شود)
  • `strcmp`, `strcmpi`: برای مقایسه رشته‌ها (حساس به بزرگی/کوچکی حروف و بدون حساسیت).
  • `contains`, `startsWith`, `endsWith`: برای بررسی وجود زیررشته یا شروع/پایان با یک الگو.
  • `upper`, `lower`: تبدیل حروف به بزرگ یا کوچک.
  • `split`, `join`: تقسیم رشته به قسمت‌ها و اتصال قسمت‌ها به یک رشته.
  • `num2str`, `str2num`, `str2double`: تبدیل اعداد به رشته و بالعکس.
  • `sprintf`: برای فرمت‌بندی رشته‌ها (مشابه C `printf`).
% مثال توابع دستکاری رشته‌ها
text_data = "MATLAB is powerful.";

% بررسی وجود یک زیررشته
has_powerful = contains(text_data, "powerful"); % true
disp(['Contains "powerful": ', num2str(has_powerful)]);

% تبدیل به حروف بزرگ
upper_text = upper(text_data); % "MATLAB IS POWERFUL."
disp(['Uppercase: ', upper_text]);

% تقسیم رشته
sentence = "This is a sample sentence.";
words = split(sentence, " "); % ["This", "is", "a", "sample", "sentence."]
disp('Words:');
disp(words);

% تبدیل عدد به رشته
num_val = 123.456;
str_num = num2str(num_val, '%.2f'); % "123.46"
disp(['Number to string: ', str_num]);

% تبدیل رشته به عدد
str_val = "987.65";
num_from_str = str2double(str_val); % 987.65 (double)
disp(['String to number: ', num2str(num_from_str)]);

آرایه‌های منطقی (Logical Arrays)

آرایه‌های منطقی برای ذخیره مقادیر `true` (درست) یا `false` (غلط) استفاده می‌شوند. در متلب، `true` به عنوان عدد `1` و `false` به عنوان عدد `0` نمایش داده می‌شود، اما نوع داده آن‌ها همچنان `logical` است. این نوع داده در کنترل جریان برنامه (مانند `if` statements) و نمایه‌گذاری شرطی (conditional indexing) بسیار پرکاربرد است.

  • عملگرهای رابطه‌ای: نتیجه عملگرهای رابطه‌ای (مانند `==` (برابری), `~=` (نابرابری), `>` (بزرگتر), `<` (کوچکتر), `>=` (بزرگتر یا مساوی), `<=` (کوچکتر یا مساوی)) یک آرایه منطقی است.
  • عملگرهای منطقی: `&` (AND منطقی), `|` (OR منطقی), `~` (NOT منطقی), `xor` (XOR منطقی).
  • نمایه‌گذاری منطقی: می‌توان از آرایه‌های منطقی برای انتخاب زیرمجموعه‌ای از عناصر یک آرایه دیگر استفاده کرد.
% مثال آرایه‌های منطقی
is_positive = (5 > 0); % true
class(is_positive) % خروجی: 'logical'

is_equal = (10 == 20); % false

% ایجاد آرایه منطقی از یک بردار
vec = [10, -5, 0, 15, -20];
is_greater_than_zero = (vec > 0); % [true, false, false, true, false]
disp('Vector > 0:');
disp(is_greater_than_zero);

% عملیات منطقی
A = [true, false, true];
B = [false, true, true];
C_and = A & B; % [false, false, true]
C_or = A | B;  % [true, true, true]
C_not = ~A;    % [false, true, false]
disp('A AND B:');
disp(C_and);

% نمایه‌گذاری منطقی
data_vec = [100, 200, 300, 400, 500];
% انتخاب عناصری که بزرگتر از 250 هستند
filtered_data = data_vec(data_vec > 250); % [300, 400, 500]
disp('Filtered data:');
disp(filtered_data);

% استفاده از find برای یافتن اندیس‌ها
indices_gt_250 = find(data_vec > 250); % [3 4 5]
disp('Indices > 250:');
disp(indices_gt_250);

% توابع true و false
all_true = true(2, 3); % یک ماتریس 2x3 از true
all_false = false(1, 5); % یک بردار 1x5 از false

آرایه‌های کاراکتری، رشته‌ها و منطقی ابزارهای قدرتمندی برای کار با داده‌های غیر عددی در متلب هستند. انتخاب بین آرایه‌های کاراکتری و رشته‌ای عمدتاً به نسخه متلب شما و نوع کاری که انجام می‌دهید بستگی دارد، اما برای کدهای جدید، استفاده از آرایه‌های رشته‌ای توصیه می‌شود. آرایه‌های منطقی نیز در ایجاد کدهای شرطی و فیلتر کردن داده‌ها نقشی اساسی ایفا می‌کنند.

آرایه‌ها و ماتریس‌ها در متلب: قلب محاسبات ماتریسی

متلب (MATLAB) که مخفف “Matrix Laboratory” است، از ابتدا برای کار با ماتریس‌ها و آرایه‌ها طراحی شده است. تقریباً هر نوع داده‌ای در متلب می‌تواند به عنوان یک آرایه یا ماتریس در نظر گرفته شود، حتی یک اسکالر (عدد تنها) نیز به عنوان یک ماتریس 1×1 تلقی می‌شود. درک عمیق این ساختار داده بنیادی، کلید باز کردن پتانسیل کامل متلب برای محاسبات علمی، مهندسی، و تحلیل داده‌ها است.

مقدمه بر آرایه‌ها و ماتریس‌ها

در متلب، تفاوت بین آرایه (Array) و ماتریس (Matrix) عمدتاً در نحوه انجام عملیات ریاضی است. یک ماتریس معمولاً به یک آرایه دو بعدی اشاره دارد که عملیات جبر خطی بر روی آن انجام می‌شود (مانند ضرب ماتریسی). یک آرایه یک اصطلاح کلی‌تر است که می‌تواند شامل هر تعداد بُعد باشد (بردارهای یک بعدی، ماتریس‌های دو بعدی، یا آرایه‌های N-بعدی) و عملیات بر روی آن می‌تواند به صورت عنصر به عنصر باشد.

  • اسکالر (Scalar): یک مقدار منفرد (ماتریس 1×1).
  • بردار (Vector): یک آرایه یک بعدی (بردار ردیفی 1xN یا بردار ستونی Nx1).
  • ماتریس (Matrix): یک آرایه دو بعدی (MxN).
  • آرایه N-بعدی (N-D Array): آرایه‌ای با بیش از دو بعد (برای مثال، برای ذخیره داده‌های تصویری رنگی یا سری‌های زمانی).

ایجاد آرایه‌ها و ماتریس‌ها

راه‌های متعددی برای ایجاد آرایه‌ها و ماتریس‌ها در متلب وجود دارد:

۱. ایجاد مستقیم (Direct Input)

با استفاده از براکت (`[]`) می‌توانید به صورت مستقیم مقادیر را وارد کنید. برای جداسازی ستون‌ها از فاصله یا کاما (`,`) و برای جداسازی ردیف‌ها از نقطه ویرگول (`;`) استفاده می‌شود.

% مثال ایجاد مستقیم
scalar_val = 5; % اسکالر
row_vector = [1 2 3 4 5]; % بردار ردیفی
column_vector = [1; 2; 3; 4; 5]; % بردار ستونی
matrix_2x3 = [10 20 30; 40 50 60]; % ماتریس 2x3

% دسترسی به ابعاد
size(row_vector)    % 1 5
size(column_vector) % 5 1
size(matrix_2x3)    % 2 3

۲. استفاده از عملگر کولون (Colon Operator `:`)

برای ایجاد دنباله‌ای از اعداد با گام مشخص.

% مثال عملگر کولون
sequence1 = 1:5; % [1 2 3 4 5]
sequence2 = 1:2:10; % [1 3 5 7 9] (شروع، گام، پایان)
sequence3 = 10:-1:1; % [10 9 8 7 6 5 4 3 2 1] (کاهشی)

۳. توابع ایجاد آرایه

متلب توابع زیادی برای ایجاد آرایه‌های خاص فراهم می‌کند:

  • `zeros(m, n)`: ماتریسی با ابعاد m در n که همه عناصر آن صفر هستند.
  • `ones(m, n)`: ماتریسی با ابعاد m در n که همه عناصر آن یک هستند.
  • `eye(n)`: ماتریس همانی (identity matrix) با ابعاد n در n.
  • `rand(m, n)`: ماتریسی با ابعاد m در n که عناصر آن اعداد تصادفی با توزیع یکنواخت بین ۰ و ۱ هستند.
  • `randn(m, n)`: ماتریسی با ابعاد m در n که عناصر آن اعداد تصادفی با توزیع نرمال (میانگین ۰، واریانس ۱) هستند.
  • `linspace(start, end, num)`: بردای ردیفی از `num` نقطه که به طور یکنواخت بین `start` و `end` توزیع شده‌اند.
  • `logspace(d1, d2, n)`: برداری ردیفی از `n` نقطه که به طور لگاریتمی بین 10d1 و 10d2 توزیع شده‌اند.
  • `diag(v)`: اگر `v` یک بردار باشد، یک ماتریس قطری با `v` در قطر اصلی ایجاد می‌کند.
% مثال توابع ایجاد آرایه
zeros_matrix = zeros(3, 4); % ماتریس 3x4 از صفرها
ones_vector = ones(1, 5); % بردار ردیفی 1x5 از یک‌ها
identity_matrix = eye(3); % ماتریس همانی 3x3
random_uniform = rand(2, 2); % ماتریس 2x2 از اعداد تصادفی یکنواخت
line_space = linspace(0, 10, 5); % [0 2.5 5 7.5 10]

عملیات ماتریسی و آرایه‌ای

متلب بین عملیات “ماتریسی” (که از قوانین جبر خطی پیروی می‌کنند) و عملیات “عنصر به عنصر” (که بر روی هر عنصر به صورت جداگانه اعمال می‌شوند) تمایز قائل می‌شود. این تمایز با استفاده از نقطه (`.`) قبل از عملگر اعمال می‌شود.

۱. عملیات عنصر به عنصر (Element-wise Operations)

این عملیات بر روی هر عنصر متناظر از دو آرایه با ابعاد یکسان اعمال می‌شوند. برای این منظور، از نقطه (`.`) قبل از عملگر استفاده می‌شود.

  • `.*`: ضرب عنصر به عنصر.
  • `./`: تقسیم عنصر به عنصر.
  • `.^`: توان عنصر به عنصر.
  • `sqrt()`, `sin()`, `cos()`, `exp()`, `log()`: توابع ریاضی تک-آرگومانی به طور پیش‌فرض عنصر به عنصر عمل می‌کنند.
% مثال عملیات عنصر به عنصر
A = [1 2; 3 4];
B = [5 6; 7 8];

C_element_wise_mult = A .* B; % ضرب عنصر به عنصر
% C_element_wise_mult =
%    5   12
%   21   32

D_element_wise_div = A ./ B; % تقسیم عنصر به عنصر
E_element_wise_pow = A .^ 2; % توان عنصر به عنصر

۲. عملیات ماتریسی (Matrix Operations)

این عملیات از قوانین جبر خطی پیروی می‌کنند و معمولاً بدون نقطه انجام می‌شوند.

  • `*`: ضرب ماتریسی. برای این عمل، تعداد ستون‌های ماتریس اول باید با تعداد ردیف‌های ماتریس دوم برابر باشد.
  • `/`: تقسیم ماتریسی راست (معادل `A * inv(B)`).
  • `\`: تقسیم ماتریسی چپ (معادل `inv(A) * B`).
  • `’`: ترانهاده مزدوج (Conjugate Transpose) – برای ماتریس‌های مختلط.
  • `.`: ترانهاده غیرمزدوج (Non-conjugate Transpose) – برای ماتریس‌های حقیقی.
% مثال عملیات ماتریسی
C_matrix_mult = A * B; % ضرب ماتریسی
% C_matrix_mult =
%   19   22
%   43   50

A_transpose = A'; % ترانهاده مزدوج (برای A حقیقی، همان غیرمزدوج است)
% A_transpose =
%    1   3
%    2   4

% اگر A مختلط باشد:
Z = [1+2i 3; 4 5-1i];
Z_conjugate_transpose = Z'; % [1-2i  4; 3  5+1i]
Z_non_conjugate_transpose = Z.'; % [1+2i  4; 3  5-1i]

نمایه‌گذاری (Indexing)

دسترسی به عناصر یا زیرآرایه‌ها در متلب از طریق نمایه‌گذاری (Indexing) انجام می‌شود. متلب از نمایه‌گذاری مبتنی بر ۱ (1-based indexing) استفاده می‌کند.

۱. نمایه‌گذاری با اندیس (Subscript Indexing)

با استفاده از مختصات ردیف و ستون برای ماتریس‌ها یا بُعدهای بیشتر برای آرایه‌های N-بعدی.

% مثال نمایه‌گذاری با اندیس
matrix_example = [10 20 30; 40 50 60; 70 80 90];

element_at_2_3 = matrix_example(2, 3); % 60
first_row = matrix_example(1, :); % [10 20 30] (کولون ':' به معنای "همه" است)
last_column = matrix_example(:, end); % [30; 60; 90] (end به معنای آخرین اندیس)
sub_matrix = matrix_example(1:2, 2:3); % [20 30; 50 60]

۲. نمایه‌گذاری خطی (Linear Indexing)

متلب ماتریس‌ها را در حافظه به صورت ستون به ستون ذخیره می‌کند. می‌توانید به هر عنصر با یک اندیس منفرد (خطی) دسترسی پیدا کنید.

% مثال نمایه‌گذاری خطی
matrix_example = [10 20 30; 40 50 60; 70 80 90]; % 3x3

element_at_linear_index_5 = matrix_example(5); % 20 (عنصر ردیف دوم، ستون دوم)
% ترتیب ذخیره: (1,1), (2,1), (3,1), (1,2), (2,2), (3,2), ...
% element_at_linear_index_5  -> (2,2) -> 50 (اشتباه نوشتم، باید 50 باشه)
% (1,1)=10, (2,1)=40, (3,1)=70, (1,2)=20, (2,2)=50
% so matrix_example(5) is 50.

% تبدیل اندیس‌های ساب‌اسکریپت به خطی
linear_idx = sub2ind(size(matrix_example), 2, 2); % 5
disp(matrix_example(linear_idx)); % 50

% تبدیل اندیس خطی به ساب‌اسکریپت
[r, c] = ind2sub(size(matrix_example), 5); % r=2, c=2

۳. نمایه‌گذاری منطقی (Logical Indexing)

با استفاده از یک آرایه منطقی (که ابعاد آن با آرایه اصلی یکسان است) می‌توانید عناصر را بر اساس یک شرط انتخاب کنید.

% مثال نمایه‌گذاری منطقی
data_vector = [10 5 -3 20 -8 15];
positive_values = data_vector(data_vector > 0); % [10 5 20 15]
% data_vector > 0  ->  [true true false true false true]

تغییر شکل و ابعاد آرایه

متلب توابعی را برای تغییر شکل (reshape) یا جابجایی (permute) ابعاد آرایه‌ها ارائه می‌دهد:

  • `reshape(A, m, n)`: آرایه `A` را به یک ماتریس `m` در `n` تغییر شکل می‌دهد. تعداد عناصر باید ثابت بماند.
  • `reshape(A, [d1 d2 d3 …])`: آرایه `A` را به ابعاد دلخواه `d1, d2, d3` و … تغییر شکل می‌دهد. می‌توانید از `[]` برای یک بعد استفاده کنید تا متلب آن را به صورت خودکار محاسبه کند.
  • `permute(A, order)`: ابعاد آرایه `A` را بر اساس ترتیب `order` جابجا می‌کند. (برای مثال، `permute(A, [2 1])` برای جابجایی ردیف‌ها و ستون‌ها در یک ماتریس).
  • `squeeze(A)`: ابعاد تک عنصری (ابعاد با اندازه ۱) را از یک آرایه حذف می‌کند.
  • `cat(dim, A, B, …)`: کاتالیز (concatenates) آرایه‌ها را در یک بعد مشخص. (معادل `[A B]` یا `[A; B]`).
% مثال تغییر شکل و ابعاد
original_matrix = [1 2 3; 4 5 6]; % 2x3
reshaped_vector = reshape(original_matrix, 1, []); % تبدیل به یک بردار ردیفی: [1 4 2 5 3 6] (ستون به ستون)
disp(reshaped_vector);

reshaped_3x2 = reshape(original_matrix, 3, 2);
disp(reshaped_3x2);

permuted_matrix = permute(original_matrix, [2 1]); % تبدیل 2x3 به 3x2
disp(permuted_matrix);

A_dim = rand(1, 5, 1, 3); % آرایه 4 بعدی با ابعاد 1x5x1x3
B_squeezed = squeeze(A_dim); % تبدیل به 5x3
size(B_squeezed) % خروجی: 5 3

مفهوم آرایه‌ها و ماتریس‌ها در متلب بسیار گسترده است و این بخش تنها نگاهی اجمالی به آن بود. تسلط بر این مفاهیم و توابع مربوطه، نه تنها سرعت کدنویسی شما را افزایش می‌دهد بلکه امکان پیاده‌سازی الگوریتم‌های پیچیده و تحلیل‌های داده‌ای مقیاس‌پذیر را فراهم می‌آورد.

انواع داده پیشرفته در متلب: ساختارها، سلول‌ها و جداول

علاوه بر انواع داده عددی و غیر عددی که تا کنون بررسی شد، متلب ساختارهای داده‌ای پیشرفته‌تری را نیز ارائه می‌دهد که برای سازماندهی و مدیریت داده‌های ناهمگن و پیچیده بسیار مفید هستند. این ساختارها شامل آرایه‌های سلولی (Cell Arrays)، ساختارها (Structures) و جداول (Tables) می‌شوند.

آرایه‌های سلولی (Cell Arrays)

آرایه‌های سلولی، برخلاف آرایه‌های معمولی که همه عناصر آن‌ها باید از یک نوع داده باشند، می‌توانند عناصر ناهمگن (Heterogeneous) را ذخیره کنند. هر عنصر در یک آرایه سلولی، خود یک “سلول” است که می‌تواند شامل هر نوع داده‌ای باشد: عدد، رشته، آرایه، حتی یک آرایه سلولی دیگر یا یک ساختار. آرایه‌های سلولی با استفاده از براکت‌های آکولاد (`{}`) تعریف می‌شوند.

  • کاربرد: ذخیره لیستی از رشته‌های با طول‌های متفاوت، نگهداری نتایج با انواع مختلف، یا گروه‌بندی داده‌های مرتبط اما ناهمگون.
  • دسترسی: برای دسترسی به محتوای یک سلول (مقدار داخل سلول)، از براکت‌های آکولاد (`{}`) استفاده می‌شود. برای دسترسی به خود سلول (به عنوان یک آرایه سلولی تک‌عنصری)، از براکت‌های معمولی (`()`) استفاده می‌شود.
% مثال ایجاد آرایه سلولی
my_cell_array = {1, 'hello', [1 2 3]; true, pi, rand(2)};
class(my_cell_array) % خروجی: 'cell'
size(my_cell_array)  % خروجی: 2 3

% دسترسی به محتوای سلول (Content Indexing)
value_at_1_2 = my_cell_array{1, 2}; % 'hello' (یک آرایه کاراکتری)
value_at_2_3 = my_cell_array{2, 3}; % یک ماتریس 2x2 از اعداد تصادفی
class(value_at_2_3) % خروجی: 'double'

% دسترسی به خود سلول (Cell Indexing)
cell_at_1_2 = my_cell_array(1, 2); % {'hello'} (یک آرایه سلولی 1x1 که حاوی 'hello' است)
class(cell_at_1_2) % خروجی: 'cell'

% تخصیص به سلول‌ها
my_cell_array{1, 1} = 100; % تغییر مقدار سلول (1,1) به 100
my_cell_array{3, 1} = 'new_row'; % اضافه کردن یک ردیف جدید (با پدینگ)

% توابع برای آرایه‌های سلولی
celldisp(my_cell_array); % نمایش محتوای تمامی سلول‌ها
cell2mat(my_cell_array(1, [1 3])) % تبدیل سلول‌هایی که محتوای عددی همگن دارند به ماتریس
% خروجی: [100 1 2 3] (سلول‌های 1,1 و 1,3 ترکیب می‌شوند)

ساختارها (Structures)

ساختارها، برای گروه‌بندی داده‌های مرتبط (از انواع داده مختلف) تحت یک نام واحد استفاده می‌شوند. هر ساختار شامل یک یا چند “فیلد” است که هر فیلد یک نام و یک مقدار دارد. ساختارها به ویژه برای نمایش “رکوردها” یا “اشیاء” که دارای ویژگی‌های مختلفی هستند، مناسب‌اند.

  • تعریف: با استفاده از عملگر نقطه (`.`) برای تعریف فیلدها.
  • کاربرد: ذخیره اطلاعات یک فرد (نام، سن، نمرات)، پارامترهای یک آزمایش (دما، فشار، نتیجه)، یا پیکربندی یک سیستم.
  • آرایه‌ای از ساختارها: می‌توانید آرایه‌ای از ساختارها ایجاد کنید که هر عنصر آرایه یک ساختار جداگانه (با فیلدهای یکسان) باشد.
% مثال ایجاد یک ساختار
student.name = 'Ali Karimi';
student.id = 12345;
student.grades = [18.5, 19, 17.25];
student.isActive = true;
class(student) % خروجی: 'struct'

% دسترسی به فیلدها
student_name = student.name; % 'Ali Karimi'
student_grades = student.grades; % [18.5 19 17.25]

% اضافه کردن فیلد جدید
student.major = 'Electrical Engineering';

% آرایه‌ای از ساختارها
students(1) = student; % کپی ساختار اول به عنصر اول آرایه

students(2).name = 'Sara Ahmadi';
students(2).id = 67890;
students(2).grades = [17, 18.5, 19.5];
students(2).isActive = false;
students(2).major = 'Computer Science';

% دسترسی به فیلدهای آرایه‌ای از ساختارها
sara_id = students(2).id; % 67890
all_names = {students.name}; % {'Ali Karimi', 'Sara Ahmadi'} (یک آرایه سلولی از نام‌ها)

توابع مفید برای ساختارها: `fieldnames`, `isfield`, `rmfield`, `struct2cell`.

جداول (Tables)

جداول، که از MATLAB R2013b به بعد معرفی شدند، یک راهکار بسیار قدرتمند و شهودی برای سازماندهی داده‌های ستونی‌شکل (columnar) ارائه می‌دهند، شبیه به آنچه در صفحات گسترده یا پایگاه‌های داده می‌بینید. هر ستون یک متغیر (variable) از جدول است و می‌تواند نوع داده متفاوتی داشته باشد. هر ردیف یک مشاهده (observation) را نشان می‌دهد.

  • تعریف: با استفاده از تابع `table()` از متغیرهای از پیش تعریف شده یا با خواندن فایل‌هایی مانند CSV یا Excel.
  • کاربرد: تحلیل‌های آماری، وارد کردن/صادر کردن داده‌ها، مدیریت داده‌های آزمایشگاهی یا داده‌های سری زمانی.
  • نام‌گذاری: ستون‌ها (متغیرها) و ردیف‌ها (در صورت لزوم) می‌توانند نام داشته باشند که دسترسی به داده‌ها را بسیار ساده‌تر می‌کند.
% مثال ایجاد جدول
Name = {'Alice'; 'Bob'; 'Charlie'}; % Cell array of strings
Age = [25; 30; 22]; % Numeric array
Score = [88; 92; 76]; % Numeric array
Height = [170; 185; 165]; % Numeric array

% ایجاد جدول از متغیرها
data_table = table(Name, Age, Score, Height);
class(data_table) % خروجی: 'table'

% نمایش جدول
disp(data_table);
%       Name     Age    Score    Height
%     ________    ___    _____    ______
%     {'Alice'}    25     88       170
%     {'Bob'}      30     92       185
%     {'Charlie'}  22     76       165

% دسترسی به داده‌ها
% 1. با استفاده از نام متغیر (ستون) - Dot notation
alice_age = data_table.Age(1); % 25
bob_score = data_table.Score(2); % 92

% 2. با استفاده از نام متغیر - Curvy braces {}
charlie_height_col = data_table(:, 'Height'); % یک جدول 3x1 با ستون Height
charlie_height_val = data_table{'Charlie', 'Height'}; % 165 (اگر نام ردیف‌ها ست شده باشد)

% 3. نمایه‌گذاری (Indexing)
first_row = data_table(1, :); % اولین ردیف به عنوان یک جدول 1x4
first_column = data_table(:, 1); % اولین ستون به عنوان یک جدول 3x1

% اضافه کردن متغیر (ستون) جدید
data_table.IsStudent = [true; true; false];
disp(data_table);

% فیلتر کردن ردیف‌ها
old_students = data_table(data_table.Age > 25, :);
disp(old_students);

توابع مفید برای جداول: `readtable`, `writetable`, `array2table`, `table2array`, `addvars`, `removevars`, `sortrows`.

مقایسه Cell Arrays, Structures و Tables

انتخاب بین این سه ساختار داده پیشرفته به نیاز خاص شما بستگی دارد:

  • Cell Arrays: مناسب برای نگهداری مجموعه‌های ناهمگن از داده‌ها که ساختار ثابتی ندارند، یا برای ذخیره لیستی از رشته‌های با طول‌های متفاوت. انعطاف‌پذیری بالا در محتوا.
  • Structures: ایده‌آل برای گروه‌بندی داده‌های مرتبط (که هر کدام ممکن است نوع متفاوتی داشته باشند) تحت فیلدهای با نام مشخص، مانند یک رکورد. ساختار ثابت فیلدها، اما مقادیر فیلدها می‌توانند متفاوت باشند.
  • Tables: بهترین گزینه برای داده‌های ستونی‌شکل که نیاز به تحلیل آماری یا نمایش جدولی دارند، به خصوص زمانی که می‌خواهید به داده‌ها بر اساس نام ستون‌ها (و در صورت وجود، نام ردیف‌ها) دسترسی داشته باشید. ترکیب قدرت ساختارها (فیلدهای نام‌گذاری شده) و آرایه‌ها (دسترسی برداری).

با تسلط بر این انواع داده پیشرفته، می‌توانید داده‌های خود را به صورت کارآمدتر و سازمان‌یافته‌تری در متلب مدیریت کنید و توانایی‌های خود را در پردازش داده‌های پیچیده افزایش دهید.

توابع مربوط به انواع داده و کاربردهای عملی در متلب

پس از آشنایی با انواع مختلف متغیرها و داده‌ها در متلب، اکنون به ابزارها و توابعی می‌پردازیم که به شما امکان می‌دهند نوع داده‌ها را تشخیص دهید، آن‌ها را تبدیل کنید، و از این دانش برای بهینه‌سازی کدهای خود در سناریوهای عملی بهره ببرید. مدیریت صحیح انواع داده، نه تنها به صحت محاسبات کمک می‌کند، بلکه نقش مهمی در کارایی و مصرف حافظه برنامه ایفا می‌کند.

توابع تشخیص نوع داده

متلب توابع متعددی را برای تشخیص نوع داده یک متغیر ارائه می‌دهد. این توابع به شما کمک می‌کنند تا از سازگاری نوع داده‌ها در عملیات‌های مختلف اطمینان حاصل کنید و رفتار کدهایتان را بر اساس نوع داده ورودی تغییر دهید.

  • `class(var)`: نام نوع داده متغیر `var` را به عنوان یک رشته بازمی‌گرداند.
  • `isa(var, ‘datatype’)`: بررسی می‌کند که آیا `var` از نوع داده مشخص شده است یا خیر (خروجی منطقی `true`/`false`).
  • `isnumeric(var)`: آیا `var` یک نوع عددی است؟
  • `islogical(var)`: آیا `var` یک آرایه منطقی است؟
  • `ischar(var)`: آیا `var` یک آرایه کاراکتری است؟
  • `isstring(var)`: آیا `var` یک آرایه رشته‌ای (MATLAB R2016b+) است؟
  • `iscell(var)`: آیا `var` یک آرایه سلولی است؟
  • `isstruct(var)`: آیا `var` یک ساختار است؟
  • `istable(var)`: آیا `var` یک جدول است؟
  • `isempty(var)`: آیا `var` یک آرایه خالی است؟
  • `isscalar(var)`, `isvector(var)`, `ismatrix(var)`: بررسی می‌کند که آیا متغیر یک اسکالر، بردار یا ماتریس است.
% مثال توابع تشخیص نوع داده
a = 10;
b = 'MATLAB';
c = true;
d = {1, 'two'};
e = struct('field', 1);
f = table(1, 'VariableNames', {'Var1'});

disp(['Type of a: ', class(a)]); % 'double'
disp(['Is b a char array? ', num2str(ischar(b))]); % true
disp(['Is c logical? ', num2str(islogical(c))]); % true
disp(['Is d a cell array? ', num2str(iscell(d))]); % true
disp(['Is e a struct? ', num2str(isstruct(e))]); % true
disp(['Is f a table? ', num2str(istable(f))]); % true
disp(['Is a numeric? ', num2str(isnumeric(a))]); % true

توابع تبدیل نوع داده

متلب توابع فراوانی برای تبدیل یک نوع داده به دیگری ارائه می‌دهد. این توابع برای اطمینان از سازگاری داده‌ها در عملیات‌ها یا برای تغییر نحوه نمایش و ذخیره‌سازی داده‌ها ضروری هستند.

  • `double(var)`, `single(var)`, `int8(var)`, `uint16(var)`, …: تبدیل به نوع عددی مشخص شده.
  • `char(var)`: تبدیل به آرایه کاراکتری.
  • `string(var)`: تبدیل به آرایه رشته‌ای.
  • `logical(var)`: تبدیل به آرایه منطقی (هر مقدار غیرصفر به `true` و صفر به `false` تبدیل می‌شود).
  • `num2str(num, format)`: تبدیل عدد به رشته (با امکان فرمت‌بندی).
  • `str2num(str)`: تبدیل رشته به عدد (سعی می‌کند مقدار عددی را از رشته استخراج کند).
  • `str2double(str)`: تبدیل رشته به عدد ممیز شناور (در R2016b+ برای string arrays ترجیح داده می‌شود، ایمن‌تر از `str2num`).
  • `mat2str(matrix)`: تبدیل ماتریس به نمایش رشته‌ای آن.
  • `cell2mat(cell_array)`: تبدیل آرایه سلولی از مقادیر عددی همگن به یک ماتریس.
  • `mat2cell(matrix, row_sizes, col_sizes)`: تقسیم ماتریس به آرایه سلولی.
  • `table2array(table_var)`: تبدیل یک جدول به آرایه عددی (فقط برای ستون‌های عددی).
  • `array2table(array_var)`: تبدیل یک آرایه به جدول.
  • `struct2table(struct_array)`: تبدیل آرایه‌ای از ساختارها به یک جدول.
  • `table2struct(table_var)`: تبدیل یک جدول به آرایه‌ای از ساختارها.
% مثال توابع تبدیل نوع داده
num_double = 15.7;
num_int = int8(num_double); % 15 (گرد شدن به سمت صفر)
disp(['Double: ', num2str(num_double), ', Int8: ', num2str(num_int)]);

str_value = "45.6";
num_from_str = str2double(str_value); % 45.6
disp(['String: ', str_value, ', Double from string: ', num2str(num_from_str)]);

char_arr = '123';
num_from_char = str2num(char_arr); % 123
disp(['Char: ', char_arr, ', Number from char: ', num2str(num_from_char)]);

logical_vec = logical([-1 0 10 0]); % [true false true false]
disp('Logical vector:');
disp(logical_vec);

cell_of_nums = {1, 2; 3, 4};
matrix_from_cell = cell2mat(cell_of_nums); % [1 2; 3 4]
disp('Matrix from cell:');
disp(matrix_from_cell);

my_table = table({'A';'B'}, [10;20], 'VariableNames', {'CharCol', 'NumCol'});
array_from_table = table2array(my_table(:, 'NumCol')); % [10; 20]
disp('Array from table numeric column:');
disp(array_from_table);

مدیریت حافظه و بهینه‌سازی

برای کاربردهای بزرگ و پیچیده در متلب، مدیریت حافظه و بهینه‌سازی کد بسیار مهم است. انتخاب صحیح انواع داده می‌تواند تأثیر چشمگیری بر عملکرد داشته باشد:

  • تخصیص اولیه (Pre-allocation): همیشه آرایه‌هایی را که قصد دارید با حلقه پر کنید، با `zeros`, `ones`, `cell`, `strings` یا `table` از قبل تخصیص دهید. این کار از تخصیص مجدد حافظه در هر تکرار حلقه جلوگیری می‌کند و سرعت را به شدت افزایش می‌دهد.
    % مثال تخصیص اولیه
    N = 10000;
    % روش نامناسب (کند)
    % my_results_slow = [];
    % for i = 1:N
    %     my_results_slow = [my_results_slow, i^2];
    % end
    
    % روش مناسب (سریع)
    my_results_fast = zeros(1, N);
    for i = 1:N
        my_results_fast(i) = i^2;
    end
            
  • استفاده از نوع داده مناسب:
    • برای اعداد صحیح کوچک (مانند مقادیر پیکسل در تصاویر 8 بیتی)، از `uint8` استفاده کنید نه `double`.
    • اگر دقت `double` لازم نیست (مثلاً برای گرافیک یا بازی‌ها)، از `single` استفاده کنید.
    • برای رشته‌ها، ترجیحاً از `string arrays` به جای `char arrays` استفاده کنید، زیرا مدیریت حافظه و عملیات آن‌ها بهینه‌تر است.
  • پاک کردن متغیرهای استفاده نشده: متغیرهای بزرگ و بلااستفاده را با `clear` از فضای کاری حذف کنید تا حافظه آزاد شود.
  • بررسی حافظه: از دستور `whos` برای مشاهده حافظه اشغال شده توسط هر متغیر استفاده کنید تا متغیرهای پرمصرف را شناسایی کنید.

مثال‌های کاربردی

در ادامه به چند مثال عملی اشاره می‌کنیم که نشان می‌دهد چگونه انواع داده‌های مختلف در سناریوهای واقعی مورد استفاده قرار می‌گیرند:

۱. تجزیه و تحلیل داده‌های حسگر

فرض کنید داده‌های یک حسگر شامل زمان، دما، رطوبت و وضعیت (مانند “OK”, “Warning”, “Error”) باشد. می‌توانید این داده‌ها را به خوبی در یک `table` یا آرایه‌ای از `struct`ها سازماندهی کنید.

% استفاده از Table
timestamps = datetime('now') + seconds(0:9)';
temperatures = randi([20, 30], 10, 1);
humidities = rand(10, 1) * 20 + 50;
status = categorical(["OK"; "Warning"; "OK"; "Error"; "OK"; "OK"; "Warning"; "OK"; "OK"; "OK"]);

sensor_data_table = table(timestamps, temperatures, humidities, status, ...
                          'VariableNames', {'Time', 'Temperature_C', 'Humidity_Perc', 'Status'});
disp(sensor_data_table);

% فیلتر کردن ردیف‌های با وضعیت 'Error'
error_readings = sensor_data_table(sensor_data_table.Status == 'Error', :);
disp('Error Readings:');
disp(error_readings);

% استفاده از Structures
sensor_readings(1).time = datetime('now');
sensor_readings(1).temperature = 25.5;
sensor_readings(1).humidity = 60;
sensor_readings(1).status = "OK";

sensor_readings(2).time = datetime('now') + seconds(1);
sensor_readings(2).temperature = 28.1;
sensor_readings(2).humidity = 70;
sensor_readings(2).status = "Warning";
% ... می‌توانید یک حلقه برای پر کردن آرایه ساختارها بنویسید

۲. پردازش تصویر با آرایه‌های uint8

تصاویر خاکستری معمولاً به صورت ماتریس‌هایی از `uint8` ذخیره می‌شوند که هر پیکسل دارای مقداری بین ۰ (سیاه) و ۲۵۵ (سفید) است. تصاویر رنگی نیز به صورت آرایه‌های 3 بعدی (ارتفاع x عرض x 3) از `uint8` ذخیره می‌شوند.

% مثال پردازش تصویر
% فرض کنید یک تصویر خاکستری 256x256 دارید
gray_image = randi([0, 255], 256, 256, 'uint8'); % ایجاد یک تصویر تصادفی برای مثال
% imshow(gray_image); % برای نمایش تصویر (نیاز به Image Processing Toolbox)

% افزایش روشنایی تصویر (محدود به 255)
brightened_image = gray_image + uint8(50); % به دلیل uint8، مقادیر بالای 255 به 255 کلیف می‌شوند
% imshow(brightened_image);

% بارگذاری و نمایش یک تصویر رنگی
% اگر تصویر 'peppers.png' در مسیر متلب باشد
% img_color = imread('peppers.png');
% class(img_color) % خروجی: 'uint8'
% size(img_color) % خروجی: [MxNx3]

% تبدیل به double برای پردازش دقیق‌تر و سپس بازگرداندن به uint8
% img_double = double(img_color) / 255; % نرمال‌سازی به [0, 1]
% % ... عملیات پردازش تصویر
% processed_img_uint8 = uint8(img_double * 255);

۳. مدیریت مجموعه‌ای از فایل‌ها و اطلاعات آن‌ها

می‌توانید اطلاعات مربوط به چندین فایل (نام، اندازه، تاریخ ایجاد) را در یک آرایه سلولی از رشته‌ها یا یک جدول ذخیره کنید.

% استفاده از Cell Array برای ذخیره نام فایل‌ها
file_list = {'report_2023.pdf', 'data_set_A.csv', 'image_001.jpg'};
long_name = file_list{1}; % 'report_2023.pdf'

% تبدیل به String Array برای عملیات راحت‌تر
file_str_array = string(file_list);
pdf_files = file_str_array(endsWith(file_str_array, ".pdf")); % ["report_2023.pdf"]

% استفاده از Table برای جزئیات بیشتر (مثلاً با dir)
% file_info = dir('*.m'); % اطلاعات فایل‌های .m در پوشه فعلی
% file_table = struct2table(file_info);
% disp(file_table(:, {'name', 'bytes', 'date'})); % نمایش نام، اندازه و تاریخ

این مثال‌ها نشان می‌دهند که چگونه انتخاب و استفاده صحیح از انواع داده و توابع مربوط به آن‌ها می‌تواند به شما در حل مسائل مختلف در متلب کمک کند. تسلط بر این ابزارها، شما را قادر می‌سازد تا کدهای قوی‌تر، کارآمدتر، و قابل نگهداری‌تری بنویسید.

جمع‌بندی و نکات کلیدی برای استفاده بهینه

در این پست وبلاگ، به بررسی جامع و تخصصی متغیرها و انواع داده در محیط قدرتمند متلب پرداختیم. از مفاهیم بنیادی تعریف متغیرها و قواعد نام‌گذاری آن‌ها گرفته تا انواع داده عددی، غیرعددی، و ساختارهای داده پیشرفته مانند آرایه‌های سلولی، ساختارها و جداول، هر جنبه‌ای با جزئیات و مثال‌های کدی کاربردی مورد کنکاش قرار گرفت.

ما آموختیم که متغیرها به عنوان ظروفی برای ذخیره اطلاعات عمل می‌کنند و انواع داده، ماهیت این اطلاعات را تعیین می‌کنند. درک دقیق تفاوت‌های بین `double` و `single`، انواع مختلف `int` و `uint`، و تفاوت‌های بین `char arrays` و `string arrays` برای بهینه‌سازی عملکرد و مصرف حافظه در متلب حیاتی است. همچنین، توانایی متلب در کار با اعداد مختلط، آرایه‌های منطقی و مدیریت فضای کاری (Workspace) نیز مورد بررسی قرار گرفت.

ساختارهای داده پیشرفته مانند آرایه‌های سلولی برای ذخیره داده‌های ناهمگن، ساختارها برای گروه‌بندی داده‌های مرتبط با فیلدهای نام‌گذاری شده، و جداول برای سازماندهی داده‌های ستونی‌شکل، ابزارهای قدرتمندی هستند که برای مدیریت داده‌های پیچیده در کاربردهای علمی، مهندسی و تحلیل داده ضروری‌اند. در نهایت، توابع تشخیص و تبدیل نوع داده، همراه با نکات مربوط به مدیریت حافظه و بهینه‌سازی، به ما در نوشتن کدهای کارآمدتر و قابل اعتمادتر کمک می‌کنند.

برای استفاده بهینه از متلب، نکات کلیدی زیر را همواره در ذهن داشته باشید:

  • انتخاب نوع داده صحیح: همیشه نوع داده‌ای را انتخاب کنید که متناسب با نیازهای دقت و محدوده داده‌های شما باشد. استفاده از `uint8` برای تصاویر یا `single` در جایی که دقت `double` لازم نیست، می‌تواند به طور قابل توجهی حافظه و زمان اجرا را کاهش دهد.
  • تخصیص اولیه (Pre-allocation): برای آرایه‌هایی که در حلقه‌ها پر می‌شوند، همیشه از تخصیص اولیه با توابعی مانند `zeros`, `ones`, `cell` یا `strings` استفاده کنید. این کار از تخصیص مکرر حافظه و کاهش عملکرد جلوگیری می‌کند.
  • شناخت تفاوت‌ها: به تفاوت بین عملیات ماتریسی و عنصر به عنصر (با استفاده از نقطه `.` قبل از عملگر) توجه کنید تا از خطاهای محاسباتی جلوگیری شود.
  • استفاده از ساختارهای داده مناسب: برای سازماندهی داده‌های پیچیده و ناهمگن، با دقت بین آرایه‌های سلولی، ساختارها و جداول انتخاب کنید. جداول به ویژه برای تحلیل‌های آماری و نمایش داده‌های جدولی بسیار قدرتمند هستند.
  • مدیریت حافظه: از `whos` برای پایش مصرف حافظه و از `clear` برای حذف متغیرهای بلااستفاده استفاده کنید، به خصوص هنگام کار با مجموعه‌های داده بزرگ.
  • استفاده از توابع `string` (R2016b+): برای کار با متن، در صورت امکان، از آرایه‌های رشته‌ای (string arrays) به جای آرایه‌های کاراکتری قدیمی استفاده کنید، زیرا مدیریت آن‌ها ساده‌تر و کارآمدتر است.
  • آشنایی با توابع تبدیل: بدانید چه توابعی برای تبدیل بین انواع داده‌های مختلف وجود دارد (مانند `num2str`, `str2double`, `cell2mat`, `table2array`) تا بتوانید داده‌ها را به فرمت مورد نیاز خود درآورید.
  • مثال‌های عملی: با کار بر روی مثال‌های واقعی و مسائل عملی، درک خود را از نحوه تعامل انواع داده‌ها در سناریوهای مختلف عمیق‌تر کنید.

در نهایت، تسلط بر متغیرها و انواع داده، نه تنها یک مهارت پایه است، بلکه یک توانایی کلیدی برای نوشتن کدهای متلب مؤثر، قوی و مقیاس‌پذیر محسوب می‌شود. با به کارگیری دانش و بینش ارائه شده در این پست، شما قادر خواهید بود پروژه‌های پیچیده‌تری را با اطمینان و کارایی بیشتری در متلب پیاده‌سازی کنید و به یک کاربر متخصص‌تر این ابزار قدرتمند تبدیل شوید.

“تسلط به برنامه‌نویسی پایتون با هوش مصنوعی: آموزش کدنویسی هوشمند با ChatGPT”

قیمت اصلی 2.290.000 ریال بود.قیمت فعلی 1.590.000 ریال است.

"تسلط به برنامه‌نویسی پایتون با هوش مصنوعی: آموزش کدنویسی هوشمند با ChatGPT"

"با شرکت در این دوره جامع و کاربردی، به راحتی مهارت‌های برنامه‌نویسی پایتون را از سطح مبتدی تا پیشرفته با کمک هوش مصنوعی ChatGPT بیاموزید. این دوره، با بیش از 6 ساعت محتوای آموزشی، شما را قادر می‌سازد تا به سرعت الگوریتم‌های پیچیده را درک کرده و اپلیکیشن‌های هوشمند ایجاد کنید. مناسب برای تمامی سطوح با زیرنویس فارسی حرفه‌ای و امکان دانلود و تماشای آنلاین."

ویژگی‌های کلیدی:

بدون نیاز به تجربه قبلی برنامه‌نویسی

زیرنویس فارسی با ترجمه حرفه‌ای

۳۰ ٪ تخفیف ویژه برای دانشجویان و دانش آموزان