Как определить функцию, которая коммутирует с D в Mathematica - PullRequest
3 голосов
/ 25 марта 2011

Я хотел бы реализовать оператор f, который коммутирует с дифференцированием D.

Unprotect[D];
D[f[y___], x] := f[D[y, x]];
Protect[D];

D[f[Sin[x]], x]
D[f[Sin[x]] + 1, x]

К сожалению, этот код дает два разных результата

f[Cos[x]] (* as expected *)
Cos[x] f´[Sin[x]] (* cannot explain *)

Я хотел бы знать, что происходит и как исправить правило замены, чтобы второе выражение также оценивалось в f[Cos[x]].

Обновление. Решение 1 Следующее решение, по-видимому, помогает переопределить оператор D (хотя я совсем близко не понимаю полностью мой собственный код).

PartialDerivative[x_, x_] := 1; 

PartialDerivative[c_, x_] := 0 /; FreeQ[c, x]; 

PartialDerivative[f_ConditionalExpectation, x_] := 
  ConditionalExpectation[PartialDerivative[f, x]];

PartialDerivative[(f_)[g__], x_] := Module[{i, n, p}, 
        n = Length[SequenceHold[g]]; 
        Sum[
          p = ConstantArray[0, n]; p[[i]] = 1; 
          ((Derivative[##1][f] & ) @@ p)[g]*
              PartialDerivative[SequenceHold[g][[i]], x], {i, 1, n}]];

Я был бы признателен, если бы кто-то более опытный мог взглянуть на код и сказать мне, подходит ли этот подход.

1 Ответ

7 голосов
/ 25 марта 2011

Шаблоны сопоставляются синтаксически, а не семантически.Для встроенных функций, если вы переопределяете их, и если ваши шаблоны не совпадают, используются встроенные правила (определения).Чтобы увидеть, будет ли шаблон соответствовать или почему он не соответствует, FullForm часто бывает полезным.Таким образом, мы видим:

In[26]:= FullForm[HoldForm[D[f[Sin[x]]+1,x]]]
Out[26]//FullForm= HoldForm[D[Plus[f[Sin[x]],1],x]]

Ваше определение действует только тогда, когда у вас есть f [ _ ] внутри D, тогда как здесь у вас есть D[Plus[f[..],1],x].Таким образом, ваше определение не совпадает, и тогда используется встроенное.Вот один из способов расширить его, чтобы охватить этот случай:

Unprotect[D];
D[f[y___], x_] := f[D[y, x]];
D[HoldPattern[Plus[left___, a_f, right___]], x_] := 
    D[Plus[left], x] + D[a, x] + D[Plus[right], x];
Protect[D];

Теперь все будет работать как положено.Однако обратите внимание, что переопределение IMO встроенных функций, таких как D, таким способом является плохой практикой, и ее следует избегать.Во-первых, вышеприведенное решение, вероятно, также не является надежным, и вы можете добавить еще много правил, чтобы оно работало во всех случаях.Кроме того, как правило, лучше избегать переопределения встроенных функций, если вы можете (одна из причин заключается в том, что это может привести к некоторым очень тонким ошибкам, поскольку некоторые другие системные функции могут использовать ту, которую вы переопределили, и у вас нет контролянад ним).Вместо этого я бы реализовал свою собственную функцию дифференциации.Это не интеграция, это относительно просто сделать, и вы не подвергаете опасности функционирование любой другой системы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...