Calculus
Giac.jl provides powerful symbolic calculus capabilities including differentiation, integration, limits, and Taylor series expansion.
Setup
using Giac
using Giac.Commands: diff, integrate, limit, series
@giac_var x yDifferentiation
Basic Derivatives
Compute derivatives using the diff command:
diff(x^2, x)
# Output: 2*x
diff(x^3, x)
# Output: 3*x^2Higher-Order Derivatives
Compute second, third, or higher-order derivatives by specifying the order:
diff(x^4, x, 2) # Second derivative
# Output: 12*x^2
diff(x^5, x, 3) # Third derivative
# Output: 60*x^2Chain Rule
The chain rule is applied automatically:
diff(sin(x^2), x)
# Output: 2*x*cos(x^2)Product Rule
Derivatives of products are handled automatically:
diff(x * sin(x), x)
# Output: sin(x)+x*cos(x)Partial Derivatives
For multivariable functions, specify the variable:
@giac_var x y
diff(x^2 * y^3, x)
# Output: 2*x*y^3
diff(x^2 * y^3, y)
# Output: 3*x^2*y^2Using the Differential operator
Beyond the function-form Giac.Commands.diff, Giac.jl also exposes a SciML/ModelingToolkit-style operator: Differential(var) is a callable that captures a single differentiation variable and applies partial differentiation to its operand. This pairs naturally with declared functions (@giac_var f(x, y)) and with bare symbolic expressions.
using Giac
@giac_var x y t f(x, y) u(t)
# Bare-expression form (matches SymPy.jl `diff(expr, var)`)
Differential(x)(x^2 + y*x) # Returns: 2*x + y
Differential(x)(sin(x) * exp(x)) # Returns: cos(x)*exp(x) + sin(x)*exp(x)
# Function-form: declared function, returns a DerivativeExpr
Dx = Differential(x)
Dy = Differential(y)
Dx(f) # ∂f/∂x
Dy(Dx(f)) # ∂²f/∂y∂x (cross partial — see "Notation" below)
Dx(Dx(f)) # ∂²f/∂x² (adjacent same-var steps collapse)
# Mono-variable functions work the same way
Dt = Differential(t)
Dt(u) # u'(t)
Dt(Dt(u)) # u''(t)
# Two-argument shorthand for n-th order (matches Symbolics.jl's Differential(x, 2))
Differential(x, 3)(f) # ∂³f/∂x³ — same as Dx(Dx(Dx(f)))
Differential(t, 2)(u) # u''(t) — same as Dt(Dt(u))
Differential(x, 2)(x^3) # 6*x — bare-expression second derivative
# Symbolics-style algebraic surface
Differential(t)^2 # === Differential(t, 2)
Differential(t)^0 # === identity
Differential(y) * Differential(x) # composition — same as Differential(y) ∘ Differential(x)
(Differential(y) ∘ Differential(x))(f) # ∂²f/∂y∂x
# Force evaluation of a lazy DerivativeExpr (no-op on plain GiacExpr —
# matches Symbolics.jl's expand_derivatives)
expand_derivatives(Dx(f)) # → diff(f(x,y), x) as a GiacExpr
expand_derivatives(x^2 + y*x) # → x^2 + y*x (identity)Notation: right-to-left Leibniz convention
In partial-derivative output (Base.show and the math comments above), Giac.jl uses the right-to-left Leibniz convention: in ∂ⁿf/∂v₁…∂vₙ, the rightmost variable in the denominator is applied first, the leftmost last. This matches the operator product (∂/∂v₁)·…·(∂/∂vₙ) f read as a chain of left-multiplications: Differential(y)(Differential(x)(f)) (apply Differential(x) first, then Differential(y)) is written ∂²f/∂y∂x and pretty-prints as D: ∂²f/∂y∂x. By Schwarz/Clairaut the value is symmetric for sufficiently smooth f, but the notation, the Base.show output, and the internal DerivativeExpr.steps field track the order of application.
The function-form path returns a DerivativeExpr that records the differentiation history as an ordered sequence of (variable, order) steps (innermost-first). The bare-expression path returns a plain GiacExpr (already simplified by GIAC). For high-order derivatives (n ≥ 4), the human-readable display switches from primes to math-convention parenthesized superscripts: D(u, 5) shows as u⁽⁵⁾(t) rather than u'''''(t). See Differential Equations for ODE/PDE workflows and the migration guide for porting from the deprecated D operator.
Integration
Indefinite Integrals
Compute antiderivatives using the integrate command:
integrate(x^2, x)
# Output: x^3/3
integrate(sin(x), x)
# Output: -cos(x)
integrate(exp(x), x)
# Output: exp(x)Definite Integrals
Specify bounds for definite integrals:
# ∫₀¹ x² dx = 1/3
integrate(x^2, x, 0, 1)
# Output: 1/3
# ∫₀^π sin(x) dx = 2
integrate(sin(x), x, 0, pi)
# Output: 2Integration Techniques
GIAC automatically applies various integration techniques:
# Integration by parts
integrate(x * exp(x), x)
# Output: (x-1)*exp(x)
# Partial fractions
integrate(1/(x^2-1), x)
# Uses partial fraction decomposition
# Trigonometric integrals
integrate(sin(x)^2, x)
# Output: x/2-sin(2*x)/4Limits
Basic Limits
Compute limits using the limit command:
# Classic limit: sin(x)/x as x→0
limit(sin(x)/x, x, 0)
# Output: 1Limits at Infinity
@giac_var inf # Create infinity symbol
limit(1/x, x, inf)
# Output: 0
limit((x^2+1)/(2*x^2-3), x, inf)
# Output: 1/2L'Hôpital's Rule Cases
GIAC automatically handles indeterminate forms:
# 0/0 form
limit((exp(x)-1)/x, x, 0)
# Output: 1
# ∞/∞ form
limit(ln(x)/x, x, inf)
# Output: 0Taylor Series
Series Expansion
Expand functions as Taylor series using the series command:
# exp(x) around x=0, order 4
series(exp(x), x, 0, 4)
# Output: 1+x+x^2/2+x^3/6+x^4/24+O(x^5)
# sin(x) around x=0, order 5
series(sin(x), x, 0, 5)
# Output: x-x^3/6+x^5/120+O(x^6)
# cos(x) around x=0, order 4
series(cos(x), x, 0, 4)
# Output: 1-x^2/2+x^4/24+O(x^5)Series Around Other Points
Expand around a point other than zero:
# exp(x) around x=1
series(exp(x), x, 1, 3)
# Expansion around x=1Advanced Topics
Gradient and Hessian
For multivariable calculus:
using Giac.Commands: gradient, hessian
@giac_var x y
f = x^2 + x*y + y^2
# Gradient: [∂f/∂x, ∂f/∂y]
gradient(f, [x, y]) # ToFix
# Output: [2*x+y, x+2*y]
# Hessian matrix
hessian(f, [x, y])
# Output: [[2, 1], [1, 2]]Implicit Differentiation
using Giac.Commands: implicitdiff
# For x² + y² = 1, find dy/dx
implicitdiff(x^2 + y^2 - 1, x, y) # ToFix
# Output: -x/yNotes
- All calculus operations work symbolically, not numerically
- For numerical integration, convert results using
to_juliaand use Julia's quadrature packages - The
diffcommand uses Leibniz notation internally - Series expansions include the order term
O(x^n)by default