1Number::WithError(3)  User Contributed Perl Documentation Number::WithError(3)
2
3
4

NAME

6       Number::WithError - Numbers with error propagation and scientific
7       rounding
8

SYNOPSIS

10         use Number::WithError;
11
12         my $num = Number::WithError->new(5.647, 0.31);
13         print $num . "\n";
14         # prints '5.65e+00 +/- 3.1e-01'
15         # (I.e. it automatically does scientific rounding)
16
17         my $another = $num * 3;
18         print $another . "\n";
19         # propagates the error assuming gaussian errors
20         # prints '1.69e+01 +/- 9.3e-01'
21
22         # trigonometric functions also work:
23         print sin($another) . "\n";
24         # prints '-9.4e-01 +/- 3.1e-01'
25
26         my $third = $another ** $num;
27         print $third. "\n";
28         # propagates both errors into one.
29         # prints '8.7e+06 +/- 8.1e+06'
30
31         # shortcut for the constructor:
32         use Number::WithError 'witherror';
33         $num = witherror('0.00032678', ['2.5e-5', '3e-5'], 5e-6);
34         # can deal with any number of errors, even with asymmetric errors
35         print $num . "\n";
36         # prints '3.268e-04 + 2.5e-05 - 3.00e-05 +/- 5.0e-06'
37         # Note: It may be annyoing that they don't all have the same
38         # exponent, but they *do* all have the sam significant digit!
39

DESCRIPTION

41       This class is a container class for numbers with a number of associated
42       symmetric and asymmetric errors. It overloads practically all common
43       arithmetic operations and trigonometric functions to propagate the
44       errors. It can do proper scientific rounding (as explained in more
45       detail below in the documentation of the "significant_digit()" method).
46
47       You can use Math::BigFloat objects as the internal representation of
48       numbers in order to support arbitrary precision calculations.
49
50       Errors are propagated using Gaussian error propagation.
51
52       With a notable exception, the test suite covers way over ninety percent
53       of the code. The remaining holes are mostly difficult-to-test corner
54       cases and sanity tests. The comparison routines are the exception for
55       which there will be more extensive tests in a future release.
56

OVERLOADED INTERFACE

58       This module uses overload to enable the use of the ordinary Perl
59       arithmetic operators on objects. All overloaded operations are also
60       availlable via methods. Here is a list of overloaded operators and the
61       equivalent methods.  The assignment forms of arithmetic operators (e.g.
62       "+=") are availlable if their normal counterpart is overloaded.
63
64       • Addition: "$x + $y" implemented by the "$x->add($y)" method.
65
66       • Increment: "$x++" implemented by the "$x->add(1)" method.
67
68       • Subtraction: "$x - $y" implemented by the "$x->subtract($y)" method
69
70       • Decrement: "$x--" implemented by the "$x->subtract(1)" method.
71
72       • Multiplication: "$x * $y" implemented by the "$x->multiply($y)"
73         method.
74
75       • Division: "$x / $y" implemented by the "$x->divide($y)" method.
76
77       • Exponentiation: "$x ** $y" implemented by the "$x->exponentiate($y)"
78         method.
79
80       • Sine: "sin($x)" implemented by the "$x->sin()" method.
81
82       • Cosine: "cos($x)" implemented by the "$x->cos()" method.
83
84       • Stringification "$x" is implemented by the "$x->round()" method.
85
86       • Cast to a number (i.e. numeric context) is implemented by the
87         "$x->number()" method.
88
89       • Boolean context is implemented by the "$x->number()" method.
90
91       • Unary minus "-$x" is implemented by the "$x->multiply(-1)" method.
92
93       • Logical not is implemented via a boolean context.
94
95       • Absolute value "abs($x)" is implemented via "$x->abs()".
96
97       • Natural logarithm "log($x)" is implemented via "$x->log()".
98
99       • Square Root "sqrt($x)" is implemented via "$x->sqrt()".
100
101       • Numeric comparison operators "$x == $y", "$x != $y", etc. are
102         implemented via "$x-$<gt"numeric_cmp($y)>.
103
104       • String comparison operators "$x eq $y", "$x ne $y", etc. are
105         implemented via "$x-$<gt"full_cmp($y)>. They might not do what you
106         expect. Please read the documentation.
107
108       Here's a list of overloadable operations that aren't overloaded in the
109       context of this module:
110
111         << >> x . & ^ | atan2 int
112

CONSTRUCTORS

