Extract complete argument and function name(s) from the Expression, (standard mathematical functions only) MAPLE

前端 未结 3 384
谎友^
谎友^ 2021-01-29 09:20

For expressions like

a1 := sin(1+a/b);
a2 := log(1+ a*b);
a3 := abs(a^2+b);

how can I get expressions of respective functions. For example

相关标签:
3条回答
  • 2021-01-29 09:48

    You can use the op() command, which breaks down expressions into their operands. For instance:

    f := sin(1+a/b);
    g := op(0,f); # sin
    h := op(1,f); # 1+a/b
    
    0 讨论(0)
  • 2021-01-29 09:54

    That's not complicated to construct. (More thoughts on that, below...)

    restart;
    
    W := (ee,nm::name) -> [op(map(`[]`@op,indets(ee,':-specfunc'(nm))))]:
    

    And now to test it,

    a1 := sin(1+a/b):
    a2 := log(1+ a*b):
    a3 := abs(a^2+b):
    
    W( a1, sin );
                           [[    a]]
                           [[1 + -]]
                           [[    b]]
    
    W( a2, ln );
                          [[a b + 1]]
    
    W( a3, abs );
                           [[ 2    ]]
                           [[a  + b]]
    

    Now a slightly longer example,

    foo := cos(1+a/b)/abs(a^2+b)
           +log(1+ a*b)*cos(s-v)
           +sin(c+d/r);
    
                  /    a\                                      
               cos|1 + -|                                      
                  \    b/                               /    d\
        foo := ---------- + ln(a b + 1) cos(s - v) + sin|c + -|
                | 2    |                                \    r/
                |a  + b|                                       
    
    W( foo, sin );
                           [[    d]]
                           [[c + -]]
                           [[    r]]
    
    W( foo, cos );
                       [[    a]         ]
                       [[1 + -], [s - v]]
                       [[    b]         ]
    
    W( foo, abs );
                           [[ 2    ]]
                           [[a  + b]]
    
    W( foo, ln );
                          [[a b + 1]]
    

    With no other context to judge by, I personally prefer to have the items above be returned within lists, to be able to handle them later more easily.

    But it looks even simpler, if one leaves out the encapsulating lists,

    Y := (ee,nm::name) -> op(map(op,indets(ee,':-specfunc'(nm)))):
    
    Y( foo, cos );
    
                              a       
                          1 + -, s - v
                              b       
    

    Now a few opinions. The reason that there is no dedicated command for doing precisely this is because there are so very many tasks in a similar vein. A programming language that is crammed full of hundreds of distinct commands to do too similar things can be awkward (or worse) to use.

    To use Maple effectively it helps to learn the basic building blocks very well. Those include at least things like,

    op, map, map[n], zip, select, remove, selectremove,
    table, indices, entries, type, indets, subsindets,
    normal, radnormal, simplify, evalc, evala, rationalize
    
    0 讨论(0)
  • 2021-01-29 09:58

    In your followup comment to another Answer you gave the further example of sin(log(abs(a+b))). I suspect that you want to be able to slice and dice even more complicated examples.

    You haven't really told use what your final goal is. Perhaps you're trying to build an expression tree. Or perhaps you're evenutally planning on doing something else with this analysis. It'd really help if you told us the final goal.

    Having said that, the following might be of some use to you.

    restart;
    
    ee := "sin(log(abs(a+b))) + sin(s+t) + abs(log(v+w))":
    
    P:=InertForm:-Parse(ee):
    
    lprint(P);
    
    
     `%+`(%sin(%log(%abs(`%+`(a,b)))),%sin(`%+`(s,t)),
          %abs(%log(`%+`(v,w))))
    

    It may be that the above inert form is something you can work with, for whatever your goal might be.

    indets(P, specfunc(name,`%+`));
    
                {a %+ b, s %+ t, v %+ w}
    
    indets(P, specfunc(anything,%abs));
    
           {%abs(a %+ b), %abs(%log(v %+ w))}
    
    indets(P, specfunc(specfunc(name,`%+`),%abs));
    
                    {%abs(a %+ b)}
    
    indets(P, specfunc(specfunc(name,`%+`),%log));
    
                    {%log(v %+ w)}
    

    Using a routine limke from my earlier Answer,

    W := (ee,nm) -> [op(map(`[]`@op,indets(ee,':-specfunc'(nm))))]:
    
    W( indets(P, specfunc(specfunc(name,`%+`),%log)), `%+` );
    
                       [[v, w]]
    
    W( indets(P, specfunc(specfunc(name,`%+`),%sin)), `%+` );
    
                       [[s, t]]
    
    W( indets(P, specfunc(specfunc(name,`%+`),%abs)), `%+` );
    
                       [[a, b]]
    

    There are other ways to get those last results (using something like W on an actual expression and not its inert form, say). I'm just trying to show you how you can do a bit more with it all.

    0 讨论(0)
提交回复
热议问题