The core concepts of calculus (or analysis) are,

Representing the infinite with limits, and

Approximating curves with straight lines.

However, with computers we're always dealing with the finite. We can leverage some tricks to represent infinite expressions, but under the hood will always be sets of discrete values.

Fortunately, we've got *numerical methods*. This includes finite differences for differentiation and a variety of tools for numerical integration, the latter of which are essentially glorified Riemann sums.

Three very common methods for numerical integration, often taught alongside elementary calculus, are the Trapezoidal Rule, Simpson's Rule, and Runge-Kutta. Each of these essentially break an interval into a bunch of slices and the difference between each of these methods has to do with how the ends of these thin slices are represented. (Read the post on Riemann sums for a deeper conceptual treatment.)

```
function trapezoidal(f::Function, a::T, b::T, n::Int) where {T}
result = 0
for (k, x_k) in enumerate(range(a, b, step=(b-a)/n))
coeff = x_k == a || x_k == b ? 1 : 2
result += coeff * f(x_k)
end
(b-a)/(2n) * result
end
```

© Daniel Marvin. Last modified: June 20, 2021.