Initial Commit

This commit is contained in:
Jordan Sherer
2018-02-08 21:28:33 -05:00
commit 678c1d3966
14352 changed files with 3176737 additions and 0 deletions
@@ -0,0 +1,41 @@
SUBROUTINE COORD(A0,B0,AP,BP,A1,B1,A2,B2)
! Examples:
! 1. From ha,dec to az,el:
! call coord(pi,pio2-lat,0.,lat,ha,dec,az,el)
! 2. From az,el to ha,dec:
! call coord(pi,pio2-lat,0.,lat,az,el,ha,dec)
! 3. From ra,dec to l,b
! call coord(4.635594495,-0.504691042,3.355395488,0.478220215,
! ra,dec,l,b)
! 4. From l,b to ra,dec
! call coord(1.705981071d0,-1.050357016d0,2.146800277d0,
! 0.478220215d0,l,b,ra,dec)
! 5. From ra,dec to ecliptic latitude (eb) and longitude (el):
! call coord(0.d0,0.d0,-pio2,pio2-23.443*pi/180,ra,dec,el,eb)
! 6. From ecliptic latitude (eb) and longitude (el) to ra,dec:
! call coord(0.d0,0.d0,-pio2,pio2-23.443*pi/180,el,eb,ra,dec)
SB0=sin(B0)
CB0=cos(B0)
SBP=sin(BP)
CBP=cos(BP)
SB1=sin(B1)
CB1=cos(B1)
SB2=SBP*SB1 + CBP*CB1*cos(AP-A1)
CB2=SQRT(1.e0-SB2**2)
B2=atan(SB2/CB2)
SAA=sin(AP-A1)*CB1/CB2
CAA=(SB1-SB2*SBP)/(CB2*CBP)
CBB=SB0/CBP
SBB=sin(AP-A0)*CB0
SA2=SAA*CBB-CAA*SBB
CA2=CAA*CBB+SAA*SBB
TA2O2=0.0 !Shut up compiler warnings. -db
IF(CA2.LE.0.e0) TA2O2=(1.e0-CA2)/SA2
IF(CA2.GT.0.e0) TA2O2=SA2/(1.e0+CA2)
A2=2.e0*atan(TA2O2)
IF(A2.LT.0.e0) A2=A2+6.2831853
RETURN
END SUBROUTINE COORD
@@ -0,0 +1,39 @@
/***************************************************************************
** **
** QCustomPlot, an easy to use, modern plotting widget for Qt **
** Copyright (C) 2011-2016 Emanuel Eichhammer **
** **
** This program is free software: you can redistribute it and/or modify **
** it under the terms of the GNU General Public License as published by **
** the Free Software Foundation, either version 3 of the License, or **
** (at your option) any later version. **
** **
** This program is distributed in the hope that it will be useful, **
** but WITHOUT ANY WARRANTY; without even the implied warranty of **
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the **
** GNU General Public License for more details. **
** **
** You should have received a copy of the GNU General Public License **
** along with this program. If not, see http://www.gnu.org/licenses/. **
** **
****************************************************************************
** Author: Emanuel Eichhammer **
** Website/Contact: http://www.qcustomplot.com/ **
** Date: 13.09.16 **
** Version: 2.0.0-beta **
****************************************************************************/
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
QApplication::setGraphicsSystem("raster");
#endif
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
@@ -0,0 +1,34 @@
// (C) Copyright John Maddock 2005.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_MATH_COMPLEX_ACOSH_INCLUDED
#define BOOST_MATH_COMPLEX_ACOSH_INCLUDED
#ifndef BOOST_MATH_COMPLEX_DETAILS_INCLUDED
# include <boost/math/complex/details.hpp>
#endif
#ifndef BOOST_MATH_COMPLEX_ATANH_INCLUDED
# include <boost/math/complex/acos.hpp>
#endif
namespace boost{ namespace math{
template<class T>
inline std::complex<T> acosh(const std::complex<T>& z)
{
//
// We use the relation acosh(z) = +-i acos(z)
// Choosing the sign of multiplier to give real(acosh(z)) >= 0
// as well as compatibility with C99.
//
std::complex<T> result = boost::math::acos(z);
if(!(boost::math::isnan)(result.imag()) && signbit(result.imag()))
return detail::mult_i(result);
return detail::mult_minus_i(result);
}
} } // namespaces
#endif // BOOST_MATH_COMPLEX_ACOSH_INCLUDED
@@ -0,0 +1,141 @@
// Copyright Aleksey Gurtovoy 2001-2004
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Preprocessed version of "boost/mpl/inherit.hpp" header
// -- DO NOT modify by hand!
namespace boost { namespace mpl {
template<
typename BOOST_MPL_AUX_NA_PARAM(T1)
, typename BOOST_MPL_AUX_NA_PARAM(T2)
>
struct inherit2
: T1, T2
{
typedef inherit2 type;
BOOST_MPL_AUX_LAMBDA_SUPPORT(2, inherit2, (T1, T2))
};
template< typename T1 >
struct inherit2< T1,empty_base >
{
typedef T1 type;
BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (T1, empty_base))
};
template< typename T2 >
struct inherit2< empty_base,T2 >
{
typedef T2 type;
BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (empty_base, T2))
};
template<>
struct inherit2< empty_base,empty_base >
{
typedef empty_base type;
BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (empty_base, empty_base))
};
BOOST_MPL_AUX_NA_SPEC(2, inherit2)
template<
typename T1 = na, typename T2 = na, typename T3 = na
>
struct inherit3
: inherit2<
typename inherit2<
T1, T2
>::type
, T3
>
{
BOOST_MPL_AUX_LAMBDA_SUPPORT(
3
, inherit3
, ( T1, T2, T3)
)
};
BOOST_MPL_AUX_NA_SPEC(3, inherit3)
template<
typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na
>
struct inherit4
: inherit2<
typename inherit3<
T1, T2, T3
>::type
, T4
>
{
BOOST_MPL_AUX_LAMBDA_SUPPORT(
4
, inherit4
, ( T1, T2, T3, T4)
)
};
BOOST_MPL_AUX_NA_SPEC(4, inherit4)
template<
typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na
, typename T5 = na
>
struct inherit5
: inherit2<
typename inherit4<
T1, T2, T3, T4
>::type
, T5
>
{
BOOST_MPL_AUX_LAMBDA_SUPPORT(
5
, inherit5
, ( T1, T2, T3, T4, T5)
)
};
BOOST_MPL_AUX_NA_SPEC(5, inherit5)
/// primary template
template<
typename T1 = empty_base, typename T2 = empty_base
, typename T3 = empty_base, typename T4 = empty_base
, typename T5 = empty_base
>
struct inherit
: inherit5< T1,T2,T3,T4,T5 >
{
};
template<>
struct inherit< na,na,na,na,na >
{
template<
typename T1 = empty_base, typename T2 = empty_base
, typename T3 = empty_base, typename T4 = empty_base
, typename T5 = empty_base
>
struct apply
: inherit< T1,T2,T3,T4,T5 >
{
};
};
BOOST_MPL_AUX_NA_SPEC_LAMBDA(5, inherit)
BOOST_MPL_AUX_NA_SPEC_ARITY(5, inherit)
BOOST_MPL_AUX_NA_SPEC_TEMPLATE_ARITY(5, 5, inherit)
}}
@@ -0,0 +1,122 @@
/* Boost interval/compare/lexicographic.hpp template implementation file
*
* 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)
*/
#ifndef BOOST_NUMERIC_INTERVAL_COMPARE_LEXICOGRAPHIC_HPP
#define BOOST_NUMERIC_INTERVAL_COMPARE_LEXICOGRAPHIC_HPP
#include <boost/numeric/interval/detail/interval_prototype.hpp>
#include <boost/numeric/interval/detail/test_input.hpp>
namespace boost {
namespace numeric {
namespace interval_lib {
namespace compare {
namespace lexicographic {
template<class T, class Policies1, class Policies2> inline
bool operator<(const interval<T, Policies1>& x, const interval<T, Policies2>& y)
{
if (detail::test_input(x, y)) throw comparison_error();
const T& xl = x.lower();
const T& yl = y.lower();
return xl < yl || (xl == yl && x.upper() < y.upper());
}
template<class T, class Policies> inline
bool operator<(const interval<T, Policies>& x, const T& y)
{
if (detail::test_input(x, y)) throw comparison_error();
return x.lower() < y;
}
template<class T, class Policies1, class Policies2> inline
bool operator<=(const interval<T, Policies1>& x, const interval<T, Policies2>& y)
{
if (detail::test_input(x, y)) throw comparison_error();
const T& xl = x.lower();
const T& yl = y.lower();
return xl < yl || (xl == yl && x.upper() <= y.upper());
}
template<class T, class Policies> inline
bool operator<=(const interval<T, Policies>& x, const T& y)
{
if (detail::test_input(x, y)) throw comparison_error();
const T& xl = x.lower();
return xl < y || (xl == y && x.upper() <= y);
}
template<class T, class Policies1, class Policies2> inline
bool operator>(const interval<T, Policies1>& x, const interval<T, Policies2>& y)
{
if (detail::test_input(x, y)) throw comparison_error();
const T& xl = x.lower();
const T& yl = y.lower();
return xl > yl || (xl == yl && x.upper() > y.upper());
}
template<class T, class Policies> inline
bool operator>(const interval<T, Policies>& x, const T& y)
{
if (detail::test_input(x, y)) throw comparison_error();
const T& xl = x.lower();
return xl > y || (xl == y && x.upper() > y);
}
template<class T, class Policies1, class Policies2> inline
bool operator>=(const interval<T, Policies1>& x, const interval<T, Policies2>& y)
{
if (detail::test_input(x, y)) throw comparison_error();
const T& xl = x.lower();
const T& yl = y.lower();
return xl > yl || (xl == yl && x.upper() >= y.upper());
}
template<class T, class Policies> inline
bool operator>=(const interval<T, Policies>& x, const T& y)
{
if (detail::test_input(x, y)) throw comparison_error();
return x.lower() >= y;
}
template<class T, class Policies1, class Policies2> inline
bool operator==(const interval<T, Policies1>& x, const interval<T, Policies2>& y)
{
if (detail::test_input(x, y)) throw comparison_error();
return x.lower() == y.lower() && x.upper() == y.upper();
}
template<class T, class Policies> inline
bool operator==(const interval<T, Policies>& x, const T& y)
{
if (detail::test_input(x, y)) throw comparison_error();
return x.lower() == y && x.upper() == y;
}
template<class T, class Policies1, class Policies2> inline
bool operator!=(const interval<T, Policies1>& x, const interval<T, Policies2>& y)
{
if (detail::test_input(x, y)) throw comparison_error();
return x.lower() != y.lower() || x.upper() != y.upper();
}
template<class T, class Policies> inline
bool operator!=(const interval<T, Policies>& x, const T& y)
{
if (detail::test_input(x, y)) throw comparison_error();
return x.lower() != y || x.upper() != y;
}
} // namespace lexicographic
} // namespace compare
} // namespace interval_lib
} // namespace numeric
} // namespace boost
#endif // BOOST_NUMERIC_INTERVAL_COMPARE_LEXICOGRAPHIC_HPP
@@ -0,0 +1,125 @@
////
Link file to hold all links
File Location: ./doc/common/links.adoc
Usage example: include::../common/links.adoc[]
Syntax: [link-id] [link] [displayed text]
Example:
:pskreporter: http://pskreporter.info/pskmap.html[PSK Reporter]
[link-id] = :pskreporter:
[link] http://pskreporter.info/pskmap.html
[displayed text] PSK Reporter
Perform searches from the doc root directory: doc
Search: grep -rl --exclude-dir="*\.svn" {pskreporter} .
grep -rl --exclude-dir="*\.svn" PSK Reporter .
grep -rl --exclude-dir="*\.svn" {devsvn} .
grep -rl --exclude-dir="*\.svn" {kvasd} .
grep -rl --exclude-dir="*\.svn" {ntpsetup} .
Include links.adoc: grep -rl --exclude-dir="*\.svn" pskreporter .
Exclude links.adoc: grep -rl --exclude-dir="*\.svn" {pskreporter} .
Note(s):
a). Don't forget a space then "." at the end.
b). To include links.adoc file itself, remove the brackets {} from
the pattern search:
c). Look at each of the files listed to ensure the [displayed text]
still makes sense in the caption. If not, just add another link. Be
aware of the translators requirements by trying to keep the displayed
text language agnostic or neutral e.g. use a proper noun like a
persons name or a document title in the language of the linked
document. Do not use plain English generic words for link text link
"here".
d). Edit lines as needed. Keeping them in alphabetic order help see dupes.
////
// General URL's
//:launchpadac6sl: https://launchpad.net/~jnogatch/+archive/wsjtx[WSJT-X Linux Packages]
:alarmejt: http://f5jmh.free.fr/index.php?page=english[AlarmeJT]
:asciidoc_cheatsheet: http://powerman.name/doc/asciidoc[AsciiDoc Cheatsheet]
:asciidoc_help: http://www.methods.co.nz/asciidoc/userguide.html[AsciiDoc User Guide]
:asciidoc_questions: http://www.methods.co.nz/asciidoc/faq.html[AsciiDoc FAQ]
:asciidoc_syntax: http://xpt.sourceforge.net/techdocs/nix/tool/asciidoc-syn/ascs01-AsciiDocMarkupSyntaxQuickSummary/single/[AsciiDoc Syntax]
:asciidoctor_style: http://asciidoctor.org/docs/asciidoc-writers-guide/#delimited-blocks[AsciiDoctor Styles Guide]
:asciidoctor_syntax: http://asciidoctor.org/docs/asciidoc-writers-guide/#delimited-blocks[AsciiDoctor Syntax Guide]
:cc_by_sa: http://creativecommons.org/licenses/by-sa/3.0/[Commons Attribution-ShareAlike 3.0 Unported License]
:debian32: http://physics.princeton.edu/pulsar/K1JT/wsjtx_{VERSION}_i386.deb[wsjtx_{VERSION}_i386.deb]
:debian64: http://physics.princeton.edu/pulsar/K1JT/wsjtx_{VERSION}_amd64.deb[wsjtx_{VERSION}_amd64.deb]
:raspbian: http://physics.princeton.edu/pulsar/K1JT/wsjtx_{VERSION}_armhf.deb[wsjtx_{VERSION}_armhf.deb]
:debian: http://www.debian.org/[Debian]
:dev_guide: http://www.physics.princeton.edu/pulsar/K1JT/wsjtx-doc/wsjt-dev-guide.html[Dev-Guide]
:devsvn1: http://sourceforge.net/p/wsjt/wsjt/HEAD/tree/[Devel-SVN]
:devsvn: http://sourceforge.net/p/wsjt/wsjt/HEAD/tree/[SourceForge]
:dimension4: http://www.thinkman.com/dimension4/[Thinking Man Software]
:download: http://physics.princeton.edu/pulsar/K1JT/wsjtx.html[Download Page]
:dxatlas: http://www.dxatlas.com/[Afreet Software, Inc.]
:dxlcommander: http://www.dxlabsuite.com/commander/[Commander]
:dxlsuite: http://www.dxlabsuite.com/[DX Lab Suite]
:fedora32: http://physics.princeton.edu/pulsar/K1JT/wsjtx-{VERSION}-i686.rpm[wsjtx-{VERSION}-i686.rpm]
:fedora64: http://physics.princeton.edu/pulsar/K1JT/wsjtx-{VERSION}-x86_64.rpm[wsjtx-{VERSION}-x86_64.rpm]
:fmt_arrl: http://www.arrl.org/frequency-measuring-test[ARRL FMT Info]
:fmt_group: https://groups.yahoo.com/neo/groups/FMT-nuts/info[FMT Group]
:fmt_k5cm: http://www.k5cm.com/[FMT Event Info]
:fmt_wspr: http://www.physics.princeton.edu/pulsar/K1JT/FMT_User.pdf[Accurate Frequency Measurements with your WSPR Setup]
:ft8_tips: http://www.physics.princeton.edu/pulsar/K1JT/FT8_Operating_Tips.pdf[here]
:gnu_gpl: http://www.gnu.org/licenses/gpl-3.0.txt[GNU General Public License]
:homepage: http://physics.princeton.edu/pulsar/K1JT/[WSJT Home Page]
:hrd: http://www.hrdsoftwarellc.com/[Ham Radio Deluxe]
:jt4eme: http://physics.princeton.edu/pulsar/K1JT/WSJT-X_1.6.0_for_JT4_v7.pdf[Using WSJT-X for JT4 EME Operation]
:jt65protocol: http://physics.princeton.edu/pulsar/K1JT/JT65.pdf[QEX]
:jtalert: http://hamapps.com/[JT-Alert]
:launchpadki7mt: https://launchpad.net/~ki7mt[KI7MT PPA's]
:log4om: http://www.log4om.com[Log4OM]
:lunarEchoes: http://physics.princeton.edu/pulsar/K1JT/LunarEchoes_QEX.pdf[QEX]
:msys_url: http://sourceforge.net/projects/mingwbuilds/files/external-binary-packages/[MSYS Download]
:ntpsetup: http://www.satsignal.eu/ntp/setup.html[Network Time Protocol Setup]
:osx_instructions: http://physics.princeton.edu/pulsar/K1JT/OSX_Readme[Mac OS X Install Instructions]
:ppa: http://en.wikipedia.org/wiki/Personal_Package_Archive[PPA]
:projsummary: http://sourceforge.net/projects/wsjt/[Project Summary]
:pskreporter: http://pskreporter.info/pskmap.html[PSK Reporter]
:sourceforge: https://sourceforge.net/user/registration[SourceForge]
:sourceforge-jtsdk: https://sourceforge.net/projects/jtsdk[SourceForge JTSDK]
:ubuntu_sdk: https://launchpad.net/~ubuntu-sdk-team/+archive/ppa[Ubuntu SDK Notice]
:wsjt_yahoo_group: https://groups.yahoo.com/neo/groups/wsjtgroup/info[WSJT Group]
:wsjtx: http://physics.princeton.edu/pulsar/K1JT/wsjtx.html[WSJT-X]
:wspr0_guide: http://www.physics.princeton.edu/pulsar/K1JT/WSPR0_Instructions.TXT[WSPR0 Guide]
:wspr: http://physics.princeton.edu/pulsar/K1JT/wspr.html[WSPR Home Page]
:wsprnet: http://wsprnet.org/drupal/[WSPRnet]
:wsprnet_activity: http://wsprnet.org/drupal/wsprnet/activity[WSPRnet Activity page]
// Download Links
:cty_dat: http://www.country-files.com/cty/[Amateur Radio Country Files]
:jtbridge: http://jt-bridge.eller.nu/[JT-Bridge]
:jtsdk_doc: http://physics.princeton.edu/pulsar/K1JT/JTSDK-DOC.exe[Download]
:jtsdk_installer: http://sourceforge.net/projects/jtsdk/files/win32/2.0.0/JTSDK-2.0.0-B2-Win32.exe/download[Download]
:jtsdk_omnirig: http://sourceforge.net/projects/jtsdk/files/win32/2.0.0/base/contrib/OmniRig.zip/download[Download]
:jtsdk_py: http://physics.princeton.edu/pulsar/K1JT/JTSDK-PY.exe[Download]
:jtsdk_qt: http://physics.princeton.edu/pulsar/K1JT/JTSDK-QT.exe[Download]
:jtsdk_vcredist: http://sourceforge.net/projects/jtsdk/files/win32/2.0.0/base/contrib/vcredist_x86.exe/download[Download]
:nh6z: http://www.nh6z.net/Amatuer_Radio_Station_NH6Z/Other_Peoples_Software.html[here]
:omnirig: http://www.dxatlas.com/OmniRig/Files/OmniRig.zip[Download]
:osx: http://physics.princeton.edu/pulsar/K1JT/wsjtx-{VERSION}-Darwin.dmg[wsjtx-{VERSION}-Darwin.dmg]
:QRA64_EME: http://physics.princeton.edu/pulsar/K1JT/QRA64_EME.pdf[QRA64 for microwave EME]
:svn: http://subversion.apache.org/packages.html#windows[Subversion]
:win32: http://physics.princeton.edu/pulsar/K1JT/wsjtx-{VERSION}-win32.exe[wsjtx-{VERSION}-win32.exe]
:wsjt_svn: http://sourceforge.net/p/wsjt/wsjt/HEAD/tree/[WSJT Source Repository]
:wspr_code: http://physics.princeton.edu/pulsar/K1JT/WSPRcode.exe[WSPRcode.exe]
:wspr_svn: http://sourceforge.net/p/wsjt/wsjt/HEAD/tree/branches/wspr/[WSPR Source Repository]
// MAIL-TO links
:alex_efros: mailto:powerman@powerman.name[Alex Efros]
:bill_somerville: mailto:g4wjs -at- c l a s s d e s i g n -dot- com [G4WJS]
:dev_mail_list: http://sourceforge.net/mailarchive/forum.php?forum_name=wsjt-devel[WSJT Developers Email List]
:dev_mail_svn: https://sourceforge.net/auth/subscriptions/[WSJT SVN Archives]
:devmail: mailto:wsjt-devel@lists.sourceforge.net[wsjt-devel@lists.sourceforge.net]
:devmail1: mailto:wsjt-devel@lists.sourceforge.net[Post Message]
:wsjtgroup_mail: mailto:wsjtgroup@yahoogroups.com[Post Message]
:greg_beam: mailto:ki7mt@yahoo.com[KI7MT]
:joe_taylor: mailto:joe@princeton.edu[K1JT]
:stuart_rackman: mailto:srackham@gmail.com[Stuart Rackham]
@@ -0,0 +1,212 @@
//
// Copyright (c) Antony Polukhin, 2013-2016.
//
//
// Distributed under the 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_TYPE_INDEX_CTTI_TYPE_INDEX_HPP
#define BOOST_TYPE_INDEX_CTTI_TYPE_INDEX_HPP
/// \file ctti_type_index.hpp
/// \brief Contains boost::typeindex::ctti_type_index class that is constexpr if C++14 constexpr is supported by compiler.
///
/// boost::typeindex::ctti_type_index class can be used as a drop-in replacement
/// for std::type_index.
///
/// It is used in situations when typeid() method is not available or
/// BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY macro is defined.
#include <boost/type_index/type_index_facade.hpp>
#include <boost/type_index/detail/compile_time_type_info.hpp>
#include <cstring>
#include <boost/static_assert.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
namespace boost { namespace typeindex {
namespace detail {
// That's the most trickiest part of the TypeIndex library:
// 1) we do not want to give user ability to manually construct and compare `struct-that-represents-type`
// 2) we need to distinguish between `struct-that-represents-type` and `const char*`
// 3) we need a thread-safe way to have references to instances `struct-that-represents-type`
// 4) we need a compile-time control to make sure that user does not copy or
// default construct `struct-that-represents-type`
//
// Solution would be the following:
/// \class ctti_data
/// Standard-layout class with private constructors and assignment operators.
///
/// You can not work with this class directly. The purpose of this class is to hold type info
/// \b when \b RTTI \b is \b off and allow ctti_type_index construction from itself.
///
/// \b Example:
/// \code
/// const detail::ctti_data& foo();
/// ...
/// type_index ti = type_index(foo());
/// std::cout << ti.pretty_name();
/// \endcode
class ctti_data {
#ifndef BOOST_NO_CXX11_DELETED_FUNCTIONS
public:
ctti_data() = delete;
ctti_data(const ctti_data&) = delete;
ctti_data& operator=(const ctti_data&) = delete;
#else
private:
ctti_data();
ctti_data(const ctti_data&);
ctti_data& operator=(const ctti_data&);
#endif
};
} // namespace detail
/// Helper method for getting detail::ctti_data of a template parameter T.
template <class T>
inline const detail::ctti_data& ctti_construct() BOOST_NOEXCEPT {
// Standard C++11, 5.2.10 Reinterpret cast:
// An object pointer can be explicitly converted to an object pointer of a different type. When a prvalue
// v of type "pointer to T1" is converted to the type "pointer to cv T2", the result is static_cast<cv
// T2*>(static_cast<cv void*>(v)) if both T1 and T2 are standard-layout types (3.9) and the alignment
// requirements of T2 are no stricter than those of T1, or if either type is void. Converting a prvalue of type
// "pointer to T1" to the type "pointer to T2" (where T1 and T2 are object types and where the alignment
// requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer
// value.
//
// Alignments are checked in `type_index_test_ctti_alignment.cpp` test.
return *reinterpret_cast<const detail::ctti_data*>(boost::detail::ctti<T>::n());
}
/// \class ctti_type_index
/// This class is a wrapper that pretends to work exactly like stl_type_index, but does
/// not require RTTI support. \b For \b description \b of \b functions \b see type_index_facade.
///
/// This class on C++14 compatible compilers has following functions marked as constexpr:
/// * default constructor
/// * copy constructors and assignemnt operations
/// * class methods: name(), before(const ctti_type_index& rhs), equal(const ctti_type_index& rhs)
/// * static methods type_id<T>(), type_id_with_cvr<T>()
/// * comparison operators
///
/// This class produces slightly longer type names, so consider using stl_type_index
/// in situations when typeid() is working.
class ctti_type_index: public type_index_facade<ctti_type_index, detail::ctti_data> {
const char* data_;
inline std::size_t get_raw_name_length() const BOOST_NOEXCEPT;
BOOST_CXX14_CONSTEXPR inline explicit ctti_type_index(const char* data) BOOST_NOEXCEPT
: data_(data)
{}
public:
typedef detail::ctti_data type_info_t;
BOOST_CXX14_CONSTEXPR inline ctti_type_index() BOOST_NOEXCEPT
: data_(boost::detail::ctti<void>::n())
{}
inline ctti_type_index(const type_info_t& data) BOOST_NOEXCEPT
: data_(reinterpret_cast<const char*>(&data))
{}
inline const type_info_t& type_info() const BOOST_NOEXCEPT;
BOOST_CXX14_CONSTEXPR inline const char* raw_name() const BOOST_NOEXCEPT;
BOOST_CXX14_CONSTEXPR inline const char* name() const BOOST_NOEXCEPT;
inline std::string pretty_name() const;
inline std::size_t hash_code() const BOOST_NOEXCEPT;
BOOST_CXX14_CONSTEXPR inline bool equal(const ctti_type_index& rhs) const BOOST_NOEXCEPT;
BOOST_CXX14_CONSTEXPR inline bool before(const ctti_type_index& rhs) const BOOST_NOEXCEPT;
template <class T>
BOOST_CXX14_CONSTEXPR inline static ctti_type_index type_id() BOOST_NOEXCEPT;
template <class T>
BOOST_CXX14_CONSTEXPR inline static ctti_type_index type_id_with_cvr() BOOST_NOEXCEPT;
template <class T>
inline static ctti_type_index type_id_runtime(const T& variable) BOOST_NOEXCEPT;
};
inline const ctti_type_index::type_info_t& ctti_type_index::type_info() const BOOST_NOEXCEPT {
return *reinterpret_cast<const detail::ctti_data*>(data_);
}
BOOST_CXX14_CONSTEXPR inline bool ctti_type_index::equal(const ctti_type_index& rhs) const BOOST_NOEXCEPT {
const char* const left = raw_name();
const char* const right = rhs.raw_name();
return /*left == right ||*/ !boost::typeindex::detail::constexpr_strcmp(left, right);
}
BOOST_CXX14_CONSTEXPR inline bool ctti_type_index::before(const ctti_type_index& rhs) const BOOST_NOEXCEPT {
const char* const left = raw_name();
const char* const right = rhs.raw_name();
return /*left != right &&*/ boost::typeindex::detail::constexpr_strcmp(left, right) < 0;
}
template <class T>
BOOST_CXX14_CONSTEXPR inline ctti_type_index ctti_type_index::type_id() BOOST_NOEXCEPT {
typedef BOOST_DEDUCED_TYPENAME boost::remove_reference<T>::type no_ref_t;
typedef BOOST_DEDUCED_TYPENAME boost::remove_cv<no_ref_t>::type no_cvr_t;
return ctti_type_index(boost::detail::ctti<no_cvr_t>::n());
}
template <class T>
BOOST_CXX14_CONSTEXPR inline ctti_type_index ctti_type_index::type_id_with_cvr() BOOST_NOEXCEPT {
return ctti_type_index(boost::detail::ctti<T>::n());
}
template <class T>
inline ctti_type_index ctti_type_index::type_id_runtime(const T& variable) BOOST_NOEXCEPT {
return variable.boost_type_index_type_id_runtime_();
}
BOOST_CXX14_CONSTEXPR inline const char* ctti_type_index::raw_name() const BOOST_NOEXCEPT {
return data_;
}
BOOST_CXX14_CONSTEXPR inline const char* ctti_type_index::name() const BOOST_NOEXCEPT {
return data_;
}
inline std::size_t ctti_type_index::get_raw_name_length() const BOOST_NOEXCEPT {
return std::strlen(raw_name() + detail::ctti_skip_size_at_end);
}
inline std::string ctti_type_index::pretty_name() const {
std::size_t len = get_raw_name_length();
while (raw_name()[len - 1] == ' ') --len; // MSVC sometimes adds whitespaces
return std::string(raw_name(), len);
}
inline std::size_t ctti_type_index::hash_code() const BOOST_NOEXCEPT {
return boost::hash_range(raw_name(), raw_name() + get_raw_name_length());
}
}} // namespace boost::typeindex
#endif // BOOST_TYPE_INDEX_CTTI_TYPE_INDEX_HPP
@@ -0,0 +1,28 @@
# /* **************************************************************************
# * *
# * (C) Copyright Paul Mensonides 2002.
# * Distributed under the 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. */
#
# ifndef BOOST_PREPROCESSOR_SEQ_SUBSEQ_HPP
# define BOOST_PREPROCESSOR_SEQ_SUBSEQ_HPP
#
# include <boost/preprocessor/config/config.hpp>
# include <boost/preprocessor/seq/first_n.hpp>
# include <boost/preprocessor/seq/rest_n.hpp>
#
# /* BOOST_PP_SEQ_SUBSEQ */
#
# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
# define BOOST_PP_SEQ_SUBSEQ(seq, i, len) BOOST_PP_SEQ_FIRST_N(len, BOOST_PP_SEQ_REST_N(i, seq))
# else
# define BOOST_PP_SEQ_SUBSEQ(seq, i, len) BOOST_PP_SEQ_SUBSEQ_I(seq, i, len)
# define BOOST_PP_SEQ_SUBSEQ_I(seq, i, len) BOOST_PP_SEQ_FIRST_N(len, BOOST_PP_SEQ_REST_N(i, seq))
# endif
#
# endif
@@ -0,0 +1,55 @@
subroutine genft8(msg,msgsent,itone)
! Encode an FT8 message, producing array itone().
use crc
use packjt
include 'ft8_params.f90'
character*22 msg,msgsent
character*87 cbits
! logical checksumok
integer*4 i4Msg6BitWords(12) !72-bit message as 6-bit words
integer*1 msgbits(KK),codeword(3*ND)
integer*1, target:: i1Msg8BitBytes(11)
integer itone(NN)
integer icos7(0:6)
data icos7/2,5,6,0,4,1,3/ !Costas 7x7 tone pattern
call packmsg(msg,i4Msg6BitWords,itype) !Pack into 12 6-bit bytes
call unpackmsg(i4Msg6BitWords,msgsent) !Unpack to get msgsent
i3bit=0 !### temporary ###
write(cbits,1000) i4Msg6BitWords,32*i3bit
1000 format(12b6.6,b8.8)
read(cbits,1001) i1Msg8BitBytes(1:10)
1001 format(10b8)
i1Msg8BitBytes(10)=iand(i1Msg8BitBytes(10),128+64+32)
i1Msg8BitBytes(11)=0
icrc12=crc12(c_loc(i1Msg8BitBytes),11)
! For reference, here's how to check the CRC
! i1Msg8BitBytes(10)=icrc12/256
! i1Msg8BitBytes(11)=iand (icrc12,255)
! checksumok = crc12_check(c_loc (i1Msg8BitBytes), 11)
! if( checksumok ) write(*,*) 'Good checksum'
write(cbits,1003) i4Msg6BitWords,i3bit,icrc12
1003 format(12b6.6,b3.3,b12.12)
read(cbits,1004) msgbits
1004 format(87i1)
call encode174(msgbits,codeword) !Encode the test message
! Message structure: S7 D29 S7 D29 S7
itone(1:7)=icos7
itone(36+1:36+7)=icos7
itone(NN-6:NN)=icos7
k=7
do j=1,ND
i=3*j -2
k=k+1
if(j.eq.30) k=k+7
itone(k)=codeword(i)*4 + codeword(i+1)*2 + codeword(i+2)
enddo
return
end subroutine genft8
@@ -0,0 +1,160 @@
//---------------------------------------------------------------------------//
// Copyright (c) 2014 Roshan <thisisroshansmail@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
//
// See http://boostorg.github.com/compute for more information.
//---------------------------------------------------------------------------//
#ifndef BOOST_COMPUTE_RANDOM_DISCRETE_DISTRIBUTION_HPP
#define BOOST_COMPUTE_RANDOM_DISCRETE_DISTRIBUTION_HPP
#include <numeric>
#include <boost/config.hpp>
#include <boost/type_traits.hpp>
#include <boost/static_assert.hpp>
#include <boost/compute/command_queue.hpp>
#include <boost/compute/function.hpp>
#include <boost/compute/algorithm/accumulate.hpp>
#include <boost/compute/algorithm/copy.hpp>
#include <boost/compute/algorithm/transform.hpp>
#include <boost/compute/detail/literal.hpp>
#include <boost/compute/types/fundamental.hpp>
namespace boost {
namespace compute {
/// \class discrete_distribution
/// \brief Produces random integers on the interval [0, n), where
/// probability of each integer is given by the weight of the ith
/// integer divided by the sum of all weights.
///
/// The following example shows how to setup a discrete distribution to
/// produce 0 and 1 with equal probability
///
/// \snippet test/test_discrete_distribution.cpp generate
///
template<class IntType = uint_>
class discrete_distribution
{
public:
typedef IntType result_type;
/// Creates a new discrete distribution with a single weight p = { 1 }.
/// This distribution produces only zeroes.
discrete_distribution()
: m_probabilities(1, double(1)),
m_scanned_probabilities(1, double(1))
{
}
/// Creates a new discrete distribution with weights given by
/// the range [\p first, \p last).
template<class InputIterator>
discrete_distribution(InputIterator first, InputIterator last)
: m_probabilities(first, last),
m_scanned_probabilities(std::distance(first, last))
{
if(first != last) {
// after this m_scanned_probabilities.back() is a sum of all
// weights from the range [first, last)
std::partial_sum(first, last, m_scanned_probabilities.begin());
std::vector<double>::iterator i = m_probabilities.begin();
std::vector<double>::iterator j = m_scanned_probabilities.begin();
for(; i != m_probabilities.end(); ++i, ++j)
{
// dividing each weight by sum of all weights to
// get probabilities
*i = *i / m_scanned_probabilities.back();
// dividing each partial sum of weights by sum of
// all weights to get partial sums of probabilities
*j = *j / m_scanned_probabilities.back();
}
}
else {
m_probabilities.push_back(double(1));
m_scanned_probabilities.push_back(double(1));
}
}
/// Destroys the discrete_distribution object.
~discrete_distribution()
{
}
/// Returns the probabilities
::std::vector<double> probabilities() const
{
return m_probabilities;
}
/// Returns the minimum potentially generated value.
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const
{
return result_type(0);
}
/// Returns the maximum potentially generated value.
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const
{
size_t type_max = static_cast<size_t>(
(std::numeric_limits<result_type>::max)()
);
if(m_probabilities.size() - 1 > type_max) {
return (std::numeric_limits<result_type>::max)();
}
return static_cast<result_type>(m_probabilities.size() - 1);
}
/// Generates uniformly distributed integers and stores
/// them to the range [\p first, \p last).
template<class OutputIterator, class Generator>
void generate(OutputIterator first,
OutputIterator last,
Generator &generator,
command_queue &queue)
{
std::string source = "inline IntType scale_random(uint x)\n";
source = source +
"{\n" +
"float rno = convert_float(x) / UINT_MAX;\n";
for(size_t i = 0; i < m_scanned_probabilities.size() - 1; i++)
{
source = source +
"if(rno <= " + detail::make_literal<float>(m_scanned_probabilities[i]) + ")\n" +
" return " + detail::make_literal(i) + ";\n";
}
source = source +
"return " + detail::make_literal(m_scanned_probabilities.size() - 1) + ";\n" +
"}\n";
BOOST_COMPUTE_FUNCTION(IntType, scale_random, (const uint_ x), {});
scale_random.set_source(source);
scale_random.define("IntType", type_name<IntType>());
generator.generate(first, last, scale_random, queue);
}
private:
::std::vector<double> m_probabilities;
::std::vector<double> m_scanned_probabilities;
BOOST_STATIC_ASSERT_MSG(
boost::is_integral<IntType>::value,
"Template argument must be integral"
);
};
} // end compute namespace
} // end boost namespace
#endif // BOOST_COMPUTE_RANDOM_UNIFORM_INT_DISTRIBUTION_HPP
@@ -0,0 +1,490 @@
///////////////////////////////////////////////////////////////
// Copyright 2012 John Maddock. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
//
// Comparison operators for cpp_int_backend:
//
#ifndef BOOST_MP_CPP_INT_MUL_HPP
#define BOOST_MP_CPP_INT_MUL_HPP
namespace boost{ namespace multiprecision{ namespace backends{
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4127) // conditional expression is constant
#endif
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
const limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
if(!val)
{
result = static_cast<limb_type>(0);
return;
}
if((void*)&a != (void*)&result)
result.resize(a.size(), a.size());
double_limb_type carry = 0;
typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_pointer p = result.limbs();
typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_pointer pe = result.limbs() + result.size();
typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>::const_limb_pointer pa = a.limbs();
while(p != pe)
{
carry += static_cast<double_limb_type>(*pa) * static_cast<double_limb_type>(val);
#ifdef __MSVC_RUNTIME_CHECKS
*p = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
#else
*p = static_cast<limb_type>(carry);
#endif
carry >>= cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits;
++p, ++pa;
}
if(carry)
{
unsigned i = result.size();
result.resize(i + 1, i + 1);
if(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::variable || (result.size() > i))
result.limbs()[i] = static_cast<limb_type>(carry);
}
result.sign(a.sign());
if(!cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::variable)
result.normalize();
}
//
// resize_for_carry forces a resize of the underlying buffer only if a previous request
// for "required" elements could possibly have failed, *and* we have checking enabled.
// This will cause an overflow error inside resize():
//
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
inline void resize_for_carry(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& /*result*/, unsigned /*required*/){}
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
inline void resize_for_carry(cpp_int_backend<MinBits1, MaxBits1, SignType1, checked, void>& result, unsigned required)
{
if(result.size() != required)
result.resize(required, required);
}
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, unsigned MinBits3, unsigned MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3>
inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3> >::value >::type
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
// Very simple long multiplication, only usable for small numbers of limb_type's
// but that's the typical use case for this type anyway:
//
// Special cases first:
//
unsigned as = a.size();
unsigned bs = b.size();
typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>::const_limb_pointer pa = a.limbs();
typename cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>::const_limb_pointer pb = b.limbs();
if(as == 1)
{
bool s = b.sign() != a.sign();
if(bs == 1)
{
result = static_cast<double_limb_type>(*pa) * static_cast<double_limb_type>(*pb);
}
else
{
limb_type l = *pa;
eval_multiply(result, b, l);
}
result.sign(s);
return;
}
if(bs == 1)
{
bool s = b.sign() != a.sign();
limb_type l = *pb;
eval_multiply(result, a, l);
result.sign(s);
return;
}
if((void*)&result == (void*)&a)
{
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t(a);
eval_multiply(result, t, b);
return;
}
if((void*)&result == (void*)&b)
{
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t(b);
eval_multiply(result, a, t);
return;
}
result.resize(as + bs, as + bs - 1);
typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_pointer pr = result.limbs();
static const double_limb_type limb_max = ~static_cast<limb_type>(0u);
static const double_limb_type double_limb_max = ~static_cast<double_limb_type>(0u);
BOOST_STATIC_ASSERT(double_limb_max - 2 * limb_max >= limb_max * limb_max);
double_limb_type carry = 0;
std::memset(pr, 0, result.size() * sizeof(limb_type));
for(unsigned i = 0; i < as; ++i)
{
unsigned inner_limit = cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::variable ? bs : (std::min)(result.size() - i, bs);
for(unsigned j = 0; j < inner_limit; ++j)
{
BOOST_ASSERT(i+j < result.size());
#if (!defined(__GLIBCXX__) && !defined(__GLIBCPP__)) || !BOOST_WORKAROUND(BOOST_GCC_VERSION, <= 50100)
BOOST_ASSERT(!std::numeric_limits<double_limb_type>::is_specialized
|| ((std::numeric_limits<double_limb_type>::max)() - carry
>
static_cast<double_limb_type>(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value) * static_cast<double_limb_type>(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value)));
#endif
carry += static_cast<double_limb_type>(pa[i]) * static_cast<double_limb_type>(pb[j]);
BOOST_ASSERT(!std::numeric_limits<double_limb_type>::is_specialized || ((std::numeric_limits<double_limb_type>::max)() - carry >= pr[i+j]));
carry += pr[i + j];
#ifdef __MSVC_RUNTIME_CHECKS
pr[i + j] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
#else
pr[i + j] = static_cast<limb_type>(carry);
#endif
carry >>= cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits;
BOOST_ASSERT(carry <= (cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value));
}
resize_for_carry(result, as + bs); // May throw if checking is enabled
if(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::variable || (i + bs < result.size()))
pr[i + bs] = static_cast<limb_type>(carry);
carry = 0;
}
result.normalize();
//
// Set the sign of the result:
//
result.sign(a.sign() != b.sign());
}
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
eval_multiply(result, result, a);
}
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
eval_multiply(result, result, val);
}
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
const double_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
if(val <= (std::numeric_limits<limb_type>::max)())
{
eval_multiply(result, a, static_cast<limb_type>(val));
}
else
{
#if defined(BOOST_LITTLE_ENDIAN) && !defined(BOOST_MP_TEST_NO_LE)
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t(val);
#else
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t;
t = val;
#endif
eval_multiply(result, a, t);
}
}
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const double_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
eval_multiply(result, result, val);
}
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
const signed_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
if(val > 0)
eval_multiply(result, a, static_cast<limb_type>(val));
else
{
eval_multiply(result, a, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(val)));
result.negate();
}
}
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const signed_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
eval_multiply(result, result, val);
}
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
const signed_double_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
if(val > 0)
{
if(val <= (std::numeric_limits<limb_type>::max)())
{
eval_multiply(result, a, static_cast<limb_type>(val));
return;
}
}
else if(val >= -static_cast<signed_double_limb_type>((std::numeric_limits<limb_type>::max)()))
{
eval_multiply(result, a, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(val)));
result.negate();
return;
}
#if defined(BOOST_LITTLE_ENDIAN) && !defined(BOOST_MP_TEST_NO_LE)
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t(val);
#else
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t;
t = val;
#endif
eval_multiply(result, a, t);
}
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const signed_double_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
eval_multiply(result, result, val);
}
//
// Now over again for trivial cpp_int's:
//
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
BOOST_MP_FORCEINLINE typename enable_if_c<
is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
&& is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
&& (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
|| is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)
>::type
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
*result.limbs() = detail::checked_multiply(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
result.sign(result.sign() != o.sign());
result.normalize();
}
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
BOOST_MP_FORCEINLINE typename enable_if_c<
is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
&& is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
>::type
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
*result.limbs() = detail::checked_multiply(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
result.normalize();
}
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
BOOST_MP_FORCEINLINE typename enable_if_c<
is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
&& is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
&& (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
|| is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)
>::type
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a,
const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
*result.limbs() = detail::checked_multiply(*a.limbs(), *b.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
result.sign(a.sign() != b.sign());
result.normalize();
}
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
BOOST_MP_FORCEINLINE typename enable_if_c<
is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
&& is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
>::type
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a,
const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
*result.limbs() = detail::checked_multiply(*a.limbs(), *b.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
result.normalize();
}
//
// Special routines for multiplying two integers to obtain a multiprecision result:
//
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
BOOST_MP_FORCEINLINE typename enable_if_c<
!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
>::type
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
signed_double_limb_type a, signed_double_limb_type b)
{
static const signed_double_limb_type mask = ~static_cast<limb_type>(0);
static const unsigned limb_bits = sizeof(limb_type) * CHAR_BIT;
bool s = false;
double_limb_type w, x, y, z;
if(a < 0)
{
a = -a;
s = true;
}
if(b < 0)
{
b = -b;
s = !s;
}
w = a & mask;
x = a >> limb_bits;
y = b & mask;
z = b >> limb_bits;
result.resize(4, 4);
limb_type* pr = result.limbs();
double_limb_type carry = w * y;
#ifdef __MSVC_RUNTIME_CHECKS
pr[0] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
carry >>= limb_bits;
carry += w * z + x * y;
pr[1] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
carry >>= limb_bits;
carry += x * z;
pr[2] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
pr[3] = static_cast<limb_type>(carry >> limb_bits);
#else
pr[0] = static_cast<limb_type>(carry);
carry >>= limb_bits;
carry += w * z + x * y;
pr[1] = static_cast<limb_type>(carry);
carry >>= limb_bits;
carry += x * z;
pr[2] = static_cast<limb_type>(carry);
pr[3] = static_cast<limb_type>(carry >> limb_bits);
#endif
result.sign(s);
result.normalize();
}
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
BOOST_MP_FORCEINLINE typename enable_if_c<
!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
>::type
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
double_limb_type a, double_limb_type b)
{
static const signed_double_limb_type mask = ~static_cast<limb_type>(0);
static const unsigned limb_bits = sizeof(limb_type) * CHAR_BIT;
double_limb_type w, x, y, z;
w = a & mask;
x = a >> limb_bits;
y = b & mask;
z = b >> limb_bits;
result.resize(4, 4);
limb_type* pr = result.limbs();
double_limb_type carry = w * y;
#ifdef __MSVC_RUNTIME_CHECKS
pr[0] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
carry >>= limb_bits;
carry += w * z;
pr[1] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
carry >>= limb_bits;
pr[2] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
carry = x * y + pr[1];
pr[1] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
carry >>= limb_bits;
carry += pr[2] + x * z;
pr[2] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
pr[3] = static_cast<limb_type>(carry >> limb_bits);
#else
pr[0] = static_cast<limb_type>(carry);
carry >>= limb_bits;
carry += w * z;
pr[1] = static_cast<limb_type>(carry);
carry >>= limb_bits;
pr[2] = static_cast<limb_type>(carry);
carry = x * y + pr[1];
pr[1] = static_cast<limb_type>(carry);
carry >>= limb_bits;
carry += pr[2] + x * z;
pr[2] = static_cast<limb_type>(carry);
pr[3] = static_cast<limb_type>(carry >> limb_bits);
#endif
result.sign(false);
result.normalize();
}
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1,
unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
BOOST_MP_FORCEINLINE typename enable_if_c<
!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
&& is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value
&& is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value
>::type
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> const& a,
cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> const& b)
{
typedef typename boost::multiprecision::detail::canonical<typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>::local_limb_type, cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::type canonical_type;
eval_multiply(result, static_cast<canonical_type>(*a.limbs()), static_cast<canonical_type>(*b.limbs()));
result.sign(a.sign() != b.sign());
}
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class SI>
BOOST_MP_FORCEINLINE typename enable_if_c<is_signed<SI>::value && (sizeof(SI) <= sizeof(signed_double_limb_type) / 2)>::type
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
SI a, SI b)
{
result = static_cast<signed_double_limb_type>(a) * static_cast<signed_double_limb_type>(b);
}
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class UI>
BOOST_MP_FORCEINLINE typename enable_if_c<is_unsigned<UI>::value && (sizeof(UI) <= sizeof(signed_double_limb_type) / 2)>::type
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
UI a, UI b)
{
result = static_cast<double_limb_type>(a) * static_cast<double_limb_type>(b);
}
#ifdef _MSC_VER
#pragma warning(pop)
#endif
}}} // namespaces
#endif
@@ -0,0 +1,162 @@
/*
[auto_generated]
boost/numeric/odeint/stepper/symplectic_rkn_sb3a_mclachlan.hpp
[begin_description]
Implementation of the symplectic MacLachlan stepper for separable Hamiltonian system.
[end_description]
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)
*/
#ifndef BOOST_NUMERIC_ODEINT_STEPPER_SYMPLECTIC_RKN_SB3A_MCLACHLAN_HPP_INCLUDED
#define BOOST_NUMERIC_ODEINT_STEPPER_SYMPLECTIC_RKN_SB3A_MCLACHLAN_HPP_INCLUDED
#include <boost/numeric/odeint/stepper/base/symplectic_rkn_stepper_base.hpp>
#include <boost/numeric/odeint/algebra/range_algebra.hpp>
#include <boost/numeric/odeint/algebra/default_operations.hpp>
#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
#include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
#include <boost/numeric/odeint/util/resizer.hpp>
#include <boost/array.hpp>
namespace boost {
namespace numeric {
namespace odeint {
#ifndef DOXYGEN_SKIP
namespace detail {
namespace symplectic_rkn_sb3a_mclachlan {
/*
exp( a1 t A ) exp( b1 t B )
exp( a2 t A ) exp( b2 t B )
exp( a3 t A ) exp( b3 t B ) exp( a3 t A )
exp( b2 t B ) exp( a2 t A )
exp( b1 t B ) exp( a1 t A )
*/
template< class Value >
struct coef_a_type : public boost::array< Value , 6 >
{
coef_a_type( void )
{
(*this)[0] = static_cast< Value >( 0.40518861839525227722 );
(*this)[1] = static_cast< Value >( -0.28714404081652408900 );
(*this)[2] = static_cast< Value >( 1 ) / static_cast< Value >( 2 ) - ( (*this)[0] + (*this)[1] );
(*this)[3] = (*this)[2];
(*this)[4] = (*this)[1];
(*this)[5] = (*this)[0];
}
};
template< class Value >
struct coef_b_type : public boost::array< Value , 6 >
{
coef_b_type( void )
{
(*this)[0] = static_cast< Value >( -3 ) / static_cast< Value >( 73 );
(*this)[1] = static_cast< Value >( 17 ) / static_cast< Value >( 59 );
(*this)[2] = static_cast< Value >( 1 ) - static_cast< Value >( 2 ) * ( (*this)[0] + (*this)[1] );
(*this)[3] = (*this)[1];
(*this)[4] = (*this)[0];
(*this)[5] = static_cast< Value >( 0 );
}
};
} // namespace symplectic_rkn_sb3a_mclachlan
} // namespace detail
#endif // DOXYGEN_SKIP
template<
class Coor ,
class Momentum = Coor ,
class Value = double ,
class CoorDeriv = Coor ,
class MomentumDeriv = Coor ,
class Time = Value ,
class Algebra = typename algebra_dispatcher< Coor >::algebra_type ,
class Operations = typename operations_dispatcher< Coor >::operations_type ,
class Resizer = initially_resizer
>
#ifndef DOXYGEN_SKIP
class symplectic_rkn_sb3a_mclachlan :
public symplectic_nystroem_stepper_base
<
6 , 4 ,
Coor , Momentum , Value , CoorDeriv , MomentumDeriv , Time , Algebra , Operations , Resizer
>
#else
class symplectic_rkn_sb3a_mclachlan : public symplectic_nystroem_stepper_base
#endif
{
public:
#ifndef DOXYGEN_SKIP
typedef symplectic_nystroem_stepper_base
<
6 , 4 ,
Coor , Momentum , Value , CoorDeriv , MomentumDeriv , Time , Algebra , Operations , Resizer
> stepper_base_type;
#endif
typedef typename stepper_base_type::algebra_type algebra_type;
typedef typename stepper_base_type::value_type value_type;
symplectic_rkn_sb3a_mclachlan( const algebra_type &algebra = algebra_type() )
: stepper_base_type(
detail::symplectic_rkn_sb3a_mclachlan::coef_a_type< value_type >() ,
detail::symplectic_rkn_sb3a_mclachlan::coef_b_type< value_type >() ,
algebra )
{ }
};
/************* DOXYGEN ***********/
/**
* \class symplectic_rkn_sb3a_mclachlan
* \brief Implement of the symmetric B3A method of Runge-Kutta-Nystroem method of sixth order.
*
* The method is of fourth order and has six stages. It is described HERE. This method cannot be used
* with multiprecision types since the coefficients are not defined analytically.
*
* ToDo Add reference to the paper.
*
* \tparam Order The order of the stepper.
* \tparam Coor The type representing the coordinates q.
* \tparam Momentum The type representing the coordinates p.
* \tparam Value The basic value type. Should be something like float, double or a high-precision type.
* \tparam CoorDeriv The type representing the time derivative of the coordinate dq/dt.
* \tparam MomemtnumDeriv The type representing the time derivative of the momentum dp/dt.
* \tparam Time The type representing the time t.
* \tparam Algebra The algebra.
* \tparam Operations The operations.
* \tparam Resizer The resizer policy.
*/
/**
* \fn symplectic_rkn_sb3a_mclachlan::symplectic_rkn_sb3a_mclachlan( const algebra_type &algebra )
* \brief Constructs the symplectic_rkn_sb3a_mclachlan. This constructor can be used as a default
* constructor if the algebra has a default constructor.
* \param algebra A copy of algebra is made and stored inside explicit_stepper_base.
*/
} // namespace odeint
} // namespace numeric
} // namespace boost
#endif // BOOST_NUMERIC_ODEINT_STEPPER_SYMPLECTIC_RKN_SB3A_MCLACHLAN_HPP_INCLUDED
@@ -0,0 +1,43 @@
/*
Copyright (c) Microsoft Corporation 2014
Copyright Rene Rivera 2015
Distributed under the 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_PREDEF_PLAT_WINDOWS_STORE_H
#define BOOST_PREDEF_PLAT_WINDOWS_STORE_H
#include <boost/predef/version_number.h>
#include <boost/predef/make.h>
#include <boost/predef/os/windows.h>
/*`
[heading `BOOST_PLAT_WINDOWS_STORE`]
[table
[[__predef_symbol__] [__predef_version__]]
[[`WINAPI_FAMILY == WINAPI_FAMILY_APP`] [__predef_detection__]]
]
*/
#define BOOST_PLAT_WINDOWS_STORE BOOST_VERSION_NUMBER_NOT_AVAILABLE
#if BOOST_OS_WINDOWS && defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP
# undef BOOST_PLAT_WINDOWS_STORE
# define BOOST_PLAT_WINDOWS_STORE BOOST_VERSION_NUMBER_AVAILABLE
#endif
#if BOOST_PLAT_WINDOWS_STORE
# define BOOST_PLAT_WINDOWS_STORE_AVAILABLE
# include <boost/predef/detail/platform_detected.h>
#endif
#define BOOST_PLAT_WINDOWS_STORE_NAME "Windows Store"
#endif
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_WINDOWS_STORE,BOOST_PLAT_WINDOWS_STORE_NAME)
@@ -0,0 +1,25 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(FUSION_VECTOR_LIMITS_07072005_1246)
#define FUSION_VECTOR_LIMITS_07072005_1246
#include <boost/fusion/support/config.hpp>
#include <boost/fusion/support/detail/pp_round.hpp>
#include <boost/preprocessor/stringize.hpp>
#if !defined(FUSION_MAX_VECTOR_SIZE)
# define FUSION_MAX_VECTOR_SIZE 10
#else
# if FUSION_MAX_VECTOR_SIZE < 3
# undef FUSION_MAX_VECTOR_SIZE
# define FUSION_MAX_VECTOR_SIZE 10
# endif
#endif
#define FUSION_MAX_VECTOR_SIZE_STR BOOST_PP_STRINGIZE(BOOST_FUSION_PP_ROUND_UP(FUSION_MAX_VECTOR_SIZE))
#endif
@@ -0,0 +1,173 @@
/*
[auto_generated]
boost/numeric/odeint/iterator/const_step_time_iterator.hpp
[begin_description]
Iterator for iterating throught the solution of an ODE with constant step size. The dereferences types containes also the time.
[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 BOOST_NUMERIC_ODEINT_ITERATOR_CONST_STEP_TIME_ITERATOR_HPP_INCLUDED
#define BOOST_NUMERIC_ODEINT_ITERATOR_CONST_STEP_TIME_ITERATOR_HPP_INCLUDED
#include <boost/numeric/odeint/stepper/stepper_categories.hpp>
#include <boost/numeric/odeint/util/stepper_traits.hpp>
#include <boost/numeric/odeint/iterator/detail/ode_iterator_base.hpp>
#include <boost/numeric/odeint/iterator/impl/const_step_iterator_impl.hpp>
namespace boost {
namespace numeric {
namespace odeint {
/* use the const_step_iterator_impl with the right tags */
template< class Stepper , class System , class State
#ifndef DOXYGEN_SKIP
, class StepperTag = typename base_tag< typename traits::stepper_category< Stepper >::type >::type
#endif
>
class const_step_time_iterator : public const_step_iterator_impl<
const_step_time_iterator< Stepper , System , State , StepperTag > ,
Stepper , System , State , detail::ode_state_time_iterator_tag , StepperTag
>
{
typedef typename traits::time_type< Stepper >::type time_type;
typedef const_step_time_iterator< Stepper , System , State , StepperTag > iterator_type;
public:
const_step_time_iterator( Stepper stepper , System sys , State &s , time_type t_start , time_type t_end , time_type dt )
: const_step_iterator_impl< iterator_type , Stepper , System , State , detail::ode_state_time_iterator_tag , StepperTag >( stepper , sys , s , t_start , t_end , dt )
{}
const_step_time_iterator( Stepper stepper , System sys , State &s )
: const_step_iterator_impl< iterator_type , Stepper , System , State , detail::ode_state_time_iterator_tag , StepperTag >( stepper , sys , s )
{}
};
template< class Stepper , class System , class State >
const_step_time_iterator< Stepper , System , State > make_const_step_time_iterator_begin(
Stepper stepper ,
System system ,
State &x ,
typename traits::time_type< Stepper >::type t_start ,
typename traits::time_type< Stepper >::type t_end ,
typename traits::time_type< Stepper >::type dt )
{
return const_step_time_iterator< Stepper , System , State >( stepper , system , x , t_start , t_end , dt );
}
template< class Stepper , class System , class State >
const_step_time_iterator< Stepper , System , State > make_const_step_time_iterator_end(
Stepper stepper ,
System system ,
State &x )
{
return const_step_time_iterator< Stepper , System , State >( stepper , system , x );
}
template< class Stepper , class System , class State >
std::pair< const_step_time_iterator< Stepper , System , State > , const_step_time_iterator< Stepper , System , State > >
make_const_step_time_range(
Stepper stepper ,
System system ,
State &x ,
typename traits::time_type< Stepper >::type t_start ,
typename traits::time_type< Stepper >::type t_end ,
typename traits::time_type< Stepper >::type dt )
{
return std::make_pair(
const_step_time_iterator< Stepper , System , State >( stepper , system , x , t_start , t_end , dt ) ,
const_step_time_iterator< Stepper , System , State >( stepper , system , x ) );
}
/**
* \class const_step_time_iterator
*
* \brief ODE Iterator with constant step size. The value type of this iterator is a std::pair containing state and time.
*
* Implements an iterator representing the solution of an ODE from t_start
* to t_end evaluated at steps with constant step size dt.
* After each iteration the iterator dereferences to a pair containing
* state and time at the next time point t+dt..
* This iterator can be used with Steppers and
* DenseOutputSteppers and it always makes use of the all the given steppers
* capabilities. A for_each over such an iterator range behaves similar to
* the integrate_const routine.
*
* const_step_time_iterator is a model of single-pass iterator.
*
* The value type of this iterator is a pair with the state type and time type of the stepper.
*
* \tparam Stepper The stepper type which should be used during the iteration.
* \tparam System The type of the system function (ODE) which should be solved.
* \tparam State The state type of the ODE.
*/
/**
* \fn make_const_step_time_iterator_begin( Stepper stepper , System system , State &x ,
typename traits::time_type< Stepper >::type t_start ,
typename traits::time_type< Stepper >::type t_end ,
typename traits::time_type< Stepper >::type dt )
*
* \brief Factory function for const_step_time_iterator. Constructs a begin iterator.
*
* \param stepper The stepper to use during the iteration.
* \param system The system function (ODE) to solve.
* \param x The initial state. const_step_time_iterator stores a reference of s and changes its value during the iteration.
* \param t_start The initial time.
* \param t_end The end time, at which the iteration should stop.
* \param dt The initial time step.
* \returns The const step time iterator.
*/
/**
* \fn make_const_step_time_iterator_end( Stepper stepper , System system , State &x )
* \brief Factory function for const_step_time_iterator. Constructs a end iterator.
*
* \param stepper The stepper to use during the iteration.
* \param system The system function (ODE) to solve.
* \param x The initial state. const_step_time_iterator store a reference of s and changes its value during the iteration.
* \returns The const step time iterator.
*/
/**
* \fn make_const_step_time_range( Stepper stepper , System system , State &x ,
typename traits::time_type< Stepper >::type t_start ,
typename traits::time_type< Stepper >::type t_end ,
typename traits::time_type< Stepper >::type dt)
*
* \brief Factory function to construct a single pass range of const_step_time_iterator. A range is here a pair of const_step_time_iterator.
*
* \param stepper The stepper to use during the iteration.
* \param system The system function (ODE) to solve.
* \param x The initial state. const_step_time_iterator stores a reference of s and changes its value during the iteration.
* \param t The initial time.
* \param t_end The end time, at which the iteration should stop.
* \param dt The initial time step.
* \returns The const step time range.
*/
} // namespace odeint
} // namespace numeric
} // namespace boost
#endif // BOOST_NUMERIC_ODEINT_ITERATOR_CONST_STEP_TIME_ITERATOR_HPP_INCLUDED
@@ -0,0 +1,317 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2014. Distributed under the 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/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_CONTAINER_FWD_HPP
#define BOOST_CONTAINER_CONTAINER_FWD_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
//! \file
//! This header file forward declares the following containers:
//! - boost::container::vector
//! - boost::container::stable_vector
//! - boost::container::static_vector
//! - boost::container::small_vector
//! - boost::container::slist
//! - boost::container::list
//! - boost::container::set
//! - boost::container::multiset
//! - boost::container::map
//! - boost::container::multimap
//! - boost::container::flat_set
//! - boost::container::flat_multiset
//! - boost::container::flat_map
//! - boost::container::flat_multimap
//! - boost::container::basic_string
//! - boost::container::string
//! - boost::container::wstring
//!
//! Forward declares the following allocators:
//! - boost::container::allocator
//! - boost::container::node_allocator
//! - boost::container::adaptive_pool
//!
//! Forward declares the following polymorphic resource classes:
//! - boost::container::pmr::memory_resource
//! - boost::container::pmr::polymorphic_allocator
//! - boost::container::pmr::monotonic_buffer_resource
//! - boost::container::pmr::pool_options
//! - boost::container::pmr::unsynchronized_pool_resource
//! - boost::container::pmr::synchronized_pool_resource
//!
//! And finally it defines the following types
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//Std forward declarations
#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP
#include <boost/container/detail/std_fwd.hpp>
#endif
namespace boost{
namespace intrusive{
namespace detail{
//Create namespace to avoid compilation errors
}}}
namespace boost{ namespace container{ namespace container_detail{
namespace bi = boost::intrusive;
namespace bid = boost::intrusive::detail;
}}}
namespace boost{ namespace container{ namespace pmr{
namespace bi = boost::intrusive;
namespace bid = boost::intrusive::detail;
}}}
#include <cstddef>
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//////////////////////////////////////////////////////////////////////////////
// Containers
//////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace container {
//! Enumeration used to configure ordered associative containers
//! with a concrete tree implementation.
enum tree_type_enum
{
red_black_tree,
avl_tree,
scapegoat_tree,
splay_tree
};
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
template<class T>
class new_allocator;
template <class T
,class Allocator = new_allocator<T> >
class vector;
template <class T
,class Allocator = new_allocator<T> >
class stable_vector;
template <class T, std::size_t Capacity>
class static_vector;
template < class T, std::size_t N
, class Allocator= new_allocator<T> >
class small_vector;
template <class T
,class Allocator = new_allocator<T> >
class deque;
template <class T
,class Allocator = new_allocator<T> >
class list;
template <class T
,class Allocator = new_allocator<T> >
class slist;
template<tree_type_enum TreeType, bool OptimizeSize>
struct tree_opt;
typedef tree_opt<red_black_tree, true> tree_assoc_defaults;
template <class Key
,class Compare = std::less<Key>
,class Allocator = new_allocator<Key>
,class Options = tree_assoc_defaults >
class set;
template <class Key
,class Compare = std::less<Key>
,class Allocator = new_allocator<Key>
,class Options = tree_assoc_defaults >
class multiset;
template <class Key
,class T
,class Compare = std::less<Key>
,class Allocator = new_allocator<std::pair<const Key, T> >
,class Options = tree_assoc_defaults >
class map;
template <class Key
,class T
,class Compare = std::less<Key>
,class Allocator = new_allocator<std::pair<const Key, T> >
,class Options = tree_assoc_defaults >
class multimap;
template <class Key
,class Compare = std::less<Key>
,class Allocator = new_allocator<Key> >
class flat_set;
template <class Key
,class Compare = std::less<Key>
,class Allocator = new_allocator<Key> >
class flat_multiset;
template <class Key
,class T
,class Compare = std::less<Key>
,class Allocator = new_allocator<std::pair<Key, T> > >
class flat_map;
template <class Key
,class T
,class Compare = std::less<Key>
,class Allocator = new_allocator<std::pair<Key, T> > >
class flat_multimap;
template <class CharT
,class Traits = std::char_traits<CharT>
,class Allocator = new_allocator<CharT> >
class basic_string;
typedef basic_string
<char
,std::char_traits<char>
,new_allocator<char> >
string;
typedef basic_string
<wchar_t
,std::char_traits<wchar_t>
,new_allocator<wchar_t> >
wstring;
static const std::size_t ADP_nodes_per_block = 256u;
static const std::size_t ADP_max_free_blocks = 2u;
static const std::size_t ADP_overhead_percent = 1u;
static const std::size_t ADP_only_alignment = 0u;
template < class T
, std::size_t NodesPerBlock = ADP_nodes_per_block
, std::size_t MaxFreeBlocks = ADP_max_free_blocks
, std::size_t OverheadPercent = ADP_overhead_percent
, unsigned Version = 2
>
class adaptive_pool;
template < class T
, unsigned Version = 2
, unsigned int AllocationDisableMask = 0>
class allocator;
static const std::size_t NodeAlloc_nodes_per_block = 256u;
template
< class T
, std::size_t NodesPerBlock = NodeAlloc_nodes_per_block
, std::size_t Version = 2>
class node_allocator;
namespace pmr {
class memory_resource;
template<class T>
class polymorphic_allocator;
class monotonic_buffer_resource;
struct pool_options;
template <class Allocator>
class resource_adaptor_imp;
class unsynchronized_pool_resource;
class synchronized_pool_resource;
} //namespace pmr {
#else
//! Default options for tree-based associative containers
//! - tree_type<red_black_tree>
//! - optimize_size<true>
typedef implementation_defined tree_assoc_defaults;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//! Type used to tag that the input range is
//! guaranteed to be ordered
struct ordered_range_t
{};
//! Value used to tag that the input range is
//! guaranteed to be ordered
static const ordered_range_t ordered_range = ordered_range_t();
//! Type used to tag that the input range is
//! guaranteed to be ordered and unique
struct ordered_unique_range_t
: public ordered_range_t
{};
//! Value used to tag that the input range is
//! guaranteed to be ordered and unique
static const ordered_unique_range_t ordered_unique_range = ordered_unique_range_t();
//! Type used to tag that the inserted values
//! should be default initialized
struct default_init_t
{};
//! Value used to tag that the inserted values
//! should be default initialized
static const default_init_t default_init = default_init_t();
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//! Type used to tag that the inserted values
//! should be value initialized
struct value_init_t
{};
//! Value used to tag that the inserted values
//! should be value initialized
static const value_init_t value_init = value_init_t();
namespace container_detail_really_deep_namespace {
//Otherwise, gcc issues a warning of previously defined
//anonymous_instance and unique_instance
struct dummy
{
dummy()
{
(void)ordered_range;
(void)ordered_unique_range;
(void)default_init;
}
};
} //detail_really_deep_namespace {
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
}} //namespace boost { namespace container {
#endif //#ifndef BOOST_CONTAINER_CONTAINER_FWD_HPP
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,24 @@
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
// 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).
//
// See http://www.boost.org/libs/type_traits for most recent version including documentation.
#ifndef BOOST_TT_IS_COMPOUND_HPP_INCLUDED
#define BOOST_TT_IS_COMPOUND_HPP_INCLUDED
#include <boost/type_traits/is_fundamental.hpp>
namespace boost {
#if defined( __CODEGEARC__ )
template <class T> struct is_compound : public integral_constant<bool, __is_compound(T)> {};
#else
template <class T> struct is_compound : public integral_constant<bool, ! ::boost::is_fundamental<T>::value> {};
#endif
} // namespace boost
#endif // BOOST_TT_IS_COMPOUND_HPP_INCLUDED
@@ -0,0 +1,947 @@
///////////////////////////////////////////////////////////////////////////////
/// \file matches.hpp
/// Contains definition of matches\<\> metafunction for determining if
/// a given expression matches a given pattern.
//
// Copyright 2008 Eric Niebler. Distributed under the 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_PROTO_MATCHES_HPP_EAN_11_03_2006
#define BOOST_PROTO_MATCHES_HPP_EAN_11_03_2006
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/arithmetic/dec.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/facilities/intercept.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_shifted.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/config.hpp>
#include <boost/mpl/logical.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/proto/detail/template_arity.hpp>
#include <boost/utility/enable_if.hpp>
#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
#include <boost/type_traits/is_array.hpp>
#endif
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/proto/proto_fwd.hpp>
#include <boost/proto/traits.hpp>
#include <boost/proto/transform/when.hpp>
#include <boost/proto/transform/impl.hpp>
#if defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable:4305) // 'specialization' : truncation from 'const int' to 'bool'
#endif
#define BOOST_PROTO_LOGICAL_typename_G BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_LOGICAL_ARITY, typename G)
#define BOOST_PROTO_LOGICAL_G BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_LOGICAL_ARITY, G)
namespace boost { namespace proto
{
namespace detail
{
template<typename Expr, typename BasicExpr, typename Grammar>
struct matches_;
template<bool B, typename Pred>
struct and_2;
template<typename And, typename Expr, typename State, typename Data>
struct _and_impl;
template<typename T, typename U>
struct array_matches
: mpl::false_
{};
template<typename T, std::size_t M>
struct array_matches<T[M], T *>
: mpl::true_
{};
template<typename T, std::size_t M>
struct array_matches<T[M], T const *>
: mpl::true_
{};
template<typename T, std::size_t M>
struct array_matches<T[M], T[proto::N]>
: mpl::true_
{};
template<typename T, typename U
BOOST_PROTO_TEMPLATE_ARITY_PARAM(long Arity = detail::template_arity<U>::value)
>
struct lambda_matches
: mpl::false_
{};
template<typename T>
struct lambda_matches<T, proto::_ BOOST_PROTO_TEMPLATE_ARITY_PARAM(-1)>
: mpl::true_
{};
template<typename T>
struct lambda_matches<T, T BOOST_PROTO_TEMPLATE_ARITY_PARAM(-1)>
: mpl::true_
{};
template<typename T, std::size_t M, typename U>
struct lambda_matches<T[M], U BOOST_PROTO_TEMPLATE_ARITY_PARAM(-1)>
: array_matches<T[M], U>
{};
template<typename T, std::size_t M>
struct lambda_matches<T[M], _ BOOST_PROTO_TEMPLATE_ARITY_PARAM(-1)>
: mpl::true_
{};
template<typename T, std::size_t M>
struct lambda_matches<T[M], T[M] BOOST_PROTO_TEMPLATE_ARITY_PARAM(-1)>
: mpl::true_
{};
template<template<typename> class T, typename Expr0, typename Grammar0>
struct lambda_matches<T<Expr0>, T<Grammar0> BOOST_PROTO_TEMPLATE_ARITY_PARAM(1) >
: lambda_matches<Expr0, Grammar0>
{};
// vararg_matches_impl
template<typename Args1, typename Back, long From, long To>
struct vararg_matches_impl;
// vararg_matches
template<typename Expr, typename Args1, typename Args2, typename Back, bool Can, bool Zero, typename Void = void>
struct vararg_matches
: mpl::false_
{};
template<typename Expr, typename Args1, typename Args2, typename Back>
struct vararg_matches<Expr, Args1, Args2, Back, true, true, typename Back::proto_is_vararg_>
: matches_<
Expr
, proto::basic_expr<ignore, Args1, Args1::arity>
, proto::basic_expr<ignore, Args2, Args1::arity>
>
{};
template<typename Expr, typename Args1, typename Args2, typename Back>
struct vararg_matches<Expr, Args1, Args2, Back, true, false, typename Back::proto_is_vararg_>
: and_2<
matches_<
Expr
, proto::basic_expr<ignore, Args1, Args2::arity>
, proto::basic_expr<ignore, Args2, Args2::arity>
>::value
, vararg_matches_impl<Args1, typename Back::proto_grammar, Args2::arity + 1, Args1::arity>
>
{};
// How terminal_matches<> handles references and cv-qualifiers.
// The cv and ref matter *only* if the grammar has a top-level ref.
//
// Expr | Grammar | Matches?
// -------------------------------------
// T T yes
// T & T yes
// T const & T yes
// T T & no
// T & T & yes
// T const & T & no
// T T const & no
// T & T const & no
// T const & T const & yes
template<typename T, typename U>
struct is_cv_ref_compatible
: mpl::true_
{};
template<typename T, typename U>
struct is_cv_ref_compatible<T, U &>
: mpl::false_
{};
template<typename T, typename U>
struct is_cv_ref_compatible<T &, U &>
: mpl::bool_<is_const<T>::value == is_const<U>::value>
{};
#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
// MSVC-7.1 has lots of problems with array types that have been
// deduced. Partially specializing terminal_matches<> on array types
// doesn't seem to work.
template<
typename T
, typename U
, bool B = is_array<BOOST_PROTO_UNCVREF(T)>::value
>
struct terminal_array_matches
: mpl::false_
{};
template<typename T, typename U, std::size_t M>
struct terminal_array_matches<T, U(&)[M], true>
: is_convertible<T, U(&)[M]>
{};
template<typename T, typename U>
struct terminal_array_matches<T, U(&)[proto::N], true>
: is_convertible<T, U *>
{};
template<typename T, typename U>
struct terminal_array_matches<T, U *, true>
: is_convertible<T, U *>
{};
// terminal_matches
template<typename T, typename U>
struct terminal_matches
: mpl::or_<
mpl::and_<
is_cv_ref_compatible<T, U>
, lambda_matches<
BOOST_PROTO_UNCVREF(T)
, BOOST_PROTO_UNCVREF(U)
>
>
, terminal_array_matches<T, U>
>
{};
#else
// terminal_matches
template<typename T, typename U>
struct terminal_matches
: mpl::and_<
is_cv_ref_compatible<T, U>
, lambda_matches<
BOOST_PROTO_UNCVREF(T)
, BOOST_PROTO_UNCVREF(U)
>
>
{};
template<typename T, std::size_t M>
struct terminal_matches<T(&)[M], T(&)[proto::N]>
: mpl::true_
{};
template<typename T, std::size_t M>
struct terminal_matches<T(&)[M], T *>
: mpl::true_
{};
// Avoid ambiguity errors on MSVC
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
template<typename T, std::size_t M>
struct terminal_matches<T const (&)[M], T const[M]>
: mpl::true_
{};
#endif
#endif
template<typename T>
struct terminal_matches<T, T>
: mpl::true_
{};
template<typename T>
struct terminal_matches<T &, T>
: mpl::true_
{};
template<typename T>
struct terminal_matches<T const &, T>
: mpl::true_
{};
template<typename T>
struct terminal_matches<T, proto::_>
: mpl::true_
{};
template<typename T>
struct terminal_matches<T, exact<T> >
: mpl::true_
{};
template<typename T, typename U>
struct terminal_matches<T, proto::convertible_to<U> >
: is_convertible<T, U>
{};
// matches_
template<typename Expr, typename BasicExpr, typename Grammar>
struct matches_
: mpl::false_
{};
template<typename Expr, typename BasicExpr>
struct matches_< Expr, BasicExpr, proto::_ >
: mpl::true_
{};
template<typename Expr, typename Tag, typename Args1, long N1, typename Args2, long N2>
struct matches_< Expr, proto::basic_expr<Tag, Args1, N1>, proto::basic_expr<Tag, Args2, N2> >
: vararg_matches< Expr, Args1, Args2, typename Args2::back_, (N1+2 > N2), (N2 > N1) >
{};
template<typename Expr, typename Tag, typename Args1, long N1, typename Args2, long N2>
struct matches_< Expr, proto::basic_expr<Tag, Args1, N1>, proto::basic_expr<proto::_, Args2, N2> >
: vararg_matches< Expr, Args1, Args2, typename Args2::back_, (N1+2 > N2), (N2 > N1) >
{};
template<typename Expr, typename Tag, typename Args1, typename Args2>
struct matches_< Expr, proto::basic_expr<Tag, Args1, 0>, proto::basic_expr<Tag, Args2, 0> >
: terminal_matches<typename Args1::child0, typename Args2::child0>
{};
template<typename Expr, typename Tag, typename Args1, typename Args2, long N2>
struct matches_< Expr, proto::basic_expr<Tag, Args1, 0>, proto::basic_expr<proto::_, Args2, N2> >
: mpl::false_
{};
template<typename Expr, typename Tag, typename Args1, typename Args2>
struct matches_< Expr, proto::basic_expr<Tag, Args1, 0>, proto::basic_expr<proto::_, Args2, 0> >
: terminal_matches<typename Args1::child0, typename Args2::child0>
{};
template<typename Expr, typename Tag, typename Args1, typename Args2>
struct matches_< Expr, proto::basic_expr<Tag, Args1, 1>, proto::basic_expr<Tag, Args2, 1> >
: matches_<
typename detail::expr_traits<typename Args1::child0>::value_type::proto_derived_expr
, typename detail::expr_traits<typename Args1::child0>::value_type::proto_grammar
, typename Args2::child0::proto_grammar
>
{};
template<typename Expr, typename Tag, typename Args1, typename Args2>
struct matches_< Expr, proto::basic_expr<Tag, Args1, 1>, proto::basic_expr<proto::_, Args2, 1> >
: matches_<
typename detail::expr_traits<typename Args1::child0>::value_type::proto_derived_expr
, typename detail::expr_traits<typename Args1::child0>::value_type::proto_grammar
, typename Args2::child0::proto_grammar
>
{};
#include <boost/proto/detail/and_n.hpp>
#include <boost/proto/detail/or_n.hpp>
#include <boost/proto/detail/matches_.hpp>
#include <boost/proto/detail/vararg_matches_impl.hpp>
#include <boost/proto/detail/lambda_matches.hpp>
// handle proto::if_
template<typename Expr, typename Tag, typename Args, long Arity, typename If, typename Then, typename Else>
struct matches_<Expr, proto::basic_expr<Tag, Args, Arity>, proto::if_<If, Then, Else> >
: mpl::eval_if_c<
static_cast<bool>(
remove_reference<
typename when<_, If>::template impl<Expr, int, int>::result_type
>::type::value
)
, matches_<Expr, proto::basic_expr<Tag, Args, Arity>, typename Then::proto_grammar>
, matches_<Expr, proto::basic_expr<Tag, Args, Arity>, typename Else::proto_grammar>
>::type
{
typedef
typename mpl::if_c<
static_cast<bool>(
remove_reference<
typename when<_, If>::template impl<Expr, int, int>::result_type
>::type::value
)
, Then
, Else
>::type
which;
};
// handle degenerate cases of proto::or_
template<typename Expr, typename BasicExpr>
struct matches_<Expr, BasicExpr, or_<> >
: mpl::false_
{
typedef not_<_> which;
};
template<typename Expr, typename BasicExpr, typename G0>
struct matches_<Expr, BasicExpr, or_<G0> >
: matches_<Expr, BasicExpr, typename G0::proto_grammar>
{
typedef G0 which;
};
// handle degenerate cases of proto::and_
template<typename Expr, typename BasicExpr>
struct matches_<Expr, BasicExpr, and_<> >
: mpl::true_
{};
template<typename Expr, typename BasicExpr, typename G0>
struct matches_<Expr, BasicExpr, and_<G0> >
: matches_<Expr, BasicExpr, typename G0::proto_grammar>
{};
// handle proto::not_
template<typename Expr, typename BasicExpr, typename Grammar>
struct matches_<Expr, BasicExpr, not_<Grammar> >
: mpl::not_<matches_<Expr, BasicExpr, typename Grammar::proto_grammar> >
{};
// handle proto::switch_
template<typename Expr, typename Tag, typename Args, long Arity, typename Cases, typename Transform>
struct matches_<Expr, proto::basic_expr<Tag, Args, Arity>, switch_<Cases, Transform> >
: matches_<
Expr
, proto::basic_expr<Tag, Args, Arity>
, typename Cases::template case_<
typename when<_,Transform>::template impl<Expr,int,int>::result_type
>::proto_grammar
>
{
typedef
typename Cases::template case_<
typename when<_, Transform>::template impl<Expr, int, int>::result_type
>
which;
};
// handle proto::switch_ with the default Transform for specially for better compile times
template<typename Expr, typename Tag, typename Args, long Arity, typename Cases>
struct matches_<Expr, proto::basic_expr<Tag, Args, Arity>, switch_<Cases> >
: matches_<
Expr
, proto::basic_expr<Tag, Args, Arity>
, typename Cases::template case_<Tag>::proto_grammar
>
{
typedef typename Cases::template case_<Tag> which;
};
}
/// \brief A Boolean metafunction that evaluates whether a given
/// expression type matches a grammar.
///
/// <tt>matches\<Expr,Grammar\></tt> inherits (indirectly) from
/// \c mpl::true_ if <tt>Expr::proto_grammar</tt> matches
/// <tt>Grammar::proto_grammar</tt>, and from \c mpl::false_
/// otherwise.
///
/// Non-terminal expressions are matched against a grammar
/// according to the following rules:
///
/// \li The wildcard pattern, \c _, matches any expression.
/// \li An expression <tt>expr\<AT, listN\<A0,A1,...An\> \></tt>
/// matches a grammar <tt>expr\<BT, listN\<B0,B1,...Bn\> \></tt>
/// if \c BT is \c _ or \c AT, and if \c Ax matches \c Bx for
/// each \c x in <tt>[0,n)</tt>.
/// \li An expression <tt>expr\<AT, listN\<A0,...An,U0,...Um\> \></tt>
/// matches a grammar <tt>expr\<BT, listM\<B0,...Bn,vararg\<V\> \> \></tt>
/// if \c BT is \c _ or \c AT, and if \c Ax matches \c Bx
/// for each \c x in <tt>[0,n)</tt> and if \c Ux matches \c V
/// for each \c x in <tt>[0,m)</tt>.
/// \li An expression \c E matches <tt>or_\<B0,B1,...Bn\></tt> if \c E
/// matches some \c Bx for \c x in <tt>[0,n)</tt>.
/// \li An expression \c E matches <tt>and_\<B0,B1,...Bn\></tt> if \c E
/// matches all \c Bx for \c x in <tt>[0,n)</tt>.
/// \li An expression \c E matches <tt>if_\<T,U,V\></tt> if
/// <tt>boost::result_of\<when\<_,T\>(E,int,int)\>::type::value</tt>
/// is \c true and \c E matches \c U; or, if
/// <tt>boost::result_of\<when\<_,T\>(E,int,int)\>::type::value</tt>
/// is \c false and \c E matches \c V. (Note: \c U defaults to \c _
/// and \c V defaults to \c not_\<_\>.)
/// \li An expression \c E matches <tt>not_\<T\></tt> if \c E does
/// not match \c T.
/// \li An expression \c E matches <tt>switch_\<C,T\></tt> if
/// \c E matches <tt>C::case_\<boost::result_of\<T(E)\>::type\></tt>.
/// (Note: T defaults to <tt>tag_of\<_\>()</tt>.)
///
/// A terminal expression <tt>expr\<AT,term\<A\> \></tt> matches
/// a grammar <tt>expr\<BT,term\<B\> \></tt> if \c BT is \c AT or
/// \c proto::_ and if one of the following is true:
///
/// \li \c B is the wildcard pattern, \c _
/// \li \c A is \c B
/// \li \c A is <tt>B &</tt>
/// \li \c A is <tt>B const &</tt>
/// \li \c B is <tt>exact\<A\></tt>
/// \li \c B is <tt>convertible_to\<X\></tt> and
/// <tt>is_convertible\<A,X\>::value</tt> is \c true.
/// \li \c A is <tt>X[M]</tt> or <tt>X(&)[M]</tt> and
/// \c B is <tt>X[proto::N]</tt>.
/// \li \c A is <tt>X(&)[M]</tt> and \c B is <tt>X(&)[proto::N]</tt>.
/// \li \c A is <tt>X[M]</tt> or <tt>X(&)[M]</tt> and
/// \c B is <tt>X*</tt>.
/// \li \c B lambda-matches \c A (see below).
///
/// A type \c B lambda-matches \c A if one of the following is true:
///
/// \li \c B is \c A
/// \li \c B is the wildcard pattern, \c _
/// \li \c B is <tt>T\<B0,B1,...Bn\></tt> and \c A is
/// <tt>T\<A0,A1,...An\></tt> and for each \c x in
/// <tt>[0,n)</tt>, \c Ax and \c Bx are types
/// such that \c Ax lambda-matches \c Bx
template<typename Expr, typename Grammar>
struct matches
: detail::matches_<
typename Expr::proto_derived_expr
, typename Expr::proto_grammar
, typename Grammar::proto_grammar
>
{};
/// INTERNAL ONLY
///
template<typename Expr, typename Grammar>
struct matches<Expr &, Grammar>
: detail::matches_<
typename Expr::proto_derived_expr
, typename Expr::proto_grammar
, typename Grammar::proto_grammar
>
{};
/// \brief A wildcard grammar element that matches any expression,
/// and a transform that returns the current expression unchanged.
///
/// The wildcard type, \c _, is a grammar element such that
/// <tt>matches\<E,_\>::value</tt> is \c true for any expression
/// type \c E.
///
/// The wildcard can also be used as a stand-in for a template
/// argument when matching terminals. For instance, the following
/// is a grammar that will match any <tt>std::complex\<\></tt>
/// terminal:
///
/// \code
/// BOOST_MPL_ASSERT((
/// matches<
/// terminal<std::complex<double> >::type
/// , terminal<std::complex< _ > >
/// >
/// ));
/// \endcode
///
/// When used as a transform, \c _ returns the current expression
/// unchanged. For instance, in the following, \c _ is used with
/// the \c fold\<\> transform to fold the children of a node:
///
/// \code
/// struct CountChildren
/// : or_<
/// // Terminals have no children
/// when<terminal<_>, mpl::int_<0>()>
/// // Use fold<> to count the children of non-terminals
/// , otherwise<
/// fold<
/// _ // <-- fold the current expression
/// , mpl::int_<0>()
/// , mpl::plus<_state, mpl::int_<1> >()
/// >
/// >
/// >
/// {};
/// \endcode
struct _ : transform<_>
{
typedef _ proto_grammar;
template<typename Expr, typename State, typename Data>
struct impl : transform_impl<Expr, State, Data>
{
typedef Expr result_type;
/// \param expr An expression
/// \return \c e
BOOST_PROTO_RETURN_TYPE_STRICT_LOOSE(result_type, typename impl::expr_param)
operator()(
typename impl::expr_param e
, typename impl::state_param
, typename impl::data_param
) const
{
return e;
}
};
};
namespace detail
{
template<typename Expr, typename State, typename Data>
struct _and_impl<proto::and_<>, Expr, State, Data>
: proto::_::impl<Expr, State, Data>
{};
template<typename G0, typename Expr, typename State, typename Data>
struct _and_impl<proto::and_<G0>, Expr, State, Data>
: proto::when<proto::_, G0>::template impl<Expr, State, Data>
{};
}
/// \brief Inverts the set of expressions matched by a grammar. When
/// used as a transform, \c not_\<\> returns the current expression
/// unchanged.
///
/// If an expression type \c E does not match a grammar \c G, then
/// \c E \e does match <tt>not_\<G\></tt>. For example,
/// <tt>not_\<terminal\<_\> \></tt> will match any non-terminal.
template<typename Grammar>
struct not_ : transform<not_<Grammar> >
{
typedef not_ proto_grammar;
template<typename Expr, typename State, typename Data>
struct impl : transform_impl<Expr, State, Data>
{
typedef Expr result_type;
/// \param e An expression
/// \pre <tt>matches\<Expr,not_\>::value</tt> is \c true.
/// \return \c e
BOOST_PROTO_RETURN_TYPE_STRICT_LOOSE(result_type, typename impl::expr_param)
operator()(
typename impl::expr_param e
, typename impl::state_param
, typename impl::data_param
) const
{
return e;
}
};
};
/// \brief Used to select one grammar or another based on the result
/// of a compile-time Boolean. When used as a transform, \c if_\<\>
/// selects between two transforms based on a compile-time Boolean.
///
/// When <tt>if_\<If,Then,Else\></tt> is used as a grammar, \c If
/// must be a Proto transform and \c Then and \c Else must be grammars.
/// An expression type \c E matches <tt>if_\<If,Then,Else\></tt> if
/// <tt>boost::result_of\<when\<_,If\>(E,int,int)\>::type::value</tt>
/// is \c true and \c E matches \c U; or, if
/// <tt>boost::result_of\<when\<_,If\>(E,int,int)\>::type::value</tt>
/// is \c false and \c E matches \c V.
///
/// The template parameter \c Then defaults to \c _
/// and \c Else defaults to \c not\<_\>, so an expression type \c E
/// will match <tt>if_\<If\></tt> if and only if
/// <tt>boost::result_of\<when\<_,If\>(E,int,int)\>::type::value</tt>
/// is \c true.
///
/// \code
/// // A grammar that only matches integral terminals,
/// // using is_integral<> from Boost.Type_traits.
/// struct IsIntegral
/// : and_<
/// terminal<_>
/// , if_< is_integral<_value>() >
/// >
/// {};
/// \endcode
///
/// When <tt>if_\<If,Then,Else\></tt> is used as a transform, \c If,
/// \c Then and \c Else must be Proto transforms. When applying
/// the transform to an expression \c E, state \c S and data \c V,
/// if <tt>boost::result_of\<when\<_,If\>(E,S,V)\>::type::value</tt>
/// is \c true then the \c Then transform is applied; otherwise
/// the \c Else transform is applied.
///
/// \code
/// // Match a terminal. If the terminal is integral, return
/// // mpl::true_; otherwise, return mpl::false_.
/// struct IsIntegral2
/// : when<
/// terminal<_>
/// , if_<
/// is_integral<_value>()
/// , mpl::true_()
/// , mpl::false_()
/// >
/// >
/// {};
/// \endcode
template<
typename If
, typename Then // = _
, typename Else // = not_<_>
>
struct if_ : transform<if_<If, Then, Else> >
{
typedef if_ proto_grammar;
template<typename Expr, typename State, typename Data>
struct impl : transform_impl<Expr, State, Data>
{
typedef
typename when<_, If>::template impl<Expr, State, Data>::result_type
condition;
typedef
typename mpl::if_c<
static_cast<bool>(remove_reference<condition>::type::value)
, when<_, Then>
, when<_, Else>
>::type
which;
typedef typename which::template impl<Expr, State, Data>::result_type result_type;
/// \param e An expression
/// \param s The current state
/// \param d A data of arbitrary type
/// \return <tt>which::impl<Expr, State, Data>()(e, s, d)</tt>
result_type operator ()(
typename impl::expr_param e
, typename impl::state_param s
, typename impl::data_param d
) const
{
return typename which::template impl<Expr, State, Data>()(e, s, d);
}
};
};
/// \brief For matching one of a set of alternate grammars. Alternates
/// tried in order to avoid ambiguity. When used as a transform, \c or_\<\>
/// applies the transform associated with the first grammar that matches
/// the expression.
///
/// An expression type \c E matches <tt>or_\<B0,B1,...Bn\></tt> if \c E
/// matches any \c Bx for \c x in <tt>[0,n)</tt>.
///
/// When applying <tt>or_\<B0,B1,...Bn\></tt> as a transform with an
/// expression \c e of type \c E, state \c s and data \c d, it is
/// equivalent to <tt>Bx()(e, s, d)</tt>, where \c x is the lowest
/// number such that <tt>matches\<E,Bx\>::value</tt> is \c true.
template<BOOST_PROTO_LOGICAL_typename_G>
struct or_ : transform<or_<BOOST_PROTO_LOGICAL_G> >
{
typedef or_ proto_grammar;
/// \param e An expression
/// \param s The current state
/// \param d A data of arbitrary type
/// \pre <tt>matches\<Expr,or_\>::value</tt> is \c true.
/// \return <tt>which()(e, s, d)</tt>, where <tt>which</tt> is the
/// sub-grammar that matched <tt>Expr</tt>.
template<typename Expr, typename State, typename Data>
struct impl
: detail::matches_<
typename Expr::proto_derived_expr
, typename Expr::proto_grammar
, or_
>::which::template impl<Expr, State, Data>
{};
template<typename Expr, typename State, typename Data>
struct impl<Expr &, State, Data>
: detail::matches_<
typename Expr::proto_derived_expr
, typename Expr::proto_grammar
, or_
>::which::template impl<Expr &, State, Data>
{};
};
/// \brief For matching all of a set of grammars. When used as a
/// transform, \c and_\<\> applies the transforms associated with
/// the each grammar in the set, and returns the result of the last.
///
/// An expression type \c E matches <tt>and_\<B0,B1,...Bn\></tt> if \c E
/// matches all \c Bx for \c x in <tt>[0,n)</tt>.
///
/// When applying <tt>and_\<B0,B1,...Bn\></tt> as a transform with an
/// expression \c e, state \c s and data \c d, it is
/// equivalent to <tt>(B0()(e, s, d),B1()(e, s, d),...Bn()(e, s, d))</tt>.
template<BOOST_PROTO_LOGICAL_typename_G>
struct and_ : transform<and_<BOOST_PROTO_LOGICAL_G> >
{
typedef and_ proto_grammar;
template<typename Expr, typename State, typename Data>
struct impl
: detail::_and_impl<and_, Expr, State, Data>
{};
};
/// \brief For matching one of a set of alternate grammars, which
/// are looked up based on some property of an expression. The
/// property on which to dispatch is specified by the \c Transform
/// template parameter, which defaults to <tt>tag_of\<_\>()</tt>.
/// That is, when the \c Trannsform is not specified, the alternate
/// grammar is looked up using the tag type of the current expression.
///
/// When used as a transform, \c switch_\<\> applies the transform
/// associated with the grammar that matches the expression.
///
/// \note \c switch_\<\> is functionally identical to \c or_\<\> but
/// is often more efficient. It does a fast, O(1) lookup using the
/// result of the specified transform to find a sub-grammar that may
/// potentially match the expression.
///
/// An expression type \c E matches <tt>switch_\<C,T\></tt> if \c E
/// matches <tt>C::case_\<boost::result_of\<T(E)\>::type\></tt>.
///
/// When applying <tt>switch_\<C,T\></tt> as a transform with an
/// expression \c e of type \c E, state \c s of type \S and data
/// \c d of type \c D, it is equivalent to
/// <tt>C::case_\<boost::result_of\<T(E,S,D)\>::type\>()(e, s, d)</tt>.
template<typename Cases, typename Transform>
struct switch_ : transform<switch_<Cases, Transform> >
{
typedef switch_ proto_grammar;
template<typename Expr, typename State, typename Data>
struct impl
: Cases::template case_<
typename when<_, Transform>::template impl<Expr, State, Data>::result_type
>::template impl<Expr, State, Data>
{};
};
/// INTERNAL ONLY (This is merely a compile-time optimization for the common case)
///
template<typename Cases>
struct switch_<Cases> : transform<switch_<Cases> >
{
typedef switch_ proto_grammar;
template<typename Expr, typename State, typename Data>
struct impl
: Cases::template case_<typename Expr::proto_tag>::template impl<Expr, State, Data>
{};
template<typename Expr, typename State, typename Data>
struct impl<Expr &, State, Data>
: Cases::template case_<typename Expr::proto_tag>::template impl<Expr &, State, Data>
{};
};
/// \brief For forcing exact matches of terminal types.
///
/// By default, matching terminals ignores references and
/// cv-qualifiers. For instance, a terminal expression of
/// type <tt>terminal\<int const &\>::type</tt> will match
/// the grammar <tt>terminal\<int\></tt>. If that is not
/// desired, you can force an exact match with
/// <tt>terminal\<exact\<int\> \></tt>. This will only
/// match integer terminals where the terminal is held by
/// value.
template<typename T>
struct exact
{};
/// \brief For matching terminals that are convertible to
/// a type.
///
/// Use \c convertible_to\<\> to match a terminal that is
/// convertible to some type. For example, the grammar
/// <tt>terminal\<convertible_to\<int\> \></tt> will match
/// any terminal whose argument is convertible to an integer.
///
/// \note The trait \c is_convertible\<\> from Boost.Type_traits
/// is used to determinal convertibility.
template<typename T>
struct convertible_to
{};
/// \brief For matching a Grammar to a variable number of
/// sub-expressions.
///
/// An expression type <tt>expr\<AT, listN\<A0,...An,U0,...Um\> \></tt>
/// matches a grammar <tt>expr\<BT, listM\<B0,...Bn,vararg\<V\> \> \></tt>
/// if \c BT is \c _ or \c AT, and if \c Ax matches \c Bx
/// for each \c x in <tt>[0,n)</tt> and if \c Ux matches \c V
/// for each \c x in <tt>[0,m)</tt>.
///
/// For example:
///
/// \code
/// // Match any function call expression, irregardless
/// // of the number of function arguments:
/// struct Function
/// : function< vararg<_> >
/// {};
/// \endcode
///
/// When used as a transform, <tt>vararg\<G\></tt> applies
/// <tt>G</tt>'s transform.
template<typename Grammar>
struct vararg
: Grammar
{
/// INTERNAL ONLY
typedef void proto_is_vararg_;
};
/// INTERNAL ONLY
///
template<BOOST_PROTO_LOGICAL_typename_G>
struct is_callable<or_<BOOST_PROTO_LOGICAL_G> >
: mpl::true_
{};
/// INTERNAL ONLY
///
template<BOOST_PROTO_LOGICAL_typename_G>
struct is_callable<and_<BOOST_PROTO_LOGICAL_G> >
: mpl::true_
{};
/// INTERNAL ONLY
///
template<typename Grammar>
struct is_callable<not_<Grammar> >
: mpl::true_
{};
/// INTERNAL ONLY
///
template<typename If, typename Then, typename Else>
struct is_callable<if_<If, Then, Else> >
: mpl::true_
{};
/// INTERNAL ONLY
///
template<typename Grammar>
struct is_callable<vararg<Grammar> >
: mpl::true_
{};
/// INTERNAL ONLY
///
template<typename Cases, typename Transform>
struct is_callable<switch_<Cases, Transform> >
: mpl::true_
{};
}}
#undef BOOST_PROTO_LOGICAL_typename_G
#undef BOOST_PROTO_LOGICAL_G
#if defined(_MSC_VER)
# pragma warning(pop)
#endif
#endif
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

