From 73960e2a46a54fbcdf792f834e28ffa48dff4306 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Mon, 26 Sep 2011 17:00:44 +0000 Subject: [PATCH] Giant file and directory rename: changed directory name from math to multiprecision and updated code to match. [SVN r74579] --- Jamroot.jam | 9 + boost-build.jam | 72 + config/Jamfile.v2 | 45 + config/has_e_float.cpp | 17 + config/has_gcc_visibility.cpp | 13 + config/has_gmp.cpp | 7 + config/has_gmpxx.cpp | 7 + config/has_long_double_support.cpp | 10 + config/has_mpfr.cpp | 7 + config/has_mpfr_class.cpp | 14 + config/has_mpreal.cpp | 14 + config/has_ntl_rr.cpp | 12 + doc/Jamfile.v2 | 67 + doc/big_number.qbk | 207 +++ doc/html/boost_bignumbers/intro.html | 44 + doc/html/boost_bignumbers/ref.html | 40 + .../boost_bignumbers/ref/backendconc.html | 38 + doc/html/boost_bignumbers/ref/bignum.html | 151 ++ doc/html/boost_bignumbers/tut.html | 44 + doc/html/boost_bignumbers/tut/ints.html | 146 ++ doc/html/boost_bignumbers/tut/reals.html | 158 +++ doc/html/boostbook.css | 588 ++++++++ doc/html/images/blank.png | Bin 0 -> 374 bytes doc/html/images/caution.png | Bin 0 -> 1250 bytes doc/html/images/caution.svg | 68 + doc/html/images/draft.png | Bin 0 -> 17454 bytes doc/html/images/home.png | Bin 0 -> 358 bytes doc/html/images/home.svg | 26 + doc/html/images/important.png | Bin 0 -> 722 bytes doc/html/images/important.svg | 25 + doc/html/images/next.png | Bin 0 -> 336 bytes doc/html/images/next.svg | 19 + doc/html/images/next_disabled.png | Bin 0 -> 1110 bytes doc/html/images/note.png | Bin 0 -> 490 bytes doc/html/images/note.svg | 33 + doc/html/images/prev.png | Bin 0 -> 334 bytes doc/html/images/prev.svg | 19 + doc/html/images/prev_disabled.png | Bin 0 -> 1109 bytes doc/html/images/tip.png | Bin 0 -> 449 bytes doc/html/images/tip.svg | 84 ++ doc/html/images/toc-blank.png | Bin 0 -> 318 bytes doc/html/images/toc-minus.png | Bin 0 -> 259 bytes doc/html/images/toc-plus.png | Bin 0 -> 264 bytes doc/html/images/up.png | Bin 0 -> 370 bytes doc/html/images/up.svg | 19 + doc/html/images/up_disabled.png | Bin 0 -> 1115 bytes doc/html/images/warning.png | Bin 0 -> 1241 bytes doc/html/images/warning.svg | 23 + doc/html/index.html | 53 + test/Jamfile.v2 | 189 +++ test/big_number_concept_check.cpp | 100 ++ test/linpack-benchmark.cpp | 1257 +++++++++++++++++ test/test_arithmetic.cpp | 894 ++++++++++++ test/test_numeric_limits.cpp | 173 +++ 54 files changed, 4692 insertions(+) create mode 100644 Jamroot.jam create mode 100644 boost-build.jam create mode 100644 config/Jamfile.v2 create mode 100644 config/has_e_float.cpp create mode 100644 config/has_gcc_visibility.cpp create mode 100644 config/has_gmp.cpp create mode 100644 config/has_gmpxx.cpp create mode 100644 config/has_long_double_support.cpp create mode 100644 config/has_mpfr.cpp create mode 100644 config/has_mpfr_class.cpp create mode 100644 config/has_mpreal.cpp create mode 100644 config/has_ntl_rr.cpp create mode 100644 doc/Jamfile.v2 create mode 100644 doc/big_number.qbk create mode 100644 doc/html/boost_bignumbers/intro.html create mode 100644 doc/html/boost_bignumbers/ref.html create mode 100644 doc/html/boost_bignumbers/ref/backendconc.html create mode 100644 doc/html/boost_bignumbers/ref/bignum.html create mode 100644 doc/html/boost_bignumbers/tut.html create mode 100644 doc/html/boost_bignumbers/tut/ints.html create mode 100644 doc/html/boost_bignumbers/tut/reals.html create mode 100644 doc/html/boostbook.css create mode 100644 doc/html/images/blank.png create mode 100644 doc/html/images/caution.png create mode 100644 doc/html/images/caution.svg create mode 100644 doc/html/images/draft.png create mode 100644 doc/html/images/home.png create mode 100644 doc/html/images/home.svg create mode 100644 doc/html/images/important.png create mode 100644 doc/html/images/important.svg create mode 100644 doc/html/images/next.png create mode 100644 doc/html/images/next.svg create mode 100644 doc/html/images/next_disabled.png create mode 100644 doc/html/images/note.png create mode 100644 doc/html/images/note.svg create mode 100644 doc/html/images/prev.png create mode 100644 doc/html/images/prev.svg create mode 100644 doc/html/images/prev_disabled.png create mode 100644 doc/html/images/tip.png create mode 100644 doc/html/images/tip.svg create mode 100644 doc/html/images/toc-blank.png create mode 100644 doc/html/images/toc-minus.png create mode 100644 doc/html/images/toc-plus.png create mode 100644 doc/html/images/up.png create mode 100644 doc/html/images/up.svg create mode 100644 doc/html/images/up_disabled.png create mode 100644 doc/html/images/warning.png create mode 100644 doc/html/images/warning.svg create mode 100644 doc/html/index.html create mode 100644 test/Jamfile.v2 create mode 100644 test/big_number_concept_check.cpp create mode 100644 test/linpack-benchmark.cpp create mode 100644 test/test_arithmetic.cpp create mode 100644 test/test_numeric_limits.cpp diff --git a/Jamroot.jam b/Jamroot.jam new file mode 100644 index 00000000..c8019258 --- /dev/null +++ b/Jamroot.jam @@ -0,0 +1,9 @@ + +import modules ; + +local boost = [ modules.peek : BOOST ] ; + +project sandbox : requirements $(boost) ; + +# This seems to prevent some Boost.Build errors that otherwise occur :-( +use-project /boost : $(boost) ; diff --git a/boost-build.jam b/boost-build.jam new file mode 100644 index 00000000..02b750a1 --- /dev/null +++ b/boost-build.jam @@ -0,0 +1,72 @@ +# Copyright Rene Rivera 2007. +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# For instructions see Jamfile.v2, or "bjam --help". + +local rule if-has-file ( file + : dir * ) +{ + local result ; + if $(dir) + { + result = [ GLOB $(dir) : $(file) ] ; + } + return $(result[1]:P) ; +} + +#~ Attempts to find the Boost source tree... + +local boost-src = [ if-has-file LICENSE_1_0.txt : + [ MATCH --boost=(.*) : $(ARGV) ] + $(BOOST) + $(BOOST_ROOT) + $(.boost-build-file:D)/../boost + $(.boost-build-file:D)/../Trunk + ] ; + +# error handling: +if ! $(boost-src) +{ + ECHO Unable to find the Boost source tree in the locations searched. ; + ECHO Try setting the environment variable BOOST to point to your ; + ECHO Boost tree, or else invoke bjam with the --boost=path option. ; + ECHO The Boost include path will not be automatically set. ; + ECHO The paths searched were [ MATCH --boost=(.*) : $(ARGV) ] $(BOOST) $(.boost-build-file:D)/../boost $(.boost-build-file:D)/../Trunk ; + ECHO But the file LICENSE_1_0.txt was not found in any of them ; +} + +#~ Attempts to find the Boost.Build files... + +local boost-build-src = [ if-has-file bootstrap.jam : + [ MATCH --boost-build=(.*) : $(ARGV) ] + $(BOOST_BUILD_PATH) + $(BOOST_BUILD) + $(boost-src)/tools/build/v2 + ] ; + +# error handling: +if ! $(boost-build-src) +{ + ECHO Unable to find the Boost.Build source tree in the locations searched. ; + ECHO Try setting the environment variable BOOST_BUILD to point to your ; + ECHO Boost.Build tree, or else invoke bjam with the --boost-build=path option. ; + ECHO The paths searched were [ MATCH --boost-build=(.*) : $(ARGV) ] $(BOOST_BUILD_PATH) $(BOOST_BUILD) $(boost-src)/tools/build/v2 ; + ECHO But bootstrap.jam was not found in any of these ; + ECHO More failures will very likely follow... ; +} + +#~ Set some common vars to refer to the Boost sources... + +BOOST ?= $(boost-src) ; +BOOST_ROOT ?= $(boost-src) ; + +#~ And load up Boost.Build... + +boost-build $(boost-build-src) ; + + + + + diff --git a/config/Jamfile.v2 b/config/Jamfile.v2 new file mode 100644 index 00000000..832e2936 --- /dev/null +++ b/config/Jamfile.v2 @@ -0,0 +1,45 @@ +# copyright John Maddock 2008 +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt. + +import modules ; +import path ; + +local ntl-path = [ modules.peek : NTL_PATH ] ; +local gmp_path = [ modules.peek : GMP_PATH ] ; +local mpfr_path = [ modules.peek : MPFR_PATH ] ; +local e_float_path = [ modules.peek : BOOST_E_FLOAT_PATH ] ; + +if ! $(e_float_path) +{ + e_float_path = ../../../../e_float ; +} + +ECHO $(BOOST_E_FLOAT_PATH) + +obj has_long_double_support : has_long_double_support.cpp ; +obj has_mpfr_class : has_mpfr_class.cpp : + $(gmp_path) $(gmp_path)/mpfr $(gmp_path)/gmpfrxx ; +obj has_mpreal : has_mpreal.cpp : + $(gmp_path) $(gmp_path)/mpfr $(gmp_path)/mpfrc++ ; +obj has_ntl_rr : has_ntl_rr.cpp : $(ntl-path)/include ; +obj has_gmpxx : has_gmpxx.cpp : + $(gmp_path) $(gmp_path)/mpfr $(gmp_path)/gmpfrxx ; +obj has_gcc_visibility : has_gcc_visibility.cpp : + gcc:-fvisibility=hidden gcc:-Werror ; +obj has_e_float : has_e_float.cpp : $(e_float_path) ; +obj has_gmp : has_gmp.cpp : + $(gmp_path) $(gmp_path)/mpfr $(gmp_path)/gmpfrxx ; +obj has_mpfr : has_mpfr.cpp : + $(mpfr_path) $(gmp_path)/mpfr $(gmp_path)/gmpfrxx ; + +explicit has_long_double_support ; +explicit has_mpfr_class ; +explicit has_mpreal ; +explicit has_ntl_rr ; +explicit has_gmpxx ; +explicit has_gcc_visibility ; +explicit has_e_float ; +explicit has_gmp ; +explicit has_mpfr ; diff --git a/config/has_e_float.cpp b/config/has_e_float.cpp new file mode 100644 index 00000000..8cadc5c6 --- /dev/null +++ b/config/has_e_float.cpp @@ -0,0 +1,17 @@ +// Copyright John Maddock 2011. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +#ifdef _MSC_VER +# pragma warning (disable : 4100) // unreferenced formal parameter +#endif + +#define E_FLOAT_TYPE_EFX + +#include +#include +#include + + diff --git a/config/has_gcc_visibility.cpp b/config/has_gcc_visibility.cpp new file mode 100644 index 00000000..6c7d6f91 --- /dev/null +++ b/config/has_gcc_visibility.cpp @@ -0,0 +1,13 @@ +// Copyright John Maddock 20010. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef __GNUC__ +# error "This is a GCC specific test case". +#endif + +int main() +{ + return 0; +} diff --git a/config/has_gmp.cpp b/config/has_gmp.cpp new file mode 100644 index 00000000..582f0027 --- /dev/null +++ b/config/has_gmp.cpp @@ -0,0 +1,7 @@ +// Copyright John Maddock 2008. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include + diff --git a/config/has_gmpxx.cpp b/config/has_gmpxx.cpp new file mode 100644 index 00000000..edf62d8c --- /dev/null +++ b/config/has_gmpxx.cpp @@ -0,0 +1,7 @@ +// Copyright John Maddock 2008. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include + diff --git a/config/has_long_double_support.cpp b/config/has_long_double_support.cpp new file mode 100644 index 00000000..d314cf38 --- /dev/null +++ b/config/has_long_double_support.cpp @@ -0,0 +1,10 @@ +// Copyright John Maddock 2008. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include + +#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +#error "long double support is not supported by Boost.Math on this Plaform: the long double version of the TR1 library will not be built." +#endif diff --git a/config/has_mpfr.cpp b/config/has_mpfr.cpp new file mode 100644 index 00000000..49d12a0b --- /dev/null +++ b/config/has_mpfr.cpp @@ -0,0 +1,7 @@ +// Copyright John Maddock 2008. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include + diff --git a/config/has_mpfr_class.cpp b/config/has_mpfr_class.cpp new file mode 100644 index 00000000..8eb3c7b2 --- /dev/null +++ b/config/has_mpfr_class.cpp @@ -0,0 +1,14 @@ +// Copyright John Maddock 2008. +// Copyright Paul A. Britow 2009 +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifdef _MSC_VER +# pragma warning (disable : 4127) // conditional expression is constant +# pragma warning (disable : 4800) // 'int' : forcing value to bool 'true' or 'false' (performance warning) +# pragma warning (disable : 4512) // assignment operator could not be generated +#endif + +#include + diff --git a/config/has_mpreal.cpp b/config/has_mpreal.cpp new file mode 100644 index 00000000..8ee8897d --- /dev/null +++ b/config/has_mpreal.cpp @@ -0,0 +1,14 @@ +// Copyright John Maddock 2008. +// Copyright Paul A. Britow 2009 +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifdef _MSC_VER +# pragma warning (disable : 4127) // conditional expression is constant +# pragma warning (disable : 4800) // 'int' : forcing value to bool 'true' or 'false' (performance warning) +# pragma warning (disable : 4512) // assignment operator could not be generated +#endif + +#include + diff --git a/config/has_ntl_rr.cpp b/config/has_ntl_rr.cpp new file mode 100644 index 00000000..f3844217 --- /dev/null +++ b/config/has_ntl_rr.cpp @@ -0,0 +1,12 @@ +// Copyright John Maddock 2008. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +#ifdef _MSC_VER +# pragma warning (disable : 4100) // unreferenced formal parameter +#endif + +#include + diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 new file mode 100644 index 00000000..2f00f026 --- /dev/null +++ b/doc/Jamfile.v2 @@ -0,0 +1,67 @@ + +# Copyright John Maddock 2011. Use, modification, and distribution are +# subject to the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +using quickbook ; + +path-constant images_location : html ; + +xml big_number : big_number.qbk ; +boostbook standalone + : + big_number + : + # Path for links to Boost: + #boost.root=../../../../.. + + # Some general style settings: + table.footnote.number.format=1 + footnote.number.format=1 + html.stylesheet=boostbook.css + + # HTML options first: + # Use graphics not text for navigation: + navig.graphics=1 + # How far down we chunk nested sections, basically all of them: + chunk.section.depth=10 + # Don't put the first section on the same page as the TOC: + chunk.first.sections=10 + # How far down sections get TOC's + toc.section.depth=10 + # Max depth in each TOC: + toc.max.depth=4 + # How far down we go with TOC's + #generate.section.toc.level=10 + # Index on type: + index.on.type=1 + + # PDF Options: + # TOC Generation: this is needed for FOP-0.9 and later: + fop1.extensions=0 + pdf:xep.extensions=1 + # TOC generation: this is needed for FOP 0.2, but must not be set to zero for FOP-0.9! + pdf:fop.extensions=0 + pdf:fop1.extensions=0 + # No indent on body text: + pdf:body.start.indent=0pt + # Margin size: + pdf:page.margin.inner=0.5in + # Margin size: + pdf:page.margin.outer=0.5in + # Paper type = A4 + pdf:paper.type=A4 + # Yes, we want graphics for admonishments: + admon.graphics=1 + # Set this one for PDF generation *only*: + # default pnd graphics are awful in PDF form, + # better use SVG's instead: + pdf:admon.graphics.extension=".svg" + pdf:use.role.for.mediaobject=1 + pdf:preferred.mediaobject.role=print + pdf:img.src.path=$(images_location)/ + pdf:draft.mode="no" + pdf:boost.url.prefix=http://www.boost.org/doc/libs/release/libs/math/doc/sf_and_dist/html + ; + +install pdf-install : standalone : . PDF ; diff --git a/doc/big_number.qbk b/doc/big_number.qbk new file mode 100644 index 00000000..4ccfb199 --- /dev/null +++ b/doc/big_number.qbk @@ -0,0 +1,207 @@ +[/ + Copyright 2011 John Maddock. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt). +] + +[library Boost.BigNumbers + [quickbook 1.5] + [copyright 2011 John Maddock] + [purpose Big Number library] + [license + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + [@http://www.boost.org/LICENSE_1_0.txt]) + ] + [authors [authors, various]] + [last-revision $Date: 2011-07-08 18:51:46 +0100 (Fri, 08 Jul 2011) $] +] + +[section:intro Introduction] + +The Big Number library comes in two distinct parts: an expression template enabled front end `big_number` +that handles all the operator overloading, expression evaluation optimization, and code reduction, and +a selection of backends that implement the actual arithmetic operations, and need conform only to the +reduced interface requirements of the front end. + +[endsect] + +[section:tut Tutorial] + +In order to use this library you need to make two choices: what kind of number do I want, and +which backend do I want to perform the actual arithmetic? + +[section:ints Integer Types] + +The following backends provide integer arithmetic: + +[table +[[Backend Type][Header][Radix][Dependencies][Pros][Cons]] +[[`gmp_int`][boost/math/big_number/gmp.hpp][2][GMP][Very fast and efficient backend.][Dependency on GNU licenced GMP library.]] +] + +[h4 gmp_int] + + namespace boost{ namespace math{ + + class gmp_int; + + typedef big_number mpz_int; + + }} // namespaces + +The `gmp_int` backend is used via the typedef `boost::math::mpz_int`. It acts as a thin wrapper around the GMP `mpz_t` +to provide an integer type that is a drop-in replacement for the native C++ integer types, but with unlimited precision. + +[h5 Example:] + + #include + + boost::math::mpz_int v = 1; + + // Do some arithmetic: + for(unsigned i = 1; i <= 1000; ++i) + v *= i; + + std::cout << i << std::endl; // prints 1000! + +[endsect] + +[section:reals Real Numbers] + +The following backends provide real number arithmetic: + +[table +[[Backend Type][Header][Radix][Dependencies][Pros][Cons]] +[[`gmp_real`][boost/math/big_number/gmp.hpp][2][GMP][Very fast and efficient backend.][Dependency on GNU licenced GMP library.]] +] + +[h4 gmp_real] + + namespace boost{ namespace math{ + + template + class gmp_real; + + typedef big_number > mpf_real_50; + typedef big_number > mpf_real_100; + typedef big_number > mpf_real_500; + typedef big_number > mpf_real_1000; + typedef big_number > mpf_real; + + }} // namespaces + +The `gmp_real` backend is used in conjunction with `big_number`: It acts as a thin wrapper around the GMP `mpf_t` +to provide an real-number type that is a drop-in replacement for the native C++ floating-point types, but with +much greater precision. + +Type `gmp_real` can be used at fixed precision by specifying a non-zero `Digits10` template parameter, or +at variable precision by setting the template argument to zero. The typedefs mpf_real_50, mpf_real_100, +mpf_real_500, mpf_real_1000 provide arithmetic types at 50, 100, 500 and 1000 decimal digits precision +respectively. The typedef mpf_real provides a variable precision type whose precision can be controlled via the +`big_number`'s member functions. + +[h5 example:] + + #include + + boost::math::gmp_real a = 2; + boost::math::gmp_real::default_precision(1000); + std::cout << boost::math::gmp_real::default_precision() << std::endl; + std::cout << sqrt(a) << std::endl; // print root-2 + +[endsect] + +[endsect] + +[section:ref Reference] + +[section:bignum big_number] + +[h4 Synopsis] + + namespace boost{ namespace math{ + + template + class big_number + { + big_number(); + big_number(see-below); + big_number& operator=(see-below); + /* Other number-type operators here */ + // string conversion: + std::string str()const; + // precision control: + static unsigned default_precision(); + static void default_precision(unsigned digits10); + unsigned precision()const; + void precision(unsigned digits10); + // Comparison: + int compare(const big_number& o)const; + template + typename enable_if, int>::type compare(const V& o)const; + }; + + }} // namespaces + +[h4 Description] + + big_number(); + big_number(see-below); + big_number& operator=(see-below); + +Type `big_number` is default constructible, and copy both constructible and assignable from: + +* Itself. +* An expression template which is the result of one of the arithmetic operators. +* Any builtin arithmetic type. +* A `std::string` or any type which is convertible to `const char*`. + + /* Other number-type operators here */ + +The following arithmetic operations are support for real-numbered types: + +* Binary +, -, *, /, +=, -=, *=, /=, ==, !=, <=, >=, <, >. +* Unary +, -. + +For integer types the following operators are also supported: + +Binary %, %=. + +(More to follow!!) + +Note that the result of the binary +, -, *, / and % operations is an expression template of "unmentionable type". + + std::string str()const; + +Returns the number formatted as a string (TODO: enable custom precision). + + static unsigned default_precision(); + static void default_precision(unsigned digits10); + unsigned precision()const; + void precision(unsigned digits10); + +These functions are only available if the Backend template parameter supports runtime changes to precision. They get and set +the default precision and the precision of *this respectively. + + int compare(const big_number& o)const; + template + typename enable_if, int>::type compare(const V& other)const; + +Returns: + +* A value less that 0 for *this < other +* A value greater that 0 for *this > other +* Zero for *this == other + +[endsect] + +[section:backendconc Backend Requirements] + +TODO, big boring job!! + +[endsect] + +[endsect] + diff --git a/doc/html/boost_bignumbers/intro.html b/doc/html/boost_bignumbers/intro.html new file mode 100644 index 00000000..ee77f4b1 --- /dev/null +++ b/doc/html/boost_bignumbers/intro.html @@ -0,0 +1,44 @@ + + + +Introduction + + + + + + + + +
+
+
+PrevUpHomeNext +
+
+ +

+ The Big Number library comes in two distinct parts: an expression template + enabled front end big_number + that handles all the operator overloading, expression evaluation optimization, + and code reduction, and a selection of backends that implement the actual arithmetic + operations, and need conform only to the reduced interface requirements of + the front end. +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bignumbers/ref.html b/doc/html/boost_bignumbers/ref.html new file mode 100644 index 00000000..c6a81e2f --- /dev/null +++ b/doc/html/boost_bignumbers/ref.html @@ -0,0 +1,40 @@ + + + +Reference + + + + + + + + +
+
+
+PrevUpHomeNext +
+ + + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bignumbers/ref/backendconc.html b/doc/html/boost_bignumbers/ref/backendconc.html new file mode 100644 index 00000000..44dd13af --- /dev/null +++ b/doc/html/boost_bignumbers/ref/backendconc.html @@ -0,0 +1,38 @@ + + + +Backend Requirements + + + + + + + +
+
+
+PrevUpHome +
+
+ +

+ TODO, big boring job!! +

+
+ + + +
+
+
+PrevUpHome +
+ + diff --git a/doc/html/boost_bignumbers/ref/bignum.html b/doc/html/boost_bignumbers/ref/bignum.html new file mode 100644 index 00000000..bcf3ef57 --- /dev/null +++ b/doc/html/boost_bignumbers/ref/bignum.html @@ -0,0 +1,151 @@ + + + +big_number + + + + + + + + +
+
+
+PrevUpHomeNext +
+
+ +
+ + Synopsis +
+
namespace boost{ namespace math{
+
+template <class Backend>
+class big_number
+{
+   big_number();
+   big_number(see-below);
+   big_number& operator=(see-below);
+   /* Other number-type operators here */
+   // string conversion:
+   std::string str()const;
+   // precision control:
+   static unsigned default_precision();
+   static void default_precision(unsigned digits10);
+   unsigned precision()const;
+   void precision(unsigned digits10);
+   // Comparison:
+   int compare(const big_number<Backend>& o)const;
+   template <class V>
+   typename enable_if<is_arithmetic<V>, int>::type compare(const V& o)const;
+};
+
+}} // namespaces
+
+
+ + Description +
+
big_number();
+big_number(see-below);
+big_number& operator=(see-below);
+
+

+ Type big_number is default + constructible, and copy both constructible and assignable from: +

+
    +
  • + Itself. +
  • +
  • + An expression template which is the result of one of the arithmetic operators. +
  • +
  • + Any builtin arithmetic type. +
  • +
  • + A std::string or any type which is convertible + to const char*. +
  • +
+
/* Other number-type operators here */
+
+

+ The following arithmetic operations are support for real-numbered types: +

+
    +
  • + Binary +, -, *, /, +, -, *, /, + ==, !, <, >=, <, >. +
  • +
  • + Unary +, -. +
  • +
+

+ For integer types the following operators are also supported: +

+

+ Binary %, %=. +

+

+ (More to follow!!) +

+

+ Note that the result of the binary +, -, *, / and % operations is an expression + template of "unmentionable type". +

+
std::string str()const;
+
+

+ Returns the number formatted as a string (TODO: enable custom precision). +

+
static unsigned default_precision();
+static void default_precision(unsigned digits10);
+unsigned precision()const;
+void precision(unsigned digits10);
+
+

+ These functions are only available if the Backend template parameter supports + runtime changes to precision. They get and set the default precision and + the precision of *this respectively. +

+
int compare(const big_number<Backend>& o)const;
+template <class V>
+typename enable_if<is_arithmetic<V>, int>::type compare(const V& other)const;
+
+

+ Returns: +

+
    +
  • + A value less that 0 for *this < other +
  • +
  • + A value greater that 0 for *this > other +
  • +
  • + Zero for *this == other +
  • +
+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bignumbers/tut.html b/doc/html/boost_bignumbers/tut.html new file mode 100644 index 00000000..92e58b08 --- /dev/null +++ b/doc/html/boost_bignumbers/tut.html @@ -0,0 +1,44 @@ + + + +Tutorial + + + + + + + + +
+
+
+PrevUpHomeNext +
+
+ + +

+ In order to use this library you need to make two choices: what kind of number + do I want, and which backend do I want to perform the actual arithmetic? +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bignumbers/tut/ints.html b/doc/html/boost_bignumbers/tut/ints.html new file mode 100644 index 00000000..b2dbce57 --- /dev/null +++ b/doc/html/boost_bignumbers/tut/ints.html @@ -0,0 +1,146 @@ + + + +Integer Types + + + + + + + + +
+
+
+PrevUpHomeNext +
+
+ +

+ The following backends provide integer arithmetic: +

+
++++++++ + + + + + + + + + + + + + + + + +
+

+ Backend Type +

+
+

+ Header +

+
+

+ Radix +

+
+

+ Dependencies +

+
+

+ Pros +

+
+

+ Cons +

+
+

+ gmp_int +

+
+

+ boost/math/big_number/gmp.hpp +

+
+

+ 2 +

+
+

+ GMP +

+
+

+ Very fast and efficient backend. +

+
+

+ Dependency on GNU licenced GMP library. +

+
+
+ + gmp_int +
+
namespace boost{ namespace math{
+
+class gmp_int;
+
+typedef big_number<gmp_int >         mpz_int;
+
+}} // namespaces
+
+

+ The gmp_int backend is used + via the typedef boost::math::mpz_int. It acts as a thin wrapper around + the GMP mpz_t to provide + an integer type that is a drop-in replacement for the native C++ integer + types, but with unlimited precision. +

+
+ + Example: +
+
#include <boost/math/big_number/gmp.hpp>
+
+boost::math::mpz_int v = 1;
+
+// Do some arithmetic:
+for(unsigned i = 1; i <= 1000; ++i)
+   v *= i;
+
+std::cout << i << std::endl; // prints 1000!
+
+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_bignumbers/tut/reals.html b/doc/html/boost_bignumbers/tut/reals.html new file mode 100644 index 00000000..cd08e445 --- /dev/null +++ b/doc/html/boost_bignumbers/tut/reals.html @@ -0,0 +1,158 @@ + + + +Real Numbers + + + + + + + + +
+
+
+PrevUpHomeNext +
+
+ +

+ The following backends provide real number arithmetic: +

+
++++++++ + + + + + + + + + + + + + + + + +
+

+ Backend Type +

+
+

+ Header +

+
+

+ Radix +

+
+

+ Dependencies +

+
+

+ Pros +

+
+

+ Cons +

+
+

+ gmp_real<N> +

+
+

+ boost/math/big_number/gmp.hpp +

+
+

+ 2 +

+
+

+ GMP +

+
+

+ Very fast and efficient backend. +

+
+

+ Dependency on GNU licenced GMP library. +

+
+
+ + gmp_real +
+
namespace boost{ namespace math{
+
+template <unsigned Digits10>
+class gmp_real;
+
+typedef big_number<gmp_real<50> >    mpf_real_50;
+typedef big_number<gmp_real<100> >   mpf_real_100;
+typedef big_number<gmp_real<500> >   mpf_real_500;
+typedef big_number<gmp_real<1000> >  mpf_real_1000;
+typedef big_number<gmp_real<0> >     mpf_real;
+
+}} // namespaces
+
+

+ The gmp_real backend is used + in conjunction with big_number: + It acts as a thin wrapper around the GMP mpf_t + to provide an real-number type that is a drop-in replacement for the native + C++ floating-point types, but with much greater precision. +

+

+ Type gmp_real can be used + at fixed precision by specifying a non-zero Digits10 + template parameter, or at variable precision by setting the template argument + to zero. The typedefs mpf_real_50, mpf_real_100, mpf_real_500, mpf_real_1000 + provide arithmetic types at 50, 100, 500 and 1000 decimal digits precision + respectively. The typedef mpf_real provides a variable precision type whose + precision can be controlled via the big_number's + member functions. +

