12

I have a problem with writing a Mathematica function. I have been requested to show the results of my experiments with the measurement uncertainty (mu) like below:

measurementValue(mu)  

Both numbers ought to be rounded with precision, given by the two most significant digits of mu.

Example:

16(11), 123.4(1.3), 1230(10), 123.345(40)||123.345(0.040)

Getting proper format of mu is simple:

NumberForm[mu, 2]

But I don't have any idea, how to round properly measurement value. Finally I want to write a function, that returns the proper format of the value and mu as output.

rhermans
  • 36,518
  • 4
  • 57
  • 149
Zabaweb
  • 171
  • 7
  • 2
    I'd suggest using some inert wrapper (I used UncertainNumber[val, err] once upon a time), and write up formatting rules so that it displays as val(err) on the front end. That is, look up the usual formatting function/boxes. – J. M.'s missing motivation Jun 17 '13 at 00:33
  • I am not sure what are you asking about. If it is the table or an array of numbers, what is wrong with the old, good plus-minus notation, like 16plusminus11? May be you need to show that on a Plot? In that case did you see ErrorListPlot and alike? – Alexei Boulbitch Jun 17 '13 at 08:53
  • 1
    @AlexeiBoulbitch x+/-dx or x(dx) is only a matter of convention. Important thing here is to force x and dx forms looks like we want to. – Kuba Jun 17 '13 at 12:14
  • There is no difference between both forms.
    The real problem is to get the same number of digits on the right of comma.
    We make: NumberForm[mu, 2] That sets proper format of mu. Now, we need to find how many digits is on the right of comma and set proper value formatting.
    – Zabaweb Jun 17 '13 at 12:37
  • @user8082 NumberForm will not help You at least not in such simple form, look at NumberForm[.4, 2] NumberForm[123, 2] NumberForm[.4, {2,2}] NumberForm[.042, {2,2}]. – Kuba Jun 17 '13 at 16:49

3 Answers3

11

I have faced this problem earlier but failed attempts with simple operations based on NumberForm, Round.. have forced me to stop looking for general solution. I have thought my skills in MMA were too low, but also today I am not able to do this in simple way. (haven't I learned anything? :))

This form of expression uncertainty in measurement is described by ISO check § 7.2.2. (link provided by OleksandrR.)

Assumptions

Since we are dealing with some kind of convention it is good to point assumptions to avoid future discussions (here and after x-measurement, dx-uncertainty):

  • dx is taken with 3 most significant digits and rounded to 2, while x is only taken with as many digits as dx imply without rounding.
  • x > dx, or is at least the same order of magnitude as dx.
  • x is given with maximum 15 digits. (so we do not use 1234567891234567 for example)

Function:

I can not supress the feelling that it is an overkill but I wanted to do this.

f[x_, dx_] := Module[{d1, d2, Rdx, Rx},
  Rdx = {{#[[1]], Round[#[[2]] + .1 #[[3]] + .01]}~Join~
   Table[0, {#2 - 2}], #2} & @@ RealDigits[dx, 10, 3];
  Rx = Fold[#2 @@ #1 &,
    RealDigits[x, 10, 15],
    {
     {#1[[1 ;; Max[#2, -Rdx[[2]] + 2 + #2]]], #2} &,
     {Table[0, {-#2 + 1}]~Join~#1, If[#2 <= 0, 1 + Abs@#2, #2]} &
     }
    ];
  d1 = If[Length@#1 == #2, #1, Insert[#1, ".", #2 + 1]] & @@ Rx;
  d2 = If[#2 == 1, Insert[#1, ".", 2], #1] & @@ Rdx;
  Row[Join[d1, {"("}, d2, {")"}]]
  ]

Examples:

data = {{12345, 678}, {12345, 6.78}, {12345, .678}, {12345, .000678}, 
        {123231231321321, 123.12312}};
data3 = {#1/100, #2} & @@@ data;
exp = f @@@ # & /@ {data, data3};

Grid[{{"{x,dx}", "expr.", "{x,dx}", "expr."}}~Join~Transpose@Riffle[{data, data3},exp], 
    Dividers -> {{3 -> True}, {2 -> True}}, Alignment -> {",", Left}]

enter image description here

Function destription: ( later...*)

Extension: If no one show much shorter solution I'll extend this a little bit. For example one could expect:

f[0.00001123,0.000001]
1.12(10) 10^(-5)
Kuba
  • 136,707
  • 13
  • 279
  • 740
  • 5
    For the full text of JCGM 100:2008(E) (GUM), see here. – Oleksandr R. Jun 20 '13 at 13:20
  • @OleksandrR. I don't know if it is legal but thank You :) – Kuba Jun 20 '13 at 13:22
  • Yes, it's legal--it's right from the ISO website and you can follow links to the same page from where you were. You only have to pay the 210 CHF if you want the printed (or printable) copy of the report. Not sure why the PDF is the same price as the printed copy. – Oleksandr R. Jun 20 '13 at 13:23
  • @OleksandrR. Oh, indeed. I should have tried harder. Sorry for accusing You. – Kuba Jun 20 '13 at 13:27
  • 4
    Regarding your answer (+1, of course), I personally would not round the uncertainty to two places if you are going to present it with three digits. Although some people will complain about "too many significant figures", IMO this objection is rooted in incorrect ideas about uncertainty analysis and can be ignored. – Oleksandr R. Jun 20 '13 at 13:34
  • @OleksandrR. I think so, but this method can be adapted to fit any convention. I wonder why nobody cares about this question. It is strange such functionality is not built in. – Kuba Jun 22 '13 at 16:54
  • 3
    I'm not sure; personally I just use PlusMinus inside Mathematica, since I don't use it for presentation (just for calculations). In some cases it may be desirable to have different positive- and negative-going errors, or to be more precise about the distribution of the measured values, so I think there isn't a single good approach, which may explain why people are happy to manually format their results for presentation after consciously making this decision. BTW, I noticed that all the GUM PDFs are also available from the BIPM site. – Oleksandr R. Jun 22 '13 at 19:47
  • As @Olek said, I'm among those who prefer describing the errors with explicit distributions. I really think reporting errors like $1.23(10)$ or $1.23\pm 0.01$ should be considered as the old fashion for pre-computer era. They are easy to calculate by pen and paper, but lots of information gets lost. – Silvia Jun 23 '13 at 22:55
  • @Silvia You are right but something has to be written at the end of error analysis. :) Moreover, I admit Astronomy is a peculiar area but, sometimes it is the most reasonable way to show errors. I mean the minimalistic way, because assumptions and simplifications dominate so much that taking to much care about error analysis would look ridiculous. (not allways of course, also very often proper error analysis is the core of publication). And, at last, why nobody don't want to face this problem just for sport? :) – Kuba Jun 24 '13 at 05:09
  • Yes I agree if the distribution model is relatively fixed, it's more convenient to just use some characteristic quantities to describe it. Anyway when I need to write down the errors, I try to cooperate with others. I give the distributions, they translate them into standard format. :D In fact I do care about this question, but found myself ignorant on this topic.. – Silvia Jun 24 '13 at 18:18
  • @Kuba You can be interested in the last part of this answer of mine. It is about achieving both nice formatting and high interoperability. – Alexey Popkov Jun 15 '16 at 12:52
  • @AlexeyPopkov this answer is so old, can't look at it ;P will have to polish it one day. Thanks for the link. – Kuba Jun 15 '16 at 13:32
  • Is this function working as intended? If I feed 0.1294, 0.2888 I get 0.12(29) but I was expecting 0.13(29) ... did I not copy your function correctly in my notebook? – Rho Phi Jun 30 '17 at 10:38
3

I solved my problem particular and wrote proper function:

f[value_, mu_, k_] :=
   Block[{n},
      n = Ceiling[n /. NSolve[mu == 10^n, n]][[1]];
      N[Round[{value, mu}, 10^(n - k)]]
   ]

Function returns two element list. The first element is proper round value, the 2nd is mu. The "k" call parameter determine how many first digits of mu is important.

Zabaweb
  • 171
  • 7
2
 f[x_, dx_, k_: 2] := Block[{y, dy, n, dn, estep, xi},
   n = RealDigits[x][[2]];
   dn = RealDigits[dx][[2]];
   estep = Abs[Max[n, dn]] + k;
   dy = If[dx >= 1, 
           NumberForm[N[dx], {k, If[-dn + k >= 0, -dn + k, 0]}, 
           ExponentStep -> estep], Round[dx 10^(-dn + k)]];
    Off[NumberForm::sigz, ScientificForm::sigz];

    xi = If[-dn + k > 0, 1, estep];
    y = NumberForm[
          N[x], {If[-dn + k >= 0, -dn + k + 2, k], 
    If[-dn + k >= 0, -dn + k, 0]}, 
        ExponentStep -> If[-dn + k > 0, 1, estep]];
      y = If[n + k > dn, y, 0];
    {y, dy}
     ];
Kuba
  • 136,707
  • 13
  • 279
  • 740
Zabaweb
  • 171
  • 7
  • Check f[1234567, 4567, 2]. Also it is switching to exponent form quite fast in cases like: f[1234567, .2]. – Kuba Jun 24 '13 at 11:28