114       All constructors accept Math::BigFloat objects in place of numbers.
115
116   new
117       This is the basic constructor for "Number::WithError" objects.
118
119       New objects can be created in one of two ways:
120
121       • The first argument is expected to be the number itself. Then come
122         zero or more errors. Errors can either be a number, a reference to an
123         array of two numbers, or "undef". In the former case, the number is
124         treated as an uncertainty which has the same magnitude in both
125         directions. (I.e. "+/- x") In case of an array reference, the first
126         number is treated as the upper error boundary and the second as the
127         lower boundary. (I.e. "+x, -y") "undef" is treated as zero error.
128
129       • The second way to create objects is passing a single string to the
130         constructor which is efficiently parsed into a number and any number
131         of errors. I'll explain the format with an example:
132
133           133.14e-5 +/- .1e-4 + 0.00002 - 1.0e-5 +/- .2e-4
134
135         In this example, the first number is parsed as the actual number.
136         The following number is treated as a symmetric error (".1e-4") The
137         two following numbers are treated as the upper and lower boundary for
138         a single error. Then comes another ordinary error.  It is also legal
139         to define the lower boundary of an error before the upper boundary.
140         (I.e. "-1.0e-5 +0.00002")
141
142         Whitespace is insignificant.
143
144         For the sake of completeness, I'll mention the regular expression
145         that is used to match numbers. It's taken from the official Perl FAQ
146         to match floating point numbers:
147
148           [+-]?(?=\d|\.\d)\d*(?:\.\d*)?(?:[Ee][+-]?\d+)?
149
150         Don't worry if you don't understand it. Just run a few tests to see
151         if it'll accept your numbers. Or go read "perldoc -q float" or pick
152         up a book on C and read up on how they define floating point numbers.
153
154       Note that trailing zeros currently have no effect. (Yes, this is a
155       BUG!)
156
157       The constructor returns a new object of this class or undef if
158       something went wrong.
159
160   new_big
161       This is an alternative constructor for "Number::WithError" objects. It
162       works exactly like "new" except that it makes all internal numbers
163       instances of "Math::BigFloat" for high precision calculations.
164
165       The module does not load "Math::BigFloat" at compile time to avoid
166       loading a big module that isn't needed all the time. Instead, this
167       module makes use of the prefork pragma and loads "Math::BigFloat" when
168       needed at run-time.
169
170   witherror
171       This constructor is not a method. It is a subroutine that can be
172       exported to your namespace on demand. It works exactly as the "new()"
173       method except it's a subroutine and shorter.
174
175       I'm normally not for this kind of shortcut in object-oriented code, but
176       if you have to create a large number of "Number::WithError" numbers,
177       you'll appreciate it. Trust me.
178
179       Note to authors of subclasses: If you inherit from this module, you'll
180       need to implement your own "witherror()" because otherwise, it will
181       still return objects of this class, not your subclass.
182
183   witherror_big
184       This is also not a method. It does the same as "witherror()".  It can
185       also be optionally be exported to your namespace.
186
187       It uses the "new_big" constructor instead of the "new" constructor used
188       by "witherror()".
189

ARITHMETIC METHODS

191       All of these methods implement an arithmetic operation on the object
192       and the method's first parameter.
193
194       The methods aren't mutators. That means they don't modify the object
195       itself, but return the result of the operation as a new object.
196
197       All of the methods accept either a plain number, a "Number::WithError"
198       object or anything that is understood by the constructors as argument,
199
200       All errors are correctly propagated using Gaussian Error Propagation.
201       The formulae used for this are mentioned in the individual methods'
202       documentation.
203
204   add
205       Adds the object a and the argument b. Returns a new object c.
206
207       Formula: "c = a + b"
208
209       Error Propagation: "err_c = sqrt( err_a^2 + err_b^2 )"
210
211   subtract
212       Subtracts the argument b from the object a. Returns a new object c.
213
214       Formula: "c = a - b"
215
216       Error Propagation: "err_c = sqrt( err_a^2 + err_b^2 )"
217
218   multiply
219       Multiplies the object a and the argument b. Returns a new object c.
220
221       Formula: "c = a * b"
222
223       Error Propagation: "err_c = sqrt( b^2 * err_a^2 + a^2 * err_b^2 )"
224
225   divide
226       Divides the object a by the argument b. Returns a new object c.
227
228       Formula: "c = a / b"
229
230       Error Propagation: "err-c = sqrt( err_a^2 / b^2 + a^2 * err_b^2 / b^4
231       )"
232
233   exponentiate
234       Raises the object a to the power of the argument b. Returns a new
235       object c.  Returns "undef" if a is negative because the error cannot be
236       propagated in that case. (Can't take log of a negative value.)
237
238       Also, please have a look at the error propagation formula below.
239       Exponentiation and logarithms are operations that can become
240       numerically unstable very easily.
241
242       Formula: "c = a ^ b"
243
244       Error Propagation: "err-c = sqrt( b^2 * a^(b-1) * err_a^2 + ln(a)^2 *
245       a^b * err_b^2 )"
246

