Я на днях процитировал записную книжку библиотеки для связанного вопроса.
http://library.wolfram.com/infocenter/Conferences/325/
Как расширить арифметику дифференциальных операторов в математике
Я напишу какой-нибудь соответствующий код. Сначала я упомяну (снова), что я собираюсь определить и работать со своим собственным некоммутативным оператором, чтобы избежать головной боли при сопоставлении с образцом от встроенного NonCommulativeMultiply. Также я буду использовать [...] вместо Subscript [a, ...] для простоты записи ascii и вставки / вывода Mathematica.
Мы будем классифицировать некоторые «базовые» сущности как скаляры или переменные, последние являются вещами, которые имеют ограничения на коммутацию. Я не рассматриваю это настолько далеко, насколько это возможно, и я лишь определяю скаляры как довольно очевидные "не переменные".
variableQ[x_] := MemberQ[{a, b, c, d}, Head[x]]
scalarQ[x_?NumericQ] := True
scalarQ[x_[a_]^n_. /; !variableQ[x[a]]] := True
scalarQ[_] := False
ncTimes[] := 1
ncTimes[a_] := a
ncTimes[a___, ncTimes[b___, c___], d___] := ncTimes[a, b, c, d]
ncTimes[a___, x_ + y_, b___] := ncTimes[a, x, b] + ncTimes[a, y, b]
ncTimes[a___, n_?scalarQ*c_, b___] := n*ncTimes[a, c, b]
ncTimes[a___, n_?scalarQ, b___] := n*ncTimes[a, b]
ncTimes[a___, x_[i_Integer]^m_., x_[i_]^n_., b___] /;
variableQ[x[i]] := ncTimes[a, x[i]^(m + n), b]
ncTimes[a___, x_[i_Integer]^m_., y_[j_Integer]^n_., b___] /;
variableQ[x[i]] && ! OrderedQ[{x, y}] := (* !!! *)
ncTimes[a, y[j]^n, x[i]^m, b]
Я буду использовать вашу форму ввода только с небольшими изменениями, поэтому мы преобразуем ** выражения для использования ncTimes.
Unprotect[NonCommutativeMultiply];
NonCommutativeMultiply[a___] := ncTimes[a]
Вот ваш пример.
In[124]:=
a[-4] ** b[1] ** a[-4] ** b[-4] ** a[1] ** c[-4] ** c[1] ** c[5]
Out[124]= ncTimes[a[-4]^2, a[1], b[1], b[-4], c[-4], c[1], c[5]]
Преимущество этого, казалось бы, трудоемкого метода состоит в том, что вы можете легко определить коммутаторы. Например, мы уже (неявно) применили это правило при формулировании приведенных выше правил.
commutator[x_[a_], y_[b_]] /; x =!= y || !VariableQ[x[a] := 0
Как правило, если у вас есть правила коммутатора, такие как
ncTimes[a[j],a[i]] == ncTimes[a[i],a[i]]+(j-i)*a[i]
всякий раз, когда j> i, вы можете канонизировать, скажем, поставив [i] перед a [j] во всех выражениях. Для этого вам необходимо изменить правило, помеченное ( !!! ), чтобы учесть такие коммутаторы.
Я должен добавить, что я ни в каком смысле не полностью протестировал приведенный выше код.
Даниэль Лихтблау
Wolfram Research