סיכום הרצאה - אוניברסיטת בר-אילן

‫© אגף התקשוב‪ ,‬אוניברסיטת בר אילן‬
‫ד"ר סמדר שץ‬
‫קורס תוכנת מטלב ויישומיה‬
‫קורס תוכנת מטלב ויישומיה‬
‫שיעור מס' ‪ :8‬פונקציות‬
‫פונקציה כאופרטור‬
‫מושג האופרטור‬
‫אופרטור הוא "מכונה" שמקבלת קלט‪ ,‬מבצעת עיבודים ומוציאה פלט‪.‬‬
‫האופרטור פועל כ"קופסה שחורה"‪ :‬אין גישה אל או שליטה על העיבודים הנעשים בו‪.‬‬
‫השימוש באופרטור נעשה ע"י אספקת קלט להפעלה ושמירת הפלט לאחר ההפעלה‪.‬‬
‫מושג הפונקציה‬
‫במתמטיקה‪ ,‬פונקציה ‪ f‬היא אופרטור הפועל על תחום במימד אחד (למשל‪ )f(x) :‬או יותר (למשל‪ .)f(x,y,z) :‬הקלט עליו‬
‫פלט‬
‫בתכנות‪ ,‬פונקציה היא תוכנית הפועלת כמו אופרטור‪ :‬מקבלת‬
‫קלט‬
‫פועלת הפונקציה נקרא ארגומנט(ים)‪.‬‬
‫פונקציה‬
‫קלט‪ ,‬מבצעת עיבודים ומחזירה פלט‪.‬‬
‫פונקציה היא "קופסה שחורה"‪ :‬לסביבה המשתמשת בה אין גישה לחישובים הנעשים בתוך הפונקציה‪ ,‬והמידע היחיד‬
‫שמתקבל מן הפונקציה נמצא בערכים המוחזרים מן הפונקציה (פלט)‪.‬‬
‫לפונקציה בתכנות יכולים להיות מספר כלשהו של ארגומנטים‪ :‬אחד‪ ,‬כמה או ללא משתני קלט‪ .‬ברוב שפות התכנות‪,‬‬
‫פונקציות מחזירות רק פלט אחד‪ .‬ב ‪ MATLAB-‬יכולים להיות לפונקציה כמה ארגומנטים של פלט‪.‬‬
‫ארגומנטים‬
‫ארגומנטים הם משתנים המעבירים מידע בין הפונקציה לסביבה הקוראת (לפעמים נקראים גם משתני ‪-‬דמה ‪dummy‬‬
‫‪.)arguments‬‬
‫‪ ‬משתני קלט מעבירים מידע מן הסביבה הקוראת אל הפונקציה‪.‬‬
‫‪ ‬משתני פלט מעבירים מידע מן הפונקציה לסביבה הקוראת‪.‬‬
‫הארגומנטים יכולים לקבל שמות שונים בכל סביבה‪:‬‬
‫‪ ‬בסביבה הקוראת‪ ,‬קלט יכול להיות משתנים או ערכים קבועים‪ .‬פלט חייב להיות משתנים‪.‬‬
‫‪ ‬בתוך הפונקציה‪ ,‬ארגומנטים של קלט ושל פלט חייבים להיות משתנים‪.‬‬
‫‪ ‬ההתאמה בין הארגומנטים בסביבה הקוראת לארגומנטים בתוך הפונקציה נעשית לפי סדר הכתיבה‪.‬‬
‫דוגמאות לארגומנטים בסביבה הקוראת – שימוש בפקודות ‪( MATLAB‬אשר כולן פונקציות)‪:‬‬
‫‪ 1‬קלט‪ 1 ,‬פלט‬
‫)‪s=size(A‬‬
‫‪ 1‬קלט‪ 2 ,‬פלט‬
‫)‪[r c] = size(A‬‬
‫‪ 2‬קלט‪ 1 ,‬פלט‬
‫)‪r = size(A,1‬‬
‫‪ 3‬קלט‪ 2 ,‬פלט‬
‫)‪[val indx]=min(A,[ ],2‬‬
‫‪ 2‬קלט‪ 0 ,‬פלט‬
‫)‪plot(x,y‬‬
‫‪ 0‬קלט‪ 1 ,‬פלט‬
‫‪mydir = pwd‬‬
‫‪ 0‬קלט‪ 0 ,‬פלט‬
‫‪clf‬‬
‫‪ 1‬קלט‪ 3 ,‬פלט‬
‫)'‪[n,t,r]=xlsread('f.xls‬‬
‫עמ' ‪ 1‬מתוך ‪9‬‬
‫שיעור ‪8‬‬
‫מאי ‪15‬‬
‫© אגף התקשוב‪ ,‬אוניברסיטת בר אילן‬
‫ד"ר סמדר שץ‬
‫קורס תוכנת מטלב ויישומיה‬
‫עד כה השתמשנו בפונקציות מוכנות‪ ,‬והכרנו רק את הסביבה הקוראת (שימוש בפקודות ‪ .)MATLAB‬בשיעור זה נלמד‬
‫לכתוב פונקציות‪.‬‬
‫מתי עדיף להשתמש בפונקציות? קלט לסקריפט אפשרי בכמה אופנים‪:‬‬
‫‪ ‬בגוף הסקריפט עצמו‪ .‬בעיה‪ :‬שינוי נתוני הקלט מחייב עריכה ושינוי של קובץ הסקריפט‪.‬‬
‫‪ ‬אתחול משתנים בסביבת העבודה הקוראת‪ ,‬לפני הפעלת הסקריפט‪ .‬בעיה‪ :‬צורך להגדיר משתנים בשמות זהים לאלה‬
‫שהסקריפט משתמש‪ ,‬כדי שאלה יוכרו בסקריפט‪ .‬הקשר בין משתנים "עצמאיים" אלה לסקריפט איננו מובן מאליו‪.‬‬
‫‪ ‬קלט מן המשתמש תוך כדי ריצה‪ .‬צורה זו אינה מתאימה למקרים בהם הסביבה הקוראת יוצרת את נתוני הקלט ללא‬
‫התערבות המשתמש‪.‬‬
‫פונק ציה מאפשרת גמישות בהגדרת הקלט והפלט שפותרת את הבעיות הנ"ל‪.‬‬
‫קובץ פונקציה במטלב‬
‫מבנה קובץ פונקציה‬
‫קבצי פונקציה דומים לקבצי סקריפט‪ :‬אלה קבצי טקסט עם סיומת ‪ .m‬וצורת כתיבת הפקודות זהה‪ .‬השוני‪ :‬בקובץ‬
‫פונקציות‪ ,‬הפקודה הראשונה לביצוע (כלומר שאיננה הערה) צריכה להיות שורת כותרת‪.‬‬
‫משתני קלט‬
‫שם הפונקציה‬
‫מבנה שורת כותרת‪:‬‬
‫)‪= fn(in1, in2, in3‬‬
‫אם יש משתנה פלט אחד‬
‫)‪= fn(in1, in2, in3‬‬
‫אם אין משתנה פלט‬
‫)‪fn(in1, in2, in3‬‬
‫מילה שמורה‬
‫משתני פלט‬
‫‪function‬‬
‫]‪[out1, out2, out3‬‬
‫‪function‬‬
‫‪out‬‬
‫‪function‬‬
‫לאחר שורת הכותרת‪ ,‬יש פקודות המבצעות את החישוב (בדומה לסקריפט)‪.‬‬
‫שם הקובץ צריך להיות זהה לשם הפונקציה‪ .‬במקרה של אי‪-‬התאמה‪ ,‬הפונקציה מוכרת לסביבה הקוראת לפי שם הקובץ‬
‫ולא לפי שם הפונקציה‪.‬‬
‫ביצוע הפונקציה ממשיך עד שתבוצע הפקודה האחרונה או עד שמתבצעת פקודת ‪.return‬‬
‫שימוש בפונקציה‬
‫אם שורת הכותרת היא‪:‬‬
‫הקריאה לפונקציה נכתבת‪:‬‬
‫)‪= fn(in1, in2, in3‬‬
‫)‪= fn(D1, D2, D3‬‬
‫]‪function [out1, out2‬‬
‫]‪ [Ra, Rb‬וסדר הביצוע הוא‪:‬‬
‫הערכים מועברים ממשתני הקלט בקריאה למשתני הקלט בפונקציה‪ ,‬בהתאמה לפי סדר‪ D1 :‬ל‪ D2 ,in1-‬ל‪ in2-‬וכו'‪.‬‬
‫מתבצע החישוב של גוף הפונקציה‪ .‬המשתנים ‪ out1, out2‬חייבים לקבל ערך עד סוף ביצוע הפונקציה וחזרה לסביבה‬
‫הקוראת‪.‬‬
‫בחזרה מן הפונקציה‪ ,‬הערכים מועברים ממשתני הפלט בפונקציה למשתני הפלט בקריאה‪ ,‬לפי הסדר‪ :‬מ‪ out1-‬ל‪ ,Ra-‬מ‪-‬‬
‫‪ out2‬ל‪ Rb-‬וכו'‪.‬‬
‫דוגמאות לצורת הכתיבה של קריאה לפונקציה‪:‬‬
‫)‪[u,v]= fn(a, b, c‬‬
‫אם בסביבה הקוראת יש פלט אחד‪ ,‬מוחזר הפלט הראשון ‪.out1‬‬
‫עמ' ‪ 2‬מתוך ‪9‬‬
‫שיעור ‪8‬‬
‫)‪t = fn(1, 2, 3‬‬
‫מאי ‪15‬‬
‫קורס תוכנת מטלב ויישומיה‬
‫© אגף התקשוב‪ ,‬אוניברסיטת בר אילן‬
‫ד"ר סמדר שץ‬
‫טווח ההכרה (‪ )scope‬של משתנים‬
‫טווח הכרה של משתנה‪ :‬הסביבות שבהן המשתנה מוכר‪.‬‬
‫לכל פונקציה יש זיכרון ‪-‬עבודה ‪ workspace‬משלה‪ .‬משתנים המוגדרים בתוך הפונקציה נקראים‪ :‬משתנים פנימיים‪ .‬טווח‬
‫ההכרה של המשתנים הפנימיים הוא הפונקציה בלבד‪ .‬עם החזרה מן הפונקציה‪ ,‬המשתנים הפנימיים נעלמים‪.‬‬
‫משתנים בזכרון‪-‬העבודה של ‪( MATLAB‬סביבת העבודה הכללית) אינם מוכרים בתוך פונקציות‪.‬‬
‫משתנים בעלי אותו שם שהוגדרו בפונקציות שונות או בזכרון העבודה הם משתנים נפרדים‪.‬‬
‫ארגומנטים של קלט ופלט בפונקציה (משתני דמה) הם משתנים פנימיים‪ .‬בפונקציה ניתן להשתמש בהם כמו בכל משתנה‬
‫פנימי‪ .‬שינוי מ שתנה קלט בתוך הפונקציה לא ישפיע על ערכו של משתנה הקלט בקריאה לפונקציה‪.‬‬
‫◄דוגמא ‪ :1‬פתרון נומרי של משוואה טרנסצנדנטית בשיטת "אריה במדבר"‪ ,‬בדומה לדוגמא ‪ .d6lion‬כאן נכתוב שתי‬
‫פונקציות‪:‬‬
‫)‪function y = d8my_fun(x,p‬‬
‫‪% calcuate cos(2 pi x) -p x‬‬
‫‪% p must be a numeric scalar‬‬
‫;‪y = cos(2*pi*x) - p*x‬‬
‫‪end‬‬
‫‪ .1‬פונקציה ‪ d8my_fun‬אשר מחשבת את )‪f(x‬‬
‫כדי לפתור את המשוואה ‪ .f(x)=0‬הפונקציה‬
‫‪ d8my_fun‬מקבלת שני ארגומנטים‪ :‬ערך ‪x‬‬
‫וכן פרמטר‪ ,‬ומחשבת את המשוואה עם‬
‫הפרמטר‪.‬‬
‫‪ .2‬פונקציה ‪ d8lion‬אשר מבצעת את אלגוריתם ההתכנסות‪ ,‬תוך שימוש בפונקציה ‪ d8my_fun‬לחישוב המשוואה‪.‬‬
‫הפונקציה מחשבת פתרון עבור פרמטר ‪ p‬עד דיוק ‪ epsilon‬ומספר מקסימלי של איטרציות ‪ ,MaxIters‬ובהינתן תחום‬
‫התחלתי ‪ .xRange‬הפונקציה מחזירה ‪ 3‬משתני פלט‪ :‬הפתרון‪ ,‬מס' האיטרציות שבוצעו‪ ,‬וכן האם הושגה התכנסות‪.‬‬
‫במקרה שיש למשוואה סימן זהה בש ני קצוות התחום ההתחלתי‪ ,‬האלגוריתם לא מתבצע ומוחזר ערך ‪ NaN‬עבור ‪.x‬‬
‫‪d8solve‬‬
‫השימוש בפונקציה ‪ d8lion‬מודגם ע"י הסקריפט‬
‫‪ .d8solve‬הפרמטר ‪ b‬מתקבל מן המשתמש‪.‬‬
‫‪b = 2, 8 iterations‬‬
‫‪1‬‬
‫תחילה משתמשים בפונקציה ‪ d8my_fun‬כדי‬
‫להציג באופן גרפי את המשוואה בתחום של ערכים‬
‫‪0.5‬‬
‫המתאים לפרמטר ‪ b‬ולאפשר למשתמש לבחור‬
‫את התחום שממנו יתחיל החיפוש‪.‬‬
‫‪0‬‬
‫‪solution = 0.2‬‬
‫הסקריפט מפעיל את הפונקציה ‪ d8lion‬עם‬
‫הפרמטר והתחום שנקלטו מן המשתמש‪ ,‬עם‬
‫‪-0.5‬‬
‫מספר מקסימלי של ‪ 10‬איטרציות ודרישת דיוק של‬
‫‪ ,0.01‬ומציג את הפתרון על השרטוט‪ .‬אם לא‬
‫‪-1‬‬
‫נמצא פתרון‪ ,‬מוצגת כותרת מתאימה‪.‬‬
‫‪-1.5‬‬
‫‪-2‬‬
‫‪0.5‬‬
‫עמ' ‪ 3‬מתוך ‪9‬‬
‫‪0.4‬‬
‫שיעור ‪8‬‬
‫‪0.3‬‬
‫‪0.2‬‬
‫‪0.1‬‬
‫‪0‬‬
‫‪-0.1‬‬
‫‪-0.2‬‬
‫‪-0.3‬‬
‫‪-0.4‬‬
‫‪-0.5‬‬
‫מאי ‪15‬‬
‫קורס תוכנת מטלב ויישומיה‬
‫© אגף התקשוב‪ ,‬אוניברסיטת בר אילן‬
‫ד"ר סמדר שץ‬
‫פונקציות משניות‬
‫קובץ ‪ mFile‬יכול לכלול יותר מפונקציה אחת‪.‬‬
‫הפונקציה הראשונה בקובץ נקראת פונקציה ראשית ‪ primary function‬ושמה זהה לשם הקובץ‪.‬‬
‫הפונקציות הנוספות בקובץ נקראות פונקציות משניות ‪subfunctions‬‬
‫מבנה ‪ mFile‬עם פונקציות משניות‪:‬‬
‫פונקציה מתחילה בשורת ‪-‬כותרת‪.‬‬
‫פונקציה מסתיימת באחד מן המקרים הבאים‪:‬‬
‫‪ ‬שורת הקוד הבאה היא שורת כותרת (כלומר‪ ,‬המשך הקוד שייך לפונקציה הבאה)‪.‬‬
‫‪ ‬סוף הקובץ‪.‬‬
‫‪ ‬פקודת ‪ .end‬אם אחת הפונקציות מסתיימת בפקודת ‪ , end‬חייבים לסיים בצורה זו את כל הפונקציות בקובץ‪.‬‬
‫טווח הכרה‪:‬‬
‫הסביבה הקוראת מכירה רק את הפונקציה הראשית (לפי שם הקובץ)‪.‬‬
‫הפונקציות המשניות מוכרות רק לשאר הפונקציות בקובץ‪ .‬הן לא מוכרות מחוץ לקובץ‪.‬‬
‫אם קיימות שתי פונקציות באותו שם‪ ,‬אחת פונקציה משנית ואחת פונקציה בקובץ נפרד‪ ,‬אז קריאה לפונקציה תבצע את‬
‫הפונקציה המשנית‪ .‬במילים אחרות‪ ,‬לפונקציה משנית יש עדיפות על פונקציה בשם זהה בקובץ אחר‪.‬‬
‫המשתנים המקומיים לפונקציה (ראשית או משנית) מוכרים רק לפונקציה עצמה (יש לכל פונקציה ‪ workspace‬משלה)‪.‬‬
‫לסיכום‪ :‬פונקציות שנמצאות בקובץ אחד מכירות זו את זו אבל לא זו את המשתנים של זו‪.‬‬
‫שימושים לפונקציות משניות‬
‫‪ ‬לכלול כמה פונקציות קצרות בקובץ אחד כדי למנוע ריבוי של קבצים‪.‬‬
‫‪" ‬להחביא" פונקציות שנכתבו בהקשר מסוים כך שלא ייעשה בהן (בטעות) שימוש כללי‪.‬‬
‫‪" ‬להחליף" בהקשר ספציפי פונקציות של מטלב או פונקציות שנכתבו ע"י המשתמש בגירסה שמתאימה יותר להקשר זה‪.‬‬
‫◄דוגמא ‪ :2‬בהמשך לדוגמא ‪ ,1‬מציאת כל הפתרונות של המשוואה בתחום נתון‪ ,‬כאשר אין דרישה שהתחום הראשוני הוא‬
‫כזה שיהיו למשוואה סימנים מנוגדים בקצותיו‪ .‬הקובץ ‪ d8sub.m‬כולל פונקציה ראשית ושתי פונקציות משניות‪:‬‬
‫‪ .1‬הפוקציה המשנית ‪ lion‬הזהה לפונקציה ‪ d8lion‬מוצאת פתרון אחד‪ ,‬כאשר מובטח שלמשוואה יהיו סימנים מנוגדים‬
‫בקצוות התחום‪.‬‬
‫‪ .2‬הפונקציה המשנית ‪ FindRange‬מוצאת את האזורים בהם המשוואה מחליפה סימן‪.‬‬
‫שתי הפונקציות משתמשות בפונקציה ‪ d8my_fun‬הנמצאת בקובץ נפרד בשם זה‪.‬‬
‫הפונקציה הראשית קוראת תחילה לפונקציה ‪ FindRange‬ושומרת את סדרת התחומים שנמצאו‪ .‬לכל תחום‪ ,‬מופעלת ‪lion‬‬
‫כדי למצוא פתרון יחיד בתחום זה‪.‬‬
‫)]‪d8sub(0.7,0.001,20,[-2 2‬‬
‫= ‪ans‬‬
‫‪-0.6723‬‬
‫‪-0.2822‬‬
‫‪0.2254‬‬
‫‪0.8516‬‬
‫‪1.1092‬‬
‫הפעלת הפונקציה עם פלט בודד‪:‬‬
‫(נקבל רק את סדרת הפתרונות)‪.‬‬
‫עמ' ‪ 4‬מתוך ‪9‬‬
‫שיעור ‪8‬‬
‫מאי ‪15‬‬
‫קורס תוכנת מטלב ויישומיה‬
‫© אגף התקשוב‪ ,‬אוניברסיטת בר אילן‬
‫ד"ר סמדר שץ‬
‫הפעלת הפונקציה עבור מספר משתני פלט‪:‬‬
‫)]‪[y,iters,flag] = d8sub(1,0.00005,10,[-2 2‬‬
‫= ‪y‬‬
‫‪-0.6396‬‬
‫‪-0.2982‬‬
‫‪0.2155‬‬
‫‪0.9489‬‬
‫‪1.0000‬‬
‫= ‪iters‬‬
‫‪10‬‬
‫‪10‬‬
‫‪10‬‬
‫‪10‬‬
‫‪10‬‬
‫= ‪flag‬‬
‫‪1‬‬
‫‪1‬‬
‫‪1‬‬
‫‪1‬‬
‫‪1‬‬
‫פונקציות אנונימיות‬
‫פונקציה אנונימית מורכבת מפקודה אחת שמחזירה ערך אחד‪( .‬הערך יכול להיות מסוג מורכב למשל מערך תאים או‬
‫מבנים‪ ,‬אבל חייב להיות משתנה אחד)‪.‬‬
‫‪hndl = @(arguments) expression‬‬
‫פקודה ליצירת פונקציה אנונימית‪:‬‬
‫משתני קלט מופרדים בפסיקים (כמו בפונקציה רגילה)‬
‫ביטוי כלשהו במטלב (לא חייב להחזיר ערך)‬
‫נוצר אובייקט מסוג ‪( function-handle‬עוד על כך‪ ,‬בשיעור ‪ 10‬על אנליזה נומרית)‬
‫שימוש בפונקציה‪:‬‬
‫מציב את ערכי ‪ arguments‬בביטוי ‪ expression‬ומחזיר את התוצאה‪.‬‬
‫‪arguments‬‬
‫‪expression‬‬
‫‪hndl‬‬
‫)‪hndl(arguments‬‬
‫אם יש בביטוי עוד משתנים שאינם ארגומנטים ‪ ,‬חייב להיות להם ערך בזמן יצירת הפונקציה‪.‬‬
‫דוגמא‪ :‬נגדיר משתנים‬
‫ופונקציה אנונימית אשר משתנים אלה הם‬
‫עבורה פרמטרים (קבועים)‪.‬‬
‫;‪x0 = 5; y0 = 2‬‬
‫‪expfun = @(x) exp(-x/x0) + y0‬‬
‫= ‪expfun‬‬
‫‪@(x)exp(-x/x0)+y0‬‬
‫)]‪expfun([0 0.1 1‬‬
‫= ‪ans‬‬
‫‪3.0000‬‬
‫‪2.9802‬‬
‫‪2.8187‬‬
‫;‪x0 = 6; y0 = 1‬‬
‫צורת השימוש בפונקציה‪:‬‬
‫אם אם נשנה את ערכי ‪ x0‬או ‪ y0‬הפונקציה לא תשתנה‪,‬‬
‫)]‪1‬‬
‫‪2.9802‬‬
‫‪2.8187‬‬
‫;‪exp(-x/x0) + y0‬‬
‫)]‪1‬‬
‫אלא אם נגדיר אותה מחדש‪.‬‬
‫‪1.8465‬‬
‫‪1.9835‬‬
‫‪expfun([0 0.1‬‬
‫= ‪ans‬‬
‫‪3.0000‬‬
‫)‪expfun = @(x‬‬
‫‪expfun([0 0.1‬‬
‫= ‪ans‬‬
‫‪2.0000‬‬
‫◄דוגמא ‪ :3‬נשנה מעט את הסקריפט ‪ d4circle‬כך שפעולות חוזרות תתבצענה ע"י פונקציות‪ .‬תזכורת‪ :‬הסקריפט מבקש‬
‫מן המשתמש לבחור קובץ תמונה ‪ circle*.jpg‬מתיקיית ‪ .shapes‬הקובץ כולל תמונה בפורמט ‪ RGB‬כלומר מערך תלת ‪-‬‬
‫עמ' ‪ 5‬מתוך ‪9‬‬
‫שיעור ‪8‬‬
‫מאי ‪15‬‬
‫קורס תוכנת מטלב ויישומיה‬
‫ד"ר סמדר שץ‬
‫© אגף התקשוב‪ ,‬אוניברסיטת בר אילן‬
‫ממדי שבו כל "מישור" מתייחס לצבע (אדום‪ ,‬ירוק וכחול)‪ ,‬מוצא ומ ציג את הנקודות (פיקסלים) השייכות לעיגול הלבן‬
‫שבצילום‪.‬‬
‫בסקריפט ‪ d8circle‬מוגדרות שתי פונקציות אנונימיות‪:‬‬
‫‪ maxall .1‬מחשבת מקסימום של כל אברי מערך (נחוצה במערכים שאינם חד‪-‬ממדיים)‪.‬‬
‫‪ and3 .2‬מבצעת איפוס של איברי מטריצה בכל המישורים של מערך תלת‪-‬ממדי‪ ,‬לפי "מסכה" (מטריצה לוגית)‪.‬‬
‫כאן מודגם שימוש בפונקציות אנונימיות גם בסקריפט (בשונה מפונקציות משניות שאפשר לכלול רק בקובץ פונקציה)‪.‬‬
‫שימושים לפונקציות אנונימיות‬
‫‪ ‬כתיבת פונקציה בצורה מקוצרת‬
‫‪ ‬הגדרת פונקציה בסקריפט‬
‫‪" ‬פונקציית מעטפת" לקביעה של פרמטרים (עוד על כך‪ ,‬בשיעור ‪ 10‬על אנליזה נומרית)‪.‬‬
‫‪ ‬הרחבת טווח‪-‬הכרה של פונקציות שהוגדרו בהקשר מקומי (שימושי בכתיבת ממשקי משתמש)‪.‬‬
‫פונקציה פנימית ‪nested function‬‬
‫פונקציה פנימית היא פונקציה המוגדרת כחלק מגוף (פקודות) של פונקציה אחרת‪.‬‬
‫הגדרת פונקציה פנימית‪ :‬מתחילה בשורת ‪-‬כותרת ומסתיימת ב‪.end-‬‬
‫בקובץ שיש בו פונקציה פנימית אחת לפחות‪ ,‬כל הפונקציות (גם הראשית וגם המשניות אם יש) חייבות להסתיים ב‪.end-‬‬
‫טווח הכרה‪ :‬פונקציה פנימית מוכרת לפונקציה שמעליה ולכל הפונקציות הפנימיות לפונקציה שמעליה‪.‬‬
‫לדוגמא‪ ,‬הפונקציה ‪ nested_f‬מוכרת לפונקציה ‪parent_f‬‬
‫אבל לא לפונקציה ‪ .sub_f‬הפונקציה ‪ sub_f‬מוכרת‬
‫לפונקציות ‪.nested_f ,parent_f‬‬
‫ארגומנטים בפונקציה הפנימית הם משתנים פנימיים‬
‫שלה‪( .‬אם משנים אותם‪ ,‬אין השפעה על הסביבה‬
‫הקוראת)‪ .‬לדוגמא ‪.arg1,arg2‬‬
‫משתנים בפונקציה הפנימית שיש להם שמות זהים‬
‫למשתנים בפונקציה שמעליהם‪ ,‬משותפים לשתי‬
‫הסביבות‪ .‬לדוגמא ‪ out1,out2‬מוכרים גם ב‪parent_f-‬‬
‫וגם ב‪( nested_f-‬אולם לא לסביבה שקוראת ל‪parent_f-‬‬
‫!)‪ .‬שינוי של המשתנים בתוך הפונקציה משפיע על הסביבה‬
‫הקוראת‪ ,‬ולהפך‪.‬‬
‫משתנים שנמצאים בפונקציה הפנימית אבל לא בפונקציה‬
‫שמעליה הם משתנים פנימיים‪ .‬לדוגמא ‪.tmp‬‬
‫◄דוגמא ‪ :4‬הפונקציה ‪ d8simulate‬מבצעת את הסימולציה הבאה‪ :‬נתונה מטריצה לוגית בה ‪ 1‬מסמן מקום מאוכלס ו‪0-‬‬
‫מסמן מקום ריק‪ .‬בכל שלב מחשבים את מספר השכנים (מספר המקומות המאוכלסים מימין‪ ,‬משמאל‪ ,‬למטה ולמעלה מכל‬
‫עמ' ‪ 6‬מתוך ‪9‬‬
‫שיעור ‪8‬‬
‫מאי ‪15‬‬
‫קורס תוכנת מטלב ויישומיה‬
‫© אגף התקשוב‪ ,‬אוניברסיטת בר אילן‬
‫ד"ר סמדר שץ‬
‫משבצת) ובהתאם לכך קובעים האם בשלב הבא המקום יהיה מאוכלס או לא‪ .‬קריטריון ההחלטה על השלב הבא נתון ע"י‬
‫מערך לוגי ‪ NextStep‬של ‪ 5‬איברים‪ :‬הראשון מתייחס ל‪ 0-‬שכנים‪ ,‬השני לשכן אחד וכך עד לחמישי המתייחס ל‪ 4-‬שכנים‪.‬‬
‫איבר שיש בו ‪ )true( 1‬מסמן שהמקום יהיה מאוכלס בשלב הבא ואיבר שיש בו ‪ )false( 0‬מסמן שהמקום יהיה ריק בשלב‬
‫הבא‪.‬‬
‫המודל כולל תנאי‪-‬שפה מחזוריים‪ ,‬כלומר איברים בעמודה הראשונה הם "שכנים" מימין של האיברים בעמודה אחרונה‬
‫וכנ"ל גם לגבי שורות ראשונה ואחרונה‪ .‬כדי לממש תנאי שפה אלה בצורה יעילה במטלב‪ ,‬אחרי כל שלב יש "לרפד" את‬
‫המטריצה כך שעמודה ראשונה מועתקת אחרי האחרונה‪ ,‬האחרונה מועתקת לפני הראשונה‪ ,‬וכנ"ל גם לגבי השורות‬
‫ראשונה ואחרונה‪.‬‬
‫בכל שלב הפונקציה מחשבת את מספר המקומות המאוכלסים‪ ,‬ובסוף הסימולציה מחזירה מערך של ערכים בכל צעדי‬
‫הסימולציה‪.‬‬
‫הקובץ ‪ d8simulate‬כולל שלוש פונקציות פנימיות‪:‬‬
‫‪ next_step .1‬מחשבת את השלב הבא (כולל קריאה לפונקציה אחרת שמעדכנת תנאי שפה מחזוריים)‪.‬‬
‫‪ plotmat .2‬מציגה מפה של האכלוס ומחשבת את כלל המקומות המאוכלסים‪.‬‬
‫‪ boundary_update .3‬מעדכנת תנאי ‪-‬שפה מחזוריים‪.‬‬
‫כל הפונקציות הפנימיות מכירות את המשתנה ‪ Mat‬שהוא מטריצה האכלוסים‪ .‬מאחר שהמטריצה יכולה להיות גדולה‬
‫מאוד‪ ,‬יש ייתרון בכך שכל פונקציה פנימית יכולה לשנות מערך זה מבלי שנצטרך בכל פעם להגדיר מערך חדש ולבצע‬
‫השמה במקום המערך מהשלב הקודם‪.‬‬
‫כמו‪-‬כן מוגדרת פונקציה אנונימית ‪ flatmat‬אשר מקבלת מערך ממימד כלשהו ומחזירה רשימת איברים (מערך עמודה)‪.‬‬
‫;]‪Next = [false false true false false‬‬
‫))‪Nt = d8simulate(Next,10,eye(7‬‬
‫= ‪Nt‬‬
‫‪7‬‬
‫‪14‬‬
‫‪14‬‬
‫‪28‬‬
‫‪14‬‬
‫‪28‬‬
‫‪28‬‬
‫‪42‬‬
‫‪14‬‬
‫‪14‬‬
‫הפעלת הפונקציה‪:‬‬
‫נניח שתא מאוכלס בצעד הבא אם יש לו ‪ 2‬שכנים‪,‬‬
‫ואיננו מאוכלס אם יש לו ‪ 3 ,1 ,0‬או ‪ 4‬שכנים‪.‬‬
‫נריץ את הסימולציה ל‪ 5-‬צעדים‪ .‬נתחיל ממטריצת‬
‫היחידה‪.‬‬
‫משמאל תיאור המצב אחרי סיום התהליך‪.‬‬
‫המשבצות השחורות ריקות והלבנות מאוכלסות‪.‬‬
‫‪1‬‬
‫‪2‬‬
‫‪3‬‬
‫‪4‬‬
‫‪5‬‬
‫‪6‬‬
‫‪7‬‬
‫‪8‬‬
‫עמ' ‪ 7‬מתוך ‪9‬‬
‫שיעור ‪8‬‬
‫‪7‬‬
‫‪6‬‬
‫‪5‬‬
‫‪4‬‬
‫‪3‬‬
‫‪2‬‬
‫‪8‬‬
‫‪1‬‬
‫מאי ‪15‬‬
‫© אגף התקשוב‪ ,‬אוניברסיטת בר אילן‬
‫ד"ר סמדר שץ‬
‫קורס תוכנת מטלב ויישומיה‬
‫;]‪Next = [false true true true false‬‬
‫;‪Init = randi(2,100)>1‬‬
‫))‪plot(d8simulate(Next,1000,Init‬‬
‫נניח שתא מאוכלס בצעד הבא אם יש לו ‪ 2 ,1‬או‬
‫‪ 3‬שכנים‪ ,‬ואיננו מאוכלס אם יש לו ‪ 0‬או ‪ 4‬שכנים‪.‬‬
‫נתחיל ממטריצה אקראית שבה כל תא מאוכלס‬
‫‪9000‬‬
‫בהסתברות ‪.0.5‬‬
‫‪8000‬‬
‫נריץ את הסימולציה ל‪ 1000-‬צעדים ונשרטט את‬
‫‪7000‬‬
‫מספר התאים המאוכלסים כפונקציה של מספר‬
‫‪6000‬‬
‫הצעד‪.‬‬
‫‪5000‬‬
‫‪4000‬‬
‫‪1000‬‬
‫‪900‬‬
‫‪800‬‬
‫‪700‬‬
‫‪600‬‬
‫‪500‬‬
‫‪400‬‬
‫‪300‬‬
‫‪200‬‬
‫‪100‬‬
‫‪0‬‬
‫‪3000‬‬
‫שימושים לפונקציות פנימיות‬
‫‪ ‬הגדרת פונקציה‪ ,‬בלי הצורך להעביר מספר גדול של ארגומנטים או כמויות גדולות של זיכרון דרך משתני קלט ופלט‪,‬‬
‫למטרות הבאות‪:‬‬
‫‪ o‬פירוק קוד ארוך לפונקציות לפי מטלות‬
‫‪ o‬שימוש חוזר בקטעי קוד לא‪-‬קצרים באותה סביבה קוראת‪.‬‬
‫‪ ‬הגדרת פונקציה עם פרמטרים קבועים‪ ,‬לצורך "ייצוא" לסביבות אחרות‪( .‬אפשר ליישם באמצעות פונקציה אנונימית‬
‫רק אם ניתן לבצע את המטלה בפקודה אחת)‪ .‬שימושי בעיקר בבניית ממשקי משתמש‪.‬‬
‫השוואה בין סקריפט לסוגי הפונקציות השונות‬
‫קלט‬
‫משתני פלט‬
‫תחום‬
‫הגדרה של‬
‫משתנים‬
‫משתנים‬
‫אחרי תום‬
‫הביצוע‬
‫מבנה‬
‫הקובץ‬
‫עמ' ‪ 8‬מתוך ‪9‬‬
‫סקריפט‬
‫קבוע‪ ,‬דרך משתנים עם‬
‫שמות ספציפיים‬
‫קבוע‪ ,‬דרך משתנים עם‬
‫שמות ספציפיים‬
‫כל המשתנים מוכרים‬
‫בזיכרון העבודה‬
‫‪workspace‬‬
‫פונקציה‬
‫גמיש‪ ,‬דרך‬
‫ארגומנטים‬
‫גמיש (בלי‪,‬‬
‫אחד או יותר)‬
‫פנימי‬
‫לפונקציה‪.‬‬
‫נשארים בזיכרון העבודה‬
‫נמחקים‬
‫רק סקריפט אחד‪ ,‬ללא‬
‫קטעי קוד של פונקציות‪.‬‬
‫ניתן להגדיר פונקציות‬
‫אנונימיות‪.‬‬
‫יכול לכלול‬
‫מספר‬
‫פונקציות‬
‫פונקציה אנונימית‬
‫גמיש‪ ,‬דרך ארגומנטים‬
‫רק פלט אחד‬
‫אין משתנים פנימיים‬
‫(רק משתני קלט)‪.‬‬
‫שאר המשתנים נחשבים‬
‫לפרמטרים וצריכים‬
‫להיות קיימים בזמן‬
‫ההגדרה‪.‬‬
‫אין משתנים פנימיים‪.‬‬
‫אין צורך בקובץ נפרד‪.‬‬
‫ניתן להגדיר גם‬
‫בסקריפט‪.‬‬
‫שיעור ‪8‬‬
‫פונקציה פנימית‬
‫ארגומנטים ‪ +‬משתנים משותפים‬
‫לפונקציה ולסביבה הקוראת‪.‬‬
‫ארגומנטים ‪ +‬משתנים משותפים‬
‫לפונקציה ולסביבה הקוראת‪.‬‬
‫משתנים משותפים לסביבה‬
‫הקוראת‪ ,‬מוכרים גם בסביבה‬
‫הקוראת וגם בפונקציה‪ .‬כל‬
‫המשתנים האחרים הם פנימיים‪.‬‬
‫משתנים פנימיים נמחקים‪.‬‬
‫משתנים משותפים נשארים כל‬
‫עוד הסביבה הקוראת פעילה‪.‬‬
‫ניתן להגדיר רק בקובץ פונקציות‪.‬‬
‫יש לסיים ב‪ end-‬את כל‬
‫הפונקציות בקובץ (גם ראשית‬
‫ומשניות)‪.‬‬
‫מאי ‪15‬‬
‫קורס תוכנת מטלב ויישומיה‬
‫© אגף התקשוב‪ ,‬אוניברסיטת בר אילן‬
‫ד"ר סמדר שץ‬
‫טווח הכרה של קבצים‬
‫כאש ר מטלב מפענח ביטוי שיש בו שם‪ ,‬הוא מחפש עצמים בעלי שם זה לפי הסדר הבא‪:‬‬
‫‪ .1‬שם משתנה (יכול להיות גם מסוג ‪.)function-handle‬‬
‫‪ .2‬אם מתבצע קובץ של פונקציות‪ :‬שם של פונקציה משנית או פנימית‪.‬‬
‫‪ .3‬קובץ ‪ .m‬בשם זה (אשר אמור להכיל קוד מטלב תקין)‪.‬‬
‫במטלב יש משתנה בשם ‪ path‬שהוא רשימה של תיקיות לחיפוש (‪ cell-array‬של מחרוזות)‪ .‬מטלב מחפש ברשימה זו את‬
‫הקובץ המבוקש לפי סדר התיקיות ברשימה‪ ,‬ומשתמש בקובץ הראשון שמצא (אפילו אם קובץ בשם זה קיים גם בתיקיות‬
‫אחרות)‪.‬‬
‫הפקודות הבאות מספקות מידע על טווח ההכרה של קבצים וכן אפשות לשנותו‪:‬‬
‫‪which fname‬‬
‫שם מלא של הקובץ (כולל תיקייה בה נמצא)‬
‫‪p = path‬‬
‫רשימת התיקיות לחיפוש‬
‫הוספת התיקייה במשתנה ‪ newpath‬לסוף רשימת החיפוש‪.‬‬
‫)‪path(path,newpath‬‬
‫הוספת התיקייה במשתנה ‪ newpath‬להתחלת רשימת החיפוש‪.‬‬
‫)‪path(newpath,path‬‬
‫)‪addpath(newpath‬‬
‫אפשר לבצע את הנ"ל גם ע"י הפקודה‪:‬‬
‫שינוי ה‪ path-‬תקף רק עד היציאה ממטלב‪ .‬בפעם הבאה יש לבצעו שוב‪ ,‬או שיש להשתמש בכלי ה‪ path-‬בשולחן העבודה‬
‫של מטלב כדי לשנות את ה‪ path-‬באופן קבוע‪.‬‬
‫דו"חות‬
‫הדו"חות הבאים רלוונטיים לשימוש בפונקציות‪:‬‬
‫עץ קריאה ‪dependency‬‬
‫דו"ח זה מבוסס על הקוד עצמו‪ ,‬ונותן רשימה של כל הפונקציות והסקריפטים בתיקייה הנוכחית‪ .‬לכל קובץ תוכנית בתיקייה‪,‬‬
‫מצויין אילו קבצים נקראים על ידו (עם ה‪ path-‬המלא שלהם‪ ,‬כולל פקודות מטלב)‪ ,‬ואילו קבצים בתיקייה הנוכחית‬
‫משתמשים בו‪.‬‬
‫ניתוח זמנים ‪profiler‬‬
‫דו"ח זה מבוסס על בדיקה מדגמית של תוכנית בזמן ריצה‪ .‬בדו"ח מצויינים לא רק זמני הריצה של קטעי קוד שונים‪ ,‬אלא‬
‫גם חלקן של פונקציות שנקראות ע"י קטע קוד מסוים בזמן הכולל של ביצוע הקוד‪.‬‬
‫תוכן ‪contents‬‬
‫דו"ח זה אוסף את כל קטעי ה‪ help-‬מקבצי התוכניות בתקייה הנוכחית ועורך אותם כ"תוכן עניינים" בקובץ ‪ contents.m‬כך‬
‫שביצוע הפקודה ‪ contents‬מציג את המידע‪.‬‬
‫עמ' ‪ 9‬מתוך ‪9‬‬
‫שיעור ‪8‬‬
‫מאי ‪15‬‬