I'm testing Around
for error propagation (v12.2), but it seems to be inconsistent.
Error results depend on the form. Am I missing something here?
Edit Same results in wolfram cloud, which has v12.3.
ClearAll[get$amplitude] ;
get$amplitude[frequency_, signal_] := Block[
{c, s},
c = Cos[2*Pi*frequency*Range[Length[signal]]] ;
s = Sin[2*Pi*frequency*Range[Length[signal]]] ;
c = 2.0*Dot[signal, c] ;
s = 2.0*Dot[signal, s] ;
Divide[{Norm[{c, s}], Sqrt[c^2 + s^2], Sqrt[c*c + s*s]}, Length[signal]]
] ;
frequency = 0.12 ;
signal = 0.5*Sin[2*Pi*frequency*Range[256]] ;
signal = Around[signal, 0.1] ;
TableForm[Map[FullForm, get$amplitude[frequency, signal]]]
(* Around[0.501507305064027`,0.008852097698515098`] *)
(* Around[0.501507305064027`,0.008852097698515098`] *)
(* Around[0.501507305064027`,0.006259378310345857`] *)
Here is a torch implementation, I was expecting results to match exactly.
What can be the reason behind this mismatch? Looks like Around
doesn't use automatic differentiation, I thought it uses Series
under the hood.
import torch
from math import pi
pi = torch.tensor(pi, dtype=torch.float64)
length = 256
time = torch.linspace(start=1.0, end=length, steps=length, dtype=torch.float64)
signal = 0.5 * torch.sin(2.0 * pi * 0.12 * time)
signal.requires_grad_(True) ;
def get_amplitude(length, frequency, time, signal):
c = torch.cos(2.0 * pi * frequency * time)
s = torch.sin(2.0 * pi * frequency * time)
c = 2.0 * torch.dot(c, signal)
s = 2.0 * torch.dot(s, signal)
return torch.sqrt(c*c + s*s) / length
amplitude = get_amplitude(256, 0.12, time, signal)
amplitude.backward()
sigma = 0.1*0.1 + torch.zeros(length, dtype=torch.float64)
sigma = torch.diag(sigma)
print(amplitude.item())
print(torch.sqrt(torch.dot(signal.grad, sigma @ signal.grad)).item())
# 0.501507305064027
# 0.008852294777182603
Around
was reimplemented in V12.3. This information may not be valuable for you, but it may also have fixed the issues you are having. $\endgroup$