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