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