Получить математика, чтобы упростить выражение с другим уравнением - PullRequest
15 голосов
/ 10 ноября 2011

У меня очень сложное выражение mathematica, которое я хотел бы упростить, используя новый, возможно, безразмерный параметр.

Пример моего выражения:

K=a*b*t/((t+f)c*d);

(фактическое выражение чудовищно велико, тысячи символов). Я хотел бы заменить все вхождения выражения t / (t + f) на p

p=t/(t+f);

Цель здесь - найти замену, чтобы все t и f были заменены на p. В этом случае замена p является безразмерным параметром, поэтому она кажется хорошей заменой кандидата.

Я не смог понять, как это сделать в Mathematica (или, если это возможно). Я попробовал:

eq1= K==a*b*t/((t+f)c*d);
eq2= p==t/(t+f);
Solve[{eq1,eq2},K]

Не удивительно, это не работает. Если бы был способ заставить его решить для K в терминах p, a, b, c, d , это могло бы сработать, но я также не могу понять, как это сделать. Мысли?


Правка № 1 (11/10/11 - 1:30) [удалено для упрощения]

ОК, новый такт. Я взял p = ton / (ton + toff) и умножил p на несколько выражений. Я знаю, что р можно полностью устранить. Новое выражение (в терминах p):

testEQ = A B p + A^2 B p^2 + (A+B)p^3;

Затем я сделал замену на p и вызвал (нормальный) FullSimplify, давая мне это выражение.

testEQ2= (ton (B ton^2 + A^2 B ton (toff + ton) + 
   A (ton^2 + B (toff + ton)^2)))/(toff + ton)^3;

Наконец, я попробовал все приведенные ниже предложения, кроме последнего (пока не уверен, как это работает!)

Работает только опция исключения. Я думаю, что я попробую этот метод с этого момента. Спасибо.

EQ1 = a1 == (ton (B ton^2 + A^2 B ton (toff + ton) + 
        A (ton^2 + B (toff + ton)^2)))/(toff + ton)^3;
EQ2 = P1 == ton/(ton + toff);
Eliminate[{EQ1, EQ2}, {ton, toff}]

A B P1 + A^2 B P1^2 + (A + B) P1^3 == a1

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

Ответы [ 3 ]

11 голосов
/ 10 ноября 2011

Вы пробовали это?

K = a*b*t/((t + f) c*d);
Solve[p == t/(t + f), t]
 -> {{t -> -((f p)/(-1 + p))}}

Simplify[K /. %[[1]] ]
 -> (a b p)/(c d)

РЕДАКТИРОВАТЬ: О, и вы знаете о Eliminiate?

Eliminate[{eq1, eq2}, {t,f}]
 -> a b p == c d K && c != 0 && d != 0

Solve[%, K]
 -> {{K -> (a b p)/(c d)}}

РЕДАКТИРОВАТЬ 2: Кроме того, в этом простом случае решение для K и t одновременно, кажется, тоже помогает:

Solve[{eq1, eq2}, {K, t}]
 -> {{K -> (a b p)/(c d), t -> -((f p)/(-1 + p))}}
9 голосов
/ 10 ноября 2011

Что-то в этом духе обсуждается в посте MathGroup по адресу

http://forums.wolfram.com/mathgroup/archive/2009/Oct/msg00023.html

(я вижу, что в нем есть апокрифическое примечание, которое весьма актуально, по крайней мере для автора этого поста.)

Вот как это можно применить в приведенном выше примере.В целях сохранения самодостаточности я повторю код замены.