@@ -0,0 +1,637 @@
///////////////////////////////////////////////////////////////////////////////
/// \file when.hpp
/// Definition of when transform.
//
// Copyright 2008 Eric Niebler. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
template<typename Grammar, typename R >
struct when<Grammar, R()>
: detail::when_impl<Grammar, R, R()>
{};
template<typename Grammar, typename R , typename A0>
struct when<Grammar, R(A0)>
: detail::when_impl<Grammar, R, R(A0)>
{};
template<typename Grammar, typename R , typename A0>
struct when<Grammar, R(A0...)>
: detail::when_impl<Grammar, R, R(A0...)>
{};
template<typename Grammar, typename R , typename A0 , typename A1>
struct when<Grammar, R(A0 , A1)>
: detail::when_impl<Grammar, R, R(A0 , A1)>
{};
template<typename Grammar, typename R , typename A0 , typename A1>
struct when<Grammar, R(A0 , A1...)>
: detail::when_impl<Grammar, R, R(A0 , A1...)>
{};
template<typename Grammar, typename R , typename A0 , typename A1 , typename A2>
struct when<Grammar, R(A0 , A1 , A2)>
: detail::when_impl<Grammar, R, R(A0 , A1 , A2)>
{};
template<typename Grammar, typename R , typename A0 , typename A1 , typename A2>
struct when<Grammar, R(A0 , A1 , A2...)>
: detail::when_impl<Grammar, R, R(A0 , A1 , A2...)>
{};
template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3>
struct when<Grammar, R(A0 , A1 , A2 , A3)>
: detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3)>
{};
template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3>
struct when<Grammar, R(A0 , A1 , A2 , A3...)>
: detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3...)>
{};
template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3 , typename A4>
struct when<Grammar, R(A0 , A1 , A2 , A3 , A4)>
: detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3 , A4)>
{};
template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3 , typename A4>
struct when<Grammar, R(A0 , A1 , A2 , A3 , A4...)>
: detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3 , A4...)>
{};
template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5>
struct when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5)>
: detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3 , A4 , A5)>
{};
template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5>
struct when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5...)>
: detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3 , A4 , A5...)>
{};
template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6>
struct when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5 , A6)>
: detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3 , A4 , A5 , A6)>
{};
template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6>
struct when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5 , A6...)>
: detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3 , A4 , A5 , A6...)>
{};
template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7>
struct when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7)>
: detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7)>
{};
template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7>
struct when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7...)>
: detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7...)>
{};
template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8>
struct when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8)>
: detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8)>
{};
template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8>
struct when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8...)>
: detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8...)>
{};
template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8 , typename A9>
struct when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9)>
: detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9)>
{};
template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8 , typename A9>
struct when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9...)>
: detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9...)>
{};
@@ -0,0 +1,32 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#ifndef BOOST_FT_IS_MEMBER_POINTER_HPP_INCLUDED
#define BOOST_FT_IS_MEMBER_POINTER_HPP_INCLUDED
#include <boost/mpl/aux_/lambda_support.hpp>
#include <boost/function_types/components.hpp>
namespace boost
{
namespace function_types
{
template< typename T, typename Tag = null_tag >
struct is_member_pointer
: function_types::represents
< function_types::components<T>
, function_types::tag<Tag ,detail::member_pointer_tag>
>
{
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,is_member_pointer,(T,Tag))
};
}
}
#endif
@@ -0,0 +1,98 @@
// Copyright Aleksey Gurtovoy 2000-2004
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Preprocessed version of "boost/mpl/not_equal_to.hpp" header
// -- DO NOT modify by hand!
namespace boost { namespace mpl {
template<
typename Tag1
, typename Tag2
>
struct not_equal_to_impl
: if_c<
( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1)
> BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2)
)
, aux::cast2nd_impl< not_equal_to_impl< Tag1,Tag1 >,Tag1, Tag2 >
, aux::cast1st_impl< not_equal_to_impl< Tag2,Tag2 >,Tag1, Tag2 >
>::type
{
};
/// for Digital Mars C++/compilers with no CTPS/TTP support
template<> struct not_equal_to_impl< na,na >
{
template< typename U1, typename U2 > struct apply
{
typedef apply type;
BOOST_STATIC_CONSTANT(int, value = 0);
};
};
template< typename Tag > struct not_equal_to_impl< na,Tag >
{
template< typename U1, typename U2 > struct apply
{
typedef apply type;
BOOST_STATIC_CONSTANT(int, value = 0);
};
};
template< typename Tag > struct not_equal_to_impl< Tag,na >
{
template< typename U1, typename U2 > struct apply
{
typedef apply type;
BOOST_STATIC_CONSTANT(int, value = 0);
};
};
template< typename T > struct not_equal_to_tag
{
typedef typename T::tag type;
};
template<
typename BOOST_MPL_AUX_NA_PARAM(N1)
, typename BOOST_MPL_AUX_NA_PARAM(N2)
>
struct not_equal_to
: not_equal_to_impl<
typename not_equal_to_tag<N1>::type
, typename not_equal_to_tag<N2>::type
>::template apply< N1,N2 >::type
{
BOOST_MPL_AUX_LAMBDA_SUPPORT(2, not_equal_to, (N1, N2))
};
BOOST_MPL_AUX_NA_SPEC2(2, 2, not_equal_to)
}}
namespace boost { namespace mpl {
template<>
struct not_equal_to_impl< integral_c_tag,integral_c_tag >
{
template< typename N1, typename N2 > struct apply
{
BOOST_STATIC_CONSTANT(bool, value =
( BOOST_MPL_AUX_VALUE_WKND(N1)::value !=
BOOST_MPL_AUX_VALUE_WKND(N2)::value )
);
typedef bool_<value> type;
};
};
}}
@@ -0,0 +1,307 @@
/* boost random/uniform_smallint.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the 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.
*
* $Id$
*
* Revision history
* 2001-04-08 added min<max assertion (N. Becker)
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_UNIFORM_SMALLINT_HPP
#define BOOST_RANDOM_UNIFORM_SMALLINT_HPP
#include <istream>
#include <iosfwd>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/detail/signed_unsigned_tools.hpp>
#include <boost/random/uniform_01.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/mpl/bool.hpp>
#ifdef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
#include <boost/mpl/if.hpp>
#endif
namespace boost {
namespace random {
// uniform integer distribution on a small range [min, max]
/**
* The distribution function uniform_smallint models a \random_distribution.
* On each invocation, it returns a random integer value uniformly distributed
* in the set of integer numbers {min, min+1, min+2, ..., max}. It assumes
* that the desired range (max-min+1) is small compared to the range of the
* underlying source of random numbers and thus makes no attempt to limit
* quantization errors.
*
* Let \f$r_{\mathtt{out}} = (\mbox{max}-\mbox{min}+1)\f$ the desired range of
* integer numbers, and
* let \f$r_{\mathtt{base}}\f$ be the range of the underlying source of random
* numbers. Then, for the uniform distribution, the theoretical probability
* for any number i in the range \f$r_{\mathtt{out}}\f$ will be
* \f$\displaystyle p_{\mathtt{out}}(i) = \frac{1}{r_{\mathtt{out}}}\f$.
* Likewise, assume a uniform distribution on \f$r_{\mathtt{base}}\f$ for
* the underlying source of random numbers, i.e.
* \f$\displaystyle p_{\mathtt{base}}(i) = \frac{1}{r_{\mathtt{base}}}\f$.
* Let \f$p_{\mathtt{out\_s}}(i)\f$ denote the random
* distribution generated by @c uniform_smallint. Then the sum over all
* i in \f$r_{\mathtt{out}}\f$ of
* \f$\displaystyle
* \left(\frac{p_{\mathtt{out\_s}}(i)}{p_{\mathtt{out}}(i)} - 1\right)^2\f$
* shall not exceed
* \f$\displaystyle \frac{r_{\mathtt{out}}}{r_{\mathtt{base}}^2}
* (r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}})
* (r_{\mathtt{out}} - r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}})\f$.
*
* The template parameter IntType shall denote an integer-like value type.
*
* @xmlnote
* The property above is the square sum of the relative differences
* in probabilities between the desired uniform distribution
* \f$p_{\mathtt{out}}(i)\f$ and the generated distribution
* \f$p_{\mathtt{out\_s}}(i)\f$.
* The property can be fulfilled with the calculation
* \f$(\mbox{base\_rng} \mbox{ mod } r_{\mathtt{out}})\f$, as follows:
* Let \f$r = r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}}\f$.
* The base distribution on \f$r_{\mathtt{base}}\f$ is folded onto the
* range \f$r_{\mathtt{out}}\f$. The numbers i < r have assigned
* \f$\displaystyle
* \left\lfloor\frac{r_{\mathtt{base}}}{r_{\mathtt{out}}}\right\rfloor+1\f$
* numbers of the base distribution, the rest has only \f$\displaystyle
* \left\lfloor\frac{r_{\mathtt{base}}}{r_{\mathtt{out}}}\right\rfloor\f$.
* Therefore,
* \f$\displaystyle p_{\mathtt{out\_s}}(i) =
* \left(\left\lfloor\frac{r_{\mathtt{base}}}
* {r_{\mathtt{out}}}\right\rfloor+1\right) /
* r_{\mathtt{base}}\f$ for i < r and \f$\displaystyle p_{\mathtt{out\_s}}(i) =
* \left\lfloor\frac{r_{\mathtt{base}}}
* {r_{\mathtt{out}}}\right\rfloor/r_{\mathtt{base}}\f$ otherwise.
* Substituting this in the
* above sum formula leads to the desired result.
* @endxmlnote
*
* Note: The upper bound for
* \f$(r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}})
* (r_{\mathtt{out}} - r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}})\f$ is
* \f$\displaystyle \frac{r_{\mathtt{out}}^2}{4}\f$. Regarding the upper bound
* for the square sum of the relative quantization error of
* \f$\displaystyle \frac{r_\mathtt{out}^3}{4r_{\mathtt{base}}^2}\f$, it
* seems wise to either choose \f$r_{\mathtt{base}}\f$ so that
* \f$r_{\mathtt{base}} > 10r_{\mathtt{out}}^2\f$ or ensure that
* \f$r_{\mathtt{base}}\f$ is
* divisible by \f$r_{\mathtt{out}}\f$.
*/
template<class IntType = int>
class uniform_smallint
{
public:
typedef IntType input_type;
typedef IntType result_type;
class param_type
{
public:
typedef uniform_smallint distribution_type;
/** constructs the parameters of a @c uniform_smallint distribution. */
param_type(IntType min_arg = 0, IntType max_arg = 9)
: _min(min_arg), _max(max_arg)
{
BOOST_ASSERT(_min <= _max);
}
/** Returns the minimum value. */
IntType a() const { return _min; }
/** Returns the maximum value. */
IntType b() const { return _max; }
/** Writes the parameters to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
{
os << parm._min << " " << parm._max;
return os;
}
/** Reads the parameters from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{
is >> parm._min >> std::ws >> parm._max;
return is;
}
/** Returns true if the two sets of parameters are equal. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{ return lhs._min == rhs._min && lhs._max == rhs._max; }
/** Returns true if the two sets of parameters are different. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
IntType _min;
IntType _max;
};
/**
* Constructs a @c uniform_smallint. @c min and @c max are the
* lower and upper bounds of the output range, respectively.
*/
explicit uniform_smallint(IntType min_arg = 0, IntType max_arg = 9)
: _min(min_arg), _max(max_arg) {}
/**
* Constructs a @c uniform_smallint from its parameters.
*/
explicit uniform_smallint(const param_type& parm)
: _min(parm.a()), _max(parm.b()) {}
/** Returns the minimum value of the distribution. */
result_type a() const { return _min; }
/** Returns the maximum value of the distribution. */
result_type b() const { return _max; }
/** Returns the minimum value of the distribution. */
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
/** Returns the maximum value of the distribution. */
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
/** Returns the parameters of the distribution. */
param_type param() const { return param_type(_min, _max); }
/** Sets the parameters of the distribution. */
void param(const param_type& parm)
{
_min = parm.a();
_max = parm.b();
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() { }
/** Returns a value uniformly distributed in the range [min(), max()]. */
template<class Engine>
result_type operator()(Engine& eng) const
{
typedef typename Engine::result_type base_result;
return generate(eng, boost::random::traits::is_integral<base_result>());
}
/** Returns a value uniformly distributed in the range [param.a(), param.b()]. */
template<class Engine>
result_type operator()(Engine& eng, const param_type& parm) const
{ return uniform_smallint(parm)(eng); }
/** Writes the distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, uniform_smallint, ud)
{
os << ud._min << " " << ud._max;
return os;
}
/** Reads the distribution from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, uniform_smallint, ud)
{
is >> ud._min >> std::ws >> ud._max;
return is;
}
/**
* Returns true if the two distributions will produce identical
* sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(uniform_smallint, lhs, rhs)
{ return lhs._min == rhs._min && lhs._max == rhs._max; }
/**
* Returns true if the two distributions may produce different
* sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(uniform_smallint)
private:
// \cond show_private
template<class Engine>
result_type generate(Engine& eng, boost::mpl::true_) const
{
// equivalent to (eng() - eng.min()) % (_max - _min + 1) + _min,
// but guarantees no overflow.
typedef typename Engine::result_type base_result;
typedef typename boost::random::traits::make_unsigned<base_result>::type base_unsigned;
typedef typename boost::random::traits::make_unsigned_or_unbounded<result_type>::type range_type;
#ifdef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
typedef typename mpl::if_c<
std::numeric_limits<range_type>::is_specialized && std::numeric_limits<base_unsigned>::is_specialized
&& (std::numeric_limits<range_type>::digits >= std::numeric_limits<base_unsigned>::digits),
range_type, base_unsigned>::type mixed_range_type;
#else
typedef base_unsigned mixed_range_type;
#endif
range_type range = random::detail::subtract<result_type>()(_max, _min);
base_unsigned base_range =
random::detail::subtract<base_result>()((eng.max)(), (eng.min)());
base_unsigned val =
random::detail::subtract<base_result>()(eng(), (eng.min)());
if(range >= base_range) {
return boost::random::detail::add<range_type, result_type>()(
static_cast<range_type>(val), _min);
} else {
// This involves mixed arithmetic between the base generators range
// type, and the result_type's range type. mixed_range_type is
// normally the same as base_unsigned which is the most efficient
// option, but requires a narrowing explcit cast if result_type
// is a multiprecision type. If no such casts are available then use
// multiprecision arithmetic throughout instead.
mixed_range_type modulus = static_cast<mixed_range_type>(range)+1;
return boost::random::detail::add<range_type, result_type>()(
static_cast<mixed_range_type>(val) % modulus, _min);
}
}
template<class Engine>
result_type generate(Engine& eng, boost::mpl::false_) const
{
typedef typename Engine::result_type base_result;
typedef typename boost::random::traits::make_unsigned<result_type>::type range_type;
range_type range = random::detail::subtract<result_type>()(_max, _min);
base_result val = boost::uniform_01<base_result>()(eng);
// what is the worst that can possibly happen here?
// base_result may not be able to represent all the values in [0, range]
// exactly. If this happens, it will cause round off error and we
// won't be able to produce all the values in the range. We don't
// care about this because the user has already told us not to by
// using uniform_smallint. However, we do need to be careful
// to clamp the result, or floating point rounding can produce
// an out of range result.
range_type offset = static_cast<range_type>(val * (static_cast<base_result>(range) + 1));
if(offset > range) return _max;
return boost::random::detail::add<range_type, result_type>()(offset , _min);
}
// \endcond
result_type _min;
result_type _max;
};
} // namespace random
using random::uniform_smallint;
} // namespace boost
#endif // BOOST_RANDOM_UNIFORM_SMALLINT_HPP
@@ -0,0 +1,350 @@
//
// 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 _BOOST_UBLAS_LU_
#define _BOOST_UBLAS_LU_
#include <boost/numeric/ublas/operation.hpp>
#include <boost/numeric/ublas/vector_proxy.hpp>
#include <boost/numeric/ublas/matrix_proxy.hpp>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/triangular.hpp>
// LU factorizations in the spirit of LAPACK and Golub & van Loan
namespace boost { namespace numeric { namespace ublas {
/** \brief
*
* \tparam T
* \tparam A
*/
template<class T = std::size_t, class A = unbounded_array<T> >
class permutation_matrix:
public vector<T, A> {
public:
typedef vector<T, A> vector_type;
typedef typename vector_type::size_type size_type;
// Construction and destruction
BOOST_UBLAS_INLINE
explicit
permutation_matrix (size_type size):
vector<T, A> (size) {
for (size_type i = 0; i < size; ++ i)
(*this) (i) = i;
}
BOOST_UBLAS_INLINE
explicit
permutation_matrix (const vector_type & init)
: vector_type(init)
{ }
BOOST_UBLAS_INLINE
~permutation_matrix () {}
// Assignment
BOOST_UBLAS_INLINE
permutation_matrix &operator = (const permutation_matrix &m) {
vector_type::operator = (m);
return *this;
}
};
template<class PM, class MV>
BOOST_UBLAS_INLINE
void swap_rows (const PM &pm, MV &mv, vector_tag) {
typedef typename PM::size_type size_type;
size_type size = pm.size ();
for (size_type i = 0; i < size; ++ i) {
if (i != pm (i))
std::swap (mv (i), mv (pm (i)));
}
}
template<class PM, class MV>
BOOST_UBLAS_INLINE
void swap_rows (const PM &pm, MV &mv, matrix_tag) {
typedef typename PM::size_type size_type;
size_type size = pm.size ();
for (size_type i = 0; i < size; ++ i) {
if (i != pm (i))
row (mv, i).swap (row (mv, pm (i)));
}
}
// Dispatcher
template<class PM, class MV>
BOOST_UBLAS_INLINE
void swap_rows (const PM &pm, MV &mv) {
swap_rows (pm, mv, typename MV::type_category ());
}
// LU factorization without pivoting
template<class M>
typename M::size_type lu_factorize (M &m) {
typedef typename M::size_type size_type;
typedef typename M::value_type value_type;
#if BOOST_UBLAS_TYPE_CHECK
typedef M matrix_type;
matrix_type cm (m);
#endif
size_type singular = 0;
size_type size1 = m.size1 ();
size_type size2 = m.size2 ();
size_type size = (std::min) (size1, size2);
for (size_type i = 0; i < size; ++ i) {
matrix_column<M> mci (column (m, i));
matrix_row<M> mri (row (m, i));
if (m (i, i) != value_type/*zero*/()) {
value_type m_inv = value_type (1) / m (i, i);
project (mci, range (i + 1, size1)) *= m_inv;
} else if (singular == 0) {
singular = i + 1;
}
project (m, range (i + 1, size1), range (i + 1, size2)).minus_assign (
outer_prod (project (mci, range (i + 1, size1)),
project (mri, range (i + 1, size2))));
}
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (singular != 0 ||
detail::expression_type_check (prod (triangular_adaptor<matrix_type, unit_lower> (m),
triangular_adaptor<matrix_type, upper> (m)),
cm), internal_logic ());
#endif
return singular;
}
// LU factorization with partial pivoting
template<class M, class PM>
typename M::size_type lu_factorize (M &m, PM &pm) {
typedef typename M::size_type size_type;
typedef typename M::value_type value_type;
#if BOOST_UBLAS_TYPE_CHECK
typedef M matrix_type;
matrix_type cm (m);
#endif
size_type singular = 0;
size_type size1 = m.size1 ();
size_type size2 = m.size2 ();
size_type size = (std::min) (size1, size2);
for (size_type i = 0; i < size; ++ i) {
matrix_column<M> mci (column (m, i));
matrix_row<M> mri (row (m, i));
size_type i_norm_inf = i + index_norm_inf (project (mci, range (i, size1)));
BOOST_UBLAS_CHECK (i_norm_inf < size1, external_logic ());
if (m (i_norm_inf, i) != value_type/*zero*/()) {
if (i_norm_inf != i) {
pm (i) = i_norm_inf;
row (m, i_norm_inf).swap (mri);
} else {
BOOST_UBLAS_CHECK (pm (i) == i_norm_inf, external_logic ());
}
value_type m_inv = value_type (1) / m (i, i);
project (mci, range (i + 1, size1)) *= m_inv;
} else if (singular == 0) {
singular = i + 1;
}
project (m, range (i + 1, size1), range (i + 1, size2)).minus_assign (
outer_prod (project (mci, range (i + 1, size1)),
project (mri, range (i + 1, size2))));
}
#if BOOST_UBLAS_TYPE_CHECK
swap_rows (pm, cm);
BOOST_UBLAS_CHECK (singular != 0 ||
detail::expression_type_check (prod (triangular_adaptor<matrix_type, unit_lower> (m),
triangular_adaptor<matrix_type, upper> (m)), cm), internal_logic ());
#endif
return singular;
}
template<class M, class PM>
typename M::size_type axpy_lu_factorize (M &m, PM &pm) {
typedef M matrix_type;
typedef typename M::size_type size_type;
typedef typename M::value_type value_type;
typedef vector<value_type> vector_type;
#if BOOST_UBLAS_TYPE_CHECK
matrix_type cm (m);
#endif
size_type singular = 0;
size_type size1 = m.size1 ();
size_type size2 = m.size2 ();
size_type size = (std::min) (size1, size2);
#ifndef BOOST_UBLAS_LU_WITH_INPLACE_SOLVE
matrix_type mr (m);
mr.assign (zero_matrix<value_type> (size1, size2));
vector_type v (size1);
for (size_type i = 0; i < size; ++ i) {
matrix_range<matrix_type> lrr (project (mr, range (0, i), range (0, i)));
vector_range<matrix_column<matrix_type> > urr (project (column (mr, i), range (0, i)));
urr.assign (solve (lrr, project (column (m, i), range (0, i)), unit_lower_tag ()));
project (v, range (i, size1)).assign (
project (column (m, i), range (i, size1)) -
axpy_prod<vector_type> (project (mr, range (i, size1), range (0, i)), urr));
size_type i_norm_inf = i + index_norm_inf (project (v, range (i, size1)));
BOOST_UBLAS_CHECK (i_norm_inf < size1, external_logic ());
if (v (i_norm_inf) != value_type/*zero*/()) {
if (i_norm_inf != i) {
pm (i) = i_norm_inf;
std::swap (v (i_norm_inf), v (i));
project (row (m, i_norm_inf), range (i + 1, size2)).swap (project (row (m, i), range (i + 1, size2)));
} else {
BOOST_UBLAS_CHECK (pm (i) == i_norm_inf, external_logic ());
}
project (column (mr, i), range (i + 1, size1)).assign (
project (v, range (i + 1, size1)) / v (i));
if (i_norm_inf != i) {
project (row (mr, i_norm_inf), range (0, i)).swap (project (row (mr, i), range (0, i)));
}
} else if (singular == 0) {
singular = i + 1;
}
mr (i, i) = v (i);
}
m.assign (mr);
#else
matrix_type lr (m);
matrix_type ur (m);
lr.assign (identity_matrix<value_type> (size1, size2));
ur.assign (zero_matrix<value_type> (size1, size2));
vector_type v (size1);
for (size_type i = 0; i < size; ++ i) {
matrix_range<matrix_type> lrr (project (lr, range (0, i), range (0, i)));
vector_range<matrix_column<matrix_type> > urr (project (column (ur, i), range (0, i)));
urr.assign (project (column (m, i), range (0, i)));
inplace_solve (lrr, urr, unit_lower_tag ());
project (v, range (i, size1)).assign (
project (column (m, i), range (i, size1)) -
axpy_prod<vector_type> (project (lr, range (i, size1), range (0, i)), urr));
size_type i_norm_inf = i + index_norm_inf (project (v, range (i, size1)));
BOOST_UBLAS_CHECK (i_norm_inf < size1, external_logic ());
if (v (i_norm_inf) != value_type/*zero*/()) {
if (i_norm_inf != i) {
pm (i) = i_norm_inf;
std::swap (v (i_norm_inf), v (i));
project (row (m, i_norm_inf), range (i + 1, size2)).swap (project (row (m, i), range (i + 1, size2)));
} else {
BOOST_UBLAS_CHECK (pm (i) == i_norm_inf, external_logic ());
}
project (column (lr, i), range (i + 1, size1)).assign (
project (v, range (i + 1, size1)) / v (i));
if (i_norm_inf != i) {
project (row (lr, i_norm_inf), range (0, i)).swap (project (row (lr, i), range (0, i)));
}
} else if (singular == 0) {
singular = i + 1;
}
ur (i, i) = v (i);
}
m.assign (triangular_adaptor<matrix_type, strict_lower> (lr) +
triangular_adaptor<matrix_type, upper> (ur));
#endif
#if BOOST_UBLAS_TYPE_CHECK
swap_rows (pm, cm);
BOOST_UBLAS_CHECK (singular != 0 ||
detail::expression_type_check (prod (triangular_adaptor<matrix_type, unit_lower> (m),
triangular_adaptor<matrix_type, upper> (m)), cm), internal_logic ());
#endif
return singular;
}
// LU substitution
template<class M, class E>
void lu_substitute (const M &m, vector_expression<E> &e) {
#if BOOST_UBLAS_TYPE_CHECK
typedef const M const_matrix_type;
typedef vector<typename E::value_type> vector_type;
vector_type cv1 (e);
#endif
inplace_solve (m, e, unit_lower_tag ());
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (detail::expression_type_check (prod (triangular_adaptor<const_matrix_type, unit_lower> (m), e), cv1), internal_logic ());
vector_type cv2 (e);
#endif
inplace_solve (m, e, upper_tag ());
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (detail::expression_type_check (prod (triangular_adaptor<const_matrix_type, upper> (m), e), cv2), internal_logic ());
#endif
}
template<class M, class E>
void lu_substitute (const M &m, matrix_expression<E> &e) {
#if BOOST_UBLAS_TYPE_CHECK
typedef const M const_matrix_type;
typedef matrix<typename E::value_type> matrix_type;
matrix_type cm1 (e);
#endif
inplace_solve (m, e, unit_lower_tag ());
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (detail::expression_type_check (prod (triangular_adaptor<const_matrix_type, unit_lower> (m), e), cm1), internal_logic ());
matrix_type cm2 (e);
#endif
inplace_solve (m, e, upper_tag ());
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (detail::expression_type_check (prod (triangular_adaptor<const_matrix_type, upper> (m), e), cm2), internal_logic ());
#endif
}
template<class M, class PMT, class PMA, class MV>
void lu_substitute (const M &m, const permutation_matrix<PMT, PMA> &pm, MV &mv) {
swap_rows (pm, mv);
lu_substitute (m, mv);
}
template<class E, class M>
void lu_substitute (vector_expression<E> &e, const M &m) {
#if BOOST_UBLAS_TYPE_CHECK
typedef const M const_matrix_type;
typedef vector<typename E::value_type> vector_type;
vector_type cv1 (e);
#endif
inplace_solve (e, m, upper_tag ());
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (detail::expression_type_check (prod (e, triangular_adaptor<const_matrix_type, upper> (m)), cv1), internal_logic ());
vector_type cv2 (e);
#endif
inplace_solve (e, m, unit_lower_tag ());
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (detail::expression_type_check (prod (e, triangular_adaptor<const_matrix_type, unit_lower> (m)), cv2), internal_logic ());
#endif
}
template<class E, class M>
void lu_substitute (matrix_expression<E> &e, const M &m) {
#if BOOST_UBLAS_TYPE_CHECK
typedef const M const_matrix_type;
typedef matrix<typename E::value_type> matrix_type;
matrix_type cm1 (e);
#endif
inplace_solve (e, m, upper_tag ());
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (detail::expression_type_check (prod (e, triangular_adaptor<const_matrix_type, upper> (m)), cm1), internal_logic ());
matrix_type cm2 (e);
#endif
inplace_solve (e, m, unit_lower_tag ());
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (detail::expression_type_check (prod (e, triangular_adaptor<const_matrix_type, unit_lower> (m)), cm2), internal_logic ());
#endif
}
template<class MV, class M, class PMT, class PMA>
void lu_substitute (MV &mv, const M &m, const permutation_matrix<PMT, PMA> &pm) {
swap_rows (pm, mv);
lu_substitute (mv, m);
}
}}}
#endif
Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

@@ -0,0 +1,17 @@
/*==============================================================================
Copyright (c) 2010 Thomas Heller
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#undef BOOST_PHOENIX_UNARY_RULE
#undef BOOST_PHOENIX_UNARY_FUNCTIONAL
#undef BOOST_PHOENIX_BINARY_RULE
#undef BOOST_PHOENIX_BINARY_FUNCTIONAL
#undef BOOST_PHOENIX_UNARY_EXPRESSION
#undef BOOST_PHOENIX_BINARY_EXPRESSION
#undef BOOST_PHOENIX_GRAMMAR
#undef BOOST_PHOENIX_UNARY_OPERATORS
#undef BOOST_PHOENIX_BINARY_OPERATORS
#undef BOOST_PHOENIX_DEFINE_OPERATOR_HPP
@@ -0,0 +1,149 @@
// Copyright John Maddock 2008.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_MATH_DISTRIBUTIONS_DETAIL_MODE_HPP
#define BOOST_MATH_DISTRIBUTIONS_DETAIL_MODE_HPP
#include <boost/math/tools/minima.hpp> // function minimization for mode
#include <boost/math/policies/error_handling.hpp>
#include <boost/math/distributions/fwd.hpp>
namespace boost{ namespace math{ namespace detail{
template <class Dist>
struct pdf_minimizer
{
pdf_minimizer(const Dist& d)
: dist(d) {}
typename Dist::value_type operator()(const typename Dist::value_type& x)
{
return -pdf(dist, x);
}
private:
Dist dist;
};
template <class Dist>
typename Dist::value_type generic_find_mode(const Dist& dist, typename Dist::value_type guess, const char* function, typename Dist::value_type step = 0)
{
BOOST_MATH_STD_USING
typedef typename Dist::value_type value_type;
typedef typename Dist::policy_type policy_type;
//
// Need to begin by bracketing the maxima of the PDF:
//
value_type maxval;
value_type upper_bound = guess;
value_type lower_bound;
value_type v = pdf(dist, guess);
if(v == 0)
{
//
// Oops we don't know how to handle this, or even in which
// direction we should move in, treat as an evaluation error:
//
return policies::raise_evaluation_error(
function,
"Could not locate a starting location for the search for the mode, original guess was %1%", guess, policy_type());
}
do
{
maxval = v;
if(step != 0)
upper_bound += step;
else
upper_bound *= 2;
v = pdf(dist, upper_bound);
}while(maxval < v);
lower_bound = upper_bound;
do
{
maxval = v;
if(step != 0)
lower_bound -= step;
else
lower_bound /= 2;
v = pdf(dist, lower_bound);
}while(maxval < v);
boost::uintmax_t max_iter = policies::get_max_root_iterations<policy_type>();
value_type result = tools::brent_find_minima(
pdf_minimizer<Dist>(dist),
lower_bound,
upper_bound,
policies::digits<value_type, policy_type>(),
max_iter).first;
if(max_iter >= policies::get_max_root_iterations<policy_type>())
{
return policies::raise_evaluation_error<value_type>(
function,
"Unable to locate solution in a reasonable time:"
" either there is no answer to the mode of the distribution"
" or the answer is infinite. Current best guess is %1%", result, policy_type());
}
return result;
}
//
// As above,but confined to the interval [0,1]:
//
template <class Dist>
typename Dist::value_type generic_find_mode_01(const Dist& dist, typename Dist::value_type guess, const char* function)
{
BOOST_MATH_STD_USING
typedef typename Dist::value_type value_type;
typedef typename Dist::policy_type policy_type;
//
// Need to begin by bracketing the maxima of the PDF:
//
value_type maxval;
value_type upper_bound = guess;
value_type lower_bound;
value_type v = pdf(dist, guess);
do
{
maxval = v;
upper_bound = 1 - (1 - upper_bound) / 2;
if(upper_bound == 1)
return 1;
v = pdf(dist, upper_bound);
}while(maxval < v);
lower_bound = upper_bound;
do
{
maxval = v;
lower_bound /= 2;
if(lower_bound < tools::min_value<value_type>())
return 0;
v = pdf(dist, lower_bound);
}while(maxval < v);
boost::uintmax_t max_iter = policies::get_max_root_iterations<policy_type>();
value_type result = tools::brent_find_minima(
pdf_minimizer<Dist>(dist),
lower_bound,
upper_bound,
policies::digits<value_type, policy_type>(),
max_iter).first;
if(max_iter >= policies::get_max_root_iterations<policy_type>())
{
return policies::raise_evaluation_error<value_type>(
function,
"Unable to locate solution in a reasonable time:"
" either there is no answer to the mode of the distribution"
" or the answer is infinite. Current best guess is %1%", result, policy_type());
}
return result;
}
}}} // namespaces
#endif // BOOST_MATH_DISTRIBUTIONS_DETAIL_MODE_HPP