LINUX.ORG.RU

Maxima: дифференцирование сложных функций

 


0

2
(%i1) depends(l,[u,v]);
(%o1)                              [l(u, v)]
(%i2) u(x,y):=x^2-y^2;
                                          2    2
(%o2)                         u(x, y) := x  - y
(%i3) v(x,y):=2*x*y;
(%o3)                          v(x, y) := 2 x y
(%i4) diff(l,x);
(%o4)                                  0
(%i5) diff(l(u,v),x);
(%o5)                                  0
(%i6)  depends([u,v],[x,y]);
(%o6)                         [u(x, y), v(x, y)]
(%i7) diff(l(u,v),x);
                                 d
(%o7)                            -- (l(u, v))
                                 dx
(%i8) diff(l,x);
                                 dl dv   dl du
(%o8)                            -- -- + -- --
                                 dv dx   du dx
(%i9) diff(l,x,2);
           2         2         2               2         2            2
       dl d v   dv  d l dv    d l  du    du   d l  dv   d l du    dl d u
(%o9)  -- --- + -- (--- -- + ----- --) + -- (----- -- + --- --) + -- ---
       dv   2   dx    2 dx   du dv dx    dx  du dv dx     2 dx    du   2
          dx        dv                                  du           dx
(%i10) 

Что сделать чтобы maxima сосчитала %o9 с дифференцированием известных функций?

★★★★★

Ответ на: комментарий от alpha

Что-то не работает. Может maxima недогоняет, что x не какой-то символ а именно первый аргумент функций u и v?

ados ★★★★★
() автор топика

В (%o9) символы u и v в двух разных ролях выступают: (1) как функции (например, 'diff(u,x,1)) и (2) как «значки», которые показывают как надо дифференцировать функцию, например 'diff(l,u,1) означает взять первую производную по первому аргумену функции l.

При подстановке надо различать эти роли. Вот так можно подставить u и v везде кроме чётных аргументов diff. Другими словами, вот тут не надо подставлять: diff(l, u, 1, v, 2).

maplist_if_index(fun, lst, pr):= block([out: []],
  if not listp(lst) then error("the second argument of maplist_if_index should be a list"),
  for i thru length(lst) do if pr(i) then out: cons(fun(part(lst, i)), out) else out: cons(part(lst, i), out),
  reverse(out));

force_list(el):=if listp(el) then el else [el];

subst_but_diff([arg]):= block([e],
  if length(arg)=2 then (e: second(arg),
    for pair in force_list(first(arg)) do e: subst_but_diff_one(rhs(pair), lhs(pair), e),
    e)
  else if length(arg)=3 then apply('subst_but_diff_one, arg)
  else error("wrong number of arguments given to subst_but_diff"));

subst_but_diff_one(a, b, expr):= block([e], local(subst_but_diff_one_local),
  define(subst_but_diff_one_local(e), buildq([a, b],
  if mapatom(e) then subst(a, b, e)
  else if nounify(part(e, 0))=nounify(diff) then
  apply(diff, 
    maplist_if_index('subst_but_diff_one_local, args(e), lambda([q], mod(q, 2)#0)))
  else map('subst_but_diff_one_local, e))),
  subst_but_diff_one_local(expr));

depends(l,[u,v])$
depends([u,v],[x,y])$

expr: diff(l, x, 2)$
subst_but_diff([u=x^2-y^2, v=2*x*y], expr);

Вывод:

(%i41) expr: diff(l, x, 2)$
(%i42) subst_but_diff([u=x^2-y^2, v=2*x*y], expr);
                 2          2                 2          2
                d l        d l               d l        d l        dl
(%o42)   2 y (2 --- y + 2 ----- x) + 2 x (2 ----- y + 2 --- x) + 2 --
                  2       du dv             du dv         2        du
                dv                                      du

vital303
()
Ответ на: комментарий от vital303

Другой способ это заменить u и v только в производных:

maplist_if_index(fun, lst, pr):= block([out: []],
  if not listp(lst) then error("the second argument of maplist_if_index should be a list"),
  for i thru length(lst) do if pr(i) then out: cons(fun(part(lst, i)), out) else out: cons(part(lst, i), out),
  reverse(out));

subst_in_diff([darg]):= block([e, expr, other, subst_local], local(subst_local),
  expr: last(darg),
  other: rest(darg, -1),
  define(subst_local(e),  buildq([other], apply('subst, endcons(e, other)))),
  subst(nounify(diff)=lambda([[arg]],
      apply(diff,
        maplist_if_index(subst_local, arg, lambda([q], q=1)))),
    expr));

depends(l,[u,v]);
depends([u,v],[x,y]);

expr: diff(l, x, 2);
subst_in_diff([u=x^2-y^2, v=2*x*y], expr);
subst_in_diff([u=x^2-y^2, v=2*x*y], u*diff(u, x)*diff(l, u));

Вывод:

(%i14) expr: diff(l, x, 2);
           2         2         2               2         2            2
       dl d v   dv  d l dv    d l  du    du   d l  dv   d l du    dl d u
(%o14) -- --- + -- (--- -- + ----- --) + -- (----- -- + --- --) + -- ---
       dv   2   dx    2 dx   du dv dx    dx  du dv dx     2 dx    du   2
          dx        dv                                  du           dx
(%i15) subst_in_diff([u=x^2-y^2, v=2*x*y], expr);
                 2          2                 2          2
                d l        d l               d l        d l        dl
(%o15)   2 y (2 --- y + 2 ----- x) + 2 x (2 ----- y + 2 --- x) + 2 --
                  2       du dv             du dv         2        du
                dv                                      du
(%i16) subst_in_diff([u=x^2-y^2, v=2*x*y], u*diff(u, x)*diff(l, u));
                                     dl
(%o16)                             2 -- u x
                                     du

В (%o16) u не заменилась.

vital303
()
Ответ на: комментарий от vital303

Ещё один способ это пакет pdiff и явно указать зависимости.

load("pdiff");

expr: diff(l(u(x, y), v(x, y)), x, 2)$
ev(expr, u(x,y):=x^2-y^2, v(x,y):=2*x*y);
(%i10) ev(expr, u(x,y):=x^2-y^2, v(x,y):=2*x*y);
                         2    2                        2    2
(%o10) 2 x (2 x l      (x  - y , 2 x y) + 2 y l      (x  - y , 2 x y))
                 (2, 0)                        (1, 1)
                     2    2                        2    2
 + 2 y (2 x l      (x  - y , 2 x y) + 2 y l      (x  - y , 2 x y))
             (1, 1)                        (0, 2)
              2    2
 + 2 l      (x  - y , 2 x y)
      (1, 0)
vital303
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.