Производный калькулятор - PullRequest
4 голосов
/ 25 мая 2010

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

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

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

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

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

Ответы [ 6 ]

6 голосов
/ 25 мая 2010

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

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

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

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

4 голосов
/ 25 мая 2010

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

4 голосов
/ 25 мая 2010

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

2 голосов
/ 25 мая 2010

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

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

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

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

1 голос
/ 25 мая 2010

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

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

...