TransWikia.com

Error propagation code

Mathematica Asked by Dinesh Kumar on April 11, 2021

I have a code for error propagation :-

err[F_, w__] := {F[Map[First, List[w]] /. List -> Sequence], 
      Block[{parms = Table[Unique[], {x, 1, Length[List[w]]}], 
            values = Table[List[w][[i, 1]], {i, 1, Length[List[w]]}], 
            errors = Table[List[w][[i, 2]], {i, 1, Length[List[w]]}]}, 
 Sqrt[Total[
 Table[(D[F[parms /. List -> Sequence], parms[[i]]] errors[[i]])^2, 
      {i, 1, Length[values]}] /. 
                      Table[parms[[i]] -> values[[i]], {i, 1, Length[values]}]]]]}

I am not able to propagate error in a complex function with this code.For example in case of real function which is defined as :-

f[a_, b_] := a + b;
err[f, {2, 0.1}, {3, 0.2}]

The output for this function is :- {5, 0.223607}. But in case of complex function say :-

f[a_, b_] := Abs[a + I b];
err[f, {2, 0.1}, {3, 0.2}]

The output is

`{Sqrt[13], Sqrt[(-0.03 + 0. I) Derivative[1][Abs][2 + 3 I]^2]}`

In output both values should be a numerical number. How can I modify my code that it will give me a numerical number in output. Thanks.

Please help me .

2 Answers

The troublesome part here is Abs is not symbolically differentiable:

D[Abs[c], c]
% /. c -> 1
Abs'[c]
Abs'[1] (* doesn't make sense *)

To circumvent this, one way is to use ND instead of D:

Needs["NumericalCalculus`"]
ND[Abs[a + b I], a, 1] /. b -> 1
0.707107

Another way is to use ComplexExpand before differentiation:

D[Abs[a + b I] // ComplexExpand, a];
% /. {a -> 1, b -> 1.}
0.707107

Corresponding fixed code:

err1[F_, w__] := {F[First /@ {w} /. List -> Sequence], 
     Block[{parms = Table[Unique[], {x, 1, Length[{w}]}], 
    values = Table[{w}[[i, 1]], {i, 1, Length[{w}]}], 
         errors = Table[{w}[[i, 2]], {i, 1, Length[{w}]}]}, 
       Sqrt[
    Total[Table[(D[ComplexExpand[F[parms /. List -> Sequence]], parms[[i]]]*
          errors[[i]])^2, 
               {i, 1, Length[values]}] /. 
      Table[parms[[i]] -> values[[i]], {i, 1, Length[values]}]]]]}

err2[F_, w__] := {F[First /@ {w} /. List -> Sequence], 
     Block[{parms = Table[Unique[], {x, 1, Length[{w}]}], 
    values = Table[{w}[[i, 1]], {i, 1, Length[{w}]}], 
         errors = Table[{w}[[i, 2]], {i, 1, Length[{w}]}]}, 
       Sqrt[
    Total[Table[(ND[F[parms /. List -> Sequence], parms[[i]], values[[i]]]*
          errors[[i]])^2, 
               {i, 1, Length[values]}] /. 
      Table[parms[[i]] -> values[[i]], {i, 1, Length[values]}]]]]}

And my attempt to make them conciser:

err1c[F_, w__] := 
 Block[{var = 
    Table[Unique[], {Length@{w}}]}, {F @@ #, (#2^2).MapThread[
          ND[F @@ var, #, #2] &, {var, #}]^2 /. Thread[var -> #] // 
      Sqrt} & @@ ({w}[Transpose])]

err2c[F_, w__] := 
 Block[{var = 
    Table[Unique[], {Length@{w}}]}, {F @@ #, (#2^2).(D[
           F @@ var // ComplexExpand, {var}] /. Thread[var -> #])^2 // 
      Sqrt} & @@ ({w}[Transpose])]

Correct answer by xzczd on April 11, 2021

As of Mathematica 12, there are some experimental functions for uncertainty propagation. In particular, see AroundReplace

Using ComplexExpand[] (as suggested by @xzczd),

AroundReplace[Abs[x + I y] // ComplexExpand, {x -> Around[2, 0.1], y -> Around[3, 0.2]}]
Around[3.605551275463989, 0.17541160386140586`]

Answered by Sterling on April 11, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP