Производный калькулятор

Я заинтересован в создании производного калькулятора. Я ломал голову над решением проблемы, но я не нашел правильного решения вообще. Может у вас есть подсказка, как начать? Спасибо

Мне жаль! Я явно хочу провести символическую дифференциацию.

Допустим, у вас есть функция f(x) = x^3 + 2x^2 + x

Я хочу отобразить производную, в этом случае f'(x) = 3x^2 + 4x + 1

Я хотел бы реализовать это в target-c для iPhone.

6 ответов

Решение

Я предполагаю, что вы пытаетесь найти точную производную функции. (Символическая дифференциация)

Вам необходимо проанализировать математическое выражение и сохранить отдельные операции в функции в древовидной структуре.

Например, x + sin²(x) будет храниться как + операция, примененная к выражению x и ^ (возведение в степень) операция sin(x) а также 2,

Затем вы можете рекурсивно дифференцировать дерево, применяя правила дифференцирования к каждому узлу. Например, + узел станет u' + v'и * узел станет uv' + vu',

Разобрать вашу строку в 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 в строковую форму, снова с помощью рекурсивной функции.

Вы должны помнить свое исчисление. в основном вам нужны две вещи: таблица производных базовых функций и правила получения производных выражений (например, d(f + g)/dx = df/dx + dg/dx). Затем возьмите парсер выражений и рекурсивно перейдите к другому дереву. ( http://www.sosmath.com/tables/derivative/derivative.html)

SLaks уже описал процедуру символьного дифференцирования. Я просто хотел бы добавить несколько вещей:

  • Символическая математика - это в основном разбор и преобразование дерева. ANTLR - отличный инструмент для обоих. Я бы предложил начать с этой замечательной книги.
  • Существуют программы с открытым исходным кодом, которые делают то, что вы хотите (например, Maxima). Рассмотрение такой программы также может быть интересным (но, вероятно, легче понять, что происходит, если вы сначала попытаетесь написать ее самостоятельно)
  • Возможно, вам также нужно какое-то упрощение для вывода. Например, просто применяя основные производные правила к выражению 2 * x даст 2 + 0*x, Это также может быть сделано путем обработки дерева (например, путем преобразования 0 * [...] в 0 а также [...] + 0 в [...] и так далее)

Символьное дифференцирование по общим функциям (+, -, *, /, ^, sin, cos и т. Д.) Игнорировать области, где функция или ее производная не определены, легко. Что сложно, возможно, нелогично, так это упростить результат.

Чтобы провести дифференцирование, сохраните операции в дереве (или даже просто в польской записи) и составьте таблицу производной каждой из элементарных операций. Затем неоднократно применяйте правило цепочки и элементарные производные вместе с установкой производной константы на 0. Это быстро и легко реализовать.

Для каких операций вы хотите вычислить производную? Если вы разрешите тригонометрические функции, такие как синус, косинус и тангенс, их, вероятно, лучше всего хранить в таблице, тогда как другие, такие как полиномы, могут быть намного проще. Вы разрешаете функциям иметь несколько входов, например, f(x,y), а не просто f(x)?

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

Другие вопросы по тегам