алгоритм нахождения производной

Я пишу программу на Python, и мне нужно найти производную функции (функция, выраженная в виде строки).

  • Например: x^2+3*x
  • Его производная: 2*x+3

Есть ли какие-нибудь доступные скрипты или есть что-то полезное, что вы можете мне подсказать?


person Dixtosa    schedule 22.11.2009    source источник
comment
@Gurdas Nijor: Производная - это уравнение, которое часто используется в исчислении для определения тангенса заданной точки в функции. en.wikipedia.org/wiki/Derivative   -  person Spoike    schedule 23.11.2009
comment
вы говорите о том же. Производная функции для любого заданного значения x даст наклон касательной. Преобразование этого в касательную функцию тривиально.   -  person Johannes Rudolph    schedule 23.11.2009


Ответы (10)


sympy делает это хорошо.

person Alex Martelli    schedule 22.11.2009
comment
Ссылка не работает? или 404-е издание ;) - person codeconscious; 03.08.2016
comment
Ваша ссылка не работает. Возможно, вы имели в виду эту ссылку или этот более подробный. - person Rory Daulton; 23.05.2017

Если вы ограничены полиномами (что, по-видимому, так и есть), в основном будет три шага:

  1. Разобрать входную строку в список коэффициентов до x^n
  2. Возьмите этот список коэффициентов и преобразуйте их в новый список коэффициентов в соответствии с правилами получения многочлена.
  3. Возьмите список коэффициентов для производной и создайте красивую строку, описывающую производную полиномиальную функцию.

Если вам нужно обрабатывать многочлены, такие как a*x^15125 + x^2 + c, использование dict для списка коэффициентов может иметь смысл, но требует немного больше внимания при выполнении итераций по этому списку.

person ndim    schedule 22.11.2009

Вы можете найти то, что ищете, в уже предоставленных ответах. Однако я хотел бы дать краткое объяснение того, как вычислять символьные производные.

Бизнес основан на перегрузке операторов и цепном правиле производных. Например, производная от v^n равна n*v^(n-1)dv/dx, верно? Итак, если у вас есть v=3*x и n=3, какой будет производная? Ответ: если f(x)=(3*x)^3, то производная:

f'(x)=3*(3*x)^2*(d/dx(3*x))=3*(3*x)^2*(3)=3^4*x^2

Цепное правило позволяет вам «связывать» операции: каждая отдельная производная проста, и вы просто «связываете» сложность. Другой пример, производная от u*v это v*du/dx+u*dv/dx, верно? Если вы получаете сложную функцию, вы просто связываете ее, скажем:

d/dx(x^3*sin(x))
u=x^3; v=sin(x)
du/dx=3*x^2; dv/dx=cos(x)
d/dx=v*du+u*dv

Как видите, дифференцирование — это всего лишь цепочка простых операций.

Теперь перегрузка оператора.

Если вы можете написать синтаксический анализатор (попробуйте Pyparsing), вы можете запросить его для оценки как функции, так и производной! Я сделал это (используя Flex/Bison) просто для удовольствия, и это довольно мощно. Чтобы вы поняли, производная вычисляется рекурсивно путем перегрузки соответствующего оператора и рекурсивного применения цепного правила, поэтому оценка "*" будет соответствовать u*v для значения функции и u*der(v)+v*der(u) для значения производной (попробуйте на C++, это тоже весело).

Так вот, я знаю, что вы не собираетесь писать свой собственный синтаксический анализатор - во что бы то ни стало используйте существующий код (посетите www.autodiff.org для автоматического различения кода Fortran и C/C++). Но всегда интересно узнать, как это работает.

Ваше здоровье,

Хуан

person Escualo    schedule 25.11.2009

Символическая дифференциация — впечатляющее введение в предмет — по крайней мере, для неспециалистов. как и я :) Код написан на C++ кстати.

person AraK    schedule 22.11.2009

Лучше поздно, чем никогда?

Я всегда выполнял символическую дифференциацию на любом языке, работая с деревом синтаксического анализа. Но недавно мне также стало известно о другом методе, использующем комплексные числа. .

Подход с использованием дерева синтаксического анализа состоит в переводе следующего крошечного кода Lisp на любой язык, который вам нравится:

(defun diff (s x)(cond
  ((eq s x) 1)
  ((atom s) 0)
  ((or (eq (car s) '+)(eq (car s) '-))(list (car s)
    (diff (cadr s) x)
    (diff (caddr s) x)
    ))
  ; ... and so on for multiplication, division, and basic functions
  ))

и после него с соответствующим упрощением, чтобы избавиться от добавления 0, умножения на 1 и т. д.

Но комплексный метод, хотя и является полностью числовым, обладает определенным волшебным качеством. Вместо того, чтобы программировать вычисление F с двойной точностью, сделайте это комплексно с двойной точностью. Затем, если вам нужна производная вычисления по переменной X, задайте для мнимой части X очень маленькое число h, например 1e-100. Затем выполните расчет и получите результат R. Теперь реальный (R) — это результат, который вы обычно получаете, а imag (R)/h = dF/dX с очень высокой точностью!

Как это работает? Возьмем случай умножения комплексных чисел:

(a+bi)(c+di) = ac + i(ad+bc) - bd

Теперь предположим, что все мнимые части равны нулю, за исключением того, что нам нужна производная по a. Мы устанавливаем b на очень маленькое число h. Теперь что мы получаем?

(a+hi)(c) = ac + hci

Таким образом, действительная часть этого числа равна ac, как и следовало ожидать, а мнимая часть, разделенная на h, равна c, которая является производной от ac по отношению к a.

Подобные рассуждения, по-видимому, применимы ко всем правилам дифференциации.

person Mike Dunlavey    schedule 17.05.2016

Поищите автоматическое дифференцирование. Существуют инструменты для Python. Кроме того, это.

person lhf    schedule 22.11.2009

Если вы думаете о написании программы дифференцирования с нуля, не используя в качестве помощи другие библиотеки, тогда алгоритм/подход к вычислению производной любого алгебраического уравнения я описал в мой блог будет полезен.

person Bikash Bishwokarma    schedule 23.05.2017

Вы можете попробовать создать класс, который будет строго представлять предел, а затем оценивать его для (f(x)-f(a))/(x-a), когда x приближается к a. Это должно дать довольно точное значение предела.

person SalmonKiller    schedule 26.11.2014

если вы используете строку в качестве входных данных, вы можете разделить отдельные термины, используя + или - char в качестве разделителя, что даст вам отдельные термины. Теперь вы можете использовать степенное правило для решения каждого термина, скажем, у вас есть x ^ 3, что с использованием степенного правила даст вам 3x ^ 2, или предположим, что у вас есть более сложный термин, например a/(x^3) или a(x^ -3), снова вы можете выделить другие переменные как константу, и теперь решение для x^-3 даст вам -3a/(x^2). Одного степенного правила должно быть достаточно, однако оно потребует широкого использования факторизации.

person amit kumar    schedule 31.01.2021

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

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

person Jack    schedule 22.11.2009