※ 引述《wwqqww (wwqqww陣亡)》之銘言:
: 最近有需要做一些複雜冗長(但重複性高)的計算式
: 在想說先產生對應那些複雜計算式的字串相對比較容易操作 然後再轉成計算式計算
: 但我一開始做一些簡單的嘗試即遇到一些問題
: 以下有一些問題,希望有大大能幫我解惑 謝謝
: 問題1:
: Input:
: f[x_, y_, z_] := x <> y <> z;
: Input:
: f["\!\(\*SubscriptBox[\"\[PartialD]\", \"m\"]\)",
: "\!\(\*SubscriptBox[\"\[PartialD]\", \"n\"]\)", "(m^2n^2)"]
: Output:
: "\!\(\*SubscriptBox[\"\[PartialD]\", \"m\"]\)\!\(\*SubscriptBox[\"\
: \[PartialD]\", \"n\"]\)(m^2n^2)"
: Input:
: ToExpresion["\!\(\*SubscriptBox[\"\[PartialD]\", \
: \"m\"]\)\!\(\*SubscriptBox[\"\[PartialD]\", \"n\"]\)m^2n^2"]
: 最後這步沒有給我預期的答案: 4 m n
: 想請問問題是出在哪裡,有沒有辦法修正?
: (會這樣預期是因為如果
: Input:
: \!\(
: \*SubscriptBox[\(\[PartialD]\), \(m\)]\(
: \*SubscriptBox[\(\[PartialD]\), \(n\)]\ \((m^2*n^2)\)\)\))
: Output:
: 4 m n
: 問題2: (有點類似問題1)
: 一樣是想要把字串換成Expresion來計算,但不是錯誤的原因是為何
: Input:
: ToExpression[
: "\!\(\*SubscriptBox[\"\[PartialD]\", \"y\"]\)" <>
: "\!\(\*SubscriptBox[\"\[PartialD]\", \"x\"]\)" <> "(x^3*y^5)"]
: Output:
: $Failed
: 想請問問題在哪裡 有沒有辦法修正?
前兩個問題是同一個問題
這牽扯到 Mathematica 是怎麼去看二維運算式的
簡單說就是 Mathematica 會把 \( 到 \) 視為一組二維運算式下去分析
以你問題 1 當中成功求值的例子來看:
\!\(
\*SubscriptBox[\(\[PartialD]\), \(m\)]\(
\*SubscriptBox[\(\[PartialD]\), \(n\)]\ \((m^2*n^2)\)\)\)
這裡面紅色跟黃色兩組 \( \) 的裡面都是偏微分符號帶下標再跟著其內容
也就是說 這個符號需要這樣子的結構才會轉換正確
問題在於 輸入字串時 Mathematica 並不會知道你後面有沒有東西
(不像直接輸入的時候 Mathematica 會等到你全部輸入完
Shift-Enter 按下去後才會去分析)
所以產生的二維運算式字串才只會把偏微分符號跟它的下標用 \( \) 括起來
這甚至在你直接在字串裡打上這整串式子也是一樣
也就是說即使這整串式子直接括引號變成字串再 ToExpression 也不會對
這個問題要硬從這裡解其實很麻煩 (你得去把 \( \) 的結構給拆開重組)
不如走另外一條路 直接產生普通的 Mathematica 函數
以這個例子來說 你可以直接產生
"D[D[m^2*n^2, n], m]" 這樣的字串再去 ToExpression 就可以了
或者如果產生這樣的字串對你有難度的話
也可以利用純函式跟 @ 的前序運算符號 (f@g@h => f[g[h]])
產生 "D[#,m]&@ D[#,n]&@ (m^2*n^2)" 這樣子的字串來用
: 問題3: (跟ToExpresion不相關 不過順便問一下)
: Input:
: \!\(
: \*SubscriptBox[\(\[PartialD]\), \(y\)]\(
: \*SubscriptBox[\(\[PartialD]\), \(x\)]\ z\)\) /. z -> (x^m*y^n)
: 為什麼OutPut是 0
: 而不是如同
: Input:
: \!\(
: \*SubscriptBox[\(\[PartialD]\), \(y\)]\(
: \*SubscriptBox[\(\[PartialD]\), \(x\)]\((x^m*y^n)\)\)\)
: Output:
: m n x^(-1 + m) y^(-1 + n)
因為這個輸入會解釋成
D[D[z, x], y] /. z -> (x^m*y^n)
或是寫成 ReplaceAll[D[D[z, x], y], z -> (x^m*y^n)]
也就是 z 被前面的偏微分符號給搶走了
那在運算時 ReplaceAll 因為沒有 HoldAll 或 HoldFirst 等屬性
所以它的參數會先運算完才進行 ReplaceAll 的運算
也就是 D[D[z, x], y] 先被求值完畢得到 0 了才做取代
解決方法可以把 z /. z -> (x^m*y^n) 給括號起來
這樣就會解釋成 D[D[z /. z -> (x^m*y^n), x], y]
就變成先代換再做了