matlab將符號表達式轉化為函數句柄的方法匯總


http://www.ilovematlab.cn/thread-260310-1-1.html

 

http://blog.sina.com.cn/s/blog_66faf9cf0101ckuu.html

 

在用符號 (symbolic) 運算得到一個符號表達式后,我們可能需要令其進一步參與數值運算。然而,很多數值運算函數,比如數值積分函數(quad,quadgk,integral),都只能接受函數句柄作為輸入。於是,將符號表達式轉化為函數句柄就成了必然。

如果不怕麻煩,完全可以通過手動輸入對應的符號表達式來建立函數句柄。然而,很多情況下我們得出的符號表達式可能極其復雜,甚至可能占據很多行。此時,手動輸入顯然相當不便。於是,找到一種自動將符號表達式轉化為函數句柄的方法就顯得尤為重要。下面列舉出三種自動轉換的辦法(三種辦法得到的函數都是匿名函數):

1. 最簡便的辦法:利用 matlabFunction(這個函數只適用於2009a及更新的版本)

  1. syms x 
  2. y=exp(x)*x^2+x+1
  3. g = matlabFunction(y)
復制代碼

如果你的matlab報錯,這說明你的版本太老,那么請使用下面兩種辦法。


2. eval + vectorize 函數:vectorize 的目的是將字符串(string)表達式里的 * / ^ 替換為 .*  ./  .^ ,以支持向量運算。eval 執行該字符串后得到函數句柄

  1. syms x 
  2. y=exp(x)*x^2+x+1
  3. g = eval_r(['@(x)',vectorize(y)])
復制代碼

這個方法需要借助 eval 函數,在論壇里已經被廣大壇友廣泛使用過。


3. str2func + vectorize  函數:str2func 函數可以直接將字符串轉化為函數句柄

  1. syms x
  2. y=exp(x)*x^2+x+1
  3. g = str2func(['@(x)',vectorize(y)])

 

 

這兩天重新 review 了一下 matlabFunction,發現這個函數其實是很強大的,特意來對 16 樓的辦法做一點補充。

matlabFunction 可以在將多個符號表達式轉換為向量化函數(這一轉換的目的是為了供fsolve等函數使用),即函數輸入是一個向量化參數,函數返回值也是一個向量化返回值。實現這一轉換只需在matlabFunction調用時使用 'vars' 參數,並將多個自變量合寫成一個向量並放在 {} 里。這個轉換是一步即可完成,很方便。而我之前在 16 樓提供的辦法實際上是分兩步轉換的:第一步是將多個函數返回值轉換為一個向量化函數返回值,第二步是將多個輸入自變量轉換為一個向量化輸入參數。顯然 16 樓的辦法沒有直接用  'vars' 參數轉換來得快。

現在還是以我在 16 樓的例子來說明這個問題。

  1. syms x1 x2;
  2. y = 2*x1 - x2 - exp(-x1);
  3. z = -x1 + 2*x2 - exp(-x2);
  4. % 16 樓的舊方法,分2步實現
  5. f1 = matlabFunction([y;z]);
  6. f1 = @(x) f1(x(1),x(2));
  7. fsolve(f1,[0 1])
  8. % 新方法:直接利用 'vars' 參數一步轉換成功
  9. f2 = matlabFunction([y;z], 'vars', {[x1 x2]});
  10. fsolve(f2,[1 1])
復制代碼

運行后會發現兩種方法得到了相同的結果。顯然,新方法更為簡潔。

另外一個例子:

  1. syms t
  2. y=sin(2*t).*exp(-0.5*t);
  3. dy = diff(y);
  4. dyf = matlabFunction(dy);
  5. t = [0:0.01:5];
  6. plot(t,subs(y));
  7. x0 = [1,2,4];
  8. x = arrayfun(@(x0) fzero(dyf,x0), x0)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM