to the MAPM Home Page
By: Michael C. Ring
View my article reprinted from the November 2001 issue of C/C++ Users Journal.
With the release of version 4.9.5, I have updated the license to allow distribution of modified library source code. In the DOCS directory of the distribution, there is a file 'license.txt' which should be inserted before any modified source files. Simply edit the 'license.txt' template accordingly, and permission is granted to distribute modified source code.
My Arbitrary Precision Math library is a set of functions that allow the user to perform math to any level of accuracy that is desired. The precision of a number is only limited by 'INT_MAX' and available memory. For a 16 bit compiler, a number may have 2^15 digits (or ~32,000). For a 32 bit compiler, a number may have 2^31 digits (or ~2.14E+9). See the README file (in the distribution as well as a link below) for a more complete discussion of the actual numerical limitations.
This library has a natural support for floating point values. From most of the other 'C' libraries I looked at, they seem to have a preference for integer only type math manipulations. (This library will also do integer only math if you desire.)
And if a library can only do integers, it can't do ...
Trig functions and other common C math library functions. This library will perform the following functions to any desired precision level : SQRT, CBRT, SIN, COS, TAN, ARC-SIN, ARC-COS, ARC-TAN, ARC-TAN2, LOG, LOG10, EXP, POW, SINH, COSH, TANH, ARC-SINH, ARC-COSH, ARC-TANH, FLOOR, CEIL, GCD, LCM, and also FACTORIAL. The full 'math.h' is not duplicated, though I think these are most of the important ones. My definition of what's important is what I've actually used in a real application.
This library also has a random number generator with a period of 1.0E+15, i.e. the generator will produce 1.0E+15 unique random numbers before the pattern repeats.
This library utilizes a fast multiplication algorithm. This results in much faster multiplications than the typical O(n^2) algorithm. It uses an FFT (fast fourier transform) based multiplication algorithm. This results in only O(n * Log2(n)) growth.
The library is written in 'C' and the distribution
includes all source code and documentation. It has been tested under
Linux (x86), FreeBSD, HP-UX, Sun Solaris, Venix, MAC OSX, DOS,
and Win 2000, NT, XP. GCC was the primary compiler used in the
Unix environment. For DOS/NT/XP, the MAPM library has been tested
with the the following compilers:
o) GCC (2.8.1, 2.95.2, and 3.2.3) for DOS (D.J. Delorie's DJGPP)
o) Borland C++ 5.x (32 bit) and Turbo C++ 3.0 (16 bit)
o) Microsoft Visual C++ 6.0 (32 bit) and Microsoft C 5.1, 8.00c (16 bit)
o) LCC-Win32 Ver 3.2/3.3
o) MINGW-32 Version mingw-1.0.1-20010726
o) Metrowerks CodeWarrior Pro 7.0
o) Watcom C/C++ 11.x, Open Watcom 1.0
o) DEV-C++ 5.0 Beta 8 Release 18.104.22.168
o) Digital Mars Compiler 8.49
o) National Instruments LabWindows CVI 6.0, 9.0
Great care was taken during design to make the library as portable as possible. If you are using a compiler not listed above, you should have minimal problems getting the library to compile on your system. If you compile the library with a compiler that I don't have access to, feel free to send me your makefile/build script and I'll include it with the next release.
NOTES ON A MICROSOFT COMPILER BUG IN Visual C++
7.x .NET 2003
There is a COMPILER BUG in Microsoft's Visual C++ 7.x (VS.NET 2003) which prevents a C++ MAPM application from compiling.
This only affects C++ applications. C applications are OK.
The compiler bug creates an error C2676 similar to this:
To work around this bug, go to http://www.microsoft.com
In the upper right corner of web page, search for "814455".
The results of the search will point you to an article on how to work around the problem.
MAPM IN A MULTI-THREADED APPLICATION :
Note that the default MAPM library is NOT thread safe. MAPM internal data structures could get corrupted if multiple MAPM functions are active at the same time. The user should guarantee that only one thread is performing MAPM functions. This can usually be achieved by a call to the operating system to obtain a 'semaphore' or 'critical code section' so the operating system will guarantee that only one MAPM thread will be active at a time.
Martin Pfingstl (Martin.Pfingstl@epost.de) created a set of stand-alone function wrappers so the MAPM library is thread-safe when using these functions. The thread-safe functions currently only work with Micosoft's compiler. As other users send me compiler specific thread-safe functions, I'll add them to the distribution.
NOTE: As of MAPM Version 4.7 , the thread safe function wrappers are included in the distribution. I will leave this link here for users that are still using older versions of MAPM but need the thread safe functions.
MAPM WITH COMPLEX NUMBERS :
Ivano Primi (firstname.lastname@example.org) has graciously submitted
a set of wrapper functions so MAPM can perform arbitrary precision arithmetic
on complex numbers. His library is not part of MAPM, it is a stand-alone
library which just calls the MAPM functions.
The (Unix and Win) complex number library can be found below in the download
section, the files begin with
Many thanks to Ivano for his work, since a few other people have asked about
complex number capability.
Orion Sky Lawlor (email@example.com) has added a very
nice C++ wrapper class to m_apm.h. This C++ class will have no effect
if you just use a normal C compiler. The library will operate as
before with no user impacts.
The syntax is the same as if you were just writing
normal code, but all the computations will be performed with the high
precision math library, using the new 'datatype' MAPM.
Using the C++ wrapper
allows you to do things like:
Using MAPM : (If you have a project or
application which uses MAPM and would like to have a link here to
your S/W or Web page, please feel free to let me know.)
By Michael Ring
By Lenimar N.
David Morrison (firstname.lastname@example.org
Martin Pfingstl (Martin.Pfingstl@epost.de)
'.zip' files should be unzipped such that the directory structure is
maintained (option '-d' on the command line : pkunzip -d
// Compute the factorial of the integer n
MAPM Factorial(MAPM n)
for (i=2; i<=n; i++)
MAPM a, f; // a,f are uninitialized (value is undefined)
MAPM b = "4.5e12"; // b is 4.5 trillion
MAPM c = 3; // c is now three
MAPM d = -6.1; // d is now minus six point one
MAPM e = c; // e is now three
MAPM array; // use normal array notation
e = -c * (23.9022 - b * d);
a = sqrt(b);
f = cbrt(e);
for (ii=0; ii < 8; ii++)
array[ii] = sin(ii + 0.21) * exp(-ii / e);
for (jj=0; jj < 4; jj++)
array2d[ii][jj] = array[ii] - sqrt(jj * 17.7654 + 2 * c);
c = "1.0e+9131";
d = log10(c);
e = sqrt(fabs(d));
/* quick and dirty example with output */
* Note the use of literal character strings as constants.
* This allows the user to specify constants that cannot be
* represented by a standard C datatype, such as a number with
* 200 digits or a number with a very large or small exponent
* (i.e., 6.21E-3714).
MAPM u, v, w, x, y, z; // arbitrary precision datatype
m_apm_cpp_precision(50); // set MINIMUM precision level
// for all calculations
x = 9.34231;
y = -21;
z = "-8.982349249829824921479824924792347921E-17";
w = (82.30421 + sin(x / "21.11") / exp(y * 0.0726426))
* "4.32917E-2" / z;
v = "3.742416" * log(-w);
u = sqrt(v) + cbrt(v);
x.toString(obuf, 50); printf("x = [%s] \n",obuf);
y.toString(obuf, 50); printf("y = [%s] \n",obuf);
z.toString(obuf, 50); printf("z = [%s] \n",obuf);
w.toString(obuf, 50); printf("w = [%s] \n",obuf);
v.toString(obuf, 50); printf("v = [%s] \n",obuf);
u.toString(obuf, 50); printf("u = [%s] \n",obuf);
Output from above code sample code :
x = [9.34231000000000000000000000000000000000000000000000E+0]
y = [-2.10000000000000000000000000000000000000000000000000E+1]
z = [-8.98234924982982492147982492479234792100000000000000E-17]
w = [-4.06165846135776503301770738763183914451375637893923E+16]
v = [1.43121038693447060414449698088102300924570797933606E+2]
u = [1.71941170788317776083850581271655444461072359345223E+1]
Fitting [Version 1.2 December 9 2007]
This software will allow the user to curve fit any number of x,y
data samples to an Nth order polynomial. Currently, the software
will support order 'N' from 1-48. Higher values of polynomial
order (> 48) can easily be obtained by simple modifications to
the source. This curve fitting software assumes you already
have the MAPM library available. (See below to download the
Lua Binding for
Lua is a powerful, light-weight programming language designed for extending
applications. Lua is also frequently used as a general purpose, stand-alone
language. Lua combines simple procedural syntax (similar to Pascal) with
powerful data description constructs based on associative arrays and extensible
sematics. Lua is dynamically typed, interpretted from bytecodes, and has
automatic memory management with garbage collection, making it ideal for
configuration, scripting, and rapid prototyping.
CHICKEN - A practical and portable Scheme system.
CHICKEN is a compiler for the Scheme programming language. CHICKEN produces
portable, efficient C, supports almost all of the current Scheme language
standard, R5RS and includes many enhancements and extensions. CHICKEN
runs on MacOS X, Windows, and many Unix flavours.
Linear Algebra -- Version 3.0 (*)
My application is called "Computational Linear Algebra --
Version 3.0" (*). I hope it will be concluded and uploaded to
ftp.simtel.net by December 2000. I'm testing it and rewriting
some functions presently.
It is an ambitious project, I've been thinking about it for years.
Given an n x n complex matrix, the CLA provides important
information about it: determinant, inverse, characteristic and
minimal polynomials, eigenvalues, eigenvectors, Jordan canonical
(If the reader studies Mathematics, I say simply: "The CLA program
calculates the Jordan canonical form of a n x n complex matrix"
and this is all! It's a difficult calculation. As far as I know
the all-mighty Mathematica cannot calculate Jordan's form of a
simple 7 x 7 matrix, for example. It calculates it only for small
matrices. The Jordan form is a very important theme from Linear
Algebra and its applications.)
It is being tested by using GCC and by Borland's C.
Arbitrary precision is important to calculate with security all
of the complex roots of a polynomial equation of high degree.
Handling big integer numbers is very important also.
A little example:
Let M be the complex matrix:
20+9i 7+21i -12-35i 7-2i -19 -15+7i -20-22i
32-27i 10-29i -17+19i -29-13i -31+38i 30+10i 15-6i
24+i -10-33i -37-i -29+26i 35+33i -36+28i -34+25i
1-6i 33+26i 34-i -21-5i -13-24i -3-29i 33+19i
-20-27i 35+17i -8+23i -2-8i -7-31i -10-13i -23+11i
-18+18i -16-28i -9+32i -11+20i 7+11i 20-22i 13-2i
32-8i 34+35i -18-9i 7-17i 21-11i -29-30i -21+36i
Using CLA (that uses the MAPM library) one can easily calculate
its determinant. It's equal to
-347964138525 + 420266812927i
Please note the huge integers above!
(*) an out of date version (9 years ago) is available at
Codon Usage and Bias Analysis Version 1.7.0
http://.... to be announced
CUBA is a cross-platform program (Windows NT/9x, various
unixes) for the analysis of genetic data in the form of
codon usage tables. MAPM is used for multinomial probability
calculations on gene sequence data. This involves large
factorials (up to 8000! so far), division, logs, and Nth
The multinomial expression that used is:
[N! / (n1! * n2! * ... nT!)] * (p1^n1 * p2^n2 * ... * pT^nT)
where N is the total number of codons in the gene sequence
(which varies between 200 and 8000 for the data so far);
n1, n2 etc are the counts for each of the 61 possible codons
that we look at; and p1, p2 etc are the expected counts for
codons calculated in various ways for different versions of
In this command interpreter, it is possible to
use several expression evaluators, and I made one
using the MAPM library. See one of the above links
to get more details.
-- Version 3.1 (*)
ChaosPro is a MDI fractal generator compatible with FractInt and
UltraFractal. It can read FractInt's *.par, *.frm, *.ifs,
*.l and *.map files, and UltraFractal's *.upr, *.uxf, *.ufm
and *.ucl files. It is completely based on 24 bit color and thus can
create smooth true color images. Its palette editor lets you have
full control over the colors. With its keyframing technique and
it's spline interpolation algorithm it can create smooth (AVI)
animations of any parameter. It can 3D transform 2D fractals
(height fields). You can write your own formulas using the built
in language, which gets compiled in real time into ready to run
optmized machine code. The compiler natively knows about complex
and quaternion numbers, which enables it to produce Quaternions
(true 3D fractals). ChaosPro has support for layers (similar to
Photoshop) which allows you to merge different fractals and thus
to combine coloring modes.
And why does ChaosPro need MAPM?
ChaosPro allows the user to zoom in. In addition to that, it
allows the user to calculate animations based on any parameters.
So if parameter values responsible for zooming would be only
double (or 80 bit TEMPREAL) values, then zooming in or creating
animations would not work if you zoomed in about 40 times.
Calculating the exact point where to zoom in would be inaccurate
and thus would be very irritating.
Creating zoom animations would be even worse. The animation
system in ChaosPro uses cubic splines for smooth interpolation,
so ChaosPro needs to solve linear equation systems in order to
calculate all the coefficients of that cubic spline. That means it
needs high precision math. ChaosPro uses MAPM to make it possible
to create animations.
(*) version 3.1 will be available in summer 2003.
Follow the links below to view the README
or to download the MAPM library. Ivano Primi's complex number wrapper package
are the files beginning with
... If you need complex numbers, then you need
the MAPM-... files as well as MAPMX-... files. The complex number wrapper
package runs on top of MAPM, they are two independent libraries.
Ivano Primi (email@example.com) has graciously submitted a set of wrapper functions so MAPM can perform arbitrary precision arithmetic on complex numbers. His library is not part of MAPM, it is a stand-alone library which just calls the MAPM functions. The (Unix and Win) complex number library can be found below in the download section, the files begin with MAPMX- ... Many thanks to Ivano for his work, since a few other people have asked about complex number capability.
Orion Sky Lawlor (firstname.lastname@example.org) has added a very nice C++ wrapper class to m_apm.h. This C++ class will have no effect if you just use a normal C compiler. The library will operate as before with no user impacts.
The syntax is the same as if you were just writing normal code, but all the computations will be performed with the high precision math library, using the new 'datatype' MAPM.
Using the C++ wrapper allows you to do things like:
Projects/Applications Using MAPM :
(If you have a project or application which uses MAPM and would like to have a link here to your S/W or Web page, please feel free to let me know.)
By Michael Ring
By Lenimar N. Andrade (email@example.com)
By David Morrison (firstname.lastname@example.org
By Michael Bedward (email@example.com)
By Jean-Marc Drezet
By Martin Pfingstl (Martin.Pfingstl@epost.de)
The '.zip' files should be unzipped such that the directory structure is maintained (option '-d' on the command line : pkunzip -d mapm-$$$.zip)