Извлечение полных аргументов и имен функций из выражения (только для стандартных математических функций) MAPLE - PullRequest
0 голосов
/ 20 сентября 2018

Для выражений типа

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

как я могу получить выражения соответствующих функций.Например,

someCommand(a1)  # should get an output 1+a/b
someCommand(a2)  # should get an output 1+a*b
someCommand(a3)  # should get an output a^2+b

Я пытался получить связанные темы из документации клена, но, к сожалению, не смог получить точно.

отредактировано: Также, как можно получить список (в последовательности)используемых функций

let

a :=sin(log(abs(a+b)));# functions can be of more than two
someCommand(a) # have to return [{sin, log, abs}, a+b]

Ответы [ 3 ]

0 голосов
/ 20 сентября 2018

Это не сложно построить.(Больше мыслей по этому поводу, ниже ...)

restart;

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

А теперь, чтобы проверить это,

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]]

Теперь немного более длинный пример,

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]]

Не имея другого контекста, по которому я могу судить, я лично предпочитаю, чтобы вышеперечисленные элементы возвращались в списки, чтобы иметь возможность обрабатывать их позже легче.

Но это выглядит еще проще, если не учитывать инкапсулирующие списки.

Y := (ee,nm::name) -> op(map(op,indets(ee,':-specfunc'(nm)))):

Y( foo, cos );

                          a       
                      1 + -, s - v
                          b       

Теперь несколько мнений.Причина, по которой не существует выделенной команды для выполнения точно , заключается в том, что в аналогичном ключе очень много задач.Язык программирования, который полон сотен различных команд для выполнения слишком похожих задач, может быть неудобным (или даже хуже) для использования.

Для эффективного использования Maple это помогает очень хорошо выучить основные строительные блоки.К ним относятся, по крайней мере, такие вещи, как,

op, map, map[n], zip, select, remove, selectremove,
table, indices, entries, type, indets, subsindets,
normal, radnormal, simplify, evalc, evala, rationalize
0 голосов
/ 20 сентября 2018

В своем последующем комментарии к другому ответу вы привели еще один пример sin(log(abs(a+b))).Я подозреваю, что вы хотите иметь возможность нарезать и нарезать кубиками еще более сложные примеры.

Вы на самом деле не сказали использовать, какова ваша конечная цель.Возможно, вы пытаетесь построить дерево выражений .Или, возможно, вы даже планируете сделать что-то еще с этим анализом.Было бы действительно помочь, если бы вы сказали нам конечную цель.

Сказав это, вам может пригодиться следующее.

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))))

Это можетбудь то, что вышеупомянутая инертная форма - это то, с чем ты можешь работать, какой бы ни была твоя цель.

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)}

Используя рутинный лимк из моего предыдущего Ответа,

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]]

Есть и другиеспособы получения этих последних результатов (например, используя что-то вроде W для реального выражения, а не его инертной формы).Я просто пытаюсь показать вам, как вы можете сделать больше со всем этим.

0 голосов
/ 20 сентября 2018

Вы можете использовать команду op(), которая разбивает выражения на их операнды.Например:

f := sin(1+a/b);
g := op(0,f); # sin
h := op(1,f); # 1+a/b
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...