Spaces:
Sleeping
Sleeping
| .. _calculus: | |
| ========== | |
| Calculus | |
| ========== | |
| This section covers how to do basic calculus tasks such as derivatives, | |
| integrals, limits, and series expansions in SymPy. If you are not familiar | |
| with the math of any part of this section, you may safely skip it. | |
| >>> from sympy import * | |
| >>> x, y, z = symbols('x y z') | |
| >>> init_printing(use_unicode=True) | |
| .. _tutorial-derivatives: | |
| Derivatives | |
| =========== | |
| To take derivatives, use the :func:`~sympy.core.function.diff` function. | |
| >>> diff(cos(x), x) | |
| -sin(x) | |
| >>> diff(exp(x**2), x) | |
| โ 2โ | |
| โx โ | |
| 2โ xโ โฏ | |
| can take multiple derivatives at once. To | |
| take multiple derivatives, pass the variable as many times as you wish to | |
| following find the third derivative of `x^4`. | |
| >>> diff(x**4, x, x, x) | |
| 24โ x | |
| >>> diff(x**4, x, 3) | |
| 24โ x | |
| You can also take derivatives with respect to many variables at once. Just | |
| pass each derivative in order, using the same syntax as for single variable | |
| derivatives. For example, each of the following will compute | |
| `\frac{\partial^7}{\partial x\partial y^2\partial z^4} e^{x y z}`. | |
| >>> expr = exp(x*y*z) | |
| >>> diff(expr, x, y, y, z, z, z, z) | |
| 3 2 โ 3 3 3 2 2 2 โ xโ yโ z | |
| x โ y โ โx โ y โ z + 14โ x โ y โ z + 52โ xโ yโ z + 48โ โ โฏ | |
| >>> diff(expr, x, y, 2, z, 4) | |
| 3 2 โ 3 3 3 2 2 2 โ xโ yโ z | |
| x โ y โ โx โ y โ z + 14โ x โ y โ z + 52โ xโ yโ z + 48โ โ โฏ | |
| >>> diff(expr, x, y, y, z, 4) | |
| 3 2 โ 3 3 3 2 2 2 โ xโ yโ z | |
| x โ y โ โx โ y โ z + 14โ x โ y โ z + 52โ xโ yโ z + 48โ โ โฏ | |
| can also be called as a method. The two ways | |
| of calling :func:`~sympy.core.function.diff` are exactly the same, and are | |
| provided only for convenience. | |
| >>> expr.diff(x, y, y, z, 4) | |
| 3 2 โ 3 3 3 2 2 2 โ xโ yโ z | |
| x โ y โ โx โ y โ z + 14โ x โ y โ z + 52โ xโ yโ z + 48โ โ โฏ | |
| To create an unevaluated derivative, use the ``Derivative`` class. It has the | |
| same syntax as :func:`~sympy.core.function.diff`. | |
| >>> deriv = Derivative(expr, x, y, y, z, 4) | |
| >>> deriv | |
| 7 | |
| โ โ xโ yโ zโ | |
| โโโโโโโโโโโโฏ โ | |
| 4 2 | |
| โz โy โx | |
| To evaluate an unevaluated derivative, use the | |
| method. | |
| >>> deriv.doit() | |
| 3 2 โ 3 3 3 2 2 2 โ xโ yโ z | |
| x โ y โ โx โ y โ z + 14โ x โ y โ z + 52โ xโ yโ z + 48โ โ โฏ | |
| These unevaluated objects are useful for delaying the evaluation of the | |
| derivative, or for printing purposes. They are also used when SymPy does not | |
| know how to compute the derivative of an expression (for example, if it | |
| contains an undefined function, which are described in the :ref:`Solving | |
| Differential Equations <tutorial-dsolve>` section). | |
| Derivatives of unspecified order can be created using tuple ``(x, n)`` where | |
| ``n`` is the order of the derivative with respect to ``x``. | |
| >>> m, n, a, b = symbols('m n a b') | |
| >>> expr = (a*x + b)**m | |
| >>> expr.diff((x, n)) | |
| n | |
| โ โ mโ | |
| โโโโ(aโ x + b) โ | |
| n | |
| โx | |
| Integrals | |
| ========= | |
| To compute an integral, use the :func:`~sympy.integrals.integrals.integrate` | |
| function. There are two kinds of integrals, definite and indefinite. To | |
| compute an indefinite integral, that is, an antiderivative, or primitive, just | |
| pass the variable after the expression. | |
| >>> integrate(cos(x), x) | |
| sin(x) | |
| Note that SymPy does not include the constant of integration. If you want it, | |
| you can add one yourself, or rephrase your problem as a differential equation | |
| and use :func:`~sympy.solvers.ode.dsolve` to solve it, which does add the | |
| constant (see :ref:`tutorial-dsolve`). | |
| .. sidebar:: Quick Tip | |
| `\infty` in SymPy is ``oo`` (that's the lowercase letter "oh" twice). This | |
| is because ``oo`` looks like `\infty`, and is easy to type. | |
| To compute a definite integral, pass the argument ``(integration_variable, | |
| lower_limit, upper_limit)``. For example, to compute | |
| .. math:: | |
| \int_0^\infty e^{-x}\,dx, | |
| we would do | |
| >>> integrate(exp(-x), (x, 0, oo)) | |
| 1 | |
| As with indefinite integrals, you can pass multiple limit tuples to perform a | |
| multiple integral. For example, to compute | |
| .. math:: | |
| \int_{-\infty}^{\infty}\int_{-\infty}^{\infty} e^{- x^{2} - y^{2}}\, dx\, dy, | |
| do | |
| >>> integrate(exp(-x**2 - y**2), (x, -oo, oo), (y, -oo, oo)) | |
| ฯ | |
| If :func:`~sympy.integrals.integrals.integrate` is unable to compute an | |
| integral, it returns an unevaluated ``Integral`` object. | |
| >>> expr = integrate(x**x, x) | |
| >>> print(expr) | |
| Integral(x**x, x) | |
| >>> expr | |
| โ | |
| โฎ x | |
| โฎ x dx | |
| โก | |
| As with ``Derivative``, you can create an unevaluated integral using | |
| ``Integral``. To later evaluate this integral, call | |
| >>> expr = Integral(log(x)**2, x) | |
| >>> expr | |
| โ | |
| โฎ 2 | |
| โฎ log (x) dx | |
| โก | |
| >>> expr.doit() | |
| 2 | |
| xโ log (x) - 2โ xโ log(x) + 2โ x | |
| uses powerful algorithms that are | |
| always improving to compute both definite and indefinite integrals, including | |
| heuristic pattern matching type algorithms, a partial implementation of the | |
| `Risch algorithm <https://en.wikipedia.org/wiki/Risch_algorithm>`_, and an | |
| algorithm using | |
| `Meijer G-functions <https://en.wikipedia.org/wiki/Meijer_g-function>`_ that is | |
| useful for computing integrals in terms of special functions, especially | |
| definite integrals. Here is a sampling of some of the power of | |
| >>> integ = Integral((x**4 + x**2*exp(x) - x**2 - 2*x*exp(x) - 2*x - | |
| ... exp(x))*exp(x)/((x - 1)**2*(x + 1)**2*(exp(x) + 1)), x) | |
| >>> integ | |
| โ | |
| โฎ โ 4 2 x 2 x xโ x | |
| โฎ โx + x โ โฏ - x - 2โ xโ โฏ - 2โ x - โฏ โ โ โฏ | |
| โฎ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ dx | |
| โฎ 2 2 โ x โ | |
| โฎ (x - 1) โ (x + 1) โ โโฏ + 1โ | |
| โก | |
| >>> integ.doit() | |
| x | |
| โ x โ โฏ | |
| logโโฏ + 1โ + โโโโโโ | |
| 2 | |
| x - 1 | |
| >>> integ = Integral(sin(x**2), x) | |
| >>> integ | |
| โ | |
| โฎ โ 2โ | |
| โฎ sinโx โ dx | |
| โก | |
| >>> integ.doit() | |
| โโ2โ xโ | |
| 3โ โ2โ โฯโ Sโโโโโโโ ฮ(3/4) | |
| โ โฯ โ | |
| โโโโโโโโโโโโโโโโโโโโโโ | |
| 8โ ฮ(7/4) | |
| >>> integ = Integral(x**y*exp(-x), (x, 0, oo)) | |
| >>> integ | |
| โ | |
| โ | |
| โฎ y -x | |
| โฎ x โ โฏ dx | |
| โก | |
| 0 | |
| >>> integ.doit() | |
| โง ฮ(y + 1) for re(y) > -1 | |
| โช | |
| โชโ | |
| โชโ | |
| โจโฎ y -x | |
| โชโฎ x โ โฏ dx otherwise | |
| โชโก | |
| โช0 | |
| โฉ | |
| This last example returned a ``Piecewise`` expression because the integral | |
| does not converge unless `\Re(y) > -1.` | |
| Numeric Integration | |
| =================== | |
| Numeric integration is a method employed in mathematical analysis to estimate | |
| the definite integral of a function across a simplified range. SymPy not only | |
| facilitates symbolic integration but also provides support for | |
| numeric integration. It leverages the precision capabilities of the ``mpmath`` | |
| library to enhance the accuracy of numeric integration calculations. | |
| >>> from sympy import Integral, Symbol, sqrt | |
| >>> x = Symbol('x') | |
| >>> integral = Integral(sqrt(2)*x, (x, 0, 1)) | |
| >>> integral | |
| 1 | |
| โ | |
| โฎ โ2โ x dx | |
| โก | |
| 0 | |
| >>> integral.evalf() | |
| 0.707106781186548 | |
| To compute the integral with a specified precision: | |
| >>> integral.evalf(50) | |
| 0.70710678118654752440084436210484903928483593768847 | |
| Numeric integration becomes a viable approach in situations where symbolic | |
| integration is impractical or impossible. This method allows for the | |
| computation of integrals through numerical techniques, even when dealing with | |
| infinite intervals or integrands: | |
| >>> Integral(exp(-(x ** 2)), (x, -oo, oo)).evalf() | |
| 1.77245385090552 | |
| >>> Integral(1 / sqrt(x), (x, 0, 1)).evalf() | |
| 2.00000000000000 | |
| Limits | |
| ====== | |
| SymPy can compute symbolic limits with the :func:`~sympy.core.expr.Expr.limit` | |
| function. The syntax to compute | |
| .. math:: | |
| \lim_{x\to x_0} f(x) | |
| is ``limit(f(x), x, x0)``. | |
| >>> limit(sin(x)/x, x, 0) | |
| 1 | |
| should be used instead of | |
| whenever the point of evaluation is a | |
| singularity. Even though SymPy has objects to represent `\infty`, using them | |
| for evaluation is not reliable because they do not keep track of things like | |
| rate of growth. Also, things like `\infty - \infty` and | |
| `\frac{\infty}{\infty}` return `\mathrm{nan}` (not-a-number). For example | |
| >>> expr = x**2/exp(x) | |
| >>> expr.subs(x, oo) | |
| nan | |
| >>> limit(expr, x, oo) | |
| 0 | |
| Like ``Derivative`` and ``Integral``, :func:`~sympy.core.expr.Expr.limit` | |
| has an unevaluated counterpart, ``Limit``. To evaluate it, use | |
| >>> expr = Limit((cos(x) - 1)/x, x, 0) | |
| >>> expr | |
| โcos(x) - 1โ | |
| lim โโโโโโโโโโโโ | |
| xโโ0โบโ x โ | |
| >>> expr.doit() | |
| 0 | |
| To evaluate a limit at one side only, pass ``'+'`` or ``'-'`` as a fourth | |
| argument to :func:`~sympy.core.expr.Expr.limit`. For example, to compute | |
| .. math:: | |
| \lim_{x\to 0^+}\frac{1}{x}, | |
| do | |
| >>> limit(1/x, x, 0, '+') | |
| โ | |
| As opposed to | |
| >>> limit(1/x, x, 0, '-') | |
| -โ | |
| Series Expansion | |
| ================ | |
| SymPy can compute asymptotic series expansions of functions around a point. To | |
| compute the expansion of `f(x)` around the point `x = x_0` terms of order | |
| `x^n`, use ``f(x).series(x, x0, n)``. ``x0`` and ``n`` can be omitted, in | |
| which case the defaults ``x0=0`` and ``n=6`` will be used. | |
| >>> expr = exp(sin(x)) | |
| >>> expr.series(x, 0, 4) | |
| 2 | |
| x โ 4โ | |
| 1 + x + โโ + Oโx โ | |
| 2 | |
| The `O\left(x^4\right)` term at the end represents the Landau order term at | |
| `x=0` (not to be confused with big O notation used in computer science, which | |
| generally represents the Landau order term at `x` where `x \rightarrow \infty`) | |
| . It means that all x terms with power greater than or equal to `x^4` are | |
| omitted. Order terms can be created and manipulated outside of ``series``. | |
| They automatically absorb higher order terms. | |
| >>> x + x**3 + x**6 + O(x**4) | |
| 3 โ 4โ | |
| x + x + Oโx โ | |
| >>> x*O(1) | |
| O(x) | |
| If you do not want the order term, use the | |
| method. | |
| >>> expr.series(x, 0, 4).removeO() | |
| 2 | |
| x | |
| โโ + x + 1 | |
| 2 | |
| The ``O`` notation supports arbitrary limit points (other than 0): | |
| >>> exp(x - 6).series(x, x0=6) | |
| 2 3 4 5 | |
| (x - 6) (x - 6) (x - 6) (x - 6) โ 6 โ | |
| -5 + โโโโโโโโ + โโโโโโโโ + โโโโโโโโ + โโโโโโโโ + x + Oโ(x - 6) ; x โ 6โ | |
| 2 6 24 120 | |
| .. _calculus-finite-differences: | |
| Finite differences | |
| ================== | |
| So far we have looked at expressions with analytic derivatives | |
| and primitive functions respectively. But what if we want to have an | |
| expression to estimate a derivative of a curve for which we lack a | |
| closed form representation, or for which we don't know the functional | |
| values for yet. One approach would be to use a finite difference | |
| approach. | |
| The simplest way the differentiate using finite differences is to use | |
| the :func:`~sympy.calculus.finite_diff.differentiate_finite` function: | |
| >>> f, g = symbols('f g', cls=Function) | |
| >>> differentiate_finite(f(x)*g(x)) | |
| -f(x - 1/2)โ g(x - 1/2) + f(x + 1/2)โ g(x + 1/2) | |
| If you already have a ``Derivative`` instance, you can use the | |
| method to generate | |
| approximations of the derivative to arbitrary order: | |
| >>> f = Function('f') | |
| >>> dfdx = f(x).diff(x) | |
| >>> dfdx.as_finite_difference() | |
| -f(x - 1/2) + f(x + 1/2) | |
| here the first order derivative was approximated around x using a | |
| minimum number of points (2 for 1st order derivative) evaluated | |
| equidistantly using a step-size of 1. We can use arbitrary steps | |
| (possibly containing symbolic expressions): | |
| >>> f = Function('f') | |
| >>> d2fdx2 = f(x).diff(x, 2) | |
| >>> h = Symbol('h') | |
| >>> d2fdx2.as_finite_difference([-3*h,-h,2*h]) | |
| f(-3โ h) f(-h) 2โ f(2โ h) | |
| โโโโโโโ - โโโโโ + โโโโโโโโ | |
| 2 2 2 | |
| 5โ h 3โ h 15โ h | |
| If you are just interested in evaluating the weights, you can do so | |
| manually: | |
| >>> finite_diff_weights(2, [-3, -1, 2], 0)[-1][-1] | |
| [1/5, -1/3, 2/15] | |
| note that we only need the last element in the last sublist | |
| returned from ``finite_diff_weights``. The reason for this is that | |
| the function also generates weights for lower derivatives and | |
| using fewer points (see the documentation of ``finite_diff_weights`` | |
| for more details). | |
| If using ``finite_diff_weights`` directly looks complicated, and the | |
| method of | |
| ``Derivative`` instances is not flexible enough, you can use | |
| ``apply_finite_diff`` which takes ``order``, ``x_list``, ``y_list`` and ``x0`` | |
| as parameters: | |
| >>> x_list = [-3, 1, 2] | |
| >>> y_list = symbols('a b c') | |
| >>> apply_finite_diff(1, x_list, y_list, 0) | |
| 3โ a b 2โ c | |
| - โโโ - โ + โโโ | |
| 20 4 5 | |