Skip to main content
Physics LibreTexts

Error Propagation

  • Page ID
    5692
  • \( \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}\)

    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


    Error Propagation is shared under a not declared license and was authored, remixed, and/or curated by LibreTexts.