ועוד. על טכנולוגיה, החיים ומה שביניהם

יום שישי, 25 בספטמבר 2009

למה Octave עדיף על Matlab בהגרלה מהתפלגות נורמלית

אחרי שסקרתי השבוע שלוש חבילות לתכנות מדעי שיכולות להוות תחליפי Matlab, אראה היום יתרון אחד של Octave על-פני החלופה הקניינית.

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

ע.א. זה - ברנש יסודי. כדי שיוכל לתחקר את התוצאות במקרה שמשהו ישתבש, הוא קרא לפונקציית randn בעזרת seed (גרעין? תרשו לי להמשיך במונח הלועזי). בכל לולאה הוא יצר מספר אחד אקראי מהתפלגות נורמלית. את ה-seed הוא יצר מהשעון בעזרת פונקציית clock, ושמר אותו בתוך מערך לצורכי שחזור. ואכן, למרות שהשתמש בפונקציית randn שהממוצע שלה הוא אפס, הוא קיבל הגרלה שבה 90% מהמדידות היו חיוביות, ורק 10% שליליות.

תחילה חשדתי שהבעיה נעוצה באלגוריתם שמייצר את המספר האקראי. ב-Mathworks כותבים שהם משתמשים באלגוריתם Zigguart (מימוש שלו ב-C תוכלו למצוא פה). אלא שאז גיליתי שהבעיה לא חוזרת ב-Octave, למרות שגם ב-Octave משתמשים באותו אלגוריתם. אחרי נסיונות לבודד את הבעיה אני חושב שאני יכול לקבוע שמדובר במימוש שונה, והתוצאות מראות שהמימוש של Octave מניב תוצאות טובות יותר.

כדי לאשש את ההנחה שלי שמדובר במימוש האלגוריתם, כתבתי את הסקריפט הבא:
% Ranncheck.m
% Run over different seeds, and draw a number from a normal distribution

DrawNum = 2500; % Number of draws
Seed = (1:DrawNum)/2;

x = zeros(1, DrawNum); % the random variable
for i = 1:DrawNum

randn('state', Seed(i));
x(i) = randn;
end

figure;
plot(Seed, x);

title('Randn distribution');
xlabel('Seed');
ylabel('randn value');
grid on;

בתוך לולאה שרצה על i (מ-1 עד 1250), אני מגריל מספר לפי התפלגות נורמלית שה-seed שלהן הוא i (ה-seed חייב להיות שלם, ואם הוא Matlab מעגל אותו). כך שלמעשה אני יכול לצייר את הפונקציה שמקשרת בין הערך המוגרל לבין ה-seed שיצר אותו.

חשוב לציין שאת הקוד הרצתי על Matlab R2008b. בינתיים אני רואה ש-Matlab שינו את המימוש ואת הקריאה לפונקציית randn. אין לי גישה עדיין לגרסת Matlab חדשה יותר, אך סביר להניח שתהיה לי בשבועות הקרובים, ואז אבד
וק את זה שוב.
להפתעתי קיבלתי את הגרף הבא:
בגרף ציירתי את הערך שמתקבל מקריאה ל-randn כפונקציה של ה-seed. ניתן לראות שהפונקציה רחוקה מלהיות פסאודו-רנדומלית. למעשה היא כמעט דטרמיניסטית. ב-zoom על הגרף ניתן להבחין במבנים של ממש.

הרצתי את אותו סקריפט ב-octave, וקיבלתי את הגרף הבא:
ניתן לראות שהמימוש ב-Octave של אות אלגוריתם מניב תוצאות מפוזרות בהרבה.

