FreeBSD Manual Pages

Math::Utils(3)	      User Contributed Perl Documentation	Math::Utils(3)

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

SYNOPSIS
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);

or

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)
{
}
else
{
}

#
# 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);

or

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);

EXPORT
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
Math::Fortran.

log10()

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

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

log2()

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

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

sign()

\$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.

copysign()

\$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.

flipsign()

\$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.

floor()

\$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)

ceil()

\$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)

fsum()

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
<https://en.wikipedia.org/wiki/Kahan_summation_algorithm>.

softmax()

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 <https://en.wikipedia.org/wiki/Softmax_function>
at Wikipedia.

uniform_scaling

uniform_01scaling

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

@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.

<https://stats.stackexchange.com/q/281164>

gcd

hcf

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);

lcm

Return the least	common multiple	of a list of integers.

\$factor = lcm(@values);

moduli()

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
consistent.

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
<https://en.wikipedia.org/wiki/Machine_epsilon>)	will be	used.

generate_fltcmp()

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;

generate_relational()

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
"pl_div()".

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

pl_evaluate()

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]);

pl_dxevaluate()

(\$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.

pl_translate()

\$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]

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

pl_sub()

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

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

pl_div()

(\$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
remainder.

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

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

pl_mult()

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

Returns the reference to	the product of the two multiplicands.

pl_derivative()

\$poly_ref = pl_derivative(\@coefficients);

Returns the derivative of a polynomial.

pl_antiderivative()

\$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 = -	pl_evaluate(\$integral, 1);

AUTHOR
John M. Gamble, "<jgamble at cpan.org>"

Math::Polynomial	for a complete set of polynomial operations, with the

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::BigInt.

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.

BUGS
Please report any bugs or feature requests to "bug-math-util at
rt.cpan.org", or	through	the web	interface at
<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Math-Utils>.  I will be
notified, and then you'll automatically be notified of progress on your
bug as I	make changes.

SUPPORT
This module is on Github	at <https://github.com/jgamble/Math-Utils>.

You can also look for information at:

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

<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Math-Utils>

o   MetaCPAN

<https://metacpan.org/release/Math-Utils>

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