Производный калькулятор
-
04-10-2019 - |
Вопрос
Я заинтересован в создании калькулятора производных.Я ломал голову над решением проблемы, но так и не нашел правильного решения.Может у вас есть подсказка, как начать?Спасибо
Мне жаль!Я явно хочу провести символическую дифференциацию.
Допустим, у вас есть функция f(x) = x^3 + 2x^2 + x.
Я хочу отобразить производную, в данном случае f'(x) = 3x^2 + 4x + 1
Я хотел бы реализовать это в Objective-C для iPhone.
Решение
Я предполагаю, что вы пытаетесь найти точное производное функции. (Символическая дифференцировка)
Вам необходимо проанализировать математическое выражение и хранить отдельные операции в функции в древесной структуре.
Например, x + sin²(x)
будет храниться как +
операция, применяемая к выражению x
и а ^
(Экспонция) Операция sin(x)
а также 2
.
Затем вы можете рекурсивно различать дерево, применяя правила дифференциации каждому узлу. Например, +
узел станет u' + v'
, и а *
Узел станет uv' + vu'
.
Другие советы
Вам нужно вспомнить ваш исчисление. В основном вам нужны две вещи: таблица производных основных функций и правил того, как определить составные выражения (например, d(f + g)/dx = df/dx + dg/dx
). Затем возьмите разрывы анализатора и рекурсивно пойти другое дерево. (http://www.sosmath.com/ttable/derivative/derivative.html.)
Разбирать свою строку в S-выражение (Несмотря на то, что это обычно воспринимается в контексте Lisp, вы можете сделать эквивалентную вещь в значительной степени любым языком), проще всего с LEX / YACC или эквивалентом, затем напишите рекурсивное «выведенное» функцию. В диалекте Ocaml-ish, что-то вроде этого:
let rec derive var = function
| Const(_) -> Const(0)
| Var(x) -> if x = var then Const(1) else Deriv(Var(x), Var(var))
| Add(x, y) -> Add(derive var x, derive var y)
| Mul(a, b) -> Add(Mul(a, derive var b), Mul(derive var a, b))
...
(Если вы не знаете синтаксис OCAML - derive
является двухпараметрической рекурсивной функцией, с первым параметром именем переменной, а второе избитое в последовательных линиях; Например, если этот параметр является структурой формы Add(x, y)
, вернуть структуру Add
построен из двух полей, со значениями производных x
и происходит y
; и аналогично для других случаев того, что derive
может получить как параметр; _
В первом шаблоне означает «совпадение»)
После этого у вас может быть некоторая функция очистки, чтобы привести к приведению результирующего выражения (уменьшая фракции и т. Д.) Но это усложняется и не является необходимым для самого вывода (то есть то, что вы получаете без него, по-прежнему является правильным ответом).
Когда ваша преобразование S-EXP выполняется, восстановите результируемый S-EXP в строку, снова с рекурсивной функцией
Слакс уже описал процедуру символического дифференцирования.Я просто хотел бы добавить несколько вещей:
- Символьная математика — это в основном синтаксический анализ и преобразование деревьев.ANTLR — отличный инструмент для обоих.Я бы посоветовал начать с этой замечательной книги. Шаблоны реализации языка
- Существуют программы с открытым исходным кодом, которые делают то, что вы хотите (например.Максима).Анализ такой программы тоже может быть интересным (но, вероятно, будет легче понять, что происходит, если вы сначала попытаетесь написать ее самостоятельно).
- Вероятно, вам также нужно какое-то упрощение вывода.Например, просто применив основные правила производной к выражению
2 * x
даст2 + 0*x
.Это также можно сделать путем обработки дерева (например,путем преобразования0 * [...]
к0
и[...] + 0
к[...]
и так далее)
Для каких операций вы хотите вычислить производное? Если вы разрешите тригонометрические функции, такие как синус, косинус и касательные, они, вероятно, лучше всего хранятся в таблице, в то время как другие, такие как полиномы, могут быть намного проще сделать. Вы позволяете функциям иметь несколько входов, например, f (x, y), а не просто f (x)?
Полиномы в одной переменную были бы мое предложение, а затем рассмотреть возможность добавления в тригонометрических, логарифмических, экспоненциальных и других расширенных функций для вычисления производных, которые могут быть труднее.
Символическая дифференцировка над общими функциями (+, -, *, /, ^, SIN, COS и т. Д.) Игнорирование регионов, где функция или его производная не определена легко. Что сложно, возможно, осторожно, упрощает результат после этого.
Для выполнения дифференциации храните операции на дереве (или даже только в польском языке) и сделать таблицу производного каждой из элементарных операций. Затем неоднократно применяют правило цепи и элементарные производные вместе с установкой производной постоянной до 0. Это быстро и легко реализовать.