Онлайн калькулятор производные высших порядков: Калькулятор производных любого порядка

Аналитическое вычисление производной функции на языке Scala / Хабр

Введение

Данный алгоритм реализован на языке Scala, характерной особенностью которого является использование case-классов, так удачно подходящих для написания алгоритма дифференцирования. В этой статье планируется описать лишь часть программы, содержащей алгоритм нахождения производной, поскольку разработка парсера для математических выражений это другая большая тема,
заслуживающая отдельной статьи


Подготовка

Сначала опишем структуру данных, в которой будет храниться исходная математическая функция. Опишем трейт MathAST:

sealed trait MathAST

И его наследников:

sealed trait SingleToken extends MathAST{
	val a: MathAST
}
sealed trait DoubleToken extends MathAST{
	val a: MathAST
	val b: MathAST
}
sealed trait LeafToken extends MathAST

SingleToken будет реализовывать case-классы унарных операторов, таких как sin(a), -a, ln(a) и т.

b и т.д.
LeafToken — «листья» дерева, т.е. константы, переменные и зарезервированные имена констант (число Пи и экспонента).

Опишем классы/объекты операторов и токенов:

case object Pi extends LeafToken
case object Exponenta extends LeafToken
case class Sin(override val a: MathAST) extends SingleToken
case class Cos(override val a: MathAST) extends SingleToken
…
case class Mul(override val a: MathAST, override val b: MathAST) extends DoubleToken
case class Add(override val a: MathAST, override val b: MathAST) extends DoubleToken
…
case class Differentiate(f: MathAST, dx: Variable) extends MathAST
case class Variable(name: String) extends LeafToken
case class Constant(value: BigDecimal) extends LeafToken

Обратите внимание на класс Differentiate, он имеет особую сигнатуру: f – исходная функция, dx – переменная, по которой происходит дифференцирование.

Теперь есть все, чтобы представить математическую функцию в виде дерева вычислений, для примера возьмем функцию: , которая примет вид:

Mul(Constant(BigDecimal(2)), Pow(x, Constant(BigDecimal(2)))

Конечно, чтобы получить дерево-выражение из обычной строки, введенной пользователем, нужно написать парсер, но, как было упомянуто выше, это уже другая тема. Скажу лишь что в программе используется самодельный парсер, наследующий трейт Parsers из пакета scala.util.parsing.combinator.


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

В основе которого лежат правила дифференцирования и таблица производных.

Опишем рекурсивную функцию, которая и будет преобразовывать исходную математическую функцию в результирующую функцию-производную:

def differentiate(f: MathAST)(implicit dx: String): MathAST

Аргумент dx, содержащий имя переменной (по которой происходит дифференцирование) помечен как неявный (

implicit), это позволит не передавать ее в рекурсивные вызовы, пусть этим занимается компилятор.

На вход рекурсивной функции подается выражение — исходная функция f(x) (в формате MathAST), возвращаемое значение — функция-производная в том же формате.

Примечание 1: Выражение может быть бинарным, унарным или токеном.
Примечание 2: Оператором может быть один из: «+», «-», «^», «*», «/», «abs», «sin», «cos», «tg», «ctg», «ln», «arcsin», «arccos», «arctg», «arcctg», «(», «)».
Примечание 3: Входные и выходные данные представлены в формате MathAST — дерево-выражение.


Общий алгоритм

В общем виде алгоритм слишком абстрактный, поэтому дальше разберем его подробнее.


  1. Рекурсивная функция получает на вход данные и используя сопоставление с образцом (pattern-matching) выполняет необходимые действия, в зависимости от типа данных.
  2. Функция высчитывает производную для входного выражения и возвращает выражение-результат. Может получиться, что аргументы a и/или b оказались не константой и не переменной, а сложной функцией u(x),
    тогда понадобится рекурсивно посчитать еще и производную u’(x), т.е. вернуть [ differentiate(u(x)) ] — перейти к шагу 1 с новыми данными — u(x).
  3. Если данные не корректны вернуть сообщение об ошибке.

Детали принципа работы и связь с математическими абстракциями

Функция приняла на вход данные — выражение-функцию, которую следует обработать в соответствии с правилами дифференцирования


Если бинарное выражение

Бинарные выражения помечены трейтом DoubleToken. »):

