תכנות נומרי עם Matlab ו-Octave/מערכים



הקדמה


פרק זה לוקה בחסר. אתם מוזמנים לתרום לוויקיספר ולהשלים אותו. ראו פירוט בדף השיחה.



בניה של מערך


מערך חד מימדי

עריכה

אחד השימושים במערך חד מימדי הוא ייצוג של וקטור מתמטי. כאשר למעשה הוקטור הוא בגודל 1*n כאשר n הוא מספר העמודות או התאים במערך.


 

כדאי לדעת:

כדאי להרחיב את הידע בוקטורים מתמטיים.


מערכים חד מימדיים בMatlab או Octave מייצגים, בין השאר, וקטורים מתמטיים (לדוגמה  ).


אפשר לבנות מערך ע"י זוג סוגריים מרובעים, שביניהם איברים מופרדים ברווחים או פסיקים. לדוגמה:

octave:21> [1, 2, 6]
ans =

   1   2   6

מייצר וקטור בעל 3 איברים: 1, 2, ו6.

אתחול מערך

עריכה

פרק זה לוקה בחסר. אתם מוזמנים לתרום לוויקיספר ולהשלים אותו. ראו פירוט בדף השיחה.



a=[]

פעולות על וקטורים

עריכה

אפשר לקשר משתנה לוקטור, לדוגמה כך:

octave:22> x = [1, 2, 6]
x =

   1   2   6

ניגשים לאיבר בוקטור על ידי סוגריים עגולים. בניגוד לרוב שפות התכנות, האיבר הראשון בוקטור הוא באינדקס 1, לא 0. לדוגמה, כדי להפוך את איברו השלישי של הוקטור ל0, נרשום זאת:

octave:22>x(3) = 0
x =

   1   2   0

כדי לכפול כל אחד מאיברי וקטור במספר, משתמשים באופרטור .* (שימו לב לנקודה לפני הכוכבית). לדוגמה:

x .* 5
ans =

    5   10   0

בצורה דומה אפשר לחבר מספר לכל אחד מאיברי וקטור, לחסר מספר מכל אחד מאיברי וקטור, וכולי.


יצירת וקטור בדילוגים

עריכה

אפשר ליצור וקטורים של מספרים בדילוגים קבועים בצורה:

<first> : <skip> : <last>

כאשר:

  • first הוא ערך האיבר הראשון
  • skip הוא ערך הדילוג
  • last הוא ערך האיבר האחרון

(אין צורך לסגור בסוגריים מרובעים.)


>> v=1:2:20
v =

   1   3   5   7   9  11  13  15  17  19

>> v=20:-0.5:15
v =

 Columns 1 through 8:

   20.000   19.500   19.000   18.500   18.000   17.500   17.000   16.500

 Columns 9 through 11:

   16.000   15.500   15.000

אם מדלגים ב-1 אפשר להשמיט את הפרמטר האמצעי (אך לא ב 1-).

octave:12> 1:10
ans =

   1   2   3   4   5   6   7   8   9  10

יצירת וקטור ריק

עריכה

כמו באתחול מערך, לפעמים צריך ליצור וקטור ריק שלתוכו יוכנס לאחר מכן. לשם כך משתמשים בסוגרים מרובעים ללא תוכן:

 s=[]
s = [](0x0)

פונקציות לוקטורים

עריכה

linspace

עריכה

בניית וקטור לפי: linspace (BASE, LIMIT, N) . כאשר base הוא המספר ממנו מתחילים, limit זה מספר היעד ו n זה מספר הרווחים

octave:45> linspace(1,0.5,3)
ans =

   1.0000    0.7500    0.5000

logspace

עריכה

כמו ב linspace רק שכאן החישוב הוא לפי בסיס לוגריתמי .

octave:46> logspace(2,4,5)
ans =

   1.0000e+02   3.1623e+02   1.0000e+03   3.1623e+03   1.0000e+04


הפונקציה מחזירה אורך של וקטור (וגם של משתנה מסוג string) .דוגמה:

vec=1:5:100 
length(vec)
ans=
20

מערך דו מימדי

עריכה
 

כדאי לדעת:

פסקה זו דורשת ידע קודם במטריצות.

מטריצה היא מערך תאים בגודל m*n כאשר m הוא מספר השורות ו n הוא מספר העמודות.

דוגמה :אתחול מטריצה a בגודל 5*4 והכנסת המספר 1 למקום ה 4,5 :

>> a(4,5)=1
a =

   0   0   0   0   0
   0   0   0   0   0
   0   0   0   0   0
   0   0   0   0   1
