יום רביעי, 9 במרץ 2011

וגרה מטריצה עם וקטור

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

ראשית, הייתם מגרילים את המטריצה:















ואז, בתור מומחי MATLAB הייתם משתמשים בפונקציה mean כדי לקבל וקטור שורה המכיל את הממוצע של כל עמודה:










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














ולסיום, הייתם מפחיתים את המטריצה הזו מהמטריצה הראשונה, לקבלת התוצאה:















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








אולם פונקציה שרבים אינם מכירים יכולה להתמודד עם חוסר ההתאמה הזה בין מימדי המטריצה והוקטור כל עוד יש התאמה מינימלית – הרשו לי להציג בפניכם את bsxfun, והנה דוגמה לשימוש בה לצורך ביצוע פעולת החיסור (minus)
בין המטריצה A והוקטור b:















בשורת הקוד האחרונה נעשה שימוש ב-function handle, וכפי שניתן לראות, התוצאה שהתקבלה זהה לזו שהתקבלה בדרך הקודמת, אולם חשוב לציין שהדרך החדשה צורכת פחות זכרון, וברוב המקרים שבהם תשתמשו ב-bsxfun היא גם תניב את התוצאות מהר יותר מהאלטרנטיבה שהוצגה.


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














האם הכרתם את bsxfun? חשבתם על דרך אחרת לבצע את המשימה שהוצגה? יש פונקציה שעזרה לכם בעבר ולדעתכם רבים לא מכירים אותה? האם אתם מכירים את השימוש ב-@ בתוך MATLAB?