replacementFunction[expr_, rep_, vars_] := 
 Module[{num = Numerator[expr], den = Denominator[expr], 
   hed = Head[expr], base, expon}, 
  If[PolynomialQ[num, vars] && 
    PolynomialQ[den, vars] && ! NumberQ[den], 
   replacementFunction[num, rep, vars]/
    replacementFunction[den, rep, vars], 
   If[hed === Power && Length[expr] == 2, 
    base = replacementFunction[expr[[1]], rep, vars];
    expon = replacementFunction[expr[[2]], rep, vars];
    PolynomialReduce[base^expon, rep, vars][[2]], 
    If[Head[hed] === Symbol && 
      MemberQ[Attributes[hed], NumericFunction], 
     Map[replacementFunction[#, rep, vars] &, expr], 
     PolynomialReduce[expr, rep, vars][[2]]]]]]

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

kK = a*b*t/((t + f) c*d);
rep = Numerator[Together[p - t/(t + f)]];

Теперь мы можем вызвать замену.Мы перечислим переменные, которые мы хотим заменить, рассматривая 'p' как параметр.Таким образом, он будет упорядочен ниже, чем другие, что означает, что замены попытаются удалить их в пользу 'p'.

In[127]:= replacementFunction[kK, rep, {t, f}]
Out[127]= (a b p)/(c d)

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

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

--- edit ---

Идея, лежащая в основе этого, заключается в использовании PolynomialReduce длясделать алгебраическую замену.То есть мы не пытаемся сопоставить с образцом, а вместо этого используем полиномиальный метод канонизации.Но в целом мы не работаем с полиномиальными входами.Таким образом, мы рекурсивно применяем эту идею к аргументам PolynomialQ внутри функций NumericQ.

Более ранние версии этой идеи, наряду с некоторыми дополнительными пояснениями, можно найти в примечании, указанном ниже, а также в примечаниях, на которые оно ссылается (как этодля пояснительной рекурсии?).

http://forums.wolfram.com/mathgroup/archive/2006/Aug/msg00283.html

--- конец edit ---

--- edit 2 ---

Asнаблюдаемый в дикой природе, этот подход не всегда упрощает.Он выполняет алгебраическую замену, которая включает в себя понятие «упорядочения терминов» (грубо говоря, «какие вещи заменяются другими?») И, следовательно, простые переменные могут расширяться до более длинных выражений.

ДругойФорма переписывания термина - это синтаксическая замена через сопоставление с образцом, и другие ответы обсуждаются с использованием этого подхода.У этого есть другой недостаток, поскольку общность шаблонов для рассмотрения может стать подавляющей.Например, что делать с k ^ 2 / (w + p ^ 4) ^ 3, когда правилом является замена k / (w + p ^ 4) на q?(В частности, как мы узнаем, что это эквивалентно (k / (w + p ^ 4)) ^ 2 * 1 / (w + p ^ 4)?)

Результат должен бытьпредставление о том, что является желательным и какие методы могут быть осуществимы.Это, конечно, обычно зависит от конкретной проблемы.

Одна вещь, которая возникает, возможно, вы хотите найти и заменить все часто встречающиеся «сложные» выражения более простыми.Это называется устранением общего подвыражения (CSE).В Mathematica это можно сделать с помощью функции Experimental`OptimizeExpression [].Вот несколько ссылок на посты MathGroup, которые обсуждают это.

http://forums.wolfram.com/mathgroup/archive/2009/Jul/msg00138.html

http://forums.wolfram.com/mathgroup/archive/2007/Nov/msg00270.html

http://forums.wolfram.com/mathgroup/archive/2006/Sep/msg00300.html

http://forums.wolfram.com/mathgroup/archive/2005/Jan/msg00387.html

http://forums.wolfram.com/mathgroup/archive/2002/Jan/msg00369.html

Вот пример из одной из этих заметок.

InputForm[Experimental`OptimizeExpression[(3 + 3*a^2 + Sqrt[5 + 6*a + 5*a^2] +
      a*(4 + Sqrt[5 + 6*a + 5*a^2]))/6]]

Out[206]//InputForm=
Experimental`OptimizedExpression[Block[{Compile`$1, Compile`$3, Compile`$4, 
   Compile`$5, Compile`$6}, Compile`$1 = a^2; Compile`$3 = 6*a; 
   Compile`$4 = 5*Compile`$1; Compile`$5 = 5 + Compile`$3 + Compile`$4; 
   Compile`$6 = Sqrt[Compile`$5]; (3 + 3*Compile`$1 + Compile`$6 + 
     a*(4 + Compile`$6))/6]]

--- end edit 2 ---

Daniel Lichtblau

7 голосов
/ 10 ноября 2011
K = a*b*t/((t+f)c*d);

FullSimplify[ K, 
 TransformationFunctions -> {(# /. t/(t + f) -> p &), Automatic}]
(a b p) / (c d)

Исправлено обновление для отображения другого метода:

EQ1 = a1 == (ton (B ton^2 + A^2 B ton (toff + ton) + 
        A (ton^2 + B (toff + ton)^2)))/(toff + ton)^3;

f = # /. ton + toff -> ton/p &;

FullSimplify[f @ EQ1]
a1 == p (A B + A^2 B p + (A + B) p^2)

Я не знаю, имеет ли это какое-то значение на данный момент, но, надеюсь, по крайней мере, это работает.

...