Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
Math::Utils(3)	      User Contributed Perl Documentation	Math::Utils(3)

       Math::Utils - Useful mathematical functions not in Perl.

	   use Math::Utils qw(:utility);    # Useful functions

	   # Base 10 and base 2	logarithms.
	   $scale = log10($pagewidth);
	   $bits = log2(1/$probability);

	   # Two uses of sign().
	   $d =	sign($z	- $w);

	   @ternaries =	sign(@coefficients);

	   # Using copysign(), $dist will be doubled negative or
	   # positive $offest, depending upon whether ($from - $to)
	   # is	positive or negative.
	   my $dist = copysign(2 * $offset, $from - $to);

	   # Change increment direction	if goal	is negative.
	   $incr = flipsign($incr, $goal);

	   # floor() and ceil()	functions.
	   $point = floor($goal);
	   $limit = ceil($goal);

	   # gcd() and lcm() functions.
	   $divisor = gcd(@multipliers);
	   $numerator =	lcm(@multipliers);

	   # Safer summation.
	   $tot	= fsum(@inputs);

	   # The remainders of n after successive divisions of b, or
	   # remainders	after a	set of divisions.
	   @rems = moduli($n, $b);


	   use Math::Utils qw(:compare);    # Make comparison functions	with tolerance.

	   # Floating point comparison function.
	   my $fltcmp =	generate_fltmcp(1.0e-7);

	   if (&$fltcmp($x0, $x1) < 0)

	   # Or	we can create single-operation comparison functions.
	   # Here we are only interested in the	greater	than and less than
	   # comparison	functions.
	   my(undef, undef,
	       $approx_gt, undef, $approx_lt) =	generate_relational(1.5e-5);


	   use Math::Utils qw(:polynomial);    # Basic polynomial ops

	   # Coefficient lists run from	0th degree upward, left	to right.
	   my @c1 = (1,	3, 5, 7, 11, 13, 17, 19);
	   my @c2 = (1,	3, 1, 7);
	   my @c3 = (1,	-1, 1)

	   my $c_ref = pl_mult(\@c1, \@c2);
	   $c_ref = pl_add($c_ref, \@c3);

       All functions can be exported by	name, or by using the tag that they're
       grouped under.

   utility tag
       Useful, general-purpose functions, including those that originated in
       FORTRAN and were	implemented in Perl in the module Math::Fortran, by J.
       A. R. Williams.

       There is	a name change -- copysign() was	known as sign()	in


	   $xlog10 = log10($x);
	   @xlog10 = log10(@x);

       Return the log base ten of the argument.	A list form of the function is
       also provided.


	   $xlog2 = log2($x);
	   @xlog2 = log2(@x);

       Return the log base two of the argument.	A list form of the function is
       also provided.


	   $s =	sign($x);
	   @valsigns = sign(@values);

       Returns -1 if the argument is negative, 0 if the	argument is zero, and
       1 if the	argument is positive.

       In list form it applies the same	operation to each member of the	list.


	   $ms = copysign($m, $n);
	   $s =	copysign($x);

       Take the	sign of	the second argument and	apply it to the	first. Zero is
       considered part of the positive signs.

	   copysign(-5,	0);  # Returns 5.
	   copysign(-5,	7);  # Returns 5.
	   copysign(-5,	-7); # Returns -5.
	   copysign(5, -7);  # Returns -5.

       If there	is only	one argument, return -1	if the argument	is negative,
       otherwise return	1. For example,	copysign(1, -4)	and copysign(-4) both
       return -1.


	   $ms = flipsign($m, $n);

       Multiply	the signs of the arguments and apply it	to the first. As with
       copysign(), zero	is considered part of the positive signs.

       Effectively this	means change the sign of the first argument if the
       second argument is negative.

	   flipsign(-5,	0);  # Returns -5.
	   flipsign(-5,	7);  # Returns -5.
	   flipsign(-5,	-7); # Returns 5.
	   flipsign(5, -7);  # Returns -5.

       If for some reason flipsign() is	called with a single argument, that
       argument	is returned unchanged.


	   $b =	floor($a/2);

	   @ilist = floor(@numbers);

       Returns the greatest integer less than or equal to its argument.	 A
       list form of the	function also exists.

	   floor(1.5, 1.87, 1);	       # Returns (1, 1,	1)
	   floor(-1.5, -1.87, -1);     # Returns (-2, -2, -1)


	   $b =	ceil($a/2);

	   @ilist = ceil(@numbers);

       Returns the lowest integer greater than or equal	to its argument.  A
       list form of the	function also exists.

	   ceil(1.5, 1.87, 1);	      #	Returns	(2, 2, 1)
	   ceil(-1.5, -1.87, -1);     #	Returns	(-1, -1, -1)


       Return a	sum of the values in the list, done in a manner	to avoid
       rounding	and cancellation errors. Currently this	is done	via Kahan's
       summation algorithm


       Return a	list of	values as probabilities.

       The function takes the list, and	creates	a new list by raising e	to
       each value. The function	then returns each value	divided	by the sum of
       the list. Each value in the new list is now a set of probabilities that
       sum to 1.0.

       The summation is	performed using	fsum() above.

       See Softmax function <>
       at Wikipedia.



       Uniformly, or linearly, scale a number either from one range to another
       range ("uniform_scaling()"), or to a default range of [0	.. 1]

	   @v =	uniform_scaling(\@original_range, \@new_range, @oldvalues);

       For example, these two lines are	equivalent, and	both return 0:

	   $y =	uniform_scaling([50, 100], [0, 1], 50);

	   $y =	uniform_01scaling([50, 100], 50);

       They may	also be	called with a list or array of numbers:

	   @cm_measures	= uniform_scaling([0, 10000], [0, 25400], @in_measures);

	   @melt_centigrade = uniform_scaling([0, 2000], [-273.15, 1726.85], \@melting_points);

       A number	that is	outside	the original bounds will be proportionally
       changed to be outside of	the new	bounds,	but then again having a	number
       outside the original bounds is probably an error	that should be checked
       before calling this function.




       Return the greatest common divisor (also	known as the highest common
       factor) of a list of integers. These are	simply synomyms:

	   $factor = gcd(@numbers);
	   $factor = hcf(@numbers);


       Return the least	common multiple	of a list of integers.

	   $factor = lcm(@values);


       Return the moduli of an integer after repeated divisions. The
       remainders are returned in a list from left to right.

	   @digits = moduli(1899, 10);	 # Returns (9, 9, 8, 1)
	   @rems = moduli(29, 3);	 # Returns (2, 0, 0, 1)

   compare tag
       Create comparison functions for floating	point (non-integer) numbers.

       Since exact comparisons of floating point numbers tend to be iffy, the
       comparison functions use	a tolerance chosen by you. You may then	use
       those functions from then on confident that comparisons will be

       If you do not provide a tolerance, a default tolerance of 1.49012e-8
       (approximately the square root of an Intel Pentium's machine epsilon
       <>)	will be	used.


       Returns a comparison function that will compare values using a
       tolerance that you supply. The generated	function will return -1	if the
       first argument compares as less than the	second,	0 if the two arguments
       compare as equal, and 1 if the first argument compares as greater than
       the second.

	   my $fltcmp =	generate_fltcmp(1.5e-7);

	   my(@xpos) = grep {&$fltcmp($_, 0) ==	1} @xvals;


       Returns a list of comparison functions that will	compare	values using a
       tolerance that you supply. The generated	functions will be the
       equivalent of the equal,	not equal, greater than, greater than or
       equal, less than, and less than or equal	operators.

	   my($eq, $ne,	$gt, $ge, $lt, $le) = generate_relational(1.5e-7);

	   my(@approx_5) = grep	{&$eq($_, 5)} @xvals;

       Of course, if you were only interested in not equal, you	could use:

	   my(undef, $ne) = generate_relational(1.5e-7);

	   my(@not_around5) = grep {&$ne($_, 5)} @xvals;

   polynomial tag
       Perform some polynomial operations on plain lists of coefficients.

	   # The coefficient lists are presumed	to go from low order to	high:
	   @coefficients = (1, 2, 4, 8);    # 1	+ 2x + 4x**2 + 8x**3

       In all functions	the coeffcient list is passed by reference to the
       function, and the functions that	return coefficients all	return
       references to a coefficient list.

       It is assumed that any leading zeros in the coefficient lists have
       already been removed before calling these functions, and	that any
       leading zeros found in the returned lists will be handled by the
       caller. This caveat is particularly important to	note in	the case of

       Although	these functions	are convenient for simple polynomial
       operations, for more advanced polynonial	operations Math::Polynomial is


       Returns either a	y-value	for a corresponding x-value, or	a list of
       y-values	on the polynomial for a	corresponding list of x-values,	using
       Horner's	method.

	   $y =	pl_evaluate(\@coefficients, $x);
	   @yvalues = pl_evaluate(\@coefficients, @xvalues);

	   @ctemperatures = pl_evaluate([-160/9, 5/9], @ftemperatures);

       The list	of X values may	also include X array references:

	   @yvalues = pl_evaluate(\@coefficients, @xvalues, \@primes, $x, [-1, -10, -100]);


	   ($y,	$dy, $ddy) = pl_dxevaluate(\@coefficients, $x);

       Returns p(x), p'(x), and	p"(x) of the polynomial	for an x-value,	using
       Horner's	method.	Note that unlike "pl_evaluate()" above,	the function
       can only	use one	x-value.

       If the polynomial is a linear equation, the second derivative value
       will be zero.  Similarly, if the	polynomial is a	simple constant, the
       first derivative	value will be zero.


	   $x =	[8, 3, 1];
	   $y =	[3, 1];

	   # Translating C<x**2	+ 3*x +	8> by C<x + 3> returns [26, 9, 1]
	   $z =	pl_translate($x, $y);

       Returns a polynomial transformed	by substituting	a polynomial variable
       with another polynomial.	 For example, a	simple linear translation by 1
       to the polynomial "x**3 + x**2 +	4*x + 4" would be accomplished by
       setting x = (y -	1); resulting in "x**3 - 2*x**2	+ 5*x".

	   $x =	[4, 4, 1, 1];
	   $y =	[-1, 1];
	   $z =	pl_translate($x, $y);	      #	Becomes	[0, 5, -2, 1]


	   $polyn_ref =	pl_add(\@m, \@n);

       Add two lists of	numbers	as though they were polynomial coefficients.


	   $polyn_ref =	pl_sub(\@m, \@n);

       Subtract	the second list	of numbers from	the first as though they were
       polynomial coefficients.


	   ($q_ref, $r_ref) = pl_div(\@numerator, \@divisor);

       Synthetic division for polynomials. Divides the first list of
       coefficients by the second list.

       Returns references to the quotient and the remainder.

       Remember	to check for leading zeros (which are rightmost	in the list)
       in the returned values. For example,

	   my @n = (4, 12, 9, 3);
	   my @d = (1, 3, 3, 1);

	   my($q_ref, $r_ref) =	pl_div(\@n, \@d);

       After division you will have returned "(3)" as the quotient, and	"(1,
       3, 0)" as the remainder.	In general, you	will want to remove the
       leading zero, or	for that matter	values within epsilon of zero, in the

	   my($q_ref, $r_ref) =	pl_div($f1, $f2);

	   # Remove any	leading	zeros (i.e., numbers smaller in
	   # magnitude than machine epsilon) in	the remainder.
	   my @remd = @{$r_ref};
	   pop @remd while (@remd and abs($remd[$#remd]) < $epsilon);

	   $f1 = $f2;
	   $f2 = [@remd];

       If $f1 and $f2 were to go through that bit of code again, not removing
       the leading zeros would lead to a divide-by-zero	error.

       If either list of coefficients is empty,	pl_div() returns undefs	for
       both quotient and remainder.


	   $m_ref = pl_mult(\@coefficients1, \@coefficients2);

       Returns the reference to	the product of the two multiplicands.


	   $poly_ref = pl_derivative(\@coefficients);

       Returns the derivative of a polynomial.


	   $poly_ref = pl_antiderivative(\@coefficients);

       Returns the antiderivative of a polynomial. The constant	value is
       always set to zero and will need	to be changed by the caller if a
       different constant is needed.

	 my @coefficients = (1,	2, -3, 2);
	 my $integral =	pl_antiderivative(\@coefficients);

	 # Integral needs to be	0 at x = 1.
	 my @coeff1 = @{$integral};
	 $coeff1[0] = -	pl_evaluate($integral, 1);

       John M. Gamble, "<jgamble at>"

       Math::Polynomial	for a complete set of polynomial operations, with the
       added convenience that objects bring.

       Among its other functions, List::Util has the mathematically useful
       functions max(),	min(), product(), sum(), and sum0().

       List::MoreUtils has the function	minmax().

       Math::Prime::Util has gcd() and lcm() functions,	as well	as vecsum(),
       vecprod(), vecmin(), and	vecmax(), which	are like the List::Util
       functions but which can force integer use, and when appropriate use

       Math::VecStat Likewise has min(), max(),	sum() (which can take as
       arguments array references as well as arrays), plus maxabs(), minabs(),
       sumbyelement(), convolute(), and	other functions.

       Please report any bugs or feature requests to "bug-math-util at", or	through	the web	interface at
       <>.  I will be
       notified, and then you'll automatically be notified of progress on your
       bug as I	make changes.

       This module is on Github	at <>.

       You can also look for information at:

       o   RT: CPAN's request tracker (report bugs here)


       o   MetaCPAN


       To J. A.	R. Williams who	got the	ball rolling with Math::Fortran.

       Copyright (c) 2017 John M. Gamble. All rights reserved. This program is
       free software; you can redistribute it and/or modify it under the same
       terms as	Perl itself.

perl v5.32.1			  2021-11-04			Math::Utils(3)


Want to link to this manual page? Use this URL:

home | help