1Math::Utils(3) User Contributed Perl Documentation Math::Utils(3)
2
3
4
6 Math::Utils - Useful mathematical functions not in Perl.
7
9 use Math::Utils qw(:utility); # Useful functions
10
11 #
12 # Base 10 and base 2 logarithms.
13 #
14 $scale = log10($pagewidth);
15 $bits = log2(1/$probability);
16
17 #
18 # Two uses of sign().
19 #
20 $d = sign($z - $w);
21
22 @ternaries = sign(@coefficients);
23
24 #
25 # Using copysign(), $dist will be doubled negative or
26 # positive $offest, depending upon whether ($from - $to)
27 # is positive or negative.
28 #
29 my $dist = copysign(2 * $offset, $from - $to);
30
31 #
32 # Change increment direction if goal is negative.
33 #
34 $incr = flipsign($incr, $goal);
35
36 #
37 # floor() and ceil() functions.
38 #
39 $point = floor($goal);
40 $limit = ceil($goal);
41
42 #
43 # Safe(r) summation.
44 #
45 $tot = fsum(@inputs);
46
47 #
48 # The remainders of n after successive divisions of b, or
49 # remainders after a set of divisions.
50 #
51 @rems = moduli($n, $b);
52
53 or
54
55 use Math::Utils qw(:compare); # Make comparison functions with tolerance.
56
57 #
58 # Floating point comparison function.
59 #
60 my $fltcmp = generate_fltmcp(1.0e-7);
61
62 if (&$fltcmp($x0, $x1) < 0)
63 {
64 add_left($data);
65 }
66 else
67 {
68 add_right($data);
69 }
70
71 #
72 # Or we can create single-operation comparison functions.
73 #
74 # Here we are only interested in the greater than and less than
75 # comparison functions.
76 #
77 my(undef, undef,
78 $approx_gt, undef, $approx_lt) = generate_relational(1.5e-5);
79
80 or
81
82 use Math::Utils qw(:polynomial); # Basic polynomial ops
83
84 #
85 # Coefficient lists run from 0th degree upward, left to right.
86 #
87 my @c1 = (1, 3, 5, 7, 11, 13, 17, 19);
88 my @c2 = (1, 3, 1, 7);
89 my @c3 = (1, -1, 1)
90
91 my $c_ref = pl_mult(\@c1, \@c2);
92 $c_ref = pl_add($c_ref, \@c3);
93
95 All functions can be exported by name, or by using the tag that they're
96 grouped under.
97
98 utility tag
99 Useful, general-purpose functions, including those that originated in
100 FORTRAN and were implemented in Perl in the module Math::Fortran, by J.
101 A. R. Williams.
102
103 There is a name change -- copysign() was known as sign() in
104 Math::Fortran.
105
106 log10()
107
108 $xlog10 = log10($x);
109 @xlog10 = log10(@x);
110
111 Return the log base ten of the argument. A list form of the function is
112 also provided.
113
114 log2()
115
116 $xlog2 = log2($x);
117 @xlog2 = log2(@x);
118
119 Return the log base two of the argument. A list form of the function is
120 also provided.
121
122 sign()
123
124 $s = sign($x);
125 @valsigns = sign(@values);
126
127 Returns -1 if the argument is negative, 0 if the argument is zero, and
128 1 if the argument is positive.
129
130 In list form it applies the same operation to each member of the list.
131
132 copysign()
133
134 $ms = copysign($m, $n);
135 $s = copysign($x);
136
137 Take the sign of the second argument and apply it to the first. Zero is
138 considered part of the positive signs.
139
140 copysign(-5, 0); # Returns 5.
141 copysign(-5, 7); # Returns 5.
142 copysign(-5, -7); # Returns -5.
143 copysign(5, -7); # Returns -5.
144
145 If there is only one argument, return -1 if the argument is negative,
146 otherwise return 1. For example, copysign(1, -4) and copysign(-4) both
147 return -1.
148
149 flipsign()
150
151 $ms = flipsign($m, $n);
152
153 Multiply the signs of the arguments and apply it to the first. As with
154 copysign(), zero is considered part of the positive signs.
155
156 Effectively this means change the sign of the first argument if the
157 second argument is negative.
158
159 flipsign(-5, 0); # Returns -5.
160 flipsign(-5, 7); # Returns -5.
161 flipsign(-5, -7); # Returns 5.
162 flipsign(5, -7); # Returns -5.
163
164 If for some reason flipsign() is called with a single argument, that
165 argument is returned unchanged.
166
167 floor()
168
169 $b = floor($a/2);
170
171 @ilist = floor(@numbers);
172
173 Returns the greatest integer less than or equal to its argument. A
174 list form of the function also exists.
175
176 floor(1.5, 1.87, 1); # Returns (1, 1, 1)
177 floor(-1.5, -1.87, -1); # Returns (-2, -2, -1)
178
179 ceil()
180
181 $b = ceil($a/2);
182
183 @ilist = ceil(@numbers);
184
185 Returns the lowest integer greater than or equal to its argument. A
186 list form of the function also exists.
187
188 ceil(1.5, 1.87, 1); # Returns (2, 2, 1)
189 ceil(-1.5, -1.87, -1); # Returns (-1, -1, -1)
190
191 fsum()
192
193 Return a sum of the values in the list, done in a manner to avoid
194 rounding and cancellation errors. Currently this is done via Kahan's
195 summation algorithm
196 <https://en.wikipedia.org/wiki/Kahan_summation_algorithm>.
197
198 gcd
199
200 hcf
201
202 Return the greatest common divisor (also known as the highest common
203 factor) of a list of integers. These are simply synomyms:
204
205 $factor = gcd(@values);
206 $factor = hfc(@numbers);
207
208 lcm
209
210 Return the greatest common divisor of a list of integers.
211
212 $factor = lcm(@values);
213
214 moduli()
215
216 Return the moduli of an integer after repeated divisions. The
217 remainders are returned in a list from left to right.
218
219 @digits = moduli(1899, 10); # Returns (9, 9, 8, 1)
220 @rems = moduli(29, 3); # Returns (2, 0, 0, 1)
221
222 compare tag
223 Create comparison functions for floating point (non-integer) numbers.
224
225 Since exact comparisons of floating point numbers tend to be iffy, the
226 comparison functions use a tolerance chosen by you. You may then use
227 those functions from then on confident that comparisons will be
228 consistent.
229
230 If you do not provide a tolerance, a default tolerance of 1.49012e-8
231 (approximately the square root of an Intel Pentium's machine epsilon
232 <https://en.wikipedia.org/wiki/Machine_epsilon>) will be used.
233
234 generate_fltcmp()
235
236 Returns a comparison function that will compare values using a
237 tolerance that you supply. The generated function will return -1 if the
238 first argument compares as less than the second, 0 if the two arguments
239 compare as equal, and 1 if the first argument compares as greater than
240 the second.
241
242 my $fltcmp = generate_fltcmp(1.5e-7);
243
244 my(@xpos) = grep {&$fltcmp($_, 0) == 1} @xvals;
245
246 generate_relational()
247
248 Returns a list of comparison functions that will compare values using a
249 tolerance that you supply. The generated functions will be the
250 equivalent of the equal, not equal, greater than, greater than or
251 equal, less than, and less than or equal operators.
252
253 my($eq, $ne, $gt, $ge, $lt, $le) = generate_relational(1.5e-7);
254
255 my(@approx_5) = grep {&$eq($_, 5)} @xvals;
256
257 Of course, if you were only interested in not equal, you could use:
258
259 my(undef, $ne) = generate_relational(1.5e-7);
260
261 my(@not_around5) = grep {&$ne($_, 5)} @xvals;
262
263 polynomial tag
264 Perform some polynomial operations on plain lists of coefficients.
265
266 #
267 # The coefficient lists are presumed to go from low order to high:
268 #
269 @coefficients = (1, 2, 4, 8); # 1 + 2x + 4x**2 + 8x**3
270
271 In all functions the coeffcient list is passed by reference to the
272 function, and the functions that return coefficients all return
273 references to a coefficient list.
274
275 It is assumed that any leading zeros in the coefficient lists have
276 already been removed before calling these functions, and that any
277 leading zeros found in the returned lists will be handled by the
278 caller. This caveat is particularly important to note in the case of
279 "pl_div()".
280
281 Although these functions are convenient for simple polynomial
282 operations, for more advanced polynonial operations Math::Polynomial is
283 recommended.
284
285 pl_evaluate()
286
287 $y = pl_evaluate(\@coefficients, $x);
288 @yvalues = pl_evaluate(\@coefficients, \@xvalues);
289
290 You can also use lists of the X values or X array references:
291
292 @yvalues = pl_evaluate(\@coefficients, \@xvalues, \@primes, $x, @negatives);
293
294 Returns either a y-value for a corresponding x-value, or a list of
295 y-values on the polynomial for a corresponding list of x-values, using
296 Horner's method.
297
298 pl_dxevaluate()
299
300 ($y, $dy, $ddy) = pl_dxevaluate(\@coefficients, $x);
301
302 Returns p(x), p'(x), and p"(x) of the polynomial for an x-value, using
303 Horner's method. Note that unlike "pl_evaluate()" above, the function
304 can only use one x-value.
305
306 If the polynomial is a linear equation, the second derivative value
307 will be zero. Similarly, if the polynomial is a simple constant, the
308 first derivative value will be zero.
309
310 pl_add()
311
312 $polyn_ref = pl_add(\@m, \@n);
313
314 Add two lists of numbers as though they were polynomial coefficients.
315
316 pl_sub()
317
318 $polyn_ref = pl_sub(\@m, \@n);
319
320 Subtract the second list of numbers from the first as though they were
321 polynomial coefficients.
322
323 pl_div()
324
325 ($q_ref, $r_ref) = pl_div(\@numerator, \@divisor);
326
327 Synthetic division for polynomials. Divides the first list of
328 coefficients by the second list.
329
330 Returns references to the quotient and the remainder.
331
332 Remember to check for leading zeros (which are rightmost in the list)
333 in the returned values. For example,
334
335 my @n = (4, 12, 9, 3);
336 my @d = (1, 3, 3, 1);
337
338 my($q_ref, $r_ref) = pl_div(\@n, \@d);
339
340 After division you will have returned "(3)" as the quotient, and "(1,
341 3, 0)" as the remainder. In general, you will want to remove the
342 leading zero, or for that matter values within epsilon of zero, in the
343 remainder.
344
345 my($q_ref, $r_ref) = pl_div($f1, $f2);
346
347 #
348 # Remove any leading zeros (i.e., numbers smaller in
349 # magnitude than machine epsilon) in the remainder.
350 #
351 my @remd = @{$r_ref};
352 pop @remd while (@remd and abs($remd[$#remd]) < $epsilon);
353
354 $f1 = $f2;
355 $f2 = [@remd];
356
357 If $f1 and $f2 were to go through that bit of code again, not removing
358 the leading zeros would lead to a divide-by-zero error.
359
360 If either list of coefficients is empty, pl_div() returns undefs for
361 both quotient and remainder.
362
363 pl_mult()
364
365 $m_ref = pl_mult(\@coefficients1, \@coefficients2);
366
367 Returns the reference to the product of the two multiplicands.
368
369 pl_derivative()
370
371 $poly_ref = pl_derivative(\@coefficients);
372
373 Returns the derivative of a polynomial.
374
375 pl_antiderivative()
376
377 $poly_ref = pl_antiderivative(\@coefficients);
378
379 Returns the antiderivative of a polynomial. The constant value is
380 always set to zero and will need to be changed by the caller if a
381 different constant is needed.
382
383 my @coefficients = (1, 2, -3, 2);
384 my $integral = pl_antiderivative(\@coefficients);
385
386 #
387 # Integral needs to be 0 at x = 1.
388 #
389 my @coeff1 = @{$integral};
390 $coeff1[0] = - pl_evaluate($integral, 1);
391
393 John M. Gamble, "<jgamble at cpan.org>"
394
396 Math::Polynomial for a complete set of polynomial operations, with the
397 added convenience that objects bring.
398
399 Among its other functions, List::Util has the mathematically useful
400 functions max(), min(), product(), sum(), and sum0().
401
402 List::MoreUtils has the function minmax().
403
404 Math::Prime::Util has gcd() and lcm() functions, as well as vecsum(),
405 vecprod(), vecmin(), and vecmax(), which are like the List::Util
406 functions but which can force integer use, and when appropriate use
407 Math::BigInt.
408
409 Math::VecStat Likewise has min(), max(), sum() (which can take as
410 arguments array references as well as arrays), plus maxabs(), minabs(),
411 sumbyelement(), convolute(), and other functions.
412
414 Please report any bugs or feature requests to "bug-math-util at
415 rt.cpan.org", or through the web interface at
416 <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Math-Utils>. I will be
417 notified, and then you'll automatically be notified of progress on your
418 bug as I make changes.
419
421 This module is on Github at <https://github.com/jgamble/Math-Utils>.
422
423 You can also look for information at:
424
425 · RT: CPAN's request tracker (report bugs here)
426
427 <http://rt.cpan.org/NoAuth/Bugs.html?Dist=Math-Utils>
428
429 · AnnoCPAN: Annotated CPAN documentation
430
431 <http://annocpan.org/dist/Math-Utils>
432
433 · CPAN Ratings
434
435 <http://cpanratings.perl.org/d/Math-Utils>
436
437 · Search CPAN
438
439 <http://search.cpan.org/dist/Math-Utils/>
440
442 To J. A. R. Williams who got the ball rolling with Math::Fortran.
443
445 Copyright (c) 2017 John M. Gamble. All rights reserved. This program is
446 free software; you can redistribute it and/or modify it under the same
447 terms as Perl itself.
448
449
450
451perl v5.28.0 2018-08-07 Math::Utils(3)