>> whos a
*** local user variables:

  Prot Name        Size                     Bytes  Class
  ==== ====        ====                     =====  ===== 
   rwd a           4x5                        160  double

Total is 20 elements using 160 bytes


יצירת מטריצה דומה ליצירת וקטור כאשר להפרדה בין השורות משתמשים ב ;

x=[1 2;3 4] 
x =

   1   2
   3   4

כאן יצרנו מטריצה בגודל 2*2 זוהי מטריצה ריבועית.

כלומר מטריצה בגודל m כאשר m הוא מספר השורות וגם העמודות, במילים אחרות, אורכה שווה לגובהה.

octave:30> whos x

*** local user variables:

  Prot Name        Size                     Bytes  Class
  ==== ====        ====                     =====  ===== 
   rwd x           2x2                         32  double

Total is 4 elements using 32 bytes

עכשיו ניצור אחת יותר גדולה. בגלל שאין לנו כוח להכניס איברים לכל המקומות, ניצור בצורה רנדומלית עם rand.

 a=rand(5,7)
a =

   0.8248817   0.2889077   0.7461950   0.8559394   0.6424179   0.8985183   0.8952427
   0.4555631   0.8670079   0.2521041   0.0840872   0.7443703   0.3556846   0.7061898
   0.3189548   0.4681194   0.9783496   0.3565062   0.7636891   0.9796930   0.0808279
   0.8375179   0.6205069   0.4382116   0.2789763   0.7823746   0.4983560   0.3552753
   0.8136271   0.5476563   0.7410189   0.0016889   0.2047131   0.4818841   0.3773963

הפונקציה rand יוצרת איברים רנדומלים לא שלמים, אבל ניתן ל"שפץ" אותם.

לדוגמא בין 1 ל 100

 a=round(rand(5,7)*100)
a =

    29    17    52    65    38    91    92
    75    78    74    54     2     9    48
     8    36   100    29     1    75    70
    38    37    25    39    43    15    87
    84    49    66    61    84    94    33

פניה לאיברים

עריכה

אם אנו רוצים לפנות לאיבר מסוים או אפילו למטריצה פנימית ניתן לפנות לאינדקס ואף לשנות אותו.

 >> a(2,5)
ans =  2
>> a(2:4,5:7)
ans =

    2    9   48
    1   75   70
   43   15   87
>>a(2,7)=0
a =

    29    17    52    65    38    91    92
    75    78    74    54     2     9     0
     8    36   100    29     1    75    70
    38    37    25    39    43    15    87
    84    49    66    61    84    94    33

פניה לשורה או עמודה שלמה באמצעות ':'

נקרא לשורה השניה

a(2,:)
ans =

      75    78    74    54     2     9     0

ולעמודה השלישית

a(:,3)
ans =

    52   
    74   
   100   
    25   
    66

