Вопрос

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

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

Допустим, у вас есть функция 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. Это быстро и легко реализовать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top