UnitfulLsqFit
Least squares fitting for Unitful
quantities.
using Unitful
using LsqFit, Latexify, Plots
using UnitfulLsqFit, UnitfulLatexify, UnitfulRecipes
default(;fontfamily="Computer Modern")
length = 1000
@. model(x, p) = p[1] + p[2]*exp(-((x-p[3])/p[4])^2) + p[5]*x
p0 = [
2.0u"m/s", # y offset
10.2u"m/s", # peak height
-1.0u"s", # x offset
0.6u"s", # peak width
1.2u"m/s^2", # slope
]
t = range(-5, 5; length)u"s"
v = model(t, p0) + randn(length)*u"m/s" # noisy signal
fit = curve_fit(model, t, v, [0.0u"m/s", 1.0u"m/s", 0.0u"s", 1.0u"s", 1.0u"m/s^2"])
mdtable([p0 fit.param];head=latexraw.([:Truth, :Fit]))
Truth | Fit |
---|---|
$2\;\mathrm{m}\,\mathrm{s}^{-1}$ | $1.943\;\mathrm{m}\,\mathrm{s}^{-1}$ |
$10.2\;\mathrm{m}\,\mathrm{s}^{-1}$ | $10.18\;\mathrm{m}\,\mathrm{s}^{-1}$ |
$-1\;\mathrm{s}$ | $-0.9983\;\mathrm{s}$ |
$0.6\;\mathrm{s}$ | $0.604\;\mathrm{s}$ |
$1.2\;\mathrm{m}\,\mathrm{s}^{-2}$ | $1.197\;\mathrm{m}\,\mathrm{s}^{-2}$ |
plot(t, v; st=:scatter, label="Samples")
plot!(t,model(t, fit.param);
linewidth=2, label="Fit",
xguide="t", yguide="v", unitformat=(l,u)->"\$$l / $(latexraw(u))\$", legend=-45,
)
/home/runner/.julia/packages/GR/9Vi4m/src/../deps/gr/bin/gksqt: error while loading shared libraries: libQt5Widgets.so.5: cannot open shared object file: No such file or directory connect: Connection refused GKS: can't connect to GKS socket application GKS: Open failed in routine OPEN_WS GKS: GKS not in proper state. GKS must be either in the state WSOP or WSAC in routine ACTIVATE_WS
Warning concerning exponential fits
Consider the function $y(x) = x^p$. If you know the dimension of $y$ and $x$, and neither of them is unitless, there is exactly one choice of $p$ that allows this comparison – and any adjacent $p^*$ will not only make the comparison inaccurate but impossible. Curve fitting in this case doesn't make sense, and will most likely simply fail with UnitfulLsqFit
. The dimensionality of the edxpression can not be determined by the values of the fit parameters.