如何从复杂的Expression Maple / Matlab构建只有两个变量和一个算术运算的子表达式?

时间:2018-09-18 08:40:39

标签: 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和RHS?

任何评论和建议都将非常有帮助

2 个答案:

答案 0 :(得分:2)

首先,您的表达式中没有子表达式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

因此expr1expr2在数学上是等效的。枫树甚至在内部保持其结构相同。 (您可以同时使用lprintdismantle命令进行检查。)

因此,在解析输入之后,您似乎都要求在{em>中识别a/b ,即使该词在逐字输入中没有相同地出现(在解析之前)。从本质上讲,这没错,但是我们需要知道这是您期望的一部分。如果将a/b识别为该值的候选表达式,而不管它是像expr1expr2那样输入的,那么这就是关键细节。如果这不是您的愿望,那么您将真的必须说明在解析后如何将它们彼此区分开来(因为它们可以解析为同一事物,具体取决于什么)已经在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/bc/bb+c

我认为,至少在上面这三个示例中模棱两可的情况下,您可能需要准确地解决自己想要的问题,然后才能明智地解决问题。

答案 1 :(得分:0)

您可以尝试使用未公开说明的mtree实用程序来创建parse tree,该实用程序可用于分析有效的代码字符串(包括符号)以及整个文件。使用方法如下:

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)

请注意,当您执行二进制操作(例如PLUSMUL)时,它们后面是*Left*Right行,其中包含操作数。

MATLAB\R20###\toolbox\matlab\codetools\@mtree\mtree.m中查看有关这些对象可以做什么的更多信息。