diff options
Diffstat (limited to 'src/boost/libs/numeric')
426 files changed, 60976 insertions, 0 deletions
diff --git a/src/boost/libs/numeric/conversion/README.md b/src/boost/libs/numeric/conversion/README.md new file mode 100644 index 000000000..987f0ecf6 --- /dev/null +++ b/src/boost/libs/numeric/conversion/README.md @@ -0,0 +1,8 @@ +# Boost.NumericConversion + +The Boost Numeric Conversion library is a collection of tools to describe and perform conversions between values of different [numeric types][1]. + +The documentation for the library can be found [here][2] + +[1]: http://www.boost.org/doc/libs/release/libs/numeric/conversion/doc/html/boost_numericconversion/definitions.html#boost_numericconversion.definitions.numeric_types +[2]: http://www.boost.org/doc/libs/release/libs/numeric/conversion/doc/html/index.html#numeric_conversion.overview diff --git a/src/boost/libs/numeric/conversion/index.html b/src/boost/libs/numeric/conversion/index.html new file mode 100644 index 000000000..305b7385a --- /dev/null +++ b/src/boost/libs/numeric/conversion/index.html @@ -0,0 +1,13 @@ +<html> +<head> +<meta http-equiv="refresh" content="0; URL=doc/html/index.html"> +</head> +<body> +Automatic redirection failed, please go to +<a href="doc/html/index.html">doc/index.html</a>. <hr> +<p>� Copyright Beman Dawes, 2001</p> +<p>Distributed under the Boost Software License, Version 1.0. (See accompanying +file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy +at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p> +</body> +</html> diff --git a/src/boost/libs/numeric/conversion/meta/libraries.json b/src/boost/libs/numeric/conversion/meta/libraries.json new file mode 100644 index 000000000..945591c80 --- /dev/null +++ b/src/boost/libs/numeric/conversion/meta/libraries.json @@ -0,0 +1,16 @@ +{ + "key": "numeric/conversion", + "name": "Numeric Conversion", + "authors": [ + "Fernando Cacciola" + ], + "description": "Optimized Policy-based Numeric Conversions.", + "category": [ + "Math", + "Miscellaneous" + ], + "maintainers": [ + "Fernando Cacciola <fernando_cacciola -at- ciudad.com.ar>", + "Brandon Kohn <blkohn -at- hotmail.com>" + ] +} diff --git a/src/boost/libs/numeric/conversion/test/Jamfile.v2 b/src/boost/libs/numeric/conversion/test/Jamfile.v2 new file mode 100644 index 000000000..16f3eba3d --- /dev/null +++ b/src/boost/libs/numeric/conversion/test/Jamfile.v2 @@ -0,0 +1,42 @@ +# Boost Numeric Conversion Library test Jamfile +# +# Copyright (C) 2003, Fernando Luis Cacciola Carballal. +# +# 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 testing ; + +project numeric_conversion_unit_tests + : + requirements + <include>. + <toolset>gcc:<cxxflags>"-ftemplate-depth-300 -g0" + <toolset>darwin:<cxxflags>"-ftemplate-depth-300 -g0" + ; + +test-suite minimal + : + [ run bounds_test.cpp ] + [ run traits_test.cpp : : : <toolset>msvc:<cxxflags>/bigobj ] + [ run converter_test.cpp ] + [ run udt_support_test.cpp ] + [ run numeric_cast_test.cpp ] + [ run udt_example_0.cpp ] + [ run numeric_cast_traits_test.cpp ] + ; + +test-suite full + : + minimal + [ compile-fail compile_fail/built_in_numeric_cast_traits.cpp ] + ; + +test-suite extra ; + +explicit minimal ; +explicit extra ; + +# support the old test target +test-suite numeric/conversion : full ; diff --git a/src/boost/libs/numeric/conversion/test/bounds_test.cpp b/src/boost/libs/numeric/conversion/test/bounds_test.cpp new file mode 100644 index 000000000..504c47c52 --- /dev/null +++ b/src/boost/libs/numeric/conversion/test/bounds_test.cpp @@ -0,0 +1,101 @@ +// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004 +// Use, modification, and distribution is 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) + +// See library home page at http://www.boost.org/libs/numeric/conversion +// +// Contact the author at: fernando_cacciola@hotmail.com +// +#include<typeinfo> +#include<iostream> +#include<iomanip> + +#include "boost/numeric/conversion/bounds.hpp" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "test_helpers.cpp" + +using namespace std ; +using namespace boost ; +using namespace numeric ; + +// Test the fields of boost::numeric::bounds<> against the expected values. +// +template<class T> +void test_bounds( T expected_lowest, T expected_highest, T expected_smallest ) +{ + T lowest = bounds<T>::lowest () ; + T highest = bounds<T>::highest () ; + T smallest = bounds<T>::smallest() ; + + BOOST_CHECK_MESSAGE ( lowest == expected_lowest, + "bounds<" << typeid(T).name() << ">::lowest() = " << printable(lowest) << ". Expected " << printable(expected_lowest) + ) ; + + BOOST_CHECK_MESSAGE ( highest == expected_highest, + "bounds<" << typeid(T).name() << ">::highest() = " << printable(highest) << ". Expected " << printable(expected_highest) + ) ; + + BOOST_CHECK_MESSAGE ( smallest == expected_smallest, + "bounds<" << typeid(T).name() << ">::smallest() = " << printable(smallest) << ". Expected " << printable(expected_smallest) + ) ; +} + + +template<class T> +void test_bounds_integer( MATCH_FNTPL_ARG(T) ) +{ + test_bounds( numeric_limits<T>::min BOOST_PREVENT_MACRO_SUBSTITUTION() + , numeric_limits<T>::max BOOST_PREVENT_MACRO_SUBSTITUTION() + , static_cast<T>(1) + ) ; +} +template<class T> +void test_bounds_float( MATCH_FNTPL_ARG(T)) +{ + test_bounds( -numeric_limits<T>::max BOOST_PREVENT_MACRO_SUBSTITUTION () + , numeric_limits<T>::max BOOST_PREVENT_MACRO_SUBSTITUTION () + , numeric_limits<T>::min BOOST_PREVENT_MACRO_SUBSTITUTION () + ) ; +} + +void test_bounds_integers() +{ + test_bounds_integer( SET_FNTPL_ARG(unsigned char) ) ; + test_bounds_integer( SET_FNTPL_ARG(signed char) ) ; + test_bounds_integer( SET_FNTPL_ARG(char) ) ; + test_bounds_integer( SET_FNTPL_ARG(unsigned short) ) ; + test_bounds_integer( SET_FNTPL_ARG(short) ) ; + test_bounds_integer( SET_FNTPL_ARG(unsigned int) ) ; + test_bounds_integer( SET_FNTPL_ARG(int) ) ; + test_bounds_integer( SET_FNTPL_ARG(unsigned long) ) ; + test_bounds_integer( SET_FNTPL_ARG(long) ) ; +} + +void test_bounds_floats() +{ + test_bounds_float( SET_FNTPL_ARG(float) ); + test_bounds_float( SET_FNTPL_ARG(double) ); + test_bounds_float( SET_FNTPL_ARG(long double) ); +} + +void test_bounds() +{ + test_bounds_integers() ; + test_bounds_floats () ; +} + + +int test_main( int, char * [] ) +{ + cout << setprecision( std::numeric_limits<long double>::digits10 ) ; + + test_bounds(); + + return 0; +} + diff --git a/src/boost/libs/numeric/conversion/test/compile_fail/built_in_numeric_cast_traits.cpp b/src/boost/libs/numeric/conversion/test/compile_fail/built_in_numeric_cast_traits.cpp new file mode 100644 index 000000000..c795d88b3 --- /dev/null +++ b/src/boost/libs/numeric/conversion/test/compile_fail/built_in_numeric_cast_traits.cpp @@ -0,0 +1,122 @@ +// +//! Copyright (c) 2011 +//! Brandon Kohn +// +// 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) +// + +#include <boost/operators.hpp> +#include <boost/numeric/conversion/cast.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/preprocessor/comparison/less.hpp> +#include <boost/preprocessor/comparison/not_equal.hpp> +#include <boost/preprocessor/repetition/for.hpp> +#include <boost/preprocessor/tuple/elem.hpp> +#include <boost/preprocessor/seq/elem.hpp> +#include <boost/preprocessor/seq/size.hpp> +#include <boost/test/minimal.hpp> + +//! Generate default traits for the specified source and target. +#define BOOST_NUMERIC_CONVERSION_GENERATE_CAST_TRAITS(r, state) \ +template <> \ +struct numeric_cast_traits< \ + BOOST_PP_SEQ_ELEM( BOOST_PP_TUPLE_ELEM(4,0,state) \ + , BOOST_PP_TUPLE_ELEM(4,3,state) ) \ + , BOOST_PP_TUPLE_ELEM(4,2,state)> \ +{ \ + typedef def_overflow_handler overflow_policy; \ + typedef UseInternalRangeChecker range_checking_policy; \ + typedef Trunc<BOOST_PP_TUPLE_ELEM(4,2,state)> rounding_policy; \ +}; \ +/***/ + +#define BOOST_NUMERIC_CONVERSION_TUPLE_SENTINAL(r, state) \ + BOOST_PP_LESS \ + ( \ + BOOST_PP_TUPLE_ELEM(4,0,state) \ + , BOOST_PP_TUPLE_ELEM(4,1,state) \ + ) \ +/***/ + +#define BOOST_NUMERIC_CONVERSION_INC_OP(r, state) \ + ( \ + BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(4,0,state)) \ + , BOOST_PP_TUPLE_ELEM(4,1,state) \ + , BOOST_PP_TUPLE_ELEM(4,2,state) \ + , BOOST_PP_TUPLE_ELEM(4,3,state) \ + ) \ +/***/ + +#define BOOST_NUMERIC_CONVERSION_GENERATE_CAST_TARGET_STEP(r, state) \ + BOOST_PP_FOR \ + ( \ + ( \ + 0 \ + , BOOST_PP_TUPLE_ELEM(4,1,state) \ + , BOOST_PP_SEQ_ELEM(BOOST_PP_TUPLE_ELEM(4,0,state),BOOST_PP_TUPLE_ELEM(4,2,state)) \ + , BOOST_PP_TUPLE_ELEM(4,2,state) \ + ) \ + , BOOST_NUMERIC_CONVERSION_TUPLE_SENTINAL \ + , BOOST_NUMERIC_CONVERSION_INC_OP \ + , BOOST_NUMERIC_CONVERSION_GENERATE_CAST_TRAITS \ + ) \ +/***/ + +#define BOOST_NUMERIC_CONVERSION_GENERATE_BUILTIN_CAST_TRAITS(types) \ + BOOST_PP_FOR \ + ( \ + (0,BOOST_PP_SEQ_SIZE(types),types,_) \ + , BOOST_NUMERIC_CONVERSION_TUPLE_SENTINAL \ + , BOOST_NUMERIC_CONVERSION_INC_OP \ + , BOOST_NUMERIC_CONVERSION_GENERATE_CAST_TARGET_STEP \ + ) \ +/***/ + +namespace boost { namespace numeric { +#if !defined( BOOST_NO_INT64_T ) + //! Generate the specializations for the built-in types. + BOOST_NUMERIC_CONVERSION_GENERATE_BUILTIN_CAST_TRAITS + ( + (char) + (boost::int8_t) + (boost::uint8_t) + (boost::int16_t) + (boost::uint16_t) + (boost::int32_t) + (boost::uint32_t) + (boost::int64_t) + (boost::uint64_t) + (float) + (double) + (long double) + ) +#else + BOOST_NUMERIC_CONVERSION_GENERATE_BUILTIN_CAST_TRAITS + ( + (char) + (boost::int8_t) + (boost::uint8_t) + (boost::int16_t) + (boost::uint16_t) + (boost::int32_t) + (boost::uint32_t) + (float) + (double) + (long double) + ) +#endif +}}//namespace boost::numeric; + +int test_main( int argc, char * argv[] ) +{ + //! This test should not compile. + return 1; +} + +#undef BOOST_NUMERIC_CONVERSION_GENERATE_BUILTIN_CAST_TRAITS +#undef BOOST_NUMERIC_CONVERSION_GENERATE_CAST_TARGET_STEP +#undef BOOST_NUMERIC_CONVERSION_INC_OP +#undef BOOST_NUMERIC_CONVERSION_TUPLE_SENTINAL +#undef BOOST_NUMERIC_CONVERSION_GENERATE_CAST_TRAITS diff --git a/src/boost/libs/numeric/conversion/test/converter_test.cpp b/src/boost/libs/numeric/conversion/test/converter_test.cpp new file mode 100644 index 000000000..a460df158 --- /dev/null +++ b/src/boost/libs/numeric/conversion/test/converter_test.cpp @@ -0,0 +1,562 @@ +// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004 +// Use, modification, and distribution is 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) + +// See library home page at http://www.boost.org/libs/numeric/conversion +// +// Contact the author at: fernando_cacciola@hotmail.com +// +#include<cstdlib> +#include<iostream> +#include<iomanip> +#include<string> +#include<typeinfo> +#include<vector> +#include<algorithm> + +#include "boost/config.hpp" +#include "boost/cstdint.hpp" +#include "boost/utility.hpp" + +// +// Borland 5.5 lacks the following math overloads +// +#if BOOST_WORKAROUND(__BORLANDC__, <= 0x551) +namespace std +{ + +inline float ceil (float x) { return std::ceil ( static_cast<double>(x)); } +inline float floor (float x) { return std::floor ( static_cast<double>(x)); } +inline long double ceil (long double x) { return std::ceill (x); } +inline long double floor (long double x) { return std::floorl(x); } + +} // namespace std +#endif + +#include "boost/numeric/conversion/converter.hpp" +#include "boost/numeric/conversion/cast.hpp" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "test_helpers.cpp" +#include "test_helpers2.cpp" +#include "test_helpers3.cpp" + +#include "boost/mpl/alias.hpp" + +using std::cout ; + +// A generic 'abs' function. +template<class N> inline N absG ( N v ) +{ + return v < static_cast<N>(0) ? static_cast<N>(-v) : v ; +} +template<> inline unsigned char absG<unsigned char> ( unsigned char v ) { return v ; } +template<> inline unsigned short absG<unsigned short> ( unsigned short v ) { return v ; } +template<> inline unsigned int absG<unsigned int> ( unsigned int v ) { return v ; } +template<> inline unsigned long absG<unsigned long> ( unsigned long v ) { return v ; } + +template<class T> inline void unused_variable ( T const& ) {} +// +// The following function excersizes specific conversions that cover +// usual and boundary cases for each relevant combination. +// +void test_conversions() +{ + using namespace boost ; + using namespace numeric ; + + // To help the test found possible bugs a random numbers are used. +#if !defined(BOOST_NO_STDC_NAMESPACE) + using std::rand ; +#endif + + boost::int16_t v16 ; + boost::uint16_t uv16 ; + boost::int32_t v32 ; + boost::uint32_t uv32 ; + + volatile float fv ; // avoid this to be cached internally in some fpu register + volatile double dv ; // avoid this to be cached internally in some fpu register + + // + // sample (representative) conversions: + // + cout << "Testing representative conversions\n"; + + // integral to integral + + // signed to signed + + // not subranged + v16 = static_cast<boost::int16_t>(rand()); + TEST_SUCCEEDING_CONVERSION_DEF(boost::int32_t,boost::int16_t,v16,v16); + + // subranged + v16 = static_cast<boost::int16_t>(rand()); + TEST_SUCCEEDING_CONVERSION_DEF(boost::int16_t,boost::int32_t,v16,v16); + TEST_POS_OVERFLOW_CONVERSION_DEF(boost::int16_t,boost::int32_t,bounds<boost::int16_t>::highest() + boost::int32_t(1) ) ; + TEST_NEG_OVERFLOW_CONVERSION_DEF(boost::int16_t,boost::int32_t,bounds<boost::int16_t>::lowest() - boost::int32_t(1) ) ; + + // signed to unsigned + + // subranged + v32 = absG(static_cast<boost::int32_t>(rand())); + v16 = absG(static_cast<boost::int16_t>(rand())); + TEST_SUCCEEDING_CONVERSION_DEF(boost::uint32_t,boost::int32_t,v32,v32); + TEST_SUCCEEDING_CONVERSION_DEF(boost::uint16_t,boost::int32_t,v16,v16); + TEST_POS_OVERFLOW_CONVERSION_DEF(boost::uint16_t,boost::int32_t,bounds<boost::uint16_t>::highest() + boost::int32_t(1) ) ; + TEST_NEG_OVERFLOW_CONVERSION_DEF(boost::uint32_t,boost::int32_t,boost::int32_t(-1) ) ; + + // unsigned to signed + + // not subranged + v32 = absG(static_cast<boost::int32_t>(rand())); + TEST_SUCCEEDING_CONVERSION_DEF(boost::int32_t,boost::uint32_t,v32,v32); + + // subranged + v16 = absG(static_cast<boost::int16_t>(rand())); + TEST_SUCCEEDING_CONVERSION_DEF(boost::int16_t,boost::uint32_t,v16,v16); + TEST_POS_OVERFLOW_CONVERSION_DEF(boost::int32_t,boost::uint32_t,bounds<boost::uint32_t>::highest() ) ; + TEST_POS_OVERFLOW_CONVERSION_DEF(boost::int16_t,boost::uint32_t,bounds<boost::uint32_t>::highest() ) ; + + // unsigned to unsigned + + // not subranged + uv16 = static_cast<boost::uint16_t>(rand()); + TEST_SUCCEEDING_CONVERSION_DEF(boost::uint32_t,boost::uint16_t,uv16,uv16); + + // subranged + uv16 = static_cast<boost::uint16_t>(rand()); + TEST_SUCCEEDING_CONVERSION_DEF(boost::uint16_t,boost::uint32_t,uv16,uv16); + TEST_POS_OVERFLOW_CONVERSION_DEF(boost::uint16_t,boost::uint32_t,bounds<boost::uint32_t>::highest() ) ; + + // integral to float + + // from signed integral + v32 = static_cast<boost::int32_t>(rand()); + TEST_SUCCEEDING_CONVERSION_DEF(double,boost::int32_t,v32,v32); + + // from uint32_tegral + uv32 = static_cast<boost::uint32_t>(rand()); + TEST_SUCCEEDING_CONVERSION_DEF(double,boost::uint32_t,uv32,uv32); + + // float to integral + + // to signed integral + v32 = static_cast<boost::int32_t>(rand()); + TEST_SUCCEEDING_CONVERSION_DEF(boost::int32_t,double,v32,v32); + + dv = static_cast<double>(bounds<boost::uint32_t>::highest()) + 1.0 ; + TEST_POS_OVERFLOW_CONVERSION_DEF(boost::int32_t,double,dv) ; + TEST_NEG_OVERFLOW_CONVERSION_DEF(boost::int32_t,double,-dv) ; + + // float to float + + // not subranged + fv = static_cast<float>(rand()) / static_cast<float>(3) ; + TEST_SUCCEEDING_CONVERSION_DEF(double,float,fv,fv); + + + // subranged + fv = static_cast<float>(rand()) / static_cast<float>(3) ; + TEST_SUCCEEDING_CONVERSION_DEF(float,double,fv,fv); + TEST_POS_OVERFLOW_CONVERSION_DEF(float,double,bounds<double>::highest()) ; + TEST_NEG_OVERFLOW_CONVERSION_DEF(float,double,bounds<double>::lowest ()) ; +} + +// Custom OverflowHandler +struct custom_overflow_handler +{ + void operator() ( boost::numeric::range_check_result r ) + { + if ( r == boost::numeric::cNegOverflow ) + cout << "negative_overflow detected!\n" ; + else if ( r == boost::numeric::cPosOverflow ) + cout << "positive_overflow detected!\n" ; + } +} ; + +template<class T, class S,class OverflowHandler> +void test_overflow_handler( MATCH_FNTPL_ARG(T), MATCH_FNTPL_ARG(S), MATCH_FNTPL_ARG(OverflowHandler), + PostCondition pos, + PostCondition neg + ) +{ + typedef boost::numeric::conversion_traits<T,S> traits ; + typedef boost::numeric::converter<T,S,traits,OverflowHandler> converter ; + + static const S psrc = boost::numeric::bounds<S>::highest(); + static const S nsrc = boost::numeric::bounds<S>::lowest (); + + static const T pres = static_cast<T>(psrc); + static const T nres = static_cast<T>(nsrc); + + test_conv_base ( ConversionInstance<converter>(pres,psrc,pos) ) ; + test_conv_base ( ConversionInstance<converter>(nres,nsrc,neg) ) ; +} + +template<class T, class S> +void test_overflow_handlers( MATCH_FNTPL_ARG(T), MATCH_FNTPL_ARG(S) ) +{ + cout << "Testing Silent Overflow Handler policy\n"; + + test_overflow_handler( SET_FNTPL_ARG(T), + SET_FNTPL_ARG(S), + SET_FNTPL_ARG(boost::numeric::silent_overflow_handler), + c_converted, + c_converted + ) ; + + cout << "Testing Default Overflow Handler policy\n"; + + test_overflow_handler( SET_FNTPL_ARG(T), + SET_FNTPL_ARG(S), + SET_FNTPL_ARG(boost::numeric::def_overflow_handler), + c_pos_overflow, + c_neg_overflow + ) ; + + cout << "Testing Custom (User-Defined) Overflow Handler policy\n"; + + test_overflow_handler( SET_FNTPL_ARG(T), + SET_FNTPL_ARG(S), + SET_FNTPL_ARG(custom_overflow_handler), + c_converted, + c_converted + ) ; +} + +// For a given float-type number 'n' of integer value (n.0), check the conversions +// within the range [n-1,n+1] taking values at: (n-1,n-0.5,n,n+0.5,n+1). +// For each sampled value there is an expected result and a PostCondition according to the +// specified round_style. +// +template<class T, class S, class Float2IntRounder> +void test_rounding_conversion ( MATCH_FNTPL_ARG(T), MATCH_FNTPL_ARG(Float2IntRounder), + S s, + PostCondition resl1, + PostCondition resl0, + PostCondition res, + PostCondition resr0, + PostCondition resr1 + ) +{ + typedef boost::numeric::conversion_traits<T,S> Traits ; + + typedef boost::numeric::converter<T,S, Traits, boost::numeric::def_overflow_handler,Float2IntRounder> + Converter ; + + S sl1 = s - static_cast<S>(1); + S sl0 = s - static_cast<S>(0.5); + S sr0 = s + static_cast<S>(0.5); + S sr1 = s + static_cast<S>(1); + + T tl1 = static_cast<T>( Converter::nearbyint(sl1) ); + T tl0 = static_cast<T>( Converter::nearbyint(sl0) ); + T t = static_cast<T>( Converter::nearbyint(s) ); + T tr0 = static_cast<T>( Converter::nearbyint(sr0) ); + T tr1 = static_cast<T>( Converter::nearbyint(sr1) ); + + test_conv_base ( ConversionInstance<Converter>(tl1,sl1,resl1) ) ; + test_conv_base ( ConversionInstance<Converter>(tl0,sl0,resl0) ) ; + test_conv_base ( ConversionInstance<Converter>(t,s,res) ) ; + test_conv_base ( ConversionInstance<Converter>(tr0,sr0,resr0) ) ; + test_conv_base ( ConversionInstance<Converter>(tr1,sr1,resr1) ) ; +} + + +template<class T,class S> +void test_round_style( MATCH_FNTPL_ARG(T), MATCH_FNTPL_ARG(S) ) +{ + S min = boost::numeric::bounds<T>::lowest(); + S max = boost::numeric::bounds<T>::highest(); + + cout << "Testing 'Trunc' Float2IntRounder policy\n"; + + test_rounding_conversion(SET_FNTPL_ARG(T), + SET_FNTPL_ARG(boost::numeric::Trunc<S>), + min, + c_neg_overflow, + c_converted, + c_converted, + c_converted, + c_converted + ) ; + + test_rounding_conversion(SET_FNTPL_ARG(T), + SET_FNTPL_ARG(boost::numeric::Trunc<S>), + max, + c_converted, + c_converted, + c_converted, + c_converted, + c_pos_overflow + ) ; + + cout << "Testing 'RoundEven' Float2IntRounder policy\n"; + + test_rounding_conversion(SET_FNTPL_ARG(T), + SET_FNTPL_ARG(boost::numeric::RoundEven<S>), + min, + c_neg_overflow, + c_converted, + c_converted, + c_converted, + c_converted + ) ; + + test_rounding_conversion(SET_FNTPL_ARG(T), + SET_FNTPL_ARG(boost::numeric::RoundEven<S>), + max, + c_converted, + c_converted, + c_converted, + c_pos_overflow, + c_pos_overflow + ) ; + + cout << "Testing 'Ceil' Float2IntRounder policy\n"; + + test_rounding_conversion(SET_FNTPL_ARG(T), + SET_FNTPL_ARG(boost::numeric::Ceil<S>), + min, + c_neg_overflow, + c_converted, + c_converted, + c_converted, + c_converted + ) ; + + test_rounding_conversion(SET_FNTPL_ARG(T), + SET_FNTPL_ARG(boost::numeric::Ceil<S>), + max, + c_converted, + c_converted, + c_converted, + c_pos_overflow, + c_pos_overflow + ) ; + + cout << "Testing 'Floor' Float2IntRounder policy\n" ; + + test_rounding_conversion(SET_FNTPL_ARG(T), + SET_FNTPL_ARG(boost::numeric::Floor<S>), + min, + c_neg_overflow, + c_neg_overflow, + c_converted, + c_converted, + c_converted + ) ; + + test_rounding_conversion(SET_FNTPL_ARG(T), + SET_FNTPL_ARG(boost::numeric::Floor<S>), + max, + c_converted, + c_converted, + c_converted, + c_converted, + c_pos_overflow + ) ; + +} + +void test_round_even( double n, double x ) +{ + double r = boost::numeric::RoundEven<double>::nearbyint(n); + BOOST_CHECK( r == x ) ; +} + +void test_round_even() +{ + cout << "Testing 'RoundEven' tie-breaking\n"; + + double min = boost::numeric::bounds<double>::lowest(); + double max = boost::numeric::bounds<double>::highest(); + +#if !defined(BOOST_NO_STDC_NAMESPACE) + using std::floor ; + using std::ceil ; +#endif + test_round_even(min, floor(min)); + test_round_even(max, ceil (max)); + test_round_even(2.0, 2.0); + test_round_even(2.3, 2.0); + test_round_even(2.5, 2.0); + test_round_even(2.7, 3.0); + test_round_even(3.0, 3.0); + test_round_even(3.3, 3.0); + test_round_even(3.5, 4.0); + test_round_even(3.7, 4.0); +} + +int double_to_int ( double n ) { return static_cast<int>(n) ; } + +void test_converter_as_function_object() +{ + cout << "Testing converter as function object.\n"; + + // Create a sample sequence of double values. + std::vector<double> S ; + for ( int i = 0 ; i < 10 ; ++ i ) + S.push_back( i * ( 18.0 / 19.0 ) ); + + // Create a sequence of int values from 's' using the standard conversion. + std::vector<int> W ; + std::transform(S.begin(),S.end(),std::back_inserter(W),double_to_int); + + // Create a sequence of int values from s using a default numeric::converter + std::vector<int> I ; + std::transform(S.begin(), + S.end(), + std::back_inserter(I), + boost::numeric::converter<int,double>() + ) ; + + // Match 'w' and 'i' which should be equal. + bool double_to_int_OK = std::equal(W.begin(),W.end(),I.begin()) ; + BOOST_CHECK_MESSAGE(double_to_int_OK, "converter (int,double) as function object"); + + // Create a sequence of double values from s using a default numeric::converter (which should be the trivial conv). + std::vector<double> D ; + std::transform(S.begin(), + S.end(), + std::back_inserter(D), + boost::numeric::converter<double,double>() + ) ; + + // Match 's' and 'd' which should be equal. + bool double_to_double_OK = std::equal(S.begin(),S.end(),D.begin()) ; + BOOST_CHECK_MESSAGE(double_to_double_OK, "converter (double,double) as function object"); +} + +#if BOOST_WORKAROUND(__IBMCPP__, <= 600 ) // VCAPP6 +# define UNOPTIMIZED +#else +# define UNOPTIMIZED volatile +#endif + +void test_optimizations() +{ + using namespace boost; + using namespace numeric; + + float fv0 = 18.0f / 19.0f ; + + // This code deosn't produce any output. + // It is intended to show the optimization of numeric::converter<> by manual inspection + // of the generated code. + // Each test shows first the equivalent hand-coded version. + // The numeric_cast<> code should be the same if full compiler optimization/inlining is used. + + //--------------------------------- + // trivial conversion. + // + // equivalent code: + UNOPTIMIZED float fv1a = fv0 ; + + float fv1b = numeric_cast<float>(fv0); + unused_variable(fv1a); + unused_variable(fv1b); + // + //--------------------------------- + + //--------------------------------- + // nonsubranged conversion. + // + // equivalent code: + UNOPTIMIZED double dv1a = static_cast<double>(fv0); + + double dv1b = numeric_cast<double>(fv0); + unused_variable(dv1a); + unused_variable(dv1b); + // + //--------------------------------- + + //------------------------------------------------------ + // subranged conversion with both-sided range checking. + // + + // equivalent code: + + { + double const& s = dv1b ; + // range checking + range_check_result r = s < static_cast<double>(bounds<float>::lowest()) + ? cNegOverflow : cInRange ; + if ( r == cInRange ) + { + r = s > static_cast<double>(bounds<float>::highest()) ? cPosOverflow : cInRange ; + } + if ( r == cNegOverflow ) + throw negative_overflow() ; + else if ( r == cPosOverflow ) + throw positive_overflow() ; + // conversion + UNOPTIMIZED float fv2a = static_cast<float>(s); + unused_variable(fv2a); + } + + float fv2b = numeric_cast<float>(dv1b); + unused_variable(fv2b); + // + //--------------------------------- + + + //--------------------------------- + // subranged rounding conversion + // + // equivalent code: + + { + double const& s = dv1b ; + // range checking + range_check_result r = s <= static_cast<double>(bounds<int>::lowest()) - static_cast<double>(1.0) + ? cNegOverflow : cInRange ; + if ( r == cInRange ) + { + r = s >= static_cast<double>(bounds<int>::highest()) + static_cast<double>(1.0) + ? cPosOverflow : cInRange ; + } + if ( r == cNegOverflow ) + throw negative_overflow() ; + else if ( r == cPosOverflow ) + throw positive_overflow() ; + // rounding + +#if !defined(BOOST_NO_STDC_NAMESPACE) + using std::floor ; +#endif + + double s1 = floor(dv1b + 0.5); + + // conversion + UNOPTIMIZED int iv1a = static_cast<int>(s1); + unused_variable(iv1a); + } + + int iv1b = numeric_cast<int>(dv1b); + unused_variable(iv1b); + // + //--------------------------------- +} + +int test_main( int, char* argv[] ) +{ + std::cout << std::setprecision( std::numeric_limits<long double>::digits10 ) ; + + test_conversions(); + test_overflow_handlers( SET_FNTPL_ARG(boost::int16_t), SET_FNTPL_ARG(boost::int32_t)); + test_round_style(SET_FNTPL_ARG(boost::int32_t), SET_FNTPL_ARG(double) ) ; + test_round_even() ; + test_converter_as_function_object(); + test_optimizations() ; + + return 0; +} +//--------------------------------------------------------------------------- + diff --git a/src/boost/libs/numeric/conversion/test/numeric_cast_test.cpp b/src/boost/libs/numeric/conversion/test/numeric_cast_test.cpp new file mode 100644 index 000000000..f94393cb1 --- /dev/null +++ b/src/boost/libs/numeric/conversion/test/numeric_cast_test.cpp @@ -0,0 +1,97 @@ +// boost utility cast test program -----------------------------------------// + +// (C) Copyright Beman Dawes, Dave Abrahams 1999. 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) + +// See http://www.boost.org for most recent version including documentation. + +// Revision History +// 28 Set 04 taken from the old cast library (Fernando Cacciola) + +#include <iostream> +#include <climits> +#include <cfloat> // for DBL_MAX (Peter Schmid) + +#include <boost/numeric/conversion/cast.hpp> + +#include "boost/test/minimal.hpp" + +# if SCHAR_MAX == LONG_MAX +# error "This test program doesn't work if SCHAR_MAX == LONG_MAX" +# endif + +using namespace boost; +using std::cout; + +int test_main( int argc, char * argv[] ) +{ + +# ifdef NDEBUG + cout << "NDEBUG is defined\n"; +# else + cout << "NDEBUG is not defined\n"; +# endif + + cout << "\nBeginning tests...\n"; + +// test implicit_cast and numeric_cast -------------------------------------// + + // tests which should succeed + long small_value = 1; + long small_negative_value = -1; + long large_value = LONG_MAX; + long large_negative_value = LONG_MIN; + signed char c = 0; + + c = large_value; // see if compiler generates warning + + c = numeric_cast<signed char>( small_value ); + BOOST_CHECK( c == 1 ); + c = 0; + c = numeric_cast<signed char>( small_value ); + BOOST_CHECK( c == 1 ); + c = 0; + c = numeric_cast<signed char>( small_negative_value ); + BOOST_CHECK( c == -1 ); + + // These tests courtesy of Joe R NWP Swatosh<joe.r.swatosh@usace.army.mil> + BOOST_CHECK( 0.0f == numeric_cast<float>( 0.0 ) ); + BOOST_CHECK( 0.0 == numeric_cast<double>( 0.0 ) ); + + // tests which should result in errors being detected + + bool caught_exception = false; + try { c = numeric_cast<signed char>( large_value ); } + catch ( numeric::bad_numeric_cast ) + { cout<<"caught bad_numeric_cast #1\n"; caught_exception = true; } + BOOST_CHECK ( caught_exception ); + + caught_exception = false; + try { c = numeric_cast<signed char>( large_negative_value ); } + catch ( numeric::bad_numeric_cast ) + { cout<<"caught bad_numeric_cast #2\n"; caught_exception = true; } + BOOST_CHECK ( caught_exception ); + + unsigned long ul; + caught_exception = false; + try { ul = numeric_cast<unsigned long>( large_negative_value ); } + catch ( numeric::bad_numeric_cast ) + { cout<<"caught bad_numeric_cast #3\n"; caught_exception = true; } + BOOST_CHECK ( caught_exception ); + + caught_exception = false; + try { ul = numeric_cast<unsigned long>( small_negative_value ); } + catch ( numeric::bad_numeric_cast ) + { cout<<"caught bad_numeric_cast #4\n"; caught_exception = true; } + BOOST_CHECK ( caught_exception ); + + caught_exception = false; + try { numeric_cast<int>( DBL_MAX ); } + catch ( numeric::bad_numeric_cast ) + { cout<<"caught bad_numeric_cast #5\n"; caught_exception = true; } + BOOST_CHECK ( caught_exception ); + + return 0 ; + +} // main diff --git a/src/boost/libs/numeric/conversion/test/numeric_cast_traits_test.cpp b/src/boost/libs/numeric/conversion/test/numeric_cast_traits_test.cpp new file mode 100644 index 000000000..f59cb6bc7 --- /dev/null +++ b/src/boost/libs/numeric/conversion/test/numeric_cast_traits_test.cpp @@ -0,0 +1,380 @@ +// +//! Copyright (c) 2011 +//! Brandon Kohn +// +// 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) +// + +#include <boost/operators.hpp> +#include <boost/numeric/conversion/cast.hpp> +#include <boost/mpl/for_each.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/cstdint.hpp> +#include <boost/test/minimal.hpp> + +//! Define a simple custom number +struct Double +{ + Double() + : v(0) + {} + + template <typename T> + explicit Double( T v ) + : v(static_cast<double>(v)) + {} + + template <typename T> + Double& operator= ( T t ) + { + v = static_cast<double>(t); + return *this; + } + + bool operator < ( const Double& rhs ) const + { + return v < rhs.v; + } + + template <typename T> + bool operator < ( T rhs ) const + { + return v < static_cast<double>(rhs); + } + + template <typename LHS> + friend bool operator < ( const LHS& lhs, const Double& rhs ) + { + return lhs < rhs.v; + } + + bool operator > ( const Double& rhs ) const + { + return v > rhs.v; + } + + template <typename LHS> + friend bool operator > ( const LHS& lhs, const Double& rhs ) + { + return lhs > rhs.v; + } + + template <typename T> + bool operator > ( T rhs ) const + { + return v > static_cast<double>(rhs); + } + + bool operator == ( const Double& rhs ) const + { + return v == rhs.v; + } + + template <typename T> + bool operator == ( T rhs ) const + { + return v == static_cast<double>(rhs); + } + + template <typename LHS> + friend bool operator == ( const LHS& lhs, const Double& rhs ) + { + return lhs == rhs.v; + } + + bool operator !() const + { + return v == 0; + } + + Double operator -() const + { + return Double(-v); + } + + Double& operator +=( const Double& t ) + { + v += t.v; + return *this; + } + + template <typename T> + Double& operator +=( T t ) + { + v += static_cast<double>(t); + return *this; + } + + Double& operator -=( const Double& t ) + { + v -= t.v; + return *this; + } + + template <typename T> + Double& operator -=( T t ) + { + v -= static_cast<double>(t); + return *this; + } + + Double& operator *= ( const Double& factor ) + { + v *= factor.v; + return *this; + } + + template <typename T> + Double& operator *=( T t ) + { + v *= static_cast<double>(t); + return *this; + } + + Double& operator /= (const Double& divisor) + { + v /= divisor.v; + return *this; + } + + template <typename T> + Double& operator /=( T t ) + { + v /= static_cast<double>(t); + return (*this); + } + + double v; +}; + +//! Define numeric_limits for the custom type. +namespace std +{ + template<> + class numeric_limits< Double > : public numeric_limits<double> + { + public: + + //! Limit our Double to a range of +/- 100.0 + static Double (min)() + { + return Double(1.e-2); + } + + static Double (max)() + { + return Double(1.e2); + } + + static Double epsilon() + { + return Double( std::numeric_limits<double>::epsilon() ); + } + }; +} + +//! Define range checking and overflow policies. +namespace custom +{ + //! Define a custom range checker + template<typename Traits, typename OverFlowHandler> + struct range_checker + { + typedef typename Traits::argument_type argument_type ; + typedef typename Traits::source_type S; + typedef typename Traits::target_type T; + + //! Check range of integral types. + static boost::numeric::range_check_result out_of_range( argument_type s ) + { + using namespace boost::numeric; + if( s > bounds<T>::highest() ) + return cPosOverflow; + else if( s < bounds<T>::lowest() ) + return cNegOverflow; + else + return cInRange; + } + + static void validate_range ( argument_type s ) + { + BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_bounded ); + OverFlowHandler()( out_of_range(s) ); + } + }; + + //! Overflow handler + struct positive_overflow{}; + struct negative_overflow{}; + + struct overflow_handler + { + void operator() ( boost::numeric::range_check_result r ) + { + using namespace boost::numeric; + if( r == cNegOverflow ) + throw negative_overflow() ; + else if( r == cPosOverflow ) + throw positive_overflow() ; + } + }; + + //! Define a rounding policy and specialize on the custom type. + template<class S> + struct Ceil : boost::numeric::Ceil<S>{}; + + template<> + struct Ceil<Double> + { + typedef Double source_type; + + typedef Double const& argument_type; + + static source_type nearbyint ( argument_type s ) + { +#if !defined(BOOST_NO_STDC_NAMESPACE) + using std::ceil ; +#endif + return Double( ceil(s.v) ); + } + + typedef boost::mpl::integral_c< std::float_round_style, std::round_toward_infinity> round_style; + }; + + //! Define a rounding policy and specialize on the custom type. + template<class S> + struct Trunc: boost::numeric::Trunc<S>{}; + + template<> + struct Trunc<Double> + { + typedef Double source_type; + + typedef Double const& argument_type; + + static source_type nearbyint ( argument_type s ) + { +#if !defined(BOOST_NO_STDC_NAMESPACE) + using std::floor; +#endif + return Double( floor(s.v) ); + } + + typedef boost::mpl::integral_c< std::float_round_style, std::round_toward_zero> round_style; + }; +}//namespace custom; + +namespace boost { namespace numeric { + + //! Define the numeric_cast_traits specializations on the custom type. + template <typename S> + struct numeric_cast_traits<Double, S> + { + typedef custom::overflow_handler overflow_policy; + typedef custom::range_checker + < + boost::numeric::conversion_traits<Double, S> + , overflow_policy + > range_checking_policy; + typedef boost::numeric::Trunc<S> rounding_policy; + }; + + template <typename T> + struct numeric_cast_traits<T, Double> + { + typedef custom::overflow_handler overflow_policy; + typedef custom::range_checker + < + boost::numeric::conversion_traits<T, Double> + , overflow_policy + > range_checking_policy; + typedef custom::Trunc<Double> rounding_policy; + }; + + //! Define the conversion from the custom type to built-in types and vice-versa. + template<typename T> + struct raw_converter< conversion_traits< T, Double > > + { + static T low_level_convert ( const Double& n ) + { + return static_cast<T>( n.v ); + } + }; + + template<typename S> + struct raw_converter< conversion_traits< Double, S > > + { + static Double low_level_convert ( const S& n ) + { + return Double(n); + } + }; +}}//namespace boost::numeric; + +#define BOOST_TEST_CATCH_CUSTOM_POSITIVE_OVERFLOW( CastCode ) \ + try { CastCode; BOOST_CHECK( false ); } \ + catch( custom::positive_overflow& ){} \ + catch(...){ BOOST_CHECK( false ); } \ +/***/ + +#define BOOST_TEST_CATCH_CUSTOM_NEGATIVE_OVERFLOW( CastCode ) \ + try { CastCode; BOOST_CHECK( false ); } \ + catch( custom::negative_overflow& ){} \ + catch(...){ BOOST_CHECK( false ); } \ +/***/ + +struct test_cast_traits +{ + template <typename T> + void operator()(T) const + { + Double d = boost::numeric_cast<Double>( static_cast<T>(50) ); + BOOST_CHECK( d.v == 50. ); + T v = boost::numeric_cast<T>( d ); + BOOST_CHECK( v == 50 ); + } +}; + +void test_numeric_cast_traits() +{ + typedef boost::mpl::vector + < + boost::int8_t + , boost::uint8_t + , boost::int16_t + , boost::uint16_t + , boost::int32_t + , boost::uint32_t +#if !defined( BOOST_NO_INT64_T ) + , boost::int64_t + , boost::uint64_t +#endif + , float + , double + , long double + > types; + boost::mpl::for_each<types>( test_cast_traits() ); + + //! Check overflow handler. + Double d( 56.0 ); + BOOST_TEST_CATCH_CUSTOM_POSITIVE_OVERFLOW( d = boost::numeric_cast<Double>( 101 ) ); + BOOST_CHECK( d.v == 56. ); + BOOST_TEST_CATCH_CUSTOM_NEGATIVE_OVERFLOW( d = boost::numeric_cast<Double>( -101 ) ); + BOOST_CHECK( d.v == 56.); + + //! Check custom round policy. + d = 5.9; + int five = boost::numeric_cast<int>( d ); + BOOST_CHECK( five == 5 ); +} + +int test_main( int argc, char * argv[] ) +{ + test_numeric_cast_traits(); + return 0; +} + +#undef BOOST_TEST_CATCH_CUSTOM_POSITIVE_OVERFLOW +#undef BOOST_TEST_CATCH_CUSTOM_NEGATIVE_OVERFLOW diff --git a/src/boost/libs/numeric/conversion/test/test_helpers.cpp b/src/boost/libs/numeric/conversion/test/test_helpers.cpp new file mode 100644 index 000000000..5f2d88d32 --- /dev/null +++ b/src/boost/libs/numeric/conversion/test/test_helpers.cpp @@ -0,0 +1,152 @@ +// Copyright (C) 2003, Fernando Luis Cacciola Carballal. +// +// 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) +// + + +// +// NOTE: This file is intended to be used ONLY by the test files +// from the Numeric Conversions Library +// +// +#include <cmath> + +#include "boost/limits.hpp" +#include "boost/utility.hpp" + +#include "boost/test/included/test_exec_monitor.hpp" + +// Convenience macros to help with compilers which don't parse +// explicit template function instantiations (MSVC6) +#define MATCH_FNTPL_ARG(t) t const* +#define SET_FNTPL_ARG(t) (static_cast< t const* >(0)) + +// +// *Minimal* example of a User Defined Numeric Type +// +// +namespace MyUDT +{ + +template<class T> +struct UDT +{ + typedef T builtin_type ; + + UDT ( T v_ ) : v (v_) {} + + T to_builtin() const { return v ; } + + friend bool operator == ( UDT const& lhs, UDT const& rhs ) + { return lhs.to_builtin() == rhs.to_builtin() ; } + + // NOTE: This operator is *required* by the Numeric Conversion Library + // if Turnc<> is used as the Float2IntRounder policy. + friend bool operator < ( UDT const& lhs, UDT const& rhs ) + { return lhs.to_builtin() < rhs.to_builtin() ; } + + friend std::ostream& operator << ( std::ostream& os, UDT const& n ) + { return os << n.to_builtin() ; } + + T v ; +} ; + +typedef UDT<int> MyInt ; +typedef UDT<double> MyFloat ; + +// +// The Float2IntRounder policies *require* a visible 'ceil' or 'floor' math function +// with standard semantics. +// In a conformant compiler, ADL can pick these functions even if they are defined +// within a user namespace, as below. +// +inline MyInt ceil ( MyInt const& x ) { return x ; } +inline MyInt floor ( MyInt const& x ) { return x ; } + +inline MyFloat floor ( MyFloat const& x ) +{ +#if !defined(BOOST_NO_STDC_NAMESPACE) + return MyFloat ( std::floor(x.to_builtin()) ) ; +#else + return MyFloat ( ::floor(x.to_builtin()) ) ; +#endif +} + +inline MyFloat ceil ( MyFloat const& x ) +{ +#if !defined(BOOST_NO_STDC_NAMESPACE) + return MyFloat ( std::ceil(x.to_builtin()) ) ; +#else + return MyFloat ( ::ceil(x.to_builtin()) ) ; +#endif +} + +} // namespace MyUDT + + +// +// The Numeric Conversion Library *requires* User Defined Numeric Types +// to properly specialize std::numeric_limits<> +// +namespace std +{ + +template<> +class numeric_limits<MyUDT::MyInt> : public numeric_limits<int> +{ + public : + + BOOST_STATIC_CONSTANT(bool, is_specialized = false); +} ; + +template<> +class numeric_limits<MyUDT::MyFloat> : public numeric_limits<double> +{ + public : + + BOOST_STATIC_CONSTANT(bool, is_specialized = false); +} ; + +} // namespace std + + + +// +// The functions floor and ceil defined within namespace MyUDT +// should be found by koenig loopkup, but some compilers don't do it right +// so we inyect them into namespace std so ordinary overload resolution +// can found them. +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) || defined(__BORLANDC__) || defined(__GNUC__) +namespace std { +using MyUDT::floor ; +using MyUDT::ceil ; +} // namespace std +#endif + + +std::string to_string( bool arg ) +{ + return arg ? "true" : "false" ; +} + +std::string to_string( ... ) { throw std::runtime_error("to_string() called with wrong type!") ; } + +// +// This is used to print 'char' values as numbers instead of characters. +// +template<class T> struct printable_number_type { typedef T type ; } ; +template<> struct printable_number_type<signed char> { typedef int type ; } ; +template<> struct printable_number_type<unsigned char> { typedef unsigned type ; } ; +template<> struct printable_number_type<char> { typedef int type ; } ; + +template<class T> +inline +typename printable_number_type<T>::type +printable( T n ) { return n ; } + + +// +/////////////////////////////////////////////////////////////////////////////////////////////// + diff --git a/src/boost/libs/numeric/conversion/test/test_helpers2.cpp b/src/boost/libs/numeric/conversion/test/test_helpers2.cpp new file mode 100644 index 000000000..8fca50b63 --- /dev/null +++ b/src/boost/libs/numeric/conversion/test/test_helpers2.cpp @@ -0,0 +1,60 @@ +// Copyright (C) 2003, Fernando Luis Cacciola Carballal. +// +// 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) +// + + +// +// NOTE: This file is intended to be used ONLY by the test files +// from the Numeric Conversions Library +// + +// +// The following 'to_string' helpers are provided to give readable names +// to the various enums used by the library. +// NOTE: specializations of boost::lexical_cast<> were not used since some compilers had +// trouble dealing with such specializations for different enumerations. +// + +std::string to_string ( boost::numeric::int_float_mixture_enum arg ) +{ + switch ( arg ) + { + case boost::numeric::integral_to_integral : return "integral_to_integral" ; + case boost::numeric::integral_to_float : return "integral_to_float" ; + case boost::numeric::float_to_integral : return "float_to_integral" ; + case boost::numeric::float_to_float : return "float_to_float" ; + } + return "(Unknown result!)" ; +} + + +std::string to_string ( boost::numeric::sign_mixture_enum arg ) +{ + switch ( arg ) + { + case boost::numeric::unsigned_to_unsigned : return "unsigned_to_unsigned" ; + case boost::numeric::signed_to_signed : return "signed_to_signed" ; + case boost::numeric::signed_to_unsigned : return "signed_to_unsigned" ; + case boost::numeric::unsigned_to_signed : return "unsigned_to_signed" ; + } + return "(Unknown result!)" ; +} + +std::string to_string ( boost::numeric::udt_builtin_mixture_enum arg ) +{ + switch ( arg ) + { + case boost::numeric::builtin_to_builtin : return "builtin_to_builtin" ; + case boost::numeric::builtin_to_udt : return "builtin_to_udt" ; + case boost::numeric::udt_to_builtin : return "udt_to_builtin" ; + case boost::numeric::udt_to_udt : return "udt_to_udt" ; + } + return "(Unknown result!)" ; +} + +// +/////////////////////////////////////////////////////////////////////////////////////////////// + diff --git a/src/boost/libs/numeric/conversion/test/test_helpers3.cpp b/src/boost/libs/numeric/conversion/test/test_helpers3.cpp new file mode 100644 index 000000000..de345ba86 --- /dev/null +++ b/src/boost/libs/numeric/conversion/test/test_helpers3.cpp @@ -0,0 +1,144 @@ +// Copyright (C) 2003, Fernando Luis Cacciola Carballal. +// +// 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) +// + + +// +// NOTE: This file is intended to be used ONLY by the test files +// from the Numeric Conversions Library +// + +// The conversion test is performed using a class whose instances encapsulate +// a particular specific conversion defnied explicitely. +// A ConversionInstance object includes the source type, the target type, +// the source value and the expected result, including possible exceptions. +// + +enum PostCondition { c_converted, c_overflow, c_neg_overflow, c_pos_overflow } ; + +template<class Converter> +struct ConversionInstance +{ + typedef Converter converter ; + + typedef typename Converter::argument_type argument_type ; + typedef typename Converter::result_type result_type ; + + typedef typename Converter::traits traits ; + typedef typename traits::target_type target_type ; + typedef typename traits::source_type source_type ; + + ConversionInstance ( result_type a_result, argument_type a_source, PostCondition a_post) + : + source(a_source), + result(a_result), + post(a_post) + {} + + std::string to_string() const + { + return std::string("converter<") + + typeid(target_type).name() + + std::string(",") + + typeid(source_type).name() + + std::string(">::convert(") ; + } + + argument_type source ; + result_type result ; + PostCondition post ; +} ; + +// +// Main conversion test point. +// Exercises a specific conversion described by 'conv'. +// +template<class Instance> +void test_conv_base( Instance const& conv ) +{ + typedef typename Instance::argument_type argument_type ; + typedef typename Instance::result_type result_type ; + typedef typename Instance::converter converter ; + + argument_type source = conv.source ; + + try + { + result_type result = converter::convert(source); + + if ( conv.post == c_converted ) + { + BOOST_CHECK_MESSAGE( result == conv.result, + conv.to_string() << printable(source) << ")= " << printable(result) << ". Expected:" << printable(conv.result) + ) ; + } + else + { + BOOST_ERROR( conv.to_string() << printable(source) << ") = " << printable(result) + << ". Expected:" << ( conv.post == c_neg_overflow ? " negative_overflow" : "positive_overflow" ) + ) ; + } + } + catch ( boost::numeric::negative_overflow const& ) + { + if ( conv.post == c_neg_overflow ) + { + BOOST_CHECK_MESSAGE( true, conv.to_string() << printable(source) << ") = negative_overflow, as expected" ) ; + } + else + { + BOOST_ERROR( conv.to_string() << printable(source) << ") = negative_overflow. Expected:" << printable(conv.result) ) ; + } + } + catch ( boost::numeric::positive_overflow const& ) + { + if ( conv.post == c_pos_overflow ) + { + BOOST_CHECK_MESSAGE( true, conv.to_string() << printable(source) << ") = positive_overflow, as expected" ) ; + } + else + { + BOOST_ERROR( conv.to_string() << printable(source) << ") = positive_overflow. Expected:" << printable(conv.result) ) ; + } + } + catch ( boost::numeric::bad_numeric_cast const& ) + { + if ( conv.post == c_overflow ) + { + BOOST_CHECK_MESSAGE( true, conv.to_string() << printable(source) << ") = bad_numeric_cast, as expected" ) ; + } + else + { + BOOST_ERROR( conv.to_string() << printable(source) << ") = bad_numeric_cast. Expected:" << printable(conv.result) ) ; + } + } +} + + +#define TEST_SUCCEEDING_CONVERSION(Conv,typeT,typeS,valueT,valueS) \ + test_conv_base( ConversionInstance< Conv >(valueT, valueS, c_converted ) ) + +#define TEST_POS_OVERFLOW_CONVERSION(Conv,typeT,typeS,valueS) \ + test_conv_base( ConversionInstance< Conv >( static_cast< typeT >(0), valueS, c_pos_overflow ) ) + +#define TEST_NEG_OVERFLOW_CONVERSION(Conv,typeT,typeS,valueS) \ + test_conv_base( ConversionInstance< Conv >( static_cast< typeT >(0), valueS, c_neg_overflow ) ) + +#define DEF_CONVERTER(T,S) boost::numeric::converter< T , S > + +#define TEST_SUCCEEDING_CONVERSION_DEF(typeT,typeS,valueT,valueS) \ + TEST_SUCCEEDING_CONVERSION( DEF_CONVERTER(typeT,typeS), typeT, typeS, valueT, valueS ) + +#define TEST_POS_OVERFLOW_CONVERSION_DEF(typeT,typeS,valueS) \ + TEST_POS_OVERFLOW_CONVERSION( DEF_CONVERTER(typeT,typeS), typeT, typeS, valueS ) + +#define TEST_NEG_OVERFLOW_CONVERSION_DEF(typeT,typeS,valueS) \ + TEST_NEG_OVERFLOW_CONVERSION( DEF_CONVERTER(typeT,typeS), typeT, typeS, valueS ) + + +// +/////////////////////////////////////////////////////////////////////////////////////////////// + diff --git a/src/boost/libs/numeric/conversion/test/traits_test.cpp b/src/boost/libs/numeric/conversion/test/traits_test.cpp new file mode 100644 index 000000000..d8d620b70 --- /dev/null +++ b/src/boost/libs/numeric/conversion/test/traits_test.cpp @@ -0,0 +1,341 @@ +// Copyright (C) 2003, Fernando Luis Cacciola Carballal. +// +// 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) +// +// +#include<iostream> +#include<iomanip> +#include<string> +#include<typeinfo> +#include<vector> +#include<algorithm> + +#include <boost/cstdint.hpp> +#include <boost/utility.hpp> +#include <boost/preprocessor/cat.hpp> + +#include <boost/numeric/conversion/conversion_traits.hpp> +#include <boost/numeric/conversion/int_float_mixture.hpp> +#include <boost/numeric/conversion/sign_mixture.hpp> +#include <boost/numeric/conversion/udt_builtin_mixture.hpp> +#include <boost/numeric/conversion/is_subranged.hpp> + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "test_helpers.cpp" +#include "test_helpers2.cpp" + +using namespace std ; +using namespace boost ; +using namespace numeric; +using namespace MyUDT ; + +// These helpers are used by generate_expected_traits<T,S>. +// Unlike the similar helpers in the implementation, they are specialized by extension. +// +template<class T, class S> struct my_is_subranged ; +template<class T, class S> struct my_is_trivial ; +template<class T, class S> struct my_int_float_mixture ; +template<class T, class S> struct my_sign_mixture ; +template<class T, class S> struct my_udt_builtin_mixture ; + +// This macro is used to define the properties of each conversion between +// the builtin arithmetric types +// +// It defines the specialization of the helper traits used by 'generate_expected_traits' +// +#define DEFINE_CONVERSION(Target,Source,Trivial,Mixture,SignMixture,UdtMixture,SubRanged) \ + \ + template<> struct my_is_subranged<Target,Source> \ + { typedef mpl::bool_< (SubRanged) > type ; } ; \ + \ + template<> struct my_is_trivial<Target,Source> \ + { typedef mpl::bool_< (Trivial) > type ; } ; \ + \ + template<> struct my_int_float_mixture<Target,Source> \ + { typedef mpl::integral_c<boost::numeric::int_float_mixture_enum, (Mixture) > type ; } ; \ + \ + template<> struct my_sign_mixture<Target,Source> \ + { typedef mpl::integral_c<boost::numeric::sign_mixture_enum, (SignMixture) > type ; } ; \ + \ + template<> struct my_udt_builtin_mixture<Target,Source> \ + { typedef mpl::integral_c<boost::numeric::udt_builtin_mixture_enum, (UdtMixture) > type ; } + + +#define cSubRanged true +#define cTrivial true + +// The following test assumes a specific relation between the sizes of the types being used; +// therefore, use specific fixed-width types instead built-in types directly. + +// NOTE --> TARGET,SOURCE +// +DEFINE_CONVERSION(boost::uint8_t , boost::uint8_t, cTrivial, integral_to_integral, unsigned_to_unsigned, builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(boost::int8_t , boost::uint8_t, !cTrivial, integral_to_integral, unsigned_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint16_t , boost::uint8_t, !cTrivial, integral_to_integral, unsigned_to_unsigned, builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(boost::int16_t , boost::uint8_t, !cTrivial, integral_to_integral, unsigned_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(boost::uint32_t , boost::uint8_t, !cTrivial, integral_to_integral, unsigned_to_unsigned, builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(boost::int32_t , boost::uint8_t, !cTrivial, integral_to_integral, unsigned_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(float , boost::uint8_t, !cTrivial, integral_to_float , unsigned_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(double , boost::uint8_t, !cTrivial, integral_to_float , unsigned_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(long double , boost::uint8_t, !cTrivial, integral_to_float , unsigned_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(MyInt , boost::uint8_t, !cTrivial, integral_to_integral, unsigned_to_signed , builtin_to_udt , !cSubRanged ); +DEFINE_CONVERSION(MyFloat , boost::uint8_t, !cTrivial, integral_to_float , unsigned_to_signed , builtin_to_udt , !cSubRanged ); + +DEFINE_CONVERSION(boost::uint8_t , boost::int8_t, !cTrivial, integral_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int8_t , boost::int8_t, cTrivial, integral_to_integral, signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(boost::uint16_t , boost::int8_t, !cTrivial, integral_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int16_t , boost::int8_t, !cTrivial, integral_to_integral, signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(boost::uint32_t , boost::int8_t, !cTrivial, integral_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int32_t , boost::int8_t, !cTrivial, integral_to_integral, signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(float , boost::int8_t, !cTrivial, integral_to_float , signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(double , boost::int8_t, !cTrivial, integral_to_float , signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(long double , boost::int8_t, !cTrivial, integral_to_float , signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(MyInt , boost::int8_t, !cTrivial, integral_to_integral, signed_to_signed , builtin_to_udt , !cSubRanged ); +DEFINE_CONVERSION(MyFloat , boost::int8_t, !cTrivial, integral_to_float , signed_to_signed , builtin_to_udt , !cSubRanged ); + +DEFINE_CONVERSION(boost::uint8_t , boost::uint16_t, !cTrivial, integral_to_integral, unsigned_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int8_t , boost::uint16_t, !cTrivial, integral_to_integral, unsigned_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint16_t , boost::uint16_t, cTrivial, integral_to_integral, unsigned_to_unsigned, builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(boost::int16_t , boost::uint16_t, !cTrivial, integral_to_integral, unsigned_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint32_t , boost::uint16_t, !cTrivial, integral_to_integral, unsigned_to_unsigned, builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(boost::int32_t , boost::uint16_t, !cTrivial, integral_to_integral, unsigned_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(float , boost::uint16_t, !cTrivial, integral_to_float , unsigned_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(double , boost::uint16_t, !cTrivial, integral_to_float , unsigned_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(long double , boost::uint16_t, !cTrivial, integral_to_float , unsigned_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(MyInt , boost::uint16_t, !cTrivial, integral_to_integral, unsigned_to_signed , builtin_to_udt , !cSubRanged ); +DEFINE_CONVERSION(MyFloat , boost::uint16_t, !cTrivial, integral_to_float , unsigned_to_signed , builtin_to_udt , !cSubRanged ); + +DEFINE_CONVERSION(boost::uint8_t , boost::int16_t, !cTrivial, integral_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int8_t , boost::int16_t, !cTrivial, integral_to_integral, signed_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint16_t , boost::int16_t, !cTrivial, integral_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int16_t , boost::int16_t, cTrivial, integral_to_integral, signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(boost::uint32_t , boost::int16_t, !cTrivial, integral_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int32_t , boost::int16_t, !cTrivial, integral_to_integral, signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(float , boost::int16_t, !cTrivial, integral_to_float , signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(double , boost::int16_t, !cTrivial, integral_to_float , signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(long double , boost::int16_t, !cTrivial, integral_to_float , signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(MyInt , boost::int16_t, !cTrivial, integral_to_integral, signed_to_signed , builtin_to_udt , !cSubRanged ); +DEFINE_CONVERSION(MyFloat , boost::int16_t, !cTrivial, integral_to_float , signed_to_signed , builtin_to_udt , !cSubRanged ); + +DEFINE_CONVERSION(boost::uint8_t , boost::uint32_t, !cTrivial, integral_to_integral, unsigned_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int8_t , boost::uint32_t, !cTrivial, integral_to_integral, unsigned_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint16_t , boost::uint32_t, !cTrivial, integral_to_integral, unsigned_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int16_t , boost::uint32_t, !cTrivial, integral_to_integral, unsigned_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint32_t , boost::uint32_t, cTrivial, integral_to_integral, unsigned_to_unsigned, builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(boost::int32_t , boost::uint32_t, !cTrivial, integral_to_integral, unsigned_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(float , boost::uint32_t, !cTrivial, integral_to_float , unsigned_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(double , boost::uint32_t, !cTrivial, integral_to_float , unsigned_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(long double , boost::uint32_t, !cTrivial, integral_to_float , unsigned_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(MyInt , boost::uint32_t, !cTrivial, integral_to_integral, unsigned_to_signed , builtin_to_udt , !cSubRanged ); +DEFINE_CONVERSION(MyFloat , boost::uint32_t, !cTrivial, integral_to_float , unsigned_to_signed , builtin_to_udt , !cSubRanged ); + +DEFINE_CONVERSION(boost::uint8_t , boost::int32_t, !cTrivial, integral_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int8_t , boost::int32_t, !cTrivial, integral_to_integral, signed_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint16_t , boost::int32_t, !cTrivial, integral_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int16_t , boost::int32_t, !cTrivial, integral_to_integral, signed_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint32_t , boost::int32_t, !cTrivial, integral_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int32_t , boost::int32_t, cTrivial, integral_to_integral, signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(float , boost::int32_t, !cTrivial, integral_to_float , signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(double , boost::int32_t, !cTrivial, integral_to_float , signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(long double , boost::int32_t, !cTrivial, integral_to_float , signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(MyInt , boost::int32_t, !cTrivial, integral_to_integral, signed_to_signed , builtin_to_udt , !cSubRanged ); +DEFINE_CONVERSION(MyFloat , boost::int32_t, !cTrivial, integral_to_float , signed_to_signed , builtin_to_udt , !cSubRanged ); + +DEFINE_CONVERSION(boost::uint8_t , float, !cTrivial, float_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int8_t , float, !cTrivial, float_to_integral, signed_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint16_t , float, !cTrivial, float_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int16_t , float, !cTrivial, float_to_integral, signed_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint32_t , float, !cTrivial, float_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int32_t , float, !cTrivial, float_to_integral, signed_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(float , float, cTrivial, float_to_float , signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(double , float, !cTrivial, float_to_float , signed_to_signed , builtin_to_builtin, ( sizeof(float) > sizeof(double) ) ); +DEFINE_CONVERSION(long double , float, !cTrivial, float_to_float , signed_to_signed , builtin_to_builtin, ( sizeof(float) > sizeof(long double) ) ); +DEFINE_CONVERSION(MyInt , float, !cTrivial, float_to_integral, signed_to_signed , builtin_to_udt , !cSubRanged ); +DEFINE_CONVERSION(MyFloat , float, !cTrivial, float_to_float , signed_to_signed , builtin_to_udt , !cSubRanged ); + +DEFINE_CONVERSION(boost::uint8_t , double, !cTrivial, float_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int8_t , double, !cTrivial, float_to_integral, signed_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint16_t , double, !cTrivial, float_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int16_t , double, !cTrivial, float_to_integral, signed_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint32_t , double, !cTrivial, float_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int32_t , double, !cTrivial, float_to_integral, signed_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(float , double, !cTrivial, float_to_float , signed_to_signed , builtin_to_builtin, ( sizeof(double) > sizeof(float) ) ); +DEFINE_CONVERSION(double , double, cTrivial, float_to_float , signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(long double , double, !cTrivial, float_to_float , signed_to_signed , builtin_to_builtin, ( sizeof(double) > sizeof(long double) ) ); +DEFINE_CONVERSION(MyInt , double, !cTrivial, float_to_integral, signed_to_signed , builtin_to_udt , !cSubRanged ); +DEFINE_CONVERSION(MyFloat , double, !cTrivial, float_to_float , signed_to_signed , builtin_to_udt , !cSubRanged ); + +DEFINE_CONVERSION(boost::uint8_t , long double, !cTrivial, float_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int8_t , long double, !cTrivial, float_to_integral, signed_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint16_t , long double, !cTrivial, float_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int16_t , long double, !cTrivial, float_to_integral, signed_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::uint32_t , long double, !cTrivial, float_to_integral, signed_to_unsigned, builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(boost::int32_t , long double, !cTrivial, float_to_integral, signed_to_signed , builtin_to_builtin, cSubRanged ); +DEFINE_CONVERSION(float , long double, !cTrivial, float_to_float , signed_to_signed , builtin_to_builtin, ( sizeof(long double) > sizeof(float) ) ); +DEFINE_CONVERSION(double , long double, !cTrivial, float_to_float , signed_to_signed , builtin_to_builtin, ( sizeof(long double) > sizeof(double) ) ); +DEFINE_CONVERSION(long double , long double, cTrivial, float_to_float , signed_to_signed , builtin_to_builtin, !cSubRanged ); +DEFINE_CONVERSION(MyInt , long double, !cTrivial, float_to_integral, signed_to_signed , builtin_to_udt , !cSubRanged ); +DEFINE_CONVERSION(MyFloat , long double, !cTrivial, float_to_float , signed_to_signed , builtin_to_udt , !cSubRanged ); + +DEFINE_CONVERSION(boost::uint8_t , MyInt, !cTrivial, integral_to_integral, signed_to_unsigned, udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(boost::int8_t , MyInt, !cTrivial, integral_to_integral, signed_to_signed , udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(boost::uint16_t , MyInt, !cTrivial, integral_to_integral, signed_to_unsigned, udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(boost::int16_t , MyInt, !cTrivial, integral_to_integral, signed_to_signed , udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(boost::uint32_t , MyInt, !cTrivial, integral_to_integral, signed_to_unsigned, udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(boost::int32_t , MyInt, !cTrivial, integral_to_integral, signed_to_signed , udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(float , MyInt, !cTrivial, integral_to_float , signed_to_signed , udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(double , MyInt, !cTrivial, integral_to_float , signed_to_signed , udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(long double , MyInt, !cTrivial, integral_to_float , signed_to_signed , udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(MyInt , MyInt, cTrivial, integral_to_integral, signed_to_signed , udt_to_udt ,!cSubRanged ); +DEFINE_CONVERSION(MyFloat , MyInt, !cTrivial, integral_to_float , signed_to_signed , udt_to_udt ,!cSubRanged ); + +DEFINE_CONVERSION(boost::uint8_t , MyFloat, !cTrivial, float_to_integral, signed_to_unsigned, udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(boost::int8_t , MyFloat, !cTrivial, float_to_integral, signed_to_signed , udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(boost::uint16_t , MyFloat, !cTrivial, float_to_integral, signed_to_unsigned, udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(boost::int16_t , MyFloat, !cTrivial, float_to_integral, signed_to_signed , udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(boost::uint32_t , MyFloat, !cTrivial, float_to_integral, signed_to_unsigned, udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(boost::int32_t , MyFloat, !cTrivial, float_to_integral, signed_to_signed , udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(float , MyFloat, !cTrivial, float_to_float , signed_to_signed , udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(double , MyFloat, !cTrivial, float_to_float , signed_to_signed , udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(long double , MyFloat, !cTrivial, float_to_float , signed_to_signed , udt_to_builtin , cSubRanged ); +DEFINE_CONVERSION(MyInt , MyFloat, !cTrivial, float_to_integral, signed_to_signed , udt_to_udt ,!cSubRanged ); +DEFINE_CONVERSION(MyFloat , MyFloat, cTrivial, float_to_float , signed_to_signed , udt_to_udt ,!cSubRanged ); + +// +// The test is performed by comparing each field of +// boost::numeric::conversion_traits<T,S> +// with the fields of +// expected_traits<T,S> +// which is a traits class constructed explicitely for each combination +// of the built-in arithmetic types. +// +template<class T, + class S, + class Supertype, + class Subtype, + class Subranged, + class Trivial + > +struct expected_traits +{ + typedef typename my_int_float_mixture <T,S>::type int_float_mixture ; + typedef typename my_sign_mixture <T,S>::type sign_mixture ; + typedef typename my_udt_builtin_mixture <T,S>::type udt_builtin_mixture ; + + typedef Subranged subranged ; + typedef Trivial trivial ; + typedef Supertype supertype ; + typedef Subtype subtype ; +} ; + +// This is used by the test engine to generate a expected_traits from T and S. +// +template<class T, class S> +struct generate_expected_traits +{ + typedef expected_traits<T, S, T, S, mpl::false_, mpl::true_ > trivial ; + typedef expected_traits<T, S, S, T, mpl::true_ , mpl::false_ > subranged ; + typedef expected_traits<T, S, T, S, mpl::false_, mpl::false_ > non_subranged ; + + typedef typename my_is_subranged<T,S>::type IsSubranged ; + typedef typename my_is_trivial <T,S>::type IsTrivial ; + + typedef typename mpl::if_<IsSubranged,subranged,non_subranged>::type non_trivial ; + + typedef typename mpl::if_<IsTrivial,trivial,non_trivial>::type type ; +} ; + +// This macro generates the code that compares a non-type field +// in boost::numeric::conversion_traits<> with its corresponding field +// in expected_traits<> +// + +#define TEST_VALUE_FIELD(Name) \ + typedef typename traits::Name BOOST_PP_CAT(t,Name) ; \ + typedef typename expected::Name BOOST_PP_CAT(x,Name) ; \ + BOOST_CHECK_MESSAGE ( ( BOOST_PP_CAT(t,Name)::value == BOOST_PP_CAT(x,Name)::value ) , \ + "conversion_traits<" << typeid(T).name() << "," << typeid(S).name() \ + << ">::" << #Name << " = " << to_string(BOOST_PP_CAT(t,Name)::value) \ + << ". Expected: " << to_string(BOOST_PP_CAT(x,Name)::value) \ + ) ; + +// This macro generates the code that compares a type field +// in numeric::conversion_traits<> with its corresponding field +// in expected_traits<> +// +#define TEST_TYPE_FIELD(Name) \ + typedef typename traits::Name BOOST_PP_CAT(t,Name) ; \ + typedef typename expected::Name BOOST_PP_CAT(x,Name) ; \ + BOOST_CHECK_MESSAGE ( ( typeid(BOOST_PP_CAT(t,Name)) == typeid(BOOST_PP_CAT(x,Name)) ) , \ + "conversion_traits<" << typeid(T).name() << "," << typeid(S).name() \ + << ">::" << #Name << " = " << typeid(BOOST_PP_CAT(t,Name)).name() \ + << ". Expected: " << typeid(BOOST_PP_CAT(x,Name)).name() \ + ) ; + +// +// Test core. +// Compares each field of boost::numeric::conversion_traits<T,S> +// with the corresponding field of expected_traits<T,S> +// +template<class T, class S> +void test_traits_base( MATCH_FNTPL_ARG(T), MATCH_FNTPL_ARG(S) ) +{ + typedef boost::numeric::conversion_traits<T,S> traits ; + typedef typename generate_expected_traits<T,S>::type expected ; + + TEST_VALUE_FIELD(int_float_mixture) ; + TEST_VALUE_FIELD(sign_mixture) ; + TEST_VALUE_FIELD(udt_builtin_mixture) ; + TEST_VALUE_FIELD(subranged) ; + TEST_VALUE_FIELD(trivial) ; + TEST_TYPE_FIELD (supertype) ; + TEST_TYPE_FIELD (subtype) ; +} + + +template<class S> +void test_traits_from( MATCH_FNTPL_ARG(S) ) +{ + test_traits_base( SET_FNTPL_ARG(boost::uint8_t) ,SET_FNTPL_ARG(S) ); + test_traits_base( SET_FNTPL_ARG(boost::int8_t) ,SET_FNTPL_ARG(S) ); + test_traits_base( SET_FNTPL_ARG(boost::uint16_t) ,SET_FNTPL_ARG(S) ); + test_traits_base( SET_FNTPL_ARG(boost::int16_t) ,SET_FNTPL_ARG(S) ); + test_traits_base( SET_FNTPL_ARG(boost::uint32_t) ,SET_FNTPL_ARG(S) ); + test_traits_base( SET_FNTPL_ARG(boost::int32_t) ,SET_FNTPL_ARG(S) ); + test_traits_base( SET_FNTPL_ARG(float) ,SET_FNTPL_ARG(S) ); + test_traits_base( SET_FNTPL_ARG(double) ,SET_FNTPL_ARG(S) ); + test_traits_base( SET_FNTPL_ARG(long double) ,SET_FNTPL_ARG(S) ); + test_traits_base( SET_FNTPL_ARG(MyInt) ,SET_FNTPL_ARG(S) ); + test_traits_base( SET_FNTPL_ARG(MyFloat) ,SET_FNTPL_ARG(S) ); +} + +void test_traits() +{ + test_traits_from( SET_FNTPL_ARG(boost::uint8_t) ); + test_traits_from( SET_FNTPL_ARG(boost::int8_t) ); + test_traits_from( SET_FNTPL_ARG(boost::uint16_t) ); + test_traits_from( SET_FNTPL_ARG(boost::int16_t) ); + test_traits_from( SET_FNTPL_ARG(boost::uint32_t) ); + test_traits_from( SET_FNTPL_ARG(boost::int32_t) ); + test_traits_from( SET_FNTPL_ARG(float) ); + test_traits_from( SET_FNTPL_ARG(double) ); + test_traits_from( SET_FNTPL_ARG(long double) ); + test_traits_from( SET_FNTPL_ARG(MyInt) ); + test_traits_from( SET_FNTPL_ARG(MyFloat) ); +} + +int test_main( int, char * []) +{ + std::cout << std::setprecision( std::numeric_limits<long double>::digits10 ) ; + + test_traits(); + + return 0; +} +//--------------------------------------------------------------------------- + diff --git a/src/boost/libs/numeric/conversion/test/udt_example_0.cpp b/src/boost/libs/numeric/conversion/test/udt_example_0.cpp new file mode 100644 index 000000000..067e5e7a4 --- /dev/null +++ b/src/boost/libs/numeric/conversion/test/udt_example_0.cpp @@ -0,0 +1,242 @@ +// Copyright (C) 2005, Fernando Luis Cacciola Carballal. +// +// 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) +// +// +#include "boost/config.hpp" +#include "boost/utility.hpp" +#include "boost/limits.hpp" +#include "boost/utility.hpp" + +#include<iostream> +#include<iomanip> +#include<string> +#include<cmath> + + +#include "boost/test/included/test_exec_monitor.hpp" + +#include "boost/numeric/conversion/cast.hpp" + +using namespace std ; +using namespace boost; +using namespace numeric; + +// +// This example illustrates how to add support for user defined types (UDTs) +// to the Boost Numeric Conversion Library. +// It is assumed that you are familiar with the following documentation: +// +// + +// +// The minimum requirement is that boost::is_arithmetic<UDT> evaluates to false +// (Otherwise the converter code will try to examine the UDT as a built-in type) +// + +// +// Let's start with the simpliest case of an UDT which supports standard conversions +// +struct Double +{ + Double( double v ) : mV(v) {} + + operator double() const { return mV ; } + + double mV ; +} ; + +double dv = (numeric_limits<double>::max)() ; +double fv = (numeric_limits<float >::max)() ; +Double Dv(dv); +Double Fv(fv); + +void simplest_case() +{ + // + // conversion_traits<>::udt_builtin_mixture works out of the box as long as boost::is_arithmetic<UDT> yields false + // + BOOST_CHECK( (conversion_traits<double,Double>::udt_builtin_mixture::value == udt_to_builtin) ) ; + BOOST_CHECK( (conversion_traits<Double,double>::udt_builtin_mixture::value == builtin_to_udt) ) ; + BOOST_CHECK( (conversion_traits<Double,Double>::udt_builtin_mixture::value == udt_to_udt ) ) ; + + // BY DEFINITION, a conversion from UDT to Builtin is subranged. No attempt is made to actually compare ranges. + BOOST_CHECK( (conversion_traits<double,Double>::subranged::value) == true ) ; + BOOST_CHECK( (conversion_traits<Double,double>::subranged::value) == false ) ; + + + + // + // Conversions to/from FLOATING types, if already supported by an UDT + // are also supported out-of-the-box by converter<> in its default configuration. + // + BOOST_CHECK( numeric_cast<double>(Dv) == static_cast<double>(Dv) ) ; + BOOST_CHECK( numeric_cast<Double>(dv) == static_cast<Double>(dv) ) ; + + BOOST_CHECK( numeric_cast<float> (Dv) == static_cast<float> (Dv) ) ; + BOOST_CHECK( numeric_cast<Double>(fv) == static_cast<Double>(fv) ) ; + + + // + // Range checking is disabled by default if an UDT is either the source or target of the conversion. + // + BOOST_CHECK( (converter<float,double>::out_of_range(dv) == cPosOverflow) ); + BOOST_CHECK( (converter<float,Double>::out_of_range(Dv) == cInRange) ); + +} + +// +// The conversion_traits<> class and therefore the converter<> class looks at +// numeric_limits<UDT>::is_integer/is_signed to generate the proper float_in and sign mixtures. +// In most implementations, is_integer/is_signed are both false for UDTs if there is no explicit specialization for it. +// Therefore, the converter<> will see any UDT for which numeric_limits<> is not specialized as Float AND unsigned. +// Signess is used in the converter<> for range checking, but range checking is disabled by default for UDTs, so, +// normally, signess is mostly irrelevant as far as the library is concerned, except for the numeric_traits<>::sign_mixture +// entry. +// is_integer, however, is relevant in that if the conversion is from a float type to an integer type, the conversion is +// "rounding" and the rounder policies will participate. +// ALL implemented rounder policies require proper definitions for floor(udt) and ceil(udt). +// These names will be searched for using ADL, so, if you need to convert TO integral types from a UDT, +// you need to supply those functions along with the UDT in right namespace (that is, any namespace that allows +// ADL to find them) + +// If your UDT doesn't supply floor/ceil, conversions to integer types +// won't compile unless a custom Float2IntRounder is used. + +Double floor ( Double v ) { return Double(std::floor(v.mV)) ; } +Double ceil ( Double v ) { return Double(std::ceil (v.mV)) ; } + +void rounding() +{ + BOOST_CHECK( numeric_cast<int>(Dv) == static_cast<int>(Dv) ) ; +} + + +// +// If your UDT can't or won't provide floor/ceil you can set-up and use your own +// Float2IntRounder policy (though doing this is not always required as shown so far) +// +struct DoubleToInt +{ + static Double nearbyint ( Double const& s ) { return Double(static_cast<int>(s)); } + + typedef mpl::integral_c< std::float_round_style, std::round_toward_zero> round_style ; +} ; + +void custom_rounding() +{ + typedef converter<int + ,Double + ,conversion_traits<int,Double> + ,void // By default UDT disable range checking so this won't be used + ,DoubleToInt + > + DoubleToIntConverter ; + + BOOST_CHECK( DoubleToIntConverter::convert(Dv) == static_cast<int>(Dv) ) ; +} + +// +// In the next Level of complexity, your UDTs might not support conversion operators +// +struct Float +{ + Float( float v ) : mV(v) {} + + float mV ; +} ; + +struct Int +{ + Int( int v ) : mV(v) {} + + int mV ; +} ; + +typedef conversion_traits<Int,Float> Float2IntTraits ; +typedef conversion_traits<Float,Int> Int2FloatTraits ; + +namespace boost { namespace numeric +{ +// +// Though static_cast<> won't work with them you can still use numeric_cast<> by specializing +// raw_converter as follows: +// +template<> struct raw_converter<Float2IntTraits> +{ + typedef Float2IntTraits::result_type result_type ; + typedef Float2IntTraits::argument_type argument_type ; + + static result_type low_level_convert ( argument_type s ) { return Int((int)s.mV); } +} ; +template<> struct raw_converter<Int2FloatTraits> +{ + typedef Int2FloatTraits::result_type result_type ; + typedef Int2FloatTraits::argument_type argument_type ; + + static result_type low_level_convert ( argument_type s ) { return Float(s.mV); } +} ; + +} } + +void custom_raw_converter() +{ + Float f (12.34); + Int i (12); + Float fi(12); + + BOOST_CHECK(numeric_cast<Int> (f).mV == i .mV ) ; + BOOST_CHECK(numeric_cast<Float>(i).mV == fi.mV ) ; +} + +// +// Alterntively, the custom raw_converter classes can be defined non-instrusively +// (not as specializations) and passed along as policies +// +struct Float2IntRawConverter +{ + static Int low_level_convert ( Float const& s ) { return Int((int)s.mV); } +} ; +struct Int2FloatRawConverter +{ + static Float low_level_convert ( Int const& s ) { return Float(s.mV); } +} ; + +void custom_raw_converter2() +{ + Float f (12.34); + Int i (12); + Float fi(12); + + typedef converter<Int + ,Float + ,Float2IntTraits + ,void // By default UDT disable range checking so this won't be used + ,void // Float2Int Rounder won't be used if Int isn't marked as integer via numeric_limits<> + ,Float2IntRawConverter + > + Float2IntConverter ; + + BOOST_CHECK(Float2IntConverter::convert(f).mV == i .mV ) ; +} + +int test_main( int, char* [] ) +{ + cout << setprecision( numeric_limits<long double>::digits10 ) ; + + simplest_case(); + rounding(); + custom_rounding(); + custom_raw_converter(); + custom_raw_converter2(); + + return 0; +} + + + + + + diff --git a/src/boost/libs/numeric/conversion/test/udt_support_test.cpp b/src/boost/libs/numeric/conversion/test/udt_support_test.cpp new file mode 100644 index 000000000..581b0e504 --- /dev/null +++ b/src/boost/libs/numeric/conversion/test/udt_support_test.cpp @@ -0,0 +1,309 @@ +// (C) Copyright 2003, Fernando Luis Cacciola Carballal. +// +// 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) +// +// +#include<iostream> +#include<iomanip> +#include<string> +#include<typeinfo> +#include<vector> +#include<algorithm> + +#include "boost/numeric/conversion/converter.hpp" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "test_helpers.cpp" +#include "test_helpers2.cpp" +#include "test_helpers3.cpp" + +using namespace std ; +using namespace boost ; +using namespace numeric ; +using namespace MyUDT ; + +//------------------------------------------------------------------------- +// These are the typical steps that are required to install support for +// conversions from/to UDT which need special treatment. +//------------------------------------------------------------------------- + + + +// +// (1) Instantiate specific convesions traits. +// This step is only for convenience. +// These traits instances are required in order to define the specializations +// that follow (and which *are required* to make the library work with MyInt and MyFloat) +// +namespace MyUDT { + +typedef conversion_traits<double , MyFloat> MyFloat_to_double_Traits; +typedef conversion_traits<int , MyFloat> MyFloat_to_int_Traits; +typedef conversion_traits<MyInt , MyFloat> MyFloat_to_MyInt_Traits; +typedef conversion_traits<int , MyInt > MyInt_to_int_Traits; +typedef conversion_traits<MyFloat, MyInt > MyInt_to_MyFloat_Traits; +typedef conversion_traits<MyInt , double > double_to_MyInt_Traits; + +} // namespace MyUDT + + +// +// (2) Define suitable raw converters. +// +// Our sample UDTs don't support implicit conversions. +// Therefore, the default raw_converter<> doesn't work, +// and we need to define our own. +// +// There are two ways of doing this: +// +// (a) One is to simply specialize boost::numeric::raw_converter<> directly. +// This way, the default converter will work out of the box, which means, for instance, +// that numeric_cast<> can be used with these UDTs. +// +// (b) Define a user class with the appropriate interface and supply it explicitely +// as a policy to a converter instance. +// +// This test uses chice (a). +// +namespace boost { + +namespace numeric { + +template<> +struct raw_converter<MyUDT::MyFloat_to_double_Traits> +{ + static double low_level_convert ( MyUDT::MyFloat const& s ) + { return s.to_builtin() ; } +} ; + +template<> +struct raw_converter<MyUDT::MyFloat_to_int_Traits> +{ + static int low_level_convert ( MyUDT::MyFloat const& s ) + { return static_cast<int>( s.to_builtin() ) ; } +} ; + +template<> +struct raw_converter<MyUDT::MyFloat_to_MyInt_Traits> +{ + static MyUDT::MyInt low_level_convert ( MyUDT::MyFloat const& s ) + { return MyUDT::MyInt( static_cast<int>(s.to_builtin()) ) ; } +} ; + +template<> +struct raw_converter<MyUDT::MyInt_to_int_Traits> +{ + static int low_level_convert ( MyUDT::MyInt const& s ) { return s.to_builtin() ; } +} ; + +template<> +struct raw_converter<MyUDT::MyInt_to_MyFloat_Traits> +{ + static MyUDT::MyFloat low_level_convert ( MyUDT::MyInt const& s ) + { + return MyUDT::MyFloat( static_cast<double>(s.to_builtin()) ) ; + } +} ; + +template<> +struct raw_converter<MyUDT::double_to_MyInt_Traits> +{ + static MyUDT::MyInt low_level_convert ( double s ) + { return MyUDT::MyInt( static_cast<int>(s) ) ; } +} ; + +} // namespace numeric + +} // namespace boost + + + +// +// (3) Define suitable range checkers +// +// By default, if a UDT is involved in a conversion, internal range checking is disabled. +// This is so because a UDT type can have any sort of range, even unbounded, thus +// the library doesn't attempt to automatically figure out the appropriate range checking logic. +// (as it does when builtin types are involved) +// However, this situation is a bit unsufficient in practice, specially from doing narrowing (subranged) +// conversions from UDTs. +// The library provides a rudimentary hook to help this out: The user can plug in his own +// range checker to the converter instance. +// +// This test shows how to define and use a custom range checker. +// + +namespace MyUDT { + +// +// The following are metaprogramming tools to allow us the implement the +// MyCustomRangeChecker generically, for either builtin or UDT types. +// + +// get_builtin_type<N>::type extracts the built-in type of our UDT's +// +template<class N> struct get_builtin_type { typedef N type ; } ; +template<> struct get_builtin_type<MyInt> { typedef int type ; } ; +template<> struct get_builtin_type<MyFloat> { typedef double type ; } ; + +// U extract_builtin ( T s ) returns 's' converted to the corresponding built-in type U. +// +template<class N> +struct extract_builtin +{ + static N apply ( N n ) { return n ; } +} ; +template<> +struct extract_builtin<MyInt> +{ + static int apply ( MyInt const& n ) { return n.to_builtin() ; } +} ; +template<> +struct extract_builtin<MyFloat> +{ + static double apply ( MyFloat const& n ) { return n.to_builtin() ; } +} ; + +template<class Traits> +struct MyCustomRangeChecker +{ + typedef typename Traits::argument_type argument_type ; + + // This custom range checker uses the fact that our 'fake' UDT are merely wrappers + // around builtin types; so it just forward the logic to the correspoding range + // checkers for the wrapped builtin types. + // + typedef typename Traits::source_type S ; + typedef typename Traits::target_type T ; + + // NOTE: S and/or T can be either UDT or builtin types. + + typedef typename get_builtin_type<S>::type builtinS ; + typedef typename get_builtin_type<T>::type builtinT ; + + // NOTE: The internal range checker used by default is *built* when you instantiate + // a converter<> with a given Traits according to the properties of the involved types. + // Currently, there is no way to instantiate this range checker as a separate class. + // However, you can see it as part of the interface of the converter + // (since the converter inherits from it) + // Therefore, here we instantiate a converter corresponding to the builtin types to access + // their associated builtin range checker. + // + typedef boost::numeric::converter<builtinT,builtinS> InternalConverter ; + + static range_check_result out_of_range ( argument_type s ) + { + return InternalConverter::out_of_range( extract_builtin<S>::apply(s) ); + } + + static void validate_range ( argument_type s ) + { + return InternalConverter::validate_range( extract_builtin<S>::apply(s) ); + } +} ; + +} // namespace MyUDT + + + + + + + + +// +// Test here +// + +void test_udt_conversions_with_defaults() +{ + cout << "Testing UDT conversion with default policies\n" ; + + // MyInt <--> int + + int mibv = rand(); + MyInt miv(mibv); + TEST_SUCCEEDING_CONVERSION_DEF(MyInt,int,miv,mibv); + TEST_SUCCEEDING_CONVERSION_DEF(int,MyInt,mibv,miv); + + // MyFloat <--> double + + double mfbv = static_cast<double>(rand()) / 3.0 ; + MyFloat mfv (mfbv); + TEST_SUCCEEDING_CONVERSION_DEF(MyFloat,double,mfv,mfbv); + TEST_SUCCEEDING_CONVERSION_DEF(double,MyFloat,mfbv,mfv); + + // MyInt <--> MyFloat + + MyInt miv2 ( static_cast<int>(mfbv) ); + MyFloat miv2F ( static_cast<int>(mfbv) ); + MyFloat mfv2 ( static_cast<double>(mibv) ); + MyInt mfv2I ( static_cast<double>(mibv) ); + TEST_SUCCEEDING_CONVERSION_DEF(MyFloat,MyInt,miv2F,miv2); + TEST_SUCCEEDING_CONVERSION_DEF(MyInt,MyFloat,mfv2I,mfv2); +} + +template<class T, class S> +struct GenerateCustomConverter +{ + typedef conversion_traits<T,S> Traits; + + typedef def_overflow_handler OverflowHandler ; + typedef Trunc<S> Float2IntRounder ; + typedef raw_converter<Traits> RawConverter ; + typedef MyCustomRangeChecker<Traits> RangeChecker ; + + typedef converter<T,S,Traits,OverflowHandler,Float2IntRounder,RawConverter,RangeChecker> type ; +} ; + +void test_udt_conversions_with_custom_range_checking() +{ + cout << "Testing UDT conversions with custom range checker\n" ; + + int mibv = rand(); + MyFloat mfv ( static_cast<double>(mibv) ); + + typedef GenerateCustomConverter<MyFloat,int>::type int_to_MyFloat_Conv ; + + TEST_SUCCEEDING_CONVERSION( int_to_MyFloat_Conv, MyFloat, int, mfv, mibv ); + + int mibv2 = rand(); + MyInt miv (mibv2); + MyFloat mfv2 ( static_cast<double>(mibv2) ); + + typedef GenerateCustomConverter<MyFloat,MyInt>::type MyInt_to_MyFloat_Conv ; + + TEST_SUCCEEDING_CONVERSION( MyInt_to_MyFloat_Conv, MyFloat, MyInt, mfv2, miv ); + + double mfbv = bounds<double>::highest(); + typedef GenerateCustomConverter<MyInt,double>::type double_to_MyInt_Conv ; + + TEST_POS_OVERFLOW_CONVERSION( double_to_MyInt_Conv, MyInt, double, mfbv ); + + MyFloat mfv3 ( bounds<double>::lowest() ) ; + typedef GenerateCustomConverter<int,MyFloat>::type MyFloat_to_int_Conv ; + + TEST_NEG_OVERFLOW_CONVERSION( MyFloat_to_int_Conv, int, MyFloat, mfv3 ); +} + + +int test_main( int, char* [] ) +{ + cout << setprecision( numeric_limits<long double>::digits10 ) ; + + test_udt_conversions_with_defaults(); + test_udt_conversions_with_custom_range_checking(); + + return 0; +} + + + + + + diff --git a/src/boost/libs/numeric/index.html b/src/boost/libs/numeric/index.html new file mode 100644 index 000000000..f1e4350be --- /dev/null +++ b/src/boost/libs/numeric/index.html @@ -0,0 +1,14 @@ +<html> +<head> +<meta http-equiv="refresh" content="0; URL=ublas/doc/index.html"> +</head> +<body> +Automatic redirection failed, please go to +<a href="ublas/doc/index.html">ublas/doc/index.html</a>. <hr> +<p>© Copyright Beman Dawes, 2001</p> +<p>Distributed under the Boost Software License, Version 1.0. (See accompanying +file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy +at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>) +</p> +</body> +</html> diff --git a/src/boost/libs/numeric/interval/Jamfile b/src/boost/libs/numeric/interval/Jamfile new file mode 100644 index 000000000..e59673e3b --- /dev/null +++ b/src/boost/libs/numeric/interval/Jamfile @@ -0,0 +1,11 @@ +# Boost.Interval Library Jamfile +# +# Copyright (c) 2018 James E. King III +# +# 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) + +# please order by name to ease maintenance +build-project examples ; +build-project test ; diff --git a/src/boost/libs/numeric/interval/LICENSE b/src/boost/libs/numeric/interval/LICENSE new file mode 100644 index 000000000..36b7cd93c --- /dev/null +++ b/src/boost/libs/numeric/interval/LICENSE @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/src/boost/libs/numeric/interval/README.md b/src/boost/libs/numeric/interval/README.md new file mode 100644 index 000000000..d211dfb32 --- /dev/null +++ b/src/boost/libs/numeric/interval/README.md @@ -0,0 +1,34 @@ +Interval, part of the collection of [Boost C++ Libraries](http://github.com/boostorg), is intended to help manipulating mathematical intervals. + +### License + +Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt). + +### Properties + +* C++03 +* Header-only + +### Build Status + +Branch | Travis | Appveyor | Coverity Scan | codecov.io | Deps | Docs | Tests | +:-------------: | ------ | -------- | ------------- | ---------- | ---- | ---- | ----- | +[`master`](https://github.com/boostorg/interval/tree/master) | [![Build Status](https://travis-ci.org/boostorg/interval.svg?branch=master)](https://travis-ci.org/boostorg/interval) | [![Build status](https://ci.appveyor.com/api/projects/status/wx6gsonby36or5m2/branch/master?svg=true)](https://ci.appveyor.com/project/jeking3/interval-o0u28/branch/master) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/17151/badge.svg)](https://scan.coverity.com/projects/boostorg-interval) | [![codecov](https://codecov.io/gh/boostorg/interval/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/interval/branch/master) | [![Deps](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/interval.html) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](http://www.boost.org/doc/libs/master/doc/html/interval.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](http://www.boost.org/development/tests/master/developer/interval.html) +[`develop`](https://github.com/boostorg/interval/tree/develop) | [![Build Status](https://travis-ci.org/boostorg/interval.svg?branch=develop)](https://travis-ci.org/boostorg/interval) | [![Build status](https://ci.appveyor.com/api/projects/status/wx6gsonby36or5m2/branch/develop?svg=true)](https://ci.appveyor.com/project/jeking3/interval-o0u28/branch/develop) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/17151/badge.svg)](https://scan.coverity.com/projects/boostorg-interval) | [![codecov](https://codecov.io/gh/boostorg/interval/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/interval/branch/develop) | [![Deps](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/interval.html) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](http://www.boost.org/doc/libs/develop/doc/html/interval.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](http://www.boost.org/development/tests/develop/developer/interval.html) + +### Directories + +| Name | Purpose | +| ----------- | ------------------------------ | +| `doc` | documentation | +| `examples` | use case examples | +| `include` | headers | +| `test` | unit tests | + +### More inintervalion + +* [Ask questions](http://stackoverflow.com/questions/ask?tags=c%2B%2B,boost,boost-interval): Be sure to read the documentation first as Boost.Interval has specific requirements. +* [Report bugs](https://github.com/boostorg/interval/issues): Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well. +* [Submit Pull Requests](https://github.com/boostorg/interval/pulls) against the **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt). Be sure to include tests proving your changes work properly. +* Discussions about the library are held on the [Boost developers mailing list](http://www.boost.org/community/groups.html#main). Be sure to read the [discussion policy](http://www.boost.org/community/policy.html) before posting and add the `[interval]` tag at the beginning of the subject line. + diff --git a/src/boost/libs/numeric/interval/examples/Jamfile.v2 b/src/boost/libs/numeric/interval/examples/Jamfile.v2 new file mode 100644 index 000000000..b2890b11c --- /dev/null +++ b/src/boost/libs/numeric/interval/examples/Jamfile.v2 @@ -0,0 +1,20 @@ +# Boost.Interval Library example Jamfile +# +# Copyright (c) 2018 James E. King III +# +# 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) + +import testing ; + +{ + test-suite interval-examples + : [ compile filter.cpp : <build>yes <toolset>msvc-10.0:<build>no ] # ambiguous sin() + [ compile findroot_demo.cpp ] + [ compile horner.cpp ] + [ compile io.cpp ] + [ compile newton-raphson.cpp ] + [ compile rational.cpp ] + # [ compile transc.cpp ] requires gmp3, mpfr + ; +} diff --git a/src/boost/libs/numeric/interval/examples/filter.cpp b/src/boost/libs/numeric/interval/examples/filter.cpp new file mode 100644 index 000000000..a2d8f32e5 --- /dev/null +++ b/src/boost/libs/numeric/interval/examples/filter.cpp @@ -0,0 +1,209 @@ +/* Boost example/filter.cpp + * two examples of filters for computing the sign of a determinant + * the second filter is based on an idea presented in + * "Interval arithmetic yields efficient dynamic filters for computational + * geometry" by Brönnimann, Burnikel and Pion, 2001 + * + * Copyright 2003 Guillaume Melquiond + * + * 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) + */ + +#include <boost/numeric/interval.hpp> +#include <cstring> +#include <iostream> + +namespace dummy { + using namespace boost; + using namespace numeric; + using namespace interval_lib; + typedef save_state<rounded_arith_opp<double> > R; + typedef checking_no_nan<double, checking_no_empty<double> > P; + typedef interval<double, policies<R, P> > I; +} + +template<class T> +class vector { + T* ptr; +public: + vector(int d) { ptr = (T*)malloc(sizeof(T) * d); } + ~vector() { free(ptr); } + const T& operator[](int i) const { return ptr[i]; } + T& operator[](int i) { return ptr[i]; } +}; + +template<class T> +class matrix { + int dim; + T* ptr; +public: + matrix(int d): dim(d) { ptr = (T*)malloc(sizeof(T) * dim * dim); } + ~matrix() { free(ptr); } + int get_dim() const { return dim; } + void assign(const matrix<T> &a) { memcpy(ptr, a.ptr, sizeof(T) * dim * dim); } + const T* operator[](int i) const { return &(ptr[i * dim]); } + T* operator[](int i) { return &(ptr[i * dim]); } +}; + +typedef dummy::I I_dbl; + +/* compute the sign of a determinant using an interval LU-decomposition; the + function answers 1 or -1 if the determinant is positive or negative (and + more importantly, the result must be provable), or 0 if the algorithm was + unable to get a correct sign */ +int det_sign_algo1(const matrix<double> &a) { + int dim = a.get_dim(); + vector<int> p(dim); + for(int i = 0; i < dim; i++) p[i] = i; + int sig = 1; + I_dbl::traits_type::rounding rnd; + typedef boost::numeric::interval_lib::unprotect<I_dbl>::type I; + matrix<I> u(dim); + for(int i = 0; i < dim; i++) { + const double* line1 = a[i]; + I* line2 = u[i]; + for(int j = 0; j < dim; j++) + line2[j] = line1[j]; + } + // computation of L and U + for(int i = 0; i < dim; i++) { + // partial pivoting + { + int pivot = i; + double max = 0; + for(int j = i; j < dim; j++) { + const I &v = u[p[j]][i]; + if (zero_in(v)) continue; + double m = norm(v); + if (m > max) { max = m; pivot = j; } + } + if (max == 0) return 0; + if (pivot != i) { + sig = -sig; + int tmp = p[i]; + p[i] = p[pivot]; + p[pivot] = tmp; + } + } + // U[i,?] + { + I *line1 = u[p[i]]; + const I &pivot = line1[i]; + if (boost::numeric::interval_lib::cerlt(pivot, 0.)) sig = -sig; + for(int k = i + 1; k < dim; k++) { + I *line2 = u[p[k]]; + I fact = line2[i] / pivot; + for(int j = i + 1; j < dim; j++) line2[j] -= fact * line1[j]; + } + } + } + return sig; +} + +/* compute the sign of a determinant using a floating-point LU-decomposition + and an a posteriori interval validation; the meaning of the answer is the + same as previously */ +int det_sign_algo2(const matrix<double> &a) { + int dim = a.get_dim(); + vector<int> p(dim); + for(int i = 0; i < dim; i++) p[i] = i; + int sig = 1; + matrix<double> lui(dim); + { + // computation of L and U + matrix<double> lu(dim); + lu.assign(a); + for(int i = 0; i < dim; i++) { + // partial pivoting + { + int pivot = i; + double max = std::abs(lu[p[i]][i]); + for(int j = i + 1; j < dim; j++) { + double m = std::abs(lu[p[j]][i]); + if (m > max) { max = m; pivot = j; } + } + if (max == 0) return 0; + if (pivot != i) { + sig = -sig; + int tmp = p[i]; + p[i] = p[pivot]; + p[pivot] = tmp; + } + } + // L[?,i] and U[i,?] + { + double *line1 = lu[p[i]]; + double pivot = line1[i]; + if (pivot < 0) sig = -sig; + for(int k = i + 1; k < dim; k++) { + double *line2 = lu[p[k]]; + double fact = line2[i] / pivot; + line2[i] = fact; + for(int j = i + 1; j < dim; j++) line2[j] -= line1[j] * fact; + } + } + } + + // computation of approximate inverses: Li and Ui + for(int j = 0; j < dim; j++) { + for(int i = j + 1; i < dim; i++) { + double *line = lu[p[i]]; + double s = - line[j]; + for(int k = j + 1; k < i; k++) s -= line[k] * lui[k][j]; + lui[i][j] = s; + } + lui[j][j] = 1 / lu[p[j]][j]; + for(int i = j - 1; i >= 0; i--) { + double *line = lu[p[i]]; + double s = 0; + for(int k = i + 1; k <= j; k++) s -= line[k] * lui[k][j]; + lui[i][j] = s / line[i]; + } + } + } + + // norm of PAUiLi-I computed with intervals + { + I_dbl::traits_type::rounding rnd; + typedef boost::numeric::interval_lib::unprotect<I_dbl>::type I; + vector<I> m1(dim); + vector<I> m2(dim); + for(int i = 0; i < dim; i++) { + for(int j = 0; j < dim; j++) m1[j] = 0; + const double *l1 = a[p[i]]; + for(int j = 0; j < dim; j++) { + double v = l1[j]; // PA[i,j] + double *l2 = lui[j]; // Ui[j,?] + for(int k = j; k < dim; k++) { + using boost::numeric::interval_lib::mul; + m1[k] += mul<I>(v, l2[k]); // PAUi[i,k] + } + } + for(int j = 0; j < dim; j++) m2[j] = m1[j]; // PAUi[i,j] * Li[j,j] + for(int j = 1; j < dim; j++) { + const I &v = m1[j]; // PAUi[i,j] + double *l2 = lui[j]; // Li[j,?] + for(int k = 0; k < j; k++) + m2[k] += v * l2[k]; // PAUiLi[i,k] + } + m2[i] -= 1; // PAUiLi-I + double ss = 0; + for(int i = 0; i < dim; i++) ss = rnd.add_up(ss, norm(m2[i])); + if (ss >= 1) return 0; + } + } + return sig; +} + +int main() { + int dim = 20; + matrix<double> m(dim); + for(int i = 0; i < dim; i++) for(int j = 0; j < dim; j++) + m[i][j] = /*1 / (i-j-0.001)*/ cos(1+i*sin(1 + j)) /*1./(1+i+j)*/; + + // compute the sign of the determinant of a "strange" matrix with the two + // algorithms, the first should fail and the second succeed + std::cout << det_sign_algo1(m) << " " << det_sign_algo2(m) << std::endl; +} diff --git a/src/boost/libs/numeric/interval/examples/findroot_demo.cpp b/src/boost/libs/numeric/interval/examples/findroot_demo.cpp new file mode 100644 index 000000000..f5330a70b --- /dev/null +++ b/src/boost/libs/numeric/interval/examples/findroot_demo.cpp @@ -0,0 +1,171 @@ +/* Boost example/findroot_demo.cpp + * find zero points of some function by dichotomy + * + * Copyright 2000 Jens Maurer + * Copyright 2002-2003 Guillaume Melquiond + * + * 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) + * + * The idea and the 2D function are based on RVInterval, + * which contains the following copyright notice: + + This file is copyrighted 1996 by Ronald Van Iwaarden. + + Permission is hereby granted, without written agreement and + without license or royalty fees, to use, copy, modify, and + distribute this software and its documentation for any + purpose, subject to the following conditions: + + The above license notice and this permission notice shall + appear in all copies or substantial portions of this software. + + The name "RVInterval" cannot be used for any modified form of + this software that does not originate from the authors. + Nevertheless, the name "RVInterval" may and should be used to + designate the optimization software implemented and described + in this package, even if embedded in any other system, as long + as any portion of this code remains. + + The authors specifically disclaim any warranties, including, + but not limited to, the implied warranties of merchantability + and fitness for a particular purpose. The software provided + hereunder is on an "as is" basis, and the authors have no + obligation to provide maintenance, support, updates, + enhancements, or modifications. In no event shall the authors + be liable to any party for direct, indirect, special, + incidental, or consequential damages arising out of the use of + this software and its documentation. +*/ + +#include <boost/numeric/interval.hpp> // must be first for <limits> workaround +#include <boost/numeric/interval/io.hpp> +#include <list> +#include <deque> +#include <vector> +#include <fstream> +#include <iostream> + + +template<class T> +struct test_func2d +{ + T operator()(T x, T y) const + { + return sin(x)*cos(y) - exp(x*y)/45.0 * (pow(x+y, 2)+100.0) - + cos(sin(y))*y/4.0; + } +}; + +template <class T> +struct test_func1d +{ + T operator()(T x) const + { + return sin(x)/(x*x+1.0); + } +}; + +template<class T> +struct test_func1d_2 +{ + T operator()(T x) const + { + using std::sqrt; + return sqrt(x*x-1.0); + } +}; + +template<class Function, class I> +void find_zeros(std::ostream & os, Function f, I searchrange) +{ + std::list<I> l, done; + l.push_back(searchrange); + while(!l.empty()) { + I range = l.front(); + l.pop_front(); + I val = f(range); + if (zero_in(val)) { + if(width(range) < 1e-6) { + os << range << '\n'; + continue; + } + // there's still a solution hidden somewhere + std::pair<I,I> p = bisect(range); + l.push_back(p.first); + l.push_back(p.second); + } + } +} + +template<class T> +std::ostream &operator<<(std::ostream &os, const std::pair<T, T> &x) { + os << "(" << x.first << ", " << x.second << ")"; + return os; +} + +template<class T, class Policies> +std::ostream &operator<<(std::ostream &os, + const boost::numeric::interval<T, Policies> &x) { + os << "[" << x.lower() << ", " << x.upper() << "]"; + return os; +} + +static const double epsilon = 5e-3; + +template<class Function, class I> +void find_zeros(std::ostream & os, Function f, I rx, I ry) +{ + typedef std::pair<I, I> rectangle; + typedef std::deque<rectangle> container; + container l, done; + // l.reserve(50); + l.push_back(std::make_pair(rx, ry)); + for(int i = 1; !l.empty(); ++i) { + rectangle rect = l.front(); + l.pop_front(); + I val = f(rect.first, rect.second); + if (zero_in(val)) { + if(width(rect.first) < epsilon && width(rect.second) < epsilon) { + os << median(rect.first) << " " << median(rect.second) << " " + << lower(rect.first) << " " << upper(rect.first) << " " + << lower(rect.second) << " " << upper(rect.second) + << '\n'; + } else { + if(width(rect.first) > width(rect.second)) { + std::pair<I,I> p = bisect(rect.first); + l.push_back(std::make_pair(p.first, rect.second)); + l.push_back(std::make_pair(p.second, rect.second)); + } else { + std::pair<I,I> p = bisect(rect.second); + l.push_back(std::make_pair(rect.first, p.first)); + l.push_back(std::make_pair(rect.first, p.second)); + } + } + } + if(i % 10000 == 0) + std::cerr << "\rIteration " << i << ", l.size() = " << l.size(); + } + std::cerr << '\n'; +} + +int main() +{ + using namespace boost; + using namespace numeric; + using namespace interval_lib; + + typedef interval<double, + policies<save_state<rounded_transc_opp<double> >, + checking_base<double> > > I; + + std::cout << "Zero points of sin(x)/(x*x+1)\n"; + find_zeros(std::cout, test_func1d<I>(), I(-11, 10)); + std::cout << "Zero points of sqrt(x*x-1)\n"; + find_zeros(std::cout, test_func1d_2<I>(), I(-5, 6)); + std::cout << "Zero points of Van Iwaarden's 2D function\n"; + std::ofstream f("func2d.data"); + find_zeros(f, test_func2d<I>(), I(-20, 20), I(-20, 20)); + std::cout << "Use gnuplot, command 'plot \"func2d.data\" with dots' to plot\n"; +} diff --git a/src/boost/libs/numeric/interval/examples/horner.cpp b/src/boost/libs/numeric/interval/examples/horner.cpp new file mode 100644 index 000000000..dfae28966 --- /dev/null +++ b/src/boost/libs/numeric/interval/examples/horner.cpp @@ -0,0 +1,47 @@ +/* Boost example/horner.cpp + * example of unprotecting rounding for a whole function computation + * + * Copyright 2002-2003 Guillaume Melquiond + * + * 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) + */ + +#include <boost/numeric/interval.hpp> +#include <iostream> + +// I is an interval class, the polynom is a simple array +template<class I> +I horner(const I& x, const I p[], int n) { + + // initialize and restore the rounding mode + typename I::traits_type::rounding rnd; + + // define the unprotected version of the interval type + typedef typename boost::numeric::interval_lib::unprotect<I>::type R; + + const R& a = x; + R y = p[n - 1]; + for(int i = n - 2; i >= 0; i--) { + y = y * a + (const R&)(p[i]); + } + return y; + + // restore the rounding mode with the destruction of rnd +} + +template<class T, class Policies> +std::ostream &operator<<(std::ostream &os, + const boost::numeric::interval<T, Policies> &x) { + os << "[" << x.lower() << ", " << x.upper() << "]"; + return os; +} + +int main() { + typedef boost::numeric::interval<double> I; + I p[3] = { -1.0, 0, 1.0 }; + I x = 1.0; + std::cout << horner(x, p, 3) << std::endl; + return 0; +} diff --git a/src/boost/libs/numeric/interval/examples/io.cpp b/src/boost/libs/numeric/interval/examples/io.cpp new file mode 100644 index 000000000..de4df4997 --- /dev/null +++ b/src/boost/libs/numeric/interval/examples/io.cpp @@ -0,0 +1,172 @@ +/* Boost examples/io.cpp + * show some exampleso of i/o operators + * thanks to all the people who commented on this point, particularly on + * the Boost mailing-list + * + * Copyright 2003 Guillaume Melquiond + * + * 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) + */ + +#include <boost/numeric/interval.hpp> +#include <boost/io/ios_state.hpp> +#include <cmath> +#include <cassert> + +namespace io_std { + +template<class T, class Policies, class CharType, class CharTraits> +std::basic_ostream<CharType, CharTraits> &operator<< + (std::basic_ostream<CharType, CharTraits> &stream, + const boost::numeric::interval<T, Policies> &value) +{ + if (empty(value)) { + return stream << "[]"; + } else { + return stream << '[' << lower(value) << ',' << upper(value) << ']'; + } +} + +} // namespace io_std + +namespace io_sngl { + +template<class T, class Policies, class CharType, class CharTraits> +std::basic_ostream<CharType, CharTraits> &operator<< + (std::basic_ostream<CharType, CharTraits> &stream, + const boost::numeric::interval<T, Policies> &value) +{ + if (empty(value)) { + return stream << "[]"; + } else if (singleton(value)) { + return stream << '[' << lower(value) << ']'; + } else { + return stream << '[' << lower(value) << ',' << upper(value) << ']'; + } +} + +} // namespace io_sngl + +namespace io_wdth { + +template<class T, class Policies, class CharType, class CharTraits> +std::basic_ostream<CharType, CharTraits> &operator<< + (std::basic_ostream<CharType, CharTraits> &stream, + const boost::numeric::interval<T, Policies> &value) +{ + if (empty(value)) { + return stream << "nothing"; + } else { + return stream << median(value) << " ± " << width(value) / 2; + } +} + +} // namespace io_wdth + +namespace io_prec { + +template<class T, class Policies, class CharType, class CharTraits> +std::basic_ostream<CharType, CharTraits> &operator<< + (std::basic_ostream<CharType, CharTraits> &stream, + const boost::numeric::interval<T, Policies> &value) +{ + if (empty(value)) { + return stream << "nothing"; + } else if (singleton(value)) { + boost::io::ios_precision_saver state(stream, std::numeric_limits<T>::digits10); + return stream << lower(value); + } else if (zero_in(value)) { + return stream << "0~"; + } else { + const T rel = width(value) / norm(value); + int range = - (int)std::log10(rel); + boost::io::ios_precision_saver state(stream, range); + return stream << median(value); + } +} + +} // namespace io_prec + +namespace io_wide { + +template<class T, class Policies, class CharType, class CharTraits> +std::basic_ostream<CharType, CharTraits> &operator<< + (std::basic_ostream<CharType, CharTraits> &stream, + const boost::numeric::interval<T, Policies> &value) +{ + if (empty(value)) { + return stream << "nothing"; + } else if (singleton(value)) { + boost::io::ios_precision_saver state(stream, std::numeric_limits<T>::digits10); + return stream << lower(value); + } else if (zero_in(value)) { + return stream << "0~"; + } else { + std::streamsize p = stream.precision(); + // FIXME poor man's power of 10, only up to 1E-15 + p = (p > 15) ? 15 : p - 1; + double eps = 1.0; for(; p > 0; --p) { eps /= 10; } + T eps2 = static_cast<T>(eps / 2) * norm(value); + boost::numeric::interval<T, Policies> r = widen(value, eps2); + return stream << '[' << lower(r) << ',' << upper(r) << ']'; + } +} + +} // namespace io_wide + +template<class T, class Policies, class CharType, class CharTraits> inline +std::basic_istream<CharType, CharTraits> &operator>> + (std::basic_istream<CharType, CharTraits> &stream, + boost::numeric::interval<T, Policies> &value) +{ + T l, u; + char c = 0; + stream >> c; + if (c == '[') { + stream >> l >> c; + if (c == ',') stream >> u >> c; else u = l; + if (c != ']') stream.setstate(stream.failbit); + } else { + stream.putback(c); + stream >> l; + u = l; + } + if (stream) + value.assign(l, u); + else + value = boost::numeric::interval<T, Policies>::empty(); + return stream; +} + +// Test program + +#include <iostream> + +int main() +{ + using namespace boost; + using namespace numeric; + using namespace interval_lib; + + typedef interval<double, + policies<rounded_math<double>, + checking_base<double> > > I; + + I tab[] = { I::empty(), I(1,1), I(1,2), I(-1,1), I(12.34,12.35), + I(1234.56,1234.57), I(123456.78, 123456.79), I::empty() }; + unsigned int len = sizeof(tab) / sizeof(I); + std::cout << "Enter an interval: (it will be the last shown)\n"; + std::cin >> tab[len - 1]; + + for(unsigned int i = 0; i < len; ++i) { + { using namespace io_std; std::cout << tab[i] << '\n'; } + { using namespace io_sngl; std::cout << tab[i] << '\n'; } + { using namespace io_wdth; std::cout << tab[i] << '\n'; } + { using namespace io_prec; std::cout << tab[i] << '\n'; } + { using namespace io_wide; std::cout << tab[i] << '\n'; } + std::cout << '\n'; + } + +} diff --git a/src/boost/libs/numeric/interval/examples/newton-raphson.cpp b/src/boost/libs/numeric/interval/examples/newton-raphson.cpp new file mode 100644 index 000000000..7936c2d4c --- /dev/null +++ b/src/boost/libs/numeric/interval/examples/newton-raphson.cpp @@ -0,0 +1,146 @@ +/* Boost example/newton-raphson.cpp + * Newton iteration for intervals + * + * Copyright 2003 Guillaume Melquiond + * + * 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) + */ + +#include <boost/numeric/interval.hpp> +#include <vector> +#include <algorithm> +#include <utility> +#include <iostream> +#include <iomanip> + +template <class I> I f(const I& x) +{ return x * (x - 1.) * (x - 2.) * (x - 3.) * (x - 4.); } +template <class I> I f_diff(const I& x) +{ return (((5. * x - 40.) * x + 105.) * x - 100.) * x + 24.; } + +static const double max_width = 1e-10; +static const double alpha = 0.75; + +using namespace boost; +using namespace numeric; +using namespace interval_lib; + +// First method: no empty intervals + +typedef interval<double> I1_aux; +typedef unprotect<I1_aux>::type I1; + +std::vector<I1> newton_raphson(const I1& xs) { + std::vector<I1> l, res; + I1 vf, vd, x, x1, x2; + l.push_back(xs); + while (!l.empty()) { + x = l.back(); + l.pop_back(); + bool x2_used; + double xx = median(x); + vf = f<I1>(xx); + vd = f_diff<I1>(x); + if (zero_in(vf) && zero_in(vd)) { + x1 = I1::whole(); + x2_used = false; + } else { + x1 = xx - division_part1(vf, vd, x2_used); + if (x2_used) x2 = xx - division_part2(vf, vd); + } + if (overlap(x1, x)) x1 = intersect(x, x1); + else if (x2_used) { x1 = x2; x2_used = false; } + else continue; + if (x2_used) { + if (overlap(x2, x)) x2 = intersect(x, x2); + else x2_used = false; + } + if (x2_used && width(x2) > width(x1)) std::swap(x1, x2); + if (!zero_in(f(x1))) { + if (x2_used) { x1 = x2; x2_used = false; } + else continue; + } + if (width(x1) < max_width) res.push_back(x1); + else if (width(x1) > alpha * width(x)) { + std::pair<I1, I1> p = bisect(x); + if (zero_in(f(p.first))) l.push_back(p.first); + x2 = p.second; + x2_used = true; + } else l.push_back(x1); + if (x2_used && zero_in(f(x2))) { + if (width(x2) < max_width) res.push_back(x2); + else l.push_back(x2); + } + } + return res; +} + +// Second method: with empty intervals + +typedef change_checking<I1_aux, checking_no_nan<double> >::type I2_aux; +typedef unprotect<I2_aux>::type I2; + +std::vector<I2> newton_raphson(const I2& xs) { + std::vector<I2> l, res; + I2 vf, vd, x, x1, x2; + l.push_back(xs); + while (!l.empty()) { + x = l.back(); + l.pop_back(); + double xx = median(x); + vf = f<I2>(xx); + vd = f_diff<I2>(x); + if (zero_in(vf) && zero_in(vd)) { + x1 = x; + x2 = I2::empty(); + } else { + bool x2_used; + x1 = intersect(x, xx - division_part1(vf, vd, x2_used)); + x2 = intersect(x, xx - division_part2(vf, vd, x2_used)); + } + if (width(x2) > width(x1)) std::swap(x1, x2); + if (empty(x1) || !zero_in(f(x1))) { + if (!empty(x2)) { x1 = x2; x2 = I2::empty(); } + else continue; + } + if (width(x1) < max_width) res.push_back(x1); + else if (width(x1) > alpha * width(x)) { + std::pair<I2, I2> p = bisect(x); + if (zero_in(f(p.first))) l.push_back(p.first); + x2 = p.second; + } else l.push_back(x1); + if (!empty(x2) && zero_in(f(x2))) { + if (width(x2) < max_width) res.push_back(x2); + else l.push_back(x2); + } + } + return res; +} + +template<class T, class Policies> +std::ostream &operator<<(std::ostream &os, + const boost::numeric::interval<T, Policies> &x) { + os << "[" << x.lower() << ", " << x.upper() << "]"; + return os; +} + +int main() { + { + I1_aux::traits_type::rounding rnd; + std::vector<I1> res = newton_raphson(I1(-1, 5.1)); + std::cout << "Results: " << std::endl << std::setprecision(12); + for(std::vector<I1>::const_iterator i = res.begin(); i != res.end(); ++i) + std::cout << " " << *i << std::endl; + std::cout << std::endl; + } + { + I2_aux::traits_type::rounding rnd; + std::vector<I2> res = newton_raphson(I2(-1, 5.1)); + std::cout << "Results: " << std::endl << std::setprecision(12); + for(std::vector<I2>::const_iterator i = res.begin(); i != res.end(); ++i) + std::cout << " " << *i << std::endl; + std::cout << std::endl; + } +} diff --git a/src/boost/libs/numeric/interval/examples/rational.cpp b/src/boost/libs/numeric/interval/examples/rational.cpp new file mode 100644 index 000000000..937171df9 --- /dev/null +++ b/src/boost/libs/numeric/interval/examples/rational.cpp @@ -0,0 +1,43 @@ +/* Boost example/rational.cpp + * example program of how to use interval< rational<> > + * + * Copyright 2002-2003 Guillaume Melquiond, Sylvain Pion + * + * 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) + */ + +// it would have been enough to only include: +// <boost/numeric/interval.hpp> +// but it's a bit overkill to include processor intrinsics +// and transcendental functions, so we do it by ourselves + +#include <boost/numeric/interval/interval.hpp> // base class +#include <boost/numeric/interval/rounded_arith.hpp> // default arithmetic rounding policy +#include <boost/numeric/interval/checking.hpp> // default checking policy +#include <boost/numeric/interval/arith.hpp> // += *= -= etc +#include <boost/numeric/interval/policies.hpp> // default policy + +#include <boost/rational.hpp> +#include <iostream> + +typedef boost::rational<int> Rat; +typedef boost::numeric::interval<Rat> Interval; + +std::ostream& operator<<(std::ostream& os, const Interval& r) { + os << "[" << r.lower() << "," << r.upper() << "]"; + return os; +} + +int main() { + Rat p(2, 3), q(3, 4); + Interval z(4, 5); + Interval a(p, q); + a += z; + z *= q; + a -= p; + a /= q; + std::cout << z << std::endl; + std::cout << a << std::endl; +} diff --git a/src/boost/libs/numeric/interval/examples/transc.cpp b/src/boost/libs/numeric/interval/examples/transc.cpp new file mode 100644 index 000000000..2036f9832 --- /dev/null +++ b/src/boost/libs/numeric/interval/examples/transc.cpp @@ -0,0 +1,90 @@ +/* Boost example/transc.cpp + * how to use an external library (GMP/MPFR in this case) in order to + * get correct transcendental functions on intervals + * + * Copyright 2003 Guillaume Melquiond + * + * 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) + */ + +#include <boost/numeric/interval.hpp> +//extern "C" { +#include <gmp.h> +#include <mpfr.h> +//} +#include <iostream> + +struct full_rounding: + boost::numeric::interval_lib::rounded_arith_opp<double> +{ +private: + typedef int mpfr_func(mpfr_t, const __mpfr_struct*, mp_rnd_t); + double invoke_mpfr(double x, mpfr_func f, mp_rnd_t r) { + mpfr_t xx; + mpfr_init_set_d(xx, x, GMP_RNDN); + f(xx, xx, r); + double res = mpfr_get_d(xx, r); + mpfr_clear(xx); + return res; + } +public: +# define GENR_FUNC(name) \ + double name##_down(double x) { return invoke_mpfr(x, mpfr_##name, GMP_RNDD); } \ + double name##_up (double x) { return invoke_mpfr(x, mpfr_##name, GMP_RNDU); } + GENR_FUNC(exp) + GENR_FUNC(log) + GENR_FUNC(sin) + GENR_FUNC(cos) + GENR_FUNC(tan) + GENR_FUNC(asin) + GENR_FUNC(acos) + GENR_FUNC(atan) + GENR_FUNC(sinh) + GENR_FUNC(cosh) + GENR_FUNC(tanh) + GENR_FUNC(asinh) + GENR_FUNC(acosh) + GENR_FUNC(atanh) +}; + +namespace dummy { + using namespace boost; + using namespace numeric; + using namespace interval_lib; + typedef save_state<full_rounding> R; + typedef checking_strict<double> P; + typedef interval<double, policies<R, P> > I; +}; + +typedef dummy::I I; + +template<class os_t> +os_t& operator<<(os_t &os, const I &a) { + os << '[' << a.lower() << ',' << a.upper() << ']'; + return os; +} + +int main() { + I x(0.5, 2.5); + std::cout << "x = " << x << std::endl; + std::cout.precision(16); +# define GENR_TEST(name) \ + std::cout << #name "(x) = " << name(x) << std::endl + GENR_TEST(exp); + GENR_TEST(log); + GENR_TEST(sin); + GENR_TEST(cos); + GENR_TEST(tan); + GENR_TEST(asin); + GENR_TEST(acos); + GENR_TEST(atan); + GENR_TEST(sinh); + GENR_TEST(cosh); + GENR_TEST(tanh); + GENR_TEST(asinh); + GENR_TEST(acosh); + GENR_TEST(atanh); + return 0; +} diff --git a/src/boost/libs/numeric/interval/index.html b/src/boost/libs/numeric/interval/index.html new file mode 100644 index 000000000..30dbacea2 --- /dev/null +++ b/src/boost/libs/numeric/interval/index.html @@ -0,0 +1,13 @@ +<html> +<head> +<meta http-equiv="refresh" content="0; URL=doc/interval.htm"> +</head> +<body> +Automatic redirection failed, please go to +<a href="doc/interval.htm">doc/interval.htm</a>. <hr> +<p>© Copyright Beman Dawes, 2001</p> +<p>Distributed under the Boost Software License, Version 1.0. (See accompanying +file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy +at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p> +</body> +</html> diff --git a/src/boost/libs/numeric/interval/meta/libraries.json b/src/boost/libs/numeric/interval/meta/libraries.json new file mode 100644 index 000000000..d3fa6cfc2 --- /dev/null +++ b/src/boost/libs/numeric/interval/meta/libraries.json @@ -0,0 +1,19 @@ +{ + "key": "numeric/interval", + "name": "Interval", + "authors": [ + "Guillaume Melquiond", + "Hervé Brönnimann", + "Sylvain Pion" + ], + "description": "Extends the usual arithmetic functions to mathematical intervals.", + "documentation": "doc/interval.htm", + "category": [ + "Math" + ], + "maintainers": [ + "Sylvain Pion <Sylvain.Pion -at- sophia.inria.fr>", + "Herve Bronnimann <hbr -at- poly.edu>", + "Guillaume Melquiond <guillaume.melquiond -at- ens-lyon.fr>" + ] +} diff --git a/src/boost/libs/numeric/interval/test/Jamfile.v2 b/src/boost/libs/numeric/interval/test/Jamfile.v2 new file mode 100644 index 000000000..0afd0edbc --- /dev/null +++ b/src/boost/libs/numeric/interval/test/Jamfile.v2 @@ -0,0 +1,55 @@ +# Boost Interval Library test Jamfile +# +# Copyright 2003 Guillaume Melquiond +# +# 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) + +project + : + source-location $(BOOST_ROOT) + : + requirements + # Enable dynamic rounding on Tru64 (Alpha CPU). + <toolset>hp_cxx,<os>OSF:<cflags>"-fprm d" + <toolset>gcc,<os>OSF:<cflags>-mfp-rounding-mode=d + <toolset>gcc:<cxxflags>-frounding-math + <toolset>msvc:<cxxflags>/fp\:strict + ; + +# bring in rules for testing +import testing ; + +{ + test-suite numeric/interval : + [ compile libs/numeric/interval/test/integer.cpp ] + + [ run libs/numeric/interval/test/add.cpp ] + [ run libs/numeric/interval/test/det.cpp ] + [ run libs/numeric/interval/test/fmod.cpp ] + [ run libs/numeric/interval/test/msvc_x64_flags.cpp : : : <build>no <toolset>msvc:<build>yes ] + [ run libs/numeric/interval/test/mul.cpp ] + [ run libs/numeric/interval/test/overflow.cpp ] + [ run libs/numeric/interval/test/pi.cpp ] + [ run libs/numeric/interval/test/pow.cpp ] + + [ run libs/numeric/interval/test/cmp.cpp + ../../../test/build//boost_test_exec_monitor/<link>static ] + [ run libs/numeric/interval/test/cmp_exn.cpp + ../../../test/build//boost_test_exec_monitor/<link>static ] + [ run libs/numeric/interval/test/cmp_exp.cpp + ../../../test/build//boost_test_exec_monitor/<link>static ] + [ run libs/numeric/interval/test/cmp_lex.cpp + ../../../test/build//boost_test_exec_monitor/<link>static ] + [ run libs/numeric/interval/test/cmp_set.cpp + ../../../test/build//boost_test_exec_monitor/<link>static ] + # https://github.com/boostorg/interval/issues/15 + # [ run libs/numeric/interval/test/cmp_tribool.cpp + # ../../../test/build//boost_test_exec_monitor/<link>static ] + [ run libs/numeric/interval/test/test_float.cpp + ../../../test/build//boost_test_exec_monitor/<link>static + : : : <build>yes <toolset>msvc-10.0:<build>no ] + # https://github.com/boostorg/interval/issues/17 + ; +} diff --git a/src/boost/libs/numeric/interval/test/add.cpp b/src/boost/libs/numeric/interval/test/add.cpp new file mode 100644 index 000000000..73d502b6b --- /dev/null +++ b/src/boost/libs/numeric/interval/test/add.cpp @@ -0,0 +1,243 @@ +/* Boost test/add.cpp + * test with symbolic operations if the addition algorithm is correct + * + * Copyright 2002-2003 Guillaume Melquiond + * + * 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) + */ + +#include <boost/numeric/interval/interval.hpp> +#include <boost/numeric/interval/arith.hpp> +#include <boost/numeric/interval/rounding.hpp> +#include <boost/numeric/interval/rounded_arith.hpp> +#include <boost/numeric/interval/utility.hpp> +#include <boost/numeric/interval/policies.hpp> +#include <boost/test/minimal.hpp> +#include "bugs.hpp" + +typedef enum { EXPR_VAR, EXPR_NEG, EXPR_UP, EXPR_DOWN, EXPR_ADD, EXPR_SUB } e_type; + +struct expr; +struct pexpr { + expr *ptr; + expr* operator->() { return ptr; } + pexpr(expr *p = NULL): ptr(p) { } +}; + +struct expr { + e_type type; + int var; + pexpr e; + pexpr e1, e2; +}; + +pexpr var(int v) { + pexpr e = new expr; + e->type = EXPR_VAR; + e->var = v; + return e; +} + +pexpr operator+(pexpr, pexpr); +pexpr operator-(pexpr, pexpr); +pexpr operator-(pexpr); + +pexpr operator+(pexpr a, pexpr b) { + if (a->type == EXPR_NEG) return b - a->e; + if (b->type == EXPR_NEG) return a - b->e; + if (a->type == EXPR_VAR && b->type == EXPR_VAR && a->var > b->var) return b + a; + pexpr c = new expr; + c->type = EXPR_ADD; + c->e1 = a; + c->e2 = b; + return c; +} + +pexpr operator-(pexpr a, pexpr b) { + if (b->type == EXPR_NEG) return a + b->e; + pexpr c = new expr; + c->type = EXPR_SUB; + c->e1 = a; + c->e2 = b; + return c; +} + +pexpr down(pexpr a) { + pexpr e = new expr; + e->type = EXPR_DOWN; + e->e = a; + return e; +} + +pexpr up(pexpr a) { + pexpr e = new expr; + e->type = EXPR_UP; + e->e = a; + return e; +} + +pexpr operator-(pexpr a) { + if (a->type == EXPR_NEG) return a->e; + if (a->type == EXPR_UP) return down(-a->e); + if (a->type == EXPR_DOWN) return up(-a->e); + if (a->type == EXPR_SUB) return a->e2 - a->e1; + if (a->type == EXPR_ADD) return -a->e1 - a->e2; + pexpr e = new expr; + e->type = EXPR_NEG; + e->e = a; + return e; +} + +bool operator==(pexpr a, pexpr b) { + if (a->type != b->type) return false; + if (a->type == EXPR_VAR) return a->var == b->var; + if (a->type == EXPR_DOWN || a->type == EXPR_UP || a->type == EXPR_NEG) + return a->e == b->e; + return a->e1 == b->e1 && a->e2 == b->e2; +} + +bool operator<=(pexpr, pexpr) { return true; } + +namespace boost { +namespace numeric { +namespace interval_lib { + +template<> +struct rounding_control<pexpr> { + typedef enum { RND_U, RND_M, RND_D } rounding_mode; + static rounding_mode mode; + rounding_control() { mode = RND_M; } + void get_rounding_mode(rounding_mode& m) { m = mode; } + void set_rounding_mode(rounding_mode m) { mode = m; } + void upward() { mode = RND_U; } + void downward() { mode = RND_D; } + pexpr force_rounding(pexpr a) { + switch (mode) { + case RND_U: return up(a); + case RND_D: return down(a); + default: throw "Unset rounding mode"; + } + } +}; + +rounding_control<pexpr>::rounding_mode rounding_control<pexpr>::mode = RND_M; + +} // namespace interval_lib +} // namespace numeric +} // namespace boost + +template<class I> +bool test_neg() { + I a(var(0), var(1)); + return equal(-a, I(-var(1), -var(0))); +} + +template<class I> +bool test_add() { + I a(var(0), var(1)), b(var(2), var(3)); + return equal(a + b, I(down(var(0) + var(2)), up(var(1) + var(3)))); +} + +template<class I> +bool test_add1() { + I a(var(0), var(1)); + return equal(a + var(2), I(down(var(0) + var(2)), up(var(1) + var(2)))); +} + +template<class I> +bool test_add2() { + I a(var(0), var(1)); + return equal(var(2) + a, I(down(var(0) + var(2)), up(var(1) + var(2)))); +} + +template<class I> +bool test_sub() { + I a(var(0), var(1)), b(var(2), var(3)); + return equal(a - b, I(down(var(0) - var(3)), up(var(1) - var(2)))); +} + +template<class I> +bool test_sub1() { + I a(var(0), var(1)); + return equal(a - var(2), I(down(var(0) - var(2)), up(var(1) - var(2)))); +} + +template<class I> +bool test_sub2() { + I a(var(0), var(1)); + return equal(var(2) - a, I(down(var(2) - var(1)), up(var(2) - var(0)))); +} + +template<class I> +bool test_addeq() { + I a(var(0), var(1)), b(var(2), var(3)); + return equal(a += b, I(down(var(0) + var(2)), up(var(1) + var(3)))); +} + +template<class I> +bool test_addeq1() { + I a(var(0), var(1)); + return equal(a += var(2), I(down(var(0) + var(2)), up(var(1) + var(2)))); +} + +template<class I> +bool test_subeq() { + I a(var(0), var(1)), b(var(2), var(3)); + return equal(a -= b, I(down(var(0) - var(3)), up(var(1) - var(2)))); +} + +template<class I> +bool test_subeq1() { + I a(var(0), var(1)); + return equal(a -= var(2), I(down(var(0) - var(2)), up(var(1) - var(2)))); +} + +struct my_checking +{ + static pexpr pos_inf() { throw; } + static pexpr neg_inf() { throw; } + static pexpr nan() { throw; } + static bool is_nan(const pexpr&) { return false; } + static pexpr empty_lower() { throw; } + static pexpr empty_upper() { throw; } + static bool is_empty(const pexpr&, const pexpr&) { return false; } +}; + +template<class Rounding> +struct my_interval { +private: + typedef boost::numeric::interval_lib::save_state<Rounding> my_rounding; + typedef boost::numeric::interval_lib::policies<my_rounding, my_checking> my_policies; +public: + typedef boost::numeric::interval<pexpr, my_policies> type; +}; + +int test_main(int, char *[]) { + typedef my_interval<boost::numeric::interval_lib::rounded_arith_std<pexpr> >::type I1; + typedef my_interval<boost::numeric::interval_lib::rounded_arith_opp<pexpr> >::type I2; + BOOST_CHECK((test_neg<I1>())); + BOOST_CHECK((test_neg<I2>())); + BOOST_CHECK((test_add<I1>())); + BOOST_CHECK((test_add<I2>())); + BOOST_CHECK((test_add1<I1>())); + BOOST_CHECK((test_add1<I2>())); + BOOST_CHECK((test_add2<I1>())); + BOOST_CHECK((test_add2<I2>())); + BOOST_CHECK((test_sub<I1>())); + BOOST_CHECK((test_sub<I2>())); + BOOST_CHECK((test_sub1<I1>())); + BOOST_CHECK((test_sub1<I2>())); + BOOST_CHECK((test_sub2<I1>())); + BOOST_CHECK((test_sub2<I2>())); + BOOST_CHECK((test_addeq<I1>())); + BOOST_CHECK((test_addeq<I2>())); + BOOST_CHECK((test_addeq1<I1>())); + BOOST_CHECK((test_addeq1<I2>())); + BOOST_CHECK((test_subeq<I1>())); + BOOST_CHECK((test_subeq<I2>())); + BOOST_CHECK((test_subeq1<I1>())); + BOOST_CHECK((test_subeq1<I2>())); + return 0; +} diff --git a/src/boost/libs/numeric/interval/test/bugs.hpp b/src/boost/libs/numeric/interval/test/bugs.hpp new file mode 100644 index 000000000..52a995607 --- /dev/null +++ b/src/boost/libs/numeric/interval/test/bugs.hpp @@ -0,0 +1,43 @@ +/* Boost test/bugs.hpp + * Handles namespace resolution quirks in older compilers and braindead + * warnings [Herve, June 3rd 2003] + * + * Copyright 2002-2003 Hervé Brönnimann + * + * 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) + */ + +#include <boost/config.hpp> + +// Borland compiler complains about unused variables a bit easily and +// incorrectly + +#ifdef __BORLANDC__ +namespace detail { + + template <class T> inline void ignore_unused_variable_warning(const T&) { } + + inline void ignore_warnings() { +# ifdef BOOST_NUMERIC_INTERVAL_CONSTANTS_HPP + using namespace boost::numeric::interval_lib::constants; + ignore_unused_variable_warning( pi_f_l ); + ignore_unused_variable_warning( pi_f_u ); + ignore_unused_variable_warning( pi_d_l ); + ignore_unused_variable_warning( pi_d_u ); +# endif + } + +} +#endif + +// Some compilers are broken with respect to name resolution + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) || defined( __BORLANDC__) + +using namespace boost; +using namespace numeric; +using namespace interval_lib; + +#endif diff --git a/src/boost/libs/numeric/interval/test/cmp.cpp b/src/boost/libs/numeric/interval/test/cmp.cpp new file mode 100644 index 000000000..e3a12a3c8 --- /dev/null +++ b/src/boost/libs/numeric/interval/test/cmp.cpp @@ -0,0 +1,215 @@ +/* Boost test/cmp.cpp + * test standard comparison functions + * + * Copyright 2002-2003 Guillaume Melquiond + * + * 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) + */ + +#include "cmp_header.hpp" + +// comparisons between [1,2] and [3,4] + +static void test_12_34() { + const I a(1,2), b(3,4); + + BOOST_CHECK(a < b); + BOOST_CHECK(a <= b); + BOOST_CHECK(!(a > b)); + BOOST_CHECK(!(a >= b)); + + BOOST_CHECK(b > a); + BOOST_CHECK(b >= a); + BOOST_CHECK(!(b < a)); + BOOST_CHECK(!(b <= a)); + + BOOST_CHECK(!(a == b)); + BOOST_CHECK(a != b); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,3] and [2,4] + +static void test_13_24() { + const I a(1,3), b(2,4); + + BOOST_C_EXN(a < b); + BOOST_C_EXN(a <= b); + BOOST_C_EXN(a > b); + BOOST_C_EXN(a >= b); + + BOOST_C_EXN(b < a); + BOOST_C_EXN(b <= a); + BOOST_C_EXN(b > a); + BOOST_C_EXN(b >= a); + + BOOST_C_EXN(a == b); + BOOST_C_EXN(a != b); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and [2,3] + +static void test_12_23() { + const I a(1,2), b(2,3); + + BOOST_C_EXN(a < b); + BOOST_CHECK(a <= b); + BOOST_CHECK(!(a > b)); + BOOST_C_EXN(a >= b); + + BOOST_CHECK(!(b < a)); + BOOST_C_EXN(b <= a); + BOOST_C_EXN(b > a); + BOOST_CHECK(b >= a); + + BOOST_C_EXN(a == b); + BOOST_C_EXN(a != b); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and 0 + +static void test_12_0() { + const I a(1,2); + const int b = 0; + + BOOST_CHECK(!(a < b)); + BOOST_CHECK(!(a <= b)); + BOOST_CHECK(a > b); + BOOST_CHECK(a >= b); + + BOOST_CHECK(!(a == b)); + BOOST_CHECK(a != b); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and 1 + +static void test_12_1() { + const I a(1,2); + const int b = 1; + + BOOST_CHECK(!(a < b)); + BOOST_C_EXN(a <= b); + BOOST_C_EXN(a > b); + BOOST_CHECK(a >= b); + + BOOST_C_EXN(a == b); + BOOST_C_EXN(a != b); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and 2 + +static void test_12_2() { + const I a(1,2); + const int b = 2; + + BOOST_C_EXN(a < b); + BOOST_CHECK(a <= b); + BOOST_CHECK(!(a > b)); + BOOST_C_EXN(a >= b); + + BOOST_C_EXN(a == b); + BOOST_C_EXN(a != b); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and 3 + +static void test_12_3() { + const I a(1,2); + const int b = 3; + + BOOST_CHECK(a < b); + BOOST_CHECK(a <= b); + BOOST_CHECK(!(a > b)); + BOOST_CHECK(!(a >= b)); + + BOOST_CHECK(!(a == b)); + BOOST_CHECK(a != b); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and [1,2] + +static void test_12_12() { + const I a(1,2), b(1,2); + BOOST_C_EXN(a == b); + BOOST_C_EXN(a != b); +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,1] and [1,1] + +static void test_11_11() { + const I a(1,1), b(1,1); + BOOST_CHECK(a == b); + BOOST_CHECK(!(a != b)); +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,1] and 1 + +static void test_11_1() { + const I a(1,1); + const int b = 1; + BOOST_CHECK(a == b); + BOOST_CHECK(!(a != b)); +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +int test_main(int, char *[]) { + test_12_34(); + test_13_24(); + test_12_23(); + test_12_0(); + test_12_1(); + test_12_2(); + test_12_3(); + test_12_12(); + test_11_11(); + test_11_1(); + + return 0; +} diff --git a/src/boost/libs/numeric/interval/test/cmp_exn.cpp b/src/boost/libs/numeric/interval/test/cmp_exn.cpp new file mode 100644 index 000000000..7f6cc0303 --- /dev/null +++ b/src/boost/libs/numeric/interval/test/cmp_exn.cpp @@ -0,0 +1,230 @@ +/* Boost test/cmp_exn.cpp + * test policies with respect to exception throwing + * + * Copyright 2004 Guillaume Melquiond + * + * 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) + */ + +#include <boost/numeric/interval/interval.hpp> +#include <boost/numeric/interval/checking.hpp> +#include <boost/numeric/interval/compare.hpp> +#include <boost/numeric/interval/policies.hpp> +#include <boost/numeric/interval/compare/tribool.hpp> +#include <boost/test/test_tools.hpp> + +struct my_checking +{ + static int nan() { return -1; } + static bool is_nan(int x) { return x < 0; } + static int empty_lower() { return -1; } + static int empty_upper() { return -1; } + static bool is_empty(int l, int u) { return l == -1 && u == -1; } +}; + +struct empty_class {}; + +typedef boost::numeric::interval_lib::policies< empty_class, my_checking > + my_policies; + +typedef boost::numeric::interval<int, my_policies> I; + +#define BOOST_C_EXN(e) \ + BOOST_CHECK_THROW(e, boost::numeric::interval_lib::comparison_error) + +static void test_cer() +{ + I const a(I::empty()), b(1,2); + int const c = 0, d = my_checking::nan(); + using namespace boost::numeric::interval_lib::compare::certain; + + BOOST_C_EXN(a < b); + BOOST_C_EXN(a <= b); + BOOST_C_EXN(a > b); + BOOST_C_EXN(a >= b); + BOOST_C_EXN(a == b); + BOOST_C_EXN(a != b); + BOOST_C_EXN(b < a); + BOOST_C_EXN(b <= a); + BOOST_C_EXN(b > a); + BOOST_C_EXN(b >= a); + BOOST_C_EXN(b == a); + BOOST_C_EXN(b != a); + + BOOST_C_EXN(a < c); + BOOST_C_EXN(a <= c); + BOOST_C_EXN(a > c); + BOOST_C_EXN(a >= c); + BOOST_C_EXN(a == c); + BOOST_C_EXN(a != c); + BOOST_C_EXN(b < d); + BOOST_C_EXN(b <= d); + BOOST_C_EXN(b > d); + BOOST_C_EXN(b >= d); + BOOST_C_EXN(b == d); + BOOST_C_EXN(b != d); +} + +static void test_def() +{ + I const a(I::empty()), b(1,2); + int const c = 0, d = my_checking::nan(); + + BOOST_C_EXN(a < b); + BOOST_C_EXN(a <= b); + BOOST_C_EXN(a > b); + BOOST_C_EXN(a >= b); + BOOST_C_EXN(a == b); + BOOST_C_EXN(a != b); + BOOST_C_EXN(b < a); + BOOST_C_EXN(b <= a); + BOOST_C_EXN(b > a); + BOOST_C_EXN(b >= a); + BOOST_C_EXN(b == a); + BOOST_C_EXN(b != a); + + BOOST_C_EXN(a < c); + BOOST_C_EXN(a <= c); + BOOST_C_EXN(a > c); + BOOST_C_EXN(a >= c); + BOOST_C_EXN(a == c); + BOOST_C_EXN(a != c); + BOOST_C_EXN(b < d); + BOOST_C_EXN(b <= d); + BOOST_C_EXN(b > d); + BOOST_C_EXN(b >= d); + BOOST_C_EXN(b == d); + BOOST_C_EXN(b != d); +} + +static void test_lex() +{ + I const a(I::empty()), b(1,2); + int const c = 0, d = my_checking::nan(); + using namespace boost::numeric::interval_lib::compare::lexicographic; + + BOOST_C_EXN(a < b); + BOOST_C_EXN(a <= b); + BOOST_C_EXN(a > b); + BOOST_C_EXN(a >= b); + BOOST_C_EXN(a == b); + BOOST_C_EXN(a != b); + BOOST_C_EXN(b < a); + BOOST_C_EXN(b <= a); + BOOST_C_EXN(b > a); + BOOST_C_EXN(b >= a); + BOOST_C_EXN(b == a); + BOOST_C_EXN(b != a); + + BOOST_C_EXN(a < c); + BOOST_C_EXN(a <= c); + BOOST_C_EXN(a > c); + BOOST_C_EXN(a >= c); + BOOST_C_EXN(a == c); + BOOST_C_EXN(a != c); + BOOST_C_EXN(b < d); + BOOST_C_EXN(b <= d); + BOOST_C_EXN(b > d); + BOOST_C_EXN(b >= d); + BOOST_C_EXN(b == d); + BOOST_C_EXN(b != d); +} + +static void test_pos() +{ + I const a(I::empty()), b(1,2); + int const c = 0, d = my_checking::nan(); + using namespace boost::numeric::interval_lib::compare::possible; + + BOOST_C_EXN(a < b); + BOOST_C_EXN(a <= b); + BOOST_C_EXN(a > b); + BOOST_C_EXN(a >= b); + BOOST_C_EXN(a == b); + BOOST_C_EXN(a != b); + BOOST_C_EXN(b < a); + BOOST_C_EXN(b <= a); + BOOST_C_EXN(b > a); + BOOST_C_EXN(b >= a); + BOOST_C_EXN(b == a); + BOOST_C_EXN(b != a); + + BOOST_C_EXN(a < c); + BOOST_C_EXN(a <= c); + BOOST_C_EXN(a > c); + BOOST_C_EXN(a >= c); + BOOST_C_EXN(a == c); + BOOST_C_EXN(a != c); + BOOST_C_EXN(b < d); + BOOST_C_EXN(b <= d); + BOOST_C_EXN(b > d); + BOOST_C_EXN(b >= d); + BOOST_C_EXN(b == d); + BOOST_C_EXN(b != d); +} + +static void test_set() +{ + I const a(I::empty()), b(1,2); + int const c = 0; + using namespace boost::numeric::interval_lib::compare::set; + + BOOST_C_EXN(a < c); + BOOST_C_EXN(a <= c); + BOOST_C_EXN(a > c); + BOOST_C_EXN(a >= c); + BOOST_C_EXN(a == c); + BOOST_C_EXN(a != c); + BOOST_C_EXN(b < c); + BOOST_C_EXN(b <= c); + BOOST_C_EXN(b > c); + BOOST_C_EXN(b >= c); + BOOST_C_EXN(b == c); + BOOST_C_EXN(b != c); +} + +static void test_tri() +{ + I const a(I::empty()), b(1,2); + int const c = 0, d = my_checking::nan(); + using namespace boost::numeric::interval_lib::compare::tribool; + + BOOST_C_EXN(a < b); + BOOST_C_EXN(a <= b); + BOOST_C_EXN(a > b); + BOOST_C_EXN(a >= b); + BOOST_C_EXN(a == b); + BOOST_C_EXN(a != b); + BOOST_C_EXN(b < a); + BOOST_C_EXN(b <= a); + BOOST_C_EXN(b > a); + BOOST_C_EXN(b >= a); + BOOST_C_EXN(b == a); + BOOST_C_EXN(b != a); + + BOOST_C_EXN(a < c); + BOOST_C_EXN(a <= c); + BOOST_C_EXN(a > c); + BOOST_C_EXN(a >= c); + BOOST_C_EXN(a == c); + BOOST_C_EXN(a != c); + BOOST_C_EXN(b < d); + BOOST_C_EXN(b <= d); + BOOST_C_EXN(b > d); + BOOST_C_EXN(b >= d); + BOOST_C_EXN(b == d); + BOOST_C_EXN(b != d); +} + +int test_main(int, char *[]) { + test_cer(); + test_def(); + test_lex(); + test_pos(); + test_set(); + test_tri(); + + return 0; +} diff --git a/src/boost/libs/numeric/interval/test/cmp_exp.cpp b/src/boost/libs/numeric/interval/test/cmp_exp.cpp new file mode 100644 index 000000000..bebd13af3 --- /dev/null +++ b/src/boost/libs/numeric/interval/test/cmp_exp.cpp @@ -0,0 +1,366 @@ +/* Boost test/cmp_exp.cpp + * test explicit comparison functions + * + * Copyright 2002-2003 Guillaume Melquiond + * + * 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) + */ + +#include "cmp_header.hpp" + +// comparisons between [1,2] and [3,4] + +static void test_12_34() { + const I a(1,2), b(3,4); + + BOOST_CHECK(cerlt(a, b)); + BOOST_CHECK(cerle(a, b)); + BOOST_CHECK(!cergt(a, b)); + BOOST_CHECK(!cerge(a, b)); + + BOOST_CHECK(!cerlt(b, a)); + BOOST_CHECK(!cerle(b, a)); + BOOST_CHECK(cergt(b, a)); + BOOST_CHECK(cerge(b, a)); + + BOOST_CHECK(poslt(a, b)); + BOOST_CHECK(posle(a, b)); + BOOST_CHECK(!posgt(a, b)); + BOOST_CHECK(!posge(a, b)); + + BOOST_CHECK(!poslt(b, a)); + BOOST_CHECK(!posle(b, a)); + BOOST_CHECK(posgt(b, a)); + BOOST_CHECK(posge(b, a)); + + BOOST_CHECK(!cereq(a, b)); + BOOST_CHECK(cerne(a, b)); + BOOST_CHECK(!poseq(a, b)); + BOOST_CHECK(posne(a, b)); + + BOOST_CHECK(!cereq(b, a)); + BOOST_CHECK(cerne(b, a)); + BOOST_CHECK(!poseq(b, a)); + BOOST_CHECK(posne(b, a)); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,3] and [2,4] + +static void test_13_24() { + const I a(1,3), b(2,4); + + BOOST_CHECK(!cerlt(a, b)); + BOOST_CHECK(!cerle(a, b)); + BOOST_CHECK(!cergt(a, b)); + BOOST_CHECK(!cerge(a, b)); + + BOOST_CHECK(!cerlt(b, a)); + BOOST_CHECK(!cerle(b, a)); + BOOST_CHECK(!cergt(b, a)); + BOOST_CHECK(!cerge(b, a)); + + BOOST_CHECK(poslt(a, b)); + BOOST_CHECK(posle(a, b)); + BOOST_CHECK(posgt(a, b)); + BOOST_CHECK(posge(a, b)); + + BOOST_CHECK(poslt(b, a)); + BOOST_CHECK(posle(b, a)); + BOOST_CHECK(posgt(b, a)); + BOOST_CHECK(posge(b, a)); + + BOOST_CHECK(!cereq(a, b)); + BOOST_CHECK(!cerne(a, b)); + BOOST_CHECK(poseq(a, b)); + BOOST_CHECK(posne(a, b)); + + BOOST_CHECK(!cereq(b, a)); + BOOST_CHECK(!cerne(b, a)); + BOOST_CHECK(poseq(b, a)); + BOOST_CHECK(posne(b, a)); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and [2,3] + +static void test_12_23() { + const I a(1,2), b(2,3); + + BOOST_CHECK(!cerlt(a, b)); + BOOST_CHECK(cerle(a, b)); + BOOST_CHECK(!cergt(a, b)); + BOOST_CHECK(!cerge(a, b)); + + BOOST_CHECK(!cerlt(b, a)); + BOOST_CHECK(!cerle(b, a)); + BOOST_CHECK(!cergt(b, a)); + BOOST_CHECK(cerge(b, a)); + + BOOST_CHECK(poslt(a, b)); + BOOST_CHECK(posle(a, b)); + BOOST_CHECK(!posgt(a, b)); + BOOST_CHECK(posge(a, b)); + + BOOST_CHECK(!poslt(b, a)); + BOOST_CHECK(posle(b, a)); + BOOST_CHECK(posgt(b, a)); + BOOST_CHECK(posge(b, a)); + + BOOST_CHECK(!cereq(a, b)); + BOOST_CHECK(!cerne(a, b)); + BOOST_CHECK(poseq(a, b)); + BOOST_CHECK(posne(a, b)); + + BOOST_CHECK(!cereq(b, a)); + BOOST_CHECK(!cerne(b, a)); + BOOST_CHECK(poseq(b, a)); + BOOST_CHECK(posne(b, a)); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and 0 + +static void test_12_0() { + const I a(1,2); + const int b = 0; + + BOOST_CHECK(!cerlt(a, b)); + BOOST_CHECK(!cerle(a, b)); + BOOST_CHECK(cergt(a, b)); + BOOST_CHECK(cerge(a, b)); + + BOOST_CHECK(cerlt(b, a)); + BOOST_CHECK(cerle(b, a)); + BOOST_CHECK(!cergt(b, a)); + BOOST_CHECK(!cerge(b, a)); + + BOOST_CHECK(!poslt(a, b)); + BOOST_CHECK(!posle(a, b)); + BOOST_CHECK(posgt(a, b)); + BOOST_CHECK(posge(a, b)); + + BOOST_CHECK(poslt(b, a)); + BOOST_CHECK(posle(b, a)); + BOOST_CHECK(!posgt(b, a)); + BOOST_CHECK(!posge(b, a)); + + BOOST_CHECK(!cereq(a, b)); + BOOST_CHECK(cerne(a, b)); + BOOST_CHECK(!poseq(a, b)); + BOOST_CHECK(posne(a, b)); + + BOOST_CHECK(!cereq(b, a)); + BOOST_CHECK(cerne(b, a)); + BOOST_CHECK(!poseq(b, a)); + BOOST_CHECK(posne(b, a)); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and 1 + +static void test_12_1() { + const I a(1,2); + const int b = 1; + + BOOST_CHECK(!cerlt(a, b)); + BOOST_CHECK(!cerle(a, b)); + BOOST_CHECK(!cergt(a, b)); + BOOST_CHECK(cerge(a, b)); + + BOOST_CHECK(!cerlt(b, a)); + BOOST_CHECK(cerle(b, a)); + BOOST_CHECK(!cergt(b, a)); + BOOST_CHECK(!cerge(b, a)); + + BOOST_CHECK(!poslt(a, b)); + BOOST_CHECK(posle(a, b)); + BOOST_CHECK(posgt(a, b)); + BOOST_CHECK(posge(a, b)); + + BOOST_CHECK(poslt(b, a)); + BOOST_CHECK(posle(b, a)); + BOOST_CHECK(!posgt(b, a)); + BOOST_CHECK(posge(b, a)); + + BOOST_CHECK(!cereq(a, b)); + BOOST_CHECK(!cerne(a, b)); + BOOST_CHECK(poseq(a, b)); + BOOST_CHECK(posne(a, b)); + + BOOST_CHECK(!cereq(b, a)); + BOOST_CHECK(!cerne(b, a)); + BOOST_CHECK(poseq(b, a)); + BOOST_CHECK(posne(b, a)); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and 2 + +static void test_12_2() { + const I a(1,2); + const int b = 2; + + BOOST_CHECK(!cerlt(a, b)); + BOOST_CHECK(cerle(a, b)); + BOOST_CHECK(!cergt(a, b)); + BOOST_CHECK(!cerge(a, b)); + + BOOST_CHECK(!cerlt(b, a)); + BOOST_CHECK(!cerle(b, a)); + BOOST_CHECK(!cergt(b, a)); + BOOST_CHECK(cerge(b, a)); + + BOOST_CHECK(poslt(a, b)); + BOOST_CHECK(posle(a, b)); + BOOST_CHECK(!posgt(a, b)); + BOOST_CHECK(posge(a, b)); + + BOOST_CHECK(!poslt(b, a)); + BOOST_CHECK(posle(b, a)); + BOOST_CHECK(posgt(b, a)); + BOOST_CHECK(posge(b, a)); + + BOOST_CHECK(!cereq(a, b)); + BOOST_CHECK(!cerne(a, b)); + BOOST_CHECK(poseq(a, b)); + BOOST_CHECK(posne(a, b)); + + BOOST_CHECK(!cereq(b, a)); + BOOST_CHECK(!cerne(b, a)); + BOOST_CHECK(poseq(b, a)); + BOOST_CHECK(posne(b, a)); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and 3 + +static void test_12_3() { + const I a(1,2); + const int b = 3; + + BOOST_CHECK(cerlt(a, b)); + BOOST_CHECK(cerle(a, b)); + BOOST_CHECK(!cergt(a, b)); + BOOST_CHECK(!cerge(a, b)); + + BOOST_CHECK(!cerlt(b, a)); + BOOST_CHECK(!cerle(b, a)); + BOOST_CHECK(cergt(b, a)); + BOOST_CHECK(cerge(b, a)); + + BOOST_CHECK(poslt(a, b)); + BOOST_CHECK(posle(a, b)); + BOOST_CHECK(!posgt(a, b)); + BOOST_CHECK(!posge(a, b)); + + BOOST_CHECK(!poslt(b, a)); + BOOST_CHECK(!posle(b, a)); + BOOST_CHECK(posgt(b, a)); + BOOST_CHECK(posge(b, a)); + + BOOST_CHECK(!cereq(a, b)); + BOOST_CHECK(cerne(a, b)); + BOOST_CHECK(!poseq(a, b)); + BOOST_CHECK(posne(a, b)); + + BOOST_CHECK(!cereq(b, a)); + BOOST_CHECK(cerne(b, a)); + BOOST_CHECK(!poseq(b, a)); + BOOST_CHECK(posne(b, a)); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +static void test_12_12() { + const I a(1,2), b(1,2); + BOOST_CHECK(!cereq(a, b)); + BOOST_CHECK(!cerne(a, b)); + BOOST_CHECK(poseq(a, b)); + BOOST_CHECK(posne(a, b)); + BOOST_CHECK(!cereq(b, a)); + BOOST_CHECK(!cerne(b, a)); + BOOST_CHECK(poseq(b, a)); + BOOST_CHECK(posne(b, a)); +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +static void test_11_11() { + const I a(1,1), b(1,1); + BOOST_CHECK(cereq(a, b)); + BOOST_CHECK(!cerne(a, b)); + BOOST_CHECK(poseq(a, b)); + BOOST_CHECK(!posne(a, b)); + BOOST_CHECK(cereq(b, a)); + BOOST_CHECK(!cerne(b, a)); + BOOST_CHECK(poseq(b, a)); + BOOST_CHECK(!posne(b, a)); +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +static void test_11_1() { + const I a(1,1); + const int b = 1; + BOOST_CHECK(cereq(a, b)); + BOOST_CHECK(!cerne(a, b)); + BOOST_CHECK(poseq(a, b)); + BOOST_CHECK(!posne(a, b)); + BOOST_CHECK(cereq(b, a)); + BOOST_CHECK(!cerne(b, a)); + BOOST_CHECK(poseq(b, a)); + BOOST_CHECK(!posne(b, a)); +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +int test_main(int, char *[]) { + test_12_34(); + test_13_24(); + test_12_23(); + test_12_0(); + test_12_1(); + test_12_2(); + test_12_3(); + test_12_12(); + test_11_11(); + test_11_1(); + + return 0; +} diff --git a/src/boost/libs/numeric/interval/test/cmp_header.hpp b/src/boost/libs/numeric/interval/test/cmp_header.hpp new file mode 100644 index 000000000..ef4c209ae --- /dev/null +++ b/src/boost/libs/numeric/interval/test/cmp_header.hpp @@ -0,0 +1,26 @@ +/* Boost test/cmp_header.hpp header file + * + * Copyright 2003 Guillaume Melquiond + * + * 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) + */ + +#include <boost/numeric/interval/interval.hpp> +#include <boost/numeric/interval/checking.hpp> +#include <boost/numeric/interval/compare.hpp> +#include <boost/numeric/interval/policies.hpp> +#include <boost/test/test_tools.hpp> +#include "bugs.hpp" + +struct empty_class {}; + +typedef boost::numeric::interval_lib::policies + <empty_class, boost::numeric::interval_lib::checking_base<int> > + my_policies; + +typedef boost::numeric::interval<int, my_policies> I; + +#define BOOST_C_EXN(e) \ + BOOST_CHECK_THROW(e, boost::numeric::interval_lib::comparison_error) diff --git a/src/boost/libs/numeric/interval/test/cmp_lex.cpp b/src/boost/libs/numeric/interval/test/cmp_lex.cpp new file mode 100644 index 000000000..6ae0bcb92 --- /dev/null +++ b/src/boost/libs/numeric/interval/test/cmp_lex.cpp @@ -0,0 +1,217 @@ +/* Boost test/cmp_lex.cpp + * test compare::lexicographic + * + * Copyright 2002-2003 Guillaume Melquiond + * + * 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) + */ + +#include "cmp_header.hpp" + +using namespace boost::numeric::interval_lib::compare::lexicographic; + +// comparisons between [1,2] and [3,4] + +static void test_12_34() { + const I a(1,2), b(3,4); + + BOOST_CHECK(a < b); + BOOST_CHECK(a <= b); + BOOST_CHECK(!(a > b)); + BOOST_CHECK(!(a >= b)); + + BOOST_CHECK(b > a); + BOOST_CHECK(b >= a); + BOOST_CHECK(!(b < a)); + BOOST_CHECK(!(b <= a)); + + BOOST_CHECK(!(a == b)); + BOOST_CHECK(a != b); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,3] and [2,4] + +static void test_13_24() { + const I a(1,3), b(2,4); + + BOOST_CHECK(a < b); + BOOST_CHECK(a <= b); + BOOST_CHECK(!(a > b)); + BOOST_CHECK(!(a >= b)); + + BOOST_CHECK(!(b < a)); + BOOST_CHECK(!(b <= a)); + BOOST_CHECK(b > a); + BOOST_CHECK(b >= a); + + BOOST_CHECK(!(a == b)); + BOOST_CHECK(a != b); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and [2,3] + +static void test_12_23() { + const I a(1,2), b(2,3); + + BOOST_CHECK(a < b); + BOOST_CHECK(a <= b); + BOOST_CHECK(!(a > b)); + BOOST_CHECK(!(a >= b)); + + BOOST_CHECK(!(b < a)); + BOOST_CHECK(!(b <= a)); + BOOST_CHECK(b > a); + BOOST_CHECK(b >= a); + + BOOST_CHECK(!(a == b)); + BOOST_CHECK(a != b); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and 0 + +static void test_12_0() { + const I a(1,2); + const int b = 0; + + BOOST_CHECK(!(a < b)); + BOOST_CHECK(!(a <= b)); + BOOST_CHECK(a > b); + BOOST_CHECK(a >= b); + + BOOST_CHECK(!(a == b)); + BOOST_CHECK(a != b); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and 1 + +static void test_12_1() { + const I a(1,2); + const int b = 1; + + BOOST_CHECK(!(a < b)); + BOOST_CHECK(!(a <= b)); + BOOST_CHECK(a > b); + BOOST_CHECK(a >= b); + + BOOST_CHECK(!(a == b)); + BOOST_CHECK(a != b); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and 2 + +static void test_12_2() { + const I a(1,2); + const int b = 2; + + BOOST_CHECK(a < b); + BOOST_CHECK(a <= b); + BOOST_CHECK(!(a > b)); + BOOST_CHECK(!(a >= b)); + + BOOST_CHECK(!(a == b)); + BOOST_CHECK(a != b); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and 3 + +static void test_12_3() { + const I a(1,2); + const int b = 3; + + BOOST_CHECK(a < b); + BOOST_CHECK(a <= b); + BOOST_CHECK(!(a > b)); + BOOST_CHECK(!(a >= b)); + + BOOST_CHECK(!(a == b)); + BOOST_CHECK(a != b); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +static void test_12_12() { + const I a(1,2), b(1,2); + + BOOST_CHECK(a == b); + BOOST_CHECK(!(a != b)); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +static void test_11_11() { + const I a(1,1), b(1,1); + + BOOST_CHECK(a == b); + BOOST_CHECK(!(a != b)); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +static void test_11_1() { + const I a(1,1); + const int b = 1; + + BOOST_CHECK(a == b); + BOOST_CHECK(!(a != b)); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +int test_main(int, char *[]) { + test_12_34(); + test_13_24(); + test_12_23(); + test_12_0(); + test_12_1(); + test_12_2(); + test_12_3(); + test_12_12(); + test_11_11(); + test_11_1(); + + return 0; +} diff --git a/src/boost/libs/numeric/interval/test/cmp_set.cpp b/src/boost/libs/numeric/interval/test/cmp_set.cpp new file mode 100644 index 000000000..55c44740e --- /dev/null +++ b/src/boost/libs/numeric/interval/test/cmp_set.cpp @@ -0,0 +1,218 @@ +/* Boost test/cmp_set.cpp + * test compare::set + * + * Copyright 2004 Guillaume Melquiond + * + * 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) + */ + +#include "cmp_header.hpp" + +using namespace boost::numeric::interval_lib::compare::set; + +// comparisons between [1,2] and [3,4] + +static void test_12_34() { + const I a(1,2), b(3,4); + + BOOST_CHECK(!(a < b)); + BOOST_CHECK(!(a <= b)); + BOOST_CHECK(!(a > b)); + BOOST_CHECK(!(a >= b)); + + BOOST_CHECK(!(b > a)); + BOOST_CHECK(!(b >= a)); + BOOST_CHECK(!(b < a)); + BOOST_CHECK(!(b <= a)); + + BOOST_CHECK(!(a == b)); + BOOST_CHECK(a != b); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,3] and [2,4] + +static void test_13_24() { + const I a(1,3), b(2,4); + + BOOST_CHECK(!(a < b)); + BOOST_CHECK(!(a <= b)); + BOOST_CHECK(!(a > b)); + BOOST_CHECK(!(a >= b)); + + BOOST_CHECK(!(b < a)); + BOOST_CHECK(!(b <= a)); + BOOST_CHECK(!(b > a)); + BOOST_CHECK(!(b >= a)); + + BOOST_CHECK(!(a == b)); + BOOST_CHECK(a != b); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,4] and [2,3] + +static void test_14_23() { + const I a(1,4), b(2,3); + + BOOST_CHECK(!(a < b)); + BOOST_CHECK(!(a <= b)); + BOOST_CHECK(a > b); + BOOST_CHECK(a >= b); + + BOOST_CHECK(b < a); + BOOST_CHECK(b <= a); + BOOST_CHECK(!(b > a)); + BOOST_CHECK(!(b >= a)); + + BOOST_CHECK(!(a == b)); + BOOST_CHECK(a != b); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and [2,3] + +static void test_12_23() { + const I a(1,2), b(2,3); + + BOOST_CHECK(!(a < b)); + BOOST_CHECK(!(a <= b)); + BOOST_CHECK(!(a > b)); + BOOST_CHECK(!(a >= b)); + + BOOST_CHECK(!(b < a)); + BOOST_CHECK(!(b <= a)); + BOOST_CHECK(!(b > a)); + BOOST_CHECK(!(b >= a)); + + BOOST_CHECK(!(a == b)); + BOOST_CHECK(a != b); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and empty set + +static void test_12_E() { + I a(1, 2), b(I::empty()); + + BOOST_CHECK(!(a < b)); + BOOST_CHECK(!(a <= b)); + BOOST_CHECK(a > b); + BOOST_CHECK(a >= b); + + BOOST_CHECK(b < a); + BOOST_CHECK(b <= a); + BOOST_CHECK(!(b > a)); + BOOST_CHECK(!(b >= a)); + + BOOST_CHECK(!(a == b)); + BOOST_CHECK(a != b); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between two empty sets + +static void test_E_E() { + I a(I::empty()), b(I::empty()); + + BOOST_CHECK(!(a < b)); + BOOST_CHECK(a <= b); + BOOST_CHECK(!(a > b)); + BOOST_CHECK(a >= b); + + BOOST_CHECK(!(b < a)); + BOOST_CHECK(b <= a); + BOOST_CHECK(!(b > a)); + BOOST_CHECK(b >= a); + + BOOST_CHECK(a == b); + BOOST_CHECK(!(a != b)); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and [1,2] + +static void test_12_12() { + const I a(1,2), b(1,2); + + BOOST_CHECK(!(a < b)); + BOOST_CHECK(a <= b); + BOOST_CHECK(!(a > b)); + BOOST_CHECK(a >= b); + + BOOST_CHECK(!(b < a)); + BOOST_CHECK(b <= a); + BOOST_CHECK(!(b > a)); + BOOST_CHECK(b >= a); + + BOOST_CHECK(a == b); + BOOST_CHECK(!(a != b)); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,1] and [1,1] + +static void test_11_11() { + const I a(1,1), b(1,1); + + BOOST_CHECK(!(a < b)); + BOOST_CHECK(a <= b); + BOOST_CHECK(!(a > b)); + BOOST_CHECK(a >= b); + + BOOST_CHECK(!(b < a)); + BOOST_CHECK(b <= a); + BOOST_CHECK(!(b > a)); + BOOST_CHECK(b >= a); + + BOOST_CHECK(a == b); + BOOST_CHECK(!(a != b)); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +int test_main(int, char *[]) { + test_12_34(); + test_13_24(); + test_14_23(); + test_12_23(); + test_12_E(); + test_E_E(); + test_12_12(); + test_11_11(); + + return 0; +} diff --git a/src/boost/libs/numeric/interval/test/cmp_tribool.cpp b/src/boost/libs/numeric/interval/test/cmp_tribool.cpp new file mode 100644 index 000000000..9b2f5a48c --- /dev/null +++ b/src/boost/libs/numeric/interval/test/cmp_tribool.cpp @@ -0,0 +1,224 @@ +/* Boost test/cmp_tribool.cpp + * test compare::tribool + * + * Copyright 2004 Guillaume Melquiond + * + * 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) + */ + +#include "cmp_header.hpp" +#include <boost/numeric/interval/compare/tribool.hpp> + +using namespace boost::numeric::interval_lib::compare::tribool; + +// comparisons between [1,2] and [3,4] + +static void test_12_34() { + const I a(1,2), b(3,4); + + BOOST_CHECK(a < b); + BOOST_CHECK(a <= b); + BOOST_CHECK(!(a > b)); + BOOST_CHECK(!(a >= b)); + + BOOST_CHECK(b > a); + BOOST_CHECK(b >= a); + BOOST_CHECK(!(b < a)); + BOOST_CHECK(!(b <= a)); + + BOOST_CHECK(!(a == b)); + BOOST_CHECK(a != b); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,3] and [2,4] + +static void test_13_24() { + const I a(1,3), b(2,4); + + BOOST_CHECK(indeterminate(a < b)); + BOOST_CHECK(indeterminate(a <= b)); + BOOST_CHECK(indeterminate(a > b)); + BOOST_CHECK(indeterminate(a >= b)); + + BOOST_CHECK(indeterminate(b < a)); + BOOST_CHECK(indeterminate(b <= a)); + BOOST_CHECK(indeterminate(b > a)); + BOOST_CHECK(indeterminate(b >= a)); + + BOOST_CHECK(indeterminate(a == b)); + BOOST_CHECK(indeterminate(a != b)); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and [2,3] + +static void test_12_23() { + const I a(1,2), b(2,3); + + BOOST_CHECK(indeterminate(a < b)); + BOOST_CHECK(a <= b); + BOOST_CHECK(!(a > b)); + BOOST_CHECK(indeterminate(a >= b)); + + BOOST_CHECK(!(b < a)); + BOOST_CHECK(indeterminate(b <= a)); + BOOST_CHECK(indeterminate(b > a)); + BOOST_CHECK(b >= a); + + BOOST_CHECK(indeterminate(a == b)); + BOOST_CHECK(indeterminate(a != b)); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and 0 + +static void test_12_0() { + const I a(1,2); + const int b = 0; + + BOOST_CHECK(!(a < b)); + BOOST_CHECK(!(a <= b)); + BOOST_CHECK(a > b); + BOOST_CHECK(a >= b); + + BOOST_CHECK(!(a == b)); + BOOST_CHECK(a != b); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and 1 + +static void test_12_1() { + const I a(1,2); + const int b = 1; + + BOOST_CHECK(!(a < b)); + BOOST_CHECK(indeterminate(a <= b)); + BOOST_CHECK(indeterminate(a > b)); + BOOST_CHECK(a >= b); + + BOOST_CHECK(indeterminate(a == b)); + BOOST_CHECK(indeterminate(a != b)); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and 2 + +static void test_12_2() { + const I a(1,2); + const int b = 2; + + BOOST_CHECK(indeterminate(a < b)); + BOOST_CHECK(a <= b); + BOOST_CHECK(!(a > b)); + BOOST_CHECK(indeterminate(a >= b)); + + BOOST_CHECK(indeterminate(a == b)); + BOOST_CHECK(indeterminate(a != b)); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and 3 + +static void test_12_3() { + const I a(1,2); + const int b = 3; + + BOOST_CHECK(a < b); + BOOST_CHECK(a <= b); + BOOST_CHECK(!(a > b)); + BOOST_CHECK(!(a >= b)); + + BOOST_CHECK(!(a == b)); + BOOST_CHECK(a != b); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,2] and [1,2] + +static void test_12_12() { + const I a(1,2), b(1,2); + + BOOST_CHECK(indeterminate(a == b)); + BOOST_CHECK(indeterminate(a != b)); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,1] and [1,1] + +static void test_11_11() { + const I a(1,1), b(1,1); + + BOOST_CHECK(a == b); + BOOST_CHECK(!(a != b)); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +// comparisons between [1,1] and 1 + +static void test_11_1() { + const I a(1,1); + const int b = 1; + + BOOST_CHECK(a == b); + BOOST_CHECK(!(a != b)); + +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(a); + ::detail::ignore_unused_variable_warning(b); +# endif +} + +int test_main(int, char *[]) { + test_12_34(); + test_13_24(); + test_12_23(); + test_12_0(); + test_12_1(); + test_12_2(); + test_12_3(); + test_12_12(); + test_11_11(); + test_11_1(); + + return 0; +} diff --git a/src/boost/libs/numeric/interval/test/det.cpp b/src/boost/libs/numeric/interval/test/det.cpp new file mode 100644 index 000000000..cc401adc6 --- /dev/null +++ b/src/boost/libs/numeric/interval/test/det.cpp @@ -0,0 +1,103 @@ +/* Boost test/det.cpp + * test protected and unprotected rounding on an unstable determinant + * + * Copyright 2002-2003 Guillaume Melquiond + * + * 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) + */ + +#include <boost/numeric/interval.hpp> +#include <boost/test/minimal.hpp> +#include "bugs.hpp" + +#define size 8 + +template<class I> +void det(I (&mat)[size][size]) { + for(int i = 0; i < size; i++) + for(int j = 0; j < size; j++) + mat[i][j] = I(1) / I(i + j + 1); + + for(int i = 0; i < size - 1; i++) { + int m = i, n = i; + typename I::base_type v = 0; + for(int a = i; a < size; a++) + for(int b = i; b < size; b++) { + typename I::base_type w = abs(mat[a][b]).lower(); + if (w > v) { m = a; n = b; v = w; } + } + if (n != i) + for(int a = 0; a < size; a++) { + I t = mat[a][n]; + mat[a][n] = mat[a][i]; + mat[a][i] = t; + } + if (m != i) + for(int b = i; b < size; b++) { + I t = mat[m][b]; + mat[m][b] = mat[m][i]; + mat[m][i] = t; + } + if (((m + n) & 1) == 1) { }; + I c = mat[i][i]; + for(int j = i + 1; j < size; j++) { + I f = mat[j][i] / c; + for(int k = i; k < size; k++) + mat[j][k] -= f * mat[i][k]; + } + if (zero_in(c)) return; + } +} + +namespace my_namespace { + +using namespace boost; +using namespace numeric; +using namespace interval_lib; + +template<class T> +struct variants { + typedef interval<T> I_op; + typedef typename change_rounding<I_op, save_state<rounded_arith_std<T> > >::type I_sp; + typedef typename unprotect<I_op>::type I_ou; + typedef typename unprotect<I_sp>::type I_su; + typedef T type; +}; + +} + +template<class T> +bool test() { + typedef my_namespace::variants<double> types; + types::I_op mat_op[size][size]; + types::I_sp mat_sp[size][size]; + types::I_ou mat_ou[size][size]; + types::I_su mat_su[size][size]; + det(mat_op); + det(mat_sp); + { types::I_op::traits_type::rounding rnd; det(mat_ou); } + { types::I_sp::traits_type::rounding rnd; det(mat_su); } + for(int i = 0; i < size; i++) + for(int j = 0; j < size; j++) { + typedef types::I_op I; + I d_op = mat_op[i][j]; + I d_sp = mat_sp[i][j]; + I d_ou = mat_ou[i][j]; + I d_su = mat_su[i][j]; + if (!(equal(d_op, d_sp) && equal(d_sp, d_ou) && equal(d_ou, d_su))) + return false; + } + return true; +} + +int test_main(int, char *[]) { + BOOST_CHECK(test<float>()); + BOOST_CHECK(test<double>()); + BOOST_CHECK(test<long double>()); +# ifdef __BORLANDC__ + ::detail::ignore_warnings(); +# endif + return 0; +} diff --git a/src/boost/libs/numeric/interval/test/fmod.cpp b/src/boost/libs/numeric/interval/test/fmod.cpp new file mode 100644 index 000000000..230dcd2f0 --- /dev/null +++ b/src/boost/libs/numeric/interval/test/fmod.cpp @@ -0,0 +1,53 @@ +/* Boost test/fmod.cpp + * test the fmod with specially crafted integer intervals + * + * Copyright 2002-2003 Guillaume Melquiond + * + * 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) + */ + +#include <boost/numeric/interval/interval.hpp> +#include <boost/numeric/interval/arith.hpp> +#include <boost/numeric/interval/arith2.hpp> +#include <boost/numeric/interval/utility.hpp> +#include <boost/numeric/interval/checking.hpp> +#include <boost/numeric/interval/rounding.hpp> +#include <boost/test/minimal.hpp> +#include "bugs.hpp" + +struct my_rounded_arith { + int sub_down(int x, int y) { return x - y; } + int sub_up (int x, int y) { return x - y; } + int mul_down(int x, int y) { return x * y; } + int mul_up (int x, int y) { return x * y; } + int div_down(int x, int y) { + int q = x / y; + return (x % y < 0) ? (q - 1) : q; + } + int int_down(int x) { return x; } +}; + +using namespace boost; +using namespace numeric; +using namespace interval_lib; + +typedef change_rounding<interval<int>, save_state_nothing<my_rounded_arith> >::type I; + +int test_main(int, char *[]) { + + BOOST_CHECK(equal(fmod(I(6,9), 7), I(6,9))); + BOOST_CHECK(equal(fmod(6, I(7,8)), I(6,6))); + BOOST_CHECK(equal(fmod(I(6,9), I(7,8)), I(6,9))); + + BOOST_CHECK(equal(fmod(I(13,17), 7), I(6,10))); + BOOST_CHECK(equal(fmod(13, I(7,8)), I(5,6))); + BOOST_CHECK(equal(fmod(I(13,17), I(7,8)), I(5,10))); + + BOOST_CHECK(equal(fmod(I(-17,-13), 7), I(4,8))); + BOOST_CHECK(equal(fmod(-17, I(7,8)), I(4,7))); + BOOST_CHECK(equal(fmod(I(-17,-13), I(7,8)), I(4,11))); + + return 0; +} diff --git a/src/boost/libs/numeric/interval/test/integer.cpp b/src/boost/libs/numeric/interval/test/integer.cpp new file mode 100644 index 000000000..3e78d8be4 --- /dev/null +++ b/src/boost/libs/numeric/interval/test/integer.cpp @@ -0,0 +1,24 @@ +/* Boost test/integer.cpp + * test int extension + * + * Copyright 2003 Guillaume Melquiond + * + * 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) + */ + +#include <boost/numeric/interval.hpp> +#include <boost/numeric/interval/ext/integer.hpp> +#include "bugs.hpp" + +typedef boost::numeric::interval<float> I; + +int main() { + I x, y; + x = 4 - (2 * y + 1) / 3; +# ifdef __BORLANDC__ + ::detail::ignore_warnings(); +# endif + return 0; +} diff --git a/src/boost/libs/numeric/interval/test/msvc_x64_flags.cpp b/src/boost/libs/numeric/interval/test/msvc_x64_flags.cpp new file mode 100644 index 000000000..a79d2bb08 --- /dev/null +++ b/src/boost/libs/numeric/interval/test/msvc_x64_flags.cpp @@ -0,0 +1,21 @@ +/* Boost test/msvc_x64_flags.cpp + * Test for amd64\ieee.c(102) : Assertion failed: (mask&~(_MCW_DN|_MCW_EM|_MCW_RC))==0. + * This happens with MSVC on x64 in Debug mode. See ticket #4964. + * + * 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) + */ + +#include <boost/numeric/interval.hpp> +#include <boost/test/minimal.hpp> +#include "bugs.hpp" + +int test_main(int, char *[]) { + boost::numeric::interval<double> i(0.0, 0.0); + boost::numeric::interval<double> i2 = 60.0 - i; +# ifdef __BORLANDC__ + ::detail::ignore_warnings(); +# endif + return 0; +} diff --git a/src/boost/libs/numeric/interval/test/mul.cpp b/src/boost/libs/numeric/interval/test/mul.cpp new file mode 100644 index 000000000..118acf325 --- /dev/null +++ b/src/boost/libs/numeric/interval/test/mul.cpp @@ -0,0 +1,124 @@ +/* Boost test/mul.cpp + * test multiplication, division, square and square root on some intervals + * + * Copyright 2002-2003 Guillaume Melquiond + * + * 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) + */ + +#include <boost/numeric/interval.hpp> +#include <boost/test/minimal.hpp> +#include "bugs.hpp" + +typedef boost::numeric::interval<double> I; + +static double min BOOST_PREVENT_MACRO_SUBSTITUTION (double a, double b, double c, double d) { + return (std::min)((std::min)(a, b), (std::min)(c, d)); +} + +static double max BOOST_PREVENT_MACRO_SUBSTITUTION (double a, double b, double c, double d) { + return (std::max)((std::max)(a, b), (std::max)(c, d)); +} + +static bool test_mul(double al, double au, double bl, double bu) { + I a(al, au), b(bl, bu); + I c = a * b; + return c.lower() == (min)(al*bl, al*bu, au*bl, au*bu) + && c.upper() == (max)(al*bl, al*bu, au*bl, au*bu); +} + +static bool test_mul1(double ac, double bl, double bu) { + I a(ac), b(bl, bu); + I c = ac * b; + I d = b * ac; + I e = a * b; + return equal(c, d) && equal(d, e); +} + +static bool test_div(double al, double au, double bl, double bu) { + I a(al, au), b(bl, bu); + I c = a / b; + return c.lower() == (min)(al/bl, al/bu, au/bl, au/bu) + && c.upper() == (max)(al/bl, al/bu, au/bl, au/bu); +} + +static bool test_div1(double al, double au, double bc) { + I a(al, au), b(bc); + I c = a / bc; + I d = a / b; + return equal(c, d); +} + +static bool test_div2(double ac, double bl, double bu) { + I a(ac), b(bl, bu); + I c = ac / b; + I d = a / b; + return equal(c, d); +} + +static bool test_square(double al, double au) { + I a(al, au); + I b = square(a); + I c = a * a; + return b.upper() == c.upper() && + (b.lower() == c.lower() || (c.lower() <= 0 && b.lower() == 0)); +} + +static bool test_sqrt(double al, double au) { + I a(al, au); + I b = square(sqrt(a)); + return subset(abs(a), b); +} + +int test_main(int, char*[]) { + BOOST_CHECK(test_mul(2, 3, 5, 7)); + BOOST_CHECK(test_mul(2, 3, -5, 7)); + BOOST_CHECK(test_mul(2, 3, -7, -5)); + BOOST_CHECK(test_mul(-2, 3, 5, 7)); + BOOST_CHECK(test_mul(-2, 3, -5, 7)); + BOOST_CHECK(test_mul(-2, 3, -7, -5)); + BOOST_CHECK(test_mul(-3, -2, 5, 7)); + BOOST_CHECK(test_mul(-3, -2, -5, 7)); + BOOST_CHECK(test_mul(-3, -2, -7, -5)); + + BOOST_CHECK(test_mul1(3, 5, 7)); + BOOST_CHECK(test_mul1(3, -5, 7)); + BOOST_CHECK(test_mul1(3, -7, -5)); + BOOST_CHECK(test_mul1(-3, 5, 7)); + BOOST_CHECK(test_mul1(-3, -5, 7)); + BOOST_CHECK(test_mul1(-3, -7, -5)); + + BOOST_CHECK(test_div(30, 42, 2, 3)); + BOOST_CHECK(test_div(30, 42, -3, -2)); + BOOST_CHECK(test_div(-30, 42, 2, 3)); + BOOST_CHECK(test_div(-30, 42, -3, -2)); + BOOST_CHECK(test_div(-42, -30, 2, 3)); + BOOST_CHECK(test_div(-42, -30, -3, -2)); + + BOOST_CHECK(test_div1(30, 42, 3)); + BOOST_CHECK(test_div1(30, 42, -3)); + BOOST_CHECK(test_div1(-30, 42, 3)); + BOOST_CHECK(test_div1(-30, 42, -3)); + BOOST_CHECK(test_div1(-42, -30, 3)); + BOOST_CHECK(test_div1(-42, -30, -3)); + + BOOST_CHECK(test_div2(30, 2, 3)); + BOOST_CHECK(test_div2(30, -3, -2)); + BOOST_CHECK(test_div2(-30, 2, 3)); + BOOST_CHECK(test_div2(-30, -3, -2)); + + BOOST_CHECK(test_square(2, 3)); + BOOST_CHECK(test_square(-2, 3)); + BOOST_CHECK(test_square(-3, 2)); + + BOOST_CHECK(test_sqrt(2, 3)); + BOOST_CHECK(test_sqrt(5, 7)); + BOOST_CHECK(test_sqrt(-1, 2)); + +# ifdef __BORLANDC__ + ::detail::ignore_warnings(); +# endif + return 0; +} diff --git a/src/boost/libs/numeric/interval/test/overflow.cpp b/src/boost/libs/numeric/interval/test/overflow.cpp new file mode 100644 index 000000000..c15fc917a --- /dev/null +++ b/src/boost/libs/numeric/interval/test/overflow.cpp @@ -0,0 +1,44 @@ +/* Boost test/overflow.cpp + * test if extended precision exponent does not disturb interval computation + * + * Copyright 2002-2003 Guillaume Melquiond + * + * 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) + */ + +#include <boost/numeric/interval.hpp> +#include <boost/test/minimal.hpp> +#include "bugs.hpp" + +template<class I> +void test_one(typename I::base_type x, typename I::base_type f) { + I y = x; + typename I::base_type g = 1 / f; + const int nb = 10000; + for(int i = 0; i < nb; i++) y *= f; + for(int i = 0; i < nb; i++) y *= g; + BOOST_CHECK(in(x, y)); +# ifdef __BORLANDC__ + ::detail::ignore_unused_variable_warning(nb); +# endif +} + +template<class I> +void test() { + test_one<I>(1., 25.); + test_one<I>(1., 0.04); + test_one<I>(-1., 25.); + test_one<I>(-1., 0.04); +} + +int test_main(int, char *[]) { + test<boost::numeric::interval<float> >(); + test<boost::numeric::interval<double> >(); + //test<boost::numeric::interval<long double> >(); +# ifdef __BORLANDC__ + ::detail::ignore_warnings(); +# endif + return 0; +} diff --git a/src/boost/libs/numeric/interval/test/pi.cpp b/src/boost/libs/numeric/interval/test/pi.cpp new file mode 100644 index 000000000..38adec99a --- /dev/null +++ b/src/boost/libs/numeric/interval/test/pi.cpp @@ -0,0 +1,59 @@ +/* Boost test/pi.cpp + * test if the pi constant is correctly defined + * + * Copyright 2002-2003 Guillaume Melquiond, Sylvain Pion + * + * 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) + */ + +#include <boost/numeric/interval.hpp> +#include <boost/limits.hpp> +#include <boost/test/minimal.hpp> +#include "bugs.hpp" + +#define PI 3.14159265358979323846 + +typedef boost::numeric::interval<int> I_i; +typedef boost::numeric::interval<float> I_f; +typedef boost::numeric::interval<double> I_d; +typedef boost::numeric::interval<long double> I_ld; + +using boost::numeric::interval_lib::pi; +using boost::numeric::interval_lib::pi_half; +using boost::numeric::interval_lib::pi_twice; + +int test_main(int, char *[]) { + I_i pi_i = pi<I_i>(); + I_f pi_f = pi<I_f>(); + I_d pi_d = pi<I_d>(); + I_ld pi_ld = pi<I_ld>(); + + BOOST_CHECK(in((int) PI, pi_i)); + BOOST_CHECK(in((float) PI, pi_f)); + BOOST_CHECK(in((double)PI, pi_d)); + BOOST_CHECK(subset(pi_i, widen(I_i((int) PI), 1))); + BOOST_CHECK(subset(pi_f, widen(I_f((float) PI), (std::numeric_limits<float> ::min)()))); + BOOST_CHECK(subset(pi_d, widen(I_d((double)PI), (std::numeric_limits<double>::min)()))); + + // We can't test the following equalities for interval<int>. + I_f pi_f_half = pi_half<I_f>(); + I_f pi_f_twice = pi_twice<I_f>(); + + I_d pi_d_half = pi_half<I_d>(); + I_d pi_d_twice = pi_twice<I_d>(); + + I_ld pi_ld_half = pi_half<I_ld>(); + I_ld pi_ld_twice = pi_twice<I_ld>(); + + BOOST_CHECK(equal(2.0f * pi_f_half, pi_f)); + BOOST_CHECK(equal(2.0 * pi_d_half, pi_d)); + BOOST_CHECK(equal(2.0l * pi_ld_half, pi_ld)); + + BOOST_CHECK(equal(2.0f * pi_f, pi_f_twice)); + BOOST_CHECK(equal(2.0 * pi_d, pi_d_twice)); + BOOST_CHECK(equal(2.0l * pi_ld, pi_ld_twice)); + + return 0; +} diff --git a/src/boost/libs/numeric/interval/test/pow.cpp b/src/boost/libs/numeric/interval/test/pow.cpp new file mode 100644 index 000000000..ef5b268b0 --- /dev/null +++ b/src/boost/libs/numeric/interval/test/pow.cpp @@ -0,0 +1,42 @@ +/* Boost test/pow.cpp + * test the pow function + * + * Copyright 2002-2003 Guillaume Melquiond + * + * 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) + */ + +#include <boost/numeric/interval.hpp> +#include <boost/test/minimal.hpp> +#include "bugs.hpp" + +bool test_pow(double al, double au, double bl, double bu, int p) { + typedef boost::numeric::interval<double> I; + I b = pow(I(al, au), p); + return b.lower() == bl && b.upper() == bu; +} + +int test_main(int, char *[]) { + BOOST_CHECK(test_pow(2, 3, 8, 27, 3)); + BOOST_CHECK(test_pow(2, 3, 16, 81, 4)); + BOOST_CHECK(test_pow(-3, 2, -27, 8, 3)); + BOOST_CHECK(test_pow(-3, 2, 0, 81, 4)); + BOOST_CHECK(test_pow(-3, -2, -27, -8, 3)); + BOOST_CHECK(test_pow(-3, -2, 16, 81, 4)); + + BOOST_CHECK(test_pow(2, 4, 1./64, 1./8, -3)); + BOOST_CHECK(test_pow(2, 4, 1./256, 1./16, -4)); + BOOST_CHECK(test_pow(-4, -2, -1./8, -1./64, -3)); + BOOST_CHECK(test_pow(-4, -2, 1./256, 1./16, -4)); + + BOOST_CHECK(test_pow(2, 3, 1, 1, 0)); + BOOST_CHECK(test_pow(-3, 2, 1, 1, 0)); + BOOST_CHECK(test_pow(-3, -2, 1, 1, 0)); + +# ifdef __BORLANDC__ + ::detail::ignore_warnings(); +# endif + return 0; +} diff --git a/src/boost/libs/numeric/interval/test/test_float.cpp b/src/boost/libs/numeric/interval/test/test_float.cpp new file mode 100644 index 000000000..8f478a79a --- /dev/null +++ b/src/boost/libs/numeric/interval/test/test_float.cpp @@ -0,0 +1,128 @@ +/* Boost test/test_float.cpp + * test arithmetic operations on a range of intervals + * + * Copyright 2003 Guillaume Melquiond + * + * 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) + */ + +#include <boost/numeric/interval.hpp> +#include <boost/test/test_tools.hpp> +#include <boost/config.hpp> +#include "bugs.hpp" + +/* All the following tests should be BOOST_CHECK; however, if a test fails, + the probability is high that hundreds of other tests will fail, so it is + replaced by BOOST_REQUIRE to avoid flooding the logs. */ + +template<class T, class F> +void test_unary() { + typedef typename F::I I; + for(I a(-10., -9.91); a.lower() <= 10.; a += 0.3) { + if (!F::validate(a)) continue; + I rI = F::f_I(a); + T rT1 = F::f_T(a.lower()), rT2 = F::f_T(a.upper()), + rT3 = F::f_T(median(a)); + BOOST_REQUIRE(in(rT1, rI)); + BOOST_REQUIRE(in(rT2, rI)); + BOOST_REQUIRE(in(rT3, rI)); + } +} + +template<class T, class F> +void test_binary() { + typedef typename F::I I; + for(I a(-10., -9.91); a.lower() <= 10.; a += 0.3) { + for(I b(-10., -9.91); b.lower() <= 10.; b += 0.3) { + if (!F::validate(a, b)) continue; + T al = a.lower(), au = a.upper(), bl = b.lower(), bu = b.upper(); + I rII = F::f_II(a, b); + I rIT1 = F::f_IT(a, bl), rIT2 = F::f_IT(a, bu); + I rTI1 = F::f_TI(al, b), rTI2 = F::f_TI(au, b); + I rTT1 = F::f_TT(al, bl), rTT2 = F::f_TT(al, bu); + I rTT3 = F::f_TT(au, bl), rTT4 = F::f_TT(au, bu); + BOOST_REQUIRE(subset(rTT1, rIT1)); + BOOST_REQUIRE(subset(rTT3, rIT1)); + BOOST_REQUIRE(subset(rTT2, rIT2)); + BOOST_REQUIRE(subset(rTT4, rIT2)); + BOOST_REQUIRE(subset(rTT1, rTI1)); + BOOST_REQUIRE(subset(rTT2, rTI1)); + BOOST_REQUIRE(subset(rTT3, rTI2)); + BOOST_REQUIRE(subset(rTT4, rTI2)); + BOOST_REQUIRE(subset(rIT1, rII)); + BOOST_REQUIRE(subset(rIT2, rII)); + BOOST_REQUIRE(subset(rTI1, rII)); + BOOST_REQUIRE(subset(rTI2, rII)); + } + } +} + +#define new_unary_bunch(name, op, val) \ + template<class T> \ + struct name { \ + typedef boost::numeric::interval<T> I; \ + static I f_I(const I& a) { return op(a); } \ + static T f_T(const T& a) { return op(a); } \ + static bool validate(const I& a) { return val; } \ + } + +//#ifndef BOOST_NO_STDC_NAMESPACE +using std::abs; +using std::sqrt; +//#endif + +new_unary_bunch(bunch_pos, +, true); +new_unary_bunch(bunch_neg, -, true); +new_unary_bunch(bunch_sqrt, sqrt, a.lower() >= 0.); +new_unary_bunch(bunch_abs, abs, true); + +template<class T> +void test_all_unaries() { + BOOST_TEST_CHECKPOINT("pos"); test_unary<T, bunch_pos<T> >(); + BOOST_TEST_CHECKPOINT("neg"); test_unary<T, bunch_neg<T> >(); + BOOST_TEST_CHECKPOINT("sqrt"); test_unary<T, bunch_sqrt<T> >(); + BOOST_TEST_CHECKPOINT("abs"); test_unary<T, bunch_abs<T> >(); +} + +#define new_binary_bunch(name, op, val) \ + template<class T> \ + struct bunch_##name { \ + typedef boost::numeric::interval<T> I; \ + static I f_II(const I& a, const I& b) { return a op b; } \ + static I f_IT(const I& a, const T& b) { return a op b; } \ + static I f_TI(const T& a, const I& b) { return a op b; } \ + static I f_TT(const T& a, const T& b) \ + { return boost::numeric::interval_lib::name<I>(a,b); } \ + static bool validate(const I& a, const I& b) { return val; } \ + } + +new_binary_bunch(add, +, true); +new_binary_bunch(sub, -, true); +new_binary_bunch(mul, *, true); +new_binary_bunch(div, /, !zero_in(b)); + +template<class T> +void test_all_binaries() { + BOOST_TEST_CHECKPOINT("add"); test_binary<T, bunch_add<T> >(); + BOOST_TEST_CHECKPOINT("sub"); test_binary<T, bunch_sub<T> >(); + BOOST_TEST_CHECKPOINT("mul"); test_binary<T, bunch_mul<T> >(); + BOOST_TEST_CHECKPOINT("div"); test_binary<T, bunch_div<T> >(); +} + +int test_main(int, char *[]) { + BOOST_TEST_CHECKPOINT("float tests"); + test_all_unaries<float> (); + test_all_binaries<float> (); + BOOST_TEST_CHECKPOINT("double tests"); + test_all_unaries<double>(); + test_all_binaries<double>(); + //BOOST_TEST_CHECKPOINT("long double tests"); + //test_all_unaries<long double>(); + //test_all_binaries<long double>(); +# ifdef __BORLANDC__ + ::detail::ignore_warnings(); +# endif + return 0; +} diff --git a/src/boost/libs/numeric/odeint/CHANGELOG b/src/boost/libs/numeric/odeint/CHANGELOG new file mode 100644 index 000000000..b1537eb1a --- /dev/null +++ b/src/boost/libs/numeric/odeint/CHANGELOG @@ -0,0 +1,9 @@ +odeint 2.1 + +* versioning system +* generation functions +* bugfixing + +odeint 2.2 (still running) + +* removing same_size and resize from state_wrapper into separate functions diff --git a/src/boost/libs/numeric/odeint/README.md b/src/boost/libs/numeric/odeint/README.md new file mode 100644 index 000000000..23e4f88b5 --- /dev/null +++ b/src/boost/libs/numeric/odeint/README.md @@ -0,0 +1,3 @@ +[![Build Status](https://travis-ci.org/headmyshoulder/odeint-v2.svg?branch=master)](https://travis-ci.org/headmyshoulder/odeint-v2) + +odeint is a highly flexible library for solving ordinary differential equations. diff --git a/src/boost/libs/numeric/odeint/examples/2d_lattice/Jamfile.v2 b/src/boost/libs/numeric/odeint/examples/2d_lattice/Jamfile.v2 new file mode 100644 index 000000000..c995ec168 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/2d_lattice/Jamfile.v2 @@ -0,0 +1,13 @@ +# Copyright 2011 Mario Mulansky +# Copyright 2012 Karsten Ahnert +# 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) + +project + : requirements + <include>../../../../.. + <define>BOOST_ALL_NO_LIB=1 + ; + +exe spreading : spreading.cpp ;
\ No newline at end of file diff --git a/src/boost/libs/numeric/odeint/examples/2d_lattice/lattice2d.hpp b/src/boost/libs/numeric/odeint/examples/2d_lattice/lattice2d.hpp new file mode 100644 index 000000000..4fd9c985e --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/2d_lattice/lattice2d.hpp @@ -0,0 +1,165 @@ +/* + Copyright 2011 Mario Mulansky + Copyright 2012-2013 Karsten Ahnert + + 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) + */ + + +/* strongly nonlinear hamiltonian lattice in 2d */ + +#ifndef LATTICE2D_HPP +#define LATTICE2D_HPP + +#include <vector> + +#include <boost/math/special_functions/pow.hpp> + +using boost::math::pow; + +template< int Kappa , int Lambda > +struct lattice2d { + + const double m_beta; + std::vector< std::vector< double > > m_omega; + + lattice2d( const double beta ) + : m_beta( beta ) + { } + + template< class StateIn , class StateOut > + void operator()( const StateIn &q , StateOut &dpdt ) + { + // q and dpdt are 2d + const int N = q.size(); + + int i; + for( i = 0 ; i < N ; ++i ) + { + const int i_l = (i-1+N) % N; + const int i_r = (i+1) % N; + for( int j = 0 ; j < N ; ++j ) + { + const int j_l = (j-1+N) % N; + const int j_r = (j+1) % N; + dpdt[i][j] = - m_omega[i][j] * pow<Kappa-1>( q[i][j] ) + - m_beta * pow<Lambda-1>( q[i][j] - q[i][j_l] ) + - m_beta * pow<Lambda-1>( q[i][j] - q[i][j_r] ) + - m_beta * pow<Lambda-1>( q[i][j] - q[i_l][j] ) + - m_beta * pow<Lambda-1>( q[i][j] - q[i_r][j] ); + } + } + } + + template< class StateIn > + double energy( const StateIn &q , const StateIn &p ) + { + // q and dpdt are 2d + const int N = q.size(); + double energy = 0.0; + int i; + for( i = 0 ; i < N ; ++i ) + { + const int i_l = (i-1+N) % N; + const int i_r = (i+1) % N; + for( int j = 0 ; j < N ; ++j ) + { + const int j_l = (j-1+N) % N; + const int j_r = (j+1) % N; + energy += p[i][j]*p[i][j] / 2.0 + + m_omega[i][j] * pow<Kappa>( q[i][j] ) / Kappa + + m_beta * pow<Lambda>( q[i][j] - q[i][j_l] ) / Lambda / 2 + + m_beta * pow<Lambda>( q[i][j] - q[i][j_r] ) / Lambda / 2 + + m_beta * pow<Lambda>( q[i][j] - q[i_l][j] ) / Lambda / 2 + + m_beta * pow<Lambda>( q[i][j] - q[i_r][j] ) / Lambda / 2; + } + } + return energy; + } + + + template< class StateIn , class StateOut > + double local_energy( const StateIn &q , const StateIn &p , StateOut &energy ) + { + // q and dpdt are 2d + const int N = q.size(); + double e = 0.0; + int i; + for( i = 0 ; i < N ; ++i ) + { + const int i_l = (i-1+N) % N; + const int i_r = (i+1) % N; + for( int j = 0 ; j < N ; ++j ) + { + const int j_l = (j-1+N) % N; + const int j_r = (j+1) % N; + energy[i][j] = p[i][j]*p[i][j] / 2.0 + + m_omega[i][j] * pow<Kappa>( q[i][j] ) / Kappa + + m_beta * pow<Lambda>( q[i][j] - q[i][j_l] ) / Lambda / 2 + + m_beta * pow<Lambda>( q[i][j] - q[i][j_r] ) / Lambda / 2 + + m_beta * pow<Lambda>( q[i][j] - q[i_l][j] ) / Lambda / 2 + + m_beta * pow<Lambda>( q[i][j] - q[i_r][j] ) / Lambda / 2; + e += energy[i][j]; + } + } + //rescale + e = 1.0/e; + for( i = 0 ; i < N ; ++i ) + for( int j = 0 ; j < N ; ++j ) + energy[i][j] *= e; + return 1.0/e; + } + + void load_pot( const char* filename , const double W , const double gap , + const size_t dim ) + { + std::ifstream in( filename , std::ios::in | std::ios::binary ); + if( !in.is_open() ) { + std::cerr << "pot file not found: " << filename << std::endl; + exit(0); + } else { + std::cout << "using pot file: " << filename << std::endl; + } + + m_omega.resize( dim ); + for( int i = 0 ; i < dim ; ++i ) + { + m_omega[i].resize( dim ); + for( size_t j = 0 ; j < dim ; ++j ) + { + if( !in.good() ) + { + std::cerr << "I/O Error: " << filename << std::endl; + exit(0); + } + double d; + in.read( (char*) &d , sizeof(d) ); + if( (d < 0) || (d > 1.0) ) + { + std::cerr << "ERROR: " << d << std::endl; + exit(0); + } + m_omega[i][j] = W*d + gap; + } + } + + } + + void generate_pot( const double W , const double gap , const size_t dim ) + { + m_omega.resize( dim ); + for( size_t i = 0 ; i < dim ; ++i ) + { + m_omega[i].resize( dim ); + for( size_t j = 0 ; j < dim ; ++j ) + { + m_omega[i][j] = W*static_cast<double>(rand())/RAND_MAX + gap; + } + } + } + +}; + +#endif diff --git a/src/boost/libs/numeric/odeint/examples/2d_lattice/nested_range_algebra.hpp b/src/boost/libs/numeric/odeint/examples/2d_lattice/nested_range_algebra.hpp new file mode 100644 index 000000000..0afa367fd --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/2d_lattice/nested_range_algebra.hpp @@ -0,0 +1,46 @@ +/* + Copyright 2011 Mario Mulansky + Copyright 2012 Karsten Ahnert + + 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) + */ + + +/* nested range algebra */ + +#ifndef NESTED_RANGE_ALGEBRA +#define NESTED_RANGE_ALGEBRA + +namespace detail { + + template< class Iterator1 , class Iterator2 , class Iterator3 , class Operation , class Algebra > + void for_each3( Iterator1 first1 , Iterator1 last1 , Iterator2 first2 , Iterator3 first3, Operation op , Algebra &algebra ) +{ + for( ; first1 != last1 ; ) + algebra.for_each3( *first1++ , *first2++ , *first3++ , op ); +} +} + + +template< class InnerAlgebra > +struct nested_range_algebra +{ + + nested_range_algebra() + : m_inner_algebra() + { } + + template< class S1 , class S2 , class S3 , class Op > + void for_each3( S1 &s1 , S2 &s2 , S3 &s3 , Op op ) + { + detail::for_each3( boost::begin( s1 ) , boost::end( s1 ) , boost::begin( s2 ) , boost::begin( s3 ) , op , m_inner_algebra ); + } + + +private: + InnerAlgebra m_inner_algebra; +}; + +#endif diff --git a/src/boost/libs/numeric/odeint/examples/2d_lattice/spreading.cpp b/src/boost/libs/numeric/odeint/examples/2d_lattice/spreading.cpp new file mode 100644 index 000000000..88c60bf72 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/2d_lattice/spreading.cpp @@ -0,0 +1,122 @@ +/* + Copyright 2011 Mario Mulansky + Copyright 2012 Karsten Ahnert + + 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) + */ + + +/* + * Example of a 2D simulation of nonlinearly coupled oscillators. + * Program just prints final energy which should be close to the initial energy (1.0). + * No parallelization is employed here. + * Run time on a 2.3GHz Intel Core-i5: about 10 seconds for 100 steps. + * Compile simply via bjam or directly: + * g++ -O3 -I${BOOST_ROOT} -I../../../../.. spreading.cpp + */ + + +#include <iostream> +#include <fstream> +#include <vector> +#include <cstdlib> +#include <sys/time.h> + +#include <boost/ref.hpp> +#include <boost/numeric/odeint/stepper/symplectic_rkn_sb3a_mclachlan.hpp> + +// we use a vector< vector< double > > as state type, +// for that some functionality has to be added for odeint to work +#include "nested_range_algebra.hpp" +#include "vector_vector_resize.hpp" + +// defines the rhs of our dynamical equation +#include "lattice2d.hpp" +/* dynamical equations (Hamiltonian structure): +dqdt_{i,j} = p_{i,j} +dpdt_{i,j} = - omega_{i,j}*q_{i,j} - \beta*[ (q_{i,j} - q_{i,j-1})^3 + +(q_{i,j} - q_{i,j+1})^3 + +(q_{i,j} - q_{i-1,j})^3 + +(q_{i,j} - q_{i+1,j})^3 ] +*/ + + +using namespace std; + +static const int MAX_N = 1024;//2048; + +static const size_t KAPPA = 2; +static const size_t LAMBDA = 4; +static const double W = 1.0; +static const double gap = 0.0; +static const size_t steps = 100; +static const double dt = 0.1; + +double initial_e = 1.0; +double beta = 1.0; +int realization_index = 0; + +//the state type +typedef vector< vector< double > > state_type; + +//the stepper, choose a symplectic one to account for hamiltonian structure +//use nested_range_algebra for calculations on vector< vector< ... > > +typedef boost::numeric::odeint::symplectic_rkn_sb3a_mclachlan< + state_type , state_type , double , state_type , state_type , double , + nested_range_algebra< boost::numeric::odeint::range_algebra > , + boost::numeric::odeint::default_operations > stepper_type; + +double time_diff_in_ms( timeval &t1 , timeval &t2 ) +{ return (t2.tv_sec - t1.tv_sec)*1000.0 + (t2.tv_usec - t1.tv_usec)/1000.0 + 0.5; } + + +int main( int argc, const char* argv[] ) { + + srand( time(NULL) ); + + lattice2d< KAPPA , LAMBDA > lattice( beta ); + + + lattice.generate_pot( W , gap , MAX_N ); + + state_type q( MAX_N , vector< double >( MAX_N , 0.0 ) ); + + state_type p( q ); + + state_type energy( q ); + + p[MAX_N/2][MAX_N/2] = sqrt( 0.5*initial_e ); + p[MAX_N/2+1][MAX_N/2] = sqrt( 0.5*initial_e ); + p[MAX_N/2][MAX_N/2+1] = sqrt( 0.5*initial_e ); + p[MAX_N/2+1][MAX_N/2+1] = sqrt( 0.5*initial_e ); + + cout.precision(10); + + lattice.local_energy( q , p , energy ); + double e=0.0; + for( size_t i=0 ; i<energy.size() ; ++i ) + for( size_t j=0 ; j<energy[i].size() ; ++j ) + { + e += energy[i][j]; + } + + cout << "initial energy: " << lattice.energy( q , p ) << endl; + + timeval elapsed_time_start , elapsed_time_end; + gettimeofday(&elapsed_time_start , NULL); + + stepper_type stepper; + + for( size_t step=0 ; step<=steps ; ++step ) + { + stepper.do_step( boost::ref( lattice ) , + make_pair( boost::ref( q ) , boost::ref( p ) ) , + 0.0 , 0.1 ); + } + + gettimeofday(&elapsed_time_end , NULL); + double elapsed_time = time_diff_in_ms( elapsed_time_start , elapsed_time_end ); + cout << steps << " steps in " << elapsed_time/1000 << " s (energy: " << lattice.energy( q , p ) << ")" << endl; +} diff --git a/src/boost/libs/numeric/odeint/examples/2d_lattice/vector_vector_resize.hpp b/src/boost/libs/numeric/odeint/examples/2d_lattice/vector_vector_resize.hpp new file mode 100644 index 000000000..7132aa59d --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/2d_lattice/vector_vector_resize.hpp @@ -0,0 +1,105 @@ +/* + Copyright 2011 Mario Mulansky + Copyright 2012 Karsten Ahnert + + 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) + */ + + +/* reserved vector */ + +#ifndef VECTOR_VECTOR_RESIZE_HPP +#define VECTOR_VECTOR_RESIZE_HPP + +#include <vector> + +#include <boost/range.hpp> + +namespace boost { namespace numeric { namespace odeint { + +template<> +struct is_resizeable< std::vector< std::vector< double > > > +{ + typedef boost::true_type type; + const static bool value = type::value; +}; + +template<> +struct same_size_impl< std::vector< std::vector< double > > , std::vector< std::vector< double > > > +{ + typedef std::vector< std::vector< double > > state_type; + + static bool same_size( const state_type &x1 , + const state_type &x2 ) + { + bool same = ( boost::size( x1 ) == boost::size( x2 ) ); + if( !same ) + return false; + typename state_type::const_iterator begin1 = boost::begin( x1 ); + typename state_type::const_iterator begin2 = boost::begin( x2 ); + while( begin1 != boost::end( x1 ) ) + same &= ( boost::size( *begin1++ ) == boost::size( *begin2++ ) ); + return same; + } +}; + +template<> +struct resize_impl< std::vector< std::vector< double > > , std::vector< std::vector< double > > > +{ + typedef std::vector< std::vector< double > > state_type; + + static void resize( state_type &x1 , const state_type &x2 ) + { + x1.resize( boost::size( x2 ) ); + typename state_type::iterator begin1 = boost::begin( x1 ); + typename state_type::const_iterator begin2 = boost::begin( x2 ); + while( begin1 != boost::end( x1 ) ) + (*begin1++).resize( boost::size( *begin2++ ) ); + } +}; + +template<> +struct state_wrapper< std::vector< std::vector< double > > > +{ + typedef std::vector< std::vector< double > > state_type; + typedef state_wrapper< state_type > state_wrapper_type; + typedef boost::true_type is_resizeable; + + state_type m_v; + + template< class State > + bool same_size( const State &x ) + { + bool same = ( boost::size( m_v ) == boost::size( x ) ); + if( !same ) + return false; + typename state_type::iterator begin1 = boost::begin( m_v ); + typename State::const_iterator begin2 = boost::begin( x ); + while( begin1 != boost::end( m_v ) ) + same &= ( boost::size( *begin1++ ) == boost::size( *begin2++ ) ); + return same; + } + + template< class State > + bool resize( const State &x ) + { + if( !same_size( x ) ) + { + m_v.resize( boost::size( x ) ); + typename state_type::iterator begin1 = boost::begin( m_v ); + typename State::const_iterator begin2 = boost::begin( x ); + while( begin1 != boost::end( m_v ) ) + (*begin1++).resize( boost::size( *begin2++ ) ); + + return true; + } else + return false; + } + +}; + +} } } + +#endif diff --git a/src/boost/libs/numeric/odeint/examples/Jamfile.v2 b/src/boost/libs/numeric/odeint/examples/Jamfile.v2 new file mode 100644 index 000000000..11813c847 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/Jamfile.v2 @@ -0,0 +1,51 @@ +# Copyright 2009-2013 Karsten Ahnert +# Copyright 2010-2013 Mario Mulansky +# Copyright 2013 Pascal Germroth +# 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) + + +project + : requirements + <define>BOOST_ALL_NO_LIB=1 + : + ; + + +exe harmonic_oscillator : harmonic_oscillator.cpp ; +exe solar_system : solar_system.cpp ; +exe chaotic_system : chaotic_system.cpp ; +exe stiff_system : stiff_system.cpp ; +exe fpu : fpu.cpp ; +exe phase_oscillator_ensemble : phase_oscillator_ensemble.cpp ; +exe harmonic_oscillator_units : harmonic_oscillator_units.cpp : <toolset>clang:<build>no ; +exe stuart_landau : stuart_landau.cpp ; +exe two_dimensional_phase_lattice : two_dimensional_phase_lattice.cpp ; +exe bulirsch_stoer : bulirsch_stoer.cpp ; +exe elliptic_functions : elliptic_functions.cpp ; +exe resizing_lattice : resizing_lattice.cpp ; +exe list_lattice : list_lattice.cpp ; +exe stepper_details : stepper_details.cpp ; +exe my_vector : my_vector.cpp ; +exe lorenz : lorenz.cpp ; +exe lorenz_point : lorenz_point.cpp ; +exe van_der_pol_stiff : van_der_pol_stiff.cpp ; +exe simple1d : simple1d.cpp ; +exe stochastic_euler : stochastic_euler.cpp ; +exe generation_functions : generation_functions.cpp ; +exe heun : heun.cpp ; +exe bind_member_functions : bind_member_functions.cpp ; +exe bind_member_functions_cpp11 : bind_member_functions_cpp11.cpp : <cxxflags>-std=c++0x ; +exe molecular_dynamics : molecular_dynamics.cpp : <cxxflags>-std=c++0x ; +exe molecular_dynamics_cells : molecular_dynamics_cells.cpp : <cxxflags>-std=c++0x ; +exe abm_precision : abm_precision.cpp ; +exe integrate_times : integrate_times.cpp ; +exe find_crossing : find_crossing.cpp : <cxxflags>-std=c++0x ; + +build-project multiprecision ; +# build-project mtl ; +# build-project ublas ; +# build-project gmpxx ; +# build-project openmp ; +# build-project mpi ; diff --git a/src/boost/libs/numeric/odeint/examples/abm_precision.cpp b/src/boost/libs/numeric/odeint/examples/abm_precision.cpp new file mode 100644 index 000000000..747919f32 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/abm_precision.cpp @@ -0,0 +1,84 @@ +/* + * abm_precision.cpp + * + * example to check the order of the multi-step methods + * + * Copyright 2009-2013 Karsten Ahnert + * Copyright 2009-2013 Mario Mulansky + * + * 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) + */ + +#include <iostream> +#include <cmath> + +#include <boost/array.hpp> +#include <boost/numeric/odeint.hpp> + +using namespace boost::numeric::odeint; + +const int Steps = 4; + +typedef double value_type; + +typedef boost::array< double , 2 > state_type; + +typedef runge_kutta_fehlberg78<state_type> initializing_stepper_type; +typedef adams_bashforth_moulton< Steps , state_type > stepper_type; +//typedef adams_bashforth< Steps , state_type > stepper_type; + +// harmonic oscillator, analytic solution x[0] = sin( t ) +struct osc +{ + void operator()( const state_type &x , state_type &dxdt , const double t ) const + { + dxdt[0] = x[1]; + dxdt[1] = -x[0]; + } +}; + +int main() +{ + stepper_type stepper; + initializing_stepper_type init_stepper; + const int o = stepper.order()+1; //order of the error is order of approximation + 1 + + const state_type x0 = {{ 0.0 , 1.0 }}; + state_type x1 = x0; + double t = 0.0; + double dt = 0.25; + // initialization, does a number of steps already to fill internal buffer, t is increased + // we use the rk78 as initializing stepper + stepper.initialize( boost::ref(init_stepper) , osc() , x1 , t , dt ); + // do a number of steps to fill the buffer with results from adams bashforth + for( size_t n=0 ; n < stepper.steps ; ++n ) + { + stepper.do_step( osc() , x1 , t , dt ); + t += dt; + } + double A = std::sqrt( x1[0]*x1[0] + x1[1]*x1[1] ); + double phi = std::asin(x1[0]/A) - t; + // now we do the actual step + stepper.do_step( osc() , x1 , t , dt ); + // only examine the error of the adams-bashforth-moulton step, not the initialization + const double f = 2.0 * std::abs( A*sin(t+dt+phi) - x1[0] ) / std::pow( dt , o ); // upper bound + + std::cout << "# " << o << " , " << f << std::endl; + + /* as long as we have errors above machine precision */ + while( f*std::pow( dt , o ) > 1E-16 ) + { + x1 = x0; + t = 0.0; + stepper.initialize( boost::ref(init_stepper) , osc() , x1 , t , dt ); + A = std::sqrt( x1[0]*x1[0] + x1[1]*x1[1] ); + phi = std::asin(x1[0]/A) - t; + // now we do the actual step + stepper.do_step( osc() , x1 , t , dt ); + // only examine the error of the adams-bashforth-moulton step, not the initialization + std::cout << dt << '\t' << std::abs( A*sin(t+dt+phi) - x1[0] ) << std::endl; + dt *= 0.5; + } +} diff --git a/src/boost/libs/numeric/odeint/examples/adaptive_iterator.cpp b/src/boost/libs/numeric/odeint/examples/adaptive_iterator.cpp new file mode 100644 index 000000000..343699de3 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/adaptive_iterator.cpp @@ -0,0 +1,361 @@ +/* + * adaptive_iterator.cpp + * + * Copyright 2012-2013 Karsten Ahnert + * Copyright 2012 Mario Mulansky + * + * 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) + */ + + + +#include <iostream> +#include <iterator> +#include <utility> +#include <algorithm> +#include <cassert> + +#include <boost/array.hpp> + +#include <boost/range/algorithm.hpp> +#include <boost/range/adaptor/filtered.hpp> +#include <boost/range/numeric.hpp> + +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp> +#include <boost/numeric/odeint/stepper/generation.hpp> + +#include <boost/numeric/odeint/iterator/adaptive_iterator.hpp> +#include <boost/numeric/odeint/iterator/adaptive_time_iterator.hpp> + +#define tab "\t" + +using namespace std; +using namespace boost::numeric::odeint; + +const double sigma = 10.0; +const double R = 28.0; +const double b = 8.0 / 3.0; + +struct lorenz +{ + template< class State , class Deriv > + void operator()( const State &x , Deriv &dxdt , double t ) const + { + dxdt[0] = sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = -b * x[2] + x[0] * x[1]; + } +}; + +#include <typeinfo> + +int main( int argc , char **argv ) +{ + typedef boost::array< double , 3 > state_type; + + /* + * Controlled steppers with time iterator + */ + + // std::for_each + { + auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() ); + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + std::for_each( make_adaptive_time_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , + make_adaptive_time_iterator_end( stepper , lorenz() , x ) , + []( const std::pair< const state_type&, double > &x ) { + std::cout << x.second << tab << x.first[0] << tab << x.first[1] << tab << x.first[2] << "\n"; } ); + } + + // std::copy_if + { + std::vector< pair< state_type , double > > res; + auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() ); + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + std::copy_if( make_adaptive_time_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , + make_adaptive_time_iterator_end( stepper , lorenz() , x ) , + std::back_inserter( res ) , + []( const pair< const state_type& , double > &x ) { + return ( x.first[0] > 0.0 ) ? true : false; } ); + for( size_t i=0 ; i<res.size() ; ++i ) + cout << res[i].first[0] << tab << res[i].first[1] << tab << res[i].first[2] << "\n"; + } + + // std::accumulate + { + auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() ); + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + double res = std::accumulate( make_adaptive_time_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , + make_adaptive_time_iterator_end( stepper , lorenz() , x ) , + 0.0 , + []( double sum , const pair< const state_type& , double > &x ) { + return sum + x.first[0]; } ); + cout << res << endl; + } + + + // std::transform + { + auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() ); + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + vector< double > weights; + std::transform( make_adaptive_time_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , + make_adaptive_time_iterator_end( stepper , lorenz() , x ) , + back_inserter( weights ) , + []( const pair< const state_type& , double > &x ) { + return sqrt( x.first[0] * x.first[0] + x.first[1] * x.first[1] + x.first[2] * x.first[2] ); } ); + for( size_t i=0 ; i<weights.size() ; ++i ) + cout << weights[i] << "\n"; + } + + + + + + + + + + + + + + /* + * Boost.Range versions of controlled stepper with time iterator + */ + + + // boost::range::for_each + { + auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() ); + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + boost::range::for_each( make_adaptive_time_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , + []( const std::pair< const state_type& , double > &x ) { + std::cout << x.second << tab << x.first[0] << tab << x.first[1] << tab << x.first[2] << "\n"; } ); + } + + + // boost::range::copy with filtered adaptor (simulating std::copy_if) + { + auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() ); + std::vector< std::pair< state_type , double > > res; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + boost::range::copy( make_adaptive_time_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) | + boost::adaptors::filtered( [] ( const pair< const state_type& , double > &x ) { return ( x.first[0] > 0.0 ); } ) , + std::back_inserter( res ) ); + for( size_t i=0 ; i<res.size() ; ++i ) + cout << res[i].first[0] << tab << res[i].first[1] << tab << res[i].first[2] << "\n"; + } + + // boost::range::accumulate + { + //[adaptive_time_iterator_accumulate_range + auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() ); + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + double res = boost::accumulate( make_adaptive_time_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , 0.0 , + []( double sum , const pair< const state_type& , double > &x ) { + return sum + x.first[0]; } ); + cout << res << endl; + //] + } + + + // boost::range::transform + { + auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() ); + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + vector< double > weights; + boost::transform( make_adaptive_time_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , back_inserter( weights ) , + []( const pair< const state_type& , double > &x ) { + return sqrt( x.first[0] * x.first[0] + x.first[1] * x.first[1] + x.first[2] * x.first[2] ); } ); + for( size_t i=0 ; i<weights.size() ; ++i ) + cout << weights[i] << "\n"; + } + + + // boost::range::find with time iterator + { + auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() ); + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + auto iter = boost::find_if( make_adaptive_time_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , + []( const std::pair< const state_type & , double > &x ) { + return ( x.first[0] < 0.0 ); } ); + cout << iter->second << "\t" << iter->first[0] << "\t" << iter->first[1] << "\t" << iter->first[2] << "\n"; + } + + + + + + + + + + + + + // /* + // * Boost.Range versions for dense output steppers + // */ + + // // boost::range::for_each + // { + // runge_kutta_dopri5< state_type > stepper; + // state_type x = {{ 10.0 , 10.0 , 10.0 }}; + // boost::range::for_each( make_adaptive_range( make_dense_output( 1.0e-6 , 1.0e-6 , stepper ) , lorenz() , x , 0.0 , 1.0 , 0.01 ) , + // []( const state_type &x ) { + // std::cout << x[0] << tab << x[1] << tab << x[2] << "\n"; } ); + // } + + + // // boost::range::for_each with time iterator + // { + // runge_kutta_dopri5< state_type > stepper; + // state_type x = {{ 10.0 , 10.0 , 10.0 }}; + // boost::range::for_each( make_adaptive_time_range( make_dense_output( 1.0e-6 , 1.0e-6 , stepper ) , lorenz() , x , 0.0 , 1.0 , 0.01 ) , + // []( const std::pair< state_type& , double > &x ) { + // std::cout << x.second << tab << x.first[0] << tab << x.first[1] << tab << x.first[2] << "\n"; } ); + + // } + + + + + + /* + * Pure iterators for controlled stepper without time iterator + */ + + // std::for_each + { + auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() ); + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + std::for_each( make_adaptive_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , + make_adaptive_iterator_end( stepper , lorenz() , x ) , + []( const state_type& x ) { + std::cout << x[0] << tab << x[1] << tab << x[2] << "\n"; } ); + } + + // std::copy_if + { + std::vector< state_type > res; + auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() ); + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + std::copy_if( make_adaptive_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , + make_adaptive_iterator_end( stepper , lorenz() , x ) , + std::back_inserter( res ) , + []( const state_type& x ) { + return ( x[0] > 0.0 ) ? true : false; } ); + for( size_t i=0 ; i<res.size() ; ++i ) + cout << res[i][0] << tab << res[i][1] << tab << res[i][2] << "\n"; + } + + // std::accumulate + { + auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() ); + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + double res = std::accumulate( make_adaptive_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , + make_adaptive_iterator_end( stepper , lorenz() , x ) , + 0.0 , + []( double sum , const state_type& x ) { + return sum + x[0]; } ); + cout << res << endl; + } + + + // std::transform + { + auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() ); + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + vector< double > weights; + std::transform( make_adaptive_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , + make_adaptive_iterator_end( stepper , lorenz() , x ) , + back_inserter( weights ) , + []( const state_type& x ) { + return sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] ); } ); + for( size_t i=0 ; i<weights.size() ; ++i ) + cout << weights[i] << "\n"; + } + + + + + + + + + + + /* + * Boost.Range versions of controlled stepper WITHOUT time iterator + */ + + + // boost::range::for_each + { + auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() ); + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + boost::range::for_each( make_adaptive_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , + []( const state_type &x ) { + std::cout << x[0] << tab << x[1] << tab << x[2] << "\n"; } ); + } + + + // boost::range::copy with filtered adaptor (simulating std::copy_if) + { + auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() ); + std::vector< state_type > res; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + boost::range::copy( make_adaptive_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) | + boost::adaptors::filtered( [] ( const state_type& x ) { return ( x[0] > 0.0 ); } ) , + std::back_inserter( res ) ); + for( size_t i=0 ; i<res.size() ; ++i ) + cout << res[i][0] << tab << res[i][1] << tab << res[i][2] << "\n"; + } + + // boost::range::accumulate + { + //[adaptive_iterator_accumulate_range + auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() ); + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + double res = boost::accumulate( make_adaptive_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , 0.0 , + []( double sum , const state_type& x ) { + return sum + x[0]; } ); + cout << res << endl; + //] + } + + + // boost::range::transform + { + auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() ); + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + vector< double > weights; + boost::transform( make_adaptive_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , back_inserter( weights ) , + []( const state_type& x ) { + return sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] ); } ); + for( size_t i=0 ; i<weights.size() ; ++i ) + cout << weights[i] << "\n"; + } + + + // boost::range::find + { + auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() ); + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + auto iter = boost::find_if( make_adaptive_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , + []( const state_type &x ) { + return ( x[0] < 0.0 ); } ); + cout << (*iter)[0] << "\t" << (*iter)[1] << "\t" << (*iter)[2] << "\n"; + } + + + + + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/bind_member_functions.cpp b/src/boost/libs/numeric/odeint/examples/bind_member_functions.cpp new file mode 100644 index 000000000..51f85e033 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/bind_member_functions.cpp @@ -0,0 +1,126 @@ +/* + [auto_generated] + libs/numeric/odeint/examples/bind_member_functions.hpp + + [begin_description] + tba. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2012 Mario Mulansky + + 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) + */ + +#include <iostream> + +#include <boost/numeric/odeint.hpp> + +namespace odeint = boost::numeric::odeint; + +typedef boost::array< double , 3 > state_type; + +//[ ode_wrapper +template< class Obj , class Mem > +class ode_wrapper +{ + Obj m_obj; + Mem m_mem; + +public: + + ode_wrapper( Obj obj , Mem mem ) : m_obj( obj ) , m_mem( mem ) { } + + template< class State , class Deriv , class Time > + void operator()( const State &x , Deriv &dxdt , Time t ) + { + (m_obj.*m_mem)( x , dxdt , t ); + } +}; + +template< class Obj , class Mem > +ode_wrapper< Obj , Mem > make_ode_wrapper( Obj obj , Mem mem ) +{ + return ode_wrapper< Obj , Mem >( obj , mem ); +} +//] + + +template< class Obj , class Mem > +class observer_wrapper +{ + Obj m_obj; + Mem m_mem; + +public: + + observer_wrapper( Obj obj , Mem mem ) : m_obj( obj ) , m_mem( mem ) { } + + template< class State , class Time > + void operator()( const State &x , Time t ) + { + (m_obj.*m_mem)( x , t ); + } +}; + +template< class Obj , class Mem > +observer_wrapper< Obj , Mem > make_observer_wrapper( Obj obj , Mem mem ) +{ + return observer_wrapper< Obj , Mem >( obj , mem ); +} + + + +//[ bind_member_function +struct lorenz +{ + void ode( const state_type &x , state_type &dxdt , double t ) const + { + dxdt[0] = 10.0 * ( x[1] - x[0] ); + dxdt[1] = 28.0 * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = -8.0 / 3.0 * x[2] + x[0] * x[1]; + } +}; + +int main( int argc , char *argv[] ) +{ + using namespace boost::numeric::odeint; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + integrate_const( runge_kutta4< state_type >() , make_ode_wrapper( lorenz() , &lorenz::ode ) , + x , 0.0 , 10.0 , 0.01 ); + return 0; +} +//] + + +/* +struct lorenz +{ + void ode( const state_type &x , state_type &dxdt , double t ) const + { + dxdt[0] = 10.0 * ( x[1] - x[0] ); + dxdt[1] = 28.0 * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = -8.0 / 3.0 * x[2] + x[0] * x[1]; + } + + void obs( const state_type &x , double t ) const + { + std::cout << t << " " << x[0] << " " << x[1] << " " << x[2] << "\n"; + } +}; + +int main( int argc , char *argv[] ) +{ + using namespace boost::numeric::odeint; + + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + integrate_const( runge_kutta4< state_type >() , + make_ode_wrapper( lorenz() , &lorenz::ode ) , + x , 0.0 , 10.0 , 0.01 , + make_observer_wrapper( lorenz() , &lorenz::obs ) ); + + return 0; +} +*/ diff --git a/src/boost/libs/numeric/odeint/examples/bind_member_functions_cpp11.cpp b/src/boost/libs/numeric/odeint/examples/bind_member_functions_cpp11.cpp new file mode 100644 index 000000000..177dded7a --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/bind_member_functions_cpp11.cpp @@ -0,0 +1,56 @@ +/* + [auto_generated] + libs/numeric/odeint/examples/bind_member_functions.hpp + + [begin_description] + tba. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2012 Mario Mulansky + + 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) + */ + +#include <iostream> +#include <array> +#include <type_traits> + +#include <boost/numeric/odeint.hpp> + +namespace odeint = boost::numeric::odeint; + + + +typedef std::array< double , 3 > state_type; + +struct lorenz +{ + void ode( const state_type &x , state_type &dxdt , double t ) const + { + const double sigma = 10.0; + const double R = 28.0; + const double b = 8.0 / 3.0; + + dxdt[0] = sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = -b * x[2] + x[0] * x[1]; + } +}; + +int main( int argc , char *argv[] ) +{ + using namespace boost::numeric::odeint; + //[ bind_member_function_cpp11 + namespace pl = std::placeholders; + + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + integrate_const( runge_kutta4< state_type >() , + std::bind( &lorenz::ode , lorenz() , pl::_1 , pl::_2 , pl::_3 ) , + x , 0.0 , 10.0 , 0.01 ); + //] + return 0; +} + diff --git a/src/boost/libs/numeric/odeint/examples/bulirsch_stoer.cpp b/src/boost/libs/numeric/odeint/examples/bulirsch_stoer.cpp new file mode 100644 index 000000000..0b18f46e9 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/bulirsch_stoer.cpp @@ -0,0 +1,100 @@ +/* + * bulirsch_stoer.cpp + * + * Copyright 2011-2013 Mario Mulansky + * Copyright 2011-2012 Karsten Ahnert + * + * 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) + */ + +#include <iostream> +#include <fstream> +#define _USE_MATH_DEFINES +#include <cmath> + +#include <boost/array.hpp> +#include <boost/ref.hpp> + +#include <boost/numeric/odeint/config.hpp> + +#include <boost/numeric/odeint.hpp> +#include <boost/numeric/odeint/stepper/bulirsch_stoer.hpp> +#include <boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp> + +using namespace std; +using namespace boost::numeric::odeint; + +typedef boost::array< double , 1 > state_type; + +/* + * x' = ( - x*sin t + 2 tan x ) y + * with x( pi/6 ) = 2/sqrt(3) the analytic solution is 1/cos t + */ + +void rhs( const state_type &x , state_type &dxdt , const double t ) +{ + dxdt[0] = ( - x[0] * sin( t ) + 2.0 * tan( t ) ) * x[0]; +} + +void rhs2( const state_type &x , state_type &dxdt , const double t ) +{ + dxdt[0] = sin(t); +} + + +ofstream out; + +void write_out( const state_type &x , const double t ) +{ + out << t << '\t' << x[0] << endl; +} + +int main() +{ + bulirsch_stoer_dense_out< state_type > stepper( 1E-8 , 0.0 , 0.0 , 0.0 ); + bulirsch_stoer< state_type > stepper2( 1E-8 , 0.0 , 0.0 , 0.0 ); + + state_type x = {{ 2.0 / sqrt(3.0) }}; + + double t = M_PI/6.0; + //double t = 0.0; + double dt = 0.01; + double t_end = M_PI/2.0 - 0.1; + //double t_end = 100.0; + + out.open( "bs.dat" ); + out.precision(16); + integrate_const( stepper , rhs , x , t , t_end , dt , write_out ); + out.close(); + + x[0] = 2.0 / sqrt(3.0); + + out.open( "bs2.dat" ); + out.precision(16); + integrate_adaptive( stepper , rhs , x , t , t_end , dt , write_out ); + out.close(); + + x[0] = 2.0 / sqrt(3.0); + + out.open( "bs3.dat" ); + out.precision(16); + integrate_adaptive( stepper2 , rhs , x , t , t_end , dt , write_out ); + out.close(); + + + typedef runge_kutta_dopri5< state_type > dopri5_type; + typedef controlled_runge_kutta< dopri5_type > controlled_dopri5_type; + typedef dense_output_runge_kutta< controlled_dopri5_type > dense_output_dopri5_type; + + dense_output_dopri5_type dopri5 = make_dense_output( 1E-9 , 1E-9 , dopri5_type() ); + + x[0] = 2.0 / sqrt(3.0); + + out.open( "bs4.dat" ); + out.precision(16); + integrate_adaptive( dopri5 , rhs , x , t , t_end , dt , write_out ); + out.close(); + +} diff --git a/src/boost/libs/numeric/odeint/examples/chaotic_system.cpp b/src/boost/libs/numeric/odeint/examples/chaotic_system.cpp new file mode 100644 index 000000000..607846898 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/chaotic_system.cpp @@ -0,0 +1,119 @@ +/* + * chaotic_system.cpp + * + * This example demonstrates how one can use odeint to determine the Lyapunov + * exponents of a chaotic system namely the well known Lorenz system. Furthermore, + * it shows how odeint interacts with boost.range. + * + * Copyright 2011-2012 Karsten Ahnert + * Copyright 2011-2013 Mario Mulansky + * + * 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) + */ + + +#include <iostream> +#include <boost/array.hpp> + +#include <boost/numeric/odeint.hpp> + +#include "gram_schmidt.hpp" + +using namespace std; +using namespace boost::numeric::odeint; + + +const double sigma = 10.0; +const double R = 28.0; +const double b = 8.0 / 3.0; + +//[ system_function_without_perturbations +struct lorenz +{ + template< class State , class Deriv > + void operator()( const State &x_ , Deriv &dxdt_ , double t ) const + { + typename boost::range_iterator< const State >::type x = boost::begin( x_ ); + typename boost::range_iterator< Deriv >::type dxdt = boost::begin( dxdt_ ); + + dxdt[0] = sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = -b * x[2] + x[0] * x[1]; + } +}; +//] + + + +//[ system_function_with_perturbations +const size_t n = 3; +const size_t num_of_lyap = 3; +const size_t N = n + n*num_of_lyap; + +typedef boost::array< double , N > state_type; +typedef boost::array< double , num_of_lyap > lyap_type; + +void lorenz_with_lyap( const state_type &x , state_type &dxdt , double t ) +{ + lorenz()( x , dxdt , t ); + + for( size_t l=0 ; l<num_of_lyap ; ++l ) + { + const double *pert = x.begin() + 3 + l * 3; + double *dpert = dxdt.begin() + 3 + l * 3; + dpert[0] = - sigma * pert[0] + 10.0 * pert[1]; + dpert[1] = ( R - x[2] ) * pert[0] - pert[1] - x[0] * pert[2]; + dpert[2] = x[1] * pert[0] + x[0] * pert[1] - b * pert[2]; + } +} +//] + + + + + +int main( int argc , char **argv ) +{ + state_type x; + lyap_type lyap; + + fill( x.begin() , x.end() , 0.0 ); + x[0] = 10.0 ; x[1] = 10.0 ; x[2] = 5.0; + + const double dt = 0.01; + + //[ integrate_transients_with_range + // explicitly choose range_algebra to override default choice of array_algebra + runge_kutta4< state_type , double , state_type , double , range_algebra > rk4; + + // perform 10000 transient steps + integrate_n_steps( rk4 , lorenz() , std::make_pair( x.begin() , x.begin() + n ) , 0.0 , dt , 10000 ); + //] + + //[ lyapunov_full_code + fill( x.begin()+n , x.end() , 0.0 ); + for( size_t i=0 ; i<num_of_lyap ; ++i ) x[n+n*i+i] = 1.0; + fill( lyap.begin() , lyap.end() , 0.0 ); + + double t = 0.0; + size_t count = 0; + while( true ) + { + + t = integrate_n_steps( rk4 , lorenz_with_lyap , x , t , dt , 100 ); + gram_schmidt< num_of_lyap >( x , lyap , n ); + ++count; + + if( !(count % 100000) ) + { + cout << t; + for( size_t i=0 ; i<num_of_lyap ; ++i ) cout << "\t" << lyap[i] / t ; + cout << endl; + } + } + //] + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/const_step_iterator.cpp b/src/boost/libs/numeric/odeint/examples/const_step_iterator.cpp new file mode 100644 index 000000000..fc393037e --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/const_step_iterator.cpp @@ -0,0 +1,296 @@ +/* + * const_step_iterator.cpp + * + * Copyright 2012-2013 Karsten Ahnert + * Copyright 2013 Mario Mulansky + * + * 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) + * + * several examples for using iterators + */ + + +#include <iostream> +#include <iterator> +#include <utility> +#include <algorithm> +#include <array> +#include <cassert> + +#include <boost/range/algorithm.hpp> +#include <boost/range/adaptor/filtered.hpp> +#include <boost/range/numeric.hpp> + +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/generation.hpp> +#include <boost/numeric/odeint/iterator/const_step_iterator.hpp> +#include <boost/numeric/odeint/iterator/const_step_time_iterator.hpp> + +#define tab "\t" + +using namespace std; +using namespace boost::numeric::odeint; + +const double sigma = 10.0; +const double R = 28.0; +const double b = 8.0 / 3.0; + +struct lorenz +{ + template< class State , class Deriv > + void operator()( const State &x , Deriv &dxdt , double t ) const + { + dxdt[0] = sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = -b * x[2] + x[0] * x[1]; + } +}; + + + +int main( int argc , char **argv ) +{ + typedef std::array< double , 3 > state_type; + + // std::for_each + { + runge_kutta4< state_type > stepper; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + std::for_each( make_const_step_time_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , + make_const_step_time_iterator_end( stepper , lorenz() , x ) , + []( const std::pair< const state_type&, double > &x ) { + std::cout << x.second << tab << x.first[0] << tab << x.first[1] << tab << x.first[2] << "\n"; } ); + } + + // std::copy_if + { + std::vector< state_type > res; + runge_kutta4< state_type > stepper; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + std::copy_if( make_const_step_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , + make_const_step_iterator_end( stepper , lorenz() , x ) , + std::back_inserter( res ) , + []( const state_type& x ) { + return ( x[0] > 0.0 ) ? true : false; } ); + for( size_t i=0 ; i<res.size() ; ++i ) + cout << res[i][0] << tab << res[i][1] << tab << res[i][2] << "\n"; + } + + // std::accumulate + { + //[ const_step_iterator_accumulate + runge_kutta4< state_type > stepper; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + double res = std::accumulate( make_const_step_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , + make_const_step_iterator_end( stepper , lorenz() , x ) , + 0.0 , + []( double sum , const state_type &x ) { + return sum + x[0]; } ); + cout << res << endl; + //] + } + + + // std::transform + { + runge_kutta4< state_type > stepper; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + vector< double > weights; + std::transform( make_const_step_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , + make_const_step_iterator_end( stepper , lorenz() , x ) , + back_inserter( weights ) , + []( const state_type &x ) { + return sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] ); } ); + for( size_t i=0 ; i<weights.size() ; ++i ) + cout << weights[i] << "\n"; + } + + + + // std::transform with time_iterator + { + runge_kutta4< state_type > stepper; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + vector< double > weights; + std::transform( make_const_step_time_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , + make_const_step_time_iterator_end( stepper , lorenz() , x ) , + back_inserter( weights ) , + []( const std::pair< const state_type &, double > &x ) { + return sqrt( x.first[0] * x.first[0] + x.first[1] * x.first[1] + x.first[2] * x.first[2] ); } ); + for( size_t i=0 ; i<weights.size() ; ++i ) + cout << weights[i] << "\n"; + } + + + + + + + + + + + // /* + // * Boost.Range versions + // */ + + + // boost::range::for_each + { + runge_kutta4< state_type > stepper; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + boost::range::for_each( make_const_step_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , + []( const state_type &x ) { + std::cout << x[0] << tab << x[1] << tab << x[2] << "\n"; } ); + } + + // boost::range::for_each with time iterator + { + runge_kutta4< state_type > stepper; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + boost::range::for_each( make_const_step_time_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , + []( const std::pair< const state_type& , double > &x ) { + std::cout << x.second << tab << x.first[0] << tab << x.first[1] << tab << x.first[2] << "\n"; } ); + } + + + // boost::range::copy with filtered adaptor (simulating std::copy_if) + { + std::vector< state_type > res; + runge_kutta4< state_type > stepper; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + boost::range::copy( make_const_step_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) | + boost::adaptors::filtered( [] ( const state_type &x ) { return ( x[0] > 0.0 ); } ) , + std::back_inserter( res ) ); + for( size_t i=0 ; i<res.size() ; ++i ) + cout << res[i][0] << tab << res[i][1] << tab << res[i][2] << "\n"; + } + + // boost::range::accumulate + { + //[const_step_iterator_accumulate_range + runge_kutta4< state_type > stepper; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + double res = boost::accumulate( make_const_step_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , 0.0 , + []( double sum , const state_type &x ) { + return sum + x[0]; } ); + cout << res << endl; + //] + } + + // boost::range::accumulate with time iterator + { + //[const_step_time_iterator_accumulate_range + runge_kutta4< state_type > stepper; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + double res = boost::accumulate( make_const_step_time_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , 0.0 , + []( double sum , const std::pair< const state_type &, double > &x ) { + return sum + x.first[0]; } ); + cout << res << endl; + //] + } + + + // boost::range::transform + { + runge_kutta4< state_type > stepper; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + vector< double > weights; + boost::transform( make_const_step_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , back_inserter( weights ) , + []( const state_type &x ) { + return sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] ); } ); + for( size_t i=0 ; i<weights.size() ; ++i ) + cout << weights[i] << "\n"; + } + + + // boost::range::find with time iterator + { + runge_kutta4< state_type > stepper; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + auto iter = boost::find_if( make_const_step_time_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , + []( const std::pair< const state_type & , double > &x ) { + return ( x.first[0] < 0.0 ); } ); + cout << iter->second << "\t" << iter->first[0] << "\t" << iter->first[1] << "\t" << iter->first[2] << "\n"; + + } + + + + + + + + + + + + + /* + * Boost.Range versions for dense output steppers + */ + + // boost::range::for_each + { + runge_kutta_dopri5< state_type > stepper; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + boost::range::for_each( make_const_step_range( make_dense_output( 1.0e-6 , 1.0e-6 , stepper ) , lorenz() , x , 0.0 , 1.0 , 0.01 ) , + []( const state_type &x ) { + std::cout << x[0] << tab << x[1] << tab << x[2] << "\n"; } ); + } + + + // boost::range::for_each with time iterator + { + runge_kutta_dopri5< state_type > stepper; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + boost::range::for_each( make_const_step_time_range( make_dense_output( 1.0e-6 , 1.0e-6 , stepper ) , lorenz() , x , 0.0 , 1.0 , 0.01 ) , + []( const std::pair< const state_type& , double > &x ) { + std::cout << x.second << tab << x.first[0] << tab << x.first[1] << tab << x.first[2] << "\n"; } ); + + } + + + + + + /* + * Pure iterators + */ + { + runge_kutta4< state_type > stepper; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + auto first = make_const_step_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ); + auto last = make_const_step_iterator_end( stepper , lorenz() , x ); + while( first != last ) + { + assert( last != first ); + cout << (*first)[0] << tab << (*first)[1] << tab << (*first)[2] << "\n"; + ++first; + } + } + + { + runge_kutta4< state_type > stepper; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + auto first = make_const_step_time_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ); + auto last = make_const_step_time_iterator_end( stepper , lorenz() , x ); + while( first != last ) + { + assert( last != first ); + cout << first->second << tab << first->first[0] << tab << first->first[1] << tab << first->first[2] << "\n"; + ++first; + } + } + + + + + + + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/elliptic.py b/src/boost/libs/numeric/odeint/examples/elliptic.py new file mode 100644 index 000000000..9f5f1d45c --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/elliptic.py @@ -0,0 +1,31 @@ +""" + Copyright 2011 Mario Mulansky + Copyright 2012 Karsten Ahnert + + Stochastic euler stepper example and Ornstein-Uhlenbeck process + + 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) +""" + + +from pylab import * +from scipy import special + +data1 = loadtxt("elliptic1.dat") +data2 = loadtxt("elliptic2.dat") +data3 = loadtxt("elliptic3.dat") + +sn1,cn1,dn1,phi1 = special.ellipj( data1[:,0] , 0.51 ) +sn2,cn2,dn2,phi2 = special.ellipj( data2[:,0] , 0.51 ) +sn3,cn3,dn3,phi3 = special.ellipj( data3[:,0] , 0.51 ) + +semilogy( data1[:,0] , abs(data1[:,1]-sn1) ) +semilogy( data2[:,0] , abs(data2[:,1]-sn2) , 'ro' ) +semilogy( data3[:,0] , abs(data3[:,1]-sn3) , '--' ) + +show() + + + diff --git a/src/boost/libs/numeric/odeint/examples/elliptic_functions.cpp b/src/boost/libs/numeric/odeint/examples/elliptic_functions.cpp new file mode 100644 index 000000000..97ba59da5 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/elliptic_functions.cpp @@ -0,0 +1,89 @@ +/* + * elliptic_functions.cpp + * + * Copyright 2011-2013 Mario Mulansky + * Copyright 2011-2012 Karsten Ahnert + * + * 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) + */ + + + + +#include <iostream> +#include <fstream> +#include <cmath> + +#include <boost/array.hpp> + +#include <boost/numeric/odeint/config.hpp> + +#include <boost/numeric/odeint.hpp> +#include <boost/numeric/odeint/stepper/bulirsch_stoer.hpp> +#include <boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp> + +using namespace std; +using namespace boost::numeric::odeint; + +typedef boost::array< double , 3 > state_type; + +/* + * x1' = x2*x3 + * x2' = -x1*x3 + * x3' = -m*x1*x2 + */ + +void rhs( const state_type &x , state_type &dxdt , const double t ) +{ + static const double m = 0.51; + + dxdt[0] = x[1]*x[2]; + dxdt[1] = -x[0]*x[2]; + dxdt[2] = -m*x[0]*x[1]; +} + +ofstream out; + +void write_out( const state_type &x , const double t ) +{ + out << t << '\t' << x[0] << '\t' << x[1] << '\t' << x[2] << endl; +} + +int main() +{ + bulirsch_stoer_dense_out< state_type > stepper( 1E-9 , 1E-9 , 1.0 , 0.0 ); + + state_type x1 = {{ 0.0 , 1.0 , 1.0 }}; + + double t = 0.0; + double dt = 0.01; + + out.open( "elliptic1.dat" ); + out.precision(16); + integrate_const( stepper , rhs , x1 , t , 100.0 , dt , write_out ); + out.close(); + + state_type x2 = {{ 0.0 , 1.0 , 1.0 }}; + + out.open( "elliptic2.dat" ); + out.precision(16); + integrate_adaptive( stepper , rhs , x2 , t , 100.0 , dt , write_out ); + out.close(); + + typedef runge_kutta_dopri5< state_type > dopri5_type; + typedef controlled_runge_kutta< dopri5_type > controlled_dopri5_type; + typedef dense_output_runge_kutta< controlled_dopri5_type > dense_output_dopri5_type; + + + dense_output_dopri5_type dopri5 = make_dense_output( 1E-9 , 1E-9 , dopri5_type() ); + //dense_output_dopri5_type dopri5( controlled_dopri5_type( default_error_checker< double >( 1E-9 , 0.0 , 0.0 , 0.0 ) ) ); + + state_type x3 = {{ 0.0 , 1.0 , 1.0 }}; + + out.open( "elliptic3.dat" ); + out.precision(16); + integrate_adaptive( dopri5 , rhs , x3 , t , 100.0 , dt , write_out ); + out.close(); +} diff --git a/src/boost/libs/numeric/odeint/examples/find_crossing.cpp b/src/boost/libs/numeric/odeint/examples/find_crossing.cpp new file mode 100644 index 000000000..a17ef4f97 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/find_crossing.cpp @@ -0,0 +1,134 @@ +/* + * find_crossing.cpp + * + * Finds the energy threshold crossing for a damped oscillator. + * The algorithm uses a dense out stepper with find_if to first find an + * interval containing the threshold crossing and the utilizes the dense out + * functionality with a bisection to further refine the interval until some + * desired precision is reached. + * + * Copyright 2015 Mario Mulansky + * + * 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) + */ + + + +#include <iostream> +#include <utility> +#include <algorithm> +#include <array> + +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/generation.hpp> +#include <boost/numeric/odeint/iterator/adaptive_iterator.hpp> + +namespace odeint = boost::numeric::odeint; + +typedef std::array<double, 2> state_type; + +const double gam = 1.0; // damping strength + +void damped_osc(const state_type &x, state_type &dxdt, const double /*t*/) +{ + dxdt[0] = x[1]; + dxdt[1] = -x[0] - gam * x[1]; +} + + +struct energy_condition { + + // defines the threshold crossing in terms of a boolean functor + + double m_min_energy; + + energy_condition(const double min_energy) + : m_min_energy(min_energy) { } + + double energy(const state_type &x) { + return 0.5 * x[1] * x[1] + 0.5 * x[0] * x[0]; + } + + bool operator()(const state_type &x) { + // becomes true if the energy becomes smaller than the threshold + return energy(x) <= m_min_energy; + } +}; + + +template<class System, class Condition> +std::pair<double, state_type> +find_condition(state_type &x0, System sys, Condition cond, + const double t_start, const double t_end, const double dt, + const double precision = 1E-6) { + + // integrates an ODE until some threshold is crossed + // returns time and state at the point of the threshold crossing + // if no threshold crossing is found, some time > t_end is returned + + auto stepper = odeint::make_dense_output(1.0e-6, 1.0e-6, + odeint::runge_kutta_dopri5<state_type>()); + + auto ode_range = odeint::make_adaptive_range(std::ref(stepper), sys, x0, + t_start, t_end, dt); + + // find the step where the condition changes + auto found_iter = std::find_if(ode_range.first, ode_range.second, cond); + + if(found_iter == ode_range.second) + { + // no threshold crossing -> return time after t_end and ic + return std::make_pair(t_end + dt, x0); + } + + // the dense out stepper now covers the interval where the condition changes + // improve the solution by bisection + double t0 = stepper.previous_time(); + double t1 = stepper.current_time(); + double t_m; + state_type x_m; + // use odeint's resizing functionality to allocate memory for x_m + odeint::adjust_size_by_resizeability(x_m, x0, + typename odeint::is_resizeable<state_type>::type()); + while(std::abs(t1 - t0) > precision) { + t_m = 0.5 * (t0 + t1); // get the mid point time + stepper.calc_state(t_m, x_m); // obtain the corresponding state + if (cond(x_m)) + t1 = t_m; // condition changer lies before midpoint + else + t0 = t_m; // condition changer lies after midpoint + } + // we found the interval of size eps, take it's midpoint as final guess + t_m = 0.5 * (t0 + t1); + stepper.calc_state(t_m, x_m); + return std::make_pair(t_m, x_m); +} + + +int main(int argc, char **argv) +{ + state_type x0 = {{10.0, 0.0}}; + const double t_start = 0.0; + const double t_end = 10.0; + const double dt = 0.1; + const double threshold = 0.1; + + energy_condition cond(threshold); + state_type x_cond; + double t_cond; + std::tie(t_cond, x_cond) = find_condition(x0, damped_osc, cond, + t_start, t_end, dt, 1E-6); + if(t_cond > t_end) + { + // time after t_end -> no threshold crossing within [t_start, t_end] + std::cout << "No threshold crossing found." << std::endl; + } else + { + std::cout.precision(16); + std::cout << "Time of energy threshold crossing: " << t_cond << std::endl; + std::cout << "State: [" << x_cond[0] << " , " << x_cond[1] << "]" << std::endl; + std::cout << "Energy: " << cond.energy(x_cond) << std::endl; + } +} diff --git a/src/boost/libs/numeric/odeint/examples/fpu.cpp b/src/boost/libs/numeric/odeint/examples/fpu.cpp new file mode 100644 index 000000000..e3ca9df44 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/fpu.cpp @@ -0,0 +1,169 @@ +/* + * fpu.cpp + * + * This example demonstrates how one can use odeint to solve the Fermi-Pasta-Ulam system. + + * Created on: July 13, 2011 + * + * Copyright 2011-2012 Karsten Ahnert + * Copyright 2011 Mario Mulansky + * 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) + */ + +#include <iostream> +#include <numeric> +#include <cmath> +#include <vector> + +#include <boost/numeric/odeint.hpp> + +#ifndef M_PI //not there on windows +#define M_PI 3.1415927 //... +#endif + +using namespace std; +using namespace boost::numeric::odeint; + +//[ fpu_system_function +typedef vector< double > container_type; + +struct fpu +{ + const double m_beta; + + fpu( const double beta = 1.0 ) : m_beta( beta ) { } + + // system function defining the ODE + void operator()( const container_type &q , container_type &dpdt ) const + { + size_t n = q.size(); + double tmp = q[0] - 0.0; + double tmp2 = tmp + m_beta * tmp * tmp * tmp; + dpdt[0] = -tmp2; + for( size_t i=0 ; i<n-1 ; ++i ) + { + tmp = q[i+1] - q[i]; + tmp2 = tmp + m_beta * tmp * tmp * tmp; + dpdt[i] += tmp2; + dpdt[i+1] = -tmp2; + } + tmp = - q[n-1]; + tmp2 = tmp + m_beta * tmp * tmp * tmp; + dpdt[n-1] += tmp2; + } + + // calculates the energy of the system + double energy( const container_type &q , const container_type &p ) const + { + // ... + //<- + double energy = 0.0; + size_t n = q.size(); + + double tmp = q[0]; + energy += 0.5 * tmp * tmp + 0.25 * m_beta * tmp * tmp * tmp * tmp; + for( size_t i=0 ; i<n-1 ; ++i ) + { + tmp = q[i+1] - q[i]; + energy += 0.5 * ( p[i] * p[i] + tmp * tmp ) + 0.25 * m_beta * tmp * tmp * tmp * tmp; + } + energy += 0.5 * p[n-1] * p[n-1]; + tmp = q[n-1]; + energy += 0.5 * tmp * tmp + 0.25 * m_beta * tmp * tmp * tmp * tmp; + + return energy; + //-> + } + + // calculates the local energy of the system + void local_energy( const container_type &q , const container_type &p , container_type &e ) const + { + // ... + //<- + size_t n = q.size(); + double tmp = q[0]; + double tmp2 = 0.5 * tmp * tmp + 0.25 * m_beta * tmp * tmp * tmp * tmp; + e[0] = tmp2; + for( size_t i=0 ; i<n-1 ; ++i ) + { + tmp = q[i+1] - q[i]; + tmp2 = 0.25 * tmp * tmp + 0.125 * m_beta * tmp * tmp * tmp * tmp; + e[i] += 0.5 * p[i] * p[i] + tmp2 ; + e[i+1] = tmp2; + } + tmp = q[n-1]; + tmp2 = 0.5 * tmp * tmp + 0.25 * m_beta * tmp * tmp * tmp * tmp; + e[n-1] += 0.5 * p[n-1] * p[n-1] + tmp2; + //-> + } +}; +//] + + + +//[ fpu_observer +struct streaming_observer +{ + std::ostream& m_out; + const fpu &m_fpu; + size_t m_write_every; + size_t m_count; + + streaming_observer( std::ostream &out , const fpu &f , size_t write_every = 100 ) + : m_out( out ) , m_fpu( f ) , m_write_every( write_every ) , m_count( 0 ) { } + + template< class State > + void operator()( const State &x , double t ) + { + if( ( m_count % m_write_every ) == 0 ) + { + container_type &q = x.first; + container_type &p = x.second; + container_type energy( q.size() ); + m_fpu.local_energy( q , p , energy ); + for( size_t i=0 ; i<q.size() ; ++i ) + { + m_out << t << "\t" << i << "\t" << q[i] << "\t" << p[i] << "\t" << energy[i] << "\n"; + } + m_out << "\n"; + clog << t << "\t" << accumulate( energy.begin() , energy.end() , 0.0 ) << "\n"; + } + ++m_count; + } +}; +//] + + + + + + + + +int main( int argc , char **argv ) +{ + //[ fpu_integration + const size_t n = 64; + container_type q( n , 0.0 ) , p( n , 0.0 ); + + for( size_t i=0 ; i<n ; ++i ) + { + p[i] = 0.0; + q[i] = 32.0 * sin( double( i + 1 ) / double( n + 1 ) * M_PI ); + } + + + const double dt = 0.1; + + typedef symplectic_rkn_sb3a_mclachlan< container_type > stepper_type; + fpu fpu_instance( 8.0 ); + + integrate_const( stepper_type() , fpu_instance , + make_pair( boost::ref( q ) , boost::ref( p ) ) , + 0.0 , 1000.0 , dt , streaming_observer( cout , fpu_instance , 10 ) ); + //] + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/generation_functions.cpp b/src/boost/libs/numeric/odeint/examples/generation_functions.cpp new file mode 100644 index 000000000..6baa5f22d --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/generation_functions.cpp @@ -0,0 +1,113 @@ +/* + libs/numeric/odeint/examples/stochastic_euler.hpp + + Copyright 2012 Karsten Ahnert + Copyright 2012-2013 Mario Mulansky + Copyright 2013 Pascal Germroth + + Stochastic euler stepper example and Ornstein-Uhlenbeck process + + 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) + */ + +#include <boost/array.hpp> + +#include <boost/numeric/odeint.hpp> + +typedef boost::array< double , 1 > state_type; + +using namespace boost::numeric::odeint; + + +//[ generation_functions_own_steppers +class custom_stepper +{ +public: + + typedef double value_type; + // ... +}; + +class custom_controller +{ + // ... +}; + +class custom_dense_output +{ + // ... +}; +//] + + +//[ generation_functions_get_controller +namespace boost { namespace numeric { namespace odeint { + +template<> +struct get_controller< custom_stepper > +{ + typedef custom_controller type; +}; + +} } } +//] + +//[ generation_functions_controller_factory +namespace boost { namespace numeric { namespace odeint { + +template<> +struct controller_factory< custom_stepper , custom_controller > +{ + custom_controller operator()( double abs_tol , double rel_tol , const custom_stepper & ) const + { + return custom_controller(); + } + + custom_controller operator()( double abs_tol , double rel_tol , double max_dt , + const custom_stepper & ) const + { + // version with maximal allowed step size max_dt + return custom_controller(); + } +}; + +} } } +//] + +int main( int argc , char **argv ) +{ + { + typedef runge_kutta_dopri5< state_type > stepper_type; + + /* + //[ generation_functions_syntax_auto + auto stepper1 = make_controlled( 1.0e-6 , 1.0e-6 , stepper_type() ); + // or with max step size limit: + // auto stepper1 = make_controlled( 1.0e-6 , 1.0e-6 , 0.01, stepper_type() ); + + auto stepper2 = make_dense_output( 1.0e-6 , 1.0e-6 , stepper_type() ); + //] + */ + + //[ generation_functions_syntax_result_of + boost::numeric::odeint::result_of::make_controlled< stepper_type >::type stepper3 = make_controlled( 1.0e-6 , 1.0e-6 , stepper_type() ); + (void)stepper3; + boost::numeric::odeint::result_of::make_dense_output< stepper_type >::type stepper4 = make_dense_output( 1.0e-6 , 1.0e-6 , stepper_type() ); + (void)stepper4; + //] + } + + { + /* + //[ generation_functions_example_custom_controller + auto stepper5 = make_controlled( 1.0e-6 , 1.0e-6 , custom_stepper() ); + //] + */ + + boost::numeric::odeint::result_of::make_controlled< custom_stepper >::type stepper5 = make_controlled( 1.0e-6 , 1.0e-6 , custom_stepper() ); + (void)stepper5; + } + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/gmpxx/Makefile b/src/boost/libs/numeric/odeint/examples/gmpxx/Makefile new file mode 100644 index 000000000..0a9f7cb01 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/gmpxx/Makefile @@ -0,0 +1,5 @@ +CXXFLAGS = -I${BOOST_ROOT} -O2 -static +LDFLAGS = -lgmpxx -lgmp + +lorenz_gmpxx: lorenz_gmpxx.cpp + ${CXX} ${CXXFLAGS} lorenz_gmpxx.cpp ${LDFLAGS} -o lorenz_gmpxx diff --git a/src/boost/libs/numeric/odeint/examples/gmpxx/lorenz_gmpxx.cpp b/src/boost/libs/numeric/odeint/examples/gmpxx/lorenz_gmpxx.cpp new file mode 100644 index 000000000..39b4c72e6 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/gmpxx/lorenz_gmpxx.cpp @@ -0,0 +1,83 @@ +/* + * lorenz_gmpxx.cpp + * + * This example demonstrates how odeint can be used with arbitrary precision types. + * + * Copyright 2011-2012 Karsten Ahnert + * Copyright 2011-2012 Mario Mulansky + * + * 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) + */ + + + +#include <iostream> +#include <boost/array.hpp> + +#include <gmpxx.h> + +#include <boost/numeric/odeint.hpp> + +using namespace std; +using namespace boost::numeric::odeint; + +//[ gmpxx_lorenz +typedef mpf_class value_type; +typedef boost::array< value_type , 3 > state_type; + +struct lorenz +{ + void operator()( const state_type &x , state_type &dxdt , value_type t ) const + { + const value_type sigma( 10.0 ); + const value_type R( 28.0 ); + const value_type b( value_type( 8.0 ) / value_type( 3.0 ) ); + + dxdt[0] = sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = -b * x[2] + x[0] * x[1]; + } +}; +//] + + + + +struct streaming_observer +{ + std::ostream& m_out; + + streaming_observer( std::ostream &out ) : m_out( out ) { } + + template< class State , class Time > + void operator()( const State &x , Time t ) const + { + m_out << t; + for( size_t i=0 ; i<x.size() ; ++i ) m_out << "\t" << x[i] ; + m_out << "\n"; + } +}; + + + + + + +int main( int argc , char **argv ) +{ + //[ gmpxx_integration + const int precision = 1024; + mpf_set_default_prec( precision ); + + state_type x = {{ value_type( 10.0 ) , value_type( 10.0 ) , value_type( 10.0 ) }}; + + cout.precision( 1000 ); + integrate_const( runge_kutta4< state_type , value_type >() , + lorenz() , x , value_type( 0.0 ) , value_type( 10.0 ) , value_type( value_type( 1.0 ) / value_type( 10.0 ) ) , + streaming_observer( cout ) ); + //] + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/gram_schmidt.hpp b/src/boost/libs/numeric/odeint/examples/gram_schmidt.hpp new file mode 100644 index 000000000..f5f56808b --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/gram_schmidt.hpp @@ -0,0 +1,89 @@ +/* + boost header: numeric/odeint/gram_schmitt.hpp + + Copyright 2011-2013 Karsten Ahnert + Copyright 2011 Mario Mulansky + + 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) + */ + +#ifndef BOOST_NUMERIC_ODEINT_GRAM_SCHMITT_HPP_INCLUDED +#define BOOST_NUMERIC_ODEINT_GRAM_SCHMITT_HPP_INCLUDED + +#include <boost/throw_exception.hpp> +#include <iterator> +#include <algorithm> +#include <numeric> + +namespace boost { +namespace numeric { +namespace odeint { + +template< class Iterator , class T > +void normalize( Iterator first , Iterator last , T norm ) +{ + while( first != last ) *first++ /= norm; +} + +template< class Iterator , class T > +void substract_vector( Iterator first1 , Iterator last1 , + Iterator first2 , T val ) +{ + while( first1 != last1 ) *first1++ -= val * ( *first2++ ); +} + +template< size_t num_of_lyap , class StateType , class LyapType > +void gram_schmidt( StateType &x , LyapType &lyap , size_t n ) +{ + if( !num_of_lyap ) return; + if( ptrdiff_t( ( num_of_lyap + 1 ) * n ) != std::distance( x.begin() , x.end() ) ) + BOOST_THROW_EXCEPTION( std::domain_error( "renormalization() : size of state does not match the number of lyapunov exponents." ) ); + + typedef typename StateType::value_type value_type; + typedef typename StateType::iterator iterator; + + value_type norm[num_of_lyap]; + value_type tmp[num_of_lyap]; + iterator first = x.begin() + n; + iterator beg1 = first , end1 = first + n ; + + std::fill( norm , norm+num_of_lyap , 0.0 ); + + // normalize first vector + norm[0] = sqrt( std::inner_product( beg1 , end1 , beg1 , 0.0 ) ); + normalize( beg1 , end1 , norm[0] ); + + beg1 += n; + end1 += n; + + for( size_t j=1 ; j<num_of_lyap ; ++j , beg1+=n , end1+=n ) + { + for( size_t k=0 ; k<j ; ++k ) + { + tmp[k] = std::inner_product( beg1 , end1 , first + k*n , 0.0 ); + // clog << j << " " << k << " " << tmp[k] << "\n"; + } + + + + for( size_t k=0 ; k<j ; ++k ) + substract_vector( beg1 , end1 , first + k*n , tmp[k] ); + + // normalize j-th vector + norm[j] = sqrt( std::inner_product( beg1 , end1 , beg1 , 0.0 ) ); + // clog << j << " " << norm[j] << "\n"; + normalize( beg1 , end1 , norm[j] ); + } + + for( size_t j=0 ; j<num_of_lyap ; j++ ) + lyap[j] += log( norm[j] ); +} + + +} // namespace odeint +} // namespace numeric +} // namespace boost + +#endif //BOOST_NUMERIC_ODEINT_GRAM_SCHMITT_HPP_INCLUDED diff --git a/src/boost/libs/numeric/odeint/examples/harmonic_oscillator.cpp b/src/boost/libs/numeric/odeint/examples/harmonic_oscillator.cpp new file mode 100644 index 000000000..a1f53c4ff --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/harmonic_oscillator.cpp @@ -0,0 +1,211 @@ +/* + Copyright 2010-2012 Karsten Ahnert + Copyright 2011-2013 Mario Mulansky + Copyright 2013 Pascal Germroth + + 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) + */ + + +#include <iostream> +#include <vector> + +#include <boost/numeric/odeint.hpp> + + + +//[ rhs_function +/* The type of container used to hold the state vector */ +typedef std::vector< double > state_type; + +const double gam = 0.15; + +/* The rhs of x' = f(x) */ +void harmonic_oscillator( const state_type &x , state_type &dxdt , const double /* t */ ) +{ + dxdt[0] = x[1]; + dxdt[1] = -x[0] - gam*x[1]; +} +//] + + + + + +//[ rhs_class +/* The rhs of x' = f(x) defined as a class */ +class harm_osc { + + double m_gam; + +public: + harm_osc( double gam ) : m_gam(gam) { } + + void operator() ( const state_type &x , state_type &dxdt , const double /* t */ ) + { + dxdt[0] = x[1]; + dxdt[1] = -x[0] - m_gam*x[1]; + } +}; +//] + + + + + +//[ integrate_observer +struct push_back_state_and_time +{ + std::vector< state_type >& m_states; + std::vector< double >& m_times; + + push_back_state_and_time( std::vector< state_type > &states , std::vector< double > × ) + : m_states( states ) , m_times( times ) { } + + void operator()( const state_type &x , double t ) + { + m_states.push_back( x ); + m_times.push_back( t ); + } +}; +//] + +struct write_state +{ + void operator()( const state_type &x ) const + { + std::cout << x[0] << "\t" << x[1] << "\n"; + } +}; + + +int main(int /* argc */ , char** /* argv */ ) +{ + using namespace std; + using namespace boost::numeric::odeint; + + + //[ state_initialization + state_type x(2); + x[0] = 1.0; // start at x=1.0, p=0.0 + x[1] = 0.0; + //] + + + + //[ integration + size_t steps = integrate( harmonic_oscillator , + x , 0.0 , 10.0 , 0.1 ); + //] + + + + //[ integration_class + harm_osc ho(0.15); + steps = integrate( ho , + x , 0.0 , 10.0 , 0.1 ); + //] + + + + + + //[ integrate_observ + vector<state_type> x_vec; + vector<double> times; + + steps = integrate( harmonic_oscillator , + x , 0.0 , 10.0 , 0.1 , + push_back_state_and_time( x_vec , times ) ); + + /* output */ + for( size_t i=0; i<=steps; i++ ) + { + cout << times[i] << '\t' << x_vec[i][0] << '\t' << x_vec[i][1] << '\n'; + } + //] + + + + + + + + //[ define_const_stepper + runge_kutta4< state_type > stepper; + integrate_const( stepper , harmonic_oscillator , x , 0.0 , 10.0 , 0.01 ); + //] + + + + + //[ integrate_const_loop + const double dt = 0.01; + for( double t=0.0 ; t<10.0 ; t+= dt ) + stepper.do_step( harmonic_oscillator , x , t , dt ); + //] + + + + + //[ define_adapt_stepper + typedef runge_kutta_cash_karp54< state_type > error_stepper_type; + //] + + + + //[ integrate_adapt + typedef controlled_runge_kutta< error_stepper_type > controlled_stepper_type; + controlled_stepper_type controlled_stepper; + integrate_adaptive( controlled_stepper , harmonic_oscillator , x , 0.0 , 10.0 , 0.01 ); + //] + + { + //[integrate_adapt_full + double abs_err = 1.0e-10 , rel_err = 1.0e-6 , a_x = 1.0 , a_dxdt = 1.0; + controlled_stepper_type controlled_stepper( + default_error_checker< double , range_algebra , default_operations >( abs_err , rel_err , a_x , a_dxdt ) ); + integrate_adaptive( controlled_stepper , harmonic_oscillator , x , 0.0 , 10.0 , 0.01 ); + //] + } + + + //[integrate_adapt_make_controlled + integrate_adaptive( make_controlled< error_stepper_type >( 1.0e-10 , 1.0e-6 ) , + harmonic_oscillator , x , 0.0 , 10.0 , 0.01 ); + //] + + + + + //[integrate_adapt_make_controlled_alternative + integrate_adaptive( make_controlled( 1.0e-10 , 1.0e-6 , error_stepper_type() ) , + harmonic_oscillator , x , 0.0 , 10.0 , 0.01 ); + //] + + #ifdef BOOST_NUMERIC_ODEINT_CXX11 + //[ define_const_stepper_cpp11 + { + runge_kutta4< state_type > stepper; + integrate_const( stepper , []( const state_type &x , state_type &dxdt , double t ) { + dxdt[0] = x[1]; dxdt[1] = -x[0] - gam*x[1]; } + , x , 0.0 , 10.0 , 0.01 ); + } + //] + + + + //[ harm_iterator_const_step] + std::for_each( make_const_step_time_iterator_begin( stepper , harmonic_oscillator, x , 0.0 , 0.1 , 10.0 ) , + make_const_step_time_iterator_end( stepper , harmonic_oscillator, x ) , + []( std::pair< const state_type & , const double & > x ) { + cout << x.second << " " << x.first[0] << " " << x.first[1] << "\n"; } ); + //] + #endif + + + + +} diff --git a/src/boost/libs/numeric/odeint/examples/harmonic_oscillator_units.cpp b/src/boost/libs/numeric/odeint/examples/harmonic_oscillator_units.cpp new file mode 100644 index 000000000..ceee83d80 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/harmonic_oscillator_units.cpp @@ -0,0 +1,121 @@ +/* + Copyright 2011-2013 Karsten Ahnert + Copyright 2011-2013 Mario Mulansky + + 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) + */ + + +#include <iostream> +#include <vector> + + +/* WARNING: Compilation in debug mode might consume enormous memory + (e.g. ~2GB on gcc 4.4 ) +*/ + +// first increase fusion macro variables (now done by odeint itself) +//#define BOOST_FUSION_INVOKE_MAX_ARITY 15 +//#define BOOST_RESULT_OF_NUM_ARGS 15 + +//[ units_define_basic_quantities + +#include <boost/numeric/odeint.hpp> +#include <boost/numeric/odeint/algebra/fusion_algebra.hpp> +#include <boost/numeric/odeint/algebra/fusion_algebra_dispatcher.hpp> + +#include <boost/units/systems/si/length.hpp> +#include <boost/units/systems/si/time.hpp> +#include <boost/units/systems/si/velocity.hpp> +#include <boost/units/systems/si/acceleration.hpp> +#include <boost/units/systems/si/io.hpp> + +#include <boost/fusion/container.hpp> + +using namespace std; +using namespace boost::numeric::odeint; +namespace fusion = boost::fusion; +namespace units = boost::units; +namespace si = boost::units::si; + +typedef units::quantity< si::time , double > time_type; +typedef units::quantity< si::length , double > length_type; +typedef units::quantity< si::velocity , double > velocity_type; +typedef units::quantity< si::acceleration , double > acceleration_type; +typedef units::quantity< si::frequency , double > frequency_type; + +typedef fusion::vector< length_type , velocity_type > state_type; +typedef fusion::vector< velocity_type , acceleration_type > deriv_type; +//] + + + +//[ units_define_ode +struct oscillator +{ + frequency_type m_omega; + + oscillator( const frequency_type &omega = 1.0 * si::hertz ) : m_omega( omega ) { } + + void operator()( const state_type &x , deriv_type &dxdt , time_type t ) const + { + fusion::at_c< 0 >( dxdt ) = fusion::at_c< 1 >( x ); + fusion::at_c< 1 >( dxdt ) = - m_omega * m_omega * fusion::at_c< 0 >( x ); + } +}; +//] + + +//[ units_observer +struct streaming_observer +{ + std::ostream& m_out; + + streaming_observer( std::ostream &out ) : m_out( out ) { } + + struct write_element + { + std::ostream &m_out; + write_element( std::ostream &out ) : m_out( out ) { }; + + template< class T > + void operator()( const T &t ) const + { + m_out << "\t" << t; + } + }; + + template< class State , class Time > + void operator()( const State &x , const Time &t ) const + { + m_out << t; + fusion::for_each( x , write_element( m_out ) ); + m_out << "\n"; + } +}; +//] + + +int main( int argc , char**argv ) +{ +// typedef dense_output_runge_kutta +// < +// controlled_runge_kutta +// < +// runge_kutta_dopri5< state_type , double , deriv_type , time_type , fusion_algebra > +// > +// > stepper_type; + + //[ units_define_stepper + typedef runge_kutta_dopri5< state_type , double , deriv_type , time_type > stepper_type; + + state_type x( 1.0 * si::meter , 0.0 * si::meter_per_second ); + + integrate_const( make_dense_output( 1.0e-6 , 1.0e-6 , stepper_type() ) , oscillator( 2.0 * si::hertz ) , + x , 0.0 * si::second , 100.0 * si::second , 0.1 * si::second , streaming_observer( cout ) ); + //] + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/heun.cpp b/src/boost/libs/numeric/odeint/examples/heun.cpp new file mode 100644 index 000000000..34fe12c42 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/heun.cpp @@ -0,0 +1,170 @@ +/* + [auto_generated] + libs/numeric/odeint/examples/heun.cpp + + [begin_description] + Examplary implementation of the method of Heun. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2012 Mario Mulansky + + 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) + */ + +#include <iostream> + + +#include <boost/fusion/container/vector.hpp> +#include <boost/fusion/container/generation/make_vector.hpp> + +#include <boost/array.hpp> + +#include <boost/numeric/odeint.hpp> + + + + + + +namespace fusion = boost::fusion; + +//[ heun_define_coefficients +template< class Value = double > +struct heun_a1 : boost::array< Value , 1 > { + heun_a1( void ) + { + (*this)[0] = static_cast< Value >( 1 ) / static_cast< Value >( 3 ); + } +}; + +template< class Value = double > +struct heun_a2 : boost::array< Value , 2 > +{ + heun_a2( void ) + { + (*this)[0] = static_cast< Value >( 0 ); + (*this)[1] = static_cast< Value >( 2 ) / static_cast< Value >( 3 ); + } +}; + + +template< class Value = double > +struct heun_b : boost::array< Value , 3 > +{ + heun_b( void ) + { + (*this)[0] = static_cast<Value>( 1 ) / static_cast<Value>( 4 ); + (*this)[1] = static_cast<Value>( 0 ); + (*this)[2] = static_cast<Value>( 3 ) / static_cast<Value>( 4 ); + } +}; + +template< class Value = double > +struct heun_c : boost::array< Value , 3 > +{ + heun_c( void ) + { + (*this)[0] = static_cast< Value >( 0 ); + (*this)[1] = static_cast< Value >( 1 ) / static_cast< Value >( 3 ); + (*this)[2] = static_cast< Value >( 2 ) / static_cast< Value >( 3 ); + } +}; +//] + + +//[ heun_stepper_definition +template< + class State , + class Value = double , + class Deriv = State , + class Time = Value , + class Algebra = boost::numeric::odeint::range_algebra , + class Operations = boost::numeric::odeint::default_operations , + class Resizer = boost::numeric::odeint::initially_resizer +> +class heun : public +boost::numeric::odeint::explicit_generic_rk< 3 , 3 , State , Value , Deriv , Time , + Algebra , Operations , Resizer > +{ + +public: + + typedef boost::numeric::odeint::explicit_generic_rk< 3 , 3 , State , Value , Deriv , Time , + Algebra , Operations , Resizer > stepper_base_type; + + typedef typename stepper_base_type::state_type state_type; + typedef typename stepper_base_type::wrapped_state_type wrapped_state_type; + typedef typename stepper_base_type::value_type value_type; + typedef typename stepper_base_type::deriv_type deriv_type; + typedef typename stepper_base_type::wrapped_deriv_type wrapped_deriv_type; + typedef typename stepper_base_type::time_type time_type; + typedef typename stepper_base_type::algebra_type algebra_type; + typedef typename stepper_base_type::operations_type operations_type; + typedef typename stepper_base_type::resizer_type resizer_type; + typedef typename stepper_base_type::stepper_type stepper_type; + + heun( const algebra_type &algebra = algebra_type() ) + : stepper_base_type( + fusion::make_vector( + heun_a1<Value>() , + heun_a2<Value>() ) , + heun_b<Value>() , heun_c<Value>() , algebra ) + { } +}; +//] + + +const double sigma = 10.0; +const double R = 28.0; +const double b = 8.0 / 3.0; + +struct lorenz +{ + template< class State , class Deriv > + void operator()( const State &x_ , Deriv &dxdt_ , double t ) const + { + typename boost::range_iterator< const State >::type x = boost::begin( x_ ); + typename boost::range_iterator< Deriv >::type dxdt = boost::begin( dxdt_ ); + + dxdt[0] = sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = -b * x[2] + x[0] * x[1]; + } +}; + +struct streaming_observer +{ + std::ostream &m_out; + streaming_observer( std::ostream &out ) : m_out( out ) { } + template< typename State , typename Value > + void operator()( const State &x , Value t ) const + { + m_out << t; + for( size_t i=0 ; i<x.size() ; ++i ) m_out << "\t" << x[i]; + m_out << "\n"; + } +}; + + + +int main( int argc , char **argv ) +{ + using namespace std; + using namespace boost::numeric::odeint; + + + //[ heun_example + typedef boost::array< double , 3 > state_type; + heun< state_type > h; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + + integrate_const( h , lorenz() , x , 0.0 , 100.0 , 0.01 , + streaming_observer( std::cout ) ); + + //] + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/integrate_times.cpp b/src/boost/libs/numeric/odeint/examples/integrate_times.cpp new file mode 100644 index 000000000..9e6b58104 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/integrate_times.cpp @@ -0,0 +1,54 @@ +/* Boost libs/numeric/odeint/examples/integrate_times.cpp + + Copyright 2009-2014 Karsten Ahnert + Copyright 2009-2014 Mario Mulansky + + example for the use of integrate_times + + 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) + */ + + +#include <iostream> +#include <boost/numeric/odeint.hpp> + +using namespace std; +using namespace boost::numeric::odeint; + + +/* + * simple 1D ODE + */ + +void rhs( const double x , double &dxdt , const double t ) +{ + dxdt = 3.0/(2.0*t*t) + x/(2.0*t); +} + +void write_cout( const double &x , const double t ) +{ + cout << t << '\t' << x << endl; +} + +// state_type = double +typedef runge_kutta_dopri5< double > stepper_type; + +const double dt = 0.1; + +int main() +{ + // create a vector with observation time points + std::vector<double> times( 91 ); + for( size_t i=0 ; i<times.size() ; ++i ) + times[i] = 1.0 + dt*i; + + double x = 0.0; //initial value x(1) = 0 + // we can provide the observation time as a boost range (i.e. the vector) + integrate_times( make_controlled( 1E-12 , 1E-12 , stepper_type() ) , rhs , + x , times , dt , write_cout ); + // or as two iterators + //integrate_times( make_controlled( 1E-12 , 1E-12 , stepper_type() ) , rhs , + // x , times.begin() , times.end() , dt , write_cout ); +} diff --git a/src/boost/libs/numeric/odeint/examples/list_lattice.cpp b/src/boost/libs/numeric/odeint/examples/list_lattice.cpp new file mode 100644 index 000000000..2c716ca11 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/list_lattice.cpp @@ -0,0 +1,78 @@ +/* + Copyright 2011-2012 Mario Mulansky + Copyright 2012-2013 Karsten Ahnert + + 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) + */ + + +/* example showing how odeint can be used with std::list */ + +#include <iostream> +#include <cmath> +#include <list> + +#include <boost/numeric/odeint.hpp> + +//[ list_bindings +typedef std::list< double > state_type; + +namespace boost { namespace numeric { namespace odeint { + +template< > +struct is_resizeable< state_type > +{ // declare resizeability + typedef boost::true_type type; + const static bool value = type::value; +}; + +template< > +struct same_size_impl< state_type , state_type > +{ // define how to check size + static bool same_size( const state_type &v1 , + const state_type &v2 ) + { + return v1.size() == v2.size(); + } +}; + +template< > +struct resize_impl< state_type , state_type > +{ // define how to resize + static void resize( state_type &v1 , + const state_type &v2 ) + { + v1.resize( v2.size() ); + } +}; + +} } } +//] + +void lattice( const state_type &x , state_type &dxdt , const double /* t */ ) +{ + state_type::const_iterator x_begin = x.begin(); + state_type::const_iterator x_end = x.end(); + state_type::iterator dxdt_begin = dxdt.begin(); + + x_end--; // stop one before last + while( x_begin != x_end ) + { + *(dxdt_begin++) = std::sin( *(x_begin) - *(x_begin++) ); + } + *dxdt_begin = sin( *x_begin - *(x.begin()) ); // periodic boundary +} + +using namespace boost::numeric::odeint; + +int main() +{ + const int N = 32; + state_type x; + for( int i=0 ; i<N ; ++i ) + x.push_back( 1.0*i/N ); + + integrate_const( runge_kutta4< state_type >() , lattice , x , 0.0 , 10.0 , 0.1 ); +} diff --git a/src/boost/libs/numeric/odeint/examples/lorenz.cpp b/src/boost/libs/numeric/odeint/examples/lorenz.cpp new file mode 100644 index 000000000..37155aaed --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/lorenz.cpp @@ -0,0 +1,31 @@ +#include <iostream> +#include <boost/array.hpp> + +#include <boost/numeric/odeint.hpp> + +using namespace std; +using namespace boost::numeric::odeint; + +const double sigma = 10.0; +const double R = 28.0; +const double b = 8.0 / 3.0; + +typedef boost::array< double , 3 > state_type; + +void lorenz( const state_type &x , state_type &dxdt , double t ) +{ + dxdt[0] = sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = -b * x[2] + x[0] * x[1]; +} + +void write_lorenz( const state_type &x , const double t ) +{ + cout << t << '\t' << x[0] << '\t' << x[1] << '\t' << x[2] << endl; +} + +int main(int argc, char **argv) +{ + state_type x = {{ 10.0 , 1.0 , 1.0 }}; // initial conditions + integrate( lorenz , x , 0.0 , 25.0 , 0.1 , write_lorenz ); +} diff --git a/src/boost/libs/numeric/odeint/examples/lorenz_point.cpp b/src/boost/libs/numeric/odeint/examples/lorenz_point.cpp new file mode 100644 index 000000000..26161675c --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/lorenz_point.cpp @@ -0,0 +1,119 @@ +/* + * Copyright 2011-2013 Mario Mulansky + * Copyright 2012 Karsten Ahnert + * + * 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) + * + * Example for the lorenz system with a 3D point type +*/ + +#include <iostream> +#include <cmath> + +#include <boost/operators.hpp> + +#include <boost/numeric/odeint.hpp> + + +//[point3D +class point3D : + boost::additive1< point3D , + boost::additive2< point3D , double , + boost::multiplicative2< point3D , double > > > +{ +public: + + double x , y , z; + + point3D() + : x( 0.0 ) , y( 0.0 ) , z( 0.0 ) + { } + + point3D( const double val ) + : x( val ) , y( val ) , z( val ) + { } + + point3D( const double _x , const double _y , const double _z ) + : x( _x ) , y( _y ) , z( _z ) + { } + + point3D& operator+=( const point3D &p ) + { + x += p.x; y += p.y; z += p.z; + return *this; + } + + point3D& operator*=( const double a ) + { + x *= a; y *= a; z *= a; + return *this; + } + +}; +//] + +//[point3D_abs_div +// only required for steppers with error control +point3D operator/( const point3D &p1 , const point3D &p2 ) +{ + return point3D( p1.x/p2.x , p1.y/p2.y , p1.z/p2.z ); +} + +point3D abs( const point3D &p ) +{ + return point3D( std::abs(p.x) , std::abs(p.y) , std::abs(p.z) ); +} +//] + +//[point3D_norm +// also only for steppers with error control +namespace boost { namespace numeric { namespace odeint { +template<> +struct vector_space_norm_inf< point3D > +{ + typedef double result_type; + double operator()( const point3D &p ) const + { + using std::max; + using std::abs; + return max( max( abs( p.x ) , abs( p.y ) ) , abs( p.z ) ); + } +}; +} } } +//] + +std::ostream& operator<<( std::ostream &out , const point3D &p ) +{ + out << p.x << " " << p.y << " " << p.z; + return out; +} + +//[point3D_main +const double sigma = 10.0; +const double R = 28.0; +const double b = 8.0 / 3.0; + +void lorenz( const point3D &x , point3D &dxdt , const double t ) +{ + dxdt.x = sigma * ( x.y - x.x ); + dxdt.y = R * x.x - x.y - x.x * x.z; + dxdt.z = -b * x.z + x.x * x.y; +} + +using namespace boost::numeric::odeint; + +int main() +{ + + point3D x( 10.0 , 5.0 , 5.0 ); + // point type defines it's own operators -> use vector_space_algebra ! + typedef runge_kutta_dopri5< point3D , double , point3D , + double , vector_space_algebra > stepper; + int steps = integrate_adaptive( make_controlled<stepper>( 1E-10 , 1E-10 ) , lorenz , x , + 0.0 , 10.0 , 0.1 ); + std::cout << x << std::endl; + std::cout << "steps: " << steps << std::endl; +} +//] diff --git a/src/boost/libs/numeric/odeint/examples/molecular_dynamics.cpp b/src/boost/libs/numeric/odeint/examples/molecular_dynamics.cpp new file mode 100644 index 000000000..e1a82e036 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/molecular_dynamics.cpp @@ -0,0 +1,160 @@ +/* + [auto_generated] + libs/numeric/odeint/examples/molecular_dynamics.cpp + + [begin_description] + Molecular dynamics example. + [end_description] + + Copyright 2009-2012 Karsten Ahnert + Copyright 2009-2012 Mario Mulansky + + 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) + */ + +#include <boost/numeric/odeint.hpp> + +#include <vector> +#include <iostream> +#include <random> + +using namespace boost::numeric::odeint; + + + +using namespace std; +#define tab "\t" + +const size_t n1 = 16; +const size_t n2 = 16; + +struct md_system +{ + static const size_t n = n1 * n2; + typedef std::vector< double > vector_type; + + md_system( double a = 0.0 , // strength of harmonic oscillator + double gamma = 0.0 , // friction + double eps = 0.1 , // interaction strenght + double sigma = 1.0 , // interaction radius + double xmax = 150.0 , double ymax = 150.0 ) + : m_a( a ) , m_gamma( gamma ) + , m_eps( eps ) , m_sigma( sigma ) + , m_xmax( xmax ) , m_ymax( ymax ) + { } + + static void init_vector_type( vector_type &x ) { x.resize( 2 * n ); } + + void operator()( vector_type const& x , vector_type const& v , vector_type &a , double t ) const + { + for( size_t i=0 ; i<n ; ++i ) + { + double diffx = x[i] - 0.5 * m_xmax , diffy = x[i+n] - 0.5 * m_ymax; + double r2 = diffx * diffx + diffy * diffy ; + double r = std::sqrt( r2 ); + a[ i ] = - m_a * r * diffx - m_gamma * v[ i ] ; + a[ n + i ] = - m_a * r * diffy - m_gamma * v[ n + i ] ; + } + + for( size_t i=0 ; i<n ; ++i ) + { + double xi = x[i] , yi = x[n+i]; + xi = periodic_bc( xi , m_xmax ); + yi = periodic_bc( yi , m_ymax ); + for( size_t j=0 ; j<i ; ++j ) + { + double xj = x[j] , yj = x[n+j]; + xj = periodic_bc( xj , m_xmax ); + yj = periodic_bc( yj , m_ymax ); + + double diffx = ( xj - xi ) , diffy = ( yj - yi ); + double r = sqrt( diffx * diffx + diffy * diffy ); + double f = lennard_jones( r ); + a[ i ] += diffx / r * f; + a[ n + i ] += diffy / r * f; + a[ j ] -= diffx / r * f; + a[ n + j ] -= diffy / r * f; + } + } + } + + void bc( vector_type &x ) + { + for( size_t i=0 ; i<n ; ++i ) + { + x[ i ] = periodic_bc( x[ i ] , m_xmax ); + x[ i + n ] = periodic_bc( x[ i + n ] , m_ymax ); + } + } + + inline double lennard_jones( double r ) const + { + double c = m_sigma / r; + double c3 = c * c * c; + double c6 = c3 * c3; + return 4.0 * m_eps * ( -12.0 * c6 * c6 / r + 6.0 * c6 / r ); + } + + static inline double periodic_bc( double x , double xmax ) + { + return ( x < 0.0 ) ? x + xmax : ( x > xmax ) ? x - xmax : x ; + } + + double m_a; + double m_gamma; + double m_eps ; + double m_sigma ; + double m_xmax , m_ymax; +}; + + + + + +int main( int argc , char *argv[] ) +{ + const size_t n = md_system::n; + typedef md_system::vector_type vector_type; + + + std::mt19937 rng; + std::normal_distribution<> dist( 0.0 , 1.0 ); + + vector_type x , v; + md_system::init_vector_type( x ); + md_system::init_vector_type( v ); + + for( size_t i=0 ; i<n1 ; ++i ) + { + for( size_t j=0 ; j<n2 ; ++j ) + { + x[i*n2+j ] = 5.0 + i * 4.0 ; + x[i*n2+j+n] = 5.0 + j * 4.0 ; + v[i] = dist( rng ) ; + v[i+n] = dist( rng ) ; + } + } + + velocity_verlet< vector_type > stepper; + const double dt = 0.025; + double t = 0.0; + md_system sys; + for( size_t oi=0 ; oi<100000 ; ++oi ) + { + for( size_t ii=0 ; ii<100 ; ++ii,t+=dt ) + stepper.do_step( sys , std::make_pair( std::ref( x ) , std::ref( v ) ) , t , dt ); + sys.bc( x ); + + std::cout << "set size square" << "\n"; + std::cout << "unset key" << "\n"; + std::cout << "p [0:" << sys.m_xmax << "][0:" << sys.m_ymax << "] '-' pt 7 ps 0.5" << "\n"; + for( size_t i=0 ; i<n ; ++i ) + std::cout << x[i] << " " << x[i+n] << " " << v[i] << " " << v[i+n] << "\n"; + std::cout << "e" << std::endl; + } + + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/molecular_dynamics_cells.cpp b/src/boost/libs/numeric/odeint/examples/molecular_dynamics_cells.cpp new file mode 100644 index 000000000..dcb7c5fda --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/molecular_dynamics_cells.cpp @@ -0,0 +1,379 @@ +/* + [auto_generated] + libs/numeric/odeint/examples/molecular_dynamics_cells.cpp + + [begin_description] + Molecular dynamics example with cells. + [end_description] + + Copyright 2009-2012 Karsten Ahnert + Copyright 2009-2012 Mario Mulansky + + 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) + */ + +#include <boost/numeric/odeint.hpp> + +#include <cstddef> +#include <vector> +#include <cmath> +#include <algorithm> +#include <tuple> +#include <iostream> +#include <random> + +#include <boost/range/algorithm/for_each.hpp> +#include <boost/range/algorithm/sort.hpp> +#include <boost/range/algorithm/unique_copy.hpp> +#include <boost/range/algorithm_ext/iota.hpp> +#include <boost/iterator/zip_iterator.hpp> +#include <boost/iterator/transform_iterator.hpp> +#include <boost/iterator/permutation_iterator.hpp> +#include <boost/iterator/counting_iterator.hpp> + +#include "point_type.hpp" + + + + + + + + +struct local_force +{ + double m_gamma; // friction + local_force( double gamma = 0.0 ) : m_gamma( gamma ) { } + template< typename Point > + Point operator()( Point& x , Point& v ) const + { + return - m_gamma * v; + } +}; + + +struct lennard_jones +{ + double m_sigma; + double m_eps; + lennard_jones( double sigma = 1.0 , double eps = 0.1 ) : m_sigma( sigma ) , m_eps( eps ) { } + double operator()( double r ) const + { + double c = m_sigma / r; + double c3 = c * c * c; + double c6 = c3 * c3; + return 4.0 * m_eps * ( -12.0 * c6 * c6 / r + 6.0 * c6 / r ); + } +}; + +template< typename F > +struct conservative_interaction +{ + F m_f; + conservative_interaction( F const &f = F() ) : m_f( f ) { } + template< typename Point > + Point operator()( Point const& x1 , Point const& x2 ) const + { + Point diff = x1 - x2; + double r = abs( diff ); + double f = m_f( r ); + return - diff / r * f; + } +}; + +template< typename F > +conservative_interaction< F > make_conservative_interaction( F const &f ) +{ + return conservative_interaction< F >( f ); +} + + + + + + + +// force = interaction( x1 , x2 ) +// force = local_force( x , v ) +template< typename LocalForce , typename Interaction > +class md_system_bs +{ +public: + + typedef std::vector< double > vector_type; + typedef point< double , 2 > point_type; + typedef point< int , 2 > index_type; + typedef std::vector< point_type > point_vector; + typedef std::vector< index_type > index_vector; + typedef std::vector< size_t > hash_vector; + typedef LocalForce local_force_type; + typedef Interaction interaction_type; + + + struct params + { + size_t n; + size_t n_cell_x , n_cell_y , n_cells; + double x_max , y_max , cell_size; + double eps , sigma; // interaction strength, interaction radius + interaction_type interaction; + local_force_type local_force; + }; + + + struct cell_functor + { + params const &m_p; + + cell_functor( params const& p ) : m_p( p ) { } + + template< typename Tuple > + void operator()( Tuple const& t ) const + { + auto point = boost::get< 0 >( t ); + size_t i1 = size_t( point[0] / m_p.cell_size ) , i2 = size_t( point[1] / m_p.cell_size ); + boost::get< 1 >( t ) = index_type( i1 , i2 ); + boost::get< 2 >( t ) = hash_func( boost::get< 1 >( t ) , m_p ); + } + }; + + + + struct transform_functor + { + typedef size_t argument_type; + typedef size_t result_type; + hash_vector const* m_index; + transform_functor( hash_vector const& index ) : m_index( &index ) { } + size_t operator()( size_t i ) const { return (*m_index)[i]; } + }; + + + + struct interaction_functor + { + hash_vector const &m_cells_begin; + hash_vector const &m_cells_end; + hash_vector const &m_order; + point_vector const &m_x; + point_vector const &m_v; + params const &m_p; + size_t m_ncellx , m_ncelly; + + interaction_functor( hash_vector const& cells_begin , hash_vector const& cells_end , hash_vector pos_order , + point_vector const&x , point_vector const& v , params const &p ) + : m_cells_begin( cells_begin ) , m_cells_end( cells_end ) , m_order( pos_order ) , m_x( x ) , m_v( v ) , + m_p( p ) { } + + template< typename Tuple > + void operator()( Tuple const &t ) const + { + point_type x = periodic_bc( boost::get< 0 >( t ) , m_p ) , v = boost::get< 1 >( t ); + index_type index = boost::get< 3 >( t ); + size_t pos_hash = boost::get< 4 >( t ); + + point_type a = m_p.local_force( x , v ); + + for( int i=-1 ; i<=1 ; ++i ) + { + for( int j=-1 ; j<=1 ; ++j ) + { + index_type cell_index = index + index_type( i , j ); + size_t cell_hash = hash_func( cell_index , m_p ); + for( size_t ii = m_cells_begin[ cell_hash ] ; ii < m_cells_end[ cell_hash ] ; ++ii ) + { + if( m_order[ ii ] == pos_hash ) continue; + point_type x2 = periodic_bc( m_x[ m_order[ ii ] ] , m_p ); + + if( cell_index[0] >= m_p.n_cell_x ) x2[0] += m_p.x_max; + if( cell_index[0] < 0 ) x2[0] -= m_p.x_max; + if( cell_index[1] >= m_p.n_cell_y ) x2[1] += m_p.y_max; + if( cell_index[1] < 0 ) x2[1] -= m_p.y_max; + + a += m_p.interaction( x , x2 ); + } + } + } + boost::get< 2 >( t ) = a; + } + }; + + + + + md_system_bs( size_t n , + local_force_type const& local_force = local_force_type() , + interaction_type const& interaction = interaction_type() , + double xmax = 100.0 , double ymax = 100.0 , double cell_size = 2.0 ) + : m_p() + { + m_p.n = n; + m_p.x_max = xmax; + m_p.y_max = ymax; + m_p.interaction = interaction; + m_p.local_force = local_force; + m_p.n_cell_x = size_t( xmax / cell_size ); + m_p.n_cell_y = size_t( ymax / cell_size ); + m_p.n_cells = m_p.n_cell_x * m_p.n_cell_y; + m_p.cell_size = cell_size; + } + + void init_point_vector( point_vector &x ) const { x.resize( m_p.n ); } + + void operator()( point_vector const& x , point_vector const& v , point_vector &a , double t ) const + { + // init + hash_vector pos_hash( m_p.n , 0 ); + index_vector pos_index( m_p.n ); + hash_vector pos_order( m_p.n , 0 ); + hash_vector cells_begin( m_p.n_cells ) , cells_end( m_p.n_cells ) , cell_order( m_p.n_cells ); + + boost::iota( pos_order , 0 ); + boost::iota( cell_order , 0 ); + + // calculate grid hash + // calcHash( m_dGridParticleHash, m_dGridParticleIndex, dPos, m_numParticles); + std::for_each( + boost::make_zip_iterator( boost::make_tuple( x.begin() , pos_index.begin() , pos_hash.begin() ) ) , + boost::make_zip_iterator( boost::make_tuple( x.end() , pos_index.end() , pos_hash.end() ) ) , + cell_functor( m_p ) ); + +// // sort particles based on hash +// // sortParticles(m_dGridParticleHash, m_dGridParticleIndex, m_numParticles); + boost::sort( pos_order , [&]( size_t i1 , size_t i2 ) -> bool { + return pos_hash[i1] < pos_hash[i2]; } ); + + + + // reorder particle arrays into sorted order and find start and end of each cell + std::for_each( cell_order.begin() , cell_order.end() , [&]( size_t i ) { + auto pos_begin = boost::make_transform_iterator( pos_order.begin() , transform_functor( pos_hash ) ); + auto pos_end = boost::make_transform_iterator( pos_order.end() , transform_functor( pos_hash ) ); + cells_begin[ i ] = std::distance( pos_begin , std::lower_bound( pos_begin , pos_end , i ) ); + cells_end[ i ] = std::distance( pos_begin , std::upper_bound( pos_begin , pos_end , i ) ); + } ); + + std::for_each( + boost::make_zip_iterator( boost::make_tuple( + x.begin() , + v.begin() , + a.begin() , + pos_index.begin() , + boost::counting_iterator< size_t >( 0 ) + ) ) , + boost::make_zip_iterator( boost::make_tuple( + x.end() , + v.end() , + a.end() , + pos_index.end() , + boost::counting_iterator< size_t >( m_p.n ) + ) ) , + interaction_functor( cells_begin , cells_end , pos_order , x , v , m_p ) ); + } + + void bc( point_vector &x ) + { + for( size_t i=0 ; i<m_p.n ; ++i ) + { + x[i][0] = periodic_bc( x[ i ][0] , m_p.x_max ); + x[i][1] = periodic_bc( x[ i ][1] , m_p.y_max ); + } + } + + static inline double periodic_bc( double x , double xmax ) + { + double tmp = x - xmax * int( x / xmax ); + return tmp >= 0.0 ? tmp : tmp + xmax; + } + + + static inline point_type periodic_bc( point_type const& x , params const& p ) + { + return point_type( periodic_bc( x[0] , p.x_max ) , periodic_bc( x[1] , p.y_max ) ); + } + + + static inline int check_interval( int i , int max ) + { + int tmp = i % max; + return tmp >= 0 ? tmp : tmp + max; + } + + + static inline size_t hash_func( index_type index , params const & p ) + { + size_t i1 = check_interval( index[0] , p.n_cell_x ); + size_t i2 = check_interval( index[1] , p.n_cell_y ); + return i1 * p.n_cell_y + i2; + } + + params m_p; +}; + + +template< typename LocalForce , typename Interaction > +md_system_bs< LocalForce , Interaction > make_md_system_bs( size_t n , LocalForce const &f1 , Interaction const &f2 , + double xmax = 100.0 , double ymax = 100.0 , double cell_size = 2.0 ) +{ + return md_system_bs< LocalForce , Interaction >( n , f1 , f2 , xmax , ymax , cell_size ); +} + + + + + + +using namespace boost::numeric::odeint; + + + +int main( int argc , char *argv[] ) +{ + const size_t n1 = 32; + const size_t n2 = 32; + const size_t n = n1 * n2; + auto sys = make_md_system_bs( n , local_force() , make_conservative_interaction( lennard_jones() ) , 100.0 , 100.0 , 2.0 ); + typedef decltype( sys ) system_type; + typedef system_type::point_vector point_vector; + + std::mt19937 rng; + std::normal_distribution<> dist( 0.0 , 1.0 ); + + point_vector x , v; + sys.init_point_vector( x ); + sys.init_point_vector( v ); + + for( size_t i=0 ; i<n1 ; ++i ) + { + for( size_t j=0 ; j<n2 ; ++j ) + { + size_t index = i * n2 + j; + x[index][0] = 10.0 + i * 2.0 ; + x[index][1] = 10.0 + j * 2.0 ; + v[index][0] = dist( rng ) ; + v[index][1] = dist( rng ) ; + } + } + + velocity_verlet< point_vector > stepper; + const double dt = 0.025; + double t = 0.0; + // std::cout << "set term x11" << endl; + for( size_t oi=0 ; oi<10000 ; ++oi ) + { + for( size_t ii=0 ; ii<50 ; ++ii,t+=dt ) + stepper.do_step( sys , std::make_pair( std::ref( x ) , std::ref( v ) ) , t , dt ); + sys.bc( x ); + + std::cout << "set size square" << "\n"; + std::cout << "unset key" << "\n"; + std::cout << "p [0:" << sys.m_p.x_max << "][0:" << sys.m_p.y_max << "] '-' pt 7 ps 0.5" << "\n"; + for( size_t i=0 ; i<n ; ++i ) + std::cout << x[i][0] << " " << x[i][1] << " " << v[i][0] << " " << v[i][1] << "\n"; + std::cout << "e" << std::endl; + } + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/mpi/Jamfile.v2 b/src/boost/libs/numeric/odeint/examples/mpi/Jamfile.v2 new file mode 100644 index 000000000..d3f18eb2c --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/mpi/Jamfile.v2 @@ -0,0 +1,15 @@ +# Copyright 2011-2013 Mario Mulansky +# Copyright 2012 Karsten Ahnert +# Copyright 2013 Pascal Germroth +# 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) + +project + : requirements + <define>BOOST_ALL_NO_LIB=1 + <library>/boost//mpi + <library>/boost//timer + ; + +exe phase_chain : phase_chain.cpp ; diff --git a/src/boost/libs/numeric/odeint/examples/mpi/phase_chain.cpp b/src/boost/libs/numeric/odeint/examples/mpi/phase_chain.cpp new file mode 100644 index 000000000..258c2f21d --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/mpi/phase_chain.cpp @@ -0,0 +1,120 @@ +/* + * phase_chain.cpp + * + * Example of MPI parallelization with odeint + * + * Copyright 2013 Karsten Ahnert + * Copyright 2013 Mario Mulansky + * Copyright 2013 Pascal Germroth + * 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) + */ + +#include <iostream> +#include <vector> +#include <boost/random.hpp> +#include <boost/timer/timer.hpp> +//[phase_chain_mpi_header +#include <boost/numeric/odeint.hpp> +#include <boost/numeric/odeint/external/mpi/mpi.hpp> +//] + +using namespace std; +using namespace boost::numeric::odeint; +using boost::timer::cpu_timer; +using boost::math::double_constants::pi; + +//[phase_chain_state +typedef mpi_state< vector<double> > state_type; +//] + +//[phase_chain_mpi_rhs +struct phase_chain_mpi_state +{ + phase_chain_mpi_state( double gamma = 0.5 ) + : m_gamma( gamma ) { } + + void operator()( const state_type &x , state_type &dxdt , double /* t */ ) const + { + const size_t M = x().size(); + const bool have_left = x.world.rank() > 0, + have_right = x.world.rank() < x.world.size()-1; + double x_left, x_right; + boost::mpi::request r_left, r_right; + if( have_left ) + { + x.world.isend( x.world.rank()-1 , 0 , x().front() ); // send to x_right + r_left = x.world.irecv( x.world.rank()-1 , 0 , x_left ); // receive from x().back() + } + if( have_right ) + { + x.world.isend( x.world.rank()+1 , 0 , x().back() ); // send to x_left + r_right = x.world.irecv( x.world.rank()+1 , 0 , x_right ); // receive from x().front() + } + for(size_t m = 1 ; m < M-1 ; ++m) + { + dxdt()[m] = coupling_func( x()[m+1] - x()[m] ) + + coupling_func( x()[m-1] - x()[m] ); + } + dxdt()[0] = coupling_func( x()[1] - x()[0] ); + if( have_left ) + { + r_left.wait(); + dxdt()[0] += coupling_func( x_left - x().front() ); + } + dxdt()[M-1] = coupling_func( x()[M-2] - x()[M-1] ); + if( have_right ) + { + r_right.wait(); + dxdt()[M-1] += coupling_func( x_right - x().back() ); + } + } + + double coupling_func( double x ) const + { + return sin( x ) - m_gamma * ( 1.0 - cos( x ) ); + } + + double m_gamma; +}; +//] + + +int main( int argc , char **argv ) +{ + //[phase_chain_mpi_init + boost::mpi::environment env( argc , argv ); + boost::mpi::communicator world; + + const size_t N = 131101; + vector<double> x; + if( world.rank() == 0 ) + { + x.resize( N ); + boost::random::uniform_real_distribution<double> distribution( 0.0 , 2.0*pi ); + boost::random::mt19937 engine( 0 ); + generate( x.begin() , x.end() , boost::bind( distribution , engine ) ); + } + + state_type x_split( world ); + split( x , x_split ); + //] + + + cpu_timer timer; + //[phase_chain_mpi_integrate + integrate_n_steps( runge_kutta4<state_type>() , phase_chain_mpi_state( 1.2 ) , + x_split , 0.0 , 0.01 , 100 ); + unsplit( x_split , x ); + //] + + if( world.rank() == 0 ) + { + double run_time = static_cast<double>(timer.elapsed().wall) * 1.0e-9; + std::cerr << run_time << "s" << std::endl; + // copy(x.begin(), x.end(), ostream_iterator<double>(cout, "\n")); + } + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/mtl/Jamfile.v2 b/src/boost/libs/numeric/odeint/examples/mtl/Jamfile.v2 new file mode 100644 index 000000000..9f4ffb0f3 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/mtl/Jamfile.v2 @@ -0,0 +1,17 @@ +# Copyright 2011-2013 Mario Mulansky +# Copyright 2012 Karsten Ahnert +# 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) + +# set your MTL4 directory here +MTL4_INCLUDE = /home/mario/MTL4 ; + +project + : requirements + <include>$(MTL4_INCLUDE) + <define>BOOST_ALL_NO_LIB=1 + ; + +exe gauss_packet : gauss_packet.cpp ; +exe implicit_euler_mtl : implicit_euler_mtl.cpp ;
\ No newline at end of file diff --git a/src/boost/libs/numeric/odeint/examples/mtl/gauss_packet.cpp b/src/boost/libs/numeric/odeint/examples/mtl/gauss_packet.cpp new file mode 100644 index 000000000..9579e5d45 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/mtl/gauss_packet.cpp @@ -0,0 +1,141 @@ +/* + * gauss_packet.cpp + * + * Schroedinger equation with potential barrier and periodic boundary conditions + * Initial Gauss packet moving to the right + * + * pipe output into gnuplot to see animation + * + * Implementation of Hamilton operator via MTL library + * + * Copyright 2011-2013 Mario Mulansky + * Copyright 2011-2012 Karsten Ahnert + * + * 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) + */ + + +#include <iostream> +#include <complex> + +#include <boost/numeric/odeint.hpp> +#include <boost/numeric/odeint/external/mtl4/mtl4.hpp> + +#include <boost/numeric/mtl/mtl.hpp> + + +using namespace std; +using namespace boost::numeric::odeint; + +typedef mtl::dense_vector< complex< double > > state_type; + +struct hamiltonian { + + typedef mtl::compressed2D< complex< double > > matrix_type; + matrix_type m_H; + + hamiltonian( const int N ) : m_H( N , N ) + { + // constructor with zero potential + m_H = 0.0; + initialize_kinetic_term(); + } + + //template< mtl::compressed2D< double > > + hamiltonian( mtl::compressed2D< double > &V ) : m_H( num_rows( V ) , num_cols( V ) ) + { + // use potential V in hamiltonian + m_H = complex<double>( 0.0 , -1.0 ) * V; + initialize_kinetic_term(); + } + + void initialize_kinetic_term( ) + { + const int N = num_rows( m_H ); + mtl::matrix::inserter< matrix_type , mtl::update_plus< complex<double> > > ins( m_H ); + const double z = 1.0; + // fill diagonal and upper and lower diagonal + for( int i = 0 ; i<N ; ++i ) + { + ins[ i ][ (i+1) % N ] << complex< double >( 0.0 , -z ); + ins[ i ][ i ] << complex< double >( 0.0 , z ); + ins[ (i+1) % N ][ i ] << complex< double >( 0.0 , -z ); + } + } + + void operator()( const state_type &psi , state_type &dpsidt , const double t ) + { + dpsidt = m_H * psi; + } + +}; + +struct write_for_gnuplot +{ + size_t m_every , m_count; + + write_for_gnuplot( size_t every = 10 ) + : m_every( every ) , m_count( 0 ) { } + + void operator()( const state_type &x , double t ) + { + if( ( m_count % m_every ) == 0 ) + { + //clog << t << endl; + cout << "p [0:" << mtl::size(x) << "][0:0.02] '-'" << endl; + for( size_t i=0 ; i<mtl::size(x) ; ++i ) + { + cout << i << "\t" << norm(x[i]) << "\n"; + } + cout << "e" << endl; + } + + ++m_count; + } +}; + +static const int N = 1024; +static const int N0 = 256; +static const double sigma0 = 20; +static const double k0 = -1.0; + +int main( int argc , char** argv ) +{ + state_type x( N , 0.0 ); + + // initialize gauss packet with nonzero velocity + for( int i=0 ; i<N ; ++i ) + { + x[i] = exp( -(i-N0)*(i-N0) / ( 4.0*sigma0*sigma0 ) ) * exp( complex< double >( 0.0 , k0*i ) ); + //x[i] += 2.0*exp( -(i+N0-N)*(i+N0-N) / ( 4.0*sigma0*sigma0 ) ) * exp( complex< double >( 0.0 , -k0*i ) ); + } + x /= mtl::two_norm( x ); + + typedef runge_kutta4< state_type > stepper; + + // create potential barrier + mtl::compressed2D< double > V( N , N ); + V = 0.0; + { + mtl::matrix::inserter< mtl::compressed2D< double > > ins( V ); + for( int i=0 ; i<N ; ++i ) + { + //ins[i][i] << 1E-4*(i-N/2)*(i-N/2); + + if( i < N/2 ) + ins[ i ][ i ] << 0.0 ; + else + ins[ i ][ i ] << 1.0 ; + + } + } + + // perform integration, output can be piped to gnuplot + integrate_const( stepper() , hamiltonian( V ) , x , 0.0 , 1000.0 , 0.1 , write_for_gnuplot( 10 ) ); + + clog << "Norm: " << mtl::two_norm( x ) << endl; + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/mtl/implicit_euler_mtl.cpp b/src/boost/libs/numeric/odeint/examples/mtl/implicit_euler_mtl.cpp new file mode 100644 index 000000000..6a1b8e731 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/mtl/implicit_euler_mtl.cpp @@ -0,0 +1,324 @@ +/* + * Copyright 2012 Karsten Ahnert + * Copyright 2012 Mario Mulansky + * + * 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) + */ + + +#include <iostream> +#include <fstream> +#include <utility> +#include "time.h" + +#include <boost/numeric/odeint.hpp> +#include <boost/phoenix/phoenix.hpp> +#include <boost/numeric/mtl/mtl.hpp> + +#include <boost/numeric/odeint/external/mtl4/implicit_euler_mtl4.hpp> + +using namespace std; +using namespace boost::numeric::odeint; + +namespace phoenix = boost::phoenix; + + + +typedef mtl::dense_vector< double > vec_mtl4; +typedef mtl::compressed2D< double > mat_mtl4; + +typedef boost::numeric::ublas::vector< double > vec_ublas; +typedef boost::numeric::ublas::matrix< double > mat_ublas; + + +// two systems defined 1 & 2 both are mostly sparse with the number of element variable +struct system1_mtl4 +{ + + void operator()( const vec_mtl4 &x , vec_mtl4 &dxdt , double t ) + { + int size = mtl::size(x); + + dxdt[ 0 ] = -0.06*x[0]; + + for (int i =1; i< size ; ++i){ + + dxdt[ i ] = 4.2*x[i-1]-2.2*x[i]*x[i]; + } + + } +}; + +struct jacobi1_mtl4 +{ + void operator()( const vec_mtl4 &x , mat_mtl4 &J , const double &t ) + { + int size = mtl::size(x); + mtl::matrix::inserter<mat_mtl4> ins(J); + + ins[0][0]=-0.06; + + for (int i =1; i< size ; ++i) + { + ins[i][i-1] = + 4.2; + ins[i][i] = -4.2*x[i]; + } + } +}; + + + +struct system1_ublas +{ + + void operator()( const vec_ublas &x , vec_ublas &dxdt , double t ) + { + int size = x.size(); + + dxdt[ 0 ] = -0.06*x[0]; + + for (int i =1; i< size ; ++i){ + + dxdt[ i ] = 4.2*x[i-1]-2.2*x[i]*x[i]; + } + + } +}; + +struct jacobi1_ublas +{ + void operator()( const vec_ublas &x , mat_ublas &J , const double &t ) + { + int size = x.size(); +// mtl::matrix::inserter<mat_mtl4> ins(J); + + J(0,0)=-0.06; + + for (int i =1; i< size ; ++i){ +//ins[i][0]=120.0*x[i]; + J(i,i-1) = + 4.2; + J(i,i) = -4.2*x[i]; + + } + } +}; + +struct system2_mtl4 +{ + + void operator()( const vec_mtl4 &x , vec_mtl4 &dxdt , double t ) + { + int size = mtl::size(x); + + + for (int i =0; i< size/5 ; i+=5){ + + dxdt[ i ] = -0.5*x[i]; + dxdt[i+1]= +25*x[i+1]*x[i+2]-740*x[i+3]*x[i+3]+4.2e-2*x[i]; + dxdt[i+2]= +25*x[i]*x[i]-740*x[i+3]*x[i+3]; + dxdt[i+3]= -25*x[i+1]*x[i+2]+740*x[i+3]*x[i+3]; + dxdt[i+4] = 0.250*x[i]*x[i+1]-44.5*x[i+3]; + + } + + } +}; + +struct jacobi2_mtl4 +{ + void operator()( const vec_mtl4 &x , mat_mtl4 &J , const double &t ) + { + int size = mtl::size(x); + mtl::matrix::inserter<mat_mtl4> ins(J); + + for (int i =0; i< size/5 ; i+=5){ + + ins[ i ][i] = -0.5; + ins[i+1][i+1]=25*x[i+2]; + ins[i+1][i+2] = 25*x[i+1]; + ins[i+1][i+3] = -740*2*x[i+3]; + ins[i+1][i] =+4.2e-2; + + ins[i+2][i]= 50*x[i]; + ins[i+2][i+3]= -740*2*x[i+3]; + ins[i+3][i+1] = -25*x[i+2]; + ins[i+3][i+2] = -25*x[i+1]; + ins[i+3][i+3] = +740*2*x[i+3]; + ins[i+4][i] = 0.25*x[i+1]; + ins[i+4][i+1] =0.25*x[i]; + ins[i+4][i+3]=-44.5; + + + + } + } +}; + + + +struct system2_ublas +{ + + void operator()( const vec_ublas &x , vec_ublas &dxdt , double t ) + { + int size = x.size(); + for (int i =0; i< size/5 ; i+=5){ + + dxdt[ i ] = -4.2e-2*x[i]; + dxdt[i+1]= +25*x[i+1]*x[i+2]-740*x[i+3]*x[i+3]+4.2e-2*x[i]; + dxdt[i+2]= +25*x[i]*x[i]-740*x[i+3]*x[i+3]; + dxdt[i+3]= -25*x[i+1]*x[i+2]+740*x[i+3]*x[i+3]; + dxdt[i+4] = 0.250*x[i]*x[i+1]-44.5*x[i+3]; + + } + + } +}; + +struct jacobi2_ublas +{ + void operator()( const vec_ublas &x , mat_ublas &J , const double &t ) + { + int size = x.size(); + + for (int i =0; i< size/5 ; i+=5){ + + J(i ,i) = -4.2e-2; + J(i+1,i+1)=25*x[i+2]; + J(i+1,i+2) = 25*x[i+1]; + J(i+1,i+3) = -740*2*x[i+3]; + J(i+1,i) =+4.2e-2; + + J(i+2,i)= 50*x[i]; + J(i+2,i+3)= -740*2*x[i+3]; + J(i+3,i+1) = -25*x[i+2]; + J(i+3,i+2) = -25*x[i+1]; + J(i+3,i+3) = +740*2*x[i+3]; + J(i+4,i) = 0.25*x[i+1]; + J(i+4,i+1) =0.25*x[i]; + J(i+4,i+3)=-44.5; + + + + } + + + } +}; + + + + +void testRidiculouslyMassiveArray( int size ) +{ + typedef boost::numeric::odeint::implicit_euler_mtl4 < double > mtl4stepper; + typedef boost::numeric::odeint::implicit_euler< double > booststepper; + + vec_mtl4 x(size , 0.0); + x[0]=1; + + + double dt = 0.02; + double endtime = 10.0; + + clock_t tstart_mtl4 = clock(); + size_t num_of_steps_mtl4 = integrate_const( + mtl4stepper() , + make_pair( system1_mtl4() , jacobi1_mtl4() ) , + x , 0.0 , endtime , dt ); + clock_t tend_mtl4 = clock() ; + + clog << x[0] << endl; + clog << num_of_steps_mtl4 << " time elapsed: " << (double)(tend_mtl4-tstart_mtl4 )/CLOCKS_PER_SEC << endl; + + vec_ublas x_ublas(size , 0.0); + x_ublas[0]=1; + + clock_t tstart_boost = clock(); + size_t num_of_steps_ublas = integrate_const( + booststepper() , + make_pair( system1_ublas() , jacobi1_ublas() ) , + x_ublas , 0.0 , endtime , dt ); + clock_t tend_boost = clock() ; + + clog << x_ublas[0] << endl; + clog << num_of_steps_ublas << " time elapsed: " << (double)(tend_boost-tstart_boost)/CLOCKS_PER_SEC<< endl; + + clog << "dt_ublas/dt_mtl4 = " << (double)( tend_boost-tstart_boost )/( tend_mtl4-tstart_mtl4 ) << endl << endl; + return ; +} + + + +void testRidiculouslyMassiveArray2( int size ) +{ + typedef boost::numeric::odeint::implicit_euler_mtl4 < double > mtl4stepper; + typedef boost::numeric::odeint::implicit_euler< double > booststepper; + + + vec_mtl4 x(size , 0.0); + x[0]=100; + + + double dt = 0.01; + double endtime = 10.0; + + clock_t tstart_mtl4 = clock(); + size_t num_of_steps_mtl4 = integrate_const( + mtl4stepper() , + make_pair( system1_mtl4() , jacobi1_mtl4() ) , + x , 0.0 , endtime , dt ); + + + clock_t tend_mtl4 = clock() ; + + clog << x[0] << endl; + clog << num_of_steps_mtl4 << " time elapsed: " << (double)(tend_mtl4-tstart_mtl4 )/CLOCKS_PER_SEC << endl; + + vec_ublas x_ublas(size , 0.0); + x_ublas[0]=100; + + clock_t tstart_boost = clock(); + size_t num_of_steps_ublas = integrate_const( + booststepper() , + make_pair( system1_ublas() , jacobi1_ublas() ) , + x_ublas , 0.0 , endtime , dt ); + + + clock_t tend_boost = clock() ; + + clog << x_ublas[0] << endl; + clog << num_of_steps_ublas << " time elapsed: " << (double)(tend_boost-tstart_boost)/CLOCKS_PER_SEC<< endl; + + clog << "dt_ublas/dt_mtl4 = " << (double)( tend_boost-tstart_boost )/( tend_mtl4-tstart_mtl4 ) << endl << endl; + return ; +} + + + + +int main( int argc , char **argv ) +{ + std::vector< size_t > length; + length.push_back( 8 ); + length.push_back( 16 ); + length.push_back( 32 ); + length.push_back( 64 ); + length.push_back( 128 ); + length.push_back( 256 ); + + for( size_t i=0 ; i<length.size() ; ++i ) + { + clog << "Testing with size " << length[i] << endl; + testRidiculouslyMassiveArray( length[i] ); + } + clog << endl << endl; + + for( size_t i=0 ; i<length.size() ; ++i ) + { + clog << "Testing with size " << length[i] << endl; + testRidiculouslyMassiveArray2( length[i] ); + } +} diff --git a/src/boost/libs/numeric/odeint/examples/multiprecision/Jamfile b/src/boost/libs/numeric/odeint/examples/multiprecision/Jamfile new file mode 100644 index 000000000..9708d4340 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/multiprecision/Jamfile @@ -0,0 +1,16 @@ +# Copyright 2011-2013 Mario Mulansky +# Copyright 2012 Karsten Ahnert +# 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) + + +project + : requirements + <define>BOOST_ALL_NO_LIB=1 + : + ; + + +exe lorenz_mp : lorenz_mp.cpp ; +exe cmp_precision : cmp_precision.cpp ; diff --git a/src/boost/libs/numeric/odeint/examples/multiprecision/cmp_precision.cpp b/src/boost/libs/numeric/odeint/examples/multiprecision/cmp_precision.cpp new file mode 100644 index 000000000..779b5e290 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/multiprecision/cmp_precision.cpp @@ -0,0 +1,68 @@ +/* Boost libs/numeric/odeint/examples/multiprecision/cmp_precision.cpp + + Copyright 2013 Karsten Ahnert + Copyright 2013 Mario Mulansky + + example comparing double to multiprecision using Boost.Multiprecision + + 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) + */ + + +#include <iostream> +#include <boost/numeric/odeint.hpp> +#include <boost/multiprecision/cpp_dec_float.hpp> + +using namespace std; +using namespace boost::numeric::odeint; + +typedef boost::multiprecision::cpp_dec_float_50 mp_50; + +/* we solve the simple ODE x' = 3/(2t^2) + x/(2t) + * with initial condition x(1) = 0. + * Analytic solution is x(t) = sqrt(t) - 1/t + */ + +void rhs_m( const mp_50 x , mp_50 &dxdt , const mp_50 t ) +{ // version for multiprecision + dxdt = mp_50(3)/(mp_50(2)*t*t) + x/(mp_50(2)*t); +} + +void rhs_d( const double x , double &dxdt , const double t ) +{ // version for double precision + dxdt = 3.0/(2.0*t*t) + x/(2.0*t); +} + +// state_type = mp_50 = deriv_type = time_type = mp_50 +typedef runge_kutta4< mp_50 , mp_50 , mp_50 , mp_50 , vector_space_algebra , default_operations , never_resizer > stepper_type_m; + +typedef runge_kutta4< double , double , double , double , vector_space_algebra , default_operations , never_resizer > stepper_type_d; + +int main() +{ + + stepper_type_m stepper_m; + stepper_type_d stepper_d; + + mp_50 dt_m( 0.5 ); + double dt_d( 0.5 ); + + cout << "dt" << '\t' << "mp" << '\t' << "double" << endl; + + while( dt_m > 1E-20 ) + { + + mp_50 x_m = 0; //initial value x(1) = 0 + stepper_m.do_step( rhs_m , x_m , mp_50( 1 ) , dt_m ); + double x_d = 0; + stepper_d.do_step( rhs_d , x_d , 1.0 , dt_d ); + + cout << dt_m << '\t'; + cout << abs((x_m - (sqrt(1+dt_m)-mp_50(1)/(1+dt_m)))/x_m) << '\t' ; + cout << abs((x_d - (sqrt(1+dt_d)-mp_50(1)/(1+dt_d)))/x_d) << endl ; + dt_m /= 2; + dt_d /= 2; + } +} diff --git a/src/boost/libs/numeric/odeint/examples/multiprecision/lorenz_mp.cpp b/src/boost/libs/numeric/odeint/examples/multiprecision/lorenz_mp.cpp new file mode 100644 index 000000000..c3e5b82e8 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/multiprecision/lorenz_mp.cpp @@ -0,0 +1,81 @@ +/* + * lorenz_mp.cpp + * + * This example demonstrates how odeint can be used with boost.multiprecision. + * + * Copyright 2011-2012 Karsten Ahnert + * Copyright 2013 Mario Mulansky + * + * 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) + */ + + + +#include <iostream> + +//[ mp_lorenz_defs +#include <boost/numeric/odeint.hpp> +#include <boost/multiprecision/cpp_dec_float.hpp> + +using namespace std; +using namespace boost::numeric::odeint; + +typedef boost::multiprecision::cpp_dec_float_50 value_type; + +typedef boost::array< value_type , 3 > state_type; +//] + +//[ mp_lorenz_rhs +struct lorenz +{ + void operator()( const state_type &x , state_type &dxdt , value_type t ) const + { + const value_type sigma( 10 ); + const value_type R( 28 ); + const value_type b( value_type( 8 ) / value_type( 3 ) ); + + dxdt[0] = sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = -b * x[2] + x[0] * x[1]; + } +}; +//] + + + + +struct streaming_observer +{ + std::ostream& m_out; + + streaming_observer( std::ostream &out ) : m_out( out ) { } + + template< class State , class Time > + void operator()( const State &x , Time t ) const + { + m_out << t; + for( size_t i=0 ; i<x.size() ; ++i ) m_out << "\t" << x[i] ; + m_out << "\n"; + } +}; + + + + + + +int main( int argc , char **argv ) +{ + //[ mp_lorenz_int + state_type x = {{ value_type( 10.0 ) , value_type( 10.0 ) , value_type( 10.0 ) }}; + + cout.precision( 50 ); + integrate_const( runge_kutta4< state_type , value_type >() , + lorenz() , x , value_type( 0.0 ) , value_type( 10.0 ) , value_type( value_type( 1.0 ) / value_type( 10.0 ) ) , + streaming_observer( cout ) ); + //] + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/my_vector.cpp b/src/boost/libs/numeric/odeint/examples/my_vector.cpp new file mode 100644 index 000000000..746dfaada --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/my_vector.cpp @@ -0,0 +1,114 @@ +/* + * Copyright 2011-2012 Mario Mulansky + * Copyright 2012-2013 Karsten Ahnert + * + * 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) + * + * Example for self defined vector type. + */ + +#include <vector> + +#include <boost/numeric/odeint.hpp> + +//[my_vector +template< size_t MAX_N > +class my_vector +{ + typedef std::vector< double > vector; + +public: + typedef vector::iterator iterator; + typedef vector::const_iterator const_iterator; + +public: + my_vector( const size_t N ) + : m_v( N ) + { + m_v.reserve( MAX_N ); + } + + my_vector() + : m_v() + { + m_v.reserve( MAX_N ); + } + +// ... [ implement container interface ] +//] + const double & operator[]( const size_t n ) const + { return m_v[n]; } + + double & operator[]( const size_t n ) + { return m_v[n]; } + + iterator begin() + { return m_v.begin(); } + + const_iterator begin() const + { return m_v.begin(); } + + iterator end() + { return m_v.end(); } + + const_iterator end() const + { return m_v.end(); } + + size_t size() const + { return m_v.size(); } + + void resize( const size_t n ) + { m_v.resize( n ); } + +private: + std::vector< double > m_v; + +}; + +//[my_vector_resizeable +// define my_vector as resizeable + +namespace boost { namespace numeric { namespace odeint { + +template<size_t N> +struct is_resizeable< my_vector<N> > +{ + typedef boost::true_type type; + static const bool value = type::value; +}; + +} } } +//] + + +typedef my_vector<3> state_type; + +void lorenz( const state_type &x , state_type &dxdt , const double t ) +{ + const double sigma( 10.0 ); + const double R( 28.0 ); + const double b( 8.0 / 3.0 ); + + dxdt[0] = sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = -b * x[2] + x[0] * x[1]; +} + +using namespace boost::numeric::odeint; + +int main() +{ + state_type x(3); + x[0] = 5.0 ; x[1] = 10.0 ; x[2] = 10.0; + + // make sure resizing is ON + BOOST_STATIC_ASSERT( is_resizeable<state_type>::value == true ); + + // my_vector works with range_algebra as it implements + // the required parts of a container interface + // no further work is required + + integrate_const( runge_kutta4< state_type >() , lorenz , x , 0.0 , 10.0 , 0.1 ); +} diff --git a/src/boost/libs/numeric/odeint/examples/nt2/Jamfile.v2 b/src/boost/libs/numeric/odeint/examples/nt2/Jamfile.v2 new file mode 100644 index 000000000..05847cd17 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/nt2/Jamfile.v2 @@ -0,0 +1,34 @@ +#============================================================================== +# Copyright 2014 LRI UMR 8623 CNRS/Univ Paris Sud XI +# Copyright 2014 NumScale SAS +# +# Distributed under the Boost Software License, Version 1.0. +# See accompanying file LICENSE.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt +#============================================================================== + +use-project boost : $(BOOST_ROOT) ; + +import os ; + +# This must be built using an NT2 installation. +# NT2_ROOT_PATH should point to the build directory. +# Currently, cxxflags needs to be set to the required architecture +# if using avx/avx2, set the environemnt variable NT2_SIMD_FLAGS to the +# required value for your compiler (i.e. -mavx2 on g++) +# If using sse2/3/4 in 64 bits, this is set automatically. + +local NT2_ROOT_PATH = [ os.environ NT2_ROOT_PATH ] ; +local NT2_SIMD_FLAGS = [ os.environ NT2_SIMD_FLAGS ] ; + +project + : requirements + <define>BOOST_ALL_NO_LIB=1 + <include>$(NT2_ROOT_PATH)/include/ + <link>static + <toolset>gcc:<cxxflags>-DBOOST_SIMD_NO_STRICT_ALIASING + <toolset>gcc:<cxxflags>-fno-strict-aliasing + <cxxflags>$(NT2_SIMD_FLAGS) + ; + +exe phase_oscillator_ensemble : phase_oscillator_ensemble.cpp ; diff --git a/src/boost/libs/numeric/odeint/examples/nt2/phase_oscillator_ensemble.cpp b/src/boost/libs/numeric/odeint/examples/nt2/phase_oscillator_ensemble.cpp new file mode 100644 index 000000000..1f28623cd --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/nt2/phase_oscillator_ensemble.cpp @@ -0,0 +1,170 @@ +//============================================================================== +// Copyright 2011-2014 Karsten Ahnert +// Copyright 2011-2014 Mario Mulansky +// Copyright 2014 LRI UMR 8623 CNRS/Univ Paris Sud XI +// Copyright 2014 NumScale SAS +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +//============================================================================== + +#include <iostream> +#include <utility> + +#include <boost/numeric/odeint.hpp> + +#ifndef M_PI //not there on windows +#define M_PI 3.141592653589793 //... +#endif + +#include <boost/random.hpp> +#include <boost/dispatch/meta/as_integer.hpp> + +#include <nt2/include/functions/cos.hpp> +#include <nt2/include/functions/sin.hpp> +#include <nt2/include/functions/atan2.hpp> +#include <nt2/table.hpp> +#include <nt2/include/functions/zeros.hpp> +#include <nt2/include/functions/sum.hpp> +#include <nt2/include/functions/mean.hpp> +#include <nt2/arithmetic/include/functions/hypot.hpp> +#include <nt2/include/functions/tie.hpp> + +#include <boost/numeric/odeint/external/nt2/nt2_algebra_dispatcher.hpp> + + +using namespace std; +using namespace boost::numeric::odeint; + +template <typename container_type, typename T> +pair< T, T > calc_mean_field( const container_type &x ) + +{ + T cos_sum = 0.0 , sin_sum = 0.0; + + nt2::tie(cos_sum,sin_sum) = nt2::tie(nt2::mean( nt2::cos(x) ), nt2::mean( nt2::sin(x) )); + + T K = nt2::hypot(sin_sum,cos_sum); + T Theta = nt2::atan2( sin_sum , cos_sum ); + + return make_pair( K , Theta ); +} + +template <typename container_type, typename T> +struct phase_ensemble +{ + typedef typename boost::dispatch::meta::as_integer<T,unsigned>::type int_type; + container_type m_omega; + T m_epsilon; + + phase_ensemble( const int_type n , T g = 1.0 , T epsilon = 1.0 ) + : m_epsilon( epsilon ) + { + m_omega = nt2::zeros(nt2::of_size(n), nt2::meta::as_<T>()); + create_frequencies( g ); + } + + void create_frequencies( T g ) + { + boost::mt19937 rng; + boost::cauchy_distribution<> cauchy( 0.0 , g ); + boost::variate_generator< boost::mt19937&, boost::cauchy_distribution<> > gen( rng , cauchy ); + generate( m_omega.begin() , m_omega.end() , gen ); +} + + void set_epsilon( T epsilon ) { m_epsilon = epsilon; } + + T get_epsilon( void ) const { return m_epsilon; } + + void operator()( const container_type &x , container_type &dxdt , T ) const + { + pair< T, T > mean = calc_mean_field<container_type,T>( x ); + dxdt = m_omega + m_epsilon * mean.first * nt2::sin( mean.second - x ); + } +}; + +template<typename T> +struct statistics_observer +{ + typedef typename boost::dispatch::meta::as_integer<T,unsigned>::type int_type; + T m_K_mean; + int_type m_count; + + statistics_observer( void ) + : m_K_mean( 0.0 ) , m_count( 0 ) { } + + template< class State > + void operator()( const State &x , T t ) + { + pair< T, T > mean = calc_mean_field<State,T>( x ); + m_K_mean += mean.first; + ++m_count; + } + + T get_K_mean( void ) const { return ( m_count != 0 ) ? m_K_mean / T( m_count ) : 0.0 ; } + + void reset( void ) { m_K_mean = 0.0; m_count = 0; } +}; + +template<typename T> +struct test_ode_table +{ + typedef nt2::table<T> array_type; + typedef void experiment_is_immutable; + + typedef typename boost::dispatch::meta::as_integer<T,unsigned>::type int_type; + + test_ode_table ( ) + : size_(16384), ensemble( size_ , 1.0 ), unif( 0.0 , 2.0 * M_PI ), gen( rng , unif ), obs() + { + x.resize(nt2::of_size(size_)); + } + + void operator()() + { + for( T epsilon = 0.0 ; epsilon < 5.0 ; epsilon += 0.1 ) + { + ensemble.set_epsilon( epsilon ); + obs.reset(); + + // start with random initial conditions + generate( x.begin() , x.end() , gen ); + // calculate some transients steps + integrate_const( runge_kutta4< array_type, T >() , boost::ref( ensemble ) , x , T(0.0) , T(10.0) , dt ); + + // integrate and compute the statistics + integrate_const( runge_kutta4< array_type, T >() , boost::ref( ensemble ) , x , T(0.0) , T(100.0) , dt , boost::ref( obs ) ); + cout << epsilon << "\t" << obs.get_K_mean() << endl; + } + } + + friend std::ostream& operator<<(std::ostream& os, test_ode_table<T> const& p) + { + return os << "(" << p.size() << ")"; + } + + std::size_t size() const { return size_; } + + private: + std::size_t size_; + phase_ensemble<array_type,T> ensemble; + boost::uniform_real<> unif; + array_type x; + boost::mt19937 rng; + boost::variate_generator< boost::mt19937&, boost::uniform_real<> > gen; + statistics_observer<T> obs; + + static const T dt = 0.1; +}; + +int main() +{ + std::cout<< " With T = [double] \n"; + test_ode_table<double> test_double; + test_double(); + + std::cout<< " With T = [float] \n"; + test_ode_table<float> test_float; + test_float(); +} diff --git a/src/boost/libs/numeric/odeint/examples/openmp/Jamfile.v2 b/src/boost/libs/numeric/odeint/examples/openmp/Jamfile.v2 new file mode 100644 index 000000000..cef4f670c --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/openmp/Jamfile.v2 @@ -0,0 +1,23 @@ +# Copyright 2011-2013 Mario Mulansky +# Copyright 2012 Karsten Ahnert +# Copyright 2013 Pascal Germroth +# 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) + +use-project /boost : $(BOOST_ROOT) ; +import openmp : * ; + +project + : requirements + <include>.. + <define>BOOST_ALL_NO_LIB=1 + <library>/boost//timer + [ openmp ] + ; + +exe lorenz_ensemble : lorenz_ensemble.cpp ; +exe lorenz_ensemble_simple : lorenz_ensemble_simple.cpp ; +exe lorenz_ensemble_nested : lorenz_ensemble_nested.cpp ; +exe phase_chain : phase_chain.cpp ; +exe phase_chain_omp_state : phase_chain_omp_state.cpp ; diff --git a/src/boost/libs/numeric/odeint/examples/openmp/lorenz_ensemble.cpp b/src/boost/libs/numeric/odeint/examples/openmp/lorenz_ensemble.cpp new file mode 100644 index 000000000..6717a505b --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/openmp/lorenz_ensemble.cpp @@ -0,0 +1,91 @@ +/* Boost libs/numeric/odeint/examples/openmp/lorenz_ensemble.cpp + + Copyright 2013 Karsten Ahnert + Copyright 2013 Mario Mulansky + Copyright 2013 Pascal Germroth + + Parallelized Lorenz ensembles + + 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) + */ + +#include <omp.h> +#include <vector> +#include <iostream> +#include <iterator> +#include <boost/numeric/odeint.hpp> +#include <boost/numeric/odeint/external/openmp/openmp.hpp> +#include <boost/lexical_cast.hpp> +#include "point_type.hpp" + +using namespace std; +using namespace boost::numeric::odeint; + +typedef point<double, 3> point_type; +typedef vector< point_type > inner_state_type; +typedef openmp_state<point_type> state_type; + +const double sigma = 10.0; +const double b = 8.0 / 3.0; + + +struct sys_func { + const vector<double> &R; + sys_func( vector<double> &R ) : R(R) {} + + void operator()( const state_type &x , state_type &dxdt , double t ) const { +# pragma omp parallel for + for(size_t j = 0 ; j < x.size() ; j++) { + size_t offset = 0; + for(size_t i = 0 ; i < j ; i++) + offset += x[i].size(); + + for(size_t i = 0 ; i < x[j].size() ; i++) { + const point_type &xi = x[j][i]; + point_type &dxdti = dxdt[j][i]; + dxdti[0] = -sigma * (xi[0] - xi[1]); + dxdti[1] = R[offset + i] * xi[0] - xi[1] - xi[0] * xi[2]; + dxdti[2] = -b * xi[2] + xi[0] * xi[1]; + } + } + } +}; + + +int main(int argc, char **argv) { + size_t n = 1024; + if(argc > 1) n = boost::lexical_cast<size_t>(argv[1]); + + vector<double> R(n); + const double Rmin = 0.1, Rmax = 50.0; +# pragma omp parallel for + for(size_t i = 0 ; i < n ; i++) + R[i] = Rmin + (Rmax - Rmin) / (n - 1) * i; + + vector<point_type> inner(n, point_type(10, 10, 10)); + state_type state; + split(inner, state); + + cerr << "openmp_state split " << n << " into"; + for(size_t i = 0 ; i != state.size() ; i++) + cerr << ' ' << state[i].size(); + cerr << endl; + + typedef runge_kutta4< state_type, double > stepper; + + const double t_max = 10.0, dt = 0.01; + + integrate_const( + stepper(), + sys_func(R), + state, + 0.0, t_max, dt + ); + + unsplit(state, inner); + std::copy( inner.begin(), inner.end(), ostream_iterator<point_type>(cout, "\n") ); + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/openmp/lorenz_ensemble_nested.cpp b/src/boost/libs/numeric/odeint/examples/openmp/lorenz_ensemble_nested.cpp new file mode 100644 index 000000000..4609c47a4 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/openmp/lorenz_ensemble_nested.cpp @@ -0,0 +1,75 @@ +/* Boost libs/numeric/odeint/examples/openmp/lorenz_ensemble_nested.cpp + + Copyright 2013 Karsten Ahnert + Copyright 2013 Pascal Germroth + Copyright 2013 Mario Mulansky + + Parallelized Lorenz ensembles using nested omp algebra + + 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) + */ + +#include <omp.h> +#include <vector> +#include <iostream> +#include <iterator> +#include <boost/numeric/odeint.hpp> +#include <boost/numeric/odeint/external/openmp/openmp.hpp> +#include <boost/lexical_cast.hpp> +#include "point_type.hpp" + +using namespace std; +using namespace boost::numeric::odeint; + +typedef point<double, 3> point_type; +typedef vector< point_type > state_type; + +const double sigma = 10.0; +const double b = 8.0 / 3.0; + + +struct sys_func { + const vector<double> &R; + sys_func( vector<double> &R ) : R(R) {} + + void operator()( const state_type &x , state_type &dxdt , double t ) const { +# pragma omp parallel for + for(size_t i = 0 ; i < x.size() ; i++) { + dxdt[i][0] = -sigma * (x[i][0] - x[i][1]); + dxdt[i][1] = R[i] * x[i][0] - x[i][1] - x[i][0] * x[i][2]; + dxdt[i][2] = -b * x[i][2] + x[i][0] * x[i][1]; + } + } +}; + + +int main(int argc, char **argv) { + size_t n = 1024; + if(argc > 1) n = boost::lexical_cast<size_t>(argv[1]); + + vector<double> R(n); + const double Rmin = 0.1, Rmax = 50.0; +# pragma omp parallel for + for(size_t i = 0 ; i < n ; i++) + R[i] = Rmin + (Rmax - Rmin) / (n - 1) * i; + + state_type state( n , point_type(10, 10, 10) ); + + typedef runge_kutta4< state_type, double , state_type , double , + openmp_nested_algebra<vector_space_algebra> > stepper; + + const double t_max = 10.0, dt = 0.01; + + integrate_const( + stepper(), + sys_func(R), + state, + 0.0, t_max, dt + ); + + std::copy( state.begin(), state.end(), ostream_iterator<point_type>(cout, "\n") ); + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/openmp/lorenz_ensemble_simple.cpp b/src/boost/libs/numeric/odeint/examples/openmp/lorenz_ensemble_simple.cpp new file mode 100644 index 000000000..fbaf24999 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/openmp/lorenz_ensemble_simple.cpp @@ -0,0 +1,79 @@ +/* Boost libs/numeric/odeint/examples/openmp/lorenz_ensemble_simple.cpp + + Copyright 2013 Karsten Ahnert + Copyright 2013 Mario Mulansky + Copyright 2013 Pascal Germroth + + Parallelized Lorenz ensembles + + 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) + */ + +#include <omp.h> +#include <vector> +#include <iostream> +#include <boost/numeric/odeint.hpp> +#include <boost/numeric/odeint/external/openmp/openmp.hpp> +#include "point_type.hpp" + +using namespace std; + +typedef vector<double> vector_type; +typedef point<double, 3> point_type; +typedef vector<point_type> state_type; + +const double sigma = 10.0; +const double b = 8.0 / 3.0; + +struct sys_func { + const vector_type &R; + sys_func( const vector_type &_R ) : R( _R ) { } + + void operator()( const state_type &x , state_type &dxdt , double t ) const { + const size_t n = x.size(); +# pragma omp parallel for + for(size_t i = 0 ; i < n ; i++) { + const point_type &xi = x[i]; + point_type &dxdti = dxdt[i]; + dxdti[0] = -sigma * (xi[0] - xi[1]); + dxdti[1] = R[i] * xi[0] - xi[1] - xi[0] * xi[2]; + dxdti[2] = -b * xi[2] + xi[0] * xi[1]; + } + } +}; + + +int main() { + using namespace boost::numeric::odeint; + + const size_t n = 1024; + vector_type R(n); + const double Rmin = 0.1, Rmax = 50.0; +# pragma omp parallel for + for(size_t i = 0 ; i < n ; i++) + R[i] = Rmin + (Rmax - Rmin) / (n - 1) * i; + + state_type X(n, point_type(10, 10, 10)); + + const double t_max = 10.0, dt = 0.01; + + // Simple stepper with constant step size + // typedef runge_kutta4<state_type, double, state_type, double, + // openmp_range_algebra> stepper; + + // integrate_const(stepper(), sys_func(R), X, 0.0, t_max, dt); + + // Controlled stepper with variable step size + typedef runge_kutta_fehlberg78<state_type, double, state_type, double, + openmp_range_algebra> error_stepper_type; + typedef controlled_runge_kutta<error_stepper_type> controlled_stepper_type; + controlled_stepper_type controlled_stepper; + + integrate_adaptive(controlled_stepper, sys_func(R), X, 0.0, t_max, dt); + + copy( X.begin(), X.end(), ostream_iterator<point_type>(cout, "\n") ); + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/openmp/openmp.jam b/src/boost/libs/numeric/odeint/examples/openmp/openmp.jam new file mode 100644 index 000000000..226bcf577 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/openmp/openmp.jam @@ -0,0 +1,52 @@ +# Copyright 2013 Karsten Ahnert +# Copyright 2013 Mario Mulansky +# Copyright 2013 Pascal Germroth +# 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) + + +# Only builds target with supported OpenMP enabled toolsets. +# +# use as: +# exe omp : omp.cpp : [ openmp ] ; +# +rule openmp return + # default + <build>no + # GNU C++ + <toolset>gcc:<cxxflags>-fopenmp + <toolset>gcc:<linkflags>-fopenmp + <toolset>gcc:<build>yes + # Microsoft Visual C++ + <toolset>msvc:<cxxflags>/openmp + <toolset>msvc:<linkflags>/openmp + <toolset>msvc:<build>yes + # Intel C++ + <toolset>intel-linux:<cxxflags>-openmp + <toolset>intel-linux:<linkflags>-openmp + <toolset>intel-linux:<build>yes + <toolset>intel-win:<cxxflags>-Qopenmp + <toolset>intel-win:<linkflags>-Qopenmp + <toolset>intel-win:<build>yes + # HP aC++ + <toolset>acc:<cxxflags>+Oopenmp + <toolset>acc:<linkflags>+Oopenmp + <toolset>acc:<build>yes + # Sun Studio + <toolset>sun:<cxxflags>-xopenmp + <toolset>sun:<linkflags>-xopenmp + <toolset>sun:<build>yes + # IBM XL + <toolset>vacpp:<cxxflags>-qsmp=omp + <toolset>vacpp:<linkflags>-qsmp=omp + <toolset>vacpp:<build>yes + # PG++ + <toolset>pgi:<cxxflags>-mp + <toolset>pgi:<linkflags>-mp + <toolset>pgi:<build>yes + # Pathscale + <toolset>pathscale:<cxxflags>-mp + <toolset>pathscale:<linkflags>-mp + <toolset>pathscale:<build>yes + ; diff --git a/src/boost/libs/numeric/odeint/examples/openmp/phase_chain.cpp b/src/boost/libs/numeric/odeint/examples/openmp/phase_chain.cpp new file mode 100644 index 000000000..08876fcce --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/openmp/phase_chain.cpp @@ -0,0 +1,95 @@ +/* + * phase_chain.cpp + * + * Example of OMP parallelization with odeint + * + * Copyright 2013 Karsten Ahnert + * Copyright 2013 Mario Mulansky + * Copyright 2013 Pascal Germroth + * 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) + */ + +#include <iostream> +#include <vector> +#include <boost/random.hpp> +#include <boost/timer/timer.hpp> +//[phase_chain_openmp_header +#include <omp.h> +#include <boost/numeric/odeint.hpp> +#include <boost/numeric/odeint/external/openmp/openmp.hpp> +//] + +using namespace std; +using namespace boost::numeric::odeint; +using boost::timer::cpu_timer; +using boost::math::double_constants::pi; + +//[phase_chain_vector_state +typedef std::vector< double > state_type; +//] + +//[phase_chain_rhs +struct phase_chain +{ + phase_chain( double gamma = 0.5 ) + : m_gamma( gamma ) { } + + void operator()( const state_type &x , state_type &dxdt , double /* t */ ) const + { + const size_t N = x.size(); + #pragma omp parallel for schedule(runtime) + for(size_t i = 1 ; i < N - 1 ; ++i) + { + dxdt[i] = coupling_func( x[i+1] - x[i] ) + + coupling_func( x[i-1] - x[i] ); + } + dxdt[0 ] = coupling_func( x[1 ] - x[0 ] ); + dxdt[N-1] = coupling_func( x[N-2] - x[N-1] ); + } + + double coupling_func( double x ) const + { + return sin( x ) - m_gamma * ( 1.0 - cos( x ) ); + } + + double m_gamma; +}; +//] + + +int main( int argc , char **argv ) +{ + //[phase_chain_init + size_t N = 131101; + state_type x( N ); + boost::random::uniform_real_distribution<double> distribution( 0.0 , 2.0*pi ); + boost::random::mt19937 engine( 0 ); + generate( x.begin() , x.end() , boost::bind( distribution , engine ) ); + //] + + //[phase_chain_stepper + typedef runge_kutta4< + state_type , double , + state_type , double , + openmp_range_algebra + > stepper_type; + //] + + //[phase_chain_scheduling + int chunk_size = N/omp_get_max_threads(); + omp_set_schedule( omp_sched_static , chunk_size ); + //] + + cpu_timer timer; + //[phase_chain_integrate + integrate_n_steps( stepper_type() , phase_chain( 1.2 ) , + x , 0.0 , 0.01 , 100 ); + //] + double run_time = static_cast<double>(timer.elapsed().wall) * 1.0e-9; + std::cerr << run_time << "s" << std::endl; + // copy(x.begin(), x.end(), ostream_iterator<double>(cout, "\n")); + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/openmp/phase_chain_omp_state.cpp b/src/boost/libs/numeric/odeint/examples/openmp/phase_chain_omp_state.cpp new file mode 100644 index 000000000..8627f58ad --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/openmp/phase_chain_omp_state.cpp @@ -0,0 +1,98 @@ +/* + * phase_chain_omp_state.cpp + * + * Example of OMP parallelization with odeint + * + * Copyright 2013 Karsten Ahnert + * Copyright 2013 Mario Mulansky + * Copyright 2013 Pascal Germroth + * 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) + */ + +#include <iostream> +#include <vector> +#include <boost/random.hpp> +#include <boost/timer/timer.hpp> +#include <omp.h> +#include <boost/numeric/odeint.hpp> +#include <boost/numeric/odeint/external/openmp/openmp.hpp> + +#include <boost/numeric/odeint.hpp> + +using namespace std; +using namespace boost::numeric::odeint; +using boost::timer::cpu_timer; +using boost::math::double_constants::pi; + +typedef openmp_state<double> state_type; + +//[phase_chain_state_rhs +struct phase_chain_omp_state +{ + phase_chain_omp_state( double gamma = 0.5 ) + : m_gamma( gamma ) { } + + void operator()( const state_type &x , state_type &dxdt , double /* t */ ) const + { + const size_t N = x.size(); + #pragma omp parallel for schedule(runtime) + for(size_t n = 0 ; n < N ; ++n) + { + const size_t M = x[n].size(); + for(size_t m = 1 ; m < M-1 ; ++m) + { + dxdt[n][m] = coupling_func( x[n][m+1] - x[n][m] ) + + coupling_func( x[n][m-1] - x[n][m] ); + } + dxdt[n][0] = coupling_func( x[n][1] - x[n][0] ); + if( n > 0 ) + { + dxdt[n][0] += coupling_func( x[n-1].back() - x[n].front() ); + } + dxdt[n][M-1] = coupling_func( x[n][M-2] - x[n][M-1] ); + if( n < N-1 ) + { + dxdt[n][M-1] += coupling_func( x[n+1].front() - x[n].back() ); + } + } + } + + double coupling_func( double x ) const + { + return sin( x ) - m_gamma * ( 1.0 - cos( x ) ); + } + + double m_gamma; +}; +//] + + +int main( int argc , char **argv ) +{ + //[phase_chain_state_init + const size_t N = 131101; + vector<double> x( N ); + boost::random::uniform_real_distribution<double> distribution( 0.0 , 2.0*pi ); + boost::random::mt19937 engine( 0 ); + generate( x.begin() , x.end() , boost::bind( distribution , engine ) ); + const size_t blocks = omp_get_max_threads(); + state_type x_split( blocks ); + split( x , x_split ); + //] + + + cpu_timer timer; + //[phase_chain_state_integrate + integrate_n_steps( runge_kutta4<state_type>() , phase_chain_omp_state( 1.2 ) , + x_split , 0.0 , 0.01 , 100 ); + unsplit( x_split , x ); + //] + + double run_time = static_cast<double>(timer.elapsed().wall) * 1.0e-9; + std::cerr << run_time << "s" << std::endl; + // copy(x.begin(), x.end(), ostream_iterator<double>(cout, "\n")); + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/phase_oscillator_ensemble.cpp b/src/boost/libs/numeric/odeint/examples/phase_oscillator_ensemble.cpp new file mode 100644 index 000000000..090fd587b --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/phase_oscillator_ensemble.cpp @@ -0,0 +1,151 @@ +/* + * phase_oscillator_ensemble.cpp + * + * Demonstrates the phase transition from an unsynchronized to an synchronized state. + * + * Copyright 2011-2012 Karsten Ahnert + * Copyright 2011-2012 Mario Mulansky + * 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) + * + */ + +#include <iostream> +#include <utility> + +#include <boost/numeric/odeint.hpp> + +#ifndef M_PI //not there on windows +#define M_PI 3.141592653589793 //... +#endif + +#include <boost/random.hpp> + +using namespace std; +using namespace boost::numeric::odeint; + +//[ phase_oscillator_ensemble_system_function +typedef vector< double > container_type; + + +pair< double , double > calc_mean_field( const container_type &x ) +{ + size_t n = x.size(); + double cos_sum = 0.0 , sin_sum = 0.0; + for( size_t i=0 ; i<n ; ++i ) + { + cos_sum += cos( x[i] ); + sin_sum += sin( x[i] ); + } + cos_sum /= double( n ); + sin_sum /= double( n ); + + double K = sqrt( cos_sum * cos_sum + sin_sum * sin_sum ); + double Theta = atan2( sin_sum , cos_sum ); + + return make_pair( K , Theta ); +} + + +struct phase_ensemble +{ + container_type m_omega; + double m_epsilon; + + phase_ensemble( const size_t n , double g = 1.0 , double epsilon = 1.0 ) + : m_omega( n , 0.0 ) , m_epsilon( epsilon ) + { + create_frequencies( g ); + } + + void create_frequencies( double g ) + { + boost::mt19937 rng; + boost::cauchy_distribution<> cauchy( 0.0 , g ); + boost::variate_generator< boost::mt19937&, boost::cauchy_distribution<> > gen( rng , cauchy ); + generate( m_omega.begin() , m_omega.end() , gen ); + } + + void set_epsilon( double epsilon ) { m_epsilon = epsilon; } + + double get_epsilon( void ) const { return m_epsilon; } + + void operator()( const container_type &x , container_type &dxdt , double /* t */ ) const + { + pair< double , double > mean = calc_mean_field( x ); + for( size_t i=0 ; i<x.size() ; ++i ) + dxdt[i] = m_omega[i] + m_epsilon * mean.first * sin( mean.second - x[i] ); + } +}; +//] + + + +//[ phase_oscillator_ensemble_observer +struct statistics_observer +{ + double m_K_mean; + size_t m_count; + + statistics_observer( void ) + : m_K_mean( 0.0 ) , m_count( 0 ) { } + + template< class State > + void operator()( const State &x , double t ) + { + pair< double , double > mean = calc_mean_field( x ); + m_K_mean += mean.first; + ++m_count; + } + + double get_K_mean( void ) const { return ( m_count != 0 ) ? m_K_mean / double( m_count ) : 0.0 ; } + + void reset( void ) { m_K_mean = 0.0; m_count = 0; } +}; +//] + + + + + + + + +int main( int argc , char **argv ) +{ + //[ phase_oscillator_ensemble_integration + const size_t n = 16384; + const double dt = 0.1; + + container_type x( n ); + + boost::mt19937 rng; + boost::uniform_real<> unif( 0.0 , 2.0 * M_PI ); + boost::variate_generator< boost::mt19937&, boost::uniform_real<> > gen( rng , unif ); + + // gamma = 1, the phase transition occurs at epsilon = 2 + phase_ensemble ensemble( n , 1.0 ); + statistics_observer obs; + + for( double epsilon = 0.0 ; epsilon < 5.0 ; epsilon += 0.1 ) + { + ensemble.set_epsilon( epsilon ); + obs.reset(); + + // start with random initial conditions + generate( x.begin() , x.end() , gen ); + + // calculate some transients steps + integrate_const( runge_kutta4< container_type >() , boost::ref( ensemble ) , x , 0.0 , 10.0 , dt ); + + // integrate and compute the statistics + integrate_const( runge_kutta4< container_type >() , boost::ref( ensemble ) , x , 0.0 , 100.0 , dt , boost::ref( obs ) ); + cout << epsilon << "\t" << obs.get_K_mean() << endl; + } + + + //] + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/point_type.hpp b/src/boost/libs/numeric/odeint/examples/point_type.hpp new file mode 100644 index 000000000..088751108 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/point_type.hpp @@ -0,0 +1,177 @@ +/* Boost libs/numeric/odeint/examples/point_type.hpp + + Copyright 2010-2012 Karsten Ahnert + Copyright 2011 Mario Mulansky + + solar system example for Hamiltonian stepper + + 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) + */ + +#ifndef POINT_TYPE_HPP_INCLUDED +#define POINT_TYPE_HPP_INCLUDED + + +#include <boost/operators.hpp> +#include <ostream> + + +//[ point_type +/*the point type */ +template< class T , size_t Dim > +class point : + boost::additive1< point< T , Dim > , + boost::additive2< point< T , Dim > , T , + boost::multiplicative2< point< T , Dim > , T + > > > + { + public: + + const static size_t dim = Dim; + typedef T value_type; + typedef point< value_type , dim > point_type; + + // ... + // constructors + //<- + point( void ) + { + for( size_t i=0 ; i<dim ; ++i ) m_val[i] = 0.0; + } + + point( value_type val ) + { + for( size_t i=0 ; i<dim ; ++i ) m_val[i] = val; + } + + point( value_type x , value_type y , value_type z = 0.0 ) + { + if( dim > 0 ) m_val[0] = x; + if( dim > 1 ) m_val[1] = y; + if( dim > 2 ) m_val[2] = z; + } + //-> + + // ... + // operators + //<- + T operator[]( size_t i ) const { return m_val[i]; } + T& operator[]( size_t i ) { return m_val[i]; } + + point_type& operator+=( const point_type& p ) + { + for( size_t i=0 ; i<dim ; ++i ) + m_val[i] += p[i]; + return *this; + } + + point_type& operator-=( const point_type& p ) + { + for( size_t i=0 ; i<dim ; ++i ) + m_val[i] -= p[i]; + return *this; + } + + point_type& operator+=( const value_type& val ) + { + for( size_t i=0 ; i<dim ; ++i ) + m_val[i] += val; + return *this; + } + + point_type& operator-=( const value_type& val ) + { + for( size_t i=0 ; i<dim ; ++i ) + m_val[i] -= val; + return *this; + } + + point_type& operator*=( const value_type &val ) + { + for( size_t i=0 ; i<dim ; ++i ) + m_val[i] *= val; + return *this; + } + + point_type& operator/=( const value_type &val ) + { + for( size_t i=0 ; i<dim ; ++i ) + m_val[i] /= val; + return *this; + } + + //-> + + private: + + T m_val[dim]; + }; + + //... + // more operators + //] + + // + // the - operator + // + template< class T , size_t Dim > + point< T , Dim > operator-( const point< T , Dim > &p ) + { + point< T , Dim > tmp; + for( size_t i=0 ; i<Dim ; ++i ) tmp[i] = -p[i]; + return tmp; + } + + // + // scalar product + // + template< class T , size_t Dim > + T scalar_prod( const point< T , Dim > &p1 , const point< T , Dim > &p2 ) + { + T tmp = 0.0; + for( size_t i=0 ; i<Dim ; ++i ) tmp += p1[i] * p2[i]; + return tmp; + } + + + + // + // norm + // + template< class T , size_t Dim > + T norm( const point< T , Dim > &p1 ) + { + return scalar_prod( p1 , p1 ); + } + + + + + // + // absolute value + // + template< class T , size_t Dim > + T abs( const point< T , Dim > &p1 ) + { + return sqrt( norm( p1 ) ); + } + + + + + // + // output operator + // + template< class T , size_t Dim > + std::ostream& operator<<( std::ostream &out , const point< T , Dim > &p ) + { + if( Dim > 0 ) out << p[0]; + for( size_t i=1 ; i<Dim ; ++i ) out << " " << p[i]; + return out; + } + + + +#endif //POINT_TYPE_HPP_INCLUDED diff --git a/src/boost/libs/numeric/odeint/examples/quadmath/Jamfile.v2 b/src/boost/libs/numeric/odeint/examples/quadmath/Jamfile.v2 new file mode 100644 index 000000000..88a046325 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/quadmath/Jamfile.v2 @@ -0,0 +1,16 @@ +# Copyright 2011 Mario Mulansky +# Copyright 2012 Karsten Ahnert +# 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) + + +project + : requirements + <define>BOOST_ALL_NO_LIB=1 + : + ; + +lib quadmath : : <name>quadmath <link>shared ; + +exe black_hole : black_hole.cpp quadmath : <cxxflags>-std=c++0x ;
\ No newline at end of file diff --git a/src/boost/libs/numeric/odeint/examples/quadmath/black_hole.cpp b/src/boost/libs/numeric/odeint/examples/quadmath/black_hole.cpp new file mode 100644 index 000000000..5a6802af0 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/quadmath/black_hole.cpp @@ -0,0 +1,151 @@ +/* + [auto_generated] + libs/numeric/odeint/examples/black_hole.cpp + + [begin_description] + This example shows how the __float128 from gcc libquadmath can be used with odeint. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2012 Lee Hodgkinson + Copyright 2012 Mario Mulansky + + 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) + */ + +#include <cstdlib> +#include <cmath> +#include <iostream> +#include <iterator> +#include <utility> +#include <algorithm> +#include <cassert> +#include <vector> +#include <complex> + +extern "C" { +#include <quadmath.h> +} + +const __float128 zero =strtoflt128 ("0.0", NULL); + +namespace std { + + inline __float128 abs( __float128 x ) + { + return fabsq( x ); + } + + inline __float128 sqrt( __float128 x ) + { + return sqrtq( x ); + } + + inline __float128 pow( __float128 x , __float128 y ) + { + return powq( x , y ); + } + + inline __float128 abs( std::complex< __float128 > x ) + { + return sqrtq( x.real() * x.real() + x.imag() * x.imag() ); + } + + inline std::complex< __float128 > pow( std::complex< __float128> x , __float128 y ) + { + __float128 r = pow( abs(x) , y ); + __float128 phi = atanq( x.imag() / x.real() ); + return std::complex< __float128 >( r * cosq( y * phi ) , r * sinq( y * phi ) ); + } +} + +inline std::ostream& operator<< (std::ostream& os, const __float128& f) { + + char* y = new char[1000]; + quadmath_snprintf(y, 1000, "%.30Qg", f) ; + os.precision(30); + os<<y; + delete[] y; + return os; +} + + +#include <boost/array.hpp> +#include <boost/range/algorithm.hpp> +#include <boost/range/adaptor/filtered.hpp> +#include <boost/range/numeric.hpp> +#include <boost/numeric/odeint.hpp> + + + +using namespace boost::numeric::odeint; +using namespace std; + +typedef __float128 my_float; +typedef std::vector< std::complex < my_float > > state_type; + +struct radMod +{ + my_float m_om; + my_float m_l; + + radMod( my_float om , my_float l ) + : m_om( om ) , m_l( l ) { } + + void operator()( const state_type &x , state_type &dxdt , my_float r ) const + { + + dxdt[0] = x[1]; + dxdt[1] = -(2*(r-1)/(r*(r-2)))*x[1]-((m_om*m_om*r*r/((r-2)*(r-2)))-(m_l*(m_l+1)/(r*(r-2))))*x[0]; + } +}; + + + + + + + +int main( int argc , char **argv ) +{ + + + state_type x(2); + + my_float re0 = strtoflt128( "-0.00008944230755601224204687038354994353820468" , NULL ); + my_float im0 = strtoflt128( "0.00004472229441850588228136889483397204368247" , NULL ); + my_float re1 = strtoflt128( "-4.464175354293244250869336196695966076150E-6 " , NULL ); + my_float im1 = strtoflt128( "-8.950483248390306670770345406051469584488E-6" , NULL ); + + x[0] = complex< my_float >( re0 ,im0 ); + x[1] = complex< my_float >( re1 ,im1 ); + + const my_float dt =strtoflt128 ("-0.001", NULL); + const my_float start =strtoflt128 ("10000.0", NULL); + const my_float end =strtoflt128 ("9990.0", NULL); + const my_float omega =strtoflt128 ("2.0", NULL); + const my_float ell =strtoflt128 ("1.0", NULL); + + + + my_float abs_err = strtoflt128( "1.0E-15" , NULL ) , rel_err = strtoflt128( "1.0E-10" , NULL ); + my_float a_x = strtoflt128( "1.0" , NULL ) , a_dxdt = strtoflt128( "1.0" , NULL ); + + typedef runge_kutta_dopri5< state_type, my_float > dopri5_type; + typedef controlled_runge_kutta< dopri5_type > controlled_dopri5_type; + typedef dense_output_runge_kutta< controlled_dopri5_type > dense_output_dopri5_type; + + dense_output_dopri5_type dopri5( controlled_dopri5_type( default_error_checker< my_float >( abs_err , rel_err , a_x , a_dxdt ) ) ); + + std::for_each( make_adaptive_time_iterator_begin(dopri5 , radMod(omega , ell) , x , start , end , dt) , + make_adaptive_time_iterator_end(dopri5 , radMod(omega , ell) , x ) , + []( const std::pair< state_type&, my_float > &x ) { + std::cout << x.second << ", " << x.first[0].real() << "\n"; } + ); + + + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/resizing_lattice.cpp b/src/boost/libs/numeric/odeint/examples/resizing_lattice.cpp new file mode 100644 index 000000000..f77f26e5d --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/resizing_lattice.cpp @@ -0,0 +1,169 @@ +/* + * resizing_lattice.cpp + * + * Demonstrates the usage of resizing of the state type during integration. + * Examplary system is a strongly nonlinear, disordered Hamiltonian lattice + * where the spreading of energy is investigated + * + * Copyright 2011-2012 Mario Mulansky + * Copyright 2012-2013 Karsten Ahnert + * 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) + * + */ + +#include <iostream> +#include <utility> + +#include <boost/numeric/odeint.hpp> + +#include <boost/ref.hpp> +#include <boost/random.hpp> + +using namespace std; +using namespace boost::numeric::odeint; + +//[ resizing_lattice_system_class +typedef vector< double > coord_type; +typedef pair< coord_type , coord_type > state_type; + +struct compacton_lattice +{ + const int m_max_N; + const double m_beta; + int m_pot_start_index; + vector< double > m_pot; + + compacton_lattice( int max_N , double beta , int pot_start_index ) + : m_max_N( max_N ) , m_beta( beta ) , m_pot_start_index( pot_start_index ) , m_pot( max_N ) + { + srand( time( NULL ) ); + // fill random potential with iid values from [0,1] + boost::mt19937 rng; + boost::uniform_real<> unif( 0.0 , 1.0 ); + boost::variate_generator< boost::mt19937&, boost::uniform_real<> > gen( rng , unif ); + generate( m_pot.begin() , m_pot.end() , gen ); + } + + void operator()( const coord_type &q , coord_type &dpdt ) + { + // calculate dpdt = -dH/dq of this hamiltonian system + // dp_i/dt = - V_i * q_i^3 - beta*(q_i - q_{i-1})^3 + beta*(q_{i+1} - q_i)^3 + const int N = q.size(); + double diff = q[0] - q[N-1]; + for( int i=0 ; i<N ; ++i ) + { + dpdt[i] = - m_pot[m_pot_start_index+i] * q[i]*q[i]*q[i] - + m_beta * diff*diff*diff; + diff = q[(i+1) % N] - q[i]; + dpdt[i] += m_beta * diff*diff*diff; + } + } + + void energy_distribution( const coord_type &q , const coord_type &p , coord_type &energies ) + { + // computes the energy per lattice site normalized by total energy + const size_t N = q.size(); + double en = 0.0; + for( size_t i=0 ; i<N ; i++ ) + { + const double diff = q[(i+1) % N] - q[i]; + energies[i] = p[i]*p[i]/2.0 + + m_pot[m_pot_start_index+i]*q[i]*q[i]*q[i]*q[i]/4.0 + + m_beta/4.0 * diff*diff*diff*diff; + en += energies[i]; + } + en = 1.0/en; + for( size_t i=0 ; i<N ; i++ ) + { + energies[i] *= en; + } + } + + double energy( const coord_type &q , const coord_type &p ) + { + // calculates the total energy of the excitation + const size_t N = q.size(); + double en = 0.0; + for( size_t i=0 ; i<N ; i++ ) + { + const double diff = q[(i+1) % N] - q[i]; + en += p[i]*p[i]/2.0 + + m_pot[m_pot_start_index+i]*q[i]*q[i]*q[i]*q[i] / 4.0 + + m_beta/4.0 * diff*diff*diff*diff; + } + return en; + } + + void change_pot_start( const int delta ) + { + m_pot_start_index += delta; + } +}; +//] + +//[ resizing_lattice_resize_function +void do_resize( coord_type &q , coord_type &p , coord_type &distr , const int N ) +{ + q.resize( N ); + p.resize( N ); + distr.resize( N ); +} +//] + +const int max_N = 1024; +const double beta = 1.0; + +int main() +{ + //[ resizing_lattice_initialize + //start with 60 sites + const int N_start = 60; + coord_type q( N_start , 0.0 ); + q.reserve( max_N ); + coord_type p( N_start , 0.0 ); + p.reserve( max_N ); + // start with uniform momentum distribution over 20 sites + fill( p.begin()+20 , p.end()-20 , 1.0/sqrt(20.0) ); + + coord_type distr( N_start , 0.0 ); + distr.reserve( max_N ); + + // create the system + compacton_lattice lattice( max_N , beta , (max_N-N_start)/2 ); + + //create the stepper, note that we use an always_resizer because state size might change during steps + typedef symplectic_rkn_sb3a_mclachlan< coord_type , coord_type , double , coord_type , coord_type , double , + range_algebra , default_operations , always_resizer > hamiltonian_stepper; + hamiltonian_stepper stepper; + hamiltonian_stepper::state_type state = make_pair( q , p ); + //] + + //[ resizing_lattice_steps_loop + double t = 0.0; + const double dt = 0.1; + const int steps = 10000; + for( int step = 0 ; step < steps ; ++step ) + { + stepper.do_step( boost::ref(lattice) , state , t , dt ); + lattice.energy_distribution( state.first , state.second , distr ); + if( distr[10] > 1E-150 ) + { + do_resize( state.first , state.second , distr , state.first.size()+20 ); + rotate( state.first.begin() , state.first.end()-20 , state.first.end() ); + rotate( state.second.begin() , state.second.end()-20 , state.second.end() ); + lattice.change_pot_start( -20 ); + cout << t << ": resized left to " << distr.size() << ", energy = " << lattice.energy( state.first , state.second ) << endl; + } + if( distr[distr.size()-10] > 1E-150 ) + { + do_resize( state.first , state.second , distr , state.first.size()+20 ); + cout << t << ": resized right to " << distr.size() << ", energy = " << lattice.energy( state.first , state.second ) << endl; + } + t += dt; + } + //] + + cout << "final lattice size: " << distr.size() << ", final energy: " << lattice.energy( state.first , state.second ) << endl; +} diff --git a/src/boost/libs/numeric/odeint/examples/simple1d.cpp b/src/boost/libs/numeric/odeint/examples/simple1d.cpp new file mode 100644 index 000000000..3a8dfa04f --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/simple1d.cpp @@ -0,0 +1,44 @@ +/* Boost libs/numeric/odeint/examples/simple1d.cpp + + Copyright 2012-2013 Mario Mulansky + Copyright 2012 Karsten Ahnert + + example for a simple one-dimensional 1st order ODE + + 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) + */ + + +#include <iostream> +#include <boost/numeric/odeint.hpp> + +using namespace std; +using namespace boost::numeric::odeint; + + +/* we solve the simple ODE x' = 3/(2t^2) + x/(2t) + * with initial condition x(1) = 0. + * Analytic solution is x(t) = sqrt(t) - 1/t + */ + +void rhs( const double x , double &dxdt , const double t ) +{ + dxdt = 3.0/(2.0*t*t) + x/(2.0*t); +} + +void write_cout( const double &x , const double t ) +{ + cout << t << '\t' << x << endl; +} + +// state_type = double +typedef runge_kutta_dopri5< double > stepper_type; + +int main() +{ + double x = 0.0; //initial value x(1) = 0 + // use dopri5 with stepsize control and allowed errors 10^-12, integrate t=1...10 + integrate_adaptive( make_controlled( 1E-12 , 1E-12 , stepper_type() ) , rhs , x , 1.0 , 10.0 , 0.1 , write_cout ); +} diff --git a/src/boost/libs/numeric/odeint/examples/solar_system.agr b/src/boost/libs/numeric/odeint/examples/solar_system.agr new file mode 100644 index 000000000..87f8c38e7 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/solar_system.agr @@ -0,0 +1,12672 @@ +# Grace project file +# +@version 50122 +@page size 792, 612 +@page scroll 5% +@page inout 5% +@link page off +@map font 0 to "Times-Roman", "Times-Roman" +@map font 1 to "Times-Italic", "Times-Italic" +@map font 2 to "Times-Bold", "Times-Bold" +@map font 3 to "Times-BoldItalic", "Times-BoldItalic" +@map font 4 to "Helvetica", "Helvetica" +@map font 5 to "Helvetica-Oblique", "Helvetica-Oblique" +@map font 6 to "Helvetica-Bold", "Helvetica-Bold" +@map font 7 to "Helvetica-BoldOblique", "Helvetica-BoldOblique" +@map font 8 to "Courier", "Courier" +@map font 9 to "Courier-Oblique", "Courier-Oblique" +@map font 10 to "Courier-Bold", "Courier-Bold" +@map font 11 to "Courier-BoldOblique", "Courier-BoldOblique" +@map font 12 to "Symbol", "Symbol" +@map font 13 to "ZapfDingbats", "ZapfDingbats" +@map color 0 to (255, 255, 255), "white" +@map color 1 to (0, 0, 0), "black" +@map color 2 to (255, 0, 0), "red" +@map color 3 to (0, 255, 0), "green" +@map color 4 to (0, 0, 255), "blue" +@map color 5 to (255, 255, 0), "yellow" +@map color 6 to (188, 143, 143), "brown" +@map color 7 to (220, 220, 220), "grey" +@map color 8 to (148, 0, 211), "violet" +@map color 9 to (0, 255, 255), "cyan" +@map color 10 to (255, 0, 255), "magenta" +@map color 11 to (255, 165, 0), "orange" +@map color 12 to (114, 33, 188), "indigo" +@map color 13 to (103, 7, 72), "maroon" +@map color 14 to (64, 224, 208), "turquoise" +@map color 15 to (0, 139, 0), "green4" +@reference date 0 +@date wrap off +@date wrap year 1950 +@default linewidth 1.0 +@default linestyle 1 +@default color 1 +@default pattern 1 +@default font 0 +@default char size 1.000000 +@default symbol size 1.000000 +@default sformat "%.8g" +@background color 0 +@page background fill on +@timestamp off +@timestamp 0.03, 0.03 +@timestamp color 1 +@timestamp rot 0 +@timestamp font 0 +@timestamp char size 1.000000 +@timestamp def "Fri Mar 18 17:58:35 2011" +@with line +@ line on +@ line loctype view +@ line 0.248774509804, 0.780637254902, 0.558823529412, 0.444852941176 +@ line linewidth 1.0 +@ line linestyle 1 +@ line color 1 +@ line arrow 0 +@ line arrow type 0 +@ line arrow length 1.000000 +@ line arrow layout 1.000000, 1.000000 +@line def +@with line +@ line on +@ line loctype view +@ line 0.730392156863, 0.126225490196, 0.621323529412, 0.411764705882 +@ line linewidth 1.0 +@ line linestyle 1 +@ line color 1 +@ line arrow 0 +@ line arrow type 0 +@ line arrow length 1.000000 +@ line arrow layout 1.000000, 1.000000 +@line def +@with line +@ line on +@ line loctype view +@ line 0.887254901961, 0.121323529412, 0.689950980392, 0.417892156863 +@ line linewidth 1.0 +@ line linestyle 1 +@ line color 1 +@ line arrow 0 +@ line arrow type 0 +@ line arrow length 1.000000 +@ line arrow layout 1.000000, 1.000000 +@line def +@with line +@ line on +@ line loctype view +@ line 1.07107843137, 0.120098039216, 0.827205882353, 0.447303921569 +@ line linewidth 1.0 +@ line linestyle 1 +@ line color 1 +@ line arrow 0 +@ line arrow type 0 +@ line arrow length 1.000000 +@ line arrow layout 1.000000, 1.000000 +@line def +@with string +@ string on +@ string loctype view +@ string 0.164215686274, 0.792892156863 +@ string color 1 +@ string rot 0 +@ string font 0 +@ string just 0 +@ string char size 2.000000 +@ string def "Sun" +@with string +@ string on +@ string loctype view +@ string 0.658088235294, 0.08 +@ string color 1 +@ string rot 0 +@ string font 0 +@ string just 0 +@ string char size 2.000000 +@ string def "Jupiter" +@with string +@ string on +@ string loctype view +@ string 0.837009803922, 0.08 +@ string color 1 +@ string rot 0 +@ string font 0 +@ string just 0 +@ string char size 2.000000 +@ string def "Saturn" +@with string +@ string on +@ string loctype view +@ string 1.00980392157, 0.08 +@ string color 1 +@ string rot 0 +@ string font 0 +@ string just 0 +@ string char size 2.000000 +@ string def "Uranus" +@with string +@ string on +@ string loctype view +@ string 0.735294117647, 0.680147058824 +@ string color 1 +@ string rot 0 +@ string font 0 +@ string just 0 +@ string char size 2.000000 +@ string def "Neptune" +@with string +@ string on +@ string loctype view +@ string 0.996323529411, 0.780637254902 +@ string color 1 +@ string rot 0 +@ string font 0 +@ string just 0 +@ string char size 2.000000 +@ string def "Pluto" +@r0 off +@link r0 to g0 +@r0 type above +@r0 linestyle 1 +@r0 linewidth 1.0 +@r0 color 1 +@r0 line 0, 0, 0, 0 +@r1 off +@link r1 to g0 +@r1 type above +@r1 linestyle 1 +@r1 linewidth 1.0 +@r1 color 1 +@r1 line 0, 0, 0, 0 +@r2 off +@link r2 to g0 +@r2 type above +@r2 linestyle 1 +@r2 linewidth 1.0 +@r2 color 1 +@r2 line 0, 0, 0, 0 +@r3 off +@link r3 to g0 +@r3 type above +@r3 linestyle 1 +@r3 linewidth 1.0 +@r3 color 1 +@r3 line 0, 0, 0, 0 +@r4 off +@link r4 to g0 +@r4 type above +@r4 linestyle 1 +@r4 linewidth 1.0 +@r4 color 1 +@r4 line 0, 0, 0, 0 +@g0 on +@g0 hidden false +@g0 type XY +@g0 stacked false +@g0 bar hgap 0.000000 +@g0 fixedpoint off +@g0 fixedpoint type 0 +@g0 fixedpoint xy 0.000000, 0.000000 +@g0 fixedpoint format general general +@g0 fixedpoint prec 6, 6 +@with g0 +@ world -32, -32, 45, 46 +@ stack world 0, 0, 0, 0 +@ znorm 1 +@ view 0.150000, 0.150000, 1.150000, 0.850000 +@ title "" +@ title font 0 +@ title size 1.500000 +@ title color 1 +@ subtitle "" +@ subtitle font 0 +@ subtitle size 1.000000 +@ subtitle color 1 +@ xaxes scale Normal +@ yaxes scale Normal +@ xaxes invert off +@ yaxes invert off +@ xaxis on +@ xaxis type zero false +@ xaxis offset 0.000000 , 0.000000 +@ xaxis bar on +@ xaxis bar color 1 +@ xaxis bar linestyle 1 +@ xaxis bar linewidth 1.0 +@ xaxis label "" +@ xaxis label layout para +@ xaxis label place auto +@ xaxis label char size 1.000000 +@ xaxis label font 0 +@ xaxis label color 1 +@ xaxis label place normal +@ xaxis tick off +@ xaxis tick major 20 +@ xaxis tick minor ticks 1 +@ xaxis tick default 6 +@ xaxis tick place rounded true +@ xaxis tick in +@ xaxis tick major size 1.000000 +@ xaxis tick major color 1 +@ xaxis tick major linewidth 1.0 +@ xaxis tick major linestyle 1 +@ xaxis tick major grid off +@ xaxis tick minor color 1 +@ xaxis tick minor linewidth 1.0 +@ xaxis tick minor linestyle 1 +@ xaxis tick minor grid off +@ xaxis tick minor size 0.500000 +@ xaxis ticklabel off +@ xaxis ticklabel format general +@ xaxis ticklabel prec 5 +@ xaxis ticklabel formula "" +@ xaxis ticklabel append "" +@ xaxis ticklabel prepend "" +@ xaxis ticklabel angle 0 +@ xaxis ticklabel skip 0 +@ xaxis ticklabel stagger 0 +@ xaxis ticklabel place normal +@ xaxis ticklabel offset auto +@ xaxis ticklabel offset 0.000000 , 0.010000 +@ xaxis ticklabel start type auto +@ xaxis ticklabel start 0.000000 +@ xaxis ticklabel stop type auto +@ xaxis ticklabel stop 0.000000 +@ xaxis ticklabel char size 1.000000 +@ xaxis ticklabel font 0 +@ xaxis ticklabel color 1 +@ xaxis tick place both +@ xaxis tick spec type none +@ yaxis on +@ yaxis type zero false +@ yaxis offset 0.000000 , 0.000000 +@ yaxis bar on +@ yaxis bar color 1 +@ yaxis bar linestyle 1 +@ yaxis bar linewidth 1.0 +@ yaxis label "" +@ yaxis label layout para +@ yaxis label place auto +@ yaxis label char size 1.000000 +@ yaxis label font 0 +@ yaxis label color 1 +@ yaxis label place normal +@ yaxis tick off +@ yaxis tick major 20 +@ yaxis tick minor ticks 1 +@ yaxis tick default 6 +@ yaxis tick place rounded true +@ yaxis tick in +@ yaxis tick major size 1.000000 +@ yaxis tick major color 1 +@ yaxis tick major linewidth 1.0 +@ yaxis tick major linestyle 1 +@ yaxis tick major grid off +@ yaxis tick minor color 1 +@ yaxis tick minor linewidth 1.0 +@ yaxis tick minor linestyle 1 +@ yaxis tick minor grid off +@ yaxis tick minor size 0.500000 +@ yaxis ticklabel off +@ yaxis ticklabel format general +@ yaxis ticklabel prec 5 +@ yaxis ticklabel formula "" +@ yaxis ticklabel append "" +@ yaxis ticklabel prepend "" +@ yaxis ticklabel angle 0 +@ yaxis ticklabel skip 0 +@ yaxis ticklabel stagger 0 +@ yaxis ticklabel place normal +@ yaxis ticklabel offset auto +@ yaxis ticklabel offset 0.000000 , 0.010000 +@ yaxis ticklabel start type auto +@ yaxis ticklabel start 0.000000 +@ yaxis ticklabel stop type auto +@ yaxis ticklabel stop 0.000000 +@ yaxis ticklabel char size 1.000000 +@ yaxis ticklabel font 0 +@ yaxis ticklabel color 1 +@ yaxis tick place both +@ yaxis tick spec type none +@ altxaxis off +@ altyaxis off +@ legend on +@ legend loctype view +@ legend 0.85, 0.8 +@ legend box color 1 +@ legend box pattern 1 +@ legend box linewidth 1.0 +@ legend box linestyle 1 +@ legend box fill color 0 +@ legend box fill pattern 1 +@ legend font 0 +@ legend char size 1.000000 +@ legend color 1 +@ legend length 4 +@ legend vgap 1 +@ legend hgap 1 +@ legend invert false +@ frame type 0 +@ frame linestyle 1 +@ frame linewidth 1.0 +@ frame color 1 +@ frame pattern 1 +@ frame background color 0 +@ frame background pattern 0 +@ s0 hidden false +@ s0 type xy +@ s0 symbol 1 +@ s0 symbol size 1.000000 +@ s0 symbol color 1 +@ s0 symbol pattern 1 +@ s0 symbol fill color 1 +@ s0 symbol fill pattern 1 +@ s0 symbol linewidth 1.0 +@ s0 symbol linestyle 1 +@ s0 symbol char 65 +@ s0 symbol char font 0 +@ s0 symbol skip 0 +@ s0 line type 1 +@ s0 line linestyle 1 +@ s0 line linewidth 2.0 +@ s0 line color 1 +@ s0 line pattern 1 +@ s0 baseline type 0 +@ s0 baseline off +@ s0 dropline off +@ s0 fill type 0 +@ s0 fill rule 0 +@ s0 fill color 1 +@ s0 fill pattern 1 +@ s0 avalue off +@ s0 avalue type 2 +@ s0 avalue char size 1.000000 +@ s0 avalue font 0 +@ s0 avalue color 1 +@ s0 avalue rot 0 +@ s0 avalue format general +@ s0 avalue prec 3 +@ s0 avalue prepend "" +@ s0 avalue append "" +@ s0 avalue offset 0.000000 , 0.000000 +@ s0 errorbar on +@ s0 errorbar place both +@ s0 errorbar color 1 +@ s0 errorbar pattern 1 +@ s0 errorbar size 1.000000 +@ s0 errorbar linewidth 1.0 +@ s0 errorbar linestyle 1 +@ s0 errorbar riser linewidth 1.0 +@ s0 errorbar riser linestyle 1 +@ s0 errorbar riser clip off +@ s0 errorbar riser clip length 0.100000 +@ s0 comment "Cols 2:3" +@ s0 legend "" +@ s1 hidden false +@ s1 type xy +@ s1 symbol 0 +@ s1 symbol size 1.000000 +@ s1 symbol color 1 +@ s1 symbol pattern 1 +@ s1 symbol fill color 1 +@ s1 symbol fill pattern 0 +@ s1 symbol linewidth 1.0 +@ s1 symbol linestyle 1 +@ s1 symbol char 65 +@ s1 symbol char font 0 +@ s1 symbol skip 0 +@ s1 line type 1 +@ s1 line linestyle 1 +@ s1 line linewidth 3.0 +@ s1 line color 1 +@ s1 line pattern 1 +@ s1 baseline type 0 +@ s1 baseline off +@ s1 dropline off +@ s1 fill type 0 +@ s1 fill rule 0 +@ s1 fill color 1 +@ s1 fill pattern 1 +@ s1 avalue off +@ s1 avalue type 2 +@ s1 avalue char size 1.000000 +@ s1 avalue font 0 +@ s1 avalue color 1 +@ s1 avalue rot 0 +@ s1 avalue format general +@ s1 avalue prec 3 +@ s1 avalue prepend "" +@ s1 avalue append "" +@ s1 avalue offset 0.000000 , 0.000000 +@ s1 errorbar on +@ s1 errorbar place both +@ s1 errorbar color 1 +@ s1 errorbar pattern 1 +@ s1 errorbar size 1.000000 +@ s1 errorbar linewidth 1.0 +@ s1 errorbar linestyle 1 +@ s1 errorbar riser linewidth 1.0 +@ s1 errorbar riser linestyle 1 +@ s1 errorbar riser clip off +@ s1 errorbar riser clip length 0.100000 +@ s1 comment "Cols 5:6" +@ s1 legend "" +@ s2 hidden false +@ s2 type xy +@ s2 symbol 0 +@ s2 symbol size 1.000000 +@ s2 symbol color 1 +@ s2 symbol pattern 1 +@ s2 symbol fill color 1 +@ s2 symbol fill pattern 0 +@ s2 symbol linewidth 1.0 +@ s2 symbol linestyle 1 +@ s2 symbol char 65 +@ s2 symbol char font 0 +@ s2 symbol skip 0 +@ s2 line type 1 +@ s2 line linestyle 1 +@ s2 line linewidth 3.0 +@ s2 line color 1 +@ s2 line pattern 1 +@ s2 baseline type 0 +@ s2 baseline off +@ s2 dropline off +@ s2 fill type 0 +@ s2 fill rule 0 +@ s2 fill color 1 +@ s2 fill pattern 1 +@ s2 avalue off +@ s2 avalue type 2 +@ s2 avalue char size 1.000000 +@ s2 avalue font 0 +@ s2 avalue color 1 +@ s2 avalue rot 0 +@ s2 avalue format general +@ s2 avalue prec 3 +@ s2 avalue prepend "" +@ s2 avalue append "" +@ s2 avalue offset 0.000000 , 0.000000 +@ s2 errorbar on +@ s2 errorbar place both +@ s2 errorbar color 1 +@ s2 errorbar pattern 1 +@ s2 errorbar size 1.000000 +@ s2 errorbar linewidth 1.0 +@ s2 errorbar linestyle 1 +@ s2 errorbar riser linewidth 1.0 +@ s2 errorbar riser linestyle 1 +@ s2 errorbar riser clip off +@ s2 errorbar riser clip length 0.100000 +@ s2 comment "Cols 8:9" +@ s2 legend "" +@ s3 hidden false +@ s3 type xy +@ s3 symbol 0 +@ s3 symbol size 1.000000 +@ s3 symbol color 1 +@ s3 symbol pattern 1 +@ s3 symbol fill color 1 +@ s3 symbol fill pattern 0 +@ s3 symbol linewidth 1.0 +@ s3 symbol linestyle 1 +@ s3 symbol char 65 +@ s3 symbol char font 0 +@ s3 symbol skip 0 +@ s3 line type 1 +@ s3 line linestyle 1 +@ s3 line linewidth 3.0 +@ s3 line color 1 +@ s3 line pattern 1 +@ s3 baseline type 0 +@ s3 baseline off +@ s3 dropline off +@ s3 fill type 0 +@ s3 fill rule 0 +@ s3 fill color 1 +@ s3 fill pattern 1 +@ s3 avalue off +@ s3 avalue type 2 +@ s3 avalue char size 1.000000 +@ s3 avalue font 0 +@ s3 avalue color 1 +@ s3 avalue rot 0 +@ s3 avalue format general +@ s3 avalue prec 3 +@ s3 avalue prepend "" +@ s3 avalue append "" +@ s3 avalue offset 0.000000 , 0.000000 +@ s3 errorbar on +@ s3 errorbar place both +@ s3 errorbar color 1 +@ s3 errorbar pattern 1 +@ s3 errorbar size 1.000000 +@ s3 errorbar linewidth 1.0 +@ s3 errorbar linestyle 1 +@ s3 errorbar riser linewidth 1.0 +@ s3 errorbar riser linestyle 1 +@ s3 errorbar riser clip off +@ s3 errorbar riser clip length 0.100000 +@ s3 comment "Cols 11:12" +@ s3 legend "" +@ s4 hidden false +@ s4 type xy +@ s4 symbol 0 +@ s4 symbol size 1.000000 +@ s4 symbol color 1 +@ s4 symbol pattern 1 +@ s4 symbol fill color 1 +@ s4 symbol fill pattern 0 +@ s4 symbol linewidth 1.0 +@ s4 symbol linestyle 1 +@ s4 symbol char 65 +@ s4 symbol char font 0 +@ s4 symbol skip 0 +@ s4 line type 1 +@ s4 line linestyle 1 +@ s4 line linewidth 3.0 +@ s4 line color 1 +@ s4 line pattern 1 +@ s4 baseline type 0 +@ s4 baseline off +@ s4 dropline off +@ s4 fill type 0 +@ s4 fill rule 0 +@ s4 fill color 1 +@ s4 fill pattern 1 +@ s4 avalue off +@ s4 avalue type 2 +@ s4 avalue char size 1.000000 +@ s4 avalue font 0 +@ s4 avalue color 1 +@ s4 avalue rot 0 +@ s4 avalue format general +@ s4 avalue prec 3 +@ s4 avalue prepend "" +@ s4 avalue append "" +@ s4 avalue offset 0.000000 , 0.000000 +@ s4 errorbar on +@ s4 errorbar place both +@ s4 errorbar color 1 +@ s4 errorbar pattern 1 +@ s4 errorbar size 1.000000 +@ s4 errorbar linewidth 1.0 +@ s4 errorbar linestyle 1 +@ s4 errorbar riser linewidth 1.0 +@ s4 errorbar riser linestyle 1 +@ s4 errorbar riser clip off +@ s4 errorbar riser clip length 0.100000 +@ s4 comment "Cols 14:15" +@ s4 legend "" +@ s5 hidden false +@ s5 type xy +@ s5 symbol 0 +@ s5 symbol size 1.000000 +@ s5 symbol color 1 +@ s5 symbol pattern 1 +@ s5 symbol fill color 1 +@ s5 symbol fill pattern 0 +@ s5 symbol linewidth 1.0 +@ s5 symbol linestyle 1 +@ s5 symbol char 65 +@ s5 symbol char font 0 +@ s5 symbol skip 0 +@ s5 line type 1 +@ s5 line linestyle 1 +@ s5 line linewidth 3.0 +@ s5 line color 1 +@ s5 line pattern 1 +@ s5 baseline type 0 +@ s5 baseline off +@ s5 dropline off +@ s5 fill type 0 +@ s5 fill rule 0 +@ s5 fill color 1 +@ s5 fill pattern 1 +@ s5 avalue off +@ s5 avalue type 2 +@ s5 avalue char size 1.000000 +@ s5 avalue font 0 +@ s5 avalue color 1 +@ s5 avalue rot 0 +@ s5 avalue format general +@ s5 avalue prec 3 +@ s5 avalue prepend "" +@ s5 avalue append "" +@ s5 avalue offset 0.000000 , 0.000000 +@ s5 errorbar on +@ s5 errorbar place both +@ s5 errorbar color 1 +@ s5 errorbar pattern 1 +@ s5 errorbar size 1.000000 +@ s5 errorbar linewidth 1.0 +@ s5 errorbar linestyle 1 +@ s5 errorbar riser linewidth 1.0 +@ s5 errorbar riser linestyle 1 +@ s5 errorbar riser clip off +@ s5 errorbar riser clip length 0.100000 +@ s5 comment "Cols 17:18" +@ s5 legend "" +@target G0.S0 +@type xy +-0.00020471 0.00655014 +-0.000847612 0.00675668 +-0.0015342 0.00688468 +-0.00225308 0.00692804 +-0.00299183 0.00688197 +-0.00373705 0.00674311 +-0.00447459 0.00650976 +-0.0051897 0.00618199 +-0.00586735 0.00576186 +-0.00649249 0.0052535 +-0.00705043 0.00466325 +-0.00752731 0.00399965 +-0.00791047 0.00327339 +-0.00818899 0.00249719 +-0.00835413 0.00168553 +-0.00839971 0.000854306 +-0.00832249 2.03576e-05 +-0.00812233 -0.000799035 +-0.00780235 -0.00158674 +-0.0073688 -0.00232635 +-0.00683085 -0.00300275 +-0.00620026 -0.00360259 +-0.00549091 -0.00411465 +-0.00471829 -0.00453016 +-0.00389894 -0.00484288 +-0.00304988 -0.0050492 +-0.00218816 -0.00514798 +-0.00133037 -0.00514046 +-0.000492311 -0.00503003 +0.000311334 -0.00482194 +0.00106719 -0.00452309 +0.00176336 -0.00414174 +0.0023895 -0.00368725 +0.00293689 -0.00316983 +0.00339843 -0.00260038 +0.00376866 -0.00199025 +0.00404372 -0.00135108 +0.00422132 -0.000694668 +0.00430073 -3.28003e-05 +0.0042827 0.000622837 +0.00416947 0.0012608 +0.00396473 0.00186999 +0.00367358 0.00243978 +0.00330251 0.00296015 +0.00285936 0.00342178 +0.00235329 0.00381622 +0.00179469 0.00413606 +0.00119514 0.00437506 +0.000567293 0.00452836 +-7.53049e-05 0.00459264 +-0.00071836 0.00456633 +-0.0013471 0.00444974 +-0.00194656 0.00424528 +-0.00250195 0.00395751 +-0.00299907 0.0035932 +-0.00342472 0.00316136 +-0.00376725 0.00267308 +-0.00401694 0.0021413 +-0.00416652 0.00158056 +-0.00421147 0.0010065 +-0.00415031 0.000435375 +-0.00398471 -0.000116498 +-0.00371947 -0.000633337 +-0.00336234 -0.00110046 +-0.00292371 -0.00150477 +-0.00241619 -0.00183519 +-0.00185406 -0.00208297 +-0.0012528 -0.0022418 +-0.000628469 -0.00230793 +2.74829e-06 -0.00228011 +0.000625026 -0.0021594 +0.00122327 -0.00194905 +0.00178344 -0.00165417 +0.00229275 -0.00128155 +0.00273988 -0.000839337 +0.00311505 -0.000336807 +0.00341009 0.000215892 +0.00361845 0.00080795 +0.00373522 0.0014281 +0.00375709 0.00206477 +0.00368232 0.00270628 +0.00351072 0.00334094 +0.00324358 0.0039572 +0.00288369 0.00454375 +0.00243523 0.00508965 +0.00190382 0.00558444 +0.00129643 0.00601825 +0.00062136 0.00638196 +-0.000111784 0.00666728 +-0.000892163 0.00686694 +-0.00170777 0.00697486 +-0.00254553 0.00698629 +-0.00339145 0.00689801 +-0.00423075 0.00670851 +-0.00504817 0.00641817 +-0.00582817 0.00602941 +-0.00655533 0.00554683 +-0.00721472 0.00497726 +-0.00779234 0.00432976 +-0.00827562 0.00361555 +-0.00865384 0.00284781 +-0.00891864 0.0020414 +-0.00906434 0.00121243 +-0.00908827 0.000377804 +-0.00899094 -0.000445331 +-0.00877603 -0.00124019 +-0.00845028 -0.0019909 +-0.00802318 -0.00268303 +-0.00750665 -0.00330403 +-0.00691449 -0.00384357 +-0.00626188 -0.00429373 +-0.00556482 -0.00464914 +-0.00483963 -0.0049069 +-0.00410248 -0.00506653 +-0.00336896 -0.00512977 +-0.00265377 -0.00510033 +-0.00197047 -0.0049837 +-0.00133124 -0.00478682 +-0.000746836 -0.00451784 +-0.000226441 -0.00418594 +0.000222331 -0.00380099 +0.000593451 -0.00337346 +0.000882467 -0.00291418 +0.00108647 -0.00243419 +0.00120406 -0.00194459 +0.00123533 -0.00145645 +0.00118179 -0.00098063 +0.0010464 -0.000527727 +0.000833454 -0.000107918 +0.000548629 0.000269138 +0.000198908 0.000594425 +-0.000207449 0.0008597 +-0.000660949 0.00105764 +-0.00115094 0.001182 +-0.00166568 0.00122777 +-0.00219249 0.00119135 +-0.00271789 0.00107074 +-0.00322782 0.000865725 +-0.00370789 0.000578006 +-0.00414371 0.00021135 +-0.00452123 -0.00022832 +-0.00482722 -0.000732913 +-0.00504967 -0.00129222 +-0.00517828 -0.00189406 +-0.00520489 -0.00252456 +-0.00512392 -0.00316849 +-0.00493266 -0.00380972 +-0.00463146 -0.00443178 +-0.00422385 -0.00501838 +-0.00371639 -0.00555403 +-0.00311849 -0.00602454 +-0.00244202 -0.00641751 +-0.00170088 -0.0067227 +-0.000910464 -0.00693225 +-8.71233e-05 -0.00704087 +0.000752367 -0.00704578 +0.0015913 -0.00694671 +0.00241347 -0.00674568 +0.00320354 -0.0064468 +0.00394729 -0.00605603 +0.00463189 -0.00558093 +0.00524599 -0.00503036 +0.00577986 -0.00441424 +0.0062254 -0.00374334 +0.00657619 -0.00302901 +0.00682745 -0.00228306 +0.00697604 -0.00151752 +0.00702042 -0.000744533 +0.00696063 2.38198e-05 +0.00679821 0.000775615 +0.0065362 0.00149923 +0.00617912 0.00218344 +0.00573286 0.00281756 +0.00520472 0.00339157 +0.00460335 0.00389621 +0.00393865 0.00432316 +0.00322179 0.00466517 +0.00246503 0.00491623 +0.00168168 0.00507174 +0.000885924 0.0051287 +9.26032e-05 0.00508585 +-0.00068299 0.00494387 +-0.00142543 0.00470552 +-0.00211951 0.00437571 +-0.00275065 0.00396159 +-0.00330531 0.0034725 +-0.00377151 0.00291985 +-0.00413922 0.00231694 +-0.00440087 0.00167859 +-0.00455163 0.00102077 +-0.0045897 0.000360038 +-0.00451645 -0.000286939 +-0.00433636 -0.000904027 +-0.00405687 -0.00147615 +-0.00368811 -0.00198982 +-0.00324241 -0.00243351 +-0.00273386 -0.002798 +-0.00217774 -0.00307652 +-0.00159 -0.00326484 +-0.000986717 -0.00336123 +-0.000383681 -0.0033663 +0.000204034 -0.00328282 +0.000762373 -0.00311552 +0.00127853 -0.00287073 +0.00174114 -0.00255624 +0.00214038 -0.00218094 +0.00246801 -0.0017546 +0.00271744 -0.0012877 +0.0028837 -0.000791139 +0.00296344 -0.000276135 +0.00295485 0.000245977 +0.0028577 0.000763873 +0.00267322 0.00126637 +0.0024041 0.00174256 +0.00205447 0.00218189 +0.00162983 0.00257432 +0.00113701 0.00291042 +0.000584157 0.00318149 +-1.93094e-05 0.0033797 +-0.000662788 0.00349826 +-0.00133455 0.00353151 +-0.00202184 0.00347518 +-0.00271103 0.00332649 +-0.00338777 0.00308434 +-0.00403724 0.00274953 +-0.00464442 0.00232482 +-0.00519441 0.00181515 +-0.00567283 0.00122762 +-0.00606627 0.00057154 +-0.00636272 -0.000141662 +-0.00655203 -0.000898636 +-0.00662641 -0.00168438 +-0.00658076 -0.00248265 +-0.00641299 -0.00327642 +-0.00612418 -0.00404845 +-0.00571862 -0.00478184 +-0.00520367 -0.00546063 +-0.00458951 -0.00607034 +-0.00388877 -0.00659837 +-0.00311599 -0.00703441 +-0.00228713 -0.00737062 +-0.001419 -0.00760176 +-0.00052874 -0.00772514 +0.000366691 -0.00774057 +0.0012509 -0.00765013 +0.00210843 -0.00745797 +0.00292501 -0.00717004 +0.00368775 -0.00679382 +0.00438529 -0.00633807 +0.00500783 -0.00581257 +0.00554725 -0.00522787 +0.00599704 -0.00459514 +0.00635231 -0.00392594 +0.00660981 -0.00323204 +0.00676782 -0.00252534 +0.00682617 -0.00181768 +0.00678621 -0.00112073 +0.00665073 -0.000445896 +0.00642398 0.000195823 +0.00611161 0.000793944 +0.00572065 0.00133863 +0.00525948 0.00182081 +0.00473775 0.00223236 +0.00416635 0.00256621 +0.00355733 0.00281658 +0.00292371 0.00297911 +0.00227941 0.00305104 +0.00163898 0.00303144 +0.00101735 0.00292134 +0.000429522 0.00272388 +-0.000109804 0.00244439 +-0.000586673 0.00209045 +-0.000988327 0.0016718 +-0.00130368 0.00120023 +-0.00152379 0.00068929 +-0.00164224 0.000153959 +-0.00165553 -0.000389828 +-0.00156321 -0.000925707 +-0.00136803 -0.00143747 +-0.00107581 -0.00190963 +-0.000695242 -0.00232799 +-0.000237499 -0.00268011 +0.00028419 -0.00295566 +0.000855081 -0.00314671 +0.00145946 -0.00324785 +0.00208119 -0.00325617 +0.00270419 -0.00317124 +0.00331286 -0.0029949 +0.00389246 -0.00273106 +0.0044294 -0.00238543 +0.0049114 -0.0019653 +0.00532771 -0.00147922 +0.00566911 -0.000936778 +0.00592803 -0.000348364 +0.00609852 0.000275049 +0.00617624 0.000922089 +0.00615847 0.00158115 +0.00604404 0.00224056 +0.00583329 0.00288869 +0.00552807 0.00351407 +0.00513166 0.00410555 +0.00464878 0.00465236 +0.00408553 0.00514429 +0.00344935 0.00557172 +0.00274903 0.00592584 +0.00199462 0.00619874 +0.00119736 0.00638358 +0.000369664 0.00647474 +-0.000475063 0.00646803 +-0.00132253 0.00636083 +-0.00215777 0.0061523 +-0.00296539 0.00584355 +-0.00372986 0.00543777 +-0.00443589 0.00494038 +-0.00506882 0.004359 +-0.00561513 0.00370351 +-0.00606283 0.00298586 +-0.00640199 0.00221989 +-0.00662518 0.00142098 +-0.00672776 0.000605622 +-0.00670819 -0.000209112 +-0.00656811 -0.0010061 +-0.00631234 -0.0017688 +-0.00594864 -0.00248175 +-0.00548747 -0.00313111 +-0.00494148 -0.00370507 +-0.00432505 -0.0041941 +-0.00365376 -0.00459117 +-0.00294383 -0.00489176 +-0.0022116 -0.00509385 +-0.00147312 -0.00519776 +-0.000743747 -0.00520592 +-3.78368e-05 -0.00512273 +0.00063148 -0.00495418 +0.00125246 -0.0047077 +0.00181488 -0.00439181 +0.00231004 -0.00401597 +0.00273085 -0.0035903 +0.00307179 -0.00312541 +0.00332892 -0.00263223 +0.00349981 -0.00212187 +0.00358356 -0.00160544 +0.0035807 -0.00109397 +0.00349323 -0.000598283 +0.00332451 -0.000128855 +0.0030793 0.000304265 +0.00276369 0.00069159 +0.00238509 0.00102432 +0.00195215 0.00129447 +0.00147476 0.00149502 +0.000963934 0.00162009 +0.000431728 0.00166509 +-0.000108887 0.0016269 +-0.000644214 0.00150408 +-0.00116005 0.00129698 +-0.00164196 0.00100797 +-0.00207563 0.00064151 +-0.00244724 0.000204212 +-0.00274392 -0.000295131 +-0.00295417 -0.000845654 +-0.00306839 -0.00143461 +-0.00307925 -0.00204764 +-0.00298211 -0.0026692 +-0.0027753 -0.00328305 +-0.00246023 -0.00387273 +-0.00204148 -0.00442224 +-0.0015266 -0.00491653 +-0.000925861 -0.00534202 +-0.000251852 -0.00568708 +0.000481 -0.00594234 +0.00125696 -0.00610085 +0.00205954 -0.00615824 +0.002872 -0.00611266 +0.00367784 -0.00596467 +0.00446119 -0.00571708 +0.00520716 -0.00537468 +0.00590206 -0.00494403 +0.00653364 -0.00443317 +0.0070912 -0.00385134 +0.00756562 -0.00320879 +0.00794947 -0.0025165 +0.00823697 -0.00178597 +0.00842398 -0.00102908 +0.00850797 -0.000257903 +0.00848803 0.000515464 +0.00836476 0.001279 +0.00814029 0.00202091 +0.00781823 0.00272972 +0.00740361 0.00339442 +0.00690288 0.00400457 +0.00632386 0.00455043 +0.00567567 0.00502309 +0.00496873 0.00541463 +0.00421462 0.00571825 +0.00342605 0.00592846 +0.00261666 0.00604125 +0.00180095 0.00605425 +0.000993963 0.00596692 +0.000211106 0.00578071 +-0.000532214 0.00549919 +-0.00122095 0.00512811 +-0.00184082 0.00467545 +-0.0023788 0.00415136 +-0.00282353 0.00356799 +-0.00316584 0.00293927 +-0.00339909 0.00228051 +-0.00351951 0.00160799 +-0.00352642 0.000938407 +-0.00342232 0.00028833 +-0.00321277 -0.000326398 +-0.00290622 -0.000891183 +-0.00251361 -0.00139316 +-0.00204795 -0.00182158 +-0.00152382 -0.00216802 +-0.000956798 -0.0024266 +-0.000362918 -0.00259395 +0.000241787 -0.00266913 +0.000841748 -0.00265351 +0.00142221 -0.00255054 +0.00196954 -0.00236551 +0.0024714 -0.00210525 +0.00291694 -0.00177791 +0.00329689 -0.0013927 +0.00360357 -0.000959609 +0.00383093 -0.000489253 +0.00397456 7.36633e-06 +0.00403161 0.000519013 +0.00400083 0.00103437 +0.00388247 0.00154219 +0.00367824 0.00203139 +0.00339133 0.0024912 +0.00302631 0.00291128 +0.00258913 0.0032818 +0.00208706 0.00359361 +0.00152867 0.00383833 +0.000923769 0.00400851 +0.000283327 0.00409775 +-0.000380585 0.00410091 +-0.00105493 0.00401425 +-0.00172584 0.00383558 +-0.00237883 0.0035645 +-0.00299902 0.0032025 +-0.00357145 0.00275314 +-0.00408143 0.00222212 +-0.00451494 0.00161737 +-0.00485908 0.000948966 +-0.00510253 0.000229046 +-0.00523601 -0.000528417 +-0.00525274 -0.00130795 +-0.00514871 -0.00209298 +-0.00492305 -0.00286637 +-0.00457804 -0.00361097 +-0.00411915 -0.0043102 +-0.00355485 -0.00494861 +-0.00289628 -0.00551238 +-0.00215687 -0.00598974 +-0.00135176 -0.0063713 +-0.000497319 -0.00665017 +0.000389423 -0.00682207 +0.0012913 -0.00688529 +0.00219149 -0.00684051 +0.00307384 -0.00669064 +0.00392329 -0.00644056 +0.00472599 -0.00609685 +0.00546959 -0.00566755 +0.00614326 -0.00516188 +0.00673779 -0.00458998 +0.00724564 -0.00396272 +0.0076609 -0.00329148 +0.00797927 -0.00258799 +0.00819807 -0.00186413 +0.00831617 -0.00113186 +0.00833398 -0.000403032 +0.0082534 0.000310724 +0.00807778 0.000998088 +0.00781192 0.00164819 +0.007462 0.00225073 +0.00703558 0.00279608 +0.00654156 0.00327549 +0.00599008 0.00368114 +0.0053925 0.0040064 +0.00476127 0.00424594 +0.00410982 0.00439594 +0.00345235 0.00445428 +0.00280362 0.00442068 +0.00217868 0.00429692 +0.00159252 0.0040869 +0.00105966 0.00379675 +0.000593729 0.00343484 +0.000206991 0.00301167 +-9.01348e-05 0.00253969 +-0.000289523 0.00203302 +-0.000385725 0.00150707 +-0.000376267 0.000978004 +-0.000261813 0.000462218 +-4.61849e-05 -2.42425e-05 +0.000263767 -0.000466267 +0.000658442 -0.000850202 +0.00112589 -0.0011643 +0.0016523 -0.00139903 +0.00222253 -0.00154732 +0.00282066 -0.00160463 +0.00343052 -0.00156894 +0.00403616 -0.00144062 +0.00462228 -0.00122224 +0.00517449 -0.000918388 +0.00567968 -0.000535338 +0.00612609 -8.08355e-05 +0.00650351 0.000436183 +0.00680331 0.00100583 +0.00701851 0.00161752 +0.00714373 0.00226012 +0.00717522 0.00292218 +0.00711082 0.00359207 +0.00694989 0.00425815 +0.00669333 0.00490883 +0.0063435 0.0055328 +0.00590418 0.00611903 +0.00538059 0.00665696 +0.00477931 0.0071366 +0.00410825 0.00754863 +0.00337664 0.00788455 +0.00259495 0.00813684 +0.00177485 0.0082991 +0.000929099 0.0083662 +7.14174e-05 0.00833452 +-0.000783652 0.00820206 +-0.00162097 0.00796868 +-0.00242508 0.00763621 +-0.0031805 0.00720865 +-0.00387212 0.00669219 +-0.00448566 0.0060953 +-0.00500808 0.00542862 +-0.0054281 0.00470482 +-0.00573664 0.00393836 +-0.00592723 0.00314508 +-0.00599634 0.00234177 +-0.00594358 0.00154561 +-0.00577177 0.000773615 +-0.00548682 4.20286e-05 +-0.00509756 -0.000634203 +-0.0046153 -0.0012419 +-0.00405343 -0.00177003 +-0.00342686 -0.00220993 +-0.0027515 -0.00255546 +-0.00204372 -0.002803 +-0.00131986 -0.00295139 +-0.000595792 -0.00300173 +0.0001134 -0.00295719 +0.000793733 -0.00282277 +0.00143251 -0.00260503 +0.00201848 -0.00231181 +0.00254191 -0.00195203 +0.00299463 -0.0015354 +0.00337006 -0.00107226 +0.00366322 -0.000573387 +0.00387063 -4.98061e-05 +0.00399039 0.000487333 +0.00402205 0.00102689 +0.00396663 0.00155788 +0.00382656 0.00206953 +0.00360566 0.00255147 +0.00330914 0.00299379 +0.0029435 0.00338716 +0.00251657 0.00372301 +0.00203742 0.00399361 +0.00151631 0.00419227 +0.000964635 0.00431347 +0.000394771 0.00435305 +-0.000180037 0.0043084 +-0.000745883 0.00417861 +-0.00128844 0.00396467 +-0.00179326 0.00366961 +-0.00224614 0.00329856 +-0.00263351 0.00285886 +-0.00294291 0.00235999 +-0.00316343 0.00181345 +-0.00328619 0.00123254 +-0.00330473 0.000632022 +-0.00321539 2.77156e-05 +-0.00301755 -0.000564045 +-0.00271372 -0.00112696 +-0.00230949 -0.00164532 +-0.00181337 -0.0021046 +-0.00123645 -0.00249193 +-0.000591989 -0.00279646 +0.000105129 -0.0030097 +0.000838903 -0.00312568 +0.00159276 -0.00314093 +0.00235007 -0.00305452 +0.00309459 -0.00286784 +0.00381083 -0.00258445 +0.00448437 -0.00220982 +0.00510212 -0.00175105 +0.00565241 -0.00121665 +0.00612518 -0.000616233 +0.00651199 3.96856e-05 +0.00680604 0.000739932 +0.00700221 0.00147286 +0.00709699 0.00222654 +0.00708849 0.0029889 +0.00697638 0.00374787 +0.00676186 0.00449153 +0.00644763 0.00520821 +0.00603785 0.00588661 +0.0055381 0.00651593 +0.00495536 0.007086 +0.00429795 0.00758738 +0.0035755 0.00801151 +0.00279889 0.00835089 +0.00198015 0.00859918 +0.00113238 0.00875143 +0.000269591 0.00880422 +-0.000593479 0.00875586 +-0.00144158 0.00860654 +-0.00225923 0.00835849 +-0.00303108 0.00801608 +-0.00374229 0.00758593 +-0.00437895 0.00707683 +-0.00492858 0.00649972 +-0.00538053 0.00586746 +-0.00572651 0.00519457 +-0.00596085 0.0044968 +-0.00608091 0.00379066 +-0.00608713 0.00309292 +-0.00598314 0.00241995 +-0.00577556 0.00178725 +-0.00547378 0.00120885 +-0.00508955 0.000696908 +-0.00463649 0.000261391 +-0.00412957 -9.01733e-05 +-0.0035846 -0.000352771 +-0.00301766 -0.000523893 +-0.00244463 -0.000603429 +-0.00188084 -0.000593487 +-0.00134065 -0.000498166 +-0.000837246 -0.000323302 +-0.000382446 -7.62015e-05 +1.34511e-05 0.000234621 +0.000341729 0.00059969 +0.000595289 0.0010088 +0.000768656 0.00145121 +0.000857967 0.00191585 +0.000860935 0.00239147 +0.00077682 0.0028668 +0.000606385 0.00333065 +0.000351857 0.00377207 +1.68928e-05 0.00418046 +-0.000393461 0.00454566 +-0.000872803 0.0048581 +-0.00141341 0.00510891 +-0.0020063 0.00529004 +-0.00264126 0.00539441 +-0.00330694 0.00541609 +-0.00399094 0.00535042 +-0.00467992 0.00519422 +-0.00535982 0.00494594 +-0.006016 0.00460586 +-0.00663356 0.00417621 +-0.00719762 0.00366132 +-0.00769374 0.00306772 +-0.00810828 0.0024041 +-0.00842893 0.00168131 +-0.00864509 0.000912188 +-0.00874839 0.000111275 +-0.00873307 -0.000705518 +-0.00859629 -0.00152138 +-0.00833835 -0.00231913 +-0.00796275 -0.00308179 +-0.00747612 -0.00379315 +-0.00688795 -0.00443836 +-0.00621032 -0.00500433 +-0.00545734 -0.00548018 +-0.00464469 -0.00585744 +-0.00378905 -0.00613023 +-0.00290757 -0.00629524 +-0.00201735 -0.0063517 +-0.00113502 -0.00630117 +-0.000276361 -0.00614734 +0.000543972 -0.00589582 +0.00131267 -0.00555378 +0.00201794 -0.00512977 +0.00264954 -0.00463342 +0.00319891 -0.00407522 +0.00365911 -0.0034663 +0.00402485 -0.00281822 +0.00429249 -0.00214282 +0.00445994 -0.00145209 +0.00452668 -0.000757982 +0.00449372 -7.23101e-05 +0.00436354 0.00059336 +0.00414008 0.00122784 +0.00382869 0.00182043 +0.00343613 0.00236104 +0.00297049 0.00284035 +0.00244119 0.0032499 +0.00185888 0.0035823 +0.00123539 0.00383136 +0.000583595 0.00399228 +-8.27271e-05 0.00406183 +-0.000749079 0.00403857 +-0.0014005 0.00392293 +-0.00202187 0.00371747 +-0.00259827 0.00342692 +-0.00311538 0.00305823 +-0.00355996 0.00262058 +-0.00392031 0.00212522 +-0.00418673 0.00158531 +-0.00435196 0.00101549 +-0.00441156 0.000431554 +-0.00436414 -0.000150138 +-0.00421145 -0.000713197 +-0.00395841 -0.0012418 +-0.00361288 -0.00172126 +-0.00318531 -0.0021385 +-0.0026884 -0.0024825 +-0.00213646 -0.00274456 +-0.00154499 -0.00291845 +-0.000930025 -0.00300052 +-0.000307715 -0.00298956 +0.000306186 -0.00288675 +0.000896679 -0.00269536 +0.00144983 -0.00242058 +0.00195298 -0.0020692 +0.00239494 -0.00164941 +0.00276608 -0.00117045 +0.00305835 -0.000642454 +0.00326536 -7.61943e-05 +0.00338233 0.000517116 +0.00340609 0.00112599 +0.00333502 0.00173881 +0.00316905 0.002344 +0.00290959 0.0029301 +0.00255953 0.00348593 +0.00212315 0.00400066 +0.00160616 0.00446398 +0.00101561 0.00486615 +0.000359859 0.0051982 +-0.000351414 0.005452 +-0.00110732 0.00562046 +-0.00189583 0.00569765 +-0.00270382 0.005679 +-0.00351729 0.0055615 +-0.00432148 0.00534383 +-0.00510113 0.00502657 +-0.00584075 0.00461236 +-0.00652499 0.00410601 +-0.00713899 0.00351457 +-0.00766889 0.00284733 +-0.00810225 0.00211574 +-0.00842857 0.00133317 +-0.00863968 0.000514676 +-0.00873017 -0.000323451 +-0.00869768 -0.00116417 +-0.00854301 -0.00199025 +-0.00827016 -0.00278485 +-0.00788619 -0.00353208 +-0.00740094 -0.00421756 +-0.00682659 -0.0048288 +-0.00617721 -0.00535559 +-0.00546821 -0.00579015 +-0.00471578 -0.00612723 +-0.00393641 -0.00636411 +-0.00314638 -0.00650046 +-0.00236139 -0.00653815 +-0.00159621 -0.00648104 +-0.000864441 -0.00633473 +-0.000178338 -0.00610627 +0.000451323 -0.00580392 +0.00101531 -0.00543692 +0.00150597 -0.00501524 +0.00191723 -0.00454941 +0.00224459 -0.00405033 +0.00248508 -0.00352909 +0.00263726 -0.00299689 +0.00270114 -0.00246484 +0.0026782 -0.00194391 +0.0025713 -0.00144475 +0.0023847 -0.000977635 +0.00212403 -0.000552323 +0.00179621 -0.000177928 +0.00140946 0.000137204 +0.000973252 0.000385644 +0.000498219 0.000561036 +-3.91598e-06 0.000658268 +-0.000520468 0.000673646 +-0.00103795 0.000605082 +-0.00154229 0.000452269 +-0.00201907 0.000216841 +-0.00245391 -9.74899e-05 +-0.00283275 -0.000484853 +-0.00314237 -0.000937196 +-0.00337079 -0.00144435 +-0.00350776 -0.00199417 +-0.00354519 -0.00257284 +-0.00347759 -0.00316519 +-0.00330234 -0.0037552 +-0.00301992 -0.00432651 +-0.00263394 -0.004863 +-0.00215106 -0.00534936 +-0.00158075 -0.00577164 +-0.000934892 -0.00611769 +-0.000227375 -0.00637753 +0.000526482 -0.00654359 +0.00131045 -0.00661083 +0.00210791 -0.00657674 +0.00290237 -0.00644127 +0.00367787 -0.00620664 +0.00441932 -0.00587715 +0.00511282 -0.00545888 +0.0057458 -0.0049595 +0.00630724 -0.00438791 +0.00678768 -0.0037541 +0.00717933 -0.00306881 +0.00747603 -0.00234341 +0.00767328 -0.00158963 +0.00776819 -0.000819462 +0.00775946 -4.49676e-05 +0.00764734 0.000721848 +0.0074336 0.00146916 +0.00712147 0.00218544 +0.00671566 0.00285957 +0.00622226 0.003481 +0.00564874 0.0040398 +0.00500392 0.00452685 +0.00429789 0.00493398 +0.00354198 0.00525409 +0.00274861 0.00548135 +0.00193126 0.00561135 +0.00110423 0.0056413 +0.000282503 0.00557017 +-0.000518552 0.00539891 +-0.00128345 0.00513053 +-0.00199696 0.00477025 +-0.00264452 0.0043255 +-0.00321269 0.0038059 +-0.00368959 0.00322316 +-0.00406541 0.00259079 +-0.00433276 0.00192386 +-0.00448708 0.00123847 +-0.00452685 0.000551326 +-0.00445371 -0.000120873 +-0.00427242 -0.000761984 +-0.00399068 -0.00135699 +-0.00361879 -0.00189247 +-0.00316926 -0.00235704 +-0.0026563 -0.0027416 +-0.00209526 -0.00303952 +-0.00150208 -0.00324671 +-0.000892858 -0.00336154 +-0.000283313 -0.00338473 +0.000311548 -0.00331911 +0.000877747 -0.00316945 +0.00140257 -0.00294212 +0.00187475 -0.00264488 +0.00228452 -0.0022866 +0.00262374 -0.00187703 +0.00288589 -0.00142656 +0.00306606 -0.000946067 +0.00316092 -0.000446673 +0.00316874 6.03597e-05 +0.00308929 0.000563789 +0.00292383 0.00105252 +0.00267508 0.00151572 +0.00234717 0.00194295 +0.0019456 0.00232425 +0.00147721 0.0026503 +0.000950161 0.00291249 +0.000373841 0.00310313 +-0.000241152 0.00321553 +-0.000883112 0.00324419 +-0.00153932 0.00318497 +-0.0021962 0.00303525 +-0.00283948 0.00279413 +-0.00345444 0.00246255 +-0.00402618 0.0020435 +-0.00453999 0.00154209 +-0.00498172 0.000965631 +-0.00533819 0.000323597 +-0.00559772 -0.000372434 +-0.00575054 -0.00110899 +-0.00578923 -0.00187101 +-0.00570912 -0.00264222 +-0.00550857 -0.00340566 +-0.0051891 -0.0041442 +-0.00475541 -0.00484113 +-0.00421526 -0.00548073 +-0.0035792 -0.00604881 +-0.00286011 -0.00653312 +-0.00207278 -0.00692371 +-0.00123334 -0.00721312 +-0.000358713 -0.00739649 +0.000533906 -0.00747153 +0.00142754 -0.0074384 +0.00230584 -0.00729955 +0.0031534 -0.00705948 +0.00395608 -0.00672447 +0.00470111 -0.0063023 +0.00537729 -0.00580201 +0.00597502 -0.00523365 +0.00648638 -0.00460801 +0.00690507 -0.00393647 +0.00722647 -0.00323077 +0.00744754 -0.00250288 +0.00756684 -0.00176482 +0.00758447 -0.00102856 +0.00750203 -0.000305872 +0.0073226 0.000391772 +0.00705071 0.00105332 +0.00669228 0.00166825 +0.00625463 0.00222674 +0.00574638 0.00271972 +0.00517749 0.0031391 +0.00455909 0.0034779 +0.00390347 0.0037304 +0.00322392 0.00389236 +0.00253455 0.00396116 +0.00185012 0.00393603 +0.00118574 0.00381817 +0.000556566 0.0036109 +-2.25989e-05 0.00331979 +-0.00053772 0.0029526 +-0.000976001 0.00251932 +-0.00132636 0.00203193 +-0.0015799 0.0015042 +-0.0017303 0.000951274 +-0.00177416 0.000389245 +-0.00171118 -0.000165416 +-0.00154427 -0.000696424 +-0.0012794 -0.00118827 +-0.000925402 -0.00162677 +-0.000493592 -0.00199953 +2.70698e-06 -0.00229631 +0.00054869 -0.00250928 +0.00112862 -0.00263312 +0.00172636 -0.00266507 +0.00232589 -0.0026048 +0.0029117 -0.00245426 +0.00346915 -0.00221742 +0.00398477 -0.00190009 +0.00444647 -0.00150957 +0.0048436 -0.00105445 +0.00516715 -0.00054431 +0.00540969 1.04888e-05 +0.00556544 0.000599016 +0.00563022 0.00120996 +0.00560147 0.00183181 +0.00547814 0.00245297 +0.00526072 0.00306192 +0.00495119 0.00364732 +0.00455293 0.00419815 +0.00407078 0.00470378 +0.00351093 0.00515414 +0.00288091 0.00553977 +0.00218957 0.00585203 +0.00144703 0.00608319 +0.00066459 0.00622658 +-0.000145305 0.00627678 +-0.000969217 0.0062298 +-0.00179285 0.00608323 +-0.00260124 0.00583646 +-0.00337901 0.00549082 +-0.0041107 0.00504975 +-0.00478109 0.0045189 +-0.00537564 0.00390614 +-0.00588094 0.00322161 +-0.00628523 0.00247751 +-0.00657879 0.00168789 +-0.00675444 0.000868354 +-0.00680788 3.556e-05 +-0.0067379 -0.000793274 +-0.00654651 -0.00160095 +-0.0062389 -0.00237087 +-0.00582321 -0.00308762 +-0.00531024 -0.00373743 +-0.00471298 -0.0043086 +-0.0040461 -0.00479177 +-0.00332542 -0.00518008 +-0.00256735 -0.00546922 +-0.0017884 -0.00565736 +-0.00100472 -0.005745 +-0.000231751 -0.0057348 +0.000516103 -0.00563129 +0.00122568 -0.00544064 +0.00188521 -0.00517039 +0.00248446 -0.0048292 +0.00301472 -0.00442662 +0.0034689 -0.00397287 +0.00384146 -0.00347863 +0.00412843 -0.00295493 +0.00432738 -0.00241293 +0.00443736 -0.00186384 +0.00445888 -0.00131875 +0.00439391 -0.000788557 +0.00424578 -0.000283835 +0.00401923 0.000185282 +0.00372032 0.000609217 +0.00335645 0.000979069 +0.00293627 0.00128676 +0.00246966 0.00152518 +0.00196767 0.00168834 +0.00144237 0.00177158 +0.000906782 0.00177171 +0.000374634 0.00168719 +-0.00013982 0.00151837 +-0.00062211 0.00126755 +-0.00105788 0.000939192 +-0.00143331 0.000539902 +-0.0017355 7.84798e-05 +-0.00195302 -0.000434197 +-0.0020763 -0.000985369 +-0.00209811 -0.00156069 +-0.00201392 -0.00214465 +-0.0018222 -0.00272105 +-0.00152451 -0.00327355 +-0.00112557 -0.00378628 +-0.000633055 -0.00424437 +-5.73322e-05 -0.0046345 +0.000588956 -0.00494528 +0.00129138 -0.00516761 +0.00203427 -0.00529484 +0.00280123 -0.00532288 +0.0035757 -0.00525016 +0.00434138 -0.00507746 +0.00508265 -0.00480782 +0.00578489 -0.0044462 +0.00643473 -0.00399929 +0.00702022 -0.00347522 +0.00753095 -0.00288331 +0.00795815 -0.00223382 +0.00829466 -0.0015377 +0.00853498 -0.000806448 +0.00867526 -5.18715e-05 +0.00871324 0.000714043 +0.00864821 0.00147928 +0.00848102 0.00223194 +0.008214 0.00296032 +0.00785095 0.00365309 +0.0073971 0.00429935 +0.00685906 0.00488881 +0.00624483 0.00541186 +0.00556369 0.00585975 +0.00482621 0.0062247 +0.00404415 0.0065001 +0.00323034 0.00668065 +0.00239859 0.00676255 +0.00156349 0.00674365 +0.000740216 0.00662369 +-5.5763e-05 0.00640438 +-0.000809002 0.0060896 +-0.00150446 0.00568539 +-0.00212791 0.00520008 +-0.00266645 0.0046441 +-0.0031089 0.00402993 +-0.00344631 0.00337174 +-0.00367231 0.00268508 +-0.00378345 0.00198639 +-0.00377942 0.0012925 +-0.00366304 0.000619996 +-0.00344021 -1.52936e-05 +-0.00311969 -0.000598859 +-0.00271266 -0.00111797 +-0.00223237 -0.00156203 +-0.00169352 -0.00192282 +-0.00111177 -0.00219464 +-0.000503202 -0.0023743 +0.000116174 -0.00246104 +0.000730839 -0.00245636 +0.00132612 -0.00236383 +0.00188848 -0.00218879 +0.00240569 -0.00193814 +0.00286702 -0.00162005 +0.00326329 -0.00124371 +0.00358691 -0.00081909 +0.00383194 -0.000356757 +0.00399402 0.000132346 +0.00407039 0.000637052 +0.00405982 0.00114613 +0.00396259 0.00164839 +0.00378047 0.00213286 +0.00351664 0.00258887 +0.00317569 0.00300614 +0.00276357 0.00337496 +0.00228756 0.00368628 +0.0017562 0.00393181 +0.0011793 0.00410421 +0.000567808 0.00419723 +-6.62365e-05 0.00420583 +-0.000709837 0.00412643 +-0.00134919 0.00395699 +-0.00196988 0.00369729 +-0.00255714 0.00334899 +-0.00309616 0.00291585 +-0.00357243 0.00240377 +-0.00397216 0.00182085 +-0.00428275 0.00117735 +-0.0044932 0.000485559 +-0.00459463 -0.000240438 +-0.00458068 -0.000985106 +-0.00444783 -0.00173189 +-0.00419567 -0.00246373 +-0.00382696 -0.00316362 +-0.00334763 -0.00381522 +-0.00276658 -0.00440338 +-0.00209531 -0.00491463 +-0.00134753 -0.00533763 +-0.000538614 -0.0056634 +0.000314911 -0.00588551 +0.00119595 -0.00600015 +0.00208732 -0.00600603 +0.00297223 -0.00590426 +0.00383465 -0.00569816 +0.00465963 -0.00539299 +0.00543352 -0.00499568 +0.00614415 -0.00451458 +0.00678095 -0.00395922 +0.00733495 -0.00333998 +0.00779888 -0.00266797 +0.00816711 -0.00195478 +0.00843565 -0.00121229 +0.0086021 -0.000452557 +0.00866565 0.000312372 +0.00862701 0.00107055 +0.00848839 0.00181028 +0.00825344 0.00252019 +0.00792727 0.00318941 +0.00751637 0.00380764 +0.0070286 0.00436529 +0.00647312 0.00485364 +0.00586037 0.00526499 +0.00520198 0.00559278 +0.00451065 0.00583183 +0.00380004 0.00597845 +0.00308458 0.00603069 +0.00237923 0.00598849 +0.00169919 0.00585382 +0.00105958 0.00563082 +0.000475013 0.00532588 +-4.08309e-05 0.0049476 +-0.000475693 0.00450673 +-0.000819203 0.00401598 +-0.00106333 0.00348968 +-0.00120277 0.00294342 +-0.00123522 0.00239352 +-0.00116153 0.00185648 +-0.000985758 0.0013484 +-0.000714944 0.000884384 +-0.000358885 0.000478036 +7.03095e-05 0.000141013 +0.000558702 -0.000117295 +0.00109108 -0.000289966 +0.00165149 -0.000372625 +0.0022238 -0.000363414 +0.00279212 -0.000262861 +0.00334123 -7.36936e-05 +0.00385693 0.000199403 +0.00432623 0.000550047 +0.00473758 0.000970433 +0.00508096 0.00145159 +0.00534795 0.00198362 +0.00553176 0.00255596 +0.00562722 0.00315752 +0.00563077 0.00377691 +0.00554042 0.00440261 +0.00535573 0.00502305 +0.00507775 0.00562679 +0.00470898 0.00620263 +0.00425336 0.0067397 +0.00371623 0.0072276 +0.00310427 0.00765649 +0.00242551 0.00801724 +0.00168927 0.00830154 +0.000906097 0.00850206 +8.77161e-05 0.0086126 +-0.000753064 0.00862827 +-0.00160248 0.00854566 +-0.00244598 0.00836301 +-0.00326843 0.00808044 +-0.00405441 0.00770005 +-0.00478849 0.00722609 +-0.00545567 0.00666504 +-0.00604179 0.00602566 +-0.006534 0.00531885 +-0.00692123 0.00455756 +-0.00719468 0.00375649 +-0.00734821 0.00293171 +-0.00737866 0.00210018 +-0.00728602 0.00127922 +-0.00707353 0.000485882 +-0.00674755 -0.000263568 +-0.00631731 -0.000954252 +-0.00579451 -0.00157311 +-0.0051929 -0.00210929 +-0.00452769 -0.00255433 +-0.00381504 -0.00290233 +-0.00307151 -0.00314994 +-0.00231357 -0.00329622 +-0.00155719 -0.00334254 +-0.000817509 -0.0032923 +-0.000108525 -0.0031507 +0.000557074 -0.00292449 +0.00116805 -0.00262168 +0.0017147 -0.00225132 +0.00218889 -0.00182325 +0.00258408 -0.00134793 +0.0028953 -0.000836208 +0.00311913 -0.000299215 +0.00325367 0.000251823 +0.00329848 0.000805695 +0.00325461 0.00135132 +0.0031245 0.00187788 +0.00291199 0.0023749 +0.0026223 0.0028324 +0.00226196 0.00324097 +0.00183883 0.00359196 +0.00136202 0.00387757 +0.00084185 0.00409103 +0.000289754 0.00422675 +-0.000281812 0.00428052 +-0.000859532 0.0042497 +-0.00142942 0.00413335 +-0.00197709 0.00393246 +-0.00248801 0.00365006 +-0.00294793 0.00329135 +-0.00334328 0.00286371 +-0.00366158 0.00237667 +-0.00389197 0.00184181 +-0.00402564 0.00127248 +-0.00405627 0.000683498 +-0.00398035 9.06782e-05 +-0.00379743 -0.000489676 +-0.00351021 -0.00104134 +-0.00312448 -0.00154876 +-0.00264891 -0.00199759 +-0.00209474 -0.00237518 +-0.00147528 -0.00267098 +-0.00080545 -0.00287681 +-0.00010121 -0.00298696 +0.000620981 -0.00299832 +0.00134465 -0.00291022 +0.00205379 -0.00272431 +0.00273315 -0.00244439 +0.00336864 -0.00207609 +0.00394745 -0.00162666 +0.00445827 -0.00110471 +0.00489136 -0.000519899 +0.00523861 0.000117241 +0.00549354 0.000795557 +0.00565134 0.00150345 +0.00570878 0.00222907 +0.00566425 0.00296044 +0.00551767 0.00368561 +0.00527047 0.00439277 +0.00492558 0.0050704 +0.00448735 0.00570735 +0.00396155 0.00629298 +0.00335535 0.00681726 +0.00267723 0.00727092 +0.001937 0.00764559 +0.00114568 0.00793394 +0.000315454 0.00812986 +-0.00054043 0.00822859 +-0.00140783 0.00822697 +-0.0022719 0.00812356 +-0.00311728 0.00791885 +-0.00392845 0.00761536 +-0.00469005 0.00721783 +-0.00538725 0.00673317 +-0.00600626 0.00617057 +-0.00653472 0.00554129 +-0.00696224 0.00485852 +-0.00728076 0.00413706 +-0.007485 0.0033929 +-0.00757267 0.00264274 +-0.00754462 0.00190343 +-0.00740488 0.0011914 +-0.00716047 0.000522057 +-0.00682112 -9.06587e-05 +-0.00639889 -0.000634758 +-0.00590762 -0.00110049 +-0.00536248 -0.00148057 +-0.00477934 -0.0017702 +-0.00417432 -0.00196712 +-0.00356329 -0.00207141 +-0.0029615 -0.00208536 +-0.00238322 -0.00201321 +-0.00184151 -0.00186089 +-0.00134805 -0.00163579 +-0.000913007 -0.00134644 +-0.000544958 -0.00100233 +-0.000250882 -0.000613633 +-3.6141e-05 -0.000191038 +9.54964e-05 0.000254446 +0.000141826 0.000711648 +0.000102173 0.00116938 +-2.26495e-05 0.00161655 +-0.000230374 0.00204232 +-0.00051732 0.00243619 +-0.000878423 0.00278811 +-0.00130728 0.00308861 +-0.00179616 0.00332894 +-0.00233609 0.00350118 +-0.00291687 0.00359837 +-0.00352719 0.00361472 +-0.00415466 0.00354572 +-0.00478601 0.00338834 +-0.00540722 0.00314122 +-0.00600377 0.0028048 +-0.00656086 0.00238153 +-0.00706378 0.00187595 +-0.00749828 0.00129478 +-0.00785101 0.000646931 +-0.00810993 -5.65498e-05 +-0.00826485 -0.000802682 +-0.00830782 -0.0015768 +-0.00823355 -0.00236294 +-0.00803971 -0.00314431 +-0.00772712 -0.00390383 +-0.0072998 -0.0046247 +-0.00676486 -0.00529098 +-0.00613228 -0.00588817 +-0.00541446 -0.00640358 +-0.00462585 -0.00682679 +-0.00378234 -0.00714983 +-0.00290074 -0.00736731 +-0.00199824 -0.00747643 +-0.00109192 -0.00747689 +-0.000198311 -0.00737071 +0.000666941 -0.00716202 +0.00148938 -0.00685681 +0.00225594 -0.0064626 +0.00295506 -0.00598828 +0.00357682 -0.00544374 +0.00411294 -0.00483972 +0.00455681 -0.00418754 +0.00490347 -0.00349896 +0.00514959 -0.00278594 +0.00529343 -0.00206058 +0.0053348 -0.0013349 +0.00527505 -0.000620779 +0.00511697 7.02093e-05 +0.00486483 0.000726877 +0.0045243 0.00133856 +0.00410243 0.00189523 +0.00360762 0.00238762 +0.00304956 0.00280741 +0.00243919 0.0031473 +0.00178858 0.00340128 +0.00111084 0.00356471 +0.000419972 0.00363457 +-0.000269337 0.00360962 +-0.000941971 0.00349056 +-0.00158268 0.00328019 +-0.00217647 0.00298351 +-0.00270897 0.00260777 +-0.00316698 0.00216243 +-0.00353883 0.00165904 +-0.00381498 0.00111098 +-0.00398833 0.000533167 +-0.00405466 -5.84376e-05 +-0.00401282 -0.000647325 +-0.00386487 -0.00121703 +-0.003616 -0.0017517 +-0.00327433 -0.00223669 +-0.00285058 -0.00265903 +-0.00235764 -0.00300785 +-0.00180999 -0.00327461 +-0.00122322 -0.00345333 +-0.000613421 -0.00354054 +3.28964e-06 -0.00353527 +0.000611222 -0.0034389 +0.00119549 -0.00325489 +0.00174231 -0.00298857 +0.00223922 -0.00264687 +0.00267522 -0.00223805 +0.00304088 -0.00177143 +0.0033284 -0.00125716 +0.0035316 -0.000705993 +0.00364591 -0.000129116 +0.00366837 0.000462045 +0.00359757 0.00105597 +0.00343362 0.00164116 +0.00317812 0.0022063 +0.0028341 0.00274034 +0.00240601 0.00323261 +0.00189966 0.00367296 +0.00132224 0.00405184 +0.000682217 0.00436044 +-1.06478e-05 0.00459086 +-0.000745393 0.00473619 +-0.00150992 0.00479076 +-0.00229108 0.00475022 +-0.00307483 0.00461179 +-0.00384644 0.00437443 +-0.00459066 0.00403899 +-0.00529206 0.00360838 +-0.00593538 0.00308771 +-0.00650591 0.00248433 +-0.00698996 0.00180781 +-0.00737532 0.00106989 +-0.00765177 0.00028423 +-0.00781149 -0.000533889 +-0.00784946 -0.00136797 +-0.00776373 -0.00220082 +-0.00755558 -0.00301512 +-0.00722949 -0.00379399 +-0.00679302 -0.00452163 +-0.00625644 -0.00518376 +-0.00563237 -0.00576811 +-0.00493526 -0.00626468 +-0.00418084 -0.00666599 +-0.00338554 -0.00696712 +-0.00256605 -0.00716565 +-0.00173875 -0.00726158 +-0.00091943 -0.0072571 +-0.000122869 -0.00715635 +0.000637337 -0.00696518 +0.00134898 -0.0066909 +0.00200134 -0.00634196 +0.00258526 -0.0059278 +0.00309316 -0.00545854 +0.00351905 -0.00494486 +0.0038585 -0.00439776 +0.00410863 -0.00382847 +0.00426805 -0.00324828 +0.00433686 -0.00266839 +0.00431658 -0.00209985 +0.00421015 -0.00155343 +0.0040219 -0.00103946 +0.00375751 -0.00056778 +0.00342399 -0.000147592 +0.00302963 0.000212691 +0.002584 0.000505574 +0.00209782 0.000724644 +0.00158291 0.000864745 +0.00105207 0.000922156 +0.000518898 0.000894778 +-2.43285e-06 0.000782316 +-0.00049742 0.000586438 +-0.000951575 0.000310912 +-0.00135081 -3.8314e-05 +-0.00168186 -0.000453093 +-0.00193276 -0.000923151 +-0.00209333 -0.00143625 +-0.00215558 -0.00197848 +-0.00211417 -0.00253461 +-0.00196668 -0.00308859 +-0.0017138 -0.00362411 +-0.00135937 -0.00412511 +-0.000910274 -0.00457646 +-0.000376169 -0.00496441 +0.000230894 -0.00527706 +0.000896945 -0.00550476 +0.00160663 -0.00564026 +0.00234377 -0.00567886 +0.00309187 -0.00561839 +0.00383461 -0.00545912 +0.00455627 -0.00520356 +0.00524205 -0.00485623 +0.00587837 -0.00442345 +0.00645302 -0.003913 +0.00695532 -0.00333392 +0.00737619 -0.00269623 +0.00770819 -0.0020107 +0.00794551 -0.00128868 +0.00808399 -0.000541855 +0.00812105 0.000217879 +0.0080557 0.000978563 +0.00788846 0.00172832 +0.00762137 0.00245546 +0.00725789 0.00314861 +0.00680294 0.00379682 +0.00626284 0.00438971 +0.00564524 0.00491753 +0.00495916 0.00537135 +0.00421486 0.0057432 +0.00342381 0.0060262 +0.00259863 0.00621473 +0.00175292 0.00630465 +0.000901122 0.0062934 +5.83161e-05 0.00618029 +-0.000760034 0.00596654 +-0.0015384 0.00565554 +-0.00226156 0.00525284 +-0.00291501 0.00476625 +-0.00348543 0.00420577 +-0.00396113 0.00358345 +-0.00433255 0.00291318 +-0.00459264 0.00221027 +-0.00473723 0.0014911 +-0.00476521 0.000772521 +-0.00467868 7.13155e-05 +-0.00448283 -0.000596375 +-0.00418579 -0.00121561 +-0.00379825 -0.00177314 +-0.00333303 -0.00225778 +-0.00280457 -0.00266069 +-0.0022284 -0.00297552 +-0.00162056 -0.00319846 +-0.000997145 -0.00332814 +-0.00037384 -0.00336551 +0.000234438 -0.00331365 +0.000813845 -0.00317745 +0.00135182 -0.00296343 +0.00183725 -0.00267943 +0.00226057 -0.00233436 +0.00261378 -0.00193799 +0.00289052 -0.00150069 +0.00308602 -0.00103327 +0.0031971 -0.000546798 +0.00322212 -5.24534e-05 +0.00316094 0.000438622 +0.00301491 0.000915438 +0.00278679 0.00136728 +0.00248077 0.00178382 +0.00210237 0.00215522 +0.00165847 0.00247229 +0.00115722 0.00272656 +0.000608027 0.00291046 +2.14703e-05 0.00301745 +-0.000590759 0.00304219 +-0.00121598 0.00298069 +-0.00184065 0.00283051 +-0.00245057 0.00259092 +-0.00303111 0.0022631 +-0.00356752 0.00185024 +-0.00404525 0.00135766 +-0.00445035 0.000792888 +-0.00476994 0.000165633 +-0.00499267 -0.000512338 +-0.00510917 -0.0012274 +-0.00511248 -0.00196437 +-0.00499844 -0.00270695 +-0.00476593 -0.0034382 +-0.00441701 -0.00414113 +-0.00395695 -0.00479925 +-0.003394 -0.00539714 +-0.00273914 -0.00592101 +-0.00200563 -0.00635907 +-0.00120855 -0.00670185 +-0.000364205 -0.00694246 +0.000510382 -0.00707654 +0.00139802 -0.00710237 +0.00228181 -0.0070206 +0.00314555 -0.00683417 +0.00397406 -0.00654801 +0.00475342 -0.00616879 +0.00547117 -0.00570464 +0.00611644 -0.00516493 +0.00667997 -0.00455993 +0.00715418 -0.00390069 +0.00753317 -0.00319875 +0.00781265 -0.00246599 +0.00798999 -0.00171449 +0.0080641 -0.000956326 +0.00803546 -0.000203513 +0.00790604 0.000532173 +0.00767925 0.00123928 +0.00735997 0.00190681 +0.00695446 0.00252434 +0.00647034 0.00308211 +0.00591656 0.00357121 +0.00530334 0.0039837 +0.00464211 0.00431277 +0.00394539 0.0045529 +0.00322669 0.00470008 +0.00250034 0.00475195 +0.00178126 0.00470798 +0.0010847 0.00456969 +0.000425889 0.00434069 +-0.000180315 0.00402686 +-0.00071989 0.0036363 +-0.00118011 0.0031793 +-0.00155001 0.00266817 +-0.00182088 0.00211692 +-0.00198664 0.00154097 +-0.00204417 0.000956581 +-0.00199349 0.000380355 +-0.00183783 -0.000171364 +-0.0015835 -0.000683078 +-0.00123965 -0.00114068 +-0.00081787 -0.00153191 +-0.000331701 -0.00184672 +0.00020388 -0.00207751 +0.000773036 -0.00221922 +0.0013596 -0.00226933 +0.00194758 -0.00222776 +0.00252154 -0.00209669 +0.00306701 -0.00188031 +0.00357067 -0.0015846 +0.00402064 -0.00121699 +0.00440651 -0.000786164 +0.0047195 -0.000301772 +0.00495243 0.000225803 +0.00509977 0.000785641 +0.00515759 0.00136648 +0.00512355 0.00195686 +0.00499683 0.0025453 +0.00477812 0.00312039 +0.0044696 0.00367094 +0.00407485 0.00418607 +0.00359884 0.00465534 +0.00304791 0.00506886 +0.00242974 0.00541738 +0.00175328 0.00569248 +0.00102874 0.00588665 +0.000267515 0.00599346 +-0.000517909 0.00600777 +-0.00131406 0.00592583 +-0.00210662 0.00574553 +-0.00288065 0.00546655 +-0.00362084 0.00509054 +-0.00431179 0.00462123 +-0.00493843 0.00406461 +-0.00548638 0.00342889 +-0.00594249 0.00272449 +-0.00629525 0.00196392 +-0.00653531 0.00116155 +-0.00665588 0.000333178 +-0.0066531 -0.000504323 +-0.00652625 -0.00133361 +-0.00627787 -0.00213742 +-0.00591366 -0.00289918 +-0.00544232 -0.00360356 +-0.00487511 -0.00423699 +-0.00422548 -0.00478799 +-0.00350849 -0.0052475 +-0.00274027 -0.005609 +-0.00193747 -0.00586854 +-0.00111679 -0.00602466 +-0.000294484 -0.00607823 +0.000513966 -0.00603223 +0.00129415 -0.00589152 +0.00203295 -0.00566258 +0.00271867 -0.00535319 +0.00334115 -0.00497226 +0.00389181 -0.00452953 +0.00436366 -0.0040354 +0.00475127 -0.0035007 +0.00505079 -0.00293659 +0.00525989 -0.00235435 +0.00537774 -0.00176529 +0.00540496 -0.00118059 +0.0053436 -0.000611242 +0.00519712 -6.78851e-05 +0.00497035 0.000439276 +0.00466946 0.000900598 +0.00430194 0.00130713 +0.00387658 0.00165074 +0.00340337 0.00192429 +0.00289346 0.00212178 +0.00235908 0.00223852 +0.00181335 0.00227135 +0.00127012 0.00221877 +0.000743763 0.00208117 +0.000248841 0.00186096 +-0.000200224 0.00156267 +-0.000589559 0.00119307 +-0.000906289 0.000761075 +-0.00113901 0.000277715 +-0.00127827 -0.000244117 +-0.00131698 -0.000789963 +-0.00125083 -0.00134423 +-0.00107852 -0.00189068 +-0.000801881 -0.00241302 +-0.000425905 -0.00289547 +4.14664e-05 -0.00332332 +0.000589638 -0.00368349 +0.00120579 -0.00396487 +0.00187537 -0.00415869 +0.00258267 -0.00425866 +0.00331135 -0.00426105 +0.00404494 -0.00416464 +0.00476733 -0.00397057 +0.00546315 -0.00368214 +0.00611806 -0.0033046 +0.00671902 -0.00284483 +0.00725444 -0.00231112 +0.00771427 -0.0017129 +0.0080901 -0.00106049 +0.00837515 -0.000364866 +0.00856428 0.000362506 +0.00865396 0.00110987 +0.00864226 0.00186533 +0.00852878 0.00261698 +0.00831465 0.00335304 +0.00800246 0.00406199 +0.00759626 0.00473263 +0.00710148 0.00535427 +0.00652497 0.00591678 +0.00587489 0.00641075 +0.00516072 0.00682765 +0.00439319 0.00715991 +0.00358421 0.00740115 +0.00274676 0.00754631 +0.00189478 0.00759186 +0.00104297 0.00753596 +0.000206579 0.00737862 +-0.000598861 0.00712192 +-0.0013579 0.00677005 +-0.00205553 0.00632948 +-0.00267764 0.00580887 +-0.00321148 0.00521905 +-0.00364612 0.00457286 +-0.00397292 0.0038848 +-0.00418589 0.00317069 +-0.00428204 0.0024472 +-0.00426149 0.00173126 +-0.00412758 0.00103953 +-0.00388669 0.000387774 +-0.00354801 -0.000209617 +-0.00312315 -0.000740122 +-0.00262566 -0.00119341 +-0.00207051 -0.00156157 +-0.00147352 -0.00183921 +-0.000850848 -0.00202347 +-0.000218514 -0.0021139 +0.000408021 -0.00211228 +0.0010142 -0.0020224 +0.00158661 -0.00184982 +0.00211323 -0.00160159 +0.0025835 -0.00128598 +0.00298842 -0.000912232 +0.00332062 -0.000490365 +0.00357431 -3.0925e-05 +0.0037453 0.000455177 +0.00383098 0.000956832 +0.00383025 0.00146288 +0.00374351 0.00196224 +0.00357261 0.00244403 +0.0033208 0.00289767 +0.00299274 0.00331304 +0.00259442 0.00368053 +0.00213314 0.0039912 +0.00161749 0.00423693 +0.00105725 0.0044105 +0.000463394 0.00450579 +-0.000152071 0.00451794 +-0.000776174 0.00444352 +-0.00139516 0.00428068 +-0.00199469 0.00402937 +-0.0025601 0.00369148 +-0.00307672 0.00327095 +-0.00353021 0.00277392 +-0.00390704 0.0022087 +-0.00419488 0.00158575 +-0.0043831 0.000917548 +-0.00446325 0.000218305 +-0.00442943 -0.000496361 +-0.00427864 -0.00120989 +-0.00401101 -0.00190529 +-0.00362985 -0.00256574 +-0.00314164 -0.00317515 +-0.00255574 -0.00371874 +-0.0018841 -0.00418349 +-0.00114075 -0.00455853 +-0.000341311 -0.00483545 +0.000497549 -0.00500839 +0.00135869 -0.00507409 +0.002225 -0.00503185 +0.0030798 -0.00488328 +0.00390729 -0.00463221 +0.00469279 -0.00428433 +0.00542295 -0.00384696 +0.00608596 -0.00332881 +0.00667161 -0.00273967 +0.00717135 -0.00209019 +0.0075783 -0.00139168 +0.00788724 -0.000655871 +0.0080946 0.000105237 +0.0081984 0.000879521 +0.00819823 0.00165489 +0.0080952 0.0024194 +0.00789191 0.00316137 +0.0075924 0.00386951 +0.00720213 0.00453303 +0.00672795 0.00514174 +0.00617803 0.00568622 +0.00556188 0.0061579 +0.00489021 0.00654928 +0.00417493 0.00685403 +0.00342899 0.0070672 +0.00266627 0.00718539 +0.00190137 0.00720692 +0.0011494 0.00713205 +0.00042569 0.00696308 +-0.000254603 0.0067045 +-0.000876855 0.00636302 +-0.00142744 0.0059476 +-0.00189422 0.00546934 +-0.00226699 0.00494124 +-0.00253796 0.00437792 +-0.00270211 0.0037952 +-0.00275745 0.00320956 +-0.00270522 0.00263761 +-0.00254979 0.00209547 +-0.00229859 0.0015982 +-0.00196172 0.0011593 +-0.00155158 0.000790248 +-0.00108233 0.000500207 +-0.00056933 0.000295844 +-2.86149e-05 0.000181259 +0.000523656 0.000158036 +0.00107165 0.000225377 +0.00160028 0.000380311 +0.00209547 0.000617937 +0.00254446 0.000931697 +0.00293592 0.00131364 +0.00326008 0.00175471 +0.00350878 0.00224494 +0.00367551 0.00277373 +0.00375537 0.00333004 +0.00374506 0.00390252 +0.00364284 0.00447971 +0.00344852 0.00505017 +0.00316337 0.00560259 +0.00279011 0.00612592 +0.00233288 0.00660948 +0.00179718 0.00704304 +0.00118987 0.00741699 +0.000519105 0.00772242 +-0.000205672 0.00795128 +-0.000973812 0.00809649 +-0.00177351 0.00815212 +-0.00259191 0.00811357 +-0.00341522 0.00797772 +-0.0042289 0.00774316 +-0.00501784 0.00741029 +-0.0057667 0.00698157 +-0.00646018 0.0064616 +-0.00708345 0.0058572 +-0.00762255 0.00517745 +-0.00806491 0.00443361 +-0.00839982 0.00363892 +-0.00861885 0.00280836 +-0.0087163 0.00195821 +-0.00868952 0.00110561 +-0.00853903 0.000267982 +-0.00826863 -0.000537593 +-0.00788522 -0.00129492 +-0.00739856 -0.00198927 +-0.00682088 -0.00260779 +-0.00616635 -0.0031399 +-0.00545057 -0.00357751 +-0.00469 -0.00391507 +-0.00390142 -0.00414962 +-0.00310147 -0.00428064 +-0.0023062 -0.00430986 +-0.00153077 -0.00424106 +-0.000789143 -0.00407979 +-9.3948e-05 -0.0038331 +0.000543677 -0.00350928 +0.00111415 -0.00311763 +0.00160948 -0.0026682 +0.00202326 -0.00217164 +0.00235067 -0.00163896 +0.00258844 -0.00108142 +0.00273482 -0.000510378 +0.00278953 6.28611e-05 +0.00275374 0.000627129 +0.00263005 0.00117152 +0.00242245 0.00168552 +0.00213629 0.00215906 +0.00177825 0.00258273 +0.00135634 0.00294782 +0.000879801 0.00324653 +0.000359112 0.00347207 +-0.000194143 0.00361888 +-0.000767365 0.00368279 +-0.0013471 0.0036612 +-0.00191923 0.00355327 +-0.00246924 0.00336008 +-0.00298254 0.0030848 +-0.0034448 0.00273276 +-0.00384243 0.00231152 +-0.00416297 0.00183079 +-0.00439565 0.00130231 +-0.0045318 0.000739597 +-0.00456527 0.000157595 +-0.00449279 -0.000427789 +-0.0043142 -0.00100022 +-0.00403248 -0.00154351 +-0.00365372 -0.0020422 +-0.00318687 -0.00248213 +-0.0026434 -0.0028509 +-0.00203681 -0.00313824 +-0.00138214 -0.00333631 +-0.000695371 -0.00343979 +7.07559e-06 -0.00344589 +0.000708855 -0.00335432 +0.00139413 -0.00316707 +0.00204794 -0.00288821 +0.00265645 -0.00252363 +0.00320721 -0.00208078 +0.00368926 -0.00156842 +0.00409323 -0.000996296 +0.00441138 -0.000375001 +0.00463761 0.000284308 +0.00476746 0.000970071 +0.00479805 0.0016705 +0.00472808 0.00237371 +0.0045578 0.0030679 +0.00428892 0.00374139 +0.00392463 0.00438284 +0.00346952 0.00498128 +0.0029296 0.00552627 +0.00231223 0.00600798 +0.00162608 0.00641738 +0.000881139 0.00674632 +8.8584e-05 0.00698771 +-0.00073925 0.0071357 +-0.001589 0.00718582 +-0.00244641 0.00713519 +-0.00329653 0.00698269 +-0.00412398 0.00672913 +-0.0049132 0.00637742 +-0.00564885 0.00593263 +-0.0063162 0.00540211 +-0.00690158 0.00479539 +-0.00739288 0.00412415 +-0.00777997 0.00340193 +-0.00805517 0.00264384 +-0.00821361 0.00186615 +-0.00825346 0.00108574 +-0.00817611 0.000319558 +-0.00798608 -0.000415947 +-0.00769089 -0.00110543 +-0.00730075 -0.00173511 +-0.0068281 -0.00229324 +-0.00628712 -0.00277036 +-0.00569322 -0.00315948 +-0.00506244 -0.00345617 +-0.00441097 -0.00365849 +-0.00375468 -0.00376683 +-0.00310875 -0.00378377 +-0.00248734 -0.00371379 +-0.00190337 -0.00356303 +-0.00136832 -0.00333901 +-0.000892187 -0.00305039 +-0.000483348 -0.00270671 +-0.000148592 -0.00231817 +0.000106895 -0.00189544 +0.00027951 -0.00144951 +0.000367195 -0.000991486 +0.000369402 -0.000532467 +0.000287052 -8.34435e-05 +0.000122501 0.000344845 +-0.0001205 0.000742011 +-0.000436834 0.00109814 +-0.000820055 0.00140389 +-0.00126242 0.00165065 +-0.00175495 0.00183063 +-0.00228744 0.00193704 +-0.00284859 0.00196421 +-0.00342606 0.00190781 +-0.00400663 0.00176499 +-0.00457635 0.00153456 +-0.00512078 0.00121716 +-0.00562527 0.000815445 +-0.00607529 0.000334156 +-0.00645678 -0.000219767 +-0.00675667 -0.000837204 +-0.00696326 -0.00150693 +-0.00706674 -0.00221581 +-0.0070596 -0.00294907 +-0.00693705 -0.00369069 +-0.00669731 -0.00442392 +-0.00634174 -0.00513179 +-0.00587492 -0.00579771 +-0.00530449 -0.00640608 +-0.00464087 -0.00694276 +-0.0038969 -0.00739556 +-0.0030873 -0.00775457 +-0.0022282 -0.0080124 +-0.00133649 -0.00816425 +-0.000429373 -0.00820789 +0.000476158 -0.00814358 +0.00136374 -0.00797388 +0.00221798 -0.0077034 +0.00302472 -0.00733853 +0.00377122 -0.00688722 +0.0044463 -0.00635863 +0.00504044 -0.00576297 +0.00554576 -0.00511117 +0.00595608 -0.00441476 +0.00626684 -0.00368559 +0.00647516 -0.00293576 +0.00657971 -0.00217738 +0.00658071 -0.00142251 +0.0064799 -0.000682991 +0.00628048 2.96505e-05 +0.00598708 0.000704315 +0.00560572 0.00133045 +0.00514382 0.00189818 +0.00461007 0.00239841 +0.00401449 0.002823 +0.00336826 0.00316491 +0.00268373 0.00341833 +0.00197421 0.00357893 +0.00125391 0.00364396 +0.000537641 0.0036125 +& +@target G0.S1 +@type xy +-3.50257 -3.81043 +-2.90668 -4.18559 +-2.25582 -4.48139 +-1.56171 -4.69102 +-0.837195 -4.80894 +-0.0961435 -4.83116 +0.646737 -4.75536 +1.37611 -4.58111 +2.07627 -4.31002 +2.73149 -3.94588 +3.3264 -3.49479 +3.8464 -2.96512 +4.27818 -2.36754 +4.61018 -1.71479 +4.83307 -1.02151 +4.9402 -0.303765 +4.92793 0.421323 +4.79585 1.13619 +4.54689 1.82342 +4.18724 2.46633 +3.72613 3.04957 +3.17543 3.5596 +2.54922 3.98513 +1.86322 4.31735 +1.1342 4.55011 +0.37942 4.67995 +-0.383861 4.706 +-1.13889 4.6298 +-1.86978 4.45512 +-2.56181 4.18765 +-3.20166 3.83474 +-3.77756 3.40513 +-4.27939 2.90866 +-4.69869 2.35605 +-5.02877 1.75864 +-5.26457 1.12822 +-5.40275 0.476853 +-5.44159 -0.183307 +-5.38095 -0.840131 +-5.22228 -1.48166 +-4.96853 -2.09621 +-4.62413 -2.67251 +-4.19499 -3.19982 +-3.6884 -3.66803 +-3.11307 -4.06785 +-2.47902 -4.39089 +-1.79755 -4.62986 +-1.08115 -4.77876 +-0.343376 -4.83299 +0.401279 -4.78963 +1.13762 -4.64757 +1.84996 -4.40771 +2.52248 -4.0731 +3.13958 -3.64907 +3.68628 -3.14329 +4.14875 -2.56573 +4.51476 -1.92855 +4.77417 -1.24586 +4.91943 -0.533385 +4.94591 0.19197 +4.85218 0.912673 +4.64016 1.61115 +4.31505 2.2704 +3.8852 2.87459 +3.36172 3.40958 +2.75807 3.86333 +2.08951 4.22628 +1.37253 4.49145 +0.624287 4.65455 +-0.137937 4.71391 +-0.897211 4.67035 +-1.63736 4.52695 +-2.34329 4.2888 +-3.00124 3.96274 +-3.59893 3.55708 +-4.12571 3.0813 +-4.5726 2.54584 +-4.93233 1.96184 +-5.19929 1.34096 +-5.36961 0.695171 +-5.44099 0.0365955 +-5.4128 -0.622618 +-5.28595 -1.27044 +-5.06288 -1.89509 +-4.74754 -2.48515 +-4.34533 -3.02966 +-3.86311 -3.5183 +-3.30911 -3.94148 +-2.69295 -4.29048 +-2.02551 -4.55762 +-1.31892 -4.73646 +-0.586419 -4.8219 +0.157763 -4.81047 +0.898612 -4.70045 +1.62056 -4.49206 +2.30776 -4.18768 +2.94449 -3.79191 +3.51551 -3.31169 +4.00658 -2.75628 +4.4049 -2.13716 +4.69965 -1.46786 +4.88242 -0.763634 +4.94764 -0.0410522 +4.89285 0.68252 +4.71891 1.38949 +4.42999 2.06265 +4.03344 2.68577 +3.5395 3.24414 +2.96089 3.72505 +2.31231 4.11812 +1.60985 4.41552 +0.870478 4.6121 +0.111443 4.70532 +-0.650195 4.69519 +-1.398 4.58403 +-2.1165 4.37627 +-2.79147 4.07819 +-3.41013 3.6976 +-3.96127 3.2436 +-4.43531 2.72634 +-4.8244 2.15674 +-5.12237 1.5463 +-5.32474 0.906922 +-5.42868 0.250714 +-5.43299 -0.41015 +-5.33808 -1.06357 +-5.14588 -1.69763 +-4.85986 -2.30076 +-4.48497 -2.86182 +-4.0276 -3.37025 +-3.49556 -3.81618 +-2.89805 -4.19059 +-2.24558 -4.48544 +-1.5499 -4.69387 +-0.823937 -4.81033 +-0.0816164 -4.83084 +0.66227 -4.75307 +1.3923 -4.57665 +2.09271 -4.30324 +2.7477 -3.93672 +3.34187 -3.48328 +3.86062 -2.95141 +4.29065 -2.35188 +4.62048 -1.69756 +4.84088 -1.00317 +4.94531 -0.284855 +4.93026 0.44024 +4.7955 1.15456 +4.54408 1.84071 +4.1823 2.4821 +3.71946 3.06347 +3.1675 3.57139 +2.54049 3.99467 +1.85412 4.32462 +1.1251 4.55516 +0.370666 4.68289 +-0.392018 4.70695 +-1.14625 4.62893 +-1.87619 4.45257 +-2.56715 4.18357 +-3.20584 3.82925 +-3.78048 3.39833 +-4.28097 2.90066 +-4.69884 2.34693 +-5.02737 1.74851 +-5.26153 1.11721 +-5.39796 0.465087 +-5.43495 -0.195648 +-5.3724 -0.852842 +-5.21177 -1.4945 +-4.95607 -2.10891 +-4.60979 -2.68479 +-4.17887 -3.21137 +-3.67071 -3.67858 +-3.09406 -4.07712 +-2.45901 -4.39867 +-1.7769 -4.63598 +-1.06026 -4.78311 +-0.322676 -4.83558 +0.421378 -4.79052 +1.15672 -4.64692 +1.86774 -4.40575 +2.53867 -4.07013 +3.154 -3.64543 +3.69887 -3.13936 +4.15954 -2.56185 +4.52387 -1.92505 +4.78183 -1.243 +4.9259 -0.531355 +4.95148 0.193071 +4.85714 0.91283 +4.64475 1.61043 +4.31947 2.26891 +3.88956 2.87249 +3.36606 3.40701 +2.76235 3.86043 +2.09364 4.22314 +1.37639 4.48809 +0.62774 4.65095 +-0.135001 4.70998 +-0.894868 4.66596 +-1.63563 4.52192 +-2.34214 4.28296 +-3.00056 3.95591 +-3.59856 3.54911 +-4.12544 3.07208 +-4.57217 2.53531 +-4.93146 1.95001 +-5.19773 1.32789 +-5.36708 0.68099 +-5.43729 0.0214915 +-5.40775 -0.63841 +-5.27943 -1.28665 +-5.05485 -1.91142 +-4.73803 -2.5013 +-4.33447 -3.04535 +-3.85107 -3.53326 +-3.29614 -3.9555 +-2.67934 -4.3034 +-2.0116 -4.56936 +-1.30505 -4.74699 +-0.572933 -4.8313 +0.170568 -4.81887 +0.910488 -4.70804 +1.63133 -4.4991 +2.31733 -4.19441 +2.95287 -3.7986 +3.52279 -3.31857 +4.01292 -2.76352 +4.41052 -2.14487 +4.70477 -1.47608 +4.88727 -0.772312 +4.9524 -0.0500763 +4.89764 0.673311 +4.72378 1.38028 +4.43489 2.05361 +4.03827 2.67704 +3.54411 3.23581 +2.96512 3.71715 +2.31599 4.1106 +1.61288 4.4083 +0.872791 4.60504 +0.113047 4.69826 +-0.649228 4.68797 +-1.39754 4.57652 +-2.11638 4.36838 +-2.79149 4.06986 +-3.41007 3.68883 +-3.96093 3.23444 +-4.43453 2.71689 +-4.82303 2.14713 +-5.12031 1.53669 +-5.32193 0.897475 +-5.42513 0.241609 +-5.42874 -0.418748 +-5.33322 -1.07151 +-5.14052 -1.7048 +-4.85414 -2.30707 +-4.47904 -2.86723 +-4.02163 -3.37473 +-3.4897 -3.81975 +-2.89243 -4.1933 +-2.2403 -4.48736 +-1.54504 -4.69509 +-0.819544 -4.81095 +-0.0777013 -4.83093 +0.665723 -4.75272 +1.39533 -4.57589 +2.09537 -4.30211 +2.75003 -3.9352 +3.3439 -3.48132 +3.86235 -2.94896 +4.29205 -2.34887 +4.62146 -1.69392 +4.84131 -0.998838 +4.94503 -0.279819 +4.92909 0.445951 +4.79323 1.16085 +4.54054 1.84745 +4.17734 2.48907 +3.71302 3.07043 +3.15955 3.57807 +2.5311 4.0008 +1.84344 4.32995 +1.11336 4.55947 +0.358121 4.68602 +-0.405051 4.70883 +-1.15945 4.62953 +-1.88924 4.45195 +-2.57977 4.18184 +-3.21778 3.82659 +-3.79156 3.39496 +-4.29105 2.8968 +-4.70785 2.34284 +-5.03531 1.74443 +-5.26842 1.11334 +-5.40389 0.461639 +-5.44001 -0.198534 +-5.37671 -0.855058 +-5.21544 -1.49598 +-4.95919 -2.10963 +-4.61243 -2.68474 +-4.18109 -3.21058 +-3.6725 -3.67706 +-3.0954 -4.07489 +-2.45985 -4.3957 +-1.77718 -4.63224 +-1.05994 -4.77852 +-0.321719 -4.82999 +0.422962 -4.78378 +1.15886 -4.63883 +1.87028 -4.39611 +2.54139 -4.05876 +3.15657 -3.63219 +3.70088 -3.12418 +4.16054 -2.54477 +4.52337 -1.9062 +4.77936 -1.22266 +4.92105 -0.509907 +4.94393 0.21513 +4.8467 0.934932 +4.63141 1.63197 +4.30336 2.28929 +3.87098 2.89116 +3.34544 3.42352 +2.74023 3.87443 +2.07061 4.23442 +1.35305 4.49659 +0.604693 4.65672 +-0.157227 4.71319 +-0.915822 4.66687 +-1.65496 4.52086 +-2.35958 4.28027 +-3.01596 3.95197 +-3.61185 3.54425 +-4.13663 3.06662 +-4.58133 2.52953 +-4.93869 1.94413 +-5.20314 1.32208 +-5.37081 0.675377 +-5.43944 0.0161671 +-5.40842 -0.643386 +-5.2787 -1.29124 +-5.05275 -1.91559 +-4.73457 -2.505 +-4.32963 -3.04853 +-3.84483 -3.53584 +-3.28847 -3.95735 +-2.67022 -4.30437 +-2.00105 -4.56926 +-1.29312 -4.74561 +-0.559725 -4.82839 +0.184865 -4.81419 +0.925616 -4.70135 +1.64695 -4.4902 +2.33304 -4.18317 +2.96819 -3.78495 +3.53721 -3.30255 +4.02593 -2.74527 +4.42162 -2.12467 +4.71353 -1.4543 +4.89336 -0.749442 +4.9556 -0.026655 +4.8979 0.696699 +4.72117 1.40305 +4.42966 2.07522 +4.03076 2.69701 +3.53476 3.25378 +2.95441 3.73285 +2.30443 4.1239 +1.60095 4.41914 +0.860912 4.61346 +0.101588 4.70438 +-0.659971 4.69194 +-1.40733 4.5785 +-2.12504 4.36855 +-2.79889 4.06837 +-3.4161 3.68584 +-3.96549 3.23009 +-4.43752 2.7113 +-4.82437 2.14041 +-5.11989 1.52898 +-5.31965 0.888906 +-5.42089 0.232338 +-5.42245 -0.428533 +-5.3248 -1.08159 +-5.12995 -1.71493 +-4.84142 -2.31697 +-4.46424 -2.87659 +-4.00488 -3.38324 +-3.4712 -3.82712 +-2.87245 -4.19923 +-2.21918 -4.49161 +-1.52318 -4.69747 +-0.797372 -4.81135 +-0.0556868 -4.82932 +0.687114 -4.74916 +1.41566 -4.57054 +2.11422 -4.29519 +2.7671 -3.92705 +3.35896 -3.47231 +3.87528 -2.93948 +4.30284 -2.33934 +4.63022 -1.68471 +4.84823 -0.990285 +4.95038 -0.272172 +4.93318 0.452527 +4.79637 1.16629 +4.54302 1.85175 +4.17942 2.49231 +3.71486 3.07273 +3.16126 3.57957 +2.53271 4.00163 +1.84491 4.33019 +1.11463 4.55919 +0.359103 4.68521 +-0.404434 4.70743 +-1.15925 4.62745 +-1.88946 4.44906 +-2.58036 4.17798 +-3.21864 3.82162 +-3.79252 3.38876 +-4.29191 2.88928 +-4.70837 2.33395 +-5.03521 1.73418 +-5.26745 1.10182 +-5.40178 0.448969 +-5.43655 -0.212156 +-5.37171 -0.869389 +-5.20879 -1.51074 +-4.95084 -2.1245 +-4.60241 -2.69942 +-4.16949 -3.22476 +-3.65952 -3.69045 +-3.08128 -4.08725 +-2.44491 -4.40685 +-1.76177 -4.64206 +-1.04443 -4.78696 +-0.306474 -4.83711 +0.437592 -4.78969 +1.17258 -4.64372 +1.88286 -4.40022 +2.55267 -4.06237 +3.16652 -3.63559 +3.70953 -3.12762 +4.16801 -2.54848 +4.52986 -1.91034 +4.78508 -1.2273 +4.92621 -0.515073 +4.94873 0.209506 +4.8513 0.928964 +4.63586 1.6258 +4.30768 2.28307 +3.87509 2.88501 +3.34925 3.41751 +2.7436 3.86861 +2.07342 4.22875 +1.35522 4.49099 +0.606174 4.65109 +-0.156411 4.7074 +-0.91559 4.66079 +-1.65518 4.51438 +-2.36008 4.27333 +-3.01654 3.94453 +-3.61231 3.53633 +-4.13676 3.05829 +-4.58097 2.5209 +-4.93771 1.93533 +-5.20145 1.31329 +-5.36836 0.666766 +-5.43625 0.00791248 +-5.40453 -0.651117 +-5.2742 -1.2983 +-5.04776 -1.92186 +-4.72925 -2.5104 +-4.32413 -3.053 +-3.83931 -3.53937 +-3.28309 -3.95997 +-2.66511 -4.30612 +-1.99631 -4.57023 +-1.28883 -4.74587 +-0.555933 -4.82805 +0.188151 -4.81333 +0.928413 -4.70004 +1.64929 -4.48848 +2.33498 -4.18107 +2.96976 -3.78245 +3.53845 -3.29961 +4.02681 -2.74183 +4.4221 -2.12066 +4.71352 -1.44965 +4.89272 -0.744103 +4.95415 -0.0206277 +4.89544 0.703366 +4.7175 1.41025 +4.4246 2.08278 +4.02418 2.70471 +3.5266 3.26135 +2.94467 3.74001 +2.29321 4.13035 +1.58841 4.42464 +0.847314 4.61778 +0.0872213 4.70737 +-0.674772 4.69351 +-1.42223 4.57866 +-2.13969 4.36736 +-2.81299 4.06598 +-3.4294 3.68243 +-3.97779 3.2259 +-4.44869 2.70658 +-4.83433 2.13545 +-5.12865 1.52402 +-5.32725 0.884211 +-5.42742 0.228113 +-5.42805 -0.432116 +-5.3296 -1.0844 +-5.13409 -1.71689 +-4.84504 -2.31803 +-4.46744 -2.87675 +-4.00772 -3.38252 +-3.47372 -3.82554 +-2.87466 -4.19681 +-2.22105 -4.48837 +-1.52466 -4.69338 +-0.798418 -4.80634 +-0.0562642 -4.82328 +0.687002 -4.74194 +1.41595 -4.56197 +2.1148 -4.28509 +2.76773 -3.91522 +3.35934 -3.45862 +3.87502 -2.92386 +4.30151 -2.32181 +4.62732 -1.66541 +4.8433 -0.969471 +4.943 -0.250236 +4.92302 0.475089 +4.78325 1.1889 +4.52689 1.87379 +4.16042 2.51317 +3.69329 3.09183 +3.13755 3.59644 +2.50741 4.01589 +1.81864 4.34162 +1.08802 4.5677 +0.33279 4.69084 +-0.429888 4.71035 +-1.18335 4.62792 +-1.91181 4.4474 +-2.60067 4.17458 +-3.23672 3.81687 +-3.80828 3.38303 +-4.30532 2.88293 +-4.71949 2.3273 +-5.04415 1.7275 +-5.27433 1.09531 +-5.40675 0.442812 +-5.43974 -0.217839 +-5.37325 -0.874507 +-5.20879 -1.51522 +-4.94937 -2.12831 +-4.59952 -2.70249 +-4.16522 -3.22703 +-3.65387 -3.69184 +-3.07426 -4.08765 +-2.43654 -4.40611 +-1.75209 -4.64001 +-1.03351 -4.78341 +-0.294458 -4.83182 +0.450508 -4.78244 +1.18612 -4.6343 +1.89668 -4.38845 +2.56634 -4.04811 +3.17955 -3.61881 +3.72142 -3.10837 +4.17822 -2.52693 +4.53788 -1.88678 +4.79047 -1.20214 +4.92863 -0.488801 +4.94797 0.236305 +4.84728 0.955672 +4.62869 1.6518 +4.2976 2.30778 +3.86249 2.90792 +3.33458 3.43822 +2.72741 3.88683 +2.05627 4.2443 +1.33764 4.50382 +0.588659 4.66123 +-0.173437 4.71496 +-0.93177 4.66593 +-1.67023 4.5173 +-2.37378 4.27422 +-3.02871 3.94358 +-3.62281 3.53374 +-4.14549 3.05423 +-4.58782 2.51553 +-4.94257 1.92883 +-5.20423 1.3058 +-5.36896 0.658474 +-5.43457 -0.000993882 +-5.40049 -0.660421 +-5.26773 -1.30775 +-5.03885 -1.93119 +-4.71792 -2.5193 +-4.31046 -3.06116 +-3.82345 -3.54645 +-3.26526 -3.96563 +-2.64562 -4.31006 +-1.97553 -4.57218 +-1.26721 -4.74562 +-0.533959 -4.82546 +0.209954 -4.80835 +0.94951 -4.69274 +1.66917 -4.47902 +2.35316 -4.16969 +2.98585 -3.76951 +3.55215 -3.28553 +4.03794 -2.72707 +4.4306 -2.10569 +4.71946 -1.43493 +4.89627 -0.730055 +4.95559 -0.00758691 +4.89509 0.71515 +4.71572 1.42062 +4.42173 2.09168 +4.02053 2.71216 +3.52242 3.26742 +2.94015 3.74481 +2.28845 4.134 +1.58347 4.42723 +0.842195 4.61939 +0.0819105 4.70801 +-0.680296 4.69317 +-1.42796 4.57727 +-2.14562 4.36483 +-2.81902 4.06221 +-3.43542 3.67732 +-3.98363 3.21936 +-4.45413 2.69856 +-4.83912 2.12593 +-5.13253 1.51305 +-5.32996 0.871892 +-5.4287 0.214606 +-5.42768 -0.446593 +-5.32741 -1.09958 +-5.12995 -1.73246 +-4.83891 -2.33367 +-4.45936 -2.8921 +-3.9978 -3.39725 +-3.46216 -3.83932 +-2.86173 -4.20938 +-2.20709 -4.4995 +-1.51005 -4.70292 +-0.783582 -4.81422 +-0.0416246 -4.82953 +0.701039 -4.74667 +1.42902 -4.56536 +2.12659 -4.28739 +2.77805 -3.91674 +3.36805 -3.45968 +3.8821 -2.92477 +4.30702 -2.32285 +4.63142 -1.66682 +4.84618 -0.971408 +4.94486 -0.252786 +4.92408 0.47191 +4.78367 1.18513 +4.5268 1.86951 +4.15986 2.50848 +3.69227 3.0868 +3.13603 3.59113 +2.50532 4.01032 +1.81592 4.33576 +1.08463 4.56147 +0.328739 4.68417 +-0.434542 4.70313 +-1.18849 4.62006 +-1.91729 4.43883 +-2.60628 4.16526 +-3.24225 3.8068 +-3.81352 3.37227 +-4.31007 2.87158 +-4.72357 2.31549 +-5.04742 1.71539 +-5.27671 1.08311 +-5.40819 0.430717 +-5.44026 -0.229627 +-5.37291 -0.885799 +-5.20769 -1.52585 +-4.94764 -2.13814 +-4.59733 -2.71142 +-4.16275 -3.23499 +-3.65129 -3.69881 +-3.07175 -4.09364 +-2.43424 -4.41118 +-1.75015 -4.64422 +-1.03201 -4.78684 +-0.293464 -4.83457 +0.450966 -4.7846 +1.18604 -4.63594 +1.89608 -4.38963 +2.56525 -4.04886 +3.178 -3.61911 +3.7194 -3.1082 +4.1757 -2.52624 +4.5348 -1.88552 +4.78671 -1.20026 +4.92405 -0.486297 +4.94237 0.23941 +4.84047 0.959295 +4.62047 1.65579 +4.28781 2.31193 +3.85101 2.91197 +3.32138 3.44188 +2.71254 3.88977 +2.03985 4.24622 +1.3199 4.50445 +0.569887 4.66034 +-0.192892 4.71241 +-0.95153 4.66164 +-1.68991 4.51127 +-2.393 4.26655 +-3.04714 3.93444 +-3.64017 3.52335 +-4.16154 3.04286 +-4.60242 2.50348 +-4.95565 1.9164 +-5.21578 1.29331 +-5.37903 0.646189 +-5.44327 -0.0128151 +-5.40797 -0.671569 +-5.27416 -1.31806 +-5.0444 -1.94055 +-4.72275 -2.52764 +-4.31472 -3.06844 +-3.82726 -3.55269 +-3.2687 -3.97084 +-2.64872 -4.31428 +-1.9783 -4.5754 +-1.26964 -4.74784 +-0.536025 -4.82662 +0.208265 -4.80838 +0.948183 -4.6915 +1.66813 -4.47635 +2.35229 -4.16543 +2.98492 -3.76349 +3.55085 -3.27761 +4.0359 -2.71721 +4.42737 -2.09391 +4.71456 -1.42139 +4.88923 -0.715022 +4.94599 0.00853012 +4.88261 0.731835 +4.70017 1.43728 +4.40308 2.10766 +3.99894 2.72682 +3.49819 3.28017 +2.91374 3.75514 +2.26045 4.14152 +1.55452 4.43168 +0.812985 4.62067 +0.0531051 4.70617 +-0.708075 4.68836 +-1.45417 4.56977 +-2.16981 4.355 +-2.84086 4.05044 +-3.45467 3.66403 +-4.00016 3.20499 +-4.4679 2.6835 +-4.85018 2.11055 +-5.14096 1.49769 +-5.33589 0.856802 +-5.4323 0.200014 +-5.4291 -0.460513 +-5.32681 -1.1127 +-5.12749 -1.74467 +-4.83469 -2.34488 +-4.45348 -2.90224 +-3.99034 -3.40625 +-3.45318 -3.84708 +-2.85128 -4.21579 +-2.19524 -4.50441 +-1.49689 -4.70617 +-0.769215 -4.81563 +-0.0262265 -4.82889 +0.717234 -4.74376 +1.44571 -4.56 +2.14339 -4.27941 +2.79451 -3.90605 +3.38366 -3.44625 +3.89632 -2.90869 +4.3193 -2.30433 +4.64123 -1.64617 +4.85307 -0.949083 +4.94849 -0.229332 +4.92422 0.495869 +4.78028 1.20893 +4.51999 1.89248 +4.14991 2.52999 +3.67959 3.10632 +3.12116 3.60821 +2.48885 4.02464 +1.79847 4.34713 +1.06682 4.56984 +0.31113 4.68956 +-0.451446 4.70566 +-1.20427 4.61991 +-1.93159 4.43624 +-2.61884 4.16045 +-3.25285 3.80002 +-3.82198 3.36376 +-4.31626 2.86156 +-4.72739 2.30418 +-5.04875 1.703 +-5.27546 1.06986 +-5.40427 0.41682 +-5.43359 -0.243932 +-5.36342 -0.900254 +-5.19533 -1.54018 +-4.93243 -2.15202 +-4.5793 -2.72452 +-4.14201 -3.24696 +-3.62802 -3.70929 +-3.04622 -4.10227 +-2.40679 -4.41762 +-1.72119 -4.64818 +-1.00205 -4.78809 +-0.263061 -4.83295 +0.481216 -4.78006 +1.21553 -4.62853 +1.9242 -4.37951 +2.59145 -4.03632 +3.20179 -3.60454 +3.74041 -3.09207 +4.19369 -2.50907 +4.54964 -1.86787 +4.79843 -1.18268 +4.9328 -0.469289 +4.94843 0.255402 +4.84418 0.973922 +4.62223 1.66881 +4.28802 2.3232 +3.85006 2.92143 +3.31961 3.44955 +2.71022 3.89574 +2.0372 4.25058 +1.31707 4.50729 +0.566972 4.66175 +-0.195823 4.71244 +-0.954423 4.66031 +-1.6927 4.50858 +-2.39562 4.26245 +-3.04947 3.92889 +-3.64206 3.51631 +-4.16282 3.0343 +-4.60286 2.49339 +-4.955 1.90482 +-5.21378 1.28033 +-5.37543 0.631953 +-5.43782 -0.0281061 +-5.40046 -0.687661 +-5.26443 -1.33466 +-5.03236 -1.9573 +-4.70836 -2.54417 +-4.29805 -3.08438 +-3.80844 -3.56766 +-3.24796 -3.98449 +-2.62637 -4.32628 +-1.95472 -4.58552 +-1.24527 -4.75589 +-0.51134 -4.83252 +0.232771 -4.81213 +0.972027 -4.6932 +1.69087 -4.47619 +2.37353 -4.16369 +3.00438 -3.7605 +3.56833 -3.27375 +4.0513 -2.71284 +4.4407 -2.0894 +4.72592 -1.41705 +4.89878 -0.711099 +4.95395 0.0118568 +4.88918 0.734459 +4.70556 1.43915 +4.40746 2.10879 +4.00241 2.72724 +3.50082 3.2799 +2.91558 3.7542 +2.2615 4.1399 +1.5548 4.42934 +0.812515 4.61756 +0.05196 4.70221 +-0.709783 4.68348 +-1.45628 4.5639 +-2.17212 4.34811 +-2.84315 4.04254 +-3.4567 3.65517 +-4.00168 3.19526 +-4.46871 2.67306 +-4.85008 2.09958 +-5.13981 1.48639 +-5.33362 0.845419 +-5.42886 0.188791 +-5.42453 -0.471337 +-5.32118 -1.1229 +-5.12092 -1.75404 +-4.82735 -2.35326 +-4.44556 -2.90951 +-3.98205 -3.41231 +-3.44474 -3.85191 +-2.84289 -4.21938 +-2.18709 -4.50681 +-1.48914 -4.70744 +-0.762014 -4.81586 +-0.0196643 -4.82818 +0.723094 -4.74222 +1.45083 -4.55771 +2.14777 -4.27644 +2.79813 -3.90244 +3.38653 -3.44203 +3.89841 -2.90387 +4.32057 -2.29887 +4.64158 -1.64006 +4.85238 -0.942316 +4.94659 -0.221934 +4.92093 0.503825 +4.77539 1.21731 +4.51332 1.9011 +4.14132 2.5386 +3.669 3.1146 +3.10856 3.61583 +2.47433 4.03126 +1.78222 4.35242 +1.04911 4.5735 +0.2923 4.69137 +-0.470991 4.70547 +-1.2241 4.61766 +-1.95126 4.43194 +-2.63794 4.15423 +-3.27099 3.79207 +-3.83885 3.35433 +-4.33161 2.85097 +-4.74103 2.29277 +-5.06061 1.69113 +-5.28552 1.05787 +-5.41259 0.405048 +-5.44029 -0.255188 +-5.36867 -0.910739 +-5.19933 -1.54968 +-4.93539 -2.16039 +-4.58144 -2.73166 +-4.14351 -3.25282 +-3.62907 -3.71384 +-3.04694 -4.10553 +-2.40728 -4.41961 +-1.7215 -4.64892 +-1.00222 -4.78757 +-0.263099 -4.83117 +0.48129 -4.77694 +1.21567 -4.62398 +1.92433 -4.3734 +2.59142 -4.02851 +3.20138 -3.59489 +3.73931 -3.08048 +4.19151 -2.4955 +4.54595 -1.85239 +4.79275 -1.16546 +4.92468 -0.450634 +4.93745 0.275062 +4.83003 0.994042 +4.60474 1.68876 +4.26719 2.34231 +3.82605 2.93903 +3.29277 3.46502 +2.68104 3.90854 +2.0063 4.2603 +1.28513 4.51367 +0.53473 4.66467 +-0.227654 4.71194 +-0.985172 4.65656 +-1.72178 4.50186 +-2.42252 4.25314 +-3.07382 3.91741 +-3.66358 3.50312 +-4.18134 3.01986 +-4.61832 2.47816 +-4.96741 1.88921 +-5.22324 1.26472 +-5.38206 0.616681 +-5.4418 -0.0427728 +-5.40197 -0.701496 +-5.26366 -1.34748 +-5.02949 -1.96896 +-4.70356 -2.55456 +-4.29145 -3.09339 +-3.80018 -3.57518 +-3.23816 -3.99042 +-2.61514 -4.33052 +-1.94219 -4.58792 +-1.23155 -4.7563 +-0.496618 -4.83076 +0.248285 -4.80802 +0.988059 -4.68656 +1.70708 -4.46686 +2.38951 -4.15154 +3.01964 -3.74548 +3.58234 -3.25587 +4.0635 -2.69223 +4.45053 -2.06631 +4.73285 -1.39185 +4.90236 -0.684293 +4.95383 0.0396776 +4.88518 0.762621 +4.69764 1.46694 +4.39577 2.1355 +3.98727 2.7522 +3.4827 3.30254 +2.89506 3.77404 +2.23924 4.15661 +1.5315 4.44273 +0.78886 4.62755 +0.028592 4.70884 +-0.732289 4.6869 +-1.47744 4.56432 +-2.19152 4.34578 +-2.86046 4.03774 +-3.47166 3.6482 +-4.01411 3.18639 +-4.47843 2.66257 +-4.85698 2.08775 +-5.14379 1.47347 +-5.33457 0.831686 +-5.42671 0.174506 +-5.4192 -0.485892 +-5.31263 -1.13742 +-5.10913 -1.76822 +-4.81235 -2.36674 +-4.42741 -2.92192 +-3.96089 -3.42327 +-3.42078 -3.86102 +-2.81644 -4.22626 +-2.15854 -4.5111 +-1.45897 -4.70882 +-0.73077 -4.81408 +0.0120178 -4.82308 +0.75454 -4.73373 +1.48134 -4.5459 +2.17667 -4.2615 +2.82477 -3.88469 +3.41035 -3.4219 +3.91897 -2.88188 +4.33754 -2.27564 +4.65482 -1.61623 +4.86187 -0.918537 +4.95249 -0.198815 +4.92352 0.525743 +4.77505 1.23758 +4.51051 1.91939 +4.13652 2.55468 +3.66267 3.12838 +3.10115 3.62726 +2.46622 4.0404 +1.77372 4.35935 +1.04047 4.57833 +0.283719 4.69421 +-0.479359 4.70641 +-1.23212 4.61676 +-1.95882 4.42925 +-2.64491 4.14977 +-3.27722 3.78586 +-3.84417 3.34639 +-4.3358 2.84133 +-4.74388 2.28148 +-5.06187 1.6783 +-5.28494 1.04363 +-5.40992 0.389586 +-5.4353 -0.271625 +-5.36117 -0.927855 +-5.18918 -1.56713 +-4.9225 -2.1778 +-4.56582 -2.74862 +-4.12524 -3.2689 +-3.60831 -3.72864 +-3.02396 -4.11865 +-2.38243 -4.43071 +-1.69522 -4.65771 +-0.975007 -4.79385 +-0.235493 -4.83482 +0.508723 -4.77796 +1.24237 -4.62247 +1.94976 -4.36957 +2.61512 -4.02265 +3.22296 -3.58738 +3.7585 -3.07174 +4.20815 -2.486 +4.55999 -1.84254 +4.80426 -1.15569 +4.93379 -0.441292 +4.94438 0.283701 +4.83502 1.00178 +4.60803 1.69545 +4.26898 2.34789 +3.82656 2.94345 +3.29214 3.46827 +2.67939 3.91059 +2.00373 4.26113 +1.28175 4.51324 +0.530646 4.66293 +-0.232301 4.70884 +-0.990211 4.65206 +-1.727 4.49593 +-2.42768 4.2458 +-3.07866 3.90872 +-3.66783 3.49318 +-4.18475 3.00882 +-4.62064 2.46622 +-4.96847 1.87662 +-5.22288 1.25174 +-5.38021 0.60359 +-5.43844 -0.0556748 +-5.39714 -0.713923 +-5.25746 -1.35916 +-5.02207 -1.97966 +-4.69512 -2.56407 +-4.28222 -3.10156 +-3.79041 -3.5819 +-3.22811 -3.99564 +-2.60506 -4.33422 +-1.93231 -4.59013 +-1.22209 -4.75709 +-0.487755 -4.83024 +0.25641 -4.80628 +0.99534 -4.68372 +1.71344 -4.46304 +2.39491 -4.14682 +3.02404 -3.73994 +3.58571 -3.24955 +4.06579 -2.68518 +4.45167 -2.05854 +4.73274 -1.38338 +4.90086 -0.675158 +4.95076 0.0494025 +4.88036 0.772816 +4.69089 1.47743 +4.38691 2.14604 +3.9762 2.76249 +3.46938 3.31223 +2.87952 3.78277 +2.22163 4.164 +1.51205 4.44844 +0.767902 4.63127 +0.00653287 4.71036 +-0.754991 4.68606 +-1.5003 4.56108 +-2.21404 4.34019 +-2.88219 4.02994 +-3.49218 3.63842 +-4.03305 3.17493 +-4.49553 2.64979 +-4.87204 2.07403 +-5.15671 1.45923 +-5.34534 0.817311 +-5.4354 0.160386 +-5.42595 -0.49941 +-5.31763 -1.15004 +-5.11262 -1.77967 +-4.81458 -2.37685 +-4.42865 -2.93055 +-3.96139 -3.43034 +-3.42078 -3.86649 +-2.81612 -4.23013 +-2.15805 -4.5134 +-1.45844 -4.70958 +-0.730277 -4.81332 +0.0124139 -4.82079 +0.754783 -4.7299 +1.48136 -4.54045 +2.17636 -4.25434 +2.82397 -3.87572 +3.40883 -3.41102 +3.91642 -2.86903 +4.33359 -2.26081 +4.64903 -1.59953 +4.85379 -0.900147 +4.94167 -0.179072 +4.90957 0.546384 +4.7577 1.25855 +4.4896 1.94004 +4.11206 2.57432 +3.63487 3.14631 +3.07037 3.64286 +2.433 4.0531 +1.73871 4.36875 +1.00439 4.58414 +0.247343 4.69632 +-0.515277 4.70486 +-1.26687 4.61172 +-1.99176 4.42102 +-2.6755 4.13875 +-3.30504 3.7725 +-3.86891 3.33117 +-4.35728 2.82477 +-4.762 2.26408 +-5.07663 1.66051 +-5.29642 1.02589 +-5.41827 0.372277 +-5.4407 -0.288178 +-5.36383 -0.943378 +-5.18931 -1.5814 +-4.92034 -2.19063 +-4.56157 -2.75985 +-4.1191 -3.27841 +-3.60048 -3.73632 +-3.0146 -4.12438 +-2.37171 -4.43437 +-1.68332 -4.65918 +-0.962115 -4.793 +-0.221829 -4.83149 +0.522894 -4.772 +1.25673 -4.61372 +1.96394 -4.35792 +2.62867 -4.00801 +3.23538 -3.56975 +3.76924 -3.05119 +4.21664 -2.4627 +4.56567 -1.8168 +4.80661 -1.12793 +4.93237 -0.412052 +4.93887 0.313776 +4.82526 1.03197 +4.59402 1.72502 +4.25092 2.37608 +3.80481 2.96959 +3.26722 3.49174 +2.65193 3.93093 +1.97446 4.278 +1.25141 4.52644 +0.499983 4.6724 +-0.262585 4.71464 +-1.01948 4.65436 +-1.75471 4.49497 +-2.45338 4.24186 +-3.10197 3.90213 +-3.68847 3.48425 +-4.20249 2.9979 +-4.63532 2.45363 +-4.97995 1.86268 +-5.23106 1.23675 +-5.385 0.587864 +-5.43977 -0.0718277 +-5.39496 -0.730182 +-5.25174 -1.37519 +-5.01282 -1.9951 +-4.68239 -2.57855 +-4.26612 -3.11467 +-3.7711 -3.59324 +-3.20584 -4.0048 +-2.58017 -4.34078 +-1.90524 -4.59372 +-1.19337 -4.75739 +-0.458 -4.82698 +0.286508 -4.7993 +1.02504 -4.67297 +1.74198 -4.44859 +2.42151 -4.12891 +3.04801 -3.7189 +3.60641 -3.22589 +4.08272 -2.65949 +4.46447 -2.03151 +4.74121 -1.35575 +4.905 -0.64766 +4.95073 0.0760591 +4.87646 0.797996 +4.68356 1.5006 +4.37667 2.16679 +3.96359 2.78054 +3.45498 3.32741 +2.86386 3.79503 +2.20518 4.17337 +1.49523 4.45501 +0.751059 4.63517 +-0.0100563 4.71171 +-0.771098 4.685 +-1.51573 4.55773 +-2.22862 4.33465 +-2.89575 4.0223 +-3.50454 3.62874 +-4.04403 3.16331 +-4.50491 2.6363 +-4.8796 2.05878 +-5.1622 1.44237 +-5.34853 0.799036 +-5.43604 0.140924 +-5.42384 -0.519772 +-5.31259 -1.17096 +-5.10453 -1.80079 +-4.80339 -2.39773 +-4.41438 -2.95076 +-3.94415 -3.44942 +-3.40078 -3.884 +-2.79367 -4.24566 +-2.13354 -4.52656 +-1.43235 -4.72006 +-0.703177 -4.8209 +0.0399239 -4.82535 +0.782067 -4.73143 +1.50779 -4.53906 +2.20131 -4.25026 +2.84692 -3.86927 +3.42932 -3.40264 +3.93411 -2.8592 +4.34826 -2.25006 +4.66061 -1.58837 +4.86231 -0.889094 +4.94727 -0.168562 +4.91248 0.555978 +4.75818 1.26694 +4.48795 1.94701 +4.10857 2.57972 +3.6298 3.15004 +3.06397 3.64487 +2.42547 4.05335 +1.73025 4.36719 +0.995189 4.58075 +0.237585 4.69106 +-0.525384 4.69771 +-1.2771 4.60267 +-2.00186 4.41009 +-2.68518 4.126 +-3.31402 3.75804 +-3.87691 3.31516 +-4.36401 2.8074 +-4.76723 2.24561 +-5.08017 1.64123 +-5.29813 1.00612 +-5.41807 0.352355 +-5.43858 -0.307914 +-5.35985 -0.962596 +-5.1836 -1.59979 +-4.91308 -2.20791 +-4.55298 -2.77579 +-4.10946 -3.29282 +-3.59007 -3.74907 +-3.00374 -4.13539 +-2.3607 -4.44362 +-1.67243 -4.66669 +-0.951614 -4.79885 +-0.211944 -4.83577 +0.531976 -4.77484 +1.26486 -4.61527 +1.97101 -4.35829 +2.6346 -4.00735 +3.2401 -3.56815 +3.77271 -3.04875 +4.21879 -2.45948 +4.56642 -1.81287 +4.80585 -1.12335 +4.92997 -0.406898 +4.93467 0.319387 +4.81909 1.03788 +4.58572 1.731 +4.24036 2.38187 +3.7919 2.97485 +3.25197 3.4961 +2.63443 3.934 +1.95489 4.2794 +1.23006 4.52582 +0.477243 4.66946 +-0.286266 4.70916 +-1.0436 4.64621 +-1.77873 4.48413 +-2.47678 4.22841 +-3.12425 3.88623 +-3.70918 3.46618 +-4.22126 2.97799 +-4.65184 2.43227 +-4.99402 1.8403 +-5.24258 1.21381 +-5.39396 0.564812 +-5.44624 -0.0945691 +-5.3991 -0.75222 +-5.25378 -1.39618 +-5.01301 -2.01475 +-4.68104 -2.59664 +-4.26353 -3.13104 +-3.76759 -3.60779 +-3.20169 -4.01746 +-2.57563 -4.35156 +-1.90052 -4.60265 +-1.18865 -4.76449 +-0.453396 -4.8323 +0.290886 -4.80287 +1.0291 -4.67478 +1.74562 -4.44863 +2.42461 -4.12711 +3.05039 -3.71521 +3.60785 -3.22024 +4.08291 -2.65186 +4.46305 -2.02192 +4.73777 -1.34433 +4.8991 -0.634632 +4.94196 0.0903405 +4.86446 0.813057 +4.66807 1.51586 +4.35758 2.18158 +3.94096 2.79417 +3.42903 3.33919 +2.835 3.80431 +2.17397 4.17962 +1.46235 4.45781 +0.717257 4.63425 +-0.0439849 4.70697 +-0.804368 4.67649 +-1.5476 4.54565 +-2.25844 4.3193 +-2.92295 4.0041 +-3.52868 3.60817 +-4.06478 3.14089 +-4.52206 2.61258 +-4.89306 2.0343 +-5.17197 1.41762 +-5.35469 0.774495 +-5.43875 0.117011 +-5.42329 -0.54269 +-5.30903 -1.19257 +-5.0982 -1.82083 +-4.79455 -2.41599 +-4.4033 -2.96706 +-3.93108 -3.46362 +-3.38594 -3.89597 +-2.7773 -4.25528 +-2.11587 -4.53373 +-1.41359 -4.72467 +-0.683564 -4.82283 +0.0601208 -4.82446 +0.802546 -4.7276 +1.5282 -4.53219 +2.22125 -4.24026 +2.86593 -3.85611 +3.44688 -3.38634 +3.94967 -2.83989 +4.36126 -2.22796 +4.67048 -1.56383 +4.86855 -0.862568 +4.94948 -0.140638 +4.91036 0.584624 +4.75161 1.29557 +4.47697 1.97484 +4.09342 2.606 +3.61089 3.17408 +3.04186 3.66606 +2.40084 4.07123 +1.70385 4.38142 +0.967826 4.59116 +0.210039 4.6976 +-0.552369 4.70047 +-1.30285 4.60186 +-2.02579 4.40598 +-2.70682 4.11891 +-3.33296 3.74833 +-3.89284 3.3032 +-4.37672 2.79356 +-4.77654 2.23026 +-5.08595 1.62472 +-5.30028 0.988796 +-5.41653 0.334556 +-5.43331 -0.325846 +-5.35082 -0.980312 +-5.17083 -1.61693 +-4.89658 -2.22409 +-4.53284 -2.79063 +-4.08582 -3.30589 +-3.56313 -3.75995 +-2.97378 -4.14367 +-2.3281 -4.44888 +-1.63767 -4.66855 +-0.915258 -4.79697 +-0.174662 -4.82991 +0.569443 -4.76484 +1.30172 -4.60109 +2.00643 -4.34004 +2.66777 -3.98528 +3.27026 -3.54266 +3.79918 -3.02038 +4.24102 -2.4289 +4.58404 -1.78083 +4.81865 -1.09066 +4.93794 -0.374378 +4.93799 0.350959 +4.8181 1.0678 +4.58091 1.75867 +4.2323 2.40682 +3.78122 2.99677 +3.2393 3.51479 +2.62039 3.94939 +1.94004 4.29152 +1.2149 4.53476 +0.462171 4.67538 +-0.300895 4.71223 +-1.0575 4.64659 +-1.79166 4.48199 +-2.48853 4.2239 +-3.13463 3.8795 +-3.71799 3.45736 +-4.2283 2.9672 +-4.65691 2.41967 +-4.9969 1.82603 +-5.24304 1.19807 +-5.39178 0.547822 +-5.44121 -0.112536 +-5.39104 -0.770845 +-5.24253 -1.4151 +-4.99849 -2.03357 +-4.66322 -2.61491 +-4.24247 -3.1483 +-3.74343 -3.62356 +-3.17467 -4.03129 +-2.5461 -4.36301 +-1.86892 -4.61132 +-1.15551 -4.77008 +-0.419328 -4.83457 +0.325222 -4.80169 +1.06301 -4.67017 +1.77841 -4.4407 +2.45562 -4.11613 +3.07901 -3.70154 +3.63358 -3.20437 +4.10537 -2.63433 +4.48199 -2.00334 +4.7531 -1.32529 +4.91083 -0.615718 +4.95025 0.10861 +4.86957 0.830233 +4.6703 1.53158 +4.35727 2.19558 +3.93847 2.80624 +3.42469 3.34921 +2.82912 3.8122 +2.16685 4.18532 +1.45424 4.46128 +0.708421 4.63548 +-0.0533021 4.70594 +-0.813911 4.67321 +-1.5571 4.54013 +-2.26761 4.3116 +-2.93149 3.99432 +-3.53629 3.59646 +-4.07115 3.12745 +-4.52693 2.59764 +-4.89617 2.01816 +-5.17314 1.40063 +-5.35378 0.756999 +-5.4357 0.0993932 +-5.41811 -0.56005 +-5.3018 -1.20931 +-5.08907 -1.83659 +-4.78374 -2.43047 +-4.39107 -2.97999 +-3.91773 -3.4748 +-3.37182 -3.90526 +-2.76275 -4.26258 +-2.10123 -4.53902 +-1.3992 -4.72798 +-0.669732 -4.82424 +0.0731315 -4.82411 +0.814512 -4.72562 +1.53894 -4.52875 +2.23064 -4.23554 +2.87385 -3.85027 +3.45327 -3.37952 +3.95447 -2.83222 +4.36441 -2.21955 +4.67191 -1.55478 +4.86816 -0.852975 +4.94716 -0.130617 +4.90597 0.594929 +4.745 1.30597 +4.46802 1.9851 +4.08203 2.61582 +3.59701 3.18312 +3.02552 3.67394 +2.38217 4.07756 +1.68308 4.38582 +0.945271 4.59328 +0.186112 4.69715 +-0.577186 4.69725 +-1.32802 4.59574 +-2.05077 4.39696 +-2.73105 4.10709 +-3.35594 3.7339 +-3.91409 3.28645 +-4.39585 2.77485 +-4.79324 2.21001 +-5.10001 1.60339 +-5.3116 0.966869 +-5.4251 0.31251 +-5.43922 -0.34755 +-5.35424 -1.00125 +-5.17198 -1.63673 +-4.89579 -2.24243 +-4.53043 -2.80726 +-4.08214 -3.32064 +-3.55854 -3.77269 +-2.96861 -4.15435 +-2.32265 -4.4575 +-1.63221 -4.67515 +-0.91 -4.8016 +-0.169777 -4.83264 +0.57382 -4.76573 +1.30547 -4.60017 +2.00944 -4.33734 +2.66992 -3.98079 +3.27139 -3.53635 +3.79906 -3.01223 +4.23939 -2.41892 +4.58054 -1.76908 +4.81293 -1.07727 +4.9296 -0.359588 +4.92665 0.366787 +4.80344 1.08419 +4.56272 1.77505 +4.2105 2.42254 +3.7559 3.01113 +3.21071 3.52713 +2.58897 3.95908 +1.90635 4.29804 +1.17963 4.53772 +0.426095 4.67453 +-0.336985 4.70747 +-1.09281 4.638 +-1.82546 4.46976 +-2.52015 4.20837 +-3.16349 3.86109 +-3.74366 3.43656 +-4.25044 2.94457 +-4.67531 2.39574 +-5.01147 1.80138 +-5.25377 1.17321 +-5.39877 0.523253 +-5.44462 -0.13637 +-5.39109 -0.793555 +-5.23947 -1.43635 +-4.99261 -2.05308 +-4.6548 -2.63245 +-4.2318 -3.16368 +-3.7308 -3.63663 +-3.16036 -4.04192 +-2.53038 -4.3711 +-1.85205 -4.61677 +-1.13775 -4.77278 +-0.40095 -4.83444 +0.343922 -4.79864 +1.0817 -4.6641 +1.79673 -4.43155 +2.47315 -4.10384 +3.09529 -3.68614 +3.6481 -3.18592 +4.1176 -2.61299 +4.49137 -1.97938 +4.75911 -1.29909 +4.91302 -0.587767 +4.94823 0.137705 +4.8631 0.859782 +4.65931 1.56084 +4.34186 2.22377 +3.9189 2.83263 +3.40141 3.37311 +2.80273 3.83304 +2.13805 4.20265 +1.42382 4.4748 +0.677191 4.64503 +-0.0845414 4.71153 +-0.844402 4.67495 +-1.58616 4.53824 +-2.29464 4.3064 +-2.956 3.98616 +-3.55787 3.58574 +-4.08951 3.11455 +-4.54183 2.58298 +-4.90745 2.00211 +-5.18068 1.38357 +-5.35752 0.739303 +-5.43558 0.0814138 +-5.41412 -0.577957 +-5.29393 -1.22678 +-5.07735 -1.85326 +-4.76822 -2.44596 +-4.37185 -2.99389 +-3.89499 -3.4867 +-3.34576 -3.91473 +-2.73369 -4.26921 +-2.06957 -4.54238 +-1.36544 -4.72771 +-0.634462 -4.82001 +0.109212 -4.81567 +0.850627 -4.71285 +1.57426 -4.51161 +2.2643 -4.21417 +2.90501 -3.82495 +3.48113 -3.35069 +3.97833 -2.80047 +4.3837 -2.18559 +4.68625 -1.51943 +4.87737 -0.817106 +4.95123 -0.0950973 +4.90512 0.629264 +4.73962 1.33837 +4.45864 2.01493 +4.06928 2.64259 +3.58159 3.20649 +3.00814 3.69371 +2.36351 4.09366 +1.66375 4.3983 +0.925822 4.60226 +0.167014 4.70283 +-0.595545 4.69982 +-1.34532 4.59543 +-2.06675 4.39398 +-2.74548 4.10164 +-3.36862 3.72617 +-3.92483 3.27662 +-4.40446 2.76309 +-4.79953 2.1965 +-5.10378 1.58834 +-5.31265 0.950484 +-5.42323 0.295047 +-5.43424 -0.365798 +-5.346 -1.01995 +-5.16037 -1.6555 +-4.88072 -2.26086 +-4.51193 -2.82489 +-4.06028 -3.33701 +-3.53349 -3.78732 +-2.94065 -4.16676 +-2.29214 -4.46725 +-1.59963 -4.68185 +-0.875919 -4.80493 +-0.134834 -4.83238 +0.608921 -4.76176 +1.34 -4.59251 +2.04266 -4.32613 +2.70112 -3.9663 +3.29993 -3.51901 +3.82442 -2.99255 +4.26115 -2.3975 +4.59845 -1.74657 +4.82687 -1.05434 +4.93962 -0.336881 +4.93291 0.38869 +4.80624 1.10478 +4.56239 1.79393 +4.20745 2.43939 +3.75053 3.02573 +3.20342 3.53933 +2.58013 3.9688 +1.89632 4.30522 +1.16872 4.54234 +0.414614 4.67659 +-0.348746 4.70699 +-1.10457 4.635 +-1.83691 4.46431 +-2.53099 4.20055 +-3.17343 3.85103 +-3.75238 3.42445 +-4.25765 2.93063 +-4.68075 2.38025 +-5.0149 1.78467 +-5.25502 1.15564 +-5.39772 0.505216 +-5.44122 -0.154467 +-5.38537 -0.811304 +-5.23154 -1.45336 +-4.98264 -2.06897 +-4.64304 -2.6469 +-4.21855 -3.17641 +-3.7164 -3.64742 +-3.14518 -4.05062 +-2.51481 -4.37762 +-1.83647 -4.62109 +-1.12254 -4.77495 +-0.386445 -4.83456 +0.357422 -4.79685 +1.09395 -4.66059 +1.80753 -4.42651 +2.48235 -4.09749 +3.1028 -3.67867 +3.65384 -3.17751 +4.12152 -2.60381 +4.49344 -1.96956 +4.75927 -1.28875 +4.9112 -0.577033 +4.94436 0.148707 +4.85707 0.8709 +4.65099 1.57188 +4.33115 2.2345 +3.90574 2.84275 +3.38577 3.38229 +2.78467 3.8409 +2.1177 4.20882 +1.40143 4.47891 +0.653091 4.64675 +-0.109929 4.71057 +-0.870589 4.67112 +-1.61261 4.53145 +-2.32079 4.29665 +-2.9813 3.97355 +-3.5818 3.57048 +-4.1116 3.09694 +-4.56169 2.56339 +-4.92477 1.98099 +-5.19526 1.36139 +-5.36924 0.71656 +-5.44446 0.0586038 +-5.42024 -0.600356 +-5.29748 -1.24833 +-5.0786 -1.87356 +-4.76749 -2.46469 +-4.36951 -3.01079 +-3.89141 -3.50158 +-3.34136 -3.92748 +-2.72882 -4.27977 +-2.06458 -4.55078 +-1.36064 -4.73399 +-0.630091 -4.82426 +0.112952 -4.81799 +0.853583 -4.71333 +1.57631 -4.51034 +2.26533 -4.2112 +2.90491 -3.82032 +3.47975 -3.34441 +3.9755 -2.79256 +4.37918 -2.17608 +4.67976 -1.50838 +4.86857 -0.804671 +4.93978 -0.0815086 +4.89069 0.643663 +4.72195 1.35313 +4.43755 2.0295 +4.04472 2.65636 +3.55367 3.21881 +2.97712 3.70395 +2.32982 4.10124 +1.62795 4.40273 +0.888595 4.60317 +0.129101 4.69999 +-0.633369 4.69316 +-1.38229 4.58503 +-2.10214 4.38004 +-2.77865 4.0845 +-3.39902 3.70624 +-3.95203 3.25441 +-4.42812 2.73914 +-4.81946 2.17136 +-5.1199 1.56256 +-5.32495 0.924605 +-5.43182 0.269564 +-5.4393 -0.390436 +-5.34776 -1.04334 +-5.15909 -1.67731 +-4.87671 -2.28081 +-4.50549 -2.84275 +-4.05174 -3.35259 +-3.52315 -3.80047 +-2.92882 -4.17737 +-2.27911 -4.47524 +-1.58569 -4.68713 +-0.861342 -4.80743 +-0.119915 -4.83204 +0.623878 -4.75851 +1.35466 -4.58631 +2.05666 -4.31695 +2.71406 -3.95413 +3.31137 -3.5039 +3.83386 -2.97461 +4.2681 -2.37692 +4.60241 -1.72364 +4.82735 -1.02946 +4.93621 -0.310553 +4.9253 0.415861 +4.79423 1.13212 +4.54595 1.8207 +4.18672 2.46486 +3.72581 3.04918 +3.17519 3.56013 +2.54899 3.98641 +1.86298 4.31924 +1.13397 4.55251 +0.379246 4.68279 +-0.383944 4.70924 +-1.13885 4.63347 +-1.86962 4.45924 +-2.56155 4.19227 +-3.20135 3.83991 +-3.77728 3.4109 +-4.27925 2.91506 +-4.69883 2.36307 +-5.02931 1.76627 +-5.26567 1.13641 +-5.40454 0.485515 +-5.44421 -0.174284 +-5.38451 -0.830885 +-5.22685 -1.47235 +-4.97417 -2.08701 +-4.63086 -2.66362 +-4.20278 -3.19142 +-3.69721 -3.66031 +-3.12281 -4.06099 +-2.48957 -4.38505 +-1.80877 -4.62519 +-1.09287 -4.77537 +-0.355423 -4.83097 +0.3891 -4.78904 +1.1255 -4.64843 +1.83811 -4.41001 +2.5111 -4.0768 +3.12886 -3.65409 +3.67642 -3.14953 +4.13992 -2.57304 +4.50711 -1.93676 +4.76784 -1.25476 +4.91451 -0.542753 +4.94244 0.182371 +4.85016 0.90309 +4.63955 1.60182 +4.31575 2.26156 +3.88706 2.86643 +3.36456 3.40226 +2.76168 3.85699 +2.09366 4.22098 +1.37699 4.48721 +0.628834 4.65136 +-0.133516 4.7117 +-0.8931 4.66903 +-1.63371 4.5264 +-2.34023 4.28888 +-2.99885 3.96331 +-3.59728 3.55799 +-4.12483 3.08242 +-4.57251 2.54704 +-4.93301 1.963 +-5.20074 1.34198 +-5.3718 0.695959 +-5.44393 0.0370746 +-5.41646 -0.622517 +-5.29031 -1.27078 +-5.06795 -1.89594 +-4.75332 -2.48657 +-4.35184 -3.03174 +-3.87034 -3.52112 +-3.31706 -3.94514 +-2.7016 -4.29509 +-2.03482 -4.56331 +-1.32882 -4.74335 +-0.596809 -4.83014 +0.147041 -4.82017 +0.887756 -4.7117 +1.60981 -4.50494 +2.29741 -4.20219 +2.93484 -3.808 +3.50689 -3.32924 +3.9993 -2.77507 +4.39923 -2.15692 +4.69581 -1.48825 +4.88053 -0.784269 +4.94771 -0.061516 +4.8948 0.662629 +4.72255 1.37053 +4.43504 2.04492 +4.03954 2.66948 +3.54628 3.22939 +2.96796 3.71185 +2.3193 4.10639 +1.61648 4.4051 +0.876509 4.60277 +0.116734 4.69684 +-0.645706 4.68732 +-1.3943 4.57654 +-2.11352 4.36901 +-2.7891 4.07103 +-3.40824 3.69049 +-3.95974 3.23657 +-4.43405 2.71946 +-4.82335 2.15014 +-5.12153 1.54013 +-5.32418 0.901353 +-5.42854 0.245892 +-5.43348 -0.414109 +-5.33945 -1.0666 +-5.14842 -1.69974 +-4.86387 -2.30203 +-4.49074 -2.86242 +-4.0354 -3.37043 +-3.50561 -3.81626 +-2.91045 -4.19095 +-2.26035 -4.48653 +-1.56694 -4.69612 +-0.842997 -4.81419 +-0.102336 -4.83668 +0.640376 -4.76121 +1.36982 -4.58727 +& +@target G0.S2 +@type xy +9.07533 -3.03929 +9.22824 -2.55085 +9.35109 -2.0541 +9.44322 -1.55058 +9.50404 -1.04192 +9.53307 -0.529761 +9.52991 -0.0158071 +9.49428 0.498206 +9.426 1.01051 +9.32499 1.51931 +9.19131 2.02279 +9.02513 2.51911 +8.82673 3.00643 +8.59654 3.48291 +8.33511 3.94673 +8.04311 4.39605 +7.72136 4.82908 +7.37081 5.24407 +6.99254 5.6393 +6.58775 6.01312 +6.15778 6.36392 +5.7041 6.69019 +5.22828 6.99051 +4.73204 7.26354 +4.21719 7.50809 +3.68567 7.72303 +3.1395 7.9074 +2.5808 8.06033 +2.01176 8.18112 +1.43463 8.26919 +0.851705 8.3241 +0.265326 8.34559 +-0.322148 8.33353 +-0.908351 8.28794 +-1.49092 8.20902 +-2.06752 8.09712 +-2.63583 7.95273 +-3.1936 7.77649 +-3.73863 7.56921 +-4.26878 7.3318 +-4.78201 7.06532 +-5.27638 6.77097 +-5.75002 6.45004 +-6.20122 6.10392 +-6.62836 5.73413 +-7.02994 5.34224 +-7.40461 4.9299 +-7.75114 4.49883 +-8.06846 4.05082 +-8.35559 3.58766 +-8.61175 3.11121 +-8.83625 2.62333 +-9.02856 2.12589 +-9.18828 1.62079 +-9.31514 1.1099 +-9.40899 0.595087 +-9.46983 0.0781871 +-9.49774 -0.43898 +-9.49295 -0.954633 +-9.45579 -1.46703 +-9.38668 -1.97446 +-9.28615 -2.47529 +-9.15483 -2.9679 +-8.99342 -3.45077 +-8.80273 -3.92239 +-8.58361 -4.38135 +-8.33702 -4.82629 +-8.06396 -5.25592 +-7.7655 -5.66899 +-7.44277 -6.06434 +-7.09695 -6.44089 +-6.72927 -6.7976 +-6.341 -7.13352 +-5.93345 -7.44775 +-5.50797 -7.73948 +-5.06593 -8.00795 +-4.60876 -8.25249 +-4.13786 -8.47248 +-3.65472 -8.66737 +-3.16079 -8.83669 +-2.65757 -8.98002 +-2.14657 -9.09704 +-1.6293 -9.18746 +-1.10729 -9.25107 +-0.582058 -9.28774 +-0.0551514 -9.29738 +0.471898 -9.27999 +0.997555 -9.23563 +1.52029 -9.16442 +2.03857 -9.06653 +2.55088 -8.94223 +3.0557 -8.79183 +3.55155 -8.6157 +4.03695 -8.41428 +4.51042 -8.1881 +4.97054 -7.93771 +5.41589 -7.66375 +5.84509 -7.36695 +6.25678 -7.04807 +6.64964 -6.70795 +7.02238 -6.34752 +7.37375 -5.96775 +7.70254 -5.56968 +8.00759 -5.15443 +8.28777 -4.72316 +8.54201 -4.2771 +8.76932 -3.81756 +8.96876 -3.34587 +9.13943 -2.86347 +9.28055 -2.3718 +9.39139 -1.87241 +9.4713 -1.36686 +9.51973 -0.856774 +9.53623 -0.343826 +9.52043 0.170274 +9.47207 0.683781 +9.39101 1.19491 +9.27722 1.70187 +9.13077 2.20282 +8.95187 2.69593 +8.74086 3.17936 +8.4982 3.65126 +8.22448 4.1098 +7.92042 4.55318 +7.58691 4.97961 +7.22492 5.38734 +6.8356 5.77469 +6.42022 6.14 +5.98017 6.48172 +5.51699 6.79836 +5.03232 7.08852 +4.52792 7.35089 +4.00567 7.58429 +3.46756 7.78764 +2.91563 7.96 +2.35206 8.10055 +1.77904 8.20863 +1.19887 8.28371 +0.613849 8.32542 +0.0263445 8.33354 +-0.56128 8.30802 +-1.14665 8.24894 +-1.72741 8.15656 +-2.30122 8.03131 +-2.86579 7.87373 +-3.41887 7.68455 +-3.95829 7.46461 +-4.48195 7.21491 +-4.98783 6.93657 +-5.47404 6.63082 +-5.93875 6.29903 +-6.38029 5.94263 +-6.79709 5.56318 +-7.18772 5.16229 +-7.55088 4.74166 +-7.88539 4.30304 +-8.19023 3.84822 +-8.46451 3.37904 +-8.70748 2.89737 +-8.91852 2.40508 +-9.09716 1.90407 +-9.24304 1.39623 +-9.35597 0.883422 +-9.43583 0.367523 +-9.48267 -0.149633 +-9.49662 -0.666238 +-9.47794 -1.18052 +-9.427 -1.69076 +-9.34425 -2.19528 +-9.23027 -2.69245 +-9.0857 -3.18071 +-8.9113 -3.65854 +-8.70791 -4.12449 +-8.47642 -4.57718 +-8.21782 -5.01527 +-7.93317 -5.43749 +-7.62355 -5.84265 +-7.29012 -6.22961 +-6.93411 -6.59729 +-6.55675 -6.9447 +-6.15935 -7.2709 +-5.74322 -7.57503 +-5.30975 -7.85629 +-4.86032 -8.11396 +-4.39636 -8.34737 +-3.91931 -8.55595 +-3.43064 -8.73916 +-2.93184 -8.89656 +-2.42441 -9.02775 +-1.90986 -9.13244 +-1.38973 -9.21035 +-0.86553 -9.26132 +-0.338811 -9.28522 +0.188891 -9.28202 +0.716033 -9.25172 +1.24108 -9.19442 +1.76249 -9.11025 +2.27874 -8.99945 +2.78831 -8.8623 +3.28969 -8.69914 +3.78139 -8.51039 +4.26193 -8.29654 +4.72985 -8.05812 +5.18371 -7.79577 +5.62211 -7.51016 +6.04365 -7.20204 +6.44697 -6.87222 +6.83077 -6.52158 +7.19376 -6.15108 +7.53469 -5.76171 +7.85237 -5.35457 +8.14565 -4.93078 +8.41344 -4.49156 +8.6547 -4.03818 +8.86845 -3.57196 +9.05378 -3.09429 +9.20987 -2.60662 +9.33594 -2.11046 +9.43132 -1.60735 +9.49542 -1.09891 +9.52773 -0.586796 +9.52786 -0.072696 +9.4955 0.441652 +9.43047 0.954478 +9.33267 1.46399 +9.20215 1.96836 +9.03906 2.46575 +8.84368 2.95433 +8.61643 3.43225 +8.35783 3.89767 +8.06857 4.34877 +7.74945 4.78375 +7.40141 5.20085 +7.02553 5.59835 +6.62302 5.97457 +6.1952 6.32792 +5.74355 6.65686 +5.26965 6.95996 +4.77519 7.23585 +4.26199 7.4833 +3.73195 7.70118 +3.18709 7.88851 +2.6295 8.04441 +2.06137 8.16817 +1.48494 8.2592 +0.902497 8.31708 +0.316389 8.34151 +-0.271028 8.33237 +-0.857386 8.28969 +-1.44032 8.21364 +-2.01748 8.10455 +-2.58657 7.96293 +-3.1453 7.78939 +-3.69147 7.58472 +-4.22296 7.34985 +-4.73769 7.08582 +-5.23373 6.79382 +-5.7092 6.47511 +-6.16237 6.13112 +-6.59161 5.76331 +-6.99543 5.37328 +-7.37244 4.96267 +-7.72143 4.53319 +-8.04129 4.08662 +-8.33106 3.62476 +-8.58991 3.14946 +-8.81718 2.66257 +-9.01231 2.16599 +-9.17488 1.66158 +-9.30463 1.15124 +-9.4014 0.636813 +-9.46515 0.120154 +-9.49599 -0.396921 +-9.49413 -0.91263 +-9.45987 -1.42522 +-9.39364 -1.933 +-9.29596 -2.43432 +-9.16745 -2.92756 +-9.0088 -3.41118 +-8.82081 -3.8837 +-8.60434 -4.34368 +-8.36032 -4.78976 +-8.08976 -5.22065 +-7.79371 -5.6351 +-7.4733 -6.03195 +-7.12971 -6.4101 +-6.76415 -6.76852 +-6.37789 -7.10623 +-5.97224 -7.42236 +-5.54853 -7.71607 +-5.10815 -7.98661 +-4.6525 -8.23329 +-4.183 -8.45549 +-3.7011 -8.65266 +-3.20828 -8.82431 +-2.70603 -8.97004 +-2.19584 -9.08949 +-1.67923 -9.18238 +-1.15772 -9.2485 +-0.632843 -9.2877 +-0.106122 -9.2999 +0.420906 -9.28509 +0.946705 -9.2433 +1.46975 -9.17467 +1.9885 -9.07937 +2.50146 -8.95764 +3.0071 -8.8098 +3.50393 -8.63622 +3.99048 -8.43734 +4.46526 -8.21366 +4.92684 -7.96575 +5.37379 -7.69424 +5.80473 -7.39983 +6.21828 -7.08328 +6.61311 -6.74542 +6.98795 -6.38714 +7.34153 -6.00942 +7.67264 -5.61328 +7.98012 -5.19983 +8.26285 -4.77022 +8.51976 -4.32569 +8.74984 -3.86753 +8.95215 -3.39707 +9.1258 -2.91574 +9.26998 -2.42498 +9.38396 -1.92633 +9.46708 -1.42135 +9.5188 -0.91165 +9.53862 -0.398907 +9.52619 0.115175 +9.48124 0.628854 +9.40359 1.14035 +9.29321 1.64787 +9.15017 2.14958 +8.97466 2.64365 +8.76699 3.12823 +8.52761 3.60148 +8.25711 4.06157 +7.9562 4.50668 +7.62573 4.93504 +7.26667 5.34488 +6.88016 5.7345 +6.46744 6.10227 +6.02991 6.4466 +5.56907 6.766 +5.08656 7.05906 +4.58414 7.32447 +4.06367 7.56102 +3.52711 7.76762 +2.97653 7.94333 +2.41406 8.0873 +1.84192 8.19887 +1.26238 8.27748 +0.67776 8.32274 +0.0903996 8.33443 +-0.497328 8.31247 +-1.08305 8.25693 +-1.66441 8.16806 +-2.23906 8.04626 +-2.80471 7.89206 +-3.3591 7.70616 +-3.90006 7.48942 +-4.42546 7.24279 +-4.93331 6.9674 +-5.42166 6.66446 +-5.88871 6.33531 +-6.33275 5.9814 +-6.75222 5.60426 +-7.14565 5.2055 +-7.51174 4.78682 +-7.8493 4.34994 +-8.15729 3.89667 +-8.43481 3.42884 +-8.68109 2.94832 +-8.89551 2.45697 +-9.07757 1.95669 +-9.22692 1.44937 +-9.34333 0.93689 +-9.42671 0.421113 +-9.47707 -0.0961171 +-9.49456 -0.612989 +-9.47942 -1.12773 +-9.432 -1.63859 +-9.35278 -2.1439 +-9.24229 -2.64201 +-9.10119 -3.13134 +-8.9302 -3.61037 +-8.73014 -4.07764 +-8.50189 -4.53175 +-8.24642 -4.97137 +-7.96477 -5.39524 +-7.65803 -5.80216 +-7.32736 -6.19098 +-6.97395 -6.56065 +-6.59906 -6.91015 +-6.20398 -7.23854 +-5.79004 -7.54497 +-5.3586 -7.82864 +-4.91105 -8.0888 +-4.44881 -8.3248 +-3.97333 -8.53603 +-3.48607 -8.72199 +-2.98851 -8.88219 +-2.48216 -9.01627 +-1.96852 -9.12388 +-1.44912 -9.20477 +-0.925479 -9.25876 +-0.399142 -9.28572 +0.128356 -9.28559 +0.655477 -9.25839 +1.18068 -9.20419 +1.70244 -9.12313 +2.21921 -9.01542 +2.7295 -8.88134 +3.23177 -8.72124 +3.72455 -8.5355 +4.20636 -8.32462 +4.67572 -8.08912 +5.1312 -7.82962 +5.5714 -7.54679 +5.99491 -7.24136 +6.40038 -6.91414 +6.78649 -6.56601 +7.15195 -6.19789 +7.49551 -5.81079 +7.81597 -5.40577 +8.11217 -4.98398 +8.38301 -4.5466 +8.62745 -4.0949 +8.84451 -3.63019 +9.03325 -3.15386 +9.19284 -2.66734 +9.32251 -2.17214 +9.42156 -1.66979 +9.48939 -1.16191 +9.52548 -0.650138 +9.52942 -0.136165 +9.50089 0.378277 +9.43969 0.891421 +9.34571 1.40147 +9.21898 1.90661 +9.05963 2.40501 +8.86793 2.89482 +8.64428 3.37419 +8.38919 3.84129 +8.10332 4.29428 +7.78746 4.73137 +7.44255 5.15079 +7.06964 5.5508 +6.66993 5.92975 +6.24474 6.286 +5.79554 6.61804 +5.3239 6.92439 +4.83152 7.20369 +4.3202 7.45469 +3.79187 7.67623 +3.24851 7.86729 +2.69221 8.02697 +2.12514 8.15452 +1.54952 8.24935 +0.967643 8.311 +0.381828 8.33917 +-0.205568 8.33373 +-0.792177 8.29468 +-1.37563 8.22221 +-1.95358 8.11662 +-2.5237 7.9784 +-3.08372 7.80817 +-3.63142 7.6067 +-4.16466 7.37489 +-4.68137 7.1138 +-5.17957 6.82457 +-5.6574 6.50849 +-6.1131 6.16695 +-6.54503 5.80144 +-6.95167 5.41352 +-7.33164 5.00483 +-7.68369 4.57709 +-8.00671 4.13207 +-8.29972 3.67157 +-8.56189 3.19743 +-8.79252 2.71153 +-8.99105 2.21574 +-9.15705 1.71194 +-9.29024 1.20201 +-9.39045 0.687826 +-9.45764 0.171232 +-9.49189 -0.345952 +-9.49341 -0.861936 +-9.4625 -1.37497 +-9.39958 -1.88335 +-9.30515 -2.38541 +-9.17983 -2.87955 +-9.0243 -3.36421 +-8.83936 -3.8379 +-8.62586 -4.2992 +-8.38472 -4.74672 +-8.11694 -5.17917 +-7.82358 -5.5953 +-7.50577 -5.99395 +-7.16465 -6.374 +-6.80147 -6.73442 +-6.41746 -7.07424 +-6.01394 -7.39257 +-5.59225 -7.68856 +-5.15375 -7.96147 +-4.69984 -8.2106 +-4.23196 -8.43532 +-3.75153 -8.63508 +-3.26004 -8.80939 +-2.75896 -8.95783 +-2.24979 -9.08005 +-1.73404 -9.17576 +-1.21324 -9.24473 +-0.688896 -9.28682 +-0.162546 -9.30194 +0.36428 -9.29007 +0.890053 -9.25125 +1.41325 -9.18559 +1.93233 -9.09326 +2.4458 -8.9745 +2.95215 -8.82962 +3.44987 -8.65898 +3.93749 -8.46303 +4.41355 -8.24225 +4.87659 -7.99721 +5.32519 -7.72854 +5.75796 -7.43692 +6.17353 -7.12312 +6.57054 -6.78794 +6.94771 -6.43227 +7.30377 -6.05706 +7.63751 -5.66333 +7.94775 -5.25215 +8.23337 -4.82467 +8.49331 -4.38212 +8.72656 -3.92576 +8.93216 -3.45693 +9.10923 -2.97704 +9.25695 -2.48754 +9.37458 -1.98993 +9.46146 -1.48578 +9.51701 -0.976705 +9.54074 -0.464357 +9.53229 0.0495622 +9.49135 0.563314 +9.41775 1.07513 +9.31143 1.58321 +9.17245 2.08572 +9.00096 2.58085 +8.79729 3.06674 +8.56184 3.54154 +8.29519 4.00344 +7.99803 4.45059 +7.67118 4.88123 +7.31562 5.29357 +6.93243 5.68593 +6.52287 6.05664 +6.0883 6.40411 +5.63021 6.72684 +5.15023 7.0234 +4.65009 7.29246 +4.13165 7.53281 +3.59687 7.74333 +3.04778 7.92306 +2.48652 8.07115 +1.9153 8.18689 +1.33639 8.26972 +0.75209 8.31924 +0.164758 8.33518 +-0.42324 8.31745 +-1.00953 8.26612 +-1.59174 8.18139 +-2.16754 8.06365 +-2.7346 7.91343 +-3.29068 7.7314 +-3.83358 7.51839 +-4.36117 7.27535 +-4.87143 7.00339 +-5.36242 6.70371 +-5.83231 6.37763 +-6.27938 6.02661 +-6.70205 5.65214 +-7.09883 5.25585 +-7.46841 4.8394 +-7.80958 4.40455 +-8.12129 3.95307 +-8.40261 3.48681 +-8.65276 3.00761 +-8.87111 2.51736 +-9.05715 2.01795 +-9.2105 1.51126 +-9.33093 0.999189 +-9.41833 0.483592 +-9.47271 -0.0336828 +-9.4942 -0.550818 +-9.48304 -1.06603 +-9.43958 -1.57759 +-9.36427 -2.08378 +-9.25767 -2.58298 +-9.12041 -3.07357 +-8.95322 -3.55404 +-8.7569 -4.0229 +-8.53232 -4.47875 +-8.28043 -4.92024 +-8.00226 -5.34609 +-7.69887 -5.7551 +-7.37142 -6.14613 +-7.02108 -6.51811 +-6.64911 -6.87004 +-6.25679 -7.20097 +-5.84545 -7.51005 +-5.41643 -7.79646 +-4.97114 -8.05948 +-4.51099 -8.29843 +-4.03742 -8.51272 +-3.55189 -8.70181 +-3.05588 -8.86523 +-2.55088 -9.0026 +-2.03841 -9.11357 +-1.51998 -9.1979 +-0.997115 -9.25536 +-0.47135 -9.28585 +0.0557809 -9.28929 +0.582741 -9.26568 +1.108 -9.21509 +1.63001 -9.13765 +2.14727 -9.03357 +2.65824 -8.90311 +3.16143 -8.7466 +3.65533 -8.56443 +4.13847 -8.35707 +4.6094 -8.12505 +5.06666 -7.86896 +5.50884 -7.58946 +5.93455 -7.28729 +6.34244 -6.96322 +6.73116 -6.61813 +7.09944 -6.25294 +7.44602 -5.86863 +7.76968 -5.46626 +8.06927 -5.04696 +8.34368 -4.6119 +8.59185 -4.16234 +8.81279 -3.69958 +9.00557 -3.225 +9.16933 -2.74002 +9.30329 -2.24612 +9.40673 -1.74486 +9.47905 -1.23781 +9.51972 -0.726617 +9.52828 -0.212968 +9.50443 0.301415 +9.44792 0.814771 +9.35864 1.32531 +9.2366 1.83122 +9.0819 2.33066 +8.89479 2.8218 +8.67565 3.30278 +8.42497 3.77176 +8.14339 4.22692 +7.83168 4.66644 +7.49074 5.08855 +7.12163 5.49152 +6.7255 5.87366 +6.30368 6.23335 +5.85761 6.56904 +5.38885 6.87926 +4.89908 7.16264 +4.39011 7.4179 +3.86384 7.64387 +3.32228 7.83951 +2.7675 8.00389 +2.20167 8.13624 +1.62702 8.23591 +1.04581 8.30241 +0.460366 8.33542 +-0.126975 8.33476 +-0.713853 8.30043 +-1.2979 8.23258 +-1.87678 8.13151 +-2.44815 7.99769 +-3.00974 7.83172 +-3.55931 7.63435 +-4.09471 7.40649 +-4.61386 7.14915 +-5.11477 6.86348 +-5.59555 6.55077 +-6.05442 6.21237 +-6.48973 5.84976 +-6.89993 5.46451 +-7.28364 5.05826 +-7.63956 4.6327 +-7.96658 4.18961 +-8.26369 3.73078 +-8.53005 3.25806 +-8.76492 2.77332 +-8.96775 2.27844 +-9.13807 1.77531 +-9.27559 1.2658 +-9.38012 0.751795 +-9.45162 0.235146 +-9.49014 -0.282319 +-9.49588 -0.798804 +-9.46913 -1.31255 +-9.41029 -1.82185 +-9.31987 -2.32502 +-9.19845 -2.82046 +-9.04674 -3.30661 +-8.8655 -3.78196 +-8.65558 -4.24507 +-8.4179 -4.69456 +-8.15346 -5.12913 +-7.8633 -5.54752 +-7.54854 -5.94855 +-7.21035 -6.33112 +-6.84993 -6.69417 +-6.46854 -7.03674 +-6.06749 -7.35791 +-5.64809 -7.65685 +-5.21173 -7.93279 +-4.7598 -8.18503 +-4.29371 -8.41295 +-3.81491 -8.61597 +-3.32487 -8.79361 +-2.82507 -8.94544 +-2.317 -9.07109 +-1.80216 -9.17028 +-1.28208 -9.24278 +-0.758273 -9.28843 +-0.232265 -9.30713 +0.294417 -9.29886 +0.820243 -9.26366 +1.34369 -9.20161 +1.86324 -9.1129 +2.37737 -8.99776 +2.88459 -8.85647 +3.3834 -8.68941 +3.87232 -8.497 +4.34989 -8.27972 +4.81467 -8.03814 +5.26524 -7.77288 +5.70019 -7.48462 +6.11815 -7.17411 +6.51779 -6.84215 +6.89778 -6.48963 +7.25687 -6.11748 +7.59383 -5.7267 +7.90747 -5.31837 +8.19666 -4.8936 +8.46033 -4.45359 +8.69746 -3.9996 +8.90711 -3.53295 +9.08837 -3.05503 +9.24043 -2.56727 +9.36254 -2.07118 +9.45403 -1.56831 +9.51432 -1.06025 +9.54291 -0.548656 +9.53939 -0.0352165 +9.50347 0.47834 +9.43496 0.99025 +9.33377 1.49872 +9.19993 2.00195 +9.03359 2.49809 +8.83504 2.9853 +8.60467 3.46176 +8.34303 3.92561 +8.05077 4.37505 +7.72871 4.80827 +7.37778 5.22352 +6.99906 5.61907 +6.59377 5.99327 +6.16323 6.3445 +5.70893 6.67125 +5.23246 6.97208 +4.73554 7.24564 +4.22001 7.4907 +3.68779 7.70612 +3.14092 7.8909 +2.58152 8.04418 +2.01178 8.16523 +1.43396 8.25344 +0.850357 8.3084 +0.263325 8.32981 +-0.324772 8.31755 +-0.911559 8.27166 +-1.49466 8.19231 +-2.07174 8.07987 +-2.64046 7.93483 +-3.19856 7.75784 +-3.74383 7.54971 +-4.27414 7.31137 +-4.78743 7.0439 +-5.28175 6.74848 +-5.75524 6.42643 +-6.20617 6.07916 +-6.63292 5.70818 +-7.034 5.31509 +-7.40806 4.90156 +-7.75387 4.46931 +-8.07035 4.02015 +-8.35655 3.55588 +-8.61168 3.07838 +-8.83506 2.58951 +-9.02618 2.09117 +-9.18463 1.58526 +-9.31016 1.07366 +-9.40265 0.55824 +-9.46208 0.0408572 +-9.48857 -0.476667 +-9.48236 -0.992543 +-9.44377 -1.50502 +-9.37326 -2.0124 +-9.27136 -2.51303 +-9.1387 -3.00529 +-8.976 -3.48766 +-8.78407 -3.95863 +-8.56378 -4.41679 +-8.31606 -4.86078 +-8.04194 -5.28929 +-7.74247 -5.70112 +-7.41878 -6.0951 +-7.07204 -6.47015 +-6.70349 -6.82525 +-6.3144 -7.15947 +-5.90609 -7.47194 +-5.4799 -7.76185 +-5.03722 -8.02846 +-4.57947 -8.2711 +-4.10809 -8.48917 +-3.62453 -8.68213 +-3.13026 -8.84951 +-2.6268 -8.99091 +-2.11562 -9.10598 +-1.59826 -9.19447 +-1.07624 -9.25615 +-0.551086 -9.2909 +-0.0243262 -9.29864 +0.502502 -9.27937 +1.02787 -9.23313 +1.55024 -9.16007 +2.0681 -9.06036 +2.57993 -8.93425 +3.08422 -8.78208 +3.57949 -8.60423 +4.06424 -8.40114 +4.53704 -8.17333 +4.99642 -7.92139 +5.44099 -7.64597 +5.86934 -7.34777 +6.28011 -7.02758 +6.67198 -6.68624 +7.04364 -6.32466 +7.39385 -5.94382 +7.72138 -5.54476 +8.02507 -5.12858 +8.30381 -4.69646 +8.55652 -4.24962 +8.78221 -3.78936 +8.97993 -3.31704 +9.14881 -2.83407 +9.28806 -2.34191 +9.39696 -1.8421 +9.47486 -1.33622 +9.52122 -0.825879 +9.53559 -0.312765 +9.51761 0.201412 +9.46704 0.714902 +9.38372 1.22592 +9.26763 1.73266 +9.11887 2.2333 +8.93766 2.72599 +8.72433 3.20889 +8.47935 3.68015 +8.20334 4.13793 +7.89703 4.58044 +7.5613 5.00588 +7.19717 5.41251 +6.80578 5.79863 +6.38841 6.16262 +5.94649 6.50289 +5.48154 6.81797 +4.99525 7.10647 +4.48938 7.36708 +3.96583 7.59862 +3.42659 7.80002 +2.87374 7.97033 +2.30943 8.10876 +1.7359 8.21462 +1.15541 8.28739 +0.570299 8.3267 +-0.0170975 8.33233 +-0.60442 8.30423 +-1.18931 8.24251 +-1.76942 8.14744 +-2.34242 8.01945 +-2.90603 7.85913 +-3.45801 7.66721 +-3.99618 7.44457 +-4.51846 7.1922 +-5.02282 6.91126 +-5.50737 6.60299 +-5.97029 6.26875 +-6.40991 5.91001 +-6.82467 5.52831 +-7.21313 5.12529 +-7.574 4.70265 +-7.90611 4.26215 +-8.20845 3.80558 +-8.48013 3.3348 +-8.72042 2.85167 +-8.9287 2.35807 +-9.10452 1.85589 +-9.24755 1.34703 +-9.35757 0.83337 +-9.43453 0.316763 +-9.47847 -0.200949 +-9.48956 -0.717961 +-9.46807 -1.23251 +-9.41441 -1.74286 +-9.32904 -2.24734 +-9.21258 -2.74433 +-9.06568 -3.23224 +-8.88911 -3.70958 +-8.68371 -4.17489 +-8.4504 -4.62677 +-8.19016 -5.06391 +-7.90403 -5.48505 +-7.59313 -5.889 +-7.2586 -6.27463 +-6.90167 -6.64089 +-6.52357 -6.9868 +-6.12561 -7.31144 +-5.70912 -7.61397 +-5.27545 -7.89361 +-4.826 -8.14966 +-4.36219 -8.38146 +-3.88546 -8.58847 +-3.39727 -8.77016 +-2.8991 -8.92611 +-2.39243 -9.05595 +-1.87878 -9.15938 +-1.35965 -9.23616 +-0.836568 -9.28613 +-0.311048 -9.30919 +0.215381 -9.30529 +0.741195 -9.27447 +1.26487 -9.21681 +1.78489 -9.13249 +2.29975 -9.02171 +2.80794 -8.88477 +3.30797 -8.72202 +3.79837 -8.53388 +4.27768 -8.32082 +4.74446 -8.0834 +5.19728 -7.82222 +5.63475 -7.53796 +6.05549 -7.23135 +6.45817 -6.90321 +6.84148 -6.55438 +7.20413 -6.18582 +7.54491 -5.79849 +7.86261 -5.39347 +8.15609 -4.97187 +8.42426 -4.53485 +8.6661 -4.08366 +8.88063 -3.61961 +9.06696 -3.14404 +9.22425 -2.65839 +9.35175 -2.16413 +9.44878 -1.6628 +9.51475 -1.15598 +9.54914 -0.645309 +9.55155 -0.132466 +9.52165 0.380833 +9.45923 0.892836 +9.36418 1.40176 +9.23651 1.9058 +9.07635 2.40313 +8.88395 2.89192 +8.65968 3.37032 +8.40406 3.83651 +8.11771 4.28866 +7.80142 4.72498 +7.45609 5.14369 +7.08277 5.54307 +6.68263 5.92145 +6.25699 6.2772 +5.80729 6.6088 +5.3351 6.91478 +4.84212 7.19377 +4.33013 7.44452 +3.80107 7.66586 +3.25694 7.85678 +2.69984 8.01637 +2.13194 8.14387 +1.55549 8.23866 +0.972788 8.30027 +0.386171 8.32838 +-0.201999 8.32283 +-0.789345 8.28361 +-1.37349 8.21089 +-1.95208 8.10498 +-2.52279 7.96634 +-3.08333 7.7956 +-3.63148 7.59353 +-4.16508 7.36103 +-4.68205 7.09914 +-5.18043 6.80905 +-5.65834 6.49204 +-6.114 6.14949 +-6.54578 5.78291 +-6.95215 5.39387 +-7.33173 4.98403 +-7.68327 4.55511 +-8.00565 4.1089 +-8.2979 3.6472 +-8.55919 3.17189 +-8.78882 2.68483 +-8.98623 2.18792 +-9.15102 1.68306 +-9.28289 1.17213 +-9.3817 0.657028 +-9.4474 0.139597 +-9.48011 -0.378324 +-9.48002 -0.894938 +-9.44746 -1.40848 +-9.38285 -1.91725 +-9.28672 -2.41956 +-9.15969 -2.91382 +-9.00247 -3.39845 +-8.81586 -3.87196 +-8.60071 -4.33292 +-8.35796 -4.77995 +-8.08863 -5.21174 +-7.79377 -5.62705 +-7.47451 -6.0247 +-7.13202 -6.4036 +-6.7675 -6.7627 +-6.38223 -7.10106 +-5.9775 -7.41777 +-5.55466 -7.71204 +-5.11508 -7.9831 +-4.66016 -8.23029 +-4.19135 -8.45299 +-3.71009 -8.65067 +-3.21787 -8.82285 +-2.71616 -8.96911 +-2.20648 -9.08912 +-1.69034 -9.18259 +-1.16926 -9.24932 +-0.644768 -9.28914 +-0.118395 -9.30199 +0.408328 -9.28785 +0.93387 -9.24676 +1.4567 -9.17884 +1.97531 -9.08427 +2.48817 -8.96329 +2.99378 -8.81621 +3.49065 -8.6434 +3.97731 -8.44531 +4.45229 -8.22244 +4.91416 -7.97535 +5.36149 -7.70469 +5.7929 -7.41115 +6.20702 -7.09549 +6.60252 -6.75856 +6.97809 -6.40123 +7.33249 -6.02448 +7.66448 -5.62933 +7.97291 -5.21687 +8.25663 -4.78824 +8.51459 -4.34468 +8.74577 -3.88745 +8.94921 -3.41789 +9.12404 -2.9374 +9.26944 -2.44743 +9.38468 -1.94949 +9.4691 -1.44515 +9.52213 -0.936016 +9.54331 -0.423744 +9.53225 0.0899632 +9.48868 0.60337 +9.41243 1.1147 +9.30346 1.62217 +9.16182 2.12394 +8.98769 2.61819 +8.7814 3.10308 +8.54337 3.57675 +8.27418 4.03739 +7.97453 4.48317 +7.64527 4.9123 +7.28737 5.32304 +6.90195 5.71367 +6.49026 6.08255 +6.05367 6.4281 +5.5937 6.74881 +5.11197 7.04325 +4.61024 7.31012 +4.09038 7.54821 +3.55435 7.7564 +3.0042 7.93374 +2.44209 8.07938 +1.87022 8.19262 +1.29088 8.27291 +0.706379 8.31984 +0.119072 8.33315 +-0.468672 8.31275 +-1.05448 8.25868 +-1.636 8.17118 +-2.2109 8.05061 +-2.77688 7.89751 +-3.3317 7.71259 +-3.87318 7.49667 +-4.3992 7.25075 +-4.90774 6.97592 +-5.39687 6.67342 +-5.86476 6.3446 +-6.30969 5.99089 +-6.73008 5.61384 +-7.12445 5.21506 +-7.49148 4.79625 +-7.82998 4.35915 +-8.13888 3.90556 +-8.41727 3.43733 +-8.66438 2.95631 +-8.87956 2.4644 +-9.06233 1.9635 +-9.21232 1.4555 +-9.32931 0.942284 +-9.41318 0.425733 +-9.46398 -0.0923083 +-9.48183 -0.61002 +-9.467 -1.12562 +-9.41986 -1.63737 +-9.34088 -2.14358 +-9.23062 -2.6426 +-9.08975 -3.13285 +-8.91902 -3.6128 +-8.71926 -4.08097 +-8.49137 -4.53598 +-8.23632 -4.97647 +-7.95516 -5.40117 +-7.64898 -5.80889 +-7.31893 -6.19847 +-6.96622 -6.56886 +-6.59211 -6.91906 +-6.19787 -7.24813 +-5.78483 -7.55523 +-5.35436 -7.83955 +-4.90784 -8.10039 +-4.4467 -8.3371 +-3.97236 -8.54908 +-3.4863 -8.73584 +-2.98998 -8.89692 +-2.4849 -9.03195 +-1.97256 -9.14061 +-1.45447 -9.22267 +-0.932143 -9.27795 +-0.407106 -9.30633 +0.119119 -9.30776 +0.645008 -9.28228 +1.16904 -9.22995 +1.6897 -9.15094 +2.20548 -9.04545 +2.71488 -8.91375 +3.21641 -8.7562 +3.70859 -8.5732 +4.18998 -8.36522 +4.65912 -8.13279 +5.11459 -7.87652 +5.55501 -7.59705 +5.979 -7.29513 +6.38522 -6.97155 +6.77236 -6.62714 +7.13915 -6.26284 +7.48435 -5.87963 +7.80676 -5.47854 +8.10524 -5.06069 +8.37869 -4.62723 +8.62606 -4.17939 +8.84637 -3.71846 +9.03869 -3.24577 +9.20219 -2.76272 +9.33608 -2.27077 +9.43968 -1.77143 +9.51238 -1.26625 +9.55365 -0.756871 +9.56307 -0.244937 +9.54029 0.267847 +9.48509 0.779744 +9.39733 1.28898 +9.277 1.79377 +9.1242 2.29229 +8.93914 2.78271 +8.72217 3.26321 +8.47376 3.73195 +8.19452 4.18711 +7.88518 4.6269 +7.54661 5.04953 +7.17982 5.45328 +6.78595 5.83645 +6.36628 6.19742 +5.92221 6.53464 +5.45527 6.84661 +4.96712 7.13196 +4.45954 7.38939 +3.9344 7.61772 +3.3937 7.81588 +2.83949 7.98295 +2.27395 8.11812 +1.69929 8.22072 +1.1178 8.29026 +0.531808 8.32637 +-0.0563274 8.32884 +-0.644231 8.29763 +-1.22953 8.23286 +-1.80985 8.13479 +-2.38286 8.00386 +-2.94625 7.84064 +-3.49779 7.64586 +-4.0353 7.4204 +-4.55667 7.16527 +-5.0599 6.88161 +-5.54309 6.57068 +-6.00443 6.23384 +-6.44224 5.87257 +-6.85498 5.48843 +-7.24121 5.08306 +-7.59965 4.65817 +-7.92915 4.21553 +-8.22869 3.75696 +-8.49741 3.28431 +-8.73458 2.79945 +-8.9396 2.30428 +-9.11203 1.80071 +-9.25155 1.29063 +-9.35798 0.775926 +-9.43125 0.258472 +-9.47144 -0.25989 +-9.47873 -0.777348 +-9.45342 -1.29213 +-9.39592 -1.80251 +-9.30672 -2.30679 +-9.18644 -2.80337 +-9.03577 -3.29065 +-8.85549 -3.76713 +-8.64646 -4.23136 +-8.4096 -4.68195 +-8.14592 -5.11756 +-7.85647 -5.53695 +-7.54238 -5.93893 +-7.20481 -6.32237 +-6.84497 -6.68623 +-6.46412 -7.02951 +-6.06356 -7.35131 +-5.64463 -7.6508 +-5.20868 -7.92721 +-4.7571 -8.17984 +-4.29133 -8.40809 +-3.81281 -8.61138 +-3.32301 -8.78925 +-2.82342 -8.94128 +-2.31553 -9.0671 +-1.80086 -9.16645 +-1.28093 -9.2391 +-0.757271 -9.28488 +-0.231404 -9.30372 +0.295136 -9.29558 +0.820822 -9.2605 +1.34413 -9.19859 +1.86353 -9.11001 +2.37752 -8.995 +2.88459 -8.85385 +3.38325 -8.68693 +3.87203 -8.49465 +4.34947 -8.27752 +4.81412 -8.03608 +5.26457 -7.77096 +5.69943 -7.48284 +6.11733 -7.17248 +6.51692 -6.84067 +6.89693 -6.48831 +7.25607 -6.11634 +7.59312 -5.72577 +7.90691 -5.31766 +8.1963 -4.89315 +8.46021 -4.45344 +8.69763 -3.99979 +8.90758 -3.53351 +9.08917 -3.05599 +9.24158 -2.56866 +9.36405 -2.07301 +9.45591 -1.57058 +9.51657 -1.06297 +9.54553 -0.551819 +9.54241 -0.0388096 +9.50688 0.474335 +9.43877 0.985858 +9.33797 1.49397 +9.20454 1.99687 +9.03861 2.49273 +8.84046 2.97971 +8.61049 3.45597 +8.34924 3.91969 +8.05737 4.36904 +7.73569 4.80223 +7.38512 5.2175 +7.00674 5.61314 +6.60176 5.98748 +6.17152 6.33892 +5.71749 6.66593 +5.24126 6.96708 +4.74456 7.24101 +4.2292 7.48648 +3.69713 7.70237 +3.15039 7.88766 +2.59108 8.04148 +2.02141 8.1631 +1.44363 8.25192 +0.860063 8.30749 +0.273049 8.32952 +-0.315037 8.31787 +-0.901813 8.27255 +-1.4849 8.19375 +-2.06196 8.08179 +-2.63065 7.93714 +-3.18873 7.76046 +-3.73398 7.55251 +-4.26428 7.31425 +-4.77758 7.04672 +-5.27193 6.75115 +-5.74548 6.42883 +-6.19648 6.08119 +-6.6233 5.70976 +-7.02446 5.31613 +-7.39858 4.90198 +-7.74443 4.46905 +-8.06091 4.01913 +-8.34706 3.55407 +-8.60208 3.07571 +-8.82528 2.58597 +-9.01614 2.08672 +-9.17426 1.57988 +-9.29936 1.06735 +-9.39132 0.551004 +-9.45013 0.0327077 +-9.4759 -0.485707 +-9.46887 -1.00244 +-9.42937 -1.51574 +-9.35786 -2.0239 +-9.25488 -2.52524 +-9.12108 -3.01818 +-8.95718 -3.50115 +-8.764 -3.97268 +-8.54242 -4.43133 +-8.29342 -4.87575 +-8.01802 -5.30464 +-7.71731 -5.71679 +-7.39244 -6.11103 +-7.0446 -6.48628 +-6.67503 -6.84153 +-6.28502 -7.17583 +-5.8759 -7.48831 +-5.44903 -7.77815 +-5.00578 -8.04463 +-4.54758 -8.28708 +-4.07587 -8.50491 +-3.5921 -8.69759 +-3.09775 -8.86466 +-2.59431 -9.00572 +-2.08328 -9.12047 +-1.56618 -9.20864 +-1.04452 -9.27005 +-0.519827 -9.30456 +0.00637733 -9.31212 +0.532568 -9.29275 +1.05722 -9.24651 +1.57883 -9.17354 +2.09587 -9.07404 +2.60684 -8.94828 +3.11027 -8.79659 +3.60467 -8.61937 +4.08858 -8.41706 +4.56056 -8.19021 +5.01919 -7.93939 +5.46307 -7.66525 +5.89084 -7.36851 +6.30115 -7.04995 +6.69268 -6.7104 +7.06417 -6.35078 +7.41437 -5.97205 +7.74209 -5.57523 +8.04617 -5.16143 +8.32552 -4.7318 +8.57907 -4.28754 +8.80583 -3.82993 +9.00487 -3.3603 +9.17532 -2.88003 +9.31639 -2.39056 +9.42736 -1.89338 +9.50759 -1.39002 +9.55655 -0.882084 +9.5738 -0.371204 +9.55896 0.140936 +9.5118 0.652617 +9.43217 1.16208 +9.32001 1.66756 +9.17541 2.16723 +8.99854 2.6593 +8.78974 3.14192 +8.54943 3.61328 +8.27818 4.07156 +7.97669 4.51496 +7.64579 4.9417 +7.28645 5.35005 +6.89977 5.7383 +6.48698 6.10483 +6.04945 6.44805 +5.58867 6.76648 +5.10626 7.05868 +4.60395 7.32335 +4.0836 7.55928 +3.54714 7.76538 +2.99662 7.94066 +2.43418 8.08429 +1.86201 8.19557 +1.28238 8.27394 +0.697598 8.319 +0.110014 8.3305 +-0.478004 8.30834 +-1.06408 8.25259 +-1.64585 8.16348 +-2.22096 8.04138 +-2.7871 7.88682 +-3.34201 7.7005 +-3.8835 7.48324 +-4.40943 7.23601 +-4.91778 6.95991 +-5.40659 6.65617 +-5.87405 6.32612 +-6.31843 5.97121 +-6.73814 5.59297 +-7.13171 5.19302 +-7.49782 4.77305 +-7.83526 4.33483 +-8.14298 3.88015 +-8.42008 3.41085 +-8.66577 2.92882 +-8.87943 2.43595 +-9.06056 1.93413 +-9.20881 1.42528 +-9.32396 0.911296 +-9.40591 0.394049 +-9.4547 -0.124602 +-9.47047 -0.64283 +-9.45351 -1.15885 +-9.40418 -1.67091 +-9.32296 -2.17731 +-9.21045 -2.67642 +-9.0673 -3.16662 +-8.89429 -3.6464 +-8.69226 -4.11427 +-8.46212 -4.56884 +-8.20485 -5.00876 +-7.92152 -5.43274 +-7.61323 -5.83959 +-7.28114 -6.22816 +-6.92648 -6.59738 +-6.55048 -6.94626 +-6.15446 -7.27386 +-5.73974 -7.57932 +-5.30769 -7.86185 +-4.8597 -8.12073 +-4.39717 -8.35532 +-3.92156 -8.56506 +-3.43432 -8.74943 +-2.93694 -8.90801 +-2.4309 -9.04043 +-1.91772 -9.14641 +-1.39892 -9.22571 +-0.876023 -9.27817 +-0.35056 -9.30368 +0.175937 -9.30222 +0.70194 -9.27381 +1.22592 -9.21854 +1.74636 -9.13656 +2.26174 -9.02811 +2.77056 -8.89347 +3.27133 -8.73298 +3.76257 -8.54705 +4.24282 -8.33617 +4.71064 -8.10088 +5.16461 -7.84179 +5.60333 -7.55955 +6.02544 -7.25492 +6.42959 -6.92868 +6.81449 -6.5817 +7.17886 -6.21491 +7.52148 -5.8293 +7.84116 -5.42591 +8.13676 -5.00588 +8.40719 -4.57037 +8.65142 -4.12062 +8.86848 -3.65794 +9.05745 -3.18368 +9.2175 -2.69926 +9.34787 -2.20615 +9.44785 -1.70588 +9.51684 -1.20001 +9.55433 -0.690172 +9.55988 -0.17803 +9.53318 0.334713 +9.474 0.846314 +9.38221 1.355 +9.25783 1.85899 +9.10096 2.35645 +8.91185 2.84556 +8.69085 3.3245 +8.43845 3.79143 +8.15529 4.24454 +7.84211 4.68203 +7.49981 5.10213 +7.12941 5.50313 +6.73208 5.88334 +6.30911 6.24115 +5.86193 6.57501 +5.39208 6.88345 +4.90125 7.1651 +4.39121 7.41869 +3.86388 7.64304 +3.32125 7.83711 +2.76541 8 +2.19853 8.1309 +1.62285 8.22919 +1.04065 8.29438 +0.454289 8.32612 +-0.13388 8.32423 +-0.721473 8.28868 +-1.30611 8.21959 +-1.88541 8.11726 +-2.45705 7.98212 +-3.01872 7.81475 +-3.56819 7.61589 +-4.1033 7.38642 +-4.62195 7.12734 +-5.12217 6.83981 +-5.60207 6.5251 +-6.05987 6.1846 +-6.49393 5.81978 +-6.90271 5.43224 +-7.2848 5.02364 +-7.63892 4.59569 +-7.96394 4.15019 +-8.25886 3.68896 +-8.52282 3.21387 +-8.75511 2.7268 +-8.95514 2.22967 +-9.12247 1.72437 +-9.2568 1.21283 +-9.35795 0.696927 +-9.42589 0.178541 +-9.46069 -0.340478 +-9.46255 -0.858315 +-9.43178 -1.3732 +-9.3688 -1.88339 +-9.27414 -2.38721 +-9.14841 -2.88303 +-8.99232 -3.36929 +-8.80667 -3.84446 +-8.59234 -4.30711 +-8.35027 -4.75585 +-8.08147 -5.18937 +-7.78703 -5.60642 +-7.46808 -6.00582 +-7.12582 -6.38647 +-6.76148 -6.74732 +-6.37634 -7.08742 +-5.97172 -7.40587 +-5.54898 -7.70185 +-5.1095 -7.9746 +-4.65471 -8.22344 +-4.18602 -8.44776 +-3.70492 -8.64702 +-3.21287 -8.82073 +-2.71136 -8.96851 +-2.2019 -9.09001 +-1.686 -9.18495 +-1.16518 -9.25315 +-0.640968 -9.29445 +-0.114887 -9.3088 +0.411535 -9.29619 +0.936776 -9.25667 +1.45932 -9.19037 +1.97765 -9.09749 +2.49026 -8.97827 +2.99567 -8.83304 +3.49239 -8.66218 +3.97897 -8.46613 +4.45395 -8.2454 +4.91593 -8.00058 +5.36349 -7.73229 +5.79527 -7.44124 +6.20992 -7.12819 +6.60612 -6.79397 +6.98259 -6.43947 +7.3381 -6.06564 +7.67145 -5.6735 +7.98147 -5.26412 +8.26705 -4.83865 +8.52715 -4.39828 +8.76075 -3.94427 +8.96692 -3.47794 +9.14476 -3.00065 +9.29348 -2.51384 +9.41234 -2.01897 +9.50067 -1.51757 +9.55791 -1.01122 +9.58357 -0.501524 +9.57729 0.0098532 +9.53877 0.521216 +9.46786 1.03083 +9.36447 1.53693 +9.22866 2.03773 +9.06059 2.53143 +8.86054 3.01621 +8.62891 3.49025 +8.36624 3.95174 +8.07318 4.39888 +7.75052 4.82989 +7.3992 5.24304 +7.02027 5.63662 +6.61491 6.00897 +6.18446 6.35851 +5.73036 6.68372 +5.25419 6.98316 +4.75763 7.25549 +4.24251 7.49948 +3.71072 7.71398 +3.16429 7.89799 +2.60531 8.05064 +2.03596 8.17117 +1.45847 8.25898 +0.87514 8.31363 +0.288305 8.3348 +-0.299676 8.32237 +-0.886433 8.27634 +-1.46959 8.19687 +-2.04681 8.08431 +-2.61575 7.93914 +-3.17415 7.76199 +-3.71978 7.55364 +-4.25049 7.31502 +-4.76423 7.04719 +-5.259 6.75133 +-5.73296 6.42874 +-6.18433 6.08083 +-6.61149 5.70911 +-7.01293 5.31518 +-7.38726 4.90071 +-7.73326 4.46742 +-8.04981 4.01713 +-8.33596 3.55165 +-8.59089 3.07286 +-8.81392 2.58266 +-9.00452 2.08294 +-9.16228 1.57562 +-9.28694 1.06259 +-9.37838 0.545751 +-9.43658 0.0269674 +-9.46165 -0.491921 +-9.45385 -1.00911 +-9.4135 -1.52283 +-9.34107 -2.03138 +-9.23711 -2.53307 +-9.10227 -3.0263 +-8.93728 -3.50951 +-8.74297 -3.98121 +-8.52025 -4.43997 +-8.27007 -4.88442 +-7.99349 -5.31327 +-7.69159 -5.72528 +-7.36554 -6.1193 +-7.01655 -6.49424 +-6.64586 -6.84907 +-6.25477 -7.18284 +-5.84462 -7.49468 +-5.41676 -7.78377 +-4.97259 -8.04938 +-4.51353 -8.29084 +-4.04101 -8.50754 +-3.55651 -8.69897 +-3.06148 -8.86466 +-2.55742 -9.00424 +-2.04584 -9.11739 +-1.52825 -9.20387 +-1.00617 -9.26351 +-0.481127 -9.2962 +0.0453362 -9.30188 +0.571693 -9.28058 +1.09642 -9.23237 +1.61798 -9.15742 +2.13487 -9.05591 +2.64557 -8.92813 +3.1486 -8.77442 +3.64247 -8.59517 +4.12572 -8.39085 +4.59691 -8.16198 +5.0546 -7.90917 +5.49741 -7.63306 +5.92396 -7.33438 +6.3329 -7.01391 +6.72293 -6.67249 +7.09278 -6.31105 +7.44119 -5.93054 +7.76699 -5.53202 +8.06903 -5.11658 +8.34621 -4.68538 +8.59749 -4.23964 +8.82188 -3.78064 +9.01846 -3.30973 +9.18637 -2.82831 +9.32484 -2.33781 +9.43316 -1.83976 +9.51069 -1.33571 +9.55691 -0.827256 +9.57135 -0.316052 +9.55368 0.196216 +9.50364 0.707821 +9.42109 1.21701 +9.30598 1.72199 +9.15842 2.22098 +8.97859 2.71214 +8.76682 3.19367 +8.52356 3.66373 +8.2494 4.12051 +7.94505 4.56223 +7.61136 4.9871 +7.24931 5.3934 +6.86001 5.77944 +6.44472 6.14359 +6.00482 6.48428 +5.5418 6.80003 +5.05731 7.08944 +4.55309 7.35119 +4.031 7.58411 +3.493 7.78709 +2.94115 7.95919 +2.37759 8.09959 +1.80452 8.20759 +1.22422 8.28266 +0.639013 8.32441 +0.051245 8.3326 +-0.536707 8.30716 +-1.12246 8.24817 +-1.70365 8.15586 +-2.27792 8.03062 +-2.84295 7.87301 +-3.3965 7.6837 +-3.93634 7.46353 +-4.46037 7.21347 +-4.96656 6.93462 +-5.45297 6.62819 +-5.91778 6.29552 +-6.35931 5.93806 +-6.77598 5.55734 +-7.16634 5.155 +-7.52908 4.73275 +-7.86303 4.29233 +-8.16714 3.83559 +-8.44051 3.36437 +-8.68237 2.88055 +-8.89211 2.38605 +-9.06925 1.88278 +-9.21342 1.37264 +-9.32441 0.857548 +-9.40214 0.339388 +-9.44665 -0.179977 +-9.4581 -0.698716 +-9.43676 -1.21503 +-9.38302 -1.72718 +-9.29738 -2.23345 +-9.18042 -2.73219 +-9.03283 -3.2218 +-8.85538 -3.70076 +-8.64892 -4.16759 +-8.41439 -4.62089 +-8.15279 -5.0593 +-7.86517 -5.48156 +-7.55267 -5.88647 +-7.21647 -6.27289 +-6.85779 -6.63977 +-6.47791 -6.98611 +-6.07815 -7.31099 +-5.65986 -7.61358 +-5.22442 -7.89309 +-4.77325 -8.14882 +-4.30778 -8.38014 +-3.82948 -8.58649 +-3.33983 -8.76737 +-2.84031 -8.92236 +-2.33244 -9.05111 +-1.81773 -9.15332 +-1.29771 -9.22879 +-0.773901 -9.27736 +-0.247838 -9.29894 +0.278949 -9.29352 +0.804931 -9.26115 +1.32859 -9.20192 +1.8484 -9.11603 +2.36286 -9.00372 +2.87047 -8.86528 +3.36975 -8.7011 +3.85924 -8.5116 +4.33748 -8.29728 +4.80304 -8.05871 +5.25453 -7.7965 +5.69057 -7.51136 +6.1098 -7.20402 +6.5109 -6.87531 +6.8926 -6.5261 +7.25364 -6.15733 +7.59282 -5.77001 +7.90897 -5.36519 +8.20098 -4.944 +8.46779 -4.50763 +8.70838 -4.05732 +8.92181 -3.59437 +9.10719 -3.12014 +9.26369 -2.63603 +9.39057 -2.14353 +9.48716 -1.64413 +9.55285 -1.1394 +9.58715 -0.630943 +9.58964 -0.120401 +9.56001 0.390545 +9.49807 0.900186 +9.4037 1.40678 +9.27694 1.90855 +9.11791 2.40372 +8.92686 2.89047 +8.70418 3.36702 +8.45035 3.83154 +8.16601 4.28225 +7.8519 4.71737 +7.50891 5.13516 +7.13805 5.53391 +6.74048 5.91195 +6.31746 6.2677 +5.87042 6.5996 +5.40087 6.90622 +4.91048 7.18618 +4.401 7.43821 +3.87431 7.66114 +3.33239 7.85395 +2.77729 8.0157 +2.21116 8.1456 +1.63622 8.24303 +1.05473 8.30746 +0.46902 8.33855 +-0.118575 8.33611 +-0.705688 8.3001 +-1.28995 8.23062 +-1.86901 8.12797 +-2.44054 7.99256 +-3.00224 7.82499 +-3.55187 7.62598 +-4.08727 7.3964 +-4.60635 7.13728 +-5.10708 6.84975 +-5.58758 6.53508 +-6.04604 6.19462 +-6.48079 5.82987 +-6.89027 5.44239 +-7.27307 5.03381 +-7.62788 4.60587 +-7.95356 4.16033 +-8.24911 3.69902 +-8.51365 3.2238 +-8.74645 2.73655 +-8.94694 2.23918 +-9.11466 1.7336 +-9.24931 1.22172 +-9.35071 0.705441 +-9.41881 0.18664 +-9.45368 -0.332827 +-9.45553 -0.85114 +-9.42467 -1.36652 +-9.36151 -1.87721 +-9.26659 -2.38155 +-9.14052 -2.87789 +-8.98402 -3.36464 +-8.79788 -3.8403 +-8.583 -4.30341 +-8.34032 -4.75258 +-8.07087 -5.18649 +-7.77573 -5.60388 +-7.45605 -6.00357 +-7.11303 -6.38445 +-6.74792 -6.74548 +-6.362 -7.08568 +-5.95661 -7.40415 +-5.53311 -7.70007 +-5.09289 -7.97267 +-4.63739 -8.22127 +-4.16803 -8.44524 +-3.68629 -8.64404 +-3.19365 -8.81719 +-2.69159 -8.96428 +-2.18163 -9.08497 +-1.66526 -9.179 +-1.14402 -9.24617 +-0.619425 -9.28636 +-0.0930099 -9.29951 +0.433694 -9.28562 +0.959157 -9.24478 +1.48185 -9.1771 +2.00026 -9.0828 +2.51287 -8.96213 +3.01818 -8.81543 +3.51472 -8.64307 +4.001 -8.44552 +4.47559 -8.22328 +4.93706 -7.97694 +5.38399 -7.70715 +5.81502 -7.4146 +6.22879 -7.10007 +6.624 -6.76439 +6.99935 -6.40846 +7.35361 -6.03323 +7.68558 -5.63974 +7.9941 -5.22905 +8.27807 -4.80232 +8.53643 -4.36075 +8.7682 -3.90561 +8.97242 -3.43822 +9.14825 -2.95995 +9.29487 -2.47225 +9.41157 -1.9766 +9.4977 -1.47454 +9.55271 -0.967658 +9.57612 -0.457581 +9.56755 0.0540176 +9.52674 0.565428 +9.45351 1.07491 +9.34779 1.5807 +9.20964 2.081 +9.03923 2.574 +8.83684 3.0579 +8.60288 3.53089 +8.33791 3.99114 +8.04258 4.43687 +7.71771 4.8663 +7.36424 5.27771 +6.98323 5.66939 +6.57589 6.0397 +6.14355 6.38707 +5.68768 6.70997 +5.20986 7.007 +4.71179 7.27682 +4.1953 7.5182 +3.6623 7.73002 +3.11482 7.91129 +2.55495 8.06113 +1.9849 8.17883 +1.40689 8.2638 +0.823228 8.31559 +0.236255 8.33392 +-0.351667 8.31866 +-0.938165 8.26984 +-1.52087 8.18764 +-2.09742 8.07241 +-2.66549 7.92464 +-3.22281 7.74497 +-3.76716 7.5342 +-4.29638 7.29325 +-4.8084 7.02319 +-5.30126 6.72519 +-5.77308 6.40055 +-6.22212 6.05068 +-6.64674 5.67707 +-7.04545 5.28131 +-7.4169 4.86507 +-7.75986 4.4301 +-8.07326 3.97818 +-8.35613 3.51117 +-8.60769 3.03093 +-8.82727 2.53938 +-9.01433 2.03843 +-9.16849 1.52999 +-9.28948 1.01598 +-9.37719 0.498292 +-9.43159 -0.0211906 +-9.45283 -0.540622 +-9.44113 -1.05819 +-9.39686 -1.57212 +-9.32046 -2.08069 +-9.21251 -2.58223 +-9.07365 -3.07511 +-8.90463 -3.55778 +& +@target G0.S3 +@type xy +8.30994 -16.2836 +8.66186 -16.1431 +9.01042 -15.9963 +9.35548 -15.8433 +9.69693 -15.6842 +10.0346 -15.5191 +10.3685 -15.3479 +10.6983 -15.1709 +11.0241 -14.9881 +11.3456 -14.7995 +11.6628 -14.6053 +11.9756 -14.4055 +12.2838 -14.2002 +12.5873 -13.9896 +12.8861 -13.7736 +13.18 -13.5524 +13.4689 -13.3262 +13.7528 -13.0949 +14.0315 -12.8586 +14.3049 -12.6176 +14.573 -12.3718 +14.8356 -12.1214 +15.0926 -11.8664 +15.344 -11.6071 +15.5897 -11.3434 +15.8296 -11.0755 +16.0636 -10.8034 +16.2917 -10.5274 +16.5137 -10.2474 +16.7296 -9.96372 +16.9393 -9.6763 +17.1428 -9.38532 +17.3399 -9.09087 +17.5306 -8.79307 +17.7149 -8.49203 +17.8927 -8.18787 +18.0639 -7.88069 +18.2284 -7.57063 +18.3863 -7.25778 +18.5374 -6.94228 +18.6817 -6.62423 +18.8192 -6.30375 +18.9498 -5.98097 +19.0734 -5.65599 +19.1901 -5.32895 +19.2997 -4.99997 +19.4024 -4.66915 +19.4979 -4.33663 +19.5863 -4.00253 +19.6675 -3.66696 +19.7416 -3.33006 +19.8085 -2.99195 +19.8681 -2.65274 +19.9205 -2.31257 +19.9656 -1.97155 +20.0035 -1.62981 +20.034 -1.28748 +20.0572 -0.944683 +20.0731 -0.601539 +20.0816 -0.258176 +20.0828 0.085282 +20.0767 0.428709 +20.0632 0.77198 +20.0423 1.11497 +20.0142 1.45755 +19.9787 1.7996 +19.9358 2.14099 +19.8857 2.48159 +19.8282 2.82128 +19.7635 3.15994 +19.6915 3.49744 +19.6122 3.83365 +19.5258 4.16844 +19.4321 4.5017 +19.3312 4.83329 +19.2232 5.1631 +19.1081 5.491 +18.9859 5.81686 +18.8567 6.14057 +18.7204 6.46199 +18.5772 6.78101 +18.4271 7.0975 +18.2701 7.41135 +18.1063 7.72243 +17.9357 8.03062 +17.7583 8.3358 +17.5743 8.63785 +17.3837 8.93665 +17.1866 9.23209 +16.983 9.52404 +16.7729 9.8124 +16.5565 10.097 +16.3338 10.3779 +16.1049 10.6547 +15.8699 10.9275 +15.6288 11.1962 +15.3818 11.4606 +15.1288 11.7205 +14.87 11.976 +14.6056 12.2269 +14.3355 12.473 +14.0598 12.7144 +13.7787 12.9508 +13.4923 13.1822 +13.2006 13.4084 +12.9037 13.6295 +12.6019 13.8452 +12.295 14.0554 +11.9834 14.2602 +11.667 14.4593 +11.346 14.6527 +11.0206 14.8403 +10.6907 15.0221 +10.3566 15.1978 +10.0184 15.3675 +9.67612 15.531 +9.32999 15.6884 +8.98012 15.8394 +8.62662 15.984 +8.26964 16.1222 +7.9093 16.2538 +7.54575 16.3788 +7.17913 16.4971 +6.80957 16.6087 +6.43722 16.7135 +6.06223 16.8114 +5.68473 16.9024 +5.30489 16.9864 +4.92286 17.0633 +4.53877 17.1332 +4.15279 17.1959 +3.76508 17.2514 +3.37579 17.2996 +2.98508 17.3406 +2.59311 17.3743 +2.20004 17.4006 +1.80604 17.4195 +1.41127 17.431 +1.0159 17.435 +0.620089 17.4316 +0.224012 17.4207 +-0.172163 17.4023 +-0.568265 17.3764 +-0.964123 17.3429 +-1.35956 17.3019 +-1.75442 17.2533 +-2.1485 17.1973 +-2.54165 17.1336 +-2.93368 17.0625 +-3.32442 16.9838 +-3.7137 16.8976 +-4.10133 16.804 +-4.48714 16.7029 +-4.87095 16.5943 +-5.25258 16.4783 +-5.63186 16.3549 +-6.00861 16.2242 +-6.38266 16.0861 +-6.75382 15.9408 +-7.12192 15.7883 +-7.4868 15.6286 +-7.84826 15.4618 +-8.20615 15.2879 +-8.56029 15.1071 +-8.9105 14.9193 +-9.25662 14.7247 +-9.59848 14.5232 +-9.93591 14.3151 +-10.2687 14.1003 +-10.5968 13.879 +-10.92 13.6513 +-11.238 13.4172 +-11.5508 13.1768 +-11.8582 12.9302 +-12.1601 12.6776 +-12.4562 12.4191 +-12.7465 12.1547 +-13.0308 11.8846 +-13.3089 11.6088 +-13.5807 11.3276 +-13.8461 11.041 +-14.1049 10.7491 +-14.357 10.4522 +-14.6023 10.1503 +-14.8406 9.84348 +-15.0718 9.53201 +-15.2958 9.21597 +-15.5124 8.89552 +-15.7217 8.57081 +-15.9234 8.24198 +-16.1174 7.90918 +-16.3037 7.57258 +-16.4821 7.23234 +-16.6526 6.88861 +-16.815 6.54155 +-16.9693 6.19133 +-17.1155 5.83813 +-17.2533 5.4821 +-17.3828 5.12341 +-17.5039 4.76225 +-17.6165 4.39879 +-17.7206 4.03319 +-17.8161 3.66564 +-17.903 3.29631 +-17.9812 2.92539 +-18.0506 2.55305 +-18.1114 2.17947 +-18.1633 1.80484 +-18.2064 1.42933 +-18.2407 1.05313 +-18.2661 0.676423 +-18.2827 0.299385 +-18.2904 -0.0777982 +-18.2893 -0.454945 +-18.2793 -0.831874 +-18.2605 -1.2084 +-18.2329 -1.58435 +-18.1964 -1.95953 +-18.1512 -2.33377 +-18.0972 -2.70688 +-18.0345 -3.07869 +-17.9631 -3.44902 +-17.8831 -3.81769 +-17.7945 -4.18453 +-17.6973 -4.54937 +-17.5917 -4.91202 +-17.4777 -5.27232 +-17.3553 -5.63011 +-17.2246 -5.98521 +-17.0857 -6.33745 +-16.9387 -6.68668 +-16.7837 -7.03273 +-16.6206 -7.37545 +-16.4498 -7.71468 +-16.2711 -8.05026 +-16.0848 -8.38204 +-15.8908 -8.70987 +-15.6895 -9.03361 +-15.4807 -9.35312 +-15.2647 -9.66824 +-15.0416 -9.97885 +-14.8114 -10.2848 +-14.5744 -10.586 +-14.3306 -10.8822 +-14.0802 -11.1735 +-13.8232 -11.4595 +-13.5599 -11.7403 +-13.2903 -12.0157 +-13.0147 -12.2855 +-12.7331 -12.5498 +-12.4456 -12.8083 +-12.1525 -13.061 +-11.8539 -13.3077 +-11.5499 -13.5485 +-11.2407 -13.7831 +-10.9264 -14.0114 +-10.6072 -14.2335 +-10.2833 -14.4492 +-9.95473 -14.6584 +-9.62174 -14.8611 +-9.28447 -15.0572 +-8.94308 -15.2466 +-8.59774 -15.4293 +-8.2486 -15.6051 +-7.89583 -15.7741 +-7.5396 -15.9362 +-7.18006 -16.0913 +-6.8174 -16.2394 +-6.45176 -16.3804 +-6.08333 -16.5143 +-5.71227 -16.6411 +-5.33874 -16.7607 +-4.96292 -16.8731 +-4.58498 -16.9783 +-4.20507 -17.0762 +-3.82337 -17.1669 +-3.44005 -17.2502 +-3.05527 -17.3263 +-2.6692 -17.395 +-2.28201 -17.4564 +-1.89387 -17.5105 +-1.50493 -17.5572 +-1.11536 -17.5967 +-0.725328 -17.6288 +-0.334998 -17.6535 +0.05547 -17.671 +0.445914 -17.6812 +0.836173 -17.6841 +1.22609 -17.6797 +1.6155 -17.6681 +2.00425 -17.6493 +2.39219 -17.6234 +2.77915 -17.5902 +3.16499 -17.55 +3.54955 -17.5026 +3.93268 -17.4483 +4.31423 -17.3869 +4.69405 -17.3185 +5.072 -17.2433 +5.44793 -17.1612 +5.82169 -17.0722 +6.19314 -16.9765 +6.56214 -16.8741 +6.92855 -16.765 +7.29224 -16.6494 +7.65306 -16.5272 +8.01089 -16.3985 +8.36559 -16.2635 +8.71702 -16.1221 +9.06507 -15.9744 +9.4096 -15.8206 +9.75049 -15.6606 +10.0876 -15.4946 +10.4209 -15.3226 +10.7501 -15.1447 +11.0752 -14.961 +11.3961 -14.7716 +11.7126 -14.5765 +12.0247 -14.3759 +12.3321 -14.1698 +12.635 -13.9584 +12.933 -13.7416 +13.2261 -13.5196 +13.5143 -13.2926 +13.7973 -13.0605 +14.0752 -12.8235 +14.3478 -12.5817 +14.615 -12.3352 +14.8767 -12.0841 +15.1329 -11.8284 +15.3834 -11.5684 +15.6282 -11.304 +15.8672 -11.0354 +16.1003 -10.7627 +16.3274 -10.486 +16.5484 -10.2055 +16.7633 -9.92114 +16.9721 -9.63312 +17.1745 -9.34155 +17.3707 -9.04653 +17.5604 -8.74817 +17.7436 -8.4466 +17.9204 -8.14191 +18.0905 -7.83423 +18.254 -7.52367 +18.4108 -7.21036 +18.5609 -6.89439 +18.7041 -6.5759 +18.8405 -6.25501 +18.97 -5.93182 +19.0926 -5.60646 +19.2081 -5.27906 +19.3167 -4.94972 +19.4182 -4.61858 +19.5126 -4.28575 +19.5999 -3.95135 +19.68 -3.61552 +19.753 -3.27836 +19.8187 -2.94001 +19.8772 -2.60059 +19.9284 -2.26022 +19.9724 -1.91902 +20.009 -1.57713 +20.0384 -1.23466 +20.0604 -0.891739 +20.0751 -0.548492 +20.0825 -0.205044 +20.0825 0.138479 +20.0752 0.481951 +20.0605 0.825247 +20.0385 1.16824 +20.0091 1.51081 +19.9725 1.85282 +19.9284 2.19415 +19.8771 2.53468 +19.8185 2.87427 +19.7526 3.21281 +19.6794 3.55016 +19.599 3.8862 +19.5113 4.22081 +19.4165 4.55387 +19.3144 4.88523 +19.2053 5.2148 +19.089 5.54243 +18.9656 5.868 +18.8352 6.19139 +18.6978 6.51249 +18.5535 6.83115 +18.4022 7.14728 +18.244 7.46073 +18.0791 7.77139 +17.9073 8.07915 +17.7289 8.38387 +17.5438 8.68545 +17.352 8.98376 +17.1538 9.27868 +16.9491 9.5701 +16.7379 9.8579 +16.5204 10.142 +16.2967 10.4222 +16.0667 10.6984 +15.8306 10.9706 +15.5885 11.2386 +15.3404 11.5023 +15.0865 11.7616 +14.8267 12.0163 +14.5613 12.2665 +14.2902 12.5119 +14.0135 12.7524 +13.7315 12.988 +13.4441 13.2186 +13.1515 13.444 +12.8537 13.6642 +12.5509 13.879 +12.2432 14.0883 +11.9307 14.2922 +11.6135 14.4904 +11.2916 14.6828 +10.9653 14.8695 +10.6347 15.0502 +10.2998 15.225 +9.96079 15.3937 +9.6178 15.5562 +9.27095 15.7125 +8.92037 15.8624 +8.56619 16.0059 +8.20854 16.143 +7.84757 16.2735 +7.4834 16.3974 +7.11617 16.5146 +6.74604 16.6251 +6.37314 16.7287 +5.99762 16.8254 +5.61962 16.9152 +5.23929 16.998 +4.8568 17.0738 +4.47228 17.1424 +4.08589 17.2039 +3.6978 17.2581 +3.30815 17.3052 +2.91711 17.3449 +2.52484 17.3773 +2.1315 17.4023 +1.73725 17.42 +1.34226 17.4302 +0.946704 17.433 +0.55074 17.4283 +0.15454 17.4161 +-0.241726 17.3964 +-0.637886 17.3692 +-1.03377 17.3345 +-1.4292 17.2922 +-1.82401 17.2424 +-2.21801 17.1851 +-2.61104 17.1202 +-3.00292 17.0478 +-3.39347 16.9678 +-3.78252 16.8804 +-4.16988 16.7855 +-4.55539 16.6831 +-4.93886 16.5732 +-5.32012 16.456 +-5.69899 16.3314 +-6.07529 16.1994 +-6.44885 16.0601 +-6.8195 15.9136 +-7.18705 15.7598 +-7.55134 15.5989 +-7.91219 15.4308 +-8.26942 15.2558 +-8.62287 15.0737 +-8.97236 14.8847 +-9.31772 14.6889 +-9.65879 14.4863 +-9.9954 14.277 +-10.3274 14.0611 +-10.6546 13.8386 +-10.9768 13.6098 +-11.2939 13.3745 +-11.6057 13.1331 +-11.9121 12.8854 +-12.2129 12.6318 +-12.508 12.3722 +-12.7972 12.1067 +-13.0803 11.8356 +-13.3573 11.5588 +-13.6279 11.2766 +-13.8921 10.9891 +-14.1497 10.6963 +-14.4005 10.3984 +-14.6445 10.0956 +-14.8815 9.78794 +-15.1114 9.47562 +-15.334 9.15876 +-15.5493 8.83752 +-15.7572 8.51203 +-15.9575 8.18246 +-16.1501 7.84895 +-16.335 7.51167 +-16.5119 7.17077 +-16.681 6.82641 +-16.8419 6.47875 +-16.9948 6.12798 +-17.1394 5.77424 +-17.2757 5.41771 +-17.4037 5.05856 +-17.5233 4.69696 +-17.6343 4.33309 +-17.7369 3.96712 +-17.8308 3.59923 +-17.9161 3.2296 +-17.9926 2.85841 +-18.0605 2.48582 +-18.1196 2.11204 +-18.1699 1.73723 +-18.2114 1.36158 +-18.2441 0.985264 +-18.2679 0.608474 +-18.2829 0.231388 +-18.289 -0.14581 +-18.2863 -0.522939 +-18.2747 -0.899814 +-18.2543 -1.27625 +-18.225 -1.65208 +-18.187 -2.0271 +-18.1402 -2.40115 +-18.0846 -2.77404 +-18.0204 -3.14559 +-17.9474 -3.51563 +-17.8659 -3.88397 +-17.7757 -4.25045 +-17.6771 -4.61489 +-17.5699 -4.97711 +-17.4544 -5.33696 +-17.3305 -5.69425 +-17.1984 -6.04883 +-17.0581 -6.40052 +-16.9096 -6.74916 +-16.7531 -7.0946 +-16.5887 -7.43668 +-16.4164 -7.77523 +-16.2364 -8.11011 +-16.0487 -8.44117 +-15.8535 -8.76825 +-15.6508 -9.09121 +-15.4407 -9.4099 +-15.2235 -9.7242 +-14.9991 -10.034 +-14.7677 -10.339 +-14.5295 -10.6393 +-14.2846 -10.9346 +-14.033 -11.2249 +-13.7749 -11.51 +-13.5105 -11.7898 +-13.2399 -12.0641 +-12.9632 -12.333 +-12.6806 -12.5961 +-12.3922 -12.8536 +-12.0981 -13.1052 +-11.7986 -13.3508 +-11.4937 -13.5904 +-11.1836 -13.8238 +-10.8685 -14.051 +-10.5485 -14.2719 +-10.2238 -14.4864 +-9.89445 -14.6944 +-9.56073 -14.8959 +-9.22276 -15.0907 +-8.8807 -15.2789 +-8.53471 -15.4603 +-8.18495 -15.6348 +-7.8316 -15.8025 +-7.47481 -15.9633 +-7.11475 -16.1171 +-6.75159 -16.2639 +-6.3855 -16.4036 +-6.01664 -16.5362 +-5.64518 -16.6617 +-5.27128 -16.78 +-4.89512 -16.891 +-4.51687 -16.9949 +-4.13668 -17.0915 +-3.75473 -17.1808 +-3.37119 -17.2628 +-2.98622 -17.3375 +-2.59999 -17.4049 +-2.21266 -17.4649 +-1.82441 -17.5176 +-1.43539 -17.563 +-1.04577 -17.6011 +-0.655717 -17.6319 +-0.265389 -17.6553 +0.125051 -17.6714 +0.51544 -17.6803 +0.905618 -17.6818 +1.29543 -17.6761 +1.68471 -17.6632 +2.0733 -17.6431 +2.46106 -17.6158 +2.84781 -17.5814 +3.23342 -17.5399 +3.61772 -17.4913 +4.00057 -17.4356 +4.38182 -17.373 +4.76131 -17.3034 +5.13891 -17.2269 +5.51446 -17.1436 +5.88782 -17.0534 +6.25885 -16.9565 +6.62741 -16.8529 +6.99336 -16.7427 +7.35656 -16.6259 +7.71687 -16.5026 +8.07417 -16.3728 +8.42831 -16.2367 +8.77918 -16.0942 +9.12663 -15.9455 +9.47055 -15.7906 +9.81081 -15.6296 +10.1473 -15.4625 +10.4799 -15.2895 +10.8084 -15.1107 +11.1328 -14.9261 +11.453 -14.7357 +11.7687 -14.5398 +12.08 -14.3383 +12.3868 -14.1313 +12.6888 -13.919 +12.986 -13.7015 +13.2783 -13.4787 +13.5655 -13.2509 +13.8477 -13.0181 +14.1247 -12.7804 +14.3964 -12.5379 +14.6626 -12.2907 +14.9234 -12.0389 +15.1786 -11.7826 +15.4281 -11.5219 +15.6719 -11.2569 +15.9099 -10.9877 +16.1419 -10.7145 +16.368 -10.4373 +16.588 -10.1562 +16.8018 -9.87133 +17.0095 -9.58283 +17.2108 -9.29079 +17.4059 -8.99532 +17.5945 -8.69654 +17.7766 -8.39456 +17.9522 -8.08949 +18.1212 -7.78144 +18.2835 -7.47054 +18.4392 -7.1569 +18.588 -6.84063 +18.7301 -6.52186 +18.8653 -6.2007 +18.9937 -5.87727 +19.115 -5.55169 +19.2294 -5.22409 +19.3368 -4.89457 +19.4371 -4.56327 +19.5303 -4.23031 +19.6164 -3.89579 +19.6953 -3.55986 +19.7671 -3.22263 +19.8316 -2.88423 +19.8889 -2.54477 +19.9389 -2.20438 +19.9817 -1.86319 +20.0171 -1.52131 +20.0453 -1.17889 +20.0662 -0.836027 +20.0797 -0.492862 +20.0859 -0.149517 +20.0847 0.193882 +20.0763 0.53721 +20.0604 0.880342 +20.0373 1.22315 +20.0068 1.56551 +19.969 1.9073 +19.9238 2.24838 +19.8714 2.58864 +19.8117 2.92795 +19.7446 3.26618 +19.6704 3.60321 +19.5889 3.93892 +19.5001 4.27317 +19.4042 4.60584 +19.3011 4.93681 +19.1909 5.26596 +19.0736 5.59316 +18.9492 5.91828 +18.8177 6.24121 +18.6793 6.56182 +18.534 6.87999 +18.3817 7.19559 +18.2226 7.50851 +18.0567 7.81863 +17.884 8.12582 +17.7046 8.42996 +17.5185 8.73094 +17.3259 9.02864 +17.1268 9.32293 +16.9212 9.61371 +16.7092 9.90086 +16.4908 10.1843 +16.2662 10.4638 +16.0355 10.7393 +15.7986 11.0108 +15.5557 11.278 +15.3068 11.541 +15.0521 11.7995 +14.7916 12.0535 +14.5253 12.3028 +14.2535 12.5474 +13.9762 12.7872 +13.6935 13.0219 +13.4054 13.2517 +13.1121 13.4762 +12.8137 13.6955 +12.5103 13.9095 +12.202 14.118 +11.8888 14.3209 +11.571 14.5182 +11.2486 14.7097 +10.9218 14.8955 +10.5906 15.0753 +10.2552 15.2491 +9.91572 15.4168 +9.57226 15.5784 +9.22496 15.7337 +8.87394 15.8827 +8.51934 16.0252 +8.16129 16.1613 +7.79993 16.2908 +7.4354 16.4137 +7.06783 16.5298 +6.69736 16.6392 +6.32415 16.7418 +5.94833 16.8375 +5.57006 16.9262 +5.18948 17.008 +4.80674 17.0826 +4.422 17.1502 +4.03541 17.2106 +3.64712 17.2637 +3.25731 17.3097 +2.86612 17.3483 +2.47372 17.3796 +2.08027 17.4035 +1.68593 17.4201 +1.29087 17.4292 +0.895262 17.4308 +0.499267 17.425 +0.103056 17.4117 +-0.2932 17.3909 +-0.689329 17.3625 +-1.08516 17.3267 +-1.48052 17.2833 +-1.87523 17.2323 +-2.26912 17.1738 +-2.66201 17.1078 +-3.05374 17.0342 +-3.44411 16.9531 +-3.83296 16.8645 +-4.22011 16.7685 +-4.60538 16.6649 +-4.9886 16.5539 +-5.36958 16.4355 +-5.74816 16.3097 +-6.12415 16.1766 +-6.49738 16.0362 +-6.86767 15.8885 +-7.23485 15.7337 +-7.59874 15.5716 +-7.95917 15.4025 +-8.31596 15.2263 +-8.66894 15.0432 +-9.01794 14.8532 +-9.36278 14.6563 +-9.70331 14.4526 +-10.0393 14.2423 +-10.3707 14.0253 +-10.6973 13.8019 +-11.0189 13.572 +-11.3353 13.3358 +-11.6464 13.0933 +-11.9521 12.8448 +-12.2521 12.5901 +-12.5464 12.3296 +-12.8348 12.0632 +-13.1171 11.7912 +-13.3932 11.5135 +-13.6629 11.2304 +-13.9261 10.942 +-14.1828 10.6484 +-14.4326 10.3497 +-14.6756 10.046 +-14.9116 9.73754 +-15.1404 9.42443 +-15.3619 9.10679 +-15.5761 8.78478 +-15.7828 8.45855 +-15.9819 8.12825 +-16.1734 7.79403 +-16.357 7.45606 +-16.5327 7.11448 +-16.7004 6.76947 +-16.8601 6.42118 +-17.0116 6.06978 +-17.1549 5.71545 +-17.2899 5.35834 +-17.4165 4.99864 +-17.5346 4.63651 +-17.6442 4.27212 +-17.7453 3.90566 +-17.8377 3.5373 +-17.9215 3.16722 +-17.9966 2.7956 +-18.0629 2.42262 +-18.1205 2.04845 +-18.1693 1.67329 +-18.2092 1.29731 +-18.2403 0.920699 +-18.2626 0.543637 +-18.276 0.166309 +-18.2805 -0.211103 +-18.2762 -0.588414 +-18.263 -0.965442 +-18.2409 -1.342 +-18.2101 -1.71792 +-18.1704 -2.093 +-18.122 -2.46707 +-18.0648 -2.83995 +-17.9989 -3.21147 +-17.9243 -3.58143 +-17.8411 -3.94967 +-17.7494 -4.31602 +-17.6491 -4.68029 +-17.5403 -5.04231 +-17.4231 -5.40192 +-17.2976 -5.75895 +-17.1638 -6.11322 +-17.0219 -6.46458 +-16.8718 -6.81286 +-16.7137 -7.15791 +-16.5477 -7.49955 +-16.3738 -7.83764 +-16.1922 -8.17203 +-16.003 -8.50256 +-15.8062 -8.82908 +-15.602 -9.15145 +-15.3904 -9.46952 +-15.1716 -9.78316 +-14.9458 -10.0922 +-14.713 -10.3966 +-14.4733 -10.6961 +-14.2269 -10.9907 +-13.9739 -11.2801 +-13.7145 -11.5644 +-13.4487 -11.8433 +-13.1767 -12.1167 +-12.8987 -12.3846 +-12.6148 -12.6469 +-12.3251 -12.9033 +-12.0298 -13.1539 +-11.7291 -13.3984 +-11.423 -13.6369 +-11.1118 -13.8693 +-10.7955 -14.0954 +-10.4744 -14.3151 +-10.1486 -14.5284 +-9.81823 -14.7353 +-9.48349 -14.9355 +-9.14454 -15.1291 +-8.80153 -15.316 +-8.45463 -15.4961 +-8.104 -15.6694 +-7.74981 -15.8358 +-7.39221 -15.9953 +-7.03139 -16.1478 +-6.6675 -16.2932 +-6.30071 -16.4315 +-5.93119 -16.5628 +-5.55911 -16.6868 +-5.18463 -16.8037 +-4.80792 -16.9134 +-4.42916 -17.0158 +-4.04851 -17.1109 +-3.66613 -17.1988 +-3.28219 -17.2793 +-2.89686 -17.3525 +-2.51031 -17.4184 +-2.1227 -17.477 +-1.7342 -17.5283 +-1.34498 -17.5722 +-0.955191 -17.6087 +-0.565004 -17.638 +-0.174583 -17.6599 +0.215913 -17.6745 +0.60632 -17.6819 +0.99648 -17.682 +1.38623 -17.6748 +1.77542 -17.6604 +2.16388 -17.6388 +2.55147 -17.61 +2.93802 -17.5741 +3.32339 -17.5311 +3.70741 -17.481 +4.08995 -17.4239 +4.47084 -17.3598 +4.84995 -17.2888 +5.22713 -17.2109 +5.60222 -17.1261 +5.97509 -17.0345 +6.3456 -16.9362 +6.7136 -16.8312 +7.07896 -16.7196 +7.44154 -16.6014 +7.80121 -16.4768 +8.15783 -16.3456 +8.51127 -16.2081 +8.8614 -16.0643 +9.20809 -15.9143 +9.55122 -15.7581 +9.89067 -15.5958 +10.2263 -15.4275 +10.558 -15.2533 +10.8857 -15.0733 +11.2092 -14.8874 +11.5284 -14.6959 +11.8432 -14.4988 +12.1535 -14.2962 +12.4592 -14.0881 +12.7602 -13.8747 +13.0563 -13.6561 +13.3476 -13.4323 +13.6338 -13.2034 +13.9148 -12.9696 +14.1907 -12.7309 +14.4612 -12.4874 +14.7263 -12.2393 +14.9859 -11.9866 +15.2399 -11.7294 +15.4883 -11.4678 +15.7309 -11.202 +15.9676 -10.932 +16.1984 -10.658 +16.4232 -10.38 +16.6419 -10.0982 +16.8545 -9.81265 +17.0609 -9.52347 +17.261 -9.23079 +17.4547 -8.93471 +17.642 -8.63534 +17.8228 -8.33279 +17.997 -8.02719 +18.1647 -7.71865 +18.3257 -7.40728 +18.48 -7.09319 +18.6275 -6.77651 +18.7682 -6.45736 +18.9021 -6.13584 +19.029 -5.81209 +19.149 -5.48621 +19.262 -5.15834 +19.3679 -4.82858 +19.4668 -4.49706 +19.5586 -4.1639 +19.6432 -3.82922 +19.7207 -3.49315 +19.791 -3.1558 +19.8541 -2.8173 +19.9099 -2.47778 +19.9585 -2.13735 +19.9998 -1.79614 +20.0339 -1.45427 +20.0606 -1.11187 +20.08 -0.769069 +20.0921 -0.425984 +20.0968 -0.0827423 +20.0942 0.26053 +20.0843 0.603708 +20.067 0.946665 +20.0424 1.28928 +20.0105 1.63142 +19.9713 1.97296 +19.9247 2.31379 +19.8708 2.65376 +19.8097 2.99277 +19.7413 3.33067 +19.6656 3.66735 +19.5827 4.00269 +19.4926 4.33655 +19.3953 4.66881 +19.2908 4.99935 +19.1793 5.32805 +19.0606 5.65478 +18.9349 5.97941 +18.8021 6.30183 +18.6624 6.62191 +18.5158 6.93953 +18.3622 7.25457 +18.2018 7.56691 +18.0347 7.87642 +17.8607 8.18298 +17.6801 8.48649 +17.4929 8.78681 +17.2991 9.08382 +17.0988 9.37742 +16.892 9.66748 +16.6789 9.95389 +16.4594 10.2365 +16.2337 10.5153 +16.0019 10.7901 +15.7639 11.0607 +15.5199 11.3271 +15.27 11.5892 +15.0143 11.8469 +14.7528 12.1 +14.4856 12.3485 +14.2128 12.5921 +13.9345 12.831 +13.6508 13.0648 +13.3619 13.2936 +13.0677 13.5172 +12.7684 13.7355 +12.4642 13.9485 +12.155 14.156 +11.8411 14.3579 +11.5225 14.5542 +11.1994 14.7447 +10.8718 14.9294 +10.5399 15.1081 +10.2038 15.2809 +9.86365 15.4475 +9.51955 15.608 +9.17162 15.7621 +8.82001 15.91 +8.46483 16.0514 +8.10623 16.1863 +7.74434 16.3147 +7.3793 16.4364 +7.01125 16.5514 +6.64032 16.6596 +6.26667 16.761 +5.89044 16.8554 +5.51178 16.943 +5.13084 17.0235 +4.74776 17.0969 +4.36271 17.1632 +3.97584 17.2224 +3.5873 17.2743 +3.19725 17.3189 +2.80585 17.3563 +2.41327 17.3863 +2.01967 17.409 +1.62521 17.4243 +1.23005 17.4321 +0.834375 17.4325 +0.438339 17.4254 +0.0421154 17.4108 +-0.354125 17.3887 +-0.75021 17.359 +-1.14597 17.3218 +-1.54123 17.2771 +-1.93581 17.2249 +-2.32955 17.165 +-2.72226 17.0977 +-3.11378 17.0228 +-3.50392 16.9404 +-3.89251 16.8505 +-4.27937 16.7531 +-4.66432 16.6483 +-5.0472 16.536 +-5.42781 16.4163 +-5.80599 16.2892 +-6.18155 16.1548 +-6.55432 16.0131 +-6.92413 15.8641 +-7.29079 15.708 +-7.65414 15.5447 +-8.01399 15.3743 +-8.37018 15.1969 +-8.72252 15.0125 +-9.07086 14.8212 +-9.41502 14.6231 +-9.75482 14.4182 +-10.0901 14.2067 +-10.4207 13.9885 +-10.7465 13.7639 +-11.0672 13.5328 +-11.3828 13.2954 +-11.693 13.0518 +-11.9978 12.8021 +-12.2969 12.5463 +-12.5903 12.2847 +-12.8776 12.0172 +-13.1589 11.7441 +-13.434 11.4654 +-13.7027 11.1812 +-13.9649 10.8918 +-14.2204 10.5972 +-14.4692 10.2975 +-14.711 9.99286 +-14.9458 9.68347 +-15.1735 9.36945 +-15.3939 9.05094 +-15.6068 8.72808 +-15.8123 8.40103 +-16.0102 8.06994 +-16.2004 7.73496 +-16.3827 7.39625 +-16.5571 7.05398 +-16.7235 6.7083 +-16.8819 6.35937 +-17.032 6.00737 +-17.1739 5.65246 +-17.3075 5.29481 +-17.4326 4.9346 +-17.5494 4.57199 +-17.6575 4.20716 +-17.7571 3.84029 +-17.8481 3.47155 +-17.9304 3.10112 +-18.004 2.72919 +-18.0688 2.35594 +-18.1248 1.98154 +-18.1721 1.60617 +-18.2105 1.23003 +-18.24 0.85329 +-18.2607 0.476137 +-18.2725 0.0987529 +-18.2754 -0.278678 +-18.2695 -0.655974 +-18.2547 -1.03295 +-18.2311 -1.40943 +-18.1986 -1.78522 +-18.1573 -2.16015 +-18.1072 -2.53404 +-18.0484 -2.9067 +-17.9808 -3.27796 +-17.9046 -3.64764 +-17.8198 -4.01556 +-17.7264 -4.38156 +-17.6244 -4.74545 +-17.514 -5.10706 +-17.3952 -5.46623 +-17.2681 -5.82278 +-17.1327 -6.17655 +-16.9891 -6.52737 +-16.8374 -6.87509 +-16.6778 -7.21954 +-16.5102 -7.56056 +-16.3347 -7.898 +-16.1516 -8.2317 +-15.9608 -8.56152 +-15.7625 -8.8873 +-15.5567 -9.2089 +-15.3437 -9.52618 +-15.1235 -9.83899 +-14.8962 -10.1472 +-14.6619 -10.4507 +-14.4208 -10.7493 +-14.1731 -11.0429 +-13.9187 -11.3314 +-13.6579 -11.6146 +-13.3909 -11.8925 +-13.1176 -12.1649 +-12.8383 -12.4318 +-12.5532 -12.6929 +-12.2623 -12.9482 +-11.9658 -13.1977 +-11.6638 -13.4411 +-11.3566 -13.6784 +-11.0443 -13.9095 +-10.7269 -14.1344 +-10.4047 -14.3529 +-10.0779 -14.565 +-9.74656 -14.7706 +-9.41087 -14.9695 +-9.07099 -15.1618 +-8.72709 -15.3474 +-8.37932 -15.5262 +-8.02787 -15.6982 +-7.67288 -15.8632 +-7.31453 -16.0213 +-6.95298 -16.1724 +-6.5884 -16.3164 +-6.22095 -16.4534 +-5.85081 -16.5832 +-5.47815 -16.7058 +-5.10312 -16.8212 +-4.7259 -16.9294 +-4.34665 -17.0304 +-3.96555 -17.1241 +-3.58276 -17.2104 +-3.19844 -17.2895 +-2.81278 -17.3613 +-2.42592 -17.4257 +-2.03804 -17.4828 +-1.64931 -17.5325 +-1.25989 -17.5749 +-0.869939 -17.61 +-0.479627 -17.6378 +-0.0891163 -17.6582 +0.301432 -17.6714 +0.691857 -17.6772 +1.082 -17.6758 +1.47169 -17.6671 +1.86079 -17.6513 +2.24913 -17.6282 +2.63655 -17.598 +3.0229 -17.5606 +3.40803 -17.5161 +3.79179 -17.4646 +4.17402 -17.4061 +4.55458 -17.3405 +4.93332 -17.2681 +5.31008 -17.1887 +5.68474 -17.1026 +6.05714 -17.0096 +6.42715 -16.9099 +6.79462 -16.8036 +7.15942 -16.6906 +7.52141 -16.571 +7.88045 -16.445 +8.23642 -16.3126 +8.58919 -16.1738 +8.93861 -16.0287 +9.28457 -15.8774 +9.62694 -15.7199 +9.9656 -15.5564 +10.3004 -15.3869 +10.6313 -15.2115 +10.9581 -15.0303 +11.2807 -14.8433 +11.599 -14.6506 +11.9128 -14.4524 +12.2222 -14.2487 +12.5269 -14.0395 +12.8268 -13.8251 +13.122 -13.6054 +13.4121 -13.3806 +13.6972 -13.1507 +13.9772 -12.9159 +14.2519 -12.6763 +14.5213 -12.4319 +14.7853 -12.1828 +15.0437 -11.9292 +15.2965 -11.6712 +15.5437 -11.4088 +15.785 -11.1422 +16.0205 -10.8714 +16.2501 -10.5966 +16.4736 -10.3179 +16.6911 -10.0354 +16.9024 -9.74915 +17.1075 -9.45933 +17.3063 -9.16602 +17.4987 -8.86934 +17.6847 -8.5694 +17.8641 -8.26631 +18.0371 -7.9602 +18.2034 -7.65116 +18.3631 -7.33933 +18.516 -7.02482 +18.6622 -6.70773 +18.8015 -6.3882 +18.934 -6.06633 +19.0596 -5.74225 +19.1782 -5.41608 +19.2898 -5.08793 +19.3944 -4.75793 +19.492 -4.4262 +19.5824 -4.09285 +19.6657 -3.75802 +19.7418 -3.42182 +19.8108 -3.08437 +19.8726 -2.7458 +19.9271 -2.40624 +19.9744 -2.0658 +20.0144 -1.72461 +20.0471 -1.38279 +20.0726 -1.04048 +20.0907 -0.697784 +20.1015 -0.354839 +20.105 -0.0117672 +20.1011 0.331306 +20.09 0.674257 +20.0715 1.01696 +20.0457 1.35929 +20.0125 1.70112 +19.9721 2.04232 +19.9243 2.38278 +19.8693 2.72237 +19.807 3.06095 +19.7374 3.39841 +19.6606 3.73463 +19.5765 4.06947 +19.4853 4.40281 +19.3869 4.73454 +19.2813 5.06452 +19.1687 5.39263 +19.0489 5.71876 +18.9222 6.04277 +18.7884 6.36454 +18.6477 6.68396 +18.5 7.0009 +18.3455 7.31524 +18.1841 7.62685 +18.016 7.93563 +17.8411 8.24144 +17.6596 8.54418 +17.4714 8.84371 +17.2767 9.13993 +17.0756 9.43271 +16.8679 9.72195 +16.654 10.0075 +16.4337 10.2893 +16.2072 10.5672 +15.9746 10.8411 +15.7359 11.1108 +15.4912 11.3764 +15.2406 11.6376 +14.9841 11.8943 +14.7219 12.1465 +14.4541 12.394 +14.1807 12.6368 +13.9018 12.8747 +13.6176 13.1076 +13.3281 13.3354 +13.0334 13.5581 +12.7336 13.7755 +12.4289 13.9875 +12.1193 14.194 +11.8049 14.395 +11.486 14.5902 +11.1624 14.7798 +10.8345 14.9635 +10.5023 15.1413 +10.1659 15.313 +9.82543 15.4787 +9.48106 15.6381 +9.13289 15.7913 +8.78105 15.9382 +8.42567 16.0786 +8.06688 16.2125 +7.70483 16.3399 +7.33965 16.4606 +6.97148 16.5746 +6.60046 16.6819 +6.22673 16.7823 +5.85045 16.8758 +5.47175 16.9624 +5.09079 17.0419 +4.70772 17.1144 +4.3227 17.1797 +3.93587 17.2379 +3.54739 17.2889 +3.15743 17.3327 +2.76614 17.3691 +2.37368 17.3982 +1.98022 17.42 +1.58592 17.4343 +1.19094 17.4413 +0.795462 17.4407 +0.39964 17.4327 +0.00364702 17.4172 +-0.392347 17.3942 +-0.788172 17.3637 +-1.18365 17.3257 +-1.57862 17.2801 +-1.97291 17.227 +-2.36633 17.1663 +-2.75871 17.0981 +-3.14988 17.0224 +-3.53966 16.9392 +-3.92788 16.8484 +-4.31435 16.7502 +-4.69891 16.6446 +-5.08137 16.5315 +-5.46156 16.411 +-5.83929 16.2832 +-6.2144 16.148 +-6.5867 16.0055 +-6.95603 15.8558 +-7.32219 15.699 +-7.68503 15.5349 +-8.04436 15.3638 +-8.40001 15.1857 +-8.75181 15.0006 +-9.09959 14.8086 +-9.44318 14.6097 +-9.78241 14.4042 +-10.1171 14.1919 +-10.4471 13.9731 +-10.7723 13.7478 +-11.0924 13.516 +-11.4073 13.278 +-11.7169 13.0337 +-12.021 12.7833 +-12.3195 12.5269 +-12.6121 12.2646 +-12.8988 11.9965 +-13.1794 11.7228 +-13.4538 11.4435 +-13.7218 11.1587 +-13.9832 10.8687 +-14.238 10.5734 +-14.486 10.2731 +-14.7271 9.96796 +-14.9611 9.658 +-15.188 9.34342 +-15.4076 9.02435 +-15.6198 8.70094 +-15.8244 8.37335 +-16.0215 8.04173 +-16.2108 7.70622 +-16.3922 7.36699 +-16.5658 7.0242 +-16.7313 6.67801 +-16.8887 6.32858 +-17.038 5.97609 +-17.179 5.62069 +-17.3116 5.26256 +-17.4359 4.90188 +-17.5516 4.53881 +-17.6589 4.17353 +-17.7575 3.80622 +-17.8475 3.43706 +-17.9288 3.06622 +-18.0015 2.69389 +-18.0653 2.32025 +-18.1204 1.94548 +-18.1666 1.56977 +-18.204 1.19329 +-18.2325 0.816227 +-18.2522 0.43877 +-18.263 0.0611005 +-18.2649 -0.316598 +-18.258 -0.694142 +-18.2421 -1.07135 +-18.2175 -1.44803 +-18.1839 -1.82401 +-18.1416 -2.19911 +-18.0905 -2.57314 +-18.0306 -2.94592 +-17.962 -3.31728 +-17.8847 -3.68704 +-17.7988 -4.05501 +-17.7044 -4.42103 +-17.6013 -4.78492 +-17.4899 -5.14651 +-17.37 -5.50562 +-17.2418 -5.8621 +-17.1053 -6.21576 +-16.9607 -6.56646 +-16.8079 -6.91401 +-16.6472 -7.25827 +-16.4785 -7.59908 +-16.302 -7.93627 +-16.1178 -8.26969 +-15.9259 -8.5992 +-15.7265 -8.92465 +-15.5197 -9.24589 +-15.3056 -9.56277 +-15.0843 -9.87516 +-14.8559 -10.1829 +-14.6205 -10.4859 +-14.3784 -10.784 +-14.1295 -11.0771 +-13.8741 -11.365 +-13.6122 -11.6477 +-13.344 -11.9249 +-13.0697 -12.1967 +-12.7894 -12.4629 +-12.5031 -12.7233 +-12.2112 -12.9779 +-11.9137 -13.2266 +-11.6107 -13.4693 +-11.3025 -13.7058 +-10.9891 -13.9362 +-10.6708 -14.1602 +-10.3476 -14.3779 +-10.0198 -14.5891 +-9.68753 -14.7938 +-9.35091 -14.9919 +-9.01012 -15.1832 +-8.66533 -15.3679 +-8.3167 -15.5457 +-7.96439 -15.7167 +-7.60857 -15.8807 +-7.24941 -16.0378 +-6.88707 -16.1878 +-6.52172 -16.3308 +-6.15353 -16.4666 +-5.78266 -16.5953 +-5.4093 -16.7169 +-5.03359 -16.8312 +-4.65572 -16.9382 +-4.27585 -17.038 +-3.89415 -17.1305 +-3.51079 -17.2157 +-3.12593 -17.2936 +-2.73975 -17.3642 +-2.35241 -17.4274 +-1.96407 -17.4832 +-1.57491 -17.5318 +-1.18509 -17.5729 +-0.794771 -17.6068 +-0.404122 -17.6333 +-0.0133061 -17.6525 +0.377515 -17.6643 +0.768181 -17.6689 +1.15853 -17.6662 +1.5484 -17.6563 +1.93764 -17.6391 +2.32608 -17.6148 +2.71358 -17.5832 +3.09998 -17.5446 +3.48512 -17.4988 +3.86885 -17.446 +4.25102 -17.3862 +4.63149 -17.3193 +5.0101 -17.2456 +5.38672 -17.1649 +5.76119 -17.0775 +6.13338 -16.9832 +6.50313 -16.8823 +6.87033 -16.7746 +7.23481 -16.6604 +7.59645 -16.5396 +7.95512 -16.4123 +8.31068 -16.2786 +8.663 -16.1386 +9.01195 -15.9923 +9.3574 -15.8398 +9.69923 -15.6811 +10.0373 -15.5164 +10.3715 -15.3458 +10.7018 -15.1692 +11.0279 -14.9868 +11.3498 -14.7987 +11.6673 -14.6049 +11.9805 -14.4055 +12.289 -14.2007 +12.5929 -13.9905 +12.892 -13.7749 +13.1863 -13.5542 +13.4755 -13.3283 +13.7597 -13.0975 +14.0388 -12.8617 +14.3125 -12.621 +14.5809 -12.3757 +14.8438 -12.1257 +15.1012 -11.8712 +15.353 -11.6122 +15.599 -11.349 +15.8393 -11.0815 +16.0736 -10.8099 +16.302 -10.5343 +16.5244 -10.2548 +16.7407 -9.97149 +16.9508 -9.68451 +17.1546 -9.39396 +17.3521 -9.09996 +17.5433 -8.8026 +17.728 -8.50201 +17.9061 -8.1983 +18.0778 -7.89158 +18.2427 -7.58196 +18.401 -7.26958 +18.5526 -6.95453 +18.6974 -6.63693 +18.8353 -6.31692 +18.9664 -5.99459 +19.0906 -5.67007 +19.2078 -5.34349 +19.318 -5.01496 +19.4211 -4.6846 +19.5172 -4.35253 +19.6062 -4.01888 +19.688 -3.68376 +19.7627 -3.34731 +19.8302 -3.00963 +19.8905 -2.67086 +19.9435 -2.33112 +19.9893 -1.99054 +20.0278 -1.64923 +20.0591 -1.30731 +20.083 -0.964929 +20.0997 -0.622193 +20.109 -0.27923 +20.111 0.0638337 +20.1057 0.406874 +20.093 0.749766 +20.073 1.09238 +20.0457 1.4346 +20.0111 1.7763 +19.9692 2.11735 +19.92 2.45762 +19.8635 2.797 +19.7997 3.13535 +19.7287 3.47256 +19.6505 3.80849 +19.5651 4.14302 +19.4724 4.47604 +19.3726 4.80741 +19.2657 5.13701 +19.1517 5.46471 +19.0306 5.79041 +18.9026 6.11396 +18.7675 6.43525 +18.6254 6.75416 +18.4765 7.07056 +18.3207 7.38434 +18.1581 7.69537 +17.9888 8.00354 +17.8127 8.30871 +17.63 8.61078 +17.4407 8.90963 +17.2449 9.20514 +17.0425 9.49718 +16.8338 9.78566 +16.6187 10.0704 +16.3974 10.3514 +16.1698 10.6285 +15.9361 10.9015 +15.6964 11.1704 +15.4507 11.4351 +15.1991 11.6954 +14.9417 11.9512 +14.6786 12.2024 +14.4098 12.449 +14.1355 12.6908 +13.8558 12.9276 +13.5707 13.1595 +13.2804 13.3863 +12.9848 13.6079 +12.6843 13.8242 +12.3788 14.0351 +12.0684 14.2406 +11.7534 14.4404 +11.4337 14.6346 +11.1095 14.823 +10.7809 15.0055 +10.448 15.1821 +10.111 15.3527 +9.76996 15.5171 +9.42502 15.6754 +9.07631 15.8274 +8.72396 15.9731 +8.36809 16.1123 +8.00885 16.245 +7.64637 16.3711 +7.28078 16.4906 +6.91223 16.6034 +6.54086 16.7094 +6.16681 16.8086 +5.79023 16.9009 +5.41126 16.9862 +5.03006 17.0645 +4.64678 17.1357 +4.26157 17.1999 +3.87459 17.2568 +3.48599 17.3066 +3.09593 17.3491 +2.70457 17.3843 +2.31208 17.4121 +1.9186 17.4326 +1.52432 17.4457 +1.12938 17.4514 +0.733969 17.4497 +0.338241 17.4404 +-0.0576318 17.4237 +-0.45348 17.3995 +-0.849133 17.3678 +-1.24442 17.3285 +-1.63916 17.2817 +-2.03319 17.2274 +-2.42633 17.1656 +-2.81841 17.0962 +-3.20925 17.0193 +-3.59867 16.935 +-3.9865 16.8431 +-4.37257 16.7438 +-4.75668 16.637 +-5.13868 16.5228 +-5.51837 16.4012 +-5.89559 16.2723 +-6.27016 16.1361 +-6.64189 15.9926 +-7.01062 15.8418 +-7.37618 15.6839 +-7.73838 15.5188 +-8.09705 15.3467 +-8.45202 15.1676 +-8.80311 14.9815 +-9.15016 14.7885 +-9.493 14.5888 +-9.83146 14.3823 +-10.1654 14.1691 +-10.4946 13.9494 +-10.8189 13.7232 +-11.1382 13.4906 +-11.4522 13.2517 +-11.761 13.0066 +-12.0642 12.7554 +-12.3617 12.4982 +-12.6534 12.2351 +-12.9392 11.9663 +-13.2188 11.6918 +-13.4922 11.4118 +-13.7592 11.1263 +-14.0196 10.8356 +-14.2734 10.5397 +-14.5203 10.2388 +-14.7603 9.93301 +-14.9933 9.62247 +-15.2191 9.30731 +-15.4375 8.98769 +-15.6486 8.66375 +-15.8521 8.33565 +-16.048 8.00353 +-16.2361 7.66755 +-16.4164 7.32786 +-16.5888 6.98464 +-16.7531 6.63803 +-16.9094 6.28821 +-17.0574 5.93534 +-17.1972 5.57959 +-17.3286 5.22114 +-17.4516 4.86015 +-17.5662 4.4968 +-17.6722 4.13126 +-17.7696 3.76371 +-17.8584 3.39434 +-17.9385 3.02331 +-18.0098 2.65081 +-18.0724 2.27703 +-18.1262 1.90213 +-18.1712 1.52631 +-18.2073 1.14975 +-18.2346 0.772632 +-18.253 0.395136 +-18.2625 0.017449 +-18.2631 -0.360246 +-18.2549 -0.737766 +-18.2378 -1.11493 +-18.2118 -1.49155 +-18.177 -1.86744 +-18.1334 -2.24244 +-18.081 -2.61634 +-18.0199 -2.98898 +-17.95 -3.36018 +-17.8714 -3.72975 +-17.7843 -4.09752 +-17.6885 -4.46331 +-17.5843 -4.82696 +-17.4716 -5.18829 +-17.3505 -5.54713 +-17.221 -5.9033 +-17.0834 -6.25665 +-16.9375 -6.607 +-16.7836 -6.9542 +-16.6217 -7.29808 +-16.4518 -7.63849 +-16.2742 -7.97527 +-16.0888 -8.30826 +-15.8958 -8.63731 +-15.6953 -8.96228 +-15.4874 -9.28302 +-15.2722 -9.59939 +-15.0498 -9.91124 +-14.8204 -10.2184 +-14.584 -10.5209 +-14.3408 -10.8184 +-14.0909 -11.1108 +-13.8345 -11.3981 +-13.5717 -11.6802 +-13.3026 -11.9568 +-13.0274 -12.2279 +-12.7461 -12.4933 +-12.4591 -12.7531 +-12.1663 -13.0069 +-11.8679 -13.2549 +-11.5641 -13.4968 +-11.2551 -13.7325 +-10.941 -13.9621 +-10.622 -14.1853 +-10.2981 -14.4021 +-9.96963 -14.6125 +-9.63668 -14.8162 +-9.29943 -15.0134 +-8.95802 -15.2038 +-8.61263 -15.3875 +-8.26342 -15.5644 +-7.91056 -15.7344 +-7.5542 -15.8974 +-7.19452 -16.0534 +-6.83169 -16.2024 +-6.46586 -16.3443 +-6.09722 -16.4791 +-5.72592 -16.6068 +-5.35214 -16.7272 +-4.97605 -16.8404 +-4.5978 -16.9463 +-4.21758 -17.045 +-3.83555 -17.1364 +-3.45188 -17.2204 +-3.06674 -17.2971 +-2.68029 -17.3665 +-2.29271 -17.4285 +-1.90416 -17.4832 +-1.5148 -17.5306 +-1.12481 -17.5705 +-0.734347 -17.6032 +-0.343575 -17.6285 +0.0473399 -17.6465 +0.438236 -17.6571 +0.828953 -17.6605 +1.21933 -17.6566 +1.6092 -17.6454 +1.99842 -17.6271 +2.38682 -17.6015 +2.77425 -17.5687 +3.16055 -17.5288 +3.54558 -17.4818 +3.92918 -17.4278 +4.31119 -17.3667 +4.69148 -17.2987 +5.06989 -17.2237 +5.44627 -17.1419 +5.82049 -17.0532 +6.1924 -16.9577 +6.56186 -16.8556 +6.92872 -16.7468 +7.29286 -16.6313 +7.65413 -16.5094 +8.0124 -16.3809 +8.36753 -16.2461 +8.7194 -16.1049 +9.06788 -15.9575 +9.41283 -15.8038 +9.75414 -15.6441 +10.0917 -15.4783 +10.4253 -15.3065 +10.755 -15.1288 +11.0805 -14.9453 +11.4017 -14.7561 +11.7186 -14.5613 +12.0311 -14.3609 +12.3389 -14.155 +12.6421 -13.9438 +12.9405 -13.7273 +13.2339 -13.5055 +13.5224 -13.2787 +13.8058 -13.0469 +14.084 -12.8101 +14.3569 -12.5686 +14.6244 -12.3223 +14.8865 -12.0714 +15.1429 -11.8161 +15.3938 -11.5563 +15.6389 -11.2922 +15.8782 -11.0239 +16.1115 -10.7515 +16.339 -10.4751 +16.5603 -10.1948 +16.7755 -9.91079 +16.9846 -9.6231 +17.1873 -9.33186 +17.3838 -9.03718 +17.5738 -8.73917 +17.7574 -8.43795 +17.9344 -8.13363 +18.1049 -7.82633 +18.2687 -7.51615 +18.4258 -7.20322 +18.5762 -6.88765 +18.7198 -6.56956 +18.8565 -6.24906 +18.9864 -5.92629 +19.1093 -5.60135 +19.2253 -5.27437 +19.3342 -4.94546 +19.4361 -4.61476 +19.531 -4.28237 +19.6187 -3.94842 +19.6992 -3.61304 +19.7726 -3.27634 +19.8388 -2.93845 +19.8978 -2.59949 +19.9496 -2.25959 +19.994 -1.91887 +20.0313 -1.57744 +20.0612 -1.23545 +20.0838 -0.893001 +20.0991 -0.55023 +20.1071 -0.20726 +20.1078 0.135786 +20.1011 0.478782 +20.0872 0.821604 +20.0659 1.16413 +20.0373 1.50623 +20.0013 1.84778 +19.9581 2.18865 +19.9076 2.52873 +19.8498 2.86788 +19.7847 3.20598 +19.7124 3.54291 +19.6329 3.87855 +19.5462 4.21276 +19.4523 4.54542 +19.3512 4.87641 +19.2431 5.20561 +19.1278 5.5329 +19.0055 5.85814 +18.8762 6.18122 +18.7399 6.50202 +18.5967 6.8204 +18.4466 7.13626 +18.2896 7.44947 +18.1259 7.75992 +17.9554 8.06747 +17.7782 8.37202 +17.5944 8.67344 +17.404 8.97161 +17.207 9.26643 +17.0037 9.55778 +16.7939 9.84553 +16.5778 10.1296 +16.3554 10.4098 +16.1269 10.6861 +15.8923 10.9583 +15.6516 11.2264 +15.405 11.4903 +15.1526 11.7497 +14.8943 12.0047 +14.6304 12.255 +14.3608 12.5007 +14.0858 12.7416 +13.8053 12.9775 +13.5195 13.2085 +13.2284 13.4343 +12.9323 13.655 +12.6311 13.8703 +12.325 14.0802 +12.014 14.2846 +11.6984 14.4835 +11.3782 14.6766 +11.0535 14.864 +10.7244 15.0455 +10.3911 15.221 +10.0537 15.3905 +9.71231 15.5539 +9.36702 15.7111 +9.01799 15.862 +8.66534 16.0065 +8.30921 16.1446 +7.94973 16.2762 +7.58703 16.4012 +7.22126 16.5196 +6.85256 16.6312 +6.48105 16.7361 +6.1069 16.8341 +5.73024 16.9253 +5.35123 17.0094 +4.97001 17.0866 +4.58673 17.1566 +4.20155 17.2196 +3.81462 17.2754 +3.42609 17.324 +3.03613 17.3653 +2.6449 17.3993 +2.25255 17.426 +1.85924 17.4454 +1.46514 17.4573 +1.07042 17.4619 +0.675244 17.459 +0.279773 17.4486 +-0.115819 17.4308 +-0.511364 17.4055 +-0.90669 17.3726 +-1.30163 17.3323 +-1.696 17.2844 +-2.08963 17.2291 +-2.48236 17.1662 +-2.874 17.0958 +-3.26437 17.0179 +-3.65331 16.9325 +-4.04064 16.8396 +-4.42618 16.7393 +-4.80975 16.6315 +-5.19119 16.5164 +-5.5703 16.3938 +-5.94692 16.264 +-6.32087 16.1268 +-6.69197 15.9824 +-7.06005 15.8307 +& +@target G0.S4 +@type xy +11.4706 -25.7229 +11.7583 -25.6068 +12.0447 -25.4879 +12.3298 -25.3662 +12.6136 -25.2418 +12.896 -25.1146 +13.177 -24.9848 +13.4566 -24.8522 +13.7348 -24.717 +14.0115 -24.5791 +14.2866 -24.4385 +14.5602 -24.2953 +14.8323 -24.1494 +15.1027 -24.001 +15.3715 -23.8499 +15.6386 -23.6963 +15.904 -23.5401 +16.1677 -23.3813 +16.4297 -23.22 +16.6899 -23.0562 +16.9482 -22.8899 +17.2048 -22.7211 +17.4594 -22.5498 +17.7122 -22.3761 +17.9631 -22.2 +18.212 -22.0214 +18.4589 -21.8405 +18.7038 -21.6572 +18.9467 -21.4715 +19.1875 -21.2835 +19.4262 -21.0932 +19.6629 -20.9006 +19.8973 -20.7057 +20.1297 -20.5086 +20.3598 -20.3092 +20.5877 -20.1076 +20.8134 -19.9039 +21.0368 -19.6979 +21.2579 -19.4899 +21.4767 -19.2796 +21.6931 -19.0673 +21.9072 -18.8529 +22.1189 -18.6365 +22.3282 -18.418 +22.535 -18.1975 +22.7394 -17.975 +22.9413 -17.7506 +23.1407 -17.5242 +23.3376 -17.2959 +23.5319 -17.0657 +23.7237 -16.8337 +23.9128 -16.5998 +24.0994 -16.3641 +24.2833 -16.1266 +24.4645 -15.8873 +24.6431 -15.6463 +24.819 -15.4036 +24.9921 -15.1592 +25.1625 -14.9131 +25.3302 -14.6654 +25.4951 -14.4161 +25.6571 -14.1652 +25.8164 -13.9128 +25.9729 -13.6588 +26.1265 -13.4034 +26.2772 -13.1464 +26.425 -12.888 +26.57 -12.6282 +26.712 -12.3671 +26.8511 -12.1045 +26.9872 -11.8406 +27.1204 -11.5755 +27.2506 -11.309 +27.3777 -11.0413 +27.5019 -10.7724 +27.6231 -10.5023 +27.7412 -10.2311 +27.8562 -9.95871 +27.9682 -9.68524 +28.0772 -9.4107 +28.183 -9.13513 +28.2857 -8.85854 +28.3853 -8.58098 +28.4817 -8.30248 +28.5751 -8.02306 +28.6652 -7.74275 +28.7523 -7.46159 +28.8361 -7.17961 +28.9168 -6.89683 +28.9942 -6.6133 +29.0685 -6.32903 +29.1395 -6.04406 +29.2074 -5.75842 +29.272 -5.47215 +29.3333 -5.18528 +29.3915 -4.89783 +29.4463 -4.60984 +29.498 -4.32134 +29.5463 -4.03236 +29.5914 -3.74294 +29.6332 -3.4531 +29.6717 -3.16288 +29.707 -2.87231 +29.7389 -2.58142 +29.7676 -2.29025 +29.793 -1.99882 +29.815 -1.70717 +29.8338 -1.41533 +29.8492 -1.12334 +29.8613 -0.831216 +29.8702 -0.539003 +29.8757 -0.246731 +29.8779 0.0455681 +29.8767 0.337863 +29.8723 0.630119 +29.8645 0.922306 +29.8535 1.21439 +29.8391 1.50634 +29.8214 1.79812 +29.8004 2.0897 +29.776 2.38105 +29.7484 2.67214 +29.7174 2.96293 +29.6832 3.25339 +29.6456 3.54349 +29.6048 3.83319 +29.5606 4.12247 +29.5132 4.41129 +29.4625 4.69961 +29.4085 4.98742 +29.3512 5.27467 +29.2907 5.56133 +29.2269 5.84738 +29.1598 6.13277 +29.0895 6.41748 +29.016 6.70148 +28.9392 6.98473 +28.8592 7.2672 +28.776 7.54887 +28.6896 7.82969 +28.6 8.10964 +28.5072 8.38868 +28.4112 8.66679 +28.312 8.94393 +28.2097 9.22008 +28.1043 9.49519 +27.9957 9.76925 +27.884 10.0422 +27.7691 10.3141 +27.6512 10.5848 +27.5302 10.8543 +27.4061 11.1226 +27.279 11.3896 +27.1488 11.6554 +27.0156 11.9199 +26.8793 12.1831 +26.7401 12.4449 +26.5979 12.7053 +26.4527 12.9643 +26.3045 13.2218 +26.1535 13.4779 +25.9994 13.7324 +25.8425 13.9855 +25.6827 14.2369 +25.5201 14.4868 +25.3546 14.735 +25.1862 14.9816 +25.015 15.2266 +24.8411 15.4698 +24.6643 15.7113 +24.4848 15.951 +24.3026 16.189 +24.1177 16.4251 +23.93 16.6595 +23.7397 16.8919 +23.5467 17.1225 +23.3511 17.3511 +23.1529 17.5778 +22.9521 17.8026 +22.7487 18.0253 +22.5428 18.2461 +22.3344 18.4648 +22.1234 18.6814 +21.91 18.8959 +21.6942 19.1084 +21.4759 19.3187 +21.2552 19.5268 +21.0321 19.7327 +20.8067 19.9365 +20.579 20.138 +20.3489 20.3373 +20.1166 20.5342 +19.882 20.7289 +19.6453 20.9213 +19.4063 21.1114 +19.1651 21.299 +18.9218 21.4843 +18.6764 21.6672 +18.4289 21.8477 +18.1793 22.0257 +17.9277 22.2013 +17.6742 22.3744 +17.4186 22.5449 +17.1611 22.713 +16.9016 22.8785 +16.6403 23.0415 +16.3771 23.2019 +16.1121 23.3597 +15.8453 23.5149 +15.5767 23.6675 +15.3064 23.8174 +15.0343 23.9646 +14.7606 24.1092 +14.4852 24.2511 +14.2083 24.3903 +13.9297 24.5268 +13.6496 24.6605 +13.3679 24.7914 +13.0848 24.9196 +12.8002 25.045 +12.5141 25.1677 +12.2267 25.2875 +11.9379 25.4045 +11.6478 25.5186 +11.3564 25.6299 +11.0637 25.7384 +10.7697 25.8439 +10.4746 25.9466 +10.1783 26.0464 +9.8809 26.1433 +9.58237 26.2373 +9.28277 26.3284 +8.98213 26.4165 +8.6805 26.5016 +8.3779 26.5839 +8.07436 26.6631 +7.76993 26.7394 +7.46463 26.8127 +7.1585 26.883 +6.85157 26.9504 +6.54388 27.0147 +6.23546 27.076 +5.92635 27.1343 +5.61657 27.1896 +5.30617 27.2418 +4.99518 27.291 +4.68364 27.3372 +4.37157 27.3804 +4.05902 27.4205 +3.74601 27.4575 +3.43259 27.4915 +3.11879 27.5224 +2.80464 27.5503 +2.49018 27.5751 +2.17544 27.5969 +1.86046 27.6156 +1.54527 27.6312 +1.22991 27.6438 +0.91442 27.6533 +0.598823 27.6597 +0.28316 27.663 +-0.0325346 27.6633 +-0.348225 27.6605 +-0.663878 27.6546 +-0.979456 27.6457 +-1.29493 27.6337 +-1.61025 27.6187 +-1.9254 27.6006 +-2.24034 27.5794 +-2.55502 27.5551 +-2.86943 27.5279 +-3.18351 27.4975 +-3.49725 27.4642 +-3.81059 27.4278 +-4.12352 27.3883 +-4.43599 27.3458 +-4.74797 27.3003 +-5.05942 27.2518 +-5.37032 27.2003 +-5.68062 27.1457 +-5.99029 27.0882 +-6.2993 27.0277 +-6.60761 26.9642 +-6.9152 26.8977 +-7.22202 26.8282 +-7.52804 26.7558 +-7.83324 26.6804 +-8.13756 26.6021 +-8.44099 26.5208 +-8.74349 26.4366 +-9.04503 26.3495 +-9.34557 26.2595 +-9.64507 26.1666 +-9.94352 26.0709 +-10.2409 25.9722 +-10.5371 25.8707 +-10.8322 25.7664 +-11.126 25.6592 +-11.4187 25.5491 +-11.7101 25.4363 +-12.0002 25.3207 +-12.2889 25.2023 +-12.5764 25.0811 +-12.8624 24.9572 +-13.1471 24.8305 +-13.4303 24.7011 +-13.712 24.569 +-13.9922 24.4342 +-14.2709 24.2967 +-14.548 24.1565 +-14.8235 24.0137 +-15.0974 23.8683 +-15.3696 23.7202 +-15.6402 23.5696 +-15.909 23.4163 +-16.1761 23.2605 +-16.4414 23.1022 +-16.7049 22.9413 +-16.9666 22.7779 +-17.2265 22.612 +-17.4844 22.4436 +-17.7404 22.2728 +-17.9945 22.0995 +-18.2467 21.9239 +-18.4968 21.7458 +-18.7449 21.5654 +-18.991 21.3826 +-19.235 21.1974 +-19.4769 21.01 +-19.7167 20.8203 +-19.9543 20.6283 +-20.1897 20.434 +-20.423 20.2375 +-20.654 20.0388 +-20.8828 19.8379 +-21.1092 19.6349 +-21.3334 19.4297 +-21.5553 19.2224 +-21.7748 19.013 +-21.992 18.8016 +-22.2067 18.5881 +-22.4191 18.3726 +-22.629 18.155 +-22.8364 17.9355 +-23.0414 17.7141 +-23.2438 17.4907 +-23.4438 17.2654 +-23.6412 17.0383 +-23.836 16.8093 +-24.0282 16.5785 +-24.2179 16.3459 +-24.4049 16.1115 +-24.5892 15.8753 +-24.7709 15.6375 +-24.9499 15.3979 +-25.1262 15.1567 +-25.2998 14.9138 +-25.4706 14.6694 +-25.6387 14.4233 +-25.804 14.1757 +-25.9665 13.9265 +-26.1262 13.6758 +-26.2831 13.4237 +-26.4371 13.1701 +-26.5883 12.915 +-26.7366 12.6586 +-26.882 12.4008 +-27.0245 12.1417 +-27.1641 11.8813 +-27.3007 11.6195 +-27.4344 11.3566 +-27.5652 11.0924 +-27.693 10.8269 +-27.8177 10.5604 +-27.9395 10.2927 +-28.0583 10.0239 +-28.174 9.75396 +-28.2867 9.48301 +-28.3964 9.21104 +-28.503 8.93807 +-28.6065 8.66415 +-28.707 8.38929 +-28.8044 8.11353 +-28.8986 7.83689 +-28.9898 7.55941 +-29.0778 7.28112 +-29.1627 7.00204 +-29.2445 6.72222 +-29.3231 6.44166 +-29.3986 6.16042 +-29.4709 5.87851 +-29.5401 5.59597 +-29.6061 5.31283 +-29.6689 5.02912 +-29.7285 4.74487 +-29.7849 4.46011 +-29.8382 4.17488 +-29.8882 3.88919 +-29.935 3.60309 +-29.9786 3.3166 +-30.0191 3.02975 +-30.0562 2.74258 +-30.0902 2.45512 +-30.121 2.1674 +-30.1485 1.87944 +-30.1728 1.59128 +-30.1938 1.30295 +-30.2117 1.01448 +-30.2263 0.725901 +-30.2376 0.437245 +-30.2458 0.148543 +-30.2507 -0.140175 +-30.2523 -0.428879 +-30.2508 -0.717537 +-30.2459 -1.00612 +-30.2379 -1.29459 +-30.2266 -1.58293 +-30.2121 -1.87109 +-30.1944 -2.15906 +-30.1735 -2.44679 +-30.1493 -2.73427 +-30.1219 -3.02145 +-30.0913 -3.30831 +-30.0575 -3.59482 +-30.0204 -3.88094 +-29.9802 -4.16665 +-29.9368 -4.45191 +-29.8902 -4.7367 +-29.8403 -5.02098 +-29.7874 -5.30473 +-29.7312 -5.58791 +-29.6718 -5.8705 +-29.6093 -6.15246 +-29.5437 -6.43376 +-29.4749 -6.71438 +-29.4029 -6.99428 +-29.3279 -7.27344 +-29.2497 -7.55183 +-29.1684 -7.82941 +-29.0839 -8.10616 +-28.9964 -8.38204 +-28.9058 -8.65703 +-28.8121 -8.9311 +-28.7154 -9.20422 +-28.6156 -9.47636 +-28.5127 -9.7475 +-28.4069 -10.0176 +-28.298 -10.2866 +-28.186 -10.5546 +-28.0711 -10.8214 +-27.9532 -11.087 +-27.8324 -11.3515 +-27.7085 -11.6148 +-27.5818 -11.8768 +-27.4521 -12.1376 +-27.3194 -12.3971 +-27.1839 -12.6553 +-27.0455 -12.9121 +-26.9042 -13.1676 +-26.7601 -13.4216 +-26.6131 -13.6742 +-26.4632 -13.9254 +-26.3106 -14.1751 +-26.1552 -14.4233 +-25.997 -14.67 +-25.836 -14.9151 +-25.6723 -15.1586 +-25.5059 -15.4005 +-25.3367 -15.6408 +-25.1649 -15.8794 +-24.9904 -16.1163 +-24.8132 -16.3515 +-24.6334 -16.585 +-24.451 -16.8167 +-24.266 -17.0467 +-24.0784 -17.2748 +-23.8883 -17.5011 +-23.6956 -17.7255 +-23.5004 -17.9481 +-23.3027 -18.1687 +-23.1026 -18.3874 +-22.9 -18.6042 +-22.6949 -18.819 +-22.4875 -19.0318 +-22.2776 -19.2425 +-22.0654 -19.4513 +-21.8509 -19.6579 +-21.634 -19.8625 +-21.4149 -20.065 +-21.1935 -20.2653 +-20.9698 -20.4635 +-20.7439 -20.6595 +-20.5158 -20.8534 +-20.2855 -21.045 +-20.053 -21.2344 +-19.8185 -21.4215 +-19.5818 -21.6063 +-19.3431 -21.7889 +-19.1023 -21.9691 +-18.8594 -22.147 +-18.6146 -22.3226 +-18.3678 -22.4958 +-18.119 -22.6666 +-17.8684 -22.835 +-17.6158 -23.0009 +-17.3613 -23.1645 +-17.105 -23.3255 +-16.8469 -23.4841 +-16.587 -23.6402 +-16.3253 -23.7938 +-16.062 -23.9448 +-15.7968 -24.0933 +-15.5301 -24.2393 +-15.2616 -24.3827 +-14.9916 -24.5235 +-14.7199 -24.6616 +-14.4467 -24.7972 +-14.172 -24.9301 +-13.8957 -25.0604 +-13.618 -25.188 +-13.3388 -25.313 +-13.0582 -25.4352 +-12.7762 -25.5547 +-12.4929 -25.6716 +-12.2082 -25.7857 +-11.9223 -25.897 +-11.635 -26.0056 +-11.3465 -26.1114 +-11.0569 -26.2145 +-10.766 -26.3147 +-10.474 -26.4122 +-10.1809 -26.5069 +-9.88668 -26.5987 +-9.59142 -26.6877 +-9.29515 -26.7739 +-8.99788 -26.8572 +-8.69966 -26.9376 +-8.40051 -27.0152 +-8.10047 -27.0899 +-7.79956 -27.1617 +-7.49782 -27.2307 +-7.19529 -27.2967 +-6.89199 -27.3598 +-6.58795 -27.42 +-6.28321 -27.4773 +-5.97781 -27.5317 +-5.67176 -27.5831 +-5.36511 -27.6315 +-5.05789 -27.6771 +-4.75013 -27.7196 +-4.44186 -27.7593 +-4.13312 -27.7959 +-3.82393 -27.8296 +-3.51434 -27.8603 +-3.20438 -27.8881 +-2.89407 -27.9128 +-2.58345 -27.9346 +-2.27256 -27.9534 +-1.96143 -27.9692 +-1.65008 -27.9821 +-1.33856 -27.9919 +-1.0269 -27.9987 +-0.715125 -28.0026 +-0.403277 -28.0034 +-0.0913854 -28.0013 +0.220515 -27.9962 +0.532392 -27.988 +0.844211 -27.9769 +1.15594 -27.9628 +1.46754 -27.9457 +1.77899 -27.9255 +2.09025 -27.9024 +2.40128 -27.8764 +2.71206 -27.8473 +3.02254 -27.8152 +3.3327 -27.7802 +3.6425 -27.7422 +3.95191 -27.7012 +4.2609 -27.6572 +4.56943 -27.6102 +4.87747 -27.5603 +5.18499 -27.5075 +5.49195 -27.4517 +5.79832 -27.3929 +6.10407 -27.3312 +6.40916 -27.2666 +6.71356 -27.199 +7.01724 -27.1285 +7.32016 -27.0551 +7.6223 -26.9788 +7.92362 -26.8996 +8.22408 -26.8175 +8.52366 -26.7325 +8.82232 -26.6446 +9.12003 -26.5539 +9.41676 -26.4603 +9.71248 -26.3638 +10.0071 -26.2645 +10.3007 -26.1624 +10.5932 -26.0574 +10.8846 -25.9497 +11.1747 -25.8391 +11.4637 -25.7258 +11.7514 -25.6097 +12.0378 -25.4908 +12.323 -25.3692 +12.6068 -25.2448 +12.8893 -25.1177 +13.1703 -24.9879 +13.45 -24.8554 +13.7282 -24.7202 +14.0049 -24.5823 +14.2801 -24.4418 +14.5537 -24.2986 +14.8258 -24.1528 +15.0962 -24.0044 +15.3651 -23.8534 +15.6322 -23.6998 +15.8977 -23.5436 +16.1614 -23.3849 +16.4234 -23.2236 +16.6836 -23.0598 +16.942 -22.8936 +17.1986 -22.7248 +17.4533 -22.5536 +17.7061 -22.3799 +17.957 -22.2038 +18.2059 -22.0253 +18.4529 -21.8444 +18.6978 -21.6611 +18.9407 -21.4755 +19.1816 -21.2875 +19.4204 -21.0972 +19.657 -20.9046 +19.8915 -20.7098 +20.1239 -20.5127 +20.3541 -20.3133 +20.582 -20.1118 +20.8077 -19.908 +21.0311 -19.7021 +21.2523 -19.4941 +21.4711 -19.2839 +21.6876 -19.0716 +21.9017 -18.8572 +22.1134 -18.6408 +22.3228 -18.4223 +22.5296 -18.2018 +22.7341 -17.9794 +22.936 -17.7549 +23.1354 -17.5286 +23.3323 -17.3003 +23.5267 -17.0701 +23.7185 -16.8381 +23.9077 -16.6042 +24.0942 -16.3685 +24.2782 -16.131 +24.4595 -15.8917 +24.6381 -15.6507 +24.814 -15.408 +24.9871 -15.1636 +25.1576 -14.9175 +25.3253 -14.6698 +25.4902 -14.4205 +25.6523 -14.1696 +25.8116 -13.9172 +25.9681 -13.6632 +26.1217 -13.4077 +26.2725 -13.1508 +26.4204 -12.8924 +26.5653 -12.6326 +26.7074 -12.3714 +26.8465 -12.1089 +26.9827 -11.845 +27.1159 -11.5798 +27.2461 -11.3133 +27.3733 -11.0456 +27.4975 -10.7767 +27.6187 -10.5066 +27.7369 -10.2353 +27.852 -9.96293 +27.964 -9.68944 +28.0729 -9.41489 +28.1788 -9.13929 +28.2815 -8.86269 +28.3811 -8.58511 +28.4776 -8.30659 +28.571 -8.02715 +28.6612 -7.74682 +28.7482 -7.46564 +28.8321 -7.18363 +28.9128 -6.90083 +28.9903 -6.61727 +29.0645 -6.33297 +29.1356 -6.04798 +29.2035 -5.76231 +29.2681 -5.47601 +29.3295 -5.18911 +29.3876 -4.90163 +29.4425 -4.6136 +29.4942 -4.32507 +29.5425 -4.03606 +29.5876 -3.7466 +29.6295 -3.45672 +29.668 -3.16647 +29.7033 -2.87586 +29.7352 -2.58493 +29.7639 -2.29372 +29.7893 -2.00225 +29.8113 -1.71056 +29.8301 -1.41868 +29.8455 -1.12665 +29.8577 -0.834485 +29.8665 -0.54223 +29.872 -0.249915 +29.8742 0.0424291 +29.8731 0.334768 +29.8687 0.627071 +29.8609 0.919304 +29.8499 1.21144 +29.8355 1.50343 +29.8178 1.79526 +29.7968 2.08689 +29.7724 2.37829 +29.7448 2.66943 +29.7139 2.96026 +29.6796 3.25077 +29.6421 3.54092 +29.6012 3.83067 +29.5571 4.12 +29.5096 4.40887 +29.4589 4.69725 +29.4049 4.9851 +29.3477 5.2724 +29.2871 5.55911 +29.2233 5.84521 +29.1563 6.13065 +29.0859 6.41541 +29.0124 6.69945 +28.9356 6.98275 +28.8556 7.26527 +28.7724 7.54698 +28.686 7.82785 +28.5963 8.10785 +28.5035 8.38694 +28.4075 8.6651 +28.3083 8.94229 +28.206 9.21848 +28.1005 9.49365 +27.9919 9.76775 +27.8802 10.0408 +27.7654 10.3127 +27.6474 10.5834 +27.5264 10.853 +27.4023 11.1213 +27.2751 11.3884 +27.1449 11.6543 +27.0117 11.9188 +26.8754 12.182 +26.7362 12.4438 +26.5939 12.7043 +26.4487 12.9633 +26.3005 13.2209 +26.1494 13.477 +25.9954 13.7316 +25.8384 13.9846 +25.6786 14.2361 +25.5159 14.4861 +25.3504 14.7343 +25.182 14.981 +25.0108 15.2259 +24.8368 15.4692 +24.66 15.7107 +24.4805 15.9505 +24.2982 16.1885 +24.1132 16.4247 +23.9255 16.659 +23.7352 16.8915 +23.5421 17.1221 +23.3465 17.3508 +23.1482 17.5775 +22.9474 17.8023 +22.744 18.0251 +22.538 18.2458 +22.3295 18.4646 +22.1185 18.6812 +21.9051 18.8958 +21.6892 19.1083 +21.4709 19.3186 +21.2501 19.5267 +21.027 19.7327 +20.8016 19.9365 +20.5738 20.138 +20.3437 20.3373 +20.1113 20.5343 +19.8767 20.729 +19.6399 20.9214 +19.4008 21.1115 +19.1596 21.2992 +18.9163 21.4845 +18.6708 21.6674 +18.4233 21.8479 +18.1737 22.0259 +17.922 22.2015 +17.6684 22.3746 +17.4128 22.5452 +17.1552 22.7133 +16.8957 22.8788 +16.6344 23.0418 +16.3711 23.2022 +16.1061 23.36 +15.8392 23.5152 +15.5706 23.6678 +15.3002 23.8177 +15.0281 23.9649 +14.7544 24.1095 +14.479 24.2514 +14.2019 24.3906 +13.9233 24.5271 +13.6432 24.6608 +13.3615 24.7918 +13.0783 24.9199 +12.7936 25.0454 +12.5076 25.168 +12.2201 25.2878 +11.9313 25.4048 +11.6411 25.5189 +11.3497 25.6302 +11.0569 25.7386 +10.763 25.8442 +10.4678 25.9469 +10.1715 26.0467 +9.874 26.1435 +9.57543 26.2375 +9.27579 26.3285 +8.97512 26.4167 +8.67345 26.5018 +8.37082 26.584 +8.06724 26.6633 +7.76278 26.7395 +7.45744 26.8128 +7.15127 26.8831 +6.84431 26.9504 +6.53659 27.0147 +6.22814 27.076 +5.91899 27.1343 +5.60919 27.1896 +5.29876 27.2418 +4.98774 27.291 +4.67617 27.3372 +4.36407 27.3803 +4.05149 27.4204 +3.73846 27.4574 +3.42502 27.4914 +3.11119 27.5223 +2.79702 27.5502 +2.48253 27.5749 +2.16777 27.5967 +1.85277 27.6154 +1.53756 27.631 +1.22219 27.6435 +0.906673 27.653 +0.591059 27.6594 +0.275379 27.6627 +-0.0403313 27.6629 +-0.356037 27.6601 +-0.671703 27.6542 +-0.987295 27.6453 +-1.30278 27.6333 +-1.61811 27.6182 +-1.93327 27.6001 +-2.24822 27.5789 +-2.56291 27.5546 +-2.87732 27.5273 +-3.19141 27.497 +-3.50515 27.4636 +-3.8185 27.4272 +-4.13143 27.3877 +-4.4439 27.3452 +-4.75588 27.2997 +-5.06734 27.2512 +-5.37823 27.1996 +-5.68853 27.145 +-5.9982 27.0875 +-6.30721 27.0269 +-6.61552 26.9634 +-6.9231 26.8969 +-7.22992 26.8274 +-7.53593 26.755 +-7.84112 26.6796 +-8.14544 26.6013 +-8.44886 26.52 +-8.75135 26.4358 +-9.05288 26.3487 +-9.3534 26.2587 +-9.6529 26.1658 +-9.95133 26.07 +-10.2487 25.9713 +-10.5449 25.8698 +-10.8399 25.7654 +-11.1338 25.6582 +-11.4264 25.5482 +-11.7178 25.4354 +-12.0079 25.3197 +-12.2966 25.2013 +-12.584 25.0801 +-12.8701 24.9562 +-13.1547 24.8295 +-13.4379 24.7001 +-13.7196 24.568 +-13.9997 24.4332 +-14.2784 24.2957 +-14.5555 24.1555 +-14.831 24.0127 +-15.1049 23.8672 +-15.3771 23.7192 +-15.6476 23.5685 +-15.9164 23.4153 +-16.1835 23.2595 +-16.4488 23.1011 +-16.7123 22.9402 +-16.974 22.7769 +-17.2338 22.611 +-17.4917 22.4426 +-17.7477 22.2718 +-18.0018 22.0986 +-18.2539 21.9229 +-18.504 21.7449 +-18.7521 21.5644 +-18.9982 21.3817 +-19.2421 21.1965 +-19.484 21.0091 +-19.7238 20.8194 +-19.9614 20.6274 +-20.1968 20.4332 +-20.43 20.2367 +-20.661 20.038 +-20.8898 19.8372 +-21.1162 19.6342 +-21.3404 19.429 +-21.5622 19.2217 +-21.7817 19.0124 +-21.9989 18.801 +-22.2136 18.5875 +-22.4259 18.372 +-22.6358 18.1545 +-22.8432 17.9351 +-23.0482 17.7136 +-23.2506 17.4903 +-23.4505 17.2651 +-23.6479 17.038 +-23.8427 16.809 +-24.0349 16.5782 +-24.2245 16.3457 +-24.4115 16.1113 +-24.5959 15.8752 +-24.7775 15.6374 +-24.9565 15.3979 +-25.1328 15.1567 +-25.3064 14.9139 +-25.4772 14.6695 +-25.6453 14.4234 +-25.8106 14.1759 +-25.9731 13.9267 +-26.1327 13.6761 +-26.2896 13.424 +-26.4436 13.1705 +-26.5948 12.9155 +-26.7431 12.6591 +-26.8885 12.4014 +-27.031 12.1423 +-27.1706 11.8819 +-27.3072 11.6203 +-27.4409 11.3574 +-27.5717 11.0932 +-27.6995 10.8279 +-27.8243 10.5614 +-27.946 10.2937 +-28.0648 10.0249 +-28.1806 9.75511 +-28.2933 9.48422 +-28.403 9.21231 +-28.5096 8.93941 +-28.6131 8.66555 +-28.7136 8.39075 +-28.811 8.11506 +-28.9053 7.83848 +-28.9964 7.56107 +-29.0845 7.28285 +-29.1694 7.00384 +-29.2512 6.72408 +-29.3299 6.44359 +-29.4054 6.16242 +-29.4778 5.88058 +-29.547 5.59811 +-29.613 5.31504 +-29.6758 5.0314 +-29.7355 4.74722 +-29.7919 4.46253 +-29.8452 4.17736 +-29.8953 3.89175 +-29.9422 3.60572 +-29.9858 3.3193 +-30.0263 3.03252 +-30.0635 2.74542 +-30.0976 2.45803 +-30.1284 2.17037 +-30.1559 1.88249 +-30.1803 1.5944 +-30.2014 1.30614 +-30.2193 1.01774 +-30.2339 0.72923 +-30.2454 0.440644 +-30.2536 0.152011 +-30.2585 -0.136638 +-30.2603 -0.425272 +-30.2587 -0.713861 +-30.254 -1.00237 +-30.246 -1.29078 +-30.2348 -1.57905 +-30.2204 -1.86714 +-30.2028 -2.15504 +-30.1819 -2.44271 +-30.1578 -2.73012 +-30.1305 -3.01724 +-30.0999 -3.30404 +-30.0662 -3.59048 +-30.0292 -3.87654 +-29.9891 -4.16219 +-29.9458 -4.44739 +-29.8992 -4.73212 +-29.8495 -5.01634 +-29.7966 -5.30003 +-29.7405 -5.58316 +-29.6813 -5.86569 +-29.6189 -6.14759 +-29.5533 -6.42885 +-29.4846 -6.70941 +-29.4127 -6.98927 +-29.3378 -7.26838 +-29.2597 -7.54671 +-29.1784 -7.82424 +-29.0941 -8.10095 +-29.0067 -8.37679 +-28.9162 -8.65174 +-28.8226 -8.92576 +-28.726 -9.19885 +-28.6263 -9.47095 +-28.5236 -9.74204 +-28.4178 -10.0121 +-28.309 -10.2811 +-28.1972 -10.549 +-28.0824 -10.8158 +-27.9646 -11.0814 +-27.8439 -11.3459 +-27.7202 -11.6091 +-27.5935 -11.8712 +-27.4639 -12.1319 +-27.3314 -12.3914 +-27.196 -12.6495 +-27.0577 -12.9063 +-26.9166 -13.1618 +-26.7725 -13.4158 +-26.6257 -13.6684 +-26.476 -13.9196 +-26.3235 -14.1693 +-26.1682 -14.4175 +-26.0101 -14.6641 +-25.8493 -14.9092 +-25.6857 -15.1528 +-25.5194 -15.3947 +-25.3504 -15.635 +-25.1787 -15.8736 +-25.0043 -16.1105 +-24.8273 -16.3457 +-24.6476 -16.5792 +-24.4654 -16.8109 +-24.2805 -17.0409 +-24.0931 -17.269 +-23.9031 -17.4953 +-23.7105 -17.7198 +-23.5155 -17.9424 +-23.3179 -18.163 +-23.1179 -18.3818 +-22.9155 -18.5986 +-22.7106 -18.8134 +-22.5032 -19.0262 +-22.2935 -19.237 +-22.0815 -19.4458 +-21.8671 -19.6525 +-21.6504 -19.8571 +-21.4313 -20.0596 +-21.2101 -20.26 +-20.9865 -20.4582 +-20.7607 -20.6543 +-20.5328 -20.8482 +-20.3026 -21.0398 +-20.0703 -21.2293 +-19.8359 -21.4164 +-19.5994 -21.6014 +-19.3608 -21.784 +-19.1201 -21.9643 +-18.8774 -22.1423 +-18.6327 -22.3179 +-18.386 -22.4911 +-18.1374 -22.662 +-17.8868 -22.8305 +-17.6344 -22.9965 +-17.3801 -23.1601 +-17.1239 -23.3213 +-16.8659 -23.48 +-16.6062 -23.6361 +-16.3446 -23.7898 +-16.0813 -23.9409 +-15.8164 -24.0896 +-15.5497 -24.2356 +-15.2814 -24.3791 +-15.0115 -24.52 +-14.74 -24.6583 +-14.4669 -24.7939 +-14.1922 -24.9269 +-13.9161 -25.0573 +-13.6385 -25.1851 +-13.3594 -25.3101 +-13.079 -25.4325 +-12.7971 -25.5521 +-12.5139 -25.6691 +-12.2293 -25.7833 +-11.9435 -25.8948 +-11.6563 -26.0035 +-11.368 -26.1094 +-11.0784 -26.2126 +-10.7876 -26.313 +-10.4957 -26.4106 +-10.2027 -26.5054 +-9.90863 -26.5974 +-9.61347 -26.6865 +-9.3173 -26.7728 +-9.02013 -26.8563 +-8.722 -26.9369 +-8.42294 -27.0146 +-8.12299 -27.0895 +-7.82217 -27.1614 +-7.52052 -27.2305 +-7.21807 -27.2967 +-6.91486 -27.3599 +-6.6109 -27.4203 +-6.30624 -27.4777 +-6.00091 -27.5322 +-5.69494 -27.5838 +-5.38836 -27.6324 +-5.08121 -27.6781 +-4.77352 -27.7209 +-4.46532 -27.7606 +-4.15664 -27.7975 +-3.84752 -27.8313 +-3.53799 -27.8622 +-3.22808 -27.8901 +-2.91783 -27.915 +-2.60727 -27.937 +-2.29642 -27.9559 +-1.98533 -27.9719 +-1.67403 -27.9849 +-1.36255 -27.9949 +-1.05093 -28.0019 +-0.739192 -28.0059 +-0.427375 -28.007 +-0.115513 -28.005 +0.196361 -28 +0.508215 -27.9921 +0.820014 -27.9811 +1.13172 -27.9671 +1.44332 -27.9502 +1.75475 -27.9303 +2.066 -27.9073 +2.37702 -27.8814 +2.6878 -27.8525 +2.99828 -27.8206 +3.30844 -27.7858 +3.61825 -27.7479 +3.92767 -27.7071 +4.23667 -27.6633 +4.54521 -27.6166 +4.85327 -27.5668 +5.16081 -27.5142 +5.46779 -27.4585 +5.77419 -27.3999 +6.07997 -27.3384 +6.38509 -27.274 +6.68953 -27.2066 +6.99324 -27.1363 +7.29621 -27.063 +7.59839 -26.9869 +7.89976 -26.9079 +8.20027 -26.8259 +8.49991 -26.7411 +8.79862 -26.6534 +9.09639 -26.5629 +9.39318 -26.4695 +9.68896 -26.3732 +9.9837 -26.2741 +10.2774 -26.1721 +10.5699 -26.0674 +10.8613 -25.9598 +11.1516 -25.8494 +11.4406 -25.7363 +11.7284 -25.6203 +12.0149 -25.5016 +12.3002 -25.3802 +12.5841 -25.256 +12.8666 -25.129 +13.1478 -24.9994 +13.4275 -24.8671 +13.7058 -24.7321 +13.9826 -24.5944 +14.2579 -24.454 +14.5317 -24.311 +14.8039 -24.1654 +15.0744 -24.0171 +15.3434 -23.8663 +15.6107 -23.7128 +15.8763 -23.5568 +16.1401 -23.3983 +16.4022 -23.2372 +16.6626 -23.0736 +16.9211 -22.9075 +17.1778 -22.7389 +17.4327 -22.5678 +17.6856 -22.3943 +17.9366 -22.2184 +18.1857 -22.04 +18.4328 -21.8593 +18.6779 -21.6762 +18.921 -21.4907 +19.162 -21.3029 +19.4009 -21.1127 +19.6377 -20.9203 +19.8724 -20.7256 +20.1049 -20.5286 +20.3352 -20.3294 +20.5633 -20.128 +20.7892 -19.9244 +21.0128 -19.7187 +21.2341 -19.5107 +21.4531 -19.3007 +21.6698 -19.0885 +21.8841 -18.8743 +22.096 -18.658 +22.3055 -18.4397 +22.5126 -18.2193 +22.7172 -17.997 +22.9193 -17.7727 +23.1189 -17.5465 +23.316 -17.3183 +23.5105 -17.0882 +23.7025 -16.8563 +23.8919 -16.6226 +24.0786 -16.387 +24.2628 -16.1496 +24.4443 -15.9104 +24.6231 -15.6696 +24.7992 -15.427 +24.9725 -15.1827 +25.1432 -14.9367 +25.3111 -14.6891 +25.4762 -14.4399 +25.6385 -14.1891 +25.798 -13.9368 +25.9547 -13.6829 +26.1085 -13.4275 +26.2595 -13.1706 +26.4076 -12.9123 +26.5528 -12.6526 +26.695 -12.3915 +26.8343 -12.129 +26.9707 -11.8652 +27.1041 -11.6001 +27.2345 -11.3337 +27.362 -11.0661 +27.4864 -10.7972 +27.6078 -10.5272 +27.7261 -10.256 +27.8414 -9.98366 +27.9537 -9.71023 +28.0628 -9.43573 +28.1689 -9.16019 +28.2718 -8.88363 +28.3717 -8.6061 +28.4684 -8.32762 +28.5619 -8.04822 +28.6523 -7.76793 +28.7396 -7.48678 +28.8237 -7.20481 +28.9046 -6.92204 +28.9822 -6.6385 +29.0567 -6.35423 +29.128 -6.06926 +29.1961 -5.78362 +29.2609 -5.49733 +29.3225 -5.21044 +29.3808 -4.92297 +29.4359 -4.63496 +29.4878 -4.34643 +29.5364 -4.05742 +29.5817 -3.76796 +29.6237 -3.47808 +29.6624 -3.18781 +29.6979 -2.8972 +29.7301 -2.60626 +29.7589 -2.31503 +29.7845 -2.02354 +29.8068 -1.73183 +29.8257 -1.43993 +29.8414 -1.14787 +29.8537 -0.855677 +29.8628 -0.563392 +29.8685 -0.271044 +29.8709 0.021335 +29.87 0.313712 +29.8657 0.606054 +29.8582 0.898329 +29.8473 1.1905 +29.8331 1.48255 +29.8156 1.77443 +29.7948 2.06611 +29.7707 2.35756 +29.7432 2.64875 +29.7125 2.93965 +29.6784 3.23022 +29.641 3.52043 +29.6004 3.81025 +29.5564 4.09964 +29.5092 4.38858 +29.4586 4.67703 +29.4048 4.96495 +29.3477 5.25233 +29.2874 5.53912 +29.2237 5.82529 +29.1569 6.11081 +29.0867 6.39565 +29.0134 6.67978 +28.9367 6.96317 +28.8569 7.24577 +28.7739 7.52757 +28.6876 7.80853 +28.5981 8.08862 +28.5055 8.36781 +28.4096 8.64606 +28.3106 8.92335 +28.2085 9.19964 +28.1031 9.4749 +27.9947 9.74911 +27.8831 10.0222 +27.7684 10.2942 +27.6506 10.5651 +27.5297 10.8347 +27.4058 11.1032 +27.2787 11.3704 +27.1487 11.6364 +27.0156 11.901 +26.8794 12.1643 +26.7403 12.4263 +26.5982 12.6869 +26.4531 12.946 +26.3051 13.2037 +26.1541 13.46 +26.0002 13.7147 +25.8433 13.9679 +25.6836 14.2195 +25.521 14.4695 +25.3556 14.7179 +25.1873 14.9647 +25.0162 15.2098 +24.8423 15.4532 +24.6657 15.6949 +24.4863 15.9348 +24.3041 16.1729 +24.1192 16.4093 +23.9316 16.6437 +23.7414 16.8764 +23.5484 17.1071 +23.3529 17.3359 +23.1547 17.5628 +22.954 17.7877 +22.7506 18.0107 +22.5448 18.2316 +22.3364 18.4504 +22.1255 18.6672 +21.9121 18.882 +21.6963 19.0946 +21.478 19.305 +21.2574 19.5133 +21.0343 19.7195 +20.8089 19.9234 +20.5812 20.1251 +20.3512 20.3245 +20.1189 20.5217 +19.8844 20.7165 +19.6476 20.9091 +19.4086 21.0993 +19.1675 21.2871 +18.9242 21.4726 +18.6788 21.6557 +18.4313 21.8363 +18.1817 22.0145 +17.9301 22.1902 +17.6765 22.3635 +17.421 22.5342 +17.1635 22.7025 +16.904 22.8682 +16.6427 23.0313 +16.3795 23.1919 +16.1145 23.3498 +15.8476 23.5052 +15.579 23.6579 +15.3087 23.808 +15.0366 23.9554 +14.7629 24.1001 +14.4875 24.2422 +14.2105 24.3815 +13.9319 24.5181 +13.6518 24.652 +13.3701 24.7831 +13.087 24.9114 +12.8023 25.037 +12.5163 25.1597 +12.2288 25.2797 +11.94 25.3968 +11.6498 25.5111 +11.3584 25.6226 +11.0657 25.7311 +10.7717 25.8369 +10.4765 25.9397 +10.1802 26.0396 +9.88273 26.1366 +9.58416 26.2307 +9.28452 26.3219 +8.98384 26.4102 +8.68216 26.4955 +8.37951 26.5778 +8.07593 26.6572 +7.77145 26.7336 +7.4661 26.807 +7.15992 26.8775 +6.85294 26.9449 +6.54519 27.0094 +6.23672 27.0708 +5.92755 27.1292 +5.61773 27.1846 +5.30728 27.237 +4.99623 27.2863 +4.68463 27.3326 +4.37251 27.3759 +4.05991 27.4161 +3.74685 27.4533 +3.43338 27.4874 +3.11952 27.5184 +2.80532 27.5464 +2.4908 27.5714 +2.17601 27.5932 +1.86098 27.612 +1.54574 27.6278 +1.23033 27.6404 +0.914779 27.65 +0.599129 27.6566 +0.283412 27.66 +-0.0323355 27.6604 +-0.34808 27.6577 +-0.663785 27.652 +-0.979416 27.6432 +-1.29494 27.6313 +-1.61032 27.6163 +-1.92552 27.5983 +-2.2405 27.5773 +-2.55524 27.5531 +-2.8697 27.526 +-3.18383 27.4957 +-3.49762 27.4625 +-3.81101 27.4262 +-4.12399 27.3868 +-4.4365 27.3444 +-4.74853 27.299 +-5.06003 27.2506 +-5.37097 27.1992 +-5.68132 27.1448 +-5.99104 27.0873 +-6.3001 27.0269 +-6.60846 26.9635 +-6.91609 26.8971 +-7.22296 26.8277 +-7.52903 26.7554 +-7.83427 26.6801 +-8.13865 26.6019 +-8.44213 26.5207 +-8.74468 26.4366 +-9.04626 26.3496 +-9.34685 26.2597 +-9.6464 26.1669 +-9.9449 26.0713 +-10.2423 25.9727 +-10.5386 25.8713 +-10.8337 25.767 +-11.1276 25.66 +-11.4203 25.55 +-11.7117 25.4373 +-12.0019 25.3218 +-12.2907 25.2035 +-12.5782 25.0824 +-12.8643 24.9586 +-13.149 24.832 +-13.4322 24.7027 +-13.714 24.5707 +-13.9942 24.436 +-14.273 24.2986 +-14.5501 24.1585 +-14.8257 24.0158 +-15.0996 23.8705 +-15.3719 23.7225 +-15.6425 23.572 +-15.9114 23.4188 +-16.1786 23.2631 +-16.4439 23.1049 +-16.7075 22.9441 +-16.9693 22.7808 +-17.2291 22.6151 +-17.4872 22.4468 +-17.7433 22.2761 +-17.9974 22.103 +-18.2496 21.9274 +-18.4998 21.7495 +-18.748 21.5692 +-18.9941 21.3865 +-19.2382 21.2015 +-19.4801 21.0142 +-19.72 20.8245 +-19.9576 20.6327 +-20.1931 20.4385 +-20.4265 20.2422 +-20.6575 20.0436 +-20.8864 19.8428 +-21.1129 19.6399 +-21.3372 19.4349 +-21.5591 19.2277 +-21.7787 19.0185 +-21.9959 18.8072 +-22.2108 18.5938 +-22.4232 18.3784 +-22.6332 18.161 +-22.8407 17.9417 +-23.0457 17.7203 +-23.2483 17.4971 +-23.4483 17.272 +-23.6457 17.045 +-23.8406 16.8161 +-24.033 16.5854 +-24.2227 16.353 +-24.4098 16.1187 +-24.5942 15.8827 +-24.776 15.645 +-24.9551 15.4056 +-25.1314 15.1645 +-25.3051 14.9218 +-25.476 14.6774 +-25.6442 14.4315 +-25.8096 14.184 +-25.9722 13.935 +-26.132 13.6845 +-26.289 13.4325 +-26.4432 13.179 +-26.5944 12.9241 +-26.7428 12.6679 +-26.8884 12.4102 +-27.031 12.1512 +-27.1707 11.8909 +-27.3075 11.6294 +-27.4413 11.3665 +-27.5722 11.1025 +-27.7001 10.8372 +-27.825 10.5708 +-27.9469 10.3032 +-28.0658 10.0346 +-28.1817 9.76481 +-28.2946 9.49401 +-28.4044 9.22218 +-28.5111 8.94937 +-28.6148 8.67559 +-28.7154 8.40088 +-28.813 8.12527 +-28.9074 7.84878 +-28.9987 7.57145 +-29.0869 7.29331 +-29.172 7.01438 +-29.254 6.7347 +-29.3328 6.4543 +-29.4084 6.17321 +-29.481 5.89145 +-29.5503 5.60906 +-29.6165 5.32607 +-29.6795 5.04251 +-29.7393 4.75841 +-29.7959 4.4738 +-29.8494 4.18871 +-29.8996 3.90317 +-29.9466 3.61721 +-29.9905 3.33087 +-30.0311 3.04416 +-30.0685 2.75714 +-30.1027 2.46981 +-30.1337 2.18223 +-30.1614 1.89441 +-30.1859 1.60638 +-30.2072 1.31819 +-30.2253 1.02986 +-30.2401 0.741411 +-30.2518 0.452887 +-30.2601 0.164315 +-30.2653 -0.124274 +-30.2672 -0.412851 +-30.2659 -0.701383 +-30.2613 -0.98984 +-30.2535 -1.27819 +-30.2425 -1.56641 +-30.2283 -1.85445 +-30.2108 -2.1423 +-30.1901 -2.42993 +-30.1662 -2.71729 +-30.1391 -3.00436 +-30.1088 -3.29112 +-30.0752 -3.57752 +-30.0385 -3.86354 +-29.9985 -4.14915 +-29.9554 -4.43432 +-29.9091 -4.71901 +-29.8596 -5.00321 +-29.8069 -5.28687 +-29.751 -5.56997 +-29.692 -5.85247 +-29.6298 -6.13436 +-29.5644 -6.41559 +-29.4959 -6.69613 +-29.4243 -6.97597 +-29.3496 -7.25506 +-29.2717 -7.53338 +-29.1907 -7.81091 +-29.1066 -8.0876 +-29.0194 -8.36343 +-28.9291 -8.63837 +-28.8358 -8.91239 +-28.7394 -9.18547 +-28.6399 -9.45757 +-28.5374 -9.72867 +-28.4319 -9.99873 +-28.3233 -10.2677 +-28.2117 -10.5356 +-28.0972 -10.8024 +-27.9796 -11.0681 +-27.8591 -11.3326 +-27.7356 -11.5958 +-27.6092 -11.8579 +-27.4799 -12.1187 +-27.3476 -12.3781 +-27.2124 -12.6363 +-27.0744 -12.8932 +-26.9335 -13.1486 +-26.7897 -13.4027 +-26.6431 -13.6554 +-26.4936 -13.9066 +-26.3414 -14.1563 +-26.1863 -14.4045 +-26.0285 -14.6512 +-25.8679 -14.8964 +-25.7046 -15.14 +-25.5385 -15.3819 +-25.3697 -15.6222 +-25.1983 -15.8609 +-25.0242 -16.0979 +-24.8474 -16.3332 +-24.668 -16.5668 +-24.4859 -16.7986 +-24.3013 -17.0286 +-24.1141 -17.2568 +-23.9243 -17.4832 +-23.7321 -17.7077 +-23.5372 -17.9304 +-23.3399 -18.1511 +-23.1402 -18.3699 +-22.9379 -18.5868 +-22.7333 -18.8017 +-22.5262 -19.0147 +-22.3168 -19.2256 +-22.1049 -19.4344 +-21.8908 -19.6412 +-21.6743 -19.846 +-21.4555 -20.0486 +-21.2344 -20.2491 +-21.0111 -20.4474 +-20.7856 -20.6436 +-20.5578 -20.8376 +-20.3279 -21.0294 +-20.0958 -21.219 +-19.8616 -21.4063 +-19.6253 -21.5913 +-19.3869 -21.7741 +-19.1465 -21.9545 +-18.904 -22.1326 +-18.6595 -22.3084 +-18.4131 -22.4818 +-18.1647 -22.6528 +-17.9144 -22.8215 +-17.6621 -22.9877 +-17.408 -23.1514 +-17.1521 -23.3127 +-16.8943 -23.4716 +-16.6347 -23.6279 +-16.3734 -23.7818 +-16.1103 -23.9331 +-15.8456 -24.0819 +-15.5791 -24.2281 +-15.311 -24.3718 +-15.0413 -24.5129 +-14.77 -24.6513 +-14.4971 -24.7872 +-14.2226 -24.9204 +-13.9467 -25.051 +-13.6693 -25.1789 +-13.3904 -25.3042 +-13.1101 -25.4268 +-12.8284 -25.5466 +-12.5454 -25.6638 +-12.261 -25.7782 +-11.9753 -25.8899 +-11.6884 -25.9989 +-11.4002 -26.105 +-11.1108 -26.2084 +-10.8202 -26.3091 +-10.5284 -26.4069 +-10.2356 -26.5019 +-9.94165 -26.5941 +-9.64665 -26.6835 +-9.35063 -26.77 +-9.05361 -26.8537 +-8.75563 -26.9346 +-8.45672 -27.0125 +-8.15691 -27.0876 +-7.85623 -27.1599 +-7.55471 -27.2292 +-7.25239 -27.2956 +-6.9493 -27.3591 +-6.64547 -27.4197 +-6.34093 -27.4774 +-6.03571 -27.5322 +-5.72986 -27.584 +-5.42339 -27.6329 +-5.11634 -27.6789 +-4.80875 -27.7219 +-4.50065 -27.7619 +-4.19207 -27.799 +-3.88304 -27.8331 +-3.5736 -27.8643 +-3.26377 -27.8925 +-2.9536 -27.9177 +-2.64311 -27.9399 +-2.33234 -27.9592 +-2.02132 -27.9754 +-1.71009 -27.9887 +-1.39867 -27.999 +-1.0871 -28.0063 +-0.775419 -28.0106 +-0.463652 -28.0119 +-0.151836 -28.0102 +0.159997 -28.0056 +0.471812 -27.9979 +0.783578 -27.9873 +1.09526 -27.9736 +1.40682 -27.957 +1.71824 -27.9373 +2.02947 -27.9147 +2.34048 -27.8891 +2.65124 -27.8605 +2.96172 -27.8289 +3.27188 -27.7944 +3.58169 -27.7568 +3.89112 -27.7163 +4.20013 -27.6728 +4.50868 -27.6264 +4.81676 -27.577 +5.12432 -27.5246 +5.43133 -27.4693 +5.73775 -27.411 +6.04356 -27.3498 +6.34872 -27.2857 +6.6532 -27.2186 +6.95697 -27.1486 +7.25999 -27.0757 +7.56222 -26.9999 +7.86365 -26.9211 +8.16423 -26.8395 +8.46393 -26.755 +8.76272 -26.6676 +9.06056 -26.5774 +9.35744 -26.4843 +9.6533 -26.3883 +9.94812 -26.2895 +10.2419 -26.1879 +10.5345 -26.0834 +10.826 -25.9761 +11.1164 -25.8661 +11.4055 -25.7532 +11.6934 -25.6376 +11.9801 -25.5192 +12.2655 -25.398 +12.5495 -25.2742 +12.8322 -25.1475 +13.1135 -25.0182 +13.3933 -24.8862 +13.6718 -24.7514 +13.9487 -24.614 +14.2242 -24.474 +14.4981 -24.3312 +14.7704 -24.1859 +15.0412 -24.0379 +15.3103 -23.8874 +15.5777 -23.7342 +15.8435 -23.5785 +16.1075 -23.4202 +16.3699 -23.2594 +16.6304 -23.0961 +16.8891 -22.9303 +17.146 -22.7619 +17.401 -22.5912 +17.6542 -22.4179 +17.9054 -22.2422 +18.1547 -22.0641 +18.402 -21.8837 +18.6474 -21.7008 +18.8906 -21.5156 +19.1319 -21.328 +19.371 -21.1381 +19.6081 -20.946 +19.843 -20.7515 +20.0758 -20.5548 +20.3063 -20.3559 +20.5347 -20.1547 +20.7608 -19.9513 +20.9847 -19.7458 +21.2063 -19.5381 +21.4256 -19.3283 +21.6425 -19.1164 +21.8571 -18.9024 +22.0693 -18.6863 +22.279 -18.4682 +22.4864 -18.2481 +22.6913 -18.026 +22.8937 -17.8019 +23.0936 -17.5759 +23.291 -17.348 +23.4858 -17.1181 +23.6781 -16.8864 +23.8678 -16.6528 +24.0549 -16.4175 +24.2393 -16.1803 +24.4211 -15.9413 +24.6002 -15.7007 +24.7766 -15.4582 +24.9503 -15.2141 +25.1213 -14.9684 +25.2895 -14.721 +25.455 -14.4719 +25.6176 -14.2213 +25.7774 -13.9691 +25.9345 -13.7154 +26.0886 -13.4602 +26.2399 -13.2035 +26.3883 -12.9454 +26.5338 -12.6858 +26.6764 -12.4249 +26.8161 -12.1625 +26.9528 -11.8989 +27.0866 -11.6339 +27.2173 -11.3677 +27.3451 -11.1002 +27.4699 -10.8315 +27.5916 -10.5615 +27.7103 -10.2905 +27.826 -10.0182 +27.9386 -9.74493 +28.0481 -9.47054 +28.1545 -9.19511 +28.2578 -8.91866 +28.358 -8.64122 +28.455 -8.36284 +28.549 -8.08353 +28.6397 -7.80332 +28.7273 -7.52226 +28.8118 -7.24036 +28.893 -6.95767 +28.9711 -6.6742 +29.0459 -6.39 +29.1176 -6.10509 +29.186 -5.81951 +29.2512 -5.53328 +29.3131 -5.24643 +29.3719 -4.95901 +29.4273 -4.67104 +29.4795 -4.38255 +29.5285 -4.09357 +29.5741 -3.80414 +29.6165 -3.51429 +29.6556 -3.22405 +29.6915 -2.93345 +29.724 -2.64252 +29.7532 -2.3513 +29.7792 -2.05982 +29.8018 -1.76811 +29.8212 -1.47621 +29.8372 -1.18414 +29.8499 -0.891938 +29.8593 -0.599637 +29.8654 -0.307269 +29.8681 -0.0148671 +29.8676 0.277537 +29.8637 0.56991 +29.8565 0.86222 +29.846 1.15443 +29.8322 1.44652 +29.815 1.73845 +29.7945 2.03018 +29.7708 2.32169 +29.7437 2.61294 +29.7133 2.90389 +29.6796 3.19453 +29.6426 3.48481 +29.6022 3.7747 +29.5586 4.06418 +29.5117 4.35319 +29.4615 4.64173 +29.4081 4.92975 +29.3513 5.21722 +29.2913 5.5041 +29.228 5.79038 +29.1615 6.076 +29.0917 6.36095 +29.0186 6.64519 +28.9423 6.92869 +28.8628 7.21142 +28.7801 7.49334 +28.6942 7.77442 +28.605 8.05464 +28.5127 8.33396 +28.4172 8.61235 +28.3185 8.88977 +28.2166 9.1662 +28.1116 9.44161 +28.0035 9.71597 +27.8922 9.98924 +27.7778 10.2614 +27.6603 10.5324 +27.5397 10.8022 +27.416 11.0709 +27.2893 11.3382 +27.1595 11.6044 +27.0267 11.8692 +26.8908 12.1327 +26.752 12.3948 +26.6101 12.6556 +26.4653 12.9149 +26.3176 13.1728 +26.1668 13.4292 +26.0132 13.6842 +25.8566 13.9375 +25.6972 14.1894 +25.5348 14.4396 +25.3697 14.6882 +25.2016 14.9352 +25.0308 15.1805 +24.8571 15.4242 +24.6807 15.666 +24.5015 15.9062 +24.3196 16.1445 +24.1349 16.3811 +23.9476 16.6158 +23.7576 16.8486 +23.5649 17.0796 +23.3695 17.3087 +23.1716 17.5358 +22.971 17.7609 +22.7679 17.9841 +22.5623 18.2053 +22.3541 18.4244 +22.1434 18.6414 +21.9302 18.8564 +21.7146 19.0692 +21.4965 19.28 +21.276 19.4885 +21.0532 19.6949 +20.828 19.8991 +20.6004 20.101 +20.3706 20.3007 +20.1385 20.4981 +19.9041 20.6932 +19.6675 20.886 +19.4287 21.0765 +& +@target G0.S5 +@type xy +-15.5389 -25.216 +-15.262 -25.3851 +-14.9833 -25.5513 +-14.7029 -25.7146 +-14.4209 -25.8751 +-14.1373 -26.0327 +-13.8522 -26.1874 +-13.5655 -26.3392 +-13.2773 -26.4881 +-12.9876 -26.634 +-12.6965 -26.7771 +-12.404 -26.9171 +-12.1101 -27.0543 +-11.8149 -27.1884 +-11.5184 -27.3196 +-11.2207 -27.4479 +-10.9218 -27.5731 +-10.6216 -27.6954 +-10.3203 -27.8146 +-10.0179 -27.9309 +-9.71447 -28.0442 +-9.40996 -28.1544 +-9.10445 -28.2617 +-8.79797 -28.3659 +-8.49055 -28.4672 +-8.18223 -28.5654 +-7.87306 -28.6606 +-7.56305 -28.7529 +-7.25226 -28.8421 +-6.9407 -28.9282 +-6.62843 -29.0114 +-6.31547 -29.0916 +-6.00185 -29.1688 +-5.68762 -29.243 +-5.37281 -29.3141 +-5.05745 -29.3823 +-4.74157 -29.4475 +-4.42522 -29.5098 +-4.10842 -29.569 +-3.7912 -29.6253 +-3.47361 -29.6786 +-3.15567 -29.729 +-2.83742 -29.7764 +-2.51889 -29.8209 +-2.20011 -29.8625 +-1.88111 -29.9011 +-1.56193 -29.9368 +-1.2426 -29.9696 +-0.923155 -29.9996 +-0.603617 -30.0266 +-0.284021 -30.0508 +0.0356029 -30.0721 +0.355223 -30.0905 +0.67481 -30.1061 +0.994334 -30.1189 +1.31377 -30.1289 +1.63308 -30.1361 +1.95223 -30.1405 +2.27121 -30.1421 +2.58998 -30.141 +2.90852 -30.1371 +3.22679 -30.1305 +3.54477 -30.1212 +3.86244 -30.1091 +4.17975 -30.0944 +4.4967 -30.077 +4.81325 -30.057 +5.12938 -30.0343 +5.44506 -30.009 +5.76026 -29.9811 +6.07497 -29.9506 +6.38916 -29.9175 +6.7028 -29.8818 +7.01586 -29.8436 +7.32834 -29.8029 +7.6402 -29.7597 +7.95142 -29.714 +8.26197 -29.6658 +8.57185 -29.6152 +8.88101 -29.5621 +9.18946 -29.5066 +9.49715 -29.4487 +9.80407 -29.3885 +10.1102 -29.3258 +10.4155 -29.2608 +10.72 -29.1935 +11.0237 -29.1239 +11.3265 -29.052 +11.6284 -28.9778 +11.9294 -28.9013 +12.2294 -28.8227 +12.5286 -28.7418 +12.8267 -28.6587 +13.1239 -28.5734 +13.4201 -28.486 +13.7153 -28.3964 +14.0095 -28.3047 +14.3026 -28.2109 +14.5947 -28.1151 +14.8857 -28.0171 +15.1756 -27.9172 +15.4645 -27.8151 +15.7522 -27.7111 +16.0387 -27.6051 +16.3242 -27.4972 +16.6084 -27.3873 +16.8915 -27.2754 +17.1735 -27.1617 +17.4542 -27.046 +17.7337 -26.9285 +18.012 -26.8091 +18.2891 -26.6879 +18.5649 -26.5649 +18.8395 -26.4401 +19.1128 -26.3135 +19.3848 -26.1852 +19.6555 -26.0551 +19.925 -25.9233 +20.1931 -25.7898 +20.4599 -25.6546 +20.7254 -25.5177 +20.9896 -25.3792 +21.2524 -25.2391 +21.5138 -25.0973 +21.7739 -24.954 +22.0326 -24.8091 +22.29 -24.6627 +22.5459 -24.5147 +22.8005 -24.3651 +23.0536 -24.2141 +23.3053 -24.0616 +23.5557 -23.9077 +23.8045 -23.7523 +24.052 -23.5954 +24.298 -23.4372 +24.5426 -23.2776 +24.7857 -23.1165 +25.0274 -22.9542 +25.2676 -22.7904 +25.5063 -22.6254 +25.7436 -22.4591 +25.9794 -22.2914 +26.2136 -22.1225 +26.4464 -21.9523 +26.6778 -21.7809 +26.9076 -21.6083 +27.1359 -21.4344 +27.3627 -21.2594 +27.588 -21.0832 +27.8117 -20.9058 +28.034 -20.7273 +28.2547 -20.5477 +28.4739 -20.3669 +28.6916 -20.1851 +28.9077 -20.0022 +29.1223 -19.8182 +29.3354 -19.6331 +29.5469 -19.4471 +29.7569 -19.26 +29.9653 -19.0719 +30.1722 -18.8828 +30.3775 -18.6928 +30.5813 -18.5018 +30.7835 -18.3099 +30.9841 -18.117 +31.1832 -17.9232 +31.3808 -17.7285 +31.5767 -17.533 +31.7711 -17.3366 +31.964 -17.1393 +32.1553 -16.9412 +32.345 -16.7422 +32.5331 -16.5424 +32.7197 -16.3419 +32.9046 -16.1405 +33.0881 -15.9384 +33.2699 -15.7355 +33.4502 -15.5319 +33.6289 -15.3276 +33.806 -15.1225 +33.9816 -14.9167 +34.1555 -14.7103 +34.3279 -14.5031 +34.4988 -14.2953 +34.668 -14.0869 +34.8357 -13.8778 +35.0018 -13.668 +35.1663 -13.4577 +35.3293 -13.2468 +35.4907 -13.0352 +35.6505 -12.8231 +35.8087 -12.6104 +35.9654 -12.3972 +36.1205 -12.1834 +36.274 -11.9691 +36.426 -11.7543 +36.5763 -11.539 +36.7252 -11.3232 +36.8724 -11.1069 +37.0181 -10.8901 +37.1622 -10.6729 +37.3048 -10.4552 +37.4458 -10.2371 +37.5852 -10.0185 +37.7231 -9.79959 +37.8594 -9.58022 +37.9942 -9.36046 +38.1274 -9.14032 +38.2591 -8.91981 +38.3892 -8.69893 +38.5178 -8.47771 +38.6448 -8.25614 +38.7702 -8.03425 +38.8942 -7.81203 +39.0166 -7.5895 +39.1374 -7.36668 +39.2567 -7.14356 +39.3745 -6.92017 +39.4907 -6.6965 +39.6054 -6.47258 +39.7186 -6.2484 +39.8302 -6.02399 +39.9403 -5.79934 +40.0489 -5.57448 +40.156 -5.3494 +40.2615 -5.12412 +40.3656 -4.89864 +40.4681 -4.67298 +40.5691 -4.44715 +40.6686 -4.22115 +40.7666 -3.995 +40.8631 -3.7687 +40.9581 -3.54226 +41.0516 -3.31569 +41.1435 -3.089 +41.234 -2.86219 +41.323 -2.63529 +41.4105 -2.40828 +41.4966 -2.18119 +41.5811 -1.95403 +41.6642 -1.72679 +41.7458 -1.49949 +41.8259 -1.27214 +41.9045 -1.04475 +41.9817 -0.817317 +42.0574 -0.589856 +42.1316 -0.362375 +42.2044 -0.134882 +42.2757 0.0926161 +42.3455 0.320111 +42.4139 0.547595 +42.4809 0.77506 +42.5464 1.0025 +42.6104 1.2299 +42.673 1.45727 +42.7342 1.68458 +42.794 1.91184 +42.8523 2.13903 +42.9091 2.36615 +42.9646 2.5932 +43.0186 2.82015 +43.0712 3.04702 +43.1224 3.27378 +43.1722 3.50044 +43.2206 3.72698 +43.2675 3.9534 +43.3131 4.17969 +43.3573 4.40585 +43.4 4.63186 +43.4414 4.85773 +43.4813 5.08344 +43.5199 5.30899 +43.5571 5.53437 +43.5929 5.75957 +43.6273 5.98459 +43.6604 6.20942 +43.6921 6.43406 +43.7224 6.65849 +43.7513 6.88272 +43.7789 7.10673 +43.8051 7.33052 +43.83 7.55409 +43.8535 7.77742 +43.8757 8.00051 +43.8965 8.22335 +43.9159 8.44595 +43.9341 8.66829 +43.9509 8.89036 +43.9663 9.11216 +43.9805 9.33369 +43.9933 9.55493 +44.0047 9.77589 +44.0149 9.99655 +44.0237 10.2169 +44.0312 10.437 +44.0375 10.6567 +44.0424 10.8762 +44.046 11.0953 +44.0483 11.3141 +44.0493 11.5325 +44.049 11.7506 +44.0474 11.9684 +44.0445 12.1858 +44.0404 12.4029 +44.0349 12.6196 +44.0282 12.8359 +44.0203 13.0519 +44.011 13.2675 +44.0005 13.4827 +43.9887 13.6975 +43.9756 13.9119 +43.9613 14.1259 +43.9458 14.3396 +43.929 14.5528 +43.9109 14.7656 +43.8916 14.978 +43.8711 15.1899 +43.8493 15.4015 +43.8263 15.6126 +43.8021 15.8232 +43.7766 16.0334 +43.7499 16.2432 +43.722 16.4525 +43.6929 16.6614 +43.6626 16.8698 +43.631 17.0777 +43.5983 17.2852 +43.5643 17.4922 +43.5292 17.6987 +43.4928 17.9047 +43.4553 18.1102 +43.4166 18.3152 +43.3766 18.5198 +43.3355 18.7238 +43.2933 18.9273 +43.2498 19.1303 +43.2052 19.3328 +43.1594 19.5347 +43.1124 19.7362 +43.0643 19.9371 +43.015 20.1374 +42.9646 20.3372 +42.913 20.5365 +42.8603 20.7352 +42.8064 20.9334 +42.7514 21.131 +42.6952 21.3281 +42.6379 21.5246 +42.5795 21.7205 +42.5199 21.9158 +42.4593 22.1106 +42.3975 22.3047 +42.3345 22.4983 +42.2705 22.6913 +42.2054 22.8837 +42.1391 23.0755 +42.0717 23.2667 +42.0033 23.4573 +41.9337 23.6473 +41.8631 23.8366 +41.7914 24.0253 +41.7185 24.2134 +41.6446 24.4009 +41.5696 24.5878 +41.4936 24.774 +41.4164 24.9595 +41.3382 25.1445 +41.2589 25.3287 +41.1786 25.5123 +41.0972 25.6953 +41.0147 25.8776 +40.9312 26.0592 +40.8467 26.2402 +40.761 26.4205 +40.6744 26.6001 +40.5867 26.7791 +40.498 26.9573 +40.4082 27.1349 +40.3174 27.3118 +40.2256 27.488 +40.1328 27.6634 +40.0389 27.8382 +39.9441 28.0123 +39.8482 28.1857 +39.7513 28.3583 +39.6534 28.5302 +39.5545 28.7015 +39.4546 28.8719 +39.3537 29.0417 +39.2518 29.2107 +39.1489 29.379 +39.0451 29.5466 +38.9402 29.7134 +38.8344 29.8795 +38.7276 30.0448 +38.6198 30.2093 +38.5111 30.3731 +38.4014 30.5362 +38.2908 30.6984 +38.1791 30.86 +38.0666 31.0207 +37.953 31.1807 +37.8386 31.3398 +37.7232 31.4982 +37.6068 31.6559 +37.4895 31.8127 +37.3713 31.9687 +37.2521 32.124 +37.1321 32.2784 +37.0111 32.4321 +36.8891 32.5849 +36.7663 32.7369 +36.6425 32.8881 +36.5179 33.0385 +36.3923 33.1881 +36.2658 33.3369 +36.1385 33.4848 +36.0102 33.6319 +35.8811 33.7781 +35.751 33.9236 +35.6201 34.0682 +35.4883 34.2119 +35.3556 34.3548 +35.222 34.4969 +35.0876 34.6381 +34.9523 34.7784 +34.8161 34.9179 +34.6791 35.0565 +34.5412 35.1942 +34.4025 35.3311 +34.2629 35.4671 +34.1224 35.6023 +33.9812 35.7365 +33.8391 35.8699 +33.6961 36.0024 +33.5523 36.134 +33.4077 36.2647 +33.2623 36.3945 +33.116 36.5234 +32.9689 36.6514 +32.8211 36.7785 +32.6724 36.9047 +32.5229 37.03 +32.3725 37.1544 +32.2214 37.2778 +32.0695 37.4003 +31.9168 37.5219 +31.7633 37.6426 +31.6091 37.7624 +31.454 37.8812 +31.2982 37.999 +31.1416 38.116 +30.9842 38.232 +30.826 38.347 +30.6671 38.4611 +30.5075 38.5742 +30.347 38.6864 +30.1859 38.7976 +30.0239 38.9079 +29.8613 39.0172 +29.6978 39.1255 +29.5337 39.2329 +29.3688 39.3393 +29.2032 39.4447 +29.0368 39.5491 +28.8698 39.6525 +28.702 39.755 +28.5335 39.8564 +28.3643 39.9569 +28.1944 40.0564 +28.0238 40.1549 +27.8524 40.2523 +27.6804 40.3488 +27.5077 40.4442 +27.3343 40.5387 +27.1602 40.6321 +26.9855 40.7245 +26.81 40.8159 +26.6339 40.9062 +26.4571 40.9956 +26.2797 41.0839 +26.1016 41.1711 +25.9228 41.2574 +25.7434 41.3426 +25.5633 41.4267 +25.3826 41.5098 +25.2012 41.5919 +25.0193 41.6729 +24.8366 41.7528 +24.6534 41.8317 +24.4695 41.9095 +24.285 41.9863 +24.0999 42.062 +23.9141 42.1366 +23.7278 42.2102 +23.5408 42.2826 +23.3533 42.354 +23.1651 42.4243 +22.9764 42.4936 +22.7871 42.5617 +22.5972 42.6288 +22.4067 42.6947 +22.2156 42.7596 +22.024 42.8233 +21.8318 42.886 +21.639 42.9475 +21.4457 43.0079 +21.2518 43.0672 +21.0573 43.1254 +20.8623 43.1825 +20.6668 43.2385 +20.4708 43.2933 +20.2742 43.347 +20.077 43.3996 +19.8794 43.4511 +19.6812 43.5014 +19.4825 43.5505 +19.2833 43.5985 +19.0836 43.6454 +18.8834 43.6912 +18.6827 43.7357 +18.4815 43.7791 +18.2798 43.8214 +18.0777 43.8625 +17.875 43.9024 +17.6719 43.9412 +17.4683 43.9788 +17.2642 44.0152 +17.0597 44.0505 +16.8547 44.0846 +16.6493 44.1174 +16.4434 44.1491 +16.2371 44.1797 +16.0303 44.209 +15.8231 44.2371 +15.6155 44.2641 +15.4075 44.2898 +15.199 44.3143 +14.9901 44.3376 +14.7808 44.3598 +14.5712 44.3807 +14.3611 44.4004 +14.1506 44.4188 +13.9397 44.4361 +13.7285 44.4521 +13.5168 44.4669 +13.3048 44.4805 +13.0924 44.4928 +12.8797 44.5039 +12.6666 44.5138 +12.4532 44.5224 +12.2394 44.5298 +12.0252 44.5359 +11.8107 44.5408 +11.5959 44.5444 +11.3808 44.5468 +11.1653 44.5479 +10.9496 44.5478 +10.7335 44.5464 +10.5171 44.5437 +10.3004 44.5397 +10.0834 44.5345 +9.86612 44.528 +9.64856 44.5202 +9.43072 44.5112 +9.21261 44.5008 +8.99424 44.4892 +8.7756 44.4762 +8.55671 44.462 +8.33757 44.4465 +8.11818 44.4297 +7.89856 44.4116 +7.67871 44.3922 +7.45862 44.3714 +7.23832 44.3494 +7.01781 44.326 +6.79708 44.3014 +6.57615 44.2754 +6.35503 44.2481 +6.13372 44.2194 +5.91222 44.1895 +5.69054 44.1582 +5.46869 44.1255 +5.24668 44.0916 +5.02451 44.0563 +4.80218 44.0196 +4.57971 43.9816 +4.3571 43.9423 +4.13435 43.9016 +3.91148 43.8596 +3.68848 43.8162 +3.46538 43.7715 +3.24216 43.7254 +3.01884 43.6779 +2.79543 43.629 +2.57193 43.5788 +2.34835 43.5273 +2.12469 43.4743 +1.90097 43.42 +1.67719 43.3643 +1.45335 43.3072 +1.22947 43.2487 +1.00555 43.1889 +0.781595 43.1276 +0.557616 43.065 +0.333619 43.001 +0.10961 42.9355 +-0.114401 42.8687 +-0.338409 42.8005 +-0.562406 42.7308 +-0.786384 42.6598 +-1.01034 42.5874 +-1.23425 42.5135 +-1.45813 42.4382 +-1.68196 42.3615 +-1.90573 42.2834 +-2.12944 42.2039 +-2.35308 42.123 +-2.57664 42.0406 +-2.80011 41.9568 +-3.02348 41.8715 +-3.24675 41.7849 +-3.46991 41.6968 +-3.69295 41.6072 +-3.91586 41.5162 +-4.13864 41.4238 +-4.36127 41.33 +-4.58375 41.2347 +-4.80607 41.1379 +-5.02822 41.0397 +-5.25019 40.94 +-5.47198 40.8389 +-5.69357 40.7364 +-5.91495 40.6323 +-6.13613 40.5269 +-6.35708 40.4199 +-6.5778 40.3115 +-6.79829 40.2016 +-7.01852 40.0903 +-7.2385 39.9775 +-7.45822 39.8632 +-7.67765 39.7475 +-7.89681 39.6302 +-8.11567 39.5115 +-8.33422 39.3914 +-8.55246 39.2697 +-8.77038 39.1466 +-8.98797 39.022 +-9.20522 38.8959 +-9.42212 38.7683 +-9.63865 38.6392 +-9.85482 38.5087 +-10.0706 38.3766 +-10.286 38.2431 +-10.501 38.108 +-10.7156 37.9715 +-10.9297 37.8335 +-11.1434 37.694 +-11.3567 37.553 +-11.5696 37.4105 +-11.7819 37.2665 +-11.9938 37.121 +-12.2052 36.974 +-12.4162 36.8256 +-12.6266 36.6756 +-12.8365 36.5241 +-13.0458 36.3711 +-13.2547 36.2166 +-13.4629 36.0606 +-13.6707 35.9031 +-13.8778 35.7441 +-14.0844 35.5836 +-14.2903 35.4216 +-14.4957 35.258 +-14.7004 35.093 +-14.9045 34.9265 +-15.108 34.7585 +-15.3108 34.5889 +-15.513 34.4179 +-15.7144 34.2454 +-15.9152 34.0713 +-16.1153 33.8958 +-16.3147 33.7187 +-16.5133 33.5402 +-16.7112 33.3601 +-16.9083 33.1785 +-17.1047 32.9955 +-17.3003 32.8109 +-17.4951 32.6249 +-17.6891 32.4373 +-17.8823 32.2483 +-18.0747 32.0577 +-18.2662 31.8657 +-18.4569 31.6721 +-18.6467 31.4771 +-18.8356 31.2806 +-19.0236 31.0826 +-19.2107 30.8831 +-19.3969 30.6821 +-19.5822 30.4797 +-19.7665 30.2758 +-19.9498 30.0704 +-20.1322 29.8635 +-20.3135 29.6551 +-20.4939 29.4453 +-20.6732 29.234 +-20.8515 29.0212 +-21.0288 28.807 +-21.205 28.5913 +-21.3801 28.3742 +-21.5541 28.1556 +-21.727 27.9355 +-21.8987 27.714 +-22.0694 27.4911 +-22.2389 27.2667 +-22.4072 27.0409 +-22.5743 26.8137 +-22.7402 26.5851 +-22.9049 26.355 +-23.0684 26.1235 +-23.2307 25.8906 +-23.3916 25.6563 +-23.5513 25.4205 +-23.7097 25.1834 +-23.8668 24.9449 +-24.0225 24.705 +-24.177 24.4637 +-24.33 24.2211 +-24.4817 23.977 +-24.632 23.7317 +-24.7808 23.4849 +-24.9283 23.2368 +-25.0743 22.9874 +-25.2189 22.7366 +-25.3619 22.4845 +-25.5035 22.2311 +-25.6436 21.9763 +-25.7821 21.7203 +-25.9191 21.4629 +-26.0546 21.2043 +-26.1885 20.9443 +-26.3207 20.6831 +-26.4514 20.4207 +-26.5804 20.1569 +-26.7078 19.8919 +-26.8335 19.6257 +-26.9575 19.3583 +-27.0799 19.0896 +-27.2005 18.8197 +-27.3194 18.5486 +-27.4365 18.2764 +-27.5518 18.0029 +-27.6654 17.7283 +-27.7772 17.4525 +-27.8871 17.1756 +-27.9952 16.8975 +-28.1014 16.6183 +-28.2058 16.338 +-28.3082 16.0566 +-28.4088 15.7741 +-28.5074 15.4906 +-28.604 15.206 +-28.6987 14.9203 +-28.7914 14.6336 +-28.8821 14.3459 +-28.9708 14.0572 +-29.0574 13.7675 +-29.142 13.4768 +-29.2244 13.1851 +-29.3048 12.8925 +-29.3831 12.599 +-29.4592 12.3046 +-29.5332 12.0092 +-29.6051 11.713 +-29.6747 11.4159 +-29.7421 11.118 +-29.8073 10.8192 +-29.8703 10.5196 +-29.931 10.2192 +-29.9894 9.91809 +-30.0456 9.61618 +-30.0994 9.31353 +-30.1509 9.01016 +-30.2001 8.70609 +-30.2468 8.40134 +-30.2912 8.09592 +-30.3333 7.78987 +-30.3729 7.48319 +-30.41 7.17592 +-30.4447 6.86806 +-30.477 6.55966 +-30.5067 6.25071 +-30.534 5.94126 +-30.5588 5.63132 +-30.581 5.32091 +-30.6007 5.01006 +-30.6178 4.69878 +-30.6323 4.38712 +-30.6442 4.07508 +-30.6536 3.76269 +-30.6603 3.44999 +-30.6643 3.13698 +-30.6657 2.82371 +-30.6645 2.51019 +-30.6606 2.19645 +-30.6539 1.88251 +-30.6446 1.56841 +-30.6325 1.25418 +-30.6177 0.939825 +-30.6002 0.625391 +-30.5798 0.3109 +-30.5568 -0.00361878 +-30.5309 -0.318137 +-30.5022 -0.632626 +-30.4707 -0.947056 +-30.4364 -1.2614 +-30.3993 -1.57562 +-30.3593 -1.8897 +-30.3165 -2.2036 +-30.2708 -2.5173 +-30.2222 -2.83075 +-30.1708 -3.14393 +-30.1165 -3.45682 +-30.0593 -3.76937 +-29.9991 -4.08156 +-29.9361 -4.39335 +-29.8701 -4.70471 +-29.8013 -5.01562 +-29.7294 -5.32602 +-29.6547 -5.63591 +-29.577 -5.94523 +-29.4964 -6.25397 +-29.4128 -6.56207 +-29.3262 -6.86952 +-29.2367 -7.17627 +-29.1443 -7.4823 +-29.0488 -7.78757 +-28.9504 -8.09204 +-28.8491 -8.39568 +-28.7448 -8.69846 +-28.6375 -9.00034 +-28.5272 -9.30129 +-28.414 -9.60127 +-28.2978 -9.90024 +-28.1786 -10.1982 +-28.0565 -10.4951 +-27.9314 -10.7908 +-27.8033 -11.0854 +-27.6724 -11.3789 +-27.5384 -11.6711 +-27.4015 -11.9621 +-27.2617 -12.2518 +-27.119 -12.5402 +-26.9733 -12.8272 +-26.8247 -13.1129 +-26.6732 -13.3971 +-26.5188 -13.6799 +-26.3615 -13.9611 +-26.2013 -14.2409 +-26.0383 -14.5191 +-25.8724 -14.7957 +-25.7037 -15.0706 +-25.5321 -15.344 +-25.3577 -15.6156 +-25.1805 -15.8855 +-25.0005 -16.1536 +-24.8177 -16.4199 +-24.6321 -16.6844 +-24.4438 -16.947 +-24.2528 -17.2078 +-24.0591 -17.4666 +-23.8626 -17.7234 +-23.6635 -17.9783 +-23.4617 -18.2311 +-23.2573 -18.4819 +-23.0502 -18.7306 +-22.8406 -18.9772 +-22.6283 -19.2216 +-22.4135 -19.4639 +-22.1962 -19.704 +-21.9764 -19.9418 +-21.754 -20.1774 +-21.5292 -20.4107 +-21.302 -20.6417 +-21.0723 -20.8703 +-20.8402 -21.0966 +-20.6058 -21.3204 +-20.369 -21.5419 +-20.13 -21.7608 +-19.8886 -21.9774 +-19.645 -22.1914 +-19.3991 -22.4029 +-19.151 -22.6118 +-18.9008 -22.8182 +-18.6484 -23.022 +-18.3939 -23.2232 +-18.1373 -23.4217 +-17.8786 -23.6176 +-17.6179 -23.8109 +-17.3553 -24.0014 +-17.0906 -24.1892 +-16.8241 -24.3743 +-16.5556 -24.5566 +-16.2853 -24.7362 +-16.0131 -24.913 +-15.7392 -25.087 +-15.4635 -25.2581 +-15.186 -25.4265 +-14.9068 -25.592 +-14.626 -25.7546 +-14.3436 -25.9144 +-14.0595 -26.0713 +-13.7739 -26.2252 +-13.4868 -26.3763 +-13.1981 -26.5245 +-12.908 -26.6697 +-12.6165 -26.812 +-12.3236 -26.9513 +-12.0294 -27.0877 +-11.7338 -27.2211 +-11.437 -27.3516 +-11.1389 -27.479 +-10.8396 -27.6035 +-10.5391 -27.725 +-10.2375 -27.8435 +-9.93474 -27.959 +-9.63096 -28.0715 +-9.32614 -28.181 +-9.02033 -28.2875 +-8.71356 -28.391 +-8.40587 -28.4915 +-8.09728 -28.589 +-7.78785 -28.6834 +-7.47759 -28.7748 +-7.16656 -28.8633 +-6.85478 -28.9487 +-6.54228 -29.0311 +-6.22911 -29.1105 +-5.9153 -29.1869 +-5.60087 -29.2603 +-5.28588 -29.3307 +-4.97034 -29.3982 +-4.6543 -29.4626 +-4.33779 -29.5241 +-4.02084 -29.5825 +-3.70349 -29.6381 +-3.38577 -29.6906 +-3.06771 -29.7402 +-2.74935 -29.7869 +-2.43072 -29.8306 +-2.11184 -29.8714 +-1.79276 -29.9093 +-1.47351 -29.9442 +-1.15411 -29.9763 +-0.834605 -30.0055 +-0.515016 -30.0317 +-0.195378 -30.0552 +0.124279 -30.0757 +0.443925 -30.0934 +0.763529 -30.1083 +1.08306 -30.1204 +1.40249 -30.1296 +1.7218 -30.1361 +2.04094 -30.1398 +2.3599 -30.1407 +2.67864 -30.1388 +2.99714 -30.1342 +3.31536 -30.1269 +3.63329 -30.1168 +3.95089 -30.1041 +4.26815 -30.0887 +4.58502 -30.0706 +4.90149 -30.0499 +5.21753 -30.0265 +5.53311 -30.0005 +5.84822 -29.9719 +6.16281 -29.9407 +6.47688 -29.907 +6.7904 -29.8706 +7.10334 -29.8318 +7.41568 -29.7904 +7.7274 -29.7466 +8.03847 -29.7002 +8.34887 -29.6514 +8.65859 -29.6001 +8.96759 -29.5464 +9.27586 -29.4903 +9.58338 -29.4318 +9.89012 -29.3709 +10.1961 -29.3076 +10.5012 -29.242 +10.8055 -29.1741 +11.1089 -29.1039 +11.4115 -29.0314 +11.7132 -28.9566 +12.014 -28.8796 +12.3138 -28.8004 +12.6127 -28.7189 +12.9107 -28.6353 +13.2076 -28.5494 +13.5036 -28.4615 +13.7985 -28.3714 +14.0925 -28.2791 +14.3853 -28.1848 +14.6772 -28.0884 +14.9679 -27.99 +15.2576 -27.8895 +15.5461 -27.787 +15.8335 -27.6825 +16.1198 -27.576 +16.405 -27.4675 +16.689 -27.3571 +16.9718 -27.2448 +17.2534 -27.1306 +17.5339 -27.0145 +17.8131 -26.8965 +18.0911 -26.7767 +18.3678 -26.655 +18.6434 -26.5315 +18.9176 -26.4063 +19.1906 -26.2793 +19.4623 -26.1505 +19.7327 -26.02 +20.0018 -25.8878 +20.2697 -25.7538 +20.5361 -25.6182 +20.8013 -25.481 +21.0651 -25.3421 +21.3276 -25.2016 +21.5887 -25.0595 +21.8485 -24.9157 +22.1068 -24.7705 +22.3638 -24.6236 +22.6194 -24.4753 +22.8736 -24.3254 +23.1264 -24.1741 +23.3778 -24.0212 +23.6278 -23.8669 +23.8763 -23.7112 +24.1234 -23.554 +24.3691 -23.3954 +24.6133 -23.2355 +24.8561 -23.0741 +25.0974 -22.9115 +25.3372 -22.7474 +25.5756 -22.5821 +25.8125 -22.4155 +26.0479 -22.2475 +26.2818 -22.0783 +26.5143 -21.9079 +26.7452 -21.7362 +26.9747 -21.5633 +27.2026 -21.3892 +27.429 -21.2139 +27.6539 -21.0374 +27.8774 -20.8598 +28.0992 -20.681 +28.3196 -20.5012 +28.5384 -20.3202 +28.7557 -20.1381 +28.9715 -19.955 +29.1857 -19.7708 +29.3984 -19.5855 +29.6096 -19.3992 +29.8192 -19.212 +30.0272 -19.0237 +30.2337 -18.8344 +30.4387 -18.6442 +30.6421 -18.453 +30.8439 -18.2609 +31.0442 -18.0678 +31.243 -17.8739 +31.4401 -17.679 +31.6357 -17.4833 +31.8298 -17.2867 +32.0222 -17.0893 +32.2131 -16.891 +32.4025 -16.6919 +32.5902 -16.492 +32.7764 -16.2913 +32.961 -16.0898 +33.1441 -15.8876 +33.3256 -15.6846 +33.5055 -15.4808 +33.6838 -15.2763 +33.8606 -15.0712 +34.0358 -14.8653 +34.2094 -14.6587 +34.3814 -14.4515 +34.5519 -14.2435 +34.7208 -14.035 +34.8881 -13.8258 +35.0539 -13.616 +35.218 -13.4055 +35.3806 -13.1945 +35.5417 -12.9829 +35.7011 -12.7707 +35.859 -12.558 +36.0153 -12.3447 +36.1701 -12.1308 +36.3232 -11.9165 +36.4748 -11.7016 +36.6249 -11.4862 +36.7734 -11.2703 +36.9203 -11.054 +37.0656 -10.8372 +37.2094 -10.6199 +37.3516 -10.4022 +37.4923 -10.184 +37.6314 -9.96543 +37.7689 -9.74643 +37.9049 -9.52704 +38.0394 -9.30725 +38.1722 -9.08709 +38.3036 -8.86655 +38.4334 -8.64566 +38.5616 -8.42442 +38.6883 -8.20284 +38.8134 -7.98093 +38.937 -7.75871 +39.0591 -7.53618 +39.1796 -7.31335 +39.2986 -7.09024 +39.416 -6.86684 +39.532 -6.64319 +39.6463 -6.41927 +39.7592 -6.19511 +39.8705 -5.9707 +39.9803 -5.74607 +40.0886 -5.52123 +40.1954 -5.29617 +40.3006 -5.07091 +40.4044 -4.84546 +40.5066 -4.61983 +40.6073 -4.39403 +40.7065 -4.16806 +40.8042 -3.94194 +40.9004 -3.71568 +40.9951 -3.48928 +41.0883 -3.26275 +41.18 -3.0361 +41.2702 -2.80934 +41.3589 -2.58249 +41.4461 -2.35553 +41.5319 -2.1285 +41.6161 -1.90138 +41.6989 -1.6742 +41.7802 -1.44696 +41.86 -1.21967 +41.9384 -0.99234 +42.0153 -0.764972 +42.0907 -0.537576 +42.1647 -0.310162 +42.2372 -0.0827375 +42.3082 0.14469 +42.3778 0.372113 +42.446 0.599523 +42.5126 0.826912 +42.5779 1.05427 +42.6417 1.2816 +42.7041 1.50888 +42.765 1.73611 +42.8245 1.96329 +42.8825 2.1904 +42.9392 2.41743 +42.9944 2.64439 +43.0482 2.87125 +43.1005 3.09803 +43.1515 3.3247 +43.201 3.55126 +43.2492 3.77771 +43.2959 4.00403 +43.3412 4.23022 +43.3852 4.45628 +43.4277 4.6822 +43.4688 4.90796 +43.5086 5.13357 +43.5469 5.35901 +43.5839 5.58428 +43.6195 5.80938 +43.6537 6.03429 +43.6865 6.25901 +43.718 6.48354 +43.7481 6.70786 +43.7768 6.93198 +43.8042 7.15588 +43.8302 7.37955 +43.8549 7.603 +43.8782 7.82621 +43.9002 8.04919 +43.9208 8.27191 +43.9401 8.49439 +43.958 8.7166 +43.9746 8.93855 +43.9899 9.16023 +44.0038 9.38164 +44.0164 9.60276 +44.0277 9.82359 +44.0377 10.0441 +44.0464 10.2644 +44.0537 10.4843 +44.0597 10.7039 +44.0645 10.9232 +44.0679 11.1422 +44.07 11.3609 +44.0709 11.5792 +44.0704 11.7972 +44.0687 12.0148 +44.0656 12.2321 +44.0613 12.449 +44.0557 12.6656 +44.0489 12.8818 +44.0407 13.0976 +44.0313 13.313 +44.0207 13.5281 +44.0087 13.7428 +43.9955 13.9571 +43.9811 14.171 +43.9654 14.3845 +43.9484 14.5975 +43.9303 14.8102 +43.9108 15.0224 +43.8902 15.2343 +43.8682 15.4457 +43.8451 15.6566 +43.8207 15.8671 +43.7952 16.0772 +43.7683 16.2869 +43.7403 16.496 +43.7111 16.7048 +43.6806 16.913 +43.649 17.1208 +43.6161 17.3281 +43.582 17.535 +43.5468 17.7413 +43.5103 17.9472 +43.4726 18.1526 +43.4338 18.3574 +43.3938 18.5618 +43.3526 18.7657 +43.3102 18.9691 +43.2667 19.1719 +43.2219 19.3743 +43.176 19.5761 +43.129 19.7774 +43.0808 19.9781 +43.0314 20.1783 +42.9809 20.378 +42.9292 20.5771 +42.8764 20.7757 +42.8224 20.9737 +42.7673 21.1712 +42.7111 21.3681 +42.6537 21.5644 +42.5952 21.7602 +42.5356 21.9554 +42.4748 22.15 +42.4129 22.344 +42.35 22.5375 +42.2859 22.7303 +42.2206 22.9226 +42.1543 23.1142 +42.0869 23.3053 +42.0184 23.4957 +41.9488 23.6856 +41.8781 23.8748 +41.8063 24.0633 +41.7334 24.2513 +41.6594 24.4386 +41.5844 24.6253 +41.5083 24.8114 +41.4311 24.9968 +41.3528 25.1816 +41.2735 25.3657 +41.1931 25.5492 +41.1117 25.732 +41.0292 25.9142 +40.9456 26.0957 +40.861 26.2765 +40.7754 26.4567 +40.6887 26.6362 +40.601 26.815 +40.5122 26.9931 +40.4225 27.1705 +40.3317 27.3473 +40.2398 27.5233 +40.147 27.6987 +40.0531 27.8733 +39.9582 28.0473 +39.8623 28.2205 +39.7654 28.393 +39.6675 28.5648 +39.5686 28.7359 +39.4686 28.9062 +39.3677 29.0759 +39.2659 29.2448 +39.163 29.4129 +39.0591 29.5803 +38.9543 29.747 +38.8484 29.913 +38.7416 30.0781 +38.6339 30.2426 +38.5252 30.4063 +38.4155 30.5692 +38.3048 30.7313 +38.1932 30.8927 +38.0806 31.0533 +37.9671 31.2132 +37.8527 31.3722 +37.7373 31.5305 +37.6209 31.688 +37.5037 31.8447 +37.3855 32.0006 +37.2663 32.1557 +37.1463 32.3101 +37.0253 32.4636 +36.9034 32.6163 +36.7806 32.7682 +36.6569 32.9193 +36.5322 33.0696 +36.4067 33.2191 +36.2803 33.3677 +36.1529 33.5155 +36.0247 33.6625 +35.8956 33.8086 +35.7656 33.954 +35.6347 34.0984 +35.5029 34.2421 +35.3703 34.3849 +35.2367 34.5268 +35.1023 34.6679 +34.9671 34.8081 +34.831 34.9475 +34.694 35.086 +34.5562 35.2237 +34.4175 35.3605 +34.2779 35.4964 +34.1376 35.6314 +33.9963 35.7655 +33.8543 35.8988 +33.7114 36.0312 +33.5677 36.1627 +33.4231 36.2933 +33.2777 36.423 +33.1316 36.5518 +32.9845 36.6798 +32.8367 36.8068 +32.6881 36.9329 +32.5386 37.0581 +32.3884 37.1823 +32.2374 37.3057 +32.0855 37.4281 +31.9329 37.5497 +31.7795 37.6703 +31.6253 37.7899 +31.4703 37.9086 +31.3146 38.0264 +31.158 38.1433 +31.0007 38.2592 +30.8427 38.3742 +30.6838 38.4882 +30.5242 38.6012 +30.3639 38.7134 +30.2028 38.8245 +30.041 38.9347 +29.8784 39.0439 +29.7151 39.1522 +29.551 39.2595 +29.3862 39.3658 +29.2207 39.4711 +29.0544 39.5755 +28.8874 39.6788 +28.7198 39.7812 +28.5514 39.8826 +28.3822 39.983 +28.2124 40.0824 +28.0419 40.1808 +27.8707 40.2783 +27.6988 40.3747 +27.5261 40.4701 +27.3528 40.5644 +27.1789 40.6578 +27.0042 40.7502 +26.8289 40.8415 +26.6529 40.9318 +26.4762 41.0211 +26.2988 41.1094 +26.1208 41.1966 +25.9422 41.2828 +25.7629 41.3679 +25.5829 41.452 +25.4023 41.5351 +25.2211 41.6171 +25.0392 41.6981 +24.8567 41.778 +24.6735 41.8568 +24.4898 41.9346 +24.3054 42.0113 +24.1204 42.087 +23.9348 42.1616 +23.7485 42.2351 +23.5617 42.3076 +23.3743 42.3789 +23.1862 42.4492 +22.9976 42.5184 +22.8084 42.5865 +22.6186 42.6536 +22.4283 42.7195 +22.2373 42.7843 +22.0458 42.8481 +21.8537 42.9107 +21.6611 42.9722 +21.4679 43.0327 +21.2741 43.092 +21.0798 43.1502 +20.8849 43.2072 +20.6895 43.2632 +20.4936 43.318 +20.2971 43.3717 +20.1001 43.4243 +19.9026 43.4757 +19.7046 43.5261 +19.506 43.5752 +19.3069 43.6233 +19.1074 43.6701 +18.9073 43.7159 +18.7067 43.7605 +18.5057 43.8039 +18.3041 43.8462 +18.1021 43.8873 +17.8995 43.9272 +17.6965 43.966 +17.4931 44.0036 +17.2891 44.0401 +17.0848 44.0753 +16.8799 44.1094 +16.6746 44.1423 +16.4689 44.1741 +16.2627 44.2046 +16.056 44.234 +15.849 44.2621 +15.6415 44.2891 +15.4336 44.3149 +15.2253 44.3394 +15.0165 44.3628 +14.8074 44.3849 +14.5978 44.4059 +14.3879 44.4256 +14.1775 44.4441 +13.9668 44.4614 +13.7556 44.4775 +13.5441 44.4924 +13.3323 44.506 +13.12 44.5184 +12.9074 44.5295 +12.6945 44.5394 +12.4811 44.5481 +12.2675 44.5556 +12.0535 44.5618 +11.8391 44.5667 +11.6244 44.5704 +11.4094 44.5728 +11.1941 44.574 +10.9785 44.5739 +10.7625 44.5726 +10.5462 44.57 +10.3297 44.5661 +10.1128 44.561 +9.89567 44.5545 +9.67824 44.5468 +9.46053 44.5378 +9.24255 44.5276 +9.0243 44.516 +8.80579 44.5032 +8.58702 44.4891 +8.36801 44.4736 +8.14875 44.4569 +7.92925 44.4389 +7.70952 44.4196 +7.48956 44.3989 +7.26938 44.377 +7.04899 44.3537 +6.82839 44.3292 +6.60758 44.3033 +6.38658 44.2761 +6.16539 44.2476 +5.94401 44.2177 +5.72245 44.1865 +5.50072 44.154 +5.27882 44.1202 +5.05677 44.085 +4.83456 44.0485 +4.6122 44.0106 +4.3897 43.9714 +4.16707 43.9308 +3.94431 43.8889 +3.72142 43.8457 +3.49843 43.801 +3.27532 43.7551 +3.05211 43.7077 +2.8288 43.659 +2.60541 43.609 +2.38194 43.5575 +2.15839 43.5047 +1.93477 43.4505 +1.71109 43.395 +1.48735 43.338 +1.26357 43.2797 +1.03975 43.22 +0.815891 43.1589 +0.592008 43.0965 +0.368105 43.0326 +0.144191 42.9673 +-0.079728 42.9007 +-0.303645 42.8326 +-0.527551 42.7631 +-0.751441 42.6922 +-0.975306 42.62 +-1.19914 42.5463 +-1.42293 42.4712 +-1.64668 42.3947 +-1.87037 42.3167 +-2.094 42.2374 +-2.31755 42.1566 +-2.54103 42.0744 +-2.76443 41.9908 +-2.98773 41.9058 +-3.21093 41.8193 +-3.43401 41.7314 +-3.65698 41.642 +-3.87983 41.5512 +-4.10254 41.459 +-4.3251 41.3654 +-4.54752 41.2703 +-4.76978 41.1737 +-4.99187 41.0757 +-5.21378 40.9763 +-5.43551 40.8754 +-5.65705 40.773 +-5.87838 40.6692 +-6.0995 40.5639 +-6.32041 40.4572 +-6.54108 40.349 +-6.76152 40.2394 +-6.98171 40.1282 +-7.20165 40.0157 +-7.42132 39.9016 +-7.64072 39.7861 +-7.85984 39.6691 +-8.07867 39.5506 +-8.29719 39.4307 +-8.51541 39.3093 +-8.7333 39.1864 +-8.95086 39.062 +-9.16809 38.9361 +-9.38497 38.8088 +-9.60148 38.68 +-9.81763 38.5497 +-10.0334 38.4179 +-10.2488 38.2846 +-10.4638 38.1498 +-10.6783 38.0135 +-10.8925 37.8758 +-11.1062 37.7365 +-11.3195 37.5958 +-11.5324 37.4536 +-11.7447 37.3098 +-11.9566 37.1646 +-12.1681 37.0179 +-12.379 36.8697 +-12.5894 36.7199 +-12.7993 36.5687 +-13.0087 36.416 +-13.2176 36.2618 +-13.4259 36.106 +-13.6336 35.9488 +-13.8408 35.7901 +-14.0474 35.6299 +-14.2534 35.4681 +-14.4588 35.3049 +-14.6636 35.1402 +-14.8678 34.9739 +-15.0713 34.8062 +-15.2742 34.6369 +-15.4764 34.4662 +-15.6779 34.2939 +-15.8787 34.1202 +-16.0789 33.9449 +-16.2783 33.7682 +-16.477 33.5899 +-16.675 33.4102 +-16.8722 33.2289 +-17.0687 33.0461 +-17.2644 32.8619 +-17.4593 32.6761 +-17.6534 32.4889 +-17.8467 32.3001 +-18.0392 32.1099 +-18.2308 31.9182 +-18.4216 31.7249 +-18.6115 31.5302 +-18.8005 31.334 +-18.9887 31.1363 +-19.1759 30.9372 +-19.3622 30.7365 +-19.5476 30.5344 +-19.732 30.3307 +-19.9155 30.1256 +-20.098 29.9191 +-20.2795 29.711 +-20.46 29.5015 +-20.6395 29.2905 +-20.818 29.0781 +-20.9954 28.8642 +-21.1718 28.6488 +-21.347 28.432 +-21.5212 28.2137 +-21.6943 27.994 +-21.8663 27.7729 +-22.0371 27.5502 +-22.2068 27.3262 +-22.3753 27.1007 +-22.5426 26.8738 +-22.7088 26.6455 +-22.8737 26.4157 +-23.0374 26.1845 +-23.1998 25.9519 +-23.361 25.718 +-23.5209 25.4826 +-23.6796 25.2458 +-23.8369 25.0076 +-23.9929 24.768 +-24.1476 24.527 +-24.3009 24.2847 +-24.4528 24.041 +-24.6034 23.7959 +-24.7525 23.5495 +-24.9002 23.3017 +-25.0465 23.0526 +-25.1914 22.8022 +-25.3347 22.5504 +-25.4766 22.2973 +-25.617 22.0428 +-25.7558 21.7871 +-25.8932 21.5301 +-26.0289 21.2717 +-26.1631 21.0121 +-26.2957 20.7512 +-26.4267 20.489 +-26.5561 20.2256 +-26.6838 19.961 +-26.8099 19.695 +-26.9343 19.4279 +-27.057 19.1595 +-27.1779 18.89 +-27.2972 18.6192 +-27.4147 18.3472 +-27.5304 18.074 +-27.6444 17.7997 +-27.7565 17.5242 +-27.8669 17.2476 +-27.9754 16.9698 +-28.082 16.6909 +-28.1868 16.4109 +-28.2896 16.1298 +-28.3906 15.8476 +-28.4897 15.5643 +-28.5867 15.28 +-28.6819 14.9946 +-28.775 14.7082 +-28.8662 14.4207 +-28.9553 14.1323 +-29.0424 13.8428 +-29.1274 13.5524 +-29.2104 13.261 +-29.2913 12.9686 +-29.37 12.6754 +-29.4467 12.3812 +-29.5212 12.0861 +-29.5935 11.7901 +-29.6637 11.4932 +-29.7316 11.1955 +-29.7973 10.897 +-29.8608 10.5976 +-29.9221 10.2975 +-29.9811 9.99655 +-30.0378 9.69485 +-30.0921 9.39241 +-30.1442 9.08924 +-30.1939 8.78537 +-30.2413 8.48081 +-30.2863 8.17558 +-30.3289 7.86971 +-30.3691 7.56322 +-30.4068 7.25611 +-30.4421 6.94843 +-30.475 6.64019 +-30.5054 6.3314 +-30.5333 6.0221 +-30.5586 5.71231 +-30.5815 5.40204 +-30.6018 5.09132 +-30.6196 4.78018 +-30.6347 4.46864 +-30.6473 4.15672 +-30.6573 3.84445 +-30.6647 3.53184 +-30.6694 3.21894 +-30.6715 2.90576 +-30.6709 2.59232 +-30.6677 2.27866 +-30.6617 1.9648 +-30.6531 1.65077 +-30.6417 1.33659 +-30.6276 1.02229 +-30.6108 0.707904 +-30.5912 0.393451 +-30.5688 0.0789631 +-30.5437 -0.235532 +-30.5158 -0.550005 +-30.485 -0.864428 +-30.4515 -1.17877 +-30.4151 -1.493 +-30.3759 -1.80709 +-30.3338 -2.12102 +-30.2889 -2.43474 +-30.2411 -2.74823 +-30.1904 -3.06146 +-30.1368 -3.3744 +-30.0804 -3.68701 +-30.021 -3.99927 +-29.9588 -4.31114 +-29.8936 -4.62259 +-29.8255 -4.93359 +-29.7545 -5.2441 +-29.6805 -5.5541 +-29.6036 -5.86355 +-29.5238 -6.17241 +-29.441 -6.48066 +-29.3553 -6.78826 +-29.2666 -7.09517 +-29.1749 -7.40136 +-29.0803 -7.70681 +-28.9827 -8.01147 +-28.8822 -8.3153 +-28.7787 -8.61829 +-28.6722 -8.92038 +-28.5627 -9.22155 +-28.4503 -9.52177 +-28.3349 -9.82099 +-28.2166 -10.1192 +-28.0953 -10.4163 +-27.971 -10.7123 +-27.8438 -11.0072 +-27.7136 -11.301 +-27.5805 -11.5935 +-27.4445 -11.8848 +-27.3055 -12.1748 +-27.1635 -12.4635 +-27.0187 -12.7509 +-26.8709 -13.0369 +-26.7202 -13.3215 +-26.5666 -13.6047 +-26.4102 -13.8863 +-26.2508 -14.1665 +-26.0886 -14.4451 +-25.9235 -14.7221 +-25.7556 -14.9975 +-25.5848 -15.2712 +-25.4112 -15.5433 +-25.2348 -15.8136 +-25.0556 -16.0822 +-24.8736 -16.349 +-24.6889 -16.6139 +-24.5014 -16.8771 +-24.3111 -17.1383 +-24.1182 -17.3976 +-23.9225 -17.655 +-23.7242 -17.9104 +-23.5232 -18.1637 +-23.3195 -18.4151 +-23.1132 -18.6643 +-22.9043 -18.9115 +-22.6928 -19.1565 +-22.4788 -19.3994 +-22.2622 -19.64 +-22.0431 -19.8785 +-21.8215 -20.1147 +-21.5974 -20.3486 +-21.3709 -20.5802 +-21.142 -20.8094 +-20.9106 -21.0363 +-20.6769 -21.2608 +-20.4408 -21.4829 +-20.2024 -21.7026 +-19.9617 -21.9198 +-19.7188 -22.1345 +-19.4736 -22.3467 +-19.2262 -22.5563 +-18.9766 -22.7634 +-18.7248 -22.9679 +-18.471 -23.1698 +-18.215 -23.3691 +-17.957 -23.5657 +-17.6969 -23.7597 +-17.4349 -23.9509 +-17.1708 -24.1395 +-16.9049 -24.3253 +-16.637 -24.5084 +-16.3672 -24.6888 +-16.0956 -24.8663 +-15.8222 -25.0411 +-15.5471 -25.2131 +-15.2701 -25.3822 +-14.9915 -25.5485 +-14.7112 -25.7119 +-14.4293 -25.8725 +-14.1457 -26.0302 +-13.8606 -26.185 +-13.5739 -26.3369 +-13.2858 -26.4859 +-12.9961 -26.6319 +-12.7051 -26.775 +-12.4126 -26.9152 +-12.1188 -27.0524 +-11.8236 -27.1867 +-11.5272 -27.318 +-11.2295 -27.4463 +-10.9306 -27.5717 +-10.6305 -27.694 +-10.3292 -27.8134 +-10.0269 -27.9298 +-9.72345 -28.0431 +-9.41898 -28.1535 +-9.11349 -28.2609 +-8.80704 -28.3652 +-8.49966 -28.4666 +-8.19137 -28.5649 +-7.88223 -28.6603 +-7.57225 -28.7526 +-7.26148 -28.8419 +-6.94996 -28.9282 +-6.63771 -29.0115 +-6.32478 -29.0918 +-6.01119 -29.1691 +-5.69699 -29.2434 +-5.3822 -29.3147 +-5.06686 -29.383 +-4.75101 -29.4483 +-4.43468 -29.5107 +-4.1179 -29.5701 +-3.8007 -29.6265 +-3.48313 -29.6799 +-3.16521 -29.7304 +-2.84697 -29.778 +-2.52846 -29.8226 +-2.2097 -29.8643 +-1.89072 -29.903 +-1.57155 -29.9389 +-1.25223 -29.9718 +-0.932797 -30.0019 +-0.61327 -30.029 +-0.293684 -30.0533 +0.0259299 -30.0748 +0.345541 -30.0934 +0.66512 -30.1091 +0.984636 -30.1221 +1.30406 -30.1322 +1.62336 -30.1395 +1.94252 -30.144 +2.26149 -30.1458 +2.58026 -30.1448 +2.89879 -30.1411 +3.21707 -30.1346 +3.53505 -30.1254 +3.85271 -30.1135 +4.17003 -30.0989 +4.48699 -30.0817 +4.80354 -30.0618 +5.11968 -30.0392 +5.43536 -30.0141 +5.75058 -29.9863 +6.0653 -29.9559 +6.3795 -29.923 +6.69315 -29.8875 +7.00623 -29.8495 +7.31872 -29.8089 +7.6306 -29.7658 +7.94184 -29.7203 +8.25241 -29.6722 +8.56231 -29.6218 +8.8715 -29.5688 +9.17997 -29.5135 +9.48768 -29.4558 +9.79464 -29.3957 +10.1008 -29.3332 +10.4062 -29.2683 +10.7107 -29.2012 +11.0144 -29.1317 +11.3172 -29.06 +11.6191 -28.9859 +11.9201 -28.9097 +12.2203 -28.8312 +12.5194 -28.7504 +12.8176 -28.6675 +13.1149 -28.5824 +13.4111 -28.4952 +13.7064 -28.4058 +14.0006 -28.3143 +14.2938 -28.2206 +14.5859 -28.1249 +14.877 -28.0272 +15.1669 -27.9274 +15.4558 -27.8256 +15.7436 -27.7217 +16.0302 -27.6159 +16.3157 -27.5081 +16.6 -27.3984 +16.8832 -27.2867 +17.1652 -27.1732 +17.446 -27.0577 +17.7256 -26.9404 +18.0039 -26.8212 +18.2811 -26.7002 +18.557 -26.5774 +18.8316 -26.4527 +19.105 -26.3263 +19.3771 -26.1982 +19.6479 -26.0683 +19.9174 -25.9367 +20.1856 -25.8033 +20.4525 -25.6683 +20.7181 -25.5317 +20.9823 -25.3934 +21.2452 -25.2534 +21.5067 -25.1119 +21.7669 -24.9687 +22.0257 -24.824 +22.2831 -24.6777 +22.5392 -24.5299 +22.7938 -24.3806 +23.047 -24.2298 +23.2989 -24.0775 +23.5493 -23.9237 +23.7983 -23.7685 +24.0458 -23.6119 +24.292 -23.4538 +24.5366 -23.2944 +24.7799 -23.1336 +25.0216 -22.9714 +25.262 -22.8079 +25.5008 -22.643 +25.7382 -22.4769 +25.9741 -22.3094 +26.2085 -22.1407 +26.4414 -21.9707 +26.6728 -21.7995 +26.9028 -21.6271 +27.1312 -21.4534 +27.3581 -21.2786 +27.5836 -21.1026 +27.8075 -20.9254 +28.0298 -20.7471 +28.2507 -20.5677 +28.4701 -20.3871 +28.6879 -20.2055 +28.9041 -20.0227 +29.1189 -19.839 +29.3321 -19.6541 +29.5438 -19.4683 +29.7539 -19.2814 +29.9625 -19.0935 +30.1695 -18.9046 +30.375 -18.7148 +30.5789 -18.524 +30.7813 -18.3323 +30.9821 -18.1396 +31.1813 -17.946 +31.379 -17.7515 +31.5752 -17.5562 +31.7698 -17.36 +31.9628 -17.1629 +32.1542 -16.965 +32.3441 -16.7662 +32.5324 -16.5666 +32.7191 -16.3663 +32.9043 -16.1651 +33.0879 -15.9632 +33.2699 -15.7605 +33.4504 -15.5571 +33.6293 -15.353 +33.8066 -15.1481 +33.9823 -14.9425 +34.1565 -14.7363 +34.3291 -14.5293 +34.5001 -14.3217 +34.6696 -14.1135 +34.8374 -13.9046 +35.0037 -13.695 +35.1685 -13.4849 +35.3316 -13.2741 +& diff --git a/src/boost/libs/numeric/odeint/examples/solar_system.cpp b/src/boost/libs/numeric/odeint/examples/solar_system.cpp new file mode 100644 index 000000000..3586d5b86 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/solar_system.cpp @@ -0,0 +1,201 @@ +/* Boost libs/numeric/odeint/examples/solar_system.cpp + + Copyright 2010-2012 Karsten Ahnert + Copyright 2011 Mario Mulansky + + Solar system example for Hamiltonian stepper + + 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) + */ + + +#include <iostream> +#include <boost/array.hpp> + +#include <boost/numeric/odeint.hpp> + +#include "point_type.hpp" + +//[ container_type_definition +// we simulate 5 planets and the sun +const size_t n = 6; + +typedef point< double , 3 > point_type; +typedef boost::array< point_type , n > container_type; +typedef boost::array< double , n > mass_type; +//] + + + + + + + +//[ coordinate_function +const double gravitational_constant = 2.95912208286e-4; + +struct solar_system_coor +{ + const mass_type &m_masses; + + solar_system_coor( const mass_type &masses ) : m_masses( masses ) { } + + void operator()( const container_type &p , container_type &dqdt ) const + { + for( size_t i=0 ; i<n ; ++i ) + dqdt[i] = p[i] / m_masses[i]; + } +}; +//] + + +//[ momentum_function +struct solar_system_momentum +{ + const mass_type &m_masses; + + solar_system_momentum( const mass_type &masses ) : m_masses( masses ) { } + + void operator()( const container_type &q , container_type &dpdt ) const + { + const size_t n = q.size(); + for( size_t i=0 ; i<n ; ++i ) + { + dpdt[i] = 0.0; + for( size_t j=0 ; j<i ; ++j ) + { + point_type diff = q[j] - q[i]; + double d = abs( diff ); + diff *= ( gravitational_constant * m_masses[i] * m_masses[j] / d / d / d ); + dpdt[i] += diff; + dpdt[j] -= diff; + + } + } + } +}; +//] + + + + + + + +//[ some_helpers +point_type center_of_mass( const container_type &x , const mass_type &m ) +{ + double overall_mass = 0.0; + point_type mean( 0.0 ); + for( size_t i=0 ; i<x.size() ; ++i ) + { + overall_mass += m[i]; + mean += m[i] * x[i]; + } + if( !x.empty() ) mean /= overall_mass; + return mean; +} + + +double energy( const container_type &q , const container_type &p , const mass_type &masses ) +{ + const size_t n = q.size(); + double en = 0.0; + for( size_t i=0 ; i<n ; ++i ) + { + en += 0.5 * norm( p[i] ) / masses[i]; + for( size_t j=0 ; j<i ; ++j ) + { + double diff = abs( q[i] - q[j] ); + en -= gravitational_constant * masses[j] * masses[i] / diff; + } + } + return en; +} +//] + + +//[ streaming_observer +struct streaming_observer +{ + std::ostream& m_out; + + streaming_observer( std::ostream &out ) : m_out( out ) { } + + template< class State > + void operator()( const State &x , double t ) const + { + container_type &q = x.first; + m_out << t; + for( size_t i=0 ; i<q.size() ; ++i ) m_out << "\t" << q[i]; + m_out << "\n"; + } +}; +//] + + +int main( int argc , char **argv ) +{ + + using namespace std; + using namespace boost::numeric::odeint; + + mass_type masses = {{ + 1.00000597682 , // sun + 0.000954786104043 , // jupiter + 0.000285583733151 , // saturn + 0.0000437273164546 , // uranus + 0.0000517759138449 , // neptune + 1.0 / ( 1.3e8 ) // pluto + }}; + + container_type q = {{ + point_type( 0.0 , 0.0 , 0.0 ) , // sun + point_type( -3.5023653 , -3.8169847 , -1.5507963 ) , // jupiter + point_type( 9.0755314 , -3.0458353 , -1.6483708 ) , // saturn + point_type( 8.3101420 , -16.2901086 , -7.2521278 ) , // uranus + point_type( 11.4707666 , -25.7294829 , -10.8169456 ) , // neptune + point_type( -15.5387357 , -25.2225594 , -3.1902382 ) // pluto + }}; + + container_type p = {{ + point_type( 0.0 , 0.0 , 0.0 ) , // sun + point_type( 0.00565429 , -0.00412490 , -0.00190589 ) , // jupiter + point_type( 0.00168318 , 0.00483525 , 0.00192462 ) , // saturn + point_type( 0.00354178 , 0.00137102 , 0.00055029 ) , // uranus + point_type( 0.00288930 , 0.00114527 , 0.00039677 ) , // neptune + point_type( 0.00276725 , -0.00170702 , -0.00136504 ) // pluto + }}; + + point_type qmean = center_of_mass( q , masses ); + point_type pmean = center_of_mass( p , masses ); + for( size_t i=0 ; i<n ; ++i ) + { + q[i] -= qmean ; + p[i] -= pmean; + } + + for( size_t i=0 ; i<n ; ++i ) p[i] *= masses[i]; + + //[ integration_solar_system + typedef symplectic_rkn_sb3a_mclachlan< container_type > stepper_type; + const double dt = 100.0; + + integrate_const( + stepper_type() , + make_pair( solar_system_coor( masses ) , solar_system_momentum( masses ) ) , + make_pair( boost::ref( q ) , boost::ref( p ) ) , + 0.0 , 200000.0 , dt , streaming_observer( cout ) ); + //] + + + return 0; +} + + +/* +Plot with gnuplot: +p "solar_system.dat" u 2:4 w l,"solar_system.dat" u 5:7 w l,"solar_system.dat" u 8:10 w l,"solar_system.dat" u 11:13 w l,"solar_system.dat" u 14:16 w l,"solar_system.dat" u 17:19 w l + */ diff --git a/src/boost/libs/numeric/odeint/examples/stepper_details.cpp b/src/boost/libs/numeric/odeint/examples/stepper_details.cpp new file mode 100644 index 000000000..d4ae8bd1e --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/stepper_details.cpp @@ -0,0 +1,200 @@ +/* + * stepper_details.cpp + * + * This example demonstrates some details about the steppers in odeint. + * + * + * Copyright 2011-2012 Karsten Ahnert + * Copyright 2012 Mario Mulansky + * Copyright 2013 Pascal Germroth + * + * 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) + */ + +#include <iostream> +#include <boost/array.hpp> +#include <boost/bind.hpp> +#include <boost/numeric/odeint.hpp> + +using namespace std; +using namespace boost::numeric::odeint; + +const size_t N = 3; + +typedef boost::array< double , N > state_type; + +//[ system_function_structure +void sys( const state_type & /*x*/ , state_type & /*dxdt*/ , const double /*t*/ ) +{ + // ... +} +//] + +void sys1( const state_type &/*x*/ , state_type &/*dxdt*/ , const double /*t*/ ) +{ +} + +void sys2( const state_type &/*x*/ , state_type &/*dxdt*/ , const double /*t*/ ) +{ +} + + +//[ symplectic_stepper_detail_system_function +typedef boost::array< double , 1 > vector_type; + + +struct harm_osc_f1 +{ + void operator()( const vector_type &p , vector_type &dqdt ) + { + dqdt[0] = p[0]; + } +}; + +struct harm_osc_f2 +{ + void operator()( const vector_type &q , vector_type &dpdt ) + { + dpdt[0] = -q[0]; + } +}; +//] + +//[ symplectic_stepper_detail_system_class +struct harm_osc +{ + void f1( const vector_type &p , vector_type &dqdt ) const + { + dqdt[0] = p[0]; + } + + void f2( const vector_type &q , vector_type &dpdt ) const + { + dpdt[0] = -q[0]; + } +}; +//] + +int main( int argc , char **argv ) +{ + using namespace std; + + // Explicit stepper example + { + double t( 0.0 ) , dt( 0.1 ); + state_type in , out , dxdtin , inout; + //[ explicit_stepper_detail_example + runge_kutta4< state_type > rk; + rk.do_step( sys1 , inout , t , dt ); // In-place transformation of inout + rk.do_step( sys2 , inout , t , dt ); // call with different system: Ok + rk.do_step( sys1 , in , t , out , dt ); // Out-of-place transformation + rk.do_step( sys1 , inout , dxdtin , t , dt ); // In-place tranformation of inout + rk.do_step( sys1 , in , dxdtin , t , out , dt ); // Out-of-place transformation + //] + } + + + + // FSAL stepper example + { + double t( 0.0 ) , dt( 0.1 ); + state_type in , in2 , in3 , out , dxdtin , dxdtout , inout , dxdtinout; + //[ fsal_stepper_detail_example + runge_kutta_dopri5< state_type > rk; + rk.do_step( sys1 , in , t , out , dt ); + rk.do_step( sys2 , in , t , out , dt ); // DONT do this, sys1 is assumed + + rk.do_step( sys2 , in2 , t , out , dt ); + rk.do_step( sys2 , in3 , t , out , dt ); // DONT do this, in2 is assumed + + rk.do_step( sys1 , inout , dxdtinout , t , dt ); + rk.do_step( sys2 , inout , dxdtinout , t , dt ); // Ok, internal derivative is not used, dxdtinout is updated + + rk.do_step( sys1 , in , dxdtin , t , out , dxdtout , dt ); + rk.do_step( sys2 , in , dxdtin , t , out , dxdtout , dt ); // Ok, internal derivative is not used + //] + } + + + // Symplectic harmonic oscillator example + { + double t( 0.0 ) , dt( 0.1 ); + //[ symplectic_stepper_detail_example + pair< vector_type , vector_type > x; + x.first[0] = 1.0; x.second[0] = 0.0; + symplectic_rkn_sb3a_mclachlan< vector_type > rkn; + rkn.do_step( make_pair( harm_osc_f1() , harm_osc_f2() ) , x , t , dt ); + //] + + //[ symplectic_stepper_detail_system_class_example + harm_osc h; + rkn.do_step( make_pair( boost::bind( &harm_osc::f1 , h , _1 , _2 ) , boost::bind( &harm_osc::f2 , h , _1 , _2 ) ) , + x , t , dt ); + //] + } + + // Simplified harmonic oscillator example + { + double t = 0.0, dt = 0.1; + //[ simplified_symplectic_stepper_example + pair< vector_type , vector_type > x; + x.first[0] = 1.0; x.second[0] = 0.0; + symplectic_rkn_sb3a_mclachlan< vector_type > rkn; + rkn.do_step( harm_osc_f1() , x , t , dt ); + //] + + vector_type q = {{ 1.0 }} , p = {{ 0.0 }}; + //[ symplectic_stepper_detail_ref_usage + rkn.do_step( harm_osc_f1() , make_pair( boost::ref( q ) , boost::ref( p ) ) , t , dt ); + rkn.do_step( harm_osc_f1() , q , p , t , dt ); + rkn.do_step( make_pair( harm_osc_f1() , harm_osc_f2() ) , q , p , t , dt ); + //] + } + + // adams_bashforth_moulton stepper example + { + double t = 0.0 , dt = 0.1; + state_type inout; + //[ multistep_detail_example + adams_bashforth_moulton< 5 , state_type > abm; + abm.initialize( sys , inout , t , dt ); + abm.do_step( sys , inout , t , dt ); + //] + + //[ multistep_detail_own_stepper_initialization + abm.initialize( runge_kutta_fehlberg78< state_type >() , sys , inout , t , dt ); + //] + } + + + + // dense output stepper examples + { + double t = 0.0 , dt = 0.1; + state_type in; + //[ dense_output_detail_example + dense_output_runge_kutta< controlled_runge_kutta< runge_kutta_dopri5< state_type > > > dense; + dense.initialize( in , t , dt ); + pair< double , double > times = dense.do_step( sys ); + (void)times; + //] + + state_type inout; + double t_start = 0.0 , t_end = 1.0; + //[ dense_output_detail_generation1 + typedef boost::numeric::odeint::result_of::make_dense_output< + runge_kutta_dopri5< state_type > >::type dense_stepper_type; + dense_stepper_type dense2 = make_dense_output( 1.0e-6 , 1.0e-6 , runge_kutta_dopri5< state_type >() ); + (void)dense2; + //] + + //[ dense_output_detail_generation2 + integrate_const( make_dense_output( 1.0e-6 , 1.0e-6 , runge_kutta_dopri5< state_type >() ) , sys , inout , t_start , t_end , dt ); + //] + } + + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/stiff_system.cpp b/src/boost/libs/numeric/odeint/examples/stiff_system.cpp new file mode 100644 index 000000000..ca71f6600 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/stiff_system.cpp @@ -0,0 +1,118 @@ +/* + * rosenbrock4.cpp + * + * Copyright 2010-2012 Mario Mulansky + * Copyright 2011-2012 Karsten Ahnert + * Copyright 2012 Andreas Angelopoulos + * + * 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) + */ + +#include <iostream> +#include <fstream> +#include <utility> + +#include <boost/numeric/odeint.hpp> + +#include <boost/phoenix/core.hpp> + +#include <boost/phoenix/core.hpp> +#include <boost/phoenix/operator.hpp> + +using namespace std; +using namespace boost::numeric::odeint; +namespace phoenix = boost::phoenix; + + + +//[ stiff_system_definition +typedef boost::numeric::ublas::vector< double > vector_type; +typedef boost::numeric::ublas::matrix< double > matrix_type; + +struct stiff_system +{ + void operator()( const vector_type &x , vector_type &dxdt , double /* t */ ) + { + dxdt[ 0 ] = -101.0 * x[ 0 ] - 100.0 * x[ 1 ]; + dxdt[ 1 ] = x[ 0 ]; + } +}; + +struct stiff_system_jacobi +{ + void operator()( const vector_type & /* x */ , matrix_type &J , const double & /* t */ , vector_type &dfdt ) + { + J( 0 , 0 ) = -101.0; + J( 0 , 1 ) = -100.0; + J( 1 , 0 ) = 1.0; + J( 1 , 1 ) = 0.0; + dfdt[0] = 0.0; + dfdt[1] = 0.0; + } +}; +//] + + + +/* +//[ stiff_system_alternative_definition +typedef boost::numeric::ublas::vector< double > vector_type; +typedef boost::numeric::ublas::matrix< double > matrix_type; + +struct stiff_system +{ + template< class State > + void operator()( const State &x , State &dxdt , double t ) + { + ... + } +}; + +struct stiff_system_jacobi +{ + template< class State , class Matrix > + void operator()( const State &x , Matrix &J , const double &t , State &dfdt ) + { + ... + } +}; +//] + */ + + + +int main( int argc , char **argv ) +{ +// typedef rosenbrock4< double > stepper_type; +// typedef rosenbrock4_controller< stepper_type > controlled_stepper_type; +// typedef rosenbrock4_dense_output< controlled_stepper_type > dense_output_type; + //[ integrate_stiff_system + vector_type x( 2 , 1.0 ); + + size_t num_of_steps = integrate_const( make_dense_output< rosenbrock4< double > >( 1.0e-6 , 1.0e-6 ) , + make_pair( stiff_system() , stiff_system_jacobi() ) , + x , 0.0 , 50.0 , 0.01 , + cout << phoenix::arg_names::arg2 << " " << phoenix::arg_names::arg1[0] << "\n" ); + //] + clog << num_of_steps << endl; + + + +// typedef runge_kutta_dopri5< vector_type > dopri5_type; +// typedef controlled_runge_kutta< dopri5_type > controlled_dopri5_type; +// typedef dense_output_runge_kutta< controlled_dopri5_type > dense_output_dopri5_type; + //[ integrate_stiff_system_alternative + + vector_type x2( 2 , 1.0 ); + + size_t num_of_steps2 = integrate_const( make_dense_output< runge_kutta_dopri5< vector_type > >( 1.0e-6 , 1.0e-6 ) , + stiff_system() , x2 , 0.0 , 50.0 , 0.01 , + cout << phoenix::arg_names::arg2 << " " << phoenix::arg_names::arg1[0] << "\n" ); + //] + clog << num_of_steps2 << endl; + + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/stochastic_euler.cpp b/src/boost/libs/numeric/odeint/examples/stochastic_euler.cpp new file mode 100644 index 000000000..c98d27b09 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/stochastic_euler.cpp @@ -0,0 +1,147 @@ +/* + libs/numeric/odeint/examples/stochastic_euler.hpp + + Copyright 2012 Karsten Ahnert + Copyright 2012 Mario Mulansky + + Stochastic euler stepper example and Ornstein-Uhlenbeck process + + 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) + */ + + +#include <vector> +#include <iostream> +#include <boost/random.hpp> +#include <boost/array.hpp> + +#include <boost/numeric/odeint.hpp> + + +/* +//[ stochastic_euler_class_definition +template< size_t N > class stochastic_euler +{ +public: + + typedef boost::array< double , N > state_type; + typedef boost::array< double , N > deriv_type; + typedef double value_type; + typedef double time_type; + typedef unsigned short order_type; + typedef boost::numeric::odeint::stepper_tag stepper_category; + + static order_type order( void ) { return 1; } + + // ... +}; +//] +*/ + + +/* +//[ stochastic_euler_do_step +template< size_t N > class stochastic_euler +{ +public: + + // ... + + template< class System > + void do_step( System system , state_type &x , time_type t , time_type dt ) const + { + deriv_type det , stoch ; + system.first( x , det ); + system.second( x , stoch ); + for( size_t i=0 ; i<x.size() ; ++i ) + x[i] += dt * det[i] + sqrt( dt ) * stoch[i]; + } +}; +//] +*/ + + + + +//[ stochastic_euler_class +template< size_t N > +class stochastic_euler +{ +public: + + typedef boost::array< double , N > state_type; + typedef boost::array< double , N > deriv_type; + typedef double value_type; + typedef double time_type; + typedef unsigned short order_type; + + typedef boost::numeric::odeint::stepper_tag stepper_category; + + static order_type order( void ) { return 1; } + + template< class System > + void do_step( System system , state_type &x , time_type t , time_type dt ) const + { + deriv_type det , stoch ; + system.first( x , det ); + system.second( x , stoch ); + for( size_t i=0 ; i<x.size() ; ++i ) + x[i] += dt * det[i] + sqrt( dt ) * stoch[i]; + } +}; +//] + + + +//[ stochastic_euler_ornstein_uhlenbeck_def +const static size_t N = 1; +typedef boost::array< double , N > state_type; + +struct ornstein_det +{ + void operator()( const state_type &x , state_type &dxdt ) const + { + dxdt[0] = -x[0]; + } +}; + +struct ornstein_stoch +{ + boost::mt19937 &m_rng; + boost::normal_distribution<> m_dist; + + ornstein_stoch( boost::mt19937 &rng , double sigma ) : m_rng( rng ) , m_dist( 0.0 , sigma ) { } + + void operator()( const state_type &x , state_type &dxdt ) + { + dxdt[0] = m_dist( m_rng ); + } +}; +//] + +struct streaming_observer +{ + template< class State > + void operator()( const State &x , double t ) const + { + std::cout << t << "\t" << x[0] << "\n"; + } +}; + + +int main( int argc , char **argv ) +{ + using namespace std; + using namespace boost::numeric::odeint; + + //[ ornstein_uhlenbeck_main + boost::mt19937 rng; + double dt = 0.1; + state_type x = {{ 1.0 }}; + integrate_const( stochastic_euler< N >() , make_pair( ornstein_det() , ornstein_stoch( rng , 1.0 ) ), + x , 0.0 , 10.0 , dt , streaming_observer() ); + //] + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/stuart_landau.cpp b/src/boost/libs/numeric/odeint/examples/stuart_landau.cpp new file mode 100644 index 000000000..84f9b04d8 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/stuart_landau.cpp @@ -0,0 +1,87 @@ +/* + * stuart_landau.cpp + * + * This example demonstrates how one can use odeint can be used with state types consisting of complex variables. + * + * Copyright 2011-2012 Karsten Ahnert + * Copyright 2011-2013 Mario Mulansky + * 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) + */ + +#include <iostream> +#include <complex> +#include <boost/array.hpp> + +#include <boost/numeric/odeint.hpp> + +using namespace std; +using namespace boost::numeric::odeint; + +//[ stuart_landau_system_function +typedef complex< double > state_type; + +struct stuart_landau +{ + double m_eta; + double m_alpha; + + stuart_landau( double eta = 1.0 , double alpha = 1.0 ) + : m_eta( eta ) , m_alpha( alpha ) { } + + void operator()( const state_type &x , state_type &dxdt , double t ) const + { + const complex< double > I( 0.0 , 1.0 ); + dxdt = ( 1.0 + m_eta * I ) * x - ( 1.0 + m_alpha * I ) * norm( x ) * x; + } +}; +//] + + +/* +//[ stuart_landau_system_function_alternative +double eta = 1.0; +double alpha = 1.0; + +void stuart_landau( const state_type &x , state_type &dxdt , double t ) +{ + const complex< double > I( 0.0 , 1.0 ); + dxdt = ( 1.0 + m_eta * I ) * x - ( 1.0 + m_alpha * I ) * norm( x ) * x; +} +//] +*/ + + +struct streaming_observer +{ + std::ostream& m_out; + + streaming_observer( std::ostream &out ) : m_out( out ) { } + + template< class State > + void operator()( const State &x , double t ) const + { + m_out << t; + m_out << "\t" << x.real() << "\t" << x.imag() ; + m_out << "\n"; + } +}; + + + + +int main( int argc , char **argv ) +{ + //[ stuart_landau_integration + state_type x = complex< double >( 1.0 , 0.0 ); + + const double dt = 0.1; + + typedef runge_kutta4< state_type > stepper_type; + + integrate_const( stepper_type() , stuart_landau( 2.0 , 1.0 ) , x , 0.0 , 10.0 , dt , streaming_observer( cout ) ); + //] + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/thrust/Makefile b/src/boost/libs/numeric/odeint/examples/thrust/Makefile new file mode 100644 index 000000000..5a33bdb32 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/thrust/Makefile @@ -0,0 +1,34 @@ +# Copyright 2011-2014 Mario Mulansky +# Copyright 2011-2012 Karsten Ahnert +# +# 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) + +# make sure BOOST_ROOT is pointing to your boost directory +# otherwise, set it here: +# BOOST_ROOT = /path/to/boost + +# path to the cuda installation +CUDA_ROOT = /usr/local/cuda +# target architecture +ARCH = sm_13 + +NVCC = $(CUDA_ROOT)/bin/nvcc + +INCLUDES += -I../../include/ -I$(BOOST_ROOT) + +NVCCFLAGS = -O3 $(INCLUDES) -arch $(ARCH) + +%.o : %.cu + $(NVCC) $(NVCCFLAGS) -c $< -o $@ + +% : %.o + $(NVCC) $(NVCCFLAGS) -o $@ $< + + +all : phase_oscillator_chain phase_oscillator_ensemble lorenz_parameters relaxation + + +clean : + -rm *~ *.o phase_oscillator_chain phase_oscillator_ensemble lorenz_parameters relaxation diff --git a/src/boost/libs/numeric/odeint/examples/thrust/lorenz_parameters.cu b/src/boost/libs/numeric/odeint/examples/thrust/lorenz_parameters.cu new file mode 100644 index 000000000..b3323756d --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/thrust/lorenz_parameters.cu @@ -0,0 +1,296 @@ +/* + Copyright 2011-2012 Karsten Ahnert + Copyright 2011-2013 Mario Mulansky + + 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) + */ + +#include <iostream> +#include <cmath> +#include <utility> + + +#include <thrust/device_vector.h> +#include <thrust/reduce.h> +#include <thrust/functional.h> + +#include <boost/numeric/odeint.hpp> + +#include <boost/numeric/odeint/external/thrust/thrust.hpp> + +#include <boost/random/mersenne_twister.hpp> +#include <boost/random/uniform_real.hpp> +#include <boost/random/variate_generator.hpp> + + +using namespace std; +using namespace boost::numeric::odeint; + +//change this to float if your device does not support double computation +typedef double value_type; + +//change this to host_vector< ... > of you want to run on CPU +typedef thrust::device_vector< value_type > state_type; +typedef thrust::device_vector< size_t > index_vector_type; +// typedef thrust::host_vector< value_type > state_type; +// typedef thrust::host_vector< size_t > index_vector_type; + + +const value_type sigma = 10.0; +const value_type b = 8.0 / 3.0; + + +//[ thrust_lorenz_parameters_define_simple_system +struct lorenz_system +{ + struct lorenz_functor + { + template< class T > + __host__ __device__ + void operator()( T t ) const + { + // unpack the parameter we want to vary and the Lorenz variables + value_type R = thrust::get< 3 >( t ); + value_type x = thrust::get< 0 >( t ); + value_type y = thrust::get< 1 >( t ); + value_type z = thrust::get< 2 >( t ); + thrust::get< 4 >( t ) = sigma * ( y - x ); + thrust::get< 5 >( t ) = R * x - y - x * z; + thrust::get< 6 >( t ) = -b * z + x * y ; + + } + }; + + lorenz_system( size_t N , const state_type &beta ) + : m_N( N ) , m_beta( beta ) { } + + template< class State , class Deriv > + void operator()( const State &x , Deriv &dxdt , value_type t ) const + { + thrust::for_each( + thrust::make_zip_iterator( thrust::make_tuple( + boost::begin( x ) , + boost::begin( x ) + m_N , + boost::begin( x ) + 2 * m_N , + m_beta.begin() , + boost::begin( dxdt ) , + boost::begin( dxdt ) + m_N , + boost::begin( dxdt ) + 2 * m_N ) ) , + thrust::make_zip_iterator( thrust::make_tuple( + boost::begin( x ) + m_N , + boost::begin( x ) + 2 * m_N , + boost::begin( x ) + 3 * m_N , + m_beta.begin() , + boost::begin( dxdt ) + m_N , + boost::begin( dxdt ) + 2 * m_N , + boost::begin( dxdt ) + 3 * m_N ) ) , + lorenz_functor() ); + } + size_t m_N; + const state_type &m_beta; +}; +//] + +struct lorenz_perturbation_system +{ + struct lorenz_perturbation_functor + { + template< class T > + __host__ __device__ + void operator()( T t ) const + { + value_type R = thrust::get< 1 >( t ); + value_type x = thrust::get< 0 >( thrust::get< 0 >( t ) ); + value_type y = thrust::get< 1 >( thrust::get< 0 >( t ) ); + value_type z = thrust::get< 2 >( thrust::get< 0 >( t ) ); + value_type dx = thrust::get< 3 >( thrust::get< 0 >( t ) ); + value_type dy = thrust::get< 4 >( thrust::get< 0 >( t ) ); + value_type dz = thrust::get< 5 >( thrust::get< 0 >( t ) ); + thrust::get< 0 >( thrust::get< 2 >( t ) ) = sigma * ( y - x ); + thrust::get< 1 >( thrust::get< 2 >( t ) ) = R * x - y - x * z; + thrust::get< 2 >( thrust::get< 2 >( t ) ) = -b * z + x * y ; + thrust::get< 3 >( thrust::get< 2 >( t ) ) = sigma * ( dy - dx ); + thrust::get< 4 >( thrust::get< 2 >( t ) ) = ( R - z ) * dx - dy - x * dz; + thrust::get< 5 >( thrust::get< 2 >( t ) ) = y * dx + x * dy - b * dz; + } + }; + + lorenz_perturbation_system( size_t N , const state_type &beta ) + : m_N( N ) , m_beta( beta ) { } + + template< class State , class Deriv > + void operator()( const State &x , Deriv &dxdt , value_type t ) const + { + thrust::for_each( + thrust::make_zip_iterator( thrust::make_tuple( + thrust::make_zip_iterator( thrust::make_tuple( + boost::begin( x ) , + boost::begin( x ) + m_N , + boost::begin( x ) + 2 * m_N , + boost::begin( x ) + 3 * m_N , + boost::begin( x ) + 4 * m_N , + boost::begin( x ) + 5 * m_N ) ) , + m_beta.begin() , + thrust::make_zip_iterator( thrust::make_tuple( + boost::begin( dxdt ) , + boost::begin( dxdt ) + m_N , + boost::begin( dxdt ) + 2 * m_N , + boost::begin( dxdt ) + 3 * m_N , + boost::begin( dxdt ) + 4 * m_N , + boost::begin( dxdt ) + 5 * m_N ) ) + ) ) , + thrust::make_zip_iterator( thrust::make_tuple( + thrust::make_zip_iterator( thrust::make_tuple( + boost::begin( x ) + m_N , + boost::begin( x ) + 2 * m_N , + boost::begin( x ) + 3 * m_N , + boost::begin( x ) + 4 * m_N , + boost::begin( x ) + 5 * m_N , + boost::begin( x ) + 6 * m_N ) ) , + m_beta.begin() , + thrust::make_zip_iterator( thrust::make_tuple( + boost::begin( dxdt ) + m_N , + boost::begin( dxdt ) + 2 * m_N , + boost::begin( dxdt ) + 3 * m_N , + boost::begin( dxdt ) + 4 * m_N , + boost::begin( dxdt ) + 5 * m_N , + boost::begin( dxdt ) + 6 * m_N ) ) + ) ) , + lorenz_perturbation_functor() ); + } + + size_t m_N; + const state_type &m_beta; +}; + +struct lyap_observer +{ + //[thrust_lorenz_parameters_observer_functor + struct lyap_functor + { + template< class T > + __host__ __device__ + void operator()( T t ) const + { + value_type &dx = thrust::get< 0 >( t ); + value_type &dy = thrust::get< 1 >( t ); + value_type &dz = thrust::get< 2 >( t ); + value_type norm = sqrt( dx * dx + dy * dy + dz * dz ); + dx /= norm; + dy /= norm; + dz /= norm; + thrust::get< 3 >( t ) += log( norm ); + } + }; + //] + + lyap_observer( size_t N , size_t every = 100 ) + : m_N( N ) , m_lyap( N ) , m_every( every ) , m_count( 0 ) + { + thrust::fill( m_lyap.begin() , m_lyap.end() , 0.0 ); + } + + template< class Lyap > + void fill_lyap( Lyap &lyap ) + { + thrust::copy( m_lyap.begin() , m_lyap.end() , lyap.begin() ); + for( size_t i=0 ; i<lyap.size() ; ++i ) + lyap[i] /= m_t_overall; + } + + + template< class State > + void operator()( State &x , value_type t ) + { + if( ( m_count != 0 ) && ( ( m_count % m_every ) == 0 ) ) + { + thrust::for_each( + thrust::make_zip_iterator( thrust::make_tuple( + boost::begin( x ) + 3 * m_N , + boost::begin( x ) + 4 * m_N , + boost::begin( x ) + 5 * m_N , + m_lyap.begin() ) ) , + thrust::make_zip_iterator( thrust::make_tuple( + boost::begin( x ) + 4 * m_N , + boost::begin( x ) + 5 * m_N , + boost::begin( x ) + 6 * m_N , + m_lyap.end() ) ) , + lyap_functor() ); + clog << t << "\n"; + } + ++m_count; + m_t_overall = t; + } + + size_t m_N; + state_type m_lyap; + size_t m_every; + size_t m_count; + value_type m_t_overall; +}; + +const size_t N = 1024*2; +const value_type dt = 0.01; + + +int main( int arc , char* argv[] ) +{ + int driver_version , runtime_version; + cudaDriverGetVersion( &driver_version ); + cudaRuntimeGetVersion ( &runtime_version ); + cout << driver_version << "\t" << runtime_version << endl; + + + //[ thrust_lorenz_parameters_define_beta + vector< value_type > beta_host( N ); + const value_type beta_min = 0.0 , beta_max = 56.0; + for( size_t i=0 ; i<N ; ++i ) + beta_host[i] = beta_min + value_type( i ) * ( beta_max - beta_min ) / value_type( N - 1 ); + + state_type beta = beta_host; + //] + + //[ thrust_lorenz_parameters_integration + state_type x( 6 * N ); + + // initialize x,y,z + thrust::fill( x.begin() , x.begin() + 3 * N , 10.0 ); + + // initial dx + thrust::fill( x.begin() + 3 * N , x.begin() + 4 * N , 1.0 ); + + // initialize dy,dz + thrust::fill( x.begin() + 4 * N , x.end() , 0.0 ); + + + // create error stepper, can be used with make_controlled or make_dense_output + typedef runge_kutta_dopri5< state_type , value_type , state_type , value_type > stepper_type; + + + lorenz_system lorenz( N , beta ); + lorenz_perturbation_system lorenz_perturbation( N , beta ); + lyap_observer obs( N , 1 ); + + // calculate transients + integrate_adaptive( make_controlled( 1.0e-6 , 1.0e-6 , stepper_type() ) , lorenz , std::make_pair( x.begin() , x.begin() + 3 * N ) , 0.0 , 10.0 , dt ); + + // calculate the Lyapunov exponents -- the main loop + double t = 0.0; + while( t < 10000.0 ) + { + integrate_adaptive( make_controlled( 1.0e-6 , 1.0e-6 , stepper_type() ) , lorenz_perturbation , x , t , t + 1.0 , 0.1 ); + t += 1.0; + obs( x , t ); + } + + vector< value_type > lyap( N ); + obs.fill_lyap( lyap ); + + for( size_t i=0 ; i<N ; ++i ) + cout << beta_host[i] << "\t" << lyap[i] << "\n"; + //] + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/thrust/phase_oscillator_chain.cu b/src/boost/libs/numeric/odeint/examples/thrust/phase_oscillator_chain.cu new file mode 100644 index 000000000..040969726 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/thrust/phase_oscillator_chain.cu @@ -0,0 +1,156 @@ +/* + Copyright 2011-2013 Mario Mulansky + Copyright 2011 Karsten Ahnert + + 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) + */ + +/* + * This example shows how to use odeint on CUDA devices with thrust. + * Note that we require at least Version 3.2 of the nVidia CUDA SDK + * and the thrust library should be installed in the CUDA include + * folder. + * + * As example we use a chain of phase oscillators with nearest neighbour + * coupling, as described in: + * + * Avis H. Cohen, Philip J. Holmes and Richard H. Rand: + * JOURNAL OF MATHEMATICAL BIOLOGY Volume 13, Number 3, 345-369, + * + */ + +#include <iostream> +#include <cmath> + +#include <thrust/device_vector.h> +#include <thrust/iterator/permutation_iterator.h> +#include <thrust/iterator/counting_iterator.h> + +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/integrate/integrate_const.hpp> +#include <boost/numeric/odeint/external/thrust/thrust.hpp> + +using namespace std; + +using namespace boost::numeric::odeint; + + +//change this to float if your device does not support double computation +typedef double value_type; + + +//[ thrust_phase_chain_system +//change this to host_vector< ... > if you want to run on CPU +typedef thrust::device_vector< value_type > state_type; +typedef thrust::device_vector< size_t > index_vector_type; +//typedef thrust::host_vector< value_type > state_type; +//typedef thrust::host_vector< size_t > index_vector_type; + +//<- +/* + * This implements the rhs of the dynamical equation: + * \phi'_0 = \omega_0 + sin( \phi_1 - \phi_0 ) + * \phi'_i = \omega_i + sin( \phi_i+1 - \phi_i ) + sin( \phi_i - \phi_i-1 ) + * \phi'_N-1 = \omega_N-1 + sin( \phi_N-1 - \phi_N-2 ) + */ +//-> +class phase_oscillators +{ + +public: + + struct sys_functor + { + template< class Tuple > + __host__ __device__ + void operator()( Tuple t ) // this functor works on tuples of values + { + // first, unpack the tuple into value, neighbors and omega + const value_type phi = thrust::get<0>(t); + const value_type phi_left = thrust::get<1>(t); // left neighbor + const value_type phi_right = thrust::get<2>(t); // right neighbor + const value_type omega = thrust::get<3>(t); + // the dynamical equation + thrust::get<4>(t) = omega + sin( phi_right - phi ) + sin( phi - phi_left ); + } + }; + + phase_oscillators( const state_type &omega ) + : m_omega( omega ) , m_N( omega.size() ) , m_prev( omega.size() ) , m_next( omega.size() ) + { + // build indices pointing to left and right neighbours + thrust::counting_iterator<size_t> c( 0 ); + thrust::copy( c , c+m_N-1 , m_prev.begin()+1 ); + m_prev[0] = 0; // m_prev = { 0 , 0 , 1 , 2 , 3 , ... , N-1 } + + thrust::copy( c+1 , c+m_N , m_next.begin() ); + m_next[m_N-1] = m_N-1; // m_next = { 1 , 2 , 3 , ... , N-1 , N-1 } + } + + void operator() ( const state_type &x , state_type &dxdt , const value_type dt ) + { + thrust::for_each( + thrust::make_zip_iterator( + thrust::make_tuple( + x.begin() , + thrust::make_permutation_iterator( x.begin() , m_prev.begin() ) , + thrust::make_permutation_iterator( x.begin() , m_next.begin() ) , + m_omega.begin() , + dxdt.begin() + ) ), + thrust::make_zip_iterator( + thrust::make_tuple( + x.end() , + thrust::make_permutation_iterator( x.begin() , m_prev.end() ) , + thrust::make_permutation_iterator( x.begin() , m_next.end() ) , + m_omega.end() , + dxdt.end()) ) , + sys_functor() + ); + } + +private: + + const state_type &m_omega; + const size_t m_N; + index_vector_type m_prev; + index_vector_type m_next; +}; +//] + +const size_t N = 32768; +const value_type pi = 3.1415926535897932384626433832795029; +const value_type epsilon = 6.0 / ( N * N ); // should be < 8/N^2 to see phase locking +const value_type dt = 0.1; + +int main( int arc , char* argv[] ) +{ + //[ thrust_phase_chain_integration + // create initial conditions and omegas on host: + vector< value_type > x_host( N ); + vector< value_type > omega_host( N ); + for( size_t i=0 ; i<N ; ++i ) + { + x_host[i] = 2.0 * pi * drand48(); + omega_host[i] = ( N - i ) * epsilon; // decreasing frequencies + } + + // copy to device + state_type x = x_host; + state_type omega = omega_host; + + // create stepper + runge_kutta4< state_type , value_type , state_type , value_type > stepper; + + // create phase oscillator system function + phase_oscillators sys( omega ); + + // integrate + integrate_const( stepper , sys , x , 0.0 , 10.0 , dt ); + + thrust::copy( x.begin() , x.end() , std::ostream_iterator< value_type >( std::cout , "\n" ) ); + std::cout << std::endl; + //] +} diff --git a/src/boost/libs/numeric/odeint/examples/thrust/phase_oscillator_ensemble.cu b/src/boost/libs/numeric/odeint/examples/thrust/phase_oscillator_ensemble.cu new file mode 100644 index 000000000..d678b8f01 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/thrust/phase_oscillator_ensemble.cu @@ -0,0 +1,280 @@ +/* + The example how the phase_oscillator ensemble can be implemented using CUDA and thrust + + Copyright 2011-2013 Mario Mulansky + Copyright 2011 Karsten Ahnert + + 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) + */ + +#include <iostream> +#include <fstream> +#include <cmath> +#include <utility> + +#include <thrust/device_vector.h> +#include <thrust/reduce.h> +#include <thrust/functional.h> + +#include <boost/numeric/odeint.hpp> +#include <boost/numeric/odeint/external/thrust/thrust.hpp> + +#include <boost/timer.hpp> +#include <boost/random/cauchy_distribution.hpp> + +using namespace std; + +using namespace boost::numeric::odeint; + +/* + * Sorry for that dirty hack, but nvcc has large problems with boost::random. + * + * Nevertheless we need the cauchy distribution from boost::random, and therefore + * we need a generator. Here it is: + */ +struct drand48_generator +{ + typedef double result_type; + result_type operator()( void ) const { return drand48(); } + result_type min( void ) const { return 0.0; } + result_type max( void ) const { return 1.0; } +}; + +//[ thrust_phase_ensemble_state_type +//change this to float if your device does not support double computation +typedef double value_type; + +//change this to host_vector< ... > of you want to run on CPU +typedef thrust::device_vector< value_type > state_type; +// typedef thrust::host_vector< value_type > state_type; +//] + + +//[ thrust_phase_ensemble_mean_field_calculator +struct mean_field_calculator +{ + struct sin_functor : public thrust::unary_function< value_type , value_type > + { + __host__ __device__ + value_type operator()( value_type x) const + { + return sin( x ); + } + }; + + struct cos_functor : public thrust::unary_function< value_type , value_type > + { + __host__ __device__ + value_type operator()( value_type x) const + { + return cos( x ); + } + }; + + static std::pair< value_type , value_type > get_mean( const state_type &x ) + { + //[ thrust_phase_ensemble_sin_sum + value_type sin_sum = thrust::reduce( + thrust::make_transform_iterator( x.begin() , sin_functor() ) , + thrust::make_transform_iterator( x.end() , sin_functor() ) ); + //] + value_type cos_sum = thrust::reduce( + thrust::make_transform_iterator( x.begin() , cos_functor() ) , + thrust::make_transform_iterator( x.end() , cos_functor() ) ); + + cos_sum /= value_type( x.size() ); + sin_sum /= value_type( x.size() ); + + value_type K = sqrt( cos_sum * cos_sum + sin_sum * sin_sum ); + value_type Theta = atan2( sin_sum , cos_sum ); + + return std::make_pair( K , Theta ); + } +}; +//] + + + +//[ thrust_phase_ensemble_sys_function +class phase_oscillator_ensemble +{ + +public: + + struct sys_functor + { + value_type m_K , m_Theta , m_epsilon; + + sys_functor( value_type K , value_type Theta , value_type epsilon ) + : m_K( K ) , m_Theta( Theta ) , m_epsilon( epsilon ) { } + + template< class Tuple > + __host__ __device__ + void operator()( Tuple t ) + { + thrust::get<2>(t) = thrust::get<1>(t) + m_epsilon * m_K * sin( m_Theta - thrust::get<0>(t) ); + } + }; + + // ... + //<- + phase_oscillator_ensemble( size_t N , value_type g = 1.0 , value_type epsilon = 1.0 ) + : m_omega() , m_N( N ) , m_epsilon( epsilon ) + { + create_frequencies( g ); + } + + void create_frequencies( value_type g ) + { + boost::cauchy_distribution< value_type > cauchy( 0.0 , g ); +// boost::variate_generator< boost::mt19937&, boost::cauchy_distribution< value_type > > gen( rng , cauchy ); + drand48_generator d48; + vector< value_type > omega( m_N ); + for( size_t i=0 ; i<m_N ; ++i ) + omega[i] = cauchy( d48 ); +// generate( omega.begin() , omega.end() , gen ); + m_omega = omega; + } + + void set_epsilon( value_type epsilon ) { m_epsilon = epsilon; } + + value_type get_epsilon( void ) const { return m_epsilon; } + //-> + + void operator() ( const state_type &x , state_type &dxdt , const value_type dt ) const + { + std::pair< value_type , value_type > mean_field = mean_field_calculator::get_mean( x ); + + thrust::for_each( + thrust::make_zip_iterator( thrust::make_tuple( x.begin() , m_omega.begin() , dxdt.begin() ) ), + thrust::make_zip_iterator( thrust::make_tuple( x.end() , m_omega.end() , dxdt.end()) ) , + sys_functor( mean_field.first , mean_field.second , m_epsilon ) + ); + } + + // ... + //<- +private: + + state_type m_omega; + const size_t m_N; + value_type m_epsilon; + //-> +}; +//] + + +//[ thrust_phase_ensemble_observer +struct statistics_observer +{ + value_type m_K_mean; + size_t m_count; + + statistics_observer( void ) + : m_K_mean( 0.0 ) , m_count( 0 ) { } + + template< class State > + void operator()( const State &x , value_type t ) + { + std::pair< value_type , value_type > mean = mean_field_calculator::get_mean( x ); + m_K_mean += mean.first; + ++m_count; + } + + value_type get_K_mean( void ) const { return ( m_count != 0 ) ? m_K_mean / value_type( m_count ) : 0.0 ; } + + void reset( void ) { m_K_mean = 0.0; m_count = 0; } +}; +//] + + + +// const size_t N = 16384 * 128; +const size_t N = 16384; +const value_type pi = 3.1415926535897932384626433832795029; +const value_type dt = 0.1; +const value_type d_epsilon = 0.1; +const value_type epsilon_min = 0.0; +const value_type epsilon_max = 5.0; +const value_type t_transients = 10.0; +const value_type t_max = 100.0; + +int main( int arc , char* argv[] ) +{ + // initial conditions on host + vector< value_type > x_host( N ); + for( size_t i=0 ; i<N ; ++i ) x_host[i] = 2.0 * pi * drand48(); + + //[ thrust_phase_ensemble_system_instance + phase_oscillator_ensemble ensemble( N , 1.0 ); + //] + + + + boost::timer timer; + boost::timer timer_local; + double dopri5_time = 0.0 , rk4_time = 0.0; + { + //[thrust_phase_ensemble_define_dopri5 + typedef runge_kutta_dopri5< state_type , value_type , state_type , value_type > stepper_type; + //] + + ofstream fout( "phase_ensemble_dopri5.dat" ); + timer.restart(); + for( value_type epsilon = epsilon_min ; epsilon < epsilon_max ; epsilon += d_epsilon ) + { + ensemble.set_epsilon( epsilon ); + statistics_observer obs; + state_type x = x_host; + + timer_local.restart(); + + // calculate some transients steps + //[ thrust_phase_ensemble_integration + size_t steps1 = integrate_const( make_controlled( 1.0e-6 , 1.0e-6 , stepper_type() ) , boost::ref( ensemble ) , x , 0.0 , t_transients , dt ); + //] + + // integrate and compute the statistics + size_t steps2 = integrate_const( make_dense_output( 1.0e-6 , 1.0e-6 , stepper_type() ) , boost::ref( ensemble ) , x , 0.0 , t_max , dt , boost::ref( obs ) ); + + fout << epsilon << "\t" << obs.get_K_mean() << endl; + cout << "Dopri5 : " << epsilon << "\t" << obs.get_K_mean() << "\t" << timer_local.elapsed() << "\t" << steps1 << "\t" << steps2 << endl; + } + dopri5_time = timer.elapsed(); + } + + + + { + //[ thrust_phase_ensemble_define_rk4 + typedef runge_kutta4< state_type , value_type , state_type , value_type > stepper_type; + //] + + ofstream fout( "phase_ensemble_rk4.dat" ); + timer.restart(); + for( value_type epsilon = epsilon_min ; epsilon < epsilon_max ; epsilon += d_epsilon ) + { + ensemble.set_epsilon( epsilon ); + statistics_observer obs; + state_type x = x_host; + + timer_local.restart(); + + // calculate some transients steps + size_t steps1 = integrate_const( stepper_type() , boost::ref( ensemble ) , x , 0.0 , t_transients , dt ); + + // integrate and compute the statistics + size_t steps2 = integrate_const( stepper_type() , boost::ref( ensemble ) , x , 0.0 , t_max , dt , boost::ref( obs ) ); + fout << epsilon << "\t" << obs.get_K_mean() << endl; + cout << "RK4 : " << epsilon << "\t" << obs.get_K_mean() << "\t" << timer_local.elapsed() << "\t" << steps1 << "\t" << steps2 << endl; + } + rk4_time = timer.elapsed(); + } + + cout << "Dopri 5 : " << dopri5_time << " s\n"; + cout << "RK4 : " << rk4_time << "\n"; + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/thrust/relaxation.cu b/src/boost/libs/numeric/odeint/examples/thrust/relaxation.cu new file mode 100644 index 000000000..f1d9f3a28 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/thrust/relaxation.cu @@ -0,0 +1,81 @@ +/* + Copyright 2011-2012 Karsten Ahnert + Copyright 2013 Mario Mulansky + + 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) + */ + + +/* + * Solves many relaxation equations dxdt = - a * x in parallel and for different values of a. + * The relaxation equations are completely uncoupled. + */ + +#include <thrust/device_vector.h> + +#include <boost/ref.hpp> + +#include <boost/numeric/odeint.hpp> +#include <boost/numeric/odeint/external/thrust/thrust.hpp> + + +using namespace std; +using namespace boost::numeric::odeint; + +// change to float if your GPU does not support doubles +typedef double value_type; +typedef thrust::device_vector< value_type > state_type; +typedef runge_kutta4< state_type , value_type , state_type , value_type > stepper_type; + +struct relaxation +{ + struct relaxation_functor + { + template< class T > + __host__ __device__ + void operator()( T t ) const + { + // unpack the parameter we want to vary and the Lorenz variables + value_type a = thrust::get< 1 >( t ); + value_type x = thrust::get< 0 >( t ); + thrust::get< 2 >( t ) = -a * x; + } + }; + + relaxation( size_t N , const state_type &a ) + : m_N( N ) , m_a( a ) { } + + void operator()( const state_type &x , state_type &dxdt , value_type t ) const + { + thrust::for_each( + thrust::make_zip_iterator( thrust::make_tuple( x.begin() , m_a.begin() , dxdt.begin() ) ) , + thrust::make_zip_iterator( thrust::make_tuple( x.end() , m_a.end() , dxdt.end() ) ) , + relaxation_functor() ); + } + + size_t m_N; + const state_type &m_a; +}; + +const size_t N = 1024 * 1024; +const value_type dt = 0.01; + +int main( int arc , char* argv[] ) +{ + // initialize the relaxation constants a + vector< value_type > a_host( N ); + for( size_t i=0 ; i<N ; ++i ) a_host[i] = drand48(); + state_type a = a_host; + + // initialize the intial state x + state_type x( N ); + thrust::fill( x.begin() , x.end() , 1.0 ); + + // integrate + relaxation relax( N , a ); + integrate_const( stepper_type() , boost::ref( relax ) , x , 0.0 , 10.0 , dt ); + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/two_dimensional_phase_lattice.cpp b/src/boost/libs/numeric/odeint/examples/two_dimensional_phase_lattice.cpp new file mode 100644 index 000000000..1fe4b9554 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/two_dimensional_phase_lattice.cpp @@ -0,0 +1,158 @@ +/* + * two_dimensional_phase_lattice.cpp + * + * This example show how one can use matrices as state types in odeint. + * + * Copyright 2011-2012 Karsten Ahnert + * Copyright 2011-2013 Mario Mulansky + * 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) + */ + +#include <iostream> +#include <map> +#include <string> +#include <fstream> + +#ifndef M_PI //not there on windows +#define M_PI 3.1415927 //... +#endif + +#include <boost/numeric/odeint.hpp> + +using namespace std; +using namespace boost::numeric::odeint; + +//[ two_dimensional_phase_lattice_definition +typedef boost::numeric::ublas::matrix< double > state_type; + +struct two_dimensional_phase_lattice +{ + two_dimensional_phase_lattice( double gamma = 0.5 ) + : m_gamma( gamma ) { } + + void operator()( const state_type &x , state_type &dxdt , double /* t */ ) const + { + size_t size1 = x.size1() , size2 = x.size2(); + + for( size_t i=1 ; i<size1-1 ; ++i ) + { + for( size_t j=1 ; j<size2-1 ; ++j ) + { + dxdt( i , j ) = + coupling_func( x( i + 1 , j ) - x( i , j ) ) + + coupling_func( x( i - 1 , j ) - x( i , j ) ) + + coupling_func( x( i , j + 1 ) - x( i , j ) ) + + coupling_func( x( i , j - 1 ) - x( i , j ) ); + } + } + + for( size_t i=0 ; i<x.size1() ; ++i ) dxdt( i , 0 ) = dxdt( i , x.size2() -1 ) = 0.0; + for( size_t j=0 ; j<x.size2() ; ++j ) dxdt( 0 , j ) = dxdt( x.size1() -1 , j ) = 0.0; + } + + double coupling_func( double x ) const + { + return sin( x ) - m_gamma * ( 1.0 - cos( x ) ); + } + + double m_gamma; +}; +//] + + +struct write_for_gnuplot +{ + size_t m_every , m_count; + + write_for_gnuplot( size_t every = 10 ) + : m_every( every ) , m_count( 0 ) { } + + void operator()( const state_type &x , double t ) + { + if( ( m_count % m_every ) == 0 ) + { + clog << t << endl; + cout << "sp '-'" << endl; + for( size_t i=0 ; i<x.size1() ; ++i ) + { + for( size_t j=0 ; j<x.size2() ; ++j ) + { + cout << i << "\t" << j << "\t" << sin( x( i , j ) ) << "\n"; + } + cout << "\n"; + } + cout << "e" << endl; + } + + ++m_count; + } +}; + +class write_snapshots +{ +public: + + typedef std::map< size_t , std::string > map_type; + + write_snapshots( void ) : m_count( 0 ) { } + + void operator()( const state_type &x , double t ) + { + map< size_t , string >::const_iterator it = m_snapshots.find( m_count ); + if( it != m_snapshots.end() ) + { + ofstream fout( it->second.c_str() ); + for( size_t i=0 ; i<x.size1() ; ++i ) + { + for( size_t j=0 ; j<x.size2() ; ++j ) + { + fout << i << "\t" << j << "\t" << x( i , j ) << "\t" << sin( x( i , j ) ) << "\n"; + } + fout << "\n"; + } + } + ++m_count; + } + + map_type& snapshots( void ) { return m_snapshots; } + const map_type& snapshots( void ) const { return m_snapshots; } + +private: + + size_t m_count; + map_type m_snapshots; +}; + + +int main( int argc , char **argv ) +{ + size_t size1 = 128 , size2 = 128; + state_type x( size1 , size2 , 0.0 ); + + for( size_t i=(size1/2-10) ; i<(size1/2+10) ; ++i ) + for( size_t j=(size2/2-10) ; j<(size2/2+10) ; ++j ) + x( i , j ) = static_cast<double>( rand() ) / RAND_MAX * 2.0 * M_PI; + + write_snapshots snapshots; + snapshots.snapshots().insert( make_pair( size_t( 0 ) , string( "lat_0000.dat" ) ) ); + snapshots.snapshots().insert( make_pair( size_t( 100 ) , string( "lat_0100.dat" ) ) ); + snapshots.snapshots().insert( make_pair( size_t( 1000 ) , string( "lat_1000.dat" ) ) ); + observer_collection< state_type , double > obs; + obs.observers().push_back( write_for_gnuplot( 10 ) ); + obs.observers().push_back( snapshots ); + + cout << "set term x11" << endl; + cout << "set pm3d map" << endl; + + integrate_const( runge_kutta4<state_type>() , two_dimensional_phase_lattice( 1.2 ) , + x , 0.0 , 1001.0 , 0.1 , boost::ref( obs ) ); + + // controlled steppers work only after ublas bugfix + //integrate_const( make_dense_output< runge_kutta_dopri5< state_type > >( 1E-6 , 1E-6 ) , two_dimensional_phase_lattice( 1.2 ) , + // x , 0.0 , 1001.0 , 0.1 , boost::ref( obs ) ); + + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/ublas/Jamfile.v2 b/src/boost/libs/numeric/odeint/examples/ublas/Jamfile.v2 new file mode 100644 index 000000000..7abff98ef --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/ublas/Jamfile.v2 @@ -0,0 +1,13 @@ +# Copyright 2011 Mario Mulansky +# Copyright 2012 Karsten Ahnert +# 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) + + +project + : requirements + <define>BOOST_ALL_NO_LIB=1 + ; + +exe lorenz_ublas : lorenz_ublas.cpp ; diff --git a/src/boost/libs/numeric/odeint/examples/ublas/lorenz_ublas.cpp b/src/boost/libs/numeric/odeint/examples/ublas/lorenz_ublas.cpp new file mode 100644 index 000000000..0e3958d07 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/ublas/lorenz_ublas.cpp @@ -0,0 +1,40 @@ +/* + * Copyright 2011-2013 Mario Mulansky + * Copyright 2012 Karsten Ahnert + * + * 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) + */ + + +#include <iostream> + +#include <boost/numeric/odeint.hpp> +#include <boost/numeric/ublas/vector.hpp> + +typedef boost::numeric::ublas::vector< double > state_type; + +void lorenz( const state_type &x , state_type &dxdt , const double t ) +{ + const double sigma( 10.0 ); + const double R( 28.0 ); + const double b( 8.0 / 3.0 ); + + dxdt[0] = sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = -b * x[2] + x[0] * x[1]; +} + +using namespace boost::numeric::odeint; + +//[ublas_main +int main() +{ + state_type x(3); + x[0] = 10.0; x[1] = 5.0 ; x[2] = 0.0; + typedef runge_kutta_dopri5< state_type > stepper; + integrate_const( make_dense_output< stepper >( 1E-6 , 1E-6 ) , lorenz , x , + 0.0 , 10.0 , 0.1 ); +} +//] diff --git a/src/boost/libs/numeric/odeint/examples/van_der_pol_stiff.cpp b/src/boost/libs/numeric/odeint/examples/van_der_pol_stiff.cpp new file mode 100644 index 000000000..a53ae4dbe --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/van_der_pol_stiff.cpp @@ -0,0 +1,95 @@ +/* + * van_der_pol_stiff.cpp + * + * Created on: Dec 12, 2011 + * + * Copyright 2012 Karsten Ahnert + * Copyright 2012-2013 Rajeev Singh + * Copyright 2012-2013 Mario Mulansky + * + * 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) + */ + +#include <iostream> +#include <fstream> +#include <utility> + +#include <boost/numeric/odeint.hpp> + +#include <boost/phoenix/core.hpp> +#include <boost/phoenix/operator.hpp> + +using namespace std; +using namespace boost::numeric::odeint; +namespace phoenix = boost::phoenix; + +const double mu = 1000.0; + + +typedef boost::numeric::ublas::vector< double > vector_type; +typedef boost::numeric::ublas::matrix< double > matrix_type; + +struct vdp_stiff +{ + void operator()( const vector_type &x , vector_type &dxdt , double t ) + { + dxdt[0] = x[1]; + dxdt[1] = -x[0] - mu * x[1] * (x[0]*x[0]-1.0); + } +}; + +struct vdp_stiff_jacobi +{ + void operator()( const vector_type &x , matrix_type &J , const double &t , vector_type &dfdt ) + { + J(0, 0) = 0.0; + J(0, 1) = 1.0; + J(1, 0) = -1.0 - 2.0*mu * x[0] * x[1]; + J(1, 1) = -mu * ( x[0] * x[0] - 1.0); + + dfdt[0] = 0.0; + dfdt[1] = 0.0; + } +}; + + +int main( int argc , char **argv ) +{ + //[ integrate_stiff_system + vector_type x( 2 ); + /* initialize random seed: */ + srand ( time(NULL) ); + + // initial conditions + for (int i=0; i<2; i++) + x[i] = 1.0; //(1.0 * rand()) / RAND_MAX; + + size_t num_of_steps = integrate_const( make_dense_output< rosenbrock4< double > >( 1.0e-6 , 1.0e-6 ) , + make_pair( vdp_stiff() , vdp_stiff_jacobi() ) , + x , 0.0 , 1000.0 , 1.0 + , cout << phoenix::arg_names::arg2 << " " << phoenix::arg_names::arg1[0] << " " << phoenix::arg_names::arg1[1] << "\n" + ); + //] + clog << num_of_steps << endl; + + + + //[ integrate_stiff_system_alternative + + vector_type x2( 2 ); + // initial conditions + for (int i=0; i<2; i++) + x2[i] = 1.0; //(1.0 * rand()) / RAND_MAX; + + //size_t num_of_steps2 = integrate_const( make_dense_output< runge_kutta_dopri5< vector_type > >( 1.0e-6 , 1.0e-6 ) , + // vdp_stiff() , x2 , 0.0 , 1000.0 , 1.0 + // , cout << phoenix::arg_names::arg2 << " " << phoenix::arg_names::arg1[0] << " " << phoenix::arg_names::arg1[1] << "\n" + // ); + //] + //clog << num_of_steps2 << endl; + + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/examples/vexcl/Jamfile.v2 b/src/boost/libs/numeric/odeint/examples/vexcl/Jamfile.v2 new file mode 100644 index 000000000..73dc8dae0 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/vexcl/Jamfile.v2 @@ -0,0 +1,32 @@ +# Copyright 2012 Karsten Ahnert +# Copyright 2013 Mario Mulansky +# +# 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 boost ; +import os ; + +boost.use-project ; + + +# change these lines to fit you configuration +local HOME = [ os.environ HOME ] ; +local VEXCL_INCLUDE = [ os.environ VEXCL_ROOT ] ; +OPENCL_INCLUDE = /usr/local/cuda/include ; + + + +lib opencl : : <name>OpenCL ; + +project : requirements + <implicit-dependency>/boost//headers + <include>$(VEXCL_INCLUDE) + <include>$(OPENCL_INCLUDE) + <toolset>gcc:<cxxflags>-std=c++0x + <library>/boost//system/ + ; + +exe lorenz_ensemble : lorenz_ensemble.cpp opencl ;
\ No newline at end of file diff --git a/src/boost/libs/numeric/odeint/examples/vexcl/lorenz_ensemble.cpp b/src/boost/libs/numeric/odeint/examples/vexcl/lorenz_ensemble.cpp new file mode 100644 index 000000000..0e7594ca3 --- /dev/null +++ b/src/boost/libs/numeric/odeint/examples/vexcl/lorenz_ensemble.cpp @@ -0,0 +1,86 @@ +/* + * Copyright 2012 Karsten Ahnert + * Copyright 2013 Mario Mulansky + * + * 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) + */ + +#include <iostream> +#include <vector> + +#include <vexcl/vexcl.hpp> + +#include <boost/numeric/odeint.hpp> +//[ vexcl_includes +#include <boost/numeric/odeint/external/vexcl/vexcl.hpp> +//] + +namespace odeint = boost::numeric::odeint; + +//[ vexcl_state_types +typedef vex::vector< double > vector_type; +typedef vex::multivector< double, 3 > state_type; +//] + + +//[ vexcl_system +const double sigma = 10.0; +const double b = 8.0 / 3.0; + +struct sys_func +{ + const vector_type &R; + + sys_func( const vector_type &_R ) : R( _R ) { } + + void operator()( const state_type &x , state_type &dxdt , double t ) const + { + dxdt(0) = -sigma * ( x(0) - x(1) ); + dxdt(1) = R * x(0) - x(1) - x(0) * x(2); + dxdt(2) = - b * x(2) + x(0) * x(1); + } +}; +//] + + +int main( int argc , char **argv ) +{ + using namespace std; + using namespace odeint; + + //[ vexcl_main + // setup the opencl context + vex::Context ctx( vex::Filter::Type(CL_DEVICE_TYPE_GPU) ); + std::cout << ctx << std::endl; + + // set up number of system, time step and integration time + const size_t n = 1024 * 1024; + const double dt = 0.01; + const double t_max = 1000.0; + + // initialize R + double Rmin = 0.1 , Rmax = 50.0 , dR = ( Rmax - Rmin ) / double( n - 1 ); + std::vector<double> x( n * 3 ) , r( n ); + for( size_t i=0 ; i<n ; ++i ) r[i] = Rmin + dR * double( i ); + vector_type R( ctx.queue() , r ); + + // initialize the state of the lorenz ensemble + state_type X(ctx.queue(), n); + X(0) = 10.0; + X(1) = 10.0; + X(2) = 10.0; + + // create a stepper + runge_kutta4< state_type > stepper; + + // solve the system + integrate_const( stepper , sys_func( R ) , X , 0.0 , t_max , dt ); + //] + + std::vector< double > res( 3 * n ); + vex::copy( X(0) , res ); + for( size_t i=0 ; i<n ; ++i ) + cout << r[i] << "\t" << res[i] << "\t" << "\n"; +} diff --git a/src/boost/libs/numeric/odeint/fix-copyright.py b/src/boost/libs/numeric/odeint/fix-copyright.py new file mode 100755 index 000000000..f4848226a --- /dev/null +++ b/src/boost/libs/numeric/odeint/fix-copyright.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python +from subprocess import check_output as run +from datetime import datetime +from itertools import groupby +from operator import itemgetter +import re +import magic + +def authors(filename): + log = run(['git', 'log', '--follow', + '--date=short','--format=%aN%x09%ad', filename], + universal_newlines=True) + for line in log.splitlines(): + author, date = line.split('\t') + if author != 'fix-copyright.py': + yield author, datetime.strptime(date, '%Y-%m-%d') + +def new_copyright(filename, previous): + def f(): + au = list(authors(filename)) + alldates = map(itemgetter(1), au) + aup = sorted(au + map(lambda a: (a, None), previous), key=itemgetter(0)) + for author, records in groupby(aup, itemgetter(0)): + dates = filter(None, map(itemgetter(1), records)) + if not dates: dates = alldates + start = min(dates) + end = max(dates) + fmt = '{0}' if start.year == end.year else '{0}-{1}' + line = 'Copyright ' + fmt.format(start.year, end.year) + ' ' + author + key = (start, author) + yield key, line + return map(itemgetter(1), sorted(f())) + +def fix_copyright(filename): + # Find copyright block in original file + prefix = set() + names = [] + lines = [] + with open(filename, 'r') as f: + content = list(f) + for i, line in enumerate(content[:15]): + m = re.match(r'^(?P<prefix>\W*)(\(c\))?\s*?copyright\s*(\(c\))?\s+\d{4}(\s*-\s*\d{4})?\s+(?P<name>.+?)\s*$', line, re.IGNORECASE) + if m: + d = m.groupdict() + prefix.add(d['prefix']) + lines.append(i) + names.append(d['name'].strip()) + if len(prefix) != 1: + print 'Not found:', filename + return + prefix = list(prefix)[0] + + print filename + new = iter(new_copyright(filename, names)) + with open(filename, 'w') as f: + for i, line in enumerate(content): + if i in lines: + for repl in new: + print >>f, prefix + repl + else: + print >>f, line, + pass + +def all_files(): + ls = run(['git', 'ls-files'], universal_newlines=True) + for filename in ls.splitlines(): + if magic.from_file(filename, mime=True).split('/')[0] == 'text': + yield filename + +for f in all_files(): + fix_copyright(f) diff --git a/src/boost/libs/numeric/odeint/index.html b/src/boost/libs/numeric/odeint/index.html new file mode 100644 index 000000000..20c131439 --- /dev/null +++ b/src/boost/libs/numeric/odeint/index.html @@ -0,0 +1,20 @@ +<!-- +Copyright 2012 Beman Daves +Copyright 2012 Karsten Ahnert +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) +--> +<html> +<head> +<meta http-equiv="refresh" content="0; URL=doc/html/index.html"> +</head> +<body> +Automatic redirection failed, please go to +<a href="doc/html/index.html">doc/html/index.html</a> +<hr> +<p>© Copyright Beman Dawes, 2001</p> +<p> Distributed under the Boost Software +License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt"> +www.boost.org/LICENSE_1_0.txt</a>)</p> +</body> +</html> diff --git a/src/boost/libs/numeric/odeint/meta/libraries.json b/src/boost/libs/numeric/odeint/meta/libraries.json new file mode 100644 index 000000000..7825fec22 --- /dev/null +++ b/src/boost/libs/numeric/odeint/meta/libraries.json @@ -0,0 +1,16 @@ +{ + "key": "numeric/odeint", + "name": "Odeint", + "authors": [ + "Karsten Ahnert", + "Mario Mulansky" + ], + "description": "Solving ordinary differential equations.", + "category": [ + "Math" + ], + "maintainers": [ + "Karsten Ahnert <karsten.ahnert -at- gmx.de>", + "Mario Mulansky <mario.mulansky -at- gmx.net>" + ] +} diff --git a/src/boost/libs/numeric/odeint/performance/Jamfile.v2 b/src/boost/libs/numeric/odeint/performance/Jamfile.v2 new file mode 100644 index 000000000..e60e4ea12 --- /dev/null +++ b/src/boost/libs/numeric/odeint/performance/Jamfile.v2 @@ -0,0 +1,32 @@ +# Copyright 2012 Karsten Ahnert +# Copyright 2012 Mario Mulansky +# 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 os ; +import modules ; +import path ; + +project + : requirements + <define>BOOST_ALL_NO_LIB=1 + <include>../../../.. + <cxxflags>-std=c++11 + <toolset>gcc:<cxxflags>-ffast-math + <toolset>intel:<cxxflags>"-fast -inline-forceinline" + : default-build release + ; + + +lib libgsl : : <name>gsl ; +lib libgslcblas : : <name>gslcblas ; + +lib libmkl : : <name>mkl_intel_lp64 <link>shared ; +lib libmkl_core : : <name>mkl_core <link>shared ; +lib libmkl_intel_thread : : <name>mkl_intel_thread ; +lib libiomp5 : : <name>iomp5 ; +lib libpthread : : <name>pthread ; + +exe odeint_rk4_array + : odeint_rk4_array.cpp + ; diff --git a/src/boost/libs/numeric/odeint/performance/Makefile b/src/boost/libs/numeric/odeint/performance/Makefile new file mode 100644 index 000000000..641cb0313 --- /dev/null +++ b/src/boost/libs/numeric/odeint/performance/Makefile @@ -0,0 +1,43 @@ +# Copyright 2011-2014 Mario Mulansky +# Copyright 2011-2014 Karsten Ahnert +# +# 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) + +# make sure BOOST_ROOT is pointing to your boost directory +# otherwise, set it here: +# BOOST_ROOT = /path/to/boost + +INCLUDES += -I../../include/ -I$(BOOST_ROOT) +GCCFLAGS = -O3 -ffast-math -DNDEBUG +# disabling -ffast-math might give slightly better performance +ICCFLAGS = -Ofast -xHost -ip -inline-forceinline -DNDEBUG +# Possible options: -fp-model source -no-fma +GFORTFLAGS = -Ofast + +bin/gcc: + mkdir -p bin/gcc + +bin/intel: + mkdir -p bin/intel + +bin/gfort: + mkdir -p bin/gfort + +bin/gcc/odeint_rk4_array: odeint_rk4_array.cpp bin/gcc + g++ ${GCCFLAGS} ${INCLUDES} -o bin/gcc/odeint_rk4_array odeint_rk4_array.cpp + +bin/gcc/c_lorenz: c_lorenz.c bin/gcc + gcc -std=c99 -Ofast -mtune=corei7-avx c_lorenz.c -o bin/gcc/c_lorenz + +bin/intel/odeint_rk4_array: odeint_rk4_array.cpp bin/intel + icpc ${ICCFLAGS} ${INCLUDES} -o bin/intel/odeint_rk4_array odeint_rk4_array.cpp + +bin/intel/c_lorenz: c_lorenz.c bin/intel + icc -std=c99 -Ofast -xHost -ansi-alias -o bin/intel/c_lorenz c_lorenz.c + +bin/gfort/fortran_lorenz: fortran_lorenz.f90 bin/gfort + gfortran ${GFORTFLAGS} fortran_lorenz.f90 -o bin/gfort/fortran_lorenz + +all: bin/gcc/odeint_rk4_array bin/intel/odeint_rk4_array bin/gcc/c_lorenz bin/intel/c_lorenz bin/gfort/fortran_lorenz diff --git a/src/boost/libs/numeric/odeint/performance/SIMD/Makefile b/src/boost/libs/numeric/odeint/performance/SIMD/Makefile new file mode 100644 index 000000000..811acd988 --- /dev/null +++ b/src/boost/libs/numeric/odeint/performance/SIMD/Makefile @@ -0,0 +1,33 @@ +# Copyright 2014 Mario Mulansky +# +# 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) + +# make sure BOOST_ROOT is pointing to your boost directory +# otherwise, set it here: +# BOOST_ROOT = /path/to/boost +# you also need NT2s SIMD libary available set the include path here: +# SIMD_INCLUDE = /path/to/simd/include + +INCLUDES = -I$(BOOST_ROOT) -I${SIMD_INCLUDE} + +# INTEL COMPILER +# change this if you want to cross-compile +ARCH = Host +# ARCH = AVX +# ARCH = SSE4.2 + +CXX = icpc +CC = icpc +CXXFLAGS = -O3 -x${ARCH} -std=c++0x -fno-alias -inline-forceinline -DNDEBUG ${INCLUDES} +# -ip + +# GCC COMPILER +# change this if you want to cross-compile +# ARCH = native +# # ARCH = core-avx-i + +# CXX = g++ +# CC = g++ +# CXXFLAGS = -O3 -ffast-math -mtune=${ARCH} -march=${ARCH} -std=c++0x -DNDEBUG ${INCLUDES} diff --git a/src/boost/libs/numeric/odeint/performance/SIMD/perf_roessler.sh b/src/boost/libs/numeric/odeint/performance/SIMD/perf_roessler.sh new file mode 100755 index 000000000..a1094f63a --- /dev/null +++ b/src/boost/libs/numeric/odeint/performance/SIMD/perf_roessler.sh @@ -0,0 +1,22 @@ +#!/bin/bash +echo "Running on ${HOSTNAME}" + +out_dir=perf_${HOSTNAME} +mkdir -p ${out_dir} + +for N in 256 1024 4096 16384 65536 262144 1048576 4194304 16777216 67108864 +do + steps=`expr 4 \* 67108864 / ${N}` + for exe in "roessler" "roessler_simd" + do + rm -f ${out_dir}/${exe}_N${N}.times + for i in {0..4} + do + likwid-pin -cS0:0 ./${exe} ${N} ${steps} >> ${out_dir}/${exe}_N${N}.times + done + for perf_ctr in "FLOPS_DP" "FLOPS_AVX" "L2" "L3" "MEM" + do + likwid-perfctr -CS0:0 -g ${perf_ctr} ./${exe} ${N} ${steps} > ${out_dir}/${exe}_N${N}_${perf_ctr}.perf + done + done +done diff --git a/src/boost/libs/numeric/odeint/performance/SIMD/roessler.cpp b/src/boost/libs/numeric/odeint/performance/SIMD/roessler.cpp new file mode 100644 index 000000000..4e6cc4229 --- /dev/null +++ b/src/boost/libs/numeric/odeint/performance/SIMD/roessler.cpp @@ -0,0 +1,125 @@ +/* + * Simulation of an ensemble of Roessler attractors + * + * Copyright 2014 Mario Mulansky + * + * 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) + * + */ + + +#include <iostream> +#include <vector> +#include <random> + +#include <boost/timer.hpp> +#include <boost/array.hpp> + +#include <boost/numeric/odeint.hpp> + +namespace odeint = boost::numeric::odeint; + +typedef boost::timer timer_type; + +typedef double fp_type; +//typedef float fp_type; + +typedef boost::array<fp_type, 3> state_type; +typedef std::vector<state_type> state_vec; + +//--------------------------------------------------------------------------- +struct roessler_system { + const fp_type m_a, m_b, m_c; + + roessler_system(const fp_type a, const fp_type b, const fp_type c) + : m_a(a), m_b(b), m_c(c) + {} + + void operator()(const state_type &x, state_type &dxdt, const fp_type t) const + { + dxdt[0] = -x[1] - x[2]; + dxdt[1] = x[0] + m_a * x[1]; + dxdt[2] = m_b + x[2] * (x[0] - m_c); + } +}; + +//--------------------------------------------------------------------------- +int main(int argc, char *argv[]) { +if(argc<3) +{ + std::cerr << "Expected size and steps as parameter" << std::endl; + exit(1); +} +const size_t n = atoi(argv[1]); +const size_t steps = atoi(argv[2]); +//const size_t steps = 50; + +const fp_type dt = 0.01; + +const fp_type a = 0.2; +const fp_type b = 1.0; +const fp_type c = 9.0; + +// random initial conditions on the device +std::vector<fp_type> x(n), y(n), z(n); +std::default_random_engine generator; +std::uniform_real_distribution<fp_type> distribution_xy(-8.0, 8.0); +std::uniform_real_distribution<fp_type> distribution_z(0.0, 20.0); +auto rand_xy = std::bind(distribution_xy, std::ref(generator)); +auto rand_z = std::bind(distribution_z, std::ref(generator)); +std::generate(x.begin(), x.end(), rand_xy); +std::generate(y.begin(), y.end(), rand_xy); +std::generate(z.begin(), z.end(), rand_z); + +state_vec state(n); +for(size_t i=0; i<n; ++i) +{ + state[i][0] = x[i]; + state[i][1] = y[i]; + state[i][2] = z[i]; +} + +std::cout.precision(16); + +std::cout << "# n: " << n << std::endl; + +std::cout << x[0] << std::endl; + + +// Stepper type - use never_resizer for slight performance improvement +odeint::runge_kutta4_classic<state_type, fp_type, state_type, fp_type, + odeint::array_algebra, + odeint::default_operations, + odeint::never_resizer> stepper; + +roessler_system sys(a, b, c); + +timer_type timer; + +fp_type t = 0.0; + +for (int step = 0; step < steps; step++) +{ + for(size_t i=0; i<n; ++i) + { + stepper.do_step(sys, state[i], t, dt); + } + t += dt; +} + +std::cout << "Integration finished, runtime for " << steps << " steps: "; +std::cout << timer.elapsed() << " s" << std::endl; + +// compute some accumulation to make sure all results have been computed +fp_type s = 0.0; +for(size_t i = 0; i < n; ++i) +{ + s += state[i][0]; +} + +std::cout << state[0][0] << std::endl; +std::cout << s/n << std::endl; + +} diff --git a/src/boost/libs/numeric/odeint/performance/SIMD/roessler_simd.cpp b/src/boost/libs/numeric/odeint/performance/SIMD/roessler_simd.cpp new file mode 100644 index 000000000..d79af4d8b --- /dev/null +++ b/src/boost/libs/numeric/odeint/performance/SIMD/roessler_simd.cpp @@ -0,0 +1,149 @@ +/* + * Simulation of an ensemble of Roessler attractors using NT2 SIMD library + * This requires the SIMD library headers. + * + * Copyright 2014 Mario Mulansky + * + * 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) + * + */ + + +#include <iostream> +#include <vector> +#include <random> + +#include <boost/timer.hpp> +#include <boost/array.hpp> + +#include <boost/numeric/odeint.hpp> +#include <boost/simd/sdk/simd/pack.hpp> +#include <boost/simd/sdk/simd/io.hpp> +#include <boost/simd/memory/allocator.hpp> +#include <boost/simd/include/functions/splat.hpp> +#include <boost/simd/include/functions/plus.hpp> +#include <boost/simd/include/functions/multiplies.hpp> + + +namespace odeint = boost::numeric::odeint; +namespace simd = boost::simd; + +typedef boost::timer timer_type; + +static const size_t dim = 3; // roessler is 3D + +typedef double fp_type; +//typedef float fp_type; + +typedef simd::pack<fp_type> simd_pack; +typedef boost::array<simd_pack, dim> state_type; +// use the simd allocator to get properly aligned memory +typedef std::vector< state_type, simd::allocator< state_type > > state_vec; + +static const size_t pack_size = simd_pack::static_size; + +//--------------------------------------------------------------------------- +struct roessler_system { + const fp_type m_a, m_b, m_c; + + roessler_system(const fp_type a, const fp_type b, const fp_type c) + : m_a(a), m_b(b), m_c(c) + {} + + void operator()(const state_type &x, state_type &dxdt, const fp_type t) const + { + dxdt[0] = -1.0*x[1] - x[2]; + dxdt[1] = x[0] + m_a * x[1]; + dxdt[2] = m_b + x[2] * (x[0] - m_c); + } +}; + +//--------------------------------------------------------------------------- +int main(int argc, char *argv[]) { +if(argc<3) +{ + std::cerr << "Expected size and steps as parameter" << std::endl; + exit(1); +} +const size_t n = atoi(argv[1]); +const size_t steps = atoi(argv[2]); + +const fp_type dt = 0.01; + +const fp_type a = 0.2; +const fp_type b = 1.0; +const fp_type c = 9.0; + +// random initial conditions on the device +std::vector<fp_type> x(n), y(n), z(n); +std::default_random_engine generator; +std::uniform_real_distribution<fp_type> distribution_xy(-8.0, 8.0); +std::uniform_real_distribution<fp_type> distribution_z(0.0, 20.0); +auto rand_xy = std::bind(distribution_xy, std::ref(generator)); +auto rand_z = std::bind(distribution_z, std::ref(generator)); +std::generate(x.begin(), x.end(), rand_xy); +std::generate(y.begin(), y.end(), rand_xy); +std::generate(z.begin(), z.end(), rand_z); + +state_vec state(n/pack_size); +for(size_t i=0; i<n/pack_size; ++i) +{ + for(size_t p=0; p<pack_size; ++p) + { + state[i][0][p] = x[i*pack_size+p]; + state[i][1][p] = y[i*pack_size+p]; + state[i][2][p] = z[i*pack_size+p]; + } +} + +std::cout << "Systems: " << n << std::endl; +std::cout << "Steps: " << steps << std::endl; +std::cout << "SIMD pack size: " << pack_size << std::endl; + +std::cout << state[0][0] << std::endl; + +// Stepper type +odeint::runge_kutta4_classic<state_type, fp_type, state_type, fp_type, + odeint::array_algebra, odeint::default_operations, + odeint::never_resizer> stepper; + +roessler_system sys(a, b, c); + +timer_type timer; + +fp_type t = 0.0; + +for(int step = 0; step < steps; step++) +{ + for(size_t i = 0; i < n/pack_size; ++i) + { + stepper.do_step(sys, state[i], t, dt); + } + t += dt; +} + +std::cout.precision(16); + +std::cout << "Integration finished, runtime for " << steps << " steps: "; +std::cout << timer.elapsed() << " s" << std::endl; + +// compute some accumulation to make sure all results have been computed +simd_pack s_pack = 0.0; +for(size_t i = 0; i < n/pack_size; ++i) +{ + s_pack += state[i][0]; +} + +fp_type s = 0.0; +for(size_t p=0; p<pack_size; ++p) +{ + s += s_pack[p]; +} + + +std::cout << state[0][0] << std::endl; +std::cout << s/n << std::endl; + +} diff --git a/src/boost/libs/numeric/odeint/performance/c_lorenz.c b/src/boost/libs/numeric/odeint/performance/c_lorenz.c new file mode 100644 index 000000000..85aba7fde --- /dev/null +++ b/src/boost/libs/numeric/odeint/performance/c_lorenz.c @@ -0,0 +1,57 @@ +#include <stdio.h> +#include <time.h> +#include <math.h> + +void lorenz(const double *x, double *restrict y) { + y[0] = 10.0 * (x[1] - x[0]); + y[1] = 28.0 * x[0] - x[1] - x[0] * x[2]; + y[2] = x[0] * x[1] - (8.0 / 3.0) * x[2]; +} + +int main(int argc, const char *argv[]) +{ + const int nb_steps = 20000000; + const double h = 1.0e-10; + const double h2 = 0.5 * h; + const double nb_loops = 21; + double x[3]; + double y[3]; + double f1[3]; + double f2[3]; + double f3[3]; + double f4[3]; + double min_time = 1E6; + clock_t begin, end; + double time_spent; + + for (int j = 0; j < nb_loops; j++) { + x[0] = 8.5; + x[1] = 3.1; + x[2] = 1.2; + begin = clock(); + for (int k = 0; k < nb_steps; k++) { + lorenz(x, f1); + for (int i = 0; i < 3; i++) { + y[i] = x[i] + h2 * f1[i]; + } + lorenz(y, f2); + for (int i = 0; i < 3; i++) { + y[i] = x[i] + h2 * f2[i]; + } + lorenz(y, f3); + for (int i = 0; i < 3; i++) { + y[i] = x[i] + h * f3[i]; + } + lorenz(y, f4); + for (int i = 0; i < 3; i++) { + x[i] = x[i] + h * (f1[i] + 2 * (f2[i] + f3[i]) + f4[i]) / 6.0; + } + } + end = clock(); + min_time = fmin(min_time, (double)(end-begin)/CLOCKS_PER_SEC); + printf("Result: %f\t runtime: %f\n", x[0], (double)(end-begin)/CLOCKS_PER_SEC); + } + printf("Minimal Runtime: %f\n", min_time); + + return 0; +} diff --git a/src/boost/libs/numeric/odeint/performance/fortran_lorenz.f90 b/src/boost/libs/numeric/odeint/performance/fortran_lorenz.f90 new file mode 100644 index 000000000..26869973c --- /dev/null +++ b/src/boost/libs/numeric/odeint/performance/fortran_lorenz.f90 @@ -0,0 +1,60 @@ +program main + implicit none + + integer, parameter :: dp = 8 + real(dp), dimension(1:3) :: x + integer, parameter :: nstep = 20000000 + real(dp) :: t = 0.0_dp + real(dp) :: h = 1.0e-10_dp + integer, parameter :: nb_loops = 21 + integer, parameter :: n = 3 + integer :: k + integer :: time_begin + integer :: time_end + integer :: count_rate + real(dp) :: time + real(dp) :: min_time = 100.0 + + do k = 1, nb_loops + x = [ 8.5_dp, 3.1_dp, 1.2_dp ] + call system_clock(time_begin, count_rate) + call rk4sys(n, t, x, h, nstep) + call system_clock(time_end, count_rate) + time = real(time_end - time_begin, dp) / real(count_rate, dp) + min_time = min(time, min_time) + write (*,*) time, x(1) + end do + write (*,*) "Minimal Runtime:", min_time +contains + subroutine xpsys(x,f) + real(dp), dimension(1:3), intent(in) :: x + real(dp), dimension(1:3), intent(out) :: f + f(1) = 10.0_dp * ( x(2) - x(1) ) + f(2) = 28.0_dp * x(1) - x(2) - x(1) * x(3) + f(3) = x(1) * x(2) - (8.0_dp / 3.0_dp) * x(3) + end subroutine xpsys + + subroutine rk4sys(n, t, x, h, nstep) + integer, intent(in) :: n + real(dp), intent(in) :: t + real(dp), dimension(1:n), intent(inout) :: x + real(dp), intent(in) :: h + integer, intent(in) :: nstep + ! Local variables + real(dp) :: h2 + real(dp), dimension(1:n) :: y, f1, f2, f3, f4 + integer :: i, k + + h2 = 0.5_dp * h + do k = 1, nstep + call xpsys(x, f1) + y = x + h2 * f1 + call xpsys(y, f2) + y = x + h2 * f2 + call xpsys(y, f3) + y = x + h * f3 + call xpsys(y, f4) + x = x + h * (f1 + 2.0_dp * (f2 + f3) + f4) / 6.0_dp + end do + end subroutine rk4sys +end program main diff --git a/src/boost/libs/numeric/odeint/performance/lorenz.hpp b/src/boost/libs/numeric/odeint/performance/lorenz.hpp new file mode 100644 index 000000000..c1ea37c9e --- /dev/null +++ b/src/boost/libs/numeric/odeint/performance/lorenz.hpp @@ -0,0 +1,33 @@ +/* + * lorenz.hpp + * + * Copyright 2011 Mario Mulansky + * Copyright 2012 Karsten Ahnert + * + * 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) + */ + + +#ifndef LORENZ_HPP_ +#define LORENZ_HPP_ + +#include <boost/array.hpp> + +struct lorenz +{ + template< class state_type > + void inline operator()( const state_type &x , state_type &dxdt , const double t ) const + { + const double sigma = 10.0; + const double R = 28.0; + const double b = 8.0 / 3.0; + dxdt[0] = sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = x[0]*x[1] - b * x[2]; + } +}; + + +#endif /* LORENZ_HPP_ */ diff --git a/src/boost/libs/numeric/odeint/performance/odeint_rk4_array.cpp b/src/boost/libs/numeric/odeint/performance/odeint_rk4_array.cpp new file mode 100644 index 000000000..6d60296f2 --- /dev/null +++ b/src/boost/libs/numeric/odeint/performance/odeint_rk4_array.cpp @@ -0,0 +1,63 @@ +/* + * odeint_rk4_array + * + * Copyright 2011 Mario Mulansky + * Copyright 2012 Karsten Ahnert + * + * 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) + */ + +#include <iostream> + +#include <boost/timer.hpp> +#include <boost/array.hpp> + +#include <boost/numeric/odeint/stepper/runge_kutta4_classic.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/algebra/array_algebra.hpp> + +#include "lorenz.hpp" + +typedef boost::timer timer_type; + +typedef boost::array< double , 3 > state_type; + +using namespace boost::numeric::odeint; + +//typedef boost::numeric::odeint::runge_kutta4_classic< state_type > rk4_odeint_type; + +// use the never resizer explicitely for optimal performance with gcc, +// for the intel compiler this doesnt matter and the above definition +// gives the same performance +typedef runge_kutta4_classic< state_type , double , state_type , double , + array_algebra, default_operations, never_resizer > rk4_odeint_type; + + +const int loops = 21; +const int num_of_steps = 20000000; +const double dt = 1E-10; + + +int main() +{ + double min_time = 1E6; // something big + rk4_odeint_type stepper; + std::clog.precision(16); + std::cout.precision(16); + for( int n=0; n<loops; n++ ) + { + state_type x = {{ 8.5, 3.1, 1.2 }}; + double t = 0.0; + timer_type timer; + for( size_t i = 0 ; i < num_of_steps ; ++i ) + { + stepper.do_step( lorenz(), x, t, dt ); + t += dt; + } + min_time = std::min( timer.elapsed() , min_time ); + std::clog << timer.elapsed() << '\t' << x[0] << std::endl; + } + std::cout << "Minimal Runtime: " << min_time << std::endl; +} diff --git a/src/boost/libs/numeric/odeint/performance/plot_result.py b/src/boost/libs/numeric/odeint/performance/plot_result.py new file mode 100644 index 000000000..f39e49fce --- /dev/null +++ b/src/boost/libs/numeric/odeint/performance/plot_result.py @@ -0,0 +1,64 @@ +""" + Copyright 2011-2014 Mario Mulansky + Copyright 2011-2014 Karsten Ahnert + + 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 numpy as np +from matplotlib import pyplot as plt + +plt.rc("font", size=16) + + +def get_runtime_from_file(filename): + gcc_perf_file = open(filename, 'r') + for line in gcc_perf_file: + if "Minimal Runtime:" in line: + return float(line.split(":")[-1]) + + +t_gcc = [get_runtime_from_file("perf_workbook/odeint_rk4_array_gcc.perf"), + get_runtime_from_file("perf_ariel/odeint_rk4_array_gcc.perf"), + get_runtime_from_file("perf_lyra/odeint_rk4_array_gcc.perf")] + +t_intel = [get_runtime_from_file("perf_workbook/odeint_rk4_array_intel.perf"), + get_runtime_from_file("perf_ariel/odeint_rk4_array_intel.perf"), + get_runtime_from_file("perf_lyra/odeint_rk4_array_intel.perf")] + +t_gfort = [get_runtime_from_file("perf_workbook/rk4_gfort.perf"), + get_runtime_from_file("perf_ariel/rk4_gfort.perf"), + get_runtime_from_file("perf_lyra/rk4_gfort.perf")] + +t_c_intel = [get_runtime_from_file("perf_workbook/rk4_c_intel.perf"), + get_runtime_from_file("perf_ariel/rk4_c_intel.perf"), + get_runtime_from_file("perf_lyra/rk4_c_intel.perf")] + +print t_c_intel + + +ind = np.arange(3) # the x locations for the groups +width = 0.15 # the width of the bars + +fig = plt.figure() +ax = fig.add_subplot(111) +rects1 = ax.bar(ind, t_gcc, width, color='b', label="odeint gcc") +rects2 = ax.bar(ind+width, t_intel, width, color='g', label="odeint intel") +rects3 = ax.bar(ind+2*width, t_c_intel, width, color='y', label="C intel") +rects4 = ax.bar(ind+3*width, t_gfort, width, color='c', label="gfort") + +ax.axis([-width, 2.0+5*width, 0.0, 0.85]) +ax.set_ylabel('Runtime (s)') +ax.set_title('Performance for integrating the Lorenz system') +ax.set_xticks(ind + 1.5*width) +ax.set_xticklabels(('Core i5-3210M\n3.1 GHz', + 'Xeon E5-2690\n3.8 GHz', + 'Opteron 8431\n 2.4 GHz')) +ax.legend(loc='upper left', prop={'size': 16}) + +plt.savefig("perf.pdf") +plt.savefig("perf.png", dpi=50) + +plt.show() diff --git a/src/boost/libs/numeric/odeint/test/Jamfile.v2 b/src/boost/libs/numeric/odeint/test/Jamfile.v2 new file mode 100644 index 000000000..68725822c --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/Jamfile.v2 @@ -0,0 +1,103 @@ +# Copyright 2012-2013 Karsten Ahnert +# Copyright 2012-2013 Mario Mulansky +# Copyright 2013 Pascal Germroth +# 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) + +# bring in rules for testing + +import testing ; + +# make sure you are using a new version of boost.build, otherwise the local +# odeint will not be included properly +# you can fix older boost.build versions by applying the patch provided in +# odeint's root, e.g.: +# cd ~/odeint-v2 +# sudo patch /usr/share/boost-build/build/toolset.jam toolset.jam.patch + +use-project boost : $(BOOST_ROOT) ; + +project + : requirements + <define>BOOST_ALL_NO_LIB=1 + # use test library + <library>/boost//unit_test_framework + <link>static + <toolset>clang:<cxxflags>-Wno-unused-variable + # <cxxflags>-D_SCL_SECURE_NO_WARNINGS + ; + +test-suite "odeint" + : + [ run euler_stepper.cpp ] + [ run runge_kutta_concepts.cpp ] + [ run runge_kutta_error_concepts.cpp ] + [ run runge_kutta_controlled_concepts.cpp ] + [ run resizing.cpp ] + [ run default_operations.cpp ] + [ run range_algebra.cpp ] + [ run implicit_euler.cpp ] +# disable in clang + [ run fusion_algebra.cpp : : : <toolset>clang:<build>no ] + [ run stepper_with_units.cpp : : : <toolset>clang:<build>no ] + [ run stepper_copying.cpp ] + [ run stepper_with_ranges.cpp ] + [ run rosenbrock4.cpp ] + [ run rosenbrock4_mp.cpp ] + [ run is_pair.cpp ] + [ run adams_bashforth.cpp ] + [ run adams_moulton.cpp ] + [ run adams_bashforth_moulton.cpp ] + [ run controlled_adams_bashforth_moulton.cpp ] + [ run adaptive_adams_coefficients.cpp ] + [ run generic_stepper.cpp ] + [ run generic_error_stepper.cpp ] + [ run bulirsch_stoer.cpp ] + [ run integrate_times.cpp ] + [ run integrate_times.cpp : : : <define>ODEINT_INTEGRATE_ITERATOR : integrate_times_iterator ] + [ run integrate.cpp ] + [ run integrate.cpp : : : <define>ODEINT_INTEGRATE_ITERATOR : integrate_iterator ] + [ run integrate_implicit.cpp ] + [ run integrate_implicit.cpp : : : <define>ODEINT_INTEGRATE_ITERATOR : integrate_implicit_iterator ] + [ run generation.cpp ] + [ run trivial_state.cpp ] + [ run is_resizeable.cpp ] + [ run resize.cpp ] + [ run same_size.cpp ] + [ run split.cpp ] + [ run symplectic_steppers.cpp ] + [ run integrators_symplectic.cpp ] + [ run integrators_symplectic.cpp : : : <define>ODEINT_INTEGRATE_ITERATOR : integrators_symplectic_iterator ] + [ run velocity_verlet.cpp ] + [ run multi_array.cpp ] + [ compile algebra_dispatcher.cpp ] + [ run integrate_stepper_refs.cpp ] + [ run const_step_iterator.cpp ] + [ run const_step_time_iterator.cpp ] + [ run adaptive_iterator.cpp ] + [ run adaptive_time_iterator.cpp ] + [ run n_step_iterator.cpp ] + [ run n_step_time_iterator.cpp ] + [ run times_iterator.cpp ] + [ run times_time_iterator.cpp ] + [ run step_size_limitation.cpp ] + [ run integrate_overflow.cpp ] + [ compile unwrap_boost_reference.cpp ] + [ compile unwrap_reference.cpp : <cxxflags>-std=c++0x : unwrap_reference_C++11 ] + [ compile std_array.cpp : <cxxflags>-std=c++0x ] + : + <testing.launcher>valgrind + ; + +# also run numeric tests +build-project numeric ; + +build-project regression ; + +# test-suite "odeint-iterator_integrate" +# : +# [ run integrate.cpp : : : : integrate_iterator ] +# : <testing.launcher>valgrind +# <define>ODEINT_ITERATOR_INTEGRATE +# ; + diff --git a/src/boost/libs/numeric/odeint/test/adams_bashforth.cpp b/src/boost/libs/numeric/odeint/test/adams_bashforth.cpp new file mode 100644 index 000000000..7574346c2 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/adams_bashforth.cpp @@ -0,0 +1,237 @@ +/* + [auto_generated] + libs/numeric/odeint/test/adams_bashforth.cpp + + [begin_description] + This file tests the use of the adams bashforth stepper. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011-2012 Mario Mulansky + + 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) + */ + + +// disable checked iterator warning for msvc + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_adams_bashforth + +#include <utility> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/list.hpp> +#include <boost/mpl/size_t.hpp> +#include <boost/mpl/range_c.hpp> + + +#include <boost/numeric/odeint/stepper/adams_bashforth.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef double value_type; + +struct lorenz +{ + template< class State , class Deriv , class Value > + void operator()( const State &_x , Deriv &_dxdt , const Value &dt ) const + { + const value_type sigma = 10.0; + const value_type R = 28.0; + const value_type b = 8.0 / 3.0; + + typename boost::range_iterator< const State >::type x = boost::begin( _x ); + typename boost::range_iterator< Deriv >::type dxdt = boost::begin( _dxdt ); + + dxdt[0] = sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = x[0]*x[1] - b * x[2]; + } +}; + +template< class State > +class rk4_decorator +{ +public: + + size_t do_count; + + template< class System , class StateIn , class DerivIn , class StateOut > + void do_step_dxdt_impl( System system , const StateIn &in , const DerivIn &dxdt , value_type t , StateOut &out , value_type dt ) + { + m_stepper.do_step( system , in , dxdt , t , out , dt ); + ++do_count; + } + + template< class System , class StateInOut , class DerivIn > + void do_step_dxdt_impl( System system , StateInOut &x , const DerivIn &dxdt , value_type t , value_type dt ) + { + m_stepper.do_step( system , x , dxdt , t , dt ); + ++do_count; + } + + + runge_kutta4< State > m_stepper; + +private: + + +}; + + +BOOST_AUTO_TEST_SUITE( adams_bashforth_test ) + +BOOST_AUTO_TEST_CASE( test_adams_bashforth_coefficients ) +{ + detail::adams_bashforth_coefficients< value_type , 1 > c1; + detail::adams_bashforth_coefficients< value_type , 2 > c2; + detail::adams_bashforth_coefficients< value_type , 3 > c3; + detail::adams_bashforth_coefficients< value_type , 4 > c4; + detail::adams_bashforth_coefficients< value_type , 5 > c5; + detail::adams_bashforth_coefficients< value_type , 6 > c6; + detail::adams_bashforth_coefficients< value_type , 7 > c7; + detail::adams_bashforth_coefficients< value_type , 8 > c8; +} + +BOOST_AUTO_TEST_CASE( test_rotating_buffer ) +{ + const size_t N = 5; + detail::rotating_buffer< size_t , N > buffer; + for( size_t i=0 ; i<N ; ++i ) buffer[i] = i; + + for( size_t i=0 ; i<N ; ++i ) + BOOST_CHECK_EQUAL( buffer[i] , i ); + + buffer.rotate(); + + for( size_t i=1 ; i<N ; ++i ) + BOOST_CHECK_EQUAL( buffer[i] , i - 1 ); + BOOST_CHECK_EQUAL( buffer[0] , size_t( N-1 ) ); +} + +BOOST_AUTO_TEST_CASE( test_copying ) +{ + typedef boost::array< double , 1 > state_type; + typedef adams_bashforth< 2 , state_type > stepper_type; + + stepper_type s1; + s1.step_storage()[0].m_v[0] = 1.5; + s1.step_storage()[1].m_v[0] = 2.25; + + stepper_type s2( s1 ); + BOOST_CHECK_CLOSE( s1.step_storage()[0].m_v[0] , s2.step_storage()[0].m_v[0] , 1.0e-14 ); + BOOST_CHECK_CLOSE( s1.step_storage()[1].m_v[0] , s2.step_storage()[1].m_v[0] , 1.0e-14 ); + BOOST_CHECK( ( &(s1.step_storage()[0]) ) != ( &(s2.step_storage()[0]) ) ); + + stepper_type s3; + state_type *p1 = &( s3.step_storage()[0].m_v ) , *p2 = &( s3.step_storage()[1].m_v ); + s3 = s1; + BOOST_CHECK( p1 == ( &( s3.step_storage()[0].m_v ) ) ); + BOOST_CHECK( p2 == ( &( s3.step_storage()[1].m_v ) ) ); + + BOOST_CHECK_CLOSE( s1.step_storage()[0].m_v[0] , s3.step_storage()[0].m_v[0] , 1.0e-14 ); + BOOST_CHECK_CLOSE( s1.step_storage()[1].m_v[0] , s3.step_storage()[1].m_v[0] , 1.0e-14 ); +} + +typedef boost::mpl::range_c< size_t , 1 , 6 > vector_of_steps; + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_init_and_steps , step_type , vector_of_steps ) +{ + const static size_t steps = step_type::value; + typedef boost::array< value_type , 3 > state_type; + + adams_bashforth< steps , state_type > stepper; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + const value_type dt = 0.01; + value_type t = 0.0; + + stepper.initialize( lorenz() , x , t , dt ); + BOOST_CHECK_CLOSE( t , value_type( steps - 1 ) * dt , 1.0e-14 ); + + stepper.do_step( lorenz() , x , t , dt ); +} + +BOOST_AUTO_TEST_CASE( test_instantiation ) +{ + typedef boost::array< double , 3 > state_type; + adams_bashforth< 1 , state_type > s1; + adams_bashforth< 2 , state_type > s2; + adams_bashforth< 3 , state_type > s3; + adams_bashforth< 4 , state_type > s4; + adams_bashforth< 5 , state_type > s5; + adams_bashforth< 6 , state_type > s6; + adams_bashforth< 7 , state_type > s7; + adams_bashforth< 8 , state_type > s8; + + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + value_type t = 0.0 , dt = 0.01; + s1.do_step( lorenz() , x , t , dt ); + s2.do_step( lorenz() , x , t , dt ); + s3.do_step( lorenz() , x , t , dt ); + s4.do_step( lorenz() , x , t , dt ); + s5.do_step( lorenz() , x , t , dt ); + s6.do_step( lorenz() , x , t , dt ); +// s7.do_step( lorenz() , x , t , dt ); +// s8.do_step( lorenz() , x , t , dt ); +} + +BOOST_AUTO_TEST_CASE( test_auto_initialization ) +{ + typedef boost::array< double , 3 > state_type; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + + adams_bashforth< 3 , state_type , value_type , state_type , value_type , range_algebra , default_operations , + initially_resizer , rk4_decorator< state_type > > adams; + + adams.initializing_stepper().do_count = 0; + adams.do_step( lorenz() , x , 0.0 , x , 0.1 ); + BOOST_CHECK_EQUAL( adams.initializing_stepper().do_count , size_t( 1 ) ); + + adams.do_step( lorenz() , x , 0.0 , x , 0.1 ); + BOOST_CHECK_EQUAL( adams.initializing_stepper().do_count , size_t( 2 ) ); + + adams.do_step( lorenz() , x , 0.0 , x , 0.1 ); + BOOST_CHECK_EQUAL( adams.initializing_stepper().do_count , size_t( 2 ) ); + + adams.do_step( lorenz() , x , 0.0 , x , 0.1 ); + BOOST_CHECK_EQUAL( adams.initializing_stepper().do_count , size_t( 2 ) ); + + adams.reset(); + + adams.do_step( lorenz() , x , 0.0 , x , 0.1 ); + BOOST_CHECK_EQUAL( adams.initializing_stepper().do_count , size_t( 3 ) ); + + adams.do_step( lorenz() , x , 0.0 , x , 0.1 ); + BOOST_CHECK_EQUAL( adams.initializing_stepper().do_count , size_t( 4 ) ); +} + +BOOST_AUTO_TEST_CASE( test_manual_initialization ) +{ + typedef boost::array< double , 3 > state_type; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + + adams_bashforth< 3 , state_type , value_type , state_type , value_type , range_algebra , default_operations , + initially_resizer , rk4_decorator< state_type > > adams; + + adams.initializing_stepper().do_count = 0; + double t = 0.0 , dt = 0.1; + adams.initialize( lorenz() , x , t , dt ); + BOOST_CHECK_EQUAL( adams.initializing_stepper().do_count , size_t( 2 ) ); + + adams.do_step( lorenz() , x , 0.0 , x , 0.1 ); + BOOST_CHECK_EQUAL( adams.initializing_stepper().do_count , size_t( 2 ) ); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/adams_bashforth_moulton.cpp b/src/boost/libs/numeric/odeint/test/adams_bashforth_moulton.cpp new file mode 100644 index 000000000..8e7688bb4 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/adams_bashforth_moulton.cpp @@ -0,0 +1,112 @@ +/* + [auto_generated] + libs/numeric/odeint/test/adams_bashforth_moulton.cpp + + [begin_description] + This file tests the use of the Adams-Bashforth-Moulton. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011 Mario Mulansky + + 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) + */ + +#define BOOST_TEST_MODULE odeint_adams_bashforth_moulton + +#include <utility> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/list.hpp> +#include <boost/mpl/size_t.hpp> +#include <boost/mpl/range_c.hpp> + +#include <boost/numeric/odeint/stepper/adams_bashforth_moulton.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef double value_type; + +struct lorenz +{ + template< class State , class Deriv , class Value > + void operator()( const State &_x , Deriv &_dxdt , const Value &dt ) const + { + const value_type sigma = 10.0; + const value_type R = 28.0; + const value_type b = 8.0 / 3.0; + + typename boost::range_iterator< const State >::type x = boost::begin( _x ); + typename boost::range_iterator< Deriv >::type dxdt = boost::begin( _dxdt ); + + dxdt[0] = sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = x[0]*x[1] - b * x[2]; + } +}; + +BOOST_AUTO_TEST_SUITE( adams_bashforth_moulton_test ) + +typedef boost::mpl::range_c< size_t , 1 , 6 > vector_of_steps; + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_init_and_steps , step_type , vector_of_steps ) +{ + const static size_t steps = step_type::value; + typedef boost::array< value_type , 3 > state_type; + + adams_bashforth_moulton< steps , state_type > stepper; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + const value_type dt = 0.01; + value_type t = 0.0; + + stepper.initialize( lorenz() , x , t , dt ); + BOOST_CHECK_CLOSE( t , value_type( steps - 1 ) * dt , 1.0e-14 ); + + stepper.do_step( lorenz() , x , t , dt ); +} + + +BOOST_AUTO_TEST_CASE( test_copying ) +{ + typedef boost::array< double , 1 > state_type; + typedef adams_bashforth_moulton< 2 , state_type > stepper_type; + + stepper_type s1; + + stepper_type s2( s1 ); + + stepper_type s3; + s3 = s1; + } + + +BOOST_AUTO_TEST_CASE( test_instantiation ) +{ + typedef boost::array< double , 3 > state_type; + adams_bashforth_moulton< 1 , state_type > s1; + adams_bashforth_moulton< 2 , state_type > s2; + adams_bashforth_moulton< 3 , state_type > s3; + adams_bashforth_moulton< 4 , state_type > s4; + adams_bashforth_moulton< 5 , state_type > s5; + adams_bashforth_moulton< 6 , state_type > s6; + adams_bashforth_moulton< 7 , state_type > s7; + adams_bashforth_moulton< 8 , state_type > s8; + + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + value_type t = 0.0 , dt = 0.01; + s1.do_step( lorenz() , x , t , dt ); + s2.do_step( lorenz() , x , t , dt ); + s3.do_step( lorenz() , x , t , dt ); + s4.do_step( lorenz() , x , t , dt ); + s5.do_step( lorenz() , x , t , dt ); + s6.do_step( lorenz() , x , t , dt ); +// s7.do_step( lorenz() , x , t , dt ); +// s8.do_step( lorenz() , x , t , dt ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/adams_moulton.cpp b/src/boost/libs/numeric/odeint/test/adams_moulton.cpp new file mode 100644 index 000000000..faccdda5b --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/adams_moulton.cpp @@ -0,0 +1,104 @@ +/* + [auto_generated] + libs/numeric/odeint/test/adams_moulton.cpp + + [begin_description] + This file tests the use of the Adams-Moulton stepper. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011-2012 Mario Mulansky + + 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) + */ + + +#define BOOST_TEST_MODULE odeint_adams_moulton + +#include <utility> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/list.hpp> +#include <boost/mpl/size_t.hpp> +#include <boost/mpl/range_c.hpp> + + +#include <boost/numeric/odeint/stepper/detail/adams_moulton_coefficients.hpp> +#include <boost/numeric/odeint/stepper/detail/rotating_buffer.hpp> +#include <boost/numeric/odeint/stepper/adams_moulton.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef double value_type; + +struct lorenz +{ + template< class State , class Deriv , class Value > + void operator()( const State &_x , Deriv &_dxdt , const Value &dt ) const + { + const value_type sigma = 10.0; + const value_type R = 28.0; + const value_type b = 8.0 / 3.0; + + typename boost::range_iterator< const State >::type x = boost::begin( _x ); + typename boost::range_iterator< Deriv >::type dxdt = boost::begin( _dxdt ); + + dxdt[0] = sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = x[0]*x[1] - b * x[2]; + } +}; + +BOOST_AUTO_TEST_SUITE( adams_moulton_test ) + +BOOST_AUTO_TEST_CASE( test_adams_moulton_coefficients ) +{ + detail::adams_moulton_coefficients< value_type , 1 > c1; + detail::adams_moulton_coefficients< value_type , 2 > c2; + detail::adams_moulton_coefficients< value_type , 3 > c3; + detail::adams_moulton_coefficients< value_type , 4 > c4; + detail::adams_moulton_coefficients< value_type , 5 > c5; + detail::adams_moulton_coefficients< value_type , 6 > c6; + detail::adams_moulton_coefficients< value_type , 7 > c7; + detail::adams_moulton_coefficients< value_type , 8 > c8; +} + +typedef boost::mpl::range_c< size_t , 1 , 6 > vector_of_steps; + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_init_and_steps , step_type , vector_of_steps ) +{ + const static size_t steps = step_type::value; + typedef boost::array< value_type , 3 > state_type; + + adams_moulton< steps , state_type > stepper; +// state_type x = {{ 10.0 , 10.0 , 10.0 }}; +// const value_type dt = 0.01; +// value_type t = 0.0; + +// stepper.do_step( lorenz() , x , t , dt ); +} + +BOOST_AUTO_TEST_CASE( test_instantiation ) +{ + typedef boost::array< double , 3 > state_type; + adams_moulton< 1 , state_type > s1; + adams_moulton< 2 , state_type > s2; + adams_moulton< 3 , state_type > s3; + adams_moulton< 4 , state_type > s4; + adams_moulton< 5 , state_type > s5; + adams_moulton< 6 , state_type > s6; + adams_moulton< 7 , state_type > s7; + adams_moulton< 8 , state_type > s8; + +// state_type x = {{ 10.0 , 10.0 , 10.0 }}; +// value_type t = 0.0 , dt = 0.01; +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/adaptive_adams_coefficients.cpp b/src/boost/libs/numeric/odeint/test/adaptive_adams_coefficients.cpp new file mode 100644 index 000000000..362458f0b --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/adaptive_adams_coefficients.cpp @@ -0,0 +1,120 @@ +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_adaptive_adams_coefficients + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp> + +#include <vector> + +#include <boost/mpl/list.hpp> +#include <boost/mpl/size_t.hpp> +#include <boost/mpl/range_c.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef double value_type; + +BOOST_AUTO_TEST_SUITE( adaptive_adams_coefficients_test ) + +typedef boost::mpl::range_c< size_t , 2 , 10 > vector_of_steps; +BOOST_AUTO_TEST_CASE_TEMPLATE( test_step, step_type, vector_of_steps ) +{ + const static size_t steps = step_type::value; + + typedef std::vector<double> deriv_type; + typedef double time_type; + + typedef detail::adaptive_adams_coefficients<steps, deriv_type, time_type> aac_type; + + std::vector<double> deriv; + deriv.push_back(-1); + + time_type t = 0.0; + time_type dt = 0.1; + + aac_type coeff; + for(size_t i=0; i<steps; ++i) + { + coeff.predict(t, dt); + coeff.do_step(deriv); + coeff.confirm(); + + t+= dt; + + if(coeff.m_eo < steps) + coeff.m_eo ++; + } + + std::vector<value_type> v(10); + v[0] = 1.0/1.0; + v[1] = 1.0/2.0; + v[2] = 5.0/12.0; + v[3] = 9.0/24.0; + v[4] = 251.0/720.0; + v[5] = 95.0/288.0; + v[6] = 19087.0/60480.0; + v[7] = 5257.0/17280.0; + v[8] = 5311869667636789.0/18014398509481984.0; + + for(size_t i=0; i<steps; ++i) + { + BOOST_CHECK_SMALL(coeff.beta[1][i] - 1.0, 1e-15); + + if(i == 0) + BOOST_CHECK_SMALL(coeff.phi[2][i].m_v[0] + 1, 1e-15); + else if (i == steps-1 && steps%2 == 1) + BOOST_CHECK_SMALL(coeff.phi[2][i].m_v[0] - 1, 1e-14); + else if (i == steps-1 && steps%2 == 0) + BOOST_CHECK_SMALL(coeff.phi[2][i].m_v[0] + 1, 1e-14); + else + BOOST_CHECK_SMALL(coeff.phi[2][i].m_v[0], 1e-15); + + BOOST_CHECK_SMALL(coeff.g[i] - v[i], 1e-15); + } +} + +BOOST_AUTO_TEST_CASE( test_copy ) +{ + typedef std::vector<double> deriv_type; + typedef double time_type; + + typedef detail::adaptive_adams_coefficients<3, deriv_type, time_type> aac_type; + aac_type c1; + + deriv_type deriv(1); + deriv[0] = 1.0; + + time_type t = 0.0; + time_type dt = 0.01; + + for(size_t i=0; i<3; ++i) + { + c1.predict(t, dt); + c1.do_step(deriv); + c1.confirm(); + + t+= dt; + + if(c1.m_eo < 3) + c1.m_eo ++; + } + + aac_type c2(c1); + BOOST_CHECK_EQUAL(c1.phi[0][0].m_v[0], c2.phi[0][0].m_v[0]); + BOOST_CHECK(&(c1.phi[0][0].m_v) != &(c2.phi[0][0].m_v)); + + aac_type c3; + deriv_type *p1 = &(c3.phi[0][0].m_v); + + c3 = c1; + BOOST_CHECK(p1 == (&(c3.phi[0][0].m_v))); + BOOST_CHECK_EQUAL(c1.phi[0][0].m_v[0], c3.phi[0][0].m_v[0]); +} + +BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file diff --git a/src/boost/libs/numeric/odeint/test/adaptive_iterator.cpp b/src/boost/libs/numeric/odeint/test/adaptive_iterator.cpp new file mode 100644 index 000000000..8f3cfa74a --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/adaptive_iterator.cpp @@ -0,0 +1,346 @@ +/* + [auto_generated] + libs/numeric/odeint/test/adaptive_iterator.cpp + + [begin_description] + This file tests the adaptive iterators. + [end_description] + + Copyright 2012-2013 Karsten Ahnert + Copyright 2012-2013 Mario Mulansky + + 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) + */ + + +#define BOOST_TEST_MODULE odeint_adaptive_iterator + +#include <iterator> +#include <algorithm> +#include <vector> + +#include <boost/numeric/odeint/config.hpp> +#include <boost/array.hpp> +#include <boost/range/algorithm/copy.hpp> +#include <boost/range/algorithm/for_each.hpp> +#include <boost/mpl/vector.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> + +#include <boost/numeric/odeint/iterator/adaptive_iterator.hpp> +#include "dummy_steppers.hpp" +#include "dummy_odes.hpp" +#include "dummy_observers.hpp" + +namespace mpl = boost::mpl; +using namespace boost::numeric::odeint; + +typedef dummy_stepper::state_type state_type; +typedef dummy_stepper::value_type value_type; + +BOOST_AUTO_TEST_SUITE( adaptive_iterator_test ) + +typedef mpl::vector< + dummy_controlled_stepper + , dummy_dense_output_stepper + > dummy_steppers; + + +BOOST_AUTO_TEST_CASE( copy_controlled_stepper_iterator ) +{ + typedef adaptive_iterator< dummy_controlled_stepper , empty_system , state_type > iterator_type; + + state_type x = {{ 1.0 }}; + iterator_type iter1( dummy_controlled_stepper() , empty_system() , x ); + iterator_type iter2( iter1 ); + + BOOST_CHECK_EQUAL( &( *iter1 ) , &x ); + BOOST_CHECK_EQUAL( &( *iter2 ) , &x ); + BOOST_CHECK_EQUAL( &( *iter1 ) , &( *iter2 ) ); + BOOST_CHECK( iter1.same( iter2 ) ); + + ++iter1; + ++iter2; + + BOOST_CHECK_EQUAL( &( *iter1 ) , &x ); + BOOST_CHECK_EQUAL( &( *iter2 ) , &x ); + BOOST_CHECK_EQUAL( &( *iter1 ) , &( *iter2 ) ); + BOOST_CHECK( iter1.same( iter2 ) ); + +} + +BOOST_AUTO_TEST_CASE( copy_dense_output_stepper_iterator ) +{ + typedef adaptive_iterator< dummy_dense_output_stepper , empty_system , state_type > iterator_type; + + state_type x = {{ 1.0 }}; + // fix by mario: do not dereference iterators at the end - made iter1 start iterator + iterator_type iter1( dummy_dense_output_stepper() , empty_system() , x , 0.0 , 1.0 , 0.1 ); + iterator_type iter2( iter1 ); + + // fix by mario: iterator dereference now always gives internal state also for dense output, consistent with other iterator implementations + // changed: iterators with dense output stepper do not have an internal state now to avoid a copy + BOOST_CHECK_NE( & (*iter1) , & (*iter2) ); + BOOST_CHECK( iter1.same( iter2 ) ); + + ++iter1; + ++iter2; + + BOOST_CHECK_NE( & (*iter1) , & (*iter2) ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + +BOOST_AUTO_TEST_CASE( copy_dense_output_stepper_iterator_with_reference_wrapper ) +{ + // bad use case, the same stepper is iterated twice + typedef adaptive_iterator< boost::reference_wrapper< dummy_dense_output_stepper > , empty_system , state_type > iterator_type; + + state_type x = {{ 1.0 }}; + dummy_dense_output_stepper stepper; + iterator_type iter1( boost::ref( stepper ) , empty_system() , x , 0.0 , 0.9 , 0.1 ); + iterator_type iter2( iter1 ); + + BOOST_CHECK_EQUAL( & (*iter1) , & (*iter2) ); + BOOST_CHECK( iter1.same( iter2 ) ); + + ++iter1; + ++iter2; + + BOOST_CHECK_EQUAL( & (*iter1) , & (*iter2) ); + BOOST_CHECK( !iter1.same( iter2 ) ); // they point to the same stepper, there the times will be different +} + + + +BOOST_AUTO_TEST_CASE( assignment_controlled_stepper_iterator ) +{ + typedef adaptive_iterator< dummy_controlled_stepper , empty_system , state_type > iterator_type; + state_type x1 = {{ 1.0 }} , x2 = {{ 2.0 }}; + iterator_type iter1 = iterator_type( dummy_controlled_stepper() , empty_system() , x1 , 0.0 , 1.0 , 0.1 ); + iterator_type iter2 = iterator_type( dummy_controlled_stepper() , empty_system() , x2 , 0.0 , 1.0 , 0.2 ); + BOOST_CHECK_EQUAL( &(*iter1) , &x1 ); + BOOST_CHECK_EQUAL( &(*iter2) , &x2 ); + // the iterators are indeed the same as this only checks the time values + BOOST_CHECK( !iter1.same( iter2 ) ); + iter2 = iter1; + BOOST_CHECK_EQUAL( &(*iter1) , &x1 ); + BOOST_CHECK_EQUAL( &(*iter2) , &x1 ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + + + +BOOST_AUTO_TEST_CASE( assignment_dense_output_stepper_iterator ) +{ + typedef adaptive_iterator< dummy_dense_output_stepper , empty_system , state_type > iterator_type; + state_type x1 = {{ 1.0 }}; + iterator_type iter1 = iterator_type( dummy_dense_output_stepper() , empty_system() , x1 , 0.0 , 1.0 , 0.1 ); + iterator_type iter2 = iterator_type( dummy_dense_output_stepper() , empty_system() , x1 , 0.0 , 1.0 , 0.2 ); + + BOOST_CHECK_NE( & (*iter1) , & (*iter2) ); + BOOST_CHECK( !iter1.same( iter2 ) ); + + iter2 = iter1; + // fix by mario: iterator dereference now always gives internal state also for dense output, consistent with other iterator implementations + // changed: iterators with dense output stepper do not have an internal state now to avoid a copy + BOOST_CHECK_NE( & (*iter1) , & (*iter2) ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + +BOOST_AUTO_TEST_CASE( assignment_dense_output_stepper_iterator_with_reference_wrapper ) +{ + typedef adaptive_iterator< boost::reference_wrapper< dummy_dense_output_stepper > , empty_system , state_type > iterator_type; + state_type x1 = {{ 1.0 }}; + + dummy_dense_output_stepper stepper; + iterator_type iter1 = iterator_type( boost::ref( stepper ) , empty_system() , x1 , 0.0 , 1.0 , 0.1 ); + iterator_type iter2 = iterator_type( boost::ref( stepper ) , empty_system() , x1 , 0.0 , 1.0 , 0.2 ); + + BOOST_CHECK_EQUAL( & (*iter1) , & (*iter2) ); + BOOST_CHECK( !iter1.same( iter2 ) ); + + iter2 = iter1; + + BOOST_CHECK_EQUAL( & (*iter1) , & (*iter2) ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + + + +BOOST_AUTO_TEST_CASE( controlled_stepper_iterator_factory ) +{ + dummy_controlled_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_adaptive_iterator_begin( stepper , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + make_adaptive_iterator_end( stepper , boost::ref( system ) , x ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-14 ); +} + +// just test if it compiles +BOOST_AUTO_TEST_CASE( dense_output_stepper_iterator_factory ) +{ + dummy_dense_output_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_adaptive_iterator_begin( stepper , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + make_adaptive_iterator_end( stepper , boost::ref( system ) , x ) , + dummy_observer() ); +} + + + +BOOST_AUTO_TEST_CASE( controlled_stepper_range ) +{ + dummy_controlled_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_adaptive_range( stepper , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-14 ); +} + +// just test if it compiles +BOOST_AUTO_TEST_CASE( dense_output_stepper_range ) +{ + dummy_dense_output_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_adaptive_range( stepper , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + dummy_observer() ); +} + + +BOOST_AUTO_TEST_CASE( controlled_stepper_iterator_with_reference_wrapper_factory ) +{ + dummy_controlled_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_adaptive_iterator_begin( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + make_adaptive_iterator_end( boost::ref( stepper ) , boost::ref( system ) , x ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-14 ); +} + +// just test if it compiles +BOOST_AUTO_TEST_CASE( dense_output_stepper_iterator_with_reference_wrapper_factory ) +{ + dummy_dense_output_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_adaptive_iterator_begin( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + make_adaptive_iterator_end( boost::ref( stepper ) , boost::ref( system ) , x ) , + dummy_observer() ); +} + +BOOST_AUTO_TEST_CASE( controlled_stepper_range_with_reference_wrapper ) +{ + dummy_controlled_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_adaptive_range( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-14 ); +} + +// just test if it compiles +BOOST_AUTO_TEST_CASE( dense_output_stepper_range_with_reference_wrapper ) +{ + dummy_dense_output_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_adaptive_range( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + dummy_observer() ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( transitivity1 , Stepper , dummy_steppers ) +{ + typedef adaptive_iterator< Stepper , empty_system , state_type > stepper_iterator; + + state_type x = {{ 1.0 }}; + stepper_iterator first1( Stepper() , empty_system() , x , 2.5 , 2.0 , 0.1 ); + stepper_iterator last1( Stepper() , empty_system() , x ); + stepper_iterator last2( Stepper() , empty_system() , x ); + + BOOST_CHECK( first1 == last1 ); + BOOST_CHECK( first1 == last2 ); + BOOST_CHECK( last1 == last2 ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm , Stepper , dummy_steppers ) +{ + typedef adaptive_iterator< Stepper , empty_system , state_type > stepper_iterator; + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + stepper_iterator first( Stepper() , empty_system() , x , 0.0 , 0.35 , 0.1 ); + stepper_iterator last( Stepper() , empty_system() , x ); + + std::copy( first , last , std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 5 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[4][0] , 2.0 , 1.0e-14 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + std::copy( make_adaptive_iterator_begin( Stepper() , empty_system() , x , 0.0 , 0.35 , 0.1 ) , + make_adaptive_iterator_end( Stepper() , empty_system() , x ) , + std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 5 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[4][0] , 2.0 , 1.0e-14 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_range_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + boost::range::copy( make_adaptive_range( Stepper() , empty_system() , x , 0.0 , 0.35 , 0.1 ) , + std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 5 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[4][0] , 2.0 , 1.0e-14 ); +} + + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/adaptive_time_iterator.cpp b/src/boost/libs/numeric/odeint/test/adaptive_time_iterator.cpp new file mode 100644 index 000000000..406a71c65 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/adaptive_time_iterator.cpp @@ -0,0 +1,332 @@ +/* + [auto_generated] + libs/numeric/odeint/test/adaptive_time_iterator.cpp + + [begin_description] + This file tests the adaptive time iterator. + [end_description] + + Copyright 2012-2013 Karsten Ahnert + Copyright 2012-2013 Mario Mulansky + + 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) + */ + + +#define BOOST_TEST_MODULE odeint_adaptive_time_iterator + +#include <iterator> +#include <algorithm> +#include <vector> + +#include <boost/numeric/odeint/config.hpp> +#include <boost/array.hpp> +#include <boost/range/algorithm/copy.hpp> +#include <boost/range/algorithm/for_each.hpp> +#include <boost/mpl/vector.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> + +#include <boost/numeric/odeint/iterator/adaptive_time_iterator.hpp> +#include "dummy_steppers.hpp" +#include "dummy_odes.hpp" +#include "dummy_observers.hpp" + +namespace mpl = boost::mpl; +using namespace boost::numeric::odeint; + + + +typedef dummy_stepper::state_type state_type; +typedef dummy_stepper::value_type value_type; +typedef dummy_stepper::time_type time_type; +typedef std::vector< std::pair< state_type , time_type > > result_vector; + +BOOST_AUTO_TEST_SUITE( adaptive_time_iterator_test ) + +typedef mpl::vector< + dummy_controlled_stepper + , dummy_dense_output_stepper + > dummy_steppers; + + +BOOST_AUTO_TEST_CASE( copy_stepper_iterator ) +{ + typedef adaptive_time_iterator< dummy_controlled_stepper , empty_system , state_type > iterator_type; + state_type x = {{ 1.0 }}; + iterator_type iter1 = iterator_type( dummy_controlled_stepper() , empty_system() , x , 0.0 , 1.0 , 0.1 ); + iterator_type iter2 = iter1; + BOOST_CHECK_EQUAL( &( iter1->first ) , &( iter2->first ) ); + BOOST_CHECK_EQUAL( &( iter1->first ) , &x ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + +BOOST_AUTO_TEST_CASE( copy_dense_output_stepper_iterator ) +{ + typedef adaptive_time_iterator< dummy_dense_output_stepper , empty_system , state_type > iterator_type; + state_type x = {{ 1.0 }}; + iterator_type iter1 = iterator_type( dummy_dense_output_stepper() , empty_system() , x , 0.0 , 1.0 , 0.1 ); + iterator_type iter2 = iter1; + BOOST_CHECK_NE( &( iter1->first ) , &( iter2->first ) ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + +BOOST_AUTO_TEST_CASE( copy_dense_output_stepper_iterator_with_reference_wrapper ) +{ + typedef adaptive_time_iterator< boost::reference_wrapper< dummy_dense_output_stepper > , empty_system , state_type > iterator_type; + state_type x = {{ 1.0 }}; + dummy_dense_output_stepper stepper; + iterator_type iter1 = iterator_type( boost::ref( stepper ) , empty_system() , x , 0.0 , 1.0 , 0.1 ); + iterator_type iter2 = iter1; + BOOST_CHECK_EQUAL( &( iter1->first ) , &( iter2->first ) ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + + +BOOST_AUTO_TEST_CASE( assignment_stepper_iterator ) +{ + typedef adaptive_time_iterator< dummy_controlled_stepper , empty_system , state_type > iterator_type; + state_type x1 = {{ 1.0 }} , x2 = {{ 2.0 }}; + iterator_type iter1 = iterator_type( dummy_controlled_stepper() , empty_system() , x1 , 0.0 , 1.0 , 0.1 ); + iterator_type iter2 = iterator_type( dummy_controlled_stepper() , empty_system() , x2 , 0.0 , 1.0 , 0.2 ); + BOOST_CHECK_EQUAL( &( iter1->first ) , &x1 ); + BOOST_CHECK_EQUAL( &( iter2->first ) , &x2 ); + BOOST_CHECK( !iter1.same( iter2 ) ); + iter2 = iter1; + BOOST_CHECK_EQUAL( &( iter1->first ) , &x1 ); + BOOST_CHECK_EQUAL( &( iter2->first ) , &x1 ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + +BOOST_AUTO_TEST_CASE( assignment_dense_output_stepper_iterator ) +{ + typedef adaptive_time_iterator< dummy_dense_output_stepper , empty_system , state_type > iterator_type; + state_type x1 = {{ 1.0 }} , x2 = {{ 2.0 }}; + iterator_type iter1 = iterator_type( dummy_dense_output_stepper() , empty_system() , x1 , 0.0 , 1.0 , 0.1 ); + iterator_type iter2 = iterator_type( dummy_dense_output_stepper() , empty_system() , x2 , 0.0 , 1.0 , 0.2 ); + BOOST_CHECK_NE( &( iter1->first ) , &x1 ); + BOOST_CHECK_NE( &( iter2->first ) , &x2 ); + BOOST_CHECK( !iter1.same( iter2 ) ); + iter2 = iter1; + BOOST_CHECK_NE( &( iter1->first ) , &x1 ); + BOOST_CHECK_NE( &( iter2->first ) , &x1 ); + BOOST_CHECK( iter1.same( iter2 ) ); + BOOST_CHECK_EQUAL( (iter1->first)[0] , (iter1->first)[0] ); +} + +BOOST_AUTO_TEST_CASE( assignment_dense_output_stepper_iterator_with_reference_wrapper ) +{ + typedef adaptive_time_iterator< boost::reference_wrapper< dummy_dense_output_stepper > , empty_system , state_type > iterator_type; + state_type x1 = {{ 1.0 }} , x2 = {{ 2.0 }}; + dummy_dense_output_stepper stepper; + iterator_type iter1 = iterator_type( boost::ref( stepper ) , empty_system() , x1 , 0.0 , 1.0 , 0.1 ); + iterator_type iter2 = iterator_type( boost::ref( stepper ) , empty_system() , x2 , 0.0 , 1.0 , 0.2 ); + + BOOST_CHECK_NE( &( iter1->first ) , &x1 ); + BOOST_CHECK_NE( &( iter2->first ) , &x2 ); + // same stepper instance -> same internal state + BOOST_CHECK_EQUAL( &( iter1->first ) , &( iter2->first ) ); + BOOST_CHECK( !iter1.same( iter2 ) ); + iter2 = iter1; + BOOST_CHECK_NE( &( iter1->first ) , &x1 ); + BOOST_CHECK_NE( &( iter2->first ) , &x1 ); + BOOST_CHECK( iter1.same( iter2 ) ); + BOOST_CHECK_EQUAL( &( iter1->first ) , &( iter2->first ) ); +} + + +BOOST_AUTO_TEST_CASE( stepper_iterator_factory ) +{ + dummy_controlled_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_adaptive_time_iterator_begin( stepper , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + make_adaptive_time_iterator_end( stepper , boost::ref( system ) , x ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-14 ); +} + +// just test if it compiles +BOOST_AUTO_TEST_CASE( dense_output_stepper_iterator_factory ) +{ + dummy_dense_output_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_adaptive_time_iterator_begin( stepper , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + make_adaptive_time_iterator_end( stepper , boost::ref( system ) , x ) , + dummy_observer() ); +} + + +BOOST_AUTO_TEST_CASE( stepper_range ) +{ + dummy_controlled_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_adaptive_time_range( stepper , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-14 ); +} + +// just test if it compiles +BOOST_AUTO_TEST_CASE( dense_output_stepper_range ) +{ + dummy_dense_output_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_adaptive_time_range( stepper , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + dummy_observer() ); +} + + +BOOST_AUTO_TEST_CASE( stepper_iterator_with_reference_wrapper_factory ) +{ + dummy_controlled_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_adaptive_time_iterator_begin( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + make_adaptive_time_iterator_end( boost::ref( stepper ) , boost::ref( system ) , x ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-14 ); +} + +// just test if it compiles +BOOST_AUTO_TEST_CASE( dense_output_stepper_iterator_with_reference_wrapper_factory ) +{ + dummy_dense_output_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_adaptive_time_iterator_begin( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + make_adaptive_time_iterator_end( boost::ref( stepper ) , boost::ref( system ) , x ) , + dummy_observer() ); +} + + + +BOOST_AUTO_TEST_CASE( stepper_range_with_reference_wrapper ) +{ + dummy_controlled_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_adaptive_time_range( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-14 ); +} + +// just test if it compiles +BOOST_AUTO_TEST_CASE( dense_output_stepper_range_with_reference_wrapper ) +{ + dummy_dense_output_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_adaptive_time_range( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + dummy_observer() ); +} + + + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( transitivity1 , Stepper , dummy_steppers ) +{ + typedef adaptive_time_iterator< Stepper , empty_system , state_type > stepper_iterator; + + state_type x = {{ 1.0 }}; + stepper_iterator first1( Stepper() , empty_system() , x , 1.5 , 1.0 , 0.1 ); + stepper_iterator last1( Stepper() , empty_system() , x ); + stepper_iterator last2( Stepper() , empty_system() , x ); + + BOOST_CHECK( first1 == last1 ); + BOOST_CHECK( first1 == last2 ); + BOOST_CHECK( last1 == last2 ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm , Stepper , dummy_steppers ) +{ + typedef adaptive_time_iterator< Stepper , empty_system , state_type > stepper_iterator; + state_type x = {{ 1.0 }}; + result_vector res; + stepper_iterator first( Stepper() , empty_system() , x , 0.0 , 0.35 , 0.1 ); + stepper_iterator last( Stepper() , empty_system() , x ); + + std::copy( first , last , std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 5 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[0].second , 0.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].second , 0.1 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].second , 0.2 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].second , 0.3 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[4].first[0] , 2.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[4].second , 0.35 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + result_vector res; + std::copy( make_adaptive_time_iterator_begin( Stepper() , empty_system() , x , 0.0 , 0.35 , 0.1 ) , + make_adaptive_time_iterator_end( Stepper() , empty_system() , x ) , + std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 5 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[0].second , 0.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].second , 0.1 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].second , 0.2 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].second , 0.3 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[4].first[0] , 2.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[4].second , 0.35 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_range_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + result_vector res; + boost::range::copy( make_adaptive_time_range( Stepper() , empty_system() , x , 0.0 , 0.35 , 0.1 ) , + std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 5 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[0].second , 0.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].second , 0.1 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].second , 0.2 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].second , 0.3 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[4].first[0] , 2.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[4].second , 0.35 , 1.0e-13 ); +} + + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/algebra_dispatcher.cpp b/src/boost/libs/numeric/odeint/test/algebra_dispatcher.cpp new file mode 100644 index 000000000..66a292fd1 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/algebra_dispatcher.cpp @@ -0,0 +1,82 @@ +/* + [auto_generated] + libs/numeric/odeint/test/algebra_dispatcher.cpp + + [begin_description] + tba. + [end_description] + + Copyright 2013 Karsten Ahnert + Copyright 2013 Mario Mulansky + Copyright 2013 Pascal Germroth + + 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) + */ + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_algebra_dispatcher + +#include <boost/numeric/odeint/config.hpp> +#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_fehlberg78.hpp> +#include <boost/numeric/odeint/algebra/fusion_algebra_dispatcher.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/array.hpp> +#include <boost/mpl/list.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + + +BOOST_AUTO_TEST_SUITE( algebra_dispatcher_test ) + +BOOST_AUTO_TEST_CASE( range_algebra_with_vector ) +{ + typedef runge_kutta4< std::vector< double > > stepper_type; + BOOST_STATIC_ASSERT(( boost::is_same< stepper_type::algebra_type , range_algebra >::value )); +} + +BOOST_AUTO_TEST_CASE( array_algebra_with_array ) +{ + typedef runge_kutta4< boost::array< double , 2 > > stepper_type; + BOOST_STATIC_ASSERT(( boost::is_same< stepper_type::algebra_type , array_algebra >::value )); +} + +BOOST_AUTO_TEST_CASE( range_algebra_with_array ) +{ + typedef runge_kutta4< boost::array< double , 2 > , double , boost::array< double , 2 > , double , range_algebra > stepper_type; + BOOST_STATIC_ASSERT(( boost::is_same< stepper_type::algebra_type , range_algebra >::value )); +} + +BOOST_AUTO_TEST_CASE( fusion_algebra_with_fusion_vector ) +{ + typedef runge_kutta4< boost::fusion::vector< double > > stepper_type; + BOOST_STATIC_ASSERT(( boost::is_same< stepper_type::algebra_type , fusion_algebra >::value )); +} + +BOOST_AUTO_TEST_CASE( fusion_algebra_with_fusion_vector2 ) +{ + typedef runge_kutta_fehlberg78< boost::fusion::vector< double > > stepper_type; + BOOST_STATIC_ASSERT(( boost::is_same< stepper_type::algebra_type , fusion_algebra >::value )); +} + +typedef boost::mpl::list< float , double , long double , std::complex< double > , std::complex< float > > fp_types; +BOOST_AUTO_TEST_CASE_TEMPLATE( vector_space_algebra_with_floating_point , T , fp_types ) +{ + typedef runge_kutta_fehlberg78< T > stepper_type; + BOOST_STATIC_ASSERT(( boost::is_same< typename stepper_type::algebra_type , vector_space_algebra >::value )); +} + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/boost_units_helpers.hpp b/src/boost/libs/numeric/odeint/test/boost_units_helpers.hpp new file mode 100644 index 000000000..7ff427578 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/boost_units_helpers.hpp @@ -0,0 +1,59 @@ +/* + [auto_generated] + libs/numeric/odeint/test/dummy_boost_units.hpp + + [begin_description] + tba. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2012 Mario Mulansky + + 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) +*/ + + +#ifndef LIBS_NUMERIC_ODEINT_TEST_DUMMY_BOOST_UNITS_HPP_DEFINED +#define LIBS_NUMERIC_ODEINT_TEST_DUMMY_BOOST_UNITS_HPP_DEFINED + +#include <boost/units/systems/si/length.hpp> +#include <boost/units/systems/si/time.hpp> +#include <boost/units/systems/si/velocity.hpp> +#include <boost/units/systems/si/acceleration.hpp> +#include <boost/units/systems/si/io.hpp> + +#include <boost/fusion/container.hpp> + + + +typedef double value_type; +typedef boost::units::quantity< boost::units::si::time , value_type > time_type; +typedef boost::units::quantity< boost::units::si::length , value_type > length_type; +typedef boost::units::quantity< boost::units::si::velocity , value_type > velocity_type; +typedef boost::units::quantity< boost::units::si::acceleration , value_type > acceleration_type; + + + +struct oscillator_mom_func_units +{ + template< class Coor , class MomDeriv > + void operator()( const Coor &q , MomDeriv &dp ) const + { + const boost::units::quantity< boost::units::si::frequency , value_type > omega = 1.0 * boost::units::si::hertz; + boost::fusion::at_c< 0 >( dp ) = - omega * omega * boost::fusion::at_c< 0 >( q ); + } +}; + +struct oscillator_coor_func_units +{ + template< class Mom , class CoorDeriv > + void operator()( const Mom &p , CoorDeriv &dq ) const + { + boost::fusion::at_c< 0 >( dq ) = boost::fusion::at_c< 0 >( p ); + } +}; + + +#endif // LIBS_NUMERIC_ODEINT_TEST_DUMMY_BOOST_UNITS_HPP_DEFINED diff --git a/src/boost/libs/numeric/odeint/test/bulirsch_stoer.cpp b/src/boost/libs/numeric/odeint/test/bulirsch_stoer.cpp new file mode 100644 index 000000000..2c6a0c95a --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/bulirsch_stoer.cpp @@ -0,0 +1,155 @@ +/* + [auto_generated] + libs/numeric/odeint/test/bulirsch_stoer.cpp + + [begin_description] + This file tests the Bulirsch-Stoer stepper. + [end_description] + + Copyright 2011 Mario Mulansky + Copyright 2012 Karsten Ahnert + + 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) + */ + + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_bulirsch_stoer + +#include <utility> +#include <iostream> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/stepper/bulirsch_stoer.hpp> +#include <boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp> + +#include <boost/numeric/odeint/integrate/integrate_adaptive.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef double value_type; +typedef boost::array< value_type , 3 > state_type; + +const double sigma = 10.0; +const double R = 28.0; +const double b = 8.0 / 3.0; + +struct lorenz +{ + template< class State , class Deriv > + void operator()( const State &x , Deriv &dxdt , double t ) const + { + dxdt[0] = sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = -b * x[2] + x[0] * x[1]; + } +}; + +struct const_system +{ + template< class State , class Deriv > + void operator()( const State &x , Deriv &dxdt , double t ) const + { + dxdt[0] = 1.0; + dxdt[1] = 1.0; + dxdt[2] = 1.0; + } +}; + +struct sin_system +{ + template< class State , class Deriv > + void operator()( const State &x , Deriv &dxdt , double t ) const + { + dxdt[0] = sin( x[0] ); + dxdt[1] = cos( x[1] ); + dxdt[2] = sin( x[2] ) + cos( x[2] ); + } +}; + +BOOST_AUTO_TEST_SUITE( bulirsch_stoer_test ) + +BOOST_AUTO_TEST_CASE( test_bulirsch_stoer ) +{ + typedef bulirsch_stoer< state_type > stepper_type; + stepper_type stepper( 1E-9 , 1E-9 , 1.0 , 0.0 ); + + state_type x; + x[0] = 10.0 ; x[1] = 10.0 ; x[2] = 5.0; + + double dt = 0.1; + + //stepper.try_step( lorenz() , x , t , dt ); + + std::cout << "starting integration..." << std::endl; + + size_t steps = integrate_adaptive( stepper , lorenz() , x , 0.0 , 10.0 , dt ); + + std::cout << "required steps: " << steps << std::endl; + + bulirsch_stoer_dense_out< state_type > bs_do( 1E-9 , 1E-9 , 1.0 , 0.0 ); + x[0] = 10.0 ; x[1] = 10.0 ; x[2] = 5.0; + double t = 0.0; + dt = 1E-1; + bs_do.initialize( x , t , dt ); + bs_do.do_step( sin_system() ); + std::cout << "one step successful, new time: " << bs_do.current_time() << " (" << t << ")" << std::endl; + + x = bs_do.current_state(); + std::cout << "x( " << bs_do.current_time() << " ) = [ " << x[0] << " , " << x[1] << " , " << x[2] << " ]" << std::endl; + + bs_do.calc_state( bs_do.current_time()/3 , x ); + std::cout << "x( " << bs_do.current_time()/3 << " ) = [ " << x[0] << " , " << x[1] << " , " << x[2] << " ]" << std::endl; + + std::cout << std::endl << "=======================================================================" << std::endl << std::endl; + + x[0] = 10.0 ; x[1] = 10.0 ; x[2] = 5.0; + t = 0.0; dt /= 3; + bs_do.initialize( x , t , dt ); + bs_do.do_step( sin_system() ); + x = bs_do.current_state(); + std::cout << "x( " << bs_do.current_time() << " ) = [ " << x[0] << " , " << x[1] << " , " << x[2] << " ]" << std::endl; + + t = dt; + bs_do.initialize( x , t , dt ); + bs_do.do_step( sin_system() ); + x = bs_do.current_state(); + + t = 2*dt; + bs_do.initialize( x , t , dt ); + bs_do.do_step( sin_system() ); + x = bs_do.current_state(); + + std::cout << "x( " << bs_do.current_time() << " ) = [ " << x[0] << " , " << x[1] << " , " << x[2] << " ]" << std::endl << std::endl << std::endl; +} + +BOOST_AUTO_TEST_CASE( test_bulirsch_stoer_adjust_size ) +{ + typedef bulirsch_stoer< state_type > stepper_type; + stepper_type stepper( 1E-9 , 1E-9 , 1.0 , 0.0 ); + + state_type x; x[0] = 10.0 ; x[1] = 10.0 ; x[2] = 5.0; + + stepper.adjust_size( x ); + + + double dt = 0.1; + + size_t steps = integrate_adaptive( stepper , lorenz() , x , 0.0 , 10.0 , dt ); + + std::cout << "required steps: " << steps << std::endl; +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/const_range.hpp b/src/boost/libs/numeric/odeint/test/const_range.hpp new file mode 100644 index 000000000..d646b1d89 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/const_range.hpp @@ -0,0 +1,50 @@ +/* + [auto_generated] + libs/numeric/odeint/test/const_range.hpp + + [begin_description] + tba. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2012 Mario Mulansky + + 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) +*/ + + +#ifndef LIBS_NUMERIC_ODEINT_TEST_CONST_RANGE_HPP_DEFINED +#define LIBS_NUMERIC_ODEINT_TEST_CONST_RANGE_HPP_DEFINED + +#include <boost/mpl/copy.hpp> +#include <boost/mpl/inserter.hpp> +#include <boost/mpl/insert.hpp> +#include <boost/mpl/end.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/mpl/range_c.hpp> +#include <boost/mpl/placeholders.hpp> + + +namespace mpl = boost::mpl; + + + +template< class N , class T > +struct const_range +{ + typedef typename mpl::copy< + mpl::range_c< typename N::value_type , 0 , N::value > , + mpl::inserter< + mpl::vector0<> , + mpl::insert< + mpl::_1 , + mpl::end< mpl::_1 > , + T + > + > + >::type type; +}; + +#endif // LIBS_NUMERIC_ODEINT_TEST_CONST_RANGE_HPP_DEFINED diff --git a/src/boost/libs/numeric/odeint/test/const_step_iterator.cpp b/src/boost/libs/numeric/odeint/test/const_step_iterator.cpp new file mode 100644 index 000000000..2d0ac9dbe --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/const_step_iterator.cpp @@ -0,0 +1,232 @@ +/* + [auto_generated] + libs/numeric/odeint/test/const_step_iterator.cpp + + [begin_description] + This file tests the const step iterator. + [end_description] + + Copyright 2012-2013 Karsten Ahnert + Copyright 2013 Mario Mulansky + + 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) + */ + + +#define BOOST_TEST_MODULE odeint_const_step_iterator + +#include <iterator> +#include <algorithm> +#include <vector> + +#include <boost/numeric/odeint/config.hpp> +#include <boost/array.hpp> +#include <boost/range/algorithm/for_each.hpp> +#include <boost/range/algorithm/copy.hpp> +#include <boost/mpl/vector.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> + +#include <boost/numeric/odeint/iterator/const_step_iterator.hpp> +#include "dummy_steppers.hpp" +#include "dummy_odes.hpp" +#include "dummy_observers.hpp" + +namespace mpl = boost::mpl; +using namespace boost::numeric::odeint; + +typedef dummy_stepper::state_type state_type; +typedef dummy_stepper::value_type value_type; + + +BOOST_AUTO_TEST_SUITE( const_step_iterator_test ) + +typedef mpl::vector< + dummy_stepper + , dummy_dense_output_stepper + > dummy_steppers; + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_stepper_iterator , Stepper , dummy_steppers ) +{ + typedef const_step_iterator< Stepper , empty_system , state_type > iterator_type; + state_type x = {{ 1.0 }}; + iterator_type iter1 = iterator_type( Stepper() , empty_system() , x , 0.0 , 0.999 , 0.1 ); + iterator_type iter2 = iter1; + BOOST_CHECK_EQUAL( &(*iter1) , &(*iter2) ); + BOOST_CHECK_EQUAL( &(*iter1) , &x ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( assignment_stepper_iterator , Stepper , dummy_steppers ) +{ + typedef const_step_iterator< Stepper , empty_system , state_type > iterator_type; + state_type x1 = {{ 1.0 }} , x2 = {{ 2.0 }}; + iterator_type iter1 = iterator_type( Stepper() , empty_system() , x1 , 0.0 , 1.0 , 0.1 ); + iterator_type iter2 = iterator_type( Stepper() , empty_system() , x2 , 0.0 , 1.0 , 0.2 ); + BOOST_CHECK_EQUAL( &(*iter1) , &x1 ); + BOOST_CHECK_EQUAL( &(*iter2) , &x2 ); + BOOST_CHECK( !iter1.same( iter2 ) ); + iter2 = iter1; + BOOST_CHECK_EQUAL( &(*iter1) , &x1 ); + BOOST_CHECK_EQUAL( &(*iter2) , &x1 ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_iterator_factory , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_const_step_iterator_begin( stepper , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + make_const_step_iterator_end( stepper , boost::ref( system ) , x ) , + dummy_observer() ); + + // dummy_steppers just add 0.25 at each step, the above for_each leads to 10 do_step calls so x should be 3.5 + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_range , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_const_step_range( stepper , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_iterator_with_reference_wrapper_factory , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_const_step_iterator_begin( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + make_const_step_iterator_end( boost::ref( stepper ) , boost::ref( system ) , x ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_range_with_reference_wrapper , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_const_step_range( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( transitivity1 , Stepper , dummy_steppers ) +{ + typedef const_step_iterator< Stepper , empty_system , state_type > stepper_iterator; + + state_type x = {{ 1.0 }}; + stepper_iterator first1( Stepper() , empty_system() , x , 2.5 , 2.0 , 0.1 ); + stepper_iterator last1( Stepper() , empty_system() , x ); + stepper_iterator last2( Stepper() , empty_system() , x ); + + BOOST_CHECK( first1 == last1 ); + BOOST_CHECK( first1 == last2 ); + BOOST_CHECK( last1 == last2 ); + + first1 = stepper_iterator( Stepper() , empty_system() , x , 2.0 , 2.0 , 0.1 ); + last1 = stepper_iterator( Stepper() , empty_system() , x ); + BOOST_CHECK( first1 != last1 ); + BOOST_CHECK( ++first1 == last1 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm , Stepper , dummy_steppers ) +{ + typedef const_step_iterator< Stepper , empty_system , state_type > stepper_iterator; + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + stepper_iterator first( Stepper() , empty_system() , x , 0.0 , 0.35 , 0.1 ); + stepper_iterator last( Stepper() , empty_system() , x ); + + std::copy( first , last , std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-14 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-14 ); // the iterator should not iterate over the end +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_negative_time_step , Stepper , dummy_steppers ) +{ + typedef const_step_iterator< Stepper , empty_system , state_type > stepper_iterator; + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + stepper_iterator first( Stepper() , empty_system() , x , 0.3 , -0.05 , -0.1 ); + stepper_iterator last( Stepper() , empty_system() , x ); + + std::copy( first , last , std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-14 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-14 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + std::copy( make_const_step_iterator_begin( Stepper() , empty_system() , x , 0.0 , 0.35 , 0.1 ) , + make_const_step_iterator_end( Stepper() , empty_system() , x ) , + std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-14 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-14 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_range_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + boost::range::copy( make_const_step_range( Stepper() , empty_system() , x , 0.0 , 0.35 , 0.1 ) , + std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-14 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-14 ); +} + + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/const_step_time_iterator.cpp b/src/boost/libs/numeric/odeint/test/const_step_time_iterator.cpp new file mode 100644 index 000000000..9227f5c04 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/const_step_time_iterator.cpp @@ -0,0 +1,218 @@ +/* + [auto_generated] + libs/numeric/odeint/test/const_step_time_iterator.cpp + + [begin_description] + This file tests the const step time iterator. + [end_description] + + Copyright 2012-2013 Karsten Ahnert + Copyright 2012-2013 Mario Mulansky + + 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) + */ + + +#define BOOST_TEST_MODULE odeint_const_step_time_iterator + +#include <iterator> +#include <algorithm> +#include <vector> + +#include <boost/numeric/odeint/config.hpp> +#include <boost/array.hpp> +#include <boost/range/algorithm/copy.hpp> +#include <boost/range/algorithm/for_each.hpp> +#include <boost/mpl/vector.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> + +#include <boost/numeric/odeint/iterator/const_step_time_iterator.hpp> +#include "dummy_steppers.hpp" +#include "dummy_odes.hpp" +#include "dummy_observers.hpp" + +namespace mpl = boost::mpl; +using namespace boost::numeric::odeint; + +typedef dummy_stepper::state_type state_type; +typedef dummy_stepper::value_type value_type; +typedef dummy_stepper::time_type time_type; +typedef std::vector< std::pair< state_type , time_type > > result_vector; + +BOOST_AUTO_TEST_SUITE( const_step_time_iterator_test ) + +typedef mpl::vector< + dummy_stepper + , dummy_dense_output_stepper + > dummy_steppers; + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_stepper_iterator , Stepper , dummy_steppers ) +{ + typedef const_step_time_iterator< Stepper , empty_system , state_type > iterator_type; + state_type x = {{ 1.0 }}; + iterator_type iter1 = iterator_type( Stepper() , empty_system() , x , 0.0 , 1.0 , 0.1 ); + iterator_type iter2 = iter1; + BOOST_CHECK_EQUAL( &( iter1->first ) , &( iter2->first ) ); + BOOST_CHECK_EQUAL( &( iter1->first ) , &x ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( assignment_stepper_iterator , Stepper , dummy_steppers ) +{ + typedef const_step_time_iterator< Stepper , empty_system , state_type > iterator_type; + state_type x1 = {{ 1.0 }} , x2 = {{ 2.0 }}; + iterator_type iter1 = iterator_type( Stepper() , empty_system() , x1 , 0.0 , 1.0 , 0.1 ); + iterator_type iter2 = iterator_type( Stepper() , empty_system() , x2 , 0.0 , 1.0 , 0.2 ); + BOOST_CHECK_EQUAL( &( iter1->first ) , &x1 ); + BOOST_CHECK_EQUAL( &( iter2->first ) , &x2 ); + BOOST_CHECK( !iter1.same( iter2 ) ); + iter2 = iter1; + BOOST_CHECK_EQUAL( &( iter1->first ) , &x1 ); + BOOST_CHECK_EQUAL( &( iter2->first ) , &x1 ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_iterator_factory , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_const_step_time_iterator_begin( stepper , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + make_const_step_time_iterator_end( stepper , boost::ref( system ) , x ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_range , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_const_step_time_range( stepper , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_iterator_with_reference_wrapper_factory , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_const_step_time_iterator_begin( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + make_const_step_time_iterator_end( boost::ref( stepper ) , boost::ref( system ) , x ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_range_with_reference_wrapper , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_const_step_time_range( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( transitivity1 , Stepper , dummy_steppers ) +{ + typedef const_step_time_iterator< Stepper , empty_system , state_type > stepper_iterator; + + state_type x = {{ 1.0 }}; + stepper_iterator first1( Stepper() , empty_system() , x , 1.5 , 1.0 , 0.1 ); + stepper_iterator last1( Stepper() , empty_system() , x ); + stepper_iterator last2( Stepper() , empty_system() , x ); + + BOOST_CHECK( first1 == last1 ); + BOOST_CHECK( first1 == last2 ); + BOOST_CHECK( last1 == last2 ); + + first1 = stepper_iterator( Stepper() , empty_system() , x , 2.0 , 2.0 , 0.1 ); + last1 = stepper_iterator( Stepper() , empty_system() , x ); + BOOST_CHECK( first1 != last1 ); + BOOST_CHECK( ++first1 == last1 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm , Stepper , dummy_steppers ) +{ + typedef const_step_time_iterator< Stepper , empty_system , state_type > stepper_iterator; + state_type x = {{ 1.0 }}; + result_vector res; + stepper_iterator first( Stepper() , empty_system() , x , 0.0 , 0.35 , 0.1 ); + stepper_iterator last( Stepper() , empty_system() , x ); + + std::copy( first , last , std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[0].second , 0.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].second , 0.1 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].second , 0.2 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].second , 0.3 , 1.0e-13 ); + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + result_vector res; + std::copy( make_const_step_time_iterator_begin( Stepper() , empty_system() , x , 0.0 , 0.35 , 0.1 ) , + make_const_step_time_iterator_end( Stepper() , empty_system() , x ) , + std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[0].second , 0.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].second , 0.1 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].second , 0.2 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].second , 0.3 , 1.0e-13 ); + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_range_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + result_vector res; + boost::range::copy( make_const_step_time_range( Stepper() , empty_system() , x , 0.0 , 0.35 , 0.1 ) , + std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[0].second , 0.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].second , 0.1 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].second , 0.2 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].second , 0.3 , 1.0e-13 ); + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/controlled_adams_bashforth_moulton.cpp b/src/boost/libs/numeric/odeint/test/controlled_adams_bashforth_moulton.cpp new file mode 100644 index 000000000..40d657209 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/controlled_adams_bashforth_moulton.cpp @@ -0,0 +1,56 @@ +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_controlled_adams_bashforth_moulton + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp> +#include <boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +struct const_sys +{ + template< class State , class Deriv , class Value > + void operator()( const State &x , Deriv &dxdt , const Value &dt ) const + { + dxdt[0] = 1; + } +}; + +typedef boost::array< double , 1 > state_type; +typedef double value_type; + +BOOST_AUTO_TEST_SUITE( controlled_adams_bashforth_moulton_test ) + +BOOST_AUTO_TEST_CASE( test_instantiation ) +{ + controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<1, state_type> > s1; + controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<2, state_type> > s2; + controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<3, state_type> > s3; + controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<4, state_type> > s4; + controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<5, state_type> > s5; + controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<6, state_type> > s6; + controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<7, state_type> > s7; + controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<8, state_type> > s8; + controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<9, state_type> > s9; + + state_type x = {{ 10.0 }}; + value_type t = 0.0 , dt = 0.01; + + s1.try_step(const_sys(), x, t, dt); + s2.try_step(const_sys(), x, t, dt); + s3.try_step(const_sys(), x, t, dt); + s4.try_step(const_sys(), x, t, dt); + s5.try_step(const_sys(), x, t, dt); + s6.try_step(const_sys(), x, t, dt); + s7.try_step(const_sys(), x, t, dt); + s8.try_step(const_sys(), x, t, dt); + s9.try_step(const_sys(), x, t, dt); +} + +BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file diff --git a/src/boost/libs/numeric/odeint/test/default_operations.cpp b/src/boost/libs/numeric/odeint/test/default_operations.cpp new file mode 100644 index 000000000..a2634b7fe --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/default_operations.cpp @@ -0,0 +1,257 @@ +/* + [auto_generated] + libs/numeric/odeint/test/default_operations.cpp + + [begin_description] + This file tests default_operations. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011 Mario Mulansky + + 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) +*/ + + +#define BOOST_TEST_MODULE odeint_standard_operations + +#include <cmath> +#include <complex> + +#include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> + +#include <boost/units/systems/si/length.hpp> +#include <boost/units/systems/si/time.hpp> +#include <boost/units/systems/si/velocity.hpp> +#include <boost/units/systems/si/acceleration.hpp> +#include <boost/units/systems/si/io.hpp> + +#include <boost/mpl/list.hpp> + +#include <boost/numeric/odeint/algebra/default_operations.hpp> + +namespace units = boost::units; +namespace si = boost::units::si; +namespace mpl = boost::mpl; +using boost::numeric::odeint::default_operations; + + +template< class Value > struct internal_value_type { typedef Value type; }; +template< class T > struct internal_value_type< std::complex< T > > { typedef T type; }; + +template< class T > struct default_eps; +template<> struct default_eps< double > { static double def_eps( void ) { return 1.0e-10; } }; +template<> struct default_eps< float > { static float def_eps( void ) { return 1.0e-5; } }; + + +typedef units::unit< units::derived_dimension< units::time_base_dimension , 2 >::type , si::system > time_2; +typedef units::unit< units::derived_dimension< units::time_base_dimension , 3 >::type , si::system > time_3; +typedef units::unit< units::derived_dimension< units::time_base_dimension , 4 >::type , si::system > time_4; +typedef units::unit< units::derived_dimension< units::time_base_dimension , 5 >::type , si::system > time_5; +typedef units::unit< units::derived_dimension< units::time_base_dimension , 6 >::type , si::system > time_6; +typedef units::unit< units::derived_dimension< units::time_base_dimension , 7 >::type , si::system > time_7; + +const time_2 second2 = si::second * si::second; +const time_3 second3 = second2 * si::second; +const time_4 second4 = second3 * si::second; +const time_5 second5 = second4 * si::second; +const time_6 second6 = second5 * si::second; +const time_7 second7 = second6 * si::second; + + + + +template< class Value , class Compare = typename internal_value_type< Value >::type > +struct double_fixture +{ + typedef Value value_type; + typedef Compare compare_type; + + double_fixture( const compare_type &eps_ = default_eps< compare_type >::def_eps() ) + : m_eps( eps_ ) , res( 0.0 ) , x1( 1.0 ) , x2( 2.0 ) , x3( 3.0 ) , x4( 4.0 ) , x5( 5.0 ) , x6( 6.0 ) , x7( 7.0 ) , x8( 8.0 ) + {} + + ~double_fixture( void ) + { + using std::abs; + BOOST_CHECK_SMALL( abs( x1 - value_type( 1.0 ) ) , m_eps ); + BOOST_CHECK_SMALL( abs( x2 - value_type( 2.0 ) ) , m_eps ); + BOOST_CHECK_SMALL( abs( x3 - value_type( 3.0 ) ) , m_eps ); + BOOST_CHECK_SMALL( abs( x4 - value_type( 4.0 ) ) , m_eps ); + BOOST_CHECK_SMALL( abs( x5 - value_type( 5.0 ) ) , m_eps ); + BOOST_CHECK_SMALL( abs( x6 - value_type( 6.0 ) ) , m_eps ); + BOOST_CHECK_SMALL( abs( x7 - value_type( 7.0 ) ) , m_eps ); + } + + const compare_type m_eps; + value_type res; + value_type x1 , x2 , x3 , x4 , x5 , x6 , x7 , x8; +}; + +template< class Value , class Compare = typename internal_value_type< Value >::type > +struct unit_fixture +{ + typedef Value value_type; + typedef Compare compare_type; + typedef units::quantity< si::length , value_type > length_type; + + typedef units::quantity< si::time , value_type > time_type; + typedef units::quantity< time_2 , value_type > time_2_type; + typedef units::quantity< time_3 , value_type > time_3_type; + typedef units::quantity< time_4 , value_type > time_4_type; + typedef units::quantity< time_5 , value_type > time_5_type; + typedef units::quantity< time_6 , value_type > time_6_type; + typedef units::quantity< time_7 , value_type > time_7_type; + + typedef units::quantity< si::velocity , value_type > velocity_type; + typedef units::quantity< si::acceleration , value_type > acceleration_type; + + unit_fixture( const compare_type &eps_ = default_eps< compare_type >::def_eps() ) + : m_eps( eps_ ) + , res( 0.0 * si::meter ) + , x( 1.0 * si::meter ) + , d1x( 2.0 * si::meter / si::second ) + , d2x( 3.0 * si::meter / si::second / si::second ) + {} + + ~unit_fixture( void ) + { + using std::abs; + BOOST_CHECK_SMALL( abs( x.value() - value_type( 1.0 ) ) , m_eps ); + BOOST_CHECK_SMALL( abs( d1x.value() - value_type( 2.0 ) ) , m_eps ); + BOOST_CHECK_SMALL( abs( d2x.value() - value_type( 3.0 ) ) , m_eps ); + } + + compare_type m_eps; + length_type res; + length_type x; + velocity_type d1x; + acceleration_type d2x; +}; + + +typedef mpl::list< float , double , std::complex< double > > test_types; + +BOOST_AUTO_TEST_SUITE( check_operations_test ) + +using std::abs; + +BOOST_AUTO_TEST_CASE_TEMPLATE( scale_sum2_test , T , test_types ) +{ + typedef double_fixture< T > fix_type; + fix_type f; + typedef typename default_operations::scale_sum2< T , T > Op; + Op op( 1.25 , 9.81 ); + op( f.res , f.x1 , f.x2 ); + BOOST_CHECK_SMALL( abs( f.res - T( 20.87 ) ) , f.m_eps ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( scale_sum3_test , T , test_types ) +{ + typedef double_fixture< T > fix_type; + fix_type f; + typedef default_operations::scale_sum3< T , T , T > Op; + Op op( 1.25 , 9.81 , 0.87 ); + op( f.res , f.x1 , f.x2 , f.x3 ); + BOOST_CHECK_SMALL( abs( f.res - T( 23.48 ) ) , f.m_eps ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( scale_sum4_test , T , test_types ) +{ + typedef double_fixture< T > fix_type; + fix_type f; + typedef default_operations::scale_sum4< T , T , T , T > Op; + Op op( 1.25 , 9.81 , 0.87 , -0.15 ); + op( f.res , f.x1 , f.x2 , f.x3 , f.x4 ); + BOOST_CHECK_SMALL( abs( f.res - T( 22.88 ) ) , f.m_eps ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( scale_sum5_test , T , test_types ) +{ + typedef double_fixture< T > fix_type; + fix_type f; + typedef default_operations::scale_sum5< T , T , T , T , T > Op; + Op op( 1.25 , 9.81 , 0.87 , -0.15 , -3.3 ); + op( f.res , f.x1 , f.x2 , f.x3 , f.x4 , f.x5 ); + BOOST_CHECK_SMALL( abs( f.res - T( 6.38 ) ) , f.m_eps ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( scale_sum6_test , T , test_types ) +{ + typedef double_fixture< T > fix_type; + fix_type f; + typedef default_operations::scale_sum6< T , T , T , T , T , T > Op; + Op op( 1.25 , 9.81 , 0.87 , -0.15 , -3.3 , 4.2 ); + op( f.res , f.x1 , f.x2 , f.x3 , f.x4 , f.x5 , f.x6 ); + BOOST_CHECK_SMALL( abs( f.res - T( 31.58 ) ) , f.m_eps ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( scale_sum7_test , T , test_types ) +{ + typedef double_fixture< T > fix_type; + fix_type f; + typedef default_operations::scale_sum7< T , T , T , T , T , T , T > Op; + Op op( 1.25 , 9.81 , 0.87 , -0.15 , -3.3 , 4.2 , -0.22 ); + op( f.res , f.x1 , f.x2 , f.x3 , f.x4 , f.x5 , f.x6 , f.x7 ); + BOOST_CHECK_SMALL( abs( f.res - T( 30.04 ) ) , f.m_eps ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( rel_error_test , T , test_types ) +{ + typedef double_fixture< T > fix_type; + fix_type f; + f.res = -1.1; + typedef default_operations::rel_error< T > Op; + Op op( 0.1 , 0.2 , 0.15 , 0.12 ); + op( f.res , -f.x1 , -f.x2 ); + BOOST_CHECK_SMALL( abs( f.res - T( 6.17978 ) ) , typename fix_type::compare_type( 1.0e-4 ) ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( maximum_test , T , test_types ) +{ + typedef double_fixture< T > fix_type; + fix_type f; + typedef default_operations::maximum< typename fix_type::compare_type > Op; + Op op; + f.res = op( f.x1 , f.x2 ); + BOOST_CHECK_SMALL( abs( f.res - T( 2.0 ) ) , f.m_eps ); +} + + + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( scale_sum2_units_test , T , test_types ) +{ + typedef unit_fixture< T > fix_type; + typedef typename fix_type::value_type value_type; + typedef typename fix_type::time_type time_type; + + fix_type f; + typedef default_operations::scale_sum2< value_type , time_type > Op; + Op op( 1.0 , time_type( 1.0 * si::second ) ); + op( f.res , f.x , f.d1x ); + BOOST_CHECK_SMALL( abs( f.res.value() - T( 3.0 ) ) , f.m_eps ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( scale_sum3_units_test , T , test_types ) +{ + typedef unit_fixture< T > fix_type; + typedef typename fix_type::value_type value_type; + typedef typename fix_type::time_type time_type; + typedef typename fix_type::time_2_type time_2_type; + + fix_type f; + typedef default_operations::scale_sum3< value_type , time_type , time_2_type > Op; + Op op( 1.0 , time_type( 1.0 * si::second ) , time_2_type( 1.0 * second2 ) ); + op( f.res , f.x , f.d1x , f.d2x ); + BOOST_CHECK_SMALL( abs( f.res.value() - T( 6.0 ) ) , f.m_eps ); +} + + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/diagnostic_state_type.hpp b/src/boost/libs/numeric/odeint/test/diagnostic_state_type.hpp new file mode 100644 index 000000000..0c21013ea --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/diagnostic_state_type.hpp @@ -0,0 +1,185 @@ +/* + [auto_generated] + libs/numeric/odeint/test/diagnostic_state_type.hpp + + [begin_description] + tba. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2012 Mario Mulansky + + 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) +*/ + + +#ifndef LIBS_NUMERIC_ODEINT_TEST_DIAGNOSTIC_STATE_TYPE_HPP_DEFINED +#define LIBS_NUMERIC_ODEINT_TEST_DIAGNOSTIC_STATE_TYPE_HPP_DEFINED + +#include <boost/array.hpp> +#include <boost/numeric/odeint/util/is_resizeable.hpp> +#include <boost/numeric/odeint/util/same_size.hpp> +#include <boost/numeric/odeint/util/resize.hpp> +#include <boost/numeric/odeint/util/state_wrapper.hpp> + +template< size_t N > +struct counter +{ + static size_t& adjust_size_count( void ) + { + static size_t m_adjust_size_count; + return m_adjust_size_count; + } + + static size_t& construct_count( void ) + { + static size_t m_construct_count; + return m_construct_count; + } + + static size_t& copy_count( void ) + { + static size_t m_copy_count; + return m_copy_count; + } + + static size_t& destroy_count( void ) + { + static size_t m_destroy_count; + return m_destroy_count; + } + + + static void init_counter( void ) + { + counter< N >::adjust_size_count() = 0; + counter< N >::construct_count() = 0; + counter< N >::copy_count() = 0; + counter< N >::destroy_count() = 0; + } +}; + +template< size_t N > +class diagnostic_type : public boost::array< double , 1 > { }; + + +typedef diagnostic_type< 0 > diagnostic_state_type; +typedef diagnostic_type< 1 > diagnostic_deriv_type; +typedef diagnostic_type< 2 > diagnostic_state_type2; +typedef diagnostic_type< 3 > diagnostic_deriv_type2; + +typedef counter< 0 > counter_state; +typedef counter< 1 > counter_deriv; +typedef counter< 2 > counter_state2; +typedef counter< 3 > counter_deriv2; + + + +namespace boost { +namespace numeric { +namespace odeint { + + template< size_t N > + struct is_resizeable< diagnostic_type< N > > + { + typedef boost::true_type type; + const static bool value = type::value; + }; + + template< size_t N , size_t M > + struct same_size_impl< diagnostic_type< N > , diagnostic_type< M > > + { + static bool same_size( const diagnostic_type< N > &x1 , const diagnostic_type< M > &x2 ) + { + return false; + } + }; + + template< size_t N , class State1 > + struct same_size_impl< diagnostic_type< N > , State1 > + { + static bool same_size( const diagnostic_type< N > &x1 , const State1 &x2 ) + { + return false; + } + }; + + template< class State1 , size_t N > + struct same_size_impl< State1 , diagnostic_type< N > > + { + static bool same_size( const State1 &x1 , const diagnostic_type< N > &x2 ) + { + return false; + } + }; + + + + template< size_t N , class StateIn > + struct resize_impl< diagnostic_type< N > , StateIn > + { + static void resize( diagnostic_type< N > &x1 , const StateIn &x2 ) + { + counter< N >::adjust_size_count()++; + } + }; + + template< size_t N > + struct state_wrapper< diagnostic_type< N > > + { + typedef state_wrapper< diagnostic_type< N > > state_wrapper_type; + typedef diagnostic_type< N > state_type; + typedef double value_type; + + state_type m_v; + + state_wrapper() : m_v() + { + counter< N >::construct_count()++; + } + + state_wrapper( const state_type &v ) : m_v( v ) + { + counter< N >::construct_count()++; + counter< N >::copy_count()++; + } + + state_wrapper( const state_wrapper_type &x ) : m_v( x.m_v ) + { + counter< N >::construct_count()++; + counter< N >::copy_count()++; + } + + state_wrapper_type& operator=( const state_wrapper_type &x ) + { + counter< N >::copy_count()++; + return *this; + } + + ~state_wrapper() + { + counter< N >::destroy_count()++; + } + }; + + +} // namespace odeint +} // namespace numeric +} // namespace boost + +#define TEST_COUNTERS( c , s1 , s2 , s3 ,s4 ) \ + BOOST_CHECK_EQUAL( c::adjust_size_count() , size_t( s1 ) ); \ + BOOST_CHECK_EQUAL( c::construct_count() , size_t( s2 ) ); \ + BOOST_CHECK_EQUAL( c::copy_count() , size_t( s3 ) ); \ + BOOST_CHECK_EQUAL( c::destroy_count() , size_t( s4 ) ); + +#define TEST_COUNTERS_MSG( c , s1 , s2 , s3 ,s4 , msg ) \ + BOOST_CHECK_EQUAL( c::adjust_size_count() , size_t( s1 ) ); \ + BOOST_CHECK_EQUAL( c::construct_count() , size_t( s2 ) ); \ + BOOST_CHECK_EQUAL( c::copy_count() , size_t( s3 ) ); \ + BOOST_CHECK_EQUAL( c::destroy_count() , size_t( s4 ) ); + + +#endif // LIBS_NUMERIC_ODEINT_TEST_DIAGNOSTIC_STATE_TYPE_HPP_DEFINED diff --git a/src/boost/libs/numeric/odeint/test/dummy_observers.hpp b/src/boost/libs/numeric/odeint/test/dummy_observers.hpp new file mode 100644 index 000000000..744c374f1 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/dummy_observers.hpp @@ -0,0 +1,41 @@ +/* + [auto_generated] + libs/numeric/odeint/test/dummy_observers.hpp + + [begin_description] + tba. + [end_description] + + Copyright 2013 Karsten Ahnert + Copyright 2013 Mario Mulansky + + 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) +*/ + + +#ifndef LIBS_NUMERIC_ODEINT_TEST_DUMMY_OBSERVERS_HPP_DEFINED +#define LIBS_NUMERIC_ODEINT_TEST_DUMMY_OBSERVERS_HPP_DEFINED + + +namespace boost { +namespace numeric { +namespace odeint { + + +struct dummy_observer +{ + template< class State > + void operator()( const State &s ) const + { + } +}; + + +} // namespace odeint +} // namespace numeric +} // namespace boost + + +#endif // LIBS_NUMERIC_ODEINT_TEST_DUMMY_OBSERVERS_HPP_DEFINED diff --git a/src/boost/libs/numeric/odeint/test/dummy_odes.hpp b/src/boost/libs/numeric/odeint/test/dummy_odes.hpp new file mode 100644 index 000000000..7a92363f6 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/dummy_odes.hpp @@ -0,0 +1,151 @@ +/* + [auto_generated] + libs/numeric/odeint/test/dummy_odes.hpp + + [begin_description] + tba. + [end_description] + + Copyright 2012-2013 Karsten Ahnert + Copyright 2013 Mario Mulansky + + 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) +*/ + + +#ifndef LIBS_NUMERIC_ODEINT_TEST_DUMMY_ODES_HPP_DEFINED +#define LIBS_NUMERIC_ODEINT_TEST_DUMMY_ODES_HPP_DEFINED + +#include <boost/fusion/include/at_c.hpp> + + + + + + +/* + * rhs functors/functions for different state types + */ +struct constant_system_functor_standard +{ + template< class State , class Deriv , class Time > + void operator()( const State &x , Deriv &dxdt , const Time t ) const + { + dxdt[0] = 1.0; + } +}; + +struct constant_system_functor_vector_space +{ + template< class State , class Deriv , class Time > + void operator()( const State &x , Deriv &dxdt , const Time t ) const + { + dxdt = 1.0; + } +}; + +struct constant_system_functor_fusion +{ + template< class State , class Deriv , class Time > + void operator()( const State &x , Deriv &dxdt , const Time t ) const + { + boost::fusion::at_c< 0 >( dxdt ) = boost::fusion::at_c< 0 >( x ) / Time( 1.0 ); + } +}; + +struct lorenz +{ + template< typename State , typename Deriv , typename Time > + void operator()( const State& x , Deriv& dxdt , const Time& t ) const + { + const Time sigma = 10.0; + const Time R = 28.0; + const Time b = 8.0 / 3.0; + dxdt[0] = sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = -b * x[2] + x[0] * x[1]; + } +}; + +template< class State , class Deriv , class Time > +void constant_system_standard( const State &x , Deriv &dxdt , const Time t ) +{ + dxdt[0] = 1.0; +} + +template< class State , class Deriv , class Time > +void constant_system_vector_space( const State &x , Deriv &dxdt , const Time t ) +{ + dxdt = 1.0; +} + +template< class State , class Deriv , class Time > +void constant_system_fusion( const State &x , Deriv &dxdt , const Time t ) +{ + boost::fusion::at_c< 0 >( dxdt ) = boost::fusion::at_c< 0 >( x ) / Time( 1.0 ); +} + + + + +/* + * rhs functors for symplectic steppers + */ +struct constant_mom_func +{ + template< class StateIn , class StateOut > + void operator()( const StateIn &q , StateOut &dp ) const + { + dp[0] = 1.0; + } +}; + +struct default_coor_func +{ + template< class StateIn , class StateOut > + void operator()( const StateIn &p , StateOut &dq ) const + { + dq[0] = p[0]; + } +}; + + + +struct constant_mom_func_vector_space_1d +{ + template< class T > + void operator()( const T &q , T &dp ) const + { + dp = 1.0; + } +}; + +struct default_coor_func_vector_space_1d +{ + template< class T > + void operator()( const T &p , T &dq ) const + { + dq = p; + } +}; + + + + + + + +struct empty_system +{ + template <class State > + void operator()( const State &x , State &dxdt , double t ) const + { + } +}; + + + + +#endif // LIBS_NUMERIC_ODEINT_TEST_DUMMY_ODES_HPP_DEFINED diff --git a/src/boost/libs/numeric/odeint/test/dummy_steppers.hpp b/src/boost/libs/numeric/odeint/test/dummy_steppers.hpp new file mode 100644 index 000000000..5f8d749fd --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/dummy_steppers.hpp @@ -0,0 +1,122 @@ +/* + [auto_generated] + libs/numeric/odeint/test/dummy_steppers.hpp + + [begin_description] + Dummy steppers for several tests. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2012 Mario Mulansky + + 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) + */ + + +#ifndef BOOST_LIBS_NUMERIC_ODEINT_TEST_DUMMY_STEPPER_HPP_INCLUDED +#define BOOST_LIBS_NUMERIC_ODEINT_TEST_DUMMY_STEPPER_HPP_INCLUDED + +#include <boost/array.hpp> +#include <boost/numeric/odeint/stepper/stepper_categories.hpp> +#include <boost/numeric/odeint/stepper/controlled_step_result.hpp> + +namespace boost { +namespace numeric { +namespace odeint { + +struct dummy_stepper +{ + typedef double value_type; + typedef value_type time_type; + typedef boost::array< value_type , 1 > state_type; + typedef state_type deriv_type; + typedef unsigned short order_type; + typedef stepper_tag stepper_category; + + order_type order( void ) const { return 1; } + + template< class System > + void do_step( System sys , state_type &x , time_type t , time_type dt ) const + { + x[0] += 0.25; + } +}; + +struct dummy_dense_output_stepper +{ + typedef double value_type; + typedef value_type time_type; + typedef boost::array< value_type , 1 > state_type; + typedef state_type deriv_type; + typedef dense_output_stepper_tag stepper_category; + + void initialize( const state_type &x0 , time_type t0 , time_type dt0 ) + { + m_x = x0; + m_t = t0; + m_dt = dt0; + } + + template< class System > + std::pair< time_type , time_type > do_step( System sys ) + { + m_x[0] += 0.25; + m_t += m_dt; + return std::make_pair( m_t - m_dt , m_t ); + } + + void calc_state( time_type t_inter , state_type &x ) const + { + value_type theta = ( m_t - t_inter ) / m_dt; + x[0] = m_x[0] - 0.25 * theta; + + } + + const time_type& current_time( void ) const + { + return m_t; + } + + const state_type& current_state( void ) const + { + return m_x; + } + + const time_type& current_time_step( void ) const + { + return m_dt; + } + + state_type m_x; + time_type m_t; + time_type m_dt; +}; + + + +struct dummy_controlled_stepper +{ + typedef double value_type; + typedef value_type time_type; + typedef boost::array< value_type , 1 > state_type; + typedef state_type deriv_type; + typedef controlled_stepper_tag stepper_category; + + template< class Sys > + controlled_step_result try_step( Sys sys , state_type &x , time_type &t , time_type &dt ) const + { + x[0] += 0.25; + t += dt; + return success; + } +}; + + +} // odeint +} // numeric +} // boost + + +#endif // BOOST_LIBS_NUMERIC_ODEINT_TEST_DUMMY_STEPPER_HPP_INCLUDED diff --git a/src/boost/libs/numeric/odeint/test/euler_stepper.cpp b/src/boost/libs/numeric/odeint/test/euler_stepper.cpp new file mode 100644 index 000000000..a274de4b2 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/euler_stepper.cpp @@ -0,0 +1,105 @@ +/* + [auto_generated] + libs/numeric/odeint/test/euler_stepper.cpp + + [begin_description] + This file tests explicit Euler stepper. + [end_description] + + Copyright 2011 Mario Mulansky + Copyright 2012 Karsten Ahnert + + 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) + */ + + +#define BOOST_TEST_MODULE odeint_explicit_euler + +#include <boost/test/unit_test.hpp> + +#include <utility> +#include <iostream> +#include <vector> + +#include <boost/numeric/odeint/stepper/euler.hpp> +#include <boost/numeric/odeint/algebra/range_algebra.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +// test with own vector implementation + +class my_vec : public std::vector< double > { + +public: + + my_vec() : std::vector< double >() + { } + + my_vec( const my_vec &x ) : std::vector< double >( x ) + { } + + + my_vec( size_t dim ) + : std::vector< double >( dim ) + { } + +}; + +namespace boost { +namespace numeric { +namespace odeint { + +template<> +struct is_resizeable< my_vec > +{ + //struct type : public boost::true_type { }; + typedef boost::true_type type; + const static bool value = type::value; +}; +} } } + +typedef double value_type; +//typedef std::vector< value_type > state_type; +typedef my_vec state_type; + +/* use functors, because functions don't work with msvc 10, I guess this is a bug */ +struct sys +{ + void operator()( const state_type &x , state_type &dxdt , const value_type t ) const + { + std::cout << "sys start " << dxdt.size() << std::endl; + dxdt[0] = x[0] + 2 * x[1]; + dxdt[1] = x[1]; + std::cout << "sys done" << std::endl; + } +}; + + +BOOST_AUTO_TEST_SUITE( explicit_euler_test ) + +BOOST_AUTO_TEST_CASE( test_euler ) +{ + range_algebra algebra; + euler< state_type > stepper( algebra ); + state_type x( 2 ); + x[0] = 0.0; x[1] = 1.0; + + std::cout << "initialized" << std::endl; + + const value_type eps = 1E-12; + const value_type dt = 0.1; + + stepper.do_step( sys() , x , 0.0 , dt ); + + using std::abs; + + // compare with analytic solution of above system + BOOST_CHECK_MESSAGE( abs( x[0] - 2.0*1.0*dt ) < eps , x[0] - 2.0*1.0*dt ); + BOOST_CHECK_MESSAGE( abs( x[1] - (1.0 + dt) ) < eps , x[1] - (1.0+dt) ); + +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/fusion_algebra.cpp b/src/boost/libs/numeric/odeint/test/fusion_algebra.cpp new file mode 100644 index 000000000..cc63fa921 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/fusion_algebra.cpp @@ -0,0 +1,184 @@ +/* + [auto_generated] + libs/numeric/odeint/test/fusion_algebra.cpp + + [begin_description] + This file tests the Fusion algebra. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011-2013 Mario Mulansky + + 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) + */ + + +#define BOOST_TEST_MODULE odeint_fusion_algebra + +// using fusion vectors as state types requires increased macro variables +#define BOOST_FUSION_INVOKE_MAX_ARITY 15 +#define BOOST_RESULT_OF_NUM_ARGS 15 + +#include <cmath> +#include <complex> +#include <utility> +#include <functional> + +#include <boost/numeric/odeint/config.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> + +#include <boost/units/systems/si/length.hpp> +#include <boost/units/systems/si/time.hpp> +#include <boost/units/systems/si/velocity.hpp> +#include <boost/units/systems/si/acceleration.hpp> +#include <boost/units/systems/si/io.hpp> + +#include <boost/fusion/container.hpp> + +#include <boost/numeric/odeint/algebra/default_operations.hpp> +#include <boost/numeric/odeint/algebra/fusion_algebra.hpp> + +namespace units = boost::units; +namespace si = boost::units::si; +namespace fusion = boost::fusion; + +using boost::numeric::odeint::default_operations; +using boost::numeric::odeint::fusion_algebra; + +typedef double value_type; +typedef units::quantity< si::time , value_type > time_type; +typedef units::quantity< si::length , value_type > length_type; +typedef units::quantity< si::velocity , value_type > velocity_type; +typedef units::quantity< si::acceleration , value_type > acceleration_type; +typedef fusion::vector< length_type , velocity_type > state_type; +typedef fusion::vector< velocity_type , acceleration_type > deriv_type; + +const time_type dt = 0.1 * si::second; + + +struct fusion_fixture +{ + fusion_fixture( void ) + : res( 0.0 * si::meter , 0.0 * si::meter_per_second ) , + x( 1.0 * si::meter , 1.0 * si::meter_per_second ) , + k1( 1.0 * si::meter_per_second , 1.0 * si::meter_per_second_squared ) , + k2( 2.0 * si::meter_per_second , 2.0 * si::meter_per_second_squared ) , + k3( 3.0 * si::meter_per_second , 3.0 * si::meter_per_second_squared ) , + k4( 4.0 * si::meter_per_second , 4.0 * si::meter_per_second_squared ) , + k5( 5.0 * si::meter_per_second , 5.0 * si::meter_per_second_squared ) , + k6( 6.0 * si::meter_per_second , 6.0 * si::meter_per_second_squared ) { } + + ~fusion_fixture( void ) + { + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( x ).value() , 1.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( x ).value() , 1.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( k1 ).value() , 1.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( k1 ).value() , 1.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( k2 ).value() , 2.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( k2 ).value() , 2.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( k3 ).value() , 3.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( k3 ).value() , 3.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( k4 ).value() , 4.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( k4 ).value() , 4.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( k5 ).value() , 5.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( k5 ).value() , 5.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( k6 ).value() , 6.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( k6 ).value() , 6.0 , 1.0e-10 ); + } + + state_type res , x; + deriv_type k1 , k2 , k3 , k4 , k5 , k6 ; +}; + + + +BOOST_AUTO_TEST_SUITE( fusion_algebra_test ) + +fusion_algebra algebra; + +BOOST_AUTO_TEST_CASE( for_each2 ) +{ + fusion_fixture f; + algebra.for_each2( f.res , f.k1 , + default_operations::scale_sum1< time_type >( dt ) ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( f.res ).value() , 0.1 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( f.res ).value() , 0.1 , 1.0e-10 ); +} + +BOOST_AUTO_TEST_CASE( for_each3 ) +{ + fusion_fixture f; + algebra.for_each3( f.res , f.x , f.k1 , + default_operations::scale_sum2< value_type , time_type >( 1.0 , dt ) ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( f.res ).value() , 1.1 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( f.res ).value() , 1.1 , 1.0e-10 ); +} + +BOOST_AUTO_TEST_CASE( for_each4 ) +{ + fusion_fixture f; + algebra.for_each4( f.res , f.x , f.k1 , f.k2 , + default_operations::scale_sum3< value_type , time_type , time_type >( 1.0 , dt , dt ) ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( f.res ).value() , 1.3 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( f.res ).value() , 1.3 , 1.0e-10 ); +} + +BOOST_AUTO_TEST_CASE( for_each5 ) +{ + fusion_fixture f; + algebra.for_each5( f.res , f.x , f.k1 , f.k2 , f.k3 , + default_operations::scale_sum4< value_type , time_type , time_type , time_type >( 1.0 , dt , dt , dt ) ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( f.res ).value() , 1.6 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( f.res ).value() , 1.6 , 1.0e-10 ); +} + +BOOST_AUTO_TEST_CASE( for_each6 ) +{ + fusion_fixture f; + algebra.for_each6( f.res , f.x , f.k1 , f.k2 , f.k3 , f.k4 , + default_operations::scale_sum5< value_type , time_type , time_type , time_type , time_type >( 1.0 , dt , dt , dt , dt ) ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( f.res ).value() , 2.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( f.res ).value() , 2.0 , 1.0e-10 ); +} + +BOOST_AUTO_TEST_CASE( for_each7 ) +{ + fusion_fixture f; + algebra.for_each7( f.res , f.x , f.k1 , f.k2 , f.k3 , f.k4 , f.k5 , + default_operations::scale_sum6< value_type , time_type , time_type , time_type , time_type , time_type >( 1.0 , dt , dt , dt , dt , dt ) ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( f.res ).value() , 2.5 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( f.res ).value() , 2.5 , 1.0e-10 ); +} + +BOOST_AUTO_TEST_CASE( for_each8 ) +{ + fusion_fixture f; + algebra.for_each8( f.res , f.x , f.k1 , f.k2 , f.k3 , f.k4 , f.k5 , f.k6 , + default_operations::scale_sum7< value_type , time_type , time_type , time_type , time_type , time_type , time_type >( 1.0 , dt , dt , dt , dt , dt , dt ) ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( f.res ).value() , 3.1 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( f.res ).value() , 3.1 , 1.0e-10 ); +} + +BOOST_AUTO_TEST_CASE( for_each15 ) +{ + fusion_fixture f; + algebra.for_each15( f.res , f.x , f.k1 , f.k2 , f.k3 , f.k4 , f.k5 , f.k6 , f.k1 , f.k2 , f.k3 , f.k4 , f.k5 , f.k6 , f.k1 , + default_operations::scale_sum14< value_type , time_type , time_type , time_type , time_type , time_type , time_type , + time_type , time_type , time_type , time_type , time_type , time_type , time_type >( 1.0 , dt , dt , dt , dt , dt , dt , dt , dt , dt , dt , dt , dt , dt ) ); + //BOOST_CHECK_CLOSE( fusion::at_c< 0 >( f.res ).value() , 3.1 , 1.0e-10 ); + //BOOST_CHECK_CLOSE( fusion::at_c< 1 >( f.res ).value() , 3.1 , 1.0e-10 ); +} + + +BOOST_AUTO_TEST_CASE( norm_inf ) +{ + double nrm = algebra.norm_inf( fusion::make_vector( 1.0 , 2.0 , 3.0 ) ); + BOOST_CHECK_CLOSE( nrm , 3.0 , 1.0e-10 ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/generation.cpp b/src/boost/libs/numeric/odeint/test/generation.cpp new file mode 100644 index 000000000..6432692d7 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/generation.cpp @@ -0,0 +1,87 @@ +/* + [auto_generated] + libs/numeric/odeint/test/generation.cpp + + [begin_description] + This file tests the generation functions. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011-2012 Mario Mulansky + + 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) + */ + + +#define BOOST_TEST_MODULE odeint_generation + +#include <vector> + +#include <boost/test/unit_test.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <boost/numeric/odeint/config.hpp> +#include <boost/numeric/odeint/stepper/generation.hpp> + +using namespace boost::numeric::odeint; + +template< class Stepper1 , class Stepper2 > +void check_stepper_type( const Stepper1 &s1 , const Stepper2 &s2 ) +{ + BOOST_STATIC_ASSERT(( boost::is_same< Stepper1 , Stepper2 >::value )); +} + +BOOST_AUTO_TEST_SUITE( generation_test ) + +typedef std::vector< double > state_type; + +typedef runge_kutta_cash_karp54< state_type > rk54_type; +typedef runge_kutta_cash_karp54_classic< state_type > rk54_classic_type; +typedef runge_kutta_dopri5< state_type > dopri5_type; +typedef runge_kutta_fehlberg78< state_type > fehlberg78_type; +typedef rosenbrock4< double > rosenbrock4_type; + + +BOOST_AUTO_TEST_CASE( test_generation_dopri5 ) +{ + check_stepper_type( make_controlled( 1.0e-6 , 1.0e-10 , dopri5_type() ) , controlled_runge_kutta< dopri5_type >() ); + check_stepper_type( make_controlled< dopri5_type >( 1.0e-6 , 1.0e-10 ) , controlled_runge_kutta< dopri5_type >() ); + + check_stepper_type( make_dense_output( 1.0e-6 , 1.0e-10 , dopri5_type() ) , dense_output_runge_kutta< controlled_runge_kutta< dopri5_type > >() ); + check_stepper_type( make_dense_output< dopri5_type >( 1.0e-6 , 1.0e-10 ) , dense_output_runge_kutta< controlled_runge_kutta< dopri5_type > >() ); +} + +BOOST_AUTO_TEST_CASE( test_generation_cash_karp54 ) +{ + check_stepper_type( make_controlled( 1.0e-6 , 1.0e-10 , rk54_type() ) , controlled_runge_kutta< rk54_type >() ); + check_stepper_type( make_controlled< rk54_type >( 1.0e-6 , 1.0e-10 ) , controlled_runge_kutta< rk54_type >() ); +} + +BOOST_AUTO_TEST_CASE( test_generation_cash_karp54_classic ) +{ + check_stepper_type( make_controlled( 1.0e-6 , 1.0e-10 , rk54_classic_type() ) , controlled_runge_kutta< rk54_classic_type >() ); + check_stepper_type( make_controlled< rk54_classic_type >( 1.0e-6 , 1.0e-10 ) , controlled_runge_kutta< rk54_classic_type >() ); +} + + +BOOST_AUTO_TEST_CASE( test_generation_fehlberg78 ) +{ + check_stepper_type( make_controlled( 1.0e-6 , 1.0e-10 , fehlberg78_type() ) , controlled_runge_kutta< fehlberg78_type >() ); + check_stepper_type( make_controlled< fehlberg78_type >( 1.0e-6 , 1.0e-10 ) , controlled_runge_kutta< fehlberg78_type >() ); +} + + +BOOST_AUTO_TEST_CASE( test_generation_rosenbrock4 ) +{ + check_stepper_type( make_controlled( 1.0e-6 , 1.0e-10 , rosenbrock4_type() ) , rosenbrock4_controller< rosenbrock4_type >() ); + check_stepper_type( make_controlled< rosenbrock4_type >( 1.0e-6 , 1.0e-10 ) , rosenbrock4_controller< rosenbrock4_type >() ); + + check_stepper_type( make_dense_output( 1.0e-6 , 1.0e-10 , rosenbrock4_type() ) , rosenbrock4_dense_output< rosenbrock4_controller< rosenbrock4_type > >() ); + check_stepper_type( make_dense_output< rosenbrock4_type >( 1.0e-6 , 1.0e-10 ) , rosenbrock4_dense_output< rosenbrock4_controller< rosenbrock4_type > >() ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/generic_error_stepper.cpp b/src/boost/libs/numeric/odeint/test/generic_error_stepper.cpp new file mode 100644 index 000000000..0b18da89b --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/generic_error_stepper.cpp @@ -0,0 +1,111 @@ +/* + [auto_generated] + libs/numeric/odeint/test/generic_error_stepper.cpp + + [begin_description] + This file tests the generic error stepper. + [end_description] + + Copyright 2011 Mario Mulansky + Copyright 2012 Karsten Ahnert + + 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) + */ + + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_generic_error_stepper + +#include <iostream> +#include <utility> + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/stepper/explicit_error_generic_rk.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54_classic.hpp> + +#include <boost/array.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +namespace fusion = boost::fusion; + +typedef double value_type; +typedef boost::array< value_type , 2 > state_type; + +void sys( const state_type &x , state_type &dxdt , const value_type &t ) +{ + dxdt[ 0 ] = x[ 0 ] + 2 * x[ 1 ]; + dxdt[ 1 ] = x[ 1 ]; +} + +typedef explicit_error_generic_rk< 6 , 5 , 4 , 5 , state_type> error_rk_generic_type; + +const boost::array< double , 1 > a1 = {{ 0.2 }}; +const boost::array< double , 2 > a2 = {{ 3.0/40.0 , 9.0/40 }}; +const boost::array< double , 3 > a3 = {{ 0.3 , -0.9 , 1.2 }}; +const boost::array< double , 4 > a4 = {{ -11.0/54.0 , 2.5 , -70.0/27.0 , 35.0/27.0 }}; +const boost::array< double , 5 > a5 = {{ 1631.0/55296.0 , 175.0/512.0 , 575.0/13824.0 , 44275.0/110592.0 , 253.0/4096.0 }}; + +const error_rk_generic_type::coef_a_type a = fusion::make_vector( a1 , a2 , a3 , a4 , a5 ); +const error_rk_generic_type::coef_b_type b = {{ 37.0/378.0 , 0.0 , 250.0/621.0 , 125.0/594.0 , 0.0 , 512.0/1771.0 }}; +const error_rk_generic_type::coef_b_type b2 = {{ b[0]-2825.0/27648.0 , b[1]-0.0 , b[2]-18575.0/48384.0 , b[3]-13525.0/55296.0 , b[4]-277.0/14336.0 , b[5]-0.25 }}; +const error_rk_generic_type::coef_c_type c = {{ 0.0 , 0.2 , 0.3 , 0.6 , 1.0 , 7.0/8 }}; + +typedef runge_kutta_cash_karp54< state_type > error_rk54_ck_generic_type; +typedef runge_kutta_cash_karp54_classic< state_type > rk54_ck_type; + +BOOST_AUTO_TEST_SUITE( generic_error_stepper_test ) + +BOOST_AUTO_TEST_CASE( test_generic_error_stepper ) +{ + //simultaneously test copying + error_rk_generic_type rk_generic_( a , b , b2 , c ); + error_rk_generic_type rk_generic = rk_generic_; + + error_rk54_ck_generic_type rk54_ck_generic_; + error_rk54_ck_generic_type rk54_ck_generic = rk54_ck_generic_; + + //std::cout << stepper; + + rk54_ck_type rk54_ck_; + rk54_ck_type rk54_ck = rk54_ck_; + + typedef error_rk_generic_type::state_type state_type; + typedef error_rk_generic_type::value_type stepper_value_type; + typedef error_rk_generic_type::deriv_type deriv_type; + typedef error_rk_generic_type::time_type time_type; + + state_type x = {{ 0.0 , 1.0 }}; + state_type y = x; + state_type z = x; + state_type x_err , y_err , z_err; + + rk_generic.do_step( sys , x , 0.0 , 0.1 , x_err ); + + rk54_ck_generic.do_step( sys , y , 0.0 , 0.1 , y_err); + + rk54_ck.do_step( sys , z , 0.0 , 0.1 , z_err ); + + BOOST_CHECK_NE( 0.0 , x[0] ); + BOOST_CHECK_NE( 1.0 , x[1] ); + BOOST_CHECK_NE( 0.0 , x_err[0] ); + BOOST_CHECK_NE( 0.0 , x_err[1] ); + // compare with analytic solution of above system + BOOST_CHECK_EQUAL( x[0] , y[0] ); + BOOST_CHECK_EQUAL( x[1] , y[1] ); + BOOST_CHECK_EQUAL( x[0] , z[0] ); + BOOST_CHECK_EQUAL( x[1] , z[1] ); + +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/generic_stepper.cpp b/src/boost/libs/numeric/odeint/test/generic_stepper.cpp new file mode 100644 index 000000000..e2c18272f --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/generic_stepper.cpp @@ -0,0 +1,104 @@ +/* + [auto_generated] + libs/numeric/odeint/test/generic_stepper.cpp + + [begin_description] + This file tests the generic stepper. + [end_description] + + Copyright 2011 Mario Mulansky + Copyright 2012 Karsten Ahnert + + 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) + */ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_generic_stepper + +#include <iostream> +#include <utility> + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/stepper/explicit_generic_rk.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4_classic.hpp> + +#include <boost/array.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +namespace fusion = boost::fusion; + +typedef double value_type; +typedef boost::array< value_type , 2 > state_type; + +void sys( const state_type &x , state_type &dxdt , const value_type &t ) +{ + dxdt[ 0 ] = x[ 0 ] + 2 * x[ 1 ]; + dxdt[ 1 ] = x[ 1 ]; +} + +typedef explicit_generic_rk< 4 , 4 , state_type> rk_generic_type; +typedef runge_kutta4< state_type > rk4_generic_type; + +const boost::array< double , 1 > a1 = {{ 0.5 }}; +const boost::array< double , 2 > a2 = {{ 0.0 , 0.5 }}; +const boost::array< double , 3 > a3 = {{ 0.0 , 0.0 , 1.0 }}; + +const rk_generic_type::coef_a_type a = fusion::make_vector( a1 , a2 , a3 ); +const rk_generic_type::coef_b_type b = {{ 1.0/6 , 1.0/3 , 1.0/3 , 1.0/6 }}; +const rk_generic_type::coef_c_type c = {{ 0.0 , 0.5 , 0.5 , 1.0 }}; + +typedef runge_kutta4_classic< state_type > rk4_type; + +BOOST_AUTO_TEST_SUITE( generic_stepper_test ) + +BOOST_AUTO_TEST_CASE( test_generic_stepper ) +{ + //simultaneously test copying + rk_generic_type rk_generic_( a , b , c ); + rk_generic_type rk_generic = rk_generic_; + + rk4_generic_type rk4_generic_; + rk4_generic_type rk4_generic = rk4_generic_; + + //std::cout << stepper; + + rk4_type rk4_; + rk4_type rk4 = rk4_; + + typedef rk_generic_type::state_type state_type; + typedef rk_generic_type::value_type stepper_value_type; + typedef rk_generic_type::deriv_type deriv_type; + typedef rk_generic_type::time_type time_type; + + state_type x = {{ 0.0 , 1.0 }}; + state_type y = x; + state_type z = x; + + rk_generic.do_step( sys , x , 0.0 , 0.1 ); + + rk4_generic.do_step( sys , y , 0.0 , 0.1 ); + + rk4.do_step( sys , z , 0.0 , 0.1 ); + + BOOST_CHECK_NE( 0.0 , x[0] ); + BOOST_CHECK_NE( 1.0 , x[1] ); + // compare with analytic solution of above system + BOOST_CHECK_EQUAL( x[0] , y[0] ); + BOOST_CHECK_EQUAL( x[1] , y[1] ); + BOOST_CHECK_EQUAL( x[0] , z[0] ); + BOOST_CHECK_EQUAL( x[1] , z[1] ); + +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/implicit_euler.cpp b/src/boost/libs/numeric/odeint/test/implicit_euler.cpp new file mode 100644 index 000000000..575c896a8 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/implicit_euler.cpp @@ -0,0 +1,86 @@ +/* + [auto_generated] + libs/numeric/odeint/test/implicit_euler.cpp + + [begin_description] + This file tests the implicit Euler stepper. + [end_description] + + Copyright 2010-2011 Mario Mulansky + Copyright 2010-2012 Karsten Ahnert + + 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) + */ + + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_implicit_euler + +#include <boost/test/unit_test.hpp> + +#include <utility> +#include <iostream> + +#include <boost/numeric/odeint/stepper/implicit_euler.hpp> +//#include <boost/numeric/odeint/util/ublas_resize.hpp> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef double value_type; +typedef boost::numeric::ublas::vector< value_type > state_type; +typedef boost::numeric::ublas::matrix< value_type > matrix_type; + +/* use functors, because functions don't work with msvc 10, I guess this is a bug */ +struct sys +{ + void operator()( const state_type &x , state_type &dxdt , const value_type t ) const + { + dxdt( 0 ) = x( 0 ) + 2 * x( 1 ); + dxdt( 1 ) = x( 1 ); + } +}; + +struct jacobi +{ + void operator()( const state_type &x , matrix_type &jacobi , const value_type t ) const + { + jacobi( 0 , 0 ) = 1; + jacobi( 0 , 1 ) = 2; + jacobi( 1 , 0 ) = 0; + jacobi( 1 , 1 ) = 1; + } +}; + +BOOST_AUTO_TEST_SUITE( implicit_euler_test ) + +BOOST_AUTO_TEST_CASE( test_euler ) +{ + implicit_euler< value_type > stepper; + state_type x( 2 ); + x(0) = 0.0; x(1) = 1.0; + + value_type eps = 1E-12; + + /* make_pair doesn't work with function pointers on msvc 10 */ + stepper.do_step( std::make_pair( sys() , jacobi() ) , x , 0.0 , 0.1 ); + + using std::abs; + + // compare with analytic solution of above system + BOOST_CHECK_MESSAGE( abs( x(0) - 20.0/81.0 ) < eps , x(0) - 20.0/81.0 ); + BOOST_CHECK_MESSAGE( abs( x(1) - 10.0/9.0 ) < eps , x(0) - 10.0/9.0 ); + +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/integrate.cpp b/src/boost/libs/numeric/odeint/test/integrate.cpp new file mode 100644 index 000000000..07d4617fa --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/integrate.cpp @@ -0,0 +1,299 @@ +/* + [auto_generated] + libs/numeric/odeint/test/integrate.cpp + + [begin_description] + This file tests the integrate function and its variants. + [end_description] + + Copyright 2011-2012 Mario Mulansky + Copyright 2011-2012 Karsten Ahnert + + 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) + */ + + +#define BOOST_TEST_MODULE odeint_integrate_functions + +#include <boost/type_traits.hpp> + +#include <vector> +#include <cmath> +#include <iostream> + +#include <boost/numeric/odeint/config.hpp> + +#include <boost/array.hpp> +#include <boost/ref.hpp> +#include <boost/iterator/counting_iterator.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> + +// nearly everything from odeint is used in these tests +#ifndef ODEINT_INTEGRATE_ITERATOR +#include <boost/numeric/odeint/integrate/integrate_const.hpp> +#include <boost/numeric/odeint/integrate/integrate_adaptive.hpp> +#include <boost/numeric/odeint/integrate/integrate_times.hpp> +#include <boost/numeric/odeint/integrate/integrate_n_steps.hpp> +#else +#include <boost/numeric/odeint/iterator/integrate/integrate_const.hpp> +#include <boost/numeric/odeint/iterator/integrate/integrate_adaptive.hpp> +#include <boost/numeric/odeint/iterator/integrate/integrate_times.hpp> +#include <boost/numeric/odeint/iterator/integrate/integrate_n_steps.hpp> +#endif +#include <boost/numeric/odeint/stepper/euler.hpp> +#include <boost/numeric/odeint/stepper/modified_midpoint.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_fehlberg78.hpp> +#include <boost/numeric/odeint/stepper/controlled_runge_kutta.hpp> +#include <boost/numeric/odeint/stepper/bulirsch_stoer.hpp> +#include <boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp> +#include <boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp> + +#include <boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp> +#include <boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp> + +#include <boost/numeric/odeint/util/detail/less_with_sign.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + + +typedef double value_type; +typedef std::vector< value_type > state_type; + +void lorenz( const state_type &x , state_type &dxdt , const value_type t ) +{ + //const value_type sigma( 10.0 ); + const value_type R( 28.0 ); + const value_type b( value_type( 8.0 ) / value_type( 3.0 ) ); + + // first component trivial + dxdt[0] = 1.0; //sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = -b * x[2] + x[0] * x[1]; +} + +struct push_back_time +{ + std::vector< double >& m_times; + + state_type& m_x; + + push_back_time( std::vector< double > × , state_type &x ) + : m_times( times ) , m_x( x ) { } + + void operator()( const state_type &x , double t ) + { + m_times.push_back( t ); + boost::numeric::odeint::copy( x , m_x ); + } +}; + +template< class Stepper > +struct perform_integrate_const_test +{ + void operator()( const value_type t_end , const value_type dt ) + { + // std::cout << "Testing integrate_const with " << typeid( Stepper ).name() << std::endl; + + state_type x( 3 , 10.0 ) , x_end( 3 ); + + std::vector< value_type > times; + + size_t steps = integrate_const( Stepper() , lorenz , x , 0.0 , t_end , + dt , push_back_time( times , x_end ) ); + + std::cout.precision(16); + std::cout << t_end << " (" << dt << "), " << steps << " , " << times.size() << " , " << 10.0+dt*steps << "=" << x_end[0] << std::endl; + + std::cout << static_cast<int>(floor(t_end/dt)) << " , " << t_end/dt << std::endl; + + BOOST_CHECK_EQUAL( static_cast<int>(times.size()) , static_cast<int>(floor(t_end/dt))+1 ); + + for( size_t i=0 ; i<times.size() ; ++i ) + { + //std::cout << i << " , " << times[i] << " , " << static_cast< value_type >(i)*dt << std::endl; + // check if observer was called at times 0,1,2,... + BOOST_CHECK_SMALL( times[i] - static_cast< value_type >(i)*dt , (i+1) * 2E-16 ); + } + + // check first, trivial, component + BOOST_CHECK_SMALL( (10.0 + times[times.size()-1]) - x_end[0] , 1E-6 ); // precision of steppers: 1E-6 + //BOOST_CHECK_EQUAL( x[1] , x_end[1] ); + //BOOST_CHECK_EQUAL( x[2] , x_end[2] ); + } +}; + +template< class Stepper > +struct perform_integrate_adaptive_test +{ + void operator()( const value_type t_end = 10.0 , const value_type dt = 0.03 ) + { + // std::cout << "Testing integrate_adaptive with " << typeid( Stepper ).name() << std::endl; + + state_type x( 3 , 10.0 ) , x_end( 3 ); + + std::vector< value_type > times; + + size_t steps = integrate_adaptive( Stepper() , lorenz , x , 0.0 , t_end , + dt , push_back_time( times , x_end ) ); + + // std::cout << t_end << " , " << steps << " , " << times.size() << " , " << dt << " , " << 10.0+t_end << "=" << x_end[0] << std::endl; + + BOOST_CHECK_EQUAL( times.size() , steps+1 ); + + BOOST_CHECK_SMALL( times[0] - 0.0 , 2E-16 ); + BOOST_CHECK_SMALL( times[times.size()-1] - t_end , times.size() * 2E-16 ); + + // check first, trivial, component + BOOST_CHECK_SMALL( (10.0 + t_end) - x_end[0] , 1E-6 ); // precision of steppers: 1E-6 +// BOOST_CHECK_EQUAL( x[1] , x_end[1] ); +// BOOST_CHECK_EQUAL( x[2] , x_end[2] ); + } +}; + + +template< class Stepper > +struct perform_integrate_times_test +{ + void operator()( const int n = 10 , const int dn=1 , const value_type dt = 0.03 ) + { + // std::cout << "Testing integrate_times with " << typeid( Stepper ).name() << std::endl; + + state_type x( 3 ) , x_end( 3 ); + x[0] = x[1] = x[2] = 10.0; + + std::vector< double > times; + + std::vector< double > obs_times( abs(n) ); + for( int i=0 ; boost::numeric::odeint::detail::less_with_sign( static_cast<double>(i) , + static_cast<double>(obs_times.size()) , + dt ) ; i+=dn ) + { + obs_times[i] = i; + } + // simple stepper + integrate_times( Stepper() , lorenz , x , obs_times.begin() , obs_times.end() , + dt , push_back_time( times , x_end ) ); + + BOOST_CHECK_EQUAL( static_cast<int>(times.size()) , abs(n) ); + + for( size_t i=0 ; i<times.size() ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_EQUAL( times[i] , static_cast<double>(i) ); + + // check first, trivial, component + BOOST_CHECK_SMALL( (10.0 + 1.0*times[times.size()-1]) - x_end[0] , 1E-6 ); // precision of steppers: 1E-6 +// BOOST_CHECK_EQUAL( x[1] , x_end[1] ); +// BOOST_CHECK_EQUAL( x[2] , x_end[2] ); + } +}; + +template< class Stepper > +struct perform_integrate_n_steps_test +{ + void operator()( const int n = 200 , const value_type dt = 0.01 ) + { + // std::cout << "Testing integrate_n_steps with " << typeid( Stepper ).name() << ". "; + // std::cout << "dt=" << dt << std::endl; + + state_type x( 3 ) , x_end( 3 ); + x[0] = x[1] = x[2] = 10.0; + + std::vector< double > times; + + // simple stepper + value_type end_time = integrate_n_steps( Stepper() , lorenz , x , 0.0 , dt , n , push_back_time( times , x_end ) ); + + BOOST_CHECK_SMALL( end_time - n*dt , 2E-16 ); + BOOST_CHECK_EQUAL( static_cast<int>(times.size()) , n+1 ); + + for( size_t i=0 ; i<times.size() ; ++i ) + { + // check if observer was called at times 0,1,2,... + BOOST_CHECK_SMALL(times[i] - static_cast< value_type >(i) * dt, 2E-16); + } + // check first, trivial, component + BOOST_CHECK_SMALL( (10.0 + end_time) - x_end[0] , 1E-6 ); // precision of steppers: 1E-6 +// BOOST_CHECK_EQUAL( x[1] , x_end[1] ); +// BOOST_CHECK_EQUAL( x[2] , x_end[2] ); + + } +}; + + + +class stepper_methods : public mpl::vector< + euler< state_type > , + modified_midpoint< state_type > , + runge_kutta4< state_type > , + runge_kutta_cash_karp54< state_type > , + runge_kutta_dopri5< state_type > , + runge_kutta_fehlberg78< state_type > , + controlled_runge_kutta< runge_kutta_cash_karp54< state_type > > , + controlled_runge_kutta< runge_kutta_dopri5< state_type > > , + controlled_runge_kutta< runge_kutta_fehlberg78< state_type > > , + bulirsch_stoer< state_type > , + dense_output_runge_kutta< controlled_runge_kutta< runge_kutta_dopri5< state_type > > >, + adaptive_adams_bashforth_moulton<3, state_type>, + adaptive_adams_bashforth_moulton<5, state_type>, + adaptive_adams_bashforth_moulton<7, state_type>, + controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<3, state_type> >, + controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<5, state_type> > + //bulirsch_stoer_dense_out< state_type > +> { }; + + + +BOOST_AUTO_TEST_SUITE( integrate_test ) + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_const_test_case , Stepper, stepper_methods ) +{ + perform_integrate_const_test< Stepper > tester; + tester( 1.005 , 0.01 ); + tester( 1.0 , 0.01 ); + tester( 1.1 , 0.01 ); + tester( -1.005 , -0.01 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_adaptive_test_case , Stepper, stepper_methods ) +{ + perform_integrate_adaptive_test< Stepper > tester; + tester( 1.005 , 0.01 ); + tester( 1.0 , 0.01 ); + tester( 1.1 , 0.01 ); + tester( -1.005 , -0.01 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_times_test_case , Stepper, stepper_methods ) +{ + perform_integrate_times_test< Stepper > tester; + tester(); + //tester( -10 , -0.01 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_n_steps_test_case , Stepper, stepper_methods ) +{ + if(!boost::is_same<Stepper, controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<3, state_type> > >::value && + !boost::is_same<Stepper, controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<5, state_type> > >::value) + { + perform_integrate_n_steps_test< Stepper > tester; + tester(); + tester( 200 , 0.01 ); + tester( 200 , 0.01 ); + tester( 200 , 0.01 ); + tester( 200 , -0.01 ); + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/integrate_implicit.cpp b/src/boost/libs/numeric/odeint/test/integrate_implicit.cpp new file mode 100644 index 000000000..4bff200ae --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/integrate_implicit.cpp @@ -0,0 +1,233 @@ +/* + [auto_generated] + libs/numeric/odeint/test/integrate_implicit.cpp + + [begin_description] + This file tests the integrate function and its variants with the implicit steppers. + [end_description] + + Copyright 2011 Mario Mulansky + Copyright 2011-2013 Karsten Ahnert + + 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) + */ + +#define BOOST_TEST_MODULE odeint_integrate_functions_implicit + +#include <vector> +#include <cmath> +#include <iostream> + +#include <boost/numeric/odeint/config.hpp> + +#include <boost/array.hpp> +#include <boost/ref.hpp> +#include <boost/iterator/counting_iterator.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> + +#ifndef ODEINT_INTEGRATE_ITERATOR +#include <boost/numeric/odeint/integrate/integrate_const.hpp> +#include <boost/numeric/odeint/integrate/integrate_adaptive.hpp> +#include <boost/numeric/odeint/integrate/integrate_times.hpp> +#include <boost/numeric/odeint/integrate/integrate_n_steps.hpp> +#else +#include <boost/numeric/odeint/iterator/integrate/integrate_const.hpp> +#include <boost/numeric/odeint/iterator/integrate/integrate_adaptive.hpp> +#include <boost/numeric/odeint/iterator/integrate/integrate_times.hpp> +#include <boost/numeric/odeint/iterator/integrate/integrate_n_steps.hpp> +#endif +#include <boost/numeric/odeint/stepper/rosenbrock4.hpp> +#include <boost/numeric/odeint/stepper/rosenbrock4_controller.hpp> +#include <boost/numeric/odeint/stepper/rosenbrock4_dense_output.hpp> + + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; +namespace ublas = boost::numeric::ublas; + +typedef double value_type; +typedef ublas::vector< value_type > state_type; +typedef boost::numeric::ublas::matrix< value_type > matrix_type; + +struct sys +{ + void operator()( const state_type &x , state_type &dxdt , const value_type &t ) const + { + dxdt( 0 ) = x( 0 ) + 2 * x( 1 ); + dxdt( 1 ) = x( 1 ); + } +}; + +struct jacobi +{ + void operator()( const state_type &x , matrix_type &jacobi , const value_type &t , state_type &dfdt ) const + { + jacobi( 0 , 0 ) = 1; + jacobi( 0 , 1 ) = 2; + jacobi( 1 , 0 ) = 0; + jacobi( 1 , 1 ) = 1; + dfdt( 0 ) = 0.0; + dfdt( 1 ) = 0.0; + } +}; + +struct push_back_time +{ + std::vector< double >& m_times; + + push_back_time( std::vector< double > × ) + : m_times( times ) { } + + void operator()( const state_type &x , double t ) + { + m_times.push_back( t ); + } +}; + +template< class Stepper > +struct perform_integrate_const_test +{ + void operator()( void ) + { + state_type x( 2 , 1.0 ); + const value_type dt = 0.03; + const value_type t_end = 10.0; + + std::vector< value_type > times; + + integrate_const( Stepper() , std::make_pair( sys() , jacobi() ) , x , 0.0 , t_end , + dt , push_back_time( times ) ); + + BOOST_CHECK_EQUAL( static_cast<int>(times.size()) , static_cast<int>(std::floor(t_end/dt))+1 ); + + for( size_t i=0 ; i<times.size() ; ++i ) + { + //std::cout << i << std::endl; + // check if observer was called at times 0,1,2,... + BOOST_CHECK_SMALL( times[i] - static_cast< value_type >(i)*dt , (i+1) * 2.0e-16 ); + } + } +}; + +template< class Stepper > +struct perform_integrate_adaptive_test +{ + void operator()( void ) + { + state_type x( 2 , 1.0 ); + const value_type dt = 0.03; + const value_type t_end = 10.0; + + std::vector< value_type > times; + + size_t steps = integrate_adaptive( Stepper() , std::make_pair( sys() , jacobi() ) , x , 0.0 , t_end , + dt , push_back_time( times ) ); + + BOOST_CHECK_EQUAL( times.size() , steps+1 ); + + BOOST_CHECK_SMALL( times[0] - 0.0 , 2.0e-16 ); + BOOST_CHECK_SMALL( times[times.size()-1] - t_end , times.size() * 3.0e-16 ); + } +}; + + +template< class Stepper > +struct perform_integrate_times_test +{ + void operator()( void ) + { + state_type x( 2 , 1.0 ); + + const value_type dt = 0.03; + + std::vector< double > times; + + // simple stepper + integrate_times( Stepper() , std::make_pair( sys() , jacobi() ) , x , + boost::counting_iterator<int>(0) , boost::counting_iterator<int>(10) , + dt , push_back_time( times ) ); + + BOOST_CHECK_EQUAL( static_cast<int>(times.size()) , 10 ); + + for( size_t i=0 ; i<times.size() ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_EQUAL( times[i] , static_cast<double>(i) ); + } +}; + +template< class Stepper > +struct perform_integrate_n_steps_test +{ + void operator()( void ) + { + state_type x( 2 , 1.0 ); + + const value_type dt = 0.03; + const int n = 200; + + std::vector< double > times; + + // simple stepper + value_type end_time = integrate_n_steps( Stepper() , std::make_pair( sys() , jacobi() ) , x , 0.0 , dt , n , push_back_time( times ) ); + + BOOST_CHECK_SMALL( end_time - n*dt , 3.0e-16 ); + BOOST_CHECK_EQUAL( static_cast<int>(times.size()) , n+1 ); + + for( size_t i=0 ; i<times.size() ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_SMALL( times[i] - static_cast< value_type >(i)*dt , (i+1) * 2.0e-16 ); + } +}; + + + +class stepper_methods : public mpl::vector< + rosenbrock4< value_type > , + rosenbrock4_controller< rosenbrock4< value_type > > , + rosenbrock4_dense_output< rosenbrock4_controller< rosenbrock4< value_type > > > +> { }; + + + +BOOST_AUTO_TEST_SUITE( integrate_test ) + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_const_test_case , Stepper, stepper_methods ) +{ + perform_integrate_const_test< Stepper > tester; + tester(); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_adaptive_test_case , Stepper, stepper_methods ) +{ + perform_integrate_adaptive_test< Stepper > tester; + tester(); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_times_test_case , Stepper, stepper_methods ) +{ + perform_integrate_times_test< Stepper > tester; + tester(); +} + + +class simple_stepper_methods : public mpl::vector< + rosenbrock4< value_type > +> { }; + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_n_steps_test_case , Stepper, simple_stepper_methods ) +{ + perform_integrate_n_steps_test< Stepper > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/integrate_overflow.cpp b/src/boost/libs/numeric/odeint/test/integrate_overflow.cpp new file mode 100644 index 000000000..0dba4046a --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/integrate_overflow.cpp @@ -0,0 +1,200 @@ +/* + [auto_generated] + libs/numeric/odeint/test/integrate_overflow.cpp + + [begin_description] + This file tests the overflow exception of the integrate functions. + [end_description] + + Copyright 2015 Mario Mulansky + + 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) + */ + + +#define BOOST_TEST_MODULE odeint_integrate_overflow + +#include <boost/test/unit_test.hpp> + +#include <utility> +#include <iostream> +#include <vector> + + +#include <vector> +#include <cmath> +#include <iostream> + +#include <boost/iterator/counting_iterator.hpp> + +#include <boost/numeric/odeint.hpp> + + +using namespace boost::numeric::odeint; + + +typedef double value_type; +typedef std::vector< value_type > state_type; + +// the famous lorenz system as usual +void lorenz( const state_type &x , state_type &dxdt , const value_type t ) +{ + //const value_type sigma( 10.0 ); + const value_type R( 28.0 ); + const value_type b( value_type( 8.0 ) / value_type( 3.0 ) ); + + // first component trivial + dxdt[0] = 1.0; //sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = -b * x[2] + x[0] * x[1]; +} + +struct push_back_time +{ + std::vector< double >& m_times; + + push_back_time( std::vector< double > × ) + : m_times( times ) { } + + void operator()( const state_type &x , double t ) + { + m_times.push_back( t ); + } +}; + +typedef runge_kutta_dopri5<state_type> stepper_type; +typedef runge_kutta_cash_karp54<state_type> cash_karp_type; + + +BOOST_AUTO_TEST_SUITE( integrate_overflow ) + +BOOST_AUTO_TEST_CASE( test_integrate_const ) +{ + state_type x(3, 5.0); + std::vector<double> times; + + // check the function signatures with normal stepper + integrate_const(stepper_type(), lorenz, x, 0.0, 10.0, 1.0); + integrate_const(stepper_type(), lorenz, x, 0.0, 10.0, 1.0, null_observer()); + // no exceptions expected for normal steppers + integrate_const(stepper_type(), lorenz, x, 0.0, 10.0, 1.0, null_observer(), max_step_checker(10)); + + + // check exceptions for controlled stepper + integrate_const(make_controlled<stepper_type>(1E-5, 1E-5), lorenz, x, 0.0, 10.0, 1.0); + // very small error terms -> standard overflow threshold of 500 should fire an exception + BOOST_CHECK_THROW(integrate_const(make_controlled<stepper_type>(1E-15, 1E-15), lorenz, x, + 0.0, 10.0, 1.0, push_back_time(times), max_step_checker()), + std::runtime_error); + // small threshold of 10 -> larger error still gives an exception + BOOST_CHECK_THROW(integrate_const(make_controlled<stepper_type>(1E-5, 1E-5), lorenz, x, + 0.0, 10.0, 1.0, push_back_time(times), max_step_checker(10)), + std::runtime_error); + + // check exceptions for dense output stepper + integrate_const(make_dense_output<stepper_type>(1E-5, 1E-5), lorenz, x, 0.0, 10.0, 1.0); + integrate_const(make_dense_output<stepper_type>(1E-5, 1E-5), lorenz, x, 0.0, 10.0, 1.0); + // very small error terms -> standard overflow threshold of 500 should fire an exception + BOOST_CHECK_THROW(integrate_const(make_dense_output<stepper_type>(1E-15, 1E-15), lorenz, x, + 0.0, 10.0, 1.0, push_back_time(times), max_step_checker()), + std::runtime_error); + // small threshold of 10 -> larger error still gives an exception + BOOST_CHECK_THROW(integrate_const(make_dense_output<stepper_type>(1E-5, 1E-5), lorenz, x, + 0.0, 10.0, 1.0, push_back_time(times), max_step_checker(10)), + std::runtime_error); +} + +BOOST_AUTO_TEST_CASE( test_integrate_n_steps ) +{ + state_type x(3, 5.0); + std::vector<double> times; + + // check the function signatures with normal stepper + integrate_n_steps(stepper_type(), lorenz, x, 0.0, 1.0, 10); + integrate_n_steps(stepper_type(), lorenz, x, 0.0, 1.0, 10, null_observer()); + // no exceptions expected for normal steppers + integrate_n_steps(stepper_type(), lorenz, x, 0.0, 1.0, 10, null_observer(), max_step_checker(10)); + + + // check exceptions for controlled stepper + integrate_n_steps(make_controlled<stepper_type>(1E-5, 1E-5), lorenz, x, 0.0, 1.0, 10); + // very small error terms -> standard overflow threshold of 500 should fire an exception + BOOST_CHECK_THROW(integrate_n_steps(make_controlled<stepper_type>(1E-15, 1E-15), lorenz, x, + 0.0, 1.0, 10, push_back_time(times), max_step_checker()), + std::runtime_error); + // small threshold of 10 -> larger error still gives an exception + BOOST_CHECK_THROW(integrate_n_steps(make_controlled<stepper_type>(1E-5, 1E-5), lorenz, x, + 0.0, 1.0, 10, push_back_time(times), max_step_checker(10)), + std::runtime_error); + + // check exceptions for dense output stepper + integrate_n_steps(make_dense_output<stepper_type>(1E-5, 1E-5), lorenz, x, 0.0, 1.0, 10); + integrate_n_steps(make_dense_output<stepper_type>(1E-5, 1E-5), lorenz, x, 0.0, 1.0, 10, push_back_time(times)); + // very small error terms -> standard overflow threshold of 500 should fire an exception + BOOST_CHECK_THROW(integrate_n_steps(make_dense_output<stepper_type>(1E-15, 1E-15), lorenz, x, + 0.0, 1.0, 10, push_back_time(times), max_step_checker()), + std::runtime_error); + // small threshold of 10 -> larger error still gives an exception + BOOST_CHECK_THROW(integrate_n_steps(make_dense_output<stepper_type>(1E-5, 1E-5), lorenz, x, + 0.0, 1.0, 10, push_back_time(times), max_step_checker(10)), + std::runtime_error); +} + +BOOST_AUTO_TEST_CASE( test_integrate_times ) +{ + state_type x(3, 5.0); + std::vector<double> times; + boost::counting_iterator<int> t0(0); + boost::counting_iterator<int> t1(10); + + // check the function signatures with normal stepper + integrate_times(stepper_type(), lorenz, x, t0, t1, 1.0 , push_back_time(times)); + // no exceptions expected for big enough step size + integrate_times(stepper_type(), lorenz, x, t0, t1, 1.0 , push_back_time(times), max_step_checker(10)); + // if dt*max_steps < observer time difference we expect an exception + BOOST_CHECK_THROW(integrate_times(stepper_type(), lorenz, x, t0, t1, 0.01, push_back_time(times), + max_step_checker(10)), + std::runtime_error); + + // check exceptions for controlled stepper + // no exception if no checker is provided + integrate_times(make_controlled<stepper_type>(1E-5, 1E-5), lorenz, x, t0, t1, 1.0 , push_back_time(times)); + // very small error terms -> standard overflow threshold of 500 should fire an exception + BOOST_CHECK_THROW(integrate_times(make_controlled<stepper_type>(1E-15, 1E-15), lorenz, x, + t0, t1, 1.0 , push_back_time(times), max_step_checker()), + std::runtime_error); + + // small threshold of 10 -> larger error still gives an exception + BOOST_CHECK_THROW(integrate_times(make_controlled<stepper_type>(1E-5, 1E-5), lorenz, x, + t0, t1, 1.0 , push_back_time(times), max_step_checker(10)), + std::runtime_error); + + // check cash karp controlled stepper + // no exception if no checker is provided + integrate_times(make_controlled<cash_karp_type>(1E-5, 1E-5), lorenz, x, t0, t1, 1.0 , push_back_time(times)); + // very small error terms -> standard overflow threshold of 500 should fire an exception + BOOST_CHECK_THROW(integrate_times(make_controlled<cash_karp_type>(1E-15, 1E-15), lorenz, x, + t0, t1, 1.0 , push_back_time(times), max_step_checker()), + std::runtime_error); + + // small threshold of 10 -> larger error still gives an exception + BOOST_CHECK_THROW(integrate_times(make_controlled<cash_karp_type>(1E-5, 1E-5), lorenz, x, + t0, t1, 1.0 , push_back_time(times), max_step_checker(10)), + std::runtime_error); + + // check exceptions for dense output stepper + integrate_times(make_dense_output<stepper_type>(1E-5, 1E-5), lorenz, x, t0, t1, 1.0 , + push_back_time(times)); + // very small error terms -> standard overflow threshold of 500 should fire an exception + BOOST_CHECK_THROW(integrate_times(make_dense_output<stepper_type>(1E-15, 1E-15), lorenz, x, + t0, t1, 1.0 , push_back_time(times), max_step_checker()), + std::runtime_error); + // small threshold of 10 -> larger error still gives an exception + BOOST_CHECK_THROW(integrate_times(make_dense_output<stepper_type>(1E-5, 1E-5), lorenz, x, + t0, t1, 1.0 , push_back_time(times), max_step_checker(10)), + std::runtime_error); +} + +BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file diff --git a/src/boost/libs/numeric/odeint/test/integrate_stepper_refs.cpp b/src/boost/libs/numeric/odeint/test/integrate_stepper_refs.cpp new file mode 100644 index 000000000..5d6d34c94 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/integrate_stepper_refs.cpp @@ -0,0 +1,271 @@ +/* + [auto_generated] + libs/numeric/odeint/test/integrate_stepper_refs.cpp + + [begin_description] + Tests the integrate functions with boost::ref( stepper) + [end_description] + + Copyright 2009-2013 Karsten Ahnert + Copyright 2009-2013 Mario Mulansky + + 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) + */ + + +#define BOOST_TEST_MODULE odeint_integrate_stepper_refs + +#include <vector> +#include <cmath> +#include <iostream> + +#include <boost/numeric/odeint/config.hpp> + +#include <boost/noncopyable.hpp> +#include <boost/test/unit_test.hpp> +#include <boost/iterator/counting_iterator.hpp> + +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint/integrate/integrate_const.hpp> +#include <boost/numeric/odeint/integrate/integrate_adaptive.hpp> +#include <boost/numeric/odeint/integrate/integrate_times.hpp> +#include <boost/numeric/odeint/integrate/integrate_n_steps.hpp> +#include <boost/numeric/odeint/stepper/controlled_step_result.hpp> + + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +typedef double value_type; +typedef std::vector< value_type > state_type; + +// minimal non-copyable basic stepper +template< +class State +> +class simple_stepper_nc : boost::noncopyable +{ +public : + typedef State state_type; + typedef double value_type; + typedef state_type deriv_type; + typedef double time_type; + typedef size_t order_type; + typedef stepper_tag stepper_category; + + template< class System > + void do_step( System system , state_type &in , time_type t , time_type dt ) + { + // empty + + } +}; + +// minimal non-copyable controlled stepper +template< +class State +> +class controlled_stepper_nc : boost::noncopyable +{ +public : + typedef State state_type; + typedef double value_type; + typedef state_type deriv_type; + typedef double time_type; + typedef size_t order_type; + typedef controlled_stepper_tag stepper_category; + + template< class System > + controlled_step_result try_step( System system , state_type &in , time_type &t , time_type &dt ) + { + std::cout << "dense out stepper: " << t << " , " << dt << std::endl; + t += dt; + return success; + } +}; + +// minimal non-copyable dense_output stepper +template< +class State +> +class dense_out_stepper_nc : boost::noncopyable +{ +public : + typedef State state_type; + typedef double value_type; + typedef state_type deriv_type; + typedef double time_type; + typedef size_t order_type; + typedef dense_output_stepper_tag stepper_category; + + void initialize( const state_type &x0 , const time_type t0 , const time_type dt0 ) + { + m_x = x0; + m_t = t0; + m_dt = dt0; + std::cout << "initialize: " << m_t << " , " << m_dt << std::endl; + } + + template< class System > + void do_step( System system ) + { + std::cout << "dense out stepper: " << m_t << " , " << m_dt << std::endl; + m_t += m_dt; + } + + void calc_state( const time_type t_inter , state_type &x ) + { + x = m_x; + } + + const state_type& current_state() const + { return m_x; } + + time_type current_time() const + { return m_t; } + + time_type current_time_step() const + { return m_dt; } + + +private : + time_type m_t; + time_type m_dt; + state_type m_x; +}; + + +void lorenz( const state_type &x , state_type &dxdt , const value_type t ) +{ + //const value_type sigma( 10.0 ); + const value_type R( 28.0 ); + const value_type b( value_type( 8.0 ) / value_type( 3.0 ) ); + + // first component trivial + dxdt[0] = 1.0; //sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = -b * x[2] + x[0] * x[1]; +} + +struct push_back_time +{ + std::vector< double >& m_times; + + state_type& m_x; + + push_back_time( std::vector< double > × , state_type &x ) + : m_times( times ) , m_x( x ) { } + + void operator()( const state_type &x , double t ) + { + m_times.push_back( t ); + boost::numeric::odeint::copy( x , m_x ); + } +}; + +template< class Stepper > +struct perform_integrate_const_test +{ + void operator()() + { + state_type x( 3 , 10.0 ) , x_end( 3 ); + + std::vector< value_type > times; + + Stepper stepper; + + integrate_const( boost::ref(stepper) , lorenz , x , 0.0 , 1.0 , + 0.1, push_back_time( times , x_end ) ); + } +}; + +template< class Stepper > +struct perform_integrate_adaptive_test +{ + void operator()() + { + state_type x( 3 , 10.0 ) , x_end( 3 ); + + std::vector< value_type > times; + + Stepper stepper; + + integrate_adaptive( boost::ref(stepper) , lorenz , x , 0.0 , 1.0 , + 0.1, push_back_time( times , x_end ) ); + } +}; + +template< class Stepper > +struct perform_integrate_n_steps_test +{ + void operator()() + { + state_type x( 3 , 10.0 ) , x_end( 3 ); + + std::vector< value_type > times; + + Stepper stepper; + + integrate_n_steps( boost::ref(stepper) , lorenz , x , 0.0 , 0.1 , + 10 , push_back_time( times , x_end ) ); + } +}; + +template< class Stepper > +struct perform_integrate_times_test +{ + void operator()() + { + state_type x( 3 , 10.0 ) , x_end( 3 ); + + std::vector< value_type > times; + + Stepper stepper; + + integrate_times( boost::ref(stepper) , lorenz , x , + boost::counting_iterator<int>(0) , boost::counting_iterator<int>(10) , 0.1 , + push_back_time( times , x_end ) ); + } +}; + +class stepper_methods : public mpl::vector< + simple_stepper_nc< state_type > , + controlled_stepper_nc< state_type >, + dense_out_stepper_nc< state_type > > { }; + +BOOST_AUTO_TEST_SUITE( integrate_stepper_refs ) + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_const_test_case , Stepper, stepper_methods ) +{ + std::cout << "integrate const" << std::endl; + perform_integrate_const_test< Stepper > tester; + tester(); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_adaptive_test_case , Stepper, stepper_methods ) +{ + std::cout << "integrate adaptive" << std::endl; + perform_integrate_adaptive_test< Stepper > tester; + tester(); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_n_steps_test_case , Stepper, stepper_methods ) +{ + std::cout << "integrate n steps" << std::endl; + perform_integrate_n_steps_test< Stepper > tester; + tester(); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_times_test_case , Stepper, stepper_methods ) +{ + std::cout << "integrate times" << std::endl; + perform_integrate_times_test< Stepper > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/integrate_times.cpp b/src/boost/libs/numeric/odeint/test/integrate_times.cpp new file mode 100644 index 000000000..2837f09e3 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/integrate_times.cpp @@ -0,0 +1,247 @@ +/* + [auto_generated] + libs/numeric/odeint/test/integrate_times.cpp + + [begin_description] + This file tests the integrate_times function and its variants. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011-2012 Mario Mulansky + + 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) + */ + +#define BOOST_TEST_MODULE odeint_integrate_times + +#include <boost/test/unit_test.hpp> + +#include <utility> +#include <iostream> +#include <vector> + +#include <boost/ref.hpp> +#include <boost/iterator/counting_iterator.hpp> + +#ifndef ODEINT_INTEGRATE_ITERATOR +#include <boost/numeric/odeint/integrate/integrate_times.hpp> +#include <boost/numeric/odeint/integrate/integrate_adaptive.hpp> +#else +#include <boost/numeric/odeint/iterator/integrate/integrate_times.hpp> +#include <boost/numeric/odeint/iterator/integrate/integrate_adaptive.hpp> +#endif +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp> +#include <boost/numeric/odeint/stepper/controlled_runge_kutta.hpp> +#include <boost/numeric/odeint/stepper/bulirsch_stoer.hpp> +#include <boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp> +#include <boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef double value_type; +typedef std::vector< value_type > state_type; + + +void lorenz( const state_type &x , state_type &dxdt , const value_type t ) +{ + BOOST_CHECK( t >= 0.0 ); + + const value_type sigma( 10.0 ); + const value_type R( 28.0 ); + const value_type b( value_type( 8.0 ) / value_type( 3.0 ) ); + + dxdt[0] = sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = -b * x[2] + x[0] * x[1]; +} + +struct push_back_time +{ + std::vector< double >& m_times; + + push_back_time( std::vector< double > × ) + : m_times( times ) { } + + void operator()( const state_type &x , double t ) + { + m_times.push_back( t ); + } +}; + +BOOST_AUTO_TEST_SUITE( integrate_times_test ) + +BOOST_AUTO_TEST_CASE( test_integrate_times ) +{ + + state_type x( 3 ); + x[0] = x[1] = x[2] = 10.0; + + const value_type dt = 0.03; + + std::vector< double > times; + + std::cout << "test rk4 stepper" << std::endl; + + // simple stepper + integrate_times( runge_kutta4< state_type >() , lorenz , x , boost::counting_iterator<int>(0) , boost::counting_iterator<int>(10) , + dt , push_back_time( times ) ); + + for( int i=0 ; i<10 ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_EQUAL( times[i] , static_cast<double>(i) ); + times.clear(); + + std::cout << "test dopri5 stepper" << std::endl; + + // controlled stepper + integrate_times( controlled_runge_kutta< runge_kutta_dopri5< state_type > >() , lorenz , x , + boost::counting_iterator<int>(0) , boost::counting_iterator<int>(10) , + dt , push_back_time( times ) ); + + for( int i=0 ; i<10 ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_EQUAL( times[i] , static_cast<double>(i) ); + times.clear(); + + std::cout << "test BS stepper" << std::endl; + + //another controlled stepper + integrate_times( bulirsch_stoer< state_type >() , lorenz , x , + boost::counting_iterator<int>(0) , boost::counting_iterator<int>(10) , + dt , push_back_time( times ) ); + + for( int i=0 ; i<10 ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_EQUAL( times[i] , static_cast<double>(i) ); + times.clear(); + + std::cout << "test dense_out stepper" << std::endl; + + // dense output stepper + integrate_times( dense_output_runge_kutta< controlled_runge_kutta< runge_kutta_dopri5< state_type > > >() , + lorenz , x , + boost::counting_iterator<int>(0) , boost::counting_iterator<int>(10) , + dt , push_back_time( times ) ); + + for( int i=0 ; i<10 ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_EQUAL( times[i] , static_cast<double>(i) ); + + std::cout << "test BS_do stepper" << std::endl; + + integrate_times( bulirsch_stoer_dense_out< state_type >() , lorenz , x , + boost::counting_iterator<int>(0) , boost::counting_iterator<int>(10) , + dt , push_back_time( times ) ); + + for( int i=0 ; i<10 ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_EQUAL( times[i] , static_cast<double>(i) ); + +} + + +BOOST_AUTO_TEST_CASE( test_integrate_times_ranges ) +{ + + state_type x( 3 ); + x[0] = x[1] = x[2] = 10.0; + + const value_type dt = 0.03; + + std::vector< double > times; + + // simple stepper + integrate_times( runge_kutta4< state_type >() , lorenz , x , + std::make_pair( boost::counting_iterator<int>(0) , boost::counting_iterator<int>(10) ) , + dt , push_back_time( times ) ); + + for( int i=0 ; i<10 ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_EQUAL( times[i] , static_cast<double>(i) ); + times.clear(); + + // controlled stepper + integrate_times( controlled_runge_kutta< runge_kutta_dopri5< state_type > >() , lorenz , x , + std::make_pair( boost::counting_iterator<int>(0) , boost::counting_iterator<int>(10) ) , + dt , push_back_time( times ) ); + + for( int i=0 ; i<10 ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_EQUAL( times[i] , static_cast<double>(i) ); + times.clear(); + + //another controlled stepper + integrate_times( bulirsch_stoer< state_type >() , lorenz , x , + std::make_pair( boost::counting_iterator<int>(0) , boost::counting_iterator<int>(10) ) , + dt , push_back_time( times ) ); + + for( int i=0 ; i<10 ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_EQUAL( times[i] , static_cast<double>(i) ); + times.clear(); + + + // dense output stepper + integrate_times( bulirsch_stoer_dense_out< state_type >() , lorenz , x , + std::make_pair( boost::counting_iterator<int>(0) , boost::counting_iterator<int>(10) ) , + dt , push_back_time( times ) ); + + for( int i=0 ; i<10 ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_EQUAL( times[i] , static_cast<double>(i) ); + +} + +BOOST_AUTO_TEST_CASE( test_integrate_times_overshoot ) +{ + state_type x( 3 ); + x[0] = x[1] = x[2] = 10.0; + double dt = -0.1; + + std::vector<double> times( 10 ); + for( int i=0 ; i<10 ; ++i ) + times[i] = 1.0-i*1.0/9.0; + + std::cout << "test rk4 stepper" << std::endl; + // simple stepper + std::vector<double> obs_times; + int steps = integrate_times( runge_kutta4< state_type >() , lorenz , x , + times.begin() , times.end() , + dt , push_back_time( obs_times ) ); +// different behavior for the iterator based integrate implementaton +#ifndef ODEINT_INTEGRATE_ITERATOR + BOOST_CHECK_EQUAL( steps , 18 ); // we really need 18 steps because dt and + // the difference of the observation times + // are so out of sync +#else + // iterator based implementation can only return the number of iteration steps + BOOST_CHECK_EQUAL( steps , 9 ); +#endif + for( int i=0 ; i<10 ; ++i ) + BOOST_CHECK_EQUAL( times[i] , obs_times[i] ); + + std::cout << "test rk_ck stepper" << std::endl; + // controlled stepper + obs_times.clear(); + integrate_times( controlled_runge_kutta< runge_kutta_cash_karp54< state_type > >() , lorenz , x , + times.begin() , times.end() , + dt , push_back_time( obs_times ) ); + for( int i=0 ; i<10 ; ++i ) + BOOST_CHECK_EQUAL( times[i] , obs_times[i] ); + + std::cout << "test dopri5 stepper" << std::endl; + // controlled stepper + obs_times.clear(); + integrate_times( dense_output_runge_kutta< controlled_runge_kutta< runge_kutta_dopri5< state_type > > >() , lorenz , x , + times.begin() , times.end() , + dt , push_back_time( obs_times ) ); + for( int i=0 ; i<10 ; ++i ) + BOOST_CHECK_EQUAL( times[i] , obs_times[i] ); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/integrators_symplectic.cpp b/src/boost/libs/numeric/odeint/test/integrators_symplectic.cpp new file mode 100644 index 000000000..2c2861950 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/integrators_symplectic.cpp @@ -0,0 +1,74 @@ +/* + [auto_generated] + libs/numeric/odeint/test/integrators_symplectic.cpp + + [begin_description] + tba. + [end_description] + + Copyright 2009-2013 Karsten Ahnert + Copyright 2009-2013 Mario Mulansky + + 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) + */ + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_iterators_symplectic + +#define BOOST_FUSION_INVOKE_MAX_ARITY 15 +#define BOOST_RESULT_OF_NUM_ARGS 15 +#define FUSION_MAX_VECTOR_SIZE 15 + +#include <cmath> + +#include <boost/test/unit_test.hpp> + +#ifndef ODEINT_INTEGRATE_ITERATOR +#include <boost/numeric/odeint/integrate/integrate_const.hpp> +#else +#include <boost/numeric/odeint/iterator/integrate/integrate_const.hpp> +#endif +#include <boost/numeric/odeint/stepper/symplectic_euler.hpp> +#include <boost/numeric/odeint/stepper/symplectic_rkn_sb3a_mclachlan.hpp> +#include <boost/numeric/odeint/stepper/symplectic_rkn_sb3a_m4_mclachlan.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; +namespace fusion = boost::fusion; + +typedef std::vector<double> container_type; + +struct harm_osc { + void operator()( const container_type &q , container_type &dpdt ) + { + dpdt[0] = -q[0]; + } +}; + +class complete_steppers : public mpl::vector< + symplectic_euler< container_type > + , symplectic_rkn_sb3a_mclachlan< container_type > + , symplectic_rkn_sb3a_m4_mclachlan< container_type > + > {}; + +BOOST_AUTO_TEST_SUITE( symplectic_steppers_test ) + + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_integrate_const , Stepper , complete_steppers ) +{ + container_type q( 1 , 1.0 ) , p( 1 , 0.0 ); + size_t steps = integrate_const( Stepper() , harm_osc() , + std::make_pair( boost::ref(q) , boost::ref(p) ) , + 0.0 , 1.0 , 0.1 ); + BOOST_CHECK( steps == 10 ); + BOOST_CHECK_CLOSE( q[0] , std::cos(1.0) , 100*std::pow( 0.1 , Stepper::order_value ) ); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/is_pair.cpp b/src/boost/libs/numeric/odeint/test/is_pair.cpp new file mode 100644 index 000000000..bf3bc35b0 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/is_pair.cpp @@ -0,0 +1,49 @@ +/* + [auto_generated] + libs/numeric/odeint/test/is_pair.cpp + + [begin_description] + This file tests the is_pair meta-function. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011-2012 Mario Mulansky + + 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) +*/ + +#define BOOST_TEST_MODULE odeint_is_pair + +#include <utility> + +#include <boost/test/unit_test.hpp> +#include <boost/static_assert.hpp> + +#include <boost/numeric/odeint/util/is_pair.hpp> + +using namespace boost::numeric::odeint; + + + +BOOST_AUTO_TEST_SUITE( is_pair_test ) + +BOOST_AUTO_TEST_CASE( test_is_pair ) +{ + typedef std::pair< int , int > type1; + typedef std::pair< int& , int > type2; + typedef std::pair< int , int& > type3; + typedef std::pair< int& , int& > type4; + typedef std::pair< const int , int > type5; + typedef std::pair< const int& , int > type6; + + BOOST_STATIC_ASSERT(( is_pair< type1 >::value )); + BOOST_STATIC_ASSERT(( is_pair< type2 >::value )); + BOOST_STATIC_ASSERT(( is_pair< type3 >::value )); + BOOST_STATIC_ASSERT(( is_pair< type4 >::value )); + BOOST_STATIC_ASSERT(( is_pair< type5 >::value )); + BOOST_STATIC_ASSERT(( is_pair< type6 >::value )); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/is_resizeable.cpp b/src/boost/libs/numeric/odeint/test/is_resizeable.cpp new file mode 100644 index 000000000..cb8e9c1c7 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/is_resizeable.cpp @@ -0,0 +1,116 @@ +/* + [auto_generated] + libs/numeric/odeint/test/is_resizeable.cpp + + [begin_description] + This file tests is_resizeable meta-function of odeint. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2012 Mario Mulansky + + 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) + */ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_is_resizeable + +#include <vector> +#include <cmath> + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/util/is_resizeable.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/units/systems/si/length.hpp> +#include <boost/units/systems/si/time.hpp> +#include <boost/units/systems/si/velocity.hpp> +#include <boost/units/systems/si/acceleration.hpp> +#include <boost/units/systems/si/io.hpp> + + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +template< typename T > struct my_seq1 {}; +template< typename T > struct my_seq2 {}; + +namespace boost { namespace fusion { namespace traits { + + template< typename T > struct is_sequence< my_seq1< T > > : boost::true_type {}; + template< typename T > struct is_sequence< my_seq2< T > > : boost::true_type {}; +} } } // boost::fusion::traits + +namespace boost { namespace numeric { namespace odeint { + + template< typename T > + struct is_resizeable< my_seq2< T > > : boost::true_type {}; + +} } } // boost::numeric::odeint + + + +BOOST_AUTO_TEST_CASE( test_vector ) +{ + BOOST_CHECK( is_resizeable< std::vector< int > >::value ); +} + +BOOST_AUTO_TEST_CASE( test_double ) +{ + BOOST_CHECK( !( is_resizeable< double >::value ) ); +} + +BOOST_AUTO_TEST_CASE( test_fusion_vector_of_vector ) +{ + typedef boost::fusion::vector< std::vector< double > , std::vector< double > > state_type; + BOOST_CHECK( is_resizeable< state_type >::value ); +} + +BOOST_AUTO_TEST_CASE( test_fusion_vector_of_double ) +{ + typedef boost::fusion::vector< double , double > state_type; + BOOST_CHECK( !( is_resizeable< state_type >::value ) ); +} + +BOOST_AUTO_TEST_CASE( test_fusion_vector_mixed1 ) +{ + typedef boost::fusion::vector< double , std::vector< double > > state_type; + BOOST_CHECK( is_resizeable< state_type >::value); +} + +BOOST_AUTO_TEST_CASE( test_fusion_vector_mixed2 ) +{ + typedef boost::fusion::vector< std::vector< double > , double > state_type; + BOOST_CHECK( is_resizeable< state_type >::value ); +} + +BOOST_AUTO_TEST_CASE( test_fusion_quantity_sequence ) +{ + namespace units = boost::units; + namespace si = boost::units::si; + + typedef double value_type; + typedef units::quantity< si::time , value_type > time_type; + typedef units::quantity< si::length , value_type > length_type; + typedef units::quantity< si::velocity , value_type > velocity_type; + typedef boost::fusion::vector< length_type , velocity_type > state_type; + + BOOST_CHECK( !( is_resizeable< state_type >::value ) ); +} + +BOOST_AUTO_TEST_CASE( test_my_seq1 ) +{ + BOOST_CHECK( !is_resizeable< my_seq1< double > >::value ); +} + +BOOST_AUTO_TEST_CASE( test_my_seq2 ) +{ + BOOST_CHECK( is_resizeable< my_seq2< double > >::value ); +}
\ No newline at end of file diff --git a/src/boost/libs/numeric/odeint/test/multi_array.cpp b/src/boost/libs/numeric/odeint/test/multi_array.cpp new file mode 100644 index 000000000..67b7f964d --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/multi_array.cpp @@ -0,0 +1,211 @@ +/* + [auto_generated] + libs/numeric/odeint/test/multi_array.cpp + + [begin_description] + tba. + [end_description] + + Copyright 2009-2012 Karsten Ahnert + Copyright 2009-2012 Mario Mulansky + + 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) + */ + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_multi_array + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/algebra/multi_array_algebra.hpp> +#include <boost/numeric/odeint/util/multi_array_adaption.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/integrate/integrate_const.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/generation.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef boost::multi_array< double , 1 > vector_type; +typedef boost::multi_array< double , 2 > matrix_type; +typedef boost::multi_array< double , 3 > tensor_type; + + +BOOST_AUTO_TEST_SUITE( multi_array_test ) + +BOOST_AUTO_TEST_CASE( test_resizeable ) +{ + BOOST_CHECK( is_resizeable< vector_type >::value ); + BOOST_CHECK( is_resizeable< matrix_type >::value ); + BOOST_CHECK( is_resizeable< tensor_type >::value ); +} + +BOOST_AUTO_TEST_CASE( test_same_size_vector1 ) +{ + vector_type v1( boost::extents[12] ); + vector_type v2( boost::extents[12] ); + BOOST_CHECK( same_size( v1 , v2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_same_size_vector2 ) +{ + vector_type v1( boost::extents[12] ); + vector_type v2( boost::extents[13] ); + BOOST_CHECK( !same_size( v1 , v2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_same_size_vector3 ) +{ + vector_type v1( boost::extents[12] ); + vector_type v2( boost::extents[vector_type::extent_range(-1,11)] ); + BOOST_CHECK( !same_size( v1 , v2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_same_size_vector4 ) +{ + vector_type v1( boost::extents[12] ); + vector_type v2( boost::extents[vector_type::extent_range(-1,10)] ); + BOOST_CHECK( !same_size( v1 , v2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_same_size_vector5 ) +{ + vector_type v1( boost::extents[vector_type::extent_range(-1,10)] ); + vector_type v2( boost::extents[vector_type::extent_range(-1,10)] ); + BOOST_CHECK( same_size( v1 , v2 ) ); +} + + + +BOOST_AUTO_TEST_CASE( test_same_size_matrix1 ) +{ + matrix_type m1( boost::extents[12][4] ); + matrix_type m2( boost::extents[12][4] ); + BOOST_CHECK( same_size( m1 , m2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_same_size_matrix2 ) +{ + matrix_type m1( boost::extents[12][4] ); + matrix_type m2( boost::extents[12][3] ); + BOOST_CHECK( !same_size( m1 , m2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_same_size_matrix3 ) +{ + matrix_type m1( boost::extents[12][matrix_type::extent_range(-1,2)] ); + matrix_type m2( boost::extents[12][3] ); + BOOST_CHECK( !same_size( m1 , m2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_same_size_matrix4 ) +{ + matrix_type m1( boost::extents[12][matrix_type::extent_range(-1,1)] ); + matrix_type m2( boost::extents[12][3] ); + BOOST_CHECK( !same_size( m1 , m2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_same_size_tensor1 ) +{ + tensor_type t1( boost::extents[ tensor_type::extent_range( -2 , 9 ) ] + [ tensor_type::extent_range( 5 , 11 ) ] + [ tensor_type::extent_range( -1 , 2 ) ] ); + tensor_type t2( boost::extents[ tensor_type::extent_range( 2 , 13 ) ] + [ tensor_type::extent_range( -1 , 5 ) ] + [ tensor_type::extent_range( 1 , 4 ) ] ); + BOOST_CHECK( !same_size( t1 , t2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_same_size_tensor2 ) +{ + tensor_type t1( boost::extents[ tensor_type::extent_range( -2 , 9 ) ] + [ tensor_type::extent_range( 5 , 11 ) ] + [ tensor_type::extent_range( -1 , 2 ) ] ); + tensor_type t2( boost::extents[ tensor_type::extent_range( -2 , 9 ) ] + [ tensor_type::extent_range( 5 , 11 ) ] + [ tensor_type::extent_range( -1 , 2 ) ] ); + BOOST_CHECK( same_size( t1 , t2 ) ); +} + + +// Tests for tensor_type + +BOOST_AUTO_TEST_CASE( test_resize_vector1 ) +{ + vector_type v1( boost::extents[4] ); + vector_type v2; + resize( v2 , v1 ); + BOOST_CHECK( same_size( v1 , v2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_resize_vector2 ) +{ + vector_type v1( boost::extents[ vector_type::extent_range( -2 , 9 ) ] ); + vector_type v2; + resize( v2 , v1 ); + BOOST_CHECK( same_size( v1 , v2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_resize_vector3 ) +{ + vector_type v1( boost::extents[ vector_type::extent_range( -2 , 9 ) ] ); + vector_type v2( boost::extents[ vector_type::extent_range( 2 , 9 ) ] ); + BOOST_CHECK( !same_size( v1 , v2 ) ); + resize( v2 , v1 ); + BOOST_CHECK( same_size( v1 , v2 ) ); +} + +struct mult4 +{ + void operator()( double &a , double const &b ) const + { + a = b * 4.0; + } +}; + +BOOST_AUTO_TEST_CASE( test_for_each2_vector ) +{ + vector_type v1( boost::extents[ vector_type::extent_range( -2 , 9 ) ] ); + vector_type v2( boost::extents[ vector_type::extent_range( 2 , 13 ) ] ); + for( int i=-2 ; i<9 ; ++i ) + v1[i] = i * 2; + multi_array_algebra::for_each2( v2 , v1 , mult4() ); + for( int i=2 ; i<13 ; ++i ) + BOOST_CHECK_EQUAL( v2[i] , v1[i-4]*4.0 ); +} + +struct vector_ode +{ + const static size_t n = 128; + void operator()( const vector_type &x , vector_type &dxdt , double t ) const + { + dxdt[-1] = x[n] - 2.0 * x[-1] + x[0]; + for( size_t i=0 ; i<n ; ++i ) + dxdt[i] = x[i-1] - 2.0 * x[i] + x[i+1]; + dxdt[n] = x[-1] - 2.0 * x[n] + x[n-1]; + } +}; + + +BOOST_AUTO_TEST_CASE( test_rk4_vector ) +{ + vector_type v1( boost::extents[ vector_type::extent_range( -1 , vector_ode::n+1 ) ] ); + integrate_const( runge_kutta4< vector_type >() , vector_ode() , v1 , 0.0 , 1.0 , 0.01 ); +} + +BOOST_AUTO_TEST_CASE( test_dopri5_vector ) +{ + vector_type v1( boost::extents[ vector_type::extent_range( -1 , vector_ode::n+1 ) ] ); + integrate_const( make_dense_output( 1.0e-6 , 1.0e-6 , runge_kutta_dopri5< vector_type >() ) , vector_ode() , v1 , 0.0 , 1.0 , 0.01 ); +} + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/n_step_iterator.cpp b/src/boost/libs/numeric/odeint/test/n_step_iterator.cpp new file mode 100644 index 000000000..bebcf6dab --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/n_step_iterator.cpp @@ -0,0 +1,225 @@ +/* + [auto_generated] + libs/numeric/odeint/test/n_step_iterator.cpp + + [begin_description] + This file tests the n-step iterator. + [end_description] + + Copyright 2009-2013 Karsten Ahnert + Copyright 2009-2013 Mario Mulansky + + 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) + */ + + +#define BOOST_TEST_MODULE odeint_n_step_iterator + +#include <iterator> +#include <algorithm> +#include <vector> + +#include <boost/numeric/odeint/config.hpp> +#include <boost/array.hpp> +#include <boost/range/algorithm/for_each.hpp> +#include <boost/range/algorithm/copy.hpp> +#include <boost/mpl/vector.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> + +#include <boost/numeric/odeint/iterator/n_step_iterator.hpp> +#include "dummy_steppers.hpp" +#include "dummy_odes.hpp" +#include "dummy_observers.hpp" + +namespace mpl = boost::mpl; +using namespace boost::numeric::odeint; + +typedef dummy_stepper::state_type state_type; +typedef dummy_stepper::value_type value_type; + + +BOOST_AUTO_TEST_SUITE( n_step_iterator_test ) + +typedef mpl::vector< + dummy_stepper + , dummy_dense_output_stepper + > dummy_steppers; + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_stepper_iterator , Stepper , dummy_steppers ) +{ + typedef n_step_iterator< Stepper , empty_system , state_type > iterator_type; + state_type x = {{ 1.0 }}; + iterator_type iter1 = iterator_type( Stepper() , empty_system() , x , 0.0 , 0.1 , 10 ); + iterator_type iter2 = iter1; + BOOST_CHECK_EQUAL( &(*iter1) , &(*iter2) ); + BOOST_CHECK_EQUAL( &(*iter1) , &x ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( assignment_stepper_iterator , Stepper , dummy_steppers ) +{ + typedef n_step_iterator< Stepper , empty_system , state_type > iterator_type; + state_type x1 = {{ 1.0 }} , x2 = {{ 2.0 }}; + iterator_type iter1 = iterator_type( Stepper() , empty_system() , x1 , 0.0 , 0.1 , 10 ); + iterator_type iter2 = iterator_type( Stepper() , empty_system() , x2 , 0.0 , 0.2 , 10 ); + BOOST_CHECK_EQUAL( &(*iter1) , &x1 ); + BOOST_CHECK_EQUAL( &(*iter2) , &x2 ); + BOOST_CHECK( !iter1.same( iter2 ) ); + iter2 = iter1; + BOOST_CHECK_EQUAL( &(*iter1) , &x1 ); + BOOST_CHECK_EQUAL( &(*iter2) , &x1 ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_iterator_factory , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_n_step_iterator_begin( stepper , boost::ref( system ) , x , 0.0 , 0.1 , 10 ) , + make_n_step_iterator_end( stepper , boost::ref( system ) , x ) , + dummy_observer() ); + + // dummy_steppers just add 0.25 at each step, the above for_each leads to 10 do_step calls so x should be 3.5 + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_range , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_n_step_range( stepper , boost::ref( system ) , x , 0.0 , 0.1 , 10 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_iterator_with_reference_wrapper_factory , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_n_step_iterator_begin( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 0.1 , 10 ) , + make_n_step_iterator_end( boost::ref( stepper ) , boost::ref( system ) , x ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_range_with_reference_wrapper , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_n_step_range( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 0.1 , 10 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( transitivity1 , Stepper , dummy_steppers ) +{ + typedef n_step_iterator< Stepper , empty_system , state_type > stepper_iterator; + + state_type x = {{ 1.0 }}; + stepper_iterator first1( Stepper() , empty_system() , x , 2.5 , 0.1 , 0 ); + stepper_iterator last1( Stepper() , empty_system() , x ); + stepper_iterator last2( Stepper() , empty_system() , x ); + + BOOST_CHECK( last1 == last2 ); + BOOST_CHECK( first1 != last1 ); + BOOST_CHECK( ++first1 == last1 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm , Stepper , dummy_steppers ) +{ + typedef n_step_iterator< Stepper , empty_system , state_type > stepper_iterator; + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + stepper_iterator first( Stepper() , empty_system() , x , 0.0 , 0.1 , 3 ); + stepper_iterator last( Stepper() , empty_system() , x ); + + std::copy( first , last , std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-14 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-14 ); // the iterator should not iterate over the end +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_negative_time_step , Stepper , dummy_steppers ) +{ + typedef n_step_iterator< Stepper , empty_system , state_type > stepper_iterator; + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + stepper_iterator first( Stepper() , empty_system() , x , 0.3 , -0.1 , 3 ); + stepper_iterator last( Stepper() , empty_system() , x ); + + std::copy( first , last , std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-14 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-14 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + std::copy( make_n_step_iterator_begin( Stepper() , empty_system() , x , 0.0 , 0.1 , 3 ) , + make_n_step_iterator_end( Stepper() , empty_system() , x ) , + std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-14 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-14 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_range_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + boost::range::copy( make_n_step_range( Stepper() , empty_system() , x , 0.0 , 0.1 , 3 ) , + std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-14 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-14 ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/n_step_time_iterator.cpp b/src/boost/libs/numeric/odeint/test/n_step_time_iterator.cpp new file mode 100644 index 000000000..fbce86767 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/n_step_time_iterator.cpp @@ -0,0 +1,213 @@ +/* + [auto_generated] + libs/numeric/odeint/test/n_step_time_iterator.cpp + + [begin_description] + This file tests the n-step time iterator. + [end_description] + + Copyright 2009-2013 Karsten Ahnert + Copyright 2009-2013 Mario Mulansky + + 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) + */ + + +#define BOOST_TEST_MODULE odeint_n_step_time_iterator + +#include <iterator> +#include <algorithm> +#include <vector> + +#include <boost/numeric/odeint/config.hpp> +#include <boost/array.hpp> +#include <boost/range/algorithm/copy.hpp> +#include <boost/range/algorithm/for_each.hpp> +#include <boost/mpl/vector.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> + +#include <boost/numeric/odeint/iterator/n_step_time_iterator.hpp> +#include "dummy_steppers.hpp" +#include "dummy_odes.hpp" +#include "dummy_observers.hpp" + +namespace mpl = boost::mpl; +using namespace boost::numeric::odeint; + +typedef dummy_stepper::state_type state_type; +typedef dummy_stepper::value_type value_type; +typedef dummy_stepper::time_type time_type; +typedef std::vector< std::pair< state_type , time_type > > result_vector; + +BOOST_AUTO_TEST_SUITE( n_step_time_iterator_test ) + +typedef mpl::vector< + dummy_stepper + , dummy_dense_output_stepper + > dummy_steppers; + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_stepper_iterator , Stepper , dummy_steppers ) +{ + typedef n_step_time_iterator< Stepper , empty_system , state_type > iterator_type; + state_type x = {{ 1.0 }}; + iterator_type iter1 = iterator_type( Stepper() , empty_system() , x , 0.0 , 0.1 , 10 ); + iterator_type iter2 = iter1; + BOOST_CHECK_EQUAL( &( iter1->first ) , &( iter2->first ) ); + BOOST_CHECK_EQUAL( &( iter1->first ) , &x ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( assignment_stepper_iterator , Stepper , dummy_steppers ) +{ + typedef n_step_time_iterator< Stepper , empty_system , state_type > iterator_type; + state_type x1 = {{ 1.0 }} , x2 = {{ 2.0 }}; + iterator_type iter1 = iterator_type( Stepper() , empty_system() , x1 , 0.0 , 0.1 , 10 ); + iterator_type iter2 = iterator_type( Stepper() , empty_system() , x2 , 0.0 , 0.2 , 10 ); + BOOST_CHECK_EQUAL( &( iter1->first ) , &x1 ); + BOOST_CHECK_EQUAL( &( iter2->first ) , &x2 ); + BOOST_CHECK( !iter1.same( iter2 ) ); + iter2 = iter1; + BOOST_CHECK_EQUAL( &( iter1->first ) , &x1 ); + BOOST_CHECK_EQUAL( &( iter2->first ) , &x1 ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_iterator_factory , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_n_step_time_iterator_begin( stepper , boost::ref( system ) , x , 0.0 , 0.1 , 10 ) , + make_n_step_time_iterator_end( stepper , boost::ref( system ) , x ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_range , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_n_step_time_range( stepper , boost::ref( system ) , x , 0.0 , 0.1 , 10 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_iterator_with_reference_wrapper_factory , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_n_step_time_iterator_begin( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 0.1 , 10 ) , + make_n_step_time_iterator_end( boost::ref( stepper ) , boost::ref( system ) , x ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_range_with_reference_wrapper , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_n_step_time_range( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 0.1 , 10 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( transitivity1 , Stepper , dummy_steppers ) +{ + typedef n_step_time_iterator< Stepper , empty_system , state_type > stepper_iterator; + + state_type x = {{ 1.0 }}; + stepper_iterator first1( Stepper() , empty_system() , x , 0.0 , 0.1 , 0 ); + stepper_iterator last1( Stepper() , empty_system() , x ); + stepper_iterator last2( Stepper() , empty_system() , x ); + + BOOST_CHECK( last1 == last2 ); + BOOST_CHECK( first1 != last1 ); + BOOST_CHECK( ++first1 == last1 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm , Stepper , dummy_steppers ) +{ + typedef n_step_time_iterator< Stepper , empty_system , state_type > stepper_iterator; + state_type x = {{ 1.0 }}; + result_vector res; + stepper_iterator first( Stepper() , empty_system() , x , 0.0 , 0.1 , 3 ); + stepper_iterator last( Stepper() , empty_system() , x ); + + std::copy( first , last , std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[0].second , 0.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].second , 0.1 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].second , 0.2 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].second , 0.3 , 1.0e-13 ); + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + result_vector res; + std::copy( make_n_step_time_iterator_begin( Stepper() , empty_system() , x , 0.0 , 0.1 , 3 ) , + make_n_step_time_iterator_end( Stepper() , empty_system() , x ) , + std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[0].second , 0.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].second , 0.1 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].second , 0.2 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].second , 0.3 , 1.0e-13 ); + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_range_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + result_vector res; + boost::range::copy( make_n_step_time_range( Stepper() , empty_system() , x , 0.0 , 0.1 , 3 ) , + std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[0].second , 0.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].second , 0.1 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].second , 0.2 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].second , 0.3 , 1.0e-13 ); + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/numeric/Jamfile.v2 b/src/boost/libs/numeric/odeint/test/numeric/Jamfile.v2 new file mode 100644 index 000000000..a4643f6a5 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/numeric/Jamfile.v2 @@ -0,0 +1,36 @@ +# Copyright 2012 Karsten Ahnert +# Copyright 2012 Mario Mulansky +# 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) + +# bring in rules for testing + + +import testing ; + +use-project boost : $(BOOST_ROOT) ; + +project + : requirements + <library>/boost/test//boost_unit_test_framework + <define>BOOST_ALL_NO_LIB=1 + <include>../../include + <link>static + <toolset>clang:<cxxflags>-Wno-unused-variable + +# <cxxflags>-D_SCL_SECURE_NO_WARNINGS + ; + +test-suite "odeint" + : + [ run runge_kutta.cpp ] + [ run symplectic.cpp ] + [ run rosenbrock.cpp ] + [ run adams_bashforth.cpp ] + [ run adams_bashforth_moulton.cpp ] + [ run adaptive_adams_bashforth_moulton.cpp ] + [ run abm_time_dependent.cpp ] + [ run order_quadrature_formula.cpp ] + [ run velocity_verlet.cpp ] + : <testing.launcher>valgrind + ; diff --git a/src/boost/libs/numeric/odeint/test/numeric/abm_time_dependent.cpp b/src/boost/libs/numeric/odeint/test/numeric/abm_time_dependent.cpp new file mode 100644 index 000000000..019a17d6c --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/numeric/abm_time_dependent.cpp @@ -0,0 +1,85 @@ +/* Boost numeric test of the adams-bashforth-moulton steppers test file + + Copyright 2013 Karsten Ahnert + Copyright 2013-2015 Mario Mulansky + + 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) +*/ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE numeric_adams_bashforth_moulton + +#include <iostream> +#include <cmath> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +typedef double value_type; + +typedef value_type state_type; + + +// simple time-dependent rhs, analytic solution x = 0.5*t^2 +struct simple_rhs +{ + void operator()( const state_type& x , state_type &dxdt , const double t ) const + { + dxdt = t; + } +}; + +BOOST_AUTO_TEST_SUITE( numeric_abm_time_dependent_test ) + + +/* generic test for all adams bashforth moulton steppers */ +template< class Stepper > +struct perform_abm_time_dependent_test +{ + void operator()( void ) + { + Stepper stepper; + const int o = stepper.order()+1; //order of the error is order of approximation + 1 + + const state_type x0 = 0.0; + state_type x1 = x0; + double t = 0.0; + double dt = 0.1; + const int steps = 10; + + integrate_n_steps( boost::ref(stepper) , simple_rhs(), x1 , t , dt , steps ); + BOOST_CHECK_LT( std::abs( 0.5 - x1 ) , std::pow( dt , o ) ); + } +}; + +typedef mpl::vector< + adams_bashforth_moulton< 2 , state_type > , + adams_bashforth_moulton< 3 , state_type > , + adams_bashforth_moulton< 4 , state_type > , + adams_bashforth_moulton< 5 , state_type > , + adams_bashforth_moulton< 6 , state_type > , + adams_bashforth_moulton< 7 , state_type > , + adams_bashforth_moulton< 8 , state_type > + > adams_bashforth_moulton_steppers; + +BOOST_AUTO_TEST_CASE_TEMPLATE( abm_time_dependent_test , Stepper, adams_bashforth_moulton_steppers ) +{ + perform_abm_time_dependent_test< Stepper > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/numeric/adams_bashforth.cpp b/src/boost/libs/numeric/odeint/test/numeric/adams_bashforth.cpp new file mode 100644 index 000000000..ca8a6cee9 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/numeric/adams_bashforth.cpp @@ -0,0 +1,117 @@ +/* Boost numeric test of the adams-bashforth steppers test file + + Copyright 2013 Karsten Ahnert + Copyright 2013-2015 Mario Mulansky + + 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) +*/ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE numeric_adams_bashforth + +#include <iostream> +#include <cmath> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +typedef double value_type; + +typedef boost::array< double , 2 > state_type; + +// harmonic oscillator, analytic solution x[0] = sin( t ) +struct osc +{ + void operator()( const state_type &x , state_type &dxdt , const double t ) const + { + dxdt[0] = x[1]; + dxdt[1] = -x[0]; + } +}; + +BOOST_AUTO_TEST_SUITE( numeric_adams_bashforth_test ) + + +/* generic test for all adams bashforth steppers */ +template< class Stepper > +struct perform_adams_bashforth_test +{ + void operator()( void ) + { + Stepper stepper; + const int o = stepper.order()+1; //order of the error is order of approximation + 1 + + const state_type x0 = {{ 0.0 , 1.0 }}; + state_type x1 = x0; + double t = 0.0; + double dt = 0.2; + // initialization, does a number of steps already to fill internal buffer, t is increased + stepper.initialize( osc() , x1 , t , dt ); + double A = std::sqrt( x1[0]*x1[0] + x1[1]*x1[1] ); + double phi = std::asin(x1[0]/A) - t; + // do a number of steps to fill the buffer with results from adams bashforth + for( size_t n=0 ; n < stepper.steps ; ++n ) + { + stepper.do_step( osc() , x1 , t , dt ); + t += dt; + } + // now we do the actual step + stepper.do_step( osc() , x1 , t , dt ); + // only examine the error of the adams-bashforth step, not the initialization + const double f = 2.0 * std::abs( A*sin(t+dt+phi) - x1[0] ) / std::pow( dt , o ); // upper bound + + std::cout << o << " , " + << Stepper::initializing_stepper_type::order_value+1 << " , " + << f << std::endl; + + /* as long as we have errors above machine precision */ + while( f*std::pow( dt , o ) > 1E-16 ) + { + x1 = x0; + t = 0.0; + stepper.initialize( osc() , x1 , t , dt ); + A = std::sqrt( x1[0]*x1[0] + x1[1]*x1[1] ); + phi = std::asin(x1[0]/A) - t; + // now we do the actual step + stepper.do_step( osc() , x1 , t , dt ); + // only examine the error of the adams-bashforth step, not the initialization + std::cout << "Testing dt=" << dt << " , " << std::abs( A*sin(t+dt+phi) - x1[0] ) << std::endl; + BOOST_CHECK_LT( std::abs( A*sin(t+dt+phi) - x1[0] ) , f*std::pow( dt , o ) ); + dt *= 0.5; + } + } +}; + +typedef mpl::vector< + adams_bashforth< 2 , state_type > , + adams_bashforth< 3 , state_type > , + adams_bashforth< 4 , state_type > , + adams_bashforth< 5 , state_type > , + adams_bashforth< 6 , state_type > , + adams_bashforth< 7 , state_type > , + adams_bashforth< 8 , state_type > + > adams_bashforth_steppers; + +BOOST_AUTO_TEST_CASE_TEMPLATE( adams_bashforth_test , Stepper, adams_bashforth_steppers ) +{ + perform_adams_bashforth_test< Stepper > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/numeric/adams_bashforth_moulton.cpp b/src/boost/libs/numeric/odeint/test/numeric/adams_bashforth_moulton.cpp new file mode 100644 index 000000000..dea57182a --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/numeric/adams_bashforth_moulton.cpp @@ -0,0 +1,119 @@ +/* Boost numeric test of the adams-bashforth-moulton steppers test file + + Copyright 2013 Karsten Ahnert + Copyright 2013 Mario Mulansky + + 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) +*/ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE numeric_adams_bashforth_moulton + +#include <iostream> +#include <cmath> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +typedef double value_type; + +typedef boost::array< double , 2 > state_type; +typedef runge_kutta_fehlberg78<state_type> initializing_stepper; + +// harmonic oscillator, analytic solution x[0] = sin( t ) +struct osc +{ + void operator()( const state_type &x , state_type &dxdt , const double t ) const + { + dxdt[0] = x[1]; + dxdt[1] = -x[0]; + } +}; + +BOOST_AUTO_TEST_SUITE( numeric_adams_bashforth_moulton_test ) + + +/* generic test for all adams bashforth moulton steppers */ +template< class Stepper > +struct perform_adams_bashforth_moulton_test +{ + void operator()( void ) + { + Stepper stepper; + initializing_stepper init_stepper; + const int o = stepper.order()+1; //order of the error is order of approximation + 1 + + const state_type x0 = {{ 0.0 , 1.0 }}; + state_type x1 = x0; + double t = 0.0; + double dt = 0.25; + // initialization, does a number of steps already to fill internal buffer, t is increased + // we use the rk78 as initializing stepper + stepper.initialize( boost::ref(init_stepper) , osc() , x1 , t , dt ); + // do a number of steps to fill the buffer with results from adams bashforth + for( size_t n=0 ; n < stepper.steps ; ++n ) + { + stepper.do_step( osc() , x1 , t , dt ); + t += dt; + } + double A = std::sqrt( x1[0]*x1[0] + x1[1]*x1[1] ); + double phi = std::asin(x1[0]/A) - t; + // now we do the actual step + stepper.do_step( osc() , x1 , t , dt ); + // only examine the error of the adams-bashforth-moulton step, not the initialization + const double f = 2.0 * std::abs( A*sin(t+dt+phi) - x1[0] ) / std::pow( dt , o ); // upper bound + + std::cout << o << " , " << f << std::endl; + + /* as long as we have errors above machine precision */ + while( f*std::pow( dt , o ) > 1E-16 ) + { + x1 = x0; + t = 0.0; + stepper.initialize( boost::ref(init_stepper) , osc() , x1 , t , dt ); + A = std::sqrt( x1[0]*x1[0] + x1[1]*x1[1] ); + phi = std::asin(x1[0]/A) - t; + // now we do the actual step + stepper.do_step( osc() , x1 , t , dt ); + // only examine the error of the adams-bashforth-moulton step, not the initialization + std::cout << "Testing dt=" << dt << " , " << std::abs( A*sin(t+dt+phi) - x1[0] ) << std::endl; + BOOST_CHECK_LT( std::abs( A*sin(t+dt+phi) - x1[0] ) , f*std::pow( dt , o ) ); + dt *= 0.5; + } + } +}; + +typedef mpl::vector< + adams_bashforth_moulton< 1 , state_type > , + adams_bashforth_moulton< 2 , state_type > , + adams_bashforth_moulton< 3 , state_type > , + adams_bashforth_moulton< 4 , state_type > , + adams_bashforth_moulton< 5 , state_type > , + adams_bashforth_moulton< 6 , state_type > , + adams_bashforth_moulton< 7 , state_type > , + adams_bashforth_moulton< 8 , state_type > + > adams_bashforth_moulton_steppers; + +BOOST_AUTO_TEST_CASE_TEMPLATE( adams_bashforth_moulton_test , Stepper, adams_bashforth_moulton_steppers ) +{ + perform_adams_bashforth_moulton_test< Stepper > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/numeric/adaptive_adams_bashforth_moulton.cpp b/src/boost/libs/numeric/odeint/test/numeric/adaptive_adams_bashforth_moulton.cpp new file mode 100644 index 000000000..0932dd1dd --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/numeric/adaptive_adams_bashforth_moulton.cpp @@ -0,0 +1,113 @@ +/* Boost numeric test of the adams-bashforth steppers test file + + Copyright 2013 Karsten Ahnert + Copyright 2013-2015 Mario Mulansky + + 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) +*/ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE numeric_adaptive_adams_bashforth_moulton + +#include <iostream> +#include <cmath> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +typedef double value_type; + +typedef boost::array< double , 2 > state_type; +typedef runge_kutta_fehlberg78<state_type> initializing_stepper; + +// harmonic oscillator, analytic solution x[0] = sin( t ) +struct osc +{ + void operator()( const state_type &x , state_type &dxdt , const double t ) const + { + dxdt[0] = x[1]; + dxdt[1] = -x[0]; + } +}; + +BOOST_AUTO_TEST_SUITE( numeric_adaptive_adams_bashforth_moulton_test ) + + +/* generic test for all adams bashforth steppers */ +template< class Stepper > +struct perform_adaptive_adams_bashforth_moulton_test +{ + void operator()( void ) + { + Stepper stepper; + initializing_stepper init_stepper; + + const int o = stepper.order()+1; //order of the error is order of approximation + 1 + + const state_type x0 = {{ 0.0 , 1.0 }}; + state_type x1 = x0; + double t = 0.0; + double dt = 0.25; + // initialization, does a number of steps to self-start the stepper with a small stepsize + stepper.initialize( init_stepper, osc() , x1 , t , dt); + double A = std::sqrt( x1[0]*x1[0] + x1[1]*x1[1] ); + double phi = std::asin(x1[0]/A) - t; + + // now we do the actual step + stepper.do_step( osc() , x1 , t , dt ); + // only examine the error of the adams-bashforth step, not the initialization + const double f = 2.0 * std::abs( A*sin(t+dt+phi) - x1[0] ) / std::pow( dt , o ); // upper bound + + std::cout << o << " , " << f << std::endl; + + /* as long as we have errors above machine precision */ + while( f*std::pow( dt , o ) > 1E-16 ) + { + x1 = x0; + t = 0.0; + stepper.initialize( init_stepper, osc() , x1 , t , dt ); + A = std::sqrt( x1[0]*x1[0] + x1[1]*x1[1] ); + phi = std::asin(x1[0]/A) - t; + // now we do the actual step + stepper.do_step( osc() , x1 , t , dt ); + stepper.reset(); + // only examine the error of the adams-bashforth step, not the initialization + std::cout << "Testing dt=" << dt << " , " << std::abs( A*sin(t+dt+phi) - x1[0] ) << std::endl; + BOOST_CHECK_LT( std::abs( A*sin(t+dt+phi) - x1[0] ) , f*std::pow( dt , o ) ); + dt *= 0.5; + } + } +}; + +typedef mpl::vector< + adaptive_adams_bashforth_moulton< 2 , state_type > , + adaptive_adams_bashforth_moulton< 3 , state_type > , + adaptive_adams_bashforth_moulton< 4 , state_type > , + adaptive_adams_bashforth_moulton< 5 , state_type > , + adaptive_adams_bashforth_moulton< 6 , state_type > , + adaptive_adams_bashforth_moulton< 7 , state_type > + > adaptive_adams_bashforth_moulton_steppers; + +BOOST_AUTO_TEST_CASE_TEMPLATE( adaptive_adams_bashforth_moulton_test , Stepper, adaptive_adams_bashforth_moulton_steppers ) +{ + perform_adaptive_adams_bashforth_moulton_test< Stepper > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/numeric/order_quadrature_formula.cpp b/src/boost/libs/numeric/odeint/test/numeric/order_quadrature_formula.cpp new file mode 100644 index 000000000..cefab4dae --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/numeric/order_quadrature_formula.cpp @@ -0,0 +1,195 @@ +/* Boost numeric test for orders of quadrature formulas test file + + Copyright 2015 Gregor de Cillia + Copyright 2015 Mario Mulansky <mario.mulansky@gmx.net> + + 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) +*/ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> + +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE order_quadrature_formula + +#include <iostream> +#include <cmath> + +#include "boost/format.hpp" + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint.hpp> + +#include <boost/numeric/ublas/vector.hpp> + +#include <boost/format.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +typedef double value_type; +typedef value_type time_type; +typedef value_type state_type; + +BOOST_AUTO_TEST_SUITE( order_of_convergence_test ) + +/* defines the simple monomial f(t) = (p+1) * t^p.*/ +struct monomial +{ + int power; + + monomial(int p = 0) : power( p ){}; + + void operator()( const state_type &x , state_type &dxdt , const time_type t ) + { + dxdt = ( 1.0 + power ) * pow( t, power ); + } +}; + + +/* generic test for all steppers that support integrate_const */ +template< class Stepper > +struct stepper_order_test +{ + void operator()( int steps = 1 ) + { + const int estimated_order = estimate_order( steps ); + const int defined_order = Stepper::order_value; + + std::cout << boost::format( "%-20i%-20i\n" ) + % estimated_order % defined_order; + + BOOST_REQUIRE_EQUAL( estimated_order, defined_order ); + } + + /* + the order of the stepper is estimated by trying to solve the ODE + x'(t) = (p+1) * t^p + until the errors are too big to be justified by finite precision. + the first value p for which the problem is *not* solved within the + finite precision tolerance is the estimate for the order of the scheme. + */ + int estimate_order( int steps ) + { + const double dt = 1.0/steps; + const double tolerance = steps*1E-15; + int p; + for( p = 0; true; p++ ) + { + // begin with x'(t) = t^0 = 1 + // => x (t) = t + // then use x'(t) = 2*t^1 + // => x (t) = t^2 + // ... + state_type x = 0.0; + + double t = integrate_n_steps( Stepper(), monomial( p ), x, 0.0, dt, + steps ); + if( fabs( x - pow( t, ( 1.0 + p ) ) ) > tolerance ) + break; + } + // the smallest power p for which the test failed is the estimated order, + // as the solution for this power is x(t) = t^{p+1} + return p; + } +}; + + +typedef mpl::vector< + euler< state_type > , + modified_midpoint< state_type > , + runge_kutta4< state_type > , + runge_kutta4_classic< state_type > , + runge_kutta_cash_karp54_classic< state_type > , + runge_kutta_cash_karp54< state_type > , + runge_kutta_dopri5< state_type > , + runge_kutta_fehlberg78< state_type > + > runge_kutta_steppers; + +typedef mpl::vector< + adams_bashforth< 2, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, runge_kutta_fehlberg78< state_type > >, + adams_bashforth< 3, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, runge_kutta_fehlberg78< state_type > >, + adams_bashforth< 4, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, runge_kutta_fehlberg78< state_type > >, + adams_bashforth< 5, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, runge_kutta_fehlberg78< state_type > >, + adams_bashforth< 6, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, runge_kutta_fehlberg78< state_type > >, + adams_bashforth< 7, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, runge_kutta_fehlberg78< state_type > >, + adams_bashforth< 8, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, runge_kutta_fehlberg78< state_type > > + > ab_steppers; + + +typedef mpl::vector< + adams_bashforth_moulton< 2, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, + runge_kutta_fehlberg78< state_type > >, + adams_bashforth_moulton< 3, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, + runge_kutta_fehlberg78< state_type > >, + adams_bashforth_moulton< 4, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, + runge_kutta_fehlberg78< state_type > >, + adams_bashforth_moulton< 5, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, + runge_kutta_fehlberg78< state_type > >, + adams_bashforth_moulton< 6, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, + runge_kutta_fehlberg78< state_type > >, + adams_bashforth_moulton< 7, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, + runge_kutta_fehlberg78< state_type > >, + adams_bashforth_moulton< 8, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, + runge_kutta_fehlberg78< state_type > > + > abm_steppers; + + +BOOST_AUTO_TEST_CASE_TEMPLATE( runge_kutta_test , Stepper, runge_kutta_steppers ) +{ + stepper_order_test< Stepper > tester; + tester(10); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( adams_bashforth_test , Stepper, ab_steppers ) +{ + stepper_order_test< Stepper > tester; + tester(16); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( adams_bashforth_moultion_test , Stepper, abm_steppers ) +{ + stepper_order_test< Stepper > tester; + tester(16); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/numeric/rosenbrock.cpp b/src/boost/libs/numeric/odeint/test/numeric/rosenbrock.cpp new file mode 100644 index 000000000..2b6a26788 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/numeric/rosenbrock.cpp @@ -0,0 +1,89 @@ +/* Boost numeric test of the rosenbrock4 stepper test file + + Copyright 2012 Karsten Ahnert + Copyright 2012 Mario Mulansky + + 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) +*/ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE numeric_rosenbrock + +#include <iostream> +#include <cmath> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/stepper/rosenbrock4.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef double value_type; +typedef boost::numeric::ublas::vector< value_type > state_type; +typedef boost::numeric::ublas::matrix< value_type > matrix_type; + +// harmonic oscillator, analytic solution x[0] = sin( t ) +struct sys +{ + void operator()( const state_type &x , state_type &dxdt , const value_type &t ) const + { + dxdt( 0 ) = x( 1 ); + dxdt( 1 ) = -x( 0 ); + } +}; + +struct jacobi +{ + void operator()( const state_type &x , matrix_type &jacobi , const value_type &t , state_type &dfdt ) const + { + jacobi( 0 , 0 ) = 0; + jacobi( 0 , 1 ) = 1; + jacobi( 1 , 0 ) = -1; + jacobi( 1 , 1 ) = 0; + dfdt( 0 ) = 0.0; + dfdt( 1 ) = 0.0; + } +}; + + +BOOST_AUTO_TEST_SUITE( numeric_rosenbrock4 ) + +BOOST_AUTO_TEST_CASE( rosenbrock4_numeric_test ) +{ + typedef rosenbrock4< value_type > stepper_type; + stepper_type stepper; + + const int o = stepper.order()+1; + + state_type x0( 2 ) , x1( 2 ); + x0(0) = 0.0; x0(1) = 1.0; + + double dt = 0.5; + + stepper.do_step( std::make_pair( sys() , jacobi() ) , x0 , 0.0 , x1 , dt ); + const double f = 2.0 * std::abs( std::sin(dt) - x1(0) ) / std::pow( dt , o ); + + std::cout << o << " , " << f << std::endl; + + while( f*std::pow( dt , o ) > 1E-16 ) + { + stepper.do_step( std::make_pair( sys() , jacobi() ) , x0 , 0.0 , x1 , dt ); + std::cout << "Testing dt=" << dt << std::endl; + BOOST_CHECK_SMALL( std::abs( std::sin(dt) - x1(0) ) , f*std::pow( dt , o ) ); + dt *= 0.5; + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/numeric/runge_kutta.cpp b/src/boost/libs/numeric/odeint/test/numeric/runge_kutta.cpp new file mode 100644 index 000000000..a71701bde --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/numeric/runge_kutta.cpp @@ -0,0 +1,177 @@ +/* Boost numeric test of the runge kutta steppers test file + + Copyright 2012 Mario Mulansky + Copyright 2012 Karsten Ahnert + + 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) +*/ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE numeric_runge_kutta + +#include <iostream> +#include <cmath> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint.hpp> +#include <boost/numeric/odeint/stepper/extrapolation_stepper.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +typedef double value_type; + +typedef boost::array< double , 2 > state_type; + +// harmonic oscillator, analytic solution x[0] = sin( t ) +struct osc +{ + void operator()( const state_type &x , state_type &dxdt , const double t ) const + { + dxdt[0] = x[1]; + dxdt[1] = -x[0]; + } +}; + +/* reset dispatcher */ +template< class StepperCategory > +struct resetter +{ + template< class Stepper > + static void reset( Stepper &stepper ) { } +}; + +template< > +struct resetter< explicit_error_stepper_fsal_tag > +{ + template< class Stepper > + static void reset( Stepper &stepper ) + { stepper.reset(); } +}; + + +BOOST_AUTO_TEST_SUITE( numeric_runge_kutta_test ) + + +/* generic test for all runge kutta steppers */ +template< class Stepper > +struct perform_runge_kutta_test +{ + void operator()( void ) + { + + Stepper stepper; + const int o = stepper.order()+1; //order of the error is order of approximation + 1 + + const state_type x0 = {{ 0.0 , 1.0 }}; + state_type x1; + const double t = 0.0; + /* do a first step with dt=0.1 to get an estimate on the prefactor of the error dx = f * dt^(order+1) */ + double dt = 0.5; + stepper.do_step( osc() , x0 , t , x1 , dt ); + const double f = 2.0 * std::abs( sin(dt) - x1[0] ) / std::pow( dt , o ); // upper bound + + std::cout << o << " , " << f << std::endl; + + /* as long as we have errors above machine precision */ + while( f*std::pow( dt , o ) > 1E-16 ) + { + // reset stepper which require resetting (fsal steppers) + resetter< typename Stepper::stepper_category >::reset( stepper ); + + stepper.do_step( osc() , x0 , t , x1 , dt ); + std::cout << "Testing dt=" << dt << std::endl; + BOOST_CHECK_LT( std::abs( sin(dt) - x1[0] ) , f*std::pow( dt , o ) ); + dt *= 0.5; + } + } +}; + + +/* generic error test for all runge kutta steppers */ +template< class Stepper > +struct perform_runge_kutta_error_test +{ + void operator()( void ) + { + Stepper stepper; + const int o = stepper.error_order()+1; //order of the error is order of approximation + 1 + + const state_type x0 = {{ 0.0 , 1.0 }}; + state_type x1 , x_err; + const double t = 0.0; + /* do a first step with dt=0.1 to get an estimate on the prefactor of the error dx = f * dt^(order+1) */ + double dt = 0.5; + stepper.do_step( osc() , x0 , t , x1 , dt , x_err ); + const double f = 2.0 * std::abs( x_err[0] ) / std::pow( dt , o ); + + std::cout << o << " , " << f << " , " << x0[0] << std::endl; + + /* as long as we have errors above machine precision */ + while( f*std::pow( dt , o ) > 1E-16 ) + { + // reset stepper which require resetting (fsal steppers) + resetter< typename Stepper::stepper_category >::reset( stepper ); + + stepper.do_step( osc() , x0 , t , x1 , dt , x_err ); + std::cout << "Testing dt=" << dt << ": " << x_err[1] << std::endl; + BOOST_CHECK_SMALL( std::abs( x_err[0] ) , f*std::pow( dt , o ) ); + dt *= 0.5; + } + } +}; + + +typedef mpl::vector< + euler< state_type > , + modified_midpoint< state_type > , + runge_kutta4< state_type > , + runge_kutta4_classic< state_type > , + runge_kutta_cash_karp54_classic< state_type > , + runge_kutta_cash_karp54< state_type > , + runge_kutta_dopri5< state_type > , + runge_kutta_fehlberg78< state_type > , + extrapolation_stepper< 4, state_type > , + extrapolation_stepper< 6, state_type > , + extrapolation_stepper< 8, state_type > , + extrapolation_stepper< 10, state_type > + > runge_kutta_steppers; + +BOOST_AUTO_TEST_CASE_TEMPLATE( runge_kutta_test , Stepper, runge_kutta_steppers ) +{ + perform_runge_kutta_test< Stepper > tester; + tester(); +} + + +typedef mpl::vector< + runge_kutta_cash_karp54_classic< state_type > , + runge_kutta_cash_karp54< state_type > , + runge_kutta_dopri5< state_type > , + runge_kutta_fehlberg78< state_type > , + extrapolation_stepper< 4, state_type > , + extrapolation_stepper< 6, state_type > , + extrapolation_stepper< 8, state_type > , + extrapolation_stepper< 10, state_type > + > runge_kutta_error_steppers; + +BOOST_AUTO_TEST_CASE_TEMPLATE( runge_kutta_error_test , Stepper, runge_kutta_error_steppers ) +{ + perform_runge_kutta_error_test< Stepper > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/numeric/symplectic.cpp b/src/boost/libs/numeric/odeint/test/numeric/symplectic.cpp new file mode 100644 index 000000000..6d3f75b15 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/numeric/symplectic.cpp @@ -0,0 +1,95 @@ +/* Boost numeric test of the symplectic steppers test file + + Copyright 2012 Mario Mulansky + Copyright 2012 Karsten Ahnert + + 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) +*/ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE numeric_symplectic + +#include <iostream> +#include <cmath> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +typedef double value_type; + +typedef boost::array< double ,1 > state_type; + +// harmonic oscillator, analytic solution x[0] = sin( t ) +struct osc +{ + void operator()( const state_type &q , state_type &dpdt ) const + { + dpdt[0] = -q[0]; + } +}; + +BOOST_AUTO_TEST_SUITE( numeric_symplectic_test ) + + +/* generic test for all symplectic steppers */ +template< class Stepper > +struct perform_symplectic_test +{ + void operator()( void ) + { + + Stepper stepper; + const int o = stepper.order()+1; //order of the error is order of approximation + 1 + + const state_type q0 = {{ 0.0 }}; + const state_type p0 = {{ 1.0 }}; + state_type q1,p1; + std::pair< state_type , state_type >x1( q1 , p1 ); + const double t = 0.0; + /* do a first step with dt=0.1 to get an estimate on the prefactor of the error dx = f * dt^(order+1) */ + double dt = 0.5; + stepper.do_step( osc() , std::make_pair( q0 , p0 ) , t , x1 , dt ); + const double f = 2.0 * std::abs( sin(dt) - x1.first[0] ) / std::pow( dt , o ); + + std::cout << o << " , " << f << std::endl; + + /* as long as we have errors above machine precision */ + while( f*std::pow( dt , o ) > 1E-16 ) + { + stepper.do_step( osc() , std::make_pair( q0 , p0 ) , t , x1 , dt ); + std::cout << "Testing dt=" << dt << std::endl; + BOOST_CHECK_SMALL( std::abs( sin(dt) - x1.first[0] ) , f*std::pow( dt , o ) ); + dt *= 0.5; + } + } +}; + + +typedef mpl::vector< + symplectic_euler< state_type > , + symplectic_rkn_sb3a_mclachlan< state_type > + > symplectic_steppers; + +BOOST_AUTO_TEST_CASE_TEMPLATE( symplectic_test , Stepper, symplectic_steppers ) +{ + perform_symplectic_test< Stepper > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/numeric/velocity_verlet.cpp b/src/boost/libs/numeric/odeint/test/numeric/velocity_verlet.cpp new file mode 100644 index 000000000..5ac77807b --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/numeric/velocity_verlet.cpp @@ -0,0 +1,93 @@ +/* Boost numeric test of the runge kutta steppers test file + + Copyright 2012 Mario Mulansky + Copyright 2012 Karsten Ahnert + + 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) +*/ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE numeric_runge_kutta + +#include <iostream> +#include <cmath> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +typedef double value_type; + +typedef boost::array< double , 1 > state_type; + +// harmonic oscillator, analytic solution x[0] = sin( t ) +struct osc +{ + void operator()( const state_type &x, const state_type &v, state_type &a, + const double t ) const + { + a[0] = -x[0]; + } +}; + +BOOST_AUTO_TEST_SUITE( velocity_verlet_test ) + +BOOST_AUTO_TEST_CASE( numeric_velocity_verlet_test ) +{ + + velocity_verlet<state_type> stepper; + const int steps = 10; + // order of the error is order of approximation + 1 + const int o = stepper.order() + 1; + + const state_type x0 = {{ 0.0 }}; + const state_type v0 = {{ 1.0 }}; + state_type x = x0; + state_type v = v0; + const double t = 0.0; + /* do a first step with dt=0.1 to get an estimate on the prefactor of the error dx = f * dt^(order+1) */ + double dt = 0.5; + for ( int step = 0; step < steps; ++step ) + { + stepper.do_step( + osc(), std::make_pair( boost::ref( x ), boost::ref( v ) ), t, dt ); + } + const double f = steps * std::abs( sin( steps * dt ) - x[0] ) / + std::pow( dt, o ); // upper bound + + std::cout << o << " , " << f << std::endl; + + /* as long as we have errors above machine precision */ + while( f*std::pow( dt , o ) > 1E-16 ) + { + x = x0; + v = v0; + stepper.reset(); + for ( int step = 0; step < steps; ++step ) + { + stepper.do_step( osc() , std::make_pair(boost::ref(x), boost::ref(v)) , t , dt ); + } + std::cout << "Testing dt=" << dt << std::endl; + BOOST_CHECK_LT( std::abs( sin( steps * dt ) - x[0] ), + f * std::pow( dt, o ) ); + dt *= 0.5; + } +}; + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/prepare_stepper_testing.hpp b/src/boost/libs/numeric/odeint/test/prepare_stepper_testing.hpp new file mode 100644 index 000000000..10c0c84e9 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/prepare_stepper_testing.hpp @@ -0,0 +1,74 @@ +/* + [auto_generated] + libs/numeric/odeint/test/prepare_stepper_testing.hpp + + [begin_description] + This file defines some helper functions for the stepper tests. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2012-2013 Mario Mulansky + + 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) + */ + +#ifndef PREPARE_STEPPER_TESTING_HPP_ +#define PREPARE_STEPPER_TESTING_HPP_ + +#include <boost/array.hpp> +#include <vector> +#include <complex> + +#include <boost/fusion/sequence.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/multiprecision/cpp_dec_float.hpp> + +#include <boost/numeric/odeint/algebra/vector_space_algebra.hpp> +#include <boost/numeric/odeint/algebra/array_algebra.hpp> +#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp> + +namespace mpl = boost::mpl; +namespace fusion = boost::fusion; + +using namespace boost::numeric::odeint; + +/* the state types that will be tested */ +typedef std::vector< double > vector_type; +typedef std::vector< std::complex<double> > complex_vector_type; +typedef double vector_space_type; +typedef boost::array< double , 1 > array_type; +typedef boost::array< std::complex<double> , 1 > complex_array_type; + +typedef boost::multiprecision::cpp_dec_float_50 mp_type; +typedef boost::array< mp_type , 1 > mp_array_type; + +typedef mpl::vector< vector_type , complex_vector_type , vector_space_type , + array_type , complex_array_type , mp_type , mp_array_type + >::type container_types; + +namespace boost { namespace numeric { namespace odeint { + + // mp_type forms a vector space + template<> + struct algebra_dispatcher< mp_type > + { + typedef vector_space_algebra algebra_type; + }; + + // add norm computation + template<> + struct vector_space_norm_inf< mp_type > + { + typedef mp_type result_type; + mp_type operator()( mp_type x ) const + { + using std::abs; + return abs(x); + } + }; + +} } } + +#endif /* PREPARE_STEPPER_TESTING_HPP_ */ diff --git a/src/boost/libs/numeric/odeint/test/range_algebra.cpp b/src/boost/libs/numeric/odeint/test/range_algebra.cpp new file mode 100644 index 000000000..d80e9519d --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/range_algebra.cpp @@ -0,0 +1,143 @@ +/* + [auto_generated] + libs/numeric/odeint/test/check_operations.cpp + + [begin_description] + This file tests interaction between the algebras and the operations. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011-2013 Mario Mulansky + + 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) + */ + +#define BOOST_TEST_MODULE odeint_standard_algebra + +#include <cmath> +#include <complex> +#include <utility> +#include <functional> +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> + +#include <boost/units/systems/si/length.hpp> +#include <boost/units/systems/si/time.hpp> +#include <boost/units/systems/si/velocity.hpp> +#include <boost/units/systems/si/io.hpp> + +#include <boost/numeric/odeint/algebra/default_operations.hpp> +#include <boost/numeric/odeint/algebra/range_algebra.hpp> +#include <boost/numeric/odeint/algebra/array_algebra.hpp> + +#include <boost/mpl/list.hpp> + +namespace units = boost::units; +namespace si = boost::units::si; + +using boost::numeric::odeint::default_operations; +using boost::numeric::odeint::range_algebra; +using boost::numeric::odeint::array_algebra; + + +BOOST_AUTO_TEST_SUITE( standard_algebra_test ) + +typedef boost::mpl::list< range_algebra , array_algebra > algebra_types; +range_algebra algebra; + +BOOST_AUTO_TEST_CASE_TEMPLATE( for_each2 , algebra_type , algebra_types ) +{ + algebra_type algebra; + boost::array< double , 2 > x1 = {{ 1.0 , 1.0 }} , x2 = {{ 2.0 , 2.0 }}; + algebra.for_each2( x1 , x2 , default_operations::scale_sum1<>( 1.0 ) ); + BOOST_CHECK_CLOSE( x1[0] , 2.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( x1[1] , 2.0 , 1.0e-10 ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( for_each3 , algebra_type , algebra_types ) +{ + algebra_type algebra; + boost::array< double , 2 > x1 = {{ 1.0 , 1.0 }} , x2 = {{ 2.0 , 2.0 }} , x3 = {{ 3.0 , 3.0 }}; + algebra.for_each3( x1 , x2 , x3 , default_operations::scale_sum2<>( 1.0 , 2.0 ) ); + BOOST_CHECK_CLOSE( x1[0] , 8.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( x1[1] , 8.0 , 1.0e-10 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( for_each4 , algebra_type , algebra_types ) +{ + algebra_type algebra; + boost::array< double , 2 > x1 = {{ 1.0 , 1.0 }} , x2 = {{ 2.0 , 2.0 }} , x3 = {{ 3.0 , 3.0 }} , x4 = {{ 4.0 , 4.0 }}; + algebra.for_each4( x1 , x2 , x3 , x4 , default_operations::scale_sum3<>( 1.0 , 2.0 , 3.0 ) ); + BOOST_CHECK_CLOSE( x1[0] , 20.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( x1[1] , 20.0 , 1.0e-10 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( for_each5 , algebra_type , algebra_types ) +{ + algebra_type algebra; + boost::array< double , 2 > x1 = {{ 1.0 , 1.0 }} , x2 = {{ 2.0 , 2.0 }} , x3 = {{ 3.0 , 3.0 }} , x4 = {{ 4.0 , 4.0 }} , x5 = {{ 5.0 , 5.0 }}; + algebra.for_each5( x1 , x2 , x3 , x4 , x5 , default_operations::scale_sum4<>( 1.0 , 2.0 , 3.0 , 4.0 ) ); + BOOST_CHECK_CLOSE( x1[0] , 40.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( x1[1] , 40.0 , 1.0e-10 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( for_each6 , algebra_type , algebra_types ) +{ + algebra_type algebra; + boost::array< double , 2 > x1 = {{ 1.0 , 1.0 }} , x2 = {{ 2.0 , 2.0 }} , x3 = {{ 3.0 , 3.0 }} , x4 = {{ 4.0 , 4.0 }} , x5 = {{ 5.0 , 5.0 }} , x6 = {{ 6.0 , 6.0 }}; + algebra.for_each6( x1 , x2 , x3 , x4 , x5 , x6 ,default_operations::scale_sum5<>( 1.0 , 2.0 , 3.0 , 4.0 , 5.0 ) ); + BOOST_CHECK_CLOSE( x1[0] , 70.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( x1[1] , 70.0 , 1.0e-10 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( for_each7 , algebra_type , algebra_types ) +{ + algebra_type algebra; + boost::array< double , 2 > x1 = {{ 1.0 , 1.0 }} , x2 = {{ 2.0 , 2.0 }} , x3 = {{ 3.0 , 3.0 }} , x4 = {{ 4.0 , 4.0 }} , x5 = {{ 5.0 , 5.0 }} , x6 = {{ 6.0 , 6.0 }} , x7 = {{ 7.0 , 7.0 }}; + algebra.for_each7( x1 , x2 , x3 , x4 , x5 , x6 , x7 , default_operations::scale_sum6<>( 1.0 , 2.0 , 3.0 , 4.0 , 5.0 , 6.0 ) ); + BOOST_CHECK_CLOSE( x1[0] , 112.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( x1[1] , 112.0 , 1.0e-10 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( for_each8 , algebra_type , algebra_types ) +{ + algebra_type algebra; + boost::array< double , 2 > x1 = {{ 1.0 , 1.0 }} , x2 = {{ 2.0 , 2.0 }} , x3 = {{ 3.0 , 3.0 }} , x4 = {{ 4.0 , 4.0 }} , x5 = {{ 5.0 , 5.0 }} , x6 = {{ 6.0 , 6.0 }} , x7 = {{ 7.0 , 7.0 }} , x8 = {{ 8.0 , 8.0 }}; + algebra.for_each8( x1 , x2 , x3 , x4 , x5 , x6 , x7 , x8 , default_operations::scale_sum7<>( 1.0 , 2.0 , 3.0 , 4.0 , 5.0 , 6.0 , 7.0 ) ); + BOOST_CHECK_CLOSE( x1[0] , 168.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( x1[1] , 168.0 , 1.0e-10 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( norm_inf , algebra_type , algebra_types ) +{ + algebra_type algebra; + boost::array< double , 2 > x = {{ 1.25 , 2.25 }}; + double nrm = algebra.norm_inf( x ); + BOOST_CHECK_CLOSE( nrm , 2.25 , 1.0e-10 ); + BOOST_CHECK_CLOSE( x[0] , 1.25 , 1.0e-10 ); + BOOST_CHECK_CLOSE( x[1] , 2.25 , 1.0e-10 ); +} + + +BOOST_AUTO_TEST_CASE( for_each2_with_units ) +{ + range_algebra algebra; + typedef units::quantity< si::time , double > time_type; + typedef units::quantity< si::length , double > length_type; + typedef units::quantity< si::velocity , double > velocity_type; + boost::array< length_type , 2 > x1 = {{ 1.0 * si::meter , 1.0 * si::meter }}; + boost::array< velocity_type , 2 > x2 = {{ 2.0 * si::meter / si::seconds , 2.0 * si::meter / si::seconds }}; + algebra.for_each2( x1 , x2 , default_operations::scale_sum1< time_type >( 0.1 * si::second ) ); + BOOST_CHECK_CLOSE( x1[0].value() , 0.2 , 1.0e-10 ); + BOOST_CHECK_CLOSE( x1[1].value() , 0.2 , 1.0e-10 ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/regression/Jamfile.v2 b/src/boost/libs/numeric/odeint/test/regression/Jamfile.v2 new file mode 100644 index 000000000..bb085f46c --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/regression/Jamfile.v2 @@ -0,0 +1,31 @@ +# Copyright 2012 Karsten Ahnert +# Copyright 2012 Mario Mulansky +# 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) + +# bring in rules for testing + + +import testing ; + +use-project boost : $(BOOST_ROOT) ; + +project + : requirements + <library>/boost/test//boost_unit_test_framework + <define>BOOST_ALL_NO_LIB=1 + <include>../../include + <link>static + <toolset>clang:<cxxflags>-Wno-unused-variable + +# <cxxflags>-D_SCL_SECURE_NO_WARNINGS + ; + +test-suite "odeint" + : + [ run regression_147.cpp ] + [ compile regression_149.cpp ] + [ run regression_168.cpp ] + [ run regression_189.cpp ] + : <testing.launcher>valgrind + ; diff --git a/src/boost/libs/numeric/odeint/test/regression/regression_147.cpp b/src/boost/libs/numeric/odeint/test/regression/regression_147.cpp new file mode 100644 index 000000000..7373782df --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/regression/regression_147.cpp @@ -0,0 +1,88 @@ +/* + + [begin_description] + Test case for issue 147 + [end_description] + + Copyright 2011-2015 Karsten Ahnert + Copyright 2011-2015 Mario Mulansky + + 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) + */ + + +// disable checked iterator warning for msvc + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_regression_147 + +#include <utility> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +typedef double state_type; + +void rhs( const state_type &x , state_type &dxdt , const double t ) +{ + dxdt = 1; +} + + +template<class Stepper, class InitStepper> +struct perform_init_test +{ + void operator()( void ) + { + double t = 0; + const double dt = 0.1; + + state_type x = 0; + + Stepper stepper; + InitStepper init_stepper; + stepper.initialize( init_stepper, rhs, x, t, dt ); + + // ab-stepper needs order-1 init steps: t and x should be (order-1)*dt + BOOST_CHECK_CLOSE( t , (stepper.order()-1)*dt , 1E-16 ); + BOOST_CHECK_CLOSE( x, ( stepper.order() - 1 ) * dt, 2E-14 ); + } +}; + +typedef mpl::vector< + euler< state_type > , + modified_midpoint< state_type > , + runge_kutta4< state_type > , + runge_kutta4_classic< state_type > , + runge_kutta_cash_karp54_classic< state_type > , + runge_kutta_cash_karp54< state_type > , + runge_kutta_dopri5< state_type > , + runge_kutta_fehlberg78< state_type > + > runge_kutta_steppers; + + +BOOST_AUTO_TEST_SUITE( regression_147_test ) + +BOOST_AUTO_TEST_CASE_TEMPLATE( init_test , InitStepper, + runge_kutta_steppers ) +{ + perform_init_test< adams_bashforth<4, state_type>, InitStepper > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/regression/regression_149.cpp b/src/boost/libs/numeric/odeint/test/regression/regression_149.cpp new file mode 100644 index 000000000..2790d683f --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/regression/regression_149.cpp @@ -0,0 +1,93 @@ +/* + + [begin_description] + Test case for issue 149: + Error C2582 with msvc-10 when using iterator-based integration + [end_description] + + Copyright 2011-2015 Karsten Ahnert + Copyright 2011-2015 Mario Mulansky + + 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) + */ + + +// disable checked iterator warning for msvc + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_regression_147 + +#include <utility> +#include <iostream> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> +#include <boost/range/algorithm/find_if.hpp> + +#include <boost/numeric/odeint.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +typedef std::vector<double> state_type; + +void rhs( const state_type &x , state_type &dxdt , const double t ) +{ +} + + +template<class Stepper> +struct perform_test +{ + void operator()( void ) + { + bulirsch_stoer< state_type > stepper( 1e-9, 0.0, 0.0, 0.0 ); + state_type x( 3, 10.0 ); + + print( boost::find_if( + make_adaptive_time_range( stepper, rhs, x, 0.0, 1.0, 0.01 ), + pred ) ); + + } + + static bool pred( const std::pair< const state_type &, double > &x ) + { + return ( x.first[0] < 0.0 ); + } + + template<class Iterator> + void print( Iterator iter ) + { + std::cout << iter->second << "\t" << iter->first[0] << "\t" + << iter->first[1] << "\t" << iter->first[2] << "\n"; + } +}; + +typedef mpl::vector< + euler< state_type > , + runge_kutta4< state_type > , + runge_kutta_cash_karp54< state_type > , + runge_kutta_dopri5< state_type > , + runge_kutta_fehlberg78< state_type > , + bulirsch_stoer< state_type > + > steppers; + + +BOOST_AUTO_TEST_SUITE( regression_147_test ) + +BOOST_AUTO_TEST_CASE_TEMPLATE( regression_147_test , Stepper, + steppers ) +{ + perform_test< Stepper > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/regression/regression_168.cpp b/src/boost/libs/numeric/odeint/test/regression/regression_168.cpp new file mode 100644 index 000000000..8349261a6 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/regression/regression_168.cpp @@ -0,0 +1,90 @@ +/* + + [begin_description] + Test case for issue 149: + Error C2582 with msvc-10 when using iterator-based integration + [end_description] + + Copyright 2011-2015 Karsten Ahnert + Copyright 2011-2015 Mario Mulansky + + 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) + */ + + +// disable checked iterator warning for msvc + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_regression_147 + +#include <utility> +#include <iostream> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> +#include <boost/range/algorithm/find_if.hpp> + +#include <boost/numeric/odeint.hpp> +#include <boost/numeric/odeint/algebra/fusion_algebra.hpp> +#include <boost/numeric/odeint/algebra/fusion_algebra_dispatcher.hpp> + + +#include <boost/units/systems/si/length.hpp> +#include <boost/units/systems/si/time.hpp> +#include <boost/units/systems/si/velocity.hpp> +#include <boost/units/systems/si/acceleration.hpp> +#include <boost/units/systems/si/io.hpp> + +#include <boost/fusion/container.hpp> + + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +namespace fusion = boost::fusion; +namespace units = boost::units; +namespace si = boost::units::si; + +typedef units::quantity< si::time , double > time_type; +typedef units::quantity< si::length , double > length_type; +typedef units::quantity< si::velocity , double > velocity_type; +typedef units::quantity< si::acceleration , double > acceleration_type; +typedef units::quantity< si::frequency , double > frequency_type; + +typedef fusion::vector< length_type , velocity_type > state_type; +typedef fusion::vector< velocity_type , acceleration_type > deriv_type; + + +struct oscillator +{ + frequency_type m_omega; + + oscillator( const frequency_type &omega = 1.0 * si::hertz ) : m_omega( omega ) { } + + void operator()( const state_type &x , deriv_type &dxdt , time_type t ) const + { + fusion::at_c< 0 >( dxdt ) = fusion::at_c< 1 >( x ); + fusion::at_c< 1 >( dxdt ) = - m_omega * m_omega * fusion::at_c< 0 >( x ); + } +}; + + +BOOST_AUTO_TEST_CASE( regression_168 ) +{ + typedef runge_kutta_dopri5< state_type , double , deriv_type , time_type > stepper_type; + + state_type x( 1.0 * si::meter , 0.0 * si::meter_per_second ); + + integrate_const( make_dense_output( 1.0e-6 , 1.0e-6 , stepper_type() ) , oscillator( 2.0 * si::hertz ) , + x , 0.0 * si::second , 100.0 * si::second , 0.1 * si::second); +}
\ No newline at end of file diff --git a/src/boost/libs/numeric/odeint/test/regression/regression_189.cpp b/src/boost/libs/numeric/odeint/test/regression/regression_189.cpp new file mode 100644 index 000000000..545300725 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/regression/regression_189.cpp @@ -0,0 +1,72 @@ +/* + + [begin_description] + Test case for issue 189: + Controlled Rosenbrock stepper fails to increase step size + [end_description] + + Copyright 2016 Karsten Ahnert + Copyright 2016 Mario Mulansky + + 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) + */ + +#define BOOST_TEST_MODULE odeint_regression_189 + +#include <boost/numeric/odeint.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/phoenix/core.hpp> +#include <boost/phoenix/operator.hpp> + +using namespace boost::numeric::odeint; +namespace phoenix = boost::phoenix; + +typedef boost::numeric::ublas::vector< double > vector_type; +typedef boost::numeric::ublas::matrix< double > matrix_type; + +struct stiff_system +{ + void operator()( const vector_type &x , vector_type &dxdt , double /* t */ ) + { + dxdt[ 0 ] = -101.0 * x[ 0 ] - 100.0 * x[ 1 ]; + dxdt[ 1 ] = x[ 0 ]; + } +}; + +struct stiff_system_jacobi +{ + void operator()( const vector_type & /* x */ , matrix_type &J , const double & /* t */ , vector_type &dfdt ) + { + J( 0 , 0 ) = -101.0; + J( 0 , 1 ) = -100.0; + J( 1 , 0 ) = 1.0; + J( 1 , 1 ) = 0.0; + dfdt[0] = 0.0; + dfdt[1] = 0.0; + } +}; + + +BOOST_AUTO_TEST_CASE( regression_189 ) +{ + vector_type x( 2 , 1.0 ); + + size_t num_of_steps = integrate_const( make_dense_output< rosenbrock4< double > >( 1.0e-6 , 1.0e-6 ) , + std::make_pair( stiff_system() , stiff_system_jacobi() ) , + x , 0.0 , 50.0 , 0.01 , + std::cout << phoenix::arg_names::arg2 << " " << phoenix::arg_names::arg1[0] << "\n" ); + // regression: number of steps should be 74 + size_t num_of_steps_expected = 74; + BOOST_CHECK_EQUAL( num_of_steps , num_of_steps_expected ); + + vector_type x2( 2 , 1.0 ); + + size_t num_of_steps2 = integrate_const( make_dense_output< runge_kutta_dopri5< vector_type > >( 1.0e-6 , 1.0e-6 ) , + stiff_system() , x2 , 0.0 , 50.0 , 0.01 , + std::cout << phoenix::arg_names::arg2 << " " << phoenix::arg_names::arg1[0] << "\n" ); + num_of_steps_expected = 1531; + BOOST_CHECK_EQUAL( num_of_steps2 , num_of_steps_expected ); +} diff --git a/src/boost/libs/numeric/odeint/test/resize.cpp b/src/boost/libs/numeric/odeint/test/resize.cpp new file mode 100644 index 000000000..db40f4bfe --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/resize.cpp @@ -0,0 +1,98 @@ +/* + [auto_generated] + libs/numeric/odeint/test/resize.cpp + + [begin_description] + This file tests the resize function of odeint. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2012 Mario Mulansky + + 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) + */ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_resize + +#include <vector> +#include <cmath> + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/util/resize.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/fusion/include/at.hpp> +#include <boost/units/systems/si/length.hpp> +#include <boost/units/systems/si/time.hpp> +#include <boost/units/systems/si/velocity.hpp> +#include <boost/units/systems/si/acceleration.hpp> +#include <boost/units/systems/si/io.hpp> + + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +BOOST_AUTO_TEST_CASE( test_vector ) +{ + std::vector< double > x1( 10 ); + std::vector< double > x2; + resize( x2 , x1 ); + BOOST_CHECK( x2.size() == 10 ); +} + + +BOOST_AUTO_TEST_CASE( test_fusion_vector_of_vector ) +{ + typedef boost::fusion::vector< std::vector< double > , std::vector< double > > state_type; + state_type x1; + boost::fusion::at_c< 0 >( x1 ).resize( 10 ); + boost::fusion::at_c< 1 >( x1 ).resize( 10 ); + state_type x2; + resize( x2 , x1 ); + BOOST_CHECK( boost::fusion::at_c< 0 >( x2 ).size() == 10 ); + BOOST_CHECK( boost::fusion::at_c< 1 >( x2 ).size() == 10 ); +} + + +BOOST_AUTO_TEST_CASE( test_fusion_vector_mixed1 ) +{ + typedef boost::fusion::vector< std::vector< double > , double > state_type; + state_type x1; + boost::fusion::at_c< 0 >( x1 ).resize( 10 ); + state_type x2; + resize( x2 , x1 ); + BOOST_CHECK( boost::fusion::at_c< 0 >( x2 ).size() == 10 ); +} + +BOOST_AUTO_TEST_CASE( test_fusion_vector_mixed2 ) +{ + typedef boost::fusion::vector< double , std::vector< double > , double > state_type; + state_type x1; + boost::fusion::at_c< 1 >( x1 ).resize( 10 ); + state_type x2; + resize( x2 , x1 ); + BOOST_CHECK( boost::fusion::at_c< 1 >( x2 ).size() == 10 ); +} + +BOOST_AUTO_TEST_CASE( test_fusion_quantity_sequence ) +{ + namespace units = boost::units; + namespace si = boost::units::si; + + typedef double value_type; + typedef units::quantity< si::time , value_type > time_type; + typedef units::quantity< si::length , value_type > length_type; + typedef units::quantity< si::velocity , value_type > velocity_type; + typedef boost::fusion::vector< length_type , velocity_type > state_type; + + state_type x1 , x2; + resize( x2 , x1 ); +} diff --git a/src/boost/libs/numeric/odeint/test/resizing.cpp b/src/boost/libs/numeric/odeint/test/resizing.cpp new file mode 100644 index 000000000..751795195 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/resizing.cpp @@ -0,0 +1,110 @@ +/* + [auto_generated] + libs/numeric/odeint/test/resizing.cpp + + [begin_description] + This file tests the resizing mechanism of odeint. + [end_description] + + Copyright 2010-2012 Karsten Ahnert + Copyright 2010-2012 Mario Mulansky + + 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) + */ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_resize + +#include <vector> +#include <cmath> + +#include <boost/array.hpp> +#include <boost/bind.hpp> +#include <boost/utility.hpp> +#include <boost/type_traits/integral_constant.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> +#include <boost/mpl/int.hpp> +#include <boost/mpl/at.hpp> + +#include <boost/numeric/odeint/stepper/euler.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4_classic.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/algebra/vector_space_algebra.hpp> + +#include <boost/numeric/odeint/util/resizer.hpp> +#include <boost/numeric/odeint/util/is_resizeable.hpp> + +#include "resizing_test_state_type.hpp" + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +namespace mpl = boost::mpl; + + + + + + +void constant_system( const test_array_type &x , test_array_type &dxdt , double t ) { dxdt[0] = 1.0; } + + +BOOST_AUTO_TEST_SUITE( check_resize_test ) + + +typedef euler< test_array_type , double , test_array_type , double , range_algebra , default_operations , never_resizer > euler_manual_type; +typedef euler< test_array_type , double , test_array_type , double , range_algebra , default_operations , initially_resizer > euler_initially_type; +typedef euler< test_array_type , double , test_array_type , double , range_algebra , default_operations , always_resizer > euler_always_type; + +typedef runge_kutta4_classic< test_array_type , double , test_array_type , double , range_algebra , default_operations , never_resizer > rk4_manual_type; +typedef runge_kutta4_classic< test_array_type , double , test_array_type , double , range_algebra , default_operations , initially_resizer > rk4_initially_type; +typedef runge_kutta4_classic< test_array_type , double , test_array_type , double , range_algebra , default_operations , always_resizer > rk4_always_type; + + +typedef runge_kutta4< test_array_type , double , test_array_type , double , range_algebra , default_operations , never_resizer > rk4_gen_manual_type; +typedef runge_kutta4< test_array_type , double , test_array_type , double , range_algebra , default_operations , initially_resizer > rk4_gen_initially_type; +typedef runge_kutta4< test_array_type , double , test_array_type , double , range_algebra , default_operations , always_resizer > rk4_gen_always_type; + + +typedef mpl::vector< + mpl::vector< euler_manual_type , mpl::int_<1> , mpl::int_<0> > , + mpl::vector< euler_initially_type , mpl::int_<1> , mpl::int_<1> > , + mpl::vector< euler_always_type , mpl::int_<1> , mpl::int_<3> > , + mpl::vector< rk4_manual_type , mpl::int_<5> , mpl::int_<0> > , + mpl::vector< rk4_initially_type , mpl::int_<5> , mpl::int_<1> > , + mpl::vector< rk4_always_type , mpl::int_<5> , mpl::int_<3> > , + mpl::vector< rk4_gen_manual_type , mpl::int_<5> , mpl::int_<0> > , + mpl::vector< rk4_gen_initially_type , mpl::int_<5> , mpl::int_<1> > , + mpl::vector< rk4_gen_always_type , mpl::int_<5> , mpl::int_<3> > + >::type resize_check_types; + + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_resize , T, resize_check_types ) +{ + typedef typename mpl::at< T , mpl::int_< 0 > >::type stepper_type; + const size_t resize_calls = mpl::at< T , mpl::int_< 1 > >::type::value; + const size_t multiplicity = mpl::at< T , mpl::int_< 2 > >::type::value; + adjust_size_count = 0; + + stepper_type stepper; + test_array_type x; + stepper.do_step( constant_system , x , 0.0 , 0.1 ); + stepper.do_step( constant_system , x , 0.0 , 0.1 ); + stepper.do_step( constant_system , x , 0.0 , 0.1 ); + + BOOST_TEST_MESSAGE( "adjust_size_count : " << adjust_size_count ); + BOOST_CHECK_MESSAGE( adjust_size_count == resize_calls * multiplicity , "adjust_size_count : " << adjust_size_count << " expected: " << resize_calls * multiplicity ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/resizing_test_state_type.hpp b/src/boost/libs/numeric/odeint/test/resizing_test_state_type.hpp new file mode 100644 index 000000000..af55937ad --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/resizing_test_state_type.hpp @@ -0,0 +1,69 @@ +/* + [auto_generated] + libs/numeric/odeint/test/resizing_test_state_type.hpp + + [begin_description] + tba. + [end_description] + + Copyright 2009-2012 Karsten Ahnert + Copyright 2009-2012 Mario Mulansky + + 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) +*/ + + +#ifndef LIBS_NUMERIC_ODEINT_TEST_RESIZING_TEST_STATE_TYPE_HPP_DEFINED +#define LIBS_NUMERIC_ODEINT_TEST_RESIZING_TEST_STATE_TYPE_HPP_DEFINED + +#include <boost/numeric/odeint/util/is_resizeable.hpp> +#include <boost/numeric/odeint/util/resize.hpp> +#include <boost/numeric/odeint/util/same_size.hpp> + +#include <boost/array.hpp> + + + +// Mario: velocity verlet tests need arrays of size 2 +// some ugly detailed dependency, maybe this can be improved? +class test_array_type : public boost::array< double , 2 > { }; + +size_t adjust_size_count; + +namespace boost { +namespace numeric { +namespace odeint { + + template<> + struct is_resizeable< test_array_type > + { + typedef boost::true_type type; + const static bool value = type::value; + }; + + template<> + struct same_size_impl< test_array_type , test_array_type > + { + static bool same_size( const test_array_type &x1 , const test_array_type &x2 ) + { + return false; + } + }; + + template<> + struct resize_impl< test_array_type , test_array_type > + { + static void resize( test_array_type &x1 , const test_array_type &x2 ) + { + adjust_size_count++; + } + }; + +} // namespace odeint +} // namespace numeric +} // namespace boost + + +#endif // LIBS_NUMERIC_ODEINT_TEST_RESIZING_TEST_STATE_TYPE_HPP_DEFINED diff --git a/src/boost/libs/numeric/odeint/test/rosenbrock4.cpp b/src/boost/libs/numeric/odeint/test/rosenbrock4.cpp new file mode 100644 index 000000000..0b7bea4ba --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/rosenbrock4.cpp @@ -0,0 +1,173 @@ +/* + [auto_generated] + libs/numeric/odeint/test/rosenbrock4.cpp + + [begin_description] + This file tests the Rosenbrock 4 stepper and its controller and dense output stepper. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011 Mario Mulansky + + 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) + */ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_rosenbrock4 + +#include <utility> +#include <iostream> + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/stepper/rosenbrock4.hpp> +#include <boost/numeric/odeint/stepper/rosenbrock4_controller.hpp> +#include <boost/numeric/odeint/stepper/rosenbrock4_dense_output.hpp> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef double value_type; +typedef boost::numeric::ublas::vector< value_type > state_type; +typedef boost::numeric::ublas::matrix< value_type > matrix_type; + + +struct sys +{ + void operator()( const state_type &x , state_type &dxdt , const value_type &t ) const + { + dxdt( 0 ) = x( 0 ) + 2 * x( 1 ); + dxdt( 1 ) = x( 1 ); + } +}; + +struct jacobi +{ + void operator()( const state_type &x , matrix_type &jacobi , const value_type &t , state_type &dfdt ) const + { + jacobi( 0 , 0 ) = 1; + jacobi( 0 , 1 ) = 2; + jacobi( 1 , 0 ) = 0; + jacobi( 1 , 1 ) = 1; + dfdt( 0 ) = 0.0; + dfdt( 1 ) = 0.0; + } +}; + +BOOST_AUTO_TEST_SUITE( rosenbrock4_test ) + +BOOST_AUTO_TEST_CASE( test_rosenbrock4_stepper ) +{ + typedef rosenbrock4< value_type > stepper_type; + stepper_type stepper; + + typedef stepper_type::state_type state_type; + typedef stepper_type::value_type stepper_value_type; + typedef stepper_type::deriv_type deriv_type; + typedef stepper_type::time_type time_type; + + state_type x( 2 ) , xerr( 2 ); + x(0) = 0.0; x(1) = 1.0; + + stepper.do_step( std::make_pair( sys() , jacobi() ) , x , 0.0 , 0.1 , xerr ); + + stepper.do_step( std::make_pair( sys() , jacobi() ) , x , 0.0 , 0.1 ); + +// using std::abs; +// value_type eps = 1E-12; +// +// // compare with analytic solution of above system +// BOOST_CHECK_SMALL( abs( x(0) - 20.0/81.0 ) , eps ); +// BOOST_CHECK_SMALL( abs( x(1) - 10.0/9.0 ) , eps ); + +} + +BOOST_AUTO_TEST_CASE( test_rosenbrock4_controller ) +{ + typedef rosenbrock4_controller< rosenbrock4< value_type > > stepper_type; + stepper_type stepper; + + typedef stepper_type::state_type state_type; + typedef stepper_type::value_type stepper_value_type; + typedef stepper_type::deriv_type deriv_type; + typedef stepper_type::time_type time_type; + + state_type x( 2 ); + x( 0 ) = 0.0 ; x(1) = 1.0; + + value_type t = 0.0 , dt = 0.01; + stepper.try_step( std::make_pair( sys() , jacobi() ) , x , t , dt ); +} + +BOOST_AUTO_TEST_CASE( test_rosenbrock4_dense_output ) +{ + typedef rosenbrock4_dense_output< rosenbrock4_controller< rosenbrock4< value_type > > > stepper_type; + typedef rosenbrock4_controller< rosenbrock4< value_type > > controlled_stepper_type; + controlled_stepper_type c_stepper; + stepper_type stepper( c_stepper ); + + typedef stepper_type::state_type state_type; + typedef stepper_type::value_type stepper_value_type; + typedef stepper_type::deriv_type deriv_type; + typedef stepper_type::time_type time_type; + state_type x( 2 ); + x( 0 ) = 0.0 ; x(1) = 1.0; + stepper.initialize( x , 0.0 , 0.1 ); + std::pair< value_type , value_type > tr = stepper.do_step( std::make_pair( sys() , jacobi() ) ); + stepper.calc_state( 0.5 * ( tr.first + tr.second ) , x ); +} + +class rosenbrock4_controller_max_dt_adaptable : public rosenbrock4_controller< rosenbrock4< value_type > > +{ + public: + void set_max_dt(value_type max_dt) + { + m_max_dt = max_dt; + } +}; + +BOOST_AUTO_TEST_CASE( test_rosenbrock4_dense_output_ref ) +{ + typedef rosenbrock4_dense_output< boost::reference_wrapper< rosenbrock4_controller_max_dt_adaptable > > stepper_type; + rosenbrock4_controller_max_dt_adaptable c_stepper; + stepper_type stepper( boost::ref( c_stepper ) ); + + typedef stepper_type::state_type state_type; + typedef stepper_type::value_type stepper_value_type; + typedef stepper_type::deriv_type deriv_type; + typedef stepper_type::time_type time_type; + state_type x( 2 ); + x( 0 ) = 0.0 ; x(1) = 1.0; + stepper.initialize( x , 0.0 , 0.1 ); + std::pair< value_type , value_type > tr = stepper.do_step( std::make_pair( sys() , jacobi() ) ); + stepper.calc_state( 0.5 * ( tr.first + tr.second ) , x ); + + // adapt the maximal step size to a small value (smaller than the step size) and make a step + const double max_dt = 1e-8; + c_stepper.set_max_dt(max_dt); + stepper.do_step( std::make_pair( sys() , jacobi() ) ); + // check if the step was done with the requested maximal step size + BOOST_CHECK_CLOSE(max_dt, stepper.current_time_step(), 1e-14); +} + +BOOST_AUTO_TEST_CASE( test_rosenbrock4_copy_dense_output ) +{ + typedef rosenbrock4_controller< rosenbrock4< value_type > > controlled_stepper_type; + typedef rosenbrock4_dense_output< controlled_stepper_type > stepper_type; + + controlled_stepper_type c_stepper; + stepper_type stepper( c_stepper ); + stepper_type stepper2( stepper ); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/rosenbrock4_mp.cpp b/src/boost/libs/numeric/odeint/test/rosenbrock4_mp.cpp new file mode 100644 index 000000000..dc295c473 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/rosenbrock4_mp.cpp @@ -0,0 +1,143 @@ +/* + [auto_generated] + libs/numeric/odeint/test/rosenbrock4.cpp + + [begin_description] + This file tests the Rosenbrock 4 stepper and its controller and dense output stepper. + [end_description] + + Copyright 2009-2012 Karsten Ahnert + Copyright 2009-2012 Mario Mulansky + + 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) + */ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_rosenbrock4 + +#include <utility> +#include <iostream> + +#include <boost/test/unit_test.hpp> +#include <boost/multiprecision/cpp_dec_float.hpp> + +#include <boost/numeric/odeint/stepper/rosenbrock4.hpp> +#include <boost/numeric/odeint/stepper/rosenbrock4_controller.hpp> +#include <boost/numeric/odeint/stepper/rosenbrock4_dense_output.hpp> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef boost::multiprecision::cpp_dec_float_50 value_type; +typedef boost::numeric::ublas::vector< value_type > state_type; +typedef boost::numeric::ublas::matrix< value_type > matrix_type; + + +struct sys +{ + void operator()( const state_type &x , state_type &dxdt , const value_type &t ) const + { + dxdt( 0 ) = x( 0 ) + 2 * x( 1 ); + dxdt( 1 ) = x( 1 ); + } +}; + +struct jacobi +{ + void operator()( const state_type &x , matrix_type &jacobi , const value_type &t , state_type &dfdt ) const + { + jacobi( 0 , 0 ) = 1; + jacobi( 0 , 1 ) = 2; + jacobi( 1 , 0 ) = 0; + jacobi( 1 , 1 ) = 1; + dfdt( 0 ) = 0.0; + dfdt( 1 ) = 0.0; + } +}; + +BOOST_AUTO_TEST_SUITE( rosenbrock4_test ) + +BOOST_AUTO_TEST_CASE( test_rosenbrock4_stepper ) +{ + typedef rosenbrock4< value_type > stepper_type; + stepper_type stepper; + + typedef stepper_type::state_type state_type; + typedef stepper_type::value_type stepper_value_type; + typedef stepper_type::deriv_type deriv_type; + typedef stepper_type::time_type time_type; + + state_type x( 2 ) , xerr( 2 ); + x(0) = 0.0; x(1) = 1.0; + + stepper.do_step( std::make_pair( sys() , jacobi() ) , x , + static_cast<value_type>(0.0) , static_cast<value_type>(0.1) , xerr ); + + stepper.do_step( std::make_pair( sys() , jacobi() ) , x , + static_cast<value_type>(0.0) , static_cast<value_type>(0.1) ); + +// using std::abs; +// value_type eps = 1E-12; +// +// // compare with analytic solution of above system +// BOOST_CHECK_SMALL( abs( x(0) - 20.0/81.0 ) , eps ); +// BOOST_CHECK_SMALL( abs( x(1) - 10.0/9.0 ) , eps ); + +} + +BOOST_AUTO_TEST_CASE( test_rosenbrock4_controller ) +{ + typedef rosenbrock4_controller< rosenbrock4< value_type > > stepper_type; + stepper_type stepper; + + typedef stepper_type::state_type state_type; + typedef stepper_type::value_type stepper_value_type; + typedef stepper_type::deriv_type deriv_type; + typedef stepper_type::time_type time_type; + + state_type x( 2 ); + x( 0 ) = 0.0 ; x(1) = 1.0; + + value_type t = 0.0 , dt = 0.01; + stepper.try_step( std::make_pair( sys() , jacobi() ) , x , t , dt ); +} + +BOOST_AUTO_TEST_CASE( test_rosenbrock4_dense_output ) +{ + typedef rosenbrock4_dense_output< rosenbrock4_controller< rosenbrock4< value_type > > > stepper_type; + typedef rosenbrock4_controller< rosenbrock4< value_type > > controlled_stepper_type; + controlled_stepper_type c_stepper; + stepper_type stepper( c_stepper ); + + typedef stepper_type::state_type state_type; + typedef stepper_type::value_type stepper_value_type; + typedef stepper_type::deriv_type deriv_type; + typedef stepper_type::time_type time_type; + state_type x( 2 ); + x( 0 ) = 0.0 ; x(1) = 1.0; + stepper.initialize( x , 0.0 , 0.1 ); + std::pair< value_type , value_type > tr = stepper.do_step( std::make_pair( sys() , jacobi() ) ); + stepper.calc_state( 0.5 * ( tr.first + tr.second ) , x ); +} + +BOOST_AUTO_TEST_CASE( test_rosenbrock4_copy_dense_output ) +{ + typedef rosenbrock4_controller< rosenbrock4< value_type > > controlled_stepper_type; + typedef rosenbrock4_dense_output< controlled_stepper_type > stepper_type; + + controlled_stepper_type c_stepper; + stepper_type stepper( c_stepper ); + stepper_type stepper2( stepper ); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/runge_kutta_concepts.cpp b/src/boost/libs/numeric/odeint/test/runge_kutta_concepts.cpp new file mode 100644 index 000000000..42235dea4 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/runge_kutta_concepts.cpp @@ -0,0 +1,217 @@ +/* + [auto_generated] + libs/numeric/odeint/test/runge_kutta_concepts.cpp + + [begin_description] + This file tests the Stepper concepts of odeint with all Runge-Kutta steppers. It's one of the main tests + of odeint. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2012-2013 Mario Mulansky + + 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) + */ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_runge_kutta_concepts + +#include <vector> +#include <cmath> +#include <iostream> + +#include <boost/numeric/odeint/config.hpp> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/ref.hpp> +#include <boost/bind.hpp> +#include <boost/utility.hpp> +#include <boost/type_traits/add_reference.hpp> + +#include <boost/mpl/vector.hpp> +#include <boost/mpl/for_each.hpp> +#include <boost/mpl/insert_range.hpp> +#include <boost/mpl/end.hpp> +#include <boost/mpl/copy.hpp> +#include <boost/mpl/placeholders.hpp> +#include <boost/mpl/inserter.hpp> + +#include <boost/numeric/odeint/stepper/euler.hpp> +#include <boost/numeric/odeint/stepper/modified_midpoint.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4_classic.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54_classic.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_fehlberg78.hpp> + +#include <boost/numeric/odeint/algebra/detail/extract_value_type.hpp> + +#include "prepare_stepper_testing.hpp" +#include "dummy_odes.hpp" + +using std::vector; + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +const double result = 2.2; + +const double eps = 1.0e-14; + +template< class Stepper , class System > +void check_stepper_concept( Stepper &stepper , System system , typename Stepper::state_type &x ) +{ + typedef Stepper stepper_type; + typedef typename stepper_type::deriv_type container_type; + typedef typename stepper_type::order_type order_type; + typedef typename stepper_type::time_type time_type; + + stepper.do_step( system , x , static_cast<time_type>(0.0) , static_cast<time_type>(0.1) ); +} + +// default case is used for vector space types like plain double +template< class Stepper , typename T > +struct perform_stepper_test +{ + typedef T vector_space_type; + void operator()( void ) const + { + using std::abs; + vector_space_type x; + x = 2.0; + Stepper stepper; + constant_system_functor_vector_space sys; +#ifndef _MSC_VER + // dont run this for MSVC due to compiler bug 697006 + check_stepper_concept( stepper , constant_system_vector_space< vector_space_type , vector_space_type , typename Stepper::time_type > , x ); +#else + check_stepper_concept( stepper , boost::cref( sys ) , x ); +#endif + check_stepper_concept( stepper , boost::cref( sys ) , x ); + std::cout << x << " ?= " << result << std::endl; + BOOST_CHECK( (abs( x - result )) < eps ); + } +}; + +template< class Stepper , typename T > +struct perform_stepper_test< Stepper , std::vector<T> > +{ + typedef std::vector<T> vector_type; + void operator()( void ) + { + using std::abs; + vector_type x( 1 , static_cast<T>(2.0) ); + Stepper stepper; + constant_system_functor_standard sys; +#ifndef _MSC_VER + // dont run this for MSVC due to compiler bug 697006 + check_stepper_concept( stepper , constant_system_standard< vector_type , vector_type , typename Stepper::time_type > , x ); +#else + check_stepper_concept( stepper , boost::cref( sys ) , x ); +#endif + check_stepper_concept( stepper , boost::cref( sys ) , x ); + std::cout << x[0] << " ?= " << result << std::endl; + BOOST_CHECK( (abs( x[0] - result )) < eps ); + } +}; + +template< class Stepper , typename T > +struct perform_stepper_test< Stepper , boost::array<T,1> > +{ + typedef boost::array<T,1> array_type; + void operator()( void ) + { + using std::abs; + array_type x; + x[0] = static_cast<T>(2.0); + Stepper stepper; + constant_system_functor_standard sys; +#ifndef _MSC_VER + // dont run this for MSVC due to compiler bug 697006 + check_stepper_concept( stepper , constant_system_standard< array_type , array_type , typename Stepper::time_type > , x ); +#else + check_stepper_concept( stepper , boost::cref( sys ) , x ); +#endif + check_stepper_concept( stepper , boost::cref( sys ) , x ); + std::cout << x[0] << " ?= " << result << std::endl; + BOOST_CHECK( (abs( x[0] - result )) < eps ); + } +}; + +// split stepper methods to ensure the final vector has less than 30(?) elements +// (stepper_methods*container_types) < 30(?) +template< class State > class stepper_methods1 : public mpl::vector< + euler< State , typename detail::extract_value_type<State>::type > , + modified_midpoint< State , typename detail::extract_value_type<State>::type > , + runge_kutta4< State , typename detail::extract_value_type<State>::type > , + runge_kutta4_classic< State , typename detail::extract_value_type<State>::type > + > { }; + +template< class State > class stepper_methods2 : public mpl::vector< + runge_kutta_cash_karp54_classic< State , typename detail::extract_value_type<State>::type > , + runge_kutta_cash_karp54< State , typename detail::extract_value_type<State>::type > , + runge_kutta_dopri5< State , typename detail::extract_value_type<State>::type > , + runge_kutta_fehlberg78< State , typename detail::extract_value_type<State>::type > + > { }; + + + +typedef mpl::copy +< + container_types , + mpl::inserter + < + mpl::vector0<> , + mpl::insert_range + < + mpl::_1 , + mpl::end< mpl::_1 > , + stepper_methods1< mpl::_2 > + > + > +>::type stepper_combinations1; + +typedef mpl::copy +< + container_types , + mpl::inserter + < + mpl::vector0<> , + mpl::insert_range + < + mpl::_1 , + mpl::end< mpl::_1 > , + stepper_methods2< mpl::_2 > + > + > +>::type stepper_combinations2; + + +BOOST_AUTO_TEST_SUITE( runge_kutta_concept_test ) + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_test1 , Stepper, stepper_combinations1 ) +{ + perform_stepper_test< Stepper , typename Stepper::deriv_type > tester; + tester(); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_test2 , Stepper, stepper_combinations2 ) +{ + perform_stepper_test< Stepper , typename Stepper::deriv_type > tester; + tester(); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/runge_kutta_controlled_concepts.cpp b/src/boost/libs/numeric/odeint/test/runge_kutta_controlled_concepts.cpp new file mode 100644 index 000000000..7f70cc533 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/runge_kutta_controlled_concepts.cpp @@ -0,0 +1,212 @@ +/* + [auto_generated] + libs/numeric/odeint/test/runge_kutta_controlled_concepts.cpp + + [begin_description] + This file tests the Stepper concepts of odeint with all Controlled Runge-Kutta steppers. + It's one of the main tests of odeint. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2012-2013 Mario Mulansky + + 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) + */ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_runge_kutta_controlled_concepts + +#include <vector> +#include <cmath> +#include <iostream> + +#include <boost/numeric/odeint/config.hpp> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/ref.hpp> +#include <boost/bind.hpp> +#include <boost/utility.hpp> +#include <boost/type_traits/add_reference.hpp> + +#include <boost/mpl/vector.hpp> +#include <boost/mpl/for_each.hpp> +#include <boost/mpl/insert_range.hpp> +#include <boost/mpl/end.hpp> +#include <boost/mpl/copy.hpp> +#include <boost/mpl/placeholders.hpp> +#include <boost/mpl/inserter.hpp> + +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54_classic.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_fehlberg78.hpp> +#include <boost/numeric/odeint/stepper/controlled_runge_kutta.hpp> +#include <boost/numeric/odeint/stepper/bulirsch_stoer.hpp> + +#include "prepare_stepper_testing.hpp" +#include "dummy_odes.hpp" + +using std::vector; + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +const double result = 2.2; // two steps + +const double eps = 1.0e-14; + +template< class Stepper , class System > +void check_controlled_stepper_concept( Stepper &stepper , System system , typename Stepper::state_type &x ) +{ + typedef Stepper stepper_type; + typedef typename stepper_type::deriv_type container_type; + //typedef typename stepper_type::order_type order_type; controlled_error_stepper don't necessarily have a order (burlish-stoer) + typedef typename stepper_type::time_type time_type; + + time_type t = 0.0 , dt = 0.1; + controlled_step_result step_result = stepper.try_step( system , x , t , dt ); + + BOOST_CHECK_MESSAGE( step_result == success , "step result: " << step_result ); // error = 0 for constant system -> step size is always too small +} + + +template< class ControlledStepper , typename T > +struct perform_controlled_stepper_test +{ + typedef T vector_space_type; + void operator()( void ) const + { + using std::abs; + vector_space_type x; + x = 2.0; + ControlledStepper controlled_stepper; + constant_system_functor_vector_space sys; +#ifndef _MSC_VER + // dont run this for MSVC due to compiler bug 697006 + check_controlled_stepper_concept( controlled_stepper , + constant_system_vector_space< vector_space_type , vector_space_type , typename ControlledStepper::time_type > + , x ); +#else + check_controlled_stepper_concept( controlled_stepper , boost::cref( sys ) , x ); +#endif + check_controlled_stepper_concept( controlled_stepper , boost::cref( sys ) , x ); + BOOST_CHECK( (abs( x - result )) < eps ); + } +}; + +template< class ControlledStepper , typename T > +struct perform_controlled_stepper_test< ControlledStepper , std::vector<T> > +{ + typedef std::vector<T> vector_type; + void operator()( void ) + { + using std::abs; + vector_type x( 1 , 2.0 ); + ControlledStepper controlled_stepper; + constant_system_functor_standard sys; +#ifndef _MSC_VER + // dont run this for MSVC due to compiler bug 697006 + + check_controlled_stepper_concept( controlled_stepper , + constant_system_standard< vector_type , vector_type , typename ControlledStepper::time_type > , + x ); +#else + check_controlled_stepper_concept( controlled_stepper , boost::cref( sys ) , x ); +#endif + check_controlled_stepper_concept( controlled_stepper , boost::cref( sys ) , x ); + BOOST_CHECK( (abs( x[0] - result )) < eps ); + } +}; + + +template< class ControlledStepper > +struct perform_controlled_stepper_test< ControlledStepper , vector_space_type > +{ + void operator()( void ) const + { + using std::abs; + vector_space_type x; + x = 2.0; + ControlledStepper controlled_stepper; + constant_system_functor_vector_space sys; +#ifndef _MSC_VER + // dont run this for MSVC due to compiler bug 697006 + check_controlled_stepper_concept( controlled_stepper , + constant_system_vector_space< vector_space_type , vector_space_type , typename ControlledStepper::time_type > + , x ); +#else + check_controlled_stepper_concept( controlled_stepper , boost::cref( sys ) , x ); +#endif + check_controlled_stepper_concept( controlled_stepper , boost::cref( sys ) , x ); + BOOST_CHECK( (abs( x - result )) < eps ); + } +}; + +template< class ControlledStepper , typename T > +struct perform_controlled_stepper_test< ControlledStepper , boost::array<T,1> > +{ + typedef boost::array<T,1> array_type; + void operator()( void ) + { + using std::abs; + array_type x; + x[0] = 2.0; + ControlledStepper controlled_stepper; + constant_system_functor_standard sys; +#ifndef _MSC_VER + // dont run this for MSVC due to compiler bug 697006 + check_controlled_stepper_concept( controlled_stepper , constant_system_standard< array_type , array_type , typename ControlledStepper::time_type > , x ); +#else + check_controlled_stepper_concept( controlled_stepper , boost::cref( sys ) , x ); +#endif + check_controlled_stepper_concept( controlled_stepper , boost::cref( sys ) , x ); + BOOST_CHECK( (abs( x[0] - result )) < eps ); + } +}; + + +template< class State > class controlled_stepper_methods : public mpl::vector< + controlled_runge_kutta< runge_kutta_cash_karp54_classic< State , typename detail::extract_value_type<State>::type > > , + controlled_runge_kutta< runge_kutta_dopri5< State , typename detail::extract_value_type<State>::type > > , + controlled_runge_kutta< runge_kutta_fehlberg78< State , typename detail::extract_value_type<State>::type > > , + bulirsch_stoer< State , typename detail::extract_value_type<State>::type > + > { }; + +typedef mpl::copy +< + container_types , + mpl::inserter + < + mpl::vector0<> , + mpl::insert_range + < + mpl::_1 , + mpl::end< mpl::_1 > , + controlled_stepper_methods< mpl::_2 > + > + > + >::type all_controlled_stepper_methods; + + + + +BOOST_AUTO_TEST_SUITE( controlled_runge_kutta_concept_test ) + +BOOST_AUTO_TEST_CASE_TEMPLATE( controlled_stepper_test , ControlledStepper , all_controlled_stepper_methods ) +{ + perform_controlled_stepper_test< ControlledStepper , typename ControlledStepper::state_type > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/runge_kutta_error_concepts.cpp b/src/boost/libs/numeric/odeint/test/runge_kutta_error_concepts.cpp new file mode 100644 index 000000000..06980772a --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/runge_kutta_error_concepts.cpp @@ -0,0 +1,182 @@ +/* + [auto_generated] + libs/numeric/odeint/test/runge_kutta_error_concepts.cpp + + [begin_description] + This file tests the Stepper concepts of odeint with all Runge-Kutta Error steppers. + It's one of the main tests of odeint. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2012-2013 Mario Mulansky + + 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) + */ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_runge_kutta_error_concepts + +#include <vector> +#include <cmath> +#include <iostream> + +#include <boost/numeric/odeint/config.hpp> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/ref.hpp> +#include <boost/bind.hpp> +#include <boost/utility.hpp> +#include <boost/type_traits/add_reference.hpp> + +#include <boost/mpl/vector.hpp> +#include <boost/mpl/for_each.hpp> +#include <boost/mpl/insert_range.hpp> +#include <boost/mpl/end.hpp> +#include <boost/mpl/copy.hpp> +#include <boost/mpl/placeholders.hpp> +#include <boost/mpl/inserter.hpp> + +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54_classic.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_fehlberg78.hpp> + +#include "prepare_stepper_testing.hpp" +#include "dummy_odes.hpp" + +using std::vector; + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +const double result = 2.4; // four steps total... + +const double eps = 1.0e-14; + +template< class Stepper , class System > +void check_error_stepper_concept( Stepper &stepper , System system , typename Stepper::state_type &x , typename Stepper::state_type &xerr ) +{ + typedef Stepper stepper_type; + typedef typename stepper_type::deriv_type container_type; + typedef typename stepper_type::order_type order_type; + typedef typename stepper_type::time_type time_type; + + stepper.do_step( system , x , static_cast<time_type>(0.0) , static_cast<time_type>(0.1) ); + stepper.do_step( system , x , static_cast<time_type>(0.0) , static_cast<time_type>(0.1) , xerr ); +} + +// default case is used for vector space types like plain double +template< class Stepper , typename T > +struct perform_error_stepper_test +{ + typedef T vector_space_type; + void operator()( void ) const + { + using std::abs; + vector_space_type x , xerr; + x = 2.0; + Stepper stepper; + constant_system_functor_vector_space sys; +#ifndef _MSC_VER + // dont run this for MSVC due to compiler bug 697006 + check_error_stepper_concept( stepper , + constant_system_vector_space< vector_space_type , vector_space_type , typename Stepper::time_type > , + x , + xerr ); +#else + check_error_stepper_concept( stepper , boost::cref( sys ) , x , xerr ); +#endif + check_error_stepper_concept( stepper , boost::cref( sys ) , x , xerr ); + + BOOST_CHECK_MESSAGE( (abs( x - result )) < eps , x ); + } +}; + +template< class Stepper , typename T > +struct perform_error_stepper_test< Stepper , std::vector<T> > +{ + typedef std::vector<T> vector_type; + void operator()( void ) + { + using std::abs; + vector_type x( 1 , 2.0 ) , xerr( 1 ); + Stepper stepper; + constant_system_functor_standard sys; +#ifndef _MSC_VER + // dont run this for MSVC due to compiler bug 697006 + check_error_stepper_concept( stepper , constant_system_standard< vector_type , vector_type , typename Stepper::time_type > , x , xerr ); +#else + check_error_stepper_concept( stepper , boost::cref( sys ) , x , xerr ); +#endif + check_error_stepper_concept( stepper , boost::cref( sys ) , x , xerr ); + BOOST_CHECK( (abs( x[0] - result )) < eps ); + } +}; + + +template< class Stepper , typename T > +struct perform_error_stepper_test< Stepper , boost::array<T,1> > +{ + typedef boost::array<T,1> array_type; + void operator()( void ) + { + using std::abs; + array_type x , xerr; + x[0] = 2.0; + Stepper stepper; + constant_system_functor_standard sys; +#ifndef _MSC_VER + // dont run this for MSVC due to compiler bug 697006 + check_error_stepper_concept( stepper , constant_system_standard< array_type , array_type , typename Stepper::time_type > , x , xerr ); +#else + check_error_stepper_concept( stepper , boost::cref( sys ) , x , xerr ); +#endif + check_error_stepper_concept( stepper , boost::cref( sys ) , x , xerr ); + BOOST_CHECK( (abs( x[0] - result )) < eps ); + } +}; + +template< class State > class error_stepper_methods : public mpl::vector< + runge_kutta_cash_karp54_classic< State , typename detail::extract_value_type<State>::type > , + runge_kutta_cash_karp54< State , typename detail::extract_value_type<State>::type > , + runge_kutta_dopri5< State , typename detail::extract_value_type<State>::type > , + runge_kutta_fehlberg78< State , typename detail::extract_value_type<State>::type > + > { }; + + +typedef mpl::copy +< + container_types , + mpl::inserter + < + mpl::vector0<> , + mpl::insert_range + < + mpl::_1 , + mpl::end< mpl::_1 > , + error_stepper_methods< mpl::_2 > + > + > + >::type all_error_stepper_methods; + + +BOOST_AUTO_TEST_SUITE( runge_kutta_error_concept_test ) + +BOOST_AUTO_TEST_CASE_TEMPLATE( error_stepper_test , Stepper , all_error_stepper_methods ) +{ + perform_error_stepper_test< Stepper , typename Stepper::state_type > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/same_size.cpp b/src/boost/libs/numeric/odeint/test/same_size.cpp new file mode 100644 index 000000000..09a04c199 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/same_size.cpp @@ -0,0 +1,65 @@ +/* + [auto_generated] + libs/numeric/odeint/test/same_size.cpp + + [begin_description] + tba. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2012 Mario Mulansky + + 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) + */ + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_dummy + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/util/same_size.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + + +BOOST_AUTO_TEST_SUITE( same_size_test ) + +BOOST_AUTO_TEST_CASE( test_vector_true ) +{ + std::vector< double > v1( 10 ) , v2( 10 ); + BOOST_CHECK_EQUAL( true , same_size( v1 , v2 ) ); +} + + +BOOST_AUTO_TEST_CASE( test_vector_false ) +{ + std::vector< double > v1( 10 ) , v2( 20 ); + BOOST_CHECK_EQUAL( false , same_size( v1 , v2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_fusion_true ) +{ + boost::fusion::vector< double , std::vector< double > > v1 , v2; + boost::fusion::at_c< 1 >( v1 ).resize( 10 ); + boost::fusion::at_c< 1 >( v2 ).resize( 10 ); + BOOST_CHECK_EQUAL( true , same_size( v1 , v2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_fusion_false ) +{ + boost::fusion::vector< double , std::vector< double > > v1 , v2; + boost::fusion::at_c< 1 >( v1 ).resize( 10 ); + boost::fusion::at_c< 1 >( v2 ).resize( 20 ); + BOOST_CHECK_EQUAL( false , same_size( v1 , v2 ) ); +} + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/split.cpp b/src/boost/libs/numeric/odeint/test/split.cpp new file mode 100644 index 000000000..b8f056be9 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/split.cpp @@ -0,0 +1,68 @@ +/* + [auto_generated] + libs/numeric/odeint/test/split.cpp + + [begin_description] + Test the range split. + [end_description] + + Copyright 2013 Karsten Ahnert + Copyright 2013 Mario Mulansky + Copyright 2013 Pascal Germroth + + 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) + */ + +#define BOOST_TEST_MODULE odeint_split + +#include <iostream> + +#include <boost/test/unit_test.hpp> +#include <boost/numeric/odeint/util/split_adaptor.hpp> +#include <boost/range/irange.hpp> + +template<class T> +inline void dump_range(const T &r) { + std::cout << '['; + std::copy(boost::begin(r), boost::end(r), std::ostream_iterator< + typename std::iterator_traits< + typename boost::range_iterator<const T>::type + >::value_type >(std::cout, " ") ); + std::cout << ']'; +} + +template<class A, class B> +inline void check_equal_range(const A a, const B b) { + BOOST_CHECK_EQUAL_COLLECTIONS( boost::begin(a), boost::end(a), boost::begin(b), boost::end(b) ); +} + + +using namespace boost::unit_test; +using namespace boost::numeric::odeint::detail; +using namespace boost; + +BOOST_AUTO_TEST_CASE( test_eleven ) +{ + // 0 1 2 3 | 4 5 6 7 | 8 9 10 11 + check_equal_range( irange(0, 12) | split(0, 3), irange(0, 4) ); + check_equal_range( irange(0, 12) | split(1, 3), irange(4, 8) ); + check_equal_range( irange(0, 12) | split(2, 3), irange(8, 12) ); +} + +BOOST_AUTO_TEST_CASE( test_ten ) +{ + // 0 1 2 3 | 4 5 6 7 | 8 9 10 + check_equal_range( irange(0, 11) | split(0, 3), irange(0, 4) ); + check_equal_range( irange(0, 11) | split(1, 3), irange(4, 8) ); + check_equal_range( irange(0, 11) | split(2, 3), irange(8, 11) ); +} + +BOOST_AUTO_TEST_CASE( test_nine ) +{ + // 0 1 2 3 | 4 5 6 | 7 8 9 + check_equal_range( irange(0, 10) | split(0, 3), irange(0, 4) ); + check_equal_range( irange(0, 10) | split(1, 3), irange(4, 7) ); + check_equal_range( irange(0, 10) | split(2, 3), irange(7, 10) ); +} diff --git a/src/boost/libs/numeric/odeint/test/std_array.cpp b/src/boost/libs/numeric/odeint/test/std_array.cpp new file mode 100644 index 000000000..350a387a8 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/std_array.cpp @@ -0,0 +1,57 @@ +/* + [auto_generated] + test/std_array.cpp + + [begin_description] + Checks if odeint compiles fine with the std::array using the array algebra + [end_description] + + Copyright 2009-2014 Karsten Ahnert + Copyright 2009-2014 Mario Mulansky + + 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) + */ + + +#define BOOST_TEST_MODULE odeint_std_array + +#include <array> +#include <boost/numeric/odeint.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/test/unit_test.hpp> + +using namespace boost::unit_test; + +typedef std::array<double, 3> state_type; + +void rhs(const state_type &x, state_type &dxdt, const double t) +{ +} + +BOOST_AUTO_TEST_SUITE( unwrap_reference_test ) + +BOOST_AUTO_TEST_CASE( test_case ) +{ + state_type x = {0.0, 0.0, 0.0}; + + typedef boost::numeric::odeint::runge_kutta4<state_type> stepper_type; +// check if array algebra is selected, but only if odeint detects c++11 +#ifdef BOOST_NUMERIC_ODEINT_CXX11 + BOOST_STATIC_ASSERT(( boost::is_same< stepper_type::algebra_type , + boost::numeric::odeint::array_algebra >::value )); +#endif + stepper_type stepper1; + stepper1.do_step(rhs, x, 0.0, 0.1); + + boost::numeric::odeint::runge_kutta4< + state_type, double, state_type, double, + boost::numeric::odeint::array_algebra > stepper; + stepper.do_step(rhs, x, 0.0, 0.1); + +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/step_size_limitation.cpp b/src/boost/libs/numeric/odeint/test/step_size_limitation.cpp new file mode 100644 index 000000000..2d8e4725d --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/step_size_limitation.cpp @@ -0,0 +1,268 @@ +/* + [auto_generated] + libs/numeric/odeint/test/step_size_limitation.cpp + + [begin_description] + Tests the step size limitation functionality + [end_description] + + Copyright 2015 Mario Mulansky + + 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) + */ + +#define BOOST_TEST_MODULE odeint_integrate_times + +#include <boost/test/unit_test.hpp> + +#include <utility> +#include <iostream> +#include <vector> + +#include <boost/numeric/odeint.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef double value_type; +typedef std::vector< value_type > state_type; + +/*********************************************** + * first part of the tests: explicit methods + *********************************************** + */ + +void damped_osc( const state_type &x , state_type &dxdt , const value_type t ) +{ + const value_type gam( 0.1); + + dxdt[0] = x[1]; + dxdt[1] = -x[0] - gam*x[1]; +} + + +struct push_back_time +{ + std::vector< double >& m_times; + + push_back_time( std::vector< double > × ) + : m_times( times ) { } + + template<typename State> + void operator()( const State &x , double t ) + { + m_times.push_back( t ); + } +}; + +BOOST_AUTO_TEST_SUITE( step_size_limitation_test ) + +BOOST_AUTO_TEST_CASE( test_step_adjuster ) +{ + // first use adjuster without step size limitation + default_step_adjuster<double, double> step_adjuster; + const double dt = 0.1; + double dt_new = step_adjuster.decrease_step(dt, 1.5, 2); + BOOST_CHECK(dt_new < dt*2.0/3.0); + + dt_new = step_adjuster.increase_step(dt, 0.8, 1); + // for errors > 0.5 no increase is performed + BOOST_CHECK(dt_new == dt); + + dt_new = step_adjuster.increase_step(dt, 0.4, 1); + // smaller errors should lead to step size increase + std::cout << dt_new << std::endl; + BOOST_CHECK(dt_new > dt); + + + // now test with step size limitation max_dt = 0.1 + default_step_adjuster<double, double> + limited_adjuster(dt); + + dt_new = limited_adjuster.decrease_step(dt, 1.5, 2); + // decreasing works as before + BOOST_CHECK(dt_new < dt*2.0/3.0); + + dt_new = limited_adjuster.decrease_step(2*dt, 1.1, 2); + // decreasing a large step size should give max_dt + BOOST_CHECK(dt_new == dt); + + dt_new = limited_adjuster.increase_step(dt, 0.8, 1); + // for errors > 0.5 no increase is performed, still valid + BOOST_CHECK(dt_new == dt); + + dt_new = limited_adjuster.increase_step(dt, 0.4, 1); + // but even for smaller errors, we should at most get 0.1 + BOOST_CHECK_EQUAL(dt_new, dt); + + dt_new = limited_adjuster.increase_step(0.9*dt, 0.1, 1); + std::cout << dt_new << std::endl; + // check that we don't increase beyond max_dt + BOOST_CHECK(dt_new == dt); +} + + +template<class Stepper> +void test_explicit_stepper(Stepper stepper, const double max_dt) +{ + state_type x( 2 ); + x[0] = x[1] = 10.0; + const size_t steps = 100; + + std::vector<double> times; + + integrate_adaptive(stepper, damped_osc, x, 0.0, steps*max_dt, max_dt, push_back_time(times)); + + BOOST_CHECK_EQUAL(times.size(), steps+1); + // check that dt remains at exactly max_dt + for( size_t i=0 ; i<times.size() ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_SMALL( times[i] - static_cast<double>(i)*max_dt , 1E-15); + times.clear(); + + // this should also work when we provide some bigger initial dt + integrate_adaptive(stepper, damped_osc, x, 0.0, steps*max_dt, 10*max_dt, push_back_time(times)); + + BOOST_CHECK_EQUAL(times.size(), steps+1); + // check that dt remains at exactly max_dt + for( size_t i=0 ; i<times.size() ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_SMALL( times[i] - static_cast<double>(i)*max_dt , 1E-15); + times.clear(); +} + + +BOOST_AUTO_TEST_CASE( test_controlled ) +{ + const double max_dt = 0.01; + + test_explicit_stepper(make_controlled(1E-2, 1E-2, max_dt, + runge_kutta_dopri5<state_type>()), + max_dt); + test_explicit_stepper(make_controlled(1E-2, 1E-2, -max_dt, + runge_kutta_dopri5<state_type>()), + -max_dt); + + test_explicit_stepper(make_controlled(1E-2, 1E-2, max_dt, + runge_kutta_cash_karp54<state_type>()), + max_dt); + test_explicit_stepper(make_controlled(1E-2, 1E-2, -max_dt, + runge_kutta_cash_karp54<state_type>()), + -max_dt); + + test_explicit_stepper(bulirsch_stoer<state_type>(1E-2, 1E-2, 1.0, 1.0, max_dt), + max_dt); + test_explicit_stepper(bulirsch_stoer<state_type>(1E-2, 1E-2, 1.0, 1.0, -max_dt), + -max_dt); +} + + +BOOST_AUTO_TEST_CASE( test_dense_out ) +{ + const double max_dt = 0.01; + test_explicit_stepper(make_dense_output(1E-2, 1E-2, max_dt, + runge_kutta_dopri5<state_type>()), + max_dt); + test_explicit_stepper(make_dense_output(1E-2, 1E-2, -max_dt, + runge_kutta_dopri5<state_type>()), + -max_dt); + + test_explicit_stepper(bulirsch_stoer_dense_out<state_type>(1E-2, 1E-2, 1, 1, max_dt), + max_dt); + + test_explicit_stepper(bulirsch_stoer_dense_out<state_type>(1E-2, 1E-2, 1, 1, -max_dt), + -max_dt); +} + + +/*********************************************** + * second part of the tests: implicit Rosenbrock + *********************************************** + */ + +typedef boost::numeric::ublas::vector< value_type > vector_type; +typedef boost::numeric::ublas::matrix< value_type > matrix_type; + + +// harmonic oscillator, analytic solution x[0] = sin( t ) +struct osc_rhs +{ + void operator()( const vector_type &x , vector_type &dxdt , const value_type &t ) const + { + dxdt( 0 ) = x( 1 ); + dxdt( 1 ) = -x( 0 ); + } +}; + +struct osc_jacobi +{ + void operator()( const vector_type &x , matrix_type &jacobi , const value_type &t , vector_type &dfdt ) const + { + jacobi( 0 , 0 ) = 0; + jacobi( 0 , 1 ) = 1; + jacobi( 1 , 0 ) = -1; + jacobi( 1 , 1 ) = 0; + dfdt( 0 ) = 0.0; + dfdt( 1 ) = 0.0; + } +}; + + +template<class Stepper> +void test_rosenbrock_stepper(Stepper stepper, const double max_dt) +{ + vector_type x( 2 ); + x(0) = x(1) = 10.0; + const size_t steps = 100; + + std::vector<double> times; + + integrate_adaptive(stepper, + std::make_pair(osc_rhs(), osc_jacobi()), + x, 0.0, steps*max_dt, max_dt, push_back_time(times)); + + BOOST_CHECK_EQUAL(times.size(), steps+1); + // check that dt remains at exactly max_dt + for( size_t i=0 ; i<times.size() ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_SMALL( times[i] - static_cast<double>(i)*max_dt , 1E-15); + times.clear(); + + // this should also work when we provide some bigger initial dt + integrate_adaptive(stepper, + std::make_pair(osc_rhs(), osc_jacobi()), + x, 0.0, steps*max_dt, 10*max_dt, push_back_time(times)); + + BOOST_CHECK_EQUAL(times.size(), steps+1); + // check that dt remains at exactly max_dt + for( size_t i=0 ; i<times.size() ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_SMALL( times[i] - static_cast<double>(i)*max_dt , 1E-15); + times.clear(); +} + + +BOOST_AUTO_TEST_CASE( test_controlled_rosenbrock ) +{ + const double max_dt = 0.01; + + test_rosenbrock_stepper(make_controlled(1E-2, 1E-2, max_dt, rosenbrock4<value_type>()), + max_dt); + test_rosenbrock_stepper(make_controlled(1E-2, 1E-2, -max_dt, rosenbrock4<value_type>()), + -max_dt); +} + + +BOOST_AUTO_TEST_CASE( test_dense_out_rosenbrock ) +{ + const double max_dt = 0.01; + + test_rosenbrock_stepper(make_dense_output(1E-2, 1E-2, max_dt, rosenbrock4<value_type>()), + max_dt); + test_rosenbrock_stepper(make_dense_output(1E-2, 1E-2, -max_dt, rosenbrock4<value_type>()), + -max_dt); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/stepper_copying.cpp b/src/boost/libs/numeric/odeint/test/stepper_copying.cpp new file mode 100644 index 000000000..c29e4de19 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/stepper_copying.cpp @@ -0,0 +1,856 @@ +/* + [auto_generated] + libs/numeric/odeint/test/stepper_copying.cpp + + [begin_description] + This file tests the copying of the steppers. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011-2012 Mario Mulansky + + 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) +*/ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC +#pragma warning(disable:4996) +#endif + + +#define BOOST_TEST_MODULE odeint_stepper_copying + +#include <boost/test/unit_test.hpp> +#include <boost/type_traits/integral_constant.hpp> + +//#include <boost/numeric/odeint/util/construct.hpp> +//#include <boost/numeric/odeint/util/destruct.hpp> +#include <boost/numeric/odeint/util/copy.hpp> + +#include <boost/numeric/odeint/util/state_wrapper.hpp> + +#include <boost/numeric/odeint/stepper/euler.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4_classic.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54_classic.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/controlled_runge_kutta.hpp> +#include <boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp> + +template< class T , size_t Dim > +class test_array +{ +public: + + const static size_t dim = Dim; + typedef T value_type; + typedef value_type* iterator; + typedef const value_type* const_iterator; + + value_type& operator[]( size_t i ) + { + return m_data[i]; + } + + const value_type& operator[]( size_t i ) const + { + return m_data[i]; + } + + iterator begin( void ) + { + return m_data; + } + + iterator end( void ) + { + return m_data + dim; + } + + const_iterator begin( void ) const + { + return m_data; + } + + const_iterator end( void ) const + { + return m_data + dim; + } + + +private: + + value_type m_data[dim]; +}; + +template< class T , size_t Dim > +class test_array2 : public test_array< T , Dim > +{ +}; + + + +/* + * Explicit testing if copying was successful is difficult, + * hence we only test if the number of copy operations is right. + * + * Otherwise one has to prepare the states. + */ + +size_t construct_count = 0; +size_t construct2_count = 0; +size_t destruct_count = 0; +size_t destruct2_count = 0; +size_t copy_count = 0; +size_t copy2_count = 0; + +void reset_counter( void ) +{ + construct_count = 0; + construct2_count = 0; + destruct_count = 0; + destruct2_count = 0; + copy_count = 0; + copy2_count = 0; +} + + +namespace boost { namespace numeric { namespace odeint { + +//provide the state_wrapper + template< class T , size_t Dim > + struct state_wrapper< test_array< T , Dim > > + { + typedef state_wrapper< test_array< T , Dim > > state_wrapper_type; + typedef test_array< T , Dim > state_type; + typedef T value_type; + + state_type m_v; + + state_wrapper() : m_v() + { + construct_count++; + } + + state_wrapper( const state_type &v ) : m_v( v ) + { + construct_count++; + copy_count++; + } + + state_wrapper( const state_wrapper_type &x ) : m_v( x.m_v ) + { + construct_count++; + copy_count++; + } + + state_wrapper_type& operator=( const state_wrapper_type &x ) + { + copy_count++; + return *this; + } + + ~state_wrapper() + { + destruct_count++; + } + }; + +//provide the state_wrapper + template< class T , size_t Dim > + struct state_wrapper< test_array2< T , Dim > > + { + typedef state_wrapper< test_array2< T , Dim > > state_wrapper_type; + typedef test_array2< T , Dim > state_type; + typedef T value_type; + + state_type m_v; + + state_wrapper() : m_v() + { + construct2_count++; + } + + state_wrapper( const state_type &v ) : m_v( v ) + { + construct2_count++; + copy2_count++; + } + + state_wrapper( const state_wrapper_type &x ) : m_v( x.m_v ) + { + construct2_count++; + copy2_count++; + } + + state_wrapper_type& operator=( const state_wrapper_type &x ) + { + copy2_count++; + return *this; + } + + ~state_wrapper() + { + destruct2_count++; + } + }; + + + } } } + + + +typedef test_array< double , 3 > state_type; +typedef test_array2< double , 3 > deriv_type; +typedef boost::numeric::odeint::euler< state_type , double , deriv_type > euler_type; +typedef boost::numeric::odeint::runge_kutta4_classic< state_type , double , deriv_type > rk4_type; +typedef boost::numeric::odeint::runge_kutta4< state_type , double , deriv_type > rk4_generic_type; +typedef boost::numeric::odeint::runge_kutta_cash_karp54_classic< state_type , double , deriv_type > rk54_type; +typedef boost::numeric::odeint::runge_kutta_cash_karp54< state_type , double , deriv_type > rk54_generic_type; +typedef boost::numeric::odeint::runge_kutta_dopri5< state_type , double , deriv_type > dopri5_type; +typedef boost::numeric::odeint::controlled_runge_kutta< rk54_type > controlled_rk54_type; +typedef boost::numeric::odeint::controlled_runge_kutta< rk54_generic_type > controlled_rk54_generic_type; +typedef boost::numeric::odeint::controlled_runge_kutta< dopri5_type > controlled_dopri5_type; +typedef boost::numeric::odeint::dense_output_runge_kutta< euler_type > dense_output_euler_type; +typedef boost::numeric::odeint::dense_output_runge_kutta< controlled_dopri5_type > dense_output_dopri5_type; + +#define CHECK_COUNTERS( c1 , c2 , c3 , c4 , c5 , c6 ) \ + BOOST_CHECK_EQUAL( construct_count , size_t( c1 ) ); \ + BOOST_CHECK_EQUAL( construct2_count , size_t( c2 ) ); \ + BOOST_CHECK_EQUAL( destruct_count , size_t( c3 ) ); \ + BOOST_CHECK_EQUAL( destruct2_count , size_t( c4) ); \ + BOOST_CHECK_EQUAL( copy_count , size_t( c5 ) ) ; \ + BOOST_CHECK_EQUAL( copy2_count, size_t( c6 ) ) + +BOOST_AUTO_TEST_SUITE( stepper_copying ) + +/* + * Construct + Destruct + * 1 deriv_type in explicit_stepper_base + */ +BOOST_AUTO_TEST_CASE( explicit_euler_construct ) +{ + reset_counter(); + { + euler_type euler; + } + CHECK_COUNTERS( 0 , 1 , 0 , 1 , 0 , 0 ); +} + + +/* + * Construct + Destruct + * 2 * 1 deriv_type in explicit_stepper_base + * + * Copying + * 1 deriv_type in explicit_stepper_base + */ +BOOST_AUTO_TEST_CASE( explicit_euler_copy_construct ) +{ + reset_counter(); + { + euler_type euler; + euler_type euler2( euler ); + } + CHECK_COUNTERS( 0 , 1 + 1 , 0 , 1 + 1 , 0 , 1 ); +} + +/* + * Construct + Destruct + * 2 * 1 deriv_type in explicit_stepper_base + * + * Copying + * 1 deriv_type in explicit_stepper_base + */ +BOOST_AUTO_TEST_CASE( explicit_euler_assign ) +{ + reset_counter(); + { + euler_type euler; + euler_type euler2; + euler2 = euler; + } + CHECK_COUNTERS( 0 , 2 , 0 , 2 , 0 , 1 ); +} + +/* + * Construct + Destruct + * 1 deriv_type in explicit_stepper_base + * 3 deriv_type in explicit_rk4 + * 1 state_type in explicit_rk4 + */ +BOOST_AUTO_TEST_CASE( explicit_rk4_construct ) +{ + reset_counter(); + { + rk4_type rk4; + } + CHECK_COUNTERS( 1 , 4 , 1 , 4 , 0 , 0 ); +} + +/* + * Construct + Destruct + * 2 * 1 deriv_type in explicit_stepper_base + * 2 * 3 deriv_type in explicit_rk4 + * 2 * 1 state_type in explicit_rk4 + * + * Copying + * 1 deriv_type in explicit_stepper_base + * 3 deriv_type in explicit_stepper_base + * 1 state_type in explicit_stepper_base + */ +BOOST_AUTO_TEST_CASE( explicit_rk4_copy_construct ) +{ + reset_counter(); + { + rk4_type rk4; + rk4_type rk4_2( rk4 ); + } + CHECK_COUNTERS( 2 , 8 , 2 , 8 , 1 , 4 ); +} + +/* + * Construct + Destruct + * 2 * 1 deriv_type in explicit_stepper_base + * 2 * 3 deriv_type in explicit_rk4 + * 2 * 1 state_type in explicit_rk4 + * + * Copying + * 1 deriv_type in explicit_stepper_base + * 3 deriv_type in explicit_stepper_base + * 1 state_type in explicit_stepper_base + */ +BOOST_AUTO_TEST_CASE( explicit_rk4_assign ) +{ + reset_counter(); + { + rk4_type rk4; + rk4_type rk4_2; + rk4 = rk4_2; + } + CHECK_COUNTERS( 2 , 8 , 2 , 8 , 1 , 4 ); +} + + +/* + * Construct + Destruct + * 1 deriv_type in explicit_stepper_base + * 3 deriv_type in explicit_rk4 + * 1 state_type in explicit_rk4 + */ +BOOST_AUTO_TEST_CASE( explicit_rk4_generic_construct ) +{ + reset_counter(); + { + rk4_generic_type rk4; + } + CHECK_COUNTERS( 1 , 4 , 1 , 4 , 0 , 0 ); +} + +/* + * Construct + Destruct + * 2 * 1 deriv_type in explicit_stepper_base + * 2 * 3 deriv_type in explicit_rk4 + * 2 * 1 state_type in explicit_rk4 + * + * Copying + * 1 deriv_type in explicit_stepper_base + * 3 deriv_type in explicit_stepper_base + * 1 state_type in explicit_stepper_base + */ +BOOST_AUTO_TEST_CASE( explicit_rk4_generic_copy_construct ) +{ + reset_counter(); + { + rk4_generic_type rk4; + rk4_generic_type rk4_2( rk4 ); + } + CHECK_COUNTERS( 2 , 8 , 2 , 8 , 1 , 4 ); +} + +/* + * Construct + Destruct + * 2 * 1 deriv_type in explicit_stepper_base + * 2 * 3 deriv_type in explicit_rk4 + * 2 * 1 state_type in explicit_rk4 + * + * Copying + * 1 deriv_type in explicit_stepper_base + * 3 deriv_type in explicit_stepper_base + * 1 state_type in explicit_stepper_base + */ +BOOST_AUTO_TEST_CASE( explicit_rk4_generic_assign ) +{ + reset_counter(); + { + rk4_generic_type rk4; + rk4_generic_type rk4_2; + rk4 = rk4_2; + } + CHECK_COUNTERS( 2 , 8 , 2 , 8 , 1 , 4 ); +} + +/* + * Construct + Destruct + * 2 explicit_rk54_ck: + * 2 * 1 deriv_type in explicit_error_stepper_base + * 2 * 5 deriv_type in explicit_error_rk54_ck + * 2 * 1 state_type in explicit_error_rk4 + * 1 controlled_stepper: + * 1 deriv_type + * 2 state_type + * + * Copying + * 1 copy process of explicit_rk54_ck: + * 1 deriv_type from explicit_error_stepper_base + * 5 deriv_type from explicit_error_rk54_ck + * 1 state_type from explicit_error_rk54_ck + */ +BOOST_AUTO_TEST_CASE( controlled_rk54_construct ) +{ + reset_counter(); + { + controlled_rk54_type stepper; + } + CHECK_COUNTERS( 4 , 13 , 4 , 13 , 1 , 6 ); +} + + +/* + * Construct + Destruct + * 3 explicit_rk54_ck: + * 3 * 1 deriv_type in explicit_error_stepper_base + * 3 * 5 deriv_type in explicit_error_rk54_ck + * 3 * 1 state_type in explicit_error_rk4 + * 2 controlled_stepper: + * 2 * 1 deriv_type + * 2 * 2 state_type + * + * Copying + * 1 copy process of explicit_rk54_ck: + * 1 deriv_type from explicit_error_stepper_base + * 5 deriv_type from explicit_error_rk54_ck + * 1 state_type from explicit_error_rk54_ck + * + * 1 process of copying controlled_error_stepper + * 1 deriv_type from explicit_error_stepper_base + * 5 deriv_type from explicit_error_rk54_ck + * 1 state_type from explicit_error_rk54_ck + * 1 deriv_type from controlled_error_stepper + * 2 state_type from controlled_error_stepper + */ +BOOST_AUTO_TEST_CASE( controlled_rk54_copy_construct ) +{ + reset_counter(); + { + controlled_rk54_type stepper; + controlled_rk54_type stepper2( stepper ); + } + CHECK_COUNTERS( 7 , 20 , 7 , 20 , 4 , 13 ); +} + +/* + * Construct + Destruct + * 4 explicit_rk54_ck: + * 4 * 1 deriv_type in explicit_error_stepper_base + * 4 * 5 deriv_type in explicit_error_rk54_ck + * 4 * 1 state_type in explicit_error_rk4 + * 2 controlled_stepper: + * 2 * 1 deriv_type + * 2 * 2 state_type + * + * Copying + * 2 copy process of explicit_rk54_ck: + * 2 * 1 deriv_type from explicit_error_stepper_base + * 2 * 5 deriv_type from explicit_error_rk54_ck + * 2 * 1 state_type from explicit_error_rk54_ck + * + * 1 process of copying controlled_error_stepper + * 1 deriv_type from explicit_error_stepper_base + * 5 deriv_type from explicit_error_rk54_ck + * 1 state_type from explicit_error_rk54_ck + * 1 deriv_type from controlled_error_stepper + * 2 state_type from controlled_error_stepper + */ +BOOST_AUTO_TEST_CASE( controlled_rk54_assign ) +{ + reset_counter(); + { + controlled_rk54_type stepper; + controlled_rk54_type stepper2; + stepper2 = stepper; + } + CHECK_COUNTERS( 8 , 26 , 8 , 26 , 5 , 19 ); +} + + + +/* + * Construct + Destruct + * 2 explicit_rk54_ck_generic: + * 2 * 1 deriv_type in explicit_error_stepper_base + * 2 * 5 deriv_type in explicit_error_rk54_ck_generic + * 2 * 1 state_type in explicit_error_rk54_ck_generic + * 1 controlled_stepper: + * 1 deriv_type + * 2 state_type + * + * Copying + * 1 copy process of explicit_rk54_ck_generic: + * 1 deriv_type from explicit_error_stepper_base + * 5 deriv_type from explicit_error_rk54_ck_generic + * 1 state_type from explicit_error_rk54_ck_generic + */ +BOOST_AUTO_TEST_CASE( controlled_rk54_generic_construct ) +{ + reset_counter(); + { + controlled_rk54_generic_type stepper; + } + CHECK_COUNTERS( 4 , 13 , 4 , 13 , 1 , 6 ); +} + + +/* + * Construct + Destruct + * 3 explicit_rk54_ck_generic: + * 3 * 1 deriv_type in explicit_error_stepper_base + * 3 * 5 deriv_type in explicit_error_rk54_ck_generic + * 3 * 1 state_type in explicit_error_rk4_generic + * 2 controlled_stepper: + * 2 * 1 deriv_type + * 2 * 2 state_type + * + * Copying + * 1 copy process of explicit_rk54_ck_generic: + * 1 deriv_type from explicit_error_stepper_base + * 5 deriv_type from explicit_error_rk54_ck_generic + * 1 state_type from explicit_error_rk54_ck_generic + * + * 1 process of copying controlled_error_stepper + * 1 deriv_type from explicit_error_stepper_base + * 5 deriv_type from explicit_error_rk54_ck_generic + * 1 state_type from explicit_error_rk54_ck_generic + * 1 deriv_type from controlled_error_stepper + * 2 state_type from controlled_error_stepper + */ +BOOST_AUTO_TEST_CASE( controlled_rk54_generic_copy_construct ) +{ + reset_counter(); + { + controlled_rk54_generic_type stepper; + controlled_rk54_generic_type stepper2( stepper ); + } + CHECK_COUNTERS( 7 , 20 , 7 , 20 , 4 , 13 ); +} + +/* + * Construct + Destruct + * 4 explicit_rk54_ck_generic: + * 4 * 1 deriv_type in explicit_error_stepper_base + * 4 * 5 deriv_type in explicit_error_rk54_ck_generic + * 4 * 1 state_type in explicit_error_rk4_generic + * 2 controlled_stepper: + * 2 * 1 deriv_type + * 2 * 2 state_type + * + * Copying + * 2 copy process of explicit_rk54_ck_generic: + * 2 * 1 deriv_type from explicit_error_stepper_base + * 2 * 5 deriv_type from explicit_error_rk54_ck_generic + * 2 * 1 state_type from explicit_error_rk54_ck_generic + * + * 1 process of copying controlled_error_stepper + * 1 deriv_type from explicit_error_stepper_base + * 5 deriv_type from explicit_error_rk54_ck_generic + * 1 state_type from explicit_error_rk54_ck_generic + * 1 deriv_type from controlled_error_stepper + * 2 state_type from controlled_error_stepper + */ +BOOST_AUTO_TEST_CASE( controlled_rk54_generic_assign ) +{ + reset_counter(); + { + controlled_rk54_generic_type stepper; + controlled_rk54_generic_type stepper2; + stepper2 = stepper; + } + CHECK_COUNTERS( 8 , 26 , 8 , 26 , 5 , 19 ); +} + + +/* + * Construct + Destruct + * 2 explicit_error_dopri5: + * 2 * 1 deriv_type in explicit_error_stepper_base_fsal + * 2 * 6 deriv_type in explicit_error_dopri5 + * 2 * 1 state_type in explicit_error_dopri5 + * 1 controlled_error_stepper (fsal): + * 2 deriv_type + * 2 state_type + * + * Copying + * 1 copy process of explicit_dopri5: + * 1 deriv_type from explicit_error_stepper_base_fsal + * 6 deriv_type from explicit_error_dopri5 + * 1 state_type from explicit_error_dopri5 + */ + +BOOST_AUTO_TEST_CASE( controlled_dopri5_construct ) +{ + reset_counter(); + { + controlled_dopri5_type dopri5; + } + CHECK_COUNTERS( 2 * 1 + 2 , 2 * (6+1) + 2 , 2 * 1 + 2 , 2 * (6+1) + 2 , 1 , 1 + 6 ); +} + + +/* + * Construct + Destruct + * 3 explicit_error_dopri5: + * 3 * 1 deriv_type in explicit_error_stepper_base_fsal + * 3 * 6 deriv_type in explicit_error_dopri5 + * 3 * 1 state_type in explicit_error_dopri5 + * 2 controlled_error_stepper (fsal): + * 2 * 2 deriv_type + * 2 * 2 state_type + * + * Copying + * 1 copy process of explicit_error_dopri5: + * 1 deriv_type from explicit_error_stepper_base_fsal + * 6 deriv_type from explicit_error_error_dopri5 + * 1 state_type from explicit_error_error_dopri5 + * + * 1 process of copying controlled_error_stepper + * 1 deriv_type from explicit_error_stepper_base_fsal + * 6 deriv_type from explicit_error_dopri5 + * 1 state_type from explicit_error_dopri5 + * 2 deriv_type from controlled_error_stepper (fsal) + * 2 state_type from controlled_error_stepper (fsal) + */ +BOOST_AUTO_TEST_CASE( controlled_dopri5_copy_construct ) +{ + reset_counter(); + { + controlled_dopri5_type dopri5; + controlled_dopri5_type dopri5_2( dopri5 ); + } + CHECK_COUNTERS( 3 * 1 + 2 * 2 , 3 * (6+1) + 2 * 2 , 3 * 1 + 2 * 2 , 3 * (6+1) + 2 * 2 , 1 + 1 + 2 , 1 + 6 + 1 + 6 + 2 ); +} + +/* + * Construct + Destruct + * 4 explicit_error_dopri5: + * 4 * 1 deriv_type in explicit_error_stepper_base_fsal + * 4 * 6 deriv_type in explicit_error_dopri5 + * 4 * 1 state_type in explicit_error_dopri5 + * 2 controlled_error_stepper (fsal): + * 2 * 2 deriv_type + * 2 * 2 state_type + * + * Copying + * 2 copy process of explicit_error_dopri5: + * 2 * 1 deriv_type from explicit_error_stepper_base_fsal + * 2 * 6 deriv_type from explicit_error_dopri5 + * 2 * 1 state_type from explicit_error_dopri5 + * + * 1 process of copying controlled_error_stepper + * 1 deriv_type from explicit_error_stepper_base + * 6 deriv_type from explicit_error_dopri5 + * 1 state_type from explicit_error_dopri5 + * 2 deriv_type from controlled_error_stepper (fsal) + * 2 state_type from controlled_error_stepper (fsal) + */ +BOOST_AUTO_TEST_CASE( controlled_dopri5_assign ) +{ + reset_counter(); + { + controlled_dopri5_type dopri5; + controlled_dopri5_type dopri5_2; + dopri5_2 = dopri5; + } + CHECK_COUNTERS( 4 * 1 + 2 * 2 , 4 * (1+6) + 2 * 2 , 4 * 1 + 2 * 2 , 4 * (1+6) + 2 * 2 , 2 * 1 + 1 + 2 , 2 * (6+1) + 1 + 6 + 2 ); +} + + +/* + * Construct + Destruct + * 2 explicit_euler: + * 2 * 1 deriv_type in explicit_stepper_base + * 1 dense_output_explicit: + * 2 state_type + * + * Copying + * 1 copy process of explicit_euler: + * 1 deriv_type from explicit_stepper_base + */ +BOOST_AUTO_TEST_CASE( dense_output_euler_construct ) +{ + reset_counter(); + { + dense_output_euler_type euler; + } + CHECK_COUNTERS( 2 , 2 * 1 , 2 , 2 * 1 , 0 , 1 ); +} + +/* + * Construct + Destruct + * 3 explicit_euler: + * 3 * 1 deriv_type in explicit_stepper_base + * 2 dense_output_explicit: + * 2 * 2 state_type + * + * Copying + * 1 copy process of explicit_euler: + * 1 deriv_type from explicit_stepper_base + * + * 1 process of copying + * 1 deriv_type from explicit_stepper_base + * 2 state_type from dense_output_explicit + */ +BOOST_AUTO_TEST_CASE( dense_output_euler_copy_construct ) +{ + reset_counter(); + { + dense_output_euler_type euler; + dense_output_euler_type euler2( euler ); + } + CHECK_COUNTERS( 2 * 2 , 3 * 1 , 2 * 2 , 3 * 1 , 2 , 1 + 1 ); +} + +/* + * Construct + Destruct + * 4 explicit_euler: + * 4 * 1 deriv_type in explicit_stepper_base + * 2 dense_output_explicit: + * 2 * 2 state_type + * + * Copying + * 2 copy process of explicit_euler: + * 2 * 1 deriv_type from explicit_stepper_base + * + * 1 process of copying dense_ouput_explicit + * 1 deriv_type from explicit_stepper_base + * 2 state_type from dense_output_explicit + */ +BOOST_AUTO_TEST_CASE( dense_output_euler_assign ) +{ + reset_counter(); + { + dense_output_euler_type euler; + dense_output_euler_type euler2; + euler2 = euler; + } + CHECK_COUNTERS( 2 * 2 , 4 * 1 , 2 * 2 , 4 * 1 , 2 , 2 * 1 + 1 ); +} + +/* + * Construct + Destruct + * 3 dense_output_dopri5: + * 3 * 1 deriv_type in explicit_error_stepper_base_fsal + * 3 * 6 deriv_type in explicit_error_dopri5 + * 3 * 1 state_type in explicit_error_dopri5 + * 2 controlled_error_stepper (fsal): + * 2 * 2 state_type + * 2 * 2 deriv_type + * 1 dense_output_controlled_explicit: + * 2 state_type + * 2 deriv_type + * + * Copying + * 2 copy process of explicit_error_dopri5: + * 2 * 1 deriv_type from explicit_erro_stepper_base_fsal + * 2 * 6 deriv_type in explicit_error_dopri5 + * 2 * 1 state_type in explicit_error_dopri5 + * 1 copy process of dense_output_controlled (fsal) + * 2 state_type + * 2 deriv_type + */ +BOOST_AUTO_TEST_CASE( dense_output_dopri5_construct ) +{ + reset_counter(); + { + dense_output_dopri5_type dopri5; + } + CHECK_COUNTERS( 3*1 + 2*2 + 2 , 3*(1+6) + 2*2 + 2 , 3*1 + 2*2 + 2 , 3*(1+6) + 2*2 + 2 , 2*1 + 2 , 2*(1+6) + 2 ); +} + +/* + * Construct + Destruct + * 4 dense_output_dopri5: + * 4 * 1 deriv_type in explicit_error_stepper_base_fsal + * 4 * 5 deriv_type in explicit_error_dopri5 + * 4 * 1 state_type in explicit_error_dopri5 + * 3 controlled_error_stepper (fsal): + * 3 * 2 state_type + * 3 * 2 deriv_type + * 2 dense_output_controlled_explicit: + * 2 * 2 state_type + * 2 * 2 deriv_type + * + * Copying + * 3 copy process of explicit_error_dopri5: + * 3 * 1 deriv_type from explicit_erro_stepper_base_fsal + * 3 * 6 deriv_type in explicit_error_dopri5 + * 3 * 1 state_type in explicit_error_dopri5 + * 2 copy process of controlled_error_stepper (fsal): + * 2 * 2 state_type + * 2 * 2 deriv_type + * 1 copy process of dense_output_controlled_explicit: + * 2 state_type + * 2 deriv_type + */ +BOOST_AUTO_TEST_CASE( dense_output_dopri5_copy_construct ) +{ + reset_counter(); + { + dense_output_dopri5_type dopri5; + dense_output_dopri5_type dopri5_2( dopri5 ); + } + CHECK_COUNTERS( 4*1 + 3*2 + 2*2 , 4*(1+6) + 3*2 + 2*2 , 4*1 + 3*2 + 2*2 , 4*(1+6) + 3*2 + 2*2 , 3*1 + 2*2 + 1*2 , 3*(6+1) + 2*2 + 2 ); +} + +/* + * Construct + Destruct + * 6 dense_output_dopri5: + * 6 * 1 deriv_type in explicit_error_stepper_base_fsal + * 6 * 6 deriv_type in explicit_error_dopri5 + * 6 * 1 state_type in explicit_error_dopri5 + * 4 controlled_error_stepper (fsal): + * 4 * 2 state_type + * 4 * 2 deriv_type + * 2 dense_output_controlled_explicit: + * 2 * 2 state_type + * 2 * 2 deriv_type + * + * Copying + * 5 copy process of explicit_error_dopri5: + * 5 * 1 deriv_type from explicit_erro_stepper_base_fsal + * 5 * 6 deriv_type in explicit_error_dopri5 + * 5 * 1 state_type in explicit_error_dopri5 + * 3 copy process of controlled_error_stepper (fsal): + * 3 * 2 state_type + * 3 * 2 deriv_type + * 1 copy process of dense_output_controlled_explicit: + * 2 state_type + * 2 deriv_type + */ +BOOST_AUTO_TEST_CASE( dense_output_dopri5_assign ) +{ + reset_counter(); + { + dense_output_dopri5_type dopri5; + dense_output_dopri5_type dopri5_2; + dopri5_2 = dopri5; + } + CHECK_COUNTERS( 6*1 + 4*2 + 2*2 , 6*(6+1) + 4*2 + 2*2 , 6*1 + 4*2 + 2*2 , 6*(6+1) + 4*2 + 2*2 , 5*1 + 3*2 + 2 , 5*(6+1) + 3*2 + 2 ); +} + + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/boost/libs/numeric/odeint/test/stepper_with_ranges.cpp b/src/boost/libs/numeric/odeint/test/stepper_with_ranges.cpp new file mode 100644 index 000000000..59f007f2d --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/stepper_with_ranges.cpp @@ -0,0 +1,292 @@ +/* + [auto_generated] + libs/numeric/odeint/test/stepper_with_ranges.cpp + + [begin_description] + This file tests if the steppers play well with Boost.Range. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011-2013 Mario Mulansky + + 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) + */ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_stepper_with_ranges + +#include <boost/test/unit_test.hpp> + +#include <vector> +#include <utility> +#include <iostream> + +#include <boost/array.hpp> +#include <boost/range.hpp> +#include <boost/ref.hpp> + +#include <boost/numeric/odeint/stepper/euler.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54_classic.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/controlled_runge_kutta.hpp> +#include <boost/numeric/odeint/stepper/symplectic_euler.hpp> +#include <boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp> + +typedef std::vector< double > state_type; +typedef boost::array< double , 3 > state_type2; + +/* explicitly force range algebra for this array! */ +namespace boost { namespace numeric { namespace odeint { + +template<> +struct algebra_dispatcher< state_type2 > +{ typedef range_algebra algebra_type; }; + +} } } + + +/* + * The two systems are needed, since for steppers with more than + * one internal step it is difficult to calculate the exact result + * + * system1 is suited for euler + */ +struct system1 +{ + template< class State , class Deriv > + void operator()( const State &x_ , Deriv &dxdt_ , double t ) + { + typename boost::range_iterator< const State >::type x = boost::begin( x_ ); + typename boost::range_iterator< Deriv >::type dxdt = boost::begin( dxdt_ ); + + dxdt[0] = x[0]; + dxdt[1] = 2.0; + dxdt[2] = 3.0; + } + + template< class State , class Deriv > + void operator()( const State &x_ , const Deriv &dxdt_ , double t ) + { + typename boost::range_iterator< const State >::type x = boost::begin( x_ ); + typename boost::range_iterator< Deriv >::type dxdt = boost::begin( dxdt_ ); + + dxdt[0] = x[0]; + dxdt[1] = 2.0; + dxdt[2] = 3.0; + } +}; + +/* + * system2 is suited for all steppers, it allows you to calculate the result analytically. + */ +struct system2 +{ + template< class State , class Deriv > + void operator()( const State &x_ , Deriv &dxdt_ , double t ) + { + typename boost::range_iterator< Deriv >::type dxdt = boost::begin( dxdt_ ); + + dxdt[0] = 1.0; + dxdt[1] = 2.0; + dxdt[2] = 3.0; + } + + template< class State , class Deriv > + void operator()( const State &x_ , const Deriv &dxdt_ , double t ) + { + typename boost::range_iterator< Deriv >::type dxdt = boost::begin( dxdt_ ); + + dxdt[0] = 1.0; + dxdt[1] = 2.0; + dxdt[2] = 3.0; + } +}; + + +/* + * Useful for Hamiltonian systems + */ +struct ham_sys +{ + template< class State , class Deriv > + void operator()( const State &x_ , Deriv &dxdt_ ) + { + typename boost::range_iterator< Deriv >::type dxdt = boost::begin( dxdt_ ); + dxdt[0] = 1.0; + dxdt[1] = 2.0; + dxdt[2] = 3.0; + } + + template< class State , class Deriv > + void operator()( const State &x_ , const Deriv &dxdt_ ) + { + typename boost::range_iterator< Deriv >::type dxdt = boost::begin( dxdt_ ); + dxdt[0] = 1.0; + dxdt[1] = 2.0; + dxdt[2] = 3.0; + } +}; + + +struct vector_fixture +{ + const static size_t dim = 6; + boost::array< double , dim > in; + boost::array< double , dim > q; + boost::array< double , dim > p; + state_type err; + + vector_fixture( void ) + : in() , err( 3 ) + { + for( size_t i=0 ; i<dim ; ++i ) + { + in[ i ] = q[i] = p[i] = double( i ); + } + for( size_t i=0 ; i<3 ; ++i ) + { + err[i] = double( i ) * 10.0; + } + } + + ~vector_fixture( void ) + { + } +}; + +#define CHECK_VALUES( x , x0 , x1 , x2 , x3 , x4 , x5 ) \ + BOOST_CHECK_CLOSE( x[0] , x0 , 1.0e-8 ); \ + BOOST_CHECK_CLOSE( x[1] , x1 , 1.0e-8 ); \ + BOOST_CHECK_CLOSE( x[2] , x2 , 1.0e-8 ); \ + BOOST_CHECK_CLOSE( x[3] , x3 , 1.0e-8 ); \ + BOOST_CHECK_CLOSE( x[4] , x4 , 1.0e-8 ); \ + BOOST_CHECK_CLOSE( x[5] , x5 , 1.0e-8 ) + + + +BOOST_AUTO_TEST_SUITE( stepper_with_ranges ) + +BOOST_AUTO_TEST_CASE( explicit_euler_with_range_v1 ) +{ + vector_fixture f; + boost::numeric::odeint::euler< state_type > euler; + euler.do_step( system1() , std::make_pair( f.in.begin() + 1 , f.in.begin() + 4 ) , 0.1 , 0.1 ); + CHECK_VALUES( f.in , 0.0 , 1.1 , 2.2 , 3.3 , 4.0 , 5.0 ); +} + + + +BOOST_AUTO_TEST_CASE( explicit_error_k54_with_range_v1 ) +{ + vector_fixture f; + boost::numeric::odeint::runge_kutta_cash_karp54_classic< state_type > rk54; + rk54.do_step( system2() , std::make_pair( f.in.begin() + 1 , f.in.begin() + 4 ) , 0.1 , 0.1 ); + CHECK_VALUES( f.in , 0.0 , 1.1 , 2.2 , 3.3 , 4.0 , 5.0 ); +} + +BOOST_AUTO_TEST_CASE( explicit_error_k54_with_range_v5 ) +{ + vector_fixture f; + boost::numeric::odeint::runge_kutta_cash_karp54_classic< state_type > rk54; + rk54.do_step( system2() , std::make_pair( f.in.begin() + 1 , f.in.begin() + 4 ) , 0.1 , 0.1 , f.err ); + CHECK_VALUES( f.in , 0.0 , 1.1 , 2.2 , 3.3 , 4.0 , 5.0 ); +} + + +BOOST_AUTO_TEST_CASE( runge_kutta_dopri5_with_range_v1 ) +{ + vector_fixture f; + boost::numeric::odeint::runge_kutta_dopri5< state_type > dopri5; + dopri5.do_step( system2() , std::make_pair( f.in.begin() + 1 , f.in.begin() + 4 ) , 0.1 , 0.1 ); + CHECK_VALUES( f.in , 0.0 , 1.1 , 2.2 , 3.3 , 4.0 , 5.0 ); +} + + +BOOST_AUTO_TEST_CASE( runge_kutta_dopri5_with_range_v5 ) +{ + vector_fixture f; + boost::numeric::odeint::runge_kutta_dopri5< state_type > dopri5; + dopri5.do_step( system2() , std::make_pair( f.in.begin() + 1 , f.in.begin() + 4 ) , 0.1 , 0.1 , f.err ); + CHECK_VALUES( f.in , 0.0 , 1.1 , 2.2 , 3.3 , 4.0 , 5.0 ); +} + + +BOOST_AUTO_TEST_CASE( controlled_error_stepper_rk54 ) +{ + double t = 0.0 , dt = 0.1; + vector_fixture f; + boost::numeric::odeint::controlled_runge_kutta< boost::numeric::odeint::runge_kutta_cash_karp54_classic< state_type > > stepper; + stepper.try_step( system2() , std::make_pair( f.in.begin() + 1 , f.in.begin() + 4 ) , t , dt ); + CHECK_VALUES( f.in , 0.0 , 1.1 , 2.2 , 3.3 , 4.0 , 5.0 ); +} + +BOOST_AUTO_TEST_CASE( controlled_error_stepper_dopri5 ) +{ + double t = 0.0 , dt = 0.1; + vector_fixture f; + boost::numeric::odeint::controlled_runge_kutta< boost::numeric::odeint::runge_kutta_dopri5< state_type > > stepper; + stepper.try_step( system2() , std::make_pair( f.in.begin() + 1 , f.in.begin() + 4 ) , t , dt ); + CHECK_VALUES( f.in , 0.0 , 1.1 , 2.2 , 3.3 , 4.0 , 5.0 ); +} + + +BOOST_AUTO_TEST_CASE( symplectic_euler_coor_func ) +{ + vector_fixture f; + boost::numeric::odeint::symplectic_euler< state_type > euler; + euler.do_step( ham_sys() , + std::make_pair( f.q.begin() + 1 , f.q.begin() + 4 ) , + std::make_pair( f.p.begin() + 3 , f.p.begin() + 6 ) , + 0.0 , 0.1 ); + CHECK_VALUES( f.q , 0.0 , 1.3 , 2.4 , 3.5 , 4.0 , 5.0 ); + CHECK_VALUES( f.p , 0.0 , 1.0 , 2.0 , 3.1 , 4.2 , 5.3 ); +} + +BOOST_AUTO_TEST_CASE( symplectic_euler_coor_and_mom_func ) +{ + vector_fixture f; + boost::numeric::odeint::symplectic_euler< state_type > euler; + euler.do_step( std::make_pair( ham_sys() , ham_sys() ) , + std::make_pair( f.q.begin() + 1 , f.q.begin() + 4 ) , + std::make_pair( f.p.begin() + 3 , f.p.begin() + 6 ) , + 0.0 , 0.1 ); + CHECK_VALUES( f.q , 0.0 , 1.1 , 2.2 , 3.3 , 4.0 , 5.0 ); + CHECK_VALUES( f.p , 0.0 , 1.0 , 2.0 , 3.1 , 4.2 , 5.3 ); +} + + +BOOST_AUTO_TEST_CASE( dense_output_euler_with_ranges ) +{ + using namespace boost::numeric::odeint; + vector_fixture f; + dense_output_runge_kutta< euler< state_type > > stepper; + stepper.initialize( std::make_pair( f.in.begin() + 1, f.in.begin() + 4 ) , 0.0 , 0.1 ); + stepper.do_step( system1() ); + stepper.calc_state( 0.05 , std::make_pair( f.in.begin() + 1 ,f.in.begin() +4 ) ); + CHECK_VALUES( f.in , 0.0 , 1.05 , 2.1 , 3.15 , 4.0 , 5.0 ); +} + +BOOST_AUTO_TEST_CASE( dense_output_dopri5_with_ranges ) +{ + using namespace boost::numeric::odeint; + vector_fixture f; + dense_output_runge_kutta< + controlled_runge_kutta< + runge_kutta_dopri5< state_type > + > > stepper; + stepper.initialize( std::make_pair( f.in.begin() + 1, f.in.begin() + 4 ) , 0.0 , 0.1 ); + stepper.do_step( system2() ); + stepper.calc_state( 0.05 , std::make_pair( f.in.begin() + 1 ,f.in.begin() +4 ) ); + CHECK_VALUES( f.in , 0.0 , 1.05 , 2.1 , 3.15 , 4.0 , 5.0 ); +} + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/stepper_with_units.cpp b/src/boost/libs/numeric/odeint/test/stepper_with_units.cpp new file mode 100644 index 000000000..3e3a64508 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/stepper_with_units.cpp @@ -0,0 +1,328 @@ +/* + [auto_generated] + libs/numeric/odeint/test/stepper_with_units.cpp + + [begin_description] + This file tests if the steppers play well with Boost.Units. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011-2013 Mario Mulansky + + 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) + */ + +#define BOOST_TEST_MODULE odeint_stepper_with_units + +// the runge-kutta 78 stepper invoked with boost units requires increased fusion macro variables! +// note that by default the rk78 + units test case is disabled as it requires enormous memory when compiling (5 GB) +#define BOOST_FUSION_INVOKE_MAX_ARITY 15 +#define BOOST_RESULT_OF_NUM_ARGS 15 + + +#include <boost/numeric/odeint/config.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/units/systems/si/length.hpp> +#include <boost/units/systems/si/time.hpp> +#include <boost/units/systems/si/velocity.hpp> +#include <boost/units/systems/si/acceleration.hpp> +#include <boost/units/systems/si/io.hpp> + +#include <boost/fusion/container.hpp> +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint/stepper/euler.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4_classic.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54_classic.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_fehlberg78.hpp> +#include <boost/numeric/odeint/stepper/controlled_runge_kutta.hpp> +#include <boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp> +#include <boost/numeric/odeint/stepper/bulirsch_stoer.hpp> +#include <boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp> +#include <boost/numeric/odeint/algebra/fusion_algebra.hpp> +#include <boost/numeric/odeint/algebra/fusion_algebra_dispatcher.hpp> + + +using namespace boost::numeric::odeint; +using namespace boost::unit_test; +namespace mpl = boost::mpl; +namespace fusion = boost::fusion; +namespace units = boost::units; +namespace si = boost::units::si; + +typedef double value_type; +typedef units::quantity< si::time , value_type > time_type; +typedef units::quantity< si::length , value_type > length_type; +typedef units::quantity< si::velocity , value_type > velocity_type; +typedef units::quantity< si::acceleration , value_type > acceleration_type; +typedef fusion::vector< length_type , velocity_type > state_type; +typedef fusion::vector< velocity_type , acceleration_type > deriv_type; + +void oscillator( const state_type &x , deriv_type &dxdt , time_type t ) +{ + const units::quantity< si::frequency , value_type > omega = 1.0 * si::hertz; + fusion::at_c< 0 >( dxdt ) = fusion::at_c< 1 >( x ); + fusion::at_c< 1 >( dxdt ) = - omega * omega * fusion::at_c< 0 >( x ); +} + +template< class Stepper > +void check_stepper( Stepper &stepper ) +{ + typedef Stepper stepper_type; + typedef typename stepper_type::state_type state_type; + typedef typename stepper_type::value_type value_type; + typedef typename stepper_type::deriv_type deriv_type; + typedef typename stepper_type::time_type time_type; + typedef typename stepper_type::order_type order_type; + typedef typename stepper_type::algebra_type algebra_type; + typedef typename stepper_type::operations_type operations_type; + + const time_type t( 0.0 * si::second ); + time_type dt( 0.1 * si::second ); + state_type x( 1.0 * si::meter , 0.0 * si::meter_per_second ); + + // test call method one + stepper.do_step( oscillator , x , t , dt ); + + // test call method two + stepper.do_step( oscillator , x , t , x , dt ); + + // test call method three + deriv_type dxdt; + oscillator( x , dxdt , t ); + stepper.do_step( oscillator , x , dxdt , t , dt ); + + // test call method four + oscillator( x , dxdt , t ); + stepper.do_step( oscillator , x , dxdt , t , x , dt ); +} + +template< class Stepper > +void check_fsal_stepper( Stepper &stepper ) +{ + typedef Stepper stepper_type; + typedef typename stepper_type::state_type state_type; + typedef typename stepper_type::value_type value_type; + typedef typename stepper_type::deriv_type deriv_type; + typedef typename stepper_type::time_type time_type; + typedef typename stepper_type::order_type order_type; + typedef typename stepper_type::algebra_type algebra_type; + typedef typename stepper_type::operations_type operations_type; + + const time_type t( 0.0 * si::second ); + time_type dt( 0.1 * si::second ); + state_type x( 1.0 * si::meter , 0.0 * si::meter_per_second ); + + // test call method one + stepper.do_step( oscillator , x , t , dt ); + + // test call method two + stepper.do_step( oscillator , x , t , x , dt ); + + // test call method three + deriv_type dxdt; + oscillator( x , dxdt , t ); + stepper.do_step( oscillator , x , dxdt , t , dt ); + + // test call method four + stepper.do_step( oscillator , x , dxdt , t , x , dxdt , dt ); +} + +template< class Stepper > +void check_error_stepper( Stepper &stepper ) +{ + typedef Stepper stepper_type; + typedef typename stepper_type::state_type state_type; + typedef typename stepper_type::value_type value_type; + typedef typename stepper_type::deriv_type deriv_type; + typedef typename stepper_type::time_type time_type; + typedef typename stepper_type::order_type order_type; + typedef typename stepper_type::algebra_type algebra_type; + typedef typename stepper_type::operations_type operations_type; + + const time_type t( 0.0 * si::second ); + time_type dt( 0.1 * si::second ); + state_type x( 1.0 * si::meter , 0.0 * si::meter_per_second ) , xerr; + + // test call method one + stepper.do_step( oscillator , x , t , dt , xerr ); + + // test call method two + stepper.do_step( oscillator , x , t , x , dt , xerr ); + + // test call method three + deriv_type dxdt; + oscillator( x , dxdt , t ); + stepper.do_step( oscillator , x , dxdt , t , dt , xerr ); + + // test call method four + stepper.do_step( oscillator , x , dxdt , t , x , dt , xerr ); +} + +template< class Stepper > +void check_fsal_error_stepper( Stepper &stepper ) +{ + typedef Stepper stepper_type; + typedef typename stepper_type::state_type state_type; + typedef typename stepper_type::value_type value_type; + typedef typename stepper_type::deriv_type deriv_type; + typedef typename stepper_type::time_type time_type; + typedef typename stepper_type::order_type order_type; + typedef typename stepper_type::algebra_type algebra_type; + typedef typename stepper_type::operations_type operations_type; + + const time_type t( 0.0 * si::second ); + time_type dt( 0.1 * si::second ); + state_type x( 1.0 * si::meter , 0.0 * si::meter_per_second ) , xerr; + + // test call method one + stepper.do_step( oscillator , x , t , dt , xerr ); + + // test call method two + stepper.do_step( oscillator , x , t , x , dt , xerr ); + + // test call method three + deriv_type dxdt; + oscillator( x , dxdt , t ); + stepper.do_step( oscillator , x , dxdt , t , dt , xerr ); + + // test call method four + stepper.do_step( oscillator , x , dxdt , t , x , dxdt , dt , xerr ); +} + +template< class Stepper > +void check_controlled_stepper( Stepper &stepper ) +{ + typedef Stepper stepper_type; + typedef typename stepper_type::state_type state_type; + typedef typename stepper_type::value_type value_type; + typedef typename stepper_type::deriv_type deriv_type; + typedef typename stepper_type::time_type time_type; + + time_type t( 0.0 * si::second ); + time_type dt( 0.1 * si::second ); + state_type x( 1.0 * si::meter , 0.0 * si::meter_per_second ); + + // test call method one + stepper.try_step( oscillator , x , t , dt ); +} + + +template< class Stepper > +void check_dense_output_stepper( Stepper &stepper ) +{ + typedef Stepper stepper_type; + typedef typename stepper_type::state_type state_type; + typedef typename stepper_type::value_type value_type; + typedef typename stepper_type::deriv_type deriv_type; + typedef typename stepper_type::time_type time_type; +// typedef typename stepper_type::order_type order_type; + + time_type t( 0.0 * si::second ); + time_type dt( 0.1 * si::second ); + state_type x( 1.0 * si::meter , 0.0 * si::meter_per_second ) , x2; + + stepper.initialize( x , t , dt ); + stepper.do_step( oscillator ); + stepper.calc_state( dt / 2.0 , x2 ); +} + + + + + + +class stepper_types : public mpl::vector +< + euler< state_type , value_type , deriv_type , time_type >, + runge_kutta4< state_type , value_type , deriv_type , time_type > , + runge_kutta4_classic< state_type , value_type , deriv_type , time_type > , + runge_kutta_cash_karp54< state_type , value_type , deriv_type , time_type >, + runge_kutta_cash_karp54_classic< state_type , value_type , deriv_type , time_type > + // don't run rk78 test - gcc requires > 5GB RAM to compile this + //, runge_kutta_fehlberg78< state_type , value_type , deriv_type , time_type > + > { }; + +class fsal_stepper_types : public mpl::vector +< + runge_kutta_dopri5< state_type , value_type , deriv_type , time_type > + > { }; + +class error_stepper_types : public mpl::vector +< + runge_kutta_cash_karp54_classic< state_type , value_type , deriv_type , time_type > + //, runge_kutta_fehlberg78< state_type , value_type , deriv_type , time_type > + > { }; + +class fsal_error_stepper_types : public mpl::vector +< + runge_kutta_dopri5< state_type , value_type , deriv_type , time_type > + > { }; + +class controlled_stepper_types : public mpl::vector +< + controlled_runge_kutta< runge_kutta_cash_karp54_classic< state_type , value_type , deriv_type , time_type > > , + controlled_runge_kutta< runge_kutta_dopri5< state_type , value_type , deriv_type , time_type > > + , bulirsch_stoer< state_type , value_type , deriv_type , time_type > + // rk78 with units needs up to 3GB memory to compile - disable testing... + //, controlled_runge_kutta< runge_kutta_fehlberg78< state_type , value_type , deriv_type , time_type > > + > { }; + +class dense_output_stepper_types : public mpl::vector +< + dense_output_runge_kutta< euler< state_type , value_type , deriv_type , time_type > > , + dense_output_runge_kutta< + controlled_runge_kutta< runge_kutta_dopri5< state_type , value_type , deriv_type , time_type > > > + //, bulirsch_stoer_dense_out< state_type , value_type , deriv_type , time_type > + > { }; + + + + +BOOST_AUTO_TEST_SUITE( stepper_with_units ) + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_test , Stepper , stepper_types ) +{ + Stepper stepper; + check_stepper( stepper ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( fsl_stepper_test , Stepper , fsal_stepper_types ) +{ + Stepper stepper; + check_fsal_stepper( stepper ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( error_stepper_test , Stepper , error_stepper_types ) +{ + Stepper stepper; + check_error_stepper( stepper ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( fsal_error_stepper_test , Stepper , fsal_error_stepper_types ) +{ + Stepper stepper; + check_fsal_error_stepper( stepper ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( controlled_stepper_test , Stepper , controlled_stepper_types ) +{ + Stepper stepper; + check_controlled_stepper( stepper ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( dense_ouput_test , Stepper , dense_output_stepper_types ) +{ + Stepper stepper; + check_dense_output_stepper( stepper ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/symplectic_steppers.cpp b/src/boost/libs/numeric/odeint/test/symplectic_steppers.cpp new file mode 100644 index 000000000..498983bdd --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/symplectic_steppers.cpp @@ -0,0 +1,391 @@ +/* + [auto_generated] + libs/numeric/odeint/test/symplectic_steppers.cpp + + [begin_description] + tba. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2013 Mario Mulansky + + 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) + */ + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_symplectic_steppers + +#define BOOST_FUSION_INVOKE_MAX_ARITY 15 +#define BOOST_RESULT_OF_NUM_ARGS 15 +#define FUSION_MAX_VECTOR_SIZE 15 + + +#include <boost/test/unit_test.hpp> + +#include <boost/array.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <boost/mpl/vector.hpp> +#include <boost/mpl/zip_view.hpp> +#include <boost/mpl/vector_c.hpp> +#include <boost/mpl/insert_range.hpp> +#include <boost/mpl/end.hpp> +#include <boost/mpl/size.hpp> +#include <boost/mpl/copy.hpp> +#include <boost/mpl/placeholders.hpp> +#include <boost/mpl/inserter.hpp> +#include <boost/mpl/at.hpp> + +#include <boost/fusion/container/vector.hpp> +#include <boost/fusion/include/make_vector.hpp> + +#include <boost/numeric/odeint/algebra/vector_space_algebra.hpp> +#include <boost/numeric/odeint/algebra/fusion_algebra.hpp> +#include <boost/numeric/odeint/stepper/symplectic_euler.hpp> +#include <boost/numeric/odeint/stepper/symplectic_rkn_sb3a_mclachlan.hpp> +#include <boost/numeric/odeint/stepper/symplectic_rkn_sb3a_m4_mclachlan.hpp> +#include <boost/numeric/odeint/integrate/integrate_const.hpp> + +#include "diagnostic_state_type.hpp" +#include "const_range.hpp" +#include "dummy_odes.hpp" +#include "boost_units_helpers.hpp" + + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; +namespace fusion = boost::fusion; + +class custom_range_algebra : public range_algebra { }; +class custom_default_operations : public default_operations { }; + + +template< class Coor , class Mom , class Value , class CoorDeriv , class MomDeriv , class Time , + class Algebra , class Operations , class Resizer > +class complete_steppers : public mpl::vector< + symplectic_euler< Coor , Mom , Value , CoorDeriv , MomDeriv , Time , + Algebra , Operations , Resizer > + , symplectic_rkn_sb3a_mclachlan< Coor , Mom , Value , CoorDeriv , MomDeriv , Time , + Algebra , Operations , Resizer > + , symplectic_rkn_sb3a_m4_mclachlan< Coor , Mom , Value , CoorDeriv , MomDeriv , Time , + Algebra , Operations , Resizer > + > {}; + +template< class Resizer > +class vector_steppers : public complete_steppers< + diagnostic_state_type , diagnostic_state_type2 , double , + diagnostic_deriv_type , diagnostic_deriv_type2 , double , + custom_range_algebra , custom_default_operations , Resizer + > { }; + + +typedef mpl::vector< initially_resizer , always_resizer , never_resizer > resizers; +typedef mpl::vector_c< int , 1 , 3 , 0 > resizer_multiplicities ; + + +typedef mpl::copy< + resizers , + mpl::inserter< + mpl::vector0<> , + mpl::insert_range< + mpl::_1 , + mpl::end< mpl::_1 > , + vector_steppers< mpl::_2 > + > + > + >::type all_stepper_methods; + + +typedef mpl::size< vector_steppers< initially_resizer > >::type num_steppers; +typedef mpl::copy< + resizer_multiplicities , + mpl::inserter< + mpl::vector0<> , + mpl::insert_range< + mpl::_1 , + mpl::end< mpl::_1 > , + const_range< num_steppers , mpl::_2 > + > + > + >::type all_multiplicities; + + + + + + + +BOOST_AUTO_TEST_SUITE( symplectic_steppers_test ) + + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_assoc_types , Stepper , vector_steppers< initially_resizer > ) +{ + BOOST_STATIC_ASSERT_MSG( + ( boost::is_same< typename Stepper::coor_type , diagnostic_state_type >::value ) , + "Coordinate type" ); + BOOST_STATIC_ASSERT_MSG( + ( boost::is_same< typename Stepper::momentum_type , diagnostic_state_type2 >::value ) , + "Momentum type" ); + BOOST_STATIC_ASSERT_MSG( + ( boost::is_same< typename Stepper::coor_deriv_type , diagnostic_deriv_type >::value ) , + "Coordinate deriv type" ); + BOOST_STATIC_ASSERT_MSG( + ( boost::is_same< typename Stepper::momentum_deriv_type , diagnostic_deriv_type2 >::value ) , + "Momentum deriv type" ); + + BOOST_STATIC_ASSERT_MSG( + ( boost::is_same< typename Stepper::state_type , std::pair< diagnostic_state_type , diagnostic_state_type2 > >::value ) , + "State type" ); + BOOST_STATIC_ASSERT_MSG( + ( boost::is_same< typename Stepper::deriv_type , std::pair< diagnostic_deriv_type , diagnostic_deriv_type2 > >::value ) , + "Deriv type" ); + + BOOST_STATIC_ASSERT_MSG( ( boost::is_same< typename Stepper::value_type , double >::value ) , "Value type" ); + BOOST_STATIC_ASSERT_MSG( ( boost::is_same< typename Stepper::time_type , double >::value ) , "Time type" ); + BOOST_STATIC_ASSERT_MSG( ( boost::is_same< typename Stepper::algebra_type , custom_range_algebra >::value ) , "Algebra type" ); + BOOST_STATIC_ASSERT_MSG( ( boost::is_same< typename Stepper::operations_type , custom_default_operations >::value ) , "Operations type" ); + + BOOST_STATIC_ASSERT_MSG( ( boost::is_same< typename Stepper::resizer_type , initially_resizer >::value ) , "Resizer type" ); + BOOST_STATIC_ASSERT_MSG( ( boost::is_same< typename Stepper::stepper_category , stepper_tag >::value ) , "Stepper category" ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_adjust_size , Stepper , vector_steppers< initially_resizer > ) +{ + counter_state::init_counter(); + counter_deriv::init_counter(); + counter_state2::init_counter(); + counter_deriv2::init_counter(); + + { + Stepper stepper; + diagnostic_state_type x; + stepper.adjust_size( x ); + } + + TEST_COUNTERS( counter_state , 0 , 0 , 0 , 0 ); + TEST_COUNTERS( counter_state2 , 0 , 0 , 0 , 0 ); + TEST_COUNTERS( counter_deriv , 1 , 1 , 0 , 1 ); + TEST_COUNTERS( counter_deriv2 , 1 , 1 , 0 , 1 ); +} + + +typedef mpl::zip_view< mpl::vector< all_stepper_methods , all_multiplicities > >::type zipped_steppers; +BOOST_AUTO_TEST_CASE_TEMPLATE( test_resizing , Stepper , zipped_steppers ) +{ + typedef typename mpl::at_c< Stepper , 0 >::type stepper_type; + const size_t multiplicity = mpl::at_c< Stepper , 1 >::type::value; + + counter_state::init_counter(); + counter_deriv::init_counter(); + counter_state2::init_counter(); + counter_deriv2::init_counter(); + + { + stepper_type stepper; + std::pair< diagnostic_state_type , diagnostic_state_type2 > x; + stepper.do_step( constant_mom_func() , x , 0.0 , 0.1 ); + stepper.do_step( constant_mom_func() , x , 0.0 , 0.1 ); + stepper.do_step( constant_mom_func() , x , 0.0 , 0.1 ); + } + + TEST_COUNTERS( counter_state , 0 , 0 , 0 , 0 ); + TEST_COUNTERS( counter_state2 , 0 , 0 , 0 , 0 ); + // dqdt is not needed when called with mom func only, so no resizing + // TEST_COUNTERS( counter_deriv , multiplicity , 1 , 0 , 1 ); + TEST_COUNTERS( counter_deriv2 , multiplicity , 1 , 0 , 1 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_copying1 , Stepper , vector_steppers< initially_resizer > ) +{ + counter_state::init_counter(); + counter_deriv::init_counter(); + counter_state2::init_counter(); + counter_deriv2::init_counter(); + + { + Stepper stepper; + Stepper stepper2( stepper ); + } + + TEST_COUNTERS( counter_state , 0 , 0 , 0 , 0 ); + TEST_COUNTERS( counter_state2 , 0 , 0 , 0 , 0 ); + TEST_COUNTERS( counter_deriv , 0 , 2 , 1 , 2 ); + TEST_COUNTERS( counter_deriv2 , 0 , 2 , 1 , 2 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_copying2 , Stepper , vector_steppers< initially_resizer > ) +{ + counter_state::init_counter(); + counter_deriv::init_counter(); + counter_state2::init_counter(); + counter_deriv2::init_counter(); + + { + Stepper stepper; + std::pair< diagnostic_state_type , diagnostic_state_type2 > x; + stepper.do_step( constant_mom_func() , x , 0.0 , 0.1 ); + Stepper stepper2( stepper ); + } + + TEST_COUNTERS( counter_state , 0 , 0 , 0 , 0 ); + TEST_COUNTERS( counter_state2 , 0 , 0 , 0 , 0 ); + // dqdt is not needed when called with mom func only, so no resizing + //TEST_COUNTERS( counter_deriv , 1 , 2 , 1 , 2 ); + TEST_COUNTERS( counter_deriv2 , 1 , 2 , 1 , 2 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_do_step_v1 , Stepper , vector_steppers< initially_resizer > ) +{ + Stepper s; + std::pair< diagnostic_state_type , diagnostic_state_type2 > x1 , x2 , x3 , x4; + x1.first[0] = 1.0; + x1.second[0] = 2.0; + x2 = x3 = x4 = x1; + diagnostic_state_type x5_coor , x5_mom; + x5_coor[0] = x1.first[0]; + x5_mom[0] = x1.second[0]; + + s.do_step( constant_mom_func() , x1 , 0.0 , 0.1 ); + + s.do_step( std::make_pair( default_coor_func() , constant_mom_func() ) , x2 , 0.0 , 0.1 ); + + default_coor_func cf; + constant_mom_func mf; + s.do_step( std::make_pair( boost::ref( cf ) , boost::ref( mf ) ) , x3 , 0.0 , 0.1 ); + + std::pair< default_coor_func , constant_mom_func > pf; + s.do_step( boost::ref( pf ) , x4 , 0.0 , 0.1 ); + + s.do_step( constant_mom_func() , std::make_pair( boost::ref( x5_coor ) , boost::ref( x5_mom ) ) , 0.0 , 0.1 ); + + // checking for absolute values is not possible here, since the steppers are to different + BOOST_CHECK_CLOSE( x1.first[0] , x2.first[0] , 1.0e-14 ); + BOOST_CHECK_CLOSE( x2.first[0] , x3.first[0] , 1.0e-14 ); + BOOST_CHECK_CLOSE( x3.first[0] , x4.first[0] , 1.0e-14 ); + BOOST_CHECK_CLOSE( x4.first[0] , x5_coor[0] , 1.0e-14 ); + + BOOST_CHECK_CLOSE( x1.second[0] , x2.second[0] , 1.0e-14 ); + BOOST_CHECK_CLOSE( x2.second[0] , x3.second[0] , 1.0e-14 ); + BOOST_CHECK_CLOSE( x3.second[0] , x4.second[0] , 1.0e-14 ); + BOOST_CHECK_CLOSE( x4.second[0] , x5_mom[0] , 1.0e-14 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_do_step_range , Stepper , vector_steppers< initially_resizer > ) +{ + Stepper s; + diagnostic_state_type q , p ; + q[0] = 1.0; + p[0] = 2.0; + + std::vector< double > x; + x.push_back( 1.0 ); + x.push_back( 2.0 ); + s.do_step( constant_mom_func() , + std::make_pair( x.begin() , x.begin() + 1 ) , + std::make_pair( x.begin() + 1 , x.begin() + 2 ) , + 0.0 , 0.1 ); + + s.do_step( constant_mom_func() , q , p , 0.0 , 0.1 ); + + BOOST_CHECK_CLOSE( q[0] , x[0] , 1.0e-14 ); + BOOST_CHECK_CLOSE( p[0] , x[1] , 1.0e-14 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_do_step_v2 , Stepper , vector_steppers< initially_resizer > ) +{ + Stepper s; + diagnostic_state_type q , p ; + q[0] = 1.0; + p[0] = 2.0; + diagnostic_state_type q2 = q , p2 = p; + + + s.do_step( constant_mom_func() , q , p , 0.0 , 0.1 ); + s.do_step( constant_mom_func() , std::make_pair( boost::ref( q2 ) , boost::ref( p2 ) ) , 0.0 , 0.1 ); + + BOOST_CHECK_CLOSE( q[0] , q2[0] , 1.0e-14 ); + BOOST_CHECK_CLOSE( p[0] , p2[0] , 1.0e-14 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_do_step_v3 , Stepper , vector_steppers< initially_resizer > ) +{ + Stepper s; + std::pair< diagnostic_state_type , diagnostic_state_type2 > x_in , x_out; + x_in.first[0] = 1.0; + x_in.second[0] = 2.0; + diagnostic_state_type q2 , p2; + q2[0] = x_in.first[0]; + p2[0] = x_in.second[0]; + + + s.do_step( constant_mom_func() , x_in , 0.0 , x_out , 0.1 ); + s.do_step( constant_mom_func() , std::make_pair( boost::ref( q2 ) , boost::ref( p2 ) ) , 0.0 , 0.1 ); + + BOOST_CHECK_CLOSE( x_in.first[0] , 1.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( x_in.second[0] , 2.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( x_out.first[0] , q2[0] , 1.0e-14 ); + BOOST_CHECK_CLOSE( x_out.second[0] , p2[0] , 1.0e-14 ); +} + + +typedef double vector_space; +typedef complete_steppers< vector_space , vector_space , double , + vector_space , vector_space , double , + vector_space_algebra , default_operations , initially_resizer > vector_space_steppers; +BOOST_AUTO_TEST_CASE_TEMPLATE( test_with_vector_space_algebra , Stepper , vector_space_steppers ) +{ + Stepper s; + std::pair< vector_space , vector_space > x; + s.do_step( constant_mom_func_vector_space_1d() , x , 0.0 , 0.1 ); + + s.do_step( std::make_pair( default_coor_func_vector_space_1d() , constant_mom_func_vector_space_1d() ) , x , 0.0 , 0.1 ); +} + + +typedef boost::fusion::vector< length_type > coor_type; +typedef boost::fusion::vector< velocity_type > mom_type; +typedef boost::fusion::vector< acceleration_type > acc_type; +typedef complete_steppers< coor_type , mom_type , double , + mom_type , acc_type , time_type, + fusion_algebra , default_operations , initially_resizer > boost_unit_steppers; +BOOST_AUTO_TEST_CASE_TEMPLATE( test_with_boost_units , Stepper , boost_unit_steppers ) +{ + namespace fusion = boost::fusion; + namespace si = boost::units::si; + Stepper s; + + coor_type q = fusion::make_vector( 1.0 * si::meter ); + mom_type p = fusion::make_vector( 2.0 * si::meter_per_second ); + time_type t = 0.0 * si::second; + time_type dt = 0.1 * si::second; + + coor_type q1 = q , q2 = q; + mom_type p1 = p , p2 = p; + + s.do_step( oscillator_mom_func_units() , std::make_pair( boost::ref( q ) , boost::ref( p ) ) , t , dt ); + + s.do_step( std::make_pair( oscillator_coor_func_units() , oscillator_mom_func_units() ) , + std::make_pair( boost::ref( q1 ) , boost::ref( p1 ) ) , t , dt ); + + s.do_step( oscillator_mom_func_units() , q2 , p2 , t , dt ); + + BOOST_CHECK_CLOSE( ( fusion::at_c< 0 >( q ).value() ) , ( fusion::at_c< 0 >( q1 ).value() ) , 1.0e-14 ); + BOOST_CHECK_CLOSE( ( fusion::at_c< 0 >( q1 ).value() ) , ( fusion::at_c< 0 >( q2 ).value() ) , 1.0e-14 ); + BOOST_CHECK_CLOSE( ( fusion::at_c< 0 >( p ).value() ) , ( fusion::at_c< 0 >( p1 ).value() ) , 1.0e-14 ); + BOOST_CHECK_CLOSE( ( fusion::at_c< 0 >( p1 ).value() ) , ( fusion::at_c< 0 >( p2 ).value() ) , 1.0e-14 ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/times_iterator.cpp b/src/boost/libs/numeric/odeint/test/times_iterator.cpp new file mode 100644 index 000000000..552d5af78 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/times_iterator.cpp @@ -0,0 +1,237 @@ +/* + [auto_generated] + libs/numeric/odeint/test/times_iterator.cpp + + [begin_description] + This file tests the n-step iterator. + [end_description] + + Copyright 2009-2013 Karsten Ahnert + Copyright 2009-2013 Mario Mulansky + + 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) + */ + + +#define BOOST_TEST_MODULE odeint_times_iterator + +#include <iterator> +#include <algorithm> +#include <vector> +#include <iostream> + +#include <boost/numeric/odeint/config.hpp> +#include <boost/array.hpp> +#include <boost/range/algorithm/for_each.hpp> +#include <boost/range/algorithm/copy.hpp> +#include <boost/mpl/vector.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> + +#include <boost/numeric/odeint/iterator/times_iterator.hpp> +#include "dummy_steppers.hpp" +#include "dummy_odes.hpp" +#include "dummy_observers.hpp" + +namespace mpl = boost::mpl; +using namespace boost::numeric::odeint; + +typedef dummy_stepper::state_type state_type; +typedef dummy_stepper::value_type value_type; + + +BOOST_AUTO_TEST_SUITE( times_iterator_test ) + +typedef mpl::vector< + dummy_stepper + , dummy_dense_output_stepper + > dummy_steppers; + +boost::array<double,4> times = {{ 0.0 , 0.1, 0.2, 0.3 }}; +typedef boost::array<double,4>::iterator time_iterator_type; + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_stepper_iterator , Stepper , dummy_steppers ) +{ + typedef times_iterator< Stepper , empty_system , state_type , time_iterator_type > iterator_type; + state_type x = {{ 1.0 }}; + iterator_type iter1 = iterator_type( Stepper() , empty_system() , x , times.begin() , times.end() , 0.1 ); + iterator_type iter2 = iter1; + BOOST_CHECK_EQUAL( &(*iter1) , &(*iter2) ); + BOOST_CHECK_EQUAL( &(*iter1) , &x ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( assignment_stepper_iterator , Stepper , dummy_steppers ) +{ + std::cout << "assignment" << std::endl; + typedef times_iterator< Stepper , empty_system , state_type , time_iterator_type> iterator_type; + state_type x1 = {{ 1.0 }} , x2 = {{ 2.0 }}; + iterator_type iter1 = iterator_type( Stepper() , empty_system() , x1 , times.begin() , times.end() , 0.1 ); + iterator_type iter2 = iterator_type( Stepper() , empty_system() , x2 , times.begin() , times.end() , 0.2 ); + BOOST_CHECK_EQUAL( &(*iter1) , &x1 ); + BOOST_CHECK_EQUAL( &(*iter2) , &x2 ); + BOOST_CHECK( !iter1.same( iter2 ) ); + iter2 = iter1; + BOOST_CHECK_EQUAL( &(*iter1) , &x1 ); + BOOST_CHECK_EQUAL( &(*iter2) , &x1 ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_iterator_factory , Stepper , dummy_steppers ) +{ + std::cout << "factory" << std::endl; + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_times_iterator_begin( stepper , boost::ref( system ) , x , times.begin(), times.end() , 0.1 ) , + make_times_iterator_end<time_iterator_type>( stepper , boost::ref( system ) , x ) , + dummy_observer() ); + + // dummy_steppers just add 0.25 at each step, the above for_each leads to 3 do_step calls so x should be 1.75 + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_range , Stepper , dummy_steppers ) +{ + std::cout << "range" << std::endl; + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_times_range( stepper , boost::ref( system ) , x , times.begin() , times.end() , 0.1 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_iterator_with_reference_wrapper_factory , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_times_iterator_begin( boost::ref( stepper ) , boost::ref( system ) , x , times.begin() , times.end() , 0.1 ) , + make_times_iterator_end<time_iterator_type>( boost::ref( stepper ) , boost::ref( system ) , x ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_range_with_reference_wrapper , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_times_range( boost::ref( stepper ) , boost::ref( system ) , x , times.begin() , times.end(), 0.1 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( transitivity1 , Stepper , dummy_steppers ) +{ + typedef times_iterator< Stepper , empty_system , state_type , time_iterator_type > stepper_iterator; + std::cout << "transitivity1" << std::endl; + state_type x = {{ 1.0 }}; + stepper_iterator first1( Stepper() , empty_system() , x , times.end() , times.end() , 0.1 ); + stepper_iterator last1( Stepper() , empty_system() , x ); + stepper_iterator last2( Stepper() , empty_system() , x ); + + BOOST_CHECK( first1 == last1 ); + BOOST_CHECK( first1 == last2 ); + BOOST_CHECK( last1 == last2 ); + + first1 = stepper_iterator( Stepper() , empty_system() , x , times.end()-1 , times.end() , 0.1 ); + last1 = stepper_iterator( Stepper() , empty_system() , x ); + BOOST_CHECK( first1 != last1 ); + BOOST_CHECK( ++first1 == last1 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm , Stepper , dummy_steppers ) +{ + typedef times_iterator< Stepper , empty_system , state_type , time_iterator_type> stepper_iterator; + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + stepper_iterator first( Stepper() , empty_system() , x , times.begin() , times.end() , 0.1 ); + stepper_iterator last( Stepper() , empty_system() , x ); + + std::copy( first , last , std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-13 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); // the iterator should not iterate over the end +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_negative_time_step , Stepper , dummy_steppers ) +{ + typedef times_iterator< Stepper , empty_system , state_type , time_iterator_type > stepper_iterator; + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + boost::array<double,4> neg_times = {{ 0.0 , -0.1, -0.2, -0.3 }}; + stepper_iterator first( Stepper() , empty_system() , x , neg_times.begin() , neg_times.end() , -0.1 ); + stepper_iterator last( Stepper() , empty_system() , x ); + + std::copy( first , last , std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-13 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + std::copy( make_times_iterator_begin( Stepper() , empty_system() , x , times.begin() , times.end() , 0.1 ) , + make_times_iterator_end<time_iterator_type>( Stepper() , empty_system() , x ) , + std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-13 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_range_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + boost::range::copy( make_times_range( Stepper() , empty_system() , x , times.begin() , times.end() , 0.1 ) , + std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-13 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/times_time_iterator.cpp b/src/boost/libs/numeric/odeint/test/times_time_iterator.cpp new file mode 100644 index 000000000..274f8a621 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/times_time_iterator.cpp @@ -0,0 +1,250 @@ +/* + [auto_generated] + libs/numeric/odeint/test/times_time_iterator.cpp + + [begin_description] + This file tests the times iterator. + [end_description] + + Copyright 2009-2013 Karsten Ahnert + Copyright 2009-2013 Mario Mulansky + + 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) + */ + + +#define BOOST_TEST_MODULE odeint_times_time_iterator + +#include <iterator> +#include <algorithm> +#include <vector> +#include <iostream> + +#include <boost/numeric/odeint/config.hpp> +#include <boost/array.hpp> +#include <boost/range/algorithm/for_each.hpp> +#include <boost/range/algorithm/copy.hpp> +#include <boost/mpl/vector.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> + +#include <boost/numeric/odeint/iterator/times_time_iterator.hpp> +#include "dummy_steppers.hpp" +#include "dummy_odes.hpp" +#include "dummy_observers.hpp" + +namespace mpl = boost::mpl; +using namespace boost::numeric::odeint; + +typedef dummy_stepper::state_type state_type; +typedef dummy_stepper::value_type value_type; +typedef dummy_stepper::time_type time_type; + +BOOST_AUTO_TEST_SUITE( times_time_iterator_test ) + +typedef mpl::vector< + dummy_stepper + , dummy_dense_output_stepper + > dummy_steppers; + +boost::array<double,4> times = {{ 0.0 , 0.1, 0.2, 0.3 }}; +typedef boost::array<double,4>::iterator time_iterator_type; +typedef std::vector< std::pair< state_type , time_type > > result_vector; + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_stepper_iterator , Stepper , dummy_steppers ) +{ + typedef times_time_iterator< Stepper , empty_system , state_type , time_iterator_type > iterator_type; + state_type x = {{ 1.0 }}; + iterator_type iter1 = iterator_type( Stepper() , empty_system() , x , times.begin() , times.end() , 0.1 ); + iterator_type iter2 = iter1; + BOOST_CHECK_EQUAL( &(iter1->first) , &(iter2->first) ); + BOOST_CHECK_EQUAL( &(iter1->first) , &x ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( assignment_stepper_iterator , Stepper , dummy_steppers ) +{ + std::cout << "assignment" << std::endl; + typedef times_time_iterator< Stepper , empty_system , state_type , time_iterator_type> iterator_type; + state_type x1 = {{ 1.0 }} , x2 = {{ 2.0 }}; + iterator_type iter1 = iterator_type( Stepper() , empty_system() , x1 , times.begin() , times.end() , 0.1 ); + iterator_type iter2 = iterator_type( Stepper() , empty_system() , x2 , times.begin() , times.end() , 0.2 ); + BOOST_CHECK_EQUAL( &(iter1->first) , &x1 ); + BOOST_CHECK_EQUAL( &(iter2->first) , &x2 ); + BOOST_CHECK( !iter1.same( iter2 ) ); + iter2 = iter1; + BOOST_CHECK_EQUAL( &(iter1->first) , &x1 ); + BOOST_CHECK_EQUAL( &(iter2->first) , &x1 ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_iterator_factory , Stepper , dummy_steppers ) +{ + std::cout << "factory" << std::endl; + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_times_time_iterator_begin( stepper , boost::ref( system ) , x , times.begin(), times.end() , 0.1 ) , + make_times_time_iterator_end<time_iterator_type>( stepper , boost::ref( system ) , x ) , + dummy_observer() ); + + // dummy_steppers just add 0.25 at each step, the above for_each leads to 3 do_step calls so x should be 1.75 + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_range , Stepper , dummy_steppers ) +{ + std::cout << "range" << std::endl; + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_times_time_range( stepper , boost::ref( system ) , x , times.begin() , times.end() , 0.1 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_iterator_with_reference_wrapper_factory , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_times_time_iterator_begin( boost::ref( stepper ) , boost::ref( system ) , x , times.begin() , times.end() , 0.1 ) , + make_times_time_iterator_end<time_iterator_type>( boost::ref( stepper ) , boost::ref( system ) , x ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_range_with_reference_wrapper , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_times_time_range( boost::ref( stepper ) , boost::ref( system ) , x , times.begin() , times.end(), 0.1 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( transitivity1 , Stepper , dummy_steppers ) +{ + typedef times_time_iterator< Stepper , empty_system , state_type , time_iterator_type > stepper_iterator; + std::cout << "transitivity1" << std::endl; + state_type x = {{ 1.0 }}; + stepper_iterator first1( Stepper() , empty_system() , x , times.end() , times.end() , 0.1 ); + stepper_iterator last1( Stepper() , empty_system() , x ); + stepper_iterator last2( Stepper() , empty_system() , x ); + + BOOST_CHECK( first1 == last1 ); + BOOST_CHECK( first1 == last2 ); + BOOST_CHECK( last1 == last2 ); + + first1 = stepper_iterator( Stepper() , empty_system() , x , times.end()-1 , times.end() , 0.1 ); + last1 = stepper_iterator( Stepper() , empty_system() , x ); + BOOST_CHECK( first1 != last1 ); + BOOST_CHECK( ++first1 == last1 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm , Stepper , dummy_steppers ) +{ + typedef times_time_iterator< Stepper , empty_system , state_type , time_iterator_type> stepper_iterator; + state_type x = {{ 1.0 }}; + result_vector res; + stepper_iterator first( Stepper() , empty_system() , x , times.begin() , times.end() , 0.1 ); + stepper_iterator last( Stepper() , empty_system() , x ); + + std::copy( first , last , std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + + for( size_t n=0 ; n<4 ; ++n ) + BOOST_CHECK_CLOSE( res[n].second , times[n] , 1.0e-13 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); // the iterator should not iterate over the end +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_negative_time_step , Stepper , dummy_steppers ) +{ + typedef times_time_iterator< Stepper , empty_system , state_type , time_iterator_type > stepper_iterator; + state_type x = {{ 1.0 }}; + result_vector res; + boost::array<double,4> neg_times = {{ 0.0 , -0.1, -0.2, -0.3 }}; + stepper_iterator first( Stepper() , empty_system() , x , neg_times.begin() , neg_times.end() , -0.1 ); + stepper_iterator last( Stepper() , empty_system() , x ); + + std::copy( first , last , std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + + for( size_t n=0 ; n<4 ; ++n ) + BOOST_CHECK_CLOSE( res[n].second , neg_times[n] , 1.0e-13 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + result_vector res; + std::copy( make_times_time_iterator_begin( Stepper() , empty_system() , x , times.begin() , times.end() , 0.1 ) , + make_times_time_iterator_end<time_iterator_type>( Stepper() , empty_system() , x ) , + std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + + for( size_t n=0 ; n<4 ; ++n ) + BOOST_CHECK_CLOSE( res[n].second , times[n] , 1.0e-13 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_range_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + result_vector res; + boost::range::copy( make_times_time_range( Stepper() , empty_system() , x , times.begin() , times.end() , 0.1 ) , + std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + + for( size_t n=0 ; n<4 ; ++n ) + BOOST_CHECK_CLOSE( res[n].second , times[n] , 1.0e-13 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/trivial_state.cpp b/src/boost/libs/numeric/odeint/test/trivial_state.cpp new file mode 100644 index 000000000..9976db7fb --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/trivial_state.cpp @@ -0,0 +1,109 @@ +/* + [auto_generated] + libs/numeric/odeint/test/trivial_state.cpp + + [begin_description] + This file tests if the steppers can integrate the trivial state consisting of a single double. + [end_description] + + Copyright 2012-2013 Mario Mulansky + Copyright 2012 Karsten Ahnert + + 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) + */ + +#include <limits> + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_trivial_state + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> +#include <boost/mpl/int.hpp> +#include <boost/mpl/at.hpp> + +#include <boost/numeric/odeint/stepper/euler.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/generation.hpp> +#include <boost/numeric/odeint/integrate/integrate_adaptive.hpp> +#include <boost/numeric/odeint/algebra/vector_space_algebra.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +namespace mpl = boost::mpl; + +struct constant_system +{ + template< typename T > + void operator()( const T &x , T &dxdt , const T t ) const + { dxdt = 1.0; } +}; + + +BOOST_AUTO_TEST_SUITE( trivial_state_test ) + +/* test different do_step methods of simple steppers */ + +typedef mpl::vector< + euler< double > , + runge_kutta4< double > , + // with floats all four parameters have to be given explicitly to override default double + euler< float , float , float , float > , + runge_kutta4< float , float , float , float > + >::type stepper_types; + + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_do_step , T, stepper_types ) +{ + typedef T stepper_type; + stepper_type stepper; + typename stepper_type::state_type x = 0.0; + typename stepper_type::time_type t = 0.0; + typename stepper_type::time_type dt = 0.1; + stepper.do_step( constant_system() , x , t , dt ); + BOOST_CHECK_CLOSE( x , 0.1 , 100*std::numeric_limits< typename stepper_type::state_type >::epsilon() ); + + // this overload is not allowed if the types of dxdt and dt are the same + // deriv_type dxdt = 1.0; + // stepper.do_step( constant_system , x , dxdt , t , dt ); + + typename stepper_type::state_type x_out; + stepper.do_step( constant_system() , x , t , x_out , dt ); + BOOST_CHECK_CLOSE( x , 0.1 , 100*std::numeric_limits< typename stepper_type::state_type >::epsilon() ); + BOOST_CHECK_CLOSE( x_out , 0.2 , 100*std::numeric_limits< typename stepper_type::state_type >::epsilon() ); +} + + +/* test integrate_adaptive with controlled steppers */ + +typedef mpl::vector< + runge_kutta_cash_karp54< double > , + runge_kutta_dopri5< double > , + // with floats all four parameters have to be given explicitly to override default double + runge_kutta_cash_karp54< float , float , float , float > , + runge_kutta_dopri5< float , float , float , float > + > error_stepper_types; + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_integrate , T , error_stepper_types ) +{ + typedef T stepper_type; + typename stepper_type::state_type x = 0.0; + typename stepper_type::time_type t0 = 0.0; + typename stepper_type::time_type t1 = 1.0; + typename stepper_type::time_type dt = 0.1; + integrate_adaptive( make_controlled< stepper_type >( 1e-6 , 1e-6 ) , constant_system() , x , t0 , t1 , dt ); + BOOST_CHECK_CLOSE( x , 1.0 , 100*std::numeric_limits< typename stepper_type::state_type >::epsilon() ); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/unwrap_boost_reference.cpp b/src/boost/libs/numeric/odeint/test/unwrap_boost_reference.cpp new file mode 100644 index 000000000..4106fdf20 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/unwrap_boost_reference.cpp @@ -0,0 +1,40 @@ +/* + [auto_generated] + libs/numeric/odeint/test/unwrap_boost_reference.cpp + + [begin_description] + tba. + [end_description] + + Copyright 2009-2012 Karsten Ahnert + Copyright 2009-2012 Mario Mulansky + + 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) + */ + +#define BOOST_TEST_MODULE odeint_unwrap_boost_reference + +#include <boost/numeric/odeint/util/unwrap_reference.hpp> +#include <boost/test/unit_test.hpp> + +using namespace boost::unit_test; + +template< typename T > +void func( T t ) +{ + typedef typename boost::numeric::odeint::unwrap_reference< T >::type type; +} + +BOOST_AUTO_TEST_SUITE( unwrap_boost_reference_test ) + +BOOST_AUTO_TEST_CASE( test_case ) +{ + int a; + func( boost::ref( a ) ); + func( a ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/unwrap_reference.cpp b/src/boost/libs/numeric/odeint/test/unwrap_reference.cpp new file mode 100644 index 000000000..7337ddd3a --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/unwrap_reference.cpp @@ -0,0 +1,42 @@ +/* + [auto_generated] + libs/numeric/odeint/test/unwrap_reference.cpp + + [begin_description] + tba. + [end_description] + + Copyright 2009-2012 Karsten Ahnert + Copyright 2009-2012 Mario Mulansky + + 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) + */ + + +#define BOOST_TEST_MODULE odeint_unwrap_reference + +#include <boost/numeric/odeint/util/unwrap_reference.hpp> + +#include <boost/test/unit_test.hpp> + +using namespace boost::unit_test; + +template< typename T > +void func( T t ) +{ + typedef typename boost::numeric::odeint::unwrap_reference< T >::type type; +} + +BOOST_AUTO_TEST_SUITE( unwrap_reference_test ) + +BOOST_AUTO_TEST_CASE( test_case ) +{ + int a; + func( std::ref( a ) ); + func( a ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/velocity_verlet.cpp b/src/boost/libs/numeric/odeint/test/velocity_verlet.cpp new file mode 100644 index 000000000..93a2e97ca --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/velocity_verlet.cpp @@ -0,0 +1,298 @@ +/* + [auto_generated] + libs/numeric/odeint/test/velocity_verlet.cpp + + [begin_description] + tba. + [end_description] + + Copyright 2009-2012 Karsten Ahnert + Copyright 2009-2012 Mario Mulansky + + 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) + */ + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_velocity_verlet + +#define BOOST_FUSION_INVOKE_MAX_ARITY 15 +#define BOOST_RESULT_OF_NUM_ARGS 15 + +#include <boost/numeric/odeint/config.hpp> + +#include "resizing_test_state_type.hpp" + +#include <boost/numeric/odeint/stepper/velocity_verlet.hpp> +#include <boost/numeric/odeint/algebra/fusion_algebra.hpp> + +#include <boost/array.hpp> +#include <boost/test/unit_test.hpp> + +#include <boost/units/systems/si/length.hpp> +#include <boost/units/systems/si/time.hpp> +#include <boost/units/systems/si/velocity.hpp> +#include <boost/units/systems/si/acceleration.hpp> +#include <boost/units/systems/si/io.hpp> + +#include <boost/fusion/include/vector.hpp> +#include <boost/fusion/include/vector20.hpp> +#include <boost/fusion/container.hpp> + +namespace fusion = boost::fusion; +namespace units = boost::units; +namespace si = boost::units::si; + +typedef double value_type; +typedef units::quantity< si::time , value_type > time_type; +typedef units::unit< units::derived_dimension< units::time_base_dimension , 2 >::type , si::system > time_2; +typedef units::quantity< time_2 , value_type > time_2_type; +typedef units::quantity< si::length , value_type > length_type; +typedef units::quantity< si::velocity , value_type > velocity_type; +typedef units::quantity< si::acceleration , value_type > acceleration_type; +typedef fusion::vector< length_type , length_type > coor_vector; +typedef fusion::vector< velocity_type , velocity_type > velocity_vector; +typedef fusion::vector< acceleration_type , acceleration_type > accelartion_vector; + + + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +size_t ode_call_count; + +struct velocity_verlet_fixture +{ + velocity_verlet_fixture( void ) { ode_call_count = 0; adjust_size_count = 0; } +}; + +struct ode +{ + template< class CoorIn , class MomentumIn , class AccelerationOut , class Time > + void operator()( const CoorIn &q , const MomentumIn &p , AccelerationOut &a , Time t ) const + { + a[0] = -q[0] - p[0]; + a[1] = -q[1] - p[1]; + ++ode_call_count; + } +}; + +struct ode_units +{ + void operator()( coor_vector const &q , velocity_vector const &p , accelartion_vector &a , time_type t ) const + { + const units::quantity< si::frequency , value_type > omega = 1.0 * si::hertz; + const units::quantity< si::frequency , value_type > friction = 0.001 * si::hertz; + fusion::at_c< 0 >( a ) = omega * omega * fusion::at_c< 0 >( q ) - friction * fusion::at_c< 0 >( p ); + fusion::at_c< 1 >( a ) = omega * omega * fusion::at_c< 1 >( q ) - friction * fusion::at_c< 0 >( p ); + ++ode_call_count; + } +}; + +template< class Q , class P > +void init_state( Q &q , P &p ) +{ + q[0] = 1.0 ; q[1] = 0.5; + p[0] = 2.0 ; p[1] = -1.0; +} + +typedef boost::array< double , 2 > array_type; +typedef std::vector< double > vector_type; + +typedef velocity_verlet< array_type > array_stepper; +typedef velocity_verlet< vector_type > vector_stepper; + +template< typename Resizer > +struct get_resizer_test_stepper +{ + typedef velocity_verlet< test_array_type , test_array_type , double , test_array_type , + double , double , range_algebra , default_operations , Resizer > type; +}; + + + + + +BOOST_AUTO_TEST_SUITE( velocity_verlet_test ) + +BOOST_FIXTURE_TEST_CASE( test_with_array_ref , velocity_verlet_fixture ) +{ + array_stepper stepper; + array_type q , p ; + init_state( q , p ); + stepper.do_step( ode() , std::make_pair( boost::ref( q ) , boost::ref( p ) ) , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) ); +} + +BOOST_FIXTURE_TEST_CASE( test_with_array_pair , velocity_verlet_fixture ) +{ + array_stepper stepper; + std::pair< array_type , array_type > xxx; + init_state( xxx.first , xxx.second ); + stepper.do_step( ode() , xxx , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) ); +} + +BOOST_FIXTURE_TEST_CASE( test_with_vector_ref , velocity_verlet_fixture ) +{ + vector_stepper stepper; + vector_type q( 2 ) , p( 2 ); + init_state( q , p ); + stepper.do_step( ode() , std::make_pair( boost::ref( q ) , boost::ref( p ) ) , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) ); +} + +BOOST_FIXTURE_TEST_CASE( test_with_vector_pair , velocity_verlet_fixture ) +{ + vector_stepper stepper; + std::pair< vector_type , vector_type > x; + x.first.resize( 2 ) ; x.second.resize( 2 ); + init_state( x.first , x.second ); + stepper.do_step( ode() , x , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) ); +} + +BOOST_FIXTURE_TEST_CASE( test_initial_resizer , velocity_verlet_fixture ) +{ + typedef get_resizer_test_stepper< initially_resizer >::type stepper_type; + std::pair< test_array_type , test_array_type > x; + init_state( x.first , x.second ); + stepper_type stepper; + stepper.do_step( ode() , x , 0.0 , 0.01 ); + stepper.do_step( ode() , x , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 3 ) ); +} + +BOOST_FIXTURE_TEST_CASE( test_always_resizer , velocity_verlet_fixture ) +{ + typedef get_resizer_test_stepper< always_resizer >::type stepper_type; + std::pair< test_array_type , test_array_type > x; + init_state( x.first , x.second ); + stepper_type stepper; + stepper.do_step( ode() , x , 0.0 , 0.01 ); + stepper.do_step( ode() , x , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 4 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 4 ) ); // attention: one more system call, since the size of the state has been changed +} + +BOOST_FIXTURE_TEST_CASE( test_with_never_resizer , velocity_verlet_fixture ) +{ + typedef get_resizer_test_stepper< never_resizer >::type stepper_type; + std::pair< test_array_type , test_array_type > x; + init_state( x.first , x.second ); + stepper_type stepper; + stepper.do_step( ode() , x , 0.0 , 0.01 ); + stepper.do_step( ode() , x , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 0 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 3 ) ); +} + +BOOST_FIXTURE_TEST_CASE( test_reset , velocity_verlet_fixture ) +{ + typedef get_resizer_test_stepper< initially_resizer >::type stepper_type; + std::pair< test_array_type , test_array_type > x; + init_state( x.first , x.second ); + stepper_type stepper; + stepper.do_step( ode() , x , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) ); + stepper.do_step( ode() , x , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 3 ) ); + stepper.reset(); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 3 ) ); + stepper.do_step( ode() , x , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 5 ) ); +} + +BOOST_FIXTURE_TEST_CASE( test_initialize1 , velocity_verlet_fixture ) +{ + typedef get_resizer_test_stepper< initially_resizer >::type stepper_type; + std::pair< test_array_type , test_array_type > x; + init_state( x.first , x.second ); + stepper_type stepper; + test_array_type ain; + ode()( x.first , x.second , ain , 0.0 ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 0 ) ); + stepper.initialize( ain ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 1 ) ); + stepper.do_step( ode() , x , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) ); +} + +BOOST_FIXTURE_TEST_CASE( test_initialize2 , velocity_verlet_fixture ) +{ + typedef get_resizer_test_stepper< initially_resizer >::type stepper_type; + std::pair< test_array_type , test_array_type > x; + init_state( x.first , x.second ); + stepper_type stepper; + stepper.initialize( ode() , x.first , x.second , 0.0 ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 1 ) ); + stepper.do_step( ode() , x , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) ); +} + + +BOOST_FIXTURE_TEST_CASE( test_adjust_size , velocity_verlet_fixture ) +{ + typedef get_resizer_test_stepper< initially_resizer >::type stepper_type; + std::pair< test_array_type , test_array_type > x; + init_state( x.first , x.second ); + stepper_type stepper; + stepper.do_step( ode() , x , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) ); + stepper.adjust_size( x.first ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 4 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) ); + stepper.do_step( ode() , x , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 4 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 4 ) ); +} + +BOOST_FIXTURE_TEST_CASE( test_with_unit_pair , velocity_verlet_fixture ) +{ + typedef velocity_verlet< coor_vector , velocity_vector , value_type , accelartion_vector , + time_type , time_2_type , fusion_algebra , default_operations > stepper_type; + + std::pair< coor_vector , velocity_vector > x; + fusion::at_c< 0 >( x.first ) = 1.0 * si::meter; + fusion::at_c< 1 >( x.first ) = 0.5 * si::meter; + fusion::at_c< 0 >( x.second ) = 2.0 * si::meter_per_second; + fusion::at_c< 1 >( x.second ) = -1.0 * si::meter_per_second; + stepper_type stepper; + stepper.do_step( ode_units() , x , 0.0 * si::second , 0.01 * si::second ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) ); +} + + +BOOST_FIXTURE_TEST_CASE( test_with_unit_ref , velocity_verlet_fixture ) +{ + typedef velocity_verlet< coor_vector , velocity_vector , value_type , accelartion_vector , + time_type , time_2_type , fusion_algebra , default_operations > stepper_type; + + coor_vector q; + velocity_vector p; + fusion::at_c< 0 >( q ) = 1.0 * si::meter; + fusion::at_c< 1 >( q ) = 0.5 * si::meter; + fusion::at_c< 0 >( p ) = 2.0 * si::meter_per_second; + fusion::at_c< 1 >( p ) = -1.0 * si::meter_per_second; + stepper_type stepper; + stepper.do_step( ode_units() , std::make_pair( boost::ref( q ) , boost::ref( p ) ) , 0.0 * si::second , 0.01 * si::second ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test_external/eigen/Jamfile.v2 b/src/boost/libs/numeric/odeint/test_external/eigen/Jamfile.v2 new file mode 100644 index 000000000..ad0cc2d2c --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/eigen/Jamfile.v2 @@ -0,0 +1,35 @@ +# Copyright 2012-2013 Karsten Ahnert +# Copyright 2012-2013 Mario Mulansky +# 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) + +# bring in rules for testing + + +import testing ; +import os ; + +use-project boost : $(BOOST_ROOT) ; + +local EIGEN_ROOT = [ os.environ EIGEN_ROOT ] ; + +project + : requirements + <library>/boost/test//boost_unit_test_framework + <define>BOOST_ALL_NO_LIB=1 + <include>$(EIGEN_ROOT) + <include>../../test + <link>static + # <cxxflags>-D_SCL_SECURE_NO_WARNINGS + ; + +test-suite "odeint" + : + [ compile is_resizeable.cpp ] + [ run same_size.cpp ] + [ run resize.cpp ] + [ run runge_kutta4.cpp ] + [ run runge_kutta_dopri5.cpp ] + [ run integrate.cpp ] + : <testing.launcher>valgrind + ; diff --git a/src/boost/libs/numeric/odeint/test_external/eigen/integrate.cpp b/src/boost/libs/numeric/odeint/test_external/eigen/integrate.cpp new file mode 100644 index 000000000..c64496a83 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/eigen/integrate.cpp @@ -0,0 +1,69 @@ +/* + [auto_generated] + integrate.cpp + + [begin_description] + tba. + [end_description] + + Copyright 2009-2012 Karsten Ahnert + Copyright 2009-2012 Mario Mulansky + + 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) + */ + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_eigen_integrate + +#include <boost/numeric/odeint/integrate/integrate.hpp> +#include <boost/numeric/odeint/external/eigen/eigen.hpp> + +#include <boost/test/unit_test.hpp> + +#include "dummy_odes.hpp" + + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + + +BOOST_AUTO_TEST_SUITE( eigen_integrate ) + +BOOST_AUTO_TEST_CASE( test_const_sys ) +{ + typedef Eigen::Matrix< double , 1 , 1 > state_type; + state_type x; + x[0] = 10.0; + double t_start = 0.0 , t_end = 1.0 , dt = 0.1; + integrate< double >( constant_system_functor_standard() , x , t_start , t_end , dt ); + BOOST_CHECK_CLOSE( x[0] , 11.0 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE( test_lorenz ) +{ + typedef Eigen::Matrix< double , 3 , 1 > state_type; + state_type x; + x[0] = 10.0; + x[1] = 10.0; + x[2] = 10.0; + double t_start = 0.0 , t_end = 1000.0 , dt = 0.1; + integrate< double >( lorenz() , x , t_start , t_end , dt ); + + std::vector< double > x2( 3 ); + x2[0] = 10.0; + x2[1] = 10.0; + x2[2] = 10.0; + integrate( lorenz() , x2 , t_start , t_end , dt ); + + BOOST_CHECK_CLOSE( x[0] , x2[0] , 1.0e-13 ); + BOOST_CHECK_CLOSE( x[1] , x2[1] , 1.0e-13 ); + BOOST_CHECK_CLOSE( x[2] , x2[2] , 1.0e-13 ); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test_external/eigen/is_resizeable.cpp b/src/boost/libs/numeric/odeint/test_external/eigen/is_resizeable.cpp new file mode 100644 index 000000000..5f29ee536 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/eigen/is_resizeable.cpp @@ -0,0 +1,47 @@ +/* + [auto_generated] + libs/numeric/odeint/test_external/eigen/is_resizeable.cpp + + [begin_description] + tba. + [end_description] + + Copyright 2013 Karsten Ahnert + Copyright 2013 Mario Mulansky + + 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) + */ + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_eigen_is_resizeable + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/external/eigen/eigen_resize.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + + +BOOST_AUTO_TEST_SUITE( is_resizeable ) + +BOOST_AUTO_TEST_CASE( test_compile_time_matrix ) +{ + typedef Eigen::Matrix< double , 1 , 1 > matrix_type; + BOOST_STATIC_ASSERT(( boost::numeric::odeint::is_resizeable< matrix_type >::value )); +} + +BOOST_AUTO_TEST_CASE( test_compile_time_array ) +{ + typedef Eigen::Array< double , 1 , 1 > array_type; + BOOST_STATIC_ASSERT(( boost::numeric::odeint::is_resizeable< array_type >::value )); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test_external/eigen/resize.cpp b/src/boost/libs/numeric/odeint/test_external/eigen/resize.cpp new file mode 100644 index 000000000..4efcdd4d3 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/eigen/resize.cpp @@ -0,0 +1,145 @@ +/* + [auto_generated] + libs/numeric/odeint/test_external/eigen/resize.cpp + + [begin_description] + tba. + [end_description] + + Copyright 2013 Karsten Ahnert + Copyright 2013 Mario Mulansky + + 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) + */ + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_eigen_resize + +#include <boost/test/unit_test.hpp> +#include <boost/numeric/odeint/external/eigen/eigen_resize.hpp> + + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + + +BOOST_AUTO_TEST_SUITE( eigen_resize ) + +BOOST_AUTO_TEST_CASE( test_compile_time_matrix ) +{ + typedef Eigen::Matrix< double , 1 , 1 > matrix_type; + matrix_type a , b; + boost::numeric::odeint::resize( a , b ); + BOOST_CHECK( boost::numeric::odeint::same_size( a , b ) ); + BOOST_CHECK_EQUAL( a.rows() , 1 ); + BOOST_CHECK_EQUAL( a.cols() , 1 ); +} + +BOOST_AUTO_TEST_CASE( test_rumtime_matrix ) +{ + typedef Eigen::Matrix< double , Eigen::Dynamic , Eigen::Dynamic > matrix_type; + matrix_type a( 5 , 2 ) , b; + + BOOST_CHECK_EQUAL( a.rows() , 5 ); + BOOST_CHECK_EQUAL( a.cols() , 2 ); + BOOST_CHECK_EQUAL( b.rows() , 0 ); + BOOST_CHECK_EQUAL( b.cols() , 0 ); + BOOST_CHECK( !boost::numeric::odeint::same_size( a , b ) ); + + boost::numeric::odeint::resize( b , a ); + + BOOST_CHECK_EQUAL( a.rows() , 5 ); + BOOST_CHECK_EQUAL( a.cols() , 2 ); + BOOST_CHECK_EQUAL( b.rows() , 5 ); + BOOST_CHECK_EQUAL( b.cols() , 2 ); + + BOOST_CHECK( boost::numeric::odeint::same_size( a , b ) ); +} + +BOOST_AUTO_TEST_CASE( test_rumtime_matrix2 ) +{ + typedef Eigen::Matrix< double , Eigen::Dynamic , Eigen::Dynamic > matrix_type; + matrix_type a( 5 , 2 ) , b( 2 , 3 ); + + BOOST_CHECK_EQUAL( a.rows() , 5 ); + BOOST_CHECK_EQUAL( a.cols() , 2 ); + BOOST_CHECK_EQUAL( b.rows() , 2 ); + BOOST_CHECK_EQUAL( b.cols() , 3 ); + BOOST_CHECK( !boost::numeric::odeint::same_size( a , b ) ); + + boost::numeric::odeint::resize( b , a ); + + BOOST_CHECK_EQUAL( a.rows() , 5 ); + BOOST_CHECK_EQUAL( a.cols() , 2 ); + BOOST_CHECK_EQUAL( b.rows() , 5 ); + BOOST_CHECK_EQUAL( b.cols() , 2 ); + + BOOST_CHECK( boost::numeric::odeint::same_size( a , b ) ); +} + + + + + + +BOOST_AUTO_TEST_CASE( test_compile_time_array ) +{ + typedef Eigen::Array< double , 1 , 1 > array_type; + array_type a , b; + boost::numeric::odeint::resize( a , b ); + BOOST_CHECK( boost::numeric::odeint::same_size( a , b ) ); + BOOST_CHECK_EQUAL( a.rows() , 1 ); + BOOST_CHECK_EQUAL( a.cols() , 1 ); +} + +BOOST_AUTO_TEST_CASE( test_rumtime_array ) +{ + typedef Eigen::Array< double , Eigen::Dynamic , Eigen::Dynamic > array_type; + array_type a( 5 , 2 ) , b; + + BOOST_CHECK_EQUAL( a.rows() , 5 ); + BOOST_CHECK_EQUAL( a.cols() , 2 ); + BOOST_CHECK_EQUAL( b.rows() , 0 ); + BOOST_CHECK_EQUAL( b.cols() , 0 ); + BOOST_CHECK( !boost::numeric::odeint::same_size( a , b ) ); + + boost::numeric::odeint::resize( b , a ); + + BOOST_CHECK_EQUAL( a.rows() , 5 ); + BOOST_CHECK_EQUAL( a.cols() , 2 ); + BOOST_CHECK_EQUAL( b.rows() , 5 ); + BOOST_CHECK_EQUAL( b.cols() , 2 ); + + BOOST_CHECK( boost::numeric::odeint::same_size( a , b ) ); +} + +BOOST_AUTO_TEST_CASE( test_rumtime_array2 ) +{ + typedef Eigen::Array< double , Eigen::Dynamic , Eigen::Dynamic > array_type; + array_type a( 5 , 2 ) , b( 2 , 3 ); + + BOOST_CHECK_EQUAL( a.rows() , 5 ); + BOOST_CHECK_EQUAL( a.cols() , 2 ); + BOOST_CHECK_EQUAL( b.rows() , 2 ); + BOOST_CHECK_EQUAL( b.cols() , 3 ); + BOOST_CHECK( !boost::numeric::odeint::same_size( a , b ) ); + + boost::numeric::odeint::resize( b , a ); + + BOOST_CHECK_EQUAL( a.rows() , 5 ); + BOOST_CHECK_EQUAL( a.cols() , 2 ); + BOOST_CHECK_EQUAL( b.rows() , 5 ); + BOOST_CHECK_EQUAL( b.cols() , 2 ); + + BOOST_CHECK( boost::numeric::odeint::same_size( a , b ) ); +} + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test_external/eigen/runge_kutta4.cpp b/src/boost/libs/numeric/odeint/test_external/eigen/runge_kutta4.cpp new file mode 100644 index 000000000..c4054fd15 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/eigen/runge_kutta4.cpp @@ -0,0 +1,94 @@ +/* + [auto_generated] + libs/numeric/odeint/test_external/eigen/runge_kutta4.cpp + + [begin_description] + tba. + [end_description] + + Copyright 2013 Karsten Ahnert + Copyright 2013 Mario Mulansky + + 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) + */ + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_eigen_runge_kutta4 + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/algebra/vector_space_algebra.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/external/eigen/eigen_resize.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +struct sys +{ + template< class State , class Deriv > + void operator()( const State &x , Deriv &dxdt , double t ) const + { + dxdt[0] = 1.0; + } +}; + + +BOOST_AUTO_TEST_SUITE( eigen_runge_kutta4 ) + +BOOST_AUTO_TEST_CASE( compile_time_matrix ) +{ + typedef Eigen::Matrix< double , 1 , 1 > state_type; + state_type x; + x[0] = 10.0; + runge_kutta4< state_type , double , state_type , double , vector_space_algebra > rk4; + rk4.do_step( sys() , x , 0.0 , 0.1 ); + BOOST_CHECK_CLOSE( x[0] , 10.1 , 1.0e-13 ); + +} + +BOOST_AUTO_TEST_CASE( runtime_matrix ) +{ + typedef Eigen::Matrix< double , Eigen::Dynamic , 1 > state_type; + state_type x( 1 ); + x[0] = 10.0; + runge_kutta4< state_type , double , state_type , double , vector_space_algebra > rk4; + rk4.do_step( sys() , x , 0.0 , 0.1 ); + BOOST_CHECK_CLOSE( x[0] , 10.1 , 1.0e-13 ); +} + + + + + + +BOOST_AUTO_TEST_CASE( compile_time_array ) +{ + typedef Eigen::Array< double , 1 , 1 > state_type; + state_type x; + x[0] = 10.0; + runge_kutta4< state_type , double , state_type , double , vector_space_algebra > rk4; + rk4.do_step( sys() , x , 0.0 , 0.1 ); + BOOST_CHECK_CLOSE( x[0] , 10.1 , 1.0e-13 ); + +} + +BOOST_AUTO_TEST_CASE( runtime_array ) +{ + typedef Eigen::Array< double , Eigen::Dynamic , 1 > state_type; + state_type x( 1 ); + x[0] = 10.0; + runge_kutta4< state_type , double , state_type , double , vector_space_algebra > rk4; + rk4.do_step( sys() , x , 0.0 , 0.1 ); + BOOST_CHECK_CLOSE( x[0] , 10.1 , 1.0e-13 ); +} + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test_external/eigen/runge_kutta_dopri5.cpp b/src/boost/libs/numeric/odeint/test_external/eigen/runge_kutta_dopri5.cpp new file mode 100644 index 000000000..516f04f75 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/eigen/runge_kutta_dopri5.cpp @@ -0,0 +1,132 @@ +/* + [auto_generated] + libs/numeric/odeint/test_external/eigen/runge_kutta_dopri5.cpp + + [begin_description] + tba. + [end_description] + + Copyright 2013 Karsten Ahnert + Copyright 2013 Mario Mulansky + + 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) + */ + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_eigen_runge_kutta4 + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/algebra/vector_space_algebra.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/stepper/controlled_runge_kutta.hpp> +#include <boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp> + +// #include <boost/numeric/odeint/external/eigen/eigen_resize.hpp> +#include <boost/numeric/odeint/external/eigen/eigen_algebra.hpp> + + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +struct sys +{ + template< class State , class Deriv > + void operator()( const State &x , Deriv &dxdt , double t ) const + { + dxdt[0] = 1.0; + } +}; + +template< class State > +struct stepper +{ + typedef runge_kutta_dopri5< State , double , State , double , vector_space_algebra > type; +}; + +template< class State > +struct controlled_stepper +{ + typedef controlled_runge_kutta< typename stepper< State >::type > type; +}; + +template< class State > +struct dense_output_stepper +{ + typedef dense_output_runge_kutta< typename controlled_stepper< State >::type > type; +}; + + + + +BOOST_AUTO_TEST_SUITE( eigen_runge_kutta_dopri5 ) + +BOOST_AUTO_TEST_CASE( compile_time_matrix ) +{ + typedef Eigen::Matrix< double , 1 , 1 > state_type; + state_type x; + x[0] = 10.0; + double t = 0.0 , dt = 0.1 ; + + // dense_output_stepper< state_type >::type s; + // s.initialize( x , t , dt ); + + // controlled_stepper< state_type >::type s; + // s.try_step( sys() , x , t , dt ); + + stepper< state_type >::type s; + s.do_step( sys() , x , t , dt ); + + // runge_kutta4< state_type , double , state_type , double , vector_space_algebra > rk4; + // rk4.do_step( sys() , x , 0.0 , 0.1 ); + // BOOST_CHECK_CLOSE( x[0] , 10.1 , 1.0e-13 ); + +} + +BOOST_AUTO_TEST_CASE( runtime_matrix ) +{ + typedef Eigen::Matrix< double , Eigen::Dynamic , 1 > state_type; + state_type x( 1 ); + x[0] = 10.0; + + // runge_kutta4< state_type , double , state_type , double , vector_space_algebra > rk4; + // rk4.do_step( sys() , x , 0.0 , 0.1 ); + // BOOST_CHECK_CLOSE( x[0] , 10.1 , 1.0e-13 ); +} + + + + + + +BOOST_AUTO_TEST_CASE( compile_time_array ) +{ + typedef Eigen::Array< double , 1 , 1 > state_type; + state_type x; + x[0] = 10.0; + // runge_kutta4< state_type , double , state_type , double , vector_space_algebra > rk4; + // rk4.do_step( sys() , x , 0.0 , 0.1 ); + // BOOST_CHECK_CLOSE( x[0] , 10.1 , 1.0e-13 ); + +} + +BOOST_AUTO_TEST_CASE( runtime_array ) +{ + typedef Eigen::Array< double , Eigen::Dynamic , 1 > state_type; + state_type x( 1 ); + x[0] = 10.0; + // runge_kutta4< state_type , double , state_type , double , vector_space_algebra > rk4; + // rk4.do_step( sys() , x , 0.0 , 0.1 ); + // BOOST_CHECK_CLOSE( x[0] , 10.1 , 1.0e-13 ); +} + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test_external/eigen/same_size.cpp b/src/boost/libs/numeric/odeint/test_external/eigen/same_size.cpp new file mode 100644 index 000000000..ea771f920 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/eigen/same_size.cpp @@ -0,0 +1,83 @@ +/* + [auto_generated] + libs/numeric/odeint/test_external/eigen/same_size.cpp + + [begin_description] + tba. + [end_description] + + Copyright 2013 Karsten Ahnert + Copyright 2013 Mario Mulansky + + 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) + */ + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_eigen_same_size + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/external/eigen/eigen_resize.hpp> + + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + + +BOOST_AUTO_TEST_SUITE( eigen_same_size ) + +BOOST_AUTO_TEST_CASE( compile_time_matrix ) +{ + typedef Eigen::Matrix< double , 1 , 1 > matrix_type; + matrix_type a , b; + BOOST_CHECK( boost::numeric::odeint::same_size( a , b ) ); +} + +BOOST_AUTO_TEST_CASE( runtime_matrix ) +{ + typedef Eigen::Matrix< double , Eigen::Dynamic , Eigen::Dynamic > matrix_type; + matrix_type a( 10 , 2 ) , b( 10 , 2 ); + BOOST_CHECK( boost::numeric::odeint::same_size( a , b ) ); +} + +BOOST_AUTO_TEST_CASE( fail_runtime_matrix ) +{ + typedef Eigen::Matrix< double , Eigen::Dynamic , Eigen::Dynamic > matrix_type; + matrix_type a( 11 , 2 ) , b( 10 , 2 ); + BOOST_CHECK( !boost::numeric::odeint::same_size( a , b ) ); + +} + + + +BOOST_AUTO_TEST_CASE( compile_time_array ) +{ + typedef Eigen::Array< double , 1 , 1 > array_type; + array_type a , b; + BOOST_CHECK( boost::numeric::odeint::same_size( a , b ) ); +} + +BOOST_AUTO_TEST_CASE( runtime_array ) +{ + typedef Eigen::Array< double , Eigen::Dynamic , Eigen::Dynamic > array_type; + array_type a( 10 , 2 ) , b( 10 , 2 ); + BOOST_CHECK( boost::numeric::odeint::same_size( a , b ) ); +} + +BOOST_AUTO_TEST_CASE( fail_runtime_array ) +{ + typedef Eigen::Array< double , Eigen::Dynamic , Eigen::Dynamic > array_type; + array_type a( 11 , 2 ) , b( 10 , 2 ); + BOOST_CHECK( !boost::numeric::odeint::same_size( a , b ) ); + +} + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test_external/gmp/Jamfile.v2 b/src/boost/libs/numeric/odeint/test_external/gmp/Jamfile.v2 new file mode 100644 index 000000000..f0e6af02c --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/gmp/Jamfile.v2 @@ -0,0 +1,26 @@ +# Copyright 2012 Karsten Ahnert +# Copyright 2012 Mario Mulansky +# 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) + +# bring in rules for testing + +import testing ; +use-project boost : $(BOOST_ROOT) ; + +project gmp + : requirements + <library>/boost/test//boost_unit_test_framework + ; + + +lib libgmp : : <name>gmp <link>shared ; +lib libgmpxx : : <name>gmpxx <link>shared ; + +test-suite "gmp" + : + [ run check_gmp.cpp libgmpxx libgmp : : : <link>shared:<define>BOOST_TEST_DYN_LINK=1 ] + [ run gmp_integrate.cpp libgmpxx libgmp : : : <link>shared:<define>BOOST_TEST_DYN_LINK=1 ] + ; + + diff --git a/src/boost/libs/numeric/odeint/test_external/gmp/check_gmp.cpp b/src/boost/libs/numeric/odeint/test_external/gmp/check_gmp.cpp new file mode 100644 index 000000000..04b3e101d --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/gmp/check_gmp.cpp @@ -0,0 +1,165 @@ +/* Boost check_gmp.cpp test file + + Copyright 2010-2012 Mario Mulansky + Copyright 2011-2012 Karsten Ahnert + + This file tests the odeint library with the gmp arbitrary precision types + + 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) +*/ + +#define BOOST_TEST_MODULE odeint_gmp + +#include <iostream> + +#include <gmpxx.h> + +#include <boost/test/unit_test.hpp> +#include <boost/array.hpp> + +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint.hpp> +//#include <boost/numeric/odeint/algebra/vector_space_algebra.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +namespace mpl = boost::mpl; + +const int precision = 1024; + +typedef mpf_class value_type; +typedef mpf_class state_type; + +//provide min, max and pow functions for mpf types - required for controlled steppers +value_type min( const value_type a , const value_type b ) +{ + if( a<b ) return a; + else return b; +} +value_type max( const value_type a , const value_type b ) +{ + if( a>b ) return a; + else return b; +} +value_type pow( const value_type a , const value_type b ) +{ + // do calculation in double precision + return value_type( std::pow( a.get_d() , b.get_d() ) ); +} + + +//provide vector_space reduce: + +namespace boost { namespace numeric { namespace odeint { + +template<> +struct vector_space_reduce< state_type > +{ + template< class Op > + state_type operator()( state_type x , Op op , state_type init ) const + { + init = op( init , x ); + return init; + } +}; + +} } } + + +void constant_system( const state_type &x , state_type &dxdt , value_type t ) +{ + dxdt = value_type( 1.0 , precision ); +} + + +/* check runge kutta stepers */ +typedef mpl::vector< + euler< state_type , value_type , state_type , value_type , vector_space_algebra > , + modified_midpoint< state_type , value_type , state_type , value_type , vector_space_algebra > , + runge_kutta4< state_type , value_type , state_type , value_type , vector_space_algebra > , + runge_kutta4_classic< state_type , value_type , state_type , value_type , vector_space_algebra > , + runge_kutta_cash_karp54_classic< state_type , value_type , state_type , value_type , vector_space_algebra > , + runge_kutta_cash_karp54< state_type , value_type , state_type , value_type , vector_space_algebra > , + runge_kutta_dopri5< state_type , value_type , state_type , value_type , vector_space_algebra > , + runge_kutta_fehlberg78< state_type , value_type , state_type , value_type , vector_space_algebra > + > stepper_types; + + +template< class Stepper > +struct perform_runge_kutta_test { + + void operator()( void ) + { + /* We have to specify the desired precision in advance! */ + mpf_set_default_prec( precision ); + + mpf_t eps_ , unity; + mpf_init( eps_ ); mpf_init( unity ); + mpf_set_d( unity , 1.0 ); + mpf_div_2exp( eps_ , unity , precision-1 ); // 2^(-precision+1) : smallest number that can be represented with used precision + value_type eps( eps_ ); + + Stepper stepper; + state_type x; + x = 0.0; + + stepper.do_step( constant_system , x , 0.0 , 0.1 ); + + BOOST_MESSAGE( eps ); + BOOST_CHECK_MESSAGE( abs( x - value_type( 0.1 , precision ) ) < eps , x - 0.1 ); + } +}; + + +BOOST_AUTO_TEST_CASE_TEMPLATE( runge_kutta_stepper_test , Stepper , stepper_types ) +{ + perform_runge_kutta_test< Stepper > tester; + tester(); +} + + +/* check controlled steppers */ +typedef mpl::vector< + controlled_runge_kutta< runge_kutta_cash_karp54_classic< state_type , value_type , state_type , value_type , vector_space_algebra > > , + controlled_runge_kutta< runge_kutta_dopri5< state_type , value_type , state_type , value_type , vector_space_algebra > > , + controlled_runge_kutta< runge_kutta_fehlberg78< state_type , value_type , state_type , value_type , vector_space_algebra > > , + bulirsch_stoer< state_type , value_type , state_type , value_type , vector_space_algebra > + > controlled_stepper_types; + + +template< class Stepper > +struct perform_controlled_test { + + void operator()( void ) + { + mpf_set_default_prec( precision ); + + mpf_t eps_ , unity; + mpf_init( eps_ ); mpf_init( unity ); + mpf_set_d( unity , 1.0 ); + mpf_div_2exp( eps_ , unity , precision-1 ); // 2^(-precision+1) : smallest number that can be represented with used precision + value_type eps( eps_ ); + + Stepper stepper; + state_type x; + x = 0.0; + + value_type t(0.0); + value_type dt(0.1); + + stepper.try_step( constant_system , x , t , dt ); + + BOOST_MESSAGE( eps ); + BOOST_CHECK_MESSAGE( abs( x - value_type( 0.1 , precision ) ) < eps , x - 0.1 ); + } +}; + +BOOST_AUTO_TEST_CASE_TEMPLATE( controlled_stepper_test , Stepper , controlled_stepper_types ) +{ + perform_controlled_test< Stepper > tester; + tester(); +} diff --git a/src/boost/libs/numeric/odeint/test_external/gmp/gmp_integrate.cpp b/src/boost/libs/numeric/odeint/test_external/gmp/gmp_integrate.cpp new file mode 100644 index 000000000..0a6be30b1 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/gmp/gmp_integrate.cpp @@ -0,0 +1,169 @@ +/* Boost check_gmp.cpp test file + + Copyright 2010-2012 Mario Mulansky + Copyright 2011-2012 Karsten Ahnert + + This file tests the odeint library with the gmp arbitrary precision types + + 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) +*/ + +#define BOOST_TEST_MODULE odeint_gmp + +#include <gmpxx.h> + +#include <boost/test/unit_test.hpp> +#include <boost/array.hpp> + +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint.hpp> +//#include <boost/numeric/odeint/algebra/vector_space_algebra.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +namespace mpl = boost::mpl; + +const int precision = 1024; + +typedef mpf_class value_type; +typedef mpf_class state_type; + +//provide min, max and pow functions for mpf types - required for controlled steppers +value_type min( const value_type a , const value_type b ) +{ + if( a<b ) return a; + else return b; +} +value_type max( const value_type a , const value_type b ) +{ + if( a>b ) return a; + else return b; +} +value_type pow( const value_type a , const value_type b ) +{ + // do the calculation in double precision... + return value_type( std::pow( a.get_d() , b.get_d() ) ); +} + + +//provide vector_space reduce: + +namespace boost { namespace numeric { namespace odeint { + +template<> +struct vector_space_reduce< state_type > +{ + template< class Op > + state_type operator()( state_type x , Op op , state_type init ) const + { + init = op( init , x ); + return init; + } +}; + +} } } + + +void constant_system( const state_type &x , state_type &dxdt , value_type t ) +{ + dxdt = value_type( 1.0 , precision ); +} + +/* check runge kutta stepers */ +typedef mpl::vector< + euler< state_type , value_type , state_type , value_type , vector_space_algebra > , + modified_midpoint< state_type , value_type , state_type , value_type , vector_space_algebra > , + runge_kutta4< state_type , value_type , state_type , value_type , vector_space_algebra > , + runge_kutta4_classic< state_type , value_type , state_type , value_type , vector_space_algebra > , + runge_kutta_cash_karp54_classic< state_type , value_type , state_type , value_type , vector_space_algebra > , + runge_kutta_cash_karp54< state_type , value_type , state_type , value_type , vector_space_algebra > , + runge_kutta_dopri5< state_type , value_type , state_type , value_type , vector_space_algebra > , + runge_kutta_fehlberg78< state_type , value_type , state_type , value_type , vector_space_algebra > + > stepper_types; + + +template< class Stepper > +struct perform_integrate_const_test { + + void operator()( void ) + { + /* We have to specify the desired precision in advance! */ + mpf_set_default_prec( precision ); + + mpf_t eps_ , unity; + mpf_init( eps_ ); mpf_init( unity ); + mpf_set_d( unity , 1.0 ); + mpf_div_2exp( eps_ , unity , precision-1 ); // 2^(-precision+1) : smallest number that can be represented with used precision + value_type eps( eps_ ); + + Stepper stepper; + state_type x; + x = 0.0; + value_type t0( 0.0 ); + value_type tend( 1.0 ); + value_type dt(0.1); + + integrate_const( stepper , constant_system , x , t0 , tend , dt ); + + x = 0.0; + t0 = 0.0; + dt = 0.1; + size_t steps = 10; + + integrate_n_steps( stepper , constant_system , x , t0 , dt , steps ); + + BOOST_CHECK_MESSAGE( abs( x - 10*dt ) < eps , x ); + } +}; + + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_const_test , Stepper , stepper_types ) +{ + perform_integrate_const_test< Stepper > tester; + tester(); +} + + +typedef mpl::vector< + controlled_runge_kutta< runge_kutta_cash_karp54_classic< state_type , value_type , state_type , value_type , vector_space_algebra > > , + controlled_runge_kutta< runge_kutta_dopri5< state_type , value_type , state_type , value_type , vector_space_algebra > > , + controlled_runge_kutta< runge_kutta_fehlberg78< state_type , value_type , state_type , value_type , vector_space_algebra > > , + bulirsch_stoer< state_type , value_type , state_type , value_type , vector_space_algebra > + > controlled_stepper_types; + + +template< class Stepper > +struct perform_integrate_adaptive_test { + + void operator()( void ) + { + mpf_set_default_prec( precision ); + + mpf_t eps_ , unity; + mpf_init( eps_ ); mpf_init( unity ); + mpf_set_d( unity , 1.0 ); + mpf_div_2exp( eps_ , unity , precision-1 ); // 2^(-precision+1) : smallest number that can be represented with used precision + value_type eps( eps_ ); + + Stepper stepper; + state_type x; + x = 0.0; + value_type t0( 0.0 ); + value_type tend( 1.0 ); + value_type dt(0.1); + + integrate_adaptive( stepper , constant_system , x , t0 , tend , dt ); + + BOOST_CHECK_MESSAGE( abs( x - tend ) < eps , x - 0.1 ); + } +}; + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_adaptive__test , Stepper , controlled_stepper_types ) +{ + perform_integrate_adaptive_test< Stepper > tester; + tester(); +} diff --git a/src/boost/libs/numeric/odeint/test_external/gsl/Jamfile.v2 b/src/boost/libs/numeric/odeint/test_external/gsl/Jamfile.v2 new file mode 100644 index 000000000..086edf6ea --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/gsl/Jamfile.v2 @@ -0,0 +1,28 @@ +# Copyright 2012 Karsten Ahnert +# Copyright 2012 Mario Mulansky +# 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) + +# bring in rules for testing + +import testing ; +use-project boost : $(BOOST_ROOT) ; + +project + : requirements + <library>/boost/test//boost_unit_test_framework + ; + + +lib libgsl : : <name>gsl <link>shared ; +lib libgslcblas : : <name>gslcblas <link>shared ; + +test-suite "gsl" + : + [ run check_gsl.cpp libgslcblas libgsl + : + : + : <link>shared:<define>BOOST_TEST_DYN_LINK=1 + ] + ; + diff --git a/src/boost/libs/numeric/odeint/test_external/gsl/check_gsl.cpp b/src/boost/libs/numeric/odeint/test_external/gsl/check_gsl.cpp new file mode 100644 index 000000000..3e7856dd2 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/gsl/check_gsl.cpp @@ -0,0 +1,58 @@ +/* Boost check_gmp.cpp test file + + Copyright 2010-2011 Karsten Ahnert + Copyright 2011 Mario Mulansky + + This file tests the odeint library with the gmp arbitrary precision types + + 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) +*/ + +#define BOOST_TEST_MODULE odeint_gsl + +#include <gsl/gsl_vector.h> +#include <boost/numeric/odeint/stepper/euler.hpp> +#include <boost/numeric/odeint/external/gsl/gsl_wrapper.hpp> + +#include <boost/test/unit_test.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef gsl_vector *state_type; + +const double sigma = 10.0; +const double R = 28.0; +const double b = 8.0 / 3.0; + +void lorenz( const state_type x , state_type dxdt , double t ) +{ + gsl_vector_set( dxdt , 0 , sigma * ( gsl_vector_get(x , 1 ) - gsl_vector_get( x , 0 ) ) ); + gsl_vector_set( dxdt , 1 , R * gsl_vector_get( x , 0 ) - gsl_vector_get( x , 1 ) - gsl_vector_get( x , 0 ) * gsl_vector_get( x , 2) ); + gsl_vector_set( dxdt , 2 , gsl_vector_get( x , 0 ) * gsl_vector_get( x , 1 ) - b * gsl_vector_get( x , 2) ); +} + +BOOST_AUTO_TEST_CASE( gsl ) +{ + euler< state_type > euler; + + state_type x = gsl_vector_alloc( 3 ); + + // check resizing + state_type y = 0; + boost::numeric::odeint::resize( y , x ); + BOOST_CHECK( 0 != y ); + + gsl_vector_set( x , 0 , 1.0); + gsl_vector_set( x , 1 , 1.0); + gsl_vector_set( x , 2 , 2.0); + + euler.do_step( lorenz , x , 0.0 , 0.1 ); + + //cout << gsl_vector_get( x , 0 ) << " " << gsl_vector_get( x , 1 ) << " " << gsl_vector_get( x , 2 ) << endl; + + gsl_vector_free( x ); + +} diff --git a/src/boost/libs/numeric/odeint/test_external/mkl/Jamfile.v2 b/src/boost/libs/numeric/odeint/test_external/mkl/Jamfile.v2 new file mode 100644 index 000000000..f585fa83d --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/mkl/Jamfile.v2 @@ -0,0 +1,30 @@ +# Copyright 2012 Karsten Ahnert +# Copyright 2012 Mario Mulansky +# 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) + +# bring in rules for testing + +import testing ; +use-project boost : $(BOOST_ROOT) ; + +project + : requirements + <library>/boost/test//boost_unit_test_framework + ; + + +lib libmkl : : <name>mkl_intel_lp64 <link>shared ; +lib libmkl_core : : <name>mkl_core <link>shared ; +lib libmkl_intel_thread : : <name>mkl_intel_thread ; +lib libiomp5 : : <name>iomp5 ; +lib libpthread : : <name>pthread ; + +test-suite "mkl" + : + [ run check_mkl.cpp libpthread libiomp5 libmkl_core libmkl_intel_thread libmkl + : + : + : <link>shared:<define>BOOST_TEST_DYN_LINK=1 + ] + ; diff --git a/src/boost/libs/numeric/odeint/test_external/mkl/check_mkl.cpp b/src/boost/libs/numeric/odeint/test_external/mkl/check_mkl.cpp new file mode 100644 index 000000000..bedbd66de --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/mkl/check_mkl.cpp @@ -0,0 +1,51 @@ +/* Boost check_mkl.cpp test file + + Copyright 2010-2011 Mario Mulansky + Copyright 2011 Karsten Ahnert + + This file tests the odeint library with the intel mkl blas1 routines + + 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) +*/ + +#define BOOST_TEST_MODULE test_mkl + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/stepper/euler.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/algebra/vector_space_algebra.hpp> +#include <boost/numeric/odeint/external/mkl/mkl_operations.hpp> + +using namespace boost::numeric::odeint; + +typedef double value_type; +typedef boost::array< value_type , 1 > state_type; + + +void constant_system( state_type &x , state_type &dxdt , value_type t ) +{ + dxdt[0] = 1.0; +} + +const double eps = 1E-14; + + +BOOST_AUTO_TEST_CASE( test_mkl ) +{ + + //to use mkl routines we have to use the vector_space_algebra and the mkl_operations + runge_kutta4< state_type , value_type , state_type , value_type , vector_space_algebra , mkl_operations > stepper; + state_type x; + x[0] = 0.0; + + stepper.do_step( constant_system , x , 0.0 , 0.1 ); + + using std::abs; + + std::cout << x[0] << " ?= " << 0.1 << std::endl; + BOOST_CHECK_SMALL( abs( x[0] - 0.1 ) , eps ); + +} diff --git a/src/boost/libs/numeric/odeint/test_external/mpi/Jamfile.v2 b/src/boost/libs/numeric/odeint/test_external/mpi/Jamfile.v2 new file mode 100644 index 000000000..0a02bccff --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/mpi/Jamfile.v2 @@ -0,0 +1,27 @@ +# Copyright 2012 Karsten Ahnert +# Copyright 2012-2013 Mario Mulansky +# Copyright 2013 Pascal Germroth +# 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 testing ; +import mpi : mpi-test ; + +use-project boost : $(BOOST_ROOT) ; + +project + : requirements + <library>/boost/test//boost_unit_test_framework + <library>/boost//mpi + <link>static + <define>BOOST_ALL_NO_LIB=1 + ; + +# mpi-test name : source : req : np=1 2 3 4 7 8 13 17 +test-suite "odeint-mpi" + : + [ mpi-test split_test ] + [ mpi-test state_test ] + [ mpi-test norm_test ] + ; + diff --git a/src/boost/libs/numeric/odeint/test_external/mpi/norm_test.cpp b/src/boost/libs/numeric/odeint/test_external/mpi/norm_test.cpp new file mode 100644 index 000000000..69f1d4065 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/mpi/norm_test.cpp @@ -0,0 +1,62 @@ +/* + Copyright 2013 Karsten Ahnert + Copyright 2013 Mario Mulansky + Copyright 2013 Pascal Germroth + + 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) + */ + +#include <iostream> +#include <sstream> +#include <cstdlib> + +#define BOOST_TEST_MODULE odeint_mpi +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/external/mpi/mpi.hpp> + +using namespace boost::numeric::odeint; + +boost::mpi::environment env; + +BOOST_AUTO_TEST_SUITE( norm_test_suite ) + +BOOST_AUTO_TEST_CASE( norm_test ) +{ + boost::mpi::communicator world; + + int ref_value = 0; + std::vector<int> in_data; + mpi_state< std::vector<int> > state(world); + + // generate data and reference value on master + if(world.rank() == 0) { + for(size_t i = 0 ; i < 400 ; i++) + in_data.push_back( rand() % 10000 ); + ref_value = *std::max_element(in_data.begin(), in_data.end()); + } + boost::mpi::broadcast(world, ref_value, 0); + + // copy to nodes + split( in_data, state ); + + int value = mpi_nested_algebra< range_algebra >::norm_inf( state ); + + { + std::ostringstream ss; + ss << "state[" << world.rank() << "]" + << " local:" << range_algebra::norm_inf( state() ) + << " global:" << value + << " ref:" << ref_value << "\n"; + std::clog << ss.str() << std::flush; + } + + BOOST_REQUIRE_EQUAL( value, ref_value ); +} + + +BOOST_AUTO_TEST_SUITE_END() + + diff --git a/src/boost/libs/numeric/odeint/test_external/mpi/split_test.cpp b/src/boost/libs/numeric/odeint/test_external/mpi/split_test.cpp new file mode 100644 index 000000000..f78a60149 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/mpi/split_test.cpp @@ -0,0 +1,61 @@ +/* + Copyright 2013 Karsten Ahnert + Copyright 2013 Mario Mulansky + Copyright 2013 Pascal Germroth + + 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) + */ + +#include <iostream> +#include <sstream> + +#define BOOST_TEST_MODULE odeint_mpi +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/external/mpi/mpi.hpp> + +using namespace boost::numeric::odeint; + +boost::mpi::environment env; + +BOOST_AUTO_TEST_SUITE( split_test_suite ) + +BOOST_AUTO_TEST_CASE( split_test ) +{ + boost::mpi::communicator world; + + const size_t total_size = 31; + + std::vector<size_t> in_data, out_data; + mpi_state< std::vector<size_t> > state(world); + + // generate data on master + if(world.rank() == 0) + for(size_t i = 0 ; i < total_size ; i++) in_data.push_back(i); + + // copy to nodes + split( in_data, state ); + + BOOST_REQUIRE((state().size() == total_size / world.size()) + || (state().size() == total_size / world.size() + 1)); + + { + std::ostringstream ss; + ss << "state[" << world.rank() << "].data = {"; + std::copy(state().begin(), state().end(), std::ostream_iterator<size_t>(ss, ", ")); + ss << "}\n"; + std::clog << ss.str() << std::flush; + } + + // copy back to master + if(world.rank() == 0) out_data.resize(in_data.size()); + unsplit( state, out_data ); + + if(world.rank() == 0) + BOOST_REQUIRE_EQUAL_COLLECTIONS(in_data.begin(), in_data.end(), out_data.begin(), out_data.end()); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test_external/mpi/state_test.cpp b/src/boost/libs/numeric/odeint/test_external/mpi/state_test.cpp new file mode 100644 index 000000000..490b46e0d --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/mpi/state_test.cpp @@ -0,0 +1,78 @@ +/* + Copyright 2013 Karsten Ahnert + Copyright 2013 Mario Mulansky + Copyright 2013 Pascal Germroth + + 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) + */ + +#include <iostream> +#include <sstream> + +#define BOOST_TEST_MODULE odeint_mpi +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/external/mpi/mpi.hpp> + +using namespace boost::numeric::odeint; + +boost::mpi::environment env; + +BOOST_AUTO_TEST_SUITE( state_test_suite ) + +BOOST_AUTO_TEST_CASE( state_test ) +{ + boost::mpi::communicator world; + + std::vector<size_t> in_data1, in_data2; + mpi_state< std::vector<size_t> > state1(world), state2(world); + + // generate data on master + if(world.rank() == 0) { + in_data1.resize(31); + in_data2.resize(33); + for(size_t i = 0 ; i < in_data2.size() ; i++) + in_data2[i] = i; + } + + // copy to nodes + split( in_data1, state1 ); + split( in_data2, state2 ); + + { + std::ostringstream ss; + ss << "state[" << world.rank() << "] {" + << state1().size() << ", " + << state2().size() << "}\n"; + std::clog << ss.str() << std::flush; + } + + // compare size + BOOST_REQUIRE( !same_size( state1, state2 ) ); + + // resize state1 to match state2. + resize( state1, state2 ); + + { + std::ostringstream ss; + ss << "state[" << world.rank() << "] 1:" + << state1().size() << " 2:" + << state2().size() << "\n"; + std::clog << ss.str() << std::flush; + } + + // compare size + BOOST_REQUIRE( same_size( state1, state2 ) ); + + // copy state2 to state1 + copy( state2, state1 ); + + BOOST_REQUIRE_EQUAL_COLLECTIONS(state1().begin(), state1().end(), + state2().begin(), state2().end()); +} + + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/boost/libs/numeric/odeint/test_external/mtl4/Jamfile.v2 b/src/boost/libs/numeric/odeint/test_external/mtl4/Jamfile.v2 new file mode 100644 index 000000000..de9d87f2c --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/mtl4/Jamfile.v2 @@ -0,0 +1,30 @@ +# Copyright 2012 Karsten Ahnert +# Copyright 2013 Mario Mulansky +# 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 testing ; +import boost ; + +# boost.use-project ; +use-project boost : $(BOOST_ROOT) ; + +# set your MTL4 directory here +MTL4_INCLUDE = /home/mario/MTL4/usr/include ; + +project + : requirements + <library>/boost/test//boost_unit_test_framework + <include>$(MTL4_INCLUDE) + <define>BOOST_ALL_NO_LIB=1 + <link>static + : + : default-build release + ; + +test-suite "odeint-mtl4" + : + [ run mtl4_resize.cpp ] + : <testing.launcher>valgrind + ; diff --git a/src/boost/libs/numeric/odeint/test_external/mtl4/mtl4_resize.cpp b/src/boost/libs/numeric/odeint/test_external/mtl4/mtl4_resize.cpp new file mode 100644 index 000000000..7ef985d3d --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/mtl4/mtl4_resize.cpp @@ -0,0 +1,89 @@ +/* Boost mtl4_resize.cpp test file + + Copyright 2012 Karsten Ahnert + Copyright 2012 Mario Mulansky + + This file tests the odeint library with the mtl4 routines. + + 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) +*/ + +#define BOOST_TEST_MODULE test_mtl4_resize + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/external/mtl4/mtl4_resize.hpp> +#include <boost/numeric/mtl/vector/dense_vector.hpp> + +namespace odeint = boost::numeric::odeint; + + +BOOST_AUTO_TEST_CASE( test_dense_vector_resizeability ) +{ + BOOST_CHECK( odeint::is_resizeable< mtl::dense_vector< double > >::value ); +} + +BOOST_AUTO_TEST_CASE( test_dense2D_resizeability ) +{ + BOOST_CHECK( odeint::is_resizeable< mtl::dense2D< double > >::value ); +} + +BOOST_AUTO_TEST_CASE( test_compressed2D_resizeability ) +{ + BOOST_CHECK( odeint::is_resizeable< mtl::compressed2D< double > >::value ); +} + + + +BOOST_AUTO_TEST_CASE( test_dense_vector_vector_same_size ) +{ + mtl::dense_vector< double > v1( 10 ) , v2( 10 ); + BOOST_CHECK( odeint::same_size( v2 , v1 ) ); +} + +BOOST_AUTO_TEST_CASE( test_dense_vector_dense2D_same_size ) +{ + mtl::dense_vector< double > v( 10 ); + mtl::dense2D< double > m( 10 , 10 ); + BOOST_CHECK( odeint::same_size( m , v ) ); +} + +BOOST_AUTO_TEST_CASE( test_dense_vector_compressed2D_same_size ) +{ + mtl::dense_vector< double > v( 10 ); + mtl::compressed2D< double > m( 10 , 10 ); + BOOST_CHECK( odeint::same_size( m , v ) ); +} + + + + +BOOST_AUTO_TEST_CASE( test_dense_vector_vector_resize ) +{ + mtl::dense_vector< double > v1( 10 ); + mtl::dense_vector< double > v2; + odeint::resize( v2 , v1 ); + BOOST_CHECK( mtl::size( v2 ) == mtl::size( v1 ) ); +} + +BOOST_AUTO_TEST_CASE( test_dense_vector_dense2D_resize ) +{ + mtl::dense_vector< double > v( 10 ); + mtl::dense2D< double > m; + + odeint::resize( m , v ); + BOOST_CHECK( m.num_cols() == mtl::size( v ) ); + BOOST_CHECK( m.num_rows() == mtl::size( v ) ); +} + +BOOST_AUTO_TEST_CASE( test_dense_vector_compressed2D_resize ) +{ + mtl::dense_vector< double > v( 10 ); + mtl::compressed2D< double > m; + + odeint::resize( m , v ); + BOOST_CHECK( m.num_cols() == mtl::size( v ) ); + BOOST_CHECK( m.num_rows() == mtl::size( v ) ); +} diff --git a/src/boost/libs/numeric/odeint/test_external/nt2/Jamfile.v2 b/src/boost/libs/numeric/odeint/test_external/nt2/Jamfile.v2 new file mode 100644 index 000000000..26763da6e --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/nt2/Jamfile.v2 @@ -0,0 +1,44 @@ +#============================================================================== +# Copyright 2014 LRI UMR 8623 CNRS/Univ Paris Sud XI +# Copyright 2014 NumScale SAS +# +# Distributed under the Boost Software License, Version 1.0. +# See accompanying file LICENSE.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt +#============================================================================== + +import testing ; +import os ; + +# This must be built using an NT2 installation. +# NT2_ROOT_PATH should point to the build directory. +# Currently, cxxflags needs to be set to the required architecture +# if using avx/avx2, set the environemnt variable NT2_SIMD_FLAGS to the +# required value for your compiler (i.e. -mavx2 on g++) +# If using sse2/3/4 in 64 bits, this is set automatically. + +local NT2_ROOT_PATH = [ os.environ NT2_ROOT_PATH ] ; +local NT2_SIMD_FLAGS = [ os.environ NT2_SIMD_FLAGS ] ; + +use-project boost : $(BOOST_ROOT) ; + +project + : requirements + <library>$(BOOST_ROOT)/boost/test/included/unit_test_framework.hpp + <define>BOOST_ALL_NO_LIB=1 + <include>$(NT2_ROOT_PATH)/include/ + <link>static + <toolset>gcc:<cxxflags>-DBOOST_SIMD_NO_STRICT_ALIASING + <toolset>gcc:<cxxflags>-fno-strict-aliasing + <cxxflags>$(NT2_SIMD_FLAGS) + ; + +test-suite "odeint" + : + [ run copy.cpp ] + [ run norm_inf.cpp ] + [ run resize.cpp ] + [ run is_resizeable.cpp ] + [ run algebra_dispatcher.cpp ] + : <testing.launcher>valgrind + ; diff --git a/src/boost/libs/numeric/odeint/test_external/nt2/algebra_dispatcher.cpp b/src/boost/libs/numeric/odeint/test_external/nt2/algebra_dispatcher.cpp new file mode 100644 index 000000000..bea6349eb --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/nt2/algebra_dispatcher.cpp @@ -0,0 +1,55 @@ +//============================================================================== +// Copyright 2014 LRI UMR 8623 CNRS/Univ Paris Sud XI +// Copyright 2014 NumScale SAS +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +//============================================================================== +#define BOOST_TEST_MODULE odeint_nt2_algebra_dispatcher + +#include <boost/test/included/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> +#include <boost/numeric/odeint/external/nt2/nt2_algebra_dispatcher.hpp> +#include <boost/numeric/odeint/algebra/default_operations.hpp> +#include <boost/mpl/list.hpp> + +#include <boost/preprocessor/repetition.hpp> +#include <boost/preprocessor/arithmetic/mul.hpp> + +#include <nt2/table.hpp> +#include <nt2/sdk/meta/as.hpp> +#include <nt2/include/functions/ones.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef boost::mpl::list< float , double > fp_types; + +#define TABLE(z,n,text) nt2::table<T> y ## n = \ + nt2::ones(1,2,nt2::meta::as_<T>() )*T(BOOST_PP_ADD(n,1)); + +#define PARAMS(z,n,text) T(BOOST_PP_ADD(n,1)), + +#define SUM(z,n,text) +BOOST_PP_MUL(BOOST_PP_ADD(n,3),BOOST_PP_ADD(n,2)) + +#define TEST(z,n,text) BOOST_CHECK_SMALL( y0(BOOST_PP_ADD(n,1)) \ + -T( 2 BOOST_PP_REPEAT(text, SUM, text) ), T(1e-10) ); + +#define TEST_CASE(z,n,text) BOOST_AUTO_TEST_CASE_TEMPLATE ( \ + BOOST_PP_CAT(odeint_foreach, n), T, fp_types ) \ +{ \ + vector_space_algebra algebra; \ + BOOST_PP_REPEAT(BOOST_PP_ADD(n,2),TABLE,tt) \ + BOOST_PP_CAT(algebra.for_each,BOOST_PP_ADD(n,2))( \ + BOOST_PP_ENUM_PARAMS(BOOST_PP_ADD(n,2),y), default_operations:: \ + BOOST_PP_CAT(scale_sum,BOOST_PP_ADD(n,1)) <T>( \ + BOOST_PP_REPEAT(n, PARAMS, text ) T(BOOST_PP_ADD(n,1)))); \ + BOOST_PP_REPEAT(2,TEST,n) \ +} + +BOOST_AUTO_TEST_SUITE( nt2_algebra ) + +BOOST_PP_REPEAT(7,TEST_CASE,dummy) + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test_external/nt2/copy.cpp b/src/boost/libs/numeric/odeint/test_external/nt2/copy.cpp new file mode 100644 index 000000000..841728efc --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/nt2/copy.cpp @@ -0,0 +1,44 @@ +//============================================================================== +// Copyright 2014 LRI UMR 8623 CNRS/Univ Paris Sud XI +// Copyright 2014 NumScale SAS +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +//============================================================================== +#include <boost/numeric/odeint.hpp> +#include <nt2/table.hpp> +#include <nt2/include/functions/linspace.hpp> + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_nt2_copy + +#include <boost/test/included/unit_test.hpp> +#include <boost/numeric/odeint/external/nt2/nt2_copy.hpp> + +#include <boost/mpl/list.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef boost::mpl::list< float , double > fp_types; + +BOOST_AUTO_TEST_SUITE( nt2_copy ) + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_copy, T, fp_types ) +{ + nt2::table<T> x = nt2::linspace(T(1),T(0),7); + + nt2::table<T> y; + + copy(y,x); + + for (std::size_t ii=1; ii<=x.size();ii++) + BOOST_CHECK_EQUAL(x(ii),y(ii)); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test_external/nt2/is_resizeable.cpp b/src/boost/libs/numeric/odeint/test_external/nt2/is_resizeable.cpp new file mode 100644 index 000000000..10ecdbb56 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/nt2/is_resizeable.cpp @@ -0,0 +1,36 @@ +//============================================================================== +// Copyright 2014 LRI UMR 8623 CNRS/Univ Paris Sud XI +// Copyright 2014 NumScale SAS +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +//============================================================================== +#include <boost/numeric/odeint.hpp> +#include <nt2/table.hpp> + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_nt2_resize + +#include <boost/test/included/unit_test.hpp> +#include <boost/numeric/odeint/external/nt2/nt2_resize.hpp> + +#include <boost/mpl/list.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef boost::mpl::list< float , double > fp_types; + +BOOST_AUTO_TEST_SUITE( nt2_is_resizeable ) + +BOOST_AUTO_TEST_CASE_TEMPLATE( is_resizeable, T, fp_types ) +{ + BOOST_STATIC_ASSERT(( boost::numeric::odeint::is_resizeable< nt2::table<T> >::value )); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test_external/nt2/norm_inf.cpp b/src/boost/libs/numeric/odeint/test_external/nt2/norm_inf.cpp new file mode 100644 index 000000000..1e1206164 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/nt2/norm_inf.cpp @@ -0,0 +1,46 @@ +//============================================================================== +// Copyright 2014 LRI UMR 8623 CNRS/Univ Paris Sud XI +// Copyright 2014 NumScale SAS +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +//============================================================================== +#include <boost/numeric/odeint.hpp> +#include <nt2/table.hpp> +#include <nt2/include/functions/zeros.hpp> +#include <nt2/include/functions/ones.hpp> + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_nt2_copy + +#include <boost/test/included/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> +#include <boost/numeric/odeint/external/nt2/nt2_norm_inf.hpp> + +#include <boost/mpl/list.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef boost::mpl::list< float , double > fp_types; + +BOOST_AUTO_TEST_SUITE( nt2_norm_inf ) + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_norm_inf, T, fp_types ) +{ + nt2::table<T> x = nt2::ones(10,1, nt2::meta::as_<T>() ); + x(4) = 55; + + nt2::table<T> y = nt2::zeros(8,8, nt2::meta::as_<T>() ); + y(6,4) = -42; + + BOOST_CHECK_SMALL(vector_space_norm_inf<nt2::table<T> >()(x) - T(55), T(1e-10)); + BOOST_CHECK_SMALL(vector_space_norm_inf<nt2::table<T> >()(y) - T(42), T(1e-10)); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test_external/nt2/resize.cpp b/src/boost/libs/numeric/odeint/test_external/nt2/resize.cpp new file mode 100644 index 000000000..56d7ce4a6 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/nt2/resize.cpp @@ -0,0 +1,45 @@ +//============================================================================== +// Copyright 2014 LRI UMR 8623 CNRS/Univ Paris Sud XI +// Copyright 2014 NumScale SAS +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +//============================================================================== +#include <boost/numeric/odeint.hpp> +#include <nt2/table.hpp> + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_nt2_resize + +#include <boost/test/included/unit_test.hpp> +#include <boost/numeric/odeint/external/nt2/nt2_resize.hpp> + +#include <boost/mpl/list.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef boost::mpl::list< float , double > fp_types; + +BOOST_AUTO_TEST_SUITE( nt2_resize ) + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_resize, T, fp_types ) +{ + nt2::table<T> x; + x.resize(nt2::of_size(10,10)); + + nt2::table<T> y; + + BOOST_CHECK_EQUAL(same_size(x,y),false); + + resize(y,x); + + BOOST_CHECK_EQUAL(same_size(x,y),true); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test_external/thrust/Makefile b/src/boost/libs/numeric/odeint/test_external/thrust/Makefile new file mode 100644 index 000000000..49d9cd71a --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/thrust/Makefile @@ -0,0 +1,34 @@ +# Copyright 2010-2014 Mario Mulansky +# Copyright 2010-2012 Karsten Ahnert +# +# 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) + +# make sure BOOST_ROOT is pointing to your boost directory +# otherwise, set it here: +# BOOST_ROOT = /path/to/boost + +# path to the cuda installation +CUDA_ROOT = /usr/local/cuda +# target architecture +ARCH = sm_13 + +NVCC = $(CUDA_ROOT)/bin/nvcc + +INCLUDES += -I../../include/ -I$(BOOST_ROOT) + +NVCCFLAGS = -O3 $(INCLUDES) -arch $(ARCH) + +%.o : %.cu + $(NVCC) $(NVCCFLAGS) -c $< -o $@ + +% : %.o + $(NVCC) $(NVCCFLAGS) -o $@ $< + + +all : check_thrust + + +clean : + -rm *~ *.o check_thrust diff --git a/src/boost/libs/numeric/odeint/test_external/thrust/check_thrust.cu b/src/boost/libs/numeric/odeint/test_external/thrust/check_thrust.cu new file mode 100644 index 000000000..3623c3721 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/thrust/check_thrust.cu @@ -0,0 +1,72 @@ +/* Boost check_thrust.cu test file + + Copyright 2010-2013 Mario Mulansky + Copyright 2010-2011 Karsten Ahnert + + This file tests the use of the euler stepper + + 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) +*/ + +//#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/stepper/euler.hpp> +#include <boost/numeric/odeint/external/thrust/thrust.hpp> + +#include <thrust/device_vector.h> +#include <thrust/fill.h> + +using namespace boost::numeric::odeint; + +typedef float base_type; +// typedef thrust::device_vector< base_type > state_type; +typedef thrust::host_vector< base_type > state_type; + +void constant_system( const state_type &x , state_type &dxdt , base_type t ) +{ + thrust::fill( dxdt.begin() , dxdt.end() , static_cast<base_type>(1.0) ); +} + +const base_type eps = 1.0e-7; + + +template< class Stepper , class System > +void check_stepper_concept( Stepper &stepper , System system , typename Stepper::state_type &x ) +{ + typedef Stepper stepper_type; + typedef typename stepper_type::state_type container_type; + typedef typename stepper_type::order_type order_type; + typedef typename stepper_type::time_type time_type; + + stepper.do_step( system , x , 0.0 , 0.1 ); + base_type xval = *boost::begin( x ); + if( fabs( xval - 0.1 ) < eps ) + std::clog << "TEST PASSED" << std::endl; + else + std::clog << "TEST FAILED" << std::endl; +} + +void test_euler_with_thrust( void ) +{ + state_type x(1); + thrust::fill( x.begin() , x.end() , static_cast<base_type>(0.0) ); + euler< state_type , base_type , state_type , base_type > euler; + check_stepper_concept( euler , constant_system , x ); + + +} + +/*test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + test_suite *test = BOOST_TEST_SUITE("check stepper with thrust"); + + test->add( BOOST_TEST_CASE( &test_euler_with_thrust ) ); + + return test; +}*/ + +int main() { + test_euler_with_thrust(); +} diff --git a/src/boost/libs/numeric/odeint/test_external/vexcl/Jamfile.v2 b/src/boost/libs/numeric/odeint/test_external/vexcl/Jamfile.v2 new file mode 100644 index 000000000..9b76b4305 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/vexcl/Jamfile.v2 @@ -0,0 +1,35 @@ +# Copyright 2012 Karsten Ahnert +# Copyright 2013 Mario Mulansky +# 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) + +# bring in rules for testing + + +import testing ; + +use-project boost : $(BOOST_ROOT) ; +VEXCL_INCLUDE = /home/karsten/boost/testing/vexcl ; +OPENCL_INCLUDE = /usr/local/cuda/include ; +#OPENCL_INCLUDE = /usr/include ; + +project + : requirements + <library>/boost/test//boost_unit_test_framework + <define>BOOST_ALL_NO_LIB=1 + <include>$(VEXCL_INCLUDE) + <include>$(OPENCL_INCLUDE) + <cxxflags>-std=c++0x + <library>/boost//system/ + ; + +lib OpenCL : : <name>OpenCL <link>shared ; + +test-suite "odeint" + : + [ run lorenz.cpp OpenCL ] + [ run norm_inf.cpp OpenCL ] + : <testing.launcher>valgrind + : + : <link>shared:<define>BOOST_TEST_DYN_LINK=1 + ;
\ No newline at end of file diff --git a/src/boost/libs/numeric/odeint/test_external/vexcl/lorenz.cpp b/src/boost/libs/numeric/odeint/test_external/vexcl/lorenz.cpp new file mode 100644 index 000000000..6bde91f68 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/vexcl/lorenz.cpp @@ -0,0 +1,147 @@ +/* Boost lorenz.cpp test file + + Copyright 2012 Karsten Ahnert + Copyright 2012 Mario Mulansky + + This file tests the odeint library with the vexcl types + + 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) +*/ + +#define BOOST_TEST_MODULE odeint_vexcl + +#include <vector> +#include <iostream> + +#include <vexcl/vexcl.hpp> + +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/controlled_runge_kutta.hpp> +#include <boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp> +#include <boost/numeric/odeint/algebra/vector_space_algebra.hpp> +#include <boost/numeric/odeint/integrate/integrate_const.hpp> +#include <boost/numeric/odeint/external/vexcl/vexcl.hpp> + +#include <boost/test/unit_test.hpp> + +using namespace boost::unit_test; +namespace odeint = boost::numeric::odeint; + + +typedef vex::vector< double > vector_type; +typedef vex::multivector< double, 3 > state_type; + + + +const double sigma = 10.0; +const double b = 8.0 / 3.0; + +struct sys_func +{ + const vector_type &R; + + sys_func( const vector_type &_R ) : R( _R ) { } + + void operator()( const state_type &x , state_type &dxdt , double t ) const + { + dxdt(0) = -sigma * ( x(0) - x(1) ); + dxdt(1) = R * x(0) - x(1) - x(0) * x(2); + dxdt(2) = - b * x(2) + x(0) * x(1); + } +}; + +const size_t n = 1024 ; +const double dt = 0.01; +const double t_max = 1.0; + + +BOOST_AUTO_TEST_CASE( integrate_const_rk4 ) +{ + vex::Context ctx( vex::Filter::Type(CL_DEVICE_TYPE_GPU) ); + + double Rmin = 0.1 , Rmax = 50.0 , dR = ( Rmax - Rmin ) / double( n - 1 ); + std::vector<double> x( n * 3 ) , r( n ); + for( size_t i=0 ; i<n ; ++i ) r[i] = Rmin + dR * double( i ); + + state_type X( ctx.queue() , n ); + X(0) = 10.0; + X(1) = 10.0; + X(2) = 10.0; + + vector_type R( ctx.queue() , r ); + + odeint::runge_kutta4< + state_type , double , state_type , double , + odeint::vector_space_algebra , odeint::default_operations + > stepper; + + odeint::integrate_const( stepper , sys_func( R ) , X , 0.0 , t_max , dt ); + + std::vector< double > res( 3 * n ); + vex::copy( X(0) , res ); + std::cout << res[0] << std::endl; +} + +BOOST_AUTO_TEST_CASE( integrate_const_controlled_rk54 ) +{ + vex::Context ctx( vex::Filter::Type(CL_DEVICE_TYPE_GPU) ); + + double Rmin = 0.1 , Rmax = 50.0 , dR = ( Rmax - Rmin ) / double( n - 1 ); + std::vector<double> x( n * 3 ) , r( n ); + for( size_t i=0 ; i<n ; ++i ) r[i] = Rmin + dR * double( i ); + + state_type X( ctx.queue() , n ); + X(0) = 10.0; + X(1) = 10.0; + X(2) = 10.0; + + vector_type R( ctx.queue() , r ); + + typedef odeint::runge_kutta_cash_karp54< + state_type , double , state_type , double , + odeint::vector_space_algebra , odeint::default_operations + > stepper_type; + typedef odeint::controlled_runge_kutta< stepper_type > controlled_stepper_type; + + odeint::integrate_const( controlled_stepper_type() , sys_func( R ) , X , 0.0 , t_max , dt ); + + std::vector< double > res( 3 * n ); + vex::copy( X(0) , res ); + std::cout << res[0] << std::endl; +} + +BOOST_AUTO_TEST_CASE( integrate_const_dense_output_dopri5 ) +{ + vex::Context ctx( vex::Filter::Type(CL_DEVICE_TYPE_GPU) ); + + double Rmin = 0.1 , Rmax = 50.0 , dR = ( Rmax - Rmin ) / double( n - 1 ); + std::vector<double> x( n * 3 ) , r( n ); + for( size_t i=0 ; i<n ; ++i ) r[i] = Rmin + dR * double( i ); + + state_type X( ctx.queue() , n ); + X(0) = 10.0; + X(1) = 10.0; + X(2) = 10.0; + + vector_type R( ctx.queue() , r ); + + typedef odeint::runge_kutta_dopri5< + state_type , double , state_type , double , + odeint::vector_space_algebra , odeint::default_operations + > stepper_type; + typedef odeint::controlled_runge_kutta< stepper_type > controlled_stepper_type; + typedef odeint::dense_output_runge_kutta< controlled_stepper_type > dense_output_stepper_type; + + odeint::integrate_const( dense_output_stepper_type() , sys_func( R ) , X , 0.0 , t_max , dt ); + + std::vector< double > res( 3 * n ); + vex::copy( X(0) , res ); + std::cout << res[0] << std::endl; +} + + + diff --git a/src/boost/libs/numeric/odeint/test_external/vexcl/norm_inf.cpp b/src/boost/libs/numeric/odeint/test_external/vexcl/norm_inf.cpp new file mode 100644 index 000000000..71481d296 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test_external/vexcl/norm_inf.cpp @@ -0,0 +1,25 @@ +#define BOOST_TEST_MODULE odeint_vexcl_norm_inf + +#include <boost/numeric/odeint/external/vexcl/vexcl_norm_inf.hpp> +#include <boost/test/unit_test.hpp> + +template <class T> +double norm(const T &x) { + return boost::numeric::odeint::vector_space_norm_inf<T>()(x); +} + +BOOST_AUTO_TEST_CASE( norm_inf ) +{ + vex::Context ctx(vex::Filter::Env); + std::cout << ctx << std::endl; + + vex::vector<double> x(ctx, 1024); + x = 41; + + vex::multivector<double, 2> y(ctx, 1024); + y = 42; + + BOOST_CHECK_EQUAL( norm(x), 41 ); + BOOST_CHECK_EQUAL( norm(y), 42 ); +} + diff --git a/src/boost/libs/numeric/odeint/toolset.jam.patch b/src/boost/libs/numeric/odeint/toolset.jam.patch new file mode 100644 index 000000000..dca997d5a --- /dev/null +++ b/src/boost/libs/numeric/odeint/toolset.jam.patch @@ -0,0 +1,61 @@ +diff --git a/src/build/toolset.jam b/src/build/toolset.jam +index b5defd5..a942cd9 100644 +--- a/src/build/toolset.jam ++++ b/src/build/toolset.jam +@@ -17,6 +17,8 @@ import regex ; + import sequence ; + import set ; + import property-set ; ++import order ; ++import "class" : new ; + + + .flag-no = 1 ; +@@ -237,6 +239,7 @@ rule handle-flag-value ( value * : properties * ) + if $(value:G) + { + local matches = [ property.select $(value) : $(properties) ] ; ++ local order ; + for local p in $(matches) + { + local att = [ feature.attributes $(p:G) ] ; +@@ -263,11 +266,24 @@ rule handle-flag-value ( value * : properties * ) + } + if path in $(att) + { +- result += [ sequence.transform path.native : $(values) ] ; ++ values = [ sequence.transform path.native : $(values) ] ; + } +- else ++ result += $(values) ; ++ if $(values[2]) + { +- result += $(values) ; ++ if ! $(order) ++ { ++ order = [ new order ] ; ++ } ++ local prev ; ++ for local v in $(values) ++ { ++ if $(prev) ++ { ++ $(order).add-pair $(prev) $(v) ; ++ } ++ prev = $(v) ; ++ } + } + } + else +@@ -275,6 +291,11 @@ rule handle-flag-value ( value * : properties * ) + result += $(p:G=) ; + } + } ++ if $(order) ++ { ++ result = [ $(order).order [ sequence.unique $(result) : stable ] ] ; ++ DELETE_MODULE $(order) ; ++ } + } + else + { diff --git a/src/boost/libs/numeric/sublibs b/src/boost/libs/numeric/sublibs new file mode 100644 index 000000000..721d7c4a9 --- /dev/null +++ b/src/boost/libs/numeric/sublibs @@ -0,0 +1 @@ +The existance of this file tells the regression reporting programs that the directory contains sub-directories which are libraries.
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/Changelog b/src/boost/libs/numeric/ublas/Changelog new file mode 100644 index 000000000..0d71a949c --- /dev/null +++ b/src/boost/libs/numeric/ublas/Changelog @@ -0,0 +1,25 @@ +Version 1.1.0 +------------- + +2014-09-16: Nasos Iliopoulos <> + * feature: Merged matrix row and column facades ( matrix as a vector of rows/columns ) + +2014-05-03: David Bellot <david.bellot@gmail.com> + * removed doxygen documentation from main source + * changed the changelog file for GNU format + * changed doc extension to a more "standard" .html + +2014-04-08 Nasos Iliopoulos <> + + * bugfix: introduced an additional swap implementation for index_pair_array and + index_triple_array to allow proper compilation of sparse containers + with g++>4.8 (4.7 also?) in C++11 mode. + +2014-04-02 Nasos Iliopoulos <> + + * Added changelog + * bugfix: corrected a big number of warnings coming from stray typedefs. Other + similar issues may be present that are not triggered by the unit tests + * bugfix: Corrected the banded matrix bug (https://svn.boost.org/trac/boost/ticket/7549) + and updated appropriate unit tests. To enable the old (incorrect though) + behaviour one should define BOOST_UBLAS_LEGACY_BANDED. diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/configuration.pri b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/configuration.pri new file mode 100644 index 000000000..59e3f1a92 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/configuration.pri @@ -0,0 +1,18 @@ +CONFIG -= qt +CONFIG += depend_includepath +win*: CONFIG += console + +# ublas include directory +INCLUDEPATH += \ + ../../../../../include + +QMAKE_CXXFLAGS += -fno-inline +QMAKE_CXXFLAGS += -std=c++17 + +# If ublas tests are build with boost source code then, +# then boost headers and boost libraries should be used. +exists(../../../../../../boost-build.jam) { + INCLUDEPATH += ../../../../../../.. + LIBS += -L../../../../../../../stage/lib + QMAKE_RPATHDIR += ../../../../../../../stage/lib +} diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/examples.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/examples.pro new file mode 100644 index 000000000..d2c3b3cc6 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/examples.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = tensor diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/construction_access/example_construction_access.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/construction_access/example_construction_access.pro new file mode 100644 index 000000000..8d6abef37 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/construction_access/example_construction_access.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +TARGET = construction_access + +include (../../configuration.pri) + +SOURCES += \ + ../../../../../examples/tensor/construction_access.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/einstein_notation/example_einstein_notation.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/einstein_notation/example_einstein_notation.pro new file mode 100644 index 000000000..302b02a10 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/einstein_notation/example_einstein_notation.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +TARGET = einstein_notation + +include (../../configuration.pri) + +SOURCES += \ + ../../../../../examples/tensor/einstein_notation.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/prod_expressions/example_prod_expressions.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/prod_expressions/example_prod_expressions.pro new file mode 100644 index 000000000..2e210c249 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/prod_expressions/example_prod_expressions.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +TARGET = prod_expression + +include (../../configuration.pri) + +SOURCES += \ + ../../../../../examples/tensor/prod_expressions.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/simple_expressions/example_simple_expressions.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/simple_expressions/example_simple_expressions.pro new file mode 100644 index 000000000..3b106c9f3 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/simple_expressions/example_simple_expressions.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +TARGET = simple_expressions + +include (../../configuration.pri) + +SOURCES += \ + ../../../../../examples/tensor/simple_expressions.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/tensor.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/tensor.pro new file mode 100644 index 000000000..d50e56c61 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/tensor.pro @@ -0,0 +1,9 @@ +TEMPLATE = subdirs +SUBDIRS = construction_access simple_expressions prod_expressions einstein_notation + + +construction_access.file = construction_access/example_construction_access.pro +simple_expressions.file = simple_expressions/example_simple_expressions.pro +prod_expressions.file = prod_expressions/example_prod_expressions.pro +einstein_notation.file = einstein_notation/example_einstein_notation.pro + diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/detail/detail.pri b/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/detail/detail.pri new file mode 100644 index 000000000..711972db4 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/detail/detail.pri @@ -0,0 +1,12 @@ +HEADERS += \ + $${INCLUDE_DIR}/boost/numeric/ublas/detail/vector_assign.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/detail/temporary.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/detail/returntype_deduction.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/detail/raw.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/detail/matrix_assign.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/detail/iterator.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/detail/duff.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/detail/documentation.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/detail/definitions.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/detail/config.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/detail/concepts.hpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/experimental/experimental.pri b/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/experimental/experimental.pri new file mode 100644 index 000000000..41dc6c46b --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/experimental/experimental.pri @@ -0,0 +1,2 @@ +HEADERS += \ + $${INCLUDE_DIR}/boost/numeric/ublas/experimental/sparse_view.hpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/include.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/include.pro new file mode 100644 index 000000000..185254103 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/include.pro @@ -0,0 +1,52 @@ +TEMPLATE = lib +TARGET = ublas + +CONFIG += \ + staticlib \ + depend_includepath +CONFIG -= qt + +INCLUDE_DIR = ../../../include + +include(detail/detail.pri) +include(experimental/experimental.pri) +include(operation/operation.pri) +include(traits/traits.pri) + +include(tensor/tensor.pri) + +INCLUDEPATH += $${INCLUDE_DIR} + +HEADERS += \ + $${INCLUDE_DIR}/boost/numeric/ublas/vector_sparse.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/vector_proxy.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/vector_of_vector.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/vector_expression.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/vector.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/triangular.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/traits.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tags.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/symmetric.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/storage_sparse.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/storage.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/operation_sparse.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/operations.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/operation_blocked.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/operation.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/matrix_sparse.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/matrix_proxy.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/matrix_expression.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/matrix.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/lu.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/io.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/hermitian.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/fwd.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/functional.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/expression_types.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/exception.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/doxydoc.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/blas.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/banded.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/assignment.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/matrix_vector.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor.hpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/operation/operation.pri b/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/operation/operation.pri new file mode 100644 index 000000000..519c4f4a6 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/operation/operation.pri @@ -0,0 +1,7 @@ +HEADERS += \ + $${INCLUDE_DIR}/boost/numeric/ublas/operation/size.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/operation/num_rows.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/operation/num_columns.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/operation/end.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/operation/c_array.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/operation/begin.hpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/tensor/tensor.pri b/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/tensor/tensor.pri new file mode 100644 index 000000000..503aacb68 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/tensor/tensor.pri @@ -0,0 +1,15 @@ +HEADERS += \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/tensor.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/extents.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/strides.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/expression.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/ostream.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/multiplication.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/functions.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/algorithms.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/expression_evaluation.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/operators_comparison.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/operators_arithmetic.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/multi_index.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/multi_index_utility.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/index.hpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/traits/traits.pri b/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/traits/traits.pri new file mode 100644 index 000000000..de327dc68 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/traits/traits.pri @@ -0,0 +1,4 @@ +HEADERS += \ + $${INCLUDE_DIR}/boost/numeric/ublas/traits/iterator_type.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/traits/const_iterator_type.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/traits/c_array.hpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/begin_end.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/begin_end.pro new file mode 100644 index 000000000..56fc9fbd4 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/begin_end.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = begin_end + +include (configuration.pri) + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/begin_end.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/comp_mat_erase.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/comp_mat_erase.pro new file mode 100644 index 000000000..b61828bc4 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/comp_mat_erase.pro @@ -0,0 +1,9 @@ +TEMPLATE = app +TARGET = comp_mat_erase + +win*: QMAKE_CXXFLAGS += /EHa + +include (configuration.pri) + +SOURCES += \ + ../../../test/comp_mat_erase.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/concepts.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/concepts.pro new file mode 100644 index 000000000..b35d7cb75 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/concepts.pro @@ -0,0 +1,16 @@ +TEMPLATE = app +TARGET = concepts + +include (configuration.pri) + +DEFINES += \ + EXTERNAL +# INTERAL +# SKIP_BAD + +linux: icc: QMAKE_CXXFLAGS += -Xc +macx: QMAKE_CXXFLAGS += -fabi-version=0 + + +SOURCES += \ + ../../../test/concepts.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/configuration.pri b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/configuration.pri new file mode 100644 index 000000000..8233c9b34 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/configuration.pri @@ -0,0 +1,55 @@ +CONFIG -= qt +CONFIG += \ + depend_includepath \ + debug +win*: CONFIG += console + +QMAKE_CXXFLAGS += -fno-inline + +# Create a directory for each test. +DESTDIR = $${TARGET} +OBJECTS_DIR = $${TARGET} + +UBLAS_TESTSET = \ + USE_DOUBLE USE_STD_COMPLEX \ + USE_RANGE USE_SLICE \ + USE_UNBOUNDED_ARRAY USE_STD_VECTOR USE_BOUNDED_VECTOR USE_MATRIX + +UBLAS_TESTSET_SPARSE = \ + USE_DOUBLE USE_STD_COMPLEX \ + USE_UNBOUNDED_ARRAY \ + USE_MAP_ARRAY USE_STD_MAP \ + USE_MAPPED_VECTOR USE_COMPRESSED_VECTOR \ + USE_MAPPED_MATRIX USE_COMPRESSED_MATRIX + # USE_RANGE USE_SLICE # Too complex for regression testing + +UBLAS_TESTSET_SPARSE_COO = \ + USE_DOUBLE USE_STD_COMPLEX \ + USE_UNBOUNDED_ARRAY \ + USE_COORDINATE_VECTOR \ + USE_COORDINATE_MATRIX + +DEFINES += BOOST_UBLAS_NO_EXCEPTIONS + +win*: DEFINES += _SCL_SECURE_NO_WARNINGS + +#Visual age IBM +xlc: DEFINES += BOOST_UBLAS_NO_ELEMENT_PROXIES + +# ublas include and test directory are included +INCLUDEPATH += \ + ../../../include \ + ../../../test + +# If ublas tests are build with boost source code then, +# then boost headers and boost libraries should be used. +exists(../../../../../../boost-build.jam) { + INCLUDEPATH += ../../../../../.. + LIBS += -L../../../../../../stage/lib + QMAKE_RPATHDIR += ../../../../../../stage/lib +} + +# Execute test once compiled. +win*: QMAKE_POST_LINK = .\\$${DESTDIR}\\$${TARGET}.exe +else: QMAKE_POST_LINK = ./$${DESTDIR}/$${TARGET} + diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/num_columns.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/num_columns.pro new file mode 100644 index 000000000..ee1d890dd --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/num_columns.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = num_columns + +include (configuration.pri) + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/num_columns.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/num_rows.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/num_rows.pro new file mode 100644 index 000000000..9de32bf95 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/num_rows.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = num_rows + +include (configuration.pri) + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/num_rows.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/placement_new.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/placement_new.pro new file mode 100644 index 000000000..11a05cec0 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/placement_new.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +TARGET = placement_new + +include (configuration.pri) + +SOURCES += \ + ../../../test/placement_new.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/size.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/size.pro new file mode 100644 index 000000000..69aee624e --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/size.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = size + +include (configuration.pri) + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/size.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/sparse_view_test.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/sparse_view_test.pro new file mode 100644 index 000000000..cd8172c98 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/sparse_view_test.pro @@ -0,0 +1,11 @@ +TEMPLATE = app +TARGET = sparse_view_test + +win*:QMAKE_CXXFLAGS += /EHa +# Support asynchronous structured exception handling +# (SEH) with the native C++ catch(...) clause. + +include (configuration.pri) + +SOURCES += \ + ../../../test/sparse_view_test.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test1.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test1.pro new file mode 100644 index 000000000..dae81d57c --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test1.pro @@ -0,0 +1,14 @@ +TEMPLATE = app +TARGET = test1 + +include (configuration.pri) + +DEFINES += $$UBLAS_TESTSET + +HEADERS += ../../../test/test1.hpp + +SOURCES += \ + ../../../test/test13.cpp \ + ../../../test/test12.cpp \ + ../../../test/test11.cpp \ + ../../../test/test1.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test2.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test2.pro new file mode 100644 index 000000000..e967a474a --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test2.pro @@ -0,0 +1,14 @@ +TEMPLATE = app +TARGET = test2 + +include (configuration.pri) + +DEFINES += $$UBLAS_TESTSET + +HEADERS += ../../../test/test2.hpp + +SOURCES += \ + ../../../test/test23.cpp \ + ../../../test/test22.cpp \ + ../../../test/test21.cpp \ + ../../../test/test2.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test3.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test3.pro new file mode 100644 index 000000000..69d0f4530 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test3.pro @@ -0,0 +1,14 @@ +TEMPLATE = app +TARGET = test3 + +include (configuration.pri) + +DEFINES += $$UBLAS_TESTSET_SPARSE + +HEADERS += ../../../test/test3.hpp + +SOURCES += \ + ../../../test/test33.cpp \ + ../../../test/test32.cpp \ + ../../../test/test31.cpp \ + ../../../test/test3.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test3_coo.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test3_coo.pro new file mode 100644 index 000000000..4af41c9d1 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test3_coo.pro @@ -0,0 +1,14 @@ +TEMPLATE = app +TARGET = test3_coo + +include (configuration.pri) + +DEFINES += $$UBLAS_TESTSET_SPARSE_COO + +HEADERS += ../../../test/test3.hpp + +SOURCES += \ + ../../../test/test33.cpp \ + ../../../test/test32.cpp \ + ../../../test/test31.cpp \ + ../../../test/test3.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test3_mvov.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test3_mvov.pro new file mode 100644 index 000000000..7009bdb17 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test3_mvov.pro @@ -0,0 +1,19 @@ +TEMPLATE = app +TARGET = test3_mvov + +include (configuration.pri) + +DEFINES += \ + USE_FLOAT \ + USE_DOUBLE \ + USE_STD_COMPLEX \ + USE_STD_MAP \ + USE_MAPPED_VECTOR_OF_MAPPED_VECTOR + +HEADERS += ../../../test/test3.hpp + +SOURCES += \ + ../../../test/test33.cpp \ + ../../../test/test32.cpp \ + ../../../test/test31.cpp \ + ../../../test/test3.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test4.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test4.pro new file mode 100644 index 000000000..0072a06a0 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test4.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = test4 + +include (configuration.pri) + +DEFINES += $$UBLAS_TESTSET + +HEADERS += ../../../test/test4.hpp + +SOURCES += \ + ../../../test/test43.cpp \ + ../../../test/test42.cpp \ + ../../../test/test4.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test5.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test5.pro new file mode 100644 index 000000000..7dfcb5c0b --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test5.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = test5 + +include (configuration.pri) + +DEFINES += $$UBLAS_TESTSET + +HEADERS += ../../../test/test5.hpp + +SOURCES += \ + ../../../test/test53.cpp \ + ../../../test/test52.cpp \ + ../../../test/test5.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test6.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test6.pro new file mode 100644 index 000000000..5721c8a83 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test6.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = test6 + +include (configuration.pri) + +DEFINES += $$UBLAS_TESTSET + +HEADERS += ../../../test/test6.hpp + +SOURCES += \ + ../../../test/test63.cpp \ + ../../../test/test62.cpp \ + ../../../test/test6.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test7.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test7.pro new file mode 100644 index 000000000..c34e201c8 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test7.pro @@ -0,0 +1,16 @@ +TEMPLATE = app +TARGET = test7 + +include (configuration.pri) + +DEFINES += \ + BOOST_UBLAS_USE_INTERVAL \ + $${UBLAS_TESTSET} + +HEADERS += ../../../test/test7.hpp + +SOURCES += \ + ../../../test/test73.cpp \ + ../../../test/test72.cpp \ + ../../../test/test71.cpp \ + ../../../test/test7.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_assignment.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_assignment.pro new file mode 100644 index 000000000..1956d82fc --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_assignment.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = test_assignment + +include (configuration.pri) + +DEFINES += \ + BOOST_UBLAS_COO_ALWAYS_DO_FULL_SORT + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_assignment.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_banded_storage_layout.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_banded_storage_layout.pro new file mode 100644 index 000000000..3cd992cf8 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_banded_storage_layout.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = test_banded_storage_layout + +include (configuration.pri) + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_banded_storage_layout.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_complex_norms.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_complex_norms.pro new file mode 100644 index 000000000..3bc6ae59b --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_complex_norms.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = test_complex_norms + +include (configuration.pri) + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_complex_norms.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_coordinate_matrix_always_do_full_sort.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_coordinate_matrix_always_do_full_sort.pro new file mode 100644 index 000000000..ef1ece33a --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_coordinate_matrix_always_do_full_sort.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = test_coordinate_matrix_always_do_full_sort + +include (configuration.pri) + +DEFINES += \ + BOOST_UBLAS_COO_ALWAYS_DO_FULL_SORT + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_coordinate_matrix_sort.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_coordinate_matrix_inplace_merge.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_coordinate_matrix_inplace_merge.pro new file mode 100644 index 000000000..c1b790116 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_coordinate_matrix_inplace_merge.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = test_coordinate_matrix_inplace_merge + +include (configuration.pri) + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_coordinate_matrix_inplace_merge.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_coordinate_matrix_sort.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_coordinate_matrix_sort.pro new file mode 100644 index 000000000..ba109cf1e --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_coordinate_matrix_sort.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = test_coordinate_matrix_sort + +include (configuration.pri) + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_coordinate_matrix_sort.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_coordinate_vector_inplace_merge.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_coordinate_vector_inplace_merge.pro new file mode 100644 index 000000000..c1b4e9a7d --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_coordinate_vector_inplace_merge.pro @@ -0,0 +1,9 @@ +TEMPLATE = app +TARGET = test_coordinate_vector_inplace_merge + +include (configuration.pri) +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_coordinate_vector_inplace_merge.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_fixed_containers.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_fixed_containers.pro new file mode 100644 index 000000000..bb7910546 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_fixed_containers.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = test_fixed_containers + +include (configuration.pri) + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_fixed_containers.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_inplace_solve_basic.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_inplace_solve_basic.pro new file mode 100644 index 000000000..c13f6af1d --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_inplace_solve_basic.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = test_inplace_solve_basic + +include (configuration.pri) + +DEFINES += \ + $$UBLAS_TESTSET + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_inplace_solve.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_inplace_solve_mvov.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_inplace_solve_mvov.pro new file mode 100644 index 000000000..3f3870e5d --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_inplace_solve_mvov.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = test_inplace_solve_mvov + +include (configuration.pri) + +DEFINES += \ + USE_MAPPED_VECTOR_OF_MAPPED_VECTOR + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_inplace_solve.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_inplace_solve_sparse.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_inplace_solve_sparse.pro new file mode 100644 index 000000000..47ebeffe4 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_inplace_solve_sparse.pro @@ -0,0 +1,14 @@ +TEMPLATE = app +TARGET = test_inplace_solve_sparse + +include (configuration.pri) + +DEFINES += \ + $$UBLAS_TESTSET_SPARSE \ + $$UBLAS_TESTSET_SPARSE_COO + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_inplace_solve.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_lu.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_lu.pro new file mode 100644 index 000000000..c44e45875 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_lu.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = test_lu + +include (configuration.pri) + +HEADERS += \ + ../../../test/common/testhelper.hpp + +SOURCES += \ + ../../../test/test_lu.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_matrix_vector.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_matrix_vector.pro new file mode 100644 index 000000000..f8fd541e9 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_matrix_vector.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = test_matrix_vector + +include (configuration.pri) + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_matrix_vector.cpp + +INCLUDEPATH += \ + ../../../include diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_tensor.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_tensor.pro new file mode 100644 index 000000000..539546631 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_tensor.pro @@ -0,0 +1,54 @@ +TEMPLATE = app +TARGET = test + +CONFIG -= qt +CONFIG += depend_includepath debug +win*: CONFIG += console + +QMAKE_CXXFLAGS += -fno-inline +QMAKE_CXXFLAGS += -std=c++17 +QMAKE_CXXFLAGS += -Wno-unknown-pragmas +#QMAKE_CXXFLAGS += --coverage + + +DEFINES += BOOST_UBLAS_NO_EXCEPTIONS +win*: DEFINES += _SCL_SECURE_NO_WARNINGS + +#Visual age IBM +xlc: DEFINES += BOOST_UBLAS_NO_ELEMENT_PROXIES + +# If ublas tests are build with boost source code then, +# then boost headers and boost libraries should be used. +exists(../../../../../../boost-build.jam) { + INCLUDEPATH += ../../../../../.. + LIBS += -L../../../../../../stage/lib + QMAKE_RPATHDIR += ../../../../../../stage/lib +} + + +LIBS +=-lboost_unit_test_framework +# -lgcov + +HEADERS += \ + ../../../test/tensor/utility.hpp + +SOURCES += \ + ../../../test/tensor/test_tensor.cpp \ + ../../../test/tensor/test_extents.cpp \ + ../../../test/tensor/test_strides.cpp \ + ../../../test/tensor/test_expression.cpp \ + ../../../test/tensor/test_expression_evaluation.cpp \ + ../../../test/tensor/test_functions.cpp \ + ../../../test/tensor/test_operators_comparison.cpp \ + ../../../test/tensor/test_operators_arithmetic.cpp \ + ../../../test/tensor/test_tensor_matrix_vector.cpp \ + ../../../test/tensor/test_multiplication.cpp \ + ../../../test/tensor/test_algorithms.cpp \ + ../../../test/tensor/test_einstein_notation.cpp \ + ../../../test/tensor/test_multi_index.cpp \ + ../../../test/tensor/test_multi_index_utility.cpp + + + +INCLUDEPATH += \ + ../../../include diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_ticket7296.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_ticket7296.pro new file mode 100644 index 000000000..b57af941d --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_ticket7296.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = test_ticket7296 + +include (configuration.pri) + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_ticket7296.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_triangular.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_triangular.pro new file mode 100644 index 000000000..734c985de --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_triangular.pro @@ -0,0 +1,16 @@ +TEMPLATE = app +TARGET = test_triangular + +include (configuration.pri) + +DEFINES += \ + BOOST_CHRONO_DYN_LINK=1 \ + BOOST_CHRONO_THREAD_DISABLED \ + BOOST_SYSTEM_DYN_LINK=1 \ + BOOST_SYSTEM_NO_DEPRECATED \ + BOOST_TIMER_DYN_LINK=1 + +SOURCES += \ + ../../../test/test_triangular.cpp + +LIBS += -lboost_timer -lboost_system -lboost_chrono diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/triangular_access.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/triangular_access.pro new file mode 100644 index 000000000..ac6da4ff3 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/triangular_access.pro @@ -0,0 +1,12 @@ +TEMPLATE = app +TARGET = triangular_access + +include (configuration.pri) + +DEFINES += NOMESSAGES + +HEADERS += \ + ../../../test/common/testhelper.hpp + +SOURCES += \ + ../../../test/triangular_access.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/triangular_layout.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/triangular_layout.pro new file mode 100644 index 000000000..1a16842e5 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/triangular_layout.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +TARGET = triangular_layout + +include (configuration.pri) + +SOURCES += \ + ../../../test/triangular_layout.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/tests.pri b/src/boost/libs/numeric/ublas/IDEs/qtcreator/tests.pri new file mode 100644 index 000000000..7b55d478c --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/tests.pri @@ -0,0 +1,72 @@ +SUBDIRS += \ + begin_end \ + comp_mat_erase \ + concepts \ + num_columns \ + num_rows \ + placement_new \ + size \ + sparse_view_test \ + test1 \ + test2 \ + test3 \ + test3_coo \ + test3_mvov \ + test4 \ + test5 \ + test6 \ + test7 \ + test_assignment \ + test_banded_storage_layout \ + test_complex_norms \ + test_coordinate_matrix_inplace_merge \ + test_coordinate_matrix_sort \ + test_coordinate_matrix_always_do_full_sort \ + test_coordinate_vector_inplace_merge \ + test_fixed_containers \ + test_inplace_solve_basic \ + test_inplace_solve_sparse \ + test_inplace_solve_mvov \ + test_lu \ + test_matrix_vector \ + test_ticket7296 \ + test_triangular \ + triangular_access \ + triangular_layout \ + test_tensor + +begin_end.file = test/begin_end.pro +comp_mat_erase.file = test/comp_mat_erase.pro +concepts.file = test/concepts.pro +num_columns.file = test/num_columns.pro +num_rows.file = test/num_rows.pro +placement_new.file = test/placement_new.pro +size.file = test/size.pro +sparse_view_test.file = test/sparse_view_test.pro +test1.file = test/test1.pro +test2.file = test/test2.pro +test3.file = test/test3.pro +test3_coo.file = test/test3_coo.pro +test3_mvov.file = test/test3_mvov.pro +test4.file = test/test4.pro +test5.file = test/test5.pro +test6.file = test/test6.pro +test7.file = test/test7.pro +test_assignment.file = test/test_assignment.pro +test_banded_storage_layout.file = test/test_banded_storage_layout.pro +test_complex_norms.file = test/test_complex_norms.pro +test_coordinate_matrix_inplace_merge.file = test/test_coordinate_matrix_inplace_merge.pro +test_coordinate_matrix_sort.file = test/test_coordinate_matrix_sort.pro +test_coordinate_matrix_always_do_full_sort.file = test/test_coordinate_matrix_always_do_full_sort.pro +test_coordinate_vector_inplace_merge.file = test/test_coordinate_vector_inplace_merge.pro +test_fixed_containers.file = test/test_fixed_containers.pro +test_inplace_solve_basic.file = test/test_inplace_solve_basic.pro +test_inplace_solve_sparse.file = test/test_inplace_solve_sparse.pro +test_inplace_solve_mvov.file = test/test_inplace_solve_mvov.pro +test_lu.file = test/test_lu.pro +test_matrix_vector.file = test/test_matrix_vector.pro +test_ticket7296.file = test/test_ticket7296.pro +test_triangular.file = test/test_triangular.pro +triangular_access.file = test/triangular_access.pro +triangular_layout.file = test/triangular_layout.pro +test_tensor.file = test/test_tensor.pro diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/ublas_develop.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/ublas_develop.pro new file mode 100644 index 000000000..8139f2493 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/ublas_develop.pro @@ -0,0 +1,17 @@ +TEMPLATE = subdirs +CONFIG += ordered +SUBDIRS = include examples # benchmarks +OTHER_FILES += ../../changelog.txt + + +include (tests.pri) + + + + + + + + + + diff --git a/src/boost/libs/numeric/ublas/README.md b/src/boost/libs/numeric/ublas/README.md new file mode 100644 index 000000000..66e2b271f --- /dev/null +++ b/src/boost/libs/numeric/ublas/README.md @@ -0,0 +1,46 @@ +Boost.uBLAS Linear Algebra Library +===== +Boost.uBLAS is part of the [Boost C++ Libraries](http://github.com/boostorg). It is directed towards scientific computing on the level of basic linear algebra constructions with matrices and vectors and their corresponding abstract operations. + + +## Documentation +uBLAS is documented at [boost.org](https://www.boost.org/doc/libs/1_69_0/libs/numeric/ublas/doc/index.html). +The development has a [wiki page](https://github.com/uBLAS/ublas/wiki). +The tensor extension has a separate [wiki page](https://github.com/BoostGSoC18/tensor/wiki). + +## License +Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt). + +## Properties +* Header-only +* Tensor extension requires C++17 compatible compiler, compiles with + * gcc 7.3.0 + * clang 6.0 + * msvc 14.1 +* Unit-tests require Boost.Test + +## Build Status + +Branch | Travis | Appveyor | codecov.io | Docs | +:-------------: | ------ | -------- | ---------- | ---- | +[`master`](https://github.com/boostorg/ublas/tree/master) | [![Build Status](https://travis-ci.org/boostorg/ublas.svg?branch=master)](https://travis-ci.org/boostorg/ublas) | [![Build status](https://ci.appveyor.com/api/projects/status/ctu3wnfowa627ful/branch/master?svg=true)](https://ci.appveyor.com/project/stefanseefeld/ublas/branch/master) | [![codecov](https://codecov.io/gh/boostorg/ublas/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/ublas/branch/master) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](http://www.boost.org/doc/libs/release/libs/numeric) +[`develop`](https://github.com/boostorg/ublas/tree/develop) | [![Build Status](https://travis-ci.org/boostorg/ublas.svg?branch=develop)](https://travis-ci.org/boostorg/ublas) | [![Build status](https://ci.appveyor.com/api/projects/status/ctu3wnfowa627ful/branch/develop?svg=true)](https://ci.appveyor.com/project/stefanseefeld/ublas/branch/develop) | [![codecov](https://codecov.io/gh/boostorg/ublas/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/ublas/branch/develop) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](http://www.boost.org/doc/libs/release/libs/numeric) + + +## Directories + +| Name | Purpose | +| ----------- | ------------------------------ | +| `doc` | documentation | +| `examples` | example files | +| `include` | headers | +| `test` | unit tests | +| `benchmarks`| timing and benchmarking | + +## More information + +* Ask questions in [stackoverflow](http://stackoverflow.com/questions/ask?tags=c%2B%2B,boost,boost-ublas) with `boost-ublas` or `ublas` tags. +* Report [bugs](https://github.com/boostorg/ublas/issues) and be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well. +* Submit your patches as pull requests against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt). +* Developer discussions about the library are held on the [Boost developers mailing list](https://lists.boost.org/mailman/listinfo.cgi/ublas). Be sure to read the [discussion policy](http://www.boost.org/community/policy.html) before posting and add the `[ublas]` tag at the beginning of the subject line +* For any other questions, you can contact David, Stefan or Cem: david.bellot-AT-gmail-DOT-com, cem.bassoy-AT-gmail-DOT-com stefan-AT-seefeld-DOT-name diff --git a/src/boost/libs/numeric/ublas/benchmarks/Jamfile b/src/boost/libs/numeric/ublas/benchmarks/Jamfile new file mode 100644 index 000000000..ab2f77e82 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/Jamfile @@ -0,0 +1,23 @@ +# +# Copyright (c) 2018 Stefan Seefeld +# 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) + +project boost/ublas/benchmarks + : requirements <library>/boost/program_options//boost_program_options + ; + +exe add : add.cpp ; +exe mm_prod : mm_prod.cpp ; +exe mv_prod : mv_prod.cpp ; +exe inner_prod : inner_prod.cpp ; +exe outer_prod : outer_prod.cpp ; + +exe reference/add : reference/add.cpp ; +exe reference/mm_prod : reference/mm_prod.cpp ; +exe reference/mv_prod : reference/mv_prod.cpp ; +exe reference/inner_prod : reference/inner_prod.cpp ; +exe reference/outer_prod : reference/outer_prod.cpp ; + +build-project opencl ; diff --git a/src/boost/libs/numeric/ublas/benchmarks/add.cpp b/src/boost/libs/numeric/ublas/benchmarks/add.cpp new file mode 100644 index 000000000..0bab90bc1 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/add.cpp @@ -0,0 +1,63 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/program_options.hpp> +#include "add.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + using vector = ublas::vector<T>; + bm::add<vector(vector, vector)> a("add(vector<" + type + ">, vector<" + type + ">)"); + a.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Vector-vector addition\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/add.hpp b/src/boost/libs/numeric/ublas/benchmarks/add.hpp new file mode 100644 index 000000000..d5d03d09f --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/add.hpp @@ -0,0 +1,36 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include "init.hpp" +#include "benchmark.hpp" + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename S> class add; + +template <typename R, typename O1, typename O2> +class add<R(O1, O2)> : public benchmark +{ +public: + add(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + c = a + b; + } +private: + O1 a; + O2 b; + R c; +}; + +}}}} diff --git a/src/boost/libs/numeric/ublas/benchmarks/benchmark.hpp b/src/boost/libs/numeric/ublas/benchmarks/benchmark.hpp new file mode 100644 index 000000000..b06cbe55f --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/benchmark.hpp @@ -0,0 +1,52 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#pragma once + +#include <iostream> +#include <chrono> +#include <ctime> +#include <cmath> +#include <string> +#include <vector> + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +class benchmark +{ + using clock = std::chrono::system_clock; +public: + benchmark(std::string const &name) : name_(name) {} + void print_header() + { + std::cout << "# benchmark : " << name_ << '\n' + << "# size \ttime (ms)" << std::endl; + } + virtual void setup(long) {} + virtual void operation(long) {} + virtual void teardown() {} + + void run(std::vector<long> const &sizes, unsigned times = 10) + { + print_header(); + for (auto s : sizes) + { + setup(s); + auto start = clock::now(); + for (unsigned i = 0; i != times; ++i) + operation(s); + auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(clock::now() - start); + teardown(); + std::cout << s << '\t' << duration.count()*1./times << std::endl; + } + } +private: + std::string name_; +}; + +}}}} diff --git a/src/boost/libs/numeric/ublas/benchmarks/init.hpp b/src/boost/libs/numeric/ublas/benchmarks/init.hpp new file mode 100644 index 000000000..1528389c3 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/init.hpp @@ -0,0 +1,37 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename T> +void init(vector<T> &v, unsigned long size, int max_value) +{ + v = vector<T>(size); + for (unsigned long i = 0; i < v.size(); ++i) + v(i) = std::rand() % max_value; +} + +template <typename T, typename L> +void init(matrix<T, L> &m, unsigned long size1, unsigned long size2, int max_value) +{ + m = matrix<T, L>(size1, size2); + for (unsigned long i = 0; i < m.size1(); ++i) + for (unsigned long j = 0; j < m.size2(); ++j) + m(i, j) = std::rand() % max_value; +} + +template <typename T, typename L> +void init(matrix<T, L> &m, unsigned long size, int max_value) +{ + return init(m, size, size, max_value); +} + +}}}} diff --git a/src/boost/libs/numeric/ublas/benchmarks/inner_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/inner_prod.cpp new file mode 100644 index 000000000..9d95a3339 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/inner_prod.cpp @@ -0,0 +1,89 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/program_options.hpp> +#include "init.hpp" +#include "benchmark.hpp" +#include <complex> +#include <string> + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename S> class inner_prod; + +template <typename R, typename V1, typename V2> +class inner_prod<R(V1, V2)> : public benchmark +{ +public: + inner_prod(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + c = ublas::inner_prod(a, b); + } +private: + V1 a; + V2 b; + R c; +}; + +}}}} + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + using vector = ublas::vector<T>; + bm::inner_prod<T(vector, vector)> p("inner_prod(vector<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Inner product\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/mm_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/mm_prod.cpp new file mode 100644 index 000000000..f87271c7e --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/mm_prod.cpp @@ -0,0 +1,62 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/program_options.hpp> +#include "prod.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + using matrix = ublas::matrix<T, ublas::basic_row_major<>>; + bm::prod<matrix(matrix, matrix)> p("prod(matrix<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512}));//, 1024})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Matrix product\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/mv_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/mv_prod.cpp new file mode 100644 index 000000000..bc6da2046 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/mv_prod.cpp @@ -0,0 +1,64 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/program_options.hpp> +#include "prod.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + using matrix = ublas::matrix<T, ublas::basic_row_major<>>; + using vector = ublas::vector<T>; + bm::prod<vector(matrix, vector)> p("prod(matrix<" + type + ">, vector<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Matrix-vector product\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/opencl/Jamfile b/src/boost/libs/numeric/ublas/benchmarks/opencl/Jamfile new file mode 100644 index 000000000..670ec66b8 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/opencl/Jamfile @@ -0,0 +1,27 @@ +# +# Copyright (c) 2018 Stefan Seefeld +# +# 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 ac ; + +# work around a bug in Boost.Build +import ../../opencl ; +import ../../clblas ; +using opencl ; +using clblas ; + +project boost/ublas/benchmarks/opencl + : requirements + <library>/boost/program_options//boost_program_options + <toolset>gcc:<cxxflags>-Wno-ignored-attributes + [ ac.check-library /clblas//clblas : <library>/clblas//clblas <library>/opencl//opencl : <build>no ] + ; + +exe add : add.cpp ; +exe mm_prod : mm_prod.cpp ; +exe mv_prod : mv_prod.cpp ; +exe inner_prod : inner_prod.cpp ; +exe outer_prod : outer_prod.cpp ; diff --git a/src/boost/libs/numeric/ublas/benchmarks/opencl/add.cpp b/src/boost/libs/numeric/ublas/benchmarks/opencl/add.cpp new file mode 100644 index 000000000..b998cd2c0 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/opencl/add.cpp @@ -0,0 +1,93 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// +// 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) + +#define BOOST_UBLAS_ENABLE_OPENCL +#include <boost/numeric/ublas/opencl.hpp> +#include <boost/program_options.hpp> +#include "benchmark.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; +namespace opencl = boost::numeric::ublas::opencl; + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { namespace opencl { + +template <typename S, bool C> class add; + +template <typename V, bool C> +class add<void(V,V,V), C> : public benchmark<void(V,V,V), C> +{ +public: + add(std::string const &name) : benchmark<void(V,V,V), C>(name) {} + virtual void operation(long l) + { + ublas::opencl::element_add(*this->a, *this->b, *this->c, this->queue); + } +}; + +}}}}} + +template <typename T> +void benchmark(std::string const &type, bool copy) +{ + using vector = ublas::vector<T>; + std::string name = "opencl::elementwise_add(vector<" + type + ">)"; + std::vector<long> sizes({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096}); + if (copy) + { + bm::opencl::add<void(vector, vector, vector), true> p(name); + p.run(sizes); + } + else + { + bm::opencl::add<void(vector, vector, vector), false> p(name); + p.run(sizes); + } +} + +int main(int argc, char **argv) +{ + opencl::library lib; + po::variables_map vm; + try + { + po::options_description desc("Matrix-vector product (OpenCL)\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + desc.add_options()("copy,c", po::value<bool>(), "include host<->device copy in timing"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + bool copy = vm.count("copy") ? vm["copy"].as<bool>() : false; + if (type == "float") + benchmark<float>("float", copy); + else if (type == "double") + benchmark<double>("double", copy); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>", copy); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>", copy); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/opencl/benchmark.hpp b/src/boost/libs/numeric/ublas/benchmarks/opencl/benchmark.hpp new file mode 100644 index 000000000..fb6075992 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/opencl/benchmark.hpp @@ -0,0 +1,214 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// +// 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) + +#ifndef opencl_benchmark_hpp_ +#define opencl_benchmark_hpp_ +#define BOOST_UBLAS_ENABLE_OPENCL + +#include <boost/numeric/ublas/opencl.hpp> +#include "../benchmark.hpp" +#include "init.hpp" +#include <memory> + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { +namespace opencl { + +struct base +{ + base(compute::device d = compute::system::default_device()) + : context(d), + queue(context, d) + {} + compute::context context; + compute::command_queue queue; +}; + +template <typename T, bool C> struct data_factory; +template <typename T> +struct data_factory<T, true> +{ + typedef T type; + typedef std::unique_ptr<type> ptr_type; + static ptr_type create(long) { return ptr_type(new T());} +}; +template <typename T> +struct data_factory<T, false> +{ + typedef T type; + typedef std::unique_ptr<type> ptr_type; + static ptr_type create(long, compute::context) { return ptr_type(new T());} +}; +template <> +struct data_factory<void, true> +{ + typedef void type; + typedef void *ptr_type; + static ptr_type create(long) { return 0;} +}; +template <> +struct data_factory<void, false> +{ + typedef void type; + typedef void *ptr_type; + static ptr_type create(long, compute::context) { return 0;} +}; +template <typename T> +struct data_factory<ublas::vector<T>, true> +{ + typedef ublas::vector<T> type; + typedef std::unique_ptr<type> ptr_type; + static ptr_type create(long l) { return ptr_type(new type(l));} +}; +template <typename T> +struct data_factory<ublas::vector<T>, false> +{ + typedef ublas::vector<T, ublas::opencl::storage> type; + typedef std::unique_ptr<type> ptr_type; + static ptr_type create(long l, compute::context c) + { return ptr_type(new type(l, c));} +}; +template <typename T, typename L> +struct data_factory<ublas::matrix<T, L>, true> +{ + typedef ublas::matrix<T, L> type; + typedef std::unique_ptr<type> ptr_type; + static ptr_type create(long l) + { return ptr_type(new type(l, l));} +}; +template <typename T, typename L> +struct data_factory<ublas::matrix<T, L>, false> +{ + typedef ublas::matrix<T, L, ublas::opencl::storage> type; + typedef std::unique_ptr<type> ptr_type; + static ptr_type create(long l, compute::context c) + { return ptr_type(new type(l, l, c));} +}; + +template <typename S, bool> class benchmark; + +template <typename R, typename O> +class benchmark<R(O), true> : public base, public ublas::benchmark::benchmark +{ +public: + benchmark(std::string const &name) + : base(), + ublas::benchmark::benchmark(name + " with copy") + {} + virtual void setup(long l) + { + r = data_factory<R, true>::create(l); + a = data_factory<O, true>::create(l); + init(*a, l, 200); + } + typename data_factory<R, true>::ptr_type r; + typename data_factory<O, true>::ptr_type a; +}; + +template <typename R, typename O1, typename O2> +class benchmark<R(O1, O2), true> : public base, public ublas::benchmark::benchmark +{ +public: + benchmark(std::string const &name) + : base(), + ublas::benchmark::benchmark(name + " with copy") + {} + virtual void setup(long l) + { + r = data_factory<R, true>::create(l); + a = data_factory<O1, true>::create(l); + init(*a, l, 200); + b = data_factory<O2, true>::create(l); + init(*b, l, 200); + } + typename data_factory<R, true>::ptr_type r; + typename data_factory<O1, true>::ptr_type a; + typename data_factory<O2, true>::ptr_type b; +}; + +template <typename R, typename O1, typename O2, typename O3> +class benchmark<R(O1, O2, O3), true> : public base, public ublas::benchmark::benchmark +{ +public: + benchmark(std::string const &name) + : base(), + ublas::benchmark::benchmark(name + " with copy") + {} + virtual void setup(long l) + { + r = data_factory<R, true>::create(l); + a = data_factory<O1, true>::create(l); + init(*a, l, 200); + b = data_factory<O2, true>::create(l); + init(*b, l, 200); + c = data_factory<O3, true>::create(l); + init(*c, l, 200); + } + typename data_factory<R, true>::ptr_type r; + typename data_factory<O1, true>::ptr_type a; + typename data_factory<O2, true>::ptr_type b; + typename data_factory<O3, true>::ptr_type c; +}; + +template <typename R, typename O> +class benchmark<R(O), false> : public base, public ublas::benchmark::benchmark +{ +public: + benchmark(std::string const &name) + : base(), + ublas::benchmark::benchmark(name + " w/o copy") + {} + virtual void setup(long l) + { + r = data_factory<R, false>::create(l, context); + a = data_factory<O, false>::create(l, context); + init(*a, l, 200); + } + typename data_factory<R, false>::ptr_type r; + typename data_factory<O, false>::ptr_type a; +}; + +template <typename R, typename O1, typename O2> +class benchmark<R(O1, O2), false> : public base, public ublas::benchmark::benchmark +{ +public: + benchmark(std::string const &name) : base(), ublas::benchmark::benchmark(name + " w/o copy") {} + virtual void setup(long l) + { + r = data_factory<R, false>::create(l, context); + a = data_factory<O1, false>::create(l, context); + init(*a, l, 200); + b = data_factory<O2, false>::create(l, context); + init(*b, l, 200); + } + typename data_factory<R, false>::ptr_type r; + typename data_factory<O1, false>::ptr_type a; + typename data_factory<O2, false>::ptr_type b; +}; + +template <typename R, typename O1, typename O2, typename O3> +class benchmark<R(O1, O2, O3), false> : public base, public ublas::benchmark::benchmark +{ +public: + benchmark(std::string const &name) : base(), ublas::benchmark::benchmark(name + " w/o copy") {} + virtual void setup(long l) + { + r = data_factory<R, false>::create(l, context); + a = data_factory<O1, false>::create(l, context); + init(*a, l, 200); + b = data_factory<O2, false>::create(l, context); + init(*b, l, 200); + c = data_factory<O3, false>::create(l, context); + init(*c, l, 200); + } + typename data_factory<R, false>::ptr_type r; + typename data_factory<O1, false>::ptr_type a; + typename data_factory<O2, false>::ptr_type b; + typename data_factory<O3, false>::ptr_type c; +}; +}}}}} + +#endif diff --git a/src/boost/libs/numeric/ublas/benchmarks/opencl/init.hpp b/src/boost/libs/numeric/ublas/benchmarks/opencl/init.hpp new file mode 100644 index 000000000..a11410283 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/opencl/init.hpp @@ -0,0 +1,40 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#pragma once + +#include <boost/numeric/ublas/opencl.hpp> +#include "../init.hpp" + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename T> +void init(T &v, unsigned long size, int max_value) +{ + // TBD +} + +template <typename T> +void init(vector<T, opencl::storage> &v, unsigned long size, int max_value) +{ + // TBD +} + +template <typename T> +void init(matrix<T, opencl::storage> &m, unsigned long size1, unsigned long size2, int max_value) +{ + // TBD +} + +template <typename T> +void init(matrix<T, opencl::storage> &m, unsigned long size, int max_value) +{ + init(m, size, size, max_value); +} + +}}}} diff --git a/src/boost/libs/numeric/ublas/benchmarks/opencl/inner_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/opencl/inner_prod.cpp new file mode 100644 index 000000000..a25664cbf --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/opencl/inner_prod.cpp @@ -0,0 +1,94 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#define BOOST_UBLAS_ENABLE_OPENCL +#include <boost/numeric/ublas/opencl.hpp> +#include <boost/program_options.hpp> +#include "benchmark.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; +namespace opencl = boost::numeric::ublas::opencl; + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { namespace opencl { + +template <typename S, bool C> class inner_prod; + +template <typename R, typename V, bool C> +class inner_prod<R(V,V), C> : public benchmark<R(V,V), C> +{ +public: + inner_prod(std::string const &name) : benchmark<R(V,V), C>(name) {} + virtual void operation(long l) + { + ublas::opencl::inner_prod(*this->a, *this->b, this->queue); + } +}; + +}}}}} + +template <typename T> +void benchmark(std::string const &type, bool copy) +{ + using vector = ublas::vector<T>; + std::string name = "opencl::inner_prod(vector<" + type + ">)"; + std::vector<long> sizes({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536}); + if (copy) + { + bm::opencl::inner_prod<T(vector,vector), true> p(name); + p.run(sizes); + } + else + { + bm::opencl::inner_prod<T(vector,vector), false> p(name); + p.run(sizes); + } +} + +int main(int argc, char **argv) +{ + opencl::library lib; + po::variables_map vm; + try + { + po::options_description desc("Inner product\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + desc.add_options()("copy,c", po::value<bool>(), "include host<->device copy in timing"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + bool copy = vm.count("copy") ? vm["copy"].as<bool>() : false; + if (type == "float") + benchmark<float>("float", copy); + else if (type == "double") + benchmark<double>("double", copy); + // else if (type == "fcomplex") + // benchmark<std::complex<float>>("std::complex<float>", copy); + // else if (type == "dcomplex") + // benchmark<std::complex<double>>("std::complex<double>", copy); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/opencl/mm_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/opencl/mm_prod.cpp new file mode 100644 index 000000000..e306031fe --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/opencl/mm_prod.cpp @@ -0,0 +1,94 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#define BOOST_UBLAS_ENABLE_OPENCL +#include <boost/numeric/ublas/opencl.hpp> +#include <boost/program_options.hpp> +#include "benchmark.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; +namespace opencl = boost::numeric::ublas::opencl; + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { namespace opencl { + +template <typename S, bool C> class prod; + +template <typename M, bool C> +class prod<void(M,M,M), C> : public benchmark<void(M,M,M), C> +{ +public: + prod(std::string const &name) : benchmark<void(M,M,M), C>(name) {} + virtual void operation(long l) + { + ublas::opencl::prod(*this->a, *this->b, *this->c, this->queue); + } +}; + +}}}}} + +template <typename T> +void benchmark(std::string const &type, bool copy) +{ + using matrix = ublas::matrix<T>; + std::string name = "opencl::prod(matrix<" + type + ">)"; + std::vector<long> sizes({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096}); + if (copy) + { + bm::opencl::prod<void(matrix, matrix, matrix), true> p(name); + p.run(sizes); + } + else + { + bm::opencl::prod<void(matrix, matrix, matrix), false> p(name); + p.run(sizes); + } +} + +int main(int argc, char **argv) +{ + opencl::library lib; + po::variables_map vm; + try + { + po::options_description desc("Matrix product (OpenCL)\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + desc.add_options()("copy,c", po::value<bool>(), "include host<->device copy in timing"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + bool copy = vm.count("copy") ? vm["copy"].as<bool>() : false; + if (type == "float") + benchmark<float>("float", copy); + else if (type == "double") + benchmark<double>("double", copy); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>", copy); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>", copy); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/opencl/mv_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/opencl/mv_prod.cpp new file mode 100644 index 000000000..70344a4b6 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/opencl/mv_prod.cpp @@ -0,0 +1,95 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#define BOOST_UBLAS_ENABLE_OPENCL +#include <boost/numeric/ublas/opencl.hpp> +#include <boost/program_options.hpp> +#include "benchmark.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; +namespace opencl = boost::numeric::ublas::opencl; + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { namespace opencl { + +template <typename S, bool C> class prod; + +template <typename M, typename V, bool C> +class prod<void(M,V,V), C> : public benchmark<void(M,V,V), C> +{ +public: + prod(std::string const &name) : benchmark<void(M,V,V), C>(name) {} + virtual void operation(long l) + { + ublas::opencl::prod(*this->a, *this->b, *this->c, this->queue); + } +}; + +}}}}} + +template <typename T> +void benchmark(std::string const &type, bool copy) +{ + using vector = ublas::vector<T>; + using matrix = ublas::matrix<T>; + std::string name = "opencl::prod(matrix<" + type + ", vector<" + type + ">)"; + std::vector<long> sizes({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096}); + if (copy) + { + bm::opencl::prod<void(matrix, vector, vector), true> p(name); + p.run(sizes); + } + else + { + bm::opencl::prod<void(matrix, vector, vector), false> p(name); + p.run(sizes); + } +} + +int main(int argc, char **argv) +{ + opencl::library lib; + po::variables_map vm; + try + { + po::options_description desc("Matrix-vector product (OpenCL)\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + desc.add_options()("copy,c", po::value<bool>(), "include host<->device copy in timing"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + bool copy = vm.count("copy") ? vm["copy"].as<bool>() : false; + if (type == "float") + benchmark<float>("float", copy); + else if (type == "double") + benchmark<double>("double", copy); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>", copy); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>", copy); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/opencl/outer_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/opencl/outer_prod.cpp new file mode 100644 index 000000000..b00bb840c --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/opencl/outer_prod.cpp @@ -0,0 +1,95 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#define BOOST_UBLAS_ENABLE_OPENCL +#include <boost/numeric/ublas/opencl.hpp> +#include <boost/program_options.hpp> +#include "benchmark.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; +namespace opencl = boost::numeric::ublas::opencl; + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { namespace opencl { + +template <typename S, bool C> class outer_prod; + +template <typename V, typename M, bool C> +class outer_prod<void(V,V,M), C> : public benchmark<void(V,V,M), C> +{ +public: + outer_prod(std::string const &name) : benchmark<void(V,V,M), C>(name) {} + virtual void operation(long l) + { + ublas::opencl::outer_prod(*this->a, *this->b, *this->c, this->queue); + } +}; + +}}}}} + +template <typename T> +void benchmark(std::string const &type, bool copy) +{ + using vector = ublas::vector<T>; + using matrix = ublas::matrix<T>; + std::string name = "opencl::outer_prod(vector<" + type + ">)"; + std::vector<long> sizes({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096}); + if (copy) + { + bm::opencl::outer_prod<void(vector, vector, matrix), true> p(name); + p.run(sizes); + } + else + { + bm::opencl::outer_prod<void(vector, vector, matrix), false> p(name); + p.run(sizes); + } +} + +int main(int argc, char **argv) +{ + opencl::library lib; + po::variables_map vm; + try + { + po::options_description desc("Outer product\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + desc.add_options()("copy,c", po::value<bool>(), "include host<->device copy in timing"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + bool copy = vm.count("copy") ? vm["copy"].as<bool>() : false; + if (type == "float") + benchmark<float>("float", copy); + else if (type == "double") + benchmark<double>("double", copy); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>", copy); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>", copy); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/outer_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/outer_prod.cpp new file mode 100644 index 000000000..b907c360f --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/outer_prod.cpp @@ -0,0 +1,90 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/program_options.hpp> +#include "init.hpp" +#include "benchmark.hpp" +#include <complex> +#include <string> + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename S> class outer_prod; + +template <typename R, typename V1, typename V2> +class outer_prod<R(V1, V2)> : public benchmark +{ +public: + outer_prod(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + c = ublas::outer_prod(a, b); + } +private: + V1 a; + V2 b; + R c; +}; + +}}}} + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + using vector = ublas::vector<T>; + using matrix = ublas::matrix<T>; + bm::outer_prod<matrix(vector, vector)> p("outer_prod(vector<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Outer product\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/plot.py b/src/boost/libs/numeric/ublas/benchmarks/plot.py new file mode 100755 index 000000000..1ca5e5a7f --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/plot.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python +# +# Copyright (c) 2018 Stefan Seefeld +# All rights reserved. +# +# This file is part of Boost.uBLAS. It is made available under the +# Boost Software License, Version 1.0. +# (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +import argparse +import matplotlib.pyplot as plt +import numpy as np + + +class plot(object): + + def __init__(self, label, data): + self.label = label + self.data = data + + +def load_file(filename): + + lines = open(filename, 'r').readlines() + label = lines[0][1:-1].strip() + lines = [l.strip() for l in lines] + lines = [l.split('#', 1)[0] for l in lines] + lines = [l for l in lines if l] + data = [l.split() for l in lines] + return plot(label, list(zip(*data))) + + +def main(argv): + + parser = argparse.ArgumentParser(prog=argv[0], description='benchmark plotter') + parser.add_argument('data', nargs='+', help='benchmark data to plot') + parser.add_argument('--log', choices=['no', 'all', 'x', 'y'], help='use a logarithmic scale') + args = parser.parse_args(argv[1:]) + runs = [load_file(d) for d in args.data] + plt.title('Benchmark plot') + plt.xlabel('size') + plt.ylabel('time (s)') + if args.log == 'all': + plot = plt.loglog + elif args.log == 'x': + plot = plt.semilogx + elif args.log == 'y': + plot = plt.semilogy + else: + plot = plt.plot + plots = [plot(r.data[0], r.data[1], label=r.label) for r in runs] + plt.legend() + plt.show() + return True + + +if __name__ == '__main__': + + import sys + sys.exit(0 if main(sys.argv) else 1) diff --git a/src/boost/libs/numeric/ublas/benchmarks/prod.hpp b/src/boost/libs/numeric/ublas/benchmarks/prod.hpp new file mode 100644 index 000000000..243bafcba --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/prod.hpp @@ -0,0 +1,36 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include "init.hpp" +#include "benchmark.hpp" + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename S> class prod; + +template <typename R, typename O1, typename O2> +class prod<R(O1, O2)> : public benchmark +{ +public: + prod(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + c = ublas::prod(a, b); + } +private: + O1 a; + O2 b; + R c; +}; + +}}}} diff --git a/src/boost/libs/numeric/ublas/benchmarks/reference/add.cpp b/src/boost/libs/numeric/ublas/benchmarks/reference/add.cpp new file mode 100644 index 000000000..d5b988701 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/reference/add.cpp @@ -0,0 +1,88 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <boost/program_options.hpp> +#include "../init.hpp" +#include "../benchmark.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename T> +class add : public benchmark +{ +public: + add(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + for (int i = 0; i < l; ++i) + c(i) = a(i) + b(i); + } +private: + ublas::vector<T> a; + ublas::vector<T> b; + ublas::vector<T> c; +}; + +}}}} + +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + bm::add<T> p("ref::add(vector<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Vector-vector addition (reference implementation)\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/reference/inner_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/reference/inner_prod.cpp new file mode 100644 index 000000000..dc1752579 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/reference/inner_prod.cpp @@ -0,0 +1,91 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/program_options.hpp> +#include "../init.hpp" +#include "../benchmark.hpp" +#include <complex> +#include <string> + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename S> class inner_prod; + +template <typename R, typename V1, typename V2> +class inner_prod<R(V1, V2)> : public benchmark +{ +public: + inner_prod(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + c = R(0); + for (int i = 0; i < l; ++i) + c += a(i) * b(i); + } +private: + V1 a; + V2 b; + R c; +}; + +}}}} + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + using vector = ublas::vector<T>; + bm::inner_prod<T(vector, vector)> p("ref::inner_prod(vector<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Inner product (reference implementation)\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/reference/mm_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/reference/mm_prod.cpp new file mode 100644 index 000000000..4b4363167 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/reference/mm_prod.cpp @@ -0,0 +1,93 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/program_options.hpp> +#include "../init.hpp" +#include "../benchmark.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename T> +class prod : public benchmark +{ +public: + prod(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + for (int i = 0; i < l; ++i) + for (int j = 0; j < l; ++j) + { + c(i,j) = 0; + for (int k = 0; k < l; ++k) + c(i,j) += a(i,k) * b(k,j); + } + } +private: + ublas::matrix<T> a; + ublas::matrix<T> b; + ublas::matrix<T> c; +}; + +}}}} + +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + // using matrix = ublas::matrix<T, ublas::basic_row_major<>>; + bm::prod<T> p("ref::prod(matrix<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512}));//, 1024})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Matrix product (reference implementation)\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/reference/mv_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/reference/mv_prod.cpp new file mode 100644 index 000000000..e3a157454 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/reference/mv_prod.cpp @@ -0,0 +1,92 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <boost/program_options.hpp> +#include "../init.hpp" +#include "../benchmark.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename T> +class prod : public benchmark +{ +public: + prod(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + for (int i = 0; i < l; ++i) + { + c(i) = 0; + for (int j = 0; j < l; ++j) + c(i) += a(i,j) * b(j); + } + } +private: + ublas::matrix<T> a; + ublas::vector<T> b; + ublas::vector<T> c; +}; + +}}}} + +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + bm::prod<T> p("ref::prod(vector<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Matrix-vector product (reference implementation)\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/reference/outer_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/reference/outer_prod.cpp new file mode 100644 index 000000000..a300066c2 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/reference/outer_prod.cpp @@ -0,0 +1,92 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/program_options.hpp> +#include "../init.hpp" +#include "../benchmark.hpp" +#include <complex> +#include <string> + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename S> class outer_prod; + +template <typename R, typename V1, typename V2> +class outer_prod<R(V1, V2)> : public benchmark +{ +public: + outer_prod(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + for (int i = 0; i < l; ++i) + for (int j = 0; j < l; ++j) + c(i,j) = - a(i) * b(j); + } +private: + V1 a; + V2 b; + R c; +}; + +}}}} + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + using vector = ublas::vector<T>; + using matrix = ublas::matrix<T>; + bm::outer_prod<matrix(vector, vector)> p("ref::outer_prod(vector<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Outer product (reference implementation)\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/clblas.jam b/src/boost/libs/numeric/ublas/clblas.jam new file mode 100644 index 000000000..d4fa247e3 --- /dev/null +++ b/src/boost/libs/numeric/ublas/clblas.jam @@ -0,0 +1,114 @@ +# Copyright (c) 2018 Stefan Seefeld +# +# Use, modification and distribution is subject to the Boost Software +# License Version 1.0. (See accompanying file LICENSE_1_0.txt or +# http://www.boost.org/LICENSE_1_0.txt) + +# Supports the clblas library +# +# After 'using clblas', the following targets are available: +# +# /clblas//clblas -- The clblas library + +import project ; +import ac ; +import errors ; +import feature ; +import "class" : new ; +import targets ; +import modules ; +import property-set ; +import toolset : using ; + +using opencl ; + +header = clBLAS.h ; +names = clBLAS ; + +library-id = 0 ; + +if --debug-configuration in [ modules.peek : ARGV ] +{ + .debug = true ; +} + +# Initializes the clblas library. +# +# Options for configuring clblas:: +# +# <search> +# The directory containing the clblas library. +# <name> +# Overrides the default library name. +# <include> +# The directory containing the clblas headers. +# +# Examples:: +# +# # Find clblas in the default system location +# using clblas ; +# # Find clblas in /usr/local +# using clblas : 1.2.7 +# : <include>/usr/local/include <search>/usr/local/lib ; +# +rule init ( version ? : # The clblas version (currently ignored) + options * : # A list of the options to use + requirements * ) # The requirements for the clblas target +{ + local caller = [ project.current ] ; + + if ! $(.initialized) + { + .initialized = true ; + + project.initialize $(__name__) ; + .project = [ project.current ] ; + project clblas ; + } + + local library-path = [ feature.get-values <search> : $(options) ] ; + local include-path = [ feature.get-values <include> : $(options) ] ; + local library-name = [ feature.get-values <name> : $(options) ] ; + + if ! $(library-path) && ! $(include-path) && ! $(library-name) + { + is-default = true ; + } + + condition = [ property-set.create $(requirements) ] ; + condition = [ property-set.create [ $(condition).base ] ] ; + + if $(.configured.$(condition)) + { + if $(is-default) + { + if $(.debug) + { + ECHO "notice: [clblas] clblas is already configured" ; + } + } + else + { + errors.user-error "clblas is already configured" ; + } + return ; + } + else + { + if $(.debug) + { + ECHO "notice: [clblas] Using pre-installed library" ; + if $(condition) + { + ECHO "notice: [clblas] Condition" [ $(condition).raw ] ; + } + } + + local mt = [ new ac-library clblas : $(.project) : $(condition) : + $(include-path) : $(library-path) : $(library-name) ] ; + $(mt).set-header $(header) ; + $(mt).set-default-names $(names) ; + targets.main-target-alternative $(mt) ; + } + .configured.$(condition) = true ; +} diff --git a/src/boost/libs/numeric/ublas/examples/tensor/Jamfile b/src/boost/libs/numeric/ublas/examples/tensor/Jamfile new file mode 100644 index 000000000..42f2fe633 --- /dev/null +++ b/src/boost/libs/numeric/ublas/examples/tensor/Jamfile @@ -0,0 +1,25 @@ +# Boost.uBLAS +# +# Copyright (c) 2018 Cem Bassoy +# +# Use, modification and distribution is 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) + + +# Project settings +project boost-ublas-tensor-example + : requirements + # these tests require C++17 + <cxxstd>11:<build>no + <define>BOOST_UBLAS_NO_EXCEPTIONS + <toolset>vacpp:<define>"BOOST_UBLAS_NO_ELEMENT_PROXIES" + <toolset>gcc:<cxxflags>"-Wall -pedantic -Wextra -std=c++17" + <toolset>gcc:<cxxflags>"-Wno-unknown-pragmas" + <toolset>msvc:<cxxflags>"/W4" # == all + ; + +exe construction_access : construction_access.cpp ; +exe simple_expressions : simple_expressions.cpp ; +exe prod_expressions : prod_expressions.cpp ; +exe einstein_notation : einstein_notation.cpp ;
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/examples/tensor/construction_access.cpp b/src/boost/libs/numeric/ublas/examples/tensor/construction_access.cpp new file mode 100644 index 000000000..053690c79 --- /dev/null +++ b/src/boost/libs/numeric/ublas/examples/tensor/construction_access.cpp @@ -0,0 +1,89 @@ +// +// Copyright (c) 2018-2019, Cem Bassoy, cem.bassoy@gmail.com +// +// 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) +// +// The authors gratefully acknowledge the support of +// Fraunhofer IOSB, Ettlingen, Germany +// + +#include <boost/numeric/ublas/tensor.hpp> +#include <boost/multiprecision/cpp_bin_float.hpp> + +#include <ostream> + +int main() +{ + using namespace boost::numeric::ublas; + using namespace boost::multiprecision; + + + // creates a three-dimensional tensor with extents 3,4 and 2 + // tensor A stores single-precision floating-point number according + // to the first-order storage format + using ftype = float; + auto A = tensor<ftype>{3,4,2}; + + // initializes the tensor with increasing values along the first-index + // using a single index. + auto vf = ftype(0); + for(auto i = 0u; i < A.size(); ++i, vf += ftype(1)) + A[i] = vf; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "A=" << A << ";" << std::endl << std::endl; + + // creates a four-dimensional tensor with extents 5,4,3 and 2 + // tensor A stores complex floating-point extended double precision numbers + // according to the last-order storage format + // and initializes it with the default value. + using ctype = std::complex<cpp_bin_float_double_extended>; + auto B = tensor<ctype,last_order>(shape{5,4,3,2},ctype{}); + + // initializes the tensor with increasing values along the last-index + // using a single-index + auto vc = ctype(0,0); + for(auto i = 0u; i < B.size(); ++i, vc += ctype(1,1)) + B[i] = vc; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "B=" << B << ";" << std::endl << std::endl; + + + + auto C = tensor<ctype,last_order>(B.extents()); + // computes the complex conjugate of elements of B + // using multi-index notation. + for(auto i = 0u; i < B.size(0); ++i) + for(auto j = 0u; j < B.size(1); ++j) + for(auto k = 0u; k < B.size(2); ++k) + for(auto l = 0u; l < B.size(3); ++l) + C.at(i,j,k,l) = std::conj(B.at(i,j,k,l)); + + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "C=" << C << ";" << std::endl << std::endl; + + + // computes the complex conjugate of elements of B + // using iterators. + auto D = tensor<ctype,last_order>(B.extents()); + std::transform(B.begin(), B.end(), D.begin(), [](auto const& b){ return std::conj(b); }); + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "D=" << D << ";" << std::endl << std::endl; + + // reshaping tensors. + auto new_extents = B.extents().base(); + std::next_permutation( new_extents.begin(), new_extents.end() ); + D.reshape( shape(new_extents) ); + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "newD=" << D << ";" << std::endl << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/examples/tensor/einstein_notation.cpp b/src/boost/libs/numeric/ublas/examples/tensor/einstein_notation.cpp new file mode 100644 index 000000000..1d95fc06b --- /dev/null +++ b/src/boost/libs/numeric/ublas/examples/tensor/einstein_notation.cpp @@ -0,0 +1,139 @@ +// +// Copyright (c) 2018-2019, Cem Bassoy, cem.bassoy@gmail.com +// +// 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) +// +// The authors gratefully acknowledge the support of +// Fraunhofer IOSB, Ettlingen, Germany +// + + +#include <boost/numeric/ublas/tensor.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <iostream> + +int main() +{ + using namespace boost::numeric::ublas; + + using format_t = column_major; + using value_t = float; + using tensor_t = tensor<value_t,format_t>; + using matrix_t = matrix<value_t,format_t>; + using namespace boost::numeric::ublas::index; + + // Tensor-Vector-Multiplications - Including Transposition + { + + auto n = shape{3,4,2}; + auto A = tensor_t(n,1); + auto B1 = matrix_t(n[1],n[2],2); + auto v1 = tensor_t(shape{n[0],1},2); + auto v2 = tensor_t(shape{n[1],1},2); +// auto v3 = tensor_t(shape{n[2],1},2); + + // C1(j,k) = B1(j,k) + A(i,j,k)*v1(i); + // tensor_t C1 = B1 + prod(A,vector_t(n[0],1),1); +// tensor_t C1 = B1 + A(_i,_,_) * v1(_i,_); + + // C2(i,k) = A(i,j,k)*v2(j) + 4; + //tensor_t C2 = prod(A,vector_t(n[1],1),2) + 4; +// tensor_t C2 = A(_,_i,_) * v2(_i,_) + 4; + + // not yet implemented! + // C3() = A(i,j,k)*T1(i)*T2(j)*T2(k); + // tensor_t C3 = prod(prod(prod(A,v1,1),v2,1),v3,1); + // tensor_t C3 = A(_i,_j,_k) * v1(_i,_) * v2(_j,_) * v3(_k,_); + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C1(j,k) = B1(j,k) + A(i,j,k)*v1(i);" << std::endl << std::endl; +// std::cout << "C1=" << C1 << ";" << std::endl << std::endl; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C2(i,k) = A(i,j,k)*v2(j) + 4;" << std::endl << std::endl; +// std::cout << "C2=" << C2 << ";" << std::endl << std::endl; + + } + + + // Tensor-Matrix-Multiplications - Including Transposition + { + auto n = shape{3,4,2}; + auto m = 5u; + auto A = tensor_t(n,2); + auto B = tensor_t(shape{n[1],n[2],m},2); + auto B1 = tensor_t(shape{m,n[0]},1); + auto B2 = tensor_t(shape{m,n[1]},1); + + + // C1(l,j,k) = B(j,k,l) + A(i,j,k)*B1(l,i); + // tensor_t C1 = B + prod(A,B1,1); +// tensor_t C1 = B + A(_i,_,_) * B1(_,_i); + + // C2(i,l,k) = A(i,j,k)*B2(l,j) + 4; + // tensor_t C2 = prod(A,B2) + 4; +// tensor_t C2 = A(_,_j,_) * B2(_,_j) + 4; + + // C3(i,l1,l2) = A(i,j,k)*T1(l1,j)*T2(l2,k); + // not yet implemented. + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C1(l,j,k) = B(j,k,l) + A(i,j,k)*B1(l,i);" << std::endl << std::endl; +// std::cout << "C1=" << C1 << ";" << std::endl << std::endl; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C2(i,l,k) = A(i,j,k)*B2(l,j) + 4;" << std::endl << std::endl; +// std::cout << "C2=" << C2 << ";" << std::endl << std::endl; + +// // formatted output +// std::cout << "% --------------------------- " << std::endl; +// std::cout << "% --------------------------- " << std::endl << std::endl; +// std::cout << "% C3(i,l1,l2) = A(i,j,k)*T1(l1,j)*T2(l2,k);" << std::endl << std::endl; +// std::cout << "C3=" << C3 << ";" << std::endl << std::endl; + } + + + // Tensor-Tensor-Multiplications Including Transposition + { + auto na = shape{3,4,5}; + auto nb = shape{4,6,3,2}; + auto A = tensor_t(na,2); + auto B = tensor_t(nb,3); + auto T1 = tensor_t(shape{na[2],na[2]},2); + auto T2 = tensor_t(shape{na[2],nb[1],nb[3]},2); + + + // C1(j,l) = T1(j,l) + A(i,j,k)*A(i,j,l) + 5; + // tensor_t C1 = T1 + prod(A,A,perm_t{1,2}) + 5; +// tensor_t C1 = T1 + A(_i,_j,_m)*A(_i,_j,_l) + 5; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C1(k,l) = T1(k,l) + A(i,j,k)*A(i,j,l) + 5;" << std::endl << std::endl; +// std::cout << "C1=" << C1 << ";" << std::endl << std::endl; + + + // C2(k,l,m) = T2(k,l,m) + A(i,j,k)*B(j,l,i,m) + 5; + //tensor_t C2 = T2 + prod(A,B,perm_t{1,2},perm_t{3,1}) + 5; +// tensor_t C2 = T2 + A(_i,_j,_k)*B(_j,_l,_i,_m) + 5; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C2(k,l,m) = T2(k,l,m) + A(i,j,k)*B(j,l,i,m) + 5;" << std::endl << std::endl; +// std::cout << "C2=" << C2 << ";" << std::endl << std::endl; + + } +} diff --git a/src/boost/libs/numeric/ublas/examples/tensor/prod_expressions.cpp b/src/boost/libs/numeric/ublas/examples/tensor/prod_expressions.cpp new file mode 100644 index 000000000..6ff725214 --- /dev/null +++ b/src/boost/libs/numeric/ublas/examples/tensor/prod_expressions.cpp @@ -0,0 +1,183 @@ +// +// Copyright (c) 2018-2019, Cem Bassoy, cem.bassoy@gmail.com +// +// 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) +// +// The authors gratefully acknowledge the support of +// Fraunhofer IOSB, Ettlingen, Germany +// + + +#include <boost/numeric/ublas/tensor.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <iostream> + +int main() +{ + using namespace boost::numeric::ublas; + + using format_t = column_major; + using value_t = float; // std::complex<double>; + using tensor_t = tensor<value_t,format_t>; + using matrix_t = matrix<value_t,format_t>; + using vector_t = vector<value_t>; + + // Tensor-Vector-Multiplications - Including Transposition + { + + auto n = shape{3,4,2}; + auto A = tensor_t(n,2); + auto q = 0u; // contraction mode + + // C1(j,k) = T2(j,k) + A(i,j,k)*T1(i); + q = 1u; + tensor_t C1 = matrix_t(n[1],n[2],2) + prod(A,vector_t(n[q-1],1),q); + + // C2(i,k) = A(i,j,k)*T1(j) + 4; + q = 2u; + tensor_t C2 = prod(A,vector_t(n[q-1],1),q) + 4; + + // C3() = A(i,j,k)*T1(i)*T2(j)*T2(k); + tensor_t C3 = prod(prod(prod(A,vector_t(n[0],1),1),vector_t(n[1],1),1),vector_t(n[2],1),1); + + // C4(i,j) = A(k,i,j)*T1(k) + 4; + q = 1u; + tensor_t C4 = prod(trans(A,{2,3,1}),vector_t(n[2],1),q) + 4; + + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C1(j,k) = T2(j,k) + A(i,j,k)*T1(i);" << std::endl << std::endl; + std::cout << "C1=" << C1 << ";" << std::endl << std::endl; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C2(i,k) = A(i,j,k)*T1(j) + 4;" << std::endl << std::endl; + std::cout << "C2=" << C2 << ";" << std::endl << std::endl; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C3() = A(i,j,k)*T1(i)*T2(j)*T2(k);" << std::endl << std::endl; + std::cout << "C3()=" << C3(0) << ";" << std::endl << std::endl; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C4(i,j) = A(k,i,j)*T1(k) + 4;" << std::endl << std::endl; + std::cout << "C4=" << C4 << ";" << std::endl << std::endl; + + } + + + // Tensor-Matrix-Multiplications - Including Transposition + { + + auto n = shape{3,4,2}; + auto A = tensor_t(n,2); + auto m = 5u; + auto q = 0u; // contraction mode + + // C1(l,j,k) = T2(l,j,k) + A(i,j,k)*T1(l,i); + q = 1u; + tensor_t C1 = tensor_t(shape{m,n[1],n[2]},2) + prod(A,matrix_t(m,n[q-1],1),q); + + // C2(i,l,k) = A(i,j,k)*T1(l,j) + 4; + q = 2u; + tensor_t C2 = prod(A,matrix_t(m,n[q-1],1),q) + 4; + + // C3(i,l1,l2) = A(i,j,k)*T1(l1,j)*T2(l2,k); + q = 3u; + tensor_t C3 = prod(prod(A,matrix_t(m+1,n[q-2],1),q-1),matrix_t(m+2,n[q-1],1),q); + + // C4(i,l1,l2) = A(i,j,k)*T2(l2,k)*T1(l1,j); + tensor_t C4 = prod(prod(A,matrix_t(m+2,n[q-1],1),q),matrix_t(m+1,n[q-2],1),q-1); + + // C5(i,k,l) = A(i,k,j)*T1(l,j) + 4; + q = 3u; + tensor_t C5 = prod(trans(A,{1,3,2}),matrix_t(m,n[1],1),q) + 4; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C1(l,j,k) = T2(l,j,k) + A(i,j,k)*T1(l,i);" << std::endl << std::endl; + std::cout << "C1=" << C1 << ";" << std::endl << std::endl; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C2(i,l,k) = A(i,j,k)*T1(l,j) + 4;" << std::endl << std::endl; + std::cout << "C2=" << C2 << ";" << std::endl << std::endl; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C3(i,l1,l2) = A(i,j,k)*T1(l1,j)*T2(l2,k);" << std::endl << std::endl; + std::cout << "C3=" << C3 << ";" << std::endl << std::endl; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C4(i,l1,l2) = A(i,j,k)*T2(l2,k)*T1(l1,j);" << std::endl << std::endl; + std::cout << "C4=" << C4 << ";" << std::endl << std::endl; + std::cout << "% C3 and C4 should have the same values, true? " << std::boolalpha << (C3 == C4) << "!" << std::endl; + + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C5(i,k,l) = A(i,k,j)*T1(l,j) + 4;" << std::endl << std::endl; + std::cout << "C5=" << C5 << ";" << std::endl << std::endl; + } + + + + + + // Tensor-Tensor-Multiplications Including Transposition + { + + using perm_t = std::vector<std::size_t>; + + auto na = shape{3,4,5}; + auto nb = shape{4,6,3,2}; + auto A = tensor_t(na,2); + auto B = tensor_t(nb,3); + + + // C1(j,l) = T(j,l) + A(i,j,k)*A(i,j,l) + 5; + tensor_t C1 = tensor_t(shape{na[2],na[2]},2) + prod(A,A,perm_t{1,2}) + 5; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C1(k,l) = T(k,l) + A(i,j,k)*A(i,j,l) + 5;" << std::endl << std::endl; + std::cout << "C1=" << C1 << ";" << std::endl << std::endl; + + + // C2(k,l,m) = T(k,l,m) + A(i,j,k)*B(j,l,i,m) + 5; + tensor_t C2 = tensor_t(shape{na[2],nb[1],nb[3]},2) + prod(A,B,perm_t{1,2},perm_t{3,1}) + 5; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C2(k,l,m) = T(k,l,m) + A(i,j,k)*B(j,l,i,m) + 5;" << std::endl << std::endl; + std::cout << "C2=" << C2 << ";" << std::endl << std::endl; + + + // C3(k,l,m) = T(k,l,m) + A(i,j,k)*trans(B(j,l,i,m),{2,3,1,4})+ 5; + tensor_t C3 = tensor_t(shape{na[2],nb[1],nb[3]},2) + prod(A,trans(B,{2,3,1,4}),perm_t{1,2}) + 5; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C3(k,l,m) = T(k,l,m) + A(i,j,k)*trans(B(j,l,i,m),{2,3,1,4})+ 5;" << std::endl << std::endl; + std::cout << "C3=" << C3 << ";" << std::endl << std::endl; + + } +} diff --git a/src/boost/libs/numeric/ublas/examples/tensor/simple_expressions.cpp b/src/boost/libs/numeric/ublas/examples/tensor/simple_expressions.cpp new file mode 100644 index 000000000..fabb00f4b --- /dev/null +++ b/src/boost/libs/numeric/ublas/examples/tensor/simple_expressions.cpp @@ -0,0 +1,63 @@ +// +// Copyright (c) 2018-2019, Cem Bassoy, cem.bassoy@gmail.com +// +// 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) +// +// The authors gratefully acknowledge the support of +// Fraunhofer IOSB, Ettlingen, Germany +// + + +#include <boost/numeric/ublas/tensor.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <ostream> + +int main() +{ + using namespace boost::numeric::ublas; + + using tensorf = tensor<float>; + using matrixf = matrix<float>; + using vectorf = vector<float>; + + auto A = tensorf{3,4,2}; + auto B = A = 2; + + // Calling overloaded operators + // and using simple tensor expression templates. + if( A != (B+1) ) + A += 2*B - 1; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "A=" << A << ";" << std::endl << std::endl; + + auto n = shape{3,4}; + auto D = matrixf(n[0],n[1],1); + auto e = vectorf(n[1],1); + auto f = vectorf(n[0],2); + + // Calling constructor with + // vector expression templates + tensorf C = 2*f; + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "C=" << C << ";" << std::endl << std::endl; + + + // Calling overloaded operators + // and mixing simple tensor and matrix expression templates + tensorf F = 3*C + 4*prod(2*D,e); + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "F=" << F << ";" << std::endl << std::endl; + + +} diff --git a/src/boost/libs/numeric/ublas/index.html b/src/boost/libs/numeric/ublas/index.html new file mode 100644 index 000000000..16cd00158 --- /dev/null +++ b/src/boost/libs/numeric/ublas/index.html @@ -0,0 +1,10 @@ +<html> +<head> +<meta http-equiv="refresh" content="0; URL=doc/index.html"> +</head> +<body> +Automatic redirection failed, please go to +<a href="doc/index.html">doc/index.html</a> <hr> +<p>Distributed under the Boost Software License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p> +</body> +</html> diff --git a/src/boost/libs/numeric/ublas/meta/libraries.json b/src/boost/libs/numeric/ublas/meta/libraries.json new file mode 100644 index 000000000..df121c3c3 --- /dev/null +++ b/src/boost/libs/numeric/ublas/meta/libraries.json @@ -0,0 +1,16 @@ +{ + "key": "numeric/ublas", + "name": "uBLAS", + "authors": [ + "Joerg Walter", + "Mathias Koch" + ], + "description": "uBLAS provides tensor, matrix, and vector classes as well as basic linear algebra routines. Several dense, packed and sparse storage schemes are supported.", + "category": [ + "Math" + ], + "maintainers": [ + "David Bellot <david.bellot -at- gmail.com>", + "Stefan Seefeld <stefan -at- seefeld.name>" + ] +} diff --git a/src/boost/libs/numeric/ublas/opencl.jam b/src/boost/libs/numeric/ublas/opencl.jam new file mode 100644 index 000000000..f16193a92 --- /dev/null +++ b/src/boost/libs/numeric/ublas/opencl.jam @@ -0,0 +1,111 @@ +# Copyright (c) 2018 Stefan Seefeld +# +# Use, modification and distribution is subject to the Boost Software +# License Version 1.0. (See accompanying file LICENSE_1_0.txt or +# http://www.boost.org/LICENSE_1_0.txt) + +# Supports the opencl library +# +# After 'using opencl', the following targets are available: +# +# /opencl//opencl -- The OpenCL library + +import project ; +import ac ; +import errors ; +import feature ; +import "class" : new ; +import targets ; +import modules ; +import property-set ; + +header = CL/cl.h ; +names = OpenCL ; + +library-id = 0 ; + +if --debug-configuration in [ modules.peek : ARGV ] +{ + .debug = true ; +} + +# Initializes the opencl library. +# +# Options for configuring opencl:: +# +# <search> +# The directory containing the OpenCL library. +# <name> +# Overrides the default library name. +# <include> +# The directory containing the OpenCL headers. +# +# Examples:: +# +# # Find OpenCL in the default system location +# using opencl ; +# # Find opencl in /usr/local +# using opencl : 1.2.7 +# : <include>/usr/local/include <search>/usr/local/lib ; +# +rule init ( version ? : # The opencl version (currently ignored) + options * : # A list of the options to use + requirements * ) # The requirements for the opencl target +{ + local caller = [ project.current ] ; + + if ! $(.initialized) + { + .initialized = true ; + + project.initialize $(__name__) ; + .project = [ project.current ] ; + project opencl ; + } + + local library-path = [ feature.get-values <search> : $(options) ] ; + local include-path = [ feature.get-values <include> : $(options) ] ; + local library-name = [ feature.get-values <name> : $(options) ] ; + + if ! $(library-path) && ! $(include-path) && ! $(library-name) + { + is-default = true ; + } + + condition = [ property-set.create $(requirements) ] ; + condition = [ property-set.create [ $(condition).base ] ] ; + + if $(.configured.$(condition)) + { + if $(is-default) + { + if $(.debug) + { + ECHO "notice: [opencl] opencl is already configured" ; + } + } + else + { + errors.user-error "opencl is already configured" ; + } + return ; + } + else + { + if $(.debug) + { + ECHO "notice: [opencl] Using pre-installed library" ; + if $(condition) + { + ECHO "notice: [opencl] Condition" [ $(condition).raw ] ; + } + } + + local mt = [ new ac-library opencl : $(.project) : $(condition) : + $(include-path) : $(library-path) : $(library-name) ] ; + $(mt).set-header $(header) ; + $(mt).set-default-names $(names) ; + targets.main-target-alternative $(mt) ; + } + .configured.$(condition) = true ; +} diff --git a/src/boost/libs/numeric/ublas/test/Jamfile b/src/boost/libs/numeric/ublas/test/Jamfile new file mode 100644 index 000000000..26b67b045 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/Jamfile @@ -0,0 +1,258 @@ +# Copyright (c) 2004-2011 Michael Stevens, David Bellot +# 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) + +# Bring in rules for testing +import testing ; + +# Define features to test: +# Value types: USE_FLOAT USE_DOUBLE USE_STD_COMPLEX +# Proxies: USE_RANGE USE_SLICE +# Storage types: USE_BOUNDED_ARRAY USE_UNBOUNDED_ARRAY +# Vector types: USE_STD_VECTOR USE_BOUNDED_VECTOR +# Matrix types: USE_MATRIX USE_BOUNDED_MATRIX USE_VECTOR_OF_VECTOR +# Adaptors: USE_ADAPTOR + +UBLAS_TESTSET = [ modules.peek : UBLAS_TESTSET ] ; +UBLAS_TESTSET ?= + USE_DOUBLE USE_STD_COMPLEX + USE_RANGE USE_SLICE + USE_UNBOUNDED_ARRAY USE_STD_VECTOR USE_BOUNDED_VECTOR USE_MATRIX + ; + +# Sparse storage: USE_MAP_ARRAY USE_STD_MAP +# Sparse vectors: USE_MAPPED_VECTOR USE_COMPRESSED_VECTOR USE_COORDINATE_VECTOR +# Sparse matrices: USE_MAPPED_MATRIX USE_COMPRESSED_MATRIX USE_COORDINATE_MATRIX USE_MAPPED_VECTOR_OF_MAPPED_VECTOR USE_GENERALIZED_VECTOR_OF_VECTOR + +UBLAS_TESTSET_SPARSE = [ modules.peek : UBLAS_TESTSET_SPARSE ] ; +UBLAS_TESTSET_SPARSE ?= + USE_DOUBLE USE_STD_COMPLEX + # USE_RANGE USE_SLICE # Too complex for regression testing + USE_UNBOUNDED_ARRAY + USE_MAP_ARRAY USE_STD_MAP + USE_MAPPED_VECTOR USE_COMPRESSED_VECTOR + USE_MAPPED_MATRIX USE_COMPRESSED_MATRIX + ; +# Generalize VofV still failing +# USE_GENERALIZED_VECTOR_OF_VECTOR + +UBLAS_TESTSET_SPARSE_COO = [ modules.peek : UBLAS_TESTSET_SPARSE_COO ] ; +UBLAS_TESTSET_SPARSE_COO ?= + USE_DOUBLE USE_STD_COMPLEX + USE_UNBOUNDED_ARRAY + USE_COORDINATE_VECTOR + USE_COORDINATE_MATRIX + ; + + +# Project settings +project boost-ublas-test + : requirements + <define>BOOST_UBLAS_NO_EXCEPTIONS + <toolset>vacpp:<define>"BOOST_UBLAS_NO_ELEMENT_PROXIES" + <toolset>gcc:<cxxflags>"-Wall -Wno-unknown-pragmas" + <toolset>msvc:<cxxflags>/bigobj + <toolset>msvc:<cxxflags>"/W4" # == all + # The define of macros below prevent warnings about the checked versions of SCL and CRT libraries. + # Most Boost code does not need these versions (as they are markedly slower). + <toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS + <toolset>msvc:<define>_SCL_SECURE_NO_DEPRECATE + <toolset>msvc:<define>_CRT_SECURE_NO_WARNINGS + <toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE + <toolset>msvc:<define>_CRT_NONSTDC_NO_DEPRECATE # Suppresses other warnings about using standard POSIX and C9X. + # Alternatively, you can just suppress the warnings (perhaps not the best way). + #<toolset>msvc:<cxxflags>/wd4996 # 'putenv': The POSIX name for this item is deprecated. + #<toolset>msvc:<cxxflags>/wd4512 # assignment operator could not be generated. + #<toolset>msvc:<cxxflags>/wd4224 # nonstandard extension used : formal parameter 'arg' was previously defined as a type. + #<toolset>msvc:<cxxflags>/wd4127 # expression is constant. + #<toolset>msvc:<cxxflags>/wd4701 # unreachable code - needed for lexical cast - temporary for Boost 1.40 & earlier. + ; + + + + +test-suite numeric/uBLAS + : [ run test1.cpp + test11.cpp + test12.cpp + test13.cpp + : # args + : # input files + : # requirements + <define>$(UBLAS_TESTSET) + ] + [ run test2.cpp + test21.cpp + test22.cpp + test23.cpp + : : : + <define>$(UBLAS_TESTSET) + ] + [ run test3.cpp + test31.cpp + test32.cpp + test33.cpp + : : : + <define>$(UBLAS_TESTSET_SPARSE) + ] + [ run test3.cpp + test31.cpp + test32.cpp + test33.cpp + : : : + <define>$(UBLAS_TESTSET_SPARSE_COO) + : test3_coo + : + ] + [ run test3.cpp + test31.cpp + test32.cpp + test33.cpp + : : : + <define>USE_FLOAT + <define>USE_DOUBLE + <define>USE_STD_COMPLEX + <define>USE_STD_MAP + <define>USE_MAPPED_VECTOR_OF_MAPPED_VECTOR + : test3_mvov + : + ] + [ run test4.cpp + test42.cpp + test43.cpp + : : : + <define>$(UBLAS_TESTSET) + ] + [ run test5.cpp + test52.cpp + test53.cpp + : : : + <define>$(UBLAS_TESTSET) + ] + [ run test6.cpp + test62.cpp + test63.cpp + : : : + <define>$(UBLAS_TESTSET) + ] +# Test commented out because boost::interval does not behave like a scalar type +# [ run test7.cpp +# test71.cpp +# test72.cpp +# test73.cpp +# : : : +# <define>BOOST_UBLAS_USE_INTERVAL +# <define>$(UBLAS_TESTSET) +# ] + + [ run placement_new.cpp + ] + [ compile concepts.cpp + : # requirements + <define>EXTERNAL +# <define>INTERAL +# <define>SKIP_BAD + <toolset>intel-linux:<cxxflags>"-Xc" + <toolset>darwin:<cxxflags>"-fabi-version=0" + ] + [ run test_lu.cpp + : : : + ] + [ run triangular_access.cpp + : : : + <define>NOMESSAGES + ] + [ run triangular_layout.cpp + ] + [ run comp_mat_erase.cpp + : : : + <toolset>msvc:<asynch-exceptions>on + ] + [ run sparse_view_test.cpp + : : : + <toolset>msvc:<asynch-exceptions>on + ] + [ run begin_end.cpp + ] + [ run num_columns.cpp + ] + [ run num_rows.cpp + ] + [ run size.cpp + ] + [ run test_coordinate_matrix_sort.cpp + ] + [ run test_coordinate_matrix_sort.cpp + : + : + : <define>BOOST_UBLAS_COO_ALWAYS_DO_FULL_SORT + : test_coordinate_matrix_always_do_full_sort + : + ] + [ run test_complex_norms.cpp + ] + [ run test_scaled_norm.cpp + : : : + <define>BOOST_UBLAS_SCALED_NORM + ] + [ run test_assignment.cpp + : : : + <define>BOOST_UBLAS_COO_ALWAYS_DO_FULL_SORT + ] + [ run test_triangular.cpp + : + : + : <library>/boost/timer//boost_timer + ] + [ run test_ticket7296.cpp + : + : + : <toolset>msvc:<cxxflags>/wd4127 # The program checks that test facilities work fine. The warning appears many times. + : + : + ] + [ run test_inplace_solve.cpp + : + : + : <define>$(UBLAS_TESTSET) + : test_inplace_solve_basic + : + ] + [ run test_inplace_solve.cpp + : + : + : <define>$(UBLAS_TESTSET_SPARSE) + <define>$(UBLAS_TESTSET_SPARSE_COO) + : test_inplace_solve_sparse + : + ] + [ run test_inplace_solve.cpp + : + : + : <define>USE_MAPPED_VECTOR_OF_MAPPED_VECTOR + : test_inplace_solve_mvov + : + ] + [ run test_coordinate_vector_inplace_merge.cpp + ] + [ run test_coordinate_matrix_inplace_merge.cpp + ] + [ run test_banded_storage_layout.cpp + : + : + : + : + : + ] + [ run test_fixed_containers.cpp + : + : + : + ] + [ run test_matrix_vector.cpp + ] + ; + +build-project opencl ; +build-project tensor ; diff --git a/src/boost/libs/numeric/ublas/test/README b/src/boost/libs/numeric/ublas/test/README new file mode 100644 index 000000000..761123141 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/README @@ -0,0 +1,31 @@ +Copyright (c) 2000-2011 Joerg Walter, Mathias Koch, David Bellot + +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) + +uBLAS test director + Use boost::test to test various uBLAS containers and expressions + +The tests can be used individually or automaticaly as part of the uBLAS regression tests. + +The tests are broken down in directorys as follows: + +test1 - dense vector and matrix tests +test2 - BLAS tests +test3 - sparse vector and matrix tests +test4 - banded/diagonal matrix tests +test5 - triangular matrix tests +test6 - symmetric matrix tests +test7 - dense vector and matrix tests with boost::numeric::internal values + +Each test directory contains: + testX.hpp Headers and types to be tested + testX.cpp Call the test functions for the defined types + testX1.cpp Implements vector tests + testX2.cpp Implements vector/matrix tests + testX3.cpp Implements matrix tests + +Missing in these tests + a) Runtime result validation. + b) Iterator interface tests. Only complete container expressions are tested diff --git a/src/boost/libs/numeric/ublas/test/begin_end.cpp b/src/boost/libs/numeric/ublas/test/begin_end.cpp new file mode 100644 index 000000000..769a51faf --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/begin_end.cpp @@ -0,0 +1,181 @@ +// Copyright (c) 2011 David Bellot +// +// 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) + +#include <cmath> +#include <boost/numeric/ublas/traits/const_iterator_type.hpp> +#include <boost/numeric/ublas/traits/iterator_type.hpp> +#include <boost/numeric/ublas/traits/c_array.hpp> +#include <boost/numeric/ublas/fwd.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_expression.hpp> +#include <boost/numeric/ublas/operation/begin.hpp> +#include <boost/numeric/ublas/operation/end.hpp> +#include <boost/numeric/ublas/tags.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/vector_expression.hpp> +#include <iostream> +#include "utils.hpp" + + +static const double TOL(1.0e-5); ///< Used for comparing two real numbers. + +#ifdef BOOST_UBLAS_NO_NESTED_CLASS_RELATION +#error "sorry this feature is not supported by your compiler" +#endif + +BOOST_UBLAS_TEST_DEF( test_vector_iteration ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Vector Iteration" ); + + typedef double value_type; + typedef boost::numeric::ublas::vector<value_type> vector_type; + + vector_type v(5); + + v(0) = 0.555950; + v(1) = 0.108929; + v(2) = 0.948014; + v(3) = 0.023787; + v(4) = 1.023787; + + + vector_type::size_type ix = 0; + for ( + boost::numeric::ublas::iterator_type<vector_type>::type it = boost::numeric::ublas::begin<vector_type>(v); + it != boost::numeric::ublas::end<vector_type>(v); + ++it + ) { + BOOST_UBLAS_DEBUG_TRACE( "*it = " << *it << " ==> " << v(ix) ); + BOOST_UBLAS_TEST_CHECK( std::abs(*it - v(ix)) <= TOL ); + ++ix; + } +} + + +BOOST_UBLAS_TEST_DEF( test_vector_const_iteration ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Vector Const Iteration" ); + + typedef double value_type; + typedef boost::numeric::ublas::vector<value_type> vector_type; + + vector_type v(5); + + v(0) = 0.555950; + v(1) = 0.108929; + v(2) = 0.948014; + v(3) = 0.023787; + v(4) = 1.023787; + + + vector_type::size_type ix = 0; + for ( + boost::numeric::ublas::const_iterator_type<vector_type>::type it = boost::numeric::ublas::begin<vector_type>(v); + it != boost::numeric::ublas::end<vector_type>(v); + ++it + ) { + BOOST_UBLAS_DEBUG_TRACE( "*it = " << *it << " ==> " << v(ix) ); + BOOST_UBLAS_TEST_CHECK( std::abs(*it - v(ix)) <= TOL ); + ++ix; + } +} + + +BOOST_UBLAS_TEST_DEF( test_row_major_matrix_iteration ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Row-major Matrix Iteration" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::row_major> matrix_type; + typedef boost::numeric::ublas::iterator_type<matrix_type, boost::numeric::ublas::tag::major>::type outer_iterator_type; + typedef boost::numeric::ublas::iterator_type<matrix_type, boost::numeric::ublas::tag::minor>::type inner_iterator_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + matrix_type::size_type row(0); + for ( + outer_iterator_type outer_it = boost::numeric::ublas::begin<boost::numeric::ublas::tag::major>(A); + outer_it != boost::numeric::ublas::end<boost::numeric::ublas::tag::major>(A); + ++outer_it + ) { + matrix_type::size_type col(0); + + for ( + inner_iterator_type inner_it = boost::numeric::ublas::begin(outer_it); + inner_it != boost::numeric::ublas::end(outer_it); + ++inner_it + ) { + BOOST_UBLAS_DEBUG_TRACE( "*it = " << *inner_it << " ==> " << A(row,col) ); + BOOST_UBLAS_TEST_CHECK( std::abs(*inner_it - A(row,col)) <= TOL ); + + ++col; + } + + ++row; + } +} + + +BOOST_UBLAS_TEST_DEF( test_col_major_matrix_iteration ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Column-major Matrix Iteration" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::column_major> matrix_type; + typedef boost::numeric::ublas::iterator_type<matrix_type, boost::numeric::ublas::tag::major>::type outer_iterator_type; + typedef boost::numeric::ublas::iterator_type<matrix_type, boost::numeric::ublas::tag::minor>::type inner_iterator_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + matrix_type::size_type col(0); + for ( + outer_iterator_type outer_it = boost::numeric::ublas::begin<boost::numeric::ublas::tag::major>(A); + outer_it != boost::numeric::ublas::end<boost::numeric::ublas::tag::major>(A); + ++outer_it + ) { + matrix_type::size_type row(0); + + for ( + inner_iterator_type inner_it = boost::numeric::ublas::begin(outer_it); + inner_it != boost::numeric::ublas::end(outer_it); + ++inner_it + ) { + BOOST_UBLAS_DEBUG_TRACE( "*it = " << *inner_it << " ==> " << A(row,col) ); + BOOST_UBLAS_TEST_CHECK( std::abs(*inner_it - A(row,col)) <= TOL ); + + ++row; + } + + ++col; + } +} + + +int main() +{ + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( test_vector_iteration ); + BOOST_UBLAS_TEST_DO( test_vector_const_iteration ); + BOOST_UBLAS_TEST_DO( test_row_major_matrix_iteration ); + BOOST_UBLAS_TEST_DO( test_col_major_matrix_iteration ); + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/common/init.hpp b/src/boost/libs/numeric/ublas/test/common/init.hpp new file mode 100644 index 000000000..a9691b4ed --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/common/init.hpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2004 Michael Stevens + * 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) + */ + +/* + * Default construct test when possible + */ + +template <class E> +struct default_construct +{ + static void test() {} +}; +template <class VC> +struct default_construct<boost::numeric::ublas::vector_container<VC> > +{ + static void test () + { + VC default_constuct; + initialize_vector (default_constuct); + std::cout << "default construct = " << default_constuct << std::endl; + } +}; +template <class MC> +struct default_construct<boost::numeric::ublas::matrix_container<MC> > +{ + static void test () + { + MC default_constuct; + initialize_vector (default_constuct); + std::cout << "default construct = " << default_constuct << std::endl; + } +}; + +/* + * Initialise test values in vector/matrix + */ + +template<class V> +void initialize_vector (V &v) { + typename V::size_type size = v.size (); + for (typename V::size_type i = 0; i < size; ++ i) + v [i] = typename V::value_type ( i + 1.f ); +} + +template<class M> +void initialize_matrix_impl (M &m, ublas::packed_proxy_tag) { + typename M::size_type size1 = m.size1 (); +#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION + for (typename M::iterator1 i = m.begin1(); i != m.end1(); ++ i) + for (typename M::iterator2 j = i.begin(); j != i.end(); ++ j) + *j = typename M::value_type ( i.index1() * size1 + j.index2() + 1.f ); +#else + for (typename M::iterator1 i = m.begin1(); i != m.end1(); ++ i) + for (typename M::iterator2 j = ublas::begin (i, ublas::iterator1_tag ()); j != ublas::end (i, ublas::iterator1_tag ()); ++ j) + *j = typename M::value_type ( i.index1() * size1 + j.index2() + 1.f ); +#endif +} + +template<class M> +void initialize_matrix_impl (M &m, ublas::sparse_proxy_tag) { + typename M::size_type size1 = m.size1 (); + typename M::size_type size2 = m.size2 (); + for (typename M::size_type i = 0; i < size1; ++ i) + for (typename M::size_type j = 0; j < size2; ++ j) + m (i, j) = typename M::value_type (i * size1 + j + 1.f); +} + +template<class M> +void initialize_matrix (M &m) { + initialize_matrix_impl (m, typename M::storage_category()); +} + +template<class M> +void initialize_matrix (M &m, ublas::lower_tag) { + typename M::size_type size1 = m.size1 (); + typename M::size_type size2 = m.size2 (); + for (typename M::size_type i = 0; i < size1; ++ i) { + typename M::size_type j = 0; + for (; j <= i; ++ j) + m (i, j) = i * size1 + j + 1.f; + for (; j < size2; ++ j) + m (i, j) = 0.f; + } +} +template<class M> +void initialize_matrix (M &m, ublas::upper_tag) { + typename M::size_type size1 = m.size1 (); + typename M::size_type size2 = m.size2 (); + for (typename M::size_type i = 0; i < size1; ++ i) { + typename M::size_type j = 0; + for (; j < i; ++ j) + m (i, j) = 0.f; + for (; j < size2; ++ j) + m (i, j) = i * size1 + j + 1.f; + } +} diff --git a/src/boost/libs/numeric/ublas/test/common/testhelper.hpp b/src/boost/libs/numeric/ublas/test/common/testhelper.hpp new file mode 100644 index 000000000..4bc152ca3 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/common/testhelper.hpp @@ -0,0 +1,165 @@ +// Copyright 2008 Gunter Winkler <guwi17@gmx.de> +// 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) + + +#ifndef _HPP_TESTHELPER_ +#define _HPP_TESTHELPER_ + +#include <utility> +#include <iostream> +#include <boost/numeric/ublas/vector_expression.hpp> +#include <boost/numeric/ublas/matrix_expression.hpp> +#include <boost/mpl/if.hpp> +#include <boost/type_traits/is_integral.hpp> +#include <boost/numeric/ublas/traits.hpp> + +static unsigned _success_counter = 0; +static unsigned _fail_counter = 0; + +static inline +void assertTrue(const char* message, bool condition) { +#ifndef NOMESSAGES + std::cout << message; +#else + (void)message; +#endif + if ( condition ) { + ++ _success_counter; + std::cout << "1\n"; // success + } else { + ++ _fail_counter; + std::cout << "0\n"; // failed + } +} + +template < class T > +void assertEquals(const char* message, T expected, T actual) { +#ifndef NOMESSAGES + std::cout << message; +#else + (void)message; +#endif + if ( expected == actual ) { + ++ _success_counter; + std::cout << "1\n"; // success + } else { + #ifndef NOMESSAGES + std::cout << " expected " << expected << " actual " << actual << " "; + #endif + ++ _fail_counter; + std::cout << "0\n"; // failed + } +} + +inline static +std::pair<unsigned, unsigned> getResults() { + return std::make_pair(_success_counter, _fail_counter); +} + +template < class M1, class M2 > +bool compare( const boost::numeric::ublas::matrix_expression<M1> & m1, + const boost::numeric::ublas::matrix_expression<M2> & m2 ) { + if ((m1().size1() != m2().size1()) || + (m1().size2() != m2().size2())) { + return false; + } + + size_t size1 = m1().size1(); + size_t size2 = m1().size2(); + for (size_t i=0; i < size1; ++i) { + for (size_t j=0; j < size2; ++j) { + if ( m1()(i,j) != m2()(i,j) ) return false; + } + } + return true; +} + +template < class M1, class M2 > +bool compare( const boost::numeric::ublas::vector_expression<M1> & m1, + const boost::numeric::ublas::vector_expression<M2> & m2 ) { + if (m1().size() != m2().size()) { + return false; + } + + size_t size = m1().size(); + for (size_t i=0; i < size; ++i) { + if ( m1()(i) != m2()(i) ) return false; + } + return true; +} + +// Compare if two matrices or vectors are equals based on distance. + +template <typename T> +struct promote_distance { + typedef typename boost::mpl::if_c<boost::is_integral<T>::value, + long double, + T>::type type; +}; + +template <typename M1, typename M2 = void> +struct distance { +private: + typedef typename boost::numeric::ublas::promote_traits<typename M1::value_type, + typename M2::value_type>::promote_type value_type; + +public: + typedef typename promote_distance<value_type>::type type; +}; + +template <typename AE> +struct distance<AE, void> { + typedef typename promote_distance<typename AE::value_type>::type type; +}; + + +template <class AE> +typename distance<AE>::type mean_square(const boost::numeric::ublas::matrix_expression<AE> &me) { + typename distance<AE>::type s(0); + typename AE::size_type i, j; + for (i=0; i!= me().size1(); i++) { + for (j=0; j!= me().size2(); j++) { + s += boost::numeric::ublas::scalar_traits<typename AE::value_type>::type_abs(me()(i,j)); + } + } + return s / (me().size1() * me().size2()); +} + +template <class AE> +typename distance<AE>::type mean_square(const boost::numeric::ublas::vector_expression<AE> &ve) { + // We could have use norm2 here, but ublas' ABS does not support unsigned types. + typename distance<AE>::type s(0); + typename AE::size_type i; + for (i = 0; i != ve().size(); i++) { + s += boost::numeric::ublas::scalar_traits<typename AE::value_type>::type_abs(ve()(i)); + } + return s / ve().size(); +} + +template < class M1, class M2 > +bool compare_distance( const boost::numeric::ublas::matrix_expression<M1> & m1, + const boost::numeric::ublas::matrix_expression<M2> & m2, + typename distance<M1, M2>::type tolerance = 0 ) { + if ((m1().size1() != m2().size1()) || + (m1().size2() != m2().size2())) { + return false; + } + + return mean_square(m2() - m1()) <= tolerance; +} + +template < class M1, class M2 > +bool compare_distance( const boost::numeric::ublas::vector_expression<M1> & m1, + const boost::numeric::ublas::vector_expression<M2> & m2, + typename distance<M1, M2>::type tolerance = 0 ) { + if (m1().size() != m2().size()) { + return false; + } + + return mean_square(m2() - m1()) <= tolerance; +} + + +#endif diff --git a/src/boost/libs/numeric/ublas/test/comp_mat_erase.cpp b/src/boost/libs/numeric/ublas/test/comp_mat_erase.cpp new file mode 100644 index 000000000..70018908d --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/comp_mat_erase.cpp @@ -0,0 +1,106 @@ +// Copyright (c) 2011 David Bellot +// +// 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) + +#include <boost/numeric/ublas/matrix_sparse.hpp> + +#define BOOST_TEST_MODULE SparseMatrixErasureTest +#include <boost/test/included/unit_test.hpp> + + +BOOST_AUTO_TEST_CASE( compressed_matrix_erase_after_end ) +{ + boost::numeric::ublas::compressed_matrix<int, boost::numeric::ublas::row_major > A(2, 2); + + BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 1 ); + BOOST_CHECK_EQUAL( A.index1_data()[0], (std::size_t) 0 ); + + A(0,0) = 1; + + BOOST_CHECK_EQUAL( A.nnz(), (std::size_t) 1 ); + BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 2 ); + + // check new element + BOOST_CHECK_EQUAL( A.index1_data()[0], (std::size_t) 0 ); + BOOST_CHECK_EQUAL( A.index2_data()[0], (std::size_t) 0 ); + BOOST_CHECK_EQUAL( A.value_data()[0], 1 ); + // check end of list marker + BOOST_CHECK_EQUAL( A.index1_data()[1], (std::size_t) 1 ); + + A.erase_element(1,0); + + BOOST_CHECK_EQUAL( A.nnz(), (std::size_t) 1 ); + BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 2 ); + BOOST_CHECK_EQUAL( A.filled2(), (std::size_t) 1 ); + + // check new element + BOOST_CHECK_EQUAL( A.index1_data()[0], (std::size_t) 0 ); + BOOST_CHECK_EQUAL( A.index2_data()[0], (std::size_t) 0 ); + BOOST_CHECK_EQUAL( A.value_data()[0], 1 ); + // check end of list marker + BOOST_CHECK_EQUAL( A.index1_data()[1], (std::size_t) 1 ); + + A.erase_element(0,0); + + BOOST_CHECK_EQUAL( A.nnz(), (std::size_t) 0 ); + BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 2 ); + BOOST_CHECK_EQUAL( A.filled2(),(std::size_t) 0 ); + BOOST_CHECK_EQUAL( A.index1_data()[0], (std::size_t) 0 ); + +} + +BOOST_AUTO_TEST_CASE( compressed_matrix_erase_in_the_middle ) +{ + boost::numeric::ublas::compressed_matrix<int, boost::numeric::ublas::row_major > A(2, 2); + + BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 1 ); + BOOST_CHECK_EQUAL( A.filled2(), (std::size_t) 0 ); + BOOST_CHECK_EQUAL( A.index1_data()[0], (std::size_t) 0 ); + + A.insert_element(0,1,5); + + BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 2 ); + BOOST_CHECK_EQUAL( A.filled2(), (std::size_t) 1 ); + + // check new element + BOOST_CHECK_EQUAL( A.index1_data()[0], (std::size_t) 0 ); + BOOST_CHECK_EQUAL( A.index2_data()[0], (std::size_t) 1 ); + BOOST_CHECK_EQUAL( A.value_data()[0], 5 ); + // check end of list marker + BOOST_CHECK_EQUAL( A.index1_data()[1], (std::size_t) 1 ); + + A.insert_element(0,0,4); + + BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 2 ); + BOOST_CHECK_EQUAL( A.filled2(), (std::size_t) 2 ); + + // check new element + BOOST_CHECK_EQUAL( A.index2_data()[0], (std::size_t) 0 ); + BOOST_CHECK_EQUAL( A.value_data()[0], 4 ); + // check previous element + BOOST_CHECK_EQUAL( A.index2_data()[1], (std::size_t) 1 ); + BOOST_CHECK_EQUAL( A.value_data()[1], 5 ); + // check end of list marker + BOOST_CHECK_EQUAL( A.index1_data()[1], (std::size_t) 2 ); + + A.erase_element(0,0); + + BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 2 ); + BOOST_CHECK_EQUAL( A.filled2(), (std::size_t) 1 ); + + BOOST_CHECK_EQUAL( A.index2_data()[0], (std::size_t) 1 ); + BOOST_CHECK_EQUAL( A.value_data()[0], 5 ); + + BOOST_CHECK_EQUAL( A.index1_data()[0], (std::size_t) 0 ); + BOOST_CHECK_EQUAL( A.index1_data()[1], (std::size_t) 1 ); + + A.erase_element(0,1); + + BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 2 ); + BOOST_CHECK_EQUAL( A.filled2(), (std::size_t) 0 ); + BOOST_CHECK_EQUAL( A.index1_data()[0], (std::size_t) 0 ); + BOOST_CHECK_EQUAL( A.index1_data()[1], (std::size_t) 0 ); + +} diff --git a/src/boost/libs/numeric/ublas/test/concepts.cpp b/src/boost/libs/numeric/ublas/test/concepts.cpp new file mode 100644 index 000000000..ba9812923 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/concepts.cpp @@ -0,0 +1,34 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/vector_proxy.hpp> +#include <boost/numeric/ublas/vector_sparse.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_proxy.hpp> +#include <boost/numeric/ublas/banded.hpp> +#include <boost/numeric/ublas/triangular.hpp> +#include <boost/numeric/ublas/symmetric.hpp> +#include <boost/numeric/ublas/hermitian.hpp> +#include <boost/numeric/ublas/matrix_sparse.hpp> +#include <boost/numeric/ublas/vector_of_vector.hpp> +#include <boost/numeric/ublas/detail/concepts.hpp> +#include <boost/numeric/ublas/experimental/sparse_view.hpp> +//#include <boost/numeric/ublas/vector_view.hpp> + +namespace ublas = boost::numeric::ublas; + + +int main () { + void (* check) (void) = ublas::concept_checks; + boost::ignore_unused_variable_warning (check); +} diff --git a/src/boost/libs/numeric/ublas/test/manual/Jamfile.v2 b/src/boost/libs/numeric/ublas/test/manual/Jamfile.v2 new file mode 100644 index 000000000..5ef982db0 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/manual/Jamfile.v2 @@ -0,0 +1,8 @@ +# Copyright (c) 2006 Michael Stevens +# 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) + +exe sp_resize : sp_resize.cpp ; + +exe test_move_semantics : test_move_semantics.cpp ; diff --git a/src/boost/libs/numeric/ublas/test/manual/sp_resize.cpp b/src/boost/libs/numeric/ublas/test/manual/sp_resize.cpp new file mode 100644 index 000000000..2d52dbbd9 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/manual/sp_resize.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2006 Michael Stevens + * 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 <iostream> + +#include <boost/numeric/ublas/vector_sparse.hpp> + +typedef double Real; + +template <class V> +void printV(const V& v) { + std::cout << "size: " << v.size() << " nnz_capacity: " << v.nnz_capacity() << " nnz: " << v.nnz() << std::endl; + for (typename V::const_iterator i = v.begin(); i != v.end(); i++) { + std::cout << i.index() << ":" << (*i) << " "; + } + std::cout << std::endl; +} + +template <class V> +void run_test() +{ + V v(10); + + v[0] = 1; + v[5] = 1; + v[8] = 1; + v[9] = 1; + + printV(v); + + v.resize(9); printV(v); + v.resize(12); printV(v); + v.resize(2); printV(v); + v.resize(0); printV(v); + + v.resize(5); v[0] = 1; printV(v); + v.resize(5,false); printV(v); +} + +int main(int, char **) { + + std::cout << "---- MAPPED ----\n"; + run_test< boost::numeric::ublas::mapped_vector<Real> >(); + std::cout << "---- COMPRESSED ----\n"; + run_test< boost::numeric::ublas::compressed_vector<Real> >(); + std::cout << "---- COORDINATE ----\n"; + run_test< boost::numeric::ublas::coordinate_vector<Real> >(); + + return 0; +} + diff --git a/src/boost/libs/numeric/ublas/test/manual/test_move_semantics.cpp b/src/boost/libs/numeric/ublas/test/manual/test_move_semantics.cpp new file mode 100644 index 000000000..188491e4f --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/manual/test_move_semantics.cpp @@ -0,0 +1,127 @@ +/** test move semantics - run with and without BOOST_UBLAS_MOVE_SEMANTICS defined */ + +// Copyright Nasos Iliopoulos, Gunter Winkler 2009. +// 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) + +#define BOOST_UBLAS_MOVE_SEMANTICS +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/io.hpp> + +namespace ublas= boost::numeric::ublas; +std::vector<double> a; + +ublas::vector<double> doubleit(ublas::vector<double> m) +{ + ublas::vector<double> r; + r=2.0*m; + std::cout << "Temporary pointer: " << &r[0] << std::endl; + return r; +} +template <class T,size_t N> +ublas::bounded_vector<T,N > doubleit(ublas::bounded_vector<T, N> m) +{ + ublas::bounded_vector<T,N> r; + r=2.0*m; + std::cout << "Temporary pointer: " << &r[0] << std::endl; + return r; +} + +template <class T,size_t N> +ublas::c_vector<T,N > doubleit(ublas::c_vector<T, N> m) +{ + ublas::c_vector<T,N> r; + r=2.0*m; + std::cout << "Temporary pointer: " << &r[0] << std::endl; + return r; +} + +ublas::matrix<double> doubleit(ublas::matrix<double> m) +{ + ublas::matrix<double> r; + r=2.0*m; + std::cout << "Temporary pointer r: " << &r(0,0) << std::endl; + return r; +} +template <class T,size_t N, size_t M> +ublas::bounded_matrix<T,N, M > doubleit(ublas::bounded_matrix<T, N, M> m) +{ + ublas::bounded_matrix<T,N, M> r; + r=2.0*m; + std::cout << "Temporary pointer: " << &(r(0,0)) << std::endl; + return r; +} + +template <class T,size_t N, size_t M> +ublas::c_matrix<T,N, M > doubleit(ublas::c_matrix<T, N, M> m) +{ + ublas::c_matrix<T,N, M> r; + r=2.0*m; + std::cout << "Temporary pointer: " << &(r(0,0)) << std::endl; + return r; +} + + +void test1() +{ + std::cout << "vector<double> --------------------------------------------------------------------" << std::endl; + ublas::vector<double> a(ublas::scalar_vector<double>(2,2.0)); + a = doubleit(a); + std::cout << "Pointer (must be equal to temp. pointer if move semantics are enabled) : " << &a[0] << std::endl; + + std::cout << a << std::endl; + + std::cout << "bounded_vector<double,2> --------------------------------------------------------------------" << std::endl; + ublas::bounded_vector<double,2> b(ublas::scalar_vector<double>(2,2.0)); + ublas::bounded_vector<double,2> c; + noalias(c)=doubleit(b); + std::cout << "Pointer (bounded_vector swaps by copy this should be different than temp. pointer) : " << &c[0] << std::endl; + c(1)=0.0; + std::cout << b << std::endl; + std::cout << c << std::endl; + + std::cout << "c_vector<double,2> --------------------------------------------------------------------" << std::endl; + ublas::c_vector<double,2> e=ublas::scalar_vector<double>(2,2.0); + ublas::c_vector<double,2> f; + f=doubleit(e); + std::cout << "Pointer (c_vector swaps by copy this should be different than temp. pointer) : " << &f[0] << std::endl; + f(1)=0; + std::cout << e << std::endl; + std::cout << f << std::endl; + +} + +void test2() { + std::cout << "matrix<double> --------------------------------------------------------------------" << std::endl; + ublas::matrix<double> a(ublas::scalar_matrix<double>(2, 3, 2.0)); + a = doubleit(a); + std::cout << "Pointer (must be equal to temp. pointer if move semantics are enabled) : " << &(a(0,0)) << std::endl; + std::cout << a << std::endl; + + std::cout << "bounded_matrix<double,2, 3> --------------------------------------------------------------------" << std::endl; + ublas::bounded_matrix<double,2, 3> b(ublas::scalar_matrix<double>(2,3, 2.0)); + ublas::bounded_matrix<double,2, 3> c; + noalias(c)=doubleit(b); + std::cout << "Pointer (bounded_matrix swaps by copy this should be different than temp. pointer) : " << &(c(0,0)) << std::endl; + c(1,1)=0.0; + std::cout << b << std::endl; + std::cout << c << std::endl; + + std::cout << "c_matrix<double,2 ,3> --------------------------------------------------------------------" << std::endl; + ublas::c_matrix<double,2, 3> e=ublas::scalar_matrix<double>(2,3, 2.0); + ublas::c_matrix<double,2, 3> f; + f=doubleit(e); + std::cout << "Pointer (c_matrix swaps by copy this should be different than temp. pointer) : " << &(f(0,0)) << std::endl; + f(1,1)=0; + std::cout << e << std::endl; + std::cout << f << std::endl; +} + +int main(){ + test1(); + test2(); + return 0; +} + diff --git a/src/boost/libs/numeric/ublas/test/num_columns.cpp b/src/boost/libs/numeric/ublas/test/num_columns.cpp new file mode 100644 index 000000000..68c9770af --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/num_columns.cpp @@ -0,0 +1,110 @@ +// Copyright (c) 2011 David Bellot +// +// 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) + +#include <boost/numeric/ublas/fwd.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_expression.hpp> +#include <boost/numeric/ublas/operation/num_columns.hpp> +#include <iostream> +#include "utils.hpp" + + +BOOST_UBLAS_TEST_DEF( test_row_major_matrix_container ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Row-major Matrix Container" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::row_major> matrix_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + BOOST_UBLAS_DEBUG_TRACE( "num_columns(A) = " << boost::numeric::ublas::num_columns(A) << " ==> " << A.size2() ); + BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::num_columns(A) == A.size2() ); +} + + +BOOST_UBLAS_TEST_DEF( test_col_major_matrix_container ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Column-major Matrix Container" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::column_major> matrix_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + BOOST_UBLAS_DEBUG_TRACE( "num_columns(A) = " << boost::numeric::ublas::num_columns(A) << " ==> " << A.size2() ); + BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::num_columns(A) == A.size2() ); +} + + +BOOST_UBLAS_TEST_DEF( test_matrix_expression ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Matrix Expression" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type> matrix_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + BOOST_UBLAS_DEBUG_TRACE( "num_columns(A') = " << boost::numeric::ublas::num_columns(boost::numeric::ublas::trans(A)) << " ==> " << boost::numeric::ublas::trans(A).size2() ); + BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::num_columns(boost::numeric::ublas::trans(A)) == boost::numeric::ublas::trans(A).size2() ); +} + + +BOOST_UBLAS_TEST_DEF( test_matrix_reference ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Matrix Reference" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type> matrix_type; + typedef boost::numeric::ublas::matrix_reference<matrix_type> matrix_reference_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + BOOST_UBLAS_DEBUG_TRACE( "num_columns(reference(A)) = " << boost::numeric::ublas::num_columns(matrix_reference_type(A)) << " ==> " << matrix_reference_type(A).size2() ); + BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::num_columns(matrix_reference_type(A)) == matrix_reference_type(A).size2() ); +} + + +int main() +{ + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( test_row_major_matrix_container ); + BOOST_UBLAS_TEST_DO( test_col_major_matrix_container ); + BOOST_UBLAS_TEST_DO( test_matrix_expression ); + BOOST_UBLAS_TEST_DO( test_matrix_reference ); + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/num_rows.cpp b/src/boost/libs/numeric/ublas/test/num_rows.cpp new file mode 100644 index 000000000..1e3a1e70a --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/num_rows.cpp @@ -0,0 +1,110 @@ +// Copyright (c) 2011 David Bellot +// +// 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) + +#include <boost/numeric/ublas/fwd.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_expression.hpp> +#include <boost/numeric/ublas/operation/num_rows.hpp> +#include <iostream> +#include "utils.hpp" + + +BOOST_UBLAS_TEST_DEF( test_row_major_matrix_container ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Row-major Matrix Container" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::row_major> matrix_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + BOOST_UBLAS_DEBUG_TRACE( "num_rows(A) = " << boost::numeric::ublas::num_rows(A) << " ==> " << A.size1() ); + BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::num_rows(A) == A.size1() ); +} + + +BOOST_UBLAS_TEST_DEF( test_col_major_matrix_container ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Column-major Matrix Container" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::column_major> matrix_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + BOOST_UBLAS_DEBUG_TRACE( "num_rows(A) = " << boost::numeric::ublas::num_rows(A) << " ==> " << A.size1() ); + BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::num_rows(A) == A.size1() ); +} + + +BOOST_UBLAS_TEST_DEF( test_matrix_expression ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Matrix Expression" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type> matrix_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + BOOST_UBLAS_DEBUG_TRACE( "num_rows(A') = " << boost::numeric::ublas::num_rows(boost::numeric::ublas::trans(A)) << " ==> " << boost::numeric::ublas::trans(A).size1() ); + BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::num_rows(boost::numeric::ublas::trans(A)) == boost::numeric::ublas::trans(A).size1() ); +} + + +BOOST_UBLAS_TEST_DEF( test_matrix_reference ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Matrix Reference" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type> matrix_type; + typedef boost::numeric::ublas::matrix_reference<matrix_type> matrix_reference_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + BOOST_UBLAS_DEBUG_TRACE( "num_rows(reference(A)) = " << boost::numeric::ublas::num_rows(matrix_reference_type(A)) << " ==> " << matrix_reference_type(A).size1() ); + BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::num_rows(matrix_reference_type(A)) == matrix_reference_type(A).size1() ); +} + + +int main() +{ + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( test_row_major_matrix_container ); + BOOST_UBLAS_TEST_DO( test_col_major_matrix_container ); + BOOST_UBLAS_TEST_DO( test_matrix_expression ); + BOOST_UBLAS_TEST_DO( test_matrix_reference ); + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/opencl/Jamfile b/src/boost/libs/numeric/ublas/test/opencl/Jamfile new file mode 100644 index 000000000..51c74675e --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/Jamfile @@ -0,0 +1,31 @@ +# +# Copyright (c) 2018 Stefan Seefeld +# +# 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 ac ; + +# work around a bug in Boost.Build +import ../../opencl ; +import ../../clblas ; +using opencl ; +using clblas ; + +project boost/ublas/test/opencl + : requirements + <toolset>gcc:<cxxflags>-Wno-ignored-attributes + [ ac.check-library /clblas//clblas : <library>/clblas//clblas <library>/opencl//opencl : <build>no ] + ; + +test-suite ocl + : [ run prod_test.cpp ] + [ run elementwise_operations_test.cpp ] + [ run inner_prod_test.cpp ] + [ run outer_prod_test.cpp ] + [ run transposition_test.cpp ] + [ run norm_test.cpp ] + [ run norm2_test.cpp ] + [ run elementwise_operations_with_constants_test.cpp ] + ; diff --git a/src/boost/libs/numeric/ublas/test/opencl/elementwise_operations_test.cpp b/src/boost/libs/numeric/ublas/test/opencl/elementwise_operations_test.cpp new file mode 100644 index 000000000..60c76e74d --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/elementwise_operations_test.cpp @@ -0,0 +1,44 @@ +#include "elementwise_operations_test.hpp" + +int main() +{ + + ///testing row major flaot elementwise operations + bench_elementwise <float, ublas::basic_row_major<>, 10, 10> b1; + + ///testing row major complex float elementwise operations + bench_elementwise <std::complex<float>, ublas::basic_row_major<>, 10, 10> b2; + + ///testing row major double elementwise operations + bench_elementwise <double, ublas::basic_row_major<>, 10, 10> b5; + + ///testing row major complex double elementwise operations + bench_elementwise <std::complex<double>, ublas::basic_row_major<>, 10, 10> b6; + + ///testing column major flaot elementwise operations + bench_elementwise <float, ublas::basic_column_major<>, 10, 10> b3; + + ///testing column major complex float elementwise operations + bench_elementwise <std::complex<float>, ublas::basic_column_major<>, 10, 10> b4; + + ///testing column major double elementwise operations + bench_elementwise <double, ublas::basic_column_major<>, 10, 10> b7; + + ///testing column major complex double elementwise operations + bench_elementwise <std::complex<double>, ublas::basic_column_major<>, 10, 10> b8; + + + std::cout << "row major:" << std::endl; + b1.run(); + b2.run(); + b5.run(); + b6.run(); + + + std::cout << "column major:" << std::endl; + b3.run(); + b4.run(); + b7.run(); + b8.run(); + +} diff --git a/src/boost/libs/numeric/ublas/test/opencl/elementwise_operations_test.hpp b/src/boost/libs/numeric/ublas/test/opencl/elementwise_operations_test.hpp new file mode 100644 index 000000000..2fe2e571a --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/elementwise_operations_test.hpp @@ -0,0 +1,114 @@ +#ifndef ELEMENT_OPENCL_HH +#define ELEMENT_OPENCL_HH +#include "test_opencl.hpp" + +template <class T, class F, int number_of_tests, int max_dimension> +class bench_elementwise +{ +public: + typedef test_opencl<T, F> test; + void run() + { + opencl::library lib; + int passedOperations = 0; + // get default device and setup context + compute::device device = compute::system::default_device(); + compute::context context(device); + compute::command_queue queue(context, device); + + std::srand(time(0)); + + ublas::matrix<T, F> a; + ublas::matrix<T, F> b; + + //matrix-matrix operations of cpu + ublas::matrix<T, F> result_m_add; + ublas::matrix<T, F> result_m_sub; + ublas::matrix<T, F> result_m_mul; + + //matrix-matrix operations of gpu + ublas::matrix<T, F> result_m_add_cl; + ublas::matrix<T, F> result_m_sub_cl; + ublas::matrix<T, F> result_m_mul_cl; + + + ublas::vector<T> va; + ublas::vector<T> vb; + + //vector-vector operations of cpu + ublas::vector<T> result_v_add; + ublas::vector<T> result_v_sub; + ublas::vector<T> result_v_mul; + + //vector-vector operations of gpu + ublas::vector<T> result_v_add_cl; + ublas::vector<T> result_v_sub_cl; + ublas::vector<T> result_v_mul_cl; + + + for (int i = 0; i<number_of_tests; i++) + { + int rows = std::rand() % max_dimension + 1; + int cols = std::rand() % max_dimension + 1; + + a.resize(rows, cols); + b.resize(rows, cols); + va.resize(rows); + vb.resize(rows); + + + test::init_matrix(a, 200); + test::init_matrix(b, 200); + test::init_vector(va, 200); + test::init_vector(vb, 200); + + result_m_add = a + b; + result_m_add_cl = opencl::element_add(a, b, queue); + + result_m_sub = a - b; + result_m_sub_cl = opencl::element_sub(a, b, queue); + + result_m_mul = ublas::element_prod(a, b); + result_m_mul_cl = opencl::element_prod(a, b, queue); + + + result_v_add = va + vb; + result_v_add_cl = opencl::element_add(va, vb, queue); + + result_v_sub = va - vb; + result_v_sub_cl = opencl::element_sub(va, vb, queue); + + result_v_mul = ublas::element_prod(va, vb); + result_v_mul_cl = opencl::element_prod(va, vb, queue); + + + + + + + if ((!test::compare(result_m_add, result_m_add_cl)) || + (!test::compare(result_m_sub, result_m_sub_cl)) || + (!test::compare(result_m_mul, result_m_mul_cl)) || + (!test::compare(result_v_add, result_v_add_cl)) || + (!test::compare(result_v_sub, result_v_sub_cl)) || + (!test::compare(result_v_mul, result_v_mul_cl)) + ) + { + std::cout << "Error in calculations" << std::endl; + + std::cout << "passed: " << passedOperations << std::endl; + return; + } + + passedOperations++; + + } + std::cout << "All is well (matrix opencl element wise operations) of " << typeid(T).name() << std::endl; + + + + } + +}; + +#endif diff --git a/src/boost/libs/numeric/ublas/test/opencl/elementwise_operations_with_constants_test.cpp b/src/boost/libs/numeric/ublas/test/opencl/elementwise_operations_with_constants_test.cpp new file mode 100644 index 000000000..4ec03f99c --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/elementwise_operations_with_constants_test.cpp @@ -0,0 +1,48 @@ +#include "elementwise_operations_with_constants_test.hpp" +#include <boost/numeric/ublas/matrix.hpp> + +int main() +{ + + ///testing row major flaot prod + bench_elementwise_constant<float, ublas::basic_row_major<>, 10, 10> b1; + + ///testing row major complex float prod + bench_elementwise_constant<std::complex<float>, ublas::basic_row_major<>, 10, 10> b2; + + + ///testing row major double prod + bench_elementwise_constant<double, ublas::basic_row_major<>, 10, 10> b3; + + ///testing row major complex float elementwise operations with constants + bench_elementwise_constant<std::complex<double>, ublas::basic_row_major<>, 10, 10> b4; + + + ///testing column major flaot elementwise operations with constants + bench_elementwise_constant<float, ublas::basic_column_major<>, 10, 10> b5; + + ///testing column major complex float elementwise operations with constants + bench_elementwise_constant<std::complex<float>, ublas::basic_column_major<>, 10, 10> b6; + + ///testing column major double elementwise operations with constants + bench_elementwise_constant<double, ublas::basic_column_major<>, 10, 10> b7; + + ///testing column major complex double elementwise operations with constants + bench_elementwise_constant<std::complex<double>, ublas::basic_column_major<>, 10, 10> b8; + + + std::cout << "Row major:" << std::endl; + b1.run(); + b2.run(); + b3.run(); + b4.run(); + + std::cout << "Column major:" << std::endl; + b5.run(); + b6.run(); + b7.run(); + b8.run(); + + return 0; + +}
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/opencl/elementwise_operations_with_constants_test.hpp b/src/boost/libs/numeric/ublas/test/opencl/elementwise_operations_with_constants_test.hpp new file mode 100644 index 000000000..f78a73827 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/elementwise_operations_with_constants_test.hpp @@ -0,0 +1,86 @@ +#ifndef TEST_ELEMENT_CONSTANT_OPENCL_HH +#define TEST_ELEMENT_CONSTANT_OPENCL_HH +#include "test_opencl.hpp" + + +template <class T, class F, int number_of_tests, int max_dimension> +class bench_elementwise_constant +{ +public: + + typedef test_opencl<T, F> test; + + void run() + { + opencl::library lib; + int passedOperations = 0; + // get default device and setup context + compute::device device = compute::system::default_device(); + compute::context context(device); + compute::command_queue queue(context, device); + + std::srand(time(0)); + + ublas::matrix<T, F> m; + ublas::matrix<T, F> m_result_add_ublas; + ublas::matrix<T, F> m_result_sub_ublas; + ublas::matrix<T, F> m_result_add_opencl; + ublas::matrix<T, F> m_result_sub_opencl; + ublas::vector<T> v; + ublas::vector<T> v_result_add_ublas; + ublas::vector<T> v_result_sub_ublas; + ublas::vector<T> v_result_add_opencl; + ublas::vector<T> v_result_sub_opencl; + + + + for (int i = 0; i<number_of_tests; i++) + { + int rows = std::rand() % max_dimension + 1; + int cols = std::rand() % max_dimension + 1; + + m.resize(rows, cols); + v.resize(rows); + + test::init_matrix(m, 200); + test::init_vector(v, 200); + + T constant = rand() % max_dimension; + ublas::matrix<T, F> m_constant_holder(rows, cols, constant); + ublas::vector<T> v_constant_holder(rows, constant); + + m_result_add_ublas = m + m_constant_holder; + m_result_sub_ublas = m - m_constant_holder; + m_result_add_opencl = opencl::element_add(m, constant, queue); + m_result_sub_opencl = opencl::element_sub(m, constant, queue); + + v_result_add_ublas = v + v_constant_holder; + v_result_sub_ublas = v - v_constant_holder; + v_result_add_opencl = opencl::element_add(v, constant, queue); + v_result_sub_opencl = opencl::element_sub(v, constant, queue); + + + + if ((!test::compare(m_result_add_ublas, m_result_add_opencl)) + || (!test::compare(m_result_sub_ublas, m_result_sub_opencl)) || + (!test::compare(v_result_add_ublas, v_result_add_opencl)) + || (!test::compare(v_result_sub_ublas, v_result_sub_opencl))) + { + std::cout << "Error in calculations" << std::endl; + + std::cout << "passed: " << passedOperations << std::endl; + return; + } + + passedOperations++; + + } + std::cout << "All is well (matrix opencl elementwise operations with constants) of " << typeid(T).name() << std::endl; + + + + } + +}; + +#endif
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/opencl/inner_prod_test.cpp b/src/boost/libs/numeric/ublas/test/opencl/inner_prod_test.cpp new file mode 100644 index 000000000..3f1480e06 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/inner_prod_test.cpp @@ -0,0 +1,23 @@ +#include "inner_prod_test.hpp" +#include <boost/numeric/ublas/matrix.hpp> + +int main() +{ + ///testing row major int inner prod + bench_inner_prod<int, 10, 10> b1; + + ///testing row major float inner prod + bench_inner_prod<float, 10, 10> b2; + + + ///testing row major double inner prod + bench_inner_prod<double, 10, 10> b3; + + + b1.run(); + b2.run(); + b3.run(); + + return 0; + +}
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/opencl/inner_prod_test.hpp b/src/boost/libs/numeric/ublas/test/opencl/inner_prod_test.hpp new file mode 100644 index 000000000..cf9dc6465 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/inner_prod_test.hpp @@ -0,0 +1,64 @@ +#ifndef TEST_INNER_PROD_HH +#define TEST_INNER_PROD_HH +#include "test_opencl.hpp" + + +template <class T, int number_of_tests, int max_dimension> +class bench_inner_prod +{ +public: + + typedef test_opencl<T> test; + + void run() + { + opencl::library lib; + int passedOperations = 0; + // get default device and setup context + compute::device device = compute::system::default_device(); + compute::context context(device); + compute::command_queue queue(context, device); + + std::srand(time(0)); + + ublas::vector<T> va; + ublas::vector<T> vb; + T result_inner_prod_ublas; + T result_inner_prod_opencl; + + + for (int i = 0; i<number_of_tests; i++) + { + int size = std::rand() % max_dimension + 1; + + va.resize(size); + vb.resize(size); + + test::init_vector(va, 200); + test::init_vector(vb, 200); + + result_inner_prod_ublas = ublas::inner_prod(va, vb); + + result_inner_prod_opencl = opencl::inner_prod(va, vb, queue); + + + if (( result_inner_prod_ublas != result_inner_prod_opencl )) + { + std::cout << "Error in calculations" << std::endl; + + std::cout << "passed: " << passedOperations << std::endl; + return; + } + + passedOperations++; + + } + std::cout << "All is well (matrix opencl inner prod) of " << typeid(T).name() << std::endl; + + + + } + +}; + +#endif diff --git a/src/boost/libs/numeric/ublas/test/opencl/norm2_test.cpp b/src/boost/libs/numeric/ublas/test/opencl/norm2_test.cpp new file mode 100644 index 000000000..1838ff320 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/norm2_test.cpp @@ -0,0 +1,32 @@ +#include "norm2_test.hpp" +#include <boost/numeric/ublas/matrix.hpp> + +int main() +{ + + ///testing float norm2 + bench_norm2<float, 10, 10> b1; + + + ///testing double norm2 + bench_norm2<double, 10, 10> b2; + + + ///testing float norm2 + bench_norm2<std::complex<float>, 10, 10> b3; + + + ///testing double norm2 + bench_norm2<std::complex<double>, 10, 10> b4; + + + + b1.run(); + b2.run(); + b3.run(); + b4.run(); + + + return 0; + +}
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/opencl/norm2_test.hpp b/src/boost/libs/numeric/ublas/test/opencl/norm2_test.hpp new file mode 100644 index 000000000..8a7d6919c --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/norm2_test.hpp @@ -0,0 +1,59 @@ +#ifndef TEST_NORM2_OPENCL_HH +#define TEST_NORM2_OPENCL_HH +#include "test_opencl.hpp" + + +template <class T, int number_of_tests, int max_dimension> +class bench_norm2 +{ +public: + + typedef test_opencl<T, ublas::basic_row_major<>> test; + + + void run() + { + opencl::library lib; + int passedOperations = 0; + // get default device and setup context + compute::device device = compute::system::default_device(); + compute::context context(device); + compute::command_queue queue(context, device); + + std::srand(time(0)); + + ublas::vector<T> v; + + + for (int i = 0; i<number_of_tests; i++) + { + int size = std::rand() % max_dimension + 1; + + v.resize(size); + test::init_vector(v, 200); + + + T norm2_cpu = ublas::norm_2(v); + T norm2_opencl = opencl::norm_2(v, queue); + + + if ((abs(norm2_cpu - norm2_opencl) / abs(norm2_cpu)) > 1e-6) //precision of float + { + std::cout << "Error in calculations" << std::endl; + + std::cout << "passed: " << passedOperations << std::endl; + return; + } + + passedOperations++; + + } + std::cout << "All is well (vector opencl a_sum) of " << typeid(T).name() << std::endl; + + + + } + +}; + +#endif
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/opencl/norm_test.cpp b/src/boost/libs/numeric/ublas/test/opencl/norm_test.cpp new file mode 100644 index 000000000..79d6eabff --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/norm_test.cpp @@ -0,0 +1,22 @@ +#include "norm_test.hpp" +#include <boost/numeric/ublas/matrix.hpp> + +int main() +{ + + ///testing float norm1 + bench_norm<float, 10, 10> b1; + + + ///testing double norm1 + bench_norm<double, 10, 10> b2; + + + + b1.run(); + b2.run(); + + + return 0; + +}
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/opencl/norm_test.hpp b/src/boost/libs/numeric/ublas/test/opencl/norm_test.hpp new file mode 100644 index 000000000..9623de908 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/norm_test.hpp @@ -0,0 +1,59 @@ +#ifndef TEST_NORM_OPENCL_HH +#define TEST_NORM_OPENCL_HH +#include "test_opencl.hpp" + + +template <class T, int number_of_tests, int max_dimension> +class bench_norm +{ +public: + + typedef test_opencl<T, ublas::basic_row_major<>> test; + + + void run() + { + opencl::library lib; + int passedOperations = 0; + // get default device and setup context + compute::device device = compute::system::default_device(); + compute::context context(device); + compute::command_queue queue(context, device); + + std::srand(time(0)); + + ublas::vector<T> v; + + + for (int i = 0; i<number_of_tests; i++) + { + int size = std::rand() % max_dimension + 1; + + v.resize(size); + test::init_vector(v, 200); + + + T norm_cpu = ublas::norm_1(v); + T norm_opencl = opencl::norm_1(v, queue); + + + if (norm_cpu != norm_opencl) //precision of float + { + std::cout << "Error in calculations" << std::endl; + + std::cout << "passed: " << passedOperations << std::endl; + return; + } + + passedOperations++; + + } + std::cout << "All is well (vector opencl a_sum) of " << typeid(T).name() << std::endl; + + + + } + +}; + +#endif
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/opencl/outer_prod_test.cpp b/src/boost/libs/numeric/ublas/test/opencl/outer_prod_test.cpp new file mode 100644 index 000000000..e7195ecbd --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/outer_prod_test.cpp @@ -0,0 +1,31 @@ +#include "outer_prod_test.hpp" + +int main() +{ + + + ///testing float outer prod + bench_outer_prod<float, 10, 10> b1; + + + ///testing double outer prod + bench_outer_prod<double, 10, 10> b2; + + + ///testing complex of float outer prod + bench_outer_prod<std::complex<float>, 10, 10> b3; + + + ///testing complex of double outer prod + bench_outer_prod<std::complex<double>, 10, 10> b4; + + + + b1.run(); + b2.run(); + b3.run(); + b4.run(); + + return 0; + +}
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/opencl/outer_prod_test.hpp b/src/boost/libs/numeric/ublas/test/opencl/outer_prod_test.hpp new file mode 100644 index 000000000..348d0b1d6 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/outer_prod_test.hpp @@ -0,0 +1,65 @@ +#ifndef TEST_PROD_OPENCL_HH +#define TEST_PROD_OPENCL_HH +#include "test_opencl.hpp" + + +template <class T, int number_of_tests, int max_dimension> +class bench_outer_prod +{ +public: + + typedef test_opencl<T> test; + + void run() + { + opencl::library lib; + int passedOperations = 0; + // get default device and setup context + compute::device device = compute::system::default_device(); + compute::context context(device); + compute::command_queue queue(context, device); + + std::srand(time(0)); + + ublas::vector<T> va; + ublas::vector<T> vb; + ublas::matrix<T> resultUBLAS; + ublas::matrix<T> resultOPENCL; + + + for (int i = 0; i<number_of_tests; i++) + { + int rows = std::rand() % max_dimension + 1; + int cols = std::rand() % max_dimension + 1; + + va.resize(rows); + vb.resize(cols); + + test::init_vector(va, 200); + test::init_vector(vb, 200); + + //matrix_matrix + resultUBLAS = ublas::outer_prod(va, vb); + resultOPENCL = opencl::outer_prod(va, vb, queue); + + + if (!test::compare(resultUBLAS, resultOPENCL)) + { + std::cout << "Error in calculations" << std::endl; + + std::cout << "passed: " << passedOperations << std::endl; + return; + } + + passedOperations++; + + } + std::cout << "All is well (matrix opencl outer prod) of " << typeid(T).name() << std::endl; + + + + } + +}; + +#endif
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/opencl/prod_test.cpp b/src/boost/libs/numeric/ublas/test/opencl/prod_test.cpp new file mode 100644 index 000000000..28c39007e --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/prod_test.cpp @@ -0,0 +1,48 @@ +#include "prod_test.hpp" +#include <boost/numeric/ublas/matrix.hpp> + +int main() +{ + + ///testing row major flaot prod + bench_prod<float, ublas::basic_row_major<>, 10, 10> b1; + + ///testing row major complex float prod + bench_prod<std::complex<float>, ublas::basic_row_major<>, 10, 10> b2; + + + ///testing row major double prod + bench_prod<double, ublas::basic_row_major<>, 10, 10> b3; + + ///testing row major complex float prod + bench_prod<std::complex<double>, ublas::basic_row_major<>, 10, 10> b4; + + + ///testing column major flaot prod + bench_prod<float, ublas::basic_column_major<>, 10, 10> b5; + + ///testing column major complex float prod + bench_prod<std::complex<float>, ublas::basic_column_major<>, 10, 10> b6; + + ///testing column major double prod + bench_prod<double, ublas::basic_column_major<>, 10, 10> b7; + + ///testing column major complex double prod + bench_prod<std::complex<double>, ublas::basic_column_major<>, 10, 10> b8; + + + std::cout << "Row major:" << std::endl; + b1.run(); + b2.run(); + b3.run(); + b4.run(); + + std::cout << "Column major:" << std::endl; + b5.run(); + b6.run(); + b7.run(); + b8.run(); + + return 0; + +}
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/opencl/prod_test.hpp b/src/boost/libs/numeric/ublas/test/opencl/prod_test.hpp new file mode 100644 index 000000000..e760a842c --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/prod_test.hpp @@ -0,0 +1,88 @@ +#ifndef TEST_PROD_OPENCL_HH +#define TEST_PROD_OPENCL_HH +#include "test_opencl.hpp" + + +template <class T, class F, int number_of_tests, int max_dimension> +class bench_prod +{ +public: + + typedef test_opencl<T, F> test; + + void run() + { + opencl::library lib; + int passedOperations = 0; + // get default device and setup context + compute::device device = compute::system::default_device(); + compute::context context(device); + compute::command_queue queue(context, device); + + std::srand(time(0)); + + ublas::matrix<T, F> a; + ublas::matrix<T, F> b; + ublas::matrix<T, F> resultUBLAS; + ublas::matrix<T, F> resultOPENCL; + ublas::vector<T> va; + ublas::vector<T> vb; + ublas::vector<T> result_vector_ublas_mv; + ublas::vector<T> result_vector_ublas_vm; + ublas::vector<T> result_vector_opencl_mv; + ublas::vector<T> result_vector_opencl_vm; + + + + for (int i = 0; i<number_of_tests; i++) + { + int rowsA = std::rand() % max_dimension + 1; + int colsA = std::rand() % max_dimension + 1; + int colsB = std::rand() % max_dimension + 1; + + a.resize(rowsA, colsA); + b.resize(colsA, colsB); + va.resize(colsA); + vb.resize(rowsA); + + + test::init_matrix(a, 200); + test::init_matrix(b, 200); + test::init_vector(va, 200); + test::init_vector(vb, 200); + + //matrix_matrix + resultUBLAS = prod(a, b); + resultOPENCL = opencl::prod(a, b, queue); + + + //matrix_vector + result_vector_ublas_mv = ublas::prod(a, va); + result_vector_opencl_mv = opencl::prod(a, va, queue); + + + //vector-matrix + result_vector_ublas_vm = ublas::prod(vb, a); + result_vector_opencl_vm = opencl::prod(vb, a, queue); + + + if ((!test::compare(resultUBLAS, resultOPENCL)) || (!test::compare(result_vector_opencl_mv, result_vector_ublas_mv)) || (!test::compare(result_vector_opencl_vm, result_vector_ublas_vm))) + { + std::cout << "Error in calculations" << std::endl; + + std::cout << "passed: " << passedOperations << std::endl; + return; + } + + passedOperations++; + + } + std::cout << "All is well (matrix opencl prod) of " << typeid(T).name() << std::endl; + + + + } + +}; + +#endif
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/opencl/test_opencl.hpp b/src/boost/libs/numeric/ublas/test/opencl/test_opencl.hpp new file mode 100644 index 000000000..fe1af32ef --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/test_opencl.hpp @@ -0,0 +1,84 @@ +#ifndef TEST_OPENCL_HEADER_HH +#define TEST_OPENCL_HEADER_HH +#include <stdio.h> + +#define BOOST_UBLAS_ENABLE_OPENCL +#include <boost/numeric/ublas/opencl.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <time.h> +#include <math.h> + + + + +namespace ublas = boost::numeric::ublas; +namespace opencl = boost::numeric::ublas::opencl; +namespace compute = boost::compute; + +template <class T, class F = ublas::basic_row_major<>> +class test_opencl +{ +public: + static bool compare(ublas::matrix<T, F>& a, ublas::matrix<T, F>& b) + { + typedef typename ublas::matrix<T, F>::size_type size_type; + if ((a.size1() != b.size1()) || (a.size2() != b.size2())) + return false; + + for (size_type i = 0; i<a.size1(); i++) + for (size_type j = 0; j<a.size2(); j++) + if (a(i, j) != b(i, j)) + { + return false; + } + return true; + + } + + + static bool compare(ublas::vector<T>& a, ublas::vector<T>& b) + { + typedef typename ublas::vector<T>::size_type size_type; + if (a.size() != b.size()) + return false; + + for (size_type i = 0; i<a.size(); i++) + if ((a[i] != b[i])) + { + return false; + } + return true; + + } + + + + static void init_matrix(ublas::matrix<T, F>& m, int max_value) + { + typedef typename ublas::matrix<T, F>::size_type size_type; + for (size_type i = 0; i < m.size1(); i++) + { + for (size_type j = 0; j<m.size2(); j++) + m(i, j) = (std::rand() % max_value) + 1; + + } + } + + + static void init_vector(ublas::vector<T>& v, int max_value) + { + typedef typename ublas::vector<T>::size_type size_type; + for (size_type i = 0; i <v.size(); i++) + { + v[i] = (std::rand() % max_value) + 1; + } + } + + + virtual void run() + { + } + +}; + +#endif diff --git a/src/boost/libs/numeric/ublas/test/opencl/transposition_test.cpp b/src/boost/libs/numeric/ublas/test/opencl/transposition_test.cpp new file mode 100644 index 000000000..f6dd6782f --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/transposition_test.cpp @@ -0,0 +1,33 @@ +#include "transposition_test.hpp" + +int main() +{ + + //Row-major + bench_trans<float, ublas::basic_row_major<>, 10, 10> b1; + bench_trans<double, ublas::basic_row_major<>, 10, 10> b2; + bench_trans<std::complex<float>, ublas::basic_row_major<>, 10, 10> b3; + bench_trans<std::complex<double>, ublas::basic_row_major<>, 10, 10> b4; + + //Column-major + bench_trans<float, ublas::basic_column_major<>, 10, 10> b5; + bench_trans<double, ublas::basic_column_major<>, 10, 10> b6; + bench_trans<std::complex<float>, ublas::basic_column_major<>, 10, 10> b7; + bench_trans<std::complex<double>, ublas::basic_column_major<>, 10, 10> b8; + + std::cout << "Row-major:" << std::endl; + b1.run(); + b2.run(); + b3.run(); + b4.run(); + + std::cout << std::endl << "Column-major:" << std::endl; + + b5.run(); + b6.run(); + b7.run(); + b8.run(); + + return 0; + +}
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/opencl/transposition_test.hpp b/src/boost/libs/numeric/ublas/test/opencl/transposition_test.hpp new file mode 100644 index 000000000..eca469f92 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/transposition_test.hpp @@ -0,0 +1,61 @@ +#ifndef TEST_TRANS_OPENCL_HH +#define TEST_TRANS_OPENCL_HH +#include "test_opencl.hpp" + + +template <class T, class F, int number_of_tests, int max_dimension> +class bench_trans +{ +public: + + typedef test_opencl<T, F> test; + + void run() + { + opencl::library lib; + int passedOperations = 0; + // get default device and setup context + compute::device device = compute::system::default_device(); + compute::context context(device); + compute::command_queue queue(context, device); + + std::srand(time(0)); + + ublas::matrix<T, F> a; + ublas::matrix<T, F> resultUBLAS; + ublas::matrix<T, F> resultOPENCL; + + + for (int i = 0; i<number_of_tests; i++) + { + int rowsA = std::rand() % max_dimension + 1; + int colsA = std::rand() % max_dimension + 1; + + a.resize(rowsA, colsA); + + test::init_matrix(a, 200); + + resultUBLAS = ublas::trans(a); + resultOPENCL = opencl::trans(a, queue); + + + if (!test::compare(resultUBLAS, resultOPENCL)) + { + std::cout << "Error in calculations" << std::endl; + + std::cout << "passed: " << passedOperations << std::endl; + return; + } + + passedOperations++; + + } + std::cout << "All is well (matrix opencl prod) of " << typeid(T).name() << std::endl; + + + + } + +}; + +#endif
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/placement_new.cpp b/src/boost/libs/numeric/ublas/test/placement_new.cpp new file mode 100644 index 000000000..940da7dab --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/placement_new.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2004 Michael Stevens + * 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) + */ + +/* + * Test placement new and array placement new for uBLAS + * See if base pointer is effected by array count cookie + */ + +#include <boost/numeric/ublas/storage.hpp> +#include <iostream> +#include <new> + +// User defined type to capture base pointer on construction + +class udt { +public: + udt () { + base_pointer = this; + } + ~udt () {} // required for GCC prior to 3.4 to generate cookie + + static udt* base_pointer; +}; + +udt* udt::base_pointer; + +int main () +{ + udt a; + udt* ap = &a; + + // Capture placement new offsets for a udt + new (ap) udt; + int new_offset = int (udt::base_pointer - ap); + new (ap) udt [1]; + int array_new_offset = int (udt::base_pointer - ap); + + // Print offsets - we expect 0,0 or 0,sizeof(std::size_t) + std::cout << new_offset <<','<< array_new_offset << std::endl; + + // Return status + if (new_offset != 0) + return -1; // Very bad if new has an offset + +#ifdef BOOST_UBLAS_USEFUL_ARRAY_PLACEMENT_NEW + bool expect_array_offset = false; +#else + bool expect_array_offset = true; +#endif + // Check match between config and array + if (!expect_array_offset && array_new_offset != 0) { + return -2; // Bad config should not enable array new + } + if (expect_array_offset && array_new_offset == 0) { + return -3; // Config could enable array new + } + + return 0; +} diff --git a/src/boost/libs/numeric/ublas/test/size.cpp b/src/boost/libs/numeric/ublas/test/size.cpp new file mode 100644 index 000000000..1fd2f9de6 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/size.cpp @@ -0,0 +1,275 @@ +// Copyright (c) 2011 David Bellot +// +// 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) + +#include <boost/numeric/ublas/fwd.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_expression.hpp> +#include <boost/numeric/ublas/operation/size.hpp> +#include <boost/numeric/ublas/tags.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/vector_expression.hpp> +#include <iostream> +#include "utils.hpp" + + +BOOST_UBLAS_TEST_DEF( test_vector_container ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Vector Container" ); + + typedef double value_type; + typedef boost::numeric::ublas::vector<value_type> vector_type; + + vector_type v(5); + + v(0) = 0.555950; + v(1) = 0.108929; + v(2) = 0.948014; + v(3) = 0.023787; + v(4) = 1.023787; + + + // size(v) + BOOST_UBLAS_DEBUG_TRACE( "size(v) = " << boost::numeric::ublas::size(v) << " ==> " << v.size() ); + BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::size(v) == v.size() ); + + // size<1>(v) + BOOST_UBLAS_DEBUG_TRACE( "size<1>(v) = " << (boost::numeric::ublas::size<1>(v)) << " ==> " << v.size() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<1>(v) == v.size()) ); + + // [NOT_COMPILE]: this should *correctly* cause a compilation error + // size<2>(v) + //BOOST_UBLAS_DEBUG_TRACE( "size<2>(v) = " << (boost::numeric::ublas::size<vector_type,2>(v)) << " ==> " << v.size() ); + //BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<2>(v) == v.size()) ); + // [/NOT_COMPILE] +} + + +BOOST_UBLAS_TEST_DEF( test_vector_expression ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Vector Expression" ); + + typedef double value_type; + typedef boost::numeric::ublas::vector<value_type> vector_type; + + vector_type v(5); + + v(0) = 0.555950; + v(1) = 0.108929; + v(2) = 0.948014; + v(3) = 0.023787; + v(4) = 1.023787; + + + // size(-v) + BOOST_UBLAS_DEBUG_TRACE( "size(-v) = " << boost::numeric::ublas::size(-v) << " ==> " << (-v).size() ); + BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::size(-v) == (-v).size() ); + + // size<1>(-v) + BOOST_UBLAS_DEBUG_TRACE( "size<1>(-v) = " << (boost::numeric::ublas::size<1>(-v)) << " ==> " << (-v).size() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<1>(-v) == (-v).size()) ); +} + + +BOOST_UBLAS_TEST_DEF( test_vector_reference ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Vector Reference" ); + + typedef double value_type; + typedef boost::numeric::ublas::vector<value_type> vector_type; + typedef boost::numeric::ublas::vector_reference<vector_type> vector_reference_type; + + vector_type v(5); + + v(0) = 0.555950; + v(1) = 0.108929; + v(2) = 0.948014; + v(3) = 0.023787; + v(4) = 1.023787; + + + // size(reference(v) + BOOST_UBLAS_DEBUG_TRACE( "size(reference(v)) = " << boost::numeric::ublas::size(vector_reference_type(v)) << " ==> " << vector_reference_type(v).size() ); + BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::size(vector_reference_type(v)) == vector_reference_type(v).size() ); + + // size<1>(reference(v)) + BOOST_UBLAS_DEBUG_TRACE( "size<1>(reference(v)) = " << (boost::numeric::ublas::size<1>(vector_reference_type(v))) << " ==> " << vector_reference_type(v).size() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<1>(vector_reference_type(v)) == vector_reference_type(v).size()) ); +} + + +BOOST_UBLAS_TEST_DEF( test_row_major_matrix_container ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Row-major Matrix Container" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::row_major> matrix_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + // [NOT_COMPILE] + // size(A) + //BOOST_UBLAS_DEBUG_TRACE( "size(A) = " << boost::numeric::ublas::size(A) << " ==> " << A.size1() ); + //BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::size(A) == A.size1() ); + // [/NOT_COMPILE] + + // size<1>(A) + BOOST_UBLAS_DEBUG_TRACE( "size<1>(A) = " << (boost::numeric::ublas::size<1>(A)) << " ==> " << A.size1() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<1>(A) == A.size1()) ); + + // size<2>(A) + BOOST_UBLAS_DEBUG_TRACE( "size<2>(A) = " << (boost::numeric::ublas::size<2>(A)) << " ==> " << A.size2() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<2>(A) == A.size2()) ); + + // size<major>(A) + BOOST_UBLAS_DEBUG_TRACE( "size<major>(A) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::major>(A)) << " ==> " << A.size1() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::major>(A) == A.size1()) ); + + // size<minor>(A) + BOOST_UBLAS_DEBUG_TRACE( "size<minor>(A) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::minor>(A)) << " ==> " << A.size2() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::minor>(A) == A.size2()) ); + + // size<leading>(A) + BOOST_UBLAS_DEBUG_TRACE( "size<leading>(A) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::leading>(A)) << " ==> " << A.size2() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::leading>(A) == A.size2()) ); +} + + +BOOST_UBLAS_TEST_DEF( test_col_major_matrix_container ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Column-major Matrix Container" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::column_major> matrix_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + // size<1>(A) + BOOST_UBLAS_DEBUG_TRACE( "size<1>(A) = " << (boost::numeric::ublas::size<1>(A)) << " ==> " << A.size1() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<1>(A) == A.size1()) ); + + // size<2>(A) + BOOST_UBLAS_DEBUG_TRACE( "size<2>(A) = " << (boost::numeric::ublas::size<2>(A)) << " ==> " << A.size2() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<2>(A) == A.size2()) ); + + // size<major>(A) + BOOST_UBLAS_DEBUG_TRACE( "size<major>(A) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::major>(A)) << " ==> " << A.size2() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::major>(A) == A.size2()) ); + + // size<minor>(A) + BOOST_UBLAS_DEBUG_TRACE( "size<minor>(A) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::minor>(A)) << " ==> " << A.size1() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::minor>(A) == A.size1()) ); + + // size<leading>(A) + BOOST_UBLAS_DEBUG_TRACE( "size<leading>(A) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::leading>(A)) << " ==> " << A.size1() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::leading>(A) == A.size1()) ); +} + + +BOOST_UBLAS_TEST_DEF( test_matrix_expression ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Matrix Expression" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type> matrix_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + // size<1>(A') + BOOST_UBLAS_DEBUG_TRACE( "size<1>(A') = " << (boost::numeric::ublas::size<1>(boost::numeric::ublas::trans(A))) << " ==> " << A.size2() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<1>(boost::numeric::ublas::trans(A)) == A.size2()) ); + + // size<2>(A') + BOOST_UBLAS_DEBUG_TRACE( "size<2>(A') = " << (boost::numeric::ublas::size<2>(boost::numeric::ublas::trans(A))) << " ==> " << A.size1() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<2>(boost::numeric::ublas::trans(A)) == A.size1()) ); + + // size<major>(A') [A is row-major => A' column-major, and viceversa] + BOOST_UBLAS_DEBUG_TRACE( "size<major>(A') = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::major>(boost::numeric::ublas::trans(A))) << " ==> " << A.size1() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::major>(boost::numeric::ublas::trans(A)) == A.size1()) ); + + // size<minor>(A') [A is row-major => A' column-major, and viceversa] + BOOST_UBLAS_DEBUG_TRACE( "size<minor>(A') = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::minor>(boost::numeric::ublas::trans(A))) << " ==> " << A.size2() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::minor>(boost::numeric::ublas::trans(A)) == A.size2()) ); + + // size<leading>(A') [A row-major => A' column-major, and viceversa] + BOOST_UBLAS_DEBUG_TRACE( "size<leading>(A') = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::leading>(boost::numeric::ublas::trans(A))) << " ==> " << A.size2() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::leading>(boost::numeric::ublas::trans(A)) == A.size2()) ); +} + + +BOOST_UBLAS_TEST_DEF( test_matrix_reference ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Matrix Reference" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type> matrix_type; + typedef boost::numeric::ublas::matrix_reference<matrix_type> matrix_reference_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + // size<1>(reference(A)) + BOOST_UBLAS_DEBUG_TRACE( "size<1>(reference(A)) = " << (boost::numeric::ublas::size<1>(matrix_reference_type(A))) << " ==> " << matrix_reference_type(A).size1() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<1>(matrix_reference_type(A)) == matrix_reference_type(A).size1()) ); + + // size<2>(reference(A)) + BOOST_UBLAS_DEBUG_TRACE( "size<2>(reference(A)) = " << (boost::numeric::ublas::size<2>(matrix_reference_type(A))) << " ==> " << matrix_reference_type(A).size2() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<2>(matrix_reference_type(A)) == matrix_reference_type(A).size2()) ); + + // size<major>(reference(A)) + BOOST_UBLAS_DEBUG_TRACE( "size<major>(reference(A) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::major>(matrix_reference_type(A))) << " ==> " << matrix_reference_type(A).size1() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::major>(matrix_reference_type(A)) == matrix_reference_type(A).size1()) ); + + // size<minor>(reference(A)) + BOOST_UBLAS_DEBUG_TRACE( "size<minor>(reference(A)) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::minor>(matrix_reference_type(A))) << " ==> " << matrix_reference_type(A).size2() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::minor>(matrix_reference_type(A)) == matrix_reference_type(A).size2()) ); + + // size<leading>(reference(A)) + BOOST_UBLAS_DEBUG_TRACE( "size<leading>(reference(A)) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::leading>(matrix_reference_type(A))) << " ==> " << matrix_reference_type(A).size2() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::leading>(matrix_reference_type(A)) == matrix_reference_type(A).size2()) ); +} + + +int main() +{ + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( test_vector_container ); + BOOST_UBLAS_TEST_DO( test_vector_expression ); + BOOST_UBLAS_TEST_DO( test_vector_reference ); + BOOST_UBLAS_TEST_DO( test_row_major_matrix_container ); + BOOST_UBLAS_TEST_DO( test_col_major_matrix_container ); + BOOST_UBLAS_TEST_DO( test_matrix_expression ); + BOOST_UBLAS_TEST_DO( test_matrix_reference ); + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/sparse_view_test.cpp b/src/boost/libs/numeric/ublas/test/sparse_view_test.cpp new file mode 100644 index 000000000..178e44427 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/sparse_view_test.cpp @@ -0,0 +1,106 @@ +// Copyright (c) 2009-2011 Gunter Winkler, David Bellot +// +// 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) + +// ublas headers + +#include <boost/numeric/ublas/experimental/sparse_view.hpp> + +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_sparse.hpp> +#include <boost/numeric/ublas/io.hpp> + +#include <boost/numeric/ublas/traits/c_array.hpp> + +// other boost headers + +// headers for testcase + +#define BOOST_TEST_MODULE SparseMatrixErasureTest +#include <boost/test/included/unit_test.hpp> + +// standard and system headers + +#include <iostream> +#include <string> + +namespace ublas = boost::numeric::ublas; + + /* + sparse input matrix: + + 1 2 0 0 + 0 3 9 0 + 0 1 4 0 + */ + + static const std::string inputMatrix = "[3,4]((1,2,0,0),(0,3,9,0),(0,1,4,0))\n"; + + const unsigned int NNZ = 6; + const unsigned int IB = 1; + const double VA[] = { 1.0, 2.0, 3.0, 9.0, 1.0, 4.0 }; + const unsigned int IA[] = { 1, 3, 5, 7 }; + const unsigned int JA[] = { 1, 2, 2, 3, 2, 3 }; + +BOOST_AUTO_TEST_CASE( test_construction_and_basic_operations ) +{ + + typedef ublas::matrix<double> DENSE_MATRIX; + + // prepare data + + DENSE_MATRIX A; + + std::istringstream iss(inputMatrix); + iss >> A; + + std::cout << A << std::endl; + + std::cout << ( ublas::make_compressed_matrix_view<ublas::row_major,IB>(3,4,NNZ,IA,JA,VA) ) << std::endl; + + typedef ublas::compressed_matrix_view<ublas::row_major, IB, unsigned int [4], unsigned int [NNZ], double[NNZ]> COMPMATVIEW; + + COMPMATVIEW viewA(3,4,NNZ,IA,JA,VA); + + std::cout << viewA << std::endl; + +} + + + +BOOST_AUTO_TEST_CASE( test_construction_from_pointers ) +{ + + std::cout << ( ublas::make_compressed_matrix_view<ublas::column_major,IB>(4,3,NNZ + , ublas::c_array_view<const unsigned int>(4,&(IA[0])) + , ublas::c_array_view<const unsigned int>(6,&(JA[0])) + , ublas::c_array_view<const double>(6,&(VA[0]))) ) << std::endl; + + unsigned int * ia = new unsigned int[4](); + unsigned int * ja = new unsigned int[6](); + double * va = new double[6](); + + std::copy(&(IA[0]),&(IA[4]),ia); + std::copy(&(JA[0]),&(JA[6]),ja); + std::copy(&(VA[0]),&(VA[6]),va); + + typedef ublas::compressed_matrix_view<ublas::column_major + , IB + , ublas::c_array_view<unsigned int> + , ublas::c_array_view<unsigned int> + , ublas::c_array_view<double> > COMPMATVIEW; + + COMPMATVIEW viewA(4,3,NNZ + , ublas::c_array_view<unsigned int>(4,ia) + , ublas::c_array_view<unsigned int>(6,ja) + , ublas::c_array_view<double>(6,va)); + + std::cout << viewA << std::endl; + + delete[] va; + delete[] ja; + delete[] ia; + +} diff --git a/src/boost/libs/numeric/ublas/test/tensor/Jamfile b/src/boost/libs/numeric/ublas/test/tensor/Jamfile new file mode 100644 index 000000000..0bbf2c569 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/Jamfile @@ -0,0 +1,42 @@ +# Boost.uBLAS +# +# Copyright (c) 2018 Cem Bassoy +# +# Use, modification and distribution is 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) + +project boost/ublas/test/tensor + : requirements + # these tests require C++17 + <cxxstd>11:<build>no + <toolset>gcc:<cxxflags>"-Wall -Wno-unknown-pragmas -Wno-sign-compare -Wno-unused-but-set-variable" + ; + +alias unit_test_framework + : # sources + /boost//unit_test_framework + ; + +# make aliases explicit so the libraries will only be built when requested +explicit unit_test_framework ; + + + +test-suite boost-ublas-tensor-test + : + [ run test_tensor.cpp + test_strides.cpp + test_operators_comparison.cpp + test_operators_arithmetic.cpp + test_multiplication.cpp + test_multi_index_utility.cpp + test_multi_index.cpp + test_functions.cpp + test_extents.cpp + test_expression_evaluation.cpp + test_einstein_notation.cpp + test_algorithms.cpp + test_tensor_matrix_vector.cpp + unit_test_framework ] + ; diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_algorithms.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_algorithms.cpp new file mode 100644 index 000000000..4215fc2a1 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_algorithms.cpp @@ -0,0 +1,288 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// 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) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// + + +#include <iostream> +#include <algorithm> +#include <vector> +#include <boost/numeric/ublas/tensor/algorithms.hpp> +#include <boost/numeric/ublas/tensor/extents.hpp> +#include <boost/numeric/ublas/tensor/strides.hpp> +#include "utility.hpp" + +#include <boost/test/unit_test.hpp> + + +BOOST_AUTO_TEST_SUITE ( test_tensor_algorithms, + * boost::unit_test::depends_on("test_extents") + * boost::unit_test::depends_on("test_strides")) + + +using test_types = zip<int,long,float,double,std::complex<float>>::with_t<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>; +using test_types2 = std::tuple<int,long,float,double,std::complex<float>>; + +struct fixture +{ + using extents_type = boost::numeric::ublas::shape; + fixture() + : extents { + extents_type{1,1}, // 1 + extents_type{1,2}, // 2 + extents_type{2,1}, // 3 + extents_type{2,3}, // 4 + extents_type{2,3,1}, // 5 + extents_type{4,1,3}, // 6 + extents_type{1,2,3}, // 7 + extents_type{4,2,3}, // 8 + extents_type{4,2,3,5} } // 9 + { + } + std::vector<extents_type> extents; +}; + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_algorithms_copy, value, test_types2, fixture ) +{ + using namespace boost::numeric; + using value_type = value; + using vector_type = std::vector<value_type>; + + + for(auto const& n : extents) { + + auto a = vector_type(n.product()); + auto b = vector_type(n.product()); + auto c = vector_type(n.product()); + + auto wa = ublas::strides<ublas::first_order>(n); + auto wb = ublas::strides<ublas::last_order> (n); + auto wc = ublas::strides<ublas::first_order>(n); + + auto v = value_type{}; + for(auto i = 0ul; i < a.size(); ++i, v+=1){ + a[i]=v; + } + + ublas::copy( n.size(), n.data(), b.data(), wb.data(), a.data(), wa.data() ); + ublas::copy( n.size(), n.data(), c.data(), wc.data(), b.data(), wb.data() ); + + for(auto i = 1ul; i < c.size(); ++i) + BOOST_CHECK_EQUAL( c[i], a[i] ); + + using size_type = typename ublas::strides<ublas::first_order>::value_type; + size_type const*const p0 = nullptr; + BOOST_CHECK_THROW( ublas::copy( n.size(), p0, c.data(), wc.data(), b.data(), wb.data() ), std::length_error ); + BOOST_CHECK_THROW( ublas::copy( n.size(), n.data(), c.data(), p0, b.data(), wb.data() ), std::length_error ); + BOOST_CHECK_THROW( ublas::copy( n.size(), n.data(), c.data(), wc.data(), b.data(), p0 ), std::length_error ); + + value_type* c0 = nullptr; + BOOST_CHECK_THROW( ublas::copy( n.size(), n.data(), c0, wc.data(), b.data(), wb.data() ), std::length_error ); + } + + // special case rank == 0 + { + auto n = ublas::shape{}; + + auto a = vector_type(n.product()); + auto b = vector_type(n.product()); + auto c = vector_type(n.product()); + + + auto wa = ublas::strides<ublas::first_order>(n); + auto wb = ublas::strides<ublas::last_order> (n); + auto wc = ublas::strides<ublas::first_order>(n); + + ublas::copy( n.size(), n.data(), b.data(), wb.data(), a.data(), wa.data() ); + ublas::copy( n.size(), n.data(), c.data(), wc.data(), b.data(), wb.data() ); + + + + BOOST_CHECK_NO_THROW( ublas::copy( n.size(), n.data(), c.data(), wc.data(), b.data(), wb.data() ) ); + + } + + + + + +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_algorithms_transform, value, test_types2, fixture ) +{ + using namespace boost::numeric; + using value_type = value; + using vector_type = std::vector<value_type>; + + + for(auto const& n : extents) { + + auto a = vector_type(n.product()); + auto b = vector_type(n.product()); + auto c = vector_type(n.product()); + + auto wa = ublas::strides<ublas::first_order>(n); + auto wb = ublas::strides<ublas::last_order> (n); + auto wc = ublas::strides<ublas::first_order>(n); + + auto v = value_type{}; + for(auto i = 0ul; i < a.size(); ++i, v+=1){ + a[i]=v; + } + + ublas::transform( n.size(), n.data(), b.data(), wb.data(), a.data(), wa.data(), [](value_type const& a){ return a + value_type(1);} ); + ublas::transform( n.size(), n.data(), c.data(), wc.data(), b.data(), wb.data(), [](value_type const& a){ return a - value_type(1);} ); + + for(auto i = 1ul; i < c.size(); ++i) + BOOST_CHECK_EQUAL( c[i], a[i] ); + + } +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_algorithms_accumulate, value, test_types2, fixture ) +{ + using namespace boost::numeric; + using value_type = value; + using vector_type = std::vector<value_type>; + + + for(auto const& n : extents) { + + auto const s = n.product(); + + auto a = vector_type(n.product()); + // auto b = vector_type(n.product()); + // auto c = vector_type(n.product()); + + auto wa = ublas::strides<ublas::first_order>(n); + // auto wb = ublas::strides<ublas::last_order> (n); + // auto wc = ublas::strides<ublas::first_order>(n); + + auto v = value_type{}; + for(auto i = 0ul; i < a.size(); ++i, v+=value_type(1)){ + a[i]=v; + } + + auto acc = ublas::accumulate( n.size(), n.data(), a.data(), wa.data(), v); + + BOOST_CHECK_EQUAL( acc, value_type( s*(s+1) / 2 ) ); + + + auto acc2 = ublas::accumulate( n.size(), n.data(), a.data(), wa.data(), v, + [](auto const& l, auto const& r){return l + r; }); + + BOOST_CHECK_EQUAL( acc2, value_type( s*(s+1) / 2 ) ); + + } +} + + + + +template<class V> +void init(std::vector<V>& a) +{ + auto v = V(1); + for(auto i = 0u; i < a.size(); ++i, ++v){ + a[i] = v; + } +} + +template<class V> +void init(std::vector<std::complex<V>>& a) +{ + auto v = std::complex<V>(1,1); + for(auto i = 0u; i < a.size(); ++i){ + a[i] = v; + v.real(v.real()+1); + v.imag(v.imag()+1); + } +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_algorithms_trans, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using vector_type = std::vector<value_type>; + using strides_type = ublas::strides<layout_type>; + using extents_type = ublas::shape; + using size_type = typename extents_type::value_type; + using permutation_type = std::vector<size_type>; + + + for(auto const& n : extents) { + + auto p = n.size(); + auto s = n.product(); + + auto pi = permutation_type(p); + auto a = vector_type(s); + auto b1 = vector_type(s); + auto b2 = vector_type(s); + auto c1 = vector_type(s); + auto c2 = vector_type(s); + + auto wa = strides_type(n); + + init(a); + + // so wie last-order. + for(auto i = size_type(0), j = p; i < n.size(); ++i, --j) + pi[i] = j; + + auto nc = typename extents_type::base_type (p); + for(auto i = 0u; i < p; ++i) + nc[pi[i]-1] = n[i]; + + auto wc = strides_type(extents_type(nc)); + auto wc_pi = typename strides_type::base_type (p); + for(auto i = 0u; i < p; ++i) + wc_pi[pi[i]-1] = wc[i]; + + ublas::copy ( p, n.data(), c1.data(), wc_pi.data(), a.data(), wa.data()); + ublas::trans( p, n.data(), pi.data(), c2.data(), wc.data(), a.data(), wa.data() ); + + if(!std::is_compound_v<value_type>) + for(auto i = 0ul; i < s; ++i) + BOOST_CHECK_EQUAL( c1[i], c2[i] ); + + + auto nb = typename extents_type::base_type (p); + for(auto i = 0u; i < p; ++i) + nb[pi[i]-1] = nc[i]; + + auto wb = strides_type (extents_type(nb)); + auto wb_pi = typename strides_type::base_type (p); + for(auto i = 0u; i < p; ++i) + wb_pi[pi[i]-1] = wb[i]; + + ublas::copy ( p, nc.data(), b1.data(), wb_pi.data(), c1.data(), wc.data()); + ublas::trans( p, nc.data(), pi.data(), b2.data(), wb.data(), c2.data(), wc.data() ); + + if(!std::is_compound_v<value_type>) + for(auto i = 0ul; i < s; ++i) + BOOST_CHECK_EQUAL( b1[i], b2[i] ); + + for(auto i = 0ul; i < s; ++i) + BOOST_CHECK_EQUAL( a[i], b2[i] ); + + } +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_einstein_notation.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_einstein_notation.cpp new file mode 100644 index 000000000..b0326c80c --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_einstein_notation.cpp @@ -0,0 +1,122 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// 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) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// +// And we acknowledge the support from all contributors. + + +#include <iostream> +#include <algorithm> +#include <boost/numeric/ublas/tensor.hpp> + +#include <boost/test/unit_test.hpp> + +#include "utility.hpp" + +BOOST_AUTO_TEST_SUITE ( test_einstein_notation, * boost::unit_test::depends_on("test_multi_index") ) + + +using test_types = zip<int,long,float,double,std::complex<float>>::with_t<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>; + +//using test_types = zip<int>::with_t<boost::numeric::ublas::first_order>; + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_einstein_multiplication, value, test_types ) +{ + using namespace boost::numeric::ublas; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = tensor<value_type,layout_type>; + using namespace boost::numeric::ublas::index; + + { + auto A = tensor_type{5,3}; + auto B = tensor_type{3,4}; + // auto C = tensor_type{4,5,6}; + + for(auto j = 0u; j < A.extents().at(1); ++j) + for(auto i = 0u; i < A.extents().at(0); ++i) + A.at( i,j ) = value_type(i+1); + + for(auto j = 0u; j < B.extents().at(1); ++j) + for(auto i = 0u; i < B.extents().at(0); ++i) + B.at( i,j ) = value_type(i+1); + + + + auto AB = A(_,_e) * B(_e,_); + + // std::cout << "A = " << A << std::endl; + // std::cout << "B = " << B << std::endl; + // std::cout << "AB = " << AB << std::endl; + + for(auto j = 0u; j < AB.extents().at(1); ++j) + for(auto i = 0u; i < AB.extents().at(0); ++i) + BOOST_CHECK_EQUAL( AB.at( i,j ) , value_type(A.at( i,0 ) * ( B.extents().at(0) * (B.extents().at(0)+1) / 2 )) ); + + + } + + + { + auto A = tensor_type{4,5,3}; + auto B = tensor_type{3,4,2}; + + for(auto k = 0u; k < A.extents().at(2); ++k) + for(auto j = 0u; j < A.extents().at(1); ++j) + for(auto i = 0u; i < A.extents().at(0); ++i) + A.at( i,j,k ) = value_type(i+1); + + for(auto k = 0u; k < B.extents().at(2); ++k) + for(auto j = 0u; j < B.extents().at(1); ++j) + for(auto i = 0u; i < B.extents().at(0); ++i) + B.at( i,j,k ) = value_type(i+1); + + auto AB = A(_d,_,_f) * B(_f,_d,_); + + // std::cout << "A = " << A << std::endl; + // std::cout << "B = " << B << std::endl; + // std::cout << "AB = " << AB << std::endl; + // n*(n+1)/2; + auto const nf = ( B.extents().at(0) * (B.extents().at(0)+1) / 2 ); + auto const nd = ( A.extents().at(0) * (A.extents().at(0)+1) / 2 ); + + for(auto j = 0u; j < AB.extents().at(1); ++j) + for(auto i = 0u; i < AB.extents().at(0); ++i) + BOOST_CHECK_EQUAL( AB.at( i,j ) , value_type(nf * nd) ); + + } + + + { + auto A = tensor_type{4,3}; + auto B = tensor_type{3,4,2}; + + for(auto j = 0u; j < A.extents().at(1); ++j) + for(auto i = 0u; i < A.extents().at(0); ++i) + A.at( i,j ) = value_type(i+1); + + for(auto k = 0u; k < B.extents().at(2); ++k) + for(auto j = 0u; j < B.extents().at(1); ++j) + for(auto i = 0u; i < B.extents().at(0); ++i) + B.at( i,j,k ) = value_type(i+1); + + auto AB = A(_d,_f) * B(_f,_d,_); + + // n*(n+1)/2; + auto const nf = ( B.extents().at(0) * (B.extents().at(0)+1) / 2 ); + auto const nd = ( A.extents().at(0) * (A.extents().at(0)+1) / 2 ); + + for(auto i = 0u; i < AB.extents().at(0); ++i) + BOOST_CHECK_EQUAL ( AB.at( i ) , value_type(nf * nd) ); + + } +} + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_expression.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_expression.cpp new file mode 100644 index 000000000..ae3ce2050 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_expression.cpp @@ -0,0 +1,170 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// 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) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// + + + + +#include <boost/numeric/ublas/tensor/expression.hpp> +#include <boost/numeric/ublas/tensor/tensor.hpp> +#include <boost/test/unit_test.hpp> +#include "utility.hpp" + +#include <functional> +#include <complex> + + + +using test_types = zip<int,long,float,double,std::complex<float>>::with_t<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>; + + +struct fixture +{ + using extents_type = boost::numeric::ublas::shape; + fixture() + : extents { + extents_type{}, // 0 + + extents_type{1,1}, // 1 + extents_type{1,2}, // 2 + extents_type{2,1}, // 3 + + extents_type{2,3}, // 4 + extents_type{2,3,1}, // 5 + extents_type{1,2,3}, // 6 + extents_type{1,1,2,3}, // 7 + extents_type{1,2,3,1,1}, // 8 + + extents_type{4,2,3}, // 9 + extents_type{4,2,1,3}, // 10 + extents_type{4,2,1,3,1}, // 11 + extents_type{1,4,2,1,3,1} } // 12 + { + } + std::vector<extents_type> extents; +}; + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_expression_access, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using tensor_expression_type = typename tensor_type::super_type; + + + for(auto const& e : extents) { + + auto v = value_type{}; + auto t = tensor_type(e); + + for(auto& tt: t){ tt = v; v+=value_type{1}; } + const auto& tensor_expression_const = static_cast<tensor_expression_type const&>( t ); + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL( tensor_expression_const()(i), t(i) ); + + } +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_unary_expression, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + auto uplus1 = std::bind( std::plus<value_type>{}, std::placeholders::_1, value_type(1) ); + + for(auto const& e : extents) { + + auto t = tensor_type(e); + auto v = value_type{}; + for(auto& tt: t) { tt = v; v+=value_type{1}; } + + const auto uexpr = ublas::detail::make_unary_tensor_expression<tensor_type>( t, uplus1 ); + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL( uexpr(i), uplus1(t(i)) ); + + auto uexpr_uexpr = ublas::detail::make_unary_tensor_expression<tensor_type>( uexpr, uplus1 ); + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL( uexpr_uexpr(i), uplus1(uplus1(t(i))) ); + + const auto & uexpr_e = uexpr.e; + + BOOST_CHECK( ( std::is_same_v< std::decay_t< decltype(uexpr_e) >, tensor_type > ) ); + + const auto & uexpr_uexpr_e_e = uexpr_uexpr.e.e; + + BOOST_CHECK( ( std::is_same_v< std::decay_t< decltype(uexpr_uexpr_e_e) >, tensor_type > ) ); + + + } +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_binary_expression, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + auto uplus1 = std::bind( std::plus<value_type>{}, std::placeholders::_1, value_type(1) ); + auto uplus2 = std::bind( std::plus<value_type>{}, std::placeholders::_1, value_type(2) ); + auto bplus = std::plus <value_type>{}; + auto bminus = std::minus<value_type>{}; + + for(auto const& e : extents) { + + auto t = tensor_type(e); + auto v = value_type{}; + for(auto& tt: t){ tt = v; v+=value_type{1}; } + + auto uexpr1 = ublas::detail::make_unary_tensor_expression<tensor_type>( t, uplus1 ); + auto uexpr2 = ublas::detail::make_unary_tensor_expression<tensor_type>( t, uplus2 ); + + BOOST_CHECK( ( std::is_same_v< std::decay_t< decltype(uexpr1.e) >, tensor_type > ) ); + BOOST_CHECK( ( std::is_same_v< std::decay_t< decltype(uexpr2.e) >, tensor_type > ) ); + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL( uexpr1(i), uplus1(t(i)) ); + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL( uexpr2(i), uplus2(t(i)) ); + + auto bexpr_uexpr = ublas::detail::make_binary_tensor_expression<tensor_type>( uexpr1, uexpr2, bplus ); + + BOOST_CHECK( ( std::is_same_v< std::decay_t< decltype(bexpr_uexpr.el.e) >, tensor_type > ) ); + BOOST_CHECK( ( std::is_same_v< std::decay_t< decltype(bexpr_uexpr.er.e) >, tensor_type > ) ); + + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL( bexpr_uexpr(i), bplus(uexpr1(i),uexpr2(i)) ); + + auto bexpr_bexpr_uexpr = ublas::detail::make_binary_tensor_expression<tensor_type>( bexpr_uexpr, t, bminus ); + + BOOST_CHECK( ( std::is_same_v< std::decay_t< decltype(bexpr_bexpr_uexpr.el.el.e) >, tensor_type > ) ); + BOOST_CHECK( ( std::is_same_v< std::decay_t< decltype(bexpr_bexpr_uexpr.el.er.e) >, tensor_type > ) ); + BOOST_CHECK( ( std::is_same_v< std::decay_t< decltype(bexpr_bexpr_uexpr.er) >, tensor_type > ) ); + BOOST_CHECK( ( std::is_same_v< std::decay_t< decltype(bexpr_bexpr_uexpr.er) >, tensor_type > ) ); + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL( bexpr_bexpr_uexpr(i), bminus(bexpr_uexpr(i),t(i)) ); + + } + + +} diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_expression_evaluation.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_expression_evaluation.cpp new file mode 100644 index 000000000..002d51a2b --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_expression_evaluation.cpp @@ -0,0 +1,240 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// 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) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// + + + +#include <boost/numeric/ublas/tensor/expression_evaluation.hpp> +#include <boost/numeric/ublas/tensor/expression.hpp> +#include <boost/numeric/ublas/tensor/tensor.hpp> +#include <boost/test/unit_test.hpp> +#include "utility.hpp" + +#include <functional> + +using test_types = zip<int,long,float,double,std::complex<float>>::with_t<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>; + + +struct fixture +{ + using extents_type = boost::numeric::ublas::shape; + fixture() + : extents{ + extents_type{}, // 0 + + extents_type{1,1}, // 1 + extents_type{1,2}, // 2 + extents_type{2,1}, // 3 + + extents_type{2,3}, // 4 + extents_type{2,3,1}, // 5 + extents_type{1,2,3}, // 6 + extents_type{1,1,2,3}, // 7 + extents_type{1,2,3,1,1}, // 8 + + extents_type{4,2,3}, // 9 + extents_type{4,2,1,3}, // 10 + extents_type{4,2,1,3,1}, // 11 + extents_type{1,4,2,1,3,1}} // 12 + { + } + std::vector<extents_type> extents; +}; + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_expression_retrieve_extents, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + auto uplus1 = std::bind( std::plus<value_type>{}, std::placeholders::_1, value_type(1) ); + auto uplus2 = std::bind( std::plus<value_type>{}, value_type(2), std::placeholders::_2 ); + auto bplus = std::plus <value_type>{}; + auto bminus = std::minus<value_type>{}; + + for(auto const& e : extents) { + + auto t = tensor_type(e); + auto v = value_type{}; + for(auto& tt: t){ tt = v; v+=value_type{1}; } + + + BOOST_CHECK( ublas::detail::retrieve_extents( t ) == e ); + + + // uexpr1 = t+1 + // uexpr2 = 2+t + auto uexpr1 = ublas::detail::make_unary_tensor_expression<tensor_type>( t, uplus1 ); + auto uexpr2 = ublas::detail::make_unary_tensor_expression<tensor_type>( t, uplus2 ); + + BOOST_CHECK( ublas::detail::retrieve_extents( uexpr1 ) == e ); + BOOST_CHECK( ublas::detail::retrieve_extents( uexpr2 ) == e ); + + // bexpr_uexpr = (t+1) + (2+t) + auto bexpr_uexpr = ublas::detail::make_binary_tensor_expression<tensor_type>( uexpr1, uexpr2, bplus ); + + BOOST_CHECK( ublas::detail::retrieve_extents( bexpr_uexpr ) == e ); + + + // bexpr_bexpr_uexpr = ((t+1) + (2+t)) - t + auto bexpr_bexpr_uexpr = ublas::detail::make_binary_tensor_expression<tensor_type>( bexpr_uexpr, t, bminus ); + + BOOST_CHECK( ublas::detail::retrieve_extents( bexpr_bexpr_uexpr ) == e ); + + } + + + for(auto i = 0u; i < extents.size()-1; ++i) + { + + auto v = value_type{}; + + auto t1 = tensor_type(extents[i]); + for(auto& tt: t1){ tt = v; v+=value_type{1}; } + + auto t2 = tensor_type(extents[i+1]); + for(auto& tt: t2){ tt = v; v+=value_type{2}; } + + BOOST_CHECK( ublas::detail::retrieve_extents( t1 ) != ublas::detail::retrieve_extents( t2 ) ); + + // uexpr1 = t1+1 + // uexpr2 = 2+t2 + auto uexpr1 = ublas::detail::make_unary_tensor_expression<tensor_type>( t1, uplus1 ); + auto uexpr2 = ublas::detail::make_unary_tensor_expression<tensor_type>( t2, uplus2 ); + + BOOST_CHECK( ublas::detail::retrieve_extents( t1 ) == ublas::detail::retrieve_extents( uexpr1 ) ); + BOOST_CHECK( ublas::detail::retrieve_extents( t2 ) == ublas::detail::retrieve_extents( uexpr2 ) ); + BOOST_CHECK( ublas::detail::retrieve_extents( uexpr1 ) != ublas::detail::retrieve_extents( uexpr2 ) ); + + // bexpr_uexpr = (t1+1) + (2+t2) + auto bexpr_uexpr = ublas::detail::make_binary_tensor_expression<tensor_type>( uexpr1, uexpr2, bplus ); + + BOOST_CHECK( ublas::detail::retrieve_extents( bexpr_uexpr ) == ublas::detail::retrieve_extents(t1) ); + + + // bexpr_bexpr_uexpr = ((t1+1) + (2+t2)) - t2 + auto bexpr_bexpr_uexpr1 = ublas::detail::make_binary_tensor_expression<tensor_type>( bexpr_uexpr, t2, bminus ); + + BOOST_CHECK( ublas::detail::retrieve_extents( bexpr_bexpr_uexpr1 ) == ublas::detail::retrieve_extents(t2) ); + + + // bexpr_bexpr_uexpr = t2 - ((t1+1) + (2+t2)) + auto bexpr_bexpr_uexpr2 = ublas::detail::make_binary_tensor_expression<tensor_type>( t2, bexpr_uexpr, bminus ); + + BOOST_CHECK( ublas::detail::retrieve_extents( bexpr_bexpr_uexpr2 ) == ublas::detail::retrieve_extents(t2) ); + } +} + + + + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_expression_all_extents_equal, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + auto uplus1 = std::bind( std::plus<value_type>{}, std::placeholders::_1, value_type(1) ); + auto uplus2 = std::bind( std::plus<value_type>{}, value_type(2), std::placeholders::_2 ); + auto bplus = std::plus <value_type>{}; + auto bminus = std::minus<value_type>{}; + + for(auto const& e : extents) { + + auto t = tensor_type(e); + auto v = value_type{}; + for(auto& tt: t){ tt = v; v+=value_type{1}; } + + + BOOST_CHECK( ublas::detail::all_extents_equal( t , e ) ); + + + // uexpr1 = t+1 + // uexpr2 = 2+t + auto uexpr1 = ublas::detail::make_unary_tensor_expression<tensor_type>( t, uplus1 ); + auto uexpr2 = ublas::detail::make_unary_tensor_expression<tensor_type>( t, uplus2 ); + + BOOST_CHECK( ublas::detail::all_extents_equal( uexpr1, e ) ); + BOOST_CHECK( ublas::detail::all_extents_equal( uexpr2, e ) ); + + // bexpr_uexpr = (t+1) + (2+t) + auto bexpr_uexpr = ublas::detail::make_binary_tensor_expression<tensor_type>( uexpr1, uexpr2, bplus ); + + BOOST_CHECK( ublas::detail::all_extents_equal( bexpr_uexpr, e ) ); + + + // bexpr_bexpr_uexpr = ((t+1) + (2+t)) - t + auto bexpr_bexpr_uexpr = ublas::detail::make_binary_tensor_expression<tensor_type>( bexpr_uexpr, t, bminus ); + + BOOST_CHECK( ublas::detail::all_extents_equal( bexpr_bexpr_uexpr , e ) ); + + } + + + for(auto i = 0u; i < extents.size()-1; ++i) + { + + auto v = value_type{}; + + auto t1 = tensor_type(extents[i]); + for(auto& tt: t1){ tt = v; v+=value_type{1}; } + + auto t2 = tensor_type(extents[i+1]); + for(auto& tt: t2){ tt = v; v+=value_type{2}; } + + BOOST_CHECK( ublas::detail::all_extents_equal( t1, ublas::detail::retrieve_extents(t1) ) ); + BOOST_CHECK( ublas::detail::all_extents_equal( t2, ublas::detail::retrieve_extents(t2) ) ); + + // uexpr1 = t1+1 + // uexpr2 = 2+t2 + auto uexpr1 = ublas::detail::make_unary_tensor_expression<tensor_type>( t1, uplus1 ); + auto uexpr2 = ublas::detail::make_unary_tensor_expression<tensor_type>( t2, uplus2 ); + + BOOST_CHECK( ublas::detail::all_extents_equal( uexpr1, ublas::detail::retrieve_extents(uexpr1) ) ); + BOOST_CHECK( ublas::detail::all_extents_equal( uexpr2, ublas::detail::retrieve_extents(uexpr2) ) ); + + // bexpr_uexpr = (t1+1) + (2+t2) + auto bexpr_uexpr = ublas::detail::make_binary_tensor_expression<tensor_type>( uexpr1, uexpr2, bplus ); + + BOOST_CHECK( ! ublas::detail::all_extents_equal( bexpr_uexpr, ublas::detail::retrieve_extents( bexpr_uexpr ) ) ); + + // bexpr_bexpr_uexpr = ((t1+1) + (2+t2)) - t2 + auto bexpr_bexpr_uexpr1 = ublas::detail::make_binary_tensor_expression<tensor_type>( bexpr_uexpr, t2, bminus ); + + BOOST_CHECK( ! ublas::detail::all_extents_equal( bexpr_bexpr_uexpr1, ublas::detail::retrieve_extents( bexpr_bexpr_uexpr1 ) ) ); + + // bexpr_bexpr_uexpr = t2 - ((t1+1) + (2+t2)) + auto bexpr_bexpr_uexpr2 = ublas::detail::make_binary_tensor_expression<tensor_type>( t2, bexpr_uexpr, bminus ); + + BOOST_CHECK( ! ublas::detail::all_extents_equal( bexpr_bexpr_uexpr2, ublas::detail::retrieve_extents( bexpr_bexpr_uexpr2 ) ) ); + + + // bexpr_uexpr2 = (t1+1) + t2 + auto bexpr_uexpr2 = ublas::detail::make_binary_tensor_expression<tensor_type>( uexpr1, t2, bplus ); + BOOST_CHECK( ! ublas::detail::all_extents_equal( bexpr_uexpr2, ublas::detail::retrieve_extents( bexpr_uexpr2 ) ) ); + + + // bexpr_uexpr2 = ((t1+1) + t2) + t1 + auto bexpr_bexpr_uexpr3 = ublas::detail::make_binary_tensor_expression<tensor_type>( bexpr_uexpr2, t1, bplus ); + BOOST_CHECK( ! ublas::detail::all_extents_equal( bexpr_bexpr_uexpr3, ublas::detail::retrieve_extents( bexpr_bexpr_uexpr3 ) ) ); + + // bexpr_uexpr2 = t1 + (((t1+1) + t2) + t1) + auto bexpr_bexpr_uexpr4 = ublas::detail::make_binary_tensor_expression<tensor_type>( t1, bexpr_bexpr_uexpr3, bplus ); + BOOST_CHECK( ! ublas::detail::all_extents_equal( bexpr_bexpr_uexpr4, ublas::detail::retrieve_extents( bexpr_bexpr_uexpr4 ) ) ); + + } +} diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_extents.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_extents.cpp new file mode 100644 index 000000000..9fbeee949 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_extents.cpp @@ -0,0 +1,449 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// 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) + +#include <boost/test/unit_test.hpp> +#include <boost/numeric/ublas/tensor/extents.hpp> +#include <vector> + +BOOST_AUTO_TEST_SUITE ( test_extents ) + + +//*boost::unit_test::label("extents") +//*boost::unit_test::label("constructor") + +BOOST_AUTO_TEST_CASE(test_extents_ctor) +{ + using namespace boost::numeric; + using extents = ublas::basic_extents<unsigned>; + + + auto e0 = extents{}; + BOOST_CHECK( e0.empty()); + BOOST_CHECK_EQUAL ( e0.size(),0); + + auto e1 = extents{1,1}; + BOOST_CHECK(!e1.empty()); + BOOST_CHECK_EQUAL ( e1.size(),2); + + auto e2 = extents{1,2}; + BOOST_CHECK(!e2.empty()); + BOOST_CHECK_EQUAL ( e2.size(),2); + + auto e3 = extents{2,1}; + BOOST_CHECK (!e3.empty()); + BOOST_CHECK_EQUAL ( e3.size(),2); + + auto e4 = extents{2,3}; + BOOST_CHECK(!e4.empty()); + BOOST_CHECK_EQUAL ( e4.size(),2); + + auto e5 = extents{2,3,1}; + BOOST_CHECK (!e5.empty()); + BOOST_CHECK_EQUAL ( e5.size(),3); + + auto e6 = extents{1,2,3}; // 6 + BOOST_CHECK(!e6.empty()); + BOOST_CHECK_EQUAL ( e6.size(),3); + + auto e7 = extents{4,2,3}; // 7 + BOOST_CHECK(!e7.empty()); + BOOST_CHECK_EQUAL ( e7.size(),3); + + BOOST_CHECK_THROW( extents({1,0}), std::length_error ); + BOOST_CHECK_THROW( extents({0} ), std::length_error ); + BOOST_CHECK_THROW( extents({3} ), std::length_error ); + BOOST_CHECK_THROW( extents({0,1}), std::length_error ); +} + + + + +struct fixture { + using extents_type = boost::numeric::ublas::basic_extents<unsigned>; + fixture() : extents{ + extents_type{}, // 0 + + extents_type{1,1}, // 1 + extents_type{1,2}, // 2 + extents_type{2,1}, // 3 + + extents_type{2,3}, // 4 + extents_type{2,3,1}, // 5 + extents_type{1,2,3}, // 6 + extents_type{1,1,2,3}, // 7 + extents_type{1,2,3,1,1}, // 8 + + extents_type{4,2,3}, // 9 + extents_type{4,2,1,3}, // 10 + extents_type{4,2,1,3,1}, // 11 + extents_type{1,4,2,1,3,1}, // 12 +} // 13 + {} + std::vector<extents_type> extents; +}; + +BOOST_FIXTURE_TEST_CASE(test_extents_access, fixture, *boost::unit_test::label("extents") *boost::unit_test::label("access")) +{ + using namespace boost::numeric; + + BOOST_REQUIRE_EQUAL(extents.size(),13); + + BOOST_CHECK_EQUAL (extents[ 0].size(), 0); + BOOST_CHECK (extents[ 0].empty() ); + + BOOST_REQUIRE_EQUAL(extents[ 1].size(), 2); + BOOST_REQUIRE_EQUAL(extents[ 2].size(), 2); + BOOST_REQUIRE_EQUAL(extents[ 3].size(), 2); + BOOST_REQUIRE_EQUAL(extents[ 4].size(), 2); + BOOST_REQUIRE_EQUAL(extents[ 5].size(), 3); + BOOST_REQUIRE_EQUAL(extents[ 6].size(), 3); + BOOST_REQUIRE_EQUAL(extents[ 7].size(), 4); + BOOST_REQUIRE_EQUAL(extents[ 8].size(), 5); + BOOST_REQUIRE_EQUAL(extents[ 9].size(), 3); + BOOST_REQUIRE_EQUAL(extents[10].size(), 4); + BOOST_REQUIRE_EQUAL(extents[11].size(), 5); + BOOST_REQUIRE_EQUAL(extents[12].size(), 6); + + + BOOST_CHECK_EQUAL(extents[1][0],1); + BOOST_CHECK_EQUAL(extents[1][1],1); + + BOOST_CHECK_EQUAL(extents[2][0],1); + BOOST_CHECK_EQUAL(extents[2][1],2); + + BOOST_CHECK_EQUAL(extents[3][0],2); + BOOST_CHECK_EQUAL(extents[3][1],1); + + BOOST_CHECK_EQUAL(extents[4][0],2); + BOOST_CHECK_EQUAL(extents[4][1],3); + + BOOST_CHECK_EQUAL(extents[5][0],2); + BOOST_CHECK_EQUAL(extents[5][1],3); + BOOST_CHECK_EQUAL(extents[5][2],1); + + BOOST_CHECK_EQUAL(extents[6][0],1); + BOOST_CHECK_EQUAL(extents[6][1],2); + BOOST_CHECK_EQUAL(extents[6][2],3); + + BOOST_CHECK_EQUAL(extents[7][0],1); + BOOST_CHECK_EQUAL(extents[7][1],1); + BOOST_CHECK_EQUAL(extents[7][2],2); + BOOST_CHECK_EQUAL(extents[7][3],3); + + BOOST_CHECK_EQUAL(extents[8][0],1); + BOOST_CHECK_EQUAL(extents[8][1],2); + BOOST_CHECK_EQUAL(extents[8][2],3); + BOOST_CHECK_EQUAL(extents[8][3],1); + BOOST_CHECK_EQUAL(extents[8][4],1); + + BOOST_CHECK_EQUAL(extents[9][0],4); + BOOST_CHECK_EQUAL(extents[9][1],2); + BOOST_CHECK_EQUAL(extents[9][2],3); + + BOOST_CHECK_EQUAL(extents[10][0],4); + BOOST_CHECK_EQUAL(extents[10][1],2); + BOOST_CHECK_EQUAL(extents[10][2],1); + BOOST_CHECK_EQUAL(extents[10][3],3); + + BOOST_CHECK_EQUAL(extents[11][0],4); + BOOST_CHECK_EQUAL(extents[11][1],2); + BOOST_CHECK_EQUAL(extents[11][2],1); + BOOST_CHECK_EQUAL(extents[11][3],3); + BOOST_CHECK_EQUAL(extents[11][4],1); + + BOOST_CHECK_EQUAL(extents[12][0],1); + BOOST_CHECK_EQUAL(extents[12][1],4); + BOOST_CHECK_EQUAL(extents[12][2],2); + BOOST_CHECK_EQUAL(extents[12][3],1); + BOOST_CHECK_EQUAL(extents[12][4],3); + BOOST_CHECK_EQUAL(extents[12][5],1); +} + +BOOST_FIXTURE_TEST_CASE(test_extents_copy_ctor, fixture, *boost::unit_test::label("extents") *boost::unit_test::label("copy_ctor")) +{ + BOOST_REQUIRE_EQUAL(extents.size(),13); + + auto e0 = extents[ 0]; // {} + auto e1 = extents[ 1]; // {1,1} + auto e2 = extents[ 2]; // {1,2} + auto e3 = extents[ 3]; // {2,1} + auto e4 = extents[ 4]; // {2,3} + auto e5 = extents[ 5]; // {2,3,1} + auto e6 = extents[ 6]; // {1,2,3} + auto e7 = extents[ 7]; // {1,1,2,3} + auto e8 = extents[ 8]; // {1,2,3,1,1} + auto e9 = extents[ 9]; // {4,2,3} + auto e10 = extents[10]; // {4,2,1,3} + auto e11 = extents[11]; // {4,2,1,3,1} + auto e12 = extents[12]; // {1,4,2,1,3,1} + + BOOST_CHECK_EQUAL (e0.size(), 0); + BOOST_CHECK (e0.empty() ); + + BOOST_REQUIRE_EQUAL(e1 .size(), 2); + BOOST_REQUIRE_EQUAL(e2 .size(), 2); + BOOST_REQUIRE_EQUAL(e3 .size(), 2); + BOOST_REQUIRE_EQUAL(e4 .size(), 2); + BOOST_REQUIRE_EQUAL(e5 .size(), 3); + BOOST_REQUIRE_EQUAL(e6 .size(), 3); + BOOST_REQUIRE_EQUAL(e7 .size(), 4); + BOOST_REQUIRE_EQUAL(e8 .size(), 5); + BOOST_REQUIRE_EQUAL(e9 .size(), 3); + BOOST_REQUIRE_EQUAL(e10.size(), 4); + BOOST_REQUIRE_EQUAL(e11.size(), 5); + BOOST_REQUIRE_EQUAL(e12.size(), 6); + + + BOOST_CHECK_EQUAL(e1[0],1); + BOOST_CHECK_EQUAL(e1[1],1); + + BOOST_CHECK_EQUAL(e2[0],1); + BOOST_CHECK_EQUAL(e2[1],2); + + BOOST_CHECK_EQUAL(e3[0],2); + BOOST_CHECK_EQUAL(e3[1],1); + + BOOST_CHECK_EQUAL(e4[0],2); + BOOST_CHECK_EQUAL(e4[1],3); + + BOOST_CHECK_EQUAL(e5[0],2); + BOOST_CHECK_EQUAL(e5[1],3); + BOOST_CHECK_EQUAL(e5[2],1); + + BOOST_CHECK_EQUAL(e6[0],1); + BOOST_CHECK_EQUAL(e6[1],2); + BOOST_CHECK_EQUAL(e6[2],3); + + BOOST_CHECK_EQUAL(e7[0],1); + BOOST_CHECK_EQUAL(e7[1],1); + BOOST_CHECK_EQUAL(e7[2],2); + BOOST_CHECK_EQUAL(e7[3],3); + + BOOST_CHECK_EQUAL(e8[0],1); + BOOST_CHECK_EQUAL(e8[1],2); + BOOST_CHECK_EQUAL(e8[2],3); + BOOST_CHECK_EQUAL(e8[3],1); + BOOST_CHECK_EQUAL(e8[4],1); + + BOOST_CHECK_EQUAL(e9[0],4); + BOOST_CHECK_EQUAL(e9[1],2); + BOOST_CHECK_EQUAL(e9[2],3); + + BOOST_CHECK_EQUAL(e10[0],4); + BOOST_CHECK_EQUAL(e10[1],2); + BOOST_CHECK_EQUAL(e10[2],1); + BOOST_CHECK_EQUAL(e10[3],3); + + BOOST_CHECK_EQUAL(e11[0],4); + BOOST_CHECK_EQUAL(e11[1],2); + BOOST_CHECK_EQUAL(e11[2],1); + BOOST_CHECK_EQUAL(e11[3],3); + BOOST_CHECK_EQUAL(e11[4],1); + + BOOST_CHECK_EQUAL(e12[0],1); + BOOST_CHECK_EQUAL(e12[1],4); + BOOST_CHECK_EQUAL(e12[2],2); + BOOST_CHECK_EQUAL(e12[3],1); + BOOST_CHECK_EQUAL(e12[4],3); + BOOST_CHECK_EQUAL(e12[5],1); + +} + +BOOST_FIXTURE_TEST_CASE(test_extents_is, fixture, *boost::unit_test::label("extents") *boost::unit_test::label("query")) +{ + BOOST_REQUIRE_EQUAL(extents.size(),13); + + auto e0 = extents[ 0]; // {} + auto e1 = extents[ 1]; // {1,1} + auto e2 = extents[ 2]; // {1,2} + auto e3 = extents[ 3]; // {2,1} + auto e4 = extents[ 4]; // {2,3} + auto e5 = extents[ 5]; // {2,3,1} + auto e6 = extents[ 6]; // {1,2,3} + auto e7 = extents[ 7]; // {1,1,2,3} + auto e8 = extents[ 8]; // {1,2,3,1,1} + auto e9 = extents[ 9]; // {4,2,3} + auto e10 = extents[10]; // {4,2,1,3} + auto e11 = extents[11]; // {4,2,1,3,1} + auto e12 = extents[12]; // {1,4,2,1,3,1} + + BOOST_CHECK( e0.empty ()); + BOOST_CHECK( ! e0.is_scalar()); + BOOST_CHECK( ! e0.is_vector()); + BOOST_CHECK( ! e0.is_matrix()); + BOOST_CHECK( ! e0.is_tensor()); + + BOOST_CHECK( ! e1.empty () ); + BOOST_CHECK( e1.is_scalar() ); + BOOST_CHECK( ! e1.is_vector() ); + BOOST_CHECK( ! e1.is_matrix() ); + BOOST_CHECK( ! e1.is_tensor() ); + + BOOST_CHECK( ! e2.empty () ); + BOOST_CHECK( ! e2.is_scalar() ); + BOOST_CHECK( e2.is_vector() ); + BOOST_CHECK( ! e2.is_matrix() ); + BOOST_CHECK( ! e2.is_tensor() ); + + BOOST_CHECK( ! e3.empty () ); + BOOST_CHECK( ! e3.is_scalar() ); + BOOST_CHECK( e3.is_vector() ); + BOOST_CHECK( ! e3.is_matrix() ); + BOOST_CHECK( ! e3.is_tensor() ); + + BOOST_CHECK( ! e4.empty () ); + BOOST_CHECK( ! e4.is_scalar() ); + BOOST_CHECK( ! e4.is_vector() ); + BOOST_CHECK( e4.is_matrix() ); + BOOST_CHECK( ! e4.is_tensor() ); + + BOOST_CHECK( ! e5.empty () ); + BOOST_CHECK( ! e5.is_scalar() ); + BOOST_CHECK( ! e5.is_vector() ); + BOOST_CHECK( e5.is_matrix() ); + BOOST_CHECK( ! e5.is_tensor() ); + + BOOST_CHECK( ! e6.empty () ); + BOOST_CHECK( ! e6.is_scalar() ); + BOOST_CHECK( ! e6.is_vector() ); + BOOST_CHECK( ! e6.is_matrix() ); + BOOST_CHECK( e6.is_tensor() ); + + BOOST_CHECK( ! e7.empty () ); + BOOST_CHECK( ! e7.is_scalar() ); + BOOST_CHECK( ! e7.is_vector() ); + BOOST_CHECK( ! e7.is_matrix() ); + BOOST_CHECK( e7.is_tensor() ); + + BOOST_CHECK( ! e8.empty () ); + BOOST_CHECK( ! e8.is_scalar() ); + BOOST_CHECK( ! e8.is_vector() ); + BOOST_CHECK( ! e8.is_matrix() ); + BOOST_CHECK( e8.is_tensor() ); + + BOOST_CHECK( ! e9.empty () ); + BOOST_CHECK( ! e9.is_scalar() ); + BOOST_CHECK( ! e9.is_vector() ); + BOOST_CHECK( ! e9.is_matrix() ); + BOOST_CHECK( e9.is_tensor() ); + + BOOST_CHECK( ! e10.empty () ); + BOOST_CHECK( ! e10.is_scalar() ); + BOOST_CHECK( ! e10.is_vector() ); + BOOST_CHECK( ! e10.is_matrix() ); + BOOST_CHECK( e10.is_tensor() ); + + BOOST_CHECK( ! e11.empty () ); + BOOST_CHECK( ! e11.is_scalar() ); + BOOST_CHECK( ! e11.is_vector() ); + BOOST_CHECK( ! e11.is_matrix() ); + BOOST_CHECK( e11.is_tensor() ); + + BOOST_CHECK( ! e12.empty () ); + BOOST_CHECK( ! e12.is_scalar() ); + BOOST_CHECK( ! e12.is_vector() ); + BOOST_CHECK( ! e12.is_matrix() ); + BOOST_CHECK( e12.is_tensor() ); +} + + +BOOST_FIXTURE_TEST_CASE(test_extents_squeeze, fixture, *boost::unit_test::label("extents") *boost::unit_test::label("squeeze")) +{ + BOOST_REQUIRE_EQUAL(extents.size(),13); + + auto e0 = extents[ 0].squeeze(); // {} + auto e1 = extents[ 1].squeeze(); // {1,1} + auto e2 = extents[ 2].squeeze(); // {1,2} + auto e3 = extents[ 3].squeeze(); // {2,1} + + auto e4 = extents[ 4].squeeze(); // {2,3} + auto e5 = extents[ 5].squeeze(); // {2,3} + auto e6 = extents[ 6].squeeze(); // {2,3} + auto e7 = extents[ 7].squeeze(); // {2,3} + auto e8 = extents[ 8].squeeze(); // {2,3} + + auto e9 = extents[ 9].squeeze(); // {4,2,3} + auto e10 = extents[10].squeeze(); // {4,2,3} + auto e11 = extents[11].squeeze(); // {4,2,3} + auto e12 = extents[12].squeeze(); // {4,2,3} + + BOOST_CHECK( (e0 == extents_type{} ) ); + BOOST_CHECK( (e1 == extents_type{1,1}) ); + BOOST_CHECK( (e2 == extents_type{1,2}) ); + BOOST_CHECK( (e3 == extents_type{2,1}) ); + + BOOST_CHECK( (e4 == extents_type{2,3}) ); + BOOST_CHECK( (e5 == extents_type{2,3}) ); + BOOST_CHECK( (e6 == extents_type{2,3}) ); + BOOST_CHECK( (e7 == extents_type{2,3}) ); + BOOST_CHECK( (e8 == extents_type{2,3}) ); + + BOOST_CHECK( (e9 == extents_type{4,2,3}) ); + BOOST_CHECK( (e10 == extents_type{4,2,3}) ); + BOOST_CHECK( (e11 == extents_type{4,2,3}) ); + BOOST_CHECK( (e12 == extents_type{4,2,3}) ); + +} + + +BOOST_FIXTURE_TEST_CASE(test_extents_valid, fixture, *boost::unit_test::label("extents") *boost::unit_test::label("valid")) +{ + + using namespace boost::numeric; + + BOOST_REQUIRE_EQUAL(extents.size(),13); + + for(auto const& e : extents){ + if(e.empty()) + BOOST_CHECK_EQUAL(e.valid(),false); + else + BOOST_CHECK_EQUAL(e.valid(), true ); + } + + BOOST_CHECK_EQUAL( extents_type{}.valid() , false ); + + BOOST_CHECK_THROW( ublas::basic_extents<unsigned>({0,1}), std::length_error ); + BOOST_CHECK_THROW( ublas::basic_extents<unsigned>({1,0,1}), std::length_error ); + +} + + +BOOST_FIXTURE_TEST_CASE(test_extents_product, fixture, *boost::unit_test::label("extents") *boost::unit_test::label("product")) +{ + + auto e0 = extents[ 0].product(); // {} + auto e1 = extents[ 1].product(); // {1,1} + auto e2 = extents[ 2].product(); // {1,2} + auto e3 = extents[ 3].product(); // {2,1} + auto e4 = extents[ 4].product(); // {2,3} + auto e5 = extents[ 5].product(); // {2,3,1} + auto e6 = extents[ 6].product(); // {1,2,3} + auto e7 = extents[ 7].product(); // {1,1,2,3} + auto e8 = extents[ 8].product(); // {1,2,3,1,1} + auto e9 = extents[ 9].product(); // {4,2,3} + auto e10 = extents[10].product(); // {4,2,1,3} + auto e11 = extents[11].product(); // {4,2,1,3,1} + auto e12 = extents[12].product(); // {1,4,2,1,3,1} + + BOOST_CHECK_EQUAL( e0 , 0 ); + BOOST_CHECK_EQUAL( e1 , 1 ); + BOOST_CHECK_EQUAL( e2 , 2 ); + BOOST_CHECK_EQUAL( e3 , 2 ); + BOOST_CHECK_EQUAL( e4 , 6 ); + BOOST_CHECK_EQUAL( e5 , 6 ); + BOOST_CHECK_EQUAL( e6 , 6 ); + BOOST_CHECK_EQUAL( e7 , 6 ); + BOOST_CHECK_EQUAL( e8 , 6 ); + BOOST_CHECK_EQUAL( e9 , 24 ); + BOOST_CHECK_EQUAL( e10, 24 ); + BOOST_CHECK_EQUAL( e11, 24 ); + BOOST_CHECK_EQUAL( e12, 24 ); + + +} + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_functions.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_functions.cpp new file mode 100644 index 000000000..64ecda396 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_functions.cpp @@ -0,0 +1,453 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// 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) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// +// And we acknowledge the support from all contributors. + + +#include <iostream> +#include <algorithm> +#include <boost/numeric/ublas/tensor.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/vector.hpp> + +#include <boost/test/unit_test.hpp> + +#include "utility.hpp" + +BOOST_AUTO_TEST_SUITE ( test_tensor_functions, * boost::unit_test::depends_on("test_tensor_contraction") ) + + +using test_types = zip<int,long,float,double,std::complex<float>>::with_t<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>; + +//using test_types = zip<int>::with_t<boost::numeric::ublas::first_order>; + + +struct fixture +{ + using extents_type = boost::numeric::ublas::shape; + fixture() + : extents { + extents_type{1,1}, // 1 + extents_type{1,2}, // 2 + extents_type{2,1}, // 3 + extents_type{2,3}, // 4 + extents_type{2,3,1}, // 5 + extents_type{4,1,3}, // 6 + extents_type{1,2,3}, // 7 + extents_type{4,2,3}, // 8 + extents_type{4,2,3,5}} // 9 + { + } + std::vector<extents_type> extents; +}; + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_prod_vector, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type,layout_type>; + using vector_type = typename tensor_type::vector_type; + + + for(auto const& n : extents){ + + auto a = tensor_type(n, value_type{2}); + + for(auto m = 0u; m < n.size(); ++m){ + + auto b = vector_type (n[m], value_type{1} ); + + auto c = ublas::prod(a, b, m+1); + + for(auto i = 0u; i < c.size(); ++i) + BOOST_CHECK_EQUAL( c[i] , value_type(n[m]) * a[i] ); + + } + } +} + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_prod_matrix, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type,layout_type>; + using matrix_type = typename tensor_type::matrix_type; + + + for(auto const& n : extents) { + + auto a = tensor_type(n, value_type{2}); + + for(auto m = 0u; m < n.size(); ++m){ + + auto b = matrix_type ( n[m], n[m], value_type{1} ); + + auto c = ublas::prod(a, b, m+1); + + for(auto i = 0u; i < c.size(); ++i) + BOOST_CHECK_EQUAL( c[i] , value_type(n[m]) * a[i] ); + + } + } +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_prod_tensor_1, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type,layout_type>; + + // left-hand and right-hand side have the + // the same number of elements + + for(auto const& na : extents) { + + auto a = tensor_type( na, value_type{2} ); + auto b = tensor_type( na, value_type{3} ); + + auto const pa = a.rank(); + + // the number of contractions is changed. + for( auto q = 0ul; q <= pa; ++q) { // pa + + auto phi = std::vector<std::size_t> ( q ); + + std::iota(phi.begin(), phi.end(), 1ul); + + auto c = ublas::prod(a, b, phi); + + auto acc = value_type(1); + for(auto i = 0ul; i < q; ++i) + acc *= a.extents().at(phi.at(i)-1); + + for(auto i = 0ul; i < c.size(); ++i) + BOOST_CHECK_EQUAL( c[i] , acc * a[0] * b[0] ); + + } + } +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_prod_tensor_2, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type,layout_type>; + + + auto compute_factorial = [](auto const& p){ + auto f = 1ul; + for(auto i = 1u; i <= p; ++i) + f *= i; + return f; + }; + + auto permute_extents = [](auto const& pi, auto const& na){ + auto nb = na; + assert(pi.size() == na.size()); + for(auto j = 0u; j < pi.size(); ++j) + nb[pi[j]-1] = na[j]; + return nb; + }; + + + // left-hand and right-hand side have the + // the same number of elements + + for(auto const& na : extents) { + + auto a = tensor_type( na, value_type{2} ); + auto const pa = a.rank(); + + + auto pi = std::vector<std::size_t>(pa); + auto fac = compute_factorial(pa); + std::iota( pi.begin(), pi.end(), 1 ); + + for(auto f = 0ul; f < fac; ++f) + { + auto nb = permute_extents( pi, na ); + auto b = tensor_type( nb, value_type{3} ); + + // the number of contractions is changed. + for( auto q = 0ul; q <= pa; ++q) { // pa + + auto phia = std::vector<std::size_t> ( q ); // concatenation for a + auto phib = std::vector<std::size_t> ( q ); // concatenation for b + + std::iota(phia.begin(), phia.end(), 1ul); + std::transform( phia.begin(), phia.end(), phib.begin(), + [&pi] ( std::size_t i ) { return pi.at(i-1); } ); + + auto c = ublas::prod(a, b, phia, phib); + + auto acc = value_type(1); + for(auto i = 0ul; i < q; ++i) + acc *= a.extents().at(phia.at(i)-1); + + for(auto i = 0ul; i < c.size(); ++i) + BOOST_CHECK_EQUAL( c[i] , acc * a[0] * b[0] ); + + } + + std::next_permutation(pi.begin(), pi.end()); + } + } +} + + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_inner_prod, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type,layout_type>; + + + for(auto const& n : extents) { + + auto a = tensor_type(n, value_type(2)); + auto b = tensor_type(n, value_type(1)); + + auto c = ublas::inner_prod(a, b); + auto r = std::inner_product(a.begin(),a.end(), b.begin(),value_type(0)); + + BOOST_CHECK_EQUAL( c , r ); + + } +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_norm, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type,layout_type>; + + + for(auto const& n : extents) { + + auto a = tensor_type(n); + + auto one = value_type(1); + auto v = one; + for(auto& aa: a) + aa = v, v += one; + + + auto c = ublas::inner_prod(a, a); + auto r = std::inner_product(a.begin(),a.end(), a.begin(),value_type(0)); + + auto r2 = ublas::norm( (a+a) / 2 ); + + BOOST_CHECK_EQUAL( c , r ); + BOOST_CHECK_EQUAL( std::sqrt( c ) , r2 ); + + } +} + + +BOOST_FIXTURE_TEST_CASE( test_tensor_real_imag_conj, fixture ) +{ + using namespace boost::numeric; + using value_type = float; + using complex_type = std::complex<value_type>; + using layout_type = ublas::first_order; + + using tensor_complex_type = ublas::tensor<complex_type,layout_type>; + using tensor_type = ublas::tensor<value_type,layout_type>; + + for(auto const& n : extents) { + + auto a = tensor_type(n); + auto r0 = tensor_type(n); + auto r00 = tensor_complex_type(n); + + + auto one = value_type(1); + auto v = one; + for(auto& aa: a) + aa = v, v += one; + + tensor_type b = (a+a) / value_type( 2 ); + tensor_type r1 = ublas::real( (a+a) / value_type( 2 ) ); + std::transform( b.begin(), b.end(), r0.begin(), [](auto const& l){ return std::real( l ); } ); + BOOST_CHECK( r0 == r1 ); + + tensor_type r2 = ublas::imag( (a+a) / value_type( 2 ) ); + std::transform( b.begin(), b.end(), r0.begin(), [](auto const& l){ return std::imag( l ); } ); + BOOST_CHECK( r0 == r2 ); + + tensor_complex_type r3 = ublas::conj( (a+a) / value_type( 2 ) ); + std::transform( b.begin(), b.end(), r00.begin(), [](auto const& l){ return std::conj( l ); } ); + BOOST_CHECK( r00 == r3 ); + + } + + for(auto const& n : extents) { + + + + + auto a = tensor_complex_type(n); + + auto r00 = tensor_complex_type(n); + auto r0 = tensor_type(n); + + + auto one = complex_type(1,1); + auto v = one; + for(auto& aa: a) + aa = v, v = v + one; + + tensor_complex_type b = (a+a) / complex_type( 2,2 ); + + + tensor_type r1 = ublas::real( (a+a) / complex_type( 2,2 ) ); + std::transform( b.begin(), b.end(), r0.begin(), [](auto const& l){ return std::real( l ); } ); + BOOST_CHECK( r0 == r1 ); + + tensor_type r2 = ublas::imag( (a+a) / complex_type( 2,2 ) ); + std::transform( b.begin(), b.end(), r0.begin(), [](auto const& l){ return std::imag( l ); } ); + BOOST_CHECK( r0 == r2 ); + + tensor_complex_type r3 = ublas::conj( (a+a) / complex_type( 2,2 ) ); + std::transform( b.begin(), b.end(), r00.begin(), [](auto const& l){ return std::conj( l ); } ); + BOOST_CHECK( r00 == r3 ); + + + + } + + + +} + + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_outer_prod, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type,layout_type>; + + for(auto const& n1 : extents) { + auto a = tensor_type(n1, value_type(2)); + for(auto const& n2 : extents) { + + auto b = tensor_type(n2, value_type(1)); + auto c = ublas::outer_prod(a, b); + + for(auto const& cc : c) + BOOST_CHECK_EQUAL( cc , a[0]*b[0] ); + } + } +} + + + +template<class V> +void init(std::vector<V>& a) +{ + auto v = V(1); + for(auto i = 0u; i < a.size(); ++i, ++v){ + a[i] = v; + } +} + +template<class V> +void init(std::vector<std::complex<V>>& a) +{ + auto v = std::complex<V>(1,1); + for(auto i = 0u; i < a.size(); ++i){ + a[i] = v; + v.real(v.real()+1); + v.imag(v.imag()+1); + } +} + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_trans, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type,layout_type>; + + auto fak = [](auto const& p){ + auto f = 1ul; + for(auto i = 1u; i <= p; ++i) + f *= i; + return f; + }; + + auto inverse = [](auto const& pi){ + auto pi_inv = pi; + for(auto j = 0u; j < pi.size(); ++j) + pi_inv[pi[j]-1] = j+1; + return pi_inv; + }; + + for(auto const& n : extents) + { + auto const p = n.size(); + auto const s = n.product(); + auto aref = tensor_type(n); + auto v = value_type{}; + for(auto i = 0u; i < s; ++i, v+=1) + aref[i] = v; + auto a = aref; + + + auto pi = std::vector<std::size_t>(p); + std::iota(pi.begin(), pi.end(), 1); + a = ublas::trans( a, pi ); + BOOST_CHECK( a == aref ); + + + auto const pfak = fak(p); + auto i = 0u; + for(; i < pfak-1; ++i) { + std::next_permutation(pi.begin(), pi.end()); + a = ublas::trans( a, pi ); + } + std::next_permutation(pi.begin(), pi.end()); + for(; i > 0; --i) { + std::prev_permutation(pi.begin(), pi.end()); + auto pi_inv = inverse(pi); + a = ublas::trans( a, pi_inv ); + } + + BOOST_CHECK( a == aref ); + + } +} + + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_multi_index.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_multi_index.cpp new file mode 100644 index 000000000..d6448de22 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_multi_index.cpp @@ -0,0 +1,146 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// 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) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// + +#include <iostream> +#include <algorithm> +#include <complex> +#include <boost/numeric/ublas/tensor.hpp> +#include <boost/numeric/ublas/tensor/multi_index.hpp> + + +#include <boost/test/unit_test.hpp> + +#include "utility.hpp" + + +BOOST_AUTO_TEST_SUITE ( test_multi_index ) + + +using test_types = zip<int,long,float,double,std::complex<float>>::with_t<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>; + + +BOOST_AUTO_TEST_CASE ( test_index_classes ) +{ + using namespace boost::numeric::ublas::index; + + + BOOST_CHECK_EQUAL ( _a.value , 1 ) ; + BOOST_CHECK_EQUAL ( _b.value , 2 ) ; + BOOST_CHECK_EQUAL ( _c.value , 3 ) ; + BOOST_CHECK_EQUAL ( _d.value , 4 ) ; + BOOST_CHECK_EQUAL ( _e.value , 5 ) ; + BOOST_CHECK_EQUAL ( _f.value , 6 ) ; + BOOST_CHECK_EQUAL ( _g.value , 7 ) ; + BOOST_CHECK_EQUAL ( _h.value , 8 ) ; + BOOST_CHECK_EQUAL ( _i.value , 9 ) ; + BOOST_CHECK_EQUAL ( _j.value , 10 ) ; + BOOST_CHECK_EQUAL ( _k.value , 11 ) ; + BOOST_CHECK_EQUAL ( _l.value , 12 ) ; + BOOST_CHECK_EQUAL ( _m.value , 13 ) ; + BOOST_CHECK_EQUAL ( _n.value , 14 ) ; + BOOST_CHECK_EQUAL ( _o.value , 15 ) ; + BOOST_CHECK_EQUAL ( _p.value , 16 ) ; + BOOST_CHECK_EQUAL ( _q.value , 17 ) ; + BOOST_CHECK_EQUAL ( _r.value , 18 ) ; + BOOST_CHECK_EQUAL ( _s.value , 19 ) ; + BOOST_CHECK_EQUAL ( _t.value , 20 ) ; + BOOST_CHECK_EQUAL ( _u.value , 21 ) ; + BOOST_CHECK_EQUAL ( _v.value , 22 ) ; + BOOST_CHECK_EQUAL ( _w.value , 23 ) ; + BOOST_CHECK_EQUAL ( _x.value , 24 ) ; + BOOST_CHECK_EQUAL ( _y.value , 25 ) ; + BOOST_CHECK_EQUAL ( _z.value , 26 ) ; + +} + +BOOST_AUTO_TEST_CASE ( test_multi_index_class_construction ) +{ + using namespace boost::numeric::ublas; + using namespace boost::numeric::ublas::index; + + + { + multi_index<2> ind(_a, _b); + + BOOST_CHECK_EQUAL ( get<0>( ind ), 1 ) ; + BOOST_CHECK_EQUAL ( get<1>( ind ), 2 ) ; + } + + + { + multi_index<2> ind(_d,_c); + + BOOST_CHECK_EQUAL ( ind[0] , 4 ) ; + BOOST_CHECK_EQUAL ( ind[1] , 3 ) ; + } +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_tensor_multi_index_class_generation, value, test_types ) +{ + using namespace boost::numeric::ublas; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = tensor<value_type,layout_type>; + + auto t = std::make_tuple ( + index::_a, // 0 + index::_b, // 1 + index::_c, // 2 + index::_d, // 3 + index::_e // 4 + ); + + { + auto a = tensor_type(shape{2,3}, value_type{2}); + auto a_ind = a( std::get<0>(t), std::get<2>(t) ); + + BOOST_CHECK_EQUAL ( std::addressof( a_ind.first ), std::addressof( a ) ) ; + + BOOST_CHECK_EQUAL (std::get<0>(a_ind.second)(), index::_a() ) ; + BOOST_CHECK_EQUAL (std::get<1>(a_ind.second)(), index::_c() ) ; + } + + { + auto a = tensor_type(shape{2,3}, value_type{2}); + auto a_ind = a( std::get<2>(t), std::get<0>(t) ); + + BOOST_CHECK_EQUAL ( std::addressof( a_ind.first ), std::addressof( a ) ) ; + + BOOST_CHECK_EQUAL (std::get<0>(a_ind.second)(), index::_c() ) ; + BOOST_CHECK_EQUAL (std::get<1>(a_ind.second)(), index::_a() ) ; + } + + { + auto a = tensor_type(shape{2,3}, value_type{2}); + auto a_ind = a( std::get<2>(t), std::get<3>(t) ); + + BOOST_CHECK_EQUAL (std::addressof( a_ind.first ), std::addressof( a ) ) ; + + BOOST_CHECK_EQUAL (std::get<0>(a_ind.second)(), index::_c() ) ; + BOOST_CHECK_EQUAL (std::get<1>(a_ind.second)(), index::_d() ) ; + } + + { + auto a = tensor_type(shape{2,3,4}, value_type{2}); + auto a_ind = a( std::get<2>(t), std::get<3>(t), std::get<0>(t) ); + + BOOST_CHECK_EQUAL (std::addressof( a_ind.first ), std::addressof( a ) ) ; + + BOOST_CHECK_EQUAL (std::get<0>(a_ind.second)(), index::_c() ) ; + BOOST_CHECK_EQUAL (std::get<1>(a_ind.second)(), index::_d() ) ; + BOOST_CHECK_EQUAL (std::get<2>(a_ind.second)(), index::_a() ) ; + } + +} + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_multi_index_utility.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_multi_index_utility.cpp new file mode 100644 index 000000000..2f31a58f2 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_multi_index_utility.cpp @@ -0,0 +1,564 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// 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) +// +// The author gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// + + +#include <boost/numeric/ublas/tensor.hpp> + +#include <boost/test/unit_test.hpp> + +BOOST_AUTO_TEST_SUITE ( test_multi_index_utility ) + + +BOOST_AUTO_TEST_CASE ( test_multi_index_has_index ) +{ + using namespace boost::numeric::ublas; + using namespace boost::numeric::ublas::index; + + { + constexpr auto tuple = std::tuple<>{}; + constexpr auto has_a = has_index<decltype(_a),decltype(tuple)>::value; + constexpr auto has_b = has_index<decltype(_b),decltype(tuple)>::value; + BOOST_CHECK( !has_a ); + BOOST_CHECK( !has_b ); + } + + + { + constexpr auto tuple = std::make_tuple(_a); + constexpr auto has_a = has_index<decltype(_a),decltype(tuple)>::value; + constexpr auto has_b = has_index<decltype(_b),decltype(tuple)>::value; + BOOST_CHECK( has_a ); + BOOST_CHECK( !has_b ); + } + + { + constexpr auto tuple = std::make_tuple(_a,_b,_,_c,_d); + constexpr auto has_a = has_index<decltype(_a),decltype(tuple)>::value; + constexpr auto has_b = has_index<decltype(_b),decltype(tuple)>::value; + constexpr auto has_c = has_index<decltype(_c),decltype(tuple)>::value; + constexpr auto has_d = has_index<decltype(_d),decltype(tuple)>::value; + constexpr auto has_e = has_index<decltype(_e),decltype(tuple)>::value; + constexpr auto has__ = has_index<decltype( _),decltype(tuple)>::value; + BOOST_CHECK( has_a ); + BOOST_CHECK( has_b ); + BOOST_CHECK( has_c ); + BOOST_CHECK( has_d ); + BOOST_CHECK( !has_e ); + BOOST_CHECK( has__ ); + } +} + + + +BOOST_AUTO_TEST_CASE ( test_multi_index_valid ) +{ + using namespace boost::numeric::ublas; + using namespace boost::numeric::ublas::index; + + { + constexpr auto tuple = std::tuple<>{}; + constexpr auto valid = valid_multi_index<decltype(tuple)>::value; + BOOST_CHECK( valid ); + } + + + { + constexpr auto tuple = std::make_tuple(_a); + constexpr auto valid = valid_multi_index<decltype(tuple)>::value; + BOOST_CHECK( valid ); + } + + { + constexpr auto tuple = std::make_tuple(_a,_,_b); + constexpr auto valid = valid_multi_index<decltype(tuple)>::value; + BOOST_CHECK( valid ); + } + + { + constexpr auto tuple = std::make_tuple(_a,_,_b,_b); + constexpr auto valid = valid_multi_index<decltype(tuple)>::value; + BOOST_CHECK( !valid ); + } + + { + constexpr auto tuple = std::make_tuple(_c,_a,_,_b,_b); + constexpr auto valid = valid_multi_index<decltype(tuple)>::value; + BOOST_CHECK( !valid ); + } + + { + constexpr auto tuple = std::make_tuple(_c,_a,_,_b); + constexpr auto valid = valid_multi_index<decltype(tuple)>::value; + BOOST_CHECK( valid ); + } + + { + constexpr auto tuple = std::make_tuple(_,_c,_a,_,_b); + constexpr auto valid = valid_multi_index<decltype(tuple)>::value; + BOOST_CHECK( valid ); + } + + { + constexpr auto tuple = std::make_tuple(_,_c,_a,_,_b,_); + constexpr auto valid = valid_multi_index<decltype(tuple)>::value; + BOOST_CHECK( valid ); + } +} + + + + + +BOOST_AUTO_TEST_CASE ( test_multi_index_number_equal_indices ) +{ + using namespace boost::numeric::ublas; + using namespace boost::numeric::ublas::index; + + { + constexpr auto lhs = std::tuple<>{}; + constexpr auto rhs = std::tuple<>{}; + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 0 ); + } + + { + constexpr auto lhs = std::make_tuple(_a); + constexpr auto rhs = std::tuple<>{}; + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 0 ); + } + + { + constexpr auto lhs = std::tuple<>{}; + constexpr auto rhs = std::make_tuple(_a); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 0 ); + } + + { + constexpr auto lhs = std::make_tuple(_b); + constexpr auto rhs = std::make_tuple(_a); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 0 ); + } + + + + { + constexpr auto lhs = std::make_tuple(_a); + constexpr auto rhs = std::make_tuple(_a); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 1 ); + } + + { + constexpr auto lhs = std::make_tuple(_a,_b); + constexpr auto rhs = std::make_tuple(_a); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 1 ); + } + + { + constexpr auto lhs = std::make_tuple(_b); + constexpr auto rhs = std::make_tuple(_a,_b); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 1 ); + } + + { + constexpr auto lhs = std::make_tuple(_a); + constexpr auto rhs = std::make_tuple(_a); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 1 ); + } + + + + { + constexpr auto lhs = std::make_tuple(_a,_b); + constexpr auto rhs = std::make_tuple(_a,_b); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 2 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a); + constexpr auto rhs = std::make_tuple(_a,_b); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 2 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a,_c); + constexpr auto rhs = std::make_tuple(_a,_b); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 2 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a,_c); + constexpr auto rhs = std::make_tuple(_a,_b,_d); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 2 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a,_d); + constexpr auto rhs = std::make_tuple(_a,_b,_d); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 3 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a,_d); + constexpr auto rhs = std::make_tuple(_a,_b,_d,_); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 3 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a,_d,_); + constexpr auto rhs = std::make_tuple(_a,_b,_d,_); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 3 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a,_d,_); + constexpr auto rhs = std::make_tuple( _,_b,_d,_); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 2 ); + } + + { + constexpr auto lhs = std::make_tuple(_,_a,_d,_); + constexpr auto rhs = std::make_tuple(_,_b,_d,_); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 1 ); + } + + { + constexpr auto lhs = std::make_tuple(_,_a,_d,_); + constexpr auto rhs = std::make_tuple(_,_b,_d,_,_); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 1 ); + } +} + + + + + + + +BOOST_AUTO_TEST_CASE ( test_multi_index_index_position ) +{ + using namespace boost::numeric::ublas; + using namespace boost::numeric::ublas::index; + + { + constexpr auto tuple = std::tuple<>{}; + constexpr auto ind = index_position<decltype(_),decltype(tuple)>::value; + BOOST_CHECK_EQUAL(ind,0); + } + + { + constexpr auto tuple = std::make_tuple(_); + constexpr auto ind = index_position<decltype(_),decltype(tuple)>::value; + BOOST_CHECK_EQUAL(ind,0); + } + + { + constexpr auto tuple = std::make_tuple(_); + constexpr auto ind = index_position<decltype(_a),decltype(tuple)>::value; + BOOST_CHECK_EQUAL(ind,1); + } + + { + constexpr auto tuple = std::make_tuple(_,_a); + constexpr auto ind = index_position<decltype(_),decltype(tuple)>::value; + BOOST_CHECK_EQUAL(ind,0); + } + + { + constexpr auto tuple = std::make_tuple(_,_a); + constexpr auto ind = index_position<decltype(_a),decltype(tuple)>::value; + BOOST_CHECK_EQUAL(ind,1); + } + + { + constexpr auto tuple = std::make_tuple(_,_a); + constexpr auto ind = index_position<decltype(_b),decltype(tuple)>::value; + BOOST_CHECK_EQUAL(ind,2); + } + + + + + { + constexpr auto tuple = std::make_tuple(_c,_,_a); + constexpr auto ind = index_position<decltype(_c),decltype(tuple)>::value; + BOOST_CHECK_EQUAL(ind,0); + } + + { + constexpr auto tuple = std::make_tuple(_c,_,_a,_); + constexpr auto ind = index_position<decltype(_),decltype(tuple)>::value; + BOOST_CHECK_EQUAL(ind,1); + } + + { + constexpr auto tuple = std::make_tuple(_c,_,_a); + constexpr auto ind = index_position<decltype(_a),decltype(tuple)>::value; + BOOST_CHECK_EQUAL(ind,2); + } + + { + constexpr auto tuple = std::make_tuple(_c,_,_a); + constexpr auto ind = index_position<decltype(_d),decltype(tuple)>::value; + BOOST_CHECK_EQUAL(ind,3); + } + +} + + + + + + + + +BOOST_AUTO_TEST_CASE ( test_multi_index_index_position_pairs ) +{ + using namespace boost::numeric::ublas; + using namespace boost::numeric::ublas::index; + + { + constexpr auto lhs = std::tuple<>{}; + constexpr auto rhs = std::tuple<>{}; + auto array = index_position_pairs(lhs, rhs); + BOOST_CHECK_EQUAL(array.size(), 0ul ); + } + + { + constexpr auto lhs = std::make_tuple(_a); + constexpr auto rhs = std::tuple<>{}; + auto array = index_position_pairs(lhs, rhs); + BOOST_CHECK_EQUAL(array.size(), 0ul ); + } + + { + constexpr auto lhs = std::tuple<>{}; + constexpr auto rhs = std::make_tuple(_a); + auto array = index_position_pairs(lhs, rhs); + BOOST_CHECK_EQUAL(array.size(), 0ul ); + } + + { + constexpr auto lhs = std::make_tuple(_b); + constexpr auto rhs = std::make_tuple(_a); + auto array = index_position_pairs(lhs, rhs); + BOOST_CHECK_EQUAL(array.size(), 0ul ); + } + + + + { + constexpr auto lhs = std::make_tuple(_a); + constexpr auto rhs = std::make_tuple(_a); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 1ul ); + BOOST_CHECK_EQUAL(array[0].first , 0 ); + BOOST_CHECK_EQUAL(array[0].second, 0 ); + } + + { + constexpr auto lhs = std::make_tuple(_a,_b); + constexpr auto rhs = std::make_tuple(_a); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 1ul ); + BOOST_CHECK_EQUAL(array[0].first , 0 ); + BOOST_CHECK_EQUAL(array[0].second, 0 ); + } + + { + constexpr auto lhs = std::make_tuple(_b); + constexpr auto rhs = std::make_tuple(_a,_b); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 1ul ); + BOOST_CHECK_EQUAL(array[0].first , 0 ); + BOOST_CHECK_EQUAL(array[0].second, 1 ); + } + + { + constexpr auto lhs = std::make_tuple(_a); + constexpr auto rhs = std::make_tuple(_a); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 1ul ); + BOOST_CHECK_EQUAL(array[0].first , 0 ); + BOOST_CHECK_EQUAL(array[0].second, 0 ); + } + + + + { + constexpr auto lhs = std::make_tuple(_a,_b); + constexpr auto rhs = std::make_tuple(_a,_b); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 2ul ); + BOOST_CHECK_EQUAL(array[0].first , 0 ); + BOOST_CHECK_EQUAL(array[0].second, 0 ); + BOOST_CHECK_EQUAL(array[1].first , 1 ); + BOOST_CHECK_EQUAL(array[1].second, 1 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a); + constexpr auto rhs = std::make_tuple(_a,_b); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 2ul ); + BOOST_CHECK_EQUAL(array[0].first , 0 ); + BOOST_CHECK_EQUAL(array[0].second, 1 ); + BOOST_CHECK_EQUAL(array[1].first , 1 ); + BOOST_CHECK_EQUAL(array[1].second, 0 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a,_c); + constexpr auto rhs = std::make_tuple(_a,_b); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 2ul ); + BOOST_CHECK_EQUAL(array[0].first , 0 ); + BOOST_CHECK_EQUAL(array[0].second, 1 ); + BOOST_CHECK_EQUAL(array[1].first , 1 ); + BOOST_CHECK_EQUAL(array[1].second, 0 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a,_c); + constexpr auto rhs = std::make_tuple(_a,_b,_d); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 2ul ); + BOOST_CHECK_EQUAL(array[0].first , 0 ); + BOOST_CHECK_EQUAL(array[0].second, 1 ); + BOOST_CHECK_EQUAL(array[1].first , 1 ); + BOOST_CHECK_EQUAL(array[1].second, 0 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a,_d); + constexpr auto rhs = std::make_tuple(_a,_b,_d); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 3ul ); + BOOST_CHECK_EQUAL(array[0].first , 0 ); + BOOST_CHECK_EQUAL(array[0].second, 1 ); + BOOST_CHECK_EQUAL(array[1].first , 1 ); + BOOST_CHECK_EQUAL(array[1].second, 0 ); + BOOST_CHECK_EQUAL(array[2].first , 2 ); + BOOST_CHECK_EQUAL(array[2].second, 2 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a,_d); + constexpr auto rhs = std::make_tuple(_a,_b,_d,_); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 3ul ); + BOOST_CHECK_EQUAL(array[0].first , 0 ); + BOOST_CHECK_EQUAL(array[0].second, 1 ); + BOOST_CHECK_EQUAL(array[1].first , 1 ); + BOOST_CHECK_EQUAL(array[1].second, 0 ); + BOOST_CHECK_EQUAL(array[2].first , 2 ); + BOOST_CHECK_EQUAL(array[2].second, 2 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a,_d,_); + constexpr auto rhs = std::make_tuple(_a,_b,_d,_); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 3ul ); + BOOST_CHECK_EQUAL(array[0].first , 0 ); + BOOST_CHECK_EQUAL(array[0].second, 1 ); + BOOST_CHECK_EQUAL(array[1].first , 1 ); + BOOST_CHECK_EQUAL(array[1].second, 0 ); + BOOST_CHECK_EQUAL(array[2].first , 2 ); + BOOST_CHECK_EQUAL(array[2].second, 2 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a,_d,_); + constexpr auto rhs = std::make_tuple( _,_b,_d,_); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 2ul ); + BOOST_CHECK_EQUAL(array[0].first , 0 ); + BOOST_CHECK_EQUAL(array[0].second, 1 ); + BOOST_CHECK_EQUAL(array[1].first , 2 ); + BOOST_CHECK_EQUAL(array[1].second, 2 ); + } + + { + constexpr auto lhs = std::make_tuple(_,_a,_d,_); + constexpr auto rhs = std::make_tuple(_,_b,_d,_); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 1ul ); + BOOST_CHECK_EQUAL(array[0].first , 2 ); + BOOST_CHECK_EQUAL(array[0].second, 2 ); + } + + { + constexpr auto lhs = std::make_tuple(_,_a,_d,_); + constexpr auto rhs = std::make_tuple(_,_b,_d,_,_); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 1ul ); + BOOST_CHECK_EQUAL(array[0].first , 2 ); + BOOST_CHECK_EQUAL(array[0].second, 2 ); + } +} + + + +BOOST_AUTO_TEST_CASE ( test_multi_index_array_to_vector ) +{ + using namespace boost::numeric::ublas; + using namespace boost::numeric::ublas::index; + + auto check = [](auto const& lhs, auto const& rhs) + { + auto array = index_position_pairs(lhs, rhs); + + auto vector_pair = array_to_vector( array ); + + BOOST_CHECK_EQUAL(vector_pair.first .size(), array.size() ); + BOOST_CHECK_EQUAL(vector_pair.second.size(), array.size() ); + + for(auto i = 0ul; i < array.size(); ++i) + { + BOOST_CHECK_EQUAL(vector_pair.first [i], array[i].first +1 ); + BOOST_CHECK_EQUAL(vector_pair.second[i], array[i].second+1 ); + } + + }; + + check(std::tuple<>{} , std::tuple<>{}); + check(std::make_tuple(_a) , std::tuple<>{}); + check(std::tuple<>{} , std::make_tuple(_a)); + check(std::make_tuple(_a) , std::make_tuple(_b)); + check(std::make_tuple(_a) , std::make_tuple(_a)); + check(std::make_tuple(_a,_b), std::make_tuple(_a)); + check(std::make_tuple(_a) , std::make_tuple(_a,_b)); + check(std::make_tuple(_a,_b), std::make_tuple(_a,_b)); + check(std::make_tuple(_b,_a), std::make_tuple(_a,_b)); + check(std::make_tuple(_b,_a,_c), std::make_tuple(_a,_b,_d)); +} + + + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_multiplication.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_multiplication.cpp new file mode 100644 index 000000000..2f1570d15 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_multiplication.cpp @@ -0,0 +1,491 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// 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) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// + + +#include <iostream> +#include <algorithm> +#include <vector> + +#include <boost/numeric/ublas/tensor/multiplication.hpp> +#include <boost/numeric/ublas/tensor/extents.hpp> +#include <boost/numeric/ublas/tensor/strides.hpp> +#include "utility.hpp" + +#include <boost/test/unit_test.hpp> + + +BOOST_AUTO_TEST_SUITE (test_tensor_contraction) + + +using test_types = zip<int,long,float,double,std::complex<float>>::with_t<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>; + +//using test_types = zip<int>::with_t<boost::numeric::ublas::first_order>; + + +struct fixture +{ + using extents_type = boost::numeric::ublas::shape; + fixture() + : extents { + extents_type{1,1}, // 1 + extents_type{1,2}, // 2 + extents_type{2,1}, // 3 + extents_type{2,3}, // 4 + extents_type{5,4}, // 5 + extents_type{2,3,1}, // 6 + extents_type{4,1,3}, // 7 + extents_type{1,2,3}, // 8 + extents_type{4,2,3}, // 9 + extents_type{4,2,3,5}} // 10 + { + } + std::vector<extents_type> extents; +}; + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE(test_tensor_mtv, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using strides_type = ublas::strides<layout_type>; + using vector_type = std::vector<value_type>; + using extents_type = ublas::shape; + using extents_type_base = typename extents_type::base_type; + using size_type = typename extents_type_base::value_type; + + + for(auto const& na : extents) { + + if(na.size() > 2) + continue; + + auto a = vector_type(na.product(), value_type{2}); + auto wa = strides_type(na); + for(auto m = 0u; m < na.size(); ++m){ + auto nb = extents_type {na[m],1}; + auto wb = strides_type (nb); + auto b = vector_type (nb.product(), value_type{1} ); + + auto nc_base = extents_type_base(std::max(na.size()-1, size_type{2}), 1); + + for(auto i = 0u, j = 0u; i < na.size(); ++i) + if(i != m) + nc_base[j++] = na[i]; + + auto nc = extents_type (nc_base); + auto wc = strides_type (nc); + auto c = vector_type (nc.product(), value_type{0}); + + ublas::detail::recursive::mtv( + size_type(m), + c.data(), nc.data(), wc.data(), + a.data(), na.data(), wa.data(), + b.data()); + + + for(auto i = 0u; i < c.size(); ++i) + BOOST_CHECK_EQUAL( c[i] , value_type(na[m]) * a[i] ); + + } + } +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_mtm, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using strides_type = ublas::strides<layout_type>; + using vector_type = std::vector<value_type>; + using extents_type = ublas::shape; + // using extents_type_base = typename extents_type::base_type; + + + for(auto const& na : extents) { + + if(na.size() != 2) + continue; + + auto a = vector_type (na.product(), value_type{2}); + auto wa = strides_type (na); + + auto nb = extents_type {na[1],na[0]}; + auto wb = strides_type (nb); + auto b = vector_type (nb.product(), value_type{1} ); + + auto nc = extents_type {na[0],nb[1]}; +auto wc = strides_type (nc); +auto c = vector_type (nc.product()); + + +ublas::detail::recursive::mtm( + c.data(), nc.data(), wc.data(), + a.data(), na.data(), wa.data(), + b.data(), nb.data(), wb.data()); + + +for(auto i = 0u; i < c.size(); ++i) +BOOST_CHECK_EQUAL( c[i] , value_type(na[1]) * a[0] ); + + +} +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_ttv, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using strides_type = ublas::strides<layout_type>; + using vector_type = std::vector<value_type>; + using extents_type = ublas::shape; + using extents_type_base = typename extents_type::base_type; + using size_type = typename extents_type_base::value_type; + + + for(auto const& na : extents) { + + auto a = vector_type(na.product(), value_type{2}); + auto wa = strides_type(na); + for(auto m = 0u; m < na.size(); ++m){ + auto b = vector_type (na[m], value_type{1} ); + auto nb = extents_type {na[m],1}; + auto wb = strides_type (nb); + + auto nc_base = extents_type_base(std::max(na.size()-1, size_type(2)),1); + + for(auto i = 0ul, j = 0ul; i < na.size(); ++i) + if(i != m) + nc_base[j++] = na[i]; + + auto nc = extents_type (nc_base); + auto wc = strides_type (nc); + auto c = vector_type (nc.product(), value_type{0}); + + ublas::ttv(size_type(m+1), na.size(), + c.data(), nc.data(), wc.data(), + a.data(), na.data(), wa.data(), + b.data(), nb.data(), wb.data()); + + + for(auto i = 0u; i < c.size(); ++i) + BOOST_CHECK_EQUAL( c[i] , value_type(na[m]) * a[i] ); + + } + } +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_ttm, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using strides_type = ublas::strides<layout_type>; + using vector_type = std::vector<value_type>; + using extents_type = ublas::shape; + using size_type = typename extents_type::value_type; + + + for(auto const& na : extents) { + + auto a = vector_type(na.product(), value_type{2}); + auto wa = strides_type(na); + for(auto m = 0u; m < na.size(); ++m){ + auto nb = extents_type {na[m], na[m] }; + auto b = vector_type (nb.product(), value_type{1} ); + auto wb = strides_type (nb); + + + auto nc = na; + auto wc = strides_type (nc); + auto c = vector_type (nc.product(), value_type{0}); + + ublas::ttm(size_type(m+1), na.size(), + c.data(), nc.data(), wc.data(), + a.data(), na.data(), wa.data(), + b.data(), nb.data(), wb.data()); + + for(auto i = 0u; i < c.size(); ++i) + BOOST_CHECK_EQUAL( c[i] , value_type(na[m]) * a[i] ); + + } + } +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_ttt_permutation, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using strides_type = ublas::strides<layout_type>; + using vector_type = std::vector<value_type>; + using extents_type = ublas::shape; + using size_type = typename strides_type::value_type; + + + auto compute_factorial = [](auto const& p){ + auto f = 1ul; + for(auto i = 1u; i <= p; ++i) + f *= i; + return f; + }; + + + auto compute_inverse_permutation = [](auto const& pi){ + auto pi_inv = pi; + for(auto j = 0u; j < pi.size(); ++j) + pi_inv[pi[j]-1] = j+1; + return pi_inv; + }; + + auto permute_extents = [](auto const& pi, auto const& na){ + auto nb = na; + assert(pi.size() == na.size()); + for(auto j = 0u; j < pi.size(); ++j) + nb[j] = na[pi[j]-1]; + return nb; + }; + + + // left-hand and right-hand side have the + // the same number of elements + + // computing the inner product with + // different permutation tuples for + // right-hand side + + for(auto const& na : extents) { + + auto wa = strides_type(na); + auto a = vector_type(na.product(), value_type{2}); + auto pa = na.size(); + auto pia = std::vector<size_type>(pa); + std::iota( pia.begin(), pia.end(), 1 ); + + auto pib = pia; + auto pib_inv = compute_inverse_permutation(pib); + + auto f = compute_factorial(pa); + + // for the number of possible permutations + // only permutation tuple pib is changed. + for(auto i = 0u; i < f; ++i) { + + auto nb = permute_extents( pib, na ); + auto wb = strides_type(nb); + auto b = vector_type(nb.product(), value_type{3}); + auto pb = nb.size(); + + // the number of contractions is changed. + for( auto q = size_type(0); q <= pa; ++q) { + + auto r = pa - q; + auto s = pb - q; + + auto pc = r+s > 0 ? std::max(r+s,size_type(2)) : size_type(2); + + auto nc_base = std::vector<size_type>( pc , 1 ); + + for(auto i = 0u; i < r; ++i) + nc_base[ i ] = na[ pia[i]-1 ]; + + for(auto i = 0u; i < s; ++i) + nc_base[ r + i ] = nb[ pib_inv[i]-1 ]; + + auto nc = extents_type ( nc_base ); + auto wc = strides_type ( nc ); + auto c = vector_type ( nc.product(), value_type(0) ); + + ublas::ttt(pa,pb,q, + pia.data(), pib_inv.data(), + c.data(), nc.data(), wc.data(), + a.data(), na.data(), wa.data(), + b.data(), nb.data(), wb.data()); + + + auto acc = value_type(1); + for(auto i = r; i < pa; ++i) + acc *= value_type(na[pia[i]-1]); + + for(auto i = 0ul; i < c.size(); ++i) + BOOST_CHECK_EQUAL( c[i] , acc * a[0] * b[0] ); + + } + + std::next_permutation(pib.begin(), pib.end()); + pib_inv = compute_inverse_permutation(pib); + } + } +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_ttt, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using strides_type = ublas::strides<layout_type>; + using vector_type = std::vector<value_type>; + using extents_type = ublas::shape; + using size_type = typename strides_type::value_type; + + // left-hand and right-hand side have the + // the same number of elements + + // computing the inner product with + // different permutation tuples for + // right-hand side + + for(auto const& na : extents) { + + auto wa = strides_type(na); + auto a = vector_type(na.product(), value_type{2}); + auto pa = na.size(); + + auto nb = na; + auto wb = strides_type(nb); + auto b = vector_type(nb.product(), value_type{3}); + auto pb = nb.size(); + + // std::cout << "na = "; + // std::copy(na.begin(), na.end(), std::ostream_iterator<size_type>(std::cout, " ")); + // std::cout << std::endl; + + // std::cout << "nb = "; + // std::copy(nb.begin(), nb.end(), std::ostream_iterator<size_type>(std::cout, " ")); + // std::cout << std::endl; + + + // the number of contractions is changed. + for( auto q = size_type(0); q <= pa; ++q) { // pa + + auto r = pa - q; + auto s = pb - q; + + auto pc = r+s > 0 ? std::max(r+s, size_type(2)) : size_type(2); + + auto nc_base = std::vector<size_type>( pc , 1 ); + + for(auto i = 0u; i < r; ++i) + nc_base[ i ] = na[ i ]; + + for(auto i = 0u; i < s; ++i) + nc_base[ r + i ] = nb[ i ]; + + auto nc = extents_type ( nc_base ); + auto wc = strides_type ( nc ); + auto c = vector_type ( nc.product(), value_type{0} ); + + // std::cout << "nc = "; + // std::copy(nc.begin(), nc.end(), std::ostream_iterator<size_type>(std::cout, " ")); + // std::cout << std::endl; + + ublas::ttt(pa,pb,q, + c.data(), nc.data(), wc.data(), + a.data(), na.data(), wa.data(), + b.data(), nb.data(), wb.data()); + + + auto acc = value_type(1); + for(auto i = r; i < pa; ++i) + acc *= value_type(na[i]); + + for(auto i = 0u; i < c.size(); ++i) + BOOST_CHECK_EQUAL( c[i] , acc * a[0] * b[0] ); + + } + + } +} + + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_inner, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using strides_type = ublas::strides<layout_type>; + using vector_type = std::vector<value_type>; + + + for(auto const& n : extents) { + + auto a = vector_type(n.product(), value_type{2}); + auto b = vector_type(n.product(), value_type{3}); + auto w = strides_type(n); + + auto c = ublas::inner(n.size(), n.data(), a.data(), w.data(), b.data(), w.data(), value_type(0)); + auto cref = std::inner_product(a.begin(), a.end(), b.begin(), value_type(0)); + + + BOOST_CHECK_EQUAL( c , cref ); + + } + +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_outer, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using extents_type = ublas::shape; + using strides_type = ublas::strides<layout_type>; + using vector_type = std::vector<value_type>; + + + for(auto const& na : extents) { + + auto a = vector_type(na.product(), value_type{2}); + auto wa = strides_type(na); + + for(auto const& nb : extents) { + + auto b = vector_type(nb.product(), value_type{3}); + auto wb = strides_type(nb); + + auto c = vector_type(nb.product()*na.product()); + auto nc = typename extents_type::base_type(na.size()+nb.size()); + + for(auto i = 0u; i < na.size(); ++i) + nc[i] = na[i]; + for(auto i = 0u; i < nb.size(); ++i) + nc[i+na.size()] = nb[i]; + + auto wc = strides_type(extents_type(nc)); + + ublas::outer(c.data(), nc.size(), nc.data(), wc.data(), + a.data(), na.size(), na.data(), wa.data(), + b.data(), nb.size(), nb.data(), wb.data()); + + for(auto const& cc : c) + BOOST_CHECK_EQUAL( cc , a[0]*b[0] ); + } + + } + +} + + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_operators_arithmetic.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_operators_arithmetic.cpp new file mode 100644 index 000000000..8bab76192 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_operators_arithmetic.cpp @@ -0,0 +1,267 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// 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) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// + + + +#include <boost/numeric/ublas/tensor.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/multiprecision/cpp_bin_float.hpp> +#include "utility.hpp" + + +using double_extended = boost::multiprecision::cpp_bin_float_double_extended; + +using test_types = zip<int,long,float,double,double_extended>::with_t<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>; + +struct fixture +{ + using extents_type = boost::numeric::ublas::basic_extents<std::size_t>; + fixture() + : extents{ + extents_type{}, // 0 + extents_type{1,1}, // 1 + extents_type{1,2}, // 2 + extents_type{2,1}, // 3 + extents_type{2,3}, // 4 + extents_type{2,3,1}, // 5 + extents_type{4,1,3}, // 6 + extents_type{1,2,3}, // 7 + extents_type{4,2,3}, // 8 + extents_type{4,2,3,5}} // 9 + { + } + std::vector<extents_type> extents; +}; + +BOOST_AUTO_TEST_SUITE(test_tensor_arithmetic_operations, * boost::unit_test::depends_on("test_tensor")) + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_binary_arithmetic_operations, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + + auto check = [](auto const& e) + { + auto t = tensor_type (e); + auto t2 = tensor_type (e); + auto r = tensor_type (e); + auto v = value_type {}; + + std::iota(t.begin(), t.end(), v); + std::iota(t2.begin(), t2.end(), v+2); + + r = t + t + t + t2; + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), 3*t(i) + t2(i) ); + + + r = t2 / (t+3) * (t+1) - t2; // r = ( t2/ ((t+3)*(t+1)) ) - t2 + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), t2(i) / (t(i)+3)*(t(i)+1) - t2(i) ); + + r = 3+t2 / (t+3) * (t+1) * t - t2; // r = 3+( t2/ ((t+3)*(t+1)*t) ) - t2 + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), 3+t2(i) / (t(i)+3)*(t(i)+1)*t(i) - t2(i) ); + + r = t2 - t + t2 - t; + + for(auto i = 0ul; i < r.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), 4 ); + + + r = tensor_type (e,1) + tensor_type (e,1); + + for(auto i = 0ul; i < r.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), 2 ); + + r = t * t * t * t2; + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), t(i)*t(i)*t(i)*t2(i) ); + + r = (t2/t2) * (t2/t2); + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), 1 ); + }; + + for(auto const& e : extents) + check(e); + + + BOOST_CHECK_NO_THROW ( tensor_type t = tensor_type(extents.at(0)) + tensor_type(extents.at(0)) ); + BOOST_CHECK_THROW ( tensor_type t = tensor_type(extents.at(0)) + tensor_type(extents.at(2)), std::runtime_error ); + BOOST_CHECK_THROW ( tensor_type t = tensor_type(extents.at(1)) + tensor_type(extents.at(2)), std::runtime_error ); + + +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_unary_arithmetic_operations, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + + auto check = [](auto const& e) + { + auto t = tensor_type (e); + auto t2 = tensor_type (e); + auto v = value_type {}; + + std::iota(t.begin(), t.end(), v); + std::iota(t2.begin(), t2.end(), v+2); + + tensor_type r1 = t + 2 + t + 2; + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r1(i), 2*t(i) + 4 ); + + tensor_type r2 = 2 + t + 2 + t; + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r2(i), 2*t(i) + 4 ); + + tensor_type r3 = (t-2) + (t-2); + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r3(i), 2*t(i) - 4 ); + + tensor_type r4 = (t*2) * (3*t); + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r4(i), 2*3*t(i)*t(i) ); + + tensor_type r5 = (t2*2) / (2*t2) * t2; + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r5(i), (t2(i)*2) / (2*t2(i)) * t2(i) ); + + tensor_type r6 = (t2/2+1) / (2/t2+1) / t2; + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r6(i), (t2(i)/2+1) / (2/t2(i)+1) / t2(i) ); + + }; + + for(auto const& e : extents) + check(e); + + BOOST_CHECK_NO_THROW ( tensor_type t = tensor_type(extents.at(0)) + 2 + tensor_type(extents.at(0)) ); + BOOST_CHECK_THROW ( tensor_type t = tensor_type(extents.at(0)) + 2 + tensor_type(extents.at(2)), std::runtime_error ); + BOOST_CHECK_THROW ( tensor_type t = tensor_type(extents.at(1)) + 2 + tensor_type(extents.at(2)), std::runtime_error ); + BOOST_CHECK_THROW ( tensor_type t = tensor_type(extents.at(2)) + 2 + tensor_type(extents.at(2)) + tensor_type(extents.at(1)), std::runtime_error ); + BOOST_CHECK_THROW ( tensor_type t = tensor_type(extents.at(2)) + 2 + tensor_type(extents.at(2)) + 2 + tensor_type(extents.at(1)), std::runtime_error ); +} + + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_assign_arithmetic_operations, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + + auto check = [](auto const& e) + { + auto t = tensor_type (e); + auto t2 = tensor_type (e); + auto r = tensor_type (e); + auto v = value_type {}; + + std::iota(t.begin(), t.end(), v); + std::iota(t2.begin(), t2.end(), v+2); + + r = t + 2; + r += t; + r += 2; + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), 2*t(i) + 4 ); + + r = 2 + t; + r += t; + r += 2; + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), 2*t(i) + 4 ); + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), 2*t(i) + 4 ); + + r = (t-2); + r += t; + r -= 2; + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), 2*t(i) - 4 ); + + r = (t*2); + r *= 3; + r *= t; + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), 2*3*t(i)*t(i) ); + + r = (t2*2); + r /= 2; + r /= t2; + r *= t2; + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), (t2(i)*2) / (2*t2(i)) * t2(i) ); + + r = (t2/2+1); + r /= (2/t2+1); + r /= t2; + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), (t2(i)/2+1) / (2/t2(i)+1) / t2(i) ); + + tensor_type q = -r; + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( q(i), -r(i) ); + + tensor_type p = +r; + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( p(i), r(i) ); + }; + + for(auto const& e : extents) + check(e); + + auto r = tensor_type (extents.at(0)); + + BOOST_CHECK_NO_THROW ( r += tensor_type(extents.at(0)) + 2 + tensor_type(extents.at(0)) ); + BOOST_CHECK_THROW ( r += tensor_type(extents.at(0)) + 2 + tensor_type(extents.at(2)), std::runtime_error ); + BOOST_CHECK_THROW ( r += tensor_type(extents.at(1)) + 2 + tensor_type(extents.at(2)), std::runtime_error ); + BOOST_CHECK_THROW ( r += tensor_type(extents.at(2)) + 2 + tensor_type(extents.at(2)) + tensor_type(extents.at(1)), std::runtime_error ); + BOOST_CHECK_THROW ( r += tensor_type(extents.at(2)) + 2 + tensor_type(extents.at(2)) + 2 + tensor_type(extents.at(1)), std::runtime_error ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_operators_comparison.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_operators_comparison.cpp new file mode 100644 index 000000000..f076e9c1e --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_operators_comparison.cpp @@ -0,0 +1,246 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// 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) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// + + + +#include <boost/numeric/ublas/tensor/operators_comparison.hpp> +#include <boost/numeric/ublas/tensor/operators_arithmetic.hpp> +#include <boost/numeric/ublas/tensor/tensor.hpp> +#include <boost/test/unit_test.hpp> +#include <boost/multiprecision/cpp_bin_float.hpp> +#include "utility.hpp" + + +using double_extended = boost::multiprecision::cpp_bin_float_double_extended; + +using test_types = zip<int,long,float,double,double_extended>::with_t<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>; + +struct fixture { + using extents_type = boost::numeric::ublas::basic_extents<std::size_t>; + fixture() + : extents{ + extents_type{}, // 0 + extents_type{1,1}, // 1 + extents_type{1,2}, // 2 + extents_type{2,1}, // 3 + extents_type{2,3}, // 4 + extents_type{2,3,1}, // 5 + extents_type{4,1,3}, // 6 + extents_type{1,2,3}, // 7 + extents_type{4,2,3}, // 8 + extents_type{4,2,3,5}} // 9 + { + } + std::vector<extents_type> extents; +}; + +BOOST_AUTO_TEST_SUITE(test_tensor_comparison, * boost::unit_test::depends_on("test_tensor")) + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_comparison, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + + auto check = [](auto const& e) + { + auto t = tensor_type (e); + auto t2 = tensor_type (e); + auto v = value_type {}; + + std::iota(t.begin(), t.end(), v); + std::iota(t2.begin(), t2.end(), v+2); + + BOOST_CHECK( t == t ); + BOOST_CHECK( t != t2 ); + + if(t.empty()) + return; + + BOOST_CHECK(!(t < t)); + BOOST_CHECK(!(t > t)); + BOOST_CHECK( t < t2 ); + BOOST_CHECK( t2 > t ); + BOOST_CHECK( t <= t ); + BOOST_CHECK( t >= t ); + BOOST_CHECK( t <= t2 ); + BOOST_CHECK( t2 >= t ); + BOOST_CHECK( t2 >= t2 ); + BOOST_CHECK( t2 >= t ); + }; + + for(auto const& e : extents) + check(e); + + auto e0 = extents.at(0); + auto e1 = extents.at(1); + auto e2 = extents.at(2); + + + auto b = false; + BOOST_CHECK_NO_THROW ( b = (tensor_type(e0) == tensor_type(e0))); + BOOST_CHECK_NO_THROW ( b = (tensor_type(e1) == tensor_type(e2))); + BOOST_CHECK_NO_THROW ( b = (tensor_type(e0) == tensor_type(e2))); + BOOST_CHECK_NO_THROW ( b = (tensor_type(e1) != tensor_type(e2))); + + BOOST_CHECK_THROW ( b = (tensor_type(e1) >= tensor_type(e2)), std::runtime_error ); + BOOST_CHECK_THROW ( b = (tensor_type(e1) <= tensor_type(e2)), std::runtime_error ); + BOOST_CHECK_THROW ( b = (tensor_type(e1) < tensor_type(e2)), std::runtime_error ); + BOOST_CHECK_THROW ( b = (tensor_type(e1) > tensor_type(e2)), std::runtime_error ); + +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_comparison_with_tensor_expressions, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + + auto check = [](auto const& e) + { + auto t = tensor_type (e); + auto t2 = tensor_type (e); + auto v = value_type {}; + + std::iota(t.begin(), t.end(), v); + std::iota(t2.begin(), t2.end(), v+2); + + BOOST_CHECK( t == t ); + BOOST_CHECK( t != t2 ); + + if(t.empty()) + return; + + BOOST_CHECK( !(t < t) ); + BOOST_CHECK( !(t > t) ); + BOOST_CHECK( t < (t2+t) ); + BOOST_CHECK( (t2+t) > t ); + BOOST_CHECK( t <= (t+t) ); + BOOST_CHECK( (t+t2) >= t ); + BOOST_CHECK( (t2+t2+2) >= t); + BOOST_CHECK( 2*t2 > t ); + BOOST_CHECK( t < 2*t2 ); + BOOST_CHECK( 2*t2 > t); + BOOST_CHECK( 2*t2 >= t2 ); + BOOST_CHECK( t2 <= 2*t2); + BOOST_CHECK( 3*t2 >= t ); + + }; + + for(auto const& e : extents) + check(e); + + auto e0 = extents.at(0); + auto e1 = extents.at(1); + auto e2 = extents.at(2); + + auto b = false; + BOOST_CHECK_NO_THROW (b = tensor_type(e0) == (tensor_type(e0) + tensor_type(e0)) ); + BOOST_CHECK_NO_THROW (b = tensor_type(e1) == (tensor_type(e2) + tensor_type(e2)) ); + BOOST_CHECK_NO_THROW (b = tensor_type(e0) == (tensor_type(e2) + 2) ); + BOOST_CHECK_NO_THROW (b = tensor_type(e1) != (2 + tensor_type(e2)) ); + + BOOST_CHECK_NO_THROW (b = (tensor_type(e0) + tensor_type(e0)) == tensor_type(e0) ); + BOOST_CHECK_NO_THROW (b = (tensor_type(e2) + tensor_type(e2)) == tensor_type(e1) ); + BOOST_CHECK_NO_THROW (b = (tensor_type(e2) + 2) == tensor_type(e0) ); + BOOST_CHECK_NO_THROW (b = (2 + tensor_type(e2)) != tensor_type(e1) ); + + BOOST_CHECK_THROW (b = tensor_type(e1) >= (tensor_type(e2) + tensor_type(e2)), std::runtime_error ); + BOOST_CHECK_THROW (b = tensor_type(e1) <= (tensor_type(e2) + tensor_type(e2)), std::runtime_error ); + BOOST_CHECK_THROW (b = tensor_type(e1) < (tensor_type(e2) + tensor_type(e2)), std::runtime_error ); + BOOST_CHECK_THROW (b = tensor_type(e1) > (tensor_type(e2) + tensor_type(e2)), std::runtime_error ); + + BOOST_CHECK_THROW (b = tensor_type(e1) >= (tensor_type(e2) + 2), std::runtime_error ); + BOOST_CHECK_THROW (b = tensor_type(e1) <= (2 + tensor_type(e2)), std::runtime_error ); + BOOST_CHECK_THROW (b = tensor_type(e1) < (tensor_type(e2) + 3), std::runtime_error ); + BOOST_CHECK_THROW (b = tensor_type(e1) > (4 + tensor_type(e2)), std::runtime_error ); + +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_comparison_with_scalar, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + + auto check = [](auto const& e) + { + + BOOST_CHECK( tensor_type(e,value_type{2}) == tensor_type(e,value_type{2}) ); + BOOST_CHECK( tensor_type(e,value_type{2}) != tensor_type(e,value_type{1}) ); + + if(e.empty()) + return; + + BOOST_CHECK( !(tensor_type(e,2) < 2) ); + BOOST_CHECK( !(tensor_type(e,2) > 2) ); + BOOST_CHECK( (tensor_type(e,2) >= 2) ); + BOOST_CHECK( (tensor_type(e,2) <= 2) ); + BOOST_CHECK( (tensor_type(e,2) == 2) ); + BOOST_CHECK( (tensor_type(e,2) != 3) ); + + BOOST_CHECK( !(2 > tensor_type(e,2)) ); + BOOST_CHECK( !(2 < tensor_type(e,2)) ); + BOOST_CHECK( (2 <= tensor_type(e,2)) ); + BOOST_CHECK( (2 >= tensor_type(e,2)) ); + BOOST_CHECK( (2 == tensor_type(e,2)) ); + BOOST_CHECK( (3 != tensor_type(e,2)) ); + + BOOST_CHECK( !( tensor_type(e,2)+3 < 5) ); + BOOST_CHECK( !( tensor_type(e,2)+3 > 5) ); + BOOST_CHECK( ( tensor_type(e,2)+3 >= 5) ); + BOOST_CHECK( ( tensor_type(e,2)+3 <= 5) ); + BOOST_CHECK( ( tensor_type(e,2)+3 == 5) ); + BOOST_CHECK( ( tensor_type(e,2)+3 != 6) ); + + + BOOST_CHECK( !( 5 > tensor_type(e,2)+3) ); + BOOST_CHECK( !( 5 < tensor_type(e,2)+3) ); + BOOST_CHECK( ( 5 >= tensor_type(e,2)+3) ); + BOOST_CHECK( ( 5 <= tensor_type(e,2)+3) ); + BOOST_CHECK( ( 5 == tensor_type(e,2)+3) ); + BOOST_CHECK( ( 6 != tensor_type(e,2)+3) ); + + + BOOST_CHECK( !( tensor_type(e,2)+tensor_type(e,3) < 5) ); + BOOST_CHECK( !( tensor_type(e,2)+tensor_type(e,3) > 5) ); + BOOST_CHECK( ( tensor_type(e,2)+tensor_type(e,3) >= 5) ); + BOOST_CHECK( ( tensor_type(e,2)+tensor_type(e,3) <= 5) ); + BOOST_CHECK( ( tensor_type(e,2)+tensor_type(e,3) == 5) ); + BOOST_CHECK( ( tensor_type(e,2)+tensor_type(e,3) != 6) ); + + + BOOST_CHECK( !( 5 > tensor_type(e,2)+tensor_type(e,3)) ); + BOOST_CHECK( !( 5 < tensor_type(e,2)+tensor_type(e,3)) ); + BOOST_CHECK( ( 5 >= tensor_type(e,2)+tensor_type(e,3)) ); + BOOST_CHECK( ( 5 <= tensor_type(e,2)+tensor_type(e,3)) ); + BOOST_CHECK( ( 5 == tensor_type(e,2)+tensor_type(e,3)) ); + BOOST_CHECK( ( 6 != tensor_type(e,2)+tensor_type(e,3)) ); + + }; + + for(auto const& e : extents) + check(e); + +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_strides.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_strides.cpp new file mode 100644 index 000000000..3a29e660a --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_strides.cpp @@ -0,0 +1,172 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// 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) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// + + + + +#include <boost/test/unit_test.hpp> +#include <boost/numeric/ublas/tensor/strides.hpp> +#include <boost/numeric/ublas/tensor/extents.hpp> + +//BOOST_AUTO_TEST_SUITE(test_strides, * boost::unit_test::depends_on("test_extents")); + +BOOST_AUTO_TEST_SUITE(test_strides) + +using test_types = std::tuple<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>; + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_strides_ctor, value, test_types) +{ + using namespace boost::numeric; + + using extents_type = ublas::basic_extents<unsigned>; + using strides_type = ublas::strides<value>; + + strides_type s0{}; + BOOST_CHECK ( s0.empty()); + BOOST_CHECK_EQUAL ( s0.size(), 0); + + strides_type s1{extents_type{1,1}}; + BOOST_CHECK (!s1.empty()); + BOOST_CHECK_EQUAL ( s1.size(), 2); + + strides_type s2{extents_type{1,2}}; + BOOST_CHECK (!s2.empty()); + BOOST_CHECK_EQUAL ( s2.size(), 2); + + strides_type s3{extents_type{2,1}}; + BOOST_CHECK (!s3.empty()); + BOOST_CHECK_EQUAL ( s3.size(), 2); + + strides_type s4{extents_type{2,3}}; + BOOST_CHECK (!s4.empty()); + BOOST_CHECK_EQUAL ( s4.size(), 2); + + strides_type s5{extents_type{2,3,1}}; + BOOST_CHECK (!s5.empty()); + BOOST_CHECK_EQUAL ( s5.size(), 3); + + strides_type s6{extents_type{1,2,3}}; + BOOST_CHECK (!s6.empty()); + BOOST_CHECK_EQUAL ( s6.size(), 3); + + strides_type s7{extents_type{4,2,3}}; + BOOST_CHECK (!s7.empty()); + BOOST_CHECK_EQUAL ( s7.size(), 3); +} + + + +BOOST_AUTO_TEST_CASE( test_strides_ctor_access_first_order) +{ + using namespace boost::numeric; + + using extents_type = ublas::basic_extents<unsigned>; + using strides_type = ublas::strides<ublas::first_order>; + + strides_type s1{extents_type{1,1}}; + BOOST_REQUIRE_EQUAL( s1.size(),2); + BOOST_CHECK_EQUAL ( s1[0], 1); + BOOST_CHECK_EQUAL ( s1[1], 1); + + strides_type s2{extents_type{1,2}}; + BOOST_REQUIRE_EQUAL ( s2.size(),2); + BOOST_CHECK_EQUAL ( s2[0], 1); + BOOST_CHECK_EQUAL ( s2[1], 1); + + strides_type s3{extents_type{2,1}}; + BOOST_REQUIRE_EQUAL ( s3.size(),2); + BOOST_CHECK_EQUAL ( s3[0], 1); + BOOST_CHECK_EQUAL ( s3[1], 1); + + strides_type s4{extents_type{2,3}}; + BOOST_REQUIRE_EQUAL ( s4.size(),2); + BOOST_CHECK_EQUAL ( s4[0], 1); + BOOST_CHECK_EQUAL ( s4[1], 2); + + strides_type s5{extents_type{2,3,1}}; + BOOST_REQUIRE_EQUAL ( s5.size(),3); + BOOST_CHECK_EQUAL ( s5[0], 1); + BOOST_CHECK_EQUAL ( s5[1], 2); + BOOST_CHECK_EQUAL ( s5[2], 6); + + strides_type s6{extents_type{1,2,3}}; + BOOST_REQUIRE_EQUAL ( s6.size(),3); + BOOST_CHECK_EQUAL ( s6[0], 1); + BOOST_CHECK_EQUAL ( s6[1], 1); + BOOST_CHECK_EQUAL ( s6[2], 2); + + strides_type s7{extents_type{2,1,3}}; + BOOST_REQUIRE_EQUAL ( s7.size(),3); + BOOST_CHECK_EQUAL ( s7[0], 1); + BOOST_CHECK_EQUAL ( s7[1], 2); + BOOST_CHECK_EQUAL ( s7[2], 2); + + strides_type s8{extents_type{4,2,3}}; + BOOST_REQUIRE_EQUAL ( s8.size(),3); + BOOST_CHECK_EQUAL ( s8[0], 1); + BOOST_CHECK_EQUAL ( s8[1], 4); + BOOST_CHECK_EQUAL ( s8[2], 8); +} + +BOOST_AUTO_TEST_CASE( test_strides_ctor_access_last_order) +{ + using namespace boost::numeric; + + using extents_type = ublas::basic_extents<unsigned>; + using strides_type = ublas::strides<ublas::last_order>; + + strides_type s1{extents_type{1,1}}; + BOOST_REQUIRE_EQUAL( s1.size(),2); + BOOST_CHECK_EQUAL ( s1[0], 1); + BOOST_CHECK_EQUAL ( s1[1], 1); + + strides_type s2{extents_type{1,2}}; + BOOST_REQUIRE_EQUAL ( s2.size(),2); + BOOST_CHECK_EQUAL ( s2[0], 1); + BOOST_CHECK_EQUAL ( s2[1], 1); + + strides_type s3{extents_type{2,1}}; + BOOST_REQUIRE_EQUAL ( s3.size(),2); + BOOST_CHECK_EQUAL ( s3[0], 1); + BOOST_CHECK_EQUAL ( s3[1], 1); + + strides_type s4{extents_type{2,3}}; + BOOST_REQUIRE_EQUAL ( s4.size(),2); + BOOST_CHECK_EQUAL ( s4[0], 3); + BOOST_CHECK_EQUAL ( s4[1], 1); + + strides_type s5{extents_type{2,3,1}}; + BOOST_REQUIRE_EQUAL ( s5.size(),3); + BOOST_CHECK_EQUAL ( s5[0], 3); + BOOST_CHECK_EQUAL ( s5[1], 1); + BOOST_CHECK_EQUAL ( s5[2], 1); + + strides_type s6{extents_type{1,2,3}}; + BOOST_REQUIRE_EQUAL ( s6.size(),3); + BOOST_CHECK_EQUAL ( s6[0], 6); + BOOST_CHECK_EQUAL ( s6[1], 3); + BOOST_CHECK_EQUAL ( s6[2], 1); + + strides_type s7{extents_type{2,1,3}}; + BOOST_REQUIRE_EQUAL ( s7.size(),3); + BOOST_CHECK_EQUAL ( s7[0], 3); + BOOST_CHECK_EQUAL ( s7[1], 3); + BOOST_CHECK_EQUAL ( s7[2], 1); + + strides_type s8{extents_type{4,2,3}}; + BOOST_REQUIRE_EQUAL ( s8.size(),3); + BOOST_CHECK_EQUAL ( s8[0], 6); + BOOST_CHECK_EQUAL ( s8[1], 3); + BOOST_CHECK_EQUAL ( s8[2], 1); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_tensor.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_tensor.cpp new file mode 100644 index 000000000..400e86245 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_tensor.cpp @@ -0,0 +1,473 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// 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) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// + + + +#include <random> +#include <boost/numeric/ublas/tensor/tensor.hpp> + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE TestTensor + +#include <boost/test/unit_test.hpp> +#include "utility.hpp" + +//BOOST_AUTO_TEST_SUITE ( test_tensor, * boost::unit_test::depends_on("test_extents") ) ; +BOOST_AUTO_TEST_SUITE ( test_tensor ) + +using test_types = zip<int,long,float,double,std::complex<float>>::with_t<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>; + + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_tensor_ctor, value, test_types) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + auto a1 = tensor_type{}; + BOOST_CHECK_EQUAL( a1.size() , 0ul ); + BOOST_CHECK( a1.empty() ); + BOOST_CHECK_EQUAL( a1.data() , nullptr); + + auto a2 = tensor_type{1,1}; + BOOST_CHECK_EQUAL( a2.size() , 1 ); + BOOST_CHECK( !a2.empty() ); + BOOST_CHECK_NE( a2.data() , nullptr); + + auto a3 = tensor_type{2,1}; + BOOST_CHECK_EQUAL( a3.size() , 2 ); + BOOST_CHECK( !a3.empty() ); + BOOST_CHECK_NE( a3.data() , nullptr); + + auto a4 = tensor_type{1,2}; + BOOST_CHECK_EQUAL( a4.size() , 2 ); + BOOST_CHECK( !a4.empty() ); + BOOST_CHECK_NE( a4.data() , nullptr); + + auto a5 = tensor_type{2,1}; + BOOST_CHECK_EQUAL( a5.size() , 2 ); + BOOST_CHECK( !a5.empty() ); + BOOST_CHECK_NE( a5.data() , nullptr); + + auto a6 = tensor_type{4,3,2}; + BOOST_CHECK_EQUAL( a6.size() , 4*3*2 ); + BOOST_CHECK( !a6.empty() ); + BOOST_CHECK_NE( a6.data() , nullptr); + + auto a7 = tensor_type{4,1,2}; + BOOST_CHECK_EQUAL( a7.size() , 4*1*2 ); + BOOST_CHECK( !a7.empty() ); + BOOST_CHECK_NE( a7.data() , nullptr); +} + + +struct fixture +{ + using extents_type = boost::numeric::ublas::basic_extents<std::size_t>; + fixture() + : extents { + extents_type{}, // 0 + extents_type{1,1}, // 1 + extents_type{1,2}, // 2 + extents_type{2,1}, // 3 + extents_type{2,3}, // 4 + extents_type{2,3,1}, // 5 + extents_type{4,1,3}, // 6 + extents_type{1,2,3}, // 7 + extents_type{4,2,3}, // 8 + extents_type{4,2,3,5}} // 9 + { + } + std::vector<extents_type> extents; +}; + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_ctor_extents, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + auto check = [](auto const& e) { + auto t = tensor_type{e}; + BOOST_CHECK_EQUAL ( t.size() , e.product() ); + BOOST_CHECK_EQUAL ( t.rank() , e.size() ); + if(e.empty()) { + BOOST_CHECK ( t.empty() ); + BOOST_CHECK_EQUAL ( t.data() , nullptr); + } + else{ + BOOST_CHECK ( !t.empty() ); + BOOST_CHECK_NE ( t.data() , nullptr); + } + }; + + for(auto const& e : extents) + check(e); +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_copy_ctor, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + auto check = [](auto const& e) + { + auto r = tensor_type{e}; + auto t = r; + BOOST_CHECK_EQUAL ( t.size() , r.size() ); + BOOST_CHECK_EQUAL ( t.rank() , r.rank() ); + BOOST_CHECK ( t.strides() == r.strides() ); + BOOST_CHECK ( t.extents() == r.extents() ); + + if(e.empty()) { + BOOST_CHECK ( t.empty() ); + BOOST_CHECK_EQUAL ( t.data() , nullptr); + } + else{ + BOOST_CHECK ( !t.empty() ); + BOOST_CHECK_NE ( t.data() , nullptr); + } + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL( t[i], r[i] ); + }; + + for(auto const& e : extents) + check(e); +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_copy_ctor_layout, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using other_layout_type = std::conditional_t<std::is_same<ublas::first_order,layout_type>::value, ublas::last_order, ublas::first_order>; + using other_tensor_type = ublas::tensor<value_type, other_layout_type>; + + + for(auto const& e : extents) + { + auto r = tensor_type{e}; + other_tensor_type t = r; + tensor_type q = t; + + BOOST_CHECK_EQUAL ( t.size() , r.size() ); + BOOST_CHECK_EQUAL ( t.rank() , r.rank() ); + BOOST_CHECK ( t.extents() == r.extents() ); + + BOOST_CHECK_EQUAL ( q.size() , r.size() ); + BOOST_CHECK_EQUAL ( q.rank() , r.rank() ); + BOOST_CHECK ( q.strides() == r.strides() ); + BOOST_CHECK ( q.extents() == r.extents() ); + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL( q[i], r[i] ); + } +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_copy_move_ctor, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + auto check = [](auto const& e) + { + auto r = tensor_type{e}; + auto t = std::move(r); + BOOST_CHECK_EQUAL ( t.size() , e.product() ); + BOOST_CHECK_EQUAL ( t.rank() , e.size() ); + + if(e.empty()) { + BOOST_CHECK ( t.empty() ); + BOOST_CHECK_EQUAL ( t.data() , nullptr); + } + else{ + BOOST_CHECK ( !t.empty() ); + BOOST_CHECK_NE ( t.data() , nullptr); + } + + }; + + for(auto const& e : extents) + check(e); +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_ctor_extents_init, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + std::random_device device{}; + std::minstd_rand0 generator(device()); + + using distribution_type = std::conditional_t<std::is_integral_v<value_type>, std::uniform_int_distribution<>, std::uniform_real_distribution<> >; + auto distribution = distribution_type(1,6); + + for(auto const& e : extents){ + auto r = static_cast<value_type>(distribution(generator)); + auto t = tensor_type{e,r}; + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL( t[i], r ); + } +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_ctor_extents_array, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using array_type = typename tensor_type::array_type; + + for(auto const& e : extents) { + auto a = array_type(e.product()); + auto v = value_type {}; + + for(auto& aa : a){ + aa = v; + v += value_type{1}; + } + auto t = tensor_type{e, a}; + v = value_type{}; + + for(auto i = 0ul; i < t.size(); ++i, v+=value_type{1}) + BOOST_CHECK_EQUAL( t[i], v); + } +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_read_write_single_index_access, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + for(auto const& e : extents) { + auto t = tensor_type{e}; + auto v = value_type {}; + for(auto i = 0ul; i < t.size(); ++i, v+=value_type{1}){ + t[i] = v; + BOOST_CHECK_EQUAL( t[i], v ); + + t(i) = v; + BOOST_CHECK_EQUAL( t(i), v ); + } + } +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_read_write_multi_index_access_at, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + auto check1 = [](const tensor_type& t) + { + auto v = value_type{}; + for(auto k = 0ul; k < t.size(); ++k){ + BOOST_CHECK_EQUAL(t[k], v); + v+=value_type{1}; + } + }; + + auto check2 = [](const tensor_type& t) + { + std::array<unsigned,2> k; + auto r = std::is_same_v<layout_type,ublas::first_order> ? 1 : 0; + auto q = std::is_same_v<layout_type,ublas::last_order > ? 1 : 0; + auto v = value_type{}; + for(k[r] = 0ul; k[r] < t.size(r); ++k[r]){ + for(k[q] = 0ul; k[q] < t.size(q); ++k[q]){ + BOOST_CHECK_EQUAL(t.at(k[0],k[1]), v); + v+=value_type{1}; + } + } + }; + + auto check3 = [](const tensor_type& t) + { + std::array<unsigned,3> k; + using op_type = std::conditional_t<std::is_same_v<layout_type,ublas::first_order>, std::minus<>, std::plus<>>; + auto r = std::is_same_v<layout_type,ublas::first_order> ? 2 : 0; + auto o = op_type{}; + auto v = value_type{}; + for(k[r] = 0ul; k[r] < t.size(r); ++k[r]){ + for(k[o(r,1)] = 0ul; k[o(r,1)] < t.size(o(r,1)); ++k[o(r,1)]){ + for(k[o(r,2)] = 0ul; k[o(r,2)] < t.size(o(r,2)); ++k[o(r,2)]){ + BOOST_CHECK_EQUAL(t.at(k[0],k[1],k[2]), v); + v+=value_type{1}; + } + } + } + }; + + auto check4 = [](const tensor_type& t) + { + std::array<unsigned,4> k; + using op_type = std::conditional_t<std::is_same_v<layout_type,ublas::first_order>, std::minus<>, std::plus<>>; + auto r = std::is_same_v<layout_type,ublas::first_order> ? 3 : 0; + auto o = op_type{}; + auto v = value_type{}; + for(k[r] = 0ul; k[r] < t.size(r); ++k[r]){ + for(k[o(r,1)] = 0ul; k[o(r,1)] < t.size(o(r,1)); ++k[o(r,1)]){ + for(k[o(r,2)] = 0ul; k[o(r,2)] < t.size(o(r,2)); ++k[o(r,2)]){ + for(k[o(r,3)] = 0ul; k[o(r,3)] < t.size(o(r,3)); ++k[o(r,3)]){ + BOOST_CHECK_EQUAL(t.at(k[0],k[1],k[2],k[3]), v); + v+=value_type{1}; + } + } + } + } + }; + + auto check = [check1,check2,check3,check4](auto const& e) { + auto t = tensor_type{e}; + auto v = value_type {}; + for(auto i = 0ul; i < t.size(); ++i){ + t[i] = v; + v+=value_type{1}; + } + + if(t.rank() == 1) check1(t); + else if(t.rank() == 2) check2(t); + else if(t.rank() == 3) check3(t); + else if(t.rank() == 4) check4(t); + + }; + + for(auto const& e : extents) + check(e); +} + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_reshape, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + + for(auto const& efrom : extents){ + for(auto const& eto : extents){ + + auto v = value_type {}; + v+=value_type{1}; + auto t = tensor_type{efrom, v}; + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL( t[i], v ); + + t.reshape(eto); + for(auto i = 0ul; i < std::min(efrom.product(),eto.product()); ++i) + BOOST_CHECK_EQUAL( t[i], v ); + + BOOST_CHECK_EQUAL ( t.size() , eto.product() ); + BOOST_CHECK_EQUAL ( t.rank() , eto.size() ); + BOOST_CHECK ( t.extents() == eto ); + + if(efrom != eto){ + for(auto i = efrom.product(); i < t.size(); ++i) + BOOST_CHECK_EQUAL( t[i], value_type{} ); + } + } + } +} + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_swap, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + for(auto const& e_t : extents){ + for(auto const& e_r : extents) { + + auto v = value_type {} + value_type{1}; + auto w = value_type {} + value_type{2}; + auto t = tensor_type{e_t, v}; + auto r = tensor_type{e_r, w}; + + std::swap( r, t ); + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL( t[i], w ); + + BOOST_CHECK_EQUAL ( t.size() , e_r.product() ); + BOOST_CHECK_EQUAL ( t.rank() , e_r.size() ); + BOOST_CHECK ( t.extents() == e_r ); + + for(auto i = 0ul; i < r.size(); ++i) + BOOST_CHECK_EQUAL( r[i], v ); + + BOOST_CHECK_EQUAL ( r.size() , e_t.product() ); + BOOST_CHECK_EQUAL ( r.rank() , e_t.size() ); + BOOST_CHECK ( r.extents() == e_t ); + + + } + } +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_standard_iterator, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + for(auto const& e : extents) + { + auto v = value_type {} + value_type{1}; + auto t = tensor_type{e, v}; + + BOOST_CHECK_EQUAL( std::distance(t.begin(), t.end ()), t.size() ); + BOOST_CHECK_EQUAL( std::distance(t.rbegin(), t.rend()), t.size() ); + + BOOST_CHECK_EQUAL( std::distance(t.cbegin(), t.cend ()), t.size() ); + BOOST_CHECK_EQUAL( std::distance(t.crbegin(), t.crend()), t.size() ); + + if(t.size() > 0) { + BOOST_CHECK( t.data() == std::addressof( *t.begin () ) ) ; + BOOST_CHECK( t.data() == std::addressof( *t.cbegin() ) ) ; + } + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_tensor_matrix_vector.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_tensor_matrix_vector.cpp new file mode 100644 index 000000000..3e34047dd --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_tensor_matrix_vector.cpp @@ -0,0 +1,472 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// 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) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// + + +#include <iostream> +#include <random> +#include <boost/numeric/ublas/tensor.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/test/unit_test.hpp> + +#include "utility.hpp" + +// BOOST_AUTO_TEST_SUITE ( test_tensor_matrix_interoperability, * boost::unit_test::depends_on("test_tensor") ) ; + +BOOST_AUTO_TEST_SUITE ( test_tensor_matrix_interoperability ) + +using test_types = zip<int,long,float,double>::with_t<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>; + + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_tensor_matrix_copy_ctor, value, test_types) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using matrix_type = typename tensor_type::matrix_type; + + tensor_type a1 = matrix_type(); + BOOST_CHECK_EQUAL( a1.size() , 0ul ); + BOOST_CHECK( a1.empty() ); + BOOST_CHECK_EQUAL( a1.data() , nullptr); + + tensor_type a2 = matrix_type(1,1); + BOOST_CHECK_EQUAL( a2.size() , 1 ); + BOOST_CHECK( !a2.empty() ); + BOOST_CHECK_NE( a2.data() , nullptr); + + tensor_type a3 = matrix_type(2,1); + BOOST_CHECK_EQUAL( a3.size() , 2 ); + BOOST_CHECK( !a3.empty() ); + BOOST_CHECK_NE( a3.data() , nullptr); + + tensor_type a4 = matrix_type(1,2); + BOOST_CHECK_EQUAL( a4.size() , 2 ); + BOOST_CHECK( !a4.empty() ); + BOOST_CHECK_NE( a4.data() , nullptr); + + tensor_type a5 = matrix_type(2,3); + BOOST_CHECK_EQUAL( a5.size() , 6 ); + BOOST_CHECK( !a5.empty() ); + BOOST_CHECK_NE( a5.data() , nullptr); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_tensor_vector_copy_ctor, value, test_types) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using vector_type = typename tensor_type::vector_type; + + tensor_type a1 = vector_type(); + BOOST_CHECK_EQUAL( a1.size() , 0ul ); + BOOST_CHECK( a1.empty() ); + BOOST_CHECK_EQUAL( a1.data() , nullptr); + + tensor_type a2 = vector_type(1); + BOOST_CHECK_EQUAL( a2.size() , 1 ); + BOOST_CHECK( !a2.empty() ); + BOOST_CHECK_NE( a2.data() , nullptr); + + tensor_type a3 = vector_type(2); + BOOST_CHECK_EQUAL( a3.size() , 2 ); + BOOST_CHECK( !a3.empty() ); + BOOST_CHECK_NE( a3.data() , nullptr); + + tensor_type a4 = vector_type(2); + BOOST_CHECK_EQUAL( a4.size() , 2 ); + BOOST_CHECK( !a4.empty() ); + BOOST_CHECK_NE( a4.data() , nullptr); + + tensor_type a5 = vector_type(3); + BOOST_CHECK_EQUAL( a5.size() , 3 ); + BOOST_CHECK( !a5.empty() ); + BOOST_CHECK_NE( a5.data() , nullptr); +} + + +struct fixture +{ + using extents_type = boost::numeric::ublas::basic_extents<std::size_t>; + fixture() + : extents{ + extents_type{1,1}, // 1 + extents_type{1,2}, // 2 + extents_type{2,1}, // 3 + extents_type{2,3}, // 4 + extents_type{9,7}, // 5 + extents_type{9,11}, // 6 + extents_type{12,12}, // 7 + extents_type{15,17}} // 8 + { + } + std::vector<extents_type> extents; +}; + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_matrix_copy_ctor_extents, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using matrix_type = typename tensor_type::matrix_type; + + auto check = [](auto const& e) { + assert(e.size()==2); + tensor_type t = matrix_type{e[0],e[1]}; + BOOST_CHECK_EQUAL ( t.size() , e.product() ); + BOOST_CHECK_EQUAL ( t.rank() , e.size() ); + BOOST_CHECK ( !t.empty() ); + BOOST_CHECK_NE ( t.data() , nullptr); + }; + + for(auto const& e : extents) + check(e); +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_vector_copy_ctor_extents, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using vector_type = typename tensor_type::vector_type; + + auto check = [](auto const& e) { + assert(e.size()==2); + if(e.empty()) + return; + + tensor_type t = vector_type(e.product()); + BOOST_CHECK_EQUAL ( t.size() , e.product() ); + BOOST_CHECK_EQUAL ( t.rank() , e.size() ); + BOOST_CHECK ( !t.empty() ); + BOOST_CHECK_NE ( t.data() , nullptr); + }; + + for(auto const& e : extents) + check(e); +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_matrix_copy_assignment, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using matrix_type = typename tensor_type::matrix_type; + + auto check = [](auto const& e) + { + assert(e.size() == 2); + auto t = tensor_type{}; + auto r = matrix_type(e[0],e[1]); + std::iota(r.data().begin(),r.data().end(), 1); + t = r; + + BOOST_CHECK_EQUAL ( t.extents().at(0) , e.at(0) ); + BOOST_CHECK_EQUAL ( t.extents().at(1) , e.at(1) ); + BOOST_CHECK_EQUAL ( t.size() , e.product() ); + BOOST_CHECK_EQUAL ( t.rank() , e.size() ); + BOOST_CHECK ( !t.empty() ); + BOOST_CHECK_NE ( t.data() , nullptr); + + for(auto j = 0ul; j < t.size(1); ++j){ + for(auto i = 0ul; i < t.size(0); ++i){ + BOOST_CHECK_EQUAL( t.at(i,j), r(i,j) ); + } + } + }; + + for(auto const& e : extents) + check(e); +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_vector_copy_assignment, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using vector_type = typename tensor_type::vector_type; + + auto check = [](auto const& e) + { + assert(e.size() == 2); + auto t = tensor_type{}; + auto r = vector_type(e[0]*e[1]); + std::iota(r.data().begin(),r.data().end(), 1); + t = r; + + BOOST_CHECK_EQUAL ( t.extents().at(0) , e.at(0)*e.at(1) ); + BOOST_CHECK_EQUAL ( t.extents().at(1) , 1); + BOOST_CHECK_EQUAL ( t.size() , e.product() ); + BOOST_CHECK_EQUAL ( t.rank() , e.size() ); + BOOST_CHECK ( !t.empty() ); + BOOST_CHECK_NE ( t.data() , nullptr); + + for(auto i = 0ul; i < t.size(); ++i){ + BOOST_CHECK_EQUAL( t[i], r(i) ); + } + }; + + for(auto const& e : extents) + check(e); +} + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_matrix_move_assignment, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using matrix_type = typename tensor_type::matrix_type; + + auto check = [](auto const& e) + { + assert(e.size() == 2); + auto t = tensor_type{}; + auto r = matrix_type(e[0],e[1]); + std::iota(r.data().begin(),r.data().end(), 1); + auto q = r; + t = std::move(r); + + BOOST_CHECK_EQUAL ( t.extents().at(0) , e.at(0) ); + BOOST_CHECK_EQUAL ( t.extents().at(1) , e.at(1) ); + BOOST_CHECK_EQUAL ( t.size() , e.product() ); + BOOST_CHECK_EQUAL ( t.rank() , e.size() ); + BOOST_CHECK ( !t.empty() ); + BOOST_CHECK_NE ( t.data() , nullptr); + + for(auto j = 0ul; j < t.size(1); ++j){ + for(auto i = 0ul; i < t.size(0); ++i){ + BOOST_CHECK_EQUAL( t.at(i,j), q(i,j) ); + } + } + }; + + for(auto const& e : extents) + check(e); +} + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_vector_move_assignment, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using vector_type = typename tensor_type::vector_type; + + auto check = [](auto const& e) + { + assert(e.size() == 2); + auto t = tensor_type{}; + auto r = vector_type(e[0]*e[1]); + std::iota(r.data().begin(),r.data().end(), 1); + auto q = r; + t = std::move(r); + + BOOST_CHECK_EQUAL ( t.extents().at(0) , e.at(0) * e.at(1)); + BOOST_CHECK_EQUAL ( t.extents().at(1) , 1); + BOOST_CHECK_EQUAL ( t.size() , e.product() ); + BOOST_CHECK_EQUAL ( t.rank() , e.size() ); + BOOST_CHECK ( !t.empty() ); + BOOST_CHECK_NE ( t.data() , nullptr); + + for(auto i = 0ul; i < t.size(); ++i){ + BOOST_CHECK_EQUAL( t[i], q(i) ); + } + }; + + for(auto const& e : extents) + check(e); +} + + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_matrix_expressions, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using matrix_type = typename tensor_type::matrix_type; + + auto check = [](auto const& e) + { + assert(e.size() == 2); + auto t = tensor_type{}; + auto r = matrix_type(e[0],e[1]); + std::iota(r.data().begin(),r.data().end(), 1); + t = r + 3*r; + tensor_type s = r + 3*r; + tensor_type q = s + r + 3*r + s; // + 3*r + + + BOOST_CHECK_EQUAL ( t.extents().at(0) , e.at(0) ); + BOOST_CHECK_EQUAL ( t.extents().at(1) , e.at(1) ); + BOOST_CHECK_EQUAL ( t.size() , e.product() ); + BOOST_CHECK_EQUAL ( t.rank() , e.size() ); + BOOST_CHECK ( !t.empty() ); + BOOST_CHECK_NE ( t.data() , nullptr); + + BOOST_CHECK_EQUAL ( s.extents().at(0) , e.at(0) ); + BOOST_CHECK_EQUAL ( s.extents().at(1) , e.at(1) ); + BOOST_CHECK_EQUAL ( s.size() , e.product() ); + BOOST_CHECK_EQUAL ( s.rank() , e.size() ); + BOOST_CHECK ( !s.empty() ); + BOOST_CHECK_NE ( s.data() , nullptr); + + BOOST_CHECK_EQUAL ( q.extents().at(0) , e.at(0) ); + BOOST_CHECK_EQUAL ( q.extents().at(1) , e.at(1) ); + BOOST_CHECK_EQUAL ( q.size() , e.product() ); + BOOST_CHECK_EQUAL ( q.rank() , e.size() ); + BOOST_CHECK ( !q.empty() ); + BOOST_CHECK_NE ( q.data() , nullptr); + + + for(auto j = 0ul; j < t.size(1); ++j){ + for(auto i = 0ul; i < t.size(0); ++i){ + BOOST_CHECK_EQUAL( t.at(i,j), 4*r(i,j) ); + BOOST_CHECK_EQUAL( s.at(i,j), t.at(i,j) ); + BOOST_CHECK_EQUAL( q.at(i,j), 3*s.at(i,j) ); + } + } + }; + + for(auto const& e : extents) + check(e); +} + + + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_vector_expressions, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using vector_type = typename tensor_type::vector_type; + + auto check = [](auto const& e) + { + assert(e.size() == 2); + auto t = tensor_type{}; + auto r = vector_type(e[0]*e[1]); + std::iota(r.data().begin(),r.data().end(), 1); + t = r + 3*r; + tensor_type s = r + 3*r; + tensor_type q = s + r + 3*r + s; // + 3*r + + + BOOST_CHECK_EQUAL ( t.extents().at(0) , e.at(0)*e.at(1) ); + BOOST_CHECK_EQUAL ( t.extents().at(1) , 1); + BOOST_CHECK_EQUAL ( t.size() , e.product() ); + BOOST_CHECK_EQUAL ( t.rank() , e.size() ); + BOOST_CHECK ( !t.empty() ); + BOOST_CHECK_NE ( t.data() , nullptr); + + BOOST_CHECK_EQUAL ( s.extents().at(0) , e.at(0)*e.at(1) ); + BOOST_CHECK_EQUAL ( s.extents().at(1) , 1); + BOOST_CHECK_EQUAL ( s.size() , e.product() ); + BOOST_CHECK_EQUAL ( s.rank() , e.size() ); + BOOST_CHECK ( !s.empty() ); + BOOST_CHECK_NE ( s.data() , nullptr); + + BOOST_CHECK_EQUAL ( q.extents().at(0) , e.at(0)*e.at(1) ); + BOOST_CHECK_EQUAL ( q.extents().at(1) , 1); + BOOST_CHECK_EQUAL ( q.size() , e.product() ); + BOOST_CHECK_EQUAL ( q.rank() , e.size() ); + BOOST_CHECK ( !q.empty() ); + BOOST_CHECK_NE ( q.data() , nullptr); + + + + for(auto i = 0ul; i < t.size(); ++i){ + BOOST_CHECK_EQUAL( t.at(i), 4*r(i) ); + BOOST_CHECK_EQUAL( s.at(i), t.at(i) ); + BOOST_CHECK_EQUAL( q.at(i), 3*s.at(i) ); + } + }; + + for(auto const& e : extents) + check(e); +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_matrix_vector_expressions, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using matrix_type = typename tensor_type::matrix_type; + using vector_type = typename tensor_type::vector_type; + + auto check = [](auto const& e) + { + if(e.product() <= 2) + return; + assert(e.size() == 2); + auto Q = tensor_type{e[0],1}; + auto A = matrix_type(e[0],e[1]); + auto b = vector_type(e[1]); + auto c = vector_type(e[0]); + std::iota(b.data().begin(),b.data().end(), 1); + std::fill(A.data().begin(),A.data().end(), 1); + std::fill(c.data().begin(),c.data().end(), 2); + std::fill(Q.begin(),Q.end(), 2); + + tensor_type T = Q + (ublas::prod(A , b) + 2*c) + 3*Q; + + BOOST_CHECK_EQUAL ( T.extents().at(0) , Q.extents().at(0) ); + BOOST_CHECK_EQUAL ( T.extents().at(1) , Q.extents().at(1)); + BOOST_CHECK_EQUAL ( T.size() , Q.size() ); + BOOST_CHECK_EQUAL ( T.size() , c.size() ); + BOOST_CHECK_EQUAL ( T.rank() , Q.rank() ); + BOOST_CHECK ( !T.empty() ); + BOOST_CHECK_NE ( T.data() , nullptr); + + for(auto i = 0ul; i < T.size(); ++i){ + auto n = e[1]; + auto ab = n * (n+1) / 2; + BOOST_CHECK_EQUAL( T(i), ab+4*Q(0)+2*c(0) ); + } + + }; + + + + for(auto const& e : extents) + check(e); +} + + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/boost/libs/numeric/ublas/test/tensor/utility.hpp b/src/boost/libs/numeric/ublas/test/tensor/utility.hpp new file mode 100644 index 000000000..b2ef266e6 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/utility.hpp @@ -0,0 +1,56 @@ +// Copyright (c) 2018-2019 +// Cem Bassoy +// +// 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) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// + +#ifndef _BOOST_UBLAS_TEST_TENSOR_UTILITY_ +#define _BOOST_UBLAS_TEST_TENSOR_UTILITY_ + +template<class ... types> +struct zip_helper; + +template<class type1, class ... types3> +struct zip_helper<std::tuple<types3...>, type1> +{ + template<class ... types2> + struct with + { + using type = std::tuple<types3...,std::pair<type1,types2>...>; + }; + template<class ... types2> + using with_t = typename with<types2...>::type; +}; + + +template<class type1, class ... types3, class ... types1> +struct zip_helper<std::tuple<types3...>, type1, types1...> +{ + template<class ... types2> + struct with + { + using next_tuple = std::tuple<types3...,std::pair<type1,types2>...>; + using type = typename zip_helper<next_tuple, types1...>::template with<types2...>::type; + }; + + template<class ... types2> + using with_t = typename with<types2...>::type; +}; + +template<class ... types> +using zip = zip_helper<std::tuple<>,types...>; + +// creates e.g. +// using test_types = zip<long,float>::with_t<first_order,last_order>; // equals +// using test_types = std::tuple< std::pair<float, first_order>, std::pair<float, last_order >, std::pair<double,first_order>, std::pair<double,last_order > +//>; +//static_assert(std::is_same< std::tuple_element_t<0,std::tuple_element_t<0,test_types2>>, float>::value,"should be float "); +//static_assert(std::is_same< std::tuple_element_t<1,std::tuple_element_t<0,test_types2>>, boost::numeric::ublas::first_order>::value,"should be boost::numeric::ublas::first_order "); + +#endif diff --git a/src/boost/libs/numeric/ublas/test/test1.cpp b/src/boost/libs/numeric/ublas/test/test1.cpp new file mode 100644 index 000000000..53de79019 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test1.cpp @@ -0,0 +1,20 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test1.hpp" + +int main () { + test_vector (); + test_matrix_vector (); + test_matrix (); + return 0; +} diff --git a/src/boost/libs/numeric/ublas/test/test1.hpp b/src/boost/libs/numeric/ublas/test/test1.hpp new file mode 100644 index 000000000..fcf3d67a5 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test1.hpp @@ -0,0 +1,33 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#ifndef TEST1_H +#define TEST1_H + +#include <iostream> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/vector_proxy.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_proxy.hpp> +#include <boost/numeric/ublas/io.hpp> + +namespace ublas = boost::numeric::ublas; + +#include "common/init.hpp" + +void test_vector (); +void test_matrix_vector (); +void test_matrix (); + + +#endif diff --git a/src/boost/libs/numeric/ublas/test/test11.cpp b/src/boost/libs/numeric/ublas/test/test11.cpp new file mode 100644 index 000000000..2d3d27527 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test11.cpp @@ -0,0 +1,265 @@ +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. + +#include "test1.hpp" + +// Test vector expression templates +template<class V, int N> +struct test_my_vector { + typedef typename V::value_type value_type; + typedef typename V::size_type size_type; + typedef typename ublas::type_traits<value_type>::real_type real_type; + + template<class VP> + void test_container_with (VP &v1) const { + // Container type tests in addition to expression types + // Insert and erase + v1.insert_element (0, 55); + v1.erase_element (1); + v1.clear (); + } + + template<class VP> + void test_expression_with (VP &v1, VP &v2, VP &v3) const { + // Expression type tests + value_type t; + size_type i; + real_type n; + + // Default Construct + default_construct<VP>::test (); + + // Copy and swap + initialize_vector (v1); + initialize_vector (v2); + v1 = v2; + std::cout << "v1 = v2 = " << v1 << std::endl; + v1.assign_temporary (v2); + std::cout << "v1.assign_temporary (v2) = " << v1 << std::endl; + v1.swap (v2); + std::cout << "v1.swap (v2) = " << v1 << " " << v2 << std::endl; + + // Zero assignment + v1 = ublas::zero_vector<> (v1.size ()); + std::cout << "v1.zero_vector = " << v1 << std::endl; + v1 = v2; + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + // Project range and slice + initialize_vector (v1); + initialize_vector (v2); + project (v1, ublas::range(0,1)) = project (v2, ublas::range(0,1)); + project (v1, ublas::range(0,1)) = project (v2, ublas::slice(0,1,1)); + project (v1, ublas::slice(2,-1,2)) = project (v2, ublas::slice(0,1,2)); + project (v1, ublas::slice(2,-1,2)) = project (v2, ublas::range(0,2)); + std::cout << "v1 = range/slice " << v1 << std::endl; +#endif + + // Unary vector operations resulting in a vector + initialize_vector (v1); + v2 = - v1; + std::cout << "- v1 = " << v2 << std::endl; + v2 = ublas::conj (v1); + std::cout << "conj (v1) = " << v2 << std::endl; + + // Binary vector operations resulting in a vector + initialize_vector (v1); + initialize_vector (v2); + v3 = v1 + v2; + std::cout << "v1 + v2 = " << v3 << std::endl; + v3 = v1 - v2; + std::cout << "v1 - v2 = " << v3 << std::endl; + v3 = ublas::element_prod (v1, v2); + std::cout << "element_prod (v1, v2) = " << v3 << std::endl; + + // Scaling a vector + t = N; + initialize_vector (v1); + v2 = value_type (1.) * v1; + std::cout << "1. * v1 = " << v2 << std::endl; + v2 = t * v1; + std::cout << "N * v1 = " << v2 << std::endl; + initialize_vector (v1); + v2 = v1 * value_type (1.); + std::cout << "v1 * 1. = " << v2 << std::endl; + v2 = v1 * t; + std::cout << "v1 * value_type(N) = " << v2 << std::endl; + // test interop with integer + v2 = v1 * N; + + std::cout << "v1 * N = " << v2 << std::endl; + + // Some assignments + initialize_vector (v1); + initialize_vector (v2); + v2 += v1; + std::cout << "v2 += v1 = " << v2 << std::endl; + v2 -= v1; + std::cout << "v2 -= v1 = " << v2 << std::endl; + v2 = v2 + v1; + std::cout << "v2 = v2 + v1 = " << v2 << std::endl; + v2 = v2 - v1; + std::cout << "v2 = v2 - v1 = " << v2 << std::endl; + v1 *= value_type (1.); + std::cout << "v1 *= 1. = " << v1 << std::endl; + v1 *= t; + std::cout << "v1 *= value_type(N) = " << v1 << std::endl; + // test interop with integer + v1 *= N; + std::cout << "v1 *= N = " << v1 << std::endl; + + // Unary vector operations resulting in a scalar + initialize_vector (v1); + t = ublas::sum (v1); + std::cout << "sum (v1) = " << t << std::endl; + n = ublas::norm_1 (v1); + std::cout << "norm_1 (v1) = " << n << std::endl; + n = ublas::norm_2 (v1); + std::cout << "norm_2 (v1) = " << n << std::endl; + n = ublas::norm_inf (v1); + std::cout << "norm_inf (v1) = " << n << std::endl; + + i = ublas::index_norm_inf (v1); + std::cout << "index_norm_inf (v1) = " << i << std::endl; + + // Binary vector operations resulting in a scalar + initialize_vector (v1); + initialize_vector (v2); + t = ublas::inner_prod (v1, v2); + std::cout << "inner_prod (v1, v2) = " << t << std::endl; + + // Scalar and Binary vector expression resulting in a vector + initialize_vector (v1); + initialize_vector (v2); + v1 = v1 * ublas::inner_prod (v1, v2); + std::cout << "v1 * inner_prod (v1, v2) = " << v1 << std::endl; + } + + void operator () () const { + V v1 (N), v2 (N), v3 (N); + test_expression_with (v1, v2, v3); + test_container_with (v1); + +#ifdef USE_RANGE + ublas::vector_range<V> vr1 (v1, ublas::range (0, N)), + vr2 (v2, ublas::range (0, N)), + vr3 (v3, ublas::range (0, N)); + test_expression_with (vr1, vr2, vr3); +#endif + +#ifdef USE_SLICE + ublas::vector_slice<V> vs1 (v1, ublas::slice (0, 1, N)), + vs2 (v2, ublas::slice (0, 1, N)), + vs3 (v3, ublas::slice (0, 1, N)); + test_expression_with (vs1, vs2, vs3); +#endif + } +}; + +// Test vector +void test_vector () { + std::cout << "test_vector" << std::endl; + +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_vector<ublas::vector<float, ublas::bounded_array<float, 3> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_vector<ublas::vector<double, ublas::bounded_array<double, 3> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_vector<ublas::vector<float, ublas::unbounded_array<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_vector<ublas::vector<double, ublas::unbounded_array<double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_vector<ublas::vector<float, std::vector<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_vector<ublas::vector<double, std::vector<double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_BOUNDED_VECTOR +#ifdef USE_FLOAT + std::cout << "float, bounded" << std::endl; + test_my_vector<ublas::bounded_vector<float, 3>, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded" << std::endl; + test_my_vector<ublas::bounded_vector<double, 3>, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded" << std::endl; + test_my_vector<ublas::bounded_vector<std::complex<float>, 3>, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded" << std::endl; + test_my_vector<ublas::bounded_vector<std::complex<double>, 3>, 3> () (); +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test12.cpp b/src/boost/libs/numeric/ublas/test/test12.cpp new file mode 100644 index 000000000..8c9e61da0 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test12.cpp @@ -0,0 +1,277 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test1.hpp" + +// Test matrix & vector expression templates +template<class V, class M, int N> +struct test_my_matrix_vector { + typedef typename V::value_type value_type; + + template<class VP, class MP> + void test_with (VP &v1, VP &v2, MP &m1) const { + { + // Rows and columns + initialize_matrix (m1); + for (int i = 0; i < N; ++ i) { + v1 = ublas::row (m1, i); + std::cout << "row (m, " << i << ") = " << v1 << std::endl; + v1 = ublas::column (m1, i); + std::cout << "column (m, " << i << ") = " << v1 << std::endl; + } + + // Outer product + initialize_vector (v1); + initialize_vector (v2); + m1 = ublas::outer_prod (v1, v2); + std::cout << "outer_prod (v1, v2) = " << m1 << std::endl; + + // Matrix vector product + initialize_matrix (m1); + initialize_vector (v1); + v2 = ublas::prod (m1, v1); + std::cout << "prod (m1, v1) = " << v2 << std::endl; + v2 = ublas::prod (v1, m1); + std::cout << "prod (v1, m1) = " << v2 << std::endl; + } + } + void operator () () const { + { + V v1 (N), v2 (N); + M m1 (N, N); + test_with (v1, v2, m1); + + ublas::matrix_row<M> mr1 (m1, 0), mr2 (m1, 1); + test_with (mr1, mr2, m1); + + ublas::matrix_column<M> mc1 (m1, 0), mc2 (m1, 1); + test_with (mc1, mc2, m1); + +#ifdef USE_RANGE + ublas::matrix_vector_range<M> mvr1 (m1, ublas::range (0, N), ublas::range (0, N)), + mvr2 (m1, ublas::range (0, N), ublas::range (0, N)); + test_with (mvr1, mvr2, m1); +#endif + +#ifdef USE_SLICE + ublas::matrix_vector_slice<M> mvs1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + mvs2 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (mvs1, mvs2, m1); +#endif + } + } +}; + +// Test matrix & vector +void test_matrix_vector () { + std::cout << "test_matrix_vector" << std::endl; + +#ifdef USE_MATRIX +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >, + ublas::matrix<float, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >, + ublas::matrix<double, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >, + ublas::matrix<std::complex<float>, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >, + ublas::matrix<std::complex<double>, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () (); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >, + ublas::matrix<float, ublas::row_major, ublas::unbounded_array<float> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >, + ublas::matrix<double, ublas::row_major, ublas::unbounded_array<double> >, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >, + ublas::matrix<std::complex<float>, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >, + ublas::matrix<std::complex<double>, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () (); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<float, std::vector<float> >, + ublas::matrix<float, ublas::row_major, std::vector<float> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<double, std::vector<double> >, + ublas::matrix<double, ublas::row_major, std::vector<double> >, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >, + ublas::matrix<std::complex<float>, ublas::row_major, std::vector<std::complex<float> > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >, + ublas::matrix<std::complex<double>, ublas::row_major, std::vector<std::complex<double> > >, 3> () (); +#endif +#endif +#endif +#endif + +#ifdef USE_BOUNDED_MATRIX +#ifdef USE_FLOAT + std::cout << "float, bounded" << std::endl; + test_my_matrix_vector<ublas::bounded_vector<float, 3>, + ublas::bounded_matrix<float, 3, 3>, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded" << std::endl; + test_my_matrix_vector<ublas::bounded_vector<double, 3>, + ublas::bounded_matrix<double, 3, 3>, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded" << std::endl; + test_my_matrix_vector<ublas::bounded_vector<std::complex<float>, 3>, + ublas::bounded_matrix<std::complex<float>, 3, 3>, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded" << std::endl; + test_my_matrix_vector<ublas::bounded_vector<std::complex<double>, 3>, + ublas::bounded_matrix<std::complex<double>, 3, 3>, 3> () (); +#endif +#endif +#endif + +#ifdef USE_VECTOR_OF_VECTOR +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >, + ublas::vector_of_vector<float, ublas::row_major, ublas::bounded_array<ublas::bounded_array<float, 3>, 3 + 1> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >, + ublas::vector_of_vector<double, ublas::row_major, ublas::bounded_array<ublas::bounded_array<double, 3>, 3 + 1> >, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >, + ublas::vector_of_vector<std::complex<float>, ublas::row_major, ublas::bounded_array<ublas::bounded_array<std::complex<float>, 3>, 3 + 1> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >, + ublas::vector_of_vector<std::complex<double>, ublas::row_major, ublas::bounded_array<ublas::bounded_array<std::complex<double>, 3>, 3 + 1> >, 3> () (); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >, + ublas::vector_of_vector<float, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<float> > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >, + ublas::vector_of_vector<double, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<double> > >, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >, + ublas::vector_of_vector<std::complex<float>, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<std::complex<float> > > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >, + ublas::vector_of_vector<std::complex<double>, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<std::complex<double> > > >, 3> () (); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<float, std::vector<float> >, + ublas::vector_of_vector<float, ublas::row_major, std::vector<std::vector<float> > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<double, std::vector<double> >, + ublas::vector_of_vector<double, ublas::row_major, std::vector<std::vector<double> > >, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >, + ublas::vector_of_vector<std::complex<float>, ublas::row_major, std::vector<std::vector<std::complex<float> > > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >, + ublas::vector_of_vector<std::complex<double>, ublas::row_major, std::vector<std::vector<std::complex<double> > > >, 3> () (); +#endif +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test13.cpp b/src/boost/libs/numeric/ublas/test/test13.cpp new file mode 100644 index 000000000..d84f321fe --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test13.cpp @@ -0,0 +1,325 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test1.hpp" + +// Test matrix expression templates +template<class M, int N> +struct test_my_matrix { + typedef typename M::value_type value_type; + + template<class VP> + void test_container_with (VP &v1) const { + // Container type tests in addition to expression types + // Insert and erase + v1.insert_element (0,0, 55); + v1.erase_element (1,1); + v1.clear (); + } + + template<class MP> + void test_expression_with (MP &m1, MP &m2, MP &m3) const { + value_type t; + + // Default Construct + default_construct<MP>::test (); + + // Copy and swap + initialize_matrix (m1); + initialize_matrix (m2); + m1 = m2; + std::cout << "m1 = m2 = " << m1 << std::endl; + m1.assign_temporary (m2); + std::cout << "m1.assign_temporary (m2) = " << m1 << std::endl; + m1.swap (m2); + std::cout << "m1.swap (m2) = " << m1 << " " << m2 << std::endl; + + // Zero assignment + m1 = ublas::zero_matrix<> (m1.size1 (), m1.size2 ()); + std::cout << "m1.zero_matrix = " << m1 << std::endl; + m1 = m2; + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + // Project range and slice + initialize_matrix (m1); + initialize_matrix (m2); + project (m1, ublas::range(0,1),ublas::range(0,1)) = project (m2, ublas::range(0,1),ublas::range(0,1)); + project (m1, ublas::range(0,1),ublas::range(0,1)) = project (m2, ublas::slice(0,1,1),ublas::slice(0,1,1)); + project (m1, ublas::slice(2,-1,2),ublas::slice(2,-1,2)) = project (m2, ublas::slice(0,1,2),ublas::slice(0,1,2)); + project (m1, ublas::slice(2,-1,2),ublas::slice(2,-1,2)) = project (m2, ublas::range(0,2),ublas::range(0,2)); + std::cout << "m1 = range/slice " << m1 << std::endl; +#endif + + // Unary matrix operations resulting in a matrix + initialize_matrix (m1); + m2 = - m1; + std::cout << "- m1 = " << m2 << std::endl; + m2 = ublas::conj (m1); + std::cout << "conj (m1) = " << m2 << std::endl; + + // Binary matrix operations resulting in a matrix + initialize_matrix (m1); + initialize_matrix (m2); + m3 = m1 + m2; + std::cout << "m1 + m2 = " << m3 << std::endl; + m3 = m1 - m2; + std::cout << "m1 - m2 = " << m3 << std::endl; + m3 = ublas::element_prod (m1, m2); + std::cout << "element_prod (m1, m2) = " << m3 << std::endl; + + // Scaling a matrix + t = N; + initialize_matrix (m1); + m2 = value_type (1.) * m1; + std::cout << "1. * m1 = " << m2 << std::endl; + m2 = t * m1; + std::cout << "N * m1 = " << m2 << std::endl; + initialize_matrix (m1); + m2 = m1 * value_type (1.); + std::cout << "m1 * 1. = " << m2 << std::endl; + m2 = m1 * t; + std::cout << "m1 * N = " << m2 << std::endl; + m2 = m1 / value_type (2.); + std::cout << "m1 / 2. = " << m2 << std::endl; + m2 = m1 / t; + std::cout << "m1 / N = " << m2 << std::endl; + + // Some assignments + initialize_matrix (m1); + initialize_matrix (m2); + m2 += m1; + std::cout << "m2 += m1 = " << m2 << std::endl; + m2 -= m1; + std::cout << "m2 -= m1 = " << m2 << std::endl; + m2 = m2 + m1; + std::cout << "m2 = m2 + m1 = " << m2 << std::endl; + m2 = m2 - m1; + std::cout << "m2 = m2 - m1 = " << m2 << std::endl; + m1 *= value_type (1.); + std::cout << "m1 *= 1. = " << m1 << std::endl; + m1 *= t; + std::cout << "m1 *= N = " << m1 << std::endl; + + // Transpose + initialize_matrix (m1); + m2 = ublas::trans (m1); + std::cout << "trans (m1) = " << m2 << std::endl; + + // Hermitean + initialize_matrix (m1); + m2 = ublas::herm (m1); + std::cout << "herm (m1) = " << m2 << std::endl; + + // Matrix multiplication + initialize_matrix (m1); + initialize_matrix (m2); + m3 = ublas::prod (m1, m2); + std::cout << "prod (m1, m2) = " << m3 << std::endl; + } + + void operator () () const { + M m1 (N, N), m2 (N, N), m3 (N, N); + test_expression_with (m1, m2, m3); + test_container_with (m1); + +#ifdef USE_RANGE + ublas::matrix_range<M> mr1 (m1, ublas::range (0, N), ublas::range (0, N)), + mr2 (m2, ublas::range (0, N), ublas::range (0, N)), + mr3 (m3, ublas::range (0, N), ublas::range (0, N)); + test_expression_with (mr1, mr2, mr3); +#endif + +#ifdef USE_SLICE + ublas::matrix_slice<M> ms1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms2 (m2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms3 (m3, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_expression_with (ms1, ms2, ms3); +#endif + } +}; + +// Test matrix +void test_matrix () { + std::cout << "test_matrix" << std::endl; + +#ifdef USE_MATRIX +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_matrix<ublas::matrix<float, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_matrix<ublas::matrix<double, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_matrix<ublas::matrix<std::complex<float>, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_matrix<ublas::matrix<std::complex<double>, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () (); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_matrix<ublas::matrix<float, ublas::row_major, ublas::unbounded_array<float> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_matrix<ublas::matrix<double, ublas::row_major, ublas::unbounded_array<double> >, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_matrix<ublas::matrix<std::complex<float>, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_matrix<ublas::matrix<std::complex<double>, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () (); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_matrix<ublas::matrix<float, ublas::row_major, std::vector<float> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_matrix<ublas::matrix<double, ublas::row_major, std::vector<double> >, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_matrix<ublas::matrix<std::complex<float>, ublas::row_major, std::vector<std::complex<float> > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_matrix<ublas::matrix<std::complex<double>, ublas::row_major, std::vector<std::complex<double> > >, 3> () (); +#endif +#endif +#endif +#endif + +#ifdef USE_BOUNDED_MATRIX +#ifdef USE_FLOAT + std::cout << "float, bounded" << std::endl; + test_my_matrix<ublas::bounded_matrix<float, 3, 3>, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded" << std::endl; + test_my_matrix<ublas::bounded_matrix<double, 3, 3>, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded" << std::endl; + test_my_matrix<ublas::bounded_matrix<std::complex<float>, 3, 3>, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded" << std::endl; + test_my_matrix<ublas::bounded_matrix<std::complex<double>, 3, 3>, 3> () (); +#endif +#endif +#endif + +#ifdef USE_VECTOR_OF_VECTOR +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_matrix<ublas::vector_of_vector<float, ublas::row_major, ublas::bounded_array<ublas::bounded_array<float, 3>, 3 + 1> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_matrix<ublas::vector_of_vector<double, ublas::row_major, ublas::bounded_array<ublas::bounded_array<double, 3>, 3 + 1> >, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_matrix<ublas::vector_of_vector<std::complex<float>, ublas::row_major, ublas::bounded_array<ublas::bounded_array<std::complex<float>, 3>, 3 + 1> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_matrix<ublas::vector_of_vector<std::complex<double>, ublas::row_major, ublas::bounded_array<ublas::bounded_array<std::complex<double>, 3>, 3 + 1> >, 3> () (); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_matrix<ublas::vector_of_vector<float, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<float> > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_matrix<ublas::vector_of_vector<double, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<double> > >, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_matrix<ublas::vector_of_vector<std::complex<float>, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<std::complex<float> > > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_matrix<ublas::vector_of_vector<std::complex<double>, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<std::complex<double> > > >, 3> () (); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_matrix<ublas::vector_of_vector<float, ublas::row_major, std::vector<std::vector<float > > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_matrix<ublas::vector_of_vector<double, ublas::row_major, std::vector<std::vector<double> > >, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_matrix<ublas::vector_of_vector<std::complex<float>, ublas::row_major, std::vector<std::vector<std::complex<float> > > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_matrix<ublas::vector_of_vector<std::complex<double>, ublas::row_major, std::vector<std::vector<std::complex<double> > > >, 3> () (); +#endif +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test2.cpp b/src/boost/libs/numeric/ublas/test/test2.cpp new file mode 100644 index 000000000..07a4c7558 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test2.cpp @@ -0,0 +1,87 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test2.hpp" + +int main () { +#ifdef USE_FLOAT + std::cout << "float" << std::endl; + test_blas_1<ublas::vector<float>, 3> ().test (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double" << std::endl; + test_blas_1<ublas::vector<double>, 3> ().test (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>" << std::endl; + test_blas_1<ublas::vector<std::complex<float> >, 3> ().test (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>" << std::endl; + test_blas_1<ublas::vector<std::complex<double> >, 3> ().test (); +#endif +#endif + + std::cout << "test_blas_2" << std::endl; + +#ifdef USE_FLOAT + std::cout << "float" << std::endl; + test_blas_2<ublas::vector<float>, ublas::matrix<float>, 3> ().test (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double" << std::endl; + test_blas_2<ublas::vector<double>, ublas::matrix<double>, 3> ().test (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>" << std::endl; + test_blas_2<ublas::vector<std::complex<float> >, ublas::matrix<std::complex<float> >, 3> ().test (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>" << std::endl; + test_blas_2<ublas::vector<std::complex<double> >, ublas::matrix<std::complex<double> >, 3> ().test (); +#endif +#endif + + std::cout << "test_blas_3" << std::endl; + +#ifdef USE_FLOAT + std::cout << "float" << std::endl; + test_blas_3<ublas::matrix<float>, 3> ().test (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double" << std::endl; + test_blas_3<ublas::matrix<double>, 3> ().test (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>" << std::endl; + test_blas_3<ublas::matrix<std::complex<float> >, 3> ().test (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>" << std::endl; + test_blas_3<ublas::matrix<std::complex<double> >, 3> ().test (); +#endif +#endif + + return 0; +} diff --git a/src/boost/libs/numeric/ublas/test/test2.hpp b/src/boost/libs/numeric/ublas/test/test2.hpp new file mode 100644 index 000000000..d4d4baa57 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test2.hpp @@ -0,0 +1,51 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#ifndef TEST2_H +#define TEST2_H + +#include <iostream> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/triangular.hpp> +#include <boost/numeric/ublas/io.hpp> +#include <boost/numeric/ublas/blas.hpp> + +namespace ublas = boost::numeric::ublas; + +#include "common/init.hpp" + +template<class V, std::size_t N> +struct test_blas_1 { + typedef typename V::value_type value_type; + typedef typename ublas::type_traits<value_type>::real_type real_type; + + void test (); +}; + +template<class V, class M, std::size_t N> +struct test_blas_2 { + typedef typename V::value_type value_type; + + void test (); +}; + +template<class M, std::size_t N> +struct test_blas_3 { + typedef typename M::value_type value_type; + + void test (); +}; + + +#endif diff --git a/src/boost/libs/numeric/ublas/test/test21.cpp b/src/boost/libs/numeric/ublas/test/test21.cpp new file mode 100644 index 000000000..408b17dc0 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test21.cpp @@ -0,0 +1,95 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test2.hpp" + +template<class V, std::size_t N> +void test_blas_1<V, N>::test () { + { + value_type t; + real_type n; + V v1 (N), v2 (N); + + // _asum + initialize_vector (v1); + n = ublas::blas_1::asum (v1); + std::cout << "asum (v1) = " << n << std::endl; + + // _amax + initialize_vector (v1); + n = ublas::blas_1::amax (v1); + std::cout << "amax (v1) = " << n << std::endl; + + // _nrm2 + initialize_vector (v1); + n = ublas::blas_1::nrm2 (v1); + std::cout << "nrm2 (v1) = " << n << std::endl; + + // _dot + // _dotu + // _dotc + initialize_vector (v1); + initialize_vector (v2); + t = ublas::blas_1::dot (v1, v2); + std::cout << "dot (v1, v2) = " << t << std::endl; + t = ublas::blas_1::dot (ublas::conj (v1), v2); + std::cout << "dot (conj (v1), v2) = " << t << std::endl; + + // _copy + initialize_vector (v2); + ublas::blas_1::copy (v1, v2); + std::cout << "copy (v1, v2) = " << v1 << std::endl; + + // _swap + initialize_vector (v1); + initialize_vector (v2); + ublas::blas_1::swap (v1, v2); + std::cout << "swap (v1, v2) = " << v1 << " " << v2 << std::endl; + + // _scal + // csscal + // zdscal + initialize_vector (v1); + ublas::blas_1::scal (v1, value_type (1)); + std::cout << "scal (v1, 1) = " << v1 << std::endl; + + // _axpy + initialize_vector (v1); + initialize_vector (v2); + ublas::blas_1::axpy (v1, value_type (1), v2); + std::cout << "axpy (v1, 1, v2) = " << v1 << std::endl; + + // _rot + initialize_vector (v1); + initialize_vector (v2); + ublas::blas_1::rot (value_type (1), v1, value_type (1), v2); + std::cout << "rot (1, v1, 1, v2) = " << v1 << " " << v2 << std::endl; + } +} + +#ifdef USE_FLOAT +template struct test_blas_1<ublas::vector<float>, 3>; +#endif + +#ifdef USE_DOUBLE +template struct test_blas_1<ublas::vector<double>, 3>; +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT +template struct test_blas_1<ublas::vector<std::complex<float> >, 3>; +#endif + +#ifdef USE_DOUBLE +template struct test_blas_1<ublas::vector<std::complex<double> >, 3>; +#endif +#endif diff --git a/src/boost/libs/numeric/ublas/test/test22.cpp b/src/boost/libs/numeric/ublas/test/test22.cpp new file mode 100644 index 000000000..13b313ea4 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test22.cpp @@ -0,0 +1,147 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test2.hpp" + +template<class V, class M, std::size_t N> +void test_blas_2<V, M, N>::test () { + { + V v1 (N), v2 (N); + M m (N, N); + + // _t_mv + initialize_vector (v1); + initialize_matrix (m); + ublas::blas_2::tmv (v1, m); + std::cout << "tmv (v1, m) = " << v1 << std::endl; + initialize_vector (v1); + initialize_matrix (m); + ublas::blas_2::tmv (v1, ublas::trans (m)); + std::cout << "tmv (v1, trans (m)) = " << v1 << std::endl; +#ifdef USE_STD_COMPLEX + initialize_vector (v1); + initialize_matrix (m); + ublas::blas_2::tmv (v1, ublas::herm (m)); + std::cout << "tmv (v1, herm (m)) = " << v1 << std::endl; +#endif + + // _t_sv + initialize_vector (v1); + initialize_vector (v2); + initialize_matrix (m, ublas::lower_tag ()); + ublas::blas_2::tsv (v1, m, ublas::lower_tag ()); + std::cout << "tsv (v1, m) = " << v1 << " " << ublas::prod (m, v1) - v2 << std::endl; + initialize_vector (v1); + initialize_vector (v2); + initialize_matrix (m, ublas::upper_tag ()); + ublas::blas_2::tsv (v1, ublas::trans (m), ublas::lower_tag ()); + std::cout << "tsv (v1, trans (m)) = " << v1 << " " << ublas::prod (ublas::trans (m), v1) - v2 << std::endl; +#ifdef USE_STD_COMPLEX + initialize_vector (v1); + initialize_vector (v2); + initialize_matrix (m, ublas::upper_tag ()); + ublas::blas_2::tsv (v1, ublas::herm (m), ublas::lower_tag ()); + std::cout << "tsv (v1, herm (m)) = " << v1 << " " << ublas::prod (ublas::herm (m), v1) - v2 << std::endl; +#endif + initialize_vector (v1); + initialize_vector (v2); + initialize_matrix (m, ublas::upper_tag ()); + ublas::blas_2::tsv (v1, m, ublas::upper_tag ()); + std::cout << "tsv (v1, m) = " << v1 << " " << ublas::prod (m, v1) - v2 << std::endl; + initialize_vector (v1); + initialize_vector (v2); + initialize_matrix (m, ublas::lower_tag ()); + ublas::blas_2::tsv (v1, ublas::trans (m), ublas::upper_tag ()); + std::cout << "tsv (v1, trans (m)) = " << v1 << " " << ublas::prod (ublas::trans (m), v1) - v2 << std::endl; +#ifdef USE_STD_COMPLEX + initialize_vector (v1); + initialize_vector (v2); + initialize_matrix (m, ublas::lower_tag ()); + ublas::blas_2::tsv (v1, ublas::herm (m), ublas::upper_tag ()); + std::cout << "tsv (v1, herm (m)) = " << v1 << " " << ublas::prod (ublas::herm (m), v1) - v2 << std::endl; +#endif + + // _g_mv + // _s_mv + // _h_mv + initialize_vector (v1); + initialize_vector (v2); + initialize_matrix (m); + ublas::blas_2::gmv (v1, value_type (1), value_type (1), m, v2); + std::cout << "gmv (v1, 1, 1, m, v2) = " << v1 << std::endl; + ublas::blas_2::gmv (v1, value_type (1), value_type (1), ublas::trans (m), v2); + std::cout << "gmv (v1, 1, 1, trans (m), v2) = " << v1 << std::endl; +#ifdef USE_STD_COMPLEX + ublas::blas_2::gmv (v1, value_type (1), value_type (1), ublas::herm (m), v2); + std::cout << "gmv (v1, 1, 1, herm (m), v2) = " << v1 << std::endl; +#endif + + // _g_r + // _g_ru + // _g_rc + initialize_vector (v1); + initialize_vector (v2); + initialize_matrix (m); + ublas::blas_2::gr (m, value_type (1), v1, v2); + std::cout << "gr (m, 1, v1, v2) = " << m << std::endl; + ublas::blas_2::gr (m, value_type (1), v1, ublas::conj (v2)); + std::cout << "gr (m, 1, v1, conj (v2)) = " << m << std::endl; + + // _s_r + initialize_vector (v1); + initialize_matrix (m); + ublas::blas_2::sr (m, value_type (1), v1); + std::cout << "sr (m, 1, v1) = " << m << std::endl; + +#ifdef USE_STD_COMPLEX + // _h_r + initialize_vector (v1); + initialize_matrix (m); + ublas::blas_2::hr (m, value_type (1), v1); + std::cout << "hr (m, 1, v1) = " << m << std::endl; +#endif + + // _s_r2 + initialize_vector (v1); + initialize_vector (v2); + initialize_matrix (m); + ublas::blas_2::sr2 (m, value_type (1), v1, v2); + std::cout << "sr2 (m, 1, v1, v2) = " << m << std::endl; + +#ifdef USE_STD_COMPLEX + // _h_r2 + initialize_vector (v1); + initialize_vector (v2); + initialize_matrix (m); + ublas::blas_2::hr2 (m, value_type (1), v1, v2); + std::cout << "hr2 (m, 1, v1, v2) = " << m << std::endl; +#endif + } +} + +#ifdef USE_FLOAT +template struct test_blas_2<ublas::vector<float>, ublas::matrix<float>, 3>; +#endif + +#ifdef USE_DOUBLE +template struct test_blas_2<ublas::vector<double>, ublas::matrix<double>, 3>; +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT +template struct test_blas_2<ublas::vector<std::complex<float> >, ublas::matrix<std::complex<float> >, 3>; +#endif + +#ifdef USE_DOUBLE +template struct test_blas_2<ublas::vector<std::complex<double> >, ublas::matrix<std::complex<double> >, 3>; +#endif +#endif diff --git a/src/boost/libs/numeric/ublas/test/test23.cpp b/src/boost/libs/numeric/ublas/test/test23.cpp new file mode 100644 index 000000000..2817710cf --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test23.cpp @@ -0,0 +1,208 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test2.hpp" + +template<class M, std::size_t N> +void test_blas_3<M, N>::test () { + { + M m1 (N, N), m2 (N, N), m3 (N, N); + + // _t_mm + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::tmm (m1, value_type (1), m2, m1); + std::cout << "tmm (m1, 1, m2, m1) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::tmm (m1, value_type (1), m2, ublas::trans (m1)); + std::cout << "tmm (m1, 1, m2, trans (m1)) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::tmm (m1, value_type (1), ublas::trans (m2), m1); + std::cout << "tmm (m1, 1, trans (m2), m1) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::tmm (m1, value_type (1), ublas::trans (m2), ublas::trans (m1)); + std::cout << "tmm (m1, 1, trans (m2), trans (m1)) = " << m1 << std::endl; +#ifdef USE_STD_COMPLEX + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::tmm (m1, value_type (1), m2, ublas::herm (m1)); + std::cout << "tmm (m1, 1, m2, herm (m1)) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::tmm (m1, value_type (1), ublas::herm (m2), m1); + std::cout << "tmm (m1, 1, herm (m2), m1) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::tmm (m1, value_type (1), ublas::trans (m2), ublas::herm (m1)); + std::cout << "tmm (m1, 1, trans (m2), herm (m1)) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::tmm (m1, value_type (1), ublas::herm (m2), ublas::trans (m1)); + std::cout << "tmm (m1, 1, herm (m2), trans (m1)) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::tmm (m1, value_type (1), ublas::herm (m2), ublas::herm (m1)); + std::cout << "tmm (m1, 1, herm (m2), herm (m1)) = " << m1 << std::endl; +#endif + + // _t_sm + initialize_matrix (m1); + initialize_matrix (m2, ublas::lower_tag ()); + initialize_matrix (m3); + ublas::blas_3::tsm (m1, value_type (1), m2, ublas::lower_tag ()); + std::cout << "tsm (m1, 1, m2) = " << m1 << " " << ublas::prod (m2, m1) - value_type (1) * m3 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2, ublas::upper_tag ()); + ublas::blas_3::tsm (m1, value_type (1), ublas::trans (m2), ublas::lower_tag ()); + std::cout << "tsm (m1, 1, trans (m2)) = " << m1 << " " << ublas::prod (ublas::trans (m2), m1) - value_type (1) * m3 << std::endl; +#ifdef USE_STD_COMPLEX + initialize_matrix (m1); + initialize_matrix (m2, ublas::upper_tag ()); + ublas::blas_3::tsm (m1, value_type (1), ublas::herm (m2), ublas::lower_tag ()); + std::cout << "tsm (m1, 1, herm (m2)) = " << m1 << " " << ublas::prod (ublas::herm (m2), m1) - value_type (1) * m3 << std::endl; +#endif + initialize_matrix (m1); + initialize_matrix (m2, ublas::upper_tag ()); + ublas::blas_3::tsm (m1, value_type (1), m2, ublas::upper_tag ()); + std::cout << "tsm (m1, 1, m2) = " << m1 << " " << ublas::prod (m2, m1) - value_type (1) * m3 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2, ublas::lower_tag ()); + ublas::blas_3::tsm (m1, value_type (1), ublas::trans (m2), ublas::upper_tag ()); + std::cout << "tsm (m1, 1, trans (m2)) = " << m1 << " " << ublas::prod (ublas::trans (m2), m1) - value_type (1) * m3 << std::endl; +#ifdef USE_STD_COMPLEX + initialize_matrix (m1); + initialize_matrix (m2, ublas::lower_tag ()); + ublas::blas_3::tsm (m1, value_type (1), ublas::herm (m2), ublas::upper_tag ()); + std::cout << "tsm (m1, 1, herm (m2)) = " << m1 << " " << ublas::prod (ublas::herm (m2), m1) - value_type (1) * m3 << std::endl; +#endif + + // _g_mm + // _s_mm + // _h_mm + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::gmm (m1, value_type (1), value_type (1), m2, m3); + std::cout << "gmm (m1, 1, 1, m2, m3) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::gmm (m1, value_type (1), value_type (1), ublas::trans (m2), m3); + std::cout << "gmm (m1, 1, 1, trans (m2), m3) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::gmm (m1, value_type (1), value_type (1), m2, ublas::trans (m3)); + std::cout << "gmm (m1, 1, 1, m2, trans (m3)) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::gmm (m1, value_type (1), value_type (1), ublas::trans (m2), ublas::trans (m3)); + std::cout << "gmm (m1, 1, 1, trans (m2), trans (m3)) = " << m1 << std::endl; +#ifdef USE_STD_COMPLEX + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::gmm (m1, value_type (1), value_type (1), ublas::herm (m2), m3); + std::cout << "gmm (m1, 1, 1, herm (m2), m3) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::gmm (m1, value_type (1), value_type (1), m2, ublas::herm (m3)); + std::cout << "gmm (m1, 1, 1, m2, herm (m3)) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::gmm (m1, value_type (1), value_type (1), ublas::herm (m2), ublas::trans (m3)); + std::cout << "gmm (m1, 1, 1, herm (m2), trans (m3)) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::gmm (m1, value_type (1), value_type (1), ublas::trans (m2), ublas::herm (m3)); + std::cout << "gmm (m1, 1, 1, trans (m2), herm (m3)) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::gmm (m1, value_type (1), value_type (1), ublas::herm (m2), ublas::herm (m3)); + std::cout << "gmm (m1, 1, 1, herm (m2), herm (m3)) = " << m1 << std::endl; +#endif + + // s_rk + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::srk (m1, value_type (1), value_type (1), m2); + std::cout << "srk (m1, 1, 1, m2) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::srk (m1, value_type (1), value_type (1), ublas::trans (m2)); + std::cout << "srk (m1, 1, 1, trans (m2)) = " << m1 << std::endl; + +#ifdef USE_STD_COMPLEX + // h_rk + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::hrk (m1, value_type (1), value_type (1), m2); + std::cout << "hrk (m1, 1, 1, m2) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::hrk (m1, value_type (1), value_type (1), ublas::herm (m2)); + std::cout << "hrk (m1, 1, 1, herm (m2)) = " << m1 << std::endl; +#endif + + // s_r2k + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::sr2k (m1, value_type (1), value_type (1), m2, m3); + std::cout << "sr2k (m1, 1, 1, m2, m3) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::sr2k (m1, value_type (1), value_type (1), ublas::trans (m2), ublas::trans (m3)); + std::cout << "sr2k (m1, 1, 1, trans (m2), trans (m3)) = " << m1 << std::endl; + +#ifdef USE_STD_COMPLEX + // h_r2k + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::hr2k (m1, value_type (1), value_type (1), m2, m3); + std::cout << "hr2k (m1, 1, 1, m2, m3) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::hr2k (m1, value_type (1), value_type (1), ublas::herm (m2), ublas::herm (m3)); + std::cout << "hr2k (m1, 1, 1, herm (m2), herm (m3)) = " << m1 << std::endl; +#endif + } +} + +#ifdef USE_FLOAT +template struct test_blas_3<ublas::matrix<float>, 3>; +#endif + +#ifdef USE_DOUBLE +template struct test_blas_3<ublas::matrix<double>, 3>; +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT +template struct test_blas_3<ublas::matrix<std::complex<float> >, 3>; +#endif + +#ifdef USE_DOUBLE +template struct test_blas_3<ublas::matrix<std::complex<double> >, 3>; +#endif +#endif diff --git a/src/boost/libs/numeric/ublas/test/test3.cpp b/src/boost/libs/numeric/ublas/test/test3.cpp new file mode 100644 index 000000000..fb2b94dad --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test3.cpp @@ -0,0 +1,20 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test3.hpp" + +int main () { + test_vector (); + test_matrix_vector (); + test_matrix (); + return 0; +} diff --git a/src/boost/libs/numeric/ublas/test/test3.hpp b/src/boost/libs/numeric/ublas/test/test3.hpp new file mode 100644 index 000000000..a9d4fc957 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test3.hpp @@ -0,0 +1,38 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#ifndef TEST3_H +#define TEST3_H + +#include <iostream> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/vector_proxy.hpp> +#include <boost/numeric/ublas/vector_sparse.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_proxy.hpp> +#include <boost/numeric/ublas/matrix_sparse.hpp> +#include <boost/numeric/ublas/vector_sparse.hpp> +#ifdef USE_GENERALIZED_VECTOR_OF_VECTOR +#include <boost/numeric/ublas/vector_of_vector.hpp> +#endif +#include <boost/numeric/ublas/io.hpp> + +namespace ublas = boost::numeric::ublas; + +#include "common/init.hpp" + +void test_vector (); +void test_matrix_vector (); +void test_matrix (); + +#endif diff --git a/src/boost/libs/numeric/ublas/test/test31.cpp b/src/boost/libs/numeric/ublas/test/test31.cpp new file mode 100644 index 000000000..776228720 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test31.cpp @@ -0,0 +1,248 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test3.hpp" + +// Test vector expression templates +template<class V, int N> +struct test_my_vector { + typedef typename V::value_type value_type; + typedef typename V::size_type size_type; + typedef typename ublas::type_traits<value_type>::real_type real_type; + + template<class VP> + void test_with (VP &v1, VP &v2, VP &v3) const { + { + value_type t; + size_type i; + real_type n; + + // Default Construct + default_construct<VP>::test (); + + // Copy and swap + initialize_vector (v1); + initialize_vector (v2); + v1 = v2; + std::cout << "v1 = v2 = " << v1 << std::endl; + v1.assign_temporary (v2); + std::cout << "v1.assign_temporary (v2) = " << v1 << std::endl; + v1.swap (v2); + std::cout << "v1.swap (v2) = " << v1 << " " << v2 << std::endl; + + // Zero assignment + v1 = ublas::zero_vector<> (v1.size ()); + std::cout << "v1.zero_vector = " << v1 << std::endl; + v1 = v2; + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + // Project range and slice + initialize_vector (v1); + initialize_vector (v2); + project (v1, ublas::range(0,1)) = project (v2, ublas::range(0,1)); + project (v1, ublas::range(0,1)) = project (v2, ublas::slice(0,1,1)); + project (v1, ublas::slice(2,-1,2)) = project (v2, ublas::slice(0,1,2)); + project (v1, ublas::slice(2,-1,2)) = project (v2, ublas::range(0,2)); + std::cout << "v1 = range/slice " << v1 << std::endl; +#endif + + // Unary vector operations resulting in a vector + initialize_vector (v1); + v2 = - v1; + std::cout << "- v1 = " << v2 << std::endl; + v2 = ublas::conj (v1); + std::cout << "conj (v1) = " << v2 << std::endl; + + // Binary vector operations resulting in a vector + initialize_vector (v1); + initialize_vector (v2); + initialize_vector (v3); + v3 = v1 + v2; + std::cout << "v1 + v2 = " << v3 << std::endl; + + v3 = v1 - v2; + std::cout << "v1 - v2 = " << v3 << std::endl; + + // Scaling a vector + t = N; + initialize_vector (v1); + v2 = value_type (1.) * v1; + std::cout << "1. * v1 = " << v2 << std::endl; + v2 = t * v1; + std::cout << "N * v1 = " << v2 << std::endl; + initialize_vector (v1); + v2 = v1 * value_type (1.); + std::cout << "v1 * 1. = " << v2 << std::endl; + v2 = v1 * t; + std::cout << "v1 * N = " << v2 << std::endl; + + // Some assignments + initialize_vector (v1); + initialize_vector (v2); + v2 += v1; + std::cout << "v2 += v1 = " << v2 << std::endl; + v2 -= v1; + std::cout << "v2 -= v1 = " << v2 << std::endl; + v2 = v2 + v1; + std::cout << "v2 = v2 + v1 = " << v2 << std::endl; + v2 = v2 - v1; + std::cout << "v2 = v2 - v1 = " << v2 << std::endl; + v1 *= value_type (1.); + std::cout << "v1 *= 1. = " << v1 << std::endl; + v1 *= t; + std::cout << "v1 *= N = " << v1 << std::endl; + + // Unary vector operations resulting in a scalar + initialize_vector (v1); + t = ublas::sum (v1); + std::cout << "sum (v1) = " << t << std::endl; + n = ublas::norm_1 (v1); + std::cout << "norm_1 (v1) = " << n << std::endl; + n = ublas::norm_2 (v1); + std::cout << "norm_2 (v1) = " << n << std::endl; + n = ublas::norm_inf (v1); + std::cout << "norm_inf (v1) = " << n << std::endl; + + i = ublas::index_norm_inf (v1); + std::cout << "index_norm_inf (v1) = " << i << std::endl; + + // Binary vector operations resulting in a scalar + initialize_vector (v1); + initialize_vector (v2); + t = ublas::inner_prod (v1, v2); + std::cout << "inner_prod (v1, v2) = " << t << std::endl; + } + } + void operator () () const { + { + V v1 (N, N), v2 (N, N), v3 (N, N); + test_with (v1, v2, v3); + +#ifdef USE_RANGE + ublas::vector_range<V> vr1 (v1, ublas::range (0, N)), + vr2 (v2, ublas::range (0, N)), + vr3 (v3, ublas::range (0, N)); + test_with (vr1, vr2, vr3); +#endif + +#ifdef USE_SLICE + ublas::vector_slice<V> vs1 (v1, ublas::slice (0, 1, N)), + vs2 (v2, ublas::slice (0, 1, N)), + vs3 (v3, ublas::slice (0, 1, N)); + test_with (vs1, vs2, vs3); +#endif + } + } +}; + +// Test vector +void test_vector () { + std::cout << "test_vector" << std::endl; + +#ifdef USE_SPARSE_VECTOR +#ifdef USE_MAP_ARRAY +#ifdef USE_FLOAT + std::cout << "float, map_array" << std::endl; + test_my_vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, map_array" << std::endl; + test_my_vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, map_array" << std::endl; + test_my_vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, map_array" << std::endl; + test_my_vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_STD_MAP +#ifdef USE_FLOAT + std::cout << "float, std::map" << std::endl; + test_my_vector<ublas::mapped_vector<float, std::map<std::size_t, float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::map" << std::endl; + test_my_vector<ublas::mapped_vector<double, std::map<std::size_t, double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::map" << std::endl; + test_my_vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::map" << std::endl; + test_my_vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > > , 3 > () (); +#endif +#endif +#endif +#endif + +#ifdef USE_COMPRESSED_VECTOR +#ifdef USE_FLOAT + std::cout << "float compressed" << std::endl; + test_my_vector<ublas::compressed_vector<float>, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double compressed" << std::endl; + test_my_vector<ublas::compressed_vector<double>, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float> compressed" << std::endl; + test_my_vector<ublas::compressed_vector<std::complex<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double> compressed" << std::endl; + test_my_vector<ublas::compressed_vector<std::complex<double> >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_COORDINATE_VECTOR +#ifdef USE_FLOAT + std::cout << "float coordinate" << std::endl; + test_my_vector<ublas::coordinate_vector<float>, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double coordinate" << std::endl; + test_my_vector<ublas::coordinate_vector<double>, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float> coordinate" << std::endl; + test_my_vector<ublas::coordinate_vector<std::complex<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double> coordinate" << std::endl; + test_my_vector<ublas::coordinate_vector<std::complex<double> >, 3 > () (); +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test32.cpp b/src/boost/libs/numeric/ublas/test/test32.cpp new file mode 100644 index 000000000..eaf492976 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test32.cpp @@ -0,0 +1,354 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test3.hpp" + +// Test matrix & vector expression templates +template<class V, class M, int N> +struct test_my_matrix_vector { + typedef typename V::value_type value_type; + + template<class VP, class MP> + void test_with (VP &v1, VP &v2, MP &m1) const { + { + // Rows and columns + initialize_matrix (m1); + for (int i = 0; i < N; ++ i) { + v1 = ublas::row (m1, i); + std::cout << "row (m, " << i << ") = " << v1 << std::endl; + v1 = ublas::column (m1, i); + std::cout << "column (m, " << i << ") = " << v1 << std::endl; + } + + // Outer product + initialize_vector (v1); + initialize_vector (v2); + m1 = ublas::outer_prod (v1, v2); + std::cout << "outer_prod (v1, v2) = " << m1 << std::endl; + + // Matrix vector product + initialize_matrix (m1); + initialize_vector (v1); + v2 = ublas::prod (m1, v1); + std::cout << "prod (m1, v1) = " << v2 << std::endl; + v2 = ublas::prod (v1, m1); + std::cout << "prod (v1, m1) = " << v2 << std::endl; + } + } + void operator () () const { + { + V v1 (N, N), v2 (N, N); + M m1 (N, N, N * N); + + test_with (v1, v2, m1); + + ublas::matrix_row<M> mr1 (m1, 0), mr2 (m1, N - 1); + test_with (mr1, mr2, m1); + + ublas::matrix_column<M> mc1 (m1, 0), mc2 (m1, N - 1); + test_with (mc1, mc2, m1); + +#ifdef USE_RANGE + ublas::matrix_vector_range<M> mvr1 (m1, ublas::range (0, N), ublas::range (0, N)), + mvr2 (m1, ublas::range (0, N), ublas::range (0, N)); + test_with (mvr1, mvr2, m1); +#endif + +#ifdef USE_SLICE + ublas::matrix_vector_slice<M> mvs1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + mvs2 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (mvs1, mvs2, m1); +#endif + } + } +}; + +// Test matrix & vector +void test_matrix_vector () { + std::cout << "test_matrix_vector" << std::endl; + +#ifdef USE_SPARSE_MATRIX +#ifdef USE_MAP_ARRAY +#ifdef USE_FLOAT + std::cout << "float, map_array" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> >, + ublas::mapped_matrix<float, ublas::row_major, ublas::map_array<std::size_t, float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, map_array" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> >, + ublas::mapped_matrix<double, ublas::row_major, ublas::map_array<std::size_t, double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, map_array" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > >, + ublas::mapped_matrix<std::complex<float>, ublas::row_major, ublas::map_array<std::size_t, std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, map_array" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > >, + ublas::mapped_matrix<std::complex<double>, ublas::row_major, ublas::map_array<std::size_t, std::complex<double> > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_STD_MAP +#ifdef USE_FLOAT + std::cout << "float, std::map" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<float, std::map<std::size_t, float> >, + ublas::mapped_matrix<float, ublas::row_major, std::map<std::size_t, float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::map" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<double, std::map<std::size_t, double> >, + ublas::mapped_matrix<double, ublas::row_major, std::map<std::size_t, double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::map" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > >, + ublas::mapped_matrix<std::complex<float>, ublas::row_major, std::map<std::size_t, std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::map" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > >, + ublas::mapped_matrix<std::complex<double>, ublas::row_major, std::map<std::size_t, std::complex<double> > >, 3 > () (); +#endif +#endif +#endif +#endif + +#ifdef USE_SPARSE_VECTOR_OF_SPARSE_VECTOR +#ifdef USE_MAP_ARRAY +#ifdef USE_FLOAT + std::cout << "float, mapped_vector map_array" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> >, + ublas::mapped_vector<float, ublas::row_major, ublas::map_array<std::size_t, ublas::map_array<std::size_t, float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, mapped_vector map_array" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> >, + ublas::mapped_vector<double, ublas::row_major, ublas::map_array<std::size_t, ublas::map_array<std::size_t, double> > >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, mapped_vector map_array" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > >, + ublas::mapped_vector<std::complex<float>, ublas::row_major, ublas::map_array<std::size_t, ublas::map_array<std::size_t, std::complex<float> > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>,mapped_vector map_array" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > >, + ublas::mapped_vector<std::complex<double>, ublas::row_major, ublas::map_array<std::size_t, ublas::map_array<std::size_t, std::complex<double> > > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_STD_MAP +#ifdef USE_FLOAT + std::cout << "float, mapped_vector std::map" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<float, std::map<std::size_t, float> >, + ublas::mapped_vector<float, ublas::row_major, std::map<std::size_t, std::map<std::size_t, float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, mapped_vector std::map" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<double, std::map<std::size_t, double> >, + ublas::mapped_vector<double, ublas::row_major, std::map<std::size_t, std::map<std::size_t, double> > >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, mapped_vector std::map" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > >, + ublas::mapped_vector<std::complex<float>, ublas::row_major, std::map<std::size_t, std::map<std::size_t, std::complex<float> > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, mapped_vector std::map" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > >, + ublas::mapped_vector<std::complex<double>, ublas::row_major, std::map<std::size_t, std::map<std::size_t, std::complex<double> > > >, 3 > () (); +#endif +#endif +#endif +#endif + +#ifdef USE_GENERALIZED_VECTOR_OF_VECTOR +#ifdef USE_MAP_ARRAY +#ifdef USE_FLOAT + std::cout << "float, generalized_vector_of_vector map_array" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> >, + ublas::generalized_vector_of_vector<float, ublas::row_major, ublas::vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> > > >, 3 > () (); + test_my_matrix_vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> >, + ublas::generalized_vector_of_vector<float, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> >, ublas::map_array<std::size_t, ublas::mapped_vector<float, ublas::map_array<std::size_t, float> > > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, generalized_vector_of_vector map_array" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> >, + ublas::generalized_vector_of_vector<double, ublas::row_major, ublas::vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> > > >, 3 > () (); + test_my_matrix_vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> >, + ublas::generalized_vector_of_vector<double, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> >, ublas::map_array<std::size_t, ublas::mapped_vector<double, ublas::map_array<std::size_t, double> > > > >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, generalized_vector_of_vector map_array" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > >, + ublas::generalized_vector_of_vector<std::complex<float>, ublas::row_major, ublas::vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > > > >, 3 > () (); + test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > >, + ublas::generalized_vector_of_vector<std::complex<float>, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > >, ublas::map_array<std::size_t, ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > > > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, generalized_vector_of_vector map_array" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > >, + ublas::generalized_vector_of_vector<std::complex<double>, ublas::row_major, ublas::vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > > > >, 3 > () (); + test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > >, + ublas::generalized_vector_of_vector<std::complex<double>, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > >, ublas::map_array<std::size_t, ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > > > > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_STD_MAP +#ifdef USE_FLOAT + std::cout << "float, generalized_vector_of_vector std::map" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<float, std::map<std::size_t, float> >, + ublas::generalized_vector_of_vector<float, ublas::row_major, ublas::vector<ublas::mapped_vector<float, std::map<std::size_t, float> > > >, 3 > () (); + test_my_matrix_vector<ublas::mapped_vector<float, std::map<std::size_t, float> >, + ublas::generalized_vector_of_vector<float, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<float, std::map<std::size_t, float> >, std::map<std::size_t, ublas::mapped_vector<float, std::map<std::size_t, float> > > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, generalized_vector_of_vector std::map" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<double, std::map<std::size_t, double> >, + ublas::generalized_vector_of_vector<double, ublas::row_major, ublas::vector<ublas::mapped_vector<double, std::map<std::size_t, double> > > >, 3 > () (); + test_my_matrix_vector<ublas::mapped_vector<double, std::map<std::size_t, double> >, + ublas::generalized_vector_of_vector<double, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<double, std::map<std::size_t, double> >, std::map<std::size_t, ublas::mapped_vector<double, std::map<std::size_t, double> > > > >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, generalized_vector_of_vector std::map" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > >, + ublas::generalized_vector_of_vector<std::complex<float>, ublas::row_major, ublas::vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > > > >, 3 > () (); + test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > >, + ublas::generalized_vector_of_vector<std::complex<float>, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > >, std::map<std::size_t, ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > > > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, generalized_vector_of_vector std::map" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > >, + ublas::generalized_vector_of_vector<std::complex<double>, ublas::row_major, ublas::vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > > > >, 3 > () (); + test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > >, + ublas::generalized_vector_of_vector<std::complex<double>, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > >, std::map<std::size_t, ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > > > > >, 3 > () (); +#endif +#endif +#endif +#endif + +#ifdef USE_COMPRESSED_MATRIX +#ifdef USE_FLOAT + std::cout << "float compressed" << std::endl; + test_my_matrix_vector<ublas::compressed_vector<float>, + ublas::compressed_matrix<float>, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double compressed" << std::endl; + test_my_matrix_vector<ublas::compressed_vector<double>, + ublas::compressed_matrix<double>, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float> compressed" << std::endl; + test_my_matrix_vector<ublas::compressed_vector<std::complex<float> >, + ublas::compressed_matrix<std::complex<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double> compressed" << std::endl; + test_my_matrix_vector<ublas::compressed_vector<std::complex<double> >, + ublas::compressed_matrix<std::complex<double> >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_COORDINATE_MATRIX +#ifdef USE_FLOAT + std::cout << "float coordinate" << std::endl; + test_my_matrix_vector<ublas::coordinate_vector<float>, + ublas::coordinate_matrix<float>, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double coordinate" << std::endl; + test_my_matrix_vector<ublas::coordinate_vector<double>, + ublas::coordinate_matrix<double>, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float> coordinate" << std::endl; + test_my_matrix_vector<ublas::coordinate_vector<std::complex<float> >, + ublas::coordinate_matrix<std::complex<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double> coordinate" << std::endl; + test_my_matrix_vector<ublas::coordinate_vector<std::complex<double> >, + ublas::coordinate_matrix<std::complex<double> >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_MAPPED_VECTOR_OF_MAPPED_VECTOR +#ifdef USE_STD_MAP +#ifdef USE_FLOAT + std::cout << "float mapped_vector_of_mapped_vector" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<float, std::map<std::size_t, float> >, + ublas::mapped_vector_of_mapped_vector<float>, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double mapped_vector_of_mapped_vector" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<double, std::map<std::size_t, double> >, + ublas::mapped_vector_of_mapped_vector<double>, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float> mapped_vector_of_mapped_vector" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > >, + ublas::mapped_vector_of_mapped_vector<std::complex<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double> mapped_vector_of_mapped_vector" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > >, + ublas::mapped_vector_of_mapped_vector<std::complex<double> >, 3 > () (); +#endif +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test33.cpp b/src/boost/libs/numeric/ublas/test/test33.cpp new file mode 100644 index 000000000..48e1424f4 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test33.cpp @@ -0,0 +1,371 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test3.hpp" + +// Test matrix expression templates +template<class M, std::size_t N> +struct test_my_matrix { + typedef typename M::value_type value_type; + + template<class MP> + void test_with (MP &m1, MP &m2, MP &m3) const { + { + value_type t; + + // Default Construct + default_construct<MP>::test (); + + // Copy and swap + initialize_matrix (m1); + initialize_matrix (m2); + m1 = m2; + std::cout << "m1 = m2 = " << m1 << std::endl; + m1.assign_temporary (m2); + std::cout << "m1.assign_temporary (m2) = " << m1 << std::endl; + m1.swap (m2); + std::cout << "m1.swap (m2) = " << m1 << " " << m2 << std::endl; + + // Zero assignment + m1 = ublas::zero_matrix<short> (m1.size1 (), m1.size2 ()); + std::cout << "m1.zero_matrix = " << m1 << std::endl; + m1 = m2; + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + // Project range and slice + initialize_matrix (m1); + initialize_matrix (m2); + project (m1, ublas::range(0,1),ublas::range(0,1)) = project (m2, ublas::range(0,1),ublas::range(0,1)); + project (m1, ublas::range(0,1),ublas::range(0,1)) = project (m2, ublas::slice(0,1,1),ublas::slice(0,1,1)); + project (m1, ublas::slice(2,-1,2),ublas::slice(2,-1,2)) = project (m2, ublas::slice(0,1,2),ublas::slice(0,1,2)); + project (m1, ublas::slice(2,-1,2),ublas::slice(2,-1,2)) = project (m2, ublas::range(0,2),ublas::range(0,2)); + std::cout << "m1 = range/slice " << m1 << std::endl; +#endif + + // Unary matrix operations resulting in a matrix + initialize_matrix (m1); + m2 = - m1; + std::cout << "- m1 = " << m2 << std::endl; + m2 = ublas::conj (m1); + std::cout << "conj (m1) = " << m2 << std::endl; + + // Binary matrix operations resulting in a matrix + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + m3 = m1 + m2; + std::cout << "m1 + m2 = " << m3 << std::endl; + m3 = m1 - m2; + std::cout << "m1 - m2 = " << m3 << std::endl; + + // Scaling a matrix + t = N; + initialize_matrix (m1); + m2 = value_type (1.) * m1; + std::cout << "1. * m1 = " << m2 << std::endl; + m2 = t * m1; + std::cout << "N * m1 = " << m2 << std::endl; + initialize_matrix (m1); + m2 = m1 * value_type (1.); + std::cout << "m1 * 1. = " << m2 << std::endl; + m2 = m1 * t; + std::cout << "m1 * N = " << m2 << std::endl; + + // Some assignments + initialize_matrix (m1); + initialize_matrix (m2); + m2 += m1; + std::cout << "m2 += m1 = " << m2 << std::endl; + m2 -= m1; + std::cout << "m2 -= m1 = " << m2 << std::endl; + m2 = m2 + m1; + std::cout << "m2 = m2 + m1 = " << m2 << std::endl; + m2 = m2 - m1; + std::cout << "m2 = m2 - m1 = " << m2 << std::endl; + m1 *= value_type (1.); + std::cout << "m1 *= 1. = " << m1 << std::endl; + m1 *= t; + std::cout << "m1 *= N = " << m1 << std::endl; + + // Transpose + initialize_matrix (m1); + m2 = ublas::trans (m1); + std::cout << "trans (m1) = " << m2 << std::endl; + + // Hermitean + initialize_matrix (m1); + m2 = ublas::herm (m1); + std::cout << "herm (m1) = " << m2 << std::endl; + + // Matrix multiplication + initialize_matrix (m1); + initialize_matrix (m2); + m3 = ublas::prod (m1, m2); + std::cout << "prod (m1, m2) = " << m3 << std::endl; + } + } + void operator () () const { + { + M m1 (N, N, N * N), m2 (N, N, N * N), m3 (N, N, N * N); + test_with (m1, m2, m3); + +#ifdef USE_RANGE + ublas::matrix_range<M> mr1 (m1, ublas::range (0, N), ublas::range (0, N)), + mr2 (m2, ublas::range (0, N), ublas::range (0, N)), + mr3 (m3, ublas::range (0, N), ublas::range (0, N)); + test_with (mr1, mr2, mr3); +#endif + +#ifdef USE_SLICE + ublas::matrix_slice<M> ms1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms2 (m2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms3 (m3, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (ms1, ms2, ms3); +#endif + } + } +}; + +// Test matrix +void test_matrix () { + std::cout << "test_matrix" << std::endl; + +#ifdef USE_SPARSE_MATRIX +#ifdef USE_MAP_ARRAY +#ifdef USE_FLOAT + std::cout << "float, mapped_matrix map_array" << std::endl; + test_my_matrix<ublas::mapped_matrix<float, ublas::row_major, ublas::map_array<std::size_t, float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, mapped_matrix map_array" << std::endl; + test_my_matrix<ublas::mapped_matrix<double, ublas::row_major, ublas::map_array<std::size_t, double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, mapped_matrix map_array" << std::endl; + test_my_matrix<ublas::mapped_matrix<std::complex<float>, ublas::row_major, ublas::map_array<std::size_t, std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, mapped_matrix map_array" << std::endl; + test_my_matrix<ublas::mapped_matrix<std::complex<double>, ublas::row_major, ublas::map_array<std::size_t, std::complex<double> > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_STD_MAP +#ifdef USE_FLOAT + std::cout << "float, mapped_matrix std::map" << std::endl; + test_my_matrix<ublas::mapped_matrix<float, ublas::row_major, std::map<std::size_t, float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, mapped_matrix std::map" << std::endl; + test_my_matrix<ublas::mapped_matrix<double, ublas::row_major, std::map<std::size_t, double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, mapped_matrix std::map" << std::endl; + test_my_matrix<ublas::mapped_matrix<std::complex<float>, ublas::row_major, std::map<std::size_t, std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, mapped_matrix std::map" << std::endl; + test_my_matrix<ublas::mapped_matrix<std::complex<double>, ublas::row_major, std::map<std::size_t, std::complex<double> > >, 3 > () (); +#endif +#endif +#endif +#endif + +#ifdef USE_SPARSE_VECTOR_OF_SPARSE_VECTOR +#ifdef USE_MAP_ARRAY +#ifdef USE_FLOAT + std::cout << "float, mapped_vector_of_mapped_vector map_array" << std::endl; + test_my_matrix<ublas::mapped_vector_of_mapped_vector<float, ublas::row_major, ublas::map_array<std::size_t, ublas::map_array<std::size_t, float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, mapped_vector_of_mapped_vector map_array" << std::endl; + test_my_matrix<ublas::mapped_vector_of_mapped_vector<double, ublas::row_major, ublas::map_array<std::size_t, ublas::map_array<std::size_t, double> > >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, mapped_vector_of_mapped_vector map_array" << std::endl; + test_my_matrix<ublas::mapped_vector_of_mapped_vector<std::complex<float>, ublas::row_major, ublas::map_array<std::size_t, ublas::map_array<std::size_t, std::complex<float> > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, mapped_vector_of_mapped_vectormap_array" << std::endl; + test_my_matrix<ublas::mapped_vector_of_mapped_vector<std::complex<double>, ublas::row_major, ublas::map_array<std::size_t, ublas::map_array<std::size_t, std::complex<double> > > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_STD_MAP +#ifdef USE_FLOAT + std::cout << "float, mapped_vector_of_mapped_vector std::map" << std::endl; + test_my_matrix<ublas::mapped_vector_of_mapped_vector<float, ublas::row_major, std::map<std::size_t, std::map<std::size_t, float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, mapped_vector_of_mapped_vector std::map" << std::endl; + test_my_matrix<ublas::mapped_vector_of_mapped_vector<double, ublas::row_major, std::map<std::size_t, std::map<std::size_t, double> > >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, mapped_vector_of_mapped_vector std::map" << std::endl; + test_my_matrix<ublas::mapped_vector_of_mapped_vector<std::complex<float>, ublas::row_major, std::map<std::size_t, std::map<std::size_t, std::complex<float> > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, mapped_vector_of_mapped_vector std::map" << std::endl; + test_my_matrix<ublas::mapped_vector_of_mapped_vector<std::complex<double>, ublas::row_major, std::map<std::size_t, std::map<std::size_t, std::complex<double> > > >, 3 > () (); +#endif +#endif +#endif +#endif + +#ifdef USE_GENERALIZED_VECTOR_OF_VECTOR +#ifdef USE_MAP_ARRAY +#ifdef USE_FLOAT + std::cout << "float,generalized_vector_of_vector map_array" << std::endl; + test_my_matrix<ublas::generalized_vector_of_vector<float, ublas::row_major, ublas::vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> > > >, 3 > () (); + test_my_matrix<ublas::generalized_vector_of_vector<float, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> >, ublas::map_array<std::size_t, ublas::mapped_vector<float, ublas::map_array<std::size_t, float> > > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, generalized_vector_of_vector map_array" << std::endl; + test_my_matrix<ublas::generalized_vector_of_vector<double, ublas::row_major, ublas::vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> > > >, 3 > () (); + test_my_matrix<ublas::generalized_vector_of_vector<double, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> >, ublas::map_array<std::size_t, ublas::mapped_vector<double, ublas::map_array<std::size_t, double> > > > >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, generalized_vector_of_vector map_array" << std::endl; + test_my_matrix<ublas::generalized_vector_of_vector<std::complex<float>, ublas::row_major, ublas::vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > > > >, 3 > () (); + test_my_matrix<ublas::generalized_vector_of_vector<std::complex<float>, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > >, ublas::map_array<std::size_t, ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > > > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, generalized_vector_of_vector map_array" << std::endl; + test_my_matrix<ublas::generalized_vector_of_vector<std::complex<double>, ublas::row_major, ublas::vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > > > >, 3 > () (); + test_my_matrix<ublas::generalized_vector_of_vector<std::complex<double>, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > >, ublas::map_array<std::size_t, ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > > > > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_STD_MAP +#ifdef USE_FLOAT + std::cout << "float, generalized_vector_of_vector std::map" << std::endl; + test_my_matrix<ublas::generalized_vector_of_vector<float, ublas::row_major, ublas::vector<ublas::mapped_vector<float, std::map<std::size_t, float> > > >, 3 > () (); + test_my_matrix<ublas::generalized_vector_of_vector<float, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<float, std::map<std::size_t, float> >, std::map<std::size_t, ublas::mapped_vector<float, std::map<std::size_t, float> > > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, generalized_vector_of_vector std::map" << std::endl; + test_my_matrix<ublas::generalized_vector_of_vector<double, ublas::row_major, ublas::vector<ublas::mapped_vector<double, std::map<std::size_t, double> > > >, 3 > () (); + test_my_matrix<ublas::generalized_vector_of_vector<double, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<double, std::map<std::size_t, double> >, std::map<std::size_t, ublas::mapped_vector<double, std::map<std::size_t, double> > > > >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, generalized_vector_of_vector std::map" << std::endl; + test_my_matrix<ublas::generalized_vector_of_vector<std::complex<float>, ublas::row_major, ublas::vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > > > >, 3 > () (); + test_my_matrix<ublas::generalized_vector_of_vector<std::complex<float>, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > >, std::map<std::size_t, ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > > > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, generalized_vector_of_vector std::map" << std::endl; + test_my_matrix<ublas::generalized_vector_of_vector<std::complex<double>, ublas::row_major, ublas::vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > > > >, 3 > () (); + test_my_matrix<ublas::generalized_vector_of_vector<std::complex<double>, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > >, std::map<std::size_t, ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > > > > >, 3 > () (); +#endif +#endif +#endif +#endif + +#ifdef USE_COMPRESSED_MATRIX +#ifdef USE_FLOAT + std::cout << "float compressed_matrix" << std::endl; + test_my_matrix<ublas::compressed_matrix<float>, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double compressed_matrix" << std::endl; + test_my_matrix<ublas::compressed_matrix<double>, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float> compressed_matrix" << std::endl; + test_my_matrix<ublas::compressed_matrix<std::complex<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double> compressed_matrix" << std::endl; + test_my_matrix<ublas::compressed_matrix<std::complex<double> >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_COORDINATE_MATRIX +#ifdef USE_FLOAT + std::cout << "float coordinate_matrix" << std::endl; + test_my_matrix<ublas::coordinate_matrix<float>, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double coordinate_matrix" << std::endl; + test_my_matrix<ublas::coordinate_matrix<double>, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float> coordinate_matrix" << std::endl; + test_my_matrix<ublas::coordinate_matrix<std::complex<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double> coordinate_matrix" << std::endl; + test_my_matrix<ublas::coordinate_matrix<std::complex<double> >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_MAPPED_VECTOR_OF_MAPPED_VECTOR +#ifdef USE_FLOAT + std::cout << "float mapped_vector_of_mapped_vector" << std::endl; + test_my_matrix<ublas::mapped_vector_of_mapped_vector<float>, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double mapped_vector_of_mapped_vector" << std::endl; + test_my_matrix<ublas::mapped_vector_of_mapped_vector<double>, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float> mapped_vector_of_mapped_vector" << std::endl; + test_my_matrix<ublas::mapped_vector_of_mapped_vector<std::complex<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double> mapped_vector_of_mapped_vector" << std::endl; + test_my_matrix<ublas::mapped_vector_of_mapped_vector<std::complex<double> >, 3 > () (); +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test4.cpp b/src/boost/libs/numeric/ublas/test/test4.cpp new file mode 100644 index 000000000..bf5816f5e --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test4.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test4.hpp" + +int main () { + test_matrix_vector (); + test_matrix (); + return 0; +} diff --git a/src/boost/libs/numeric/ublas/test/test4.hpp b/src/boost/libs/numeric/ublas/test/test4.hpp new file mode 100644 index 000000000..fc5b48cbe --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test4.hpp @@ -0,0 +1,39 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#ifndef TEST4_H +#define TEST4_H + +#include <iostream> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_proxy.hpp> +#include <boost/numeric/ublas/banded.hpp> +#include <boost/numeric/ublas/io.hpp> + +namespace ublas = boost::numeric::ublas; + +#include "common/init.hpp" + +//#define USE_BANDED +#define USE_DIAGONAL + + +void test_matrix_vector (); +void test_matrix (); + + +// FIXME slice are failing in assignment to zero elements +#undef USE_SLICE + +#endif diff --git a/src/boost/libs/numeric/ublas/test/test42.cpp b/src/boost/libs/numeric/ublas/test/test42.cpp new file mode 100644 index 000000000..d284e6854 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test42.cpp @@ -0,0 +1,366 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test4.hpp" +#include "utils.hpp" + +// Test matrix & vector expression templates +template<class V, class M, int N> +struct test_my_matrix_vector { + typedef typename V::value_type value_type; + + template<class VP, class MP> + void test_with (VP &v1, VP &v2, MP &m1) const { + { +#ifndef USE_DIAGONAL + // Rows and columns + initialize_matrix (m1); + for (int i = 0; i < N; ++ i) { + v2 = ublas::row (m1, i); + std::cout << "row (m, " << i << ") = " << v2 << std::endl; + v2 = ublas::column (m1, i); + std::cout << "column (m, " << i << ") = " << v2 << std::endl; + } + + // Outer product + initialize_vector (v1); + initialize_vector (v2); + v1 (0) = 0; + v1 (N - 1) = 0; + m1 = ublas::outer_prod (v1, v2); + std::cout << "outer_prod (v1, v2) = " << m1 << std::endl; + + // Matrix vector product + initialize_matrix (m1); + initialize_vector (v1); + v2 = ublas::prod (m1, v1); + std::cout << "prod (m1, v1) = " << v2 << std::endl; + v2 = ublas::prod (v1, m1); + std::cout << "prod (v1, m1) = " << v2 << std::endl; +#else + BOOST_UBLAS_NOT_USED(v1); + BOOST_UBLAS_NOT_USED(v2); + BOOST_UBLAS_NOT_USED(m1); +#endif + } + } + void operator () () const { + { + V v1 (N), v2 (N); +#ifdef USE_BANDED + M m1 (N, N, 1, 1); +#endif +#ifdef USE_DIAGONAL + M m1 (N, N); +#endif + test_with (v1, v2, m1); + + ublas::matrix_row<M> mr1 (m1, 1), mr2 (m1, 1); + test_with (mr1, mr2, m1); + + ublas::matrix_column<M> mc1 (m1, 1), mc2 (m1, 1); + test_with (mc1, mc2, m1); + +#ifdef USE_RANGE + ublas::matrix_vector_range<M> mvr1 (m1, ublas::range (0, N), ublas::range (0, N)), + mvr2 (m1, ublas::range (0, N), ublas::range (0, N)); + test_with (mvr1, mvr2, m1); +#endif + +#ifdef USE_SLICE + ublas::matrix_vector_slice<M> mvs1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + mvs2 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (mvs1, mvs2, m1); +#endif + } + } + + void operator () (int) const { +#ifdef USE_ADAPTOR + { +#ifdef USE_BANDED + V v1 (N), v2 (N); + M m1 (N, N, 1, 1); + ublas::banded_adaptor<M> bam1 (m1, 1, 1); + test_with (v1, v2, bam1); + + ublas::matrix_row<ublas::banded_adaptor<M> > mr1 (bam1, 1), mr2 (bam1, 1); + test_with (mr1, mr2, bam1); + + ublas::matrix_column<ublas::banded_adaptor<M> > mc1 (bam1, 1), mc2 (bam1, 1); + test_with (mc1, mc2, bam1); + +#ifdef USE_RANGE + ublas::matrix_vector_range<ublas::banded_adaptor<M> > mvr1 (bam1, ublas::range (0, N), ublas::range (0, N)), + mvr2 (bam1, ublas::range (0, N), ublas::range (0, N)); + test_with (mvr1, mvr2, bam1); +#endif + +#ifdef USE_SLICE + ublas::matrix_vector_slice<ublas::banded_adaptor<M> > mvs1 (bam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + mvs2 (bam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (mvs1, mvs2, bam1); +#endif +#endif +#ifdef USE_DIAGONAL + V v1 (N), v2 (N); + M m1 (N, N); + ublas::diagonal_adaptor<M> dam1 (m1); + test_with (v1, v2, dam1); + + ublas::matrix_row<ublas::diagonal_adaptor<M> > mr1 (dam1, 1), mr2 (dam1, 1); + test_with (mr1, mr2, dam1); + + ublas::matrix_column<ublas::diagonal_adaptor<M> > mc1 (dam1, 1), mc2 (dam1, 1); + test_with (mc1, mc2, dam1); + +#ifdef USE_RANGE + ublas::matrix_vector_range<ublas::diagonal_adaptor<M> > mvr1 (dam1, ublas::range (0, N), ublas::range (0, N)), + mvr2 (dam1, ublas::range (0, N), ublas::range (0, N)); + test_with (mvr1, mvr2, dam1); +#endif + +#ifdef USE_SLICE + ublas::matrix_vector_slice<ublas::diagonal_adaptor<M> > mvs1 (dam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + mvs2 (dam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (mvs1, mvs2, dam1); +#endif +#endif + } +#endif + } +}; + +// Test matrix & vector +void test_matrix_vector () { + std::cout << "test_matrix_vector" << std::endl; + +#ifdef USE_BANDED +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >, + ublas::banded_matrix<float, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >, + ublas::banded_matrix<float, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >, + ublas::banded_matrix<double, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >, + ublas::banded_matrix<double, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () (0); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >, + ublas::banded_matrix<std::complex<float>, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >, + ublas::banded_matrix<std::complex<float>, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >, + ublas::banded_matrix<std::complex<double>, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >, + ublas::banded_matrix<std::complex<double>, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () (0); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >, + ublas::banded_matrix<float, ublas::row_major, ublas::unbounded_array<float> >, 3> () (); + test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >, + ublas::banded_matrix<float, ublas::row_major, ublas::unbounded_array<float> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >, + ublas::banded_matrix<double, ublas::row_major, ublas::unbounded_array<double> >, 3> () (); + test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >, + ublas::banded_matrix<double, ublas::row_major, ublas::unbounded_array<double> >, 3> () (0); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >, + ublas::banded_matrix<std::complex<float>, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >, + ublas::banded_matrix<std::complex<float>, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >, + ublas::banded_matrix<std::complex<double>, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >, + ublas::banded_matrix<std::complex<double>, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () (0); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<float, std::vector<float> >, + ublas::banded_matrix<float, ublas::row_major, std::vector<float> >, 3> () (); + test_my_matrix_vector<ublas::vector<float, std::vector<float> >, + ublas::banded_matrix<float, ublas::row_major, std::vector<float> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<double, std::vector<double> >, + ublas::banded_matrix<double, ublas::row_major, std::vector<double> >, 3> () (); + test_my_matrix_vector<ublas::vector<double, std::vector<double> >, + ublas::banded_matrix<double, ublas::row_major, std::vector<double> >, 3> () (0); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >, + ublas::banded_matrix<std::complex<float>, ublas::row_major, std::vector<std::complex<float> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >, + ublas::banded_matrix<std::complex<float>, ublas::row_major, std::vector<std::complex<float> > >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >, + ublas::banded_matrix<std::complex<double>, ublas::row_major, std::vector<std::complex<double> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >, + ublas::banded_matrix<std::complex<double>, ublas::row_major, std::vector<std::complex<double> > >, 3> () (0); +#endif +#endif +#endif +#endif + +#ifdef USE_DIAGONAL +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >, + ublas::diagonal_matrix<float, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >, + ublas::diagonal_matrix<float, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >, + ublas::diagonal_matrix<double, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >, + ublas::diagonal_matrix<double, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () (0); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >, + ublas::diagonal_matrix<std::complex<float>, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >, + ublas::diagonal_matrix<std::complex<float>, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >, + ublas::diagonal_matrix<std::complex<double>, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >, + ublas::diagonal_matrix<std::complex<double>, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () (0); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >, + ublas::diagonal_matrix<float, ublas::row_major, ublas::unbounded_array<float> >, 3> () (); + test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >, + ublas::diagonal_matrix<float, ublas::row_major, ublas::unbounded_array<float> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >, + ublas::diagonal_matrix<double, ublas::row_major, ublas::unbounded_array<double> >, 3> () (); + test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >, + ublas::diagonal_matrix<double, ublas::row_major, ublas::unbounded_array<double> >, 3> () (0); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >, + ublas::diagonal_matrix<std::complex<float>, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >, + ublas::diagonal_matrix<std::complex<float>, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >, + ublas::diagonal_matrix<std::complex<double>, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >, + ublas::diagonal_matrix<std::complex<double>, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () (0); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<float, std::vector<float> >, + ublas::diagonal_matrix<float, ublas::row_major, std::vector<float> >, 3> () (); + test_my_matrix_vector<ublas::vector<float, std::vector<float> >, + ublas::diagonal_matrix<float, ublas::row_major, std::vector<float> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<double, std::vector<double> >, + ublas::diagonal_matrix<double, ublas::row_major, std::vector<double> >, 3> () (); + test_my_matrix_vector<ublas::vector<double, std::vector<double> >, + ublas::diagonal_matrix<double, ublas::row_major, std::vector<double> >, 3> () (0); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >, + ublas::diagonal_matrix<std::complex<float>, ublas::row_major, std::vector<std::complex<float> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >, + ublas::diagonal_matrix<std::complex<float>, ublas::row_major, std::vector<std::complex<float> > >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >, + ublas::diagonal_matrix<std::complex<double>, ublas::row_major, std::vector<std::complex<double> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >, + ublas::diagonal_matrix<std::complex<double>, ublas::row_major, std::vector<std::complex<double> > >, 3> () (0); +#endif +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test43.cpp b/src/boost/libs/numeric/ublas/test/test43.cpp new file mode 100644 index 000000000..9db3c9b2c --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test43.cpp @@ -0,0 +1,326 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test4.hpp" + +// Test matrix expression templates +template<class M, int N> +struct test_my_matrix { + typedef typename M::value_type value_type; + + template<class MP> + void test_with (MP &m1, MP &m2, MP &m3) const { + { + value_type t; + + // Default Construct + default_construct<MP>::test (); + + // Copy and swap + initialize_matrix (m1); + initialize_matrix (m2); + m1 = m2; + std::cout << "m1 = m2 = " << m1 << std::endl; + m1.assign_temporary (m2); + std::cout << "m1.assign_temporary (m2) = " << m1 << std::endl; + m1.swap (m2); + std::cout << "m1.swap (m2) = " << m1 << " " << m2 << std::endl; + + // Zero assignment + m1 = ublas::zero_matrix<> (m1.size1 (), m1.size2 ()); + std::cout << "m1.zero_matrix = " << m1 << std::endl; + m1 = m2; + + // Unary matrix operations resulting in a matrix + initialize_matrix (m1); + m2 = - m1; + std::cout << "- m1 = " << m2 << std::endl; + m2 = ublas::conj (m1); + std::cout << "conj (m1) = " << m2 << std::endl; + + // Binary matrix operations resulting in a matrix + initialize_matrix (m1); + initialize_matrix (m2); + m3 = m1 + m2; + std::cout << "m1 + m2 = " << m3 << std::endl; + m3 = m1 - m2; + std::cout << "m1 - m2 = " << m3 << std::endl; + + // Scaling a matrix + t = N; + initialize_matrix (m1); + m2 = value_type (1.) * m1; + std::cout << "1. * m1 = " << m2 << std::endl; + m2 = t * m1; + std::cout << "N * m1 = " << m2 << std::endl; + initialize_matrix (m1); + m2 = m1 * value_type (1.); + std::cout << "m1 * 1. = " << m2 << std::endl; + m2 = m1 * t; + std::cout << "m1 * N = " << m2 << std::endl; + + // Some assignments + initialize_matrix (m1); + initialize_matrix (m2); + m2 += m1; + std::cout << "m2 += m1 = " << m2 << std::endl; + m2 -= m1; + std::cout << "m2 -= m1 = " << m2 << std::endl; + m2 = m2 + m1; + std::cout << "m2 = m2 + m1 = " << m2 << std::endl; + m2 = m2 - m1; + std::cout << "m2 = m2 - m1 = " << m2 << std::endl; + m1 *= value_type (1.); + std::cout << "m1 *= 1. = " << m1 << std::endl; + m1 *= t; + std::cout << "m1 *= N = " << m1 << std::endl; + + // Transpose + initialize_matrix (m1); + m2 = ublas::trans (m1); + std::cout << "trans (m1) = " << m2 << std::endl; + + // Hermitean + initialize_matrix (m1); + m2 = ublas::herm (m1); + std::cout << "herm (m1) = " << m2 << std::endl; + + // Matrix multiplication + initialize_matrix (m1); + initialize_matrix (m2); + // Banded times banded isn't banded + std::cout << "prod (m1, m2) = " << ublas::prod (m1, m2) << std::endl; + } + } + void operator () () const { + { +#ifdef USE_BANDED + M m1 (N, N, 1, 1), m2 (N, N, 1, 1), m3 (N, N, 1, 1); +#endif +#ifdef USE_DIAGONAL + M m1 (N, N), m2 (N, N), m3 (N, N); +#endif + test_with (m1, m2, m3); + +#ifdef USE_RANGE + ublas::matrix_range<M> mr1 (m1, ublas::range (0, N), ublas::range (0, N)), + mr2 (m2, ublas::range (0, N), ublas::range (0, N)), + mr3 (m3, ublas::range (0, N), ublas::range (0, N)); + test_with (mr1, mr2, mr3); +#endif + +#ifdef USE_SLICE + ublas::matrix_slice<M> ms1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms2 (m2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms3 (m3, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (ms1, ms2, ms3); +#endif + } + +#ifdef USE_ADAPTOR + { +#ifdef USE_BANDED + M m1 (N, N, 1, 1), m2 (N, N, 1, 1), m3 (N, N, 1, 1); + ublas::banded_adaptor<M> bam1 (m1, 1, 1), bam2 (m2, 1, 1), bam3 (m3, 1, 1); + test_with (bam1, bam2, bam3); + +#ifdef USE_RANGE + ublas::matrix_range<ublas::banded_adaptor<M> > mr1 (bam1, ublas::range (0, N), ublas::range (0, N)), + mr2 (bam2, ublas::range (0, N), ublas::range (0, N)), + mr3 (bam3, ublas::range (0, N), ublas::range (0, N)); + test_with (mr1, mr2, mr3); +#endif + +#ifdef USE_SLICE + ublas::matrix_slice<ublas::banded_adaptor<M> > ms1 (bam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms2 (bam2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms3 (bam3, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (ms1, ms2, ms3); +#endif +#endif +#ifdef USE_DIAGONAL + M m1 (N, N), m2 (N, N), m3 (N, N); + ublas::diagonal_adaptor<M> dam1 (m1), dam2 (m2), dam3 (m3); + test_with (dam1, dam2, dam3); + +#ifdef USE_RANGE + ublas::matrix_range<ublas::diagonal_adaptor<M> > mr1 (dam1, ublas::range (0, N), ublas::range (0, N)), + mr2 (dam2, ublas::range (0, N), ublas::range (0, N)), + mr3 (dam3, ublas::range (0, N), ublas::range (0, N)); + test_with (mr1, mr2, mr3); +#endif + +#ifdef USE_SLICE + ublas::matrix_slice<ublas::diagonal_adaptor<M> > ms1 (dam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms2 (dam2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms3 (dam3, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (ms1, ms2, ms3); +#endif +#endif + } +#endif + + } +}; + +// Test matrix +void test_matrix () { + std::cout << "test_matrix" << std::endl; + +#ifdef USE_BANDED +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_matrix<ublas::banded_matrix<float, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_matrix<ublas::banded_matrix<double, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_matrix<ublas::banded_matrix<std::complex<float>, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_matrix<ublas::banded_matrix<std::complex<double>, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_matrix<ublas::banded_matrix<float, ublas::row_major, ublas::unbounded_array<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_matrix<ublas::banded_matrix<double, ublas::row_major, ublas::unbounded_array<double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_matrix<ublas::banded_matrix<std::complex<float>, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_matrix<ublas::banded_matrix<std::complex<double>, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_matrix<ublas::banded_matrix<float, ublas::row_major, std::vector<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_matrix<ublas::banded_matrix<double, ublas::row_major, std::vector<double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_matrix<ublas::banded_matrix<std::complex<float>, ublas::row_major, std::vector<std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_matrix<ublas::banded_matrix<std::complex<double>, ublas::row_major, std::vector<std::complex<double> > >, 3 > () (); +#endif +#endif +#endif +#endif + +#ifdef USE_DIAGONAL +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_matrix<ublas::diagonal_matrix<float, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_matrix<ublas::diagonal_matrix<double, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_matrix<ublas::diagonal_matrix<std::complex<float>, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_matrix<ublas::diagonal_matrix<std::complex<double>, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_matrix<ublas::diagonal_matrix<float, ublas::row_major, ublas::unbounded_array<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_matrix<ublas::diagonal_matrix<double, ublas::row_major, ublas::unbounded_array<double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_matrix<ublas::diagonal_matrix<std::complex<float>, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_matrix<ublas::diagonal_matrix<std::complex<double>, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_matrix<ublas::diagonal_matrix<float, ublas::row_major, std::vector<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_matrix<ublas::diagonal_matrix<double, ublas::row_major, std::vector<double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_matrix<ublas::diagonal_matrix<std::complex<float>, ublas::row_major, std::vector<std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_matrix<ublas::diagonal_matrix<std::complex<double>, ublas::row_major, std::vector<std::complex<double> > >, 3 > () (); +#endif +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test5.cpp b/src/boost/libs/numeric/ublas/test/test5.cpp new file mode 100644 index 000000000..548cd6033 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test5.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test5.hpp" + +int main () { + test_matrix_vector (); + test_matrix (); + return 0; +} diff --git a/src/boost/libs/numeric/ublas/test/test5.hpp b/src/boost/libs/numeric/ublas/test/test5.hpp new file mode 100644 index 000000000..a13dfa2ef --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test5.hpp @@ -0,0 +1,35 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#ifndef TEST5_H +#define TEST5_H + +#include <iostream> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_proxy.hpp> +#include <boost/numeric/ublas/triangular.hpp> +#include <boost/numeric/ublas/io.hpp> + +namespace ublas = boost::numeric::ublas; + +#include "common/init.hpp" + +void test_matrix_vector (); +void test_matrix (); + + +// FIXME slice are failing in assignment to zero elements +#undef USE_SLICE + +#endif diff --git a/src/boost/libs/numeric/ublas/test/test52.cpp b/src/boost/libs/numeric/ublas/test/test52.cpp new file mode 100644 index 000000000..4803ce260 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test52.cpp @@ -0,0 +1,214 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test5.hpp" + +// Test matrix & vector expression templates +template<class V, class M, int N> +struct test_my_matrix_vector { + typedef typename V::value_type value_type; + + template<class VP, class MP> + void test_with (VP &v1, VP &v2, MP &m1) const { + { + // Rows and columns + initialize_matrix (m1); + for (int i = 0; i < N; ++ i) { + v2 = ublas::row (m1, i); + std::cout << "row (m, " << i << ") = " << v2 << std::endl; + v2 = ublas::column (m1, i); + std::cout << "column (m, " << i << ") = " << v2 << std::endl; + } + + // Outer product + initialize_vector (v1); + initialize_vector (v2); + v1 (0) = 0; + v2 (N - 1) = 0; + m1 = ublas::outer_prod (v1, v2); + std::cout << "outer_prod (v1, v2) = " << m1 << std::endl; + + // Matrix vector product + initialize_matrix (m1); + initialize_vector (v1); + v2 = ublas::prod (m1, v1); + std::cout << "prod (m1, v1) = " << v2 << std::endl; + v2 = ublas::prod (v1, m1); + std::cout << "prod (v1, m1) = " << v2 << std::endl; + } + } + void operator () () const { + { + V v1 (N), v2 (N); + M m1 (N, N); + test_with (v1, v2, m1); + + ublas::matrix_row<M> mr1 (m1, N - 1), mr2 (m1, N - 1); + test_with (mr1, mr2, m1); + + ublas::matrix_column<M> mc1 (m1, 0), mc2 (m1, 0); + test_with (mc1, mc2, m1); + +#ifdef USE_RANGE + ublas::matrix_vector_range<M> mvr1 (m1, ublas::range (0, N), ublas::range (0, N)), + mvr2 (m1, ublas::range (0, N), ublas::range (0, N)); + test_with (mvr1, mvr2, m1); +#endif + +#ifdef USE_SLICE + ublas::matrix_vector_slice<M> mvs1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + mvs2 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (mvs1, mvs2, m1); +#endif + } + } + + void operator () (int) const { +#ifdef USE_ADAPTOR + { + V v1 (N), v2 (N); + M m1 (N, N); + ublas::triangular_adaptor<M> tam1 (m1); + test_with (v1, v2, tam1); + + ublas::matrix_row<ublas::triangular_adaptor<M> > mr1 (tam1, N - 1), mr2 (tam1, N - 1); + test_with (mr1, mr2, tam1); + + ublas::matrix_column<ublas::triangular_adaptor<M> > mc1 (tam1, 0), mc2 (tam1, 0); + test_with (mc1, mc2, tam1); + +#ifdef USE_RANGE + ublas::matrix_vector_range<ublas::triangular_adaptor<M> > mvr1 (tam1, ublas::range (0, N), ublas::range (0, N)), + mvr2 (tam1, ublas::range (0, N), ublas::range (0, N)); + test_with (mvr1, mvr2, tam1); +#endif + +#ifdef USE_SLICE + ublas::matrix_vector_slice<ublas::triangular_adaptor<M> > mvs1 (tam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + mvs2 (tam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (mvs1, mvs2, tam1); +#endif + } +#endif + } +}; + +// Test matrix & vector +void test_matrix_vector () { + std::cout << "test_matrix_vector" << std::endl; + +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >, + ublas::triangular_matrix<float, ublas::lower, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >, + ublas::triangular_matrix<float, ublas::lower, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >, + ublas::triangular_matrix<double, ublas::lower, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >, + ublas::triangular_matrix<double, ublas::lower, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () (0); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >, + ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >, + ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >, + ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >, + ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () (0); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >, + ublas::triangular_matrix<float, ublas::lower, ublas::row_major, ublas::unbounded_array<float> >, 3> () (); + test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >, + ublas::triangular_matrix<float, ublas::lower, ublas::row_major, ublas::unbounded_array<float> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >, + ublas::triangular_matrix<double, ublas::lower, ublas::row_major, ublas::unbounded_array<double> >, 3> () (); + test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >, + ublas::triangular_matrix<double, ublas::lower, ublas::row_major, ublas::unbounded_array<double> >, 3> () (0); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >, + ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >, + ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >, + ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >, + ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () (0); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<float, std::vector<float> >, + ublas::triangular_matrix<float, ublas::lower, ublas::row_major, std::vector<float> >, 3> () (); + test_my_matrix_vector<ublas::vector<float, std::vector<float> >, + ublas::triangular_matrix<float, ublas::lower, ublas::row_major, std::vector<float> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<double, std::vector<double> >, + ublas::triangular_matrix<double, ublas::lower, ublas::row_major, std::vector<double> >, 3> () (); + test_my_matrix_vector<ublas::vector<double, std::vector<double> >, + ublas::triangular_matrix<double, ublas::lower, ublas::row_major, std::vector<double> >, 3> () (0); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >, + ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, std::vector<std::complex<float> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >, + ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, std::vector<std::complex<float> > >, 3> () (0); + + std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >, + ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, std::vector<std::complex<double> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >, + ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, std::vector<std::complex<double> > >, 3> () (0); +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test53.cpp b/src/boost/libs/numeric/ublas/test/test53.cpp new file mode 100644 index 000000000..250d462d4 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test53.cpp @@ -0,0 +1,223 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test5.hpp" + +// Test matrix expression templates +template<class M, int N> +struct test_my_matrix { + typedef typename M::value_type value_type; + + template<class MP> + void test_with (MP &m1, MP &m2, MP &m3) const { + { + value_type t; + + // Default Construct + default_construct<MP>::test (); + + // Copy and swap + initialize_matrix (m1); + initialize_matrix (m2); + m1 = m2; + std::cout << "m1 = m2 = " << m1 << std::endl; + m1.assign_temporary (m2); + std::cout << "m1.assign_temporary (m2) = " << m1 << std::endl; + m1.swap (m2); + std::cout << "m1.swap (m2) = " << m1 << " " << m2 << std::endl; + + // Zero assignment + m1 = ublas::zero_matrix<> (m1.size1 (), m1.size2 ()); + std::cout << "m1.zero_matrix = " << m1 << std::endl; + m1 = m2; + + // Unary matrix operations resulting in a matrix + initialize_matrix (m1); + m2 = - m1; + std::cout << "- m1 = " << m2 << std::endl; + m2 = ublas::conj (m1); + std::cout << "conj (m1) = " << m2 << std::endl; + + // Binary matrix operations resulting in a matrix + initialize_matrix (m1); + initialize_matrix (m2); + m3 = m1 + m2; + std::cout << "m1 + m2 = " << m3 << std::endl; + m3 = m1 - m2; + std::cout << "m1 - m2 = " << m3 << std::endl; + + // Scaling a matrix + t = N; + initialize_matrix (m1); + m2 = value_type (1.) * m1; + std::cout << "1. * m1 = " << m2 << std::endl; + m2 = t * m1; + std::cout << "N * m1 = " << m2 << std::endl; + initialize_matrix (m1); + m2 = m1 * value_type (1.); + std::cout << "m1 * 1. = " << m2 << std::endl; + m2 = m1 * t; + std::cout << "m1 * N = " << m2 << std::endl; + + // Some assignments + initialize_matrix (m1); + initialize_matrix (m2); + m2 += m1; + std::cout << "m2 += m1 = " << m2 << std::endl; + m2 -= m1; + std::cout << "m2 -= m1 = " << m2 << std::endl; + m2 = m2 + m1; + std::cout << "m2 = m2 + m1 = " << m2 << std::endl; + m2 = m2 - m1; + std::cout << "m2 = m2 - m1 = " << m2 << std::endl; + m1 *= value_type (1.); + std::cout << "m1 *= 1. = " << m1 << std::endl; + m1 *= t; + std::cout << "m1 *= N = " << m1 << std::endl; + + // Transpose + initialize_matrix (m1); + // Transpose of a triangular isn't triangular of the same kind + std::cout << "trans (m1) = " << ublas::trans (m1) << std::endl; + + // Hermitian + initialize_matrix (m1); + // Hermitian of a triangular isn't hermitian of the same kind + std::cout << "herm (m1) = " << ublas::herm (m1) << std::endl; + + // Matrix multiplication + initialize_matrix (m1); + initialize_matrix (m2); + m3 = ublas::prod (m1, m2); + std::cout << "prod (m1, m2) = " << m3 << std::endl; + } + } + void operator () () const { + { + M m1 (N, N), m2 (N, N), m3 (N, N); + test_with (m1, m2, m3); + +#ifdef USE_RANGE + ublas::matrix_range<M> mr1 (m1, ublas::range (0, N), ublas::range (0, N)), + mr2 (m2, ublas::range (0, N), ublas::range (0, N)), + mr3 (m3, ublas::range (0, N), ublas::range (0, N)); + test_with (mr1, mr2, mr3); +#endif + +#ifdef USE_SLICE + ublas::matrix_slice<M> ms1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms2 (m2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms3 (m3, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (ms1, ms2, ms3); +#endif + } + +#ifdef USE_ADAPTOR + { + M m1 (N, N), m2 (N, N), m3 (N, N); + ublas::triangular_adaptor<M> tam1 (m1), tam2 (m2), tam3 (m3); + test_with (tam1, tam2, tam3); + +#ifdef USE_RANGE + ublas::matrix_range<ublas::triangular_adaptor<M> > mr1 (tam1, ublas::range (0, N), ublas::range (0, N)), + mr2 (tam2, ublas::range (0, N), ublas::range (0, N)), + mr3 (tam3, ublas::range (0, N), ublas::range (0, N)); + test_with (mr1, mr2, mr3); +#endif + +#ifdef USE_SLICE + ublas::matrix_slice<ublas::triangular_adaptor<M> > ms1 (tam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms2 (tam2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms3 (tam3, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (ms1, ms2, ms3); +#endif + } +#endif + } +}; + +// Test matrix +void test_matrix () { + std::cout << "test_matrix" << std::endl; + +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_matrix<ublas::triangular_matrix<float, ublas::lower, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_matrix<ublas::triangular_matrix<double, ublas::lower, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_matrix<ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_matrix<ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_matrix<ublas::triangular_matrix<float, ublas::lower, ublas::row_major, ublas::unbounded_array<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_matrix<ublas::triangular_matrix<double, ublas::lower, ublas::row_major, ublas::unbounded_array<double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_matrix<ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_matrix<ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_matrix<ublas::triangular_matrix<float, ublas::lower, ublas::row_major, std::vector<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_matrix<ublas::triangular_matrix<double, ublas::lower, ublas::row_major, std::vector<double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_matrix<ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, std::vector<std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE +std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_matrix<ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, std::vector<std::complex<double> > >, 3 > () (); +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test6.cpp b/src/boost/libs/numeric/ublas/test/test6.cpp new file mode 100644 index 000000000..61a5c3105 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test6.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test6.hpp" + +int main () { + test_matrix_vector (); + test_matrix (); + return 0; +} diff --git a/src/boost/libs/numeric/ublas/test/test6.hpp b/src/boost/libs/numeric/ublas/test/test6.hpp new file mode 100644 index 000000000..766d6b929 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test6.hpp @@ -0,0 +1,32 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#ifndef TEST6_H +#define TEST6_H + +#include <iostream> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_proxy.hpp> +#include <boost/numeric/ublas/symmetric.hpp> +#include <boost/numeric/ublas/io.hpp> + +namespace ublas = boost::numeric::ublas; + +#include "common/init.hpp" + +void test_matrix_vector (); +void test_matrix (); + + +#endif diff --git a/src/boost/libs/numeric/ublas/test/test62.cpp b/src/boost/libs/numeric/ublas/test/test62.cpp new file mode 100644 index 000000000..5d7feb9a3 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test62.cpp @@ -0,0 +1,218 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test6.hpp" + +// Test matrix & vector expression templates +template<class V, class M, int N> +struct test_my_matrix_vector { + typedef typename V::value_type value_type; + + template<class VP, class MP> + void test_with (VP &v1, VP &v2, MP &m1) const { + { + // Rows and columns + initialize_matrix (m1); + for (int i = 0; i < N; ++ i) { + v2 = ublas::row (m1, i); + std::cout << "row (m, " << i << ") = " << v2 << std::endl; + v2 = ublas::column (m1, i); + std::cout << "column (m, " << i << ") = " << v2 << std::endl; + } + + // Outer product + initialize_vector (v1); + initialize_vector (v2); + v1 (0) = 0; + v1 (N - 1) = 0; + v2 (0) = 0; + v2 (N - 1) = 0; + m1 = ublas::outer_prod (v1, v2); + std::cout << "outer_prod (v1, v2) = " << m1 << std::endl; + + // Matrix vector product + initialize_matrix (m1); + initialize_vector (v1); + v2 = ublas::prod (m1, v1); + std::cout << "prod (m1, v1) = " << v2 << std::endl; + v2 = ublas::prod (v1, m1); + std::cout << "prod (v1, m1) = " << v2 << std::endl; + } + } + void operator () () const { + { + V v1 (N), v2 (N); + M m1 (N, N); + test_with (v1, v2, m1); + + ublas::matrix_row<M> mr1 (m1, N - 1), mr2 (m1, N - 1); + test_with (mr1, mr2, m1); + + ublas::matrix_column<M> mc1 (m1, 0), mc2 (m1, 0); + test_with (mc1, mc2, m1); + +#ifdef USE_RANGE + ublas::matrix_vector_range<M> mvr1 (m1, ublas::range (0, N), ublas::range (0, N)), + mvr2 (m1, ublas::range (0, N), ublas::range (0, N)); + test_with (mvr1, mvr2, m1); +#endif + +#ifdef USE_SLICE + ublas::matrix_vector_slice<M> mvs1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + mvs2 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (mvs1, mvs2, m1); +#endif + } + } + + void operator () (int) const { +#ifdef USE_ADAPTOR + { + V v1 (N), v2 (N); + M m1 (N, N); + ublas::symmetric_adaptor<M> tam1 (m1); + test_with (v1, v2, tam1); + + ublas::matrix_row<ublas::symmetric_adaptor<M> > mr1 (tam1, N - 1), mr2 (tam1, N - 1); + test_with (mr1, mr2, tam1); + + ublas::matrix_column<ublas::symmetric_adaptor<M> > mc1 (tam1, 0), mc2 (tam1, 0); + test_with (mc1, mc2, tam1); + +#ifdef USE_RANGE + ublas::matrix_vector_range<ublas::symmetric_adaptor<M> > mvr1 (tam1, ublas::range (0, N), ublas::range (0, N)), + mvr2 (tam1, ublas::range (0, N), ublas::range (0, N)); + test_with (mvr1, mvr2, tam1); +#endif + +#ifdef USE_SLICE + ublas::matrix_vector_slice<ublas::symmetric_adaptor<M> > mvs1 (tam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + mvs2 (tam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (mvs1, mvs2, tam1); +#endif + } +#endif + } +}; + +// Test matrix & vector +void test_matrix_vector () { + std::cout << "test_matrix_vector" << std::endl; + +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >, + ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >, + ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >, + ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >, + ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () (0); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >, + ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >, + ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >, + ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >, + ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () (0); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >, + ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, ublas::unbounded_array<float> >, 3> () (); + test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >, + ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, ublas::unbounded_array<float> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >, + ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, ublas::unbounded_array<double> >, 3> () (); + test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >, + ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, ublas::unbounded_array<double> >, 3> () (0); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >, + ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >, + ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >, + ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >, + ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () (0); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<float, std::vector<float> >, + ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, std::vector<float> >, 3> () (); + test_my_matrix_vector<ublas::vector<float, std::vector<float> >, + ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, std::vector<float> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<double, std::vector<double> >, + ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, std::vector<double> >, 3> () (); + test_my_matrix_vector<ublas::vector<double, std::vector<double> >, + ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, std::vector<double> >, 3> () (0); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >, + ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, std::vector<std::complex<float> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >, + ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, std::vector<std::complex<float> > >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >, + ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, std::vector<std::complex<double> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >, + ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, std::vector<std::complex<double> > >, 3> () (0); +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test63.cpp b/src/boost/libs/numeric/ublas/test/test63.cpp new file mode 100644 index 000000000..4a0013d2c --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test63.cpp @@ -0,0 +1,223 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test6.hpp" + +// Test matrix expression templates +template<class M, int N> +struct test_my_matrix { + typedef typename M::value_type value_type; + + template<class MP> + void test_with (MP &m1, MP &m2, MP &m3) const { + { + value_type t; + + // Default Construct + default_construct<MP>::test (); + + // Copy and swap + initialize_matrix (m1); + initialize_matrix (m2); + m1 = m2; + std::cout << "m1 = m2 = " << m1 << std::endl; + m1.assign_temporary (m2); + std::cout << "m1.assign_temporary (m2) = " << m1 << std::endl; + m1.swap (m2); + std::cout << "m1.swap (m2) = " << m1 << " " << m2 << std::endl; + + // Zero assignment + m1 = ublas::zero_matrix<> (m1.size1 (), m1.size2 ()); + std::cout << "m1.zero_matrix = " << m1 << std::endl; + m1 = m2; + + // Unary matrix operations resulting in a matrix + initialize_matrix (m1); + m2 = - m1; + std::cout << "- m1 = " << m2 << std::endl; + m2 = ublas::conj (m1); + std::cout << "conj (m1) = " << m2 << std::endl; + + // Binary matrix operations resulting in a matrix + initialize_matrix (m1); + initialize_matrix (m2); + m3 = m1 + m2; + std::cout << "m1 + m2 = " << m3 << std::endl; + m3 = m1 - m2; + std::cout << "m1 - m2 = " << m3 << std::endl; + + // Scaling a matrix + t = N; + initialize_matrix (m1); + m2 = value_type (1.) * m1; + std::cout << "1. * m1 = " << m2 << std::endl; + m2 = t * m1; + std::cout << "N * m1 = " << m2 << std::endl; + initialize_matrix (m1); + m2 = m1 * value_type (1.); + std::cout << "m1 * 1. = " << m2 << std::endl; + m2 = m1 * t; + std::cout << "m1 * N = " << m2 << std::endl; + + // Some assignments + initialize_matrix (m1); + initialize_matrix (m2); + m2 += m1; + std::cout << "m2 += m1 = " << m2 << std::endl; + m2 -= m1; + std::cout << "m2 -= m1 = " << m2 << std::endl; + m2 = m2 + m1; + std::cout << "m2 = m2 + m1 = " << m2 << std::endl; + m2 = m2 - m1; + std::cout << "m2 = m1 - m1 = " << m2 << std::endl; + m1 *= value_type (1.); + std::cout << "m1 *= 1. = " << m1 << std::endl; + m1 *= t; + std::cout << "m1 *= N = " << m1 << std::endl; + + // Transpose + initialize_matrix (m1); + m2 = ublas::trans (m1); + std::cout << "trans (m1) = " << m2 << std::endl; + + // Hermitean + initialize_matrix (m1); + m2 = ublas::herm (m1); + std::cout << "herm (m1) = " << m2 << std::endl; + + // Matrix multiplication + initialize_matrix (m1); + initialize_matrix (m2); + m3 = ublas::prod (m1, m2); + std::cout << "prod (m1, m2) = " << m3 << std::endl; + } + } + void operator () () const { + { + M m1 (N, N), m2 (N, N), m3 (N, N); + test_with (m1, m2, m3); + +#ifdef USE_RANGE + ublas::matrix_range<M> mr1 (m1, ublas::range (0, N), ublas::range (0, N)), + mr2 (m2, ublas::range (0, N), ublas::range (0, N)), + mr3 (m3, ublas::range (0, N), ublas::range (0, N)); + test_with (mr1, mr2, mr3); +#endif + +#ifdef USE_SLICE + ublas::matrix_slice<M> ms1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms2 (m2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms3 (m3, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (ms1, ms2, ms3); +#endif + } + +#ifdef USE_ADAPTOR + { + M m1 (N, N), m2 (N, N), m3 (N, N); + ublas::symmetric_adaptor<M> sam1 (m1), sam2 (m2), sam3 (m3); + test_with (sam1, sam2, sam3); + +#ifdef USE_RANGE + ublas::matrix_range<ublas::symmetric_adaptor<M> > mr1 (sam1, ublas::range (0, N), ublas::range (0, N)), + mr2 (sam2, ublas::range (0, N), ublas::range (0, N)), + mr3 (sam3, ublas::range (0, N), ublas::range (0, N)); + test_with (mr1, mr2, mr3); +#endif + +#ifdef USE_SLICE + ublas::matrix_slice<ublas::symmetric_adaptor<M> > ms1 (sam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms2 (sam2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms3 (sam3, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (ms1, ms2, ms3); +#endif + } +#endif + } +}; + +// Test matrix +void test_matrix () { + std::cout << "test_matrix" << std::endl; + +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_matrix<ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_matrix<ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_matrix<ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_matrix<ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_matrix<ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, ublas::unbounded_array<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_matrix<ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, ublas::unbounded_array<double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_matrix<ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_matrix<ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_matrix<ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, std::vector<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_matrix<ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, std::vector<double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_matrix<ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, std::vector<std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_matrix<ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, std::vector<std::complex<double> > >, 3 > () (); +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test7.cpp b/src/boost/libs/numeric/ublas/test/test7.cpp new file mode 100644 index 000000000..f564031ce --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test7.cpp @@ -0,0 +1,31 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include <iostream> + +#include <boost/numeric/interval.hpp> +#include <boost/numeric/interval/io.hpp> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/io.hpp> + +#include "test7.hpp" + +// this testcase requires fix of task #2473 + +int main () { + test_vector (); + test_matrix_vector (); + test_matrix (); + return 0; +} diff --git a/src/boost/libs/numeric/ublas/test/test7.hpp b/src/boost/libs/numeric/ublas/test/test7.hpp new file mode 100644 index 000000000..5dbae1fca --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test7.hpp @@ -0,0 +1,36 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#ifndef TEST7_H +#define TEST7_H + +#include <iostream> + +#include <boost/numeric/interval.hpp> +#include <boost/numeric/interval/io.hpp> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/vector_proxy.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_proxy.hpp> +#include <boost/numeric/ublas/io.hpp> + +namespace ublas = boost::numeric::ublas; + +#include "common/init.hpp" + +void test_vector (); +void test_matrix_vector (); +void test_matrix (); + + +#endif diff --git a/src/boost/libs/numeric/ublas/test/test71.cpp b/src/boost/libs/numeric/ublas/test/test71.cpp new file mode 100644 index 000000000..89e9ccf78 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test71.cpp @@ -0,0 +1,170 @@ +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test7.hpp" + +// Test vector expression templates +template<class V, int N> +struct test_my_vector { + typedef typename V::value_type value_type; + typedef typename V::size_type size_type; + typedef typename ublas::type_traits<value_type>::real_type real_type; + + template<class VP> + void test_with (VP &v1, VP &v2, VP &v3) const { + { + value_type t; + size_type i; + real_type n; + + // Copy and swap + initialize_vector (v1); + initialize_vector (v2); + v1 = v2; + std::cout << "v1 = v2 = " << v1 << std::endl; + v1.assign_temporary (v2); + std::cout << "v1.assign_temporary (v2) = " << v1 << std::endl; + v1.swap (v2); + std::cout << "v1.swap (v2) = " << v1 << " " << v2 << std::endl; + + // Zero assignment + v1 = ublas::zero_vector<value_type> (v1.size ()); + std::cout << "v1.zero_vector = " << v1 << std::endl; + v1 = v2; + + // Unary vector operations resulting in a vector + initialize_vector (v1); + v2 = - v1; + std::cout << "- v1 = " << v2 << std::endl; + v2 = ublas::conj (v1); + std::cout << "conj (v1) = " << v2 << std::endl; + + // Binary vector operations resulting in a vector + initialize_vector (v1); + initialize_vector (v2); + v3 = v1 + v2; + std::cout << "v1 + v2 = " << v3 << std::endl; + + v3 = v1 - v2; + std::cout << "v1 - v2 = " << v3 << std::endl; + + // Scaling a vector + t = value_type (N); + initialize_vector (v1); + v2 = value_type (1.) * v1; + std::cout << "1. * v1 = " << v2 << std::endl; +// v2 = t * v1; + std::cout << "N * v1 = " << v2 << std::endl; + initialize_vector (v1); +// v2 = v1 * value_type (1.); + std::cout << "v1 * 1. = " << v2 << std::endl; +// v2 = v1 * t; + std::cout << "v1 * N = " << v2 << std::endl; + + // Some assignments + initialize_vector (v1); + initialize_vector (v2); + v2 += v1; + std::cout << "v2 += v1 = " << v2 << std::endl; + v2 -= v1; + std::cout << "v2 -= v1 = " << v2 << std::endl; + v2 = v2 + v1; + std::cout << "v2 = v2 + v1 = " << v2 << std::endl; + v2 = v2 - v1; + std::cout << "v2 = v2 - v1 = " << v2 << std::endl; + v1 *= value_type (1.); + std::cout << "v1 *= 1. = " << v1 << std::endl; + v1 *= t; + std::cout << "v1 *= N = " << v1 << std::endl; + + // Unary vector operations resulting in a scalar + initialize_vector (v1); + t = ublas::sum (v1); + std::cout << "sum (v1) = " << t << std::endl; + n = ublas::norm_1 (v1); + std::cout << "norm_1 (v1) = " << n << std::endl; + n = ublas::norm_2 (v1); + std::cout << "norm_2 (v1) = " << n << std::endl; + n = ublas::norm_inf (v1); + std::cout << "norm_inf (v1) = " << n << std::endl; + + i = ublas::index_norm_inf (v1); + std::cout << "index_norm_inf (v1) = " << i << std::endl; + + // Binary vector operations resulting in a scalar + initialize_vector (v1); + initialize_vector (v2); + t = ublas::inner_prod (v1, v2); + std::cout << "inner_prod (v1, v2) = " << t << std::endl; + } + } + void operator () () const { + { + V v1 (N), v2 (N), v3 (N); + test_with (v1, v2, v3); + +#ifdef USE_RANGE + ublas::vector_range<V> vr1 (v1, ublas::range (0, N)), + vr2 (v2, ublas::range (0, N)), + vr3 (v3, ublas::range (0, N)); + test_with (vr1, vr2, vr3); +#endif + +#ifdef USE_SLICE + ublas::vector_slice<V> vs1 (v1, ublas::slice (0, 1, N)), + vs2 (v2, ublas::slice (0, 1, N)), + vs3 (v3, ublas::slice (0, 1, N)); + test_with (vs1, vs2, vs3); +#endif + } + } +}; + +// Test vector +void test_vector () { + std::cout << "test_vector" << std::endl; + +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, bounded_array" << std::endl; + test_my_vector<ublas::vector<boost::numeric::interval<float>, ublas::bounded_array<boost::numeric::interval<float>, 3> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, bounded_array" << std::endl; + test_my_vector<ublas::vector<boost::numeric::interval<double>, ublas::bounded_array<boost::numeric::interval<double>, 3> >, 3 > () (); +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, unbounded_array" << std::endl; + test_my_vector<ublas::vector<boost::numeric::interval<float>, ublas::unbounded_array<boost::numeric::interval<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, unbounded_array" << std::endl; + test_my_vector<ublas::vector<boost::numeric::interval<double>, ublas::unbounded_array<boost::numeric::interval<double> > >, 3 > () (); +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, std::vector" << std::endl; + test_my_vector<ublas::vector<boost::numeric::interval<float>, std::vector<boost::numeric::interval<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, std::vector" << std::endl; + test_my_vector<ublas::vector<boost::numeric::interval<double>, std::vector<boost::numeric::interval<double> > >, 3 > () (); +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test72.cpp b/src/boost/libs/numeric/ublas/test/test72.cpp new file mode 100644 index 000000000..bdc3f3e8b --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test72.cpp @@ -0,0 +1,165 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test7.hpp" + +// Test matrix & vector expression templates +template<class V, class M, int N> +struct test_my_matrix_vector { + typedef typename V::value_type value_type; + + template<class VP, class MP> + void test_with (VP &v1, VP &v2, MP &m1) const { + { + // Rows and columns + initialize_matrix (m1); + for (int i = 0; i < N; ++ i) { + v1 = ublas::row (m1, i); + std::cout << "row (m, " << i << ") = " << v1 << std::endl; + v1 = ublas::column (m1, i); + std::cout << "column (m, " << i << ") = " << v1 << std::endl; + } + + // Outer product + initialize_vector (v1); + initialize_vector (v2); + m1 = ublas::outer_prod (v1, v2); + std::cout << "outer_prod (v1, v2) = " << m1 << std::endl; + + // Matrix vector product + initialize_matrix (m1); + initialize_vector (v1); + v2 = ublas::prod (m1, v1); + std::cout << "prod (m1, v1) = " << v2 << std::endl; + v2 = ublas::prod (v1, m1); + std::cout << "prod (v1, m1) = " << v2 << std::endl; + } + } + void operator () () const { + { + V v1 (N), v2 (N); + M m1 (N, N); + test_with (v1, v2, m1); + + ublas::matrix_row<M> mr1 (m1, 0), mr2 (m1, 1); + test_with (mr1, mr2, m1); + + ublas::matrix_column<M> mc1 (m1, 0), mc2 (m1, 1); + test_with (mc1, mc2, m1); + +#ifdef USE_RANGE + ublas::matrix_vector_range<M> mvr1 (m1, ublas::range (0, N), ublas::range (0, N)), + mvr2 (m1, ublas::range (0, N), ublas::range (0, N)); + test_with (mvr1, mvr2, m1); +#endif + +#ifdef USE_SLICE + ublas::matrix_vector_slice<M> mvs1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + mvs2 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (mvs1, mvs2, m1); +#endif + } + } +}; + +// Test matrix & vector +void test_matrix_vector () { + std::cout << "test_matrix_vector" << std::endl; + +#ifdef USE_MATRIX +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<boost::numeric::interval<float>, ublas::bounded_array<boost::numeric::interval<float>, 3> >, + ublas::matrix<boost::numeric::interval<float>, ublas::row_major, ublas::bounded_array<boost::numeric::interval<float>, 3 * 3> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<boost::numeric::interval<double>, ublas::bounded_array<boost::numeric::interval<double>, 3> >, + ublas::matrix<boost::numeric::interval<double>, ublas::row_major, ublas::bounded_array<boost::numeric::interval<double>, 3 * 3> >, 3> () (); +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<boost::numeric::interval<float>, ublas::unbounded_array<boost::numeric::interval<float> > >, + ublas::matrix<boost::numeric::interval<float>, ublas::row_major, ublas::unbounded_array<boost::numeric::interval<float> > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<boost::numeric::interval<double>, ublas::unbounded_array<boost::numeric::interval<double> > >, + ublas::matrix<boost::numeric::interval<double>, ublas::row_major, ublas::unbounded_array<boost::numeric::interval<double> > >, 3> () (); +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<boost::numeric::interval<float>, std::vector<boost::numeric::interval<float> > >, + ublas::matrix<boost::numeric::interval<float>, ublas::row_major, std::vector<boost::numeric::interval<float> > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<boost::numeric::interval<double>, std::vector<boost::numeric::interval<double> > >, + ublas::matrix<boost::numeric::interval<double>, ublas::row_major, std::vector<boost::numeric::interval<double> > >, 3> () (); +#endif +#endif +#endif + +#ifdef USE_VECTOR_OF_VECTOR +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<boost::numeric::interval<float>, ublas::bounded_array<boost::numeric::interval<float>, 3> >, + ublas::vector_of_vector<boost::numeric::interval<float>, ublas::row_major, ublas::bounded_array<ublas::bounded_array<boost::numeric::interval<float>, 3>, 3 + 1> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<boost::numeric::interval<double>, ublas::bounded_array<boost::numeric::interval<double>, 3> >, + ublas::vector_of_vector<boost::numeric::interval<double>, ublas::row_major, ublas::bounded_array<ublas::bounded_array<boost::numeric::interval<double>, 3>, 3 + 1> >, 3> () (); +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<boost::numeric::interval<float>, ublas::unbounded_array<boost::numeric::interval<float> > >, + ublas::vector_of_vector<boost::numeric::interval<float>, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<boost::numeric::interval<float> > > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<boost::numeric::interval<double>, ublas::unbounded_array<boost::numeric::interval<double> > >, + ublas::vector_of_vector<boost::numeric::interval<double>, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<boost::numeric::interval<double> > > >, 3> () (); +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<boost::numeric::interval<float>, std::vector<boost::numeric::interval<float> > >, + ublas::vector_of_vector<boost::numeric::interval<float>, ublas::row_major, std::vector<std::vector<boost::numeric::interval<float> > > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<boost::numeric::interval<double>, std::vector<boost::numeric::interval<double> > >, + ublas::vector_of_vector<boost::numeric::interval<double>, ublas::row_major, std::vector<std::vector<boost::numeric::interval<double> > > >, 3> () (); +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test73.cpp b/src/boost/libs/numeric/ublas/test/test73.cpp new file mode 100644 index 000000000..e2d68ceed --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test73.cpp @@ -0,0 +1,202 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// 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) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test7.hpp" + +// Test matrix expression templates +template<class M, int N> +struct test_my_matrix { + typedef typename M::value_type value_type; + + template<class MP> + void test_with (MP &m1, MP &m2, MP &m3) const { + { + value_type t; + + // Copy and swap + initialize_matrix (m1); + initialize_matrix (m2); + m1 = m2; + std::cout << "m1 = m2 = " << m1 << std::endl; + m1.assign_temporary (m2); + std::cout << "m1.assign_temporary (m2) = " << m1 << std::endl; + m1.swap (m2); + std::cout << "m1.swap (m2) = " << m1 << " " << m2 << std::endl; + + // Zero assignment + m1 = ublas::zero_matrix<value_type> (m1.size1 (), m1.size2 ()); + std::cout << "m1.zero_matrix = " << m1 << std::endl; + m1 = m2; + + // Unary matrix operations resulting in a matrix + initialize_matrix (m1); + m2 = - m1; + std::cout << "- m1 = " << m2 << std::endl; + m2 = ublas::conj (m1); + std::cout << "conj (m1) = " << m2 << std::endl; + + // Binary matrix operations resulting in a matrix + initialize_matrix (m1); + initialize_matrix (m2); + m3 = m1 + m2; + std::cout << "m1 + m2 = " << m3 << std::endl; + m3 = m1 - m2; + std::cout << "m1 - m2 = " << m3 << std::endl; + + // Scaling a matrix + t = N; + initialize_matrix (m1); + m2 = value_type (1.) * m1; + std::cout << "1. * m1 = " << m2 << std::endl; + m2 = t * m1; + std::cout << "N * m1 = " << m2 << std::endl; + initialize_matrix (m1); + m2 = m1 * value_type (1.); + std::cout << "m1 * 1. = " << m2 << std::endl; + m2 = m1 * t; + std::cout << "m1 * N = " << m2 << std::endl; + + // Some assignments + initialize_matrix (m1); + initialize_matrix (m2); + m2 += m1; + std::cout << "m2 += m1 = " << m2 << std::endl; + m2 -= m1; + std::cout << "m2 -= m1 = " << m2 << std::endl; + m2 = m2 + m1; + std::cout << "m2 = m2 + m1 = " << m2 << std::endl; + m2 = m2 - m1; + std::cout << "m2 = m1 - m1 = " << m2 << std::endl; + m1 *= value_type (1.); + std::cout << "m1 *= 1. = " << m1 << std::endl; + m1 *= t; + std::cout << "m1 *= N = " << m1 << std::endl; + + // Transpose + initialize_matrix (m1); + m2 = ublas::trans (m1); + std::cout << "trans (m1) = " << m2 << std::endl; + + // Hermitean + initialize_matrix (m1); + m2 = ublas::herm (m1); + std::cout << "herm (m1) = " << m2 << std::endl; + + // Matrix multiplication + initialize_matrix (m1); + initialize_matrix (m2); + m3 = ublas::prod (m1, m2); + std::cout << "prod (m1, m2) = " << m3 << std::endl; + } + } + void operator () () const { + { + M m1 (N, N), m2 (N, N), m3 (N, N); + test_with (m1, m2, m3); + +#ifdef USE_RANGE + ublas::matrix_range<M> mr1 (m1, ublas::range (0, N), ublas::range (0, N)), + mr2 (m2, ublas::range (0, N), ublas::range (0, N)), + mr3 (m3, ublas::range (0, N), ublas::range (0, N)); + test_with (mr1, mr2, mr3); +#endif + +#ifdef USE_SLICE + ublas::matrix_slice<M> ms1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms2 (m2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms3 (m3, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (ms1, ms2, ms3); +#endif + } + } +}; + +// Test matrix +void test_matrix () { + std::cout << "test_matrix" << std::endl; + +#ifdef USE_MATRIX +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, bounded_array" << std::endl; + test_my_matrix<ublas::matrix<boost::numeric::interval<float>, ublas::row_major, ublas::bounded_array<boost::numeric::interval<float>, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, bounded_array" << std::endl; + test_my_matrix<ublas::matrix<boost::numeric::interval<double>, ublas::row_major, ublas::bounded_array<boost::numeric::interval<double>, 3 * 3> >, 3 > () (); +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, unbounded_array" << std::endl; + test_my_matrix<ublas::matrix<boost::numeric::interval<float>, ublas::row_major, ublas::unbounded_array<boost::numeric::interval<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, unbounded_array" << std::endl; + test_my_matrix<ublas::matrix<boost::numeric::interval<double>, ublas::row_major, ublas::unbounded_array<boost::numeric::interval<double> > >, 3 > () (); +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, std::vector" << std::endl; + test_my_matrix<ublas::matrix<boost::numeric::interval<float>, ublas::row_major, std::vector<boost::numeric::interval<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, std::vector" << std::endl; + test_my_matrix<ublas::matrix<boost::numeric::interval<double>, ublas::row_major, std::vector<boost::numeric::interval<double> > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_VECTOR_OF_VECTOR +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, bounded_array" << std::endl; + test_my_matrix<ublas::vector_of_vector<boost::numeric::interval<float>, ublas::row_major, ublas::bounded_array<ublas::bounded_array<boost::numeric::interval<float>, 3>, 3 + 1> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, bounded_array" << std::endl; + test_my_matrix<ublas::vector_of_vector<boost::numeric::interval<double>, ublas::row_major, ublas::bounded_array<ublas::bounded_array<boost::numeric::interval<double>, 3>, 3 + 1> >, 3 > () (); +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, unbounded_array" << std::endl; + test_my_matrix<ublas::vector_of_vector<boost::numeric::interval<float>, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<boost::numeric::interval<float> > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, unbounded_array" << std::endl; + test_my_matrix<ublas::vector_of_vector<boost::numeric::interval<double>, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<boost::numeric::interval<double> > > >, 3 > () (); +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, std::vector" << std::endl; + test_my_matrix<ublas::vector_of_vector<boost::numeric::interval<float>, ublas::row_major, std::vector<std::vector<boost::numeric::interval<float> > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, std::vector" << std::endl; + test_my_matrix<ublas::vector_of_vector<boost::numeric::interval<double>, ublas::row_major, std::vector<std::vector<boost::numeric::interval<double> > > >, 3 > () (); +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test_assignment.cpp b/src/boost/libs/numeric/ublas/test/test_assignment.cpp new file mode 100644 index 000000000..ab8be58c6 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_assignment.cpp @@ -0,0 +1,790 @@ +// +// Copyright (c) 2010 Athanasios Iliopoulos +// +// 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) +// + +#include <boost/numeric/ublas/assignment.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/vector_proxy.hpp> +#include <boost/numeric/ublas/vector_sparse.hpp> +#include <boost/numeric/ublas/matrix_sparse.hpp> +#include <boost/numeric/ublas/io.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/timer.hpp> +#include <ctime> +#include "common/testhelper.hpp" +#include "utils.hpp" + +using namespace boost::numeric::ublas; + +template <class V> +bool test_vector() { + bool pass = true; + + V a(3), ra(3); + a <<= 1, 2, 3; + ra(0) = typename V::value_type(1); ra(1) = typename V::value_type(2); ra(2) = typename V::value_type(3); + pass &= compare_distance(a, ra); + + V b(7), rb(7); + b<<= a, 10, a; + rb(0) = typename V::value_type(1); rb(1) = typename V::value_type(2); rb(2) = typename V::value_type(3); + rb(3) = typename V::value_type(10); rb(4) = typename V::value_type(1); rb(5) = typename V::value_type(2); rb(6) = typename V::value_type(3); + pass &= compare_distance(b, rb); + + { + V c(6), rc(6); + c <<= 1, move(2), 3 ,4, 5, move(-5), 10, 10; + rc(0) = typename V::value_type(1); rc(1) = typename V::value_type(10); rc(2) = typename V::value_type(10); + rc(3) = typename V::value_type(3); rc(4) = typename V::value_type(4); rc(5) = typename V::value_type(5); + pass &= compare_distance(c, rc); + + V d(6), rd(6); + d <<= 1, move_to(3), 3 ,4, 5, move_to(1), 10, 10; + rd(0) = typename V::value_type(1); rd(1) = typename V::value_type(10); rd(2) = typename V::value_type(10); + rd(3) = typename V::value_type(3); rd(4) = typename V::value_type(4); rd(5) = typename V::value_type(5); + pass &= compare_distance(d, rd); + } + + { + V c(6), rc(6); + c <<= 1, move<2>(), 3 ,4, 5, move<-5>(), 10, 10; + rc(0) = typename V::value_type(1); rc(1) = typename V::value_type(10); rc(2) = typename V::value_type(10); + rc(3) = typename V::value_type(3); rc(4) = typename V::value_type(4); rc(5) = typename V::value_type(5); + pass &= compare_distance(c, rc); + + V d(6), rd(6); + d <<= 1, move_to<3>(), 3 ,4, 5, move_to<1>(), 10, 10; + rd(0) = typename V::value_type(1); rd(1) = typename V::value_type(10); rd(2) = typename V::value_type(10); + rd(3) = typename V::value_type(3); rd(4) = typename V::value_type(4); rd(5) = typename V::value_type(5); + pass &= compare_distance(d, rd); + } + + + { + V f(6), rf(6); + f <<= 5, 5, 5, 5, 5, 5; + V fa(3); fa<<= 1, 2, 3; + f <<= fill_policy::index_plus_assign(), fa; + rf <<= 6,7,8, 5, 5, 5; + pass &= compare_distance(f, rf); + } + + { + V f(6), rf(6); + f <<= 5, 5, 5, 5, 5, 5; + V fa(3); fa<<= 1, 2, 3; + f <<= fill_policy::index_minus_assign(), fa; + rf <<= 4,3,2, 5, 5, 5; + pass &= compare_distance(f, rf); + } + + return pass; +} + +template <class V> +bool test_vector_sparse_push_back() { + bool pass = true; + + V a(3), ra(3); + a <<= fill_policy::sparse_push_back(), 1, 2, 3; + ra(0) = typename V::value_type(1); ra(1) = typename V::value_type(2); ra(2) = typename V::value_type(3); + pass &= compare_distance(a, ra); + + V b(7), rb(7); + b<<= fill_policy::sparse_push_back(), a, 10, a; + rb(0) = typename V::value_type(1); rb(1) = typename V::value_type(2); rb(2) = typename V::value_type(3); + rb(3) = typename V::value_type(10), rb(4)= typename V::value_type(1); rb(5) = typename V::value_type(2); rb(6) = typename V::value_type(3); + pass &= compare_distance(b, rb); + + V c(6), rc(6); + c <<= fill_policy::sparse_push_back(), 1, move(2), 3 ,4, 5; // Move back (i.e. negative is dangerous for push_back) + rc(0) = typename V::value_type(1); rc(1) = typename V::value_type(0); rc(2) = typename V::value_type(0); + rc(3) = typename V::value_type(3); rc(4) = typename V::value_type(4); rc(5) = typename V::value_type(5); + pass &= compare_distance(c, rc); + + V d(6), rd(6); + d <<= fill_policy::sparse_push_back(), 1, move_to(3), 3 ,4, 5; // Move back (i.e. before current index is dangerous for push_back) + rd(0) = typename V::value_type(1); rd(1) = typename V::value_type(0); rd(2) = typename V::value_type(0); + rd(3) = typename V::value_type(3); rd(4) = typename V::value_type(4); rd(5) = typename V::value_type(5); + pass &= compare_distance(d, rd); + + V e(6), re(6); + e <<= fill_policy::sparse_push_back(), 1, move_to(3), 3 ,4, 5, fill_policy::sparse_insert(), move_to(1), 10, 10; // If you want to move back, use this + re(0) = typename V::value_type(1); re(1) = typename V::value_type(10); re(2) = typename V::value_type(10); + re(3) = typename V::value_type(3); re(4) = typename V::value_type(4); re(5) = typename V::value_type(5); + pass &= compare_distance(e, re); + + return pass; +} + + +template <class V> +bool test_vector_sparse_insert() { + bool pass = true; + + V a(3), ra(3); + a <<= fill_policy::sparse_insert(), 1, 2, 3; + ra(0) = typename V::value_type(1); ra(1) = typename V::value_type(2); ra(2) = typename V::value_type(3); + pass &= compare_distance(a, ra); + + V b(7), rb(7); + b<<= fill_policy::sparse_insert(), a, 10, a; + rb(0) = typename V::value_type(1); rb(1) = typename V::value_type(2); rb(2) = typename V::value_type(3); + rb(3) = typename V::value_type(10), rb(4) = typename V::value_type(1); rb(5)= typename V::value_type(2); rb(6) = typename V::value_type(3); + pass &= compare_distance(b, rb); + + V c(6), rc(6); + c <<= fill_policy::sparse_insert(), 1, move(2), 3 ,4, 5, move(-5), 10, 10; // Move back (i.e. negative is dangerous for sparse) + rc(0) = typename V::value_type(1); rc(1) = typename V::value_type(10); rc(2) = typename V::value_type(10); + rc(3) = typename V::value_type(3); rc(4) = typename V::value_type(4); rc(5) = typename V::value_type(5); + pass &= compare_distance(c, rc); + + + V d(6), rd(6); + d <<= fill_policy::sparse_insert(), 1, move_to(3), 3 ,4, 5, move_to(1), 10, 10; // Move back (i.e.before is dangerous for sparse) + rd(0) = typename V::value_type(1); rd(1) = typename V::value_type(10); rd(2) = typename V::value_type(10); + rd(3) = typename V::value_type(3); rd(4) = typename V::value_type(4); rd(5) = typename V::value_type(5); + pass &= compare_distance(d, rd); + + + return pass; +} + + +template <class V> +bool test_matrix() { + bool pass = true; + + V A(3,3), RA(3,3); + A <<= 1, 2, 3, 4, 5, 6, 7, 8, 9; + RA(0,0)= typename V::value_type(1); RA(0,1)=typename V::value_type(2); RA(0,2)=typename V::value_type(3); + RA(1,0)= typename V::value_type(4); RA(1,1)=typename V::value_type(5); RA(1,2)=typename V::value_type(6); + RA(2,0)= typename V::value_type(7); RA(2,1)=typename V::value_type(8); RA(2,2)=typename V::value_type(9); + pass &= compare_distance(A, RA); + + { + V B(3,3), RB(3,3); + vector<typename V::value_type> b(3); + b<<= 4,5,6; + B<<= 1, 2, 3, b, 7, project(b, range(1,3)); + RB<<=1, 2, 3, 4, 5, 6, 7, 5, 6; // If the first worked we can now probably use it. + pass &= compare_distance(B, RB); + } + + { + V B(3,3), RB(3,3); + vector<typename V::value_type> b(3); + b<<= 4,5,6; + B<<= move(1,0), b, move_to(0,0), 1, 2, 3, move(1,0), 7, project(b, range(1,3)); + RB<<=1, 2, 3, 4, 5, 6, 7, 5, 6; + pass &= compare_distance(B, RB); + } + + { + V B(3,3), RB(3,3); + vector<typename V::value_type> b(9); + b<<= 1, 2, 3, 4, 5, 6, 7, 8, 9; + B<<=b; + RB<<=1, 2, 3, 4, 5, 6, 7, 8, 9; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + V C(2,2); + C <<= 2, 3, + 4, 5; + B<<= C,C, + C,C; + RB <<= 2,3,2,3, + 4,5,4,5, + 2,3,2,3, + 4,5,4,5; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + V C(2,2); + C <<= 2, 3, 4, 5; + B<<= C, zero_matrix<typename V::value_type>(2,2), + zero_matrix<typename V::value_type>(2,2), C; + RB<<= 2,3,0,0, + 4,5,0,0, + 0,0,2,3, + 0,0,4,5; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + V C(2,2); + C <<= 2, 3, 4, 5; + B<<= C, zero_matrix<typename V::value_type>(2,2), + zero_matrix<typename V::value_type>(2,2), C; + RB<<= 2,3,0,0, + 4,5,0,0, + 0,0,2,3, + 0,0,4,5; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); // We need that because of the non-zero instatiation of dense types. + V C(2,2); + C <<= 2, 3, 4, 5; + B<<= move(1,1), C; + RB<<= 0,0,0,0, + 0,2,3,0, + 0,4,5,0, + 0,0,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<= move_to(0,1), 2, 3, next_row(), 1, 2, next_row(), 4, 5; + RB<<= 0,2,3,0, + 1,2,0,0, + 4,5,0,0, + 0,0,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=traverse_policy::by_column(), move_to(0,1), 2, 3, 6, next_column(), 4, 5; + RB<<= 0,2,4,0, + 0,3,5,0, + 0,6,0,0, + 0,0,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=traverse_policy::by_column(), move_to(0,1), 2, 3, next_row(), traverse_policy::by_row(), 4, 5; + RB<<= 0,2,0,0, + 0,3,0,0, + 0,0,0,0, + 4,5,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=traverse_policy::by_column(), move_to(0,1), 2, 3, begin2(), traverse_policy::by_row(), 4, 5, 6, 7, 8; + RB<<= 0,2,0,0, + 0,3,0,0, + 4,5,6,7, + 8,0,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=traverse_policy::by_column(), move_to(0,1), 2, 3, begin2(), traverse_policy::by_row(), 4, 5, 6, 7, 8,9, begin1(), 1, 2; + RB<<= 0,2,1,2, + 0,3,0,0, + 4,5,6,7, + 8,9,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = scalar_matrix<typename V::value_type>(4,4,1); + V C(2,2); + C <<= 1, 2, 3, 4; + B<<= fill_policy::index_plus_assign(), move(1,1), C; + RB<<= 1,1,1,1, + 1,2,3,1, + 1,4,5,1, + 1,1,1,1; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = scalar_matrix<typename V::value_type>(4,4,5); + V C(2,2); + C <<= 1, 2, 3, 4; + B<<= fill_policy::index_minus_assign(), move(1,1), C; + RB<<= 5,5,5,5, + 5,4,3,5, + 5,2,1,5, + 5,5,5,5; + pass &= compare_distance(B, RB); + } + + + return pass; +} + +template <class V> +bool test_matrix_sparse_push_back() { + bool pass = true; + + V A(3,3), RA(3,3); + A <<= fill_policy::sparse_push_back(), 1, 2, 3, 4, 5, 6, 7, 8, 9; + RA(0,0)= typename V::value_type(1); RA(0,1)= typename V::value_type(2); RA(0,2)= typename V::value_type(3); + RA(1,0)= typename V::value_type(4); RA(1,1)= typename V::value_type(5); RA(1,2)= typename V::value_type(6); + RA(2,0)= typename V::value_type(7); RA(2,1)= typename V::value_type(8); RA(2,2)= typename V::value_type(9); + pass &= compare_distance(A, RA); + + { + V B(3,3), RB(3,3); + vector<typename V::value_type> b(3); + b<<= 4,5,6; + B<<=fill_policy::sparse_push_back(), 1, 2, 3, b, 7, project(b, range(1,3)); + RB<<= 1, 2, 3, 4, 5, 6, 7, 5, 6; // If the first worked we can now probably use it. + pass &= compare_distance(B, RB); + } + + { + V B(3,3), RB(3,3); + vector<typename V::value_type> b(3); + b<<= 4,5,6; + B<<=fill_policy::sparse_push_back(), move(1,0), b, fill_policy::sparse_insert(), move_to(0,0), 1, 2, 3, move(1,0), 7, project(b, range(1,3)); + RB<<=1, 2, 3, 4, 5, 6, 7, 5, 6; + pass &= compare_distance(B, RB); + } + + { + V B(3,3), RB(3,3); + vector<typename V::value_type> b(9); + b<<= 1, 2, 3, 4, 5, 6, 7, 8, 9; + B<<=b; + RB<<=1, 2, 3, 4, 5, 6, 7, 8, 9; + pass &= compare_distance(B, RB); + } + + + { + V B(4,4), RB(4,4); + V C(2,2); + C <<= 2, 3, + 4, 5; + // It might get complicated for sparse push_back, this must go into the tutorial. (This way is not convient nor fast) + B<<=fill_policy::sparse_push_back(), C, move_to(2,2), C, fill_policy::sparse_insert(), move_to(0,2), C, C; + RB <<= 2,3,2,3, + 4,5,4,5, + 2,3,2,3, + 4,5,4,5; + pass &= compare_distance(B, RB); + } + + + { + V B(4,4), RB(4,4); + V C(2,2); + C <<= 2, 3, 4, 5; + B<<=fill_policy::sparse_push_back(), C, move_to(2,2), C; + RB<<= 2,3,0,0, + 4,5,0,0, + 0,0,2,3, + 0,0,4,5; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + V C(2,2); + C <<= 2, 3, 4, 5; + B<<=fill_policy::sparse_push_back(), move(1,1), C; + RB<<= 0,0,0,0, + 0,2,3,0, + 0,4,5,0, + 0,0,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=fill_policy::sparse_push_back(), move_to(0,1), 2, 3, next_row(), 1, 2, next_row(), 4, 5; + RB<<= 0,2,3,0, + 1,2,0,0, + 4,5,0,0, + 0,0,0,0; + pass &= compare_distance(B, RB); + } + // The next will not work with sparse push_back because elements that are prior to the ones already in are attempted to be added +/* + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=fill_policy::sparse_push_back(),traverse_policy::by_column(), move_to(0,1), 2, 3, 6, next_column(), 4, 5; + RB<<= 0,2,4,0, + 0,3,5,0, + 0,6,0,0, + 0,0,0,0; + pass &= compare_distance(B, RB); + } +*/ + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=fill_policy::sparse_push_back(),traverse_policy::by_column(), move_to(0,1), 2, 3, next_row(), traverse_policy::by_row(), 4, 5; + RB<<= 0,2,0,0, + 0,3,0,0, + 0,0,0,0, + 4,5,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=fill_policy::sparse_push_back(),traverse_policy::by_column(), move_to(0,1), 2, 3, begin2(), traverse_policy::by_row(), 4, 5, 6, 7, 8; + RB<<= 0,2,0,0, + 0,3,0,0, + 4,5,6,7, + 8,0,0,0; + pass &= compare_distance(B, RB); + } + + // The next will not work with sparse push_back because elements that are prior to the ones already in are attempted to be added +/* + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=fill_policy::sparse_push_back(),traverse_policy::by_column(), move_to(0,1), 2, 3, begin2(), traverse_policy::by_row(), 4, 5, 6, 7, 8,9, begin1(), 1, 2; + RB<<= 0,2,1,2, + 0,3,0,0, + 4,5,6,7, + 8,9,0,0; + pass &= compare_distance(B, RB); + } +*/ + return pass; +} + +template <class V> +bool test_matrix_sparse_insert() { + bool pass = true; + + V A(3,3), RA(3,3); + A <<= fill_policy::sparse_insert(), 1, 2, 3, 4, 5, 6, 7, 8, 9; + RA(0,0)= typename V::value_type(1); RA(0,1)= typename V::value_type(2); RA(0,2)= typename V::value_type(3); + RA(1,0)= typename V::value_type(4); RA(1,1)= typename V::value_type(5); RA(1,2)= typename V::value_type(6); + RA(2,0)= typename V::value_type(7); RA(2,1)= typename V::value_type(8); RA(2,2)= typename V::value_type(9); + pass &= compare_distance(A, RA); + + { + V B(3,3), RB(3,3); + vector<typename V::value_type> b(3); + b<<= 4,5,6; + B<<=fill_policy::sparse_insert(), 1, 2, 3, b, 7, project(b, range(1,3)); + RB<<=1, 2, 3, 4, 5, 6, 7, 5, 6; // If the first worked we can now probably use it. + pass &= compare_distance(B, RB); + } + + { + V B(3,3), RB(3,3); + vector<typename V::value_type> b(3); + b<<= 4,5,6; + B<<=fill_policy::sparse_insert(), move(1,0), b, fill_policy::sparse_insert(), move_to(0,0), 1, 2, 3, move(1,0), 7, project(b, range(1,3)); + RB<<=1, 2, 3, 4, 5, 6, 7, 5, 6; + pass &= compare_distance(B, RB); + } + + { + V B(3,3), RB(3,3); + vector<typename V::value_type> b(9); + b<<= 1, 2, 3, 4, 5, 6, 7, 8, 9; + B<<=b; + RB<<=1, 2, 3, 4, 5, 6, 7, 8, 9; + pass &= compare_distance(B, RB); + } + + + { + V B(4,4), RB(4,4); + V C(2,2); + C <<= 2, 3, + 4, 5; + B<<=fill_policy::sparse_insert(), C, C, C, C; + RB <<= 2,3,2,3, + 4,5,4,5, + 2,3,2,3, + 4,5,4,5; + pass &= compare_distance(B, RB); + } + + + { + V B(4,4), RB(4,4); + V C(2,2); + C <<= 2, 3, 4, 5; + B<<=fill_policy::sparse_insert(), C, move_to(2,2), C; + RB<<= 2,3,0,0, + 4,5,0,0, + 0,0,2,3, + 0,0,4,5; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + V C(2,2); + C <<= 2, 3, 4, 5; + B<<=fill_policy::sparse_insert(), move(1,1), C; + RB<<= 0,0,0,0, + 0,2,3,0, + 0,4,5,0, + 0,0,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=fill_policy::sparse_insert(), move_to(0,1), 2, 3, next_row(), 1, 2, next_row(), 4, 5; + RB<<= 0,2,3,0, + 1,2,0,0, + 4,5,0,0, + 0,0,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=fill_policy::sparse_insert(),traverse_policy::by_column(), move_to(0,1), 2, 3, 6, next_column(), 4, 5; + RB<<= 0,2,4,0, + 0,3,5,0, + 0,6,0,0, + 0,0,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=fill_policy::sparse_insert(),traverse_policy::by_column(), move_to(0,1), 2, 3, next_row(), traverse_policy::by_row(), 4, 5; + RB<<= 0,2,0,0, + 0,3,0,0, + 0,0,0,0, + 4,5,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=fill_policy::sparse_insert(),traverse_policy::by_column(), move_to(0,1), 2, 3, begin2(), traverse_policy::by_row(), 4, 5, 6, 7, 8; + RB<<= 0,2,0,0, + 0,3,0,0, + 4,5,6,7, + 8,0,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=fill_policy::sparse_insert(),traverse_policy::by_column(), move_to(0,1), 2, 3, begin2(), traverse_policy::by_row(), 4, 5, 6, 7, 8,9, begin1(), 1, 2; + RB<<= 0,2,1,2, + 0,3,0,0, + 4,5,6,7, + 8,9,0,0; + pass &= compare_distance(B, RB); + } + + return pass; +} + + +BOOST_UBLAS_TEST_DEF (test_vector) { + + BOOST_UBLAS_DEBUG_TRACE( "Starting operator \"<<= \" vector assignment tests" ); + + BOOST_UBLAS_TEST_CHECK(test_vector<vector<double> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<vector<float> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<vector<long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<vector<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<vector<int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<vector<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<vector<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<vector<char> >()); + + BOOST_UBLAS_TEST_CHECK((test_vector<bounded_vector<double,7> >())); + BOOST_UBLAS_TEST_CHECK((test_vector<bounded_vector<float,7> >())); + BOOST_UBLAS_TEST_CHECK((test_vector<bounded_vector<long,7> >())); + BOOST_UBLAS_TEST_CHECK((test_vector<bounded_vector<unsigned long,7> >())); + BOOST_UBLAS_TEST_CHECK((test_vector<bounded_vector<int,7> >())); + BOOST_UBLAS_TEST_CHECK((test_vector<bounded_vector<unsigned int,7> >())); + BOOST_UBLAS_TEST_CHECK((test_vector<bounded_vector<std::size_t,7> >())); + BOOST_UBLAS_TEST_CHECK((test_vector<bounded_vector<char,7> >())); + + BOOST_UBLAS_TEST_CHECK(test_vector<mapped_vector<double> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<mapped_vector<float> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<mapped_vector<long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<mapped_vector<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<mapped_vector<int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<mapped_vector<unsigned int> >()) + BOOST_UBLAS_TEST_CHECK(test_vector<mapped_vector<std::size_t> >()) + BOOST_UBLAS_TEST_CHECK(test_vector<mapped_vector<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_vector<compressed_vector<double> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<compressed_vector<float> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<compressed_vector<long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<compressed_vector<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<compressed_vector<int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<compressed_vector<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<compressed_vector<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<compressed_vector<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_vector<coordinate_vector<double> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<coordinate_vector<float> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<coordinate_vector<long> >()) + BOOST_UBLAS_TEST_CHECK(test_vector<coordinate_vector<unsigned long> >()) + BOOST_UBLAS_TEST_CHECK(test_vector<coordinate_vector<int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<coordinate_vector<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<coordinate_vector<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<coordinate_vector<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<compressed_vector<double> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<compressed_vector<float> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<compressed_vector<long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<compressed_vector<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<compressed_vector<int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<compressed_vector<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<compressed_vector<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<compressed_vector<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<coordinate_vector<double> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<coordinate_vector<float> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<coordinate_vector<long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<coordinate_vector<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<coordinate_vector<int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<coordinate_vector<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<coordinate_vector<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<coordinate_vector<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<compressed_vector<double> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<compressed_vector<float> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<compressed_vector<long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<compressed_vector<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<compressed_vector<int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<compressed_vector<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<compressed_vector<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<compressed_vector<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<coordinate_vector<double> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<coordinate_vector<float> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<coordinate_vector<long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<coordinate_vector<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<coordinate_vector<int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<coordinate_vector<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<coordinate_vector<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<coordinate_vector<char> >()); +} + +BOOST_UBLAS_TEST_DEF (test_matrix) { + + BOOST_UBLAS_DEBUG_TRACE( "Starting operator \"<<= \" matrix assignment tests" ); + + BOOST_UBLAS_TEST_CHECK(test_matrix<matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<matrix<char> >()); + + BOOST_UBLAS_TEST_CHECK((test_matrix<bounded_matrix<double,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix<bounded_matrix<float,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix<bounded_matrix<long,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix<bounded_matrix<unsigned long,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix<bounded_matrix<int,7,7 > >())); + BOOST_UBLAS_TEST_CHECK((test_matrix<bounded_matrix<unsigned int,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix<bounded_matrix<char,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix<bounded_matrix<std::size_t,7, 7> >())); + + BOOST_UBLAS_TEST_CHECK(test_matrix<mapped_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<mapped_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<mapped_matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<mapped_matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<mapped_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<mapped_matrix<unsigned int> >()) + BOOST_UBLAS_TEST_CHECK(test_matrix<mapped_matrix<std::size_t> >()) + BOOST_UBLAS_TEST_CHECK(test_matrix<mapped_matrix<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_matrix<compressed_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<compressed_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<compressed_matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<compressed_matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<compressed_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<compressed_matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<compressed_matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<compressed_matrix<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_matrix<coordinate_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<coordinate_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<coordinate_matrix<long> >()) + BOOST_UBLAS_TEST_CHECK(test_matrix<coordinate_matrix<unsigned long> >()) + BOOST_UBLAS_TEST_CHECK(test_matrix<coordinate_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<coordinate_matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<coordinate_matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<coordinate_matrix<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<compressed_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<compressed_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<compressed_matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<compressed_matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<compressed_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<compressed_matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<compressed_matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<compressed_matrix<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<coordinate_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<coordinate_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<coordinate_matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<coordinate_matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<coordinate_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<coordinate_matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<coordinate_matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<coordinate_matrix<char> >()); + + + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<compressed_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<compressed_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<compressed_matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<compressed_matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<compressed_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<compressed_matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<compressed_matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<compressed_matrix<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<coordinate_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<coordinate_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<coordinate_matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<coordinate_matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<coordinate_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<coordinate_matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<coordinate_matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<coordinate_matrix<char> >()); +} + + +int main () { + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( test_vector ); + BOOST_UBLAS_TEST_DO( test_matrix ); + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/test_banded_storage_layout.cpp b/src/boost/libs/numeric/ublas/test/test_banded_storage_layout.cpp new file mode 100644 index 000000000..d5c640b93 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_banded_storage_layout.cpp @@ -0,0 +1,287 @@ + +#include <iostream> +#include <boost/numeric/ublas/banded.hpp> +#include <boost/numeric/ublas/io.hpp> +#include <boost/numeric/ublas/operation.hpp> +#include <iomanip> + +#include "utils.hpp" + +using namespace boost::numeric::ublas; + +int expected_index( size_t index, column_major ) { + // this is the data shown on http://www.netlib.org/lapack/lug/node124.html + // read column-by-column, aka column_major + int mapping[] = { 0, 11, 21, 31, 12, 22, 32, 42, 23, 33, 43, 53, 34, 44, 54, 0, 45, 55, 0, 0 }; + return mapping[ index ]; +} + + +int expected_index( size_t index, row_major ) { + // this is the data shown on http://www.netlib.org/lapack/lug/node124.html + // read row-by-row, aka row_major + int mapping[] = { 0, 0, 11, 12, 0, 21, 22, 23, 31, 32, 33, 34, 42, 43, 44, 45, 53, 54, 55, 0 }; + return mapping[ index ]; +} + +int expected_index_6_by_5( size_t index, column_major ) { + // read column-by-column, aka column_major + int mapping[] = { 0, 11, 21, 31, 12, 22, 32, 42, 23, 33, 43, 53, 34, 44, 54, 64, 45, 55, 65, 0 }; + return mapping[ index ]; +} + +int expected_index_6_by_5( size_t index, row_major ) { + // read row-by-row, aka row_major + int mapping[] = { 0, 0, 11, 12, 0, 21, 22, 23, 31, 32, 33, 34, 42, 43, 44, 45, 53, 54, 55, 0, 64, 65, 0, 0 }; + return mapping[ index ]; +} + +int expected_index_5_by_6( size_t index, column_major ) { + // read column-by-column, aka column_major + int mapping[] = { 0, 11, 21, 31, 12, 22, 32, 42, 23, 33, 43, 53, 34, 44, 54, 0, 45, 55, 0, 0, 56, 0, 0, 0 }; + return mapping[ index ]; +} + +int expected_index_5_by_6( size_t index, row_major ) { + // read row-by-row, aka row_major + int mapping[] = { 0, 0, 11, 12, 0, 21, 22, 23, 31, 32, 33, 34, 42, 43, 44, 45, 53, 54, 55, 56}; + return mapping[ index ]; +} + +template< typename Orientation > +bool test_band_storage() { + + int m = 5; + int n = 5; + int kl = 2; + int ku = 1; + + banded_matrix< int, Orientation > test_matrix( m, n, kl, ku ); + test_matrix.clear(); + size_t band_storage_size = test_matrix.data().size(); + + test_matrix( 0, 0 ) = 11; + test_matrix( 0, 1 ) = 12; + test_matrix( 1, 0 ) = 21; + test_matrix( 1, 1 ) = 22; + test_matrix( 1, 2 ) = 23; + test_matrix( 2, 0 ) = 31; + test_matrix( 2, 1 ) = 32; + test_matrix( 2, 2 ) = 33; + test_matrix( 2, 3 ) = 34; + test_matrix( 3, 1 ) = 42; + test_matrix( 3, 2 ) = 43; + test_matrix( 3, 3 ) = 44; + test_matrix( 3, 4 ) = 45; + test_matrix( 4, 2 ) = 53; + test_matrix( 4, 3 ) = 54; + test_matrix( 4, 4 ) = 55; + + BOOST_UBLAS_TEST_TRACE( "Full matrix" ); + BOOST_UBLAS_TEST_TRACE( std::setw( 3 ) << test_matrix ); + + BOOST_UBLAS_TEST_TRACE( "data() of matrix" ); + for ( size_t i = 0; i < band_storage_size; ++i ) { + std::cerr << test_matrix.data()[ i ] << " "; + } + std::cerr << std::endl; + + BOOST_UBLAS_TEST_TRACE( "Expected data() of matrix" ); + for ( size_t i = 0; i < band_storage_size; ++i ) { + std::cerr << expected_index( i, Orientation() ) << " "; + } + std::cerr << std::endl; + + size_t mismatch = 0; + + for ( size_t i = 0; i < band_storage_size; ++i ) { + if ( test_matrix.data()[ i ] != expected_index( i, Orientation() ) ) { + ++mismatch; + } + } + + return 0 == mismatch; +} + +template< typename Orientation > +bool test_band_storage_6_by_5() { + + int m = 6; + int n = 5; + int kl = 2; + int ku = 1; + + + banded_matrix< int, Orientation > test_matrix( m, n, kl, ku ); + test_matrix.clear(); + size_t band_storage_size = test_matrix.data().size(); + + test_matrix( 0, 0 ) = 11; + test_matrix( 0, 1 ) = 12; + test_matrix( 1, 0 ) = 21; + test_matrix( 1, 1 ) = 22; + test_matrix( 1, 2 ) = 23; + test_matrix( 2, 0 ) = 31; + test_matrix( 2, 1 ) = 32; + test_matrix( 2, 2 ) = 33; + test_matrix( 2, 3 ) = 34; + test_matrix( 3, 1 ) = 42; + test_matrix( 3, 2 ) = 43; + test_matrix( 3, 3 ) = 44; + test_matrix( 3, 4 ) = 45; + test_matrix( 4, 2 ) = 53; + test_matrix( 4, 3 ) = 54; + test_matrix( 4, 4 ) = 55; + test_matrix( 5, 3 ) = 64; + test_matrix( 5, 4 ) = 65; + + BOOST_UBLAS_TEST_TRACE( "Full matrix" ); + BOOST_UBLAS_TEST_TRACE( std::setw( 3 ) << test_matrix ); + + BOOST_UBLAS_TEST_TRACE( "data() of matrix" ); + for ( size_t i = 0; i < band_storage_size; ++i ) { + std::cerr << test_matrix.data()[ i ] << " "; + } + std::cerr << std::endl; + + BOOST_UBLAS_TEST_TRACE( "Expected data() of matrix" ); + for ( size_t i = 0; i < band_storage_size; ++i ) { + std::cerr << expected_index_6_by_5( i, Orientation() ) << " "; + } + std::cerr << std::endl; + + size_t mismatch = 0; + + for ( size_t i = 0; i < band_storage_size; ++i ) { + if ( test_matrix.data()[ i ] != expected_index_6_by_5( i, Orientation() ) ) { + ++mismatch; + } + } + + return 0 == mismatch; +} + +template< typename Orientation > +bool test_band_storage_5_by_6() { + + int m = 5; + int n = 6; + int kl = 2; + int ku = 1; + + banded_matrix< int, Orientation > test_matrix( m, n, kl, ku ); + test_matrix.clear(); + size_t band_storage_size = test_matrix.data().size(); + + test_matrix( 0, 0 ) = 11; + test_matrix( 0, 1 ) = 12; + test_matrix( 1, 0 ) = 21; + test_matrix( 1, 1 ) = 22; + test_matrix( 1, 2 ) = 23; + test_matrix( 2, 0 ) = 31; + test_matrix( 2, 1 ) = 32; + test_matrix( 2, 2 ) = 33; + test_matrix( 2, 3 ) = 34; + test_matrix( 3, 1 ) = 42; + test_matrix( 3, 2 ) = 43; + test_matrix( 3, 3 ) = 44; + test_matrix( 3, 4 ) = 45; + test_matrix( 4, 2 ) = 53; + test_matrix( 4, 3 ) = 54; + test_matrix( 4, 4 ) = 55; + test_matrix( 4, 5 ) = 56; + + BOOST_UBLAS_TEST_TRACE( "Full matrix" ); + BOOST_UBLAS_TEST_TRACE( std::setw( 3 ) << test_matrix ); + + BOOST_UBLAS_TEST_TRACE( "data() of matrix" ); + for ( size_t i = 0; i < band_storage_size; ++i ) { + std::cerr << test_matrix.data()[ i ] << " "; + } + std::cerr << std::endl; + + BOOST_UBLAS_TEST_TRACE( "Expected data() of matrix" ); + for ( size_t i = 0; i < band_storage_size; ++i ) { + std::cerr << expected_index_5_by_6( i, Orientation() ) << " "; + } + std::cerr << std::endl; + + size_t mismatch = 0; + + for ( size_t i = 0; i < band_storage_size; ++i ) { + if ( test_matrix.data()[ i ] != expected_index_5_by_6( i, Orientation() ) ) { + ++mismatch; + } + } + + return 0 == mismatch; +} + + + + +BOOST_UBLAS_TEST_DEF( banded_matrix_column_major ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: storage layout banded_matrix < column_major >" ); + + BOOST_UBLAS_TEST_CHECK( test_band_storage< column_major >() ); +} + +BOOST_UBLAS_TEST_DEF( banded_matrix_row_major ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: storage layout banded_matrix < row_major >" ); + + BOOST_UBLAS_TEST_CHECK( test_band_storage< row_major >() ); +} + +BOOST_UBLAS_TEST_DEF( banded_matrix_column_major_6_by_5 ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: storage layout banded_matrix < column_major > 6x5" ); + + BOOST_UBLAS_TEST_CHECK( test_band_storage_6_by_5< column_major >() ); +} + +BOOST_UBLAS_TEST_DEF( banded_matrix_row_major_6_by_5 ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: storage layout banded_matrix < row_major > 6x5" ); + + BOOST_UBLAS_TEST_CHECK( test_band_storage_6_by_5< row_major >() ); +} + +BOOST_UBLAS_TEST_DEF( banded_matrix_column_major_5_by_6 ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: storage layout banded_matrix < column_major > 5x6" ); + + BOOST_UBLAS_TEST_CHECK( test_band_storage_5_by_6< column_major >() ); +} + +BOOST_UBLAS_TEST_DEF( banded_matrix_row_major_5_by_6 ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: storage layout banded_matrix < row_major > 5x6" ); + + BOOST_UBLAS_TEST_CHECK( test_band_storage_5_by_6< row_major >() ); +} + +int main() +{ + + BOOST_UBLAS_TEST_SUITE( "Test storage layout of banded matrix type" ); + + BOOST_UBLAS_TEST_TRACE( "Example data taken from http://www.netlib.org/lapack/lug/node124.html" ); + + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( banded_matrix_column_major ); + + BOOST_UBLAS_TEST_DO( banded_matrix_row_major ); + + BOOST_UBLAS_TEST_DO( banded_matrix_column_major_6_by_5 ); + + BOOST_UBLAS_TEST_DO( banded_matrix_row_major_6_by_5 ); + + BOOST_UBLAS_TEST_DO( banded_matrix_column_major_5_by_6 ); + + BOOST_UBLAS_TEST_DO( banded_matrix_row_major_5_by_6 ); + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/test_complex_norms.cpp b/src/boost/libs/numeric/ublas/test/test_complex_norms.cpp new file mode 100644 index 000000000..0c37ed45b --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_complex_norms.cpp @@ -0,0 +1,119 @@ +// Copyright 2010 Gunter Winkler <guwi17@gmx.de> +// 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) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/io.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <complex> + +#include "utils.hpp" + +using namespace boost::numeric::ublas; + +static const double TOL(1.0e-5); ///< Used for comparing two real numbers. + +BOOST_UBLAS_TEST_DEF ( test_double_complex_norm_inf ) { + typedef std::complex<double> dComplex; + vector<dComplex> v(4); + for (unsigned int i = 0; i < v.size(); ++i) + v[i] = dComplex(i, i + 1); + + const double expected = abs(v[3]); + + BOOST_UBLAS_DEBUG_TRACE( "norm is " << norm_inf(v) ); + BOOST_UBLAS_TEST_CHECK(std::abs(norm_inf(v) - expected) < TOL); + v *= 3.; + BOOST_UBLAS_TEST_CHECK(std::abs(norm_inf(v) - (3.0*expected)) < TOL); +} + +BOOST_UBLAS_TEST_DEF ( test_double_complex_norm_2 ) { + typedef std::complex<double> dComplex; + vector<dComplex> v(4); + for (unsigned int i = 0; i < v.size(); ++i) + v[i] = dComplex(i, i + 1); + + const double expected = sqrt(44.0); + + BOOST_UBLAS_DEBUG_TRACE( "norm is " << norm_2(v) ); + BOOST_UBLAS_TEST_CHECK(std::abs(norm_2(v) - expected) < TOL); + v *= 3.; + BOOST_UBLAS_TEST_CHECK(std::abs(norm_2(v) - (3.0*expected)) < TOL); +} + +BOOST_UBLAS_TEST_DEF ( test_double_complex_norm_2_square ) { + typedef std::complex<double> dComplex; + vector<dComplex> v(4); + for (unsigned int i = 0; i < v.size(); ++i) + v[i] = dComplex(i, i + 1); + + const double expected = 44; + + BOOST_UBLAS_DEBUG_TRACE( "square norm is " << norm_2_square(v) ); + BOOST_UBLAS_TEST_CHECK(std::abs(norm_2_square(v) - expected) < TOL); + v *= 3.; + BOOST_UBLAS_TEST_CHECK(std::abs(norm_2_square(v) - (9.0*expected)) < TOL); +} + + +BOOST_UBLAS_TEST_DEF ( test_float_complex_norm_inf ) { + typedef std::complex<float> dComplex; + vector<dComplex> v(4); + for (unsigned short i = 0; i < v.size(); ++i) { + unsigned short imag(i + 1); + v[i] = dComplex(i, imag); + } + + const float expected = abs(v[3]); + + BOOST_UBLAS_DEBUG_TRACE( "norm is " << norm_inf(v) ); + BOOST_UBLAS_TEST_CHECK(std::abs(norm_inf(v) - expected) < TOL); + v *= 3.f; + BOOST_UBLAS_TEST_CHECK(std::abs(norm_inf(v) - (3.0*expected)) < TOL); +} + +BOOST_UBLAS_TEST_DEF ( test_float_complex_norm_2 ) { + typedef std::complex<float> dComplex; + vector<dComplex> v(4); + for (unsigned short i = 0; i < v.size(); ++i) { + unsigned short imag(i + 1); + v[i] = dComplex(i, imag); + } + + const double expected = sqrt(44.0); + + BOOST_UBLAS_DEBUG_TRACE( "norm is " << norm_2(v) ); + BOOST_UBLAS_TEST_CHECK(std::abs(norm_2(v) - expected) < TOL); + v *= 3.f; + BOOST_UBLAS_TEST_CHECK(std::abs(norm_2(v) - (3.0*expected)) < TOL); +} + +BOOST_UBLAS_TEST_DEF ( test_float_complex_norm_2_square ) { + typedef std::complex<float> dComplex; + vector<dComplex> v(4); + for (unsigned short i = 0; i < v.size(); ++i) { + unsigned short imag(i + 1); + v[i] = dComplex(i, imag); + } + + const double expected = 44; + + BOOST_UBLAS_DEBUG_TRACE( "square norm is " << norm_2_square(v) ); + BOOST_UBLAS_TEST_CHECK(std::abs(norm_2_square(v) - expected) < TOL); + v *= 3.f; + BOOST_UBLAS_TEST_CHECK(std::abs(norm_2_square(v) - (9.0*expected)) < TOL); +} + +int main() { + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( test_double_complex_norm_inf ); + BOOST_UBLAS_TEST_DO( test_float_complex_norm_inf ); + BOOST_UBLAS_TEST_DO( test_double_complex_norm_2 ); + BOOST_UBLAS_TEST_DO( test_float_complex_norm_2 ); + BOOST_UBLAS_TEST_DO( test_double_complex_norm_2_square ); + BOOST_UBLAS_TEST_DO( test_float_complex_norm_2_square ); + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/test_coordinate_matrix_inplace_merge.cpp b/src/boost/libs/numeric/ublas/test/test_coordinate_matrix_inplace_merge.cpp new file mode 100644 index 000000000..aac3504eb --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_coordinate_matrix_inplace_merge.cpp @@ -0,0 +1,118 @@ +// Copyright (c) 2011 David Bellot +// +// 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) + +#ifndef BOOST_UBLAS_NO_ELEMENT_PROXIES +# define BOOST_UBLAS_NO_ELEMENT_PROXIES +#endif + +#include <boost/numeric/ublas/assignment.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_sparse.hpp> +#include <boost/numeric/ublas/matrix_expression.hpp> +#include <boost/numeric/ublas/io.hpp> +#include "common/testhelper.hpp" +#include "utils.hpp" + +using std::cout; +using std::endl; + +const double TOL = 1e-15; + +template<typename T> +bool check_sortedness(const boost::numeric::ublas::coordinate_matrix<T>& matrix) { + bool result = true; + typedef boost::numeric::ublas::coordinate_matrix<T> matrix_type; + typename matrix_type::index_array_type i1 = matrix.index1_data(); + typename matrix_type::index_array_type i2 = matrix.index2_data(); + typename matrix_type::array_size_type size = matrix.filled(); + + for (typename matrix_type::array_size_type i = 0; i + 1 < size && result; ++ i) { + result &= ( (i1[i] < i1[i + 1]) || + ((i1[i] == i1[i]) && + (i2[i] < i2[i + 1])) ); + + } + return result; +} + +void print_entries(size_t size_x, size_t size_y, + const std::vector<std::pair<size_t, size_t> >& entries) +{ + std::cerr << "Error - Size:" << size_x << " x " << size_y << ". Entries: "; + for (size_t i = 0; i < entries.size(); ++ i) { + std::cerr << entries[i].first << ", " << entries[i].second << "; "; + } + std::cerr << "\n"; +} + + +BOOST_UBLAS_TEST_DEF( test_coordinate_matrix_inplace_merge_random ) +{ + const size_t max_repeats = 100; + const size_t max_size = 100; + const size_t dim_var = 10; + const size_t nr_entries = 10; + + for (size_t repeats = 1; repeats < max_repeats; ++repeats ) { + for (size_t size = 1; size < max_size; size += 5) { + size_t size_x = size + rand() % dim_var; + size_t size_y = size + rand() % dim_var; + + boost::numeric::ublas::coordinate_matrix<double> matrix_coord(size_x, size_y); + boost::numeric::ublas::matrix<double> matrix_dense(size_x, size_y, 0); + + matrix_coord.sort(); + + std::vector<std::pair<size_t, size_t> > entries; + for (size_t entry = 0; entry < nr_entries; ++ entry) { + int x = rand() % size_x; + int y = rand() % size_y; + entries.push_back(std::make_pair(x, y)); + matrix_coord.append_element(x, y, 1); + matrix_dense(x, y) += 1; + } + matrix_coord.sort(); + + { + bool sorted = check_sortedness(matrix_coord); + bool identical = compare_distance(matrix_coord, matrix_dense, TOL); + if (!(sorted && identical)) { + print_entries(size_x, size_y, entries); + } + BOOST_UBLAS_TEST_CHECK( check_sortedness(matrix_coord) ); + BOOST_UBLAS_TEST_CHECK( compare_distance(matrix_coord, matrix_dense, TOL) ); + } + + for (size_t entry = 0; entry < nr_entries; ++ entry) { + int x = rand() % size_x; + int y = rand() % size_y; + entries.push_back(std::make_pair(x, y)); + matrix_coord(x, y) += 1; + matrix_dense(x, y) += 1; + matrix_coord.sort(); + } + + { + bool sorted = check_sortedness(matrix_coord); + bool identical = compare_distance(matrix_coord, matrix_dense, TOL); + if (!(sorted && identical)) { + print_entries(size_x, size_y, entries); + } + BOOST_UBLAS_TEST_CHECK( sorted ); + BOOST_UBLAS_TEST_CHECK( identical ); + } + } + } +} + +int main() +{ + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( test_coordinate_matrix_inplace_merge_random ); + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/test_coordinate_matrix_sort.cpp b/src/boost/libs/numeric/ublas/test/test_coordinate_matrix_sort.cpp new file mode 100644 index 000000000..d07abb3b1 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_coordinate_matrix_sort.cpp @@ -0,0 +1,73 @@ +// Copyright (c) 2011 David Bellot +// +// 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) + +#ifndef BOOST_UBLAS_NO_ELEMENT_PROXIES +# define BOOST_UBLAS_NO_ELEMENT_PROXIES +#endif + +#include<boost/numeric/ublas/matrix_sparse.hpp> +#include<boost/numeric/ublas/io.hpp> + +#include "utils.hpp" + +using std::cout; +using std::endl; + +BOOST_UBLAS_TEST_DEF( test_coordinate_matrix_sort ) +{ + + boost::numeric::ublas::coordinate_matrix<double> matrix_mask(3, 3, 2); + cout << "Setting matrix(1,1) = 2.1" << endl; + matrix_mask(1,1) = 2.1; + + cout << "Displaying matrix(1,1)" << endl; + std::cout << matrix_mask(1,1) << std::endl; + + BOOST_UBLAS_DEBUG_TRACE( "Displaying matrix(1,1)" << matrix_mask(1,1) ); + BOOST_UBLAS_TEST_CHECK( matrix_mask(1,1) == 2.1 ); + + BOOST_UBLAS_TEST_CHECK( matrix_mask.index1_data()[0] == 1 ); + BOOST_UBLAS_TEST_CHECK( matrix_mask.index2_data()[0] == 1 ); + BOOST_UBLAS_TEST_CHECK( matrix_mask.value_data()[0] == 2.1 ); + + BOOST_UBLAS_DEBUG_TRACE( "Setting matrix(0,1) = 1.1" ); + matrix_mask(0, 1) = 1.1; + + BOOST_UBLAS_TEST_CHECK( matrix_mask.index1_data()[0] == 1 ); + BOOST_UBLAS_TEST_CHECK( matrix_mask.index2_data()[0] == 1 ); + BOOST_UBLAS_TEST_CHECK( matrix_mask.value_data()[0] == 2.1 ); + + BOOST_UBLAS_TEST_CHECK( matrix_mask.index1_data()[1] == 0 ); + BOOST_UBLAS_TEST_CHECK( matrix_mask.index2_data()[1] == 1 ); + BOOST_UBLAS_TEST_CHECK( matrix_mask.value_data()[1] == 1.1 ); + + BOOST_UBLAS_DEBUG_TRACE( "Sort the matrix - this would be triggered by any element lookup." ); + matrix_mask.sort(); + + BOOST_UBLAS_TEST_CHECK( matrix_mask.index1_data()[1] == 1 ); + BOOST_UBLAS_TEST_CHECK( matrix_mask.index2_data()[1] == 1 ); + BOOST_UBLAS_TEST_CHECK( matrix_mask.value_data()[1] == 2.1 ); + + BOOST_UBLAS_TEST_CHECK( matrix_mask.index1_data()[0] == 0 ); + BOOST_UBLAS_TEST_CHECK( matrix_mask.index2_data()[0] == 1 ); + BOOST_UBLAS_TEST_CHECK( matrix_mask.value_data()[0] == 1.1 ); + + BOOST_UBLAS_DEBUG_TRACE( "Displaying matrix(1,1)" << matrix_mask(1,1) ); + BOOST_UBLAS_TEST_CHECK( matrix_mask(1,1) == 2.1 ); + + BOOST_UBLAS_DEBUG_TRACE( "Displaying matrix(0,1)" << matrix_mask(0,1) ); + BOOST_UBLAS_TEST_CHECK( matrix_mask(0,1) == 1.1 ); + +} + +int main() +{ + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( test_coordinate_matrix_sort ); + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/test_coordinate_vector_inplace_merge.cpp b/src/boost/libs/numeric/ublas/test/test_coordinate_vector_inplace_merge.cpp new file mode 100644 index 000000000..73a4247ce --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_coordinate_vector_inplace_merge.cpp @@ -0,0 +1,107 @@ +// Copyright (c) 2011 David Bellot +// +// 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) + +#ifndef BOOST_UBLAS_NO_ELEMENT_PROXIES +# define BOOST_UBLAS_NO_ELEMENT_PROXIES +#endif + +#include <boost/numeric/ublas/assignment.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/vector_sparse.hpp> +#include <boost/numeric/ublas/vector_expression.hpp> +#include <boost/numeric/ublas/io.hpp> +#include "common/testhelper.hpp" +#include "utils.hpp" + +const double TOL = 1e-15; + +template<typename T> +bool check_sortedness(const boost::numeric::ublas::coordinate_vector<T>& vector) { + bool result = true; + typedef boost::numeric::ublas::coordinate_vector<T> vector_type; + typename vector_type::index_array_type idx = vector.index_data(); + typename vector_type::size_type size = vector.filled(); + + for (typename vector_type::size_type i = 0; i + 1 < size && result; ++ i) { + result &= (idx[i] < idx[i + 1]); + } + return result; +} + +void print_entries(size_t size, + const std::vector<size_t>& entries) +{ + std::cerr << "Error entries - Size:" << size << ". Entries: "; + for (size_t i = 0; i < entries.size(); ++ i) { + std::cerr << entries[i] << "; "; + } + std::cerr << "\n"; +} + +BOOST_UBLAS_TEST_DEF( test_coordinate_vector_inplace_merge_random ) +{ + const size_t max_repeats = 100; + const size_t max_size = 100; + const size_t dim_var = 10; + const size_t nr_entries = 10; + + for (size_t repeats = 1; repeats < max_repeats; ++repeats ) { + for (size_t size = 1; size < max_size; size += 5) { + size_t size_vec = size + rand() % dim_var; + + boost::numeric::ublas::coordinate_vector<double> vector_coord(size_vec); + boost::numeric::ublas::vector<double> vector_dense(size_vec, 0); + + vector_coord.sort(); + + std::vector<size_t> entries; + for (size_t entry = 0; entry < nr_entries; ++ entry) { + int x = rand() % size_vec; + entries.push_back(x); + vector_coord.append_element(x, 1); + vector_dense(x) += 1; + } + vector_coord.sort(); + + { + bool sorted = check_sortedness(vector_coord); + bool identical = compare_distance(vector_coord, vector_dense, TOL); + if (!(sorted && identical)) { + print_entries(size_vec, entries); + } + BOOST_UBLAS_TEST_CHECK( check_sortedness(vector_coord) ); + BOOST_UBLAS_TEST_CHECK( compare_distance(vector_coord, vector_dense, TOL) ); + } + + for (size_t entry = 0; entry < nr_entries; ++ entry) { + int x = rand() % size_vec; + entries.push_back(x); + vector_coord(x) += 1; + vector_dense(x) += 1; + vector_coord.sort(); + } + + { + bool sorted = check_sortedness(vector_coord); + bool identical = compare_distance(vector_coord, vector_dense, TOL); + if (!(sorted && identical)) { + print_entries(size_vec, entries); + } + BOOST_UBLAS_TEST_CHECK( sorted ); + BOOST_UBLAS_TEST_CHECK( identical ); + } + } + } +} + +int main() +{ + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( test_coordinate_vector_inplace_merge_random ); + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/test_fixed_containers.cpp b/src/boost/libs/numeric/ublas/test/test_fixed_containers.cpp new file mode 100644 index 000000000..76f5a2886 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_fixed_containers.cpp @@ -0,0 +1,325 @@ +#undef BOOST_UBLAS_NO_EXCEPTIONS +#include "common/testhelper.hpp" +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/assignment.hpp> +#include <boost/numeric/ublas/io.hpp> +#include <string> +#include <complex> +#include <iomanip> +#include "utils.hpp" + +#ifdef BOOST_UBLAS_CPP_GE_2011 + +using namespace boost::numeric::ublas; + +using std::cout; +using std::endl; + + +template <typename T> +struct data_type { + typedef T value_type; +}; + +template <typename T> +struct data_type< std::complex<T> > { + typedef typename std::complex<T>::value_type value_type; +}; + + +template < class T > +bool test_vector( std::string type_name) +{ + typedef typename data_type<T>::value_type component_type; + + BOOST_UBLAS_DEBUG_TRACE( std::string("Testing for: ") + type_name ); + + bool pass = true; + + { + typedef fixed_vector<T, 1> vec1; + + vec1 v1( static_cast<component_type>(122.0) ); + + pass &= ( v1(0) == static_cast<component_type>(122.0) ); + + } + + { + typedef fixed_vector<T, 3> vec3; + + vec3 v1(static_cast<component_type>(0.0), + static_cast<component_type>(0.0), + static_cast<component_type>(0.0)); + + pass &=(sizeof( vec3 ) == v1.size() * sizeof( T ) ) ; + + vector<T> v( 3, 0 ) ; + + pass &= compare( v1, v ); + + v1 <<= static_cast<component_type>(10.0), 10, 33; + v <<= static_cast<component_type>(10.0), 10, 33; + + pass &= compare( v1, v ); + + + vec3 v2; + + v2( 0 ) = static_cast<component_type>(10.0); + v2( 1 ) = 10; + v2( 2 ) = 33; + pass &= compare( v, v2 ); + + v2 += v; + + pass &= compare( v2, 2*v ); + + + v1 = 2*v1 + v - 6*v2; + pass &= compare( v1, (3-2*6)*v ); + + + vec3 v3{ static_cast<component_type>(-90.0), + static_cast<component_type>(-90.0), + static_cast<component_type>(-297.0) }; + pass &= compare( v3, v1 ); + + vec3 v4 = { static_cast<component_type>(-90.0), + static_cast<component_type>(-90.0), + static_cast<component_type>(-297.0) }; + pass &= compare( v4, v1 ); + + vec3 v5( static_cast<component_type>(-90.0), + static_cast<component_type>(-90.0), + static_cast<component_type>(-297.0) ); + pass &= compare( v5, v1 ); + + vec3 v6( static_cast<component_type>(5.0), + static_cast<component_type>(8.0), + static_cast<component_type>(9.0) ); + + matrix<T> M = outer_prod( v6, v6), L( 3, 3); + + L <<= 25, 40, 45, 40, 64, 72, 45, 72, 81; + + pass &= compare( M, L ); + + L <<= 1, 2, 3, 4, 5, 6, 7, 8, 9; + v6 <<= 4, 5, 6; + vec3 v7 ( static_cast<component_type>(32.0), + static_cast<component_type>(77.0), + static_cast<component_type>(122.0) ); + + pass &= compare( v7, prod(L, v6) ); + + vec3 v8(prod(L, v6)); + + pass &= compare( v7, v8 ); + } + + + { + const std::size_t N = 33; + typedef fixed_vector<T, N> vec33; + + vec33 v1; + vector<T> v( N ); + + for ( std::size_t i = 0; i != v1.size(); i++) + { + v1( i ) = static_cast<component_type>(3.14159*i); + v ( i ) = static_cast<component_type>(3.14159*i); + } + + pass &= compare( v1, v ); + + + auto ip = inner_prod( v, v); + auto ip1 = inner_prod( v1, v1); + + pass &= ( ip == ip1 ) ; + + T c = 0; + for (auto i = v1.begin(); i != v1.end(); i++) + { + *i = c; + c = c + 1; + } + + c = 0; + for (auto i = v.begin(); i != v.end(); i++) + { + *i = c; + c = c + 1; + } + + pass &= compare( v1, v ); + + // Check if bad index indeed works + try { + T a; + a=v1( 100 ); + BOOST_UBLAS_NOT_USED( a ); + + } catch ( bad_index &e) { + std::cout << " Caught (GOOD): " << e.what() << endl; + pass &= true; + } + + + } + return pass; +} + +template < class T > +bool test_matrix( std::string type_name) +{ + typedef typename data_type<T>::value_type component_type; + + BOOST_UBLAS_DEBUG_TRACE( std::string("Testing for: ") + type_name ); + + bool pass = true; + + typedef fixed_matrix<T, 3, 4> mat34; + typedef fixed_matrix<T, 4, 3> mat43; + typedef fixed_matrix<T, 3, 3> mat33; + + + { + typedef fixed_matrix<T, 1, 1> mat1; + + mat1 m1( static_cast<component_type>(122.0) ); + + pass &= ( m1(0, 0) == static_cast<component_type>(122.0) ); + } + + + { + mat34 m1( T(static_cast<component_type>(3.0)) ); + + pass &=(sizeof( mat34 ) == m1.size1()*m1.size2()*sizeof( T ) ) ; + + matrix<T> m( 3, 4, static_cast<component_type>(3.0) ) ; + + pass &= compare( m1, m ); + + cout << m1 << endl; + cout << m << endl; + + + m1 <<= 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12; + m <<= 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12; + + pass &= compare( m1, m ); + + cout << m1 << endl; + cout << m << endl; + + mat34 m2( static_cast<component_type>(0.0) ); + + T count = 1 ; + for ( std::size_t i = 0; i != m2.size1(); i++) + { + for (std::size_t j = 0; j!= m2.size2(); j++) + { + m2( i, j ) = count; + count = count + 1; + } + + } + pass &= compare( m2, m ); + cout << m2 << endl; + + } + { + mat34 m1((T)1, (T)2, (T)3, (T)3, (T)3, (T)2, (T)5, (T)4, (T)2, (T)6, (T)5, (T)2); + mat43 m2((T)4, (T)5, (T)6, (T)3, (T)2, (T)2, (T)1, (T)4, (T)2, (T)6, (T)5, (T)2); + + mat33 m3(prod(m1, m2)); + + matrix<T> m(3, 3); + m <<= 31,36,22,47,59,40,43,52,38; + + pass &= compare(m ,m3); + + mat33 m4; + m4 <<= (T)1, (T)2, (T)1, (T)2, (T)1, (T)3, (T)1, (T)2, (T) 5; + m3 = prod(m4, trans(m4)); + + m<<=6,7,10,7,14,19,10,19,30; + + cout << m3 << endl; + pass &= compare(m ,m3); + + m3 = 2 * m4 - 1 * m3; + + cout << m3 << endl; + + m <<= -4,-3,-8,-3,-12,-13,-8,-15,-20; + + pass &= compare(m, m3); + + m = m3; + + m3 = trans(m); + + pass &= compare(m3, trans(m)); + + // Check if bad index indeed works + try { + T a; + a=m1( 100, 100 ); + BOOST_UBLAS_NOT_USED( a ); + + } catch ( bad_index &e) { + std::cout << " Caught (GOOD): " << e.what() << endl; + pass &= true; + } + + } + + return pass; + +} + +BOOST_UBLAS_TEST_DEF (test_fixed) { + + BOOST_UBLAS_DEBUG_TRACE( "Starting fixed container tests" ); + + BOOST_UBLAS_TEST_CHECK( test_vector< double >( "double") ); + BOOST_UBLAS_TEST_CHECK( test_vector< float >( "float") ); + BOOST_UBLAS_TEST_CHECK( test_vector< int >( "int") ); + + BOOST_UBLAS_TEST_CHECK( test_vector< std::complex<double> >( "std::complex<double>") ); + BOOST_UBLAS_TEST_CHECK( test_vector< std::complex<float> >( "std::complex<float>") ); + BOOST_UBLAS_TEST_CHECK( test_vector< std::complex<int> >( "std::complex<int>") ); + + BOOST_UBLAS_TEST_CHECK( test_matrix< double >( "double") ); + BOOST_UBLAS_TEST_CHECK( test_matrix< float >( "float") ); + BOOST_UBLAS_TEST_CHECK( test_matrix< int >( "int") ); + + BOOST_UBLAS_TEST_CHECK( test_matrix< std::complex<double> >( "std::complex<double>") ); + BOOST_UBLAS_TEST_CHECK( test_matrix< std::complex<float> >( "std::complex<float>") ); + BOOST_UBLAS_TEST_CHECK( test_matrix< std::complex<int> >( "std::complex<int>") ); +} + + +int main () { + + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( test_fixed ); + + BOOST_UBLAS_TEST_END(); +} + +#else + +int main () { + + BOOST_UBLAS_TEST_BEGIN(); + BOOST_UBLAS_TEST_END(); +} +#endif // BOOST_UBLAS_CPP_GE_2011 diff --git a/src/boost/libs/numeric/ublas/test/test_inplace_solve.cpp b/src/boost/libs/numeric/ublas/test/test_inplace_solve.cpp new file mode 100644 index 000000000..b2bf58d45 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_inplace_solve.cpp @@ -0,0 +1,123 @@ +#include <iostream> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_sparse.hpp> +#include <boost/numeric/ublas/triangular.hpp> +#include <boost/numeric/ublas/io.hpp> + +#include "utils.hpp" + +namespace ublas = boost::numeric::ublas; + +static const double TOL(1.0e-5); ///< Used for comparing two real numbers. +static const int n(10); ///< defines the test matrix size + +template<class mat, class vec> +double diff(const mat& A, const vec& x, const vec& b) { + return ublas::norm_2(prod(A, x) - b); +} + +// efficiently fill matrix depending on majority +template<class mat> +void fill_matrix(mat& A, ublas::column_major_tag) { + for (int i=0; i<n; ++i) { + if (i-1>=0) { + A(i-1, i) = -1; + } + A(i, i) = 1; + if (i+1<n) { + A(i+1, i) = -2; + } + } +} +template<class mat> +void fill_matrix(mat& A, ublas::row_major_tag) { + for (int i=0; i<n; ++i) { + if (i-1>=0) { + A(i, i-1) = -1; + } + A(i, i) = 1; + if (i+1<n) { + A(i, i+1) = -2; + } + } +} + +template<class mat> +BOOST_UBLAS_TEST_DEF ( test_inplace_solve ) +{ + mat A(n, n); + A.clear(); + fill_matrix(A, typename mat::orientation_category()); + + ublas::vector<double> b(n, 1.0); + + // The test matrix is not triangular, but is interpreted that way by + // inplace_solve using the lower_tag/upper_tags. For checking, the + // triangular_adaptor makes A triangular for comparison. + { + ublas::vector<double> x(b); + ublas::inplace_solve(A, x, ublas::lower_tag()); + BOOST_UBLAS_TEST_CHECK(diff(ublas::triangular_adaptor<mat, ublas::lower>(A), x, b) < TOL); + } + { + ublas::vector<double> x(b); + ublas::inplace_solve(A, x, ublas::upper_tag()); + BOOST_UBLAS_TEST_CHECK(diff (ublas::triangular_adaptor<mat, ublas::upper>(A), x, b) < TOL); + } + { + ublas::vector<double> x(b); + ublas::inplace_solve(x, A, ublas::lower_tag()); + BOOST_UBLAS_TEST_CHECK(diff (trans(ublas::triangular_adaptor<mat, ublas::lower>(A)), x, b) < TOL); + } + { + ublas::vector<double> x(b); + ublas::inplace_solve(x, A, ublas::upper_tag()); + BOOST_UBLAS_TEST_CHECK(diff (trans(ublas::triangular_adaptor<mat, ublas::upper>(A)), x , b) < TOL); + } +} + +int main() { + + // typedefs are needed as macros do not work with "," in template arguments + + BOOST_UBLAS_TEST_BEGIN(); + +#ifdef USE_MATRIX + typedef ublas::matrix<double, ublas::row_major> mat_doub_rowmaj; + typedef ublas::matrix<double, ublas::column_major> mat_doub_colmaj; + BOOST_UBLAS_TEST_DO( test_inplace_solve<mat_doub_rowmaj> ); + BOOST_UBLAS_TEST_DO( test_inplace_solve<mat_doub_colmaj> ); +#endif + +#ifdef USE_COMPRESSED_MATRIX + typedef ublas::compressed_matrix<double, ublas::row_major> commat_doub_rowmaj; + typedef ublas::compressed_matrix<double, ublas::column_major> commat_doub_colmaj; + BOOST_UBLAS_TEST_DO( test_inplace_solve<commat_doub_rowmaj> ); + BOOST_UBLAS_TEST_DO( test_inplace_solve<commat_doub_colmaj> ); +#endif + +#ifdef USE_MAPPED_MATRIX + typedef ublas::mapped_matrix<double, ublas::row_major> mapmat_doub_rowmaj; + typedef ublas::mapped_matrix<double, ublas::column_major> mapmat_doub_colmaj; + BOOST_UBLAS_TEST_DO( test_inplace_solve<mapmat_doub_rowmaj> ); + BOOST_UBLAS_TEST_DO( test_inplace_solve<mapmat_doub_colmaj> ); +#endif + +#ifdef USE_COORDINATE_MATRIX + typedef ublas::coordinate_matrix<double, ublas::row_major> cormat_doub_rowmaj; + typedef ublas::coordinate_matrix<double, ublas::column_major> cormat_doub_colmaj; + BOOST_UBLAS_TEST_DO( test_inplace_solve<cormat_doub_rowmaj> ); + BOOST_UBLAS_TEST_DO( test_inplace_solve<cormat_doub_colmaj> ); +#endif + +#ifdef USE_MAPPED_VECTOR_OF_MAPPED_VECTOR + typedef ublas::mapped_vector_of_mapped_vector<double, ublas::row_major> mvmv_doub_rowmaj; + typedef ublas::mapped_vector_of_mapped_vector<double, ublas::column_major> mvmv_doub_colmaj; + BOOST_UBLAS_TEST_DO( test_inplace_solve<mvmv_doub_rowmaj> ); + BOOST_UBLAS_TEST_DO( test_inplace_solve<mvmv_doub_colmaj> ); +#endif + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/test_lu.cpp b/src/boost/libs/numeric/ublas/test/test_lu.cpp new file mode 100644 index 000000000..866ecf2f2 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_lu.cpp @@ -0,0 +1,70 @@ +// Copyright 2008 Gunter Winkler <guwi17@gmx.de> +// 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) + +// switch automatic singular check off +#define BOOST_UBLAS_TYPE_CHECK 0 + +#include <boost/numeric/ublas/io.hpp> +#include <boost/numeric/ublas/lu.hpp> +#include <boost/cstdlib.hpp> + +#include "common/testhelper.hpp" + +#include <iostream> +#include <sstream> + +using namespace boost::numeric::ublas; +using std::string; + +static const string matrix_IN = "[3,3]((1,2,2),(2,3,3),(3,4,6))\0"; +static const string matrix_LU = "[3,3]((3,4,6),(3.33333343e-01,6.66666627e-01,0),(6.66666687e-01,4.99999911e-01,-1))\0"; +static const string matrix_INV= "[3,3]((-3,2,-7.94728621e-08),(1.50000012,0,-5.00000060e-01),(4.99999911e-01,-1,5.00000060e-01))\0"; +static const string matrix_PM = "[3](2,2,2)"; + +int main () { + + typedef float TYPE; + + typedef matrix<TYPE> MATRIX; + + MATRIX A; + MATRIX LU; + MATRIX INV; + + { + std::istringstream is(matrix_IN); + is >> A; + } + { + std::istringstream is(matrix_LU); + is >> LU; + } + { + std::istringstream is(matrix_INV); + is >> INV; + } + permutation_matrix<>::vector_type temp; + { + std::istringstream is(matrix_PM); + is >> temp; + } + permutation_matrix<> PM(temp); + + permutation_matrix<> pm(3); + + std::size_t result = lu_factorize<MATRIX, permutation_matrix<> >(A, pm); + + assertTrue("factorization completed: ", 0 == result); + assertTrue("LU factors are correct: ", compare(A, LU)); + assertTrue("permutation is correct: ", compare(pm, PM)); + + MATRIX B = identity_matrix<TYPE>(A.size2()); + + lu_substitute(A, pm, B); + + assertTrue("inverse is correct: ", compare(B, INV)); + + return (getResults().second > 0) ? boost::exit_failure : boost::exit_success; +} diff --git a/src/boost/libs/numeric/ublas/test/test_matrix_vector.cpp b/src/boost/libs/numeric/ublas/test/test_matrix_vector.cpp new file mode 100644 index 000000000..586028737 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_matrix_vector.cpp @@ -0,0 +1,456 @@ +// +// Copyright (c) 2013 Joaquim Duran +// +// 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) +// + +#include <boost/numeric/ublas/assignment.hpp> +#include <boost/numeric/ublas/matrix_sparse.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_vector.hpp> +#include "common/testhelper.hpp" +#include "utils.hpp" + +using namespace boost::numeric::ublas; + + +template <class Vector, class StorageCategory> +void guardSparsePreserveResize( Vector &vec, typename Vector::size_type new_size, StorageCategory) // Because sparse matrices don't have preserve data implemented +{ + vec.resize( new_size ); +} + + +template <class Vector> +void guardSparsePreserveResize( Vector &vec, typename Vector::size_type new_size, sparse_tag) // Because sparse matrices don't have preserve data implemented +{ + vec.resize( new_size, false ); +} + +template <class Matrix> +bool test_matrix_row_facade() { + bool pass = true; + + typedef matrix_row_vector<Matrix> RowVector; + + { // Testing resize + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_row_facade: resize" ); + + typename Matrix::size_type num_rows = 3; + typename Matrix::size_type num_cols = 5; + + Matrix matrix(num_rows, num_cols); + RowVector rows(matrix); + pass &= (matrix.size1() == num_rows); + pass &= (rows.size() == num_rows); + pass &= (matrix.size2() == num_cols); + + typename Matrix::size_type new_num_rows = 6; + guardSparsePreserveResize( rows, new_num_rows, typename Matrix::storage_category()); + //rows.resize(new_num_rows); + + pass &= (matrix.size1() == new_num_rows); + pass &= (rows.size() == new_num_rows); + pass &= (matrix.size2() == num_cols); + } + + { // Testing operator() + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_row_facade: operator()" ); + + Matrix A(3,3), RA(3,3); + RowVector rows(A); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + for(typename Matrix::size_type i = 0; i < A.size1(); i++) { + rows(i) = matrix_row<Matrix>(RA, i); + } + + pass &= compare_distance(A, RA); + } + + { // Testing operator[] + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_row_facade: operator[]" ); + + Matrix A(3,3), RA(3,3); + RowVector rows(A); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + for(typename Matrix::size_type i = 0; i < A.size1(); i++) { + rows[i] = matrix_row<Matrix>(RA, i); + } + + pass &= compare_distance(A, RA); + } + + { // Testing operator[] const + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_row_facade: operator[] const" ); + + Matrix RA(3,3); + RowVector rows(RA); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + for(typename Matrix::size_type i = 0; i < RA.size1(); i++) { + pass &= compare_distance(rows[i], matrix_row<Matrix>(RA, i)); + } + } + + { // Testing const iterator + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_row_facade: const iterator" ); + + Matrix RA(3,3); + RowVector rows(RA); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + typename RowVector::size_type i = 0; + for(typename RowVector::const_iterator iter = rows.begin(); + iter != rows.end(); + iter++) { + pass &= compare_distance(*iter, matrix_row<Matrix>(RA, i++)); + } + } + + { // Testing iterator + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_row_facade: iterator" ); + + Matrix A(3,3), RA(3,3); + RowVector rows(A); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + typename RowVector::size_type i = 0; + for(typename RowVector::iterator iter = rows.begin(); + iter != rows.end(); + iter++) { + *iter = matrix_row<Matrix>(RA, i++); + } + + pass &= compare_distance(A, RA); + } + + { // Testing reserse iterator + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_row_facade: reverse iterator" ); + + Matrix A(3,3), RA(3,3); + RowVector rows(A); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + typename RowVector::size_type i = rows.size(); + for(typename RowVector::reverse_iterator iter = rows.rbegin(); + iter != rows.rend(); + iter++) { + *iter = matrix_row<Matrix>(RA, --i); + } + + pass &= compare_distance(A, RA); + } + + { // Testing const reverse iterator + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_row_facade: const reverse iterator" ); + + Matrix RA(3,3); + RowVector rows(RA); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + typename RowVector::size_type i = rows.size(); + for(typename RowVector::const_reverse_iterator iter = rows.rbegin(); + iter != rows.rend(); + iter++) { + pass &= compare_distance(*iter, matrix_row<Matrix>(RA, --i)); + } + } + + return pass; +} + + +template <class Matrix> +bool test_matrix_column_facade() { + bool pass = true; + + typedef matrix_column_vector<Matrix> ColumnVector; + + { // Testing resize + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_column_facade: resize" ); + typename Matrix::size_type num_rows = 5; + typename Matrix::size_type num_cols = 3; + + Matrix matrix(num_rows, num_cols); + ColumnVector columns(matrix); + pass &= (matrix.size2() == num_cols); + pass &= (columns.size() == num_cols); + pass &= (matrix.size1() == num_rows); + + typename Matrix::size_type new_num_cols = 6; + guardSparsePreserveResize( columns, new_num_cols, typename Matrix::storage_category()); + //columns.resize(new_num_cols); + pass &= (matrix.size2() == new_num_cols); + pass &= (columns.size() == new_num_cols); + pass &= (matrix.size1() == num_rows); + } + + { // Testing operator () + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_column_facade: operator()" ); + + Matrix A(3,3), RA(3,3); + ColumnVector columns(A); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + for(typename Matrix::size_type i = 0; i < A.size2(); i++) { + columns(i) = matrix_column<Matrix>(RA, i); + } + + pass &= compare_distance(A, RA); + } + + { // Testing operator[] + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_column_facade: operator[]" ); + + Matrix A(3,3), RA(3,3); + ColumnVector columns(A); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + for(typename Matrix::size_type i = 0; i < A.size2(); i++) { + columns[i] = matrix_column<Matrix>(RA, i); + } + + pass &= compare_distance(A, RA); + } + + { // Testing operator[] const + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_column_facade: operator[] const" ); + + Matrix RA(3,3); + ColumnVector columns(RA); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + for(typename Matrix::size_type i = 0; i < RA.size2(); i++) { + pass &= compare_distance(columns[i], matrix_column<Matrix>(RA, i)); + } + } + + { // Testing iterator + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_column_facade: iterator" ); + + Matrix A(3,3), RA(3,3); + ColumnVector columns(A); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + typename ColumnVector::size_type i = 0; + for(typename ColumnVector::iterator iter = columns.begin(); + iter != columns.end(); + iter++) { + *iter = matrix_column<Matrix>(RA, i++); + } + + pass &= compare_distance(A, RA); + } + + { // Testing const iterator + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_column_facade: const iterator" ); + + Matrix RA(3,3); + ColumnVector columns(RA); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + typename ColumnVector::size_type i = 0; + for(typename ColumnVector::const_iterator iter = columns.begin(); + iter != columns.end(); + iter++) { + pass &= compare_distance(*iter, matrix_column<Matrix>(RA, i++)); + } + } + + { // Testing reserse iterator + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_column_facade: reverese iterator" ); + + Matrix A(3,3), RA(3,3); + ColumnVector columns(A); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + typename ColumnVector::size_type i = columns.size(); + for(typename ColumnVector::reverse_iterator iter = columns.rbegin(); + iter != columns.rend(); + iter++) { + *iter = matrix_column<Matrix>(RA, --i); + } + + pass &= compare_distance(A, RA); + } + + { // Testing const reverse iterator + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_column_facade: const reverese iterator" ); + + Matrix RA(3,3); + ColumnVector columns(RA); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + typename ColumnVector::size_type i = columns.size(); + for(typename ColumnVector::const_reverse_iterator iter = columns.rbegin(); + iter != columns.rend(); + iter++) { + pass &= compare_distance(*iter, matrix_column<Matrix>(RA, --i)); + } + } + + return pass; +} + + +BOOST_UBLAS_TEST_DEF (test_matrix_row_facade) { + + BOOST_UBLAS_DEBUG_TRACE( "Starting matrix row vector facade" ); + + BOOST_UBLAS_DEBUG_TRACE( "Testing matrix..." ); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<matrix<char> >()); + + BOOST_UBLAS_DEBUG_TRACE( "Testing bounded_matrix..." ); + BOOST_UBLAS_TEST_CHECK((test_matrix_row_facade<bounded_matrix<double,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_row_facade<bounded_matrix<float,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_row_facade<bounded_matrix<long,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_row_facade<bounded_matrix<unsigned long,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_row_facade<bounded_matrix<int,7,7 > >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_row_facade<bounded_matrix<unsigned int,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_row_facade<bounded_matrix<char,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_row_facade<bounded_matrix<std::size_t,7, 7> >())); + + BOOST_UBLAS_DEBUG_TRACE( "Testing mapped_matrix..." ); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<mapped_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<mapped_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<mapped_matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<mapped_matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<mapped_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<mapped_matrix<unsigned int> >()) + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<mapped_matrix<std::size_t> >()) + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<mapped_matrix<char> >()); + + BOOST_UBLAS_DEBUG_TRACE( "Testing compressed_matrix..." ); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<compressed_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<compressed_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<compressed_matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<compressed_matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<compressed_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<compressed_matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<compressed_matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<compressed_matrix<char> >()); + + BOOST_UBLAS_DEBUG_TRACE( "Testing coordinate_matrix..." ); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<coordinate_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<coordinate_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<coordinate_matrix<long> >()) + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<coordinate_matrix<unsigned long> >()) + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<coordinate_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<coordinate_matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<coordinate_matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<coordinate_matrix<char> >()); +} + + +BOOST_UBLAS_TEST_DEF (test_matrix_column_facade) { + + BOOST_UBLAS_DEBUG_TRACE( "Starting matrix row column facade" ); + + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<matrix<char> >()); + + BOOST_UBLAS_TEST_CHECK((test_matrix_column_facade<bounded_matrix<double,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_column_facade<bounded_matrix<float,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_column_facade<bounded_matrix<long,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_column_facade<bounded_matrix<unsigned long,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_column_facade<bounded_matrix<int,7,7 > >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_column_facade<bounded_matrix<unsigned int,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_column_facade<bounded_matrix<char,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_column_facade<bounded_matrix<std::size_t,7, 7> >())); + + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<mapped_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<mapped_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<mapped_matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<mapped_matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<mapped_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<mapped_matrix<unsigned int> >()) + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<mapped_matrix<std::size_t> >()) + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<mapped_matrix<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<compressed_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<compressed_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<compressed_matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<compressed_matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<compressed_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<compressed_matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<compressed_matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<compressed_matrix<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<coordinate_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<coordinate_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<coordinate_matrix<long> >()) + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<coordinate_matrix<unsigned long> >()) + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<coordinate_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<coordinate_matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<coordinate_matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<coordinate_matrix<char> >()); +} + + +int main () { + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( test_matrix_row_facade ); + BOOST_UBLAS_TEST_DO( test_matrix_column_facade ); + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/test_scaled_norm.cpp b/src/boost/libs/numeric/ublas/test/test_scaled_norm.cpp new file mode 100644 index 000000000..74065048f --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_scaled_norm.cpp @@ -0,0 +1,41 @@ +// 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) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/io.hpp> + +#include "utils.hpp" + +using namespace boost::numeric::ublas; + +static const double TOL(1.0e-5); ///< Used for comparing two real numbers. + +BOOST_UBLAS_TEST_DEF ( test_double_scaled_norm_2 ) { + vector<double> v(2); + v[0] = 0; v[1] = 1.0e155; + + const double expected = 1.0e155; + + BOOST_UBLAS_DEBUG_TRACE( "norm is " << norm_2(v) ); + BOOST_UBLAS_TEST_CHECK(std::abs(norm_2(v) - expected) < TOL); +} + +BOOST_UBLAS_TEST_DEF ( test_float_scaled_norm_2 ) { + vector<float> v(2); + v[0] = 0; v[1] = 1.0e20; + + const float expected = 1.0e20; + + BOOST_UBLAS_DEBUG_TRACE( "norm is " << norm_2(v) ); + BOOST_UBLAS_TEST_CHECK(std::abs(norm_2(v) - expected) < TOL); +} + +int main() { + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( test_double_scaled_norm_2 ); + BOOST_UBLAS_TEST_DO( test_float_scaled_norm_2 ); + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/test_ticket7296.cpp b/src/boost/libs/numeric/ublas/test/test_ticket7296.cpp new file mode 100644 index 000000000..bf4d2d861 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_ticket7296.cpp @@ -0,0 +1,292 @@ +/** + * \file libs/numeric/ublas/test/test_utils.hpp + * + * \brief Test suite for utils.hpp. + * + * Copyright (c) 2012, Marco Guazzone + * + * 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) + * + * \author Marco Guazzone (marco.guazzone@gmail.com) + */ + +#include <boost/numeric/ublas/io.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <complex> +#include <cstddef> +#include "utils.hpp" + + +namespace ublas = boost::numeric::ublas; + + +static const float tol(1e-6f); +static const float mul(tol*10); + + +BOOST_UBLAS_TEST_DEF( check ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: 'check'" ); + + BOOST_UBLAS_TEST_CHECK( true ); +} + +BOOST_UBLAS_TEST_DEF( check_eq ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: 'check_eq'" ); + + BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." ); + BOOST_UBLAS_TEST_CHECK_EQ( short(1), short(1) ); + BOOST_UBLAS_TEST_CHECK_EQ( int(1), int(1) ); + BOOST_UBLAS_TEST_CHECK_EQ( long(1), long(1) ); + BOOST_UBLAS_TEST_CHECK_EQ( unsigned(1), unsigned(1) ); + + BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." ); + BOOST_UBLAS_TEST_CHECK_EQ( short(1), int(1) ); + BOOST_UBLAS_TEST_CHECK_EQ( short(1), int(1) ); + BOOST_UBLAS_TEST_CHECK_EQ( int(1), long(1) ); + BOOST_UBLAS_TEST_CHECK_EQ( long(1), int(1) ); + + BOOST_UBLAS_DEBUG_TRACE( "-- Test aliases." ); + BOOST_UBLAS_TEST_CHECK_EQUAL( int(1), int(1) ); +} + +BOOST_UBLAS_TEST_DEF( check_close ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: 'check_close'" ); + + const float c1(1*mul); + const float c2(2*mul); + + // Check T vs. T + BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." ); + BOOST_UBLAS_TEST_CHECK_CLOSE( float(c1), float(c1), tol ); + BOOST_UBLAS_TEST_CHECK_CLOSE( double(c1), double(c1), tol ); + BOOST_UBLAS_TEST_CHECK_CLOSE( std::complex<float>(c1,c2), std::complex<float>(c1,c2), tol ); + BOOST_UBLAS_TEST_CHECK_CLOSE( std::complex<double>(c1,c2), std::complex<double>(c1,c2), tol ); + + // Check T1 vs. T2 + BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." ); + BOOST_UBLAS_TEST_CHECK_CLOSE( float(c1), double(c1), tol ); + BOOST_UBLAS_TEST_CHECK_CLOSE( double(c1), float(c1), tol ); + BOOST_UBLAS_TEST_CHECK_CLOSE( std::complex<float>(c1,c2), std::complex<double>(c1,c2), tol ); + BOOST_UBLAS_TEST_CHECK_CLOSE( std::complex<double>(c1,c2), std::complex<float>(c1,c2), tol ); + + // Check alias + BOOST_UBLAS_DEBUG_TRACE( "-- Test aliases." ); + BOOST_UBLAS_TEST_CHECK_PRECISION( float(c1), float(c1), tol ); +} + +BOOST_UBLAS_TEST_DEF( check_rel_close ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: 'check_rel_close'" ); + + const float c1(1*mul); + const float c2(2*mul); + + // Check T vs. T + BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." ); + BOOST_UBLAS_TEST_CHECK_REL_CLOSE( float(c1), float(c1), tol ); + BOOST_UBLAS_TEST_CHECK_REL_CLOSE( double(c1), double(c1), tol ); + BOOST_UBLAS_TEST_CHECK_REL_CLOSE( std::complex<float>(c1,c2), std::complex<float>(c1,c2), tol ); + BOOST_UBLAS_TEST_CHECK_REL_CLOSE( std::complex<double>(c1,c2), std::complex<double>(c1,c2), tol ); + + // Check T1 vs. T2 + BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." ); + BOOST_UBLAS_TEST_CHECK_REL_CLOSE( float(c1), double(c1), tol ); + BOOST_UBLAS_TEST_CHECK_REL_CLOSE( double(c1), float(c1), tol ); + BOOST_UBLAS_TEST_CHECK_REL_CLOSE( std::complex<float>(c1,c2), std::complex<double>(c1,c2), tol ); + BOOST_UBLAS_TEST_CHECK_REL_CLOSE( std::complex<double>(c1,c2), std::complex<float>(c1,c2), tol ); + + // Check alias + BOOST_UBLAS_DEBUG_TRACE( "-- Test aliases." ); + BOOST_UBLAS_TEST_CHECK_REL_PRECISION( float(c1), float(c1), tol ); +} + +BOOST_UBLAS_TEST_DEF( check_vector_eq ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: 'check_vector_eq'" ); + + const std::size_t n(5); + + ublas::vector<short> sv = ublas::scalar_vector<short>(n, 1); + ublas::vector<int> iv = ublas::scalar_vector<int>(n, 1); + ublas::vector<long> lv = ublas::scalar_vector<long>(n, 1L); + ublas::vector<unsigned> uv = ublas::scalar_vector<unsigned>(n, 1u); + + // Check T vs. T + BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." ); + BOOST_UBLAS_TEST_CHECK_VECTOR_EQ( sv, sv, n ); + BOOST_UBLAS_TEST_CHECK_VECTOR_EQ( iv, iv, n ); + BOOST_UBLAS_TEST_CHECK_VECTOR_EQ( lv, lv, n ); + BOOST_UBLAS_TEST_CHECK_VECTOR_EQ( uv, uv, n ); + + // Check T1 vs. T2 + BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." ); + BOOST_UBLAS_TEST_CHECK_VECTOR_EQ( sv, iv, n ); + BOOST_UBLAS_TEST_CHECK_VECTOR_EQ( iv, sv, n ); + BOOST_UBLAS_TEST_CHECK_VECTOR_EQ( iv, lv, n ); + BOOST_UBLAS_TEST_CHECK_VECTOR_EQ( lv, iv, n ); +} + +BOOST_UBLAS_TEST_DEF( check_vector_close ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: 'check_vector_close'" ); + + const std::size_t n(5); + + ublas::vector<float> fv = ublas::scalar_vector<float>(n, 1); + ublas::vector<float> dv = ublas::scalar_vector<float>(n, 1); + ublas::vector< std::complex<float> > cfv = ublas::scalar_vector< std::complex<float> >(n, std::complex<float>(1,2)); + ublas::vector< std::complex<double> > cdv = ublas::scalar_vector< std::complex<double> >(n, std::complex<double>(1,2)); + + // Check T vs. T + BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." ); + BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE( fv, fv, n, tol ); + BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE( dv, dv, n, tol ); + BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE( cfv, cfv, n, tol ); + BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE( cdv, cdv, n, tol ); + + // Check T1 vs. T2 + BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." ); + BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE( fv, dv, n, tol ); + BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE( dv, fv, n, tol ); + BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE( cfv, cdv, n, tol ); + BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE( cdv, cfv, n, tol ); +} + +BOOST_UBLAS_TEST_DEF( check_vector_rel_close ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: 'check_vector_rel_close'" ); + + const std::size_t n(5); + const float c1(1*mul); + const float c2(2*mul); + + ublas::vector<float> fv = ublas::scalar_vector<float>(n, c1); + ublas::vector<double> dv = ublas::scalar_vector<double>(n, c1); + ublas::vector< std::complex<float> > cfv = ublas::scalar_vector< std::complex<float> >(n, std::complex<float>(c1,c2)); + ublas::vector< std::complex<double> > cdv = ublas::scalar_vector< std::complex<double> >(n, std::complex<double>(c1,c2)); + + // Check T vs. T + BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." ); + BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE( fv, fv, n, tol ); + BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE( dv, dv, n, tol ); + BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE( cfv, cfv, n, tol ); + BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE( cdv, cdv, n, tol ); + + // Check T1 vs. T2 + BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." ); + BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE( fv, dv, n, tol ); + BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE( dv, fv, n, tol ); + BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE( cfv, cdv, n, tol ); + BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE( cdv, cfv, n, tol ); +} + +BOOST_UBLAS_TEST_DEF( check_matrix_eq ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: 'check_matrix_eq'" ); + + const std::size_t nr(3); + const std::size_t nc(4); + + ublas::matrix<short> sv = ublas::scalar_matrix<short>(nr, nc, 1); + ublas::matrix<int> iv = ublas::scalar_matrix<int>(nr, nc, 1); + ublas::matrix<long> lv = ublas::scalar_matrix<long>(nr, nc, 1L); + ublas::matrix<unsigned> uv = ublas::scalar_matrix<unsigned>(nr, nc, 1u); + + // Check T vs. T + BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." ); + BOOST_UBLAS_TEST_CHECK_MATRIX_EQ( sv, sv, nr, nc ); + BOOST_UBLAS_TEST_CHECK_MATRIX_EQ( iv, iv, nr, nc ); + BOOST_UBLAS_TEST_CHECK_MATRIX_EQ( lv, lv, nr, nc ); + BOOST_UBLAS_TEST_CHECK_MATRIX_EQ( uv, uv, nr, nc ); + + // Check T1 vs. T2 + BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." ); + BOOST_UBLAS_TEST_CHECK_MATRIX_EQ( sv, iv, nr, nc ); + BOOST_UBLAS_TEST_CHECK_MATRIX_EQ( iv, sv, nr, nc ); + BOOST_UBLAS_TEST_CHECK_MATRIX_EQ( iv, lv, nr, nc ); + BOOST_UBLAS_TEST_CHECK_MATRIX_EQ( lv, iv, nr, nc ); +} + +BOOST_UBLAS_TEST_DEF( check_matrix_close ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: 'check_matrix_close'" ); + + const std::size_t nr(3); + const std::size_t nc(4); + const float c1(1*mul); + const float c2(2*mul); + + ublas::matrix<float> fA = ublas::scalar_matrix<float>(nr, nc, c1); + ublas::matrix<double> dA = ublas::scalar_matrix<double>(nr, nc, c1); + ublas::matrix< std::complex<float> > cfA = ublas::scalar_matrix< std::complex<float> >(nr, nc, std::complex<float>(c1,c2)); + ublas::matrix< std::complex<double> > cdA = ublas::scalar_matrix< std::complex<double> >(nr, nc, std::complex<double>(c1,c2)); + + // Check T vs. T + BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." ); + BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE( fA, fA, nr, nc, tol ); + BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE( dA, dA, nr, nc, tol ); + BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE( cfA, cfA, nr, nc, tol ); + BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE( cdA, cdA, nr, nc, tol ); + + // Check T1 vs. T2 + BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." ); + BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE( fA, dA, nr, nc, tol ); + BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE( dA, fA, nr, nc, tol ); + BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE( cfA, cdA, nr, nc, tol ); + BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE( cdA, cfA, nr, nc, tol ); +} + + +BOOST_UBLAS_TEST_DEF( check_matrix_rel_close ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: 'check_matrix_rel_close'" ); + + const std::size_t nr(3); + const std::size_t nc(4); + const float c1(1*mul); + const float c2(2*mul); + + ublas::matrix<float> fA = ublas::scalar_matrix<float>(nr, nc, c1); + ublas::matrix<double> dA = ublas::scalar_matrix<double>(nr, nc, c1); + ublas::matrix< std::complex<float> > cfA = ublas::scalar_matrix< std::complex<float> >(nr, nc, std::complex<float>(c1,c2)); + ublas::matrix< std::complex<double> > cdA = ublas::scalar_matrix< std::complex<double> >(nr, nc, std::complex<double>(c1,c2)); + + // Check T vs. T + BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." ); + BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE( fA, fA, nr, nc, tol ); + BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE( dA, dA, nr, nc, tol ); + BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE( cfA, cfA, nr, nc, tol ); + BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE( cdA, cdA, nr, nc, tol ); + + // Check T1 vs. T2 + BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." ); + BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE( fA, dA, nr, nc, tol ); + BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE( dA, fA, nr, nc, tol ); + BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE( cfA, cdA, nr, nc, tol ); + BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE( cdA, cfA, nr, nc, tol ); +} + + +int main() +{ + BOOST_UBLAS_TEST_SUITE( "Test 'utils.hpp' functionalities" ); + + BOOST_UBLAS_TEST_BEGIN(); + BOOST_UBLAS_TEST_DO( check ); + BOOST_UBLAS_TEST_DO( check_eq ); + BOOST_UBLAS_TEST_DO( check_close ); + BOOST_UBLAS_TEST_DO( check_rel_close ); + BOOST_UBLAS_TEST_DO( check_vector_eq ); + BOOST_UBLAS_TEST_DO( check_vector_close ); + BOOST_UBLAS_TEST_DO( check_vector_rel_close ); + BOOST_UBLAS_TEST_DO( check_matrix_eq ); + BOOST_UBLAS_TEST_DO( check_matrix_close ); + BOOST_UBLAS_TEST_DO( check_matrix_rel_close ); + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/test_triangular.cpp b/src/boost/libs/numeric/ublas/test/test_triangular.cpp new file mode 100644 index 000000000..c6cba9134 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_triangular.cpp @@ -0,0 +1,129 @@ +#include <iostream> +#include <stdlib.h> +#include <cmath> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_sparse.hpp> +#include <boost/numeric/ublas/triangular.hpp> +#include <boost/numeric/ublas/io.hpp> + +#include <boost/timer/timer.hpp> + +namespace ublas = boost::numeric::ublas; + +template<class mat, class vec> +double diff(const mat& A, const vec& x, const vec& b) { + vec temp(prod(A, x) - b); + double result = 0; + for (typename vec::size_type i=0; i<temp.size(); ++i) { + result += temp(i)*temp(i); + } + return std::sqrt(result); +} + +template<class mat, class vec> +double diff(const vec& x, const mat& A, const vec& b) { + return diff(trans(A), x, b); +} + +namespace ublas = boost::numeric::ublas; + + +int main() { + const int n=7000; +#if 1 + ublas::compressed_matrix<double, ublas::row_major> mat_row_upp(n, n); + ublas::compressed_matrix<double, ublas::column_major> mat_col_upp(n, n); + ublas::compressed_matrix<double, ublas::row_major> mat_row_low(n, n); + ublas::compressed_matrix<double, ublas::column_major> mat_col_low(n, n); +#else + ublas::matrix<double, ublas::row_major> mat_row_upp(n, n, 0); + ublas::matrix<double, ublas::column_major> mat_col_upp(n, n, 0); + ublas::matrix<double, ublas::row_major> mat_row_low(n, n, 0); + ublas::matrix<double, ublas::column_major> mat_col_low(n, n, 0); +#endif + ublas::vector<double> b(n, 1); + + std::cerr << "Constructing..." << std::endl; + for (int i=0; i<n; ++i) { + b(i) = std::rand() % 10; + double main = -10 + std::rand() % 20 ; + if (main == 0) main+=1; + double side = -10 + std::rand() % 20 ; + if (i-1>=0) { + mat_row_low(i, i-1) = side; + } + mat_row_low(i, i) = main; + + mat_col_low(i, i) = main; + if (i+1<n) { + mat_col_low(i+1, i) = side; + } + + mat_row_upp(i, i) = main; + if (i+1<n) { + mat_row_upp(i, i+1) = side; + } + + if (i-1>=0) { + mat_col_upp(i-1, i) = side; + } + mat_col_upp(i, i) = main; + } + + std::cerr << "Starting..." << std::endl; + { + boost::timer::auto_cpu_timer t(std::cerr, "col_low x: %t sec CPU, %w sec real\n"); + ublas::vector<double> x(b); + ublas::inplace_solve(mat_col_low, x, ublas::lower_tag()); + std::cerr << "delta: " << diff(mat_col_low, x, b) << "\n"; + } + { + boost::timer::auto_cpu_timer t(std::cerr, "row_low x: %t sec CPU, %w sec real\n"); + ublas::vector<double> x(b); + ublas::inplace_solve(mat_row_low, x, ublas::lower_tag()); + std::cerr << "delta: " << diff(mat_row_low, x, b) << "\n"; + } + + { + boost::timer::auto_cpu_timer t(std::cerr, "col_upp x: %t sec CPU, %w sec real\n"); + ublas::vector<double> x(b); + ublas::inplace_solve(mat_col_upp, x, ublas::upper_tag()); + std::cerr << "delta: " << diff(mat_col_upp, x, b) << "\n"; + } + { + boost::timer::auto_cpu_timer t(std::cerr, "row_upp x: %t sec CPU, %w sec real\n"); + ublas::vector<double> x(b); + ublas::inplace_solve(mat_row_upp, x, ublas::upper_tag()); + std::cerr << "delta: " << diff(mat_row_upp, x, b) << "\n"; + } + + { + boost::timer::auto_cpu_timer t(std::cerr, "x col_low: %t sec CPU, %w sec real\n"); + ublas::vector<double> x(b); + ublas::inplace_solve(x, mat_col_low, ublas::lower_tag()); + std::cerr << "delta: " << diff(x, mat_col_low, b) << "\n"; + } + { + boost::timer::auto_cpu_timer t(std::cerr, "x row_low: %t sec CPU, %w sec real\n"); + ublas::vector<double> x(b); + ublas::inplace_solve(x, mat_row_low, ublas::lower_tag()); + std::cerr << "delta: " << diff(x, mat_row_low, b) << "\n"; + } + + { + boost::timer::auto_cpu_timer t(std::cerr, "x col_upp: %t sec CPU, %w sec real\n"); + ublas::vector<double> x(b); + ublas::inplace_solve(x, mat_col_upp, ublas::upper_tag()); + std::cerr << "delta: " << diff(x, mat_col_upp, b) << "\n"; + } + { + boost::timer::auto_cpu_timer t(std::cerr, "x row_upp: %t sec CPU, %w sec real\n"); + ublas::vector<double> x(b); + ublas::inplace_solve(x, mat_row_upp, ublas::upper_tag()); + std::cerr << "delta: " << diff(x, mat_row_upp, b) << "\n"; + } + + +} diff --git a/src/boost/libs/numeric/ublas/test/triangular_access.cpp b/src/boost/libs/numeric/ublas/test/triangular_access.cpp new file mode 100644 index 000000000..c2c9b7733 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/triangular_access.cpp @@ -0,0 +1,220 @@ +/* Test program to test find functions of triagular matrices + * + * author: Gunter Winkler ( guwi17 at gmx dot de ) + */ +// Copyright 2008 Gunter Winkler <guwi17@gmx.de> +// 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) + + +#include <boost/numeric/ublas/triangular.hpp> +#include <boost/numeric/ublas/io.hpp> +#include <boost/cstdlib.hpp> + +#include "common/testhelper.hpp" + +#ifdef BOOST_UBLAS_NO_NESTED_CLASS_RELATION +using boost::numeric::ublas::iterator1_tag; +using boost::numeric::ublas::iterator2_tag; +#endif + +template < class MAT > +void test_iterator( MAT & A ) { + +#ifndef NOMESSAGES + std::cout << "=>"; +#endif + // check mutable iterators + typename MAT::iterator1 it1 = A.begin1(); + typename MAT::iterator1 it1_end = A.end1(); + + for ( ; it1 != it1_end; ++it1 ) { +#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION + typename MAT::iterator2 it2 = it1.begin(); + typename MAT::iterator2 it2_end = it1.end(); +#else + typename MAT::iterator2 it2 = begin(it1, iterator1_tag()); + typename MAT::iterator2 it2_end = end(it1, iterator1_tag()); +#endif + for ( ; it2 != it2_end ; ++ it2 ) { +#ifndef NOMESSAGES + std::cout << "( " << it2.index1() << ", " << it2.index2() << ") " << std::flush; +#endif + * it2 = ( 10 * it2.index1() + it2.index2() ); + } +#ifndef NOMESSAGES + std::cout << std::endl; +#endif + } + +} + +template < class MAT > +void test_iterator2( MAT & A ) { + +#ifndef NOMESSAGES + std::cout << "=>"; +#endif + // check mutable iterators + typename MAT::iterator2 it2 = A.begin2(); + typename MAT::iterator2 it2_end = A.end2(); + + for ( ; it2 != it2_end; ++it2 ) { +#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION + typename MAT::iterator1 it1 = it2.begin(); + typename MAT::iterator1 it1_end = it2.end(); +#else + typename MAT::iterator1 it1 = begin(it2, iterator2_tag()); + typename MAT::iterator1 it1_end = end(it2, iterator2_tag()); +#endif + for ( ; it1 != it1_end ; ++ it1 ) { +#ifndef NOMESSAGES + std::cout << "( " << it1.index1() << ", " << it1.index2() << ") " << std::flush; +#endif + * it1 = ( 10 * it1.index1() + it1.index2() ); + } +#ifndef NOMESSAGES + std::cout << std::endl; +#endif + } + +} + +template < class MAT > +typename MAT::value_type +test_iterator3( const MAT & A ) { + +#ifndef NOMESSAGES + std::cout << "=>"; +#endif + typename MAT::value_type result = 0; + + // check mutable iterators + typename MAT::const_iterator1 it1 = A.begin1(); + typename MAT::const_iterator1 it1_end = A.end1(); + + for ( ; it1 != it1_end; ++it1 ) { +#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION + typename MAT::const_iterator2 it2 = it1.begin(); + typename MAT::const_iterator2 it2_end = it1.end(); +#else + typename MAT::const_iterator2 it2 = begin(it1, iterator1_tag()); + typename MAT::const_iterator2 it2_end = end(it1, iterator1_tag()); +#endif + for ( ; it2 != it2_end ; ++ it2 ) { +#ifndef NOMESSAGES + std::cout << "( " << it2.index1() << ", " << it2.index2() << ") " << std::flush; +#endif + result += * it2; + } +#ifndef NOMESSAGES + std::cout << std::endl; +#endif + } + return result; + +} + + +int main () { + using namespace boost::numeric::ublas; + + typedef double VALUE_TYPE; + typedef triangular_matrix<VALUE_TYPE, lower> LT; + typedef triangular_matrix<VALUE_TYPE, unit_lower> ULT; + typedef triangular_matrix<VALUE_TYPE, strict_lower> SLT; + typedef triangular_matrix<VALUE_TYPE, upper> UT; + typedef triangular_matrix<VALUE_TYPE, unit_upper> UUT; + typedef triangular_matrix<VALUE_TYPE, strict_upper> SUT; + + LT A(5,5); + + test_iterator(A); + test_iterator2(A); + + ULT B(5,5); + + test_iterator(B); + test_iterator2(B); + + SLT C(5,5); + + test_iterator(C); + test_iterator2(C); + + UT D(5,5); + + test_iterator(D); + test_iterator2(D); + + UUT E(5,5); + + test_iterator(E); + test_iterator2(E); + + SUT F(5,5); + + test_iterator(F); + test_iterator2(F); + + assertTrue("Write access using iterators: ", true); + + assertEquals(" LT: ",420.0,test_iterator3(A)); + assertEquals("ULT: ",315.0,test_iterator3(B)); + assertEquals("SLT: ",310.0,test_iterator3(C)); + assertEquals(" UT: ",240.0,test_iterator3(D)); + assertEquals("UUT: ",135.0,test_iterator3(E)); + assertEquals("SUT: ",130.0,test_iterator3(F)); + + assertTrue("Read access using iterators: ", true); + +#ifndef NOMESSAGES + std::cout << A << B << C << D << E << F << std::endl; +#endif + + typedef matrix<VALUE_TYPE> MATRIX; + MATRIX mat(5,5); + triangular_adaptor<MATRIX, lower> lta((mat)); + triangular_adaptor<MATRIX, unit_lower> ulta((mat)); + triangular_adaptor<MATRIX, strict_lower> slta((mat)); + triangular_adaptor<MATRIX, upper> uta((mat)); + triangular_adaptor<MATRIX, unit_upper> uuta((mat)); + triangular_adaptor<MATRIX, strict_upper> suta((mat)); + + test_iterator ( lta ); + test_iterator2( lta ); + + test_iterator ( ulta ); + test_iterator2( ulta ); + + test_iterator ( slta ); + test_iterator2( slta ); + + test_iterator ( uta ); + test_iterator2( uta ); + + test_iterator ( uuta ); + test_iterator2( uuta ); + + test_iterator ( suta ); + test_iterator2( suta ); + + assertTrue("Write access using adaptors: ", true); + + assertEquals(" LTA: ",420.0,test_iterator3( lta )); + assertEquals("ULTA: ",315.0,test_iterator3( ulta )); + assertEquals("SLTA: ",310.0,test_iterator3( slta )); + + assertEquals(" UTA: ",240.0,test_iterator3( uta )); + assertEquals("UUTA: ",135.0,test_iterator3( uuta )); + assertEquals("SUTA: ",130.0,test_iterator3( suta )); + + assertTrue("Read access using adaptors: ", true); + +#ifndef NOMESSAGES + std::cout << mat << std::endl; +#endif + + return (getResults().second > 0) ? boost::exit_failure : boost::exit_success; +} diff --git a/src/boost/libs/numeric/ublas/test/triangular_layout.cpp b/src/boost/libs/numeric/ublas/test/triangular_layout.cpp new file mode 100644 index 000000000..f4da9752b --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/triangular_layout.cpp @@ -0,0 +1,139 @@ +// Copyright 2008 Gunter Winkler <guwi17@gmx.de> +// Thanks to Tiago Requeijo for providing this test +// 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) + +#include <iostream> +#include <boost/numeric/ublas/symmetric.hpp> +#include <boost/numeric/ublas/triangular.hpp> +#include <boost/cstdlib.hpp> + +using namespace std; +namespace ublas = boost::numeric::ublas; + +int main() +{ + int sz = 4; + ublas::symmetric_matrix<int, ublas::upper, ublas::column_major> UpCol (sz, sz); + ublas::symmetric_matrix<int, ublas::upper, ublas::row_major> UpRow (sz, sz); + ublas::symmetric_matrix<int, ublas::lower, ublas::column_major> LoCol (sz, sz); + ublas::symmetric_matrix<int, ublas::lower, ublas::row_major> LoRow (sz, sz); + + ublas::triangular_matrix<int, ublas::upper, ublas::column_major> TrUpCol (sz, sz); + ublas::triangular_matrix<int, ublas::upper, ublas::row_major> TrUpRow (sz, sz); + ublas::triangular_matrix<int, ublas::lower, ublas::column_major> TrLoCol (sz, sz); + ublas::triangular_matrix<int, ublas::lower, ublas::row_major> TrLoRow (sz, sz); + + for(int i=0; i<sz; ++i) + for(int j=i; j<sz; ++j) + { + // Symmetric + UpCol(i,j) = 10*i + j; + UpRow(i,j) = 10*i + j; + LoCol(i,j) = 10*i + j; + LoRow(i,j) = 10*i + j; + // Triangular + TrUpCol(i,j) = 10*i + j; + TrUpRow(i,j) = 10*i + j; + TrLoCol(j,i) = 10*i + j; + TrLoRow(j,i) = 10*i + j; + } + + //get pointers to data + int* uc = &(UpCol.data()[0]); + int* ur = &(UpRow.data()[0]); + int* lc = &(LoCol.data()[0]); + int* lr = &(LoRow.data()[0]); + int* tuc = &(TrUpCol.data()[0]); + int* tur = &(TrUpRow.data()[0]); + int* tlc = &(TrLoCol.data()[0]); + int* tlr = &(TrLoRow.data()[0]); + + // upper, column_major + // storage should be: 0 1 11 2 12 22 3 13 23 33 + int uc_correct[] = {0, 1, 11, 2, 12, 22, 3, 13, 23, 33}; + + // upper, row_major + // storage should be: 0 1 2 3 11 12 13 22 23 33 + int ur_correct[] = {0, 1, 2, 3, 11, 12, 13, 22, 23, 33}; + + // lower, column_major + // storage should be: 0 1 2 3 11 12 13 22 23 33 + int lc_correct[] = {0, 1, 2, 3, 11, 12, 13, 22, 23, 33}; + + // lower, row_major + // storage should be: 0 1 11 2 12 22 3 13 23 33 + int lr_correct[] = {0, 1, 11, 2, 12, 22, 3, 13, 23, 33}; + + bool success = true; + + // Test Symmetric + for(int i=0; i<sz*(sz+1)/2; ++i) + if(uc[i] != uc_correct[i]) + { + cout << "Storage error (Symmetric, Upper, Column major)" << endl; + success = false; + break; + } + + for(int i=0; i<sz*(sz+1)/2; ++i) + if(ur[i] != ur_correct[i]) + { + cout << "Storage error (Symmetric, Upper, Row major)" << endl; + success = false; + break; + } + + for(int i=0; i<sz*(sz+1)/2; ++i) + if(lc[i] != lc_correct[i]) + { + cout << "Storage error (Symmetric, Lower, Column major)" << endl; + success = false; + break; + } + + for(int i=0; i<sz*(sz+1)/2; ++i) + if(lr[i] != lr_correct[i]) + { + cout << "Storage error (Symmetric, Lower, Row major)" << endl; + success = false; + break; + } + + // Test Triangular + for(int i=0; i<sz*(sz+1)/2; ++i) + if(tuc[i] != uc_correct[i]) + { + cout << "Storage error (Triangular, Upper, Column major)" << endl; + success = false; + break; + } + + for(int i=0; i<sz*(sz+1)/2; ++i) + if(tur[i] != ur_correct[i]) + { + cout << "Storage error (Triangular, Upper, Row major)" << endl; + success = false; + break; + } + + for(int i=0; i<sz*(sz+1)/2; ++i) + if(tlc[i] != lc_correct[i]) + { + cout << "Storage error (Triangular, Lower, Column major)" << endl; + success = false; + break; + } + + for(int i=0; i<sz*(sz+1)/2; ++i) + if(tlr[i] != lr_correct[i]) + { + cout << "Storage error (Triangular, Lower, Row major)" << endl; + success = false; + break; + } + + + return (success)?boost::exit_success:boost::exit_failure; +} diff --git a/src/boost/libs/numeric/ublas/test/utils.hpp b/src/boost/libs/numeric/ublas/test/utils.hpp new file mode 100644 index 000000000..65708e17e --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/utils.hpp @@ -0,0 +1,396 @@ +/** + * \file util.hpp + * + * \brief Utility macros/functions for testing and debugging purpose. + * + * Basic usage: + * <pre> + * BOOST_UBLAS_TEST_DEF( test_case_1 ) + * { + * // do your test stuff + * } + * + * BOOST_UBLAS_TEST_DEF( test_case_2 ) + * { + * // do your test stuff + * } + * + * // ... + * + * BOOST_UBLAS_TEST_DEF( test_case_n ) + * { + * // do your test stuff + * } + * + * int main() + * { + * BOOST_UBLAS_TEST_SUITE( "My Test Suite" ); // optional + * + * BOOST_UBLAS_TEST_BEGIN(); + * BOOST_UBLAS_TEST_DO( test_case_1 ); + * BOOST_UBLAS_TEST_DO( test_case_2 ); + * // ... + * BOOST_UBLAS_TEST_DO( test_case_n ); + * BOOST_UBLAS_TEST_END(); + * } + * </pre> + * Inside each <em>test_case_<code>k</code></em> you can use the various + * \c BOOST_UBLAS_TEST_CHECK* macros. + * + * <hr/> + * + * Copyright (c) 2009-2012, Marco Guazzone + * + * 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) + * + * \author Marco Guazzone, marco.guazzone@gmail.com + */ + +#ifndef BOOST_NUMERIC_UBLAS_TEST_UTILS_HPP +#define BOOST_NUMERIC_UBLAS_TEST_UTILS_HPP + + +#include <boost/numeric/ublas/detail/config.hpp> +#include <boost/numeric/ublas/traits.hpp> + +#include <boost/math/special_functions/fpclassify.hpp> // isnan, isinf + +#include <cmath> +#include <complex> +#include <cstddef> +#include <iostream> +#include <limits> +#include <stdexcept> + +#define BOOST_UBLAS_NOT_USED(x) (void)(x) + +namespace boost { namespace numeric { namespace ublas { namespace test { namespace detail { namespace /*<unnamed>*/ { + + using ::std::abs; + using ::std::max; + +/// Check if the given complex number is a NaN. +// read the comments in fpclassify as well +template <typename T> +BOOST_UBLAS_INLINE +bool (isnan)(::std::complex<T> const& z) +{ + // According to IEEE, NaN is different even by itself + return (z != z) || (boost::math::isnan)(z.real()) || (boost::math::isnan)(z.imag()); +} + +/// Check if two (real) numbers are close each other (wrt a given tolerance). +template <typename T1, typename T2, typename T3> +BOOST_UBLAS_INLINE +bool close_to(T1 x, T2 y, T3 tol) +{ + typedef typename promote_traits<typename promote_traits<T1,T2>::promote_type, + T3>::promote_type real_type; + + if ((boost::math::isnan)(x) || (boost::math::isnan)(y)) + { + // According to IEEE, NaN is different even by itself + return false; + } + return abs(x-y) <= (max(static_cast<real_type>(abs(x)), static_cast<real_type>(abs(y)))*tol); +} + +/// Check if two complex numbers are close each other (wrt a given tolerance). +template <typename T1, typename T2, typename T3> +BOOST_UBLAS_INLINE +bool close_to(::std::complex<T1> const& x, ::std::complex<T2> const& y, T3 tol) +{ + typedef typename promote_traits<typename promote_traits<T1,T2>::promote_type, + T3>::promote_type real_type; + + if ((isnan)(x) || (isnan)(y)) + { + // According to IEEE, NaN is different even by itself + return false; + } + ::std::complex<real_type> xx(x); + ::std::complex<real_type> yy(y); + + return abs(xx-yy) <= (max(abs(xx), abs(yy))*tol); +} + +/// Check if two (real) numbers are close each other (wrt a given tolerance). +template <typename T1, typename T2, typename T3> +BOOST_UBLAS_INLINE +bool rel_close_to(T1 x, T2 y, T3 tol) +{ + //typedef typename promote_traits<typename promote_traits<T1,T2>::promote_type, + // T3>::promote_type real_type; + + if ((boost::math::isnan)(x) || (boost::math::isnan)(y)) + { + // According to IEEE, NaN is different even by itself + return false; + } + return abs(x-y)/abs(y) <= tol; +} + +/// Check if two complex numbers are close each other (wrt a given tolerance). +template <typename T1, typename T2, typename T3> +BOOST_UBLAS_INLINE +bool rel_close_to(::std::complex<T1> const& x, ::std::complex<T2> const& y, T3 tol) +{ + typedef typename promote_traits<typename promote_traits<T1,T2>::promote_type, + T3>::promote_type real_type; + + if ((isnan)(x) || (isnan)(y)) + { + // According to IEEE, NaN is different even by itself + return false; + } + ::std::complex<real_type> xx(x); + ::std::complex<real_type> yy(y); + + return abs(xx-yy)/abs(yy) <= tol; +} + +}}}}}} // Namespace boost::numeric::ublas::test::detail::<unnamed> + + +/// Expand its argument \a x. +#define BOOST_UBLAS_TEST_EXPAND_(x) x + + +/// Expand its argument \a x inside parenthesis. +#define BOOST_UBLAS_TEST_EXPANDP_(x) (x) + + +/// Transform its argument \a x into a string. +#define BOOST_UBLAS_TEST_STRINGIFY_(x) #x + + +/// Concatenate its two \e string arguments \a x and \a y. +#define BOOST_UBLAS_TEST_JOIN_(x,y) x ## y + + +/// Output the message \a x if in debug-mode; otherwise output nothing. +/// Note: we don't use macro expansion inside parenthesis to let \a m be an +/// expression of the form <code>a << b</code>. +#ifndef NDEBUG +# define BOOST_UBLAS_DEBUG_TRACE(x) ::std::cerr << "[Debug>> " << BOOST_UBLAS_TEST_EXPAND_(x) << ::std::endl +#else +# define BOOST_UBLAS_DEBUG_TRACE(x) /**/ +#endif // NDEBUG + + +/// Define the name \a m of the entire test suite. +#define BOOST_UBLAS_TEST_SUITE(m) ::std::cerr << "--- Test Suite: " << BOOST_UBLAS_TEST_EXPAND_(m) << " ---" << ::std::endl; + + +/// Define the beginning of a test suite. +#define BOOST_UBLAS_TEST_BEGIN() /* [BOOST_UBLAS_TEST_BEGIN] */ \ + { \ + /* Begin of Test Suite */ \ + ::std::size_t test_fails__(0) \ + /* [/BOOST_UBLAS_TEST_BEGIN] */ + + +/// Define a test case \a x inside the current test suite. +#define BOOST_UBLAS_TEST_DEF(x) static void BOOST_UBLAS_TEST_EXPAND_(x)(::std::size_t& test_fails__) + + +/// Call the test case \a x. +#define BOOST_UBLAS_TEST_DO(x) /* [BOOST_UBLAS_TEST_DO] */ \ + try \ + { \ + BOOST_UBLAS_TEST_EXPAND_(x)(test_fails__); \ + } \ + catch (::std::exception& e) \ + { \ + ++test_fails__; \ + BOOST_UBLAS_TEST_ERROR( e.what() ); \ + } \ + catch (...) \ + { \ + ++test_fails__; \ + } \ + /* [/BOOST_UBLAS_TEST_DO] */ + + +/// Define the end of a test suite and return non-zero value if any test failed. +#define BOOST_UBLAS_TEST_END() /* [BOOST_UBLAS_TEST_END] */ \ + if (test_fails__ > 0) \ + { \ + ::std::cerr << "Number of failed tests: " << test_fails__ << ::std::endl; \ + return EXIT_FAILURE; \ + } \ + else \ + { \ + ::std::cerr << "No failed test" << ::std::endl; \ + return EXIT_SUCCESS; \ + } \ + } /* End of test suite */ \ + /* [/BOOST_UBLAS_TEST_END] */ + + +/// Output the message \a m. +/// Note: we don't use macro expansion inside parenthesis to let \a m be an +/// expression of the form <code>a << b</code>. +#define BOOST_UBLAS_TEST_TRACE(m) ::std::cerr << "[Info>> " << BOOST_UBLAS_TEST_EXPAND_(m) << ::std::endl + + +/// Check the truth of assertion \a x. +#define BOOST_UBLAS_TEST_CHECK(x) /* [BOOST_UBLAS_TEST_CHECK] */ \ + if (!BOOST_UBLAS_TEST_EXPANDP_(x)) \ + { \ + BOOST_UBLAS_TEST_ERROR( "Failed assertion: " << BOOST_UBLAS_TEST_STRINGIFY_(x) ); \ + ++test_fails__; \ + } \ + /* [/BOOST_UBLAS_TEST_CHECK] */ + + +/// Check for the equality of \a x against \a y. +#define BOOST_UBLAS_TEST_CHECK_EQ(x,y) /* [BOOST_UBLAS_TEST_CHECK_EQUAL] */ \ + if (!(BOOST_UBLAS_TEST_EXPANDP_(x) == BOOST_UBLAS_TEST_EXPANDP_(y))) \ + { \ + BOOST_UBLAS_TEST_ERROR( "Failed assertion: (" << BOOST_UBLAS_TEST_STRINGIFY_(x) << " == " << BOOST_UBLAS_TEST_STRINGIFY_(y) << ")" ); \ + ++test_fails__; \ + } \ + /* [/BOOST_UBLAS_TEST_CHECK_EQUAL] */ + + +/// Alias for macro \c BOOST_UBLAS_TEST_CHECK_EQ (for backward compatibility). +#define BOOST_UBLAS_TEST_CHECK_EQUAL(x,y) BOOST_UBLAS_TEST_CHECK_EQ(x,y) + + +/// Check that \a x and \a y are close with respect to a given precision \a e. +#define BOOST_UBLAS_TEST_CHECK_CLOSE(x,y,e) /* [BOOST_UBLAS_TEST_CHECK_CLOSE] */ \ + if (!::boost::numeric::ublas::test::detail::close_to(BOOST_UBLAS_TEST_EXPAND_(x), BOOST_UBLAS_TEST_EXPAND_(y), BOOST_UBLAS_TEST_EXPAND_(e))) \ + { \ + BOOST_UBLAS_TEST_ERROR( "Failed assertion: abs(" << BOOST_UBLAS_TEST_STRINGIFY_(x) << "-" << BOOST_UBLAS_TEST_STRINGIFY_(y) << ") <= " << BOOST_UBLAS_TEST_STRINGIFY_(e) << " [with " << BOOST_UBLAS_TEST_STRINGIFY_(x) << " == " << BOOST_UBLAS_TEST_EXPANDP_(x) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y) << " == " << BOOST_UBLAS_TEST_EXPANDP_(y) << " and " << BOOST_UBLAS_TEST_STRINGIFY_(e) << " == " << BOOST_UBLAS_TEST_EXPANDP_(e) << "]" ); \ + ++test_fails__; \ + } \ + /* [/BOOST_UBLAS_TEST_CHECK_CLOSE] */ + + +/// Alias for macro \c BOOST_UBLAS_TEST_CHECK_CLOSE (for backward compatibility), +#define BOOST_UBLAS_TEST_CHECK_PRECISION(x,y,e) BOOST_UBLAS_TEST_CHECK_CLOSE(x,y,e) + + +/// Check that \a x is close to \a y with respect to a given relative precision \a e. +#define BOOST_UBLAS_TEST_CHECK_REL_CLOSE(x,y,e) /* [BOOST_UBLAS_TEST_CHECK_REL_CLOSE] */ \ + if (!::boost::numeric::ublas::test::detail::rel_close_to(BOOST_UBLAS_TEST_EXPAND_(x), BOOST_UBLAS_TEST_EXPAND_(y), BOOST_UBLAS_TEST_EXPAND_(e))) \ + { \ + BOOST_UBLAS_TEST_ERROR( "Failed assertion: abs((" << BOOST_UBLAS_TEST_STRINGIFY_(x) << "-" << BOOST_UBLAS_TEST_STRINGIFY_(y) << ")/" << BOOST_UBLAS_TEST_STRINGIFY_(y) << ") <= " << BOOST_UBLAS_TEST_STRINGIFY_(e) << " [with " << BOOST_UBLAS_TEST_STRINGIFY_(x) << " == " << BOOST_UBLAS_TEST_EXPANDP_(x) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y) << " == " << BOOST_UBLAS_TEST_EXPANDP_(y) << " and " << BOOST_UBLAS_TEST_STRINGIFY_(e) << " == " << BOOST_UBLAS_TEST_EXPANDP_(e) << "]" ); \ + ++test_fails__; \ + } \ + /* [/BOOST_UBLAS_TEST_CHECK_REL_CLOSE] */ + + +/// Alias for macro \c BOOST_UBLAS_TEST_CHECK_REL_CLOSE (for backward compatibility), +#define BOOST_UBLAS_TEST_CHECK_REL_PRECISION(x,y,e) BOOST_UBLAS_TEST_CHECK_REL_CLOSE(x,y,e) + + +/// Check that elements of \a x and \a y are equal. +#define BOOST_UBLAS_TEST_CHECK_VECTOR_EQ(x,y,n) /* [BOOST_UBLAS_TEST_CHECK_VECTOR_EQ] */ \ + if (BOOST_UBLAS_TEST_EXPANDP_(n) > 0) \ + { \ + ::std::size_t n__ = BOOST_UBLAS_TEST_EXPAND_(n); \ + for (::std::size_t i__ = n__; i__ > 0; --i__) \ + { \ + if (!(BOOST_UBLAS_TEST_EXPANDP_(x)[n__-i__]==BOOST_UBLAS_TEST_EXPANDP_(y)[n__-i__])) \ + { \ + BOOST_UBLAS_TEST_ERROR( "Failed assertion: (" << BOOST_UBLAS_TEST_STRINGIFY_(x[i__]) << "==" << BOOST_UBLAS_TEST_STRINGIFY_(y[i__]) << ")" << " [with " << BOOST_UBLAS_TEST_STRINGIFY_(x[i__]) << " == " << BOOST_UBLAS_TEST_EXPANDP_(x)[n__-i__] << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y[i__]) << " == " << BOOST_UBLAS_TEST_EXPANDP_(y)[n__-i__] << ", " << BOOST_UBLAS_TEST_STRINGIFY_(i__) << " == " << i__ << " and " << BOOST_UBLAS_TEST_STRINGIFY_(n) << " == " << n__ << "]" ); \ + ++test_fails__; \ + } \ + } \ + } \ + /* [/BOOST_UBLAS_TEST_CHECK_VECTOR_EQ] */ + + +/// Check that elements of \a x and \a y are close with respect to a given precision \a e. +#define BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE(x,y,n,e) /* [BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE] */ \ + if (BOOST_UBLAS_TEST_EXPANDP_(n) > 0) \ + { \ + ::std::size_t n__ = BOOST_UBLAS_TEST_EXPAND_(n); \ + for (::std::size_t i__ = n__; i__ > 0; --i__) \ + { \ + if (!::boost::numeric::ublas::test::detail::close_to(BOOST_UBLAS_TEST_EXPANDP_(x)[n__-i__], BOOST_UBLAS_TEST_EXPANDP_(y)[n__-i__], BOOST_UBLAS_TEST_EXPANDP_(e))) \ + { \ + BOOST_UBLAS_TEST_ERROR( "Failed assertion: abs((" << BOOST_UBLAS_TEST_STRINGIFY_(x[i__]) << "-" << BOOST_UBLAS_TEST_STRINGIFY_(y[i__]) << ") <= " << BOOST_UBLAS_TEST_STRINGIFY_(e) << " [with " << BOOST_UBLAS_TEST_STRINGIFY_(x[i__]) << " == " << BOOST_UBLAS_TEST_EXPANDP_(x)[n__-i__] << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y[i__]) << " == " << BOOST_UBLAS_TEST_EXPANDP_(y)[n__-i__] << ", " << BOOST_UBLAS_TEST_STRINGIFY_(i__) << " == " << i__ << " and " << BOOST_UBLAS_TEST_STRINGIFY_(n) << " == " << n__ << "]" ); \ + ++test_fails__; \ + } \ + } \ + } \ + /* [/BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE] */ + + +/// Check that elements of \a x and \a y are close with respect to a given relative precision \a e. +#define BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE(x,y,n,e) /* [BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE] */ \ + if (BOOST_UBLAS_TEST_EXPANDP_(n) > 0) \ + { \ + ::std::size_t n__ = BOOST_UBLAS_TEST_EXPAND_(n); \ + for (::std::size_t i__ = n__; i__ > 0; --i__) \ + { \ + if (!::boost::numeric::ublas::test::detail::rel_close_to(BOOST_UBLAS_TEST_EXPANDP_(x)[n__-i__], BOOST_UBLAS_TEST_EXPANDP_(y)[n__-i__], BOOST_UBLAS_TEST_EXPANDP_(e))) \ + { \ + BOOST_UBLAS_TEST_ERROR( "Failed assertion: abs((" << BOOST_UBLAS_TEST_STRINGIFY_(x[i__]) << "-" << BOOST_UBLAS_TEST_STRINGIFY_(y[i__]) << ") <= " << BOOST_UBLAS_TEST_STRINGIFY_(e) << " [with " << BOOST_UBLAS_TEST_STRINGIFY_(x[i__]) << " == " << BOOST_UBLAS_TEST_EXPANDP_(x)[n__-i__] << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y[i__]) << " == " << BOOST_UBLAS_TEST_EXPANDP_(y)[n__-i__] << ", " << BOOST_UBLAS_TEST_STRINGIFY_(i__) << " == " << i__ << " and " << BOOST_UBLAS_TEST_STRINGIFY_(n) << " == " << n__ << "]" ); \ + ++test_fails__; \ + } \ + } \ + } \ + /* [/BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE] */ + + +/// Check that elements of matrices \a x and \a y are equal. +#define BOOST_UBLAS_TEST_CHECK_MATRIX_EQ(x,y,nr,nc) /* [BOOST_UBLAS_TEST_CHECK_MATRIX_EQ] */ \ + for (::std::size_t i__ = 0; i__ < BOOST_UBLAS_TEST_EXPANDP_(nr); ++i__) \ + { \ + for (::std::size_t j__ = 0; j__ < BOOST_UBLAS_TEST_EXPANDP_(nc); ++j__) \ + { \ + if (!(BOOST_UBLAS_TEST_EXPANDP_(x)(i__,j__)==BOOST_UBLAS_TEST_EXPANDP_(y)(i__,j__))) \ + { \ + BOOST_UBLAS_TEST_ERROR( "Failed assertion: (" << BOOST_UBLAS_TEST_STRINGIFY_(x(i__,j__)) << " == " << BOOST_UBLAS_TEST_STRINGIFY_(y(i__,j__)) << ") [with " << BOOST_UBLAS_TEST_STRINGIFY_(x(i__,j__)) << " == " << BOOST_UBLAS_TEST_EXPANDP_(x)(i__,j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y(i__,j__)) << " == " << BOOST_UBLAS_TEST_EXPANDP_(y)(i__,j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(i__) << " == " << i__ << ", " << BOOST_UBLAS_TEST_STRINGIFY_(j__) << " == " << BOOST_UBLAS_TEST_EXPANDP_(j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(nr) << " == " << BOOST_UBLAS_TEST_EXPANDP_(nr) << " and " << BOOST_UBLAS_TEST_STRINGIFY_(nc) << " == " << BOOST_UBLAS_TEST_EXPANDP_(nc) << "]" ); \ + ++test_fails__; \ + } \ + } \ + } \ + /* [/BOOST_UBLAS_TEST_CHECK_MATRIX_EQ] */ + + +/// Check that elements of matrices \a x and \a y are close with respect to a given precision \a e. +#define BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE(x,y,nr,nc,e) /* [BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE] */ \ + for (::std::size_t i__ = 0; i__ < BOOST_UBLAS_TEST_EXPANDP_(nr); ++i__) \ + { \ + for (::std::size_t j__ = 0; j__ < BOOST_UBLAS_TEST_EXPANDP_(nc); ++j__) \ + { \ + if (!::boost::numeric::ublas::test::detail::close_to(BOOST_UBLAS_TEST_EXPANDP_(x)(i__,j__), BOOST_UBLAS_TEST_EXPANDP_(y)(i__,j__), BOOST_UBLAS_TEST_EXPANDP_(e))) \ + { \ + BOOST_UBLAS_TEST_ERROR( "Failed assertion: abs((" << BOOST_UBLAS_TEST_STRINGIFY_(x(i__,j__)) << "-" << BOOST_UBLAS_TEST_STRINGIFY_(y(i__,j__)) << ") <= " << BOOST_UBLAS_TEST_STRINGIFY_(e) << " [with " << BOOST_UBLAS_TEST_STRINGIFY_(x(i__,j__)) << " == " << BOOST_UBLAS_TEST_EXPANDP_(x)(i__,j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y(i__,j__)) << " == " << BOOST_UBLAS_TEST_EXPANDP_(y)(i__,j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(i__) << " == " << i__ << ", " << BOOST_UBLAS_TEST_STRINGIFY_(j__) << " == " << BOOST_UBLAS_TEST_EXPANDP_(j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(nr) << " == " << BOOST_UBLAS_TEST_EXPANDP_(nr) << " and " << BOOST_UBLAS_TEST_STRINGIFY_(nc) << " == " << BOOST_UBLAS_TEST_EXPANDP_(nc) << "]" ); \ + ++test_fails__; \ + } \ + } \ + } \ + /* [/BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE] */ + + +/// Check that elements of matrices \a x and \a y are close with respect to a given relative precision \a e. +#define BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE(x,y,nr,nc,e) /* [BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE] */ \ + for (::std::size_t i__ = 0; i__ < BOOST_UBLAS_TEST_EXPANDP_(nr); ++i__) \ + { \ + for (::std::size_t j__ = 0; j__ < BOOST_UBLAS_TEST_EXPANDP_(nc); ++j__) \ + { \ + if (!::boost::numeric::ublas::test::detail::rel_close_to(BOOST_UBLAS_TEST_EXPANDP_(x)(i__,j__), BOOST_UBLAS_TEST_EXPANDP_(y)(i__,j__), BOOST_UBLAS_TEST_EXPANDP_(e))) \ + { \ + BOOST_UBLAS_TEST_ERROR( "Failed assertion: abs((" << BOOST_UBLAS_TEST_STRINGIFY_(x(i__,j__)) << "-" << BOOST_UBLAS_TEST_STRINGIFY_(y(i__,j__)) << ") <= " << BOOST_UBLAS_TEST_STRINGIFY_(e) << " [with " << BOOST_UBLAS_TEST_STRINGIFY_(x(i__,j__)) << " == " << BOOST_UBLAS_TEST_EXPANDP_(x)(i__,j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y(i__,j__)) << " == " << BOOST_UBLAS_TEST_EXPANDP_(y)(i__,j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(i__) << " == " << i__ << ", " << BOOST_UBLAS_TEST_STRINGIFY_(j__) << " == " << BOOST_UBLAS_TEST_EXPANDP_(j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(nr) << " == " << BOOST_UBLAS_TEST_EXPANDP_(nr) << " and " << BOOST_UBLAS_TEST_STRINGIFY_(nc) << " == " << BOOST_UBLAS_TEST_EXPANDP_(nc) << "]" ); \ + ++test_fails__; \ + } \ + } \ + } \ + /* [/BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE] */ + +///< Output the error message \a x. +#ifdef _MSC_VER +# define BOOST_UBLAS_TEST_ERROR(x) ::std::cerr << "[Error (" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << ")>> " << BOOST_UBLAS_TEST_EXPAND_(x) << ::std::endl +#else +# define BOOST_UBLAS_TEST_ERROR(x) ::std::cerr << "[Error (" << __FILE__ << ":" << __func__ << ":" << __LINE__ << ")>> " << BOOST_UBLAS_TEST_EXPAND_(x) << ::std::endl +#endif + +#endif // BOOST_NUMERIC_UBLAS_TEST_UTILS_HPP |