בהמשך לפעם הקודמת, הפעם נראה דרך לגזור פונקציה בצורה סימבולית.
תזכורת: ההבדל ממה שראינו בפעם הקודמת, הוא שאנחנו נקבל בתור Input איזשהו ביטוי שמתאר את הפונקציה שלנו, ונחזיר ביטוי שמתאר את הנגזרת שלה.
איך נעשה את זה? הכרנו בעבר Expression Trees (טיפ מספר 173-175).
נשתמש בהם בשביל לייצג את הפונקציות והנגזרות שלהן.
המימוש הוא יחסית פשוט, זה נראה משהו כזה:
|
|
קצת הסבר: הפונקציה InnerDifferentiate יודעת לגזור פונקציות לפי חוקי הגזירה:
- $ (u + v)’ = u’ + v’ $
- $ (u - v)’ = u’ - v’ $
- $ (u \cdot v)’ = u’v + v’u $
- $ \displaystyle{(\frac{u}{v})’ = \frac{u’v - v’u}{v^2}} $
בנוסף: היא מחזירה 0 במידה והיא מקבלת קבוע, ומחזירה 1 במידה והיא מקבלת פרמטר. (הפונקציה כרגע מניחה שקיים פרמטר יחיד, לפיה היא גוזרת)
הפונקציה DifferentiateUnary יודעת לגזור קריאה לפונקציה פשוטה (למשל $ \sin $, $ \cos $, $ \exp $) עפ"י כלל השרשרת
$ (f(g(x)))’ = f’(g(x)) \cdot g’(x) $
שימו לב שהפונקציה GetDerivative משיגה MethodInfo על ידי טריק שראינו בעבר (ראו גם טיפ מספר 176)
כעקרון המימוש יחסית פשוט, ולא עושה הרבה דברים שיכל לעשות, למשל לפשט את הנגזרות, להתמודד עם מינוס לביטוי, להתמודד עם בסיסים אחרים של הלוגריתם וכו’.
איך משתמשים בזה? ככה:
|
|
זה מחזיר משהו כזה:
((((Cos(x) 1) ((x x) + 1)) - ((((1 x) + (1 x)) + 0) Sin(x))) / (((x x) + 1) ((x * x) + 1)))
שאחרי כמה פישוטים אפשר לראות שזה זהה למה שקיבלנו פעם שעברה.
אז למה זה יותר טוב?
קודם כל, אנחנו מקבלים הפעם ביטוי מתמטי ולא סתם פונקציה אמורפית, כך שאנחנו יכולים לעשות על ביטוי זה אנליזה מתמטית טהורה (לצורך העניין, אם למשל קיבלנו בשיעורי בית איזשהו ביטוי מתמטי ואנחנו צריכים לגזור אותו, אפשר בתיאוריה להשתמש בקוד כזה כדי לעשות את זה)
בנוסף, יותר קל לגזור את הביטוי מספר פעמים, במידה וזו מטרתנו (בפעם הקודמת התקשינו לגזור את הפונקציה יותר מפעם אחת)
המשך יום סימבולי טוב