METHODS FOR BUILTIN FUNCTIONS

248       These methods calculate functions of the object and return the result
249       as a new object.
250
251   sqrt
252       Calculates the square root of the object a and returns the result as a
253       new object c.  Returns undef if a is negative.
254
255       Formula: "c = sqrt(a)"
256
257       Error Propagation: "err-c = sqrt( err-a^2 / (2*sqrt(a))^2 ) = abs(
258       err-a / (2*sqrt(a)) )"
259
260   log
261       Calculates the natural logarithm of an object a. Returns a new object
262       c.  If a is negative, the function returns undef.
263
264       Formula: "c = log(a)"
265
266       Error Propagation: "err-c = sqrt( err-a^2 / a^2 ) = abs( err-a / a )"
267
268   sin
269       Calculates the sine of the object a and returns the result as a new
270       object c.
271
272       Formula: "c = sin(a)"
273
274       Error Propagation: "err-c = sqrt( cos(a)^2 * err-a^2 ) = abs( cos(a) *
275       err-a )"
276
277   cos
278       Calculates the cosine of the object a and returns the result as a new
279       object c.
280
281       Formula: "c = cos(a)"
282
283       Error Propagation: "err-c = sqrt( sin(a)^2 * err-a^2 ) = abs( sin(a) *
284       err-a )"
285
286   tan
287       Calculates the tangent of the object a and returns the result as a new
288       object c.
289
290       Formula: "c = tan(a)"
291
292       Error Propagation: "err-c = sqrt( err-a^2 / cos(a)^4 ) = abs( err-a /
293       cos(a)^2 )"
294
295       Since there is no built-in "tan()" function, this operation is not
296       available via the overloaded interface.
297
298   abs
299       Calculates the absolute value of an object a. Leaves the errors
300       untouched. Returns a new object c.
301
302       Formula: "c = abs(a)"
303
304       Error Propagation: "err-c = err-a"
305

ROUNDING, STRINGIFICATION AND OUTPUT METHODS

