Error Propagation
- Page ID
- 4961
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)
( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\id}{\mathrm{id}}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\kernel}{\mathrm{null}\,}\)
\( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\)
\( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\)
\( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)
\( \newcommand{\vectorA}[1]{\vec{#1}} % arrow\)
\( \newcommand{\vectorAt}[1]{\vec{\text{#1}}} % arrow\)
\( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vectorC}[1]{\textbf{#1}} \)
\( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)
\( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)
\( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)Automatic Error Propagation With Mathematica
There is an "Application Library" for Mathematica called Experimental Data Analyst (EDA). It offers a number of tools for the analysis of experimental data. This document discusses one set of tools in EDA which provide the ability to automatically propagate experimental errors.
First we will need to load the EDA library. In the following command the In[1]:=
is the prompt from Mathematica; you will not type that part. Also, in the command there are no apostrophes ', but two graves `.
In[1]:= Needs["EDA`"]
Simple Calculations
In order to alert Mathematica to the fact that we want to do calculations including error propagation, we need to wrap the value and the error in a Datum
construct:
In[2]:= x = Datum[ {1.51, 0.03} ]
Out[2]= Datum[ {1.51, 0.03} ]
This tells Mathematica to interpret x
as a variable with value 1.51 and error 0.03. Mathematica has echoed the value of x
back to the screen with Out[2]= Datum[ {1.51, 0.03} ]
.
We similarly define a variable y
:
In[3]:= y = Datum[ {3.75, 0.08} ]
Out[3]= Datum[ {3.75, 0.08} ]
Now we can combine x
and y
using all the standard arithmetic operations. For example:
In[4]:= x + y
Out[4]= Datum[{5.26, 0.085}]
Thus (1.51 ± 0.03) + (3.75 ± 0.08) is (5.260 ± 0.085), which you can easily verify by hand.
Similarly:
In[5]:= x - y
Out[5]= Datum[{-2.24, 0.085}]
In[6]:= x * y
Out[6] = Datum[{5.66, 0.17}]
In[7]:= x / y
Out[7]= Datum[{0.403, 0.012}]
In Mathematica a^b
gives a
to the power b
. This case is handled too:
In[8]:= x^3
Out[8]= Datum[{3.44, 0.21}]
Sqrt
is the square root operator:
In[9]:= Sqrt[x]
Out[9]= Datum[{1.229, 0.012}]
You can also use virtually every transcendental function, such as Sin
(sine), Cos
(cosine), Log
(natural logarithm), etc.
In[10]:= Log[x]
Out[10]= Datum[{0.412, 0.02}]
Say you have a number of different value,error pairs that you wish to combine. The Data
construct handles this case. In the examples below we will "recycle" the variables x
and y
. You should also notice that in the definition of x
and y
the value,error pairs are surrounded by curly braces {}
, and the whole list of these is also surrounded by another pair of curly braces.
In[11]:= x = Data[ {17.3, .4}, {0.034, 0.0005}, {123, 9} ]
Out[11]= Data[{17.3, 0.4}, {0.034, 0.0005}, {123, 9}]
In[12]:= y = Data[ {23.5, .7}, {0.123, 0.0014}, {412, 15} ]
Out[12]= Data[{23.5, 0.7}, {0.123, 0.0014}, {412, 15}]
In[13]:= x + y
Out[13]= Data[{40.8, 0.81}, {0.157, 0.0015}, {535., 17.}]
In[14]:= x * y
Out[14]= Data[{407., 15.}, {0.004182, 0.000078}, {50700., 4100.}]
Data
can handle all the cases that Datum
can.
Complex Calculations
Although the Datum
and Data
constructs work well for simple calculations, imagine you are attempting something more complex such as:
2 x^2 / z - y z / x
As discussed in the First Year Physics Laboratory Manual, such a combination requires that one takes the partial derivatives of the expression with respect to x
, y
and z
, multiply each derivative by the corresponding error in the variable, and combine these terms in quadrature, i.e. the square root of the sum of the squares. The Datum
and Data
constructs are fairly clever, but not clever enough to do this.
However, EDA supplies a routine CombineWithError
that does all the steps described above. For example:
In[15]:= x = {17.3, .4}, {0.034, 0.0005}, {123, 9}
Out[15]= {17.3, 0.4}, {0.034, 0.0005}, {123, 9}
In[16]:= y = {23.5, .7}, {0.123, 0.0014}, {412, 15}
Out[16]= {23.5, 0.7}, {0.123, 0.0014}, {412, 15}
In[17]:= z = {11.3, .8}, {.345, .023}, {75, 11}
Out[17]= {11.3, 0.8}, {0.345, 0.023}, {75, 11}
In[18]:= CombineWithError[ 2 x^2 / z - y z / x ]
Out[18]= {37.6, 6.1}, {-1.24, 0.12}, {150., 130.}
Of course, CombineWithError
can handle simple cases too. Here we repeat the first calculation we did above in the Simple Calculations section, which was adding 1.51 ± 0.03 to 3.75 ± 0.08:
In[19]:= x = {1.51, 0.03}
Out[19]= {1.51, 0.03}
In[20]:= y = {3.75, 0.08}
Out[20]= {3.75, 0.08}
In[21]:= CombineWithError[x + y]
Out[21]= {5.26, 0.085}
There is one small caveat in using this routine. We can use the Datum
and Data
constructs directly without defining variables such as x
and y
:
In[22]:= Datum[{1.51, 0.03}] + Datum[{3.75, 0.08}]
Out[22]= Datum[{5.26, 0.085}]
CombineWithError
must contain the actual symbols so that it knows how to take the partial derivatives of the expression. Thus the following command generates an error message and fails:
In[23]:= CombineWithError[ {1.51, 0.03} + {3.75, 0.08} ]
CombineWithError::unequallength: The number of datapoints in the variables are not all equal or an unexpected specification of variable names was encountered.
Out[23]= $Failed