אנליזה נומרית 1 701132 תרגול :1 MATLAB סימולציה, MATLAB היא סביבה אינטראקטיבית לחישוב מדעי והנדסי, ויזואליזציה ותכנון אלגוריתמים.
החלונות העיקריים בתוכנה: פקודה כל interpreter :Command window (console) מטלב היא סביבת מתקמפלת ומתבצעת "במקום". בחלון זה ניתן לרשום את הפקודות. :Current Folder ספרית העבודה הנוכחית. באופן ראשוני, כל הקבצים שבהם משתמשים צריכים להיות בספריית העבודה )בהמשך ניתן להגדיר גם ספריות נוספות ע"י.)addpath :Command history היסטוריה של כל הפקודות. :Workspace המקום בו מופיעה רשימת המשתנים הנוכחיים. :Editor החלון בו עורכים קבצים )לא מופיע בתמונה(. קבלת עזרה: קבלת עזרה במטלב נעשית ע"י הפקודה, help func_name או.doc func_name קיימת עזרה גם באינטרנט ע"י חיפוש שם הפקודה.
מבני נתונים: לא מגדירים טיפוסים במטלב. הטיפוסים נקבעים ע"י התוכנה בזמן ריצה. מבנה הנתונים העיקרי במטלב הוא מטריצה. לדוגמא, משתנה מספרי "רגיל" הוא מטריצה.1X1 דוגמאות: וקטור שורה: >> a=[0.2,7,11,5] a = 0.2000 7.0000 11.0000 5.0000 >> b=[0.2;7;11;5] וקטור עמודה: b = 0.2000 7.0000 11.0000 5.0000
מטריצה 0X0: ה"חוק": רווח או פסיק למעבר עמודה. נקודה-פסיק למעבר שורה. במקרה של הגדרה לא חוקית בביצוע השורה תהיה הודעת שגיאה >> A=[3 4 5; 4 7 9; 2 6 7] A = 3 4 5 4 7 9 2 6 7 >> A=[3 4 5; 4 7 9; 2 6]??? Error using ==> vertcat CAT arguments dimensions are not consistent.
>> 1:5 אופרטור :"a:b:c" ניתן להגדיר וקטורים של סדרות באופן הבא: )מאוד שימושי בעבודה עם אינדקסים, ובדוגמא האחרונה - ליצור "רשתות" לפונקציות( >> 1:3:5 1 2 3 4 5 1 4 >> 1:-3:-15 1-2 -5-8 -11-14 >> x = 0:0.25:1 x = 0 0.2500 0.5000 0.7500 1.0000
>> A=[3 4 5; 4 7 9; 2 6 7] הוצאת נתונים מתוך מטריצות: אינדקסים במטלב מתחילים מ- 1 ולא מ- 0 A = 3 4 5 4 7 9 2 6 7 >> A(1:2,2:3) 4 5 7 9 >> A(1,[1,3]) 3 5
>> A' שחלוף :)transpose( 3 4 2 4 7 6 5 9 7 >> s = 'Hello World' מערך של :)string( chars
>> A=ones(3,3) פעולות על מבני נתונים: מטריצות אלמנטריות )משמשות גם להקצאת זיכרון(:.ones, eye, zeros פונקציות נוספות: randn,.rand, A = 1 1 1 1 1 1 1 1 1 >> B = eye(3) B = 1 0 0 0 1 0 0 0 1 >> C = zeros(3,5) C = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
>> A+B פעולות חיבור/חיסור: מתבצעות "איבר-איבר" 2 1 1 1 2 1 1 1 2
פעולות כפל/חילוק/חזקה: אילו הם פעולות "מטריציות" לפי אלגברה ליניארית גדלים צריכים להתאים לפי אלגברה ליניארית. >> A*B % B is identity, therefore answer is A. 1 1 1 1 1 1 1 1 1 >> A^2 % same as A*A 3 3 3 3 3 3 3 3 3 >> A\B % same as inv(a)*b see later.
פעולות כפל/חילוק/חזקה "איבר-איבר" גדלים צריכים להיות זהים. >> A.*B % B is identity, A is ones. Therefore answer is B. 1 0 0 0 1 0 0 0 1 >> x = 0:0.25:1 חישוב פונקציות על מטריצות: x = 0 0.2500 0.5000 0.7500 1.0000 >> f = sin(x) f = 0 0.2474 0.4794 0.6816 0.8415 >> f = sin(x).*cos(x) f = 0 0.2397 0.4207 0.4987 0.4546
>> size(zeros(3,5)) פעולות שימושיות: :isempty, sum, mean, max, min, size 3 5 >> max([4,5,6]) 6 >> max([4,5,6 ; 7,8,9]) 7 8 9
A פתרון מערכת משוואות ליניאריות )אופרטור חילוק מטריצות( 3x 5y 44 3 5 x1 44 1 x A b 2x y 27 2 1 x 2 27 האופציה השנייה היא הטובה יותר: >> A=[3,-5 ; 2,1];b=[-44 ; 27]; x b במטלב ישנן 7 אופציות >> s = inv(a)*b % inverts A and multiply more expensive and not stable do not use. s = 7.0000 13.0000 >> s = A\b % just calculates the result faster, more stable s = 7 13
פונקציית find ותנאים לוגיים: >> x = [1.1,2.21, 3.2, 4.4,5.5, 6.6, 7.6,8.8]; x = 1.1 2.21 3.2 4.4 5.5 6.6 7.6 8.8 >> find(x>5) 6 7 8
% if sentence if i==1 statement; end % if-else if res(n,2) ~= 0 statement; else statement; end % if-elseif if (A > B) statement; elseif (A< B) statement; elseif ~A statement; else statement; end בקרת זרימה: משפטי תנאי:
% for loop for n=1:1:4 statement; end % while loop a = 4; fa=sin(a); b = 2; fb = sin(b); while a - b > 5 * eps x = (a+b)/2; fx = sin(x); if sign(fx) == sign(fa), a = x; fa=fx; break; else b = x; fb = fx; end end בקרת זרימה: לולאות:
הצגת פלט המספרים הצגת ספרות: במספר עצמו המספרים עצמם הם.double זה רק עניין של פורמט תצוגה. אין כל שינוי >> format short >> x=31.415926 x = 31.4159 >> format long >> x x = 31.415925999999999 >> format long e >> x x = 3.141592600000000e+001 >> format short e >> x x = 3.1416e+001
>> digits(2); >> vpa(pi) עבודה עם מספר ספרות דיוק 3.1 >> vpa(3.45678*1000) 3.5*10^3 >> vpa(3.45678*1000,4) 3457.0
עבודה עם ה- editor : בד כ לא נוח לעבוד בצורה אינטראקטיבית בלבד ל- session. session מאבדים את מה שקרה בין o קבצי ההפעלה של matlab הם עם סיומת "m.". o ניתן ליצור קובץ כזה לכתוב בו רשימת פקודות ולשמור אותו בשם מסוים. o כדי להפעיל קובץ הפקודות my_m_file.m פשוט כותבים ב Matlab את השם my_m_file וזה מריץ את הפקודות סדרתית בסביבה הגלובלית אם הקובץ ניגש לדוגמא למשתנה A שהיה קיים ב- workspace אז הוא ישנה אותו גלובאלית. o הרצת הפקודות קוראת באותו האופן כאילו הורצו "ידנית". ניתן להריץ ולשמור אוטומטית ע"י כפתור.run
קבצי פונקציות: הדרך הכי טבעית לעבוד. קובץ שבו כתובה פונקציה צריך להיות בעל שם זהה לשם הפונקציה הראשית שלו. הפונקציות מקבלות קלט וכל הפעולות הנעשות בהם הם בבלוק לוקאלי בלבד כמו ב- C. ערך המשתנים בסיום התכנית הוא הערך המוחזר ע"י הפונקציה. בקובץ :pyt.m function [c,d,e]= pyt(a,b) % returns the hyotensus (yeter) in a right angle % triangle according to Pythagoras theorem % c is the hyotensus % d and e are the two sharp angles c=sqrt(a.^2+b.^2); d=atan(b/a); e=pi/2-d; >> help pyt returns the hyotensus (yeter) in a right angle triangle according to Pythagoras theorem c is the hyotensus d and e are the two sharp angles ההערות מיד לאחר שורת ההכרזה ישמשו לצורך תיעוד העזרה:
אם מסיימים כל פונקציה ב-; return ניתן לכתוב באותו קובץ פונקציות עזר נוספות. הפונקציה הראשית היא הפונקציה הראשונה בעלת אותו השם כמו הקובץ עצמו: function [c,d,e]= pyt(a,b) % returns the hyotensus (yeter) in a right angle % triangle according to Pythagoras theorem % c is the hyotensus % d and e are the two sharp angles c=calclength(a,b); d=atan(b/a); e=pi/2-d; return; function L = calclength(a,b) L = sqrt(a.^2+b.^2); return; הפונקציה calclength שבדוגמא היא לוקאלית ולא "מוכרת" מחוץ לקובץ זה.
function [c,d,e]= pyt(a,b) norm = @norm2; c = calclength(a,b,norm); d = atan(b/a); e = pi/2-d; return; שימוש במצביעים לפונקציות )שימושי מאוד בקורס(: הפונקציה norm2 יכולה להיות גם פונקציה חיצונית. function L = calclength(a,b,norm_func) L = norm_func(a,b); return; function n = norm2(a,b) n = sqrt(a.^2+b.^2); return;
פקודות שימושיות: של :save/load ניתן לשמור את המשתנים הנוכחיים ולהעלות אותם. שימושי כאשר זמן ריצה תכניות ארוך מאוד. clc ניקוי של מסך ה- console. clear A שחרור זיכרון של המשתנה A. אם A "נדרס" הזיכרון משתחררת אוטומטית. clear all משחרר את כל המשתנים הקיימים ב- workspace. close all סוגר את כל החלונות הנוספים (figures) ראה ויזואליזציה. diary( diary_file ), diary off מקליט את כל הפלט לקובץ. s=sprintf( Mydata%d,I) זהה לאותה הפקודה ב- C.
>> disp('hello world') hello world >> disp(['the kid is ', num2str(30), ' years old']) The kid is 30 years old disp ממשק להדפסה לconsole. קיצורים שימושיים: ctrl+'r' השמה של שורות מסומנות להערה. ctrl+'t' החזרה מהערה. ctrl+'i' סידור של אינדנטציה של הקוד )טאבים(..)debug הרץ את מה שהסמן מסמן )שימושי במצב f9
y=sin(x).*cos(50*x) figure; x=0:0.01:5; y=sin(x).*cos(50*x); plot(x,y) title('example plot') xlabel('x') וויזואליזציה ציור גרפים/תמונות: figure הקצאה של חלון ציור. הפונקציה הכי שימושית לציור גרפים היא :plot % adds a title % adds a title to the x axis ylabel('y=sin(x).*cos(50*x)')% adds a title to the y axis 1 Example plot 0.8 0.6 0.4 0.2 0-0.2-0.4-0.6-0.8-1 0 0.5 1 1.5 2 2.5 3 3.5 4 4.5 5 x
ציור כמה גרפים על אותה התמונה: figure; x=0:0.01:5; subplot(1,3,1); % plots a line of 3 plots. Now we plot the first. y=sin(x).*cos(50*x); plot(x,y,'-r') % red line title('example plot 1') xlabel('x') ylabel('y=sin(x).*cos(50*x)') subplot(1,3,2); % Now we plot the second. y=exp(x); plot(x,y,':k','linewidth',2); % thick line title('example plot 2') xlabel('x') ylabel('exp(x)') subplot(1,3,3); % Now we plot the third. y=log(x); plot(x,y,'-.b','linewidth',2); % title('example plot 3') xlabel('x') ylabel('ln(x)')
y=sin(x).*cos(50*x) exp(x) ln(x) 1 Example plot 1 150 Example plot 2 2 Example plot 3 1 0.5 100 0 0-1 -2-0.5 50-3 -4-1 0 1 2 3 4 5 x 0 0 1 2 3 4 5 x -5 0 1 2 3 4 5 x
ציור כמה גרפים "אחד על השני": figure; x = 0:0.01:1; y=exp(x); plot(x,y,':k','linewidth',2); % thick line hold on y=sin(x); plot(x,y,'-.r','linewidth',2); % hold off title('example multiple lines') xlabel('x') legend('exp(x)','sin(x)'); 3 2.5 Example multiple lines exp(x) sin(x) 2 1.5 1 0.5 0 0 0.2 0.4 0.6 0.8 1 x
שימוש בפונקציות C ממשק :mex )לקריאה עצמית לא מועבר בשיעור( * הערה: החלק הזה אינו שימושי בקורס, אך מאוד שימושי בהמשך. מטלב הוא בעצם מעטפת לפקודות,fortran C, ו- Java. לכן, פקודות build-in הם בעצם מעטפת לפקודות אחרות אשר ממומשות מאוד ביעילות. לעומת זאת שימוש בלולאות for הוא מאוד איטי כיוון שכל איטרציה מתקמפלת מחדש. עדכון איברים ידנית בתוך מערך או מטריצה גם כן מאוד איטיים. לכן, בהרבה מקרים, לצורך מהירות הקוד, נרצה להוציא פונקציה מסויימת "החוצה" לשפת C ששם נממש אותה באופן טבעי ויעיל. דוגמא: incarr היא פונקציה המקבלת מערך x ומוסיפה לו 1 לכל איבר.
הקובץ הבא הוא :incarrmex.c #include "mex.h" void mexfunction( int nlhs, mxarray *plhs[], int nrhs, const mxarray *prhs[]) { // plhs array of pointers to output variables // prhs - array of pointers to input variables int i,m,n = 0; double* In = mxgetpr(prhs[0]); // getting actual pointer for first input variable double* Out = 0; m = mxgetm(prhs[0]); // getting sizes n = mxgetn(prhs[0]); // getting sizes //Allocate memory and assign output pointer plhs[0] = mxcreatedoublematrix(n, m, mxreal); //mxreal is our data-type //Get a pointer to the data space in our newly allocated memory Out = mxgetpr(plhs[0]); for(i=0 ; i < m*n ; i++){ Out[i] = In[i]+1; } }
mex incarrmex.c function [y] = incarr(x) % mex example for y = x+1. y = incarrmex(x); end לצורך קומפילציה יש להשתמש ב: בפעם הראשונה מאטלב ידרוש לבחור קומפיילר ל- C. קובץ המטלב לצורך "מעטפת": הערה: ניתן "להתממשק" בצורה דומה גם עם אובייקטים ב- Java. מידע נמצא בתיעוד מאטלב.