307       This section documents methods dealing with the extraction of data from
308       the object. The methods implement rounding of numbers, stringification
309       of the object and extracting meta information like the significant
310       digit.
311
312   number
313       Determines the significant digit using the "significant_digit()"
314       method, rounds the number that the object "number()" is called on
315       represents to that digit and returns the rounded number.
316
317       Regardless of the internal representation of the number, this returns
318       an unblessed string / an unblessed floating point number.
319
320       To gain access to the raw number representation in the object, use the
321       "raw_number" method.
322
323       Either way, the number will be in scientific notation. That means the
324       first non-zero digit comes before the decimal point and following the
325       decimal point and any number of digits is an exponent in "eXXX"
326       notation.
327
328   raw_number
329       This method returns the internal representation of the number in the
330       object. It does not round as appropriate. It does not clone
331       "Math::BigFloat" objects either. So make sure you do that if necessary!
332
333   round
334       This method determines the significant digit using the
335       "significant_digit()" method. Then, it rounds the number represented by
336       the object and all associated errors to that digit.
337
338       Then, the method concatenates the number with its errors and returns
339       the resulting string. In case of symmetric errors, the string "+/-"
340       will be prepended to the error. In case of asymmetric errors, a "+"
341       will be prepended to the first/upper error component and a "-" to the
342       second/lower error component.
343
344       Returns the previously described string.
345
346   significant_digit
347       This method returns the significant digit of the number it is called on
348       as an integer. If the number has no errors or all errors are "undef" or
349       zero, this method returns "undef".
350
351       The return value of this method is to be interpreted as follows: If
352       this method returns "-5", the significant digit is "1 * 10**-5" or
353       0.00001. If it returns 3, the significant digit is "1 * 10**3" or 1000.
354       If it returns 0, the significant digit is 1.
355
356       The return value is computed by the following algorithm: The individual
357       significant digit of a single error is: Take the exponent of the first
358       non-zero digit in the error. The digit after this first non-zero digit
359       is the significant one.
360
361       This method returns the minimum of the individual significant digits of
362       all errors.
363
364       That means:
365
366         5 +/- 0.0132 + 0.5 - 1
367
368       Will yield a return value of "-3" since the first error has the lowest
369       significant digit.
370
371       This algorithm is also used for determining the significant digit for
372       rounding. It is extremely important that you realize this isn't carved
373       in stone. The way the significant digit is computed in the presence of
374       errors is merely a convention. In this case, it stems from particle
375       physics. It might well be that in your particular scientific community,
376       there are other conventions.  One, for example, is to use the second
377       non-zero digit only if the first is a 1.
378
379   error
380       This method returns a reference to an array of errors of the object it
381       is called on.
382
383       Unlike the "raw_error()" method, this method takes proper care to copy
384       all objects and references to defy action at a distance. The structure
385       of the returned array reference is akin to that returned by
386       "raw_error()".
387
388       Furthermore, this method rounds all errors to the significant digit as
389       determined by "significant_digit()".
390
391   raw_error
392       Returns the internal representation of the errors of the current
393       object.  Note that (just like "raw_number()", this does not clone the
394       data for safe use without action at a distance. Instead, it directly
395       returns the internal reference to the error structure.  The structure
396       is an array of errors. Each error may either be a string or floating
397       point number or a "Math::BigFloat" object or an array reference. In
398       case of an array reference, it is an asymmetric error. The inner array
399       contains two strings/numbers/"Math::BigFloat"s.
400
401       Note that this practically breaks encapsulation and code relying on it
402       might break with future releases.
403
404   as_array
405       This method returns the information stored in the object as an array
406       (i.e. a list in this context) which can be passed to the "new()" method
407       to recreate the object.
408
409       The first element of the return list will be the number itself. If the
410       object uses "Math::BigFloat" for the internal representation, this
411       element will be a copy of the internal object. Otherwise, it will be
412       the internal representation of the number with full precision.
413
414       Following the number will be all errors either as numbers,
415       "Math::BigFloat" objects or arrays containing two asymmetric errors.
416       (Either as numbers or objects as explained above.) The data returned by
417       this method will be copied deeply before being returned.
418
419   round_a_number
420       This is a helper function which can round a number to the specified
421       significant digit (defined as the return value of the
422       "significant_digit" method):
423
424         my $rounded = round_a_number(12.01234567, -3);
425         # $rounded is now 1.2012e01
426

COMPARISON

428       This section lists methods that implement different comparisons between
429       objects.
430
431   numeric_cmp
432       This method implements a numeric comparison of two numbers.  It
433       compares the object it is called on to the first argument of the
434       method. If the first argument is omitted or undefined, the method
435       returns "undef".
436
437       Numeric comparison means in this case that the represented numbers will
438       be rounded and then compared. If you would like a comparison that takes
439       care of errors, please have a look at the "full_cmp()" method.
440
441       The method returns "-1" if the rounded number represented by the object
442       is numerically less than the rounded number represented by the first
443       argument. It returns 0 if they are equal and 1 if the object's rounded
444       number is more than that of the argument.
445
446       This method implements the overloaded numeric comparison operations.
447
448   full_cmp
449       This method implements a full comparison of two objects. That means, it
450       takes their numeric values, rounds them and compares them just like the
451       "numeric_cmp()" method.
452
453       If, however, the numbers are equal, this method iterates over the
454       errors, rounds them and then compares them. If all errors are equal,
455       this method returns 0. If an error is found to differ, the method
456       returns 1 in case the object's error is larger and "-1" in case the
457       argument's error is larger.
458
459       Comparing an asymmetric error to a symmetric error is a special case.
460       It can never be the same error, hence the method will not return 0.
461       Instead, it guesses which error is larger by using the upper error
462       bound of the asymmetric error. (Well, yes, not very useful.)
463

SUPPORT

465       Bugs should be reported via the CPAN bug tracker at
466
467       <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Number-WithError>
468
469       For other issues, contact the author.
470

SEE ALSO

472       You may use Math::BigFloat with this module. Also, it should be
473       possible to use Math::Symbolic to calculate larger formulas. Just
474       assign a "Number::WithError" object to the "Math::Symbolic" variables
475       and it should work.
476
477       You also possibly want to have a look at the prefork pragma.
478
479       The test suite is implemented using the Test::LectroTest module. In
480       order to keep the total test time in reasonable bounds, the default
481       number of test attempts to falsify the test properties is kept at a low
482       number of 100. You can enable more rigorous testing by setting the
483       environment variable "PERL_TEST_ATTEMPTS" to a higher value. A value in
484       the range of 1500 to 3000 is probably a good idea, but takes a long
485       time to test.
486

AUTHOR

488       Steffen Mueller <smueller@cpan.org>, <http://steffen-mueller.net/>
489
491       Copyright 2006-2010 Steffen Mueller.
492
493       This program is free software; you can redistribute it and/or modify it
494       under the same terms as Perl itself.
495
496
497
498perl v5.34.0                      2022-01-21              Number::WithError(3)
Impressum