標籤:

在Live Editor里用Symbolic Math Toolbox是一種什麼樣的體驗

之前我看書遇到Matrix Calculus相關的公式經常就這麼似懂非懂地一掠而過,這兩天心血來潮想稍微把基本的東西算得清楚一些,就看到了這份Review[1]。裡面有個問題是計算:

nabla_textbf{x}f(textbf{A}textbf{x}) A: mtimes m, textbf{x}: mtimes 1 f: mathbb{R}^{mtimes1}rightarrowmathbb{R}

正好看到之前Live Editor簡介里有評論說在Live Editor里用符號計算效果拔群,於是我就想試試用Symbolic Math Toolbox來算一下這個梯度的表達式。由於上次用符號工具箱已經是很多很多年以前了,做這麼簡單的一件事情也要一邊讀文檔一邊Google一邊嘗試,磕磕碰碰了差不多一晚上才算是達成了這個小目標。首先上截圖:

輸出里數學公式的渲染還是讓我覺得非常驚喜的。同樣的表達式在命令窗口裡的輸出是長這樣的:

grad_f_x(y1, y2) =n n a1_1*D([1], f_y)(a1_1*x1 + a1_2*x2, a2_1*x1 + a2_2*x2) + a2_1*D([2], f_y)(a1_1*x1 + a1_2*x2, a2_1*x1 + a2_2*x2)n a1_2*D([1], f_y)(a1_1*x1 + a1_2*x2, a2_1*x1 + a2_2*x2) + a2_2*D([2], f_y)(a1_1*x1 + a1_2*x2, a2_1*x1 + a2_2*x2)n

可以想像如果是更加複雜的公式,在Live Editor里的效果肯定比文本版高到不知道哪裡去了。

但是!凡事就怕但是!雖然Live Editor的公式可視化做得很好,就Symbolic Math Toolbox本身來說,我並沒有找到比較直觀的方法來實現這個相當簡單的推導。讓我把我嘗試的過程和碰到的糾結之處簡要描述一下。

首先當然是創建符號矩陣,這個在文檔里直接就有例子。不過符號工具箱默認所有變數都是複數,既然我不太需要考慮複數,我就自己寫了個wrapper說明我只用實數:

function A = sym_matrix(name, matrix_size)nA = sym(name, matrix_size);nassumeAlso(A, real);n

這樣我想轉置一下什麼的就可以愉快地用A了(因為A是共軛轉置)。

第二步是表示 f(textbf{A}textbf{x}) 。前面公式里已經標明 f 是一個多元函數,而 f(textbf{A}textbf{x}) 相當於是一個複合函數 f(y), y=textbf{Ax}。然而我不知道怎麼樣可以比較好地表達多元複合函數,尤其是當 f 只能定義成抽象函數(abstract function)的時候。compose似乎是用來實現複合函數的,但它並不支持用在抽象函數上。我嘗試了好一會兒,最後只能曲線救國,使用subs來定義一個新的函數。

具體來說,我先用符號矩陣聲明了一個多元函數,就是截圖裡面的sym_matrix_func。這個函數是這樣子的:

function sym_matrix_func(func_name, in_matrix)n% Create arg_list based on in_matrixnarg_list = [];ncomma = ;nfor idx = 1 : numel(in_matrix)n elem = in_matrix(idx);n arg_list = [arg_list, comma, char(elem)]; %#okn comma = ,;nendnevalin(base, [syms , func_name, (, arg_list, )]);n

接著用表達式 textbf{y}=textbf{Ax} 去替換f_y里的自變數,得到一個關於 textbf{x} 的函數,就是這一行:

f_x = subs(f_y, [y1, y2], [y_vec(1), y_vec(2)])n

然後就可以對f_x愉快地求梯度了:

grad_f_x = gradient(f_x, x)n

然後......就得到了這麼一個表達式:

我盯著這坨東西看了一會兒,才突然意識到這坨東西不就是 textbf{A}^Tnabla_textbf{y}f(textbf{y}) 嘛,於是在兩邊同乘一個 textbf{A}^{-T} 驗證一下,就有了最後一步:

second_term = inv(A) * grad_f_x;n

然後看看Live Editor里輸出的漂亮整齊的結果,的確是 nabla_textbf{y}f(textbf{y}) 嘛,雖然因為我不得不新構建一個函數f_y,函數的變數都被展開成了textbf{Ax} 的形式......

經過這一番嘗試,我的體驗就是,Live Editor的數學符號可視效果的確非常炫酷,但是符號運算工具箱給我的感覺還是——怎麼描述呢,難以得心應手。一些我們已經非常習慣的數學思維不方便直接在MATLAB里表達出來,時不時地要費一些心思另闢蹊徑或者是殺出一條血路。當然,我覺得不順手也很可能是因為我對這個工具箱不太熟悉,操作起來比較業餘。如果誰能來給我一些人生的經驗又或者把我批判一番,我也是會很excited的。

最後,我好懷念之前某台電腦上盜版的Mathematica啊......不知道現在的Mathematica已經進化到什麼程度了呢。

[1] see.stanford.edu/materi

*題圖來源於網路中某個已不可考的位置

推薦閱讀:

如何快速重寫一份你不了解 組織較差的代碼?(算是代碼整理吧)
求推薦matlab編程比較好的書籍?
理工科女生筆記本選購諮詢?
有正整數1~10,出現的概率分布給定,如何利用MATLAB按照各數字出現的概率輸出一個數字?

TAG:MATLAB |