如何从复杂表达式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