问题
let the Symbolic expression is as below.
y = s + (a/b)*log((a+c)/(b*a)); %# it can be any type of expression
how can I get all possible sub-expressions with two variables and one operator between them.
subExpression1 = b*a;
subExpression2 = a/b;
I got stuck whlie extracting sub-expressions based on operator. if I read one operator I have to study its LHS and RHS and verify that it operates just on one variable but not a other subexpression.
Is there a way to study both LHS and RHS of a operator ??
any comments and suggestions would be very helpful
回答1:
Firstly, there is no subexpression a*b
in your expression. Inside the call to log
in your unparsed input there appears a subterm c/b*a
. But in Maple's syntax that gets parsed to something mathematically equivalent to (c*a)/b
and not c/(b*a)
.
But your question contains other ambiguity. Let's consider a few examples:
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
So the expr1
and expr2
are mathematically equivalent. Maple is even holding their structures the same, internally. (You can check that using both the lprint
and the dismantle
commands.)
So you appear to be asking for a/b
to be recognized in either, after parsing the input, even though that term does not appear indentically in the verbatim input (before parsing). That's not wrong, per se, but we'll need to know that it's part of your expectation. If a/b
is to be recognized as a candidate subpression of that value, regardless of whether it's entered like expr1
or expr2
, then that is a key detail. If that is not your desire then you will really have to justify how they could be distinguished from each other after parsing (since they may parse to the same thing, depending on what's occurred already in the Maple session!).
Also, how do you intend on handling something which is mathematically equivalent to (a*s)/(b)
? Do you want code that returns all possible arithmetic pairings, eg. a*s, a/b, s/b
? Or do you want just a*s
, or just a/b
, or just s/b
?
Now consider another example:
expr3 := a+c*a/b;
c a
expr3 := a + ---
b
normal(expr3);
a (b + c)
---------
b
Those are mathematically equivalent, though stored differently. Depending on your definition of acceptable "sub-expression" you may or may not want want a/b
, or c/b
, or b+c
, in your results.
I think that you'll probably need to resolve what precisely you want, in at least these three example's ambiguous situations above, before your question could be resolved sensibly.
回答2:
You can try the semi-documented mtree
utility to create a parse tree, which can be used to analyze valid code strings (including symbolics) as well as whole files. Here's how to use it:
tree = mtree('y = s + (a/b)*log((a+c)/(b*a));');
The you can do all sorts of things with it, like dump it to text:
>> 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)
Notice that when you have binary operations (e.g. PLUS
or MUL
) they are followed by a *Left
and a *Right
line which contains the operands.
Take a look inside MATLAB\R20###\toolbox\matlab\codetools\@mtree\mtree.m
for more information on what can be done with these objects.
来源:https://stackoverflow.com/questions/52382409/how-to-construct-sub-expressions-with-only-two-variables-and-one-arithmatic-oper