+
+ + example: +
+
#include <boost/math/big_number/gmp.hpp>
+
+boost::math::gmp_real a = 2;
+boost::math::gmp_real::default_precision(1000);
+std::cout << boost::math::gmp_real::default_precision() << std::endl;
+std::cout << sqrt(a) << std::endl; // print root-2
+
+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boostbook.css b/doc/html/boostbook.css new file mode 100644 index 00000000..252fa9ec --- /dev/null +++ b/doc/html/boostbook.css @@ -0,0 +1,588 @@ +/*============================================================================= + Copyright (c) 2004 Joel de Guzman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompany- + ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +/*============================================================================= + Body defaults +=============================================================================*/ + + body + { + margin: 1em; + font-family: sans-serif; + } + +/*============================================================================= + Paragraphs +=============================================================================*/ + + p + { + text-align: left; + font-size: 10pt; + line-height: 1.15; + } + +/*============================================================================= + Program listings +=============================================================================*/ + + /* Code on paragraphs */ + p tt.computeroutput + { + font-size: 9pt; + } + + pre.synopsis + { + font-size: 90%; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; + } + + .programlisting, + .screen + { + font-size: 9pt; + display: block; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; + } + + /* Program listings in tables don't get borders */ + td .programlisting, + td .screen + { + margin: 0pc 0pc 0pc 0pc; + padding: 0pc 0pc 0pc 0pc; + } + +/*============================================================================= + Headings +=============================================================================*/ + + h1, h2, h3, h4, h5, h6 + { + text-align: left; + margin: 1em 0em 0.5em 0em; + font-weight: bold; + } + + h1 { font: 140% } + h2 { font: bold 140% } + h3 { font: bold 130% } + h4 { font: bold 120% } + h5 { font: italic 110% } + h6 { font: italic 100% } + + /* Top page titles */ + title, + h1.title, + h2.title + h3.title, + h4.title, + h5.title, + h6.title, + .refentrytitle + { + font-weight: bold; + margin-bottom: 1pc; + } + + h1.title { font-size: 140% } + h2.title { font-size: 140% } + h3.title { font-size: 130% } + h4.title { font-size: 120% } + h5.title { font-size: 110% } + h6.title { font-size: 100% } + + .section h1 + { + margin: 0em 0em 0.5em 0em; + font-size: 140%; + } + + .section h2 { font-size: 140% } + .section h3 { font-size: 130% } + .section h4 { font-size: 120% } + .section h5 { font-size: 110% } + .section h6 { font-size: 100% } + + /* Code on titles */ + h1 tt.computeroutput { font-size: 140% } + h2 tt.computeroutput { font-size: 140% } + h3 tt.computeroutput { font-size: 130% } + h4 tt.computeroutput { font-size: 120% } + h5 tt.computeroutput { font-size: 110% } + h6 tt.computeroutput { font-size: 100% } + +/*============================================================================= + Author +=============================================================================*/ + + h3.author + { + font-size: 100% + } + +/*============================================================================= + Lists +=============================================================================*/ + + li + { + font-size: 10pt; + line-height: 1.3; + } + + /* Unordered lists */ + ul + { + text-align: left; + } + + /* Ordered lists */ + ol + { + text-align: left; + } + +/*============================================================================= + Links +=============================================================================*/ + + a + { + text-decoration: none; /* no underline */ + } + + a:hover + { + text-decoration: underline; + } + +/*============================================================================= + Spirit style navigation +=============================================================================*/ + + .spirit-nav + { + text-align: right; + } + + .spirit-nav a + { + color: white; + padding-left: 0.5em; + } + + .spirit-nav img + { + border-width: 0px; + } + +/*============================================================================= + Copyright footer +=============================================================================*/ + .copyright-footer + { + text-align: right; + font-size: 70%; + } + + .copyright-footer p + { + text-align: right; + font-size: 80%; + } + +/*============================================================================= + Table of contents +=============================================================================*/ + + .toc + { + margin: 1pc 4% 0pc 4%; + padding: 0.1pc 1pc 0.1pc 1pc; + font-size: 80%; + line-height: 1.15; + } + + .boost-toc + { + float: right; + padding: 0.5pc; + } + +/*============================================================================= + Tables +=============================================================================*/ + + .table-title, + div.table p.title + { + margin-left: 4%; + padding-right: 0.5em; + padding-left: 0.5em; + } + + .informaltable table, + .table table + { + width: 92%; + margin-left: 4%; + margin-right: 4%; + } + + div.informaltable table, + div.table table + { + padding: 4px; + } + + /* Table Cells */ + div.informaltable table tr td, + div.table table tr td + { + padding: 0.5em; + text-align: left; + font-size: 9pt; + } + + div.informaltable table tr th, + div.table table tr th + { + padding: 0.5em 0.5em 0.5em 0.5em; + border: 1pt solid white; + font-size: 80%; + } + + table.simplelist + { + width: auto !important; + margin: 0em !important; + padding: 0em !important; + border: none !important; + } + table.simplelist td + { + margin: 0em !important; + padding: 0em !important; + text-align: left !important; + font-size: 9pt !important; + border: none !important; + } + +/*============================================================================= + Blurbs +=============================================================================*/ + + div.note, + div.tip, + div.important, + div.caution, + div.warning, + p.blurb + { + font-size: 9pt; /* A little bit smaller than the main text */ + line-height: 1.2; + display: block; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; + } + + p.blurb img + { + padding: 1pt; + } + +/*============================================================================= + Variable Lists +=============================================================================*/ + + /* Make the terms in definition lists bold */ + div.variablelist dl dt, + span.term + { + font-weight: bold; + font-size: 10pt; + } + + div.variablelist table tbody tr td + { + text-align: left; + vertical-align: top; + padding: 0em 2em 0em 0em; + font-size: 10pt; + margin: 0em 0em 0.5em 0em; + line-height: 1; + } + + div.variablelist dl dt + { + margin-bottom: 0.2em; + } + + div.variablelist dl dd + { + margin: 0em 0em 0.5em 2em; + font-size: 10pt; + } + + div.variablelist table tbody tr td p, + div.variablelist dl dd p + { + margin: 0em 0em 0.5em 0em; + line-height: 1; + } + +/*============================================================================= + Misc +=============================================================================*/ + + /* Title of books and articles in bibliographies */ + span.title + { + font-style: italic; + } + + span.underline + { + text-decoration: underline; + } + + span.strikethrough + { + text-decoration: line-through; + } + + /* Copyright, Legal Notice */ + div div.legalnotice p + { + text-align: left + } + +/*============================================================================= + Colors +=============================================================================*/ + + @media screen + { + body { + background-color: #FFFFFF; + } + + /* Links */ + a + { + color: #005a9c; + } + + a:visited + { + color: #9c5a9c; + } + + h1 a, h2 a, h3 a, h4 a, h5 a, h6 a, + h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover, + h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited + { + text-decoration: none; /* no underline */ + color: #000000; + } + + /* Syntax Highlighting */ + .keyword { color: #0000AA; } + .identifier { color: #000000; } + .special { color: #707070; } + .preprocessor { color: #402080; } + .char { color: teal; } + .comment { color: #800000; } + .string { color: teal; } + .number { color: teal; } + .white_bkd { background-color: #FFFFFF; } + .dk_grey_bkd { background-color: #999999; } + + /* Copyright, Legal Notice */ + .copyright + { + color: #666666; + font-size: small; + } + + div div.legalnotice p + { + color: #666666; + } + + /* Program listing */ + pre.synopsis + { + border: 1px solid #DCDCDC; + } + + .programlisting, + .screen + { + border: 1px solid #DCDCDC; + } + + td .programlisting, + td .screen + { + border: 0px solid #DCDCDC; + } + + /* Blurbs */ + div.note, + div.tip, + div.important, + div.caution, + div.warning, + p.blurb + { + border: 1px solid #DCDCDC; + } + + /* Table of contents */ + .toc + { + border: 1px solid #DCDCDC; + } + + /* Tables */ + div.informaltable table tr td, + div.table table tr td + { + border: 1px solid #DCDCDC; + } + + div.informaltable table tr th, + div.table table tr th + { + background-color: #F0F0F0; + border: 1px solid #DCDCDC; + } + + .copyright-footer + { + color: #8F8F8F; + } + + /* Misc */ + span.highlight + { + color: #00A000; + } + } + + @media print + { + /* Links */ + a + { + color: black; + } + + a:visited + { + color: black; + } + + .spirit-nav + { + display: none; + } + + /* Program listing */ + pre.synopsis + { + border: 1px solid gray; + } + + .programlisting, + .screen + { + border: 1px solid gray; + } + + td .programlisting, + td .screen + { + border: 0px solid #DCDCDC; + } + + /* Table of contents */ + .toc + { + border: 1px solid gray; + } + + .informaltable table, + .table table + { + border: 1px solid gray; + border-collapse: collapse; + } + + /* Tables */ + div.informaltable table tr td, + div.table table tr td + { + border: 1px solid gray; + } + + div.informaltable table tr th, + div.table table tr th + { + border: 1px solid gray; + } + + table.simplelist tr td + { + border: none !important; + } + + /* Misc */ + span.highlight + { + font-weight: bold; + } + } + +/*============================================================================= + Images +=============================================================================*/ + + span.inlinemediaobject img + { + vertical-align: middle; + } + +/*============================================================================== + Super and Subscript: style so that line spacing isn't effected, see + http://www.adobe.com/cfusion/communityengine/index.cfm?event=showdetails&productId=1&postId=5341 +==============================================================================*/ + +sup, +sub { + height: 0; + line-height: 1; + vertical-align: baseline; + _vertical-align: bottom; + position: relative; + +} + +sup { + bottom: 1ex; +} + +sub { + top: .5ex; +} + diff --git a/doc/html/images/blank.png b/doc/html/images/blank.png new file mode 100644 index 0000000000000000000000000000000000000000..764bf4f0c3bb4a09960b04b6fa9c9024bca703bc GIT binary patch literal 374 zcmeAS@N?(olHy`uVBq!ia0y~yU}ykg4kiW$2A`O3a~K#HSkfJR9T^xl_H+M9WMyDr z)b(_645^s&_M)R8g96V1g9H1Y`?|@Qa8+HmHda4(nQ?zM!!?FAj1kNm*b;aTNHv%; cj9>w=gf!;AOne?`3=9kmp00i_>zopr0Be8NW(e>Jab;j&;NV~o5MYpy zU{F+KFf?Rva$<;zVn|MA$j)XcE@r5%W@u?)XlW_#>0#*UDemd%nKFf8%9P?MQ>y38 zVVEwkZjIWyHF@jSt$X(}?A@Du?i|Cp zbLXyIW4Lzh+_h`h?%iX!chB(NJdh*`E$$X&!4}4&+z{J`|sZwzJC|^ z{$1kxcf;@BzyJTw@c+NS|Nj#IN5NBISn~R-X--a%afBxQ|J!3zMjr_SU zk_iHr)f*lf{$5^Qz}I)@3FlWvw(w~u=1P@VsTP+$RNGvxbHL-(%M6nc6`{zlU zjGQJeveps+!&Jb&mD)L@hA} z1_tL6*NBqf{Irtt#G+IN2MuLS&)mfHRNut(%;anZ6Fnn63k6F{eFF=914D)6qRirw zN{8Ia;*!i{z0_j8l+uFyyb`_S{M?DV6n8K%Fld2|%S_KpEGaEYWk@zRFt#waFg8d` zG)YZPF-fe)lBATd3a!N{b-$VA&f+n^|#(~yCI Ofx*+&&t;ucLK6T%G-N*j literal 0 HcmV?d00001 diff --git a/doc/html/images/caution.svg b/doc/html/images/caution.svg new file mode 100644 index 00000000..4bd586a0 --- /dev/null +++ b/doc/html/images/caution.svg @@ -0,0 +1,68 @@ + + + + + + Attenzione + + + + pulsante + + + + + Open Clip Art Library + + + + + Architetto Francesco Rollandin + + + + + Architetto Francesco Rollandin + + + + image/svg+xml + + + en + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/html/images/draft.png b/doc/html/images/draft.png new file mode 100644 index 0000000000000000000000000000000000000000..0084708c9b8287c51efa6b40b8d492854191455e GIT binary patch literal 17454 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 YsPxZ;53A2HFfcH9y85}Sb4q9e0Fi|iga7~l literal 0 HcmV?d00001 diff --git a/doc/html/images/home.png b/doc/html/images/home.png new file mode 100644 index 0000000000000000000000000000000000000000..5584aacb097a80e66a5320312b6e4eb017af1a06 GIT binary patch literal 358 zcmeAS@N?(olHy`uVBq!ia0y~yU=Rjj7G?$phK4%r{|pQa%*9TgAsieWw;%dHU|?WS z3GfMV6&Dfg?(A@OuseF>a6(*+nzF*onKLh6zO-%YmOy{sw6wJU|Nk%gvq74Hfq|za z$S?Rm0x$^OKX;CSfq}EYBeIx*fm;ZK886+f`@_J%pjzS@Q4*Y=R#Ki=l*-_nm|T>f zo0^iDsNj}alvU8YOY t9}F9JU6`43jMG5vNQA& + + + + + + + +]> + + + + + + + + + + + + + + diff --git a/doc/html/images/important.png b/doc/html/images/important.png new file mode 100644 index 0000000000000000000000000000000000000000..12c90f607a1b27ddde0a7d922ae255e8c90e883e GIT binary patch literal 722 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4rT@hhU+WOo?>8NcoN_f;wr$vARr(hAt9lu zscC6x>EvV>6{VS+EaBwj6ciMco$ZvI98_E!l$@NLot<4>UER|o(bHqOcQ41TYc{y!?kM?_wFg)yJvXsp5^oB z9Pi&Vyniq7|3Ab3{~Z7S3p{_W`TV)z`}cpO z$(;G%_wGG* z?AW<;=dNA5cJJQ3=g*(NfB*jb_wWDz|6hCQ@I3|w2F4_BcNgdM3%p4T42R|DNig) zWpL0?*7VFxOi%SqOwUZtRxr^s(z8&owA44S&^IttNG{4OE~#|Ltt>9dOx8;+)=McZ z$j>X$OU}=oxJz*d0|SE=*tpE}yu^~yqEv=t literal 0 HcmV?d00001 diff --git a/doc/html/images/important.svg b/doc/html/images/important.svg new file mode 100644 index 00000000..dd84f3fe --- /dev/null +++ b/doc/html/images/important.svg @@ -0,0 +1,25 @@ + + + + + + + + +]> + + + + + + + + + + + + + + + diff --git a/doc/html/images/next.png b/doc/html/images/next.png new file mode 100644 index 0000000000000000000000000000000000000000..59800b4e87f60c0e3383ede2b384b9be0f5ffe8d GIT binary patch literal 336 zcmeAS@N?(olHy`uVBq!ia0y~yU=Rjj7G?$phK4%r{|pQa%*9TgAsieWw;%dHU|?WS z3GfMV6&Dfg?(8r&Hr}>%OQ656nzF)*4nJa0`Jj)#l9-t%+}PK^d+g590~2^trx_V+aGYt)W#Kgko@Q{~>i6>w}LxPb)_bi1gN;4a>^d{wc + + + + + +]> + + + + + + + + + + + diff --git a/doc/html/images/next_disabled.png b/doc/html/images/next_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..10a8c59d7b3741260b7bfe918b62d0670cad8433 GIT binary patch literal 1110 zcmeAS@N?(olHy`uVBq!ia0y~yU=Rjj4rT@h2G_o0{}>n;SkfJR9T^xl_SO6joXo($ zppfhlZ{Pm>`SaViZ};!tyLt1*|NsBbojZ3P6EBL3=9l=JzX3_ zD&{0TNo#1Z_o+&KnDHU@)Rs;LG+GiER_Ffe$!`njxgN@xNAPfH=1 literal 0 HcmV?d00001 diff --git a/doc/html/images/note.png b/doc/html/images/note.png new file mode 100644 index 0000000000000000000000000000000000000000..d0c3c645ab9af6318035b026dd86944b9ddc9114 GIT binary patch literal 490 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4h9AWhNCh`Dhvz^OiAAEE({E-dXuv&t)U99M06BF~bt=lC3t1z!y3OU-_; z>3=1k>J3(3i_72APIz-IDqpqc+E%+vGv;(%KfZ!%@4A+C&xmZ75-RagX8L}A{%x+r zX<~gz))PX{awr=ezabJ<%O$qq%HpE?3}IarYhrI#g}e)4`)(-lYr?KO{@fm?UzpsD z&F7x?_G;CcbIZ>^o0GCAMe@{JfwtZgS9s0dn=t$|`IrrC3yU6#%a-U6G$wZz0 z>m`@($9HNPdGJ4#pEvb;3eT@>Ck6%v=MvY5lHmNblJdl&R0anPWlhiA#Pn3(#PrPM zYy}fNBRvZROG|wN3w;Aah2)~l;*v^-+{)sT%w)aPV!f2og8aM^z2yAdiMtecFfcG^ zfsM;d&r2*RElOoDPD(L1F;6y4H8Hg?FgGwTOER!DNJ%kHHBU4$OExhPxjgw70|Nse jNLN5&dMbmFNrjP#wt==mQ8cF^C=xwg{an^LB{Ts5w*0vf literal 0 HcmV?d00001 diff --git a/doc/html/images/note.svg b/doc/html/images/note.svg new file mode 100644 index 00000000..648299d2 --- /dev/null +++ b/doc/html/images/note.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + diff --git a/doc/html/images/prev.png b/doc/html/images/prev.png new file mode 100644 index 0000000000000000000000000000000000000000..d88a40f923e3c554125f01cd366707c60cfcad04 GIT binary patch literal 334 zcmeAS@N?(olHy`uVBq!ia0y~yU=Rjj7G?$phK4%r{|pQa%*9TgAsieWw;%dHU|?WS z3GfMV6&DdqOG`60Hr}>%%ZlYo1O0u~loc*tzSP~>;p||S5Et|R|Noh1c$yg)73T~N2spa`a*~JRJ5eh~I1}5!gYtAz;Fo=OPI2WZRmSpDVDTHL^rZN~B=o=X8 z8<-ql-^0nkz!2u?;uumfC;0|1OPoRyGxLNShYX~Tl_Wf9G1_imu)%RA9}mw<0X2^e zQioc&m}WXSvRw^OFi2qFa&lm1W^U?K=~^Ook|m{hVvche^Q6-g?(V)Vn8U=toEqFE UkjD9gfq{X+)78&qol`;+00?PtqyPW_ literal 0 HcmV?d00001 diff --git a/doc/html/images/prev.svg b/doc/html/images/prev.svg new file mode 100644 index 00000000..6d88ffdd --- /dev/null +++ b/doc/html/images/prev.svg @@ -0,0 +1,19 @@ + + + + + + +]> + + + + + + + + + + + diff --git a/doc/html/images/prev_disabled.png b/doc/html/images/prev_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..ab3c17e02d156e7494dbab2f9cd66af46af2358c GIT binary patch literal 1109 zcmeAS@N?(olHy`uVBq!ia0y~yU=Rjj4rT@h2G_o0{}>n;SkfJR9T^xl_SO6joXo($ zppfhlO-<`D(~2b}=LHv2RC7dZWAVCrDh<7Ss(U_A1L-MNQRp<#x>RYL|A z0d8w%7gb?npBLs13>ys`SR)0#F|i0-(0!9|ZvFp)$&5@KPtr;p8yJ{=^Qv)(GIJ<+ zNI0-0Zew5(Fj?c!G-tyG77m3Osc(4d6PFVdQ&MBb@ E0L^J1b^rhX literal 0 HcmV?d00001 diff --git a/doc/html/images/tip.png b/doc/html/images/tip.png new file mode 100644 index 0000000000000000000000000000000000000000..5c4aab3bb3543191c360387c4af9a3cbaa051345 GIT binary patch literal 449 zcmeAS@N?(olHy`uVBq!ia0y~yV31^BV36QoU|?X-y2mNSz`($iDJ87yAgr${wU6ATeb^ycE^w7cIp z?_W?xU6%d(bb~@Shbi-aG=ETBbm~(ogOmrW&bwBIxdt+K+A3yD;V_t}R>0LF5GN)x zed{W(mq$!1ciVpPy1}W+9bm)Xrgda~bSbG?a3DdjluYV+O9SdLnMpASqX+9EZY3c7C@7#N&OTq83NAIrA4U>si~GJ7Ut&0mS)MRMrP)TsYwQg=9VeOrfC+2Nk)mu rLdL(;85kJ&K)M1F(^DCYOe>5`v<1B4~iR4S3j3^P6 + + + + + lamp + + + + office + + lamp + + + + + Open Clip Art Library + + + + + Sergio Luiz Araujo Silva + + + + + Public Domain + + + set 2005 + image/svg+xml + + + en + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/html/images/toc-blank.png b/doc/html/images/toc-blank.png new file mode 100644 index 0000000000000000000000000000000000000000..6ffad17a0c7a78deaae58716e8071cc40cb0b8e0 GIT binary patch literal 318 zcmeAS@N?(olHy`uVBq!ia0y~yVBlw9VBln7W?*2DUznZ3z`$S-;1lA?z`)P|#tmSq zfuVt+q2a)R0}Txg{}~t<{xkdsQ~$xN|NsB{3#)lDFfcGCdAqwXbg;^LFfcI4dAc}; zRNPAb@qhn+dx4sSAN-68Y+`}}843&7&M+`cx!`muLvG^(1_lP_64!{5;QX|b^2DN4 z1_upgP0!rK^itl1hi%%HopDWWCg4y_C{| z{JavqiARt`YJFJnVhX)qGzOMplv!L->5yAl zT#}irms+fsQd*FoSE84kpF44v;tmD|1}(60ndy0nC8b5F42emG<`xDZ$;L?r7Ky3J=GDKJX@I;2(iM=Hp2}coT4AYeplx7Y_5oxZgQu&X%Q~lo FCIGT9P(J_w literal 0 HcmV?d00001 diff --git a/doc/html/images/up.png b/doc/html/images/up.png new file mode 100644 index 0000000000000000000000000000000000000000..17d9c3ec491ae1ba22188ce85985623c92ffa9be GIT binary patch literal 370 zcmeAS@N?(olHy`uVBq!ia0y~yU=Rjj7G?$phK4%r{|pQa%*9TgAsieWw;%dHU|?X- z3h)VW6&DdqOG|Thu-mqE%ZlYoyE{8BU%nLR@2jS)FmvY2qel)W#Kk;%^zi@x|I?Un z*fKCM@RbDl1^-6|46X<6oM2#J;4JWnEM{Qf76M_$OLy!3FfcHvmbgZg1m~xflqVLY zGWaGY7v<-srer26xMdclmgg5`7c2NiC>R+Sn6#IzInThrAO_OlT$Gwvl9`{U5R#dj z%3x@qZ(yu%U~+tY4<`cyLy@P8V@SoEspmFwHW&!FJyeg_(XezvV9WvAI|r@_>dZZG zPW6aiOT!J--9O?NG0%AP;}ge|4lDQN4=-}8`?JGwx}?mMnO)OdyQdu$nQCjPRV}jm z$u!Qa8E-cQ-r3Nz>Y(YPTd#BPEH+&8GWqfD!}4*53%dA!%#3$cIv;a~fq{X+)78&q Iol`;+0POUaApigX literal 0 HcmV?d00001 diff --git a/doc/html/images/up.svg b/doc/html/images/up.svg new file mode 100644 index 00000000..d31aa9c8 --- /dev/null +++ b/doc/html/images/up.svg @@ -0,0 +1,19 @@ + + + + + + +]> + + + + + + + + + + + diff --git a/doc/html/images/up_disabled.png b/doc/html/images/up_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..e22bc8712192df3a8faa3264b0ec71ff3aaaa96c GIT binary patch literal 1115 zcmeAS@N?(olHy`uVBq!ia0y~yU=Rjj4rT@h2G_o0{}>n;SkfJR9T^xl_SO6joXo($ zppfhl|Nrwy-~uYR zhzc&Dg3GAj3M#mY3a+7o>!{!cD!7RXZlQwPsNfDNxQhzzp@RFU-~lRlhzcH|g2$-f z2`YGs3Z9{Y=cwQXDtL(sUZH~5sNfAMc#8_&p@R3Q-~%f7hzdTTg3qYn3o7`E3cjI& z@2KDhD)@;CexZWjsNfGO_=^hup@RP~@T}IQi-CcGuO!GX7$yd$8C(zCIl;idaKO{W zF{ENn(v#GNhX4QTi=1XMFdktN{`IZ@p>>FWLcsvS9SfKMdlAq$6s7@ONV`8frfZ~QMdG-hBC2vApc;y96* zmcYQFpvLCIAmDK02m=$xYzYU3L}6wQg@_sdlHD~JI1CtW_~{utEVY`?z`(%Z>FVdQ I&MBb@06Fw0-2eap literal 0 HcmV?d00001 diff --git a/doc/html/images/warning.png b/doc/html/images/warning.png new file mode 100644 index 0000000000000000000000000000000000000000..1c33db8f34a8b42b373179b46a2d8d8a10e061a9 GIT binary patch literal 1241 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4rT@hhU+WOo?>8NW(e>JaphoO5CF?5GB9W| zFc>m0I59AIF)#!%FhnshWHT@nGcZ&$Ftji*^e`|?VPKe2T|Fl#Xiikroa*YO3=B&x zEth(EEp2I8I%UezrAyZ`FswB+TsvjTRtAQxnwndCdbZA)vvujxty{P5WnkF5cJ1D+ zTaPg?91{>YCLwX`*s*gA4Ce#{&Phm|)6~4iz;I1d^V+p*_ZS%N-Mjakf#JEL;`8Uv z-!m}0=iqq%{{43bhVS3M|7T$MKMF=efJz}yVEuRs0|NtNlDE4HLkFv@2Ll7c3r`ov zkcwNmlWOyu3izvS7ejxP>R-!INP5f(XN|IS^C^Iyp?`SUk1vQO?s(K&l| zi|Nkt0@~*ymDp65*E-HED6u(s{Mfrxmah{JrgAMTIq)Du?nC5nnYTRgThA|azEdIl zD^uvV>~q(b?>`Fd;xnAbe7so1I$-&keKN}|vNNOCvX<~g{)wp7{&hR__v^cBU*Gq* zV3YS!cBPWsl#eNWc|~nAXWMOB8tQWBuXo=4>}cytyX_5F^Az{bVJ>7~U~n#RjVKAu zPb(=;EJ|f?&`{R&%uP&B^-WCAOwLv?(KFJsP_VSrH?Yt*FjPn`$}BFabjYnNF3C*R zOD)z*DJ{s)E742N&z-nSaR&nfgBIAh%=Em(lG377hGY|?B=Z!b6jL*k#Ka_13kwTN zLrZf@a|7cv1EVApQ-8txlNlHo_&~Y>64O%|j7%zwOtcNO4T_>U4H+017(8A5T-G@y GGywozG)2h( literal 0 HcmV?d00001 diff --git a/doc/html/images/warning.svg b/doc/html/images/warning.svg new file mode 100644 index 00000000..fc8d7484 --- /dev/null +++ b/doc/html/images/warning.svg @@ -0,0 +1,23 @@ + + + + + + + + +]> + + + + + + + + + + + + + diff --git a/doc/html/index.html b/doc/html/index.html new file mode 100644 index 00000000..c9d159d1 --- /dev/null +++ b/doc/html/index.html @@ -0,0 +1,53 @@ + + + +Chapter 1. Boost.BigNumbers + + + + + + +
+
+
Next
+
+
+

+Chapter 1. Boost.BigNumbers

+

+various authors +

+
+
+

+ Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +

+
+
+ +
+ + + +

Last revised: July 08, 2011 at 18:51:46 +0100

+
+
Next
+ + diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 new file mode 100644 index 00000000..24b697e7 --- /dev/null +++ b/test/Jamfile.v2 @@ -0,0 +1,189 @@ +# copyright John Maddock 2008 +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt. + +import modules ; +import path ; + +local ntl-path = [ modules.peek : NTL_PATH ] ; +local gmp_path = [ modules.peek : GMP_PATH ] ; +local mpfr_path = [ modules.peek : MPFR_PATH ] ; +local e_float_path = [ modules.peek : BOOST_E_FLOAT_PATH ] ; + +if ! $(e_float_path) +{ + e_float_path = ../../../../e_float ; +} + +project : requirements + $(gmp_path) + $(gmp_path)/mpfr + $(gmp_path)/gmpfrxx + $(mpfr_path) + ../../.. + $(e_float_path) + $(gmp_path) + $(mpfr_path) + $(mpfr_path)/build.vc10/lib/Win32/Debug + msvc:static + E_FLOAT_DIGITS10=100 + E_FLOAT_TYPE_EFX + ; + +lib gmp ; +lib mpfr ; + +E_FLOAT_SRC = [ GLOB $(e_float_path)/libs/e_float/src/e_float : *.cpp ] + [ GLOB $(e_float_path)/libs/e_float/src/e_float/efx : *.cpp ] + [ GLOB $(e_float_path)/libs/e_float/src/functions/constants : *.cpp ] + [ GLOB $(e_float_path)/libs/e_float/src/functions/elementary : *.cpp ] + [ GLOB $(e_float_path)/libs/e_float/src/functions/gamma : *.cpp ] + [ GLOB $(e_float_path)/libs/e_float/src/functions/integer : *.cpp ] + [ GLOB $(e_float_path)/libs/e_float/src/functions/tables : *.cpp ] + [ GLOB $(e_float_path)/libs/e_float/src/functions/zeta : *.cpp ] + [ GLOB $(e_float_path)/libs/e_float/src/generic_functions/constants : *.cpp ] + [ GLOB $(e_float_path)/libs/e_float/src/generic_functions/elementary : *.cpp ] + [ GLOB $(e_float_path)/libs/e_float/src/utility : *.cpp ] + ; + +lib e_float : $(E_FLOAT_SRC) + : + [ check-target-builds ../config//has_e_float : : no ] + ; + +run test_arithmetic.cpp + : # command line + : # input files + : # requirements + TEST_BACKEND + : test_arithmetic_backend_concept ; + +run test_arithmetic.cpp gmp + : # command line + : # input files + : # requirements + TEST_MPF50 + [ check-target-builds ../config//has_gmp : : no ] + : test_arithmetic_mpf50 ; + +run test_arithmetic.cpp gmp + : # command line + : # input files + : # requirements + TEST_MPF + [ check-target-builds ../config//has_gmp : : no ] + : test_arithmetic_mpf ; + +run test_arithmetic.cpp gmp + : # command line + : # input files + : # requirements + TEST_MPZ + [ check-target-builds ../config//has_gmp : : no ] + : test_arithmetic_mpz ; + +run test_arithmetic.cpp gmp + : # command line + : # input files + : # requirements + TEST_MPQ + [ check-target-builds ../config//has_gmp : : no ] + : test_arithmetic_mpq ; + +run test_arithmetic.cpp mpfr gmp + : # command line + : # input files + : # requirements + TEST_MPFR + [ check-target-builds ../config//has_mpfr : : no ] + : test_arithmetic_mpfr ; + +run test_arithmetic.cpp mpfr gmp + : # command line + : # input files + : # requirements + TEST_MPFR_50 + [ check-target-builds ../config//has_mpfr : : no ] + : test_arithmetic_mpfr_50 ; + +run test_arithmetic.cpp $(E_FLOAT_SRC) + : # command line + : # input files + : # requirements + TEST_E_FLOAT + [ check-target-builds ../config//has_e_float : : no ] + : test_arithmetic_e_float ; + +run test_numeric_limits.cpp + : # command line + : # input files + : # requirements + TEST_BACKEND + : test_numeric_limits_backend_concept ; + +run test_numeric_limits.cpp gmp + : # command line + : # input files + : # requirements + TEST_MPF50 + [ check-target-builds ../config//has_gmp : : no ] + : test_numeric_limits_mpf50 ; + +run test_numeric_limits.cpp gmp + : # command line + : # input files + : # requirements + TEST_MPF + [ check-target-builds ../config//has_gmp : : no ] + : test_numeric_limits_mpf ; + +run test_numeric_limits.cpp gmp + : # command line + : # input files + : # requirements + TEST_MPZ + [ check-target-builds ../config//has_gmp : : no ] + : test_numeric_limits_mpz ; + +run test_numeric_limits.cpp gmp + : # command line + : # input files + : # requirements + TEST_MPQ + [ check-target-builds ../config//has_gmp : : no ] + : test_numeric_limits_mpq ; + +run test_numeric_limits.cpp mpfr + : # command line + : # input files + : # requirements + TEST_MPFR + [ check-target-builds ../config//has_mpfr : : no ] + : test_numeric_limits_mpfr ; + +run test_numeric_limits.cpp mpfr + : # command line + : # input files + : # requirements + TEST_MPFR_50 + [ check-target-builds ../config//has_mpfr : : no ] + : test_numeric_limits_mpfr_50 ; + + +run test_numeric_limits.cpp $(E_FLOAT_SRC) + : # command line + : # input files + : # requirements + TEST_E_FLOAT + [ check-target-builds ../config//has_e_float : : no ] + : test_numeric_limits_e_float ; + +run big_number_concept_check.cpp mpfr + : # command line + : # input files + : # requirements + TEST_MPFR_50 + [ check-target-builds ../config//has_mpfr : : no ] + : big_number_concept_check_mpfr_50 ; + diff --git a/test/big_number_concept_check.cpp b/test/big_number_concept_check.cpp new file mode 100644 index 00000000..466af22f --- /dev/null +++ b/test/big_number_concept_check.cpp @@ -0,0 +1,100 @@ + +// Copyright John Maddock 2011. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// +// This tests two things: that e_float meets our +// conceptual requirements, and that we can instantiate +// all our distributions and special functions on this type. +// +#define BOOST_MATH_ASSERT_UNDEFINED_POLICY false +#define BOOST_MATH_INSTANTIATE_MINIMUM + +#ifdef _MSC_VER +# pragma warning(disable:4800) +# pragma warning(disable:4512) +# pragma warning(disable:4127) +# pragma warning(disable:4512) +# pragma warning(disable:4503) // decorated name length exceeded, name was truncated +#endif + +#if !defined(TEST_MPF50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_E_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) +# define TEST_MPF50 +# define TEST_MPF +# define TEST_BACKEND +# define TEST_MPZ +# define TEST_MPFR +# define TEST_MPFR_50 +# define TEST_E_FLOAT + +#ifdef _MSC_VER +#pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") +#endif +#ifdef __GNUC__ +#pragma warning "CAUTION!!: No backend type specified so testing everything.... this will take some time!!" +#endif + +#endif + +#if defined(TEST_MPF50) || defined(TEST_MPF) || defined(TEST_MPZ) +#include +#endif +#ifdef TEST_BACKEND +#include +#endif +#ifdef TEST_E_FLOAT +#include +#endif +#if defined(TEST_MPFR) || defined(TEST_MPFR_50) +#include +#endif + +#include +#include "libs/math/test/compile_test/instantiate.hpp" + +void foo() +{ +#ifdef TEST_BACKEND + instantiate(boost::math::big_number_real_architype()); +#endif +#ifdef TEST_MPF_50 + instantiate(boost::math::mpf_real_50()); +#endif +#ifdef TEST_MPF + instantiate(boost::math::mpf_real()); +#endif +#ifdef TEST_MPFR_50 + instantiate(boost::math::mpfr_real_50()); +#endif +#ifdef TEST_MPFR + instantiate(boost::math::mpfr_real()); +#endif +#ifdef TEST_E_FLOAT + instantiate(boost::math::e_float()); +#endif +} + +int main() +{ +#ifdef TEST_BACKEND + BOOST_CONCEPT_ASSERT((boost::math::concepts::RealTypeConcept)); +#endif +#ifdef TEST_MPF_50 + BOOST_CONCEPT_ASSERT((boost::math::concepts::RealTypeConcept)); +#endif +#ifdef TEST_MPF + BOOST_CONCEPT_ASSERT((boost::math::concepts::RealTypeConcept)); +#endif +#ifdef TEST_MPFR_50 + BOOST_CONCEPT_ASSERT((boost::math::concepts::RealTypeConcept)); +#endif +#ifdef TEST_MPFR + BOOST_CONCEPT_ASSERT((boost::math::concepts::RealTypeConcept)); +#endif +#ifdef TEST_E_FLOAT + BOOST_CONCEPT_ASSERT((boost::math::concepts::RealTypeConcept)); +#endif + +} diff --git a/test/linpack-benchmark.cpp b/test/linpack-benchmark.cpp new file mode 100644 index 00000000..27fdde3e --- /dev/null +++ b/test/linpack-benchmark.cpp @@ -0,0 +1,1257 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2011 John Maddock. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +/* 1000d.f -- translated by f2c (version 20050501). +You must link the resulting object file with libf2c: +on Microsoft Windows system, link with libf2c.lib; +on Linux or Unix systems, link with .../path/to/libf2c.a -lm +or, if you install libf2c.a in a standard place, with -lf2c -lm +-- in that order, at the end of the command line, as in +cc *.o -lf2c -lm +Source for libf2c is in /netlib/f2c/libf2c.zip, e.g., + +http://www.netlib.org/f2c/libf2c.zip +*/ +#include +#include +#include +#include + +#ifdef TEST_MPF_100 +#include +typedef boost::math::mpf_real_100 real_type; +#elif defined(TEST_MPFR_100) +#include +typedef boost::math::mpfr_real_100 real_type; +#elif defined(TEST_GMPXX) +#include +typedef mpf_class real_type; +#elif defined(TEST_MPFRXX) +#include +typedef mpfr_class real_type; +#elif defined(TEST_E_FLOAT) +#include +#include +#include +typedef ::efx::e_float real_type; +using ef::abs; +#elif defined(TEST_E_FLOAT_BN) +#include +typedef boost::math::e_float real_type; +#else +typedef double real_type; +#endif + +#ifndef CAST_TO_RT +# define CAST_TO_RT(x) x +#endif + +extern "C" { +#include "f2c.h" + integer s_wsfe(cilist *), e_wsfe(void), do_fio(integer *, char *, ftnlen), + s_wsle(cilist *), do_lio(integer *, integer *, char *, ftnlen), + e_wsle(void); + /* Subroutine */ int s_stop(char *, ftnlen); + +#undef abs +#undef dabs +#define dabs abs +#undef min +#undef max +#undef dmin +#undef dmax +#define dmin min +#define dmax max + +} +#include + +using std::min; +using std::max; + +/* Table of constant values */ + +static integer c__0 = 0; +static real_type c_b7 = CAST_TO_RT(1); +static integer c__1 = 1; +static integer c__9 = 9; + +inline double second_(void) +{ + return ((double)(clock())) / CLOCKS_PER_SEC; +} + +int dgefa_(real_type *, integer *, integer *, integer *, integer *), dgesl_(real_type *, integer *, integer *, integer *, real_type *, integer *); +int dmxpy_(integer *, real_type *, integer *, integer *, real_type *, real_type *); +int matgen_(real_type *, integer *, integer *, real_type *, real_type *); +real_type epslon_(real_type *); +real_type ran_(integer *); +int dscal_(integer *, real_type *, real_type *, integer *); +int daxpy_(integer *, real_type *, real_type *, integer *, real_type *, integer *); +integer idamax_(integer *, real_type *, integer *); +real_type ddot_(integer *, real_type *, integer *, real_type *, integer *); +int daxpy_(integer *, real_type *, real_type *, integer *, real_type *, integer *); +int dmxpy_(integer *, real_type *, integer *, integer *, real_type *, real_type *); + + +extern "C" int MAIN__() +{ +#ifdef TEST_MPF_100 + std::cout << "Testing mp_number >" << std::endl; +#elif defined(TEST_MPFR_100) + std::cout << "Testing mp_number >" << std::endl; +#elif defined(TEST_GMPXX) + std::cout << "Testing mpf_class at 100 decimal degits" << std::endl; + mpf_set_default_prec(((100 + 1) * 1000L) / 301L); +#elif defined(TEST_MPFRXX) + std::cout << "Testing mpfr_class at 100 decimal degits" << std::endl; + mpfr_set_default_prec(((100 + 1) * 1000L) / 301L); +#elif defined(TEST_E_FLOAT) + std::cout << "Testing boost::ef::e_float" << std::endl; +#elif defined(TEST_E_FLOAT_BN) + std::cout << "Testing boost::math::e_float" << std::endl; +#else + std::cout << "Testing double" << std::endl; +#endif + + + /* Format strings */ + static char fmt_1[] = "(\002 Please send the results of this run to:\002" + "//\002 Jack J. Dongarra\002/\002 Computer Science Department\002/" + "\002 University of Tennessee\002/\002 Knoxville, Tennessee 37996" + "-1300\002//\002 Fax: 615-974-8296\002//\002 Internet: dongarra@c" + "s.utk.edu\002/)"; + static char fmt_40[] = "(\002 norm. resid resid mac" + "hep\002,\002 x(1) x(n)\002)"; + static char fmt_50[] = "(1p5e16.8)"; + static char fmt_60[] = "(//\002 times are reported for matrices of or" + "der \002,i5)"; + static char fmt_70[] = "(6x,\002factor\002,5x,\002solve\002,6x,\002tota" + "l\002,5x,\002mflops\002,7x,\002unit\002,6x,\002ratio\002)"; + static char fmt_80[] = "(\002 times for array with leading dimension o" + "f\002,i4)"; + static char fmt_110[] = "(6(1pe11.3))"; + + /* System generated locals */ + integer i__1; + real_type d__1, d__2, d__3; + + /* Builtin functions */ + + /* Local variables */ + static real_type a[1001000] /* was [1001][1000] */, b[1000]; + static integer i__, n; + static real_type x[1000]; + static double t1; + static integer lda; + static double ops; + static real_type eps; + static integer info; + static double time[6], cray, total; + static integer ipvt[1000]; + static real_type resid, norma; + static real_type normx; + static real_type residn; + + /* Fortran I/O blocks */ + static cilist io___4 = { 0, 6, 0, fmt_1, 0 }; + static cilist io___20 = { 0, 6, 0, fmt_40, 0 }; + static cilist io___21 = { 0, 6, 0, fmt_50, 0 }; + static cilist io___22 = { 0, 6, 0, fmt_60, 0 }; + static cilist io___23 = { 0, 6, 0, fmt_70, 0 }; + static cilist io___24 = { 0, 6, 0, fmt_80, 0 }; + static cilist io___25 = { 0, 6, 0, fmt_110, 0 }; + static cilist io___26 = { 0, 6, 0, 0, 0 }; + + + lda = 1001; + + /* this program was updated on 10/12/92 to correct a */ + /* problem with the random number generator. The previous */ + /* random number generator had a short period and produced */ + /* singular matrices occasionally. */ + + n = 1000; + cray = .056f; + s_wsfe(&io___4); + e_wsfe(); + /* Computing 3rd power */ + d__1 = (real_type) n; + /* Computing 2nd power */ + d__2 = (real_type) n; + ops = boost::lexical_cast(real_type(d__1 * (d__1 * d__1) * 2. / 3. + d__2 * d__2 * 2.)); + + matgen_(a, &lda, &n, b, &norma); + + /* ****************************************************************** */ + /* ****************************************************************** */ + /* you should replace the call to dgefa and dgesl */ + /* by calls to your linear equation solver. */ + /* ****************************************************************** */ + /* ****************************************************************** */ + + t1 = second_(); + dgefa_(a, &lda, &n, ipvt, &info); + time[0] = second_() - t1; + t1 = second_(); + dgesl_(a, &lda, &n, ipvt, b, &c__0); + time[1] = second_() - t1; + total = time[0] + time[1]; + /* ****************************************************************** */ + /* ****************************************************************** */ + + /* compute a residual to verify results. */ + + i__1 = n; + for (i__ = 1; i__ <= i__1; ++i__) { + x[i__ - 1] = b[i__ - 1]; + /* L10: */ + } + matgen_(a, &lda, &n, b, &norma); + i__1 = n; + for (i__ = 1; i__ <= i__1; ++i__) { + b[i__ - 1] = -b[i__ - 1]; + /* L20: */ + } + dmxpy_(&n, b, &n, &lda, x, a); + resid = CAST_TO_RT(0); + normx = CAST_TO_RT(0); + i__1 = n; + for (i__ = 1; i__ <= i__1; ++i__) { + /* Computing MAX */ + d__2 = resid, d__3 = (d__1 = b[i__ - 1], abs(d__1)); + resid = max(d__2,d__3); + /* Computing MAX */ + d__2 = normx, d__3 = (d__1 = x[i__ - 1], abs(d__1)); + normx = max(d__2,d__3); + /* L30: */ + } + eps = epslon_(&c_b7); + residn = resid / (n * norma * normx * eps); + s_wsfe(&io___20); + e_wsfe(); + s_wsfe(&io___21); + /* + do_fio(&c__1, (char *)&residn, (ftnlen)sizeof(real_type)); + do_fio(&c__1, (char *)&resid, (ftnlen)sizeof(real_type)); + do_fio(&c__1, (char *)&eps, (ftnlen)sizeof(real_type)); + do_fio(&c__1, (char *)&x[0], (ftnlen)sizeof(real_type)); + do_fio(&c__1, (char *)&x[n - 1], (ftnlen)sizeof(real_type)); + */ + std::cout << std::setw(12) << std::setprecision(5) << residn << " " << resid << " " << eps << " " << x[0] << " " << x[n-1] << std::endl; + e_wsfe(); + + s_wsfe(&io___22); + do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); + e_wsfe(); + s_wsfe(&io___23); + e_wsfe(); + + time[2] = total; + time[3] = ops / (total * 1e6); + time[4] = 2. / time[3]; + time[5] = total / cray; + s_wsfe(&io___24); + do_fio(&c__1, (char *)&lda, (ftnlen)sizeof(integer)); + e_wsfe(); + s_wsfe(&io___25); + for (i__ = 1; i__ <= 6; ++i__) { + // do_fio(&c__1, (char *)&time[i__ - 1], (ftnlen)sizeof(real_type)); + std::cout << std::setw(12) << std::setprecision(5) << time[i__ - 1]; + } + e_wsfe(); + s_wsle(&io___26); + do_lio(&c__9, &c__1, " end of tests -- this version dated 10/12/92", ( + ftnlen)44); + e_wsle(); + + s_stop("", (ftnlen)0); + return 0; +} /* MAIN__ */ + +/* Subroutine */ int matgen_(real_type *a, integer *lda, integer *n, + real_type *b, real_type *norma) +{ + /* System generated locals */ + integer a_dim1, a_offset, i__1, i__2; + real_type d__1, d__2; + + /* Local variables */ + static integer i__, j; + static integer init[4]; + + + /* Parameter adjustments */ + a_dim1 = *lda; + a_offset = 1 + a_dim1; + a -= a_offset; + --b; + + /* Function Body */ + init[0] = 1; + init[1] = 2; + init[2] = 3; + init[3] = 1325; + *norma = CAST_TO_RT(0); + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + i__2 = *n; + for (i__ = 1; i__ <= i__2; ++i__) { + a[i__ + j * a_dim1] = ran_(init) - .5f; + /* Computing MAX */ + d__2 = (d__1 = a[i__ + j * a_dim1], abs(d__1)); + *norma = max(d__2,*norma); + /* L20: */ + } + /* L30: */ + } + i__1 = *n; + for (i__ = 1; i__ <= i__1; ++i__) { + b[i__] = CAST_TO_RT(0); + /* L35: */ + } + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + i__2 = *n; + for (i__ = 1; i__ <= i__2; ++i__) { + b[i__] += a[i__ + j * a_dim1]; + /* L40: */ + } + /* L50: */ + } + return 0; +} /* matgen_ */ + +/* Subroutine */ int dgefa_(real_type *a, integer *lda, integer *n, integer * + ipvt, integer *info) +{ + /* System generated locals */ + integer a_dim1, a_offset, i__1, i__2, i__3; + + /* Local variables */ + static integer j, k, l; + static real_type t; + static integer kp1, nm1; + + + /* dgefa factors a double precision matrix by gaussian elimination. */ + + /* dgefa is usually called by dgeco, but it can be called */ + /* directly with a saving in time if rcond is not needed. */ + /* (time for dgeco) = (1 + 9/n)*(time for dgefa) . */ + + /* on entry */ + + /* a double precision(lda, n) */ + /* the matrix to be factored. */ + + /* lda integer */ + /* the leading dimension of the array a . */ + + /* n integer */ + /* the order of the matrix a . */ + + /* on return */ + + /* a an upper triangular matrix and the multipliers */ + /* which were used to obtain it. */ + /* the factorization can be written a = l*u where */ + /* l is a product of permutation and unit lower */ + /* triangular matrices and u is upper triangular. */ + + /* ipvt integer(n) */ + /* an integer vector of pivot indices. */ + + /* info integer */ + /* = 0 normal value. */ + /* = k if u(k,k) .eq. 0.0 . this is not an error */ + /* condition for this subroutine, but it does */ + /* indicate that dgesl or dgedi will divide by zero */ + /* if called. use rcond in dgeco for a reliable */ + /* indication of singularity. */ + + /* linpack. this version dated 08/14/78 . */ + /* cleve moler, university of new mexico, argonne national lab. */ + + /* subroutines and functions */ + + /* blas daxpy,dscal,idamax */ + + /* internal variables */ + + + + /* gaussian elimination with partial pivoting */ + + /* Parameter adjustments */ + a_dim1 = *lda; + a_offset = 1 + a_dim1; + a -= a_offset; + --ipvt; + + /* Function Body */ + *info = 0; + nm1 = *n - 1; + if (nm1 < 1) { + goto L70; + } + i__1 = nm1; + for (k = 1; k <= i__1; ++k) { + kp1 = k + 1; + + /* find l = pivot index */ + + i__2 = *n - k + 1; + l = idamax_(&i__2, &a[k + k * a_dim1], &c__1) + k - 1; + ipvt[k] = l; + + /* zero pivot implies this column already triangularized */ + + if (a[l + k * a_dim1] == 0.) { + goto L40; + } + + /* interchange if necessary */ + + if (l == k) { + goto L10; + } + t = a[l + k * a_dim1]; + a[l + k * a_dim1] = a[k + k * a_dim1]; + a[k + k * a_dim1] = t; +L10: + + /* compute multipliers */ + + t = -1. / a[k + k * a_dim1]; + i__2 = *n - k; + dscal_(&i__2, &t, &a[k + 1 + k * a_dim1], &c__1); + + /* row elimination with column indexing */ + + i__2 = *n; + for (j = kp1; j <= i__2; ++j) { + t = a[l + j * a_dim1]; + if (l == k) { + goto L20; + } + a[l + j * a_dim1] = a[k + j * a_dim1]; + a[k + j * a_dim1] = t; +L20: + i__3 = *n - k; + daxpy_(&i__3, &t, &a[k + 1 + k * a_dim1], &c__1, &a[k + 1 + j * + a_dim1], &c__1); + /* L30: */ + } + goto L50; +L40: + *info = k; +L50: + /* L60: */ + ; + } +L70: + ipvt[*n] = *n; + if (a[*n + *n * a_dim1] == 0.) { + *info = *n; + } + return 0; +} /* dgefa_ */ + +/* Subroutine */ int dgesl_(real_type *a, integer *lda, integer *n, integer * + ipvt, real_type *b, integer *job) +{ + /* System generated locals */ + integer a_dim1, a_offset, i__1, i__2; + + /* Local variables */ + static integer k, l; + static real_type t; + static integer kb, nm1; + + + /* dgesl solves the double precision system */ + /* a * x = b or trans(a) * x = b */ + /* using the factors computed by dgeco or dgefa. */ + + /* on entry */ + + /* a double precision(lda, n) */ + /* the output from dgeco or dgefa. */ + + /* lda integer */ + /* the leading dimension of the array a . */ + + /* n integer */ + /* the order of the matrix a . */ + + /* ipvt integer(n) */ + /* the pivot vector from dgeco or dgefa. */ + + /* b double precision(n) */ + /* the right hand side vector. */ + + /* job integer */ + /* = 0 to solve a*x = b , */ + /* = nonzero to solve trans(a)*x = b where */ + /* trans(a) is the transpose. */ + + /* on return */ + + /* b the solution vector x . */ + + /* error condition */ + + /* a division by zero will occur if the input factor contains a */ + /* zero on the diagonal. technically this indicates singularity */ + /* but it is often caused by improper arguments or improper */ + /* setting of lda . it will not occur if the subroutines are */ + /* called correctly and if dgeco has set rcond .gt. 0.0 */ + /* or dgefa has set info .eq. 0 . */ + + /* to compute inverse(a) * c where c is a matrix */ + /* with p columns */ + /* call dgeco(a,lda,n,ipvt,rcond,z) */ + /* if (rcond is too small) go to ... */ + /* do 10 j = 1, p */ + /* call dgesl(a,lda,n,ipvt,c(1,j),0) */ + /* 10 continue */ + + /* linpack. this version dated 08/14/78 . */ + /* cleve moler, university of new mexico, argonne national lab. */ + + /* subroutines and functions */ + + /* blas daxpy,ddot */ + + /* internal variables */ + + + /* Parameter adjustments */ + a_dim1 = *lda; + a_offset = 1 + a_dim1; + a -= a_offset; + --ipvt; + --b; + + /* Function Body */ + nm1 = *n - 1; + if (*job != 0) { + goto L50; + } + + /* job = 0 , solve a * x = b */ + /* first solve l*y = b */ + + if (nm1 < 1) { + goto L30; + } + i__1 = nm1; + for (k = 1; k <= i__1; ++k) { + l = ipvt[k]; + t = b[l]; + if (l == k) { + goto L10; + } + b[l] = b[k]; + b[k] = t; +L10: + i__2 = *n - k; + daxpy_(&i__2, &t, &a[k + 1 + k * a_dim1], &c__1, &b[k + 1], &c__1); + /* L20: */ + } +L30: + + /* now solve u*x = y */ + + i__1 = *n; + for (kb = 1; kb <= i__1; ++kb) { + k = *n + 1 - kb; + b[k] /= a[k + k * a_dim1]; + t = -b[k]; + i__2 = k - 1; + daxpy_(&i__2, &t, &a[k * a_dim1 + 1], &c__1, &b[1], &c__1); + /* L40: */ + } + goto L100; +L50: + + /* job = nonzero, solve trans(a) * x = b */ + /* first solve trans(u)*y = b */ + + i__1 = *n; + for (k = 1; k <= i__1; ++k) { + i__2 = k - 1; + t = ddot_(&i__2, &a[k * a_dim1 + 1], &c__1, &b[1], &c__1); + b[k] = (b[k] - t) / a[k + k * a_dim1]; + /* L60: */ + } + + /* now solve trans(l)*x = y */ + + if (nm1 < 1) { + goto L90; + } + i__1 = nm1; + for (kb = 1; kb <= i__1; ++kb) { + k = *n - kb; + i__2 = *n - k; + b[k] += ddot_(&i__2, &a[k + 1 + k * a_dim1], &c__1, &b[k + 1], &c__1); + l = ipvt[k]; + if (l == k) { + goto L70; + } + t = b[l]; + b[l] = b[k]; + b[k] = t; +L70: + /* L80: */ + ; + } +L90: +L100: + return 0; +} /* dgesl_ */ + +/* Subroutine */ int daxpy_(integer *n, real_type *da, real_type *dx, + integer *incx, real_type *dy, integer *incy) +{ + /* System generated locals */ + integer i__1; + + /* Local variables */ + static integer i__, m, ix, iy, mp1; + + + /* constant times a vector plus a vector. */ + /* uses unrolled loops for increments equal to one. */ + /* jack dongarra, linpack, 3/11/78. */ + + + /* Parameter adjustments */ + --dy; + --dx; + + /* Function Body */ + if (*n <= 0) { + return 0; + } + if (*da == 0.) { + return 0; + } + if (*incx == 1 && *incy == 1) { + goto L20; + } + + /* code for unequal increments or equal increments */ + /* not equal to 1 */ + + ix = 1; + iy = 1; + if (*incx < 0) { + ix = (-(*n) + 1) * *incx + 1; + } + if (*incy < 0) { + iy = (-(*n) + 1) * *incy + 1; + } + i__1 = *n; + for (i__ = 1; i__ <= i__1; ++i__) { + dy[iy] += *da * dx[ix]; + ix += *incx; + iy += *incy; + /* L10: */ + } + return 0; + + /* code for both increments equal to 1 */ + + + /* clean-up loop */ + +L20: + m = *n % 4; + if (m == 0) { + goto L40; + } + i__1 = m; + for (i__ = 1; i__ <= i__1; ++i__) { + dy[i__] += *da * dx[i__]; + /* L30: */ + } + if (*n < 4) { + return 0; + } +L40: + mp1 = m + 1; + i__1 = *n; + for (i__ = mp1; i__ <= i__1; i__ += 4) { + dy[i__] += *da * dx[i__]; + dy[i__ + 1] += *da * dx[i__ + 1]; + dy[i__ + 2] += *da * dx[i__ + 2]; + dy[i__ + 3] += *da * dx[i__ + 3]; + /* L50: */ + } + return 0; +} /* daxpy_ */ + +real_type ddot_(integer *n, real_type *dx, integer *incx, real_type *dy, + integer *incy) +{ + /* System generated locals */ + integer i__1; + real_type ret_val; + + /* Local variables */ + static integer i__, m, ix, iy, mp1; + static real_type dtemp; + + + /* forms the dot product of two vectors. */ + /* uses unrolled loops for increments equal to one. */ + /* jack dongarra, linpack, 3/11/78. */ + + + /* Parameter adjustments */ + --dy; + --dx; + + /* Function Body */ + ret_val = CAST_TO_RT(0); + dtemp = CAST_TO_RT(0); + if (*n <= 0) { + return ret_val; + } + if (*incx == 1 && *incy == 1) { + goto L20; + } + + /* code for unequal increments or equal increments */ + /* not equal to 1 */ + + ix = 1; + iy = 1; + if (*incx < 0) { + ix = (-(*n) + 1) * *incx + 1; + } + if (*incy < 0) { + iy = (-(*n) + 1) * *incy + 1; + } + i__1 = *n; + for (i__ = 1; i__ <= i__1; ++i__) { + dtemp += dx[ix] * dy[iy]; + ix += *incx; + iy += *incy; + /* L10: */ + } + ret_val = dtemp; + return ret_val; + + /* code for both increments equal to 1 */ + + + /* clean-up loop */ + +L20: + m = *n % 5; + if (m == 0) { + goto L40; + } + i__1 = m; + for (i__ = 1; i__ <= i__1; ++i__) { + dtemp += dx[i__] * dy[i__]; + /* L30: */ + } + if (*n < 5) { + goto L60; + } +L40: + mp1 = m + 1; + i__1 = *n; + for (i__ = mp1; i__ <= i__1; i__ += 5) { + dtemp = dtemp + dx[i__] * dy[i__] + dx[i__ + 1] * dy[i__ + 1] + dx[ + i__ + 2] * dy[i__ + 2] + dx[i__ + 3] * dy[i__ + 3] + dx[i__ + + 4] * dy[i__ + 4]; + /* L50: */ + } +L60: + ret_val = dtemp; + return ret_val; +} /* ddot_ */ + +/* Subroutine */ int dscal_(integer *n, real_type *da, real_type *dx, + integer *incx) +{ + /* System generated locals */ + integer i__1, i__2; + + /* Local variables */ + static integer i__, m, mp1, nincx; + + + /* scales a vector by a constant. */ + /* uses unrolled loops for increment equal to one. */ + /* jack dongarra, linpack, 3/11/78. */ + + + /* Parameter adjustments */ + --dx; + + /* Function Body */ + if (*n <= 0) { + return 0; + } + if (*incx == 1) { + goto L20; + } + + /* code for increment not equal to 1 */ + + nincx = *n * *incx; + i__1 = nincx; + i__2 = *incx; + for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) { + dx[i__] = *da * dx[i__]; + /* L10: */ + } + return 0; + + /* code for increment equal to 1 */ + + + /* clean-up loop */ + +L20: + m = *n % 5; + if (m == 0) { + goto L40; + } + i__2 = m; + for (i__ = 1; i__ <= i__2; ++i__) { + dx[i__] = *da * dx[i__]; + /* L30: */ + } + if (*n < 5) { + return 0; + } +L40: + mp1 = m + 1; + i__2 = *n; + for (i__ = mp1; i__ <= i__2; i__ += 5) { + dx[i__] = *da * dx[i__]; + dx[i__ + 1] = *da * dx[i__ + 1]; + dx[i__ + 2] = *da * dx[i__ + 2]; + dx[i__ + 3] = *da * dx[i__ + 3]; + dx[i__ + 4] = *da * dx[i__ + 4]; + /* L50: */ + } + return 0; +} /* dscal_ */ + +integer idamax_(integer *n, real_type *dx, integer *incx) +{ + /* System generated locals */ + integer ret_val, i__1; + real_type d__1; + + /* Local variables */ + static integer i__, ix; + static real_type dmax__; + + + /* finds the index of element having max. dabsolute value. */ + /* jack dongarra, linpack, 3/11/78. */ + + + /* Parameter adjustments */ + --dx; + + /* Function Body */ + ret_val = 0; + if (*n < 1) { + return ret_val; + } + ret_val = 1; + if (*n == 1) { + return ret_val; + } + if (*incx == 1) { + goto L20; + } + + /* code for increment not equal to 1 */ + + ix = 1; + dmax__ = abs(dx[1]); + ix += *incx; + i__1 = *n; + for (i__ = 2; i__ <= i__1; ++i__) { + if ((d__1 = dx[ix], abs(d__1)) <= dmax__) { + goto L5; + } + ret_val = i__; + dmax__ = (d__1 = dx[ix], abs(d__1)); +L5: + ix += *incx; + /* L10: */ + } + return ret_val; + + /* code for increment equal to 1 */ + +L20: + dmax__ = abs(dx[1]); + i__1 = *n; + for (i__ = 2; i__ <= i__1; ++i__) { + if ((d__1 = dx[i__], abs(d__1)) <= dmax__) { + goto L30; + } + ret_val = i__; + dmax__ = (d__1 = dx[i__], abs(d__1)); +L30: + ; + } + return ret_val; +} /* idamax_ */ + +real_type epslon_(real_type *x) +{ +#if defined(TEST_MPF_100) || defined(TEST_MPFR_100) || defined(TEST_GMPXX) || defined(TEST_MPFRXX) + return std::ldexp(1.0, 1 - ((100 + 1) * 1000L) / 301L); +#elif defined(TEST_E_FLOAT_BN) + return std::pow(10.0, 1-std::numeric_limits::digits10); +#else + return CAST_TO_RT(std::numeric_limits::epsilon()); +#endif +} /* epslon_ */ + +/* Subroutine */ int mm_(real_type *a, integer *lda, integer *n1, integer * + n3, real_type *b, integer *ldb, integer *n2, real_type *c__, + integer *ldc) +{ + /* System generated locals */ + integer a_dim1, a_offset, b_dim1, b_offset, c_dim1, c_offset, i__1, i__2; + + /* Local variables */ + static integer i__, j; + + + /* purpose: */ + /* multiply matrix b times matrix c and store the result in matrix a. */ + + /* parameters: */ + + /* a double precision(lda,n3), matrix of n1 rows and n3 columns */ + + /* lda integer, leading dimension of array a */ + + /* n1 integer, number of rows in matrices a and b */ + + /* n3 integer, number of columns in matrices a and c */ + + /* b double precision(ldb,n2), matrix of n1 rows and n2 columns */ + + /* ldb integer, leading dimension of array b */ + + /* n2 integer, number of columns in matrix b, and number of rows in */ + /* matrix c */ + + /* c double precision(ldc,n3), matrix of n2 rows and n3 columns */ + + /* ldc integer, leading dimension of array c */ + + /* ---------------------------------------------------------------------- */ + + /* Parameter adjustments */ + a_dim1 = *lda; + a_offset = 1 + a_dim1; + a -= a_offset; + b_dim1 = *ldb; + b_offset = 1 + b_dim1; + b -= b_offset; + c_dim1 = *ldc; + c_offset = 1 + c_dim1; + c__ -= c_offset; + + /* Function Body */ + i__1 = *n3; + for (j = 1; j <= i__1; ++j) { + i__2 = *n1; + for (i__ = 1; i__ <= i__2; ++i__) { + a[i__ + j * a_dim1] = CAST_TO_RT(0); + /* L10: */ + } + dmxpy_(n2, &a[j * a_dim1 + 1], n1, ldb, &c__[j * c_dim1 + 1], &b[ + b_offset]); + /* L20: */ + } + + return 0; +} /* mm_ */ + +/* Subroutine */ int dmxpy_(integer *n1, real_type *y, integer *n2, integer * + ldm, real_type *x, real_type *m) +{ + /* System generated locals */ + integer m_dim1, m_offset, i__1, i__2; + + /* Local variables */ + static integer i__, j, jmin; + + + /* purpose: */ + /* multiply matrix m times vector x and add the result to vector y. */ + + /* parameters: */ + + /* n1 integer, number of elements in vector y, and number of rows in */ + /* matrix m */ + + /* y double precision(n1), vector of length n1 to which is added */ + /* the product m*x */ + + /* n2 integer, number of elements in vector x, and number of columns */ + /* in matrix m */ + + /* ldm integer, leading dimension of array m */ + + /* x double precision(n2), vector of length n2 */ + + /* m double precision(ldm,n2), matrix of n1 rows and n2 columns */ + + /* ---------------------------------------------------------------------- */ + + /* cleanup odd vector */ + + /* Parameter adjustments */ + --y; + m_dim1 = *ldm; + m_offset = 1 + m_dim1; + m -= m_offset; + --x; + + /* Function Body */ + j = *n2 % 2; + if (j >= 1) { + i__1 = *n1; + for (i__ = 1; i__ <= i__1; ++i__) { + y[i__] += x[j] * m[i__ + j * m_dim1]; + /* L10: */ + } + } + + /* cleanup odd group of two vectors */ + + j = *n2 % 4; + if (j >= 2) { + i__1 = *n1; + for (i__ = 1; i__ <= i__1; ++i__) { + y[i__] = y[i__] + x[j - 1] * m[i__ + (j - 1) * m_dim1] + x[j] * m[ + i__ + j * m_dim1]; + /* L20: */ + } + } + + /* cleanup odd group of four vectors */ + + j = *n2 % 8; + if (j >= 4) { + i__1 = *n1; + for (i__ = 1; i__ <= i__1; ++i__) { + y[i__] = y[i__] + x[j - 3] * m[i__ + (j - 3) * m_dim1] + x[j - 2] + * m[i__ + (j - 2) * m_dim1] + x[j - 1] * m[i__ + (j - 1) * + m_dim1] + x[j] * m[i__ + j * m_dim1]; + /* L30: */ + } + } + + /* cleanup odd group of eight vectors */ + + j = *n2 % 16; + if (j >= 8) { + i__1 = *n1; + for (i__ = 1; i__ <= i__1; ++i__) { + y[i__] = y[i__] + x[j - 7] * m[i__ + (j - 7) * m_dim1] + x[j - 6] + * m[i__ + (j - 6) * m_dim1] + x[j - 5] * m[i__ + (j - 5) * + m_dim1] + x[j - 4] * m[i__ + (j - 4) * m_dim1] + x[j - 3] + * m[i__ + (j - 3) * m_dim1] + x[j - 2] * m[i__ + (j - 2) + * m_dim1] + x[j - 1] * m[i__ + (j - 1) * m_dim1] + x[j] * + m[i__ + j * m_dim1]; + /* L40: */ + } + } + + /* main loop - groups of sixteen vectors */ + + jmin = j + 16; + i__1 = *n2; + for (j = jmin; j <= i__1; j += 16) { + i__2 = *n1; + for (i__ = 1; i__ <= i__2; ++i__) { + y[i__] = y[i__] + x[j - 15] * m[i__ + (j - 15) * m_dim1] + x[j - + 14] * m[i__ + (j - 14) * m_dim1] + x[j - 13] * m[i__ + (j + - 13) * m_dim1] + x[j - 12] * m[i__ + (j - 12) * m_dim1] + + x[j - 11] * m[i__ + (j - 11) * m_dim1] + x[j - 10] * m[ + i__ + (j - 10) * m_dim1] + x[j - 9] * m[i__ + (j - 9) * + m_dim1] + x[j - 8] * m[i__ + (j - 8) * m_dim1] + x[j - 7] + * m[i__ + (j - 7) * m_dim1] + x[j - 6] * m[i__ + (j - 6) * + m_dim1] + x[j - 5] * m[i__ + (j - 5) * m_dim1] + x[j - 4] + * m[i__ + (j - 4) * m_dim1] + x[j - 3] * m[i__ + (j - 3) + * m_dim1] + x[j - 2] * m[i__ + (j - 2) * m_dim1] + x[j - + 1] * m[i__ + (j - 1) * m_dim1] + x[j] * m[i__ + j * + m_dim1]; + /* L50: */ + } + /* L60: */ + } + return 0; +} /* dmxpy_ */ + +real_type ran_(integer *iseed) +{ + /* System generated locals */ + real_type ret_val; + + /* Local variables */ + static integer it1, it2, it3, it4; + + + /* modified from the LAPACK auxiliary routine 10/12/92 JD */ + /* -- LAPACK auxiliary routine (version 1.0) -- */ + /* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ + /* Courant Institute, Argonne National Lab, and Rice University */ + /* February 29, 1992 */ + + /* .. Array Arguments .. */ + /* .. */ + + /* Purpose */ + /* ======= */ + + /* DLARAN returns a random double number from a uniform (0,1) */ + /* distribution. */ + + /* Arguments */ + /* ========= */ + + /* ISEED (input/output) INTEGER array, dimension (4) */ + /* On entry, the seed of the random number generator; the array */ + /* elements must be between 0 and 4095, and ISEED(4) must be */ + /* odd. */ + /* On exit, the seed is updated. */ + + /* Further Details */ + /* =============== */ + + /* This routine uses a multiplicative congruential method with modulus */ + /* 2**48 and multiplier 33952834046453 (see G.S.Fishman, */ + /* 'Multiplicative congruential random number generators with modulus */ + /* 2**b: an exhaustive analysis for b = 32 and a partial analysis for */ + /* b = 48', Math. Comp. 189, pp 331-344, 1990). */ + + /* 48-bit integers are stored in 4 integer array elements with 12 bits */ + /* per element. Hence the routine is portable across machines with */ + /* integers of 32 bits or more. */ + + /* .. Parameters .. */ + /* .. */ + /* .. Local Scalars .. */ + /* .. */ + /* .. Intrinsic Functions .. */ + /* .. */ + /* .. Executable Statements .. */ + + /* multiply the seed by the multiplier modulo 2**48 */ + + /* Parameter adjustments */ + --iseed; + + /* Function Body */ + it4 = iseed[4] * 2549; + it3 = it4 / 4096; + it4 -= it3 << 12; + it3 = it3 + iseed[3] * 2549 + iseed[4] * 2508; + it2 = it3 / 4096; + it3 -= it2 << 12; + it2 = it2 + iseed[2] * 2549 + iseed[3] * 2508 + iseed[4] * 322; + it1 = it2 / 4096; + it2 -= it1 << 12; + it1 = it1 + iseed[1] * 2549 + iseed[2] * 2508 + iseed[3] * 322 + iseed[4] + * 494; + it1 %= 4096; + + /* return updated seed */ + + iseed[1] = it1; + iseed[2] = it2; + iseed[3] = it3; + iseed[4] = it4; + + /* convert 48-bit integer to a double number in the interval (0,1) */ + + ret_val = ((real_type) it1 + ((real_type) it2 + ((real_type) it3 + ( + real_type) it4 * 2.44140625e-4) * 2.44140625e-4) * 2.44140625e-4) + * 2.44140625e-4; + return ret_val; + + /* End of RAN */ + +} /* ran_ */ + +/* + +Double results: +~~~~~~~~~~~~~~ + +norm. resid resid machep x(1) x(n) +6.4915 7.207e-013 2.2204e-016 1 1 + + + +times are reported for matrices of order 1000 +factor solve total mflops unit ratio +times for array with leading dimension of1001 +1.443 0.003 1.446 462.43 0.004325 25.821 + + +mpf_class results: +~~~~~~~~~~~~~~~~~~ + +norm. resid resid machep x(1) x(n) +3.6575e-05 5.2257e-103 2.8575e-101 1 1 + + + +times are reported for matrices of order 1000 +factor solve total mflops unit ratio +times for array with leading dimension of1001 +266.45 0.798 267.24 2.5021 0.79933 4772.2 + + +mp_number >: +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + norm. resid resid machep x(1) x(n) + 0.36575e-4 0.52257e-102 0.28575e-100 0.1e1 0.1e1 + + + + times are reported for matrices of order 1000 + factor solve total mflops unit ratio + times for array with leading dimension of1001 + 279.96 0.84 280.8 2.3813 0.83988 5014.3 + +boost::math::ef::e_float: +~~~~~~~~~~~~~~~~~~~~~~~~~ + + norm. resid resid machep x(1) x(n) + 2.551330735e-16 1.275665107e-112 1e-99 1 1 + + + + times are reported for matrices of order 1000 + factor solve total mflops unit ratio + times for array with leading dimension of1001 + 363.89 1.074 364.97 1.8321 1.0916 6517.3 +*/ diff --git a/test/test_arithmetic.cpp b/test/test_arithmetic.cpp new file mode 100644 index 00000000..3e82e749 --- /dev/null +++ b/test/test_arithmetic.cpp @@ -0,0 +1,894 @@ +/////////////////////////////////////////////////////////////// +// Copyright 2011 John Maddock. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_ + +#include +#include + +#if !defined(TEST_MPF50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_E_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) +# define TEST_MPF50 +# define TEST_MPF +# define TEST_BACKEND +# define TEST_MPZ +# define TEST_MPFR +# define TEST_MPFR_50 +# define TEST_E_FLOAT +# define TEST_MPQ + +#ifdef _MSC_VER +#pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") +#endif +#ifdef __GNUC__ +#pragma warning "CAUTION!!: No backend type specified so testing everything.... this will take some time!!" +#endif + +#endif + +#if defined(TEST_MPF50) || defined(TEST_MPF) || defined(TEST_MPZ) || defined(TEST_MPQ) +#include +#endif +#ifdef TEST_BACKEND +#include +#endif +#ifdef TEST_E_FLOAT +#include +#endif +#if defined(TEST_MPFR) || defined(TEST_MPFR_50) +#include +#endif + +#define BOOST_TEST_THROW(x, EX)\ + try { x; BOOST_ERROR("Expected exception not thrown"); } \ + catch(const EX&){}\ + catch(...){ BOOST_ERROR("Incorrect exception type thrown"); } + +#undef BOOST_TEST +#define BOOST_TEST(x)\ + try {\ + if(x){}else{ BOOST_ERROR("Value was zero: "); }\ + }\ + catch(const std::exception& e){ \ + BOOST_ERROR("Unexpected exception: ");\ + BOOST_LIGHTWEIGHT_TEST_OSTREAM << e.what() << std::endl;\ + } + +bool isfloat(float){ return true; } +bool isfloat(double){ return true; } +bool isfloat(long double){ return true; } +template bool isfloat(T){ return false; } + +#define BOOST_TEST_CLOSE(x, y, tol)\ + if(x == 0){\ + BOOST_TEST(y == 0); }\ + else if(!isfloat(x)){\ + BOOST_TEST(x == y); }\ + else if((x != y) && (::fabsl(static_cast((x-y)/x)) > tol))\ + {\ + BOOST_ERROR("Expected tolerance was exceeded: ");\ + BOOST_LIGHTWEIGHT_TEST_OSTREAM << std::setprecision(34) << "(x-y)/x = " << ::fabsl(static_cast((x-y)/x)) \ + << " tolerance = " << tol << std::endl;\ + } + +template +void test_integer_ops(const T&){} + +template +void test_integer_ops(const boost::mpl::int_&) +{ + Real a(20); + Real b(7); + Real c; + BOOST_TEST(a % b == 20 % 7); + BOOST_TEST(a % 7 == 20 % 7); + BOOST_TEST(a % 7u == 20 % 7); + BOOST_TEST(-a % b == -20 % 7); + BOOST_TEST(-a % -b == -20 % -7); + BOOST_TEST(a % -b == 20 % -7); + BOOST_TEST(-a % 7 == -20 % 7); + BOOST_TEST(-a % -7 == -20 % -7); + BOOST_TEST(a % -7 == 20 % -7); + BOOST_TEST(-a % 7u == -20 % 7); + + b = -b; + BOOST_TEST(a % b == 20 % -7); + a = -a; + BOOST_TEST(a % b == -20 % -7); + BOOST_TEST(a % -7 == -20 % -7); + b = 7; + BOOST_TEST(a % b == -20 % 7); + BOOST_TEST(a % 7 == -20 % 7); + BOOST_TEST(a % 7u == -20 % 7); + + a = 20; + a %= b; + BOOST_TEST(a == 20 % 7); + a = -20; + a %= b; + BOOST_TEST(a == -20 % 7); + a = 20; + a %= -b; + BOOST_TEST(a == 20 % -7); + a = -20; + a %= -b; + BOOST_TEST(a == -20 % -7); + + a = 20; + a %= 7; + BOOST_TEST(a == 20 % 7); + a = -20; + a %= 7; + BOOST_TEST(a == -20 % 7); + a = 20; + a %= -7; + BOOST_TEST(a == 20 % -7); + a = -20; + a %= -7; + BOOST_TEST(a == -20 % -7); +#ifndef BOOST_NO_LONG_LONG + a = 20; + a %= 7uLL; + BOOST_TEST(a == 20 % 7); + a = -20; + a %= 7uLL; + BOOST_TEST(a == -20 % 7); + a = 20; + a %= -7LL; + BOOST_TEST(a == 20 % -7); + a = -20; + a %= -7LL; + BOOST_TEST(a == -20 % -7); +#endif + a = 20; + BOOST_TEST(++a == 21); + BOOST_TEST(--a == 20); + BOOST_TEST(a++ == 20); + BOOST_TEST(a == 21); + BOOST_TEST(a-- == 21); + BOOST_TEST(a == 20); + a = 2000; + a <<= 20; + BOOST_TEST(a == 2000L << 20); + a >>= 20; + BOOST_TEST(a == 2000); + a <<= 20u; + BOOST_TEST(a == 2000L << 20); + a >>= 20u; + BOOST_TEST(a == 2000); + BOOST_TEST_THROW(a <<= -20, std::out_of_range); + BOOST_TEST_THROW(a >>= -20, std::out_of_range); +#ifndef BOOST_NO_LONG_LONG + if(sizeof(long long) > sizeof(std::size_t)) + { + // extreme values should trigger an exception: + BOOST_TEST_THROW(a >>= (1uLL << (sizeof(long long) * CHAR_BIT - 2)), std::out_of_range); + BOOST_TEST_THROW(a <<= (1uLL << (sizeof(long long) * CHAR_BIT - 2)), std::out_of_range); + } +#endif + a = 20; + b = a << 20; + BOOST_TEST(b == (20 << 20)); + b = a >> 2; + BOOST_TEST(b == (20 >> 2)); + b = (a + 2) << 10; + BOOST_TEST(b == (22 << 10)); + b = (a + 3) >> 3; + BOOST_TEST(b == (23 >> 3)); + // + // Bit fiddling: + // + int i = 1020304; + int j = 56789123; + int k = 4523187; + a = i; + b = j; + c = a; + c &= b; + BOOST_TEST(c == (i & j)); + c = a; + c &= j; + BOOST_TEST(c == (i & j)); + c = a; + c &= a + b; + BOOST_TEST(c == (i & (i + j))); + BOOST_TEST((a & b) == (i & j)); + c = k; + a = a & (b + k); + BOOST_TEST(a == (i & (j + k))); + a = i; + a = (b + k) & a; + BOOST_TEST(a == (i & (j + k))); + a = i; + c = a & b & k; + BOOST_TEST(c == (i&j&k)); + + a = i; + b = j; + c = a; + c |= b; + BOOST_TEST(c == (i | j)); + c = a; + c |= j; + BOOST_TEST(c == (i | j)); + c = a; + c |= a + b; + BOOST_TEST(c == (i | (i + j))); + BOOST_TEST((a | b) == (i | j)); + c = k; + a = a | (b + k); + BOOST_TEST(a == (i | (j + k))); + a = i; + a = (b + k) | a; + BOOST_TEST(a == (i | (j + k))); + a = i; + c = a | b | k; + BOOST_TEST(c == (i|j|k)); + + a = i; + b = j; + c = a; + c ^= b; + BOOST_TEST(c == (i ^ j)); + c = a; + c ^= j; + BOOST_TEST(c == (i ^ j)); + c = a; + c ^= a + b; + BOOST_TEST(c == (i ^ (i + j))); + BOOST_TEST((a ^ b) == (i ^ j)); + c = k; + a = a ^ (b + k); + BOOST_TEST(a == (i ^ (j + k))); + a = i; + a = (b + k) ^ a; + BOOST_TEST(a == (i ^ (j + k))); + a = i; + c = a ^ b ^ k; + BOOST_TEST(c == (i^j^k)); + a = i; + b = j; + c = k; + BOOST_TEST(~a == ~i); + c = a & ~b; + BOOST_TEST(c == (i & ~j)); + c = ~(a | b); + BOOST_TEST(c == ~(i | j)); + // + // Non-member functions: + // + a = -20; + BOOST_TEST(abs(a) == 20); + BOOST_TEST(abs(-a) == 20); + BOOST_TEST(abs(+a) == 20); + a = 20; + BOOST_TEST(abs(a) == 20); + BOOST_TEST(abs(-a) == 20); + BOOST_TEST(abs(+a) == 20); +} + +template +void test_real_ops(const T&){} + +template +void test_real_ops(const boost::mpl::int_&) +{ +#if defined(TEST_MPF) || defined(TEST_MPF_50) || defined(TEST_BACKEND) || defined(TEST_MPFR) + BOOST_TEST(abs(Real(2)) == 2); + BOOST_TEST(abs(Real(-2)) == 2); + BOOST_TEST(fabs(Real(2)) == 2); + BOOST_TEST(fabs(Real(-2)) == 2); + BOOST_TEST(floor(Real(5) / 2) == 2); + BOOST_TEST(ceil(Real(5) / 2) == 3); + BOOST_TEST(floor(Real(-5) / 2) == -3); + BOOST_TEST(ceil(Real(-5) / 2) == -2); + BOOST_TEST(trunc(Real(5) / 2) == 2); + BOOST_TEST(trunc(Real(-5) / 2) == -2); + // + // ldexp and frexp, these pretty much have to implemented by each backend: + // + BOOST_TEST(ldexp(Real(2), 5) == 64); + BOOST_TEST(ldexp(Real(2), -5) == Real(2) / 32); + Real v(512); + int exp; + Real r = frexp(v, &exp); + BOOST_TEST(r == 0.5); + BOOST_TEST(exp == 10); + BOOST_TEST(v == 512); + v = 1 / v; + r = frexp(v, &exp); + BOOST_TEST(r == 0.5); + BOOST_TEST(exp == -8); + // + // pow and exp: + // + v = 3.25; + r = pow(v, 0); + BOOST_TEST(r == 1); + r = pow(v, 1); + BOOST_TEST(r == 3.25); + r = pow(v, 2); + BOOST_TEST(r == boost::math::pow<2>(3.25)); + r = pow(v, 3); + BOOST_TEST(r == boost::math::pow<3>(3.25)); + r = pow(v, 4); + BOOST_TEST(r == boost::math::pow<4>(3.25)); + r = pow(v, 5); + BOOST_TEST(r == boost::math::pow<5>(3.25)); + r = pow(v, 6); + BOOST_TEST(r == boost::math::pow<6>(3.25)); + r = pow(v, 25); + BOOST_TEST(r == boost::math::pow<25>(Real(3.25))); + /* + r = pow(v, 56); + BOOST_TEST(r == boost::math::pow<56>(Real(3.25))); + */ +#endif +} + +#ifdef TEST_E_FLOAT + +template +struct lexical_cast_target_type +{ + typedef long double type; +}; + +#else + +template +struct lexical_cast_target_type +{ + typedef typename boost::mpl::if_< + boost::is_signed, + boost::intmax_t, + typename boost::mpl::if_< + boost::is_unsigned, + boost::uintmax_t, + T + >::type + >::type type; +}; + +#endif + +template +void test_negative_mixed(boost::mpl::true_ const&) +{ + typedef typename lexical_cast_target_type::type target_type; + std::cout << "Testing mixed arithmetic with type: " << typeid(Real).name() << " and " << typeid(Num).name() << std::endl; + Num n1 = -static_cast(1uLL << (std::numeric_limits::digits - 1)); + Num n2 = -1; + Num n3 = 0; + Num n4 = -20; + Num n5 = -8; + BOOST_TEST((Real(n2) < 0) == true); + BOOST_TEST((Real(n2) <= 0) == true); + BOOST_TEST((Real(n2) > 0) == false); + BOOST_TEST((Real(n2) >= 0) == false); + BOOST_TEST((Real(n2) == 0) == false); + BOOST_TEST((Real(n2) != 0) == true); + BOOST_TEST((Real(n2) == n2) == true); + BOOST_TEST((Real(n2) != n2) == false); + BOOST_TEST((Real(n2) >= n2) == true); + BOOST_TEST((Real(n2) <= n2) == true); + BOOST_TEST((Real(n2) > n2) == false); + BOOST_TEST((Real(n2) < n2) == false); + // Default construct: + BOOST_TEST(Real(n1) == n1); + BOOST_TEST(Real(n2) == n2); + BOOST_TEST(Real(n3) == n3); + BOOST_TEST(Real(n4) == n4); + BOOST_TEST(n1 == Real(n1)); + BOOST_TEST(n2 == Real(n2)); + BOOST_TEST(n3 == Real(n3)); + BOOST_TEST(n4 == Real(n4)); +#if defined(TEST_MPFR) || defined(TEST_MPFR_50) + Num tol = 10 * std::numeric_limits::epsilon(); +#else + Num tol = 0; +#endif + BOOST_TEST_CLOSE(n1, boost::lexical_cast(Real(n1).str(0, boost::is_floating_point::value)), tol); + BOOST_TEST_CLOSE(n2, boost::lexical_cast(Real(n2).str(0, boost::is_floating_point::value)), 0); + BOOST_TEST_CLOSE(n3, boost::lexical_cast(Real(n3).str(0, boost::is_floating_point::value)), 0); + BOOST_TEST_CLOSE(n4, boost::lexical_cast(Real(n4).str(0, boost::is_floating_point::value)), 0); + // Assignment: + Real r(0); + BOOST_TEST(r != n1); + r = n1; + BOOST_TEST(r == n1); + r = n2; + BOOST_TEST(r == n2); + r = n3; + BOOST_TEST(r == n3); + r = n4; + BOOST_TEST(r == n4); + // Addition: + r = n2; + BOOST_TEST(r + n4 == n2 + n4); + BOOST_TEST(Real(r + n4) == n2 + n4); + r += n4; + BOOST_TEST(r == n2 + n4); + // subtraction: + r = n4; + BOOST_TEST(r - n5 == n4 - n5); + BOOST_TEST(Real(r - n5) == n4 - n5); + r -= n5; + BOOST_TEST(r == n4 - n5); + // Multiplication: + r = n2; + BOOST_TEST(r * n4 == n2 * n4); + BOOST_TEST(Real(r * n4) == n2 * n4); + r *= n4; + BOOST_TEST(r == n2 * n4); + // Division: + r = n1; + BOOST_TEST(r / n5 == n1 / n5); + BOOST_TEST(Real(r / n5) == n1 / n5); + r /= n5; + BOOST_TEST(r == n1 / n5); + // + // Extra cases for full coverage: + // + r = Real(n4) + n5; + BOOST_TEST(r == n4 + n5); + r = n4 + Real(n5); + BOOST_TEST(r == n4 + n5); + r = Real(n4) - n5; + BOOST_TEST(r == n4 - n5); + r = n4 - Real(n5); + BOOST_TEST(r == n4 - n5); + r = n4 * Real(n5); + BOOST_TEST(r == n4 * n5); + r = (4 * n4) / Real(4); + BOOST_TEST(r == n4); +} + +template +void test_negative_mixed(boost::mpl::false_ const&) +{ +} + +template +void test_mixed() +{ + typedef typename lexical_cast_target_type::type target_type; + std::cout << "Testing mixed arithmetic with type: " << typeid(Real).name() << " and " << typeid(Num).name() << std::endl; + Num n1 = static_cast(1uLL << (std::numeric_limits::digits - 1)); + Num n2 = 1; + Num n3 = 0; + Num n4 = 20; + Num n5 = 8; + BOOST_TEST((Real(n2) < 0) == false); + BOOST_TEST((Real(n2) <= 0) == false); + BOOST_TEST((Real(n2) > 0) == true); + BOOST_TEST((Real(n2) >= 0) == true); + BOOST_TEST((Real(n2) == 0) == false); + BOOST_TEST((Real(n2) != 0) == true); + BOOST_TEST((Real(n2) == n2) == true); + BOOST_TEST((Real(n2) != n2) == false); + BOOST_TEST((Real(n2) >= n2) == true); + BOOST_TEST((Real(n2) <= n2) == true); + BOOST_TEST((Real(n2) > n2) == false); + BOOST_TEST((Real(n2) < n2) == false); + // Default construct: + BOOST_TEST(Real(n1) == n1); + BOOST_TEST(Real(n2) == n2); + BOOST_TEST(Real(n3) == n3); + BOOST_TEST(Real(n4) == n4); + BOOST_TEST(Real(n1).template convert_to() == n1); + BOOST_TEST(Real(n2).template convert_to() == n2); + BOOST_TEST(Real(n3).template convert_to() == n3); + BOOST_TEST(Real(n4).template convert_to() == n4); + BOOST_TEST(n1 == Real(n1)); + BOOST_TEST(n2 == Real(n2)); + BOOST_TEST(n3 == Real(n3)); + BOOST_TEST(n4 == Real(n4)); + std::cout << Real(n1).str(0, boost::is_floating_point::value) << std::endl; +#if defined(TEST_MPFR) || defined(TEST_MPFR_50) + Num tol = 10 * std::numeric_limits::epsilon(); +#else + Num tol = 0; +#endif + BOOST_TEST_CLOSE(n1, boost::lexical_cast(Real(n1).str(0, boost::is_floating_point::value)), tol); + BOOST_TEST_CLOSE(n2, boost::lexical_cast(Real(n2).str(0, boost::is_floating_point::value)), 0); + BOOST_TEST_CLOSE(n3, boost::lexical_cast(Real(n3).str(0, boost::is_floating_point::value)), 0); + BOOST_TEST_CLOSE(n4, boost::lexical_cast(Real(n4).str(0, boost::is_floating_point::value)), 0); + // Assignment: + Real r(0); + BOOST_TEST(r != n1); + r = n1; + BOOST_TEST(r == n1); + r = n2; + BOOST_TEST(r == n2); + r = n3; + BOOST_TEST(r == n3); + r = n4; + BOOST_TEST(r == n4); + // Addition: + r = n2; + BOOST_TEST(r + n4 == n2 + n4); + BOOST_TEST(Real(r + n4) == n2 + n4); + r += n4; + BOOST_TEST(r == n2 + n4); + // subtraction: + r = n4; + BOOST_TEST(r - n5 == n4 - n5); + BOOST_TEST(Real(r - n5) == n4 - n5); + r -= n5; + BOOST_TEST(r == n4 - n5); + // Multiplication: + r = n2; + BOOST_TEST(r * n4 == n2 * n4); + BOOST_TEST(Real(r * n4) == n2 * n4); + r *= n4; + BOOST_TEST(r == n2 * n4); + // Division: + r = n1; + BOOST_TEST(r / n5 == n1 / n5); + BOOST_TEST(Real(r / n5) == n1 / n5); + r /= n5; + BOOST_TEST(r == n1 / n5); + // + // special cases for full coverage: + // + r = n5 + Real(n4); + BOOST_TEST(r == n4 + n5); + r = n4 - Real(n5); + BOOST_TEST(r == n4 - n5); + r = n4 * Real(n5); + BOOST_TEST(r == n4 * n5); + r = (4 * n4) / Real(4); + BOOST_TEST(r == n4); + test_negative_mixed(boost::mpl::bool_::is_signed>()); +} + +template +void test() +{ +#ifndef NO_MIXED_OPS + test_mixed(); + test_mixed(); + test_mixed(); + test_mixed(); + test_mixed(); + test_mixed(); + test_mixed(); + test_mixed(); + test_mixed(); +#ifdef BOOST_HAS_LONG_LONG + test_mixed(); + test_mixed(); +#endif + test_mixed(); + test_mixed(); + test_mixed(); +#endif + // + // Integer only functions: + // + test_integer_ops(typename boost::math::number_category::type()); + // + // Real number only functions: + // + test_real_ops(typename boost::math::number_category::type()); + // + // Test basic arithmetic: + // + Real a(8); + Real b(64); + Real c(500); + Real d(1024); + BOOST_TEST(a + b == 72); + a += b; + BOOST_TEST(a == 72); + BOOST_TEST(a - b == 8); + a -= b; + BOOST_TEST(a == 8); + BOOST_TEST(a * b == 8*64L); + a *= b; + BOOST_TEST(a == 8*64L); + BOOST_TEST(a / b == 8); + a /= b; + BOOST_TEST(a == 8); + Real ac(a); + BOOST_TEST(ac == a); + BOOST_TEST(-a == -8); + ac = a * c; + BOOST_TEST(ac == 8*500L); + ac = 8*500L; + ac = ac + b + c; + BOOST_TEST(ac == 8*500L+64+500); + ac = a; + ac = b + c + ac; + BOOST_TEST(ac == 8+64+500); + ac = ac - b + c; + BOOST_TEST(ac == 8+64+500-64+500); + ac = a; + ac = b + c - ac; + BOOST_TEST(ac == -8+64+500); + ac = a; + ac = ac * b; + BOOST_TEST(ac == 8*64); + ac = a; + ac *= b * ac; + BOOST_TEST(ac == 8*8*64); + ac = b; + ac = ac / a; + BOOST_TEST(ac == 64/8); + ac = b; + ac /= ac / a; + BOOST_TEST(ac == 64 / (64/8)); + ac = a; + ac = b + ac * a; + BOOST_TEST(ac == 64 * 2); + ac = a; + ac = b - ac * a; + BOOST_TEST(ac == 0); + ac = a; + ac = b * (ac + a); + BOOST_TEST(ac == 64 * (16)); + ac = a; + ac = b / (ac * 1); + BOOST_TEST(ac == 64 / 8); + ac = a; + ac = ac + b; + BOOST_TEST(ac == 8 + 64); + ac = a; + ac = a + ac; + BOOST_TEST(ac == 16); + ac = a; + ac = ac - b; + BOOST_TEST(ac == 8 - 64); + ac = a; + ac = a - ac; + BOOST_TEST(ac == 0); + ac = a; + ac += a + b; + BOOST_TEST(ac == 80); + ac = a; + ac += b + a; + BOOST_TEST(ac == 80); + ac = a; + ac -= a + b; + BOOST_TEST(ac == -64); + ac = a; + ac -= b - a; + BOOST_TEST(ac == 16 - 64); + ac = +a; + BOOST_TEST(ac == 8); + ac = -a; + BOOST_TEST(ac == -8); + ac = 8; + ac = a * ac; + BOOST_TEST(ac == 8*8); + ac = a; + ac = a; + ac += +a; + BOOST_TEST(ac == 16); + ac = a; + ac += -a; + BOOST_TEST(ac == 0); + ac = a; + ac += b - a; + BOOST_TEST(ac == 8 + 64-8); + ac = a; + ac += b*c; + BOOST_TEST(ac == 8 + 64 * 500); + ac = a; + ac = a; + ac -= +a; + BOOST_TEST(ac == 0); + ac = a; + ac -= -a; + BOOST_TEST(ac == 16); + ac = a; + ac -= c - b; + BOOST_TEST(ac == 8 - (500-64)); + ac = a; + ac -= b*c; + BOOST_TEST(ac == 8 - 500*64); + ac = a; + ac += ac * b; + BOOST_TEST(ac == 8 + 8 * 64); + ac = a; + ac -= ac * b; + BOOST_TEST(ac == 8 - 8 * 64); + ac = a * 8; + ac *= +a; + BOOST_TEST(ac == 64 * 8); + ac = a; + ac *= -a; + BOOST_TEST(ac == -64); + ac = a; + ac *= b * c; + BOOST_TEST(ac == 8 * 64 * 500); + ac = a; + ac *= b / a; + BOOST_TEST(ac == 8 * 64 / 8); + ac = a; + ac *= b + c; + BOOST_TEST(ac == 8 * (64 + 500)); + ac = b; + ac /= +a; + BOOST_TEST(ac == 8); + ac = b; + ac /= -a; + BOOST_TEST(ac == -8); + ac = b; + ac /= b / a; + BOOST_TEST(ac == 64 / (64/8)); + ac = b; + ac /= a + Real(0); + BOOST_TEST(ac == 8); + // + // simple tests with immediate values, these calls can be optimised in many backends: + // + ac = a + b; + BOOST_TEST(ac == 72); + ac = a + +b; + BOOST_TEST(ac == 72); + ac = +a + b; + BOOST_TEST(ac == 72); + ac = +a + +b; + BOOST_TEST(ac == 72); + ac = a + -b; + BOOST_TEST(ac == 8 - 64); + ac = -a + b; + BOOST_TEST(ac == -8+64); + ac = -a + -b; + BOOST_TEST(ac == -72); + ac = a + - + -b; // lots of unary operators!! + BOOST_TEST(ac == 72); + ac = a; + ac = b / ac; + BOOST_TEST(ac == b / a); + // + // Comparisons: + // + BOOST_TEST((a == b) == false); + BOOST_TEST((a != b) == true); + BOOST_TEST((a <= b) == true); + BOOST_TEST((a < b) == true); + BOOST_TEST((a >= b) == false); + BOOST_TEST((a > b) == false); + + BOOST_TEST((a+b == b) == false); + BOOST_TEST((a+b != b) == true); + BOOST_TEST((a+b >= b) == true); + BOOST_TEST((a+b > b) == true); + BOOST_TEST((a+b <= b) == false); + BOOST_TEST((a+b < b) == false); + + BOOST_TEST((a == b+a) == false); + BOOST_TEST((a != b+a) == true); + BOOST_TEST((a <= b+a) == true); + BOOST_TEST((a < b+a) == true); + BOOST_TEST((a >= b+a) == false); + BOOST_TEST((a > b+a) == false); + + BOOST_TEST((a+b == b+a) == true); + BOOST_TEST((a+b != b+a) == false); + BOOST_TEST((a+b <= b+a) == true); + BOOST_TEST((a+b < b+a) == false); + BOOST_TEST((a+b >= b+a) == true); + BOOST_TEST((a+b > b+a) == false); + + BOOST_TEST((8 == b+a) == false); + BOOST_TEST((8 != b+a) == true); + BOOST_TEST((8 <= b+a) == true); + BOOST_TEST((8 < b+a) == true); + BOOST_TEST((8 >= b+a) == false); + BOOST_TEST((8 > b+a) == false); + BOOST_TEST((800 == b+a) == false); + BOOST_TEST((800 != b+a) == true); + BOOST_TEST((800 >= b+a) == true); + BOOST_TEST((800 > b+a) == true); + BOOST_TEST((800 <= b+a) == false); + BOOST_TEST((800 < b+a) == false); + BOOST_TEST((72 == b+a) == true); + BOOST_TEST((72 != b+a) == false); + BOOST_TEST((72 <= b+a) == true); + BOOST_TEST((72 < b+a) == false); + BOOST_TEST((72 >= b+a) == true); + BOOST_TEST((72 > b+a) == false); + // + // Test sign and zero functions, plus use in boolian context: + // + a = 20; + BOOST_TEST(a.sign() > 0); + BOOST_TEST(!a.is_zero()); + a = -20; + BOOST_TEST(a.sign() < 0); + BOOST_TEST(!a.is_zero()); + a = 0; + BOOST_TEST(a.sign() == 0); + BOOST_TEST(a.is_zero()); + if(a) + { + BOOST_ERROR("Unexpected non-zero result"); + } + if(!a){} + else + { + BOOST_ERROR("Unexpected zero result"); + } + b = 2; + if(!b) + { + BOOST_ERROR("Unexpected zero result"); + } + if(b){} + else + { + BOOST_ERROR("Unexpected non-zero result"); + } + if(a && b) + { + BOOST_ERROR("Unexpected zero result"); + } + if(!(a || b)) + { + BOOST_ERROR("Unexpected zero result"); + } + if(a + b){} + else + { + BOOST_ERROR("Unexpected zero result"); + } + if(b - 2) + { + BOOST_ERROR("Unexpected non-zero result"); + } + // + // Test iostreams: + // + std::stringstream ss; + a = 20; + b = 2; + ss << a; + ss >> c; + BOOST_TEST(a == c); + ss.clear(); + ss << a + b; + ss >> c; + BOOST_TEST(c == 22); + BOOST_TEST(c == a + b); +} + + +int main() +{ +#ifdef TEST_BACKEND + test >(); +#endif +#ifdef TEST_MPF50 + test(); +#endif +#ifdef TEST_MPF + boost::math::mpf_real::default_precision(1000); + /* + boost::math::mpf_real r; + r.precision(50); + BOOST_TEST(r.precision() >= 50); + */ + BOOST_TEST(boost::math::mpf_real::default_precision() == 1000); + test(); +#endif +#ifdef TEST_MPZ + test(); +#endif +#ifdef TEST_MPQ + test(); +#endif +#ifdef TEST_E_FLOAT + test(); +#endif +#ifdef TEST_MPFR + test(); +#endif +#ifdef TEST_MPFR_50 + test(); +#endif + return boost::report_errors(); +} + diff --git a/test/test_numeric_limits.cpp b/test/test_numeric_limits.cpp new file mode 100644 index 00000000..1cd7f695 --- /dev/null +++ b/test/test_numeric_limits.cpp @@ -0,0 +1,173 @@ +/////////////////////////////////////////////////////////////// +// Copyright 2011 John Maddock. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_ + +#include + +#if !defined(TEST_MPF50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_E_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) +# define TEST_MPF50 +# define TEST_MPF +# define TEST_BACKEND +# define TEST_MPZ +# define TEST_MPFR +# define TEST_MPFR_50 +# define TEST_E_FLOAT +# define TEST_MPQ + +#ifdef _MSC_VER +#pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") +#endif +#ifdef __GNUC__ +#pragma warning "CAUTION!!: No backend type specified so testing everything.... this will take some time!!" +#endif + +#endif + +#if defined(TEST_MPF50) || defined(TEST_MPF) || defined(TEST_MPZ) || defined(TEST_MPQ) +#include +#endif +#ifdef TEST_BACKEND +#include +#endif +#ifdef TEST_E_FLOAT +#include +#endif +#if defined(TEST_MPFR) || defined(TEST_MPFR_50) +#include +#endif + +#define PRINT(x)\ + std::cout << BOOST_STRINGIZE(x) << " = " << std::numeric_limits::x << std::endl; + +template +void test() +{ + // + // Note really a test just yet, but we can at least print out all the values: + // + std::cout << "numeric_limits values for type " << typeid(Number).name() << std::endl; + + PRINT(is_specialized); + PRINT(min()); + PRINT(max()); +#ifndef BOOST_NO_NUMERIC_LIMITS_LOWEST + PRINT(lowest()); +#endif + PRINT(digits); + PRINT(digits10); +#ifndef BOOST_NO_NUMERIC_LIMITS_LOWEST + PRINT(max_digits10); +#endif + PRINT(is_signed); + PRINT(is_integer); + PRINT(is_exact); + PRINT(radix); + PRINT(epsilon()); + PRINT(round_error()); + PRINT(min_exponent); + PRINT(min_exponent10); + PRINT(max_exponent); + PRINT(max_exponent10); + PRINT(has_infinity); + PRINT(has_quiet_NaN); + PRINT(has_signaling_NaN); + PRINT(has_denorm); + PRINT(has_denorm_loss); + PRINT(infinity()); + PRINT(quiet_NaN()); + PRINT(signaling_NaN()); + PRINT(denorm_min()); + PRINT(is_iec559); + PRINT(is_bounded); + PRINT(is_modulo); + PRINT(traps); + PRINT(tinyness_before); + PRINT(round_style); + + if(std::numeric_limits::is_specialized) + { + if(std::numeric_limits::has_quiet_NaN) + { + BOOST_TEST((boost::math::isnan)(std::numeric_limits::quiet_NaN())); + BOOST_TEST(FP_NAN == (boost::math::fpclassify)(std::numeric_limits::quiet_NaN())); + BOOST_TEST(!(boost::math::isfinite)(std::numeric_limits::quiet_NaN())); + BOOST_TEST(!(boost::math::isnormal)(std::numeric_limits::quiet_NaN())); + BOOST_TEST(!(boost::math::isinf)(std::numeric_limits::quiet_NaN())); + } + if(std::numeric_limits::has_signaling_NaN) + { + BOOST_TEST((boost::math::isnan)(std::numeric_limits::signaling_NaN())); + BOOST_TEST(FP_NAN == (boost::math::fpclassify)(std::numeric_limits::signaling_NaN())); + BOOST_TEST(!(boost::math::isfinite)(std::numeric_limits::signaling_NaN())); + BOOST_TEST(!(boost::math::isnormal)(std::numeric_limits::signaling_NaN())); + BOOST_TEST(!(boost::math::isinf)(std::numeric_limits::signaling_NaN())); + } + if(std::numeric_limits::has_infinity) + { + BOOST_TEST((boost::math::isinf)(std::numeric_limits::infinity())); + BOOST_TEST(FP_INFINITE == (boost::math::fpclassify)(std::numeric_limits::infinity())); + BOOST_TEST(!(boost::math::isfinite)(std::numeric_limits::infinity())); + BOOST_TEST(!(boost::math::isnormal)(std::numeric_limits::infinity())); + BOOST_TEST(!(boost::math::isnan)(std::numeric_limits::infinity())); + } + if(std::numeric_limits::has_denorm) + { + BOOST_TEST(FP_SUBNORMAL == (boost::math::fpclassify)(std::numeric_limits::denorm_min())); + BOOST_TEST((boost::math::isfinite)(std::numeric_limits::denorm_min())); + BOOST_TEST(!(boost::math::isnormal)(std::numeric_limits::denorm_min())); + BOOST_TEST(!(boost::math::isinf)(std::numeric_limits::denorm_min())); + BOOST_TEST(!(boost::math::isnan)(std::numeric_limits::denorm_min())); + } + } + Number n = 0; + BOOST_TEST((boost::math::fpclassify)(n) == FP_ZERO); + BOOST_TEST((boost::math::isfinite)(n)); + BOOST_TEST(!(boost::math::isnormal)(n)); + BOOST_TEST(!(boost::math::isinf)(n)); + BOOST_TEST(!(boost::math::isnan)(n)); + n = 2; + BOOST_TEST((boost::math::fpclassify)(n) == FP_NORMAL); + BOOST_TEST((boost::math::isfinite)(n)); + BOOST_TEST((boost::math::isnormal)(n)); + BOOST_TEST(!(boost::math::isinf)(n)); + BOOST_TEST(!(boost::math::isnan)(n)); +} + + +int main() +{ +#ifdef TEST_BACKEND + test >(); +#endif +#ifdef TEST_MPF50 + test(); +#endif +#ifdef TEST_MPF + boost::math::mpf_real::default_precision(1000); + /* + boost::math::mpf_real r; + r.precision(50); + BOOST_TEST(r.precision() >= 50); + */ + BOOST_TEST(boost::math::mpf_real::default_precision() == 1000); + test(); +#endif +#ifdef TEST_MPZ + test(); +#endif +#ifdef TEST_MPQ + test(); +#endif +#ifdef TEST_E_FLOAT + test(); +#endif +#ifdef TEST_MPFR + test(); +#endif +#ifdef TEST_MPFR_50 + test(); +#endif + return boost::report_errors(); +} +