R4 — Calculus

Goal: differentiate, integrate, take limits and expand series — and learn to read the answer Leonardo gives when it cannot do one of them.

Why every command names the variable

derive(f, x), integral(f, x), limit(f, x, a) — the variable is always an argument, never inferred. That is not ceremony:

> derive(x * y, x)
y
> derive(x * y, y)
x

run this session

Same expression, two different questions, two different answers. Guessing which you meant would be guessing at mathematics, so Leonardo asks. In exchange, every command here has the same shape — what, then with respect to what — and one you have read is one you can read.

Derivatives

> derive(x^3, x)
(3.0 * (x ^ 2.0))
> derive(sin(x) * x, x)
((cos(x) * x) + sin(x))
> derive(exp(2x), x)
(exp((2.0 * x)) * 2.0)

run this session

Product rule and chain rule, applied without being named.

A second derivative is derive twice. The prompt’s derive takes exactly one variable, so you nest it:

> derive(derive(x^4, x), x)
(4.0 * (3.0 * (x ^ 2.0)))

run this session

And a partial derivative needs no special syntax at all — naming the variable is what makes it partial, as the first section showed.

Integrals

Three arguments is the antiderivative; five is a definite integral:

> integral(x^2, x)
((x ^ 3.0) / 3.0)
> integral(x^2, x, 0, 3)
9.0

run this session

The interesting ones are where technique matters, and you are not asked to choose it:

> integral(x * exp(x), x)
((x * exp(x)) + (-1.0 * exp(x)))
> integral(1/(x^2 - 1), x)
((0.5 * ln((x + -1.0))) + (-0.5 * ln((x + 1.0))))

run this session

The first is integration by parts; the second a partial-fraction decomposition.

When it cannot, it says so by doing nothing

> integral(exp(x^2), x)
integral(exp((x ^ 2.0)), x)

run this session

The answer is the integral itself, unchanged.

That is not an error message and not a failure to try. exp(x^2) has no elementary antiderivative — no combination of the usual functions differentiates to it — so there is nothing to return, and returning something plausible would be far worse than returning nothing.

An answer identical to your question means “declined”. You will meet that shape all over Leonardo: limit, solve and the transforms all do it.

It is worth trusting, because the alternative is a confident wrong answer you have no way to spot.

Some non-elementary integrals are important enough to have names, and those it knows:

> integral(sin(x)/x, x)
Si(x)
> integral(exp(-x^2), x)
(0.88623 * erf(x))

run this session

Si is the sine integral; erf the error function. Both are real answers — just not answers writable with sin, exp and friends.

Limits

> limit(sin(x)/x, x, 0)
1.0
> limit((x^2 + 1)/(2x^2 - x), x, inf)
0.5

run this session

inf is a literal you can use anywhere a limit point is wanted.

A one-sided limit takes a trailing + or -, which is how you ask about a pole from one side:

> limit(1/x, x, 0, +)
inf
> limit(1/x, x, 0, -)
-inf

run this session

Two different answers, which is exactly why the two-sided limit there does not exist.

Series

> taylor(exp(x), x, 0, 4)
((((1.0 + x) + (0.5 * (x ^ 2.0))) + (0.16667 * (x ^ 3.0))) + (0.04167 * (x ^ 4.0)))

run this session

The arguments are what, in which variable, about which point, to what order. maclaurin(exp(x), x, 4) is the same thing, since a Maclaurin series is a Taylor series about zero.

The centre need not be a number:

> taylor(x^2, x, a, 2)
(((a ^ 2.0) + ((2.0 * a) * (x + (-1.0 * a)))) + ((x + (-1.0 * a)) ^ 2.0))

run this session

Try it yourself

Find where x^3 - 3x has a horizontal tangent: differentiate it, then solve the result for zero.

Answers ```text > derive(x^3 - 3x, x) ((3.0 * (x ^ 2.0)) + -3.0) > solve(3x^2 - 3 = 0, x) x_1 := -1.0 x_2 := 1.0 ``` *[run this session](https://lycogrypho.github.io/Leonardo/app/#s=precision%205%0Acolors%20dark%0Apretty%20off%0Alatex%20off%0Anames%20off%0Alogic%20minmax%0Alogic%20symmetric%20off%0Aexact%20precision%2030%0Aexact%20off%0Ax_1%20%3A%3D%20-1.0%0Ax_2%20%3A%3D%201.0)* Horizontal tangents at `x = ±1`. Note that the derivative had to be **copied into** the second line rather than nested: ```text > unset x_1 x_1 unset > unset x_2 x_2 unset > solve(derive(x^3 - 3x, x) = 0, x) x_1 := -1.0 x_2 := 1.0 ``` *[run this session](https://lycogrypho.github.io/Leonardo/app/#s=precision%205%0Acolors%20dark%0Apretty%20off%0Alatex%20off%0Anames%20off%0Alogic%20minmax%0Alogic%20symmetric%20off%0Aexact%20precision%2030%0Aexact%20off%0Ax_1%20%3A%3D%20-1.0%0Ax_2%20%3A%3D%201.0)* That declined — the unchanged-answer shape again. `solve` was handed an equation whose left side is still a `derive(...)` node, and its solver works on polynomial structure it can read, so it did not pretend. Compute first, then solve.

What you learned

  • The variable is always an argument, and exactly one. Nest derive for a second derivative; naming the variable is what makes a derivative partial.
  • integral(f, x) is the antiderivative; integral(f, x, a, b) is a number.
  • An unchanged answer means “declined” — the single most useful convention in the library, and the reason you can trust the answers that do come back.
  • limit takes an optional +/- and understands inf; taylor takes a centre, which may be symbolic.

Previous: R3 — Naming things · Next: R5 — Equations · All lessons


This site uses Just the Docs, a documentation theme for Jekyll.