ואיך כל זה מסביר את הבאג של החבר שלי? ברגע שקוראים ל-randn עם seed שמסתמך על ה-clock (שהרזולוציה שלו היא מילישנייה) בתוך לולאה, והביצוע של הלולאה קצר יחסית (יחסית להתקדמות של ה-clock), צפויים לקבל ערכי seed קרובים אחד לשני, ואו אז ההתפלגות ממנה יוגרלו הערכים לא תיראה נורמלית (כי למעשה נגריל ערכים מאיזור מסויים בגרף הראשון.

מסקנות:
  1. המימוש ב-Octave עדיף על זה של Matlab.
  2. אם משתמשים ב-Matlab, לא כדאי להסתמך על ה-clock ליצירת ה-seed בקריאה ל-randn, אלא אם כן אתם בטוחים שמשך זמן ביצוע לולאה בודדת ארוך יחסית.
  3. כדאי לבדוק מה עשו ב-Matlab בגרסאות חדשות יותר, הם יצרו עוד גנרטורים חוץ מ-state, וייתכן שהספק-באג הזה בכלל תוקן.
(וטיפ: מי שמריץ את הסקריפט על Octave בגרסה 3.0 ומקבל הודעת שגיאה שקשורה לפונטים כשהוא מבקש לשמור את הגרף בעזרת פקודת print - כדאי לו לעיין בפוסט הזה. בגרסה 3.2 הבאג אמור להיות מתוקן, אך עוד לא בדקתי).


יום חמישי, 24 בספטמבר 2009

חידה: האם לאונרד כהן יגיע להופעה הערב?

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


(צולם מול קניון איילון, על דרך ששת הימים.)

יום שני, 21 בספטמבר 2009

"מה עושים ביום כיפור?"

שואלת אשתי את אבישג, כמעט בת 4. "רוכבים על אופניים", עונה הגדולה בלי להתבלבל. "מי אמר לכם?", אני שואל. "הגננת", היא עונה.

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

יום ראשון, 20 בספטמבר 2009

חלופות קוד חופשי ל-Matlab

יוצא לי להשתמש בעבודה די הרבה ב-Matlab, ולכן כשהתקנתי לינוקס על ה-PC שלי לפני כשנתיים וחצי, בדקתי אם אפשר להתקין עליו Matlab. שמחתי לגלות שקיימת גרסת Matlab ללינוקס (למעשה הגרסה ללינוקס ולמק היא אותה גרסה), אך כשבאתי להתקין את התוכנה קיבלתי הודעת שגיאה. נבירה קצרה באינטרנט גילתה את מקור הבעיה: Matlab דורשת פנטיום 4 ומעלה, בעוד לי יש (על ה-IBM X30 המזדקן שלי) פנטיום 3. מה איכפת ל-Matlab איזה מעבד אני מריץ? מסתבר שב-Matlab דורשים תמיכה במשהו שנקרא SSE2 שנתמך בגרסה 4 של פנטיום. אגב, גם לא כל מעבדי ה-Atom של אינטל תומכים בדבר הזה, אז אם חשבתם לקנות נטבוק ולהתקין עליו Matlab, כדאי שתוודאו מראש שהמעבד שנשפכם חשקה בו תומך באפשרות.

מעז יצא מתוק: גיליתי לא פחות משלוש תוכנות לתכנות מדעי שמופצות תחת רשיונות קוד פתוח, ושממצבות את עצמן כתחליף Matlab (בניגוד נניח ל-R, שהיא חבילת תכנות מדעי ללא יומרה לתאימות כלשהי ל-Matlab). השלוש הן Octave, Scilab ו-FreeMat.

לפני שצוללים לכל אחת מהאפשרויות, הערה כללית: אף אחת מהאלטרנטיבות לא תואמת למנוע הגרפי של Matlab או למנוע של Simulink. המשמעות: כל הפקודות שמתייחסות ל-properties של handle מסויים בגרף, או כל הפקודות שמתייחסות למודל ב-Simulink, לא רלוונטיות בתחליפים הנ"ל, ויגררו הודעת שגיאה בריצה.

Octave
יתרונות: החבילה הותיקה ביותר היא גם היציבה ביותר בשוק. התאימות שלה ל-Matlab כמעט מושלמת: רוב הפונקציות החישוביות שיש ב-Matlab (כולל מה-Toolboxes) קיימות גם ב-Octave, ודרך הקריאה להן זהה לזו שב-Matlab. למעשה, מה שסגור ב-Matlab הוא רק ה-kernel שמבצע את החישובים. מבחינה חוקית, אין דרך להגן בקניין רוחני על תחביר (syntax) של שפה. Octave מנצלים בדיוק את זה: הם פיתחו kernel משלהם שמשתמש באותו syntax, וכך מאפשרים הרצה של סקריפטים ופונקציות גם על Octave וגם על Matlab.
חסרונות: ל-Octave אין סביבת עבודה (IDE) שבאה איתו. יש ברשת פיתרון לא רע בכלל שנקרא qtOctave, אבל הוא רץ רק על לינוקס. דרך אחרת (בה אני משתמש) היא להריץ Octave ב-Terminal ולהשתמש -text editor החביב עליכם לעריכת הקבצים. למרות שאני מוצא את הדרך הזו מספקת, אין ספק שסביבת העבודה של Matlab עשירה בהרבה, והאפשרויות שמתלוות לה הופכות את העבודה לנוחה ויעילה יותר. בנוסף, ל-Octave אין מודול גרפי משל עצמו, אלא הוא משתמש (נכון להיום) ב-gnuplot. מודול זה עני בתכונות (אין אפשרות לשמור גרף מהחלון, רק משורת הפקודה, והזום זמין רק ב-windows ולא בלינוקס, שזה בכלל מוזר). ידוע לי משיחות שנערכות בקבוצות דיון של Octave שיש שם מחשבות לעבור בעתיד לחבילה גרפית אחרת, ואף התחילו לבחון כמה אפשרויות. חסרון אחרון: תמיכה קהילתית חלשה יחסית למה שהתרגלתי בעולם הקוד הפתוח, בין היתר בגלל שימוש במדיות מיושנות (mailing lists במקום פורומים ו-wiki. השנה היא 2009, לעזאזל).
Scilab
יתרונות
: מכילה IDE מלא. יותר מזה - מכילה חבילה שנקראת Scicos ושמהווה חלופה ל-Simulink. אמנם אין תאימות ל-Simulink, אבל מי שאוהב להשתמש בתכנות גרפי והמערכות שלו נראות כמו משוואות דיפרנציאליות, ימצא ב-Scicos פתרון לא רע בכלל.
חסרונות: התאימות ל-Matlab לא מתקרבת לזו של Octave.
FreeMat
גילו נאות: לא הרצתי מעולם FreeMat מסיבות שיוזכרו בחסרונות.
יתרונות: תאימות ל-Matlab; יעילות ריצה בזכות מהדר JIT (הלא הוא Just In Time Compiler, שמאפשר קומפילציה חלקית של הקוד, לדוגמה לפני לולאת for. קיים גם ב-Matlab, אך לא ב-Octave או ב-Scilab, שם רצוי להמשיך בכתיבה וקטורית); תיעוד מפורט וברור באתר.
חסרונות: הפרויקט מתנהל בלי גב של האקדמיה (Octave מפותח ע"י אוניברסיטאות בארה"ב ובאנגליה) או התעשיה (Scilab מפותח ע"י קונסורציום של חברות בצרפת). לכן התמיכה בפרויקט חלשה, ההתקדמות איטית (הגרסה האחרונה ממרץ 2008), והגרוע מכל - המחברים לא טרחו לסדר את עניין הרשיון הפתוח. המשמעות: הפצות רבות (וביניהן Mandriva בה אני משתמש) מסרבות לצרף את התוכנה ל-repositories שלהן. כלומר, כדי להקין את התוכנה יש צורך לקמפל את קוד המקור שלה, ואנחנו הרי באנו להנות.

סיכום
אם יש לכם כסף ו-EULA לא מעניין אתכם (ואת התעשיות הבטחוניות בארץ, לדוגמה, הוא מעניין ועוד איך), לכו על Matlab. הוא יעיל, הוא נוח, יש בו הכי הרבה אופציות, והוא יעשה לכם נעים בגב.

אם אין לכם כסף, או אם לא בא לכם להצהיר בפני Mathworks והדוד סם איזה שימוש אתם עושים בתוכנה, אני ממליץ על Octave. בחודשים האחרונים התחלתי להשתמש ב-Octave גם בעבודה, ואף אחד לא שם לב. כלומר, אני לא מתקשה להריץ פונקציות וסקריפטים שחבריי כתבו ב-Matlab (ובלבד שאלה לא מכילים קריאות ל-GUI או למודלים של Simulink), וחבריי מריצים ללא קושי פונקציות וסקריפטים שאני כותב ב-Octave. השימוש ב-command line ו- text editor לא נראה לי נורא, אבל אני מדור שלמד ש-terminal היא לא קללה. למעשה, גם כשאני משתמש ב-Matlab ורוצה לדעת משהו על משתנה אני משתמש בפקודת whos ולא ב-variabes editor או איך שלא קוראים לזה, כך שכנראה שאני לא דוגמה. אבל גם אם צריך לשלם מחיר מסויים באי-נוחות, אני סבור שהמחיר הזה, יחסית לאלטרנטיבות, משתלם.

תכנות נעים!