Предотвратить переупорядочение в производном выводе?

последний пост на Блог Wolfram Blog предлагает следующую функцию для более традиционного форматирования производных.

pdConv[f_] := 
 TraditionalForm[
  f /. Derivative[inds__][g_][vars__] :> 
    Apply[Defer[D[g[vars], ##]] &, 
     Transpose[{{vars}, {inds}}] /. {{var_, 0} :> 
        Sequence[], {var_, 1} :> {var}}]
 ]

Пример использования, Dt[d[x, a]] // pdConv дает:

введите здесь описание изображения

Не нарушая общих возможностей pdConv, может ли кто-нибудь изменить его, чтобы сохранить заданный порядок переменных и получить вывод, показанный ниже? (конечно, это чисто из эстетических соображений, чтобы человеку было легче следовать выводам)

введите здесь описание изображения

Я подозреваю, что это будет нетривиально реализовать --- если только кто-нибудь не знает волшебную опцию Global, которую можно временно переопределить в Block.

Для чего это стоит, эти вопросы SO могут быть связаны:


person telefunkenvf14    schedule 24.12.2011    source источник
comment
Интересный вопрос. Не могли бы вы быть немного более конкретным, когда вы говорите данный порядок [переменных]?   -  person Mr.Wizard    schedule 24.12.2011
comment
@Mr.Wizard - Чтобы уточнить, если f[b,a] является функцией, переданной в Dt, то я бы хотел, чтобы полное дифференцирование выводилось как Dt[b]*D[f,b] + Dt[a]* D[f,a] вместо сортировки вывода в Dt[a]*D[f,a] + Dt[b]*D[f,b]. (вы, ребята, кажется, поняли это ниже ... не хотели оставлять ваш вопрос висящим.)   -  person telefunkenvf14    schedule 24.12.2011


Ответы (3)


Вероятно, есть более чистый способ сделать s, но если это чисто для целей презентации, вы можете сделать что-то вроде

pdConv[f_, vv_] :=
 Module[{v},
  (HoldForm[
       Evaluate@
        TraditionalForm[((f /. Thread[vv -> #]) /. 
           Derivative[inds__][g_][vars__] :> 
            Apply[Defer[D[g[vars], ##]] &, 
             Transpose[{{vars}, {inds}}] /. {{var_, 0} :> 
                Sequence[], {var_, 1} :> {var}}])]] /. 
      Thread[# -> vv]) &@ Table[Unique[v], {Length[vv]}]]

Здесь дополнительный параметр vv представляет собой список переменных в f в том порядке, в котором вы хотите, чтобы частные производные отображались. Чтобы использовать эту функцию, вы должны сделать что-то вроде

pdConv[Dt[d[x, c]], {x, c}]

уравнения в правильном порядке

По сути, это решение временно заменяет список переменных vv списком фиктивных переменных, которые находятся в правильном лексикографическом порядке, применяет преобразование, а затем заменяет фиктивные переменные исходными переменными, сохраняя желаемый порядок путем переноса преобразованное выражение в HoldForm.

person Heike    schedule 24.12.2011
comment
@Mr.Wizard Думаю, все бывает впервые ;-) - person Heike; 24.12.2011
comment
Могу ли я позаимствовать вашу идею замены и реализовать ее в своем собственном стиле, или вы предпочитаете, чтобы я этого не делал? - person Mr.Wizard; 24.12.2011
comment
@Heike Я думаю, что ваша идея работает ... Идеей для улучшения было бы удержание функции ввода (через атрибуты) и использование уровня для автоматического определения порядка переменных. Тем не менее, я не уверен, что это испортит другие примеры, приведенные в исходном сообщении в блоге. - person telefunkenvf14; 24.12.2011
comment
@telefunken Я попытаюсь реализовать это, и оставлю вас играть с результатом. - person Mr.Wizard; 24.12.2011

Пересмотрено после знакомства с гораздо более совершенным методом Хайке. Надеюсь, не сломав.

ClearAll[pdConv]

pdConv[order_List][f_] :=
  With[{R = Thread[order -> Sort@order]},
    HoldForm@TraditionalForm@# /. Reverse[R, 2] &[
     f /. R /. Derivative[inds__][g_][vars__] :>
        (Defer@D[g[vars], ##] & @@ Pick[{vars}, {inds}, 1])]
  ]

Использовать:

Dt[d[x, a]] // pdConv[{x, a}]

Dt[d[x, a, c, b]] // pdConv[{x, a, c, b}]

Автоматический заказ для узкого корпуса:

ClearAll[pdConvAuto]
SetAttributes[pdConvAuto, HoldFirst]

pdConvAuto[f : Dt@_@syms__] :=
  With[{R = Thread[{syms} -> Sort@{syms}]},
    HoldForm@TraditionalForm@# /. Reverse[R, 2] &[
     f /. R /. Derivative[inds__][g_][vars__] :>
        (Defer@D[g[vars], ##] & @@ Pick[{vars}, {inds}, 1])]
  ]

Использовать:

Dt[d[x, a, c, b]] // pdConvAuto
person Mr.Wizard    schedule 24.12.2011
comment
Ты быстрый! Я поиграю с ним и отчитаюсь. Также можно проверить некоторые другие примеры из блога Wolfram (чтобы убедиться, что они все еще работают). - person telefunkenvf14; 24.12.2011

Я понял, что Dt[d[x, a, c, b]] уже дает упорядоченный вывод, только наоборот. Я, вероятно, неправильно понимаю ситуацию, но в некоторых случаях этого оказывается достаточно:

ClearAll[pdConv]

pdConv[f_] :=
 Apply[Plus, HoldForm@TraditionalForm@#, {2}] &[
  Reverse[List @@ f] /. Derivative[inds__][g_][vars__] :>
    (Defer@D[g[vars], ##] & @@ Pick[{vars}, {inds}, 1])
  ]

Dt[d[x, a, r, c, b]] // pdConv
person Mr.Wizard    schedule 24.12.2011