case Add(a, b) => Add(differentiate(a), differentiate(b))
case Sub(a, b) => Sub(differentiate(a), differentiate(b))
…

  1. Если оператор «+»: вернуть [ differentiate(a) + differentiate(b) ].
  2. Если оператор «-»: вернуть [ differentiate(a) — differentiate(b) ].
  3. Если оператор «*»: Умножение представляет из себя более сложный случай, операнды a и b могут быть константами или переменными (всего 4 комбинации: u(x)*c, u(x)*v(x), c*c, c*u(x)).
    Функция анализирует какой из 4 вариантов попался и возвращает выражение используя правило дифференцирования № 1, № 3, и №5,
    если один из операндов – сложная функция. Например: если a = u(x), а b = v(x), то вернуть [ differentiate(a) * b + a * differentiate(b)) ].
    Приватный метод isDependsOnVar проверяет, зависит ли подвыражение от переменной, по которой производится дифференцирование. c, c=const Constant(BigDecimal(0)) }else Add(Mul(differentiate(a), b), Mul(a, differentiate(b))) }
    Если унарное выражение

    Классы SingleToken обрабатываются следующим образом:

    case e: SingleToken =>
    val d = e match {
    	case Sin(x) => Cos(x)
    	case Cos(x) => Usub(Sin(x))
    	case Tg(x) => Div(Constant(BigDecimal(1)), Pow(Cos(x), Constant(BigDecimal(2))))
    	…
    }
    if (isLeaf(e.a)) d else Mul(d, differentiate(e.a))

    Оператор проверяется на соответствие одному из доступных операторов («sin», «-», «cos», …)
    Для примера, оператор «sin»: вернуть [ cos(a) ], если a = x, если же a — сложная функция u(x), то вернуть [ cos(a) * differentiate(a) ].

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

    Отдельно следует рассмотреть оператор abs — модуль, поскольку его нет в таблице.

    Приватный метод isLeaf выясняет сложная функция или нет, в первом случае нужно вернуть текущий результат умноженный на производную вложенной функции, а во втором просто вернуть текущий результат.

    Если один токен

    Речь идет о переменной или константе

    case Variable(a) => if (a == dx) Constant(BigDecimal(1)) else Constant(BigDecimal(0))
    case Constant(a) => Constant(BigDecimal(0))
    case Pi | Exponenta => Constant(BigDecimal(0))
    case _ => throw new AbstractEvaluateException("Differentiate: Wrong input data")

    1. Введены некорректные данные, вывести сообщение об ошибке и завершить работу.
    2. Если переменная (по которой осуществляется дифференцирование, например x), вернуть [ 1 ].
    3. Если константа, вернуть [ 0 ].

    Напоследок добавим строку:

    case Differentiate(_f, _dx) => differentiate(_f)(_dx.name)

    Это на случай, если внутри функции есть вложенная производная, т. c, c=const Constant(BigDecimal(0)) }else Add(Mul(differentiate(a), b), Mul(a, differentiate(b))) } case e: SingleToken => val d = e match { case Sin(x) => Cos(x) case Cos(x) => Usub(Sin(x)) case Tg(x) => Div(Constant(BigDecimal(1)), Pow(Cos(x), Constant(BigDecimal(2)))) case Ctg(x) => Usub(Div(Constant(BigDecimal(1)), Pow(Sin(x), Constant(BigDecimal(2))))) case Abs(x) => Div(x, Abs(x)) case Ln(x) => Div(Constant(BigDecimal(1)), x) case Sqrt(x) => Div(Constant(BigDecimal(1)), Mul(Constant(BigDecimal(2)), Sqrt(x))) case Usub(x) => Usub(differentiate(x)) case Arcsin(x) => Div(Constant(BigDecimal(1)), Sqrt(Sub(Constant(BigDecimal(1)), Pow(x, Constant(BigDecimal(2)))))) case Arccos(x) => Usub(Div(Constant(BigDecimal(1)), Sqrt(Sub(Constant(BigDecimal(1)), Pow(x, Constant(BigDecimal(2))))))) case Arctg(x) => Div(Constant(BigDecimal(1)), Sub(Constant(BigDecimal(1)), Pow(x, Constant(BigDecimal(2))))) case Arcctg(x) => Usub(Div(Constant(BigDecimal(1)), Sub(Constant(BigDecimal(1)), Pow(x, Constant(BigDecimal(2)))))) case _ => throw new AbstractEvaluateException(«Differentiate: Unknown unary operator») } if (isLeaf(e.

    a)) d else Mul(d, differentiate(e.a)) case Variable(a) => if (a == dx) Constant(BigDecimal(1)) else Constant(BigDecimal(0)) case Constant(a) => Constant(BigDecimal(0)) case Pi | Exponenta => Constant(BigDecimal(0)) case _ => throw new AbstractEvaluateException(«Differentiate: Wrong input data») } private def isLeaf(e: MathAST): Boolean = e match { case Variable(_) | Constant(_) => true case Pi | Exponenta => true case _ => false } private def isDependsOnVar(tree: MathAST)(implicit dx: String): Boolean = tree match{ case e: DoubleToken => (e.a match { case Variable(name) => if(name == dx) true else false case _ => isDependsOnVar(e.a) })||(e.b match { case Variable(name) => if(name == dx) true else false case _ => isDependsOnVar(e.b) }) case e: SingleToken => isDependsOnVar(e.a) case Variable(name) => if(name == dx) true else false case _ => false } }

    Заключение

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


    Список литературы


    • Математический портал «mathprofi.ru» mathprofi.ru/slozhnye_proizvodnye_logarifmicheskaja_proizvodnaja.html
    • Odersky M. «Programming in Scala (second edition)»
    • Хостманн К. «Scala для нетерпеливых»

    Уравнение второго порядка онлайн

    Решение уравнений

    В дифференциальных уравнениях (ДУ) второго порядка обязательно есть вторая производная у», но отсутствуют производные высших порядков.

    Различают два типа линейных дифференциальных уравнений (ДУ) 2-го порядка с постоянными коэффициентами: однородные и неоднородные.

    Однородное ДУ имеет вид: у» + ру’ + qу = 0. В правой части уравнения всегда будет 0, р, q — числа.

    Неоднородное ДУ имеет следующий вид: у» + ру’ + qу = f (х), где р, q — постоянные числа, в правой части уравнения — функция f (х), которая зависит только от х. Наиболее простой случай — f (х) является числом, кроме 0.

    Решить дифференциальное уравнение, значит, найти все решения, удовлетворяющие этому уравнению.

    Чтобы решить однородное уравнение 2-го порядка, нужно вначале составить характеристическое уравнение. Для этого заменим первую производную «лямбдой», а вместо у ничего не запишем. В результате получим обычное квадратное уравнение вида: λ2 + рλ + q = 0.

    Далее находим корни уравнения. Здесь возможны 3 варианта.

    1 вариант. Дискриминант (D) больше 0, тогда характеристическое уравнение λ2 + рλ + q = 0 имеет 2 разных действительных корня (λ1, λ2).

    Общее решение ДУ принимает следующий вид: у = С1еλ1

    х + С2еλ2х1, С2 — произвольные числа).

    При λ1 = 0 общее решение уравнения упрощается: у = С1 + С2еλ2х.

    2 вариант. Дискриминант равен 0, тогда характеристическое уравнение имеет 2 равных действительных корня. В этом случае общее решение однородного уравнения имеет вид: у = С1еλ1х + С2хееλ1х. Т.к λ1 = λ2, в формулу можно поставить λ2.
    Если оба корня равны 0, получим общее решение уравнения: у = С1е + С2 = С1 + С2x.

    3 вариант. Дискриминант меньше 0, уравнение λ2 + рλ + q = 0 имеет сопряженные комплексные корни: λ1 = а — bi, λ2

    = а + bi.
    Общее решение уравнения будет иметь такой вид: у = еах • (С1соs Вх + С2sinВх).

    Чтобы решить неоднородное уравнение у» + ру’ + qу = f (х), нужно:
    1. записать соответствующее однородное уравнение, обнулив правую часть неоднородного уравнения: у» + ру’ + qу = 0 и найти его общее решение.
    2. способом подбора найти частное решение неоднородного уравнения.
    3. составить общее решение неоднородного уравнения.

    Ax2 + Bx + C = 0
    x2 +x + = 0
    X1 =X2 =

    Предыдущая Уравнение окружности

    Следующая Нелинейные уравнения

    Калькулятор неявного дифференцирования с шагами

    Калькулятор неявного дифференцирования найдет первую и вторую производные неявной функции, рассматривая $$$y$$$ как функцию от $$$x$$$ или $$$x$$ $ в зависимости от $$$y$$$ с показанными шагами. {3} = 2 x y\right)$$$. 9{2}{\left(x \right)} \frac{d}{dx} \left(y{\left(x \right)}\right)$$$.

    Дифференцировать правую часть уравнения.

    Применить постоянное кратное правило $$$\frac{d}{dx} \left(c f{\left(x \right)}\right) = c \frac{d}{dx} \left(f{ \left(x \right)}\right)$$$ с $$$c = 2$$$ и $$$f{\left(x \right)} = x y{\left(x \right)}$ $$:

    $${\color{red}\left(\frac{d}{dx} \left(2 x y{\left(x\right)}\right)\right)} = {\color {red}\left(2 \frac{d}{dx} \left(x y{\left(x \right)}\right)\right)}$$

    Применить правило произведения $$$\frac{d}{dx} \left(f{\left(x\right)} g{\left(x \right)}\right) = \frac{d} {dx} \ влево (е {\ влево (х \ вправо)} \ вправо) г {\ влево (х \ вправо)} + f {\ влево (х \ вправо)} \ гидроразрыва {d} {dx} \ влево (g {\ left (x \ right)} \ right) $ $ $ с $ $ $ f {\ left (x \ right)} = x $ $ $ and $ $ $ g {\ left (x \ right)} = y {\ left (x \ right)} $ $ $:

    $ $ 2 {\ color {red} \ left (\ frac {d} {dx} \ left (x y {\ left (x \ right)} \ справа) \ справа)} знак равно 2 {\ цвет {красный} \ влево (\ гидроразрыва {d} {dx} \ влево (х \ вправо) у {\ влево (х \ вправо)} + х \ гидроразрыва {d} {dx} \left(y{\left(x \right)}\right)\right)}$$ 9{n — 1}$$$ с $$$n = 1$$$, другими словами, $$$\frac{d}{dx} \left(x\right) = 1$$$:

    $ $ 2 х \ гидроразрыва {d} {dx} \ влево (у {\ влево (х \ вправо)} \ вправо) + 2 у {\ влево (х \ вправо)} {\ цвет {красный} \ влево (\ гидроразрыва {d}{dx} \left(x\right)\right)} = 2 x \frac{d}{dx} \left(y{\left(x \right)}\right) + 2 y{\left (x \right)} {\color{red}\left(1\right)}$$

    Таким образом, $$$\frac{d}{dx} \left(2 x y{\left(x \right) }\right) = 2 x \frac{d}{dx} \left(y{\left(x \right)}\right) + 2 y{\left(x \right)}$$$. {2} \frac{dy}{dx} = 2 x \frac{dy}{dx } + 2 у$$$. 9{2}}$$$A

    Исчисление I — Производные высшего порядка

    Показать мобильное уведомление Показать все примечания Скрыть все примечания

    Уведомление для мобильных устройств

    Похоже, вы используете устройство с «узкой» шириной экрана ( т. е. вы, вероятно, используете мобильный телефон). Из-за характера математики на этом сайте лучше всего просматривать в ландшафтном режиме. Если ваше устройство не находится в ландшафтном режиме, многие уравнения будут отображаться сбоку вашего устройства (должна быть возможность прокрутки, чтобы увидеть их), а некоторые пункты меню будут обрезаны из-за узкой ширины экрана.

    Раздел 3.

    3} \ влево ( {5t} \ вправо) \ конец {выравнивание *} \] 94}}}\конец{выравнивание*}\]

    Это нормально. Однако хотелось бы, чтобы в ответе не было производных. Как правило, мы не возражаем против наличия \(x\) и/или \(y\) в ответе при неявном дифференцировании, но нам действительно не нравятся производные в ответе. Однако мы можем избавиться от производной, признав, что знаем, что такое первая производная, и подставив ее во второе уравнение производной. Это дает 94}}}\конец{выравнивание*}\]

    Теперь, когда мы нашли некоторые производные более высокого порядка, нам, вероятно, следует поговорить об интерпретации второй производной.

    Если положение объекта задано как \(s\left( t \right)\), мы знаем, что скорость является первой производной положения.

    \[v\влево( т \вправо) = s’\влево( т \вправо)\]

    Ускорение объекта является первой производной скорости, но поскольку это первая производная функции положения, мы также можем рассматривать ускорение как вторую производную функции положения.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *