Получить математику для упрощения выражения с помощью другого уравнения

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

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

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

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

p=t/(t+f);

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

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

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

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

Ответы

Ответ 1

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

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)

EDIT: О, и знаете ли вы Eliminiate?

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

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

EDIT 2: Кроме того, в этом простом случае решение для K и t одновременно похоже на трюк:

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

Ответ 2

Что-то вдоль этих строк обсуждается в сообщении 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. Возможно, некоторые другие могут лучше соответствовать конкретному выражению (выражениям), которое вы хотите обработать.

--- изменить ---

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

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

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

--- конец редактирования ---

--- изменить 2 ---

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

Другая форма перезаписи терминов - синтаксическая замена с помощью сопоставления с образцом, и в других ответах обсуждается использование этого подхода. У этого есть другой недостаток, поскольку общность рассматриваемых моделей может стать ошеломляющей. Например, что делать с 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 ---

Даниэль Лихтблау

Ответ 3

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)

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