Examples

Simple example

First we generate a small dataset by adding uniform noise to $f(x)=|x|$

using Random, Distributions

n = 50
x = range(-5, 5, length=n)
dx = x[2] - x[1]

f_noisy = abs.(x) + rand(Uniform(-0.05, 0.05), n)

then we call tvdiff using a regularization parameter of α=0.2 for 100 iterations.

using NoiseRobustDifferentiation

û = tvdiff(f_noisy, 100, 0.2, dx=dx)

We compare the results to the true derivative $u(x)=sign(x)$ and a naive implementation of finite differences.

û_FDM = diff(f_noisy) / dx  # FDM

Examples from paper

Let's reconstruct the figures from Rick Chartrand's paper "Numerical differentiation of noisy, non-smooth data".

The corresponding datasets can be found under /docs/data.

Small-scale example

The small-scale example in the paper is a more noisy variant of our first example. We start by loading the data.

using NoiseRobustDifferentiation
using CSV, DataFrames

file = CSV.File("../data/demo_small.csv")
df = DataFrame(file)
data = df.noisyabsdata

Applying finite differences leads to a noisy and inaccurate result that amplifies the noise:

A strongly regularized result is obtained by calling tvdiff with α=0.2.

û = tvdiff(data, 500, 0.2, scale="small", dx=0.01, ε=1e-6)

Because of keyword argument defaults, this is equal to calling

û = tvdiff(data, 500, 0.2)

A better result is obtained after 7000 iterations, though differences are minimal.

û = tvdiff(data, 7000, 0.2)

Large-scale example

The data in this example was obtained from a whole-room calorimeter.

using NoiseRobustDifferentiation
using CSV, DataFrames

file = CSV.File("../data/demo_large.csv")
df = DataFrame(file)
data = df.largescaledata

Computing derivates using naive finite differences gives a useless result:

Using tvdiff with ε=1e-9, we obtain a strongly regularized result. Larger values of $\varepsilon$ improve conditioning and speed, while smaller values give more accurate results with sharper jumps.

û = tvdiff(data, 40, 1e-1, scale="large", precond="amg_rs", ε=1e-9)

Therefore raising $\varepsilon$ to 1e-7 gives a smoother result. However, jumps in the derivative are also smoothed away.

û = tvdiff(data, 40, 1e-1, scale="large", precond="amg_rs", ε=1e-7)