如何从复杂表达式Maple/Matlab中构造只有两个变量和一个算术运算的子表达式?
让符号表达式如下所示如何从复杂表达式Maple/Matlab中构造只有两个变量和一个算术运算的子表达式?,matlab,symbolic-math,maple,Matlab,Symbolic Math,Maple,让符号表达式如下所示 y = s + (a/b)*log((a+c)/(b*a)); %# it can be any type of expression 如何得到所有可能的子表达式,其中包含两个变量和一个运算符 subExpression1 = b*a; subExpression2 = a/b; 我在基于运算符提取子表达式时遇到了麻烦。如果我读一个运算符,我必须研究它的LHS和RHS,并验证它只对一个变量起作用,而不是对另一个子表达式起作用 有没有一种方法可以同时研究操作员的LHS和R
y = s + (a/b)*log((a+c)/(b*a)); %# it can be any type of expression
如何得到所有可能的子表达式,其中包含两个变量和一个运算符
subExpression1 = b*a;
subExpression2 = a/b;
我在基于运算符提取子表达式时遇到了麻烦。如果我读一个运算符,我必须研究它的LHS和RHS,并验证它只对一个变量起作用,而不是对另一个子表达式起作用
有没有一种方法可以同时研究操作员的LHS和RHS
任何评论和建议都会非常有用首先,表达式中没有子表达式
a*b
。在对未分析输入的log
的调用中,会出现一个子项c/b*a
。但在Maple的语法中,它被解析成数学上等同于(c*a)/b
,而不是c/(b*a)
但你的问题还包含其他模糊性。让我们考虑几个例子:
restart;
expr1 := y = s + (a/b)*log(a+c/b*a);
c a
a ln(a + ---)
b
expr1 := y = s + -------------
b
expr2 := y = s + a*log(a+c/b*a)/b;
c a
a ln(a + ---)
b
expr2 := y = s + -------------
b
expr2 - expr1;
0 = 0
因此expr1
和expr2
在数学上是等价的。枫树甚至在内部保持着它们的结构不变。(您可以使用lprint
和dismoble
命令检查是否正确。)
因此,在解析输入之后,您似乎要求在这两种语言中识别a/b
,即使该术语在逐字输入中(解析之前)没有出现一致性。这本身并没有错,但我们需要知道这是你期望的一部分。如果要将a/b
识别为该值的候选子表达式,不管它是像expr1
还是expr2
那样输入的,则这是一个关键细节。如果这不是您的愿望,那么您将真的必须证明在解析后如何将它们彼此区分开来(因为它们可能解析为相同的东西,这取决于Maple会话中已经发生了什么!)
另外,你打算如何处理数学上等同于(a*s)/(b)
?是否需要返回所有可能的算术对的代码,例如a*s、a/b、s/b
?或者您只想要a*s
,或者只想要a/b
,或者只想要s/b
现在考虑另一个例子:
expr3 := a+c*a/b;
c a
expr3 := a + ---
b
normal(expr3);
a (b + c)
---------
b
虽然存储方式不同,但它们在数学上是等价的。根据您对可接受的“子表达式”的定义,您可能希望也可能不希望结果中出现a/b
、或c/b
、或b+c
我认为,至少在上述三个示例的模棱两可的情况下,您可能需要准确地解决您想要的问题,然后才能明智地解决您的问题。您可以尝试使用半文档化的
mtree
实用程序来创建一个可用于分析有效代码字符串(包括符号)的以及整个文件。以下是如何使用它:
tree = mtree('y = s + (a/b)*log((a+c)/(b*a));');
您可以使用它执行各种操作,例如将其转储到文本:
>> tree.dumptree
1 *<root>: EXPR: 1/03
2 *Arg: EQUALS: 1/03
3 *Left: ID: 1/01 (y)
4 *Right: PLUS: 1/07
5 *Left: CALL: 1/05
6 *Left: ID: 1/05 (s)
7 *Right: MUL: 1/14
8 *Left: PARENS: 1/09
9 *Arg: DIV: 1/11
10 *Left: CALL: 1/10
11 *Left: ID: 1/10 (a)
12 *Right: CALL: 1/12
13 *Left: ID: 1/12 (b)
14 *Right: CALL: 1/18
15 *Left: ID: 1/15 (log)
16 *Right: DIV: 1/24
17 *Left: PARENS: 1/19
18 *Arg: PLUS: 1/21
19 *Left: CALL: 1/20
20 *Left: ID: 1/20 (a)
21 *Right: CALL: 1/22
22 *Left: ID: 1/22 (c)
23 *Right: PARENS: 1/25
24 *Arg: MUL: 1/27
25 *Left: CALL: 1/26
26 *Left: ID: 1/26 (b)
27 *Right: CALL: 1/28
28 *Left: ID: 1/28 (a)
>tree.dumptree
1*:表达式:1/03
2*Arg:等于:1/03
3*左:ID:1/01(y)
4*右:加:1/07
5*左:电话:1/05
6*左:识别号:1/05(s)
7*右:MUL:1/14
8*左:附件:1/09
9*Arg:DIV:1/11
10*左:呼叫:1/10
11*左:ID:1/10(a)
12*右:呼叫:1/12
13*左:ID:1/12(b)
14*右:电话:1/18
15*左:ID:1/15(日志)
16*右:分区:1/24
17*左:巴黎:1/19
18*Arg:加上:1/21
19*左:呼叫:1/20
20*左:ID:1/20(a)
21*右侧:呼叫:1/22
22*左:ID:1/22(c)
23*右:巴黎:1/25
24*Arg:MUL:1/27
25*左:呼叫:1/26
26*左:ID:1/26(b)
27*右:电话:1/28
28*左:ID:1/28(a)
请注意,当您进行二进制操作(例如PLUS
或MUL
)时,它们后面跟着一条*左
和一条*右
行,其中包含操作数
查看
MATLAB\R20\toolbox\MATLAB\codetools\@mtree\mtree.m
了解有关如何处理这些对象的更多信息。这与您的,甚至更广泛的您的有什么不同?感觉就像你一直在问类似的问题,而没有添加任何可能有助于回答潜在问题的上下文。如果你一直问类似的问题,对任何人都没有效率。。。将问题限制在一种语言上也是有帮助的,因为语法、符号表达式的处理和解决方案都是特定于语言的。前面的问题是基于操作数的,但这个问题是基于算术运算符的子表达式。另外,在这个问题中,我的要求是只获取有效的表达式(在本例中是b*a和a/b)。剩下的子/表达式很复杂,我不感兴趣。我想你没有领会我的意思,提供上下文有助于更完整地回答问题。你可以问“我因为Y而被X困住了,帮我解Xa,Xb,Xc,…”,而不是“我因为Y而被X困住了,这里是一个例子,这是我所期望的,这是我被困住的地方”,你可以学到更多,得到更完整的答案。可选,但可能更容易。你也没有提到我关于不同语言的观点。是的,现在我明白你的意思了。谢谢,我会再加上几句,谢谢你,没有什么含糊不清的地方。你的解释很详细。我对我的问题稍加修改。现在,关于我需要什么,例如在expr3:a+ca/b中。我需要一个g