נפנה לתת מטריצה מהאיבר במקום

 
a([3:end;4:6)
ans =

  29     1    75   
  39    43    15   
  61    84    94

שימו לב לשימוש ב end, הביטוי end טוב למטריצות שתוכניות מבקשות מהמשתמש.

ניתן לפנות בצורה זו לביטויים שונים . לדוגמא : end-1 (השורה או העמודה לפני האחרונה)

פניה לאיבר במטריצה פרוסה:

ניתן לפנות לאיברים במטריצה לפי אינדקס אחד, בקריאה כזו התוכנה עוברת על העמודות מלמעלה למטה ומשמאל לימין.

לדוגמה הכנסת 1 לאיבר החמישי במטיצה 4*5

a(4,5)=0;
 a(5)=1
a =

   0   1   0   0   0
   0   0   0   0   0
   0   0   0   0   0
   0   0   0   0   0

פעולות חשבוניות בוקטורים ומטריצות

עריכה

פרק זה לוקה בחסר. אתם מוזמנים לתרום לוויקיספר ולהשלים אותו. ראו פירוט בדף השיחה.



חוקי מטריצות

עריכה

פרק זה לוקה בחסר. אתם מוזמנים לתרום לוויקיספר ולהשלים אותו. ראו פירוט בדף השיחה.



שחלוף

עריכה

במטריצה של מספרים שלמים, פעולת השחלוף (transpose בלעז) מחליפה את שורות המטריצה בעמודות שלה . שחלוף מבוצע ע"י הוספת גרש ( ' ) אחרי המטריצה.


octave:15> a = [1,0;2,3]
a =

   1   0
   2   3

octave:16> a'
ans =

   1   2
   0   3

מציאת דטרמיננטה

עריכה

דטרמיננטה של מטריצה הוא סקלר המתקבל מביצוע חישובים על המטריצה.

במטלב ואוקטב קיימת פונקציה המבצעת את החישוב על המטריצה ומחזירה את הדטרמיננטה הפונקציה נקראת בקיצור det.

נחשב דטרמיננטה של מטריצה :

octave:114> det([1 2 3;4 5 6;7 4 3])
ans = -6.0000

אם נשחלף את המטריצה הדטרמיננטה ישתנה?

octave:114> det([1 2 3;4 5 6;7 4 3]')
ans = -6.0000

כנראה שלא . שחלוף מטריצה לא משפיע על הדטרמיננטה.

פונקציות לשימוש בוקטורים ומטריצות

עריכה

מעצבת מטריצה או וקטור מחדש.

שימו לב שחייבת להיות התאמה במימדים של המטריצה או הוקטור המקורי ומטריצת היעד:

octave:5> a=[1,2,3;4,5,6;7,8,9];
octave:6> reshape(a,1,9)
ans =

   1   4   7   2   5   8   3   6   9

מציאת ביטוי מסוים הקיים במטריצה או וקטור. מחזיר את האינדקס של האיבר המקיים את הביטוי.

octave:62> a=[6,4,3,9];
octave:63> find(a>3 & a<9)
ans =

   1   2

כפל אברי המטריצה. מקבלת גם מימדים (אם נוסיף מימד שני =2 נקבל את החישוב לפי שורות)

octave:70> a=[2 2;2 2;3 3]
a =

   2   2
   2   2
   3   3

octave:71> prod(a)
ans =

   12   12

octave:72> prod(a,2)
ans =

   4
   4
   9


הפונקציה מחשבת סכום האיברים .

כאשר מוסיפים בפרמטר שני 2 החישוב יבוצע על השורות.
octave:32> a=[2,5;9,3]'
a =

   2   9
   5   3

octave:33> sum(a,1)
ans =

    7   12

octave:34> sum(a,2)
ans =

   11
    8

מחשבת סכום ומוסיפה לאברי השורה האחרונה או העמודה. כאשר מוסיפים בפרמטר שני 2 החישוב יבוצע על השורות.

octave:35> cumsum(a)
ans =

    2    9
    7   12

octave:36> cumsum(a,2)
ans =

    2   11
    5    8


הפונקציה מחזירה את מימדי הוקטור או המטריצה.

>> x=1:9
x =

  1  2  3  4  5  6  7  8  9

>> size(x)
ans =

   1   9


>> x=[1:4;8:-1:5]
x =

   1   2   3   4
   8   7   6   5

>> size(x)
ans =

   2   4

סידור האיברים מהקטן לגדול. כאשר מקבל פרמטר שני לביצוע הפעולה על השורות.

x=round(rand(3)*10)
x =

    1    3    6
   10    1    1
    9    6   10

>> sort(x)
ans =

    1    1    1
    9    3    6
   10    6   10

>> sort(x,2)
ans =

    1    3    6
    1    1   10
    6    9   10

הכנסנו מטריצה רנדומלית לערך x . ביצענו פעולת מיון רגילה (על העמודות) ולאחר מכן פעולת מיון על השורות.

אם נוציא שני פרמטרים מהפונקציה הפרמטר השני יהיה האינדקס של השינויים.

 [a,b]=sort(vec)
a =

   5   5   8   9

b =

   2   4   3   1

שימו לב שכאשר יש שני מספרים זהים התוכנה תסדר אותם לפי סדר הקריאה-מימין לשמאל.

מציאת הערך הגדול ביותר בוקטור והאינדקס שלו (אם מציבים לשתי ערכים). במטריצה ימצא את הערכים הגדולים בכל עמודה והאינדקס שלהם (כנ"ל).

>>c =[16  2  3 13]
 
 >>[d s]=max(c)
d =  16
s =  1
>>x=magic(4)
x =

   16    2    3   13
    5   11   10    8
    9    7    6   12
    4   14   15    1
>> [c v]=max(x)
c =

   16   14   15   13

v =

   1   4   4   1

 </source
<source lang="matlab">
 fliplr(x)
ans =

   13    3    2   16
    8   10   11    5
   12    6    7    9
    1   15   14    4

> כדי למצוא את האיבר הגדול ביותר במטריצה נשתמש ב max(max(c))

יצירת מטריצה שאיבריה רנדומליים (שברים עשרוניים) בגודל m*n או m (ריבועית).

ראו דוגמה בפסקה של בניית מטריצות.

שינוי סדר האיברים מימין לשמאל

 fliplr(x)
ans =

   13    3    2   16
    8   10   11    5
   12    6    7    9
    1   15   14    4


שינוי סדר האברים מלמעלה למטה.

flipud(x)
ans =

    4   14   15    1
    9    7    6   12
    5   11   10    8
   16    2    3   13

יצירת מטריצת היחידה. שימו לב שאין צורך במימדי השורות והעמודות אלא רק באחד מהם מאחר ומדובר במטריצה ריבועית.

eyes(3)
ans =

   1   0   0
   0   1   0
   0   0   1

zeros/ones

עריכה

zeros-יצירת מטריצת אפסים.

zeros(3)
ans =

   0   0   0
   0   0   0
   0   0   0

ones-יצירת מטריצת המורכבת מאברים שהם הספרה 1.

 ones(3,2)
ans =

   1   1
   1   1
   1   1

כאן רצינו מטריצה 3*2 של אחדים, ולכן הכנסנו עוד נתון לפונקציה (3,2) .

הפונקציה מבצעת שני דברים:

  • מוציאה אלכסון כלשהו ממטריצה (לאו דוקא המרכזי)
  • מחזירה מטריצת אלכסון מוקטור (מטריצת אלכסון - כל האברים הם 0 מלבד האלכסון) .
x=round(rand(3,2)*10)
 x =

   9   0
   5   7
   1   8
 diag(x)
ans =

   9
   7
diag(x,-1)
ans =

   5
   8

בשלב ראשון יצרנו מטריצה בגודל 3*2 עם איברים רנדומליים בין 1 ל 10.

לאחר מכן ביקשנו באמצעות diag את האלכסון הראשי וקיבלנו את הוקטור [7 9]. ביקשנו גם את הוקטור שמתחיל במקום ה 1- (הוקטור הראשי מתחלי ב 0) וקיבלנו את הוקטור [8 5].

מה יקרה עם נפעיל את הפונקציה על וקטור? במקרה הזה הפונקציה תיצור מטריצת אלכסון.

 diag([1 2 3 4])
ans =

   1   0   0   0
   0   2   0   0
   0   0   3   0
   0   0   0   4

 diag(diag(x,-1),1)
ans =

   0   5   0
   0   0   8
   0   0   0

במקרה השני השתמשנו באלכסון במקום ה 1- במטריצה x ויצרנו איתו מטריצה שהוא האלכסון שלה במקום ה - 1.

הפונקציה יוצרת מטריצה שהיא ריבוע קסם (סכום כל שורה שווה לסכום כל עמודה ושווה לאלכסונים). המטריצה צריכה להיות ריבועית.

magic(4)
ans =

   16    2    3   13
    5   11   10    8
    9    7    6   12
    4   14   15    1


פונקציות נוספות ניתן לראות כאן

מציאת המטריצה ההפוכה

מערך תלת מימדי

עריכה

ראינו עד עכשיו מערכים חד ודו מימדים, אבל במטלב ואוקטב ניתן ליצור גם מערכים תלת מימדי.

מערך תלת מימדי הו מהצורה: A(n,m,z)

כאשר:

  • A-שם המערך התלת מימדי
  • n-מספר השורות
  • m-מספר העמודות
  • z- האורך (מספר המטריצות n*m)

ניתן במספר דרכים לאתחל מערך תלת מימדי:

לבנות בסיס בעזרת zeros או ones:

octave:19> a=zeros(3,3,3)
a =

ans(:,:,1) =

   0   0   0
   0   0   0
   0   0   0

ans(:,:,2) =

   0   0   0
   0   0   0
   0   0   0

ans(:,:,3) =

   0   0   0
   0   0   0
   0   0   0

לעצב מחדש מערך קיים עם reshpe:

octave:25> v=1:18;
octave:26> a=reshape(v,2,3,3)
a =

ans(:,:,1) =

   1   3   5
   2   4   6

ans(:,:,2) =

    7    9   11
    8   10   12

ans(:,:,3) =

   13   15   17
   14   16   18
 

שימו לב:

מימדי המערך חייבים להתאים אחד לשני. אם בדוגמה היינו מנסים (3,4,2) היתה מתקבל שגיאה. המערך הפרוס הוא כפולת המימדים  
 

עכשיו תורכם:

כתבו מערך תלת מימדי3*3*3 של ערכים רנדומליים בין 9-1
פתרון
octave:26>ceil(rand(3,3,3)*9)

הסבר: כמו שאר פונקציות הבניה גם rand יכולה לקבל 3 מימדים. rand מחזירה שברים עשרוניים ולכן עיגלנו עם ceil כלומר לכיוון מעלה (אחרת גם 0 היה נכלל בתוצאות) וכפלנו עם 9 כדי ליצור מרווח מ 1 - 9


הפרק הקודם:
מחרוזות
מערכים הפרק הבא:
מספרים מרוכבים