Упростите выражение
Блокноты MuPAD® будут демонтированы в будущем релизе. Используйте live скрипты MATLAB® вместо этого.
Live скрипты MATLAB поддерживают большую часть функциональности MuPAD, хотя существуют некоторые различия. Для получения дополнительной информации смотрите, Преобразовывают Notebook MuPAD в Live скрипты MATLAB.
Simplify(f
) Simplify(f
,Steps = numberOfSteps
) Simplify(f
,options
)
Simplify(f)
применяет переписывающие термин правила к f
и возвращает самое простое выражение, которое это может найти.
Методы поиска самого простого представления выражения отличаются для Simplify
и simplify
. Функция simplify
выполняет линейный поиск, пытающийся улучшить результат, возвращенный предыдущим шагом упрощения. Функция Simplify
использует результаты, возвращенные всеми предыдущими шагами упрощения (поиск по первому наилучшему совпадению). Функция simplify
быстрее. Функция Simplify
является медленнее, но более эффективной и более конфигурируемой.
Термин “самый простой” задан можно следующим образом. Один объект более прост, чем другой, если он имеет меньшую оценку. Если два объекта имеют ту же оценку, Simplify
выбирает более простой объект с помощью внутренней эвристики. Оценка является функцией, которая присваивает неотрицательный вещественный номер каждому объекту MuPAD®. Чтобы заменить оценку по умолчанию, используемую Simplify
, используйте опцию Valuation
. Simplify
использует оценку для поиска по первому наилучшему совпадению что касается определения лучшего результата в последнем шаге. Однако можно задать отдельный метод для итогового шага упрощения при помощи опции Criterion
.
Процесс упрощения состоит из шагов. На каждом шаге Simplify
выполняет один из следующих видов задач для a := f
или некоторых (ранее полученный) объект a
, эквивалентный f
. На каждом шаге Simplify
может произвести новые объекты, эквивалентные f
(результаты) или новые задачи сделать или оба:
'InitialStep' : Найдите все правила для a
. Функция Simplify
выполняет поиск всех правил для каждого нового объекта a
. Этот поиск не приводит ни к какому новому результату.
Перезапись шага: Примените одно правило к a
. Этот шаг может или привести к сбою или произвести эквивалентный объект как результат.
Шаг подвыражения: Выполните один шаг в упрощении операнда a
. Замените операнд на возвращенный результат (если существуют какие-либо результаты). Этот шаг может произвести новый эквивалентный объект.
Каждая открытая задача имеет приоритет, который определяет, что сделать затем. Упрощение останавливается в любом из следующих случаев:
Нет никаких более открытых задач.
Simplify
достиг ограничения по времени, заданного Seconds
.
Simplify
выполнил максимальное количество шагов упрощения, заданных Steps
.
Simplify
возвратил объект, заданный Goal
.
Simplify
всегда возвращает “самый простой” эквивалентный объект, найденный на всех шагах упрощения, если вы не задаете другой OutputType
.
Правила формируют конкретный доменный Rule
. Они состоят из шаблона (левая сторона), выражение (правая сторона) и опции.
MuPAD организует правила для Simplify
в основах правила. Можно изменить основу правила по умолчанию при помощи опции RuleBase
. Также можно задать собственный механизм выбора правила при помощи опции SelectRules
.
Как правило, Simplify
применяет выбранные правила к данному объекту a
в целом. Следующий случай является исключением из этого правила. Если шаблон правила и объекта a
является оба суммой или продуктом, то Simplify
применяет правило к каждой подсумме или промежуточному результату a
, который имеет то же количество операндов как шаблон.
При помощи опции ApplyRule
можно задать собственную функцию, которая применяет конкретное правило к конкретному объекту. В противном случае Simplify
использует метод по умолчанию.
Приложение правила к объекту a
перестало работать, если шаблон не соответствует (см. match
), объект a
. Производительность Simplify
строго зависит от количества успешных соответствий. Поэтому, если вы задаете свою собственную основу правила, она должна избавиться от несоответствия с правилами перед выбором правила.
Шаг упрощения для операнда работает как шаг упрощения над упрощением f
. Исключения следующие. Выполняя шаг упрощения для операнда, MuPAD не применяет определенные правила (см. детали о SelectRules
).
MuPAD определяет приоритеты открытых задач можно следующим образом. Приоритет выполнения начального шага для выражения зависит от оценки выражения. Приоритет выполнения шага упрощения на операнде зависит от отношения между полной оценкой выражения и оценкой операнда и приоритетом задачи самого высокого ранга в списке ожидающих выполнения задач операнда. Наконец, приоритет применения правила к выражению равняется приоритету правила, умноженного на оценку выражения.
Стратегия определяет приоритет правила. См. опцию Strategy
для деталей.
Simplify
никогда не использует симметрию математической эквивалентности выражений. Поэтому можно использовать Simplify
в качестве общей системы перезаписи.
Simplify
сопоставляет со списками, наборами и таблицами.
Для доменных элементов d
Simplify
может быть перегружен двумя способами. Во-первых, Simplify
использует слот d::dom::Simplify
. Если тот слот не существует, Simplify
использует d::dom::simplify
. Если слот, который использует Simplify
, не является списком, Simplify
вызывает слот и принимает результат как простой (даже если оценка не соглашается). В этом случае Simplify
не применяет никакие другие правила к d
. Однако Simplify
использует оценку, чтобы решить, должно ли это заменить доменный элемент, который происходит как операнд в другом объекте с его “упрощенной” версией. Если слот является списком, его записи должны быть правилами, и Simplify
применяет их согласно их приоритету.
Самый легкий способ использовать Simplify
состоит в том, чтобы принять все значения по умолчанию, и затем включить выражение, которое вы хотите упростить:
Simplify(sin(x)^2 + cos(x)^2)
По умолчанию Simplify
возвращает только одно выражение, которое функция рассматривает как самое простое. Чтобы возвратить список всех эквивалентных выражений, используйте опцию All
:
Simplify(sin(x)^2 + cos(x)^2, All)
Вывод предыдущего примера короток, потому что, как только simplifier находит 1
, это сразу останавливается. После этого simplifier не ищет другие эквивалентные выражения. Кроме того, simplifier отбрасывает эквивалентные выражения, которые значительно более сложны, чем лучшее выражение, найденное ранее. Можно выключить оба механизма:
Simplify(sin(x)^2 + cos(x)^2, All, Discard = FALSE, IsSimple = FALSE)
По умолчанию Simplify
использует оценку, которая способствует выражениям с меньшим количеством различных иррациональных подвыражений. Например, Simplify
принимает, что выражение, содержащее только sin(x)
или cos(x)
, более просто, чем выражение, содержащее обоих:
Simplify(cos(x)*sin(x))
Если вы берете length
в качестве меры по сложности для выражений, Simplify
возвращает другой результат:
Simplify(cos(x)*sin(x), Valuation = length)
Количество по умолчанию шагов равняется 100. Чтобы изменить максимальное количество возможных шагов упрощения, используйте опцию Steps
. Например, уменьшение (приводящий к ускорению) и увеличение (приводящий к, вероятно, лучшему упрощению) количество шагов упрощения:
f := ln(x) + ln(3) - ln(3*x) + (exp(x) - 1)/(exp(x/2) + 1): Simplify(f, Steps = 8), Simplify(f, Steps = 120)
delete f:
Для многих выражений количество по умолчанию шагов упрощения не позволяет simplifier находить хорошее упрощение:
Simplify(e^(a* x *(a + 1) + b2* y *(y + b2* x* y)))
Увеличение этого предела часто помогает:
Simplify(e^(a* x *(a + 1) + b2* y *(y + b2* x* y)), Steps=125)
По умолчанию функции упрощения не комбинируют логарифмы:
Simplify(ln(x^3 - 1) - ln(x - 1))
Используя опцию IgnoreAnalyticConstraints
, часто можно получать более короткие результаты:
Simplify(ln(x^3 - 1) - ln(x - 1), IgnoreAnalyticConstraints)
Можно написать то же выражение в различных системах координат. Например, используйте Декартовы и полярные координаты:
assume(x/r = cos(Symbol::theta)): assumeAlso(y/r = sin(Symbol::theta)): assumeAlso(r = sqrt(x^2+y^2)): x/sqrt(x^2+y^2) + I*y/sqrt(x^2+y^2) = exp(I*Symbol::theta); Simplify(%)
Следующее выражение эквивалентно exp(x)
:
a := -1/(sin(1/2*I*x)^2 + 4*sin(1/4*I*x)^4 - 4*sin(1/4*I*x)^2 + 1)*(sin(1/2*I*x)^2 - 4*I*sin(1/2*I*x)*sin(1/4*I*x)^2 + 2*I*sin(1/2*I*x) - 4*sin(1/4*I*x)^4 + 4*sin(1/4*I*x)^2 - 1)
Simplify
распознает эквивалентность a
и exp(x)
в 100 шагах. Чтобы показать, как функция доказывает эквивалентность на каждом шаге, используйте опцию OutputType
. Обратите внимание на то, что доказательством, возвращенным Simplify
, не является доказательство в строгом математическом смысле. Simplify
использует правила от основы правила по умолчанию:
Simplify(a, OutputType = "Proof")
Input was -(sin((x*I)/2)^2 - 4*sin((x*I)/2)*sin((x*I)/4)^2*I + 2*sin((x*I)/2)*I - \ 4*sin((x*I)/4)^4 + 4*sin((x*I)/4)^2 - 1)/(sin((x*I)/2)^2 + 4*sin((x*I)/4)^\ 4 - 4*sin((x*I)/4)^2 + 1) Applying the rule Simplify::combineSinCos gives cos(x*I) - sin(x*I)*I Applying the rule Simplify::expand gives cosh(x) + sinh(x) Applying the rule X -> rewrite(X, exp) gives exp(x) END OF PROOF
Также можно использовать Simplify
для экспериментов с формальными грамматиками, данными только несколькими правилами. В этом случае лучший подход не должен использовать основы правила, но использовать метод SelectRules
, который возвращает список всех правил. Следующий пример представляет общий ассоциативный оператор ?
. Пример вычисляет количество всех возможных размещений круглых скобок. Во-первых, задайте operator
, и затем присоедините его к функции, которая управляет ее выводом (см. funcenv
). Укажите, что единственное применимое правило является ассоциативным законом. В вызове Simplify
, определенного номер шагов к очень большому значению, чтобы выполнить полный поиск. Обратите внимание на то, что большинство грамматик производит бесконечно много слов и проводит бесконечное время, чтобы закончить полный поиск:
_f := funcenv(() -> procname(args())): operator("?", _f, Binary, 1000): R := Rule((X ? Y) ? Z, X ? (Y ? Z)): selectProc := () -> [R]: S := Simplify(u ? v ? x ? y ? z, Steps = 10^10, SelectRules = selectProc, All):
PRETTYPRINT := FALSE: print(Plain, S): PRETTYPRINT := TRUE:
[u ? (v ? (x ? (y ? z))), u ? (v ? ((x ? y) ? z)), u ? ((v ? (x ? y)) ? z)\ , u ? (((v ? x) ? y) ? z), u ? ((v ? x) ? (y ? z)), (u ? (v ? x)) ? (y ? z\ ), ((u ? v) ? x) ? (y ? z), (u ? v) ? (x ? (y ? z)), (u ? v) ? ((x ? y) ? \ z), (u ? (v ? (x ? y))) ? z, (u ? ((v ? x) ? y)) ? z, ((u ? (v ? x)) ? y) \ ? z, (((u ? v) ? x) ? y) ? z, ((u ? v) ? (x ? y)) ? z]
Существует 14 возможных способов поместить круглые скобки:
nops(S); delete fout, _f, R, S, selectProc: operator("?", Delete):
Если вы хотите задать больший ряд правил, лучший подход должен использовать вашу собственную основу правила. Классическим примером является дифференцирование. Несмотря на то, что эвристический поиск должен быть медленнее, чем простой рекурсивный алгоритм, этот пример подходит для демонстрации некоторых факторов эффективности. Запустите путем определения функциональной среды mydiff
, который ничего не делает:
mydiff := funcenv(mydiff): mydiff::type := "mydiff"
Цель этого определения состоит в том, чтобы показать, что виды MuPAD управляют в основах правила типами выражений, к которым MuPAD применяет те правила. Поэтому mydiff
получает свой собственный тип. Теперь, задайте основу правила Myrules
с обычными правилами дифференцирования. Не используйте дополнительные правила:
Myrules := newDomain("Myrules"): Myrules::mydiff := [Rule(mydiff(f, x), 0, {(f, x) -> not has(f, x)}), Rule(mydiff(x, x), 1), Rule(mydiff(x^n, x), n*x^(n - 1)), Rule(mydiff(f*g, x), f*mydiff(g, x) + g*mydiff(f, x)), Rule(mydiff(f + g, x), mydiff(f, x) + mydiff(g, x)) ]:
Эта основа правила работает на выражение x 2:
Simplify(mydiff(x^2, x), RuleBase = Myrules)
Однако основа правила не работает на следующее выражение:
Simplify(mydiff(x + 3, x), RuleBase = Myrules)
Попытайтесь улучшить ту основу правила. Как первый шаг, увеличьте число шагов упрощения. Увеличение числа шагов не помогает в этом случае:
Simplify(mydiff(x + 3, x), RuleBase = Myrules, Steps = 200)
Как второй шаг, более тщательно изучите по эквивалентным выражениям, возвращенным Simplify
. Иногда, Simplify
находит ожидаемый результат, но не возвращает его, потому что оценка ожидаемого результата выше, чем оценка некоторого другого эквивалентного выражения. Для выражения x + 3
функция Simplify
не находит ожидаемый результат:
l := Simplify(mydiff(x + 3, x), RuleBase = Myrules, All)
Обратите внимание на то, что производная 1 появляется в результате. Используйте опцию OutputType
, чтобы проверять, как Simplify
управляет третьим сроком l[3]
и как это доказывает эквивалентность ввода и вывода на каждом шаге:
Simplify(mydiff(x + 3, x), RuleBase = Myrules, Goal = l[3], OutputType = "Proof")
Input was mydiff(x + 3, x) Applying the rule mydiff(f*g, x) -> f*mydiff(g, x) + g*mydiff(f, x) gives (x + 3)*mydiff(1, x) + mydiff(x + 3, x) END OF PROOF
Теперь вы видите, что для каждого выражения f, необходимо задать правило для diffentiating продуктов потому что f = 1 f. Измените то правило:
(Myrules::mydiff)[4] := Rule(mydiff(f*g, x), f*mydiff(g, x) + g*mydiff(f, x), {(f, g) -> f <> 1 and g <> 1}):
Обновленная основа правила работает:
Simplify(mydiff(x + 3, x), RuleBase=Myrules, Remember=FALSE)
Используйте несколько опций, чтобы оптимизировать вызов Simplify
. Как первый шаг, измерьтесь, сколько шагов типичный пример делает прежде, чем возвратить ожидаемый выходной параметр:
Simplify(mydiff(5*x^4 + x^3 + x^2 + x + 1, x), RuleBase = Myrules, Steps = 2000, Goal = 20*x^3 + 3*x^2 + 2*x + 1, OutputType = "NumberOfSteps")
Избегайте приложения равенства f = f + 0. Выключите помнить механизм. Когда помнить механизм работает, Simplify
игнорирует изменения в основе правила:
Myrules::mydiff[5] := Rule(mydiff(f + g, x), mydiff(f, x) + mydiff(g, x), {(f, g) -> f <> 0 and g <> 0}): Simplify(mydiff(5*x^4 + x^3 + x^2 + x + 1, x), RuleBase = Myrules, Steps = 2000, Goal = 20*x^3 + 3*x^2 + 2*x + 1, OutputType = "NumberOfSteps", Remember = FALSE)
Затем, попытайтесь изменить критерии оценки. Например, используйте length
:
Simplify(mydiff(5*x^4 + x^3 + x^2 + x + 1, x), RuleBase = Myrules, Steps = 2000, Goal = 20*x^3 + 3*x^2 + 2*x + 1, OutputType = "NumberOfSteps", Valuation = length)
Чтобы оптимизировать вызов Simplify
, также можно задать собственную стратегию упрощения. Например, первое правило, кажется, обеспечивает очень полезное упрощение каждый раз, когда оно применяется. Поэтому присвойте высокий приоритет этому правилу путем предположения, что в среднем это правило упрощает свой вход до 0.03 из исходной сложности:
Myrules::mydiff[1] := subsop(Myrules::mydiff[1], 4 = table("MyStrategy" = 0.03)): Simplify(mydiff(5*x^4 + x^3 + x^2 + x + 1, x), RuleBase = Myrules, Steps = 3000, Goal = 20*x^3 + 3*x^2 + 2*x + 1, OutputType = "NumberOfSteps", Strategy = "MyStrategy")
При использовании оценки length
вы получаете следующий результат:
Simplify(mydiff(5*x^4 + x^3 + x^2 + x + 1, x), RuleBase = Myrules, Steps = 3000, Goal = 20*x^3 + 3*x^2 + 2*x + 1, OutputType = "NumberOfSteps", Strategy = "MyStrategy", Valuation = length)
Когда вы используете находящееся в matcher упрощение, большинство правил не соответствует к большинству объектов. Попытка совпадать со всеми правилами ко всем объектам производит много шагов перезаписи сбоя. Рекомендуемый подход должен отбросить эти провальные правила во время начального шага. Отбрасывание провальных правил сокращает число шагов. Это также увеличивает время выполнения на шаг небольшим количеством. Определение процедуры вместо списка правил может помочь вам отбросить провальные правила во время начального шага. Можно задать правила при помощи шаблона или процедуру в качестве их первого аргумента:
Myrules::mydiff := proc(df) begin [if not has(op(df, 1), op(df, 2)) then Rule(X -> 0) else case type(op(df, 1)) of "_plus" do Rule(X -> map(op(X, 1), mydiff, op(X, 2))); break of "_mult" do Rule(mydiff(f*g, x), f*mydiff(g, x) + g*mydiff(f, x)); break of "_power" do Rule(X -> op(X, [1,2])*op(X, [1,1])^(op(X, [1,2]) - 1)); break of DOM_IDENT do assert(op(df, 1) = op(df, 2)); Rule(X -> 1); break otherwise null() end_case end_if] end_proc: Simplify(mydiff(5*x^4 + x^3 + x^2 + x + 1, x), RuleBase = Myrules, Steps = 200, Goal = 20*x^3 + 3*x^2 + 2*x + 1, OutputType = "NumberOfSteps")
delete Myrules, mydiff:
|
Любой объект |
|
Когда вы используете опцию |
|
Опция, заданная как Задайте функциональный |
|
Опция, заданная как Задайте функциональный |
|
Опция, заданная как Задайте функциональный |
|
Опция, заданная как Если функция |
|
При использовании этой опции simplifier применяет следующие правила к выражениям:
При использовании этой опции функция |
|
Опция, заданная как Задайте функциональный |
|
Опция, заданная как Ограничьте усилие, которое инвестируют в один шаг упрощения. Здесь |
|
Опция, заданная как Задайте тип возвращаемого значения. Значение Даже если вы задаете выходной тип как Если вы устанавливаете эту опцию на Технически, доказательствами являются объекты того же типа как вывод |
|
Опция, заданная как Опция |
|
Опция, заданная как Базовый |
|
Опция, заданная как То, когда вы используете опцию |
|
Опция, заданная как Когда вы используете опцию Можно задать любую основу правила и использовать любой вид правила. Единственное ограничение - то, что |
|
Опция, заданная как Когда вы используете опцию |
|
Опция, заданная как Когда вы используете опцию |
|
Опция, заданная как Когда вы используете опцию По умолчанию Если конкретное правило не распознает стратегию Если вы используете Если |
|
Опция, заданная как Когда вы используете опцию Хорошая оценка является компромиссом между концепциями максимального типа и контекстно-свободным. Для контекстно-свободной оценки и оператор выражения и оценки операндов определяют оценку выражения. Для оценки максимального типа обычно оценка выражения равняется максимуму оценок его операндов. Типичным контекстно-свободным примером является MuPAD предлагает контекстно-свободной оценке |
Simplify
возвращает объект, математически эквивалентный входу. С опцией OutputType = "All"
функция Simplify
возвращает список всех эквивалентных объектов, найденных во время упрощения. С опцией OutputType = "NumberOfSteps"
функция возвращает положительное целое число. С опцией OutputType = "Proof"
функция возвращает строку, содержащую доказательство эквивалентности входа и результата.
f