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

#
# Safe(r) 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 ten 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>.

moduli()

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

@rems = moduli(29, 3);	 # Returns (2, 0, 0, 1)
@digits = moduli(1899, 10);	 # Returns (9, 9, 8, 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 particulary 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()

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

You can also use	lists of the X values or X array references:

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

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.

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.

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

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   AnnoCPAN: Annotated CPAN documentation

<http://annocpan.org/dist/Math-Utils>

o   CPAN	Ratings

<http://cpanratings.perl.org/d/Math-Utils>

o   Search CPAN

<http://search.cpan.org/dist/Math-Utils/>

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

Copyright 2015 by John M. Gamble

This program is free software; you can redistribute it and/or modify it
under the terms of the the Artistic License (2.0). You may obtain a
copy of the full	license	at: