Re: [问题] ToExpression的几个问题

楼主: LPH66 (-6.2598534e+18f)   2013-06-02 13:01:10
※ 引述《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]
就变成先代换再做了
作者: wwqqww (wwqqww)   2013-06-02 21:22:00
哦喔 解释得非常清楚 感谢

Links booklink

Contact Us: admin [ a t ] ucptt.com