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,60 @@
// (C) Copyright 2009-2011 Frederic Bron.
//
// 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_HAS_MINUS_HPP_INCLUDED
#define BOOST_TT_HAS_MINUS_HPP_INCLUDED
#define BOOST_TT_TRAIT_NAME has_minus
#define BOOST_TT_TRAIT_OP -
#define BOOST_TT_FORBIDDEN_IF\
(\
/* Lhs==pointer and Rhs==fundamental and Rhs!=integral */\
(\
::boost::is_pointer< Lhs_noref >::value && \
::boost::is_fundamental< Rhs_nocv >::value && \
(! ::boost::is_integral< Rhs_noref >::value )\
) || \
/* Lhs==void* and (Rhs==fundamental or Rhs==pointer) */\
(\
::boost::is_pointer< Lhs_noref >::value && \
::boost::is_void< Lhs_noptr >::value && \
( \
::boost::is_fundamental< Rhs_nocv >::value || \
::boost::is_pointer< Rhs_noref >::value\
)\
) || \
/* Rhs==void* and (Lhs==fundamental or Lhs==pointer) */\
(\
::boost::is_pointer< Rhs_noref >::value && \
::boost::is_void< Rhs_noptr >::value && \
(\
::boost::is_fundamental< Lhs_nocv >::value || \
::boost::is_pointer< Lhs_noref >::value\
)\
) ||\
/* Lhs=fundamental and Rhs=pointer */\
(\
::boost::is_fundamental< Lhs_nocv >::value && \
::boost::is_pointer< Rhs_noref >::value\
) ||\
/* two different pointers */\
(\
::boost::is_pointer< Lhs_noref >::value && \
::boost::is_pointer< Rhs_noref >::value && \
(! ::boost::is_same< Lhs_nocv, Rhs_nocv >::value )\
)\
)
#include <boost/type_traits/detail/has_binary_operator.hpp>
#undef BOOST_TT_TRAIT_NAME
#undef BOOST_TT_TRAIT_OP
#undef BOOST_TT_FORBIDDEN_IF
#endif
@@ -0,0 +1,27 @@
// Copyright 2010 John Maddock
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
#ifndef BOOST_TYPE_TRAITS_EXT_ADD_LVALUE_REFERENCE__HPP
#define BOOST_TYPE_TRAITS_EXT_ADD_LVALUE_REFERENCE__HPP
#include <boost/type_traits/add_reference.hpp>
namespace boost{
template <class T> struct add_lvalue_reference
{
typedef typename boost::add_reference<T>::type type;
};
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template <class T> struct add_lvalue_reference<T&&>
{
typedef T& type;
};
#endif
}
#endif // BOOST_TYPE_TRAITS_EXT_ADD_LVALUE_REFERENCE__HPP
@@ -0,0 +1,635 @@
// (C) Copyright John Maddock 2006.
// 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_SF_DIGAMMA_HPP
#define BOOST_MATH_SF_DIGAMMA_HPP
#ifdef _MSC_VER
#pragma once
#pragma warning(push)
#pragma warning(disable:4702) // Unreachable code (release mode only warning)
#endif
#include <boost/math/special_functions/math_fwd.hpp>
#include <boost/math/tools/rational.hpp>
#include <boost/math/tools/series.hpp>
#include <boost/math/tools/promotion.hpp>
#include <boost/math/policies/error_handling.hpp>
#include <boost/math/constants/constants.hpp>
#include <boost/mpl/comparison.hpp>
#include <boost/math/tools/big_constant.hpp>
namespace boost{
namespace math{
namespace detail{
//
// Begin by defining the smallest value for which it is safe to
// use the asymptotic expansion for digamma:
//
inline unsigned digamma_large_lim(const mpl::int_<0>*)
{ return 20; }
inline unsigned digamma_large_lim(const mpl::int_<113>*)
{ return 20; }
inline unsigned digamma_large_lim(const void*)
{ return 10; }
//
// Implementations of the asymptotic expansion come next,
// the coefficients of the series have been evaluated
// in advance at high precision, and the series truncated
// at the first term that's too small to effect the result.
// Note that the series becomes divergent after a while
// so truncation is very important.
//
// This first one gives 34-digit precision for x >= 20:
//
template <class T>
inline T digamma_imp_large(T x, const mpl::int_<113>*)
{
BOOST_MATH_STD_USING // ADL of std functions.
static const T P[] = {
BOOST_MATH_BIG_CONSTANT(T, 113, 0.083333333333333333333333333333333333333333333333333),
BOOST_MATH_BIG_CONSTANT(T, 113, -0.0083333333333333333333333333333333333333333333333333),
BOOST_MATH_BIG_CONSTANT(T, 113, 0.003968253968253968253968253968253968253968253968254),
BOOST_MATH_BIG_CONSTANT(T, 113, -0.0041666666666666666666666666666666666666666666666667),
BOOST_MATH_BIG_CONSTANT(T, 113, 0.0075757575757575757575757575757575757575757575757576),
BOOST_MATH_BIG_CONSTANT(T, 113, -0.021092796092796092796092796092796092796092796092796),
BOOST_MATH_BIG_CONSTANT(T, 113, 0.083333333333333333333333333333333333333333333333333),
BOOST_MATH_BIG_CONSTANT(T, 113, -0.44325980392156862745098039215686274509803921568627),
BOOST_MATH_BIG_CONSTANT(T, 113, 3.0539543302701197438039543302701197438039543302701),
BOOST_MATH_BIG_CONSTANT(T, 113, -26.456212121212121212121212121212121212121212121212),
BOOST_MATH_BIG_CONSTANT(T, 113, 281.4601449275362318840579710144927536231884057971),
BOOST_MATH_BIG_CONSTANT(T, 113, -3607.510546398046398046398046398046398046398046398),
BOOST_MATH_BIG_CONSTANT(T, 113, 54827.583333333333333333333333333333333333333333333),
BOOST_MATH_BIG_CONSTANT(T, 113, -974936.82385057471264367816091954022988505747126437),
BOOST_MATH_BIG_CONSTANT(T, 113, 20052695.796688078946143462272494530559046688078946),
BOOST_MATH_BIG_CONSTANT(T, 113, -472384867.72162990196078431372549019607843137254902),
BOOST_MATH_BIG_CONSTANT(T, 113, 12635724795.916666666666666666666666666666666666667)
};
x -= 1;
T result = log(x);
result += 1 / (2 * x);
T z = 1 / (x*x);
result -= z * tools::evaluate_polynomial(P, z);
return result;
}
//
// 19-digit precision for x >= 10:
//
template <class T>
inline T digamma_imp_large(T x, const mpl::int_<64>*)
{
BOOST_MATH_STD_USING // ADL of std functions.
static const T P[] = {
BOOST_MATH_BIG_CONSTANT(T, 64, 0.083333333333333333333333333333333333333333333333333),
BOOST_MATH_BIG_CONSTANT(T, 64, -0.0083333333333333333333333333333333333333333333333333),
BOOST_MATH_BIG_CONSTANT(T, 64, 0.003968253968253968253968253968253968253968253968254),
BOOST_MATH_BIG_CONSTANT(T, 64, -0.0041666666666666666666666666666666666666666666666667),
BOOST_MATH_BIG_CONSTANT(T, 64, 0.0075757575757575757575757575757575757575757575757576),
BOOST_MATH_BIG_CONSTANT(T, 64, -0.021092796092796092796092796092796092796092796092796),
BOOST_MATH_BIG_CONSTANT(T, 64, 0.083333333333333333333333333333333333333333333333333),
BOOST_MATH_BIG_CONSTANT(T, 64, -0.44325980392156862745098039215686274509803921568627),
BOOST_MATH_BIG_CONSTANT(T, 64, 3.0539543302701197438039543302701197438039543302701),
BOOST_MATH_BIG_CONSTANT(T, 64, -26.456212121212121212121212121212121212121212121212),
BOOST_MATH_BIG_CONSTANT(T, 64, 281.4601449275362318840579710144927536231884057971),
};
x -= 1;
T result = log(x);
result += 1 / (2 * x);
T z = 1 / (x*x);
result -= z * tools::evaluate_polynomial(P, z);
return result;
}
//
// 17-digit precision for x >= 10:
//
template <class T>
inline T digamma_imp_large(T x, const mpl::int_<53>*)
{
BOOST_MATH_STD_USING // ADL of std functions.
static const T P[] = {
BOOST_MATH_BIG_CONSTANT(T, 53, 0.083333333333333333333333333333333333333333333333333),
BOOST_MATH_BIG_CONSTANT(T, 53, -0.0083333333333333333333333333333333333333333333333333),
BOOST_MATH_BIG_CONSTANT(T, 53, 0.003968253968253968253968253968253968253968253968254),
BOOST_MATH_BIG_CONSTANT(T, 53, -0.0041666666666666666666666666666666666666666666666667),
BOOST_MATH_BIG_CONSTANT(T, 53, 0.0075757575757575757575757575757575757575757575757576),
BOOST_MATH_BIG_CONSTANT(T, 53, -0.021092796092796092796092796092796092796092796092796),
BOOST_MATH_BIG_CONSTANT(T, 53, 0.083333333333333333333333333333333333333333333333333),
BOOST_MATH_BIG_CONSTANT(T, 53, -0.44325980392156862745098039215686274509803921568627)
};
x -= 1;
T result = log(x);
result += 1 / (2 * x);
T z = 1 / (x*x);
result -= z * tools::evaluate_polynomial(P, z);
return result;
}
//
// 9-digit precision for x >= 10:
//
template <class T>
inline T digamma_imp_large(T x, const mpl::int_<24>*)
{
BOOST_MATH_STD_USING // ADL of std functions.
static const T P[] = {
BOOST_MATH_BIG_CONSTANT(T, 24, 0.083333333333333333333333333333333333333333333333333),
BOOST_MATH_BIG_CONSTANT(T, 24, -0.0083333333333333333333333333333333333333333333333333),
BOOST_MATH_BIG_CONSTANT(T, 24, 0.003968253968253968253968253968253968253968253968254)
};
x -= 1;
T result = log(x);
result += 1 / (2 * x);
T z = 1 / (x*x);
result -= z * tools::evaluate_polynomial(P, z);
return result;
}
//
// Fully generic asymptotic expansion in terms of Bernoulli numbers, see:
// http://functions.wolfram.com/06.14.06.0012.01
//
template <class T>
struct digamma_series_func
{
private:
int k;
T xx;
T term;
public:
digamma_series_func(T x) : k(1), xx(x * x), term(1 / (x * x)) {}
T operator()()
{
T result = term * boost::math::bernoulli_b2n<T>(k) / (2 * k);
term /= xx;
++k;
return result;
}
typedef T result_type;
};
template <class T, class Policy>
inline T digamma_imp_large(T x, const Policy& pol, const mpl::int_<0>*)
{
BOOST_MATH_STD_USING
digamma_series_func<T> s(x);
T result = log(x) - 1 / (2 * x);
boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon<T, Policy>(), max_iter, -result);
result = -result;
policies::check_series_iterations<T>("boost::math::digamma<%1%>(%1%)", max_iter, pol);
return result;
}
//
// Now follow rational approximations over the range [1,2].
//
// 35-digit precision:
//
template <class T>
T digamma_imp_1_2(T x, const mpl::int_<113>*)
{
//
// Now the approximation, we use the form:
//
// digamma(x) = (x - root) * (Y + R(x-1))
//
// Where root is the location of the positive root of digamma,
// Y is a constant, and R is optimised for low absolute error
// compared to Y.
//
// Max error found at 128-bit long double precision: 5.541e-35
// Maximum Deviation Found (approximation error): 1.965e-35
//
static const float Y = 0.99558162689208984375F;
static const T root1 = T(1569415565) / 1073741824uL;
static const T root2 = (T(381566830) / 1073741824uL) / 1073741824uL;
static const T root3 = ((T(111616537) / 1073741824uL) / 1073741824uL) / 1073741824uL;
static const T root4 = (((T(503992070) / 1073741824uL) / 1073741824uL) / 1073741824uL) / 1073741824uL;
static const T root5 = BOOST_MATH_BIG_CONSTANT(T, 113, 0.52112228569249997894452490385577338504019838794544e-36);
static const T P[] = {
BOOST_MATH_BIG_CONSTANT(T, 113, 0.25479851061131551526977464225335883769),
BOOST_MATH_BIG_CONSTANT(T, 113, -0.18684290534374944114622235683619897417),
BOOST_MATH_BIG_CONSTANT(T, 113, -0.80360876047931768958995775910991929922),
BOOST_MATH_BIG_CONSTANT(T, 113, -0.67227342794829064330498117008564270136),
BOOST_MATH_BIG_CONSTANT(T, 113, -0.26569010991230617151285010695543858005),
BOOST_MATH_BIG_CONSTANT(T, 113, -0.05775672694575986971640757748003553385),
BOOST_MATH_BIG_CONSTANT(T, 113, -0.0071432147823164975485922555833274240665),
BOOST_MATH_BIG_CONSTANT(T, 113, -0.00048740753910766168912364555706064993274),
BOOST_MATH_BIG_CONSTANT(T, 113, -0.16454996865214115723416538844975174761e-4),
BOOST_MATH_BIG_CONSTANT(T, 113, -0.20327832297631728077731148515093164955e-6)
};
static const T Q[] = {
BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
BOOST_MATH_BIG_CONSTANT(T, 113, 2.6210924610812025425088411043163287646),
BOOST_MATH_BIG_CONSTANT(T, 113, 2.6850757078559596612621337395886392594),
BOOST_MATH_BIG_CONSTANT(T, 113, 1.4320913706209965531250495490639289418),
BOOST_MATH_BIG_CONSTANT(T, 113, 0.4410872083455009362557012239501953402),
BOOST_MATH_BIG_CONSTANT(T, 113, 0.081385727399251729505165509278152487225),
BOOST_MATH_BIG_CONSTANT(T, 113, 0.0089478633066857163432104815183858149496),
BOOST_MATH_BIG_CONSTANT(T, 113, 0.00055861622855066424871506755481997374154),
BOOST_MATH_BIG_CONSTANT(T, 113, 0.1760168552357342401304462967950178554e-4),
BOOST_MATH_BIG_CONSTANT(T, 113, 0.20585454493572473724556649516040874384e-6),
BOOST_MATH_BIG_CONSTANT(T, 113, -0.90745971844439990284514121823069162795e-11),
BOOST_MATH_BIG_CONSTANT(T, 113, 0.48857673606545846774761343500033283272e-13),
};
T g = x - root1;
g -= root2;
g -= root3;
g -= root4;
g -= root5;
T r = tools::evaluate_polynomial(P, T(x-1)) / tools::evaluate_polynomial(Q, T(x-1));
T result = g * Y + g * r;
return result;
}
//
// 19-digit precision:
//
template <class T>
T digamma_imp_1_2(T x, const mpl::int_<64>*)
{
//
// Now the approximation, we use the form:
//
// digamma(x) = (x - root) * (Y + R(x-1))
//
// Where root is the location of the positive root of digamma,
// Y is a constant, and R is optimised for low absolute error
// compared to Y.
//
// Max error found at 80-bit long double precision: 5.016e-20
// Maximum Deviation Found (approximation error): 3.575e-20
//
static const float Y = 0.99558162689208984375F;
static const T root1 = T(1569415565) / 1073741824uL;
static const T root2 = (T(381566830) / 1073741824uL) / 1073741824uL;
static const T root3 = BOOST_MATH_BIG_CONSTANT(T, 64, 0.9016312093258695918615325266959189453125e-19);
static const T P[] = {
BOOST_MATH_BIG_CONSTANT(T, 64, 0.254798510611315515235),
BOOST_MATH_BIG_CONSTANT(T, 64, -0.314628554532916496608),
BOOST_MATH_BIG_CONSTANT(T, 64, -0.665836341559876230295),
BOOST_MATH_BIG_CONSTANT(T, 64, -0.314767657147375752913),
BOOST_MATH_BIG_CONSTANT(T, 64, -0.0541156266153505273939),
BOOST_MATH_BIG_CONSTANT(T, 64, -0.00289268368333918761452)
};
static const T Q[] = {
BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
BOOST_MATH_BIG_CONSTANT(T, 64, 2.1195759927055347547),
BOOST_MATH_BIG_CONSTANT(T, 64, 1.54350554664961128724),
BOOST_MATH_BIG_CONSTANT(T, 64, 0.486986018231042975162),
BOOST_MATH_BIG_CONSTANT(T, 64, 0.0660481487173569812846),
BOOST_MATH_BIG_CONSTANT(T, 64, 0.00298999662592323990972),
BOOST_MATH_BIG_CONSTANT(T, 64, -0.165079794012604905639e-5),
BOOST_MATH_BIG_CONSTANT(T, 64, 0.317940243105952177571e-7)
};
T g = x - root1;
g -= root2;
g -= root3;
T r = tools::evaluate_polynomial(P, T(x-1)) / tools::evaluate_polynomial(Q, T(x-1));
T result = g * Y + g * r;
return result;
}
//
// 18-digit precision:
//
template <class T>
T digamma_imp_1_2(T x, const mpl::int_<53>*)
{
//
// Now the approximation, we use the form:
//
// digamma(x) = (x - root) * (Y + R(x-1))
//
// Where root is the location of the positive root of digamma,
// Y is a constant, and R is optimised for low absolute error
// compared to Y.
//
// Maximum Deviation Found: 1.466e-18
// At double precision, max error found: 2.452e-17
//
static const float Y = 0.99558162689208984F;
static const T root1 = T(1569415565) / 1073741824uL;
static const T root2 = (T(381566830) / 1073741824uL) / 1073741824uL;
static const T root3 = BOOST_MATH_BIG_CONSTANT(T, 53, 0.9016312093258695918615325266959189453125e-19);
static const T P[] = {
BOOST_MATH_BIG_CONSTANT(T, 53, 0.25479851061131551),
BOOST_MATH_BIG_CONSTANT(T, 53, -0.32555031186804491),
BOOST_MATH_BIG_CONSTANT(T, 53, -0.65031853770896507),
BOOST_MATH_BIG_CONSTANT(T, 53, -0.28919126444774784),
BOOST_MATH_BIG_CONSTANT(T, 53, -0.045251321448739056),
BOOST_MATH_BIG_CONSTANT(T, 53, -0.0020713321167745952)
};
static const T Q[] = {
BOOST_MATH_BIG_CONSTANT(T, 53, 1.0),
BOOST_MATH_BIG_CONSTANT(T, 53, 2.0767117023730469),
BOOST_MATH_BIG_CONSTANT(T, 53, 1.4606242909763515),
BOOST_MATH_BIG_CONSTANT(T, 53, 0.43593529692665969),
BOOST_MATH_BIG_CONSTANT(T, 53, 0.054151797245674225),
BOOST_MATH_BIG_CONSTANT(T, 53, 0.0021284987017821144),
BOOST_MATH_BIG_CONSTANT(T, 53, -0.55789841321675513e-6)
};
T g = x - root1;
g -= root2;
g -= root3;
T r = tools::evaluate_polynomial(P, T(x-1)) / tools::evaluate_polynomial(Q, T(x-1));
T result = g * Y + g * r;
return result;
}
//
// 9-digit precision:
//
template <class T>
inline T digamma_imp_1_2(T x, const mpl::int_<24>*)
{
//
// Now the approximation, we use the form:
//
// digamma(x) = (x - root) * (Y + R(x-1))
//
// Where root is the location of the positive root of digamma,
// Y is a constant, and R is optimised for low absolute error
// compared to Y.
//
// Maximum Deviation Found: 3.388e-010
// At float precision, max error found: 2.008725e-008
//
static const float Y = 0.99558162689208984f;
static const T root = 1532632.0f / 1048576;
static const T root_minor = static_cast<T>(0.3700660185912626595423257213284682051735604e-6L);
static const T P[] = {
0.25479851023250261e0f,
-0.44981331915268368e0f,
-0.43916936919946835e0f,
-0.61041765350579073e-1f
};
static const T Q[] = {
0.1e1,
0.15890202430554952e1f,
0.65341249856146947e0f,
0.63851690523355715e-1f
};
T g = x - root;
g -= root_minor;
T r = tools::evaluate_polynomial(P, T(x-1)) / tools::evaluate_polynomial(Q, T(x-1));
T result = g * Y + g * r;
return result;
}
template <class T, class Tag, class Policy>
T digamma_imp(T x, const Tag* t, const Policy& pol)
{
//
// This handles reflection of negative arguments, and all our
// error handling, then forwards to the T-specific approximation.
//
BOOST_MATH_STD_USING // ADL of std functions.
T result = 0;
//
// Check for negative arguments and use reflection:
//
if(x <= -1)
{
// Reflect:
x = 1 - x;
// Argument reduction for tan:
T remainder = x - floor(x);
// Shift to negative if > 0.5:
if(remainder > 0.5)
{
remainder -= 1;
}
//
// check for evaluation at a negative pole:
//
if(remainder == 0)
{
return policies::raise_pole_error<T>("boost::math::digamma<%1%>(%1%)", 0, (1-x), pol);
}
result = constants::pi<T>() / tan(constants::pi<T>() * remainder);
}
if(x == 0)
return policies::raise_pole_error<T>("boost::math::digamma<%1%>(%1%)", 0, x, pol);
//
// If we're above the lower-limit for the
// asymptotic expansion then use it:
//
if(x >= digamma_large_lim(t))
{
result += digamma_imp_large(x, t);
}
else
{
//
// If x > 2 reduce to the interval [1,2]:
//
while(x > 2)
{
x -= 1;
result += 1/x;
}
//
// If x < 1 use recurrance to shift to > 1:
//
while(x < 1)
{
result -= 1/x;
x += 1;
}
result += digamma_imp_1_2(x, t);
}
return result;
}
template <class T, class Policy>
T digamma_imp(T x, const mpl::int_<0>* t, const Policy& pol)
{
//
// This handles reflection of negative arguments, and all our
// error handling, then forwards to the T-specific approximation.
//
BOOST_MATH_STD_USING // ADL of std functions.
T result = 0;
//
// Check for negative arguments and use reflection:
//
if(x <= -1)
{
// Reflect:
x = 1 - x;
// Argument reduction for tan:
T remainder = x - floor(x);
// Shift to negative if > 0.5:
if(remainder > 0.5)
{
remainder -= 1;
}
//
// check for evaluation at a negative pole:
//
if(remainder == 0)
{
return policies::raise_pole_error<T>("boost::math::digamma<%1%>(%1%)", 0, (1 - x), pol);
}
result = constants::pi<T>() / tan(constants::pi<T>() * remainder);
}
if(x == 0)
return policies::raise_pole_error<T>("boost::math::digamma<%1%>(%1%)", 0, x, pol);
//
// If we're above the lower-limit for the
// asymptotic expansion then use it, the
// limit is a linear interpolation with
// limit = 10 at 50 bit precision and
// limit = 250 at 1000 bit precision.
//
int lim = 10 + ((tools::digits<T>() - 50) * 240L) / 950;
T two_x = ldexp(x, 1);
if(x >= lim)
{
result += digamma_imp_large(x, pol, t);
}
else if(floor(x) == x)
{
//
// Special case for integer arguments, see
// http://functions.wolfram.com/06.14.03.0001.01
//
result = -constants::euler<T, Policy>();
T val = 1;
while(val < x)
{
result += 1 / val;
val += 1;
}
}
else if(floor(two_x) == two_x)
{
//
// Special case for half integer arguments, see:
// http://functions.wolfram.com/06.14.03.0007.01
//
result = -2 * constants::ln_two<T, Policy>() - constants::euler<T, Policy>();
int n = itrunc(x);
if(n)
{
for(int k = 1; k < n; ++k)
result += 1 / T(k);
for(int k = n; k <= 2 * n - 1; ++k)
result += 2 / T(k);
}
}
else
{
//
// Rescale so we can use the asymptotic expansion:
//
while(x < lim)
{
result -= 1 / x;
x += 1;
}
result += digamma_imp_large(x, pol, t);
}
return result;
}
//
// Initializer: ensure all our constants are initialized prior to the first call of main:
//
template <class T, class Policy>
struct digamma_initializer
{
struct init
{
init()
{
typedef typename policies::precision<T, Policy>::type precision_type;
do_init(mpl::bool_<precision_type::value && (precision_type::value <= 113)>());
}
void do_init(const mpl::true_&)
{
boost::math::digamma(T(1.5), Policy());
boost::math::digamma(T(500), Policy());
}
void do_init(const mpl::false_&){}
void force_instantiate()const{}
};
static const init initializer;
static void force_instantiate()
{
initializer.force_instantiate();
}
};
template <class T, class Policy>
const typename digamma_initializer<T, Policy>::init digamma_initializer<T, Policy>::initializer;
} // namespace detail
template <class T, class Policy>
inline typename tools::promote_args<T>::type
digamma(T x, const Policy&)
{
typedef typename tools::promote_args<T>::type result_type;
typedef typename policies::evaluation<result_type, Policy>::type value_type;
typedef typename policies::precision<T, Policy>::type precision_type;
typedef typename mpl::if_<
mpl::or_<
mpl::less_equal<precision_type, mpl::int_<0> >,
mpl::greater<precision_type, mpl::int_<114> >
>,
mpl::int_<0>,
typename mpl::if_<
mpl::less<precision_type, mpl::int_<25> >,
mpl::int_<24>,
typename mpl::if_<
mpl::less<precision_type, mpl::int_<54> >,
mpl::int_<53>,
typename mpl::if_<
mpl::less<precision_type, mpl::int_<65> >,
mpl::int_<64>,
mpl::int_<113>
>::type
>::type
>::type
>::type tag_type;
typedef typename policies::normalise<
Policy,
policies::promote_float<false>,
policies::promote_double<false>,
policies::discrete_quantile<>,
policies::assert_undefined<> >::type forwarding_policy;
// Force initialization of constants:
detail::digamma_initializer<value_type, forwarding_policy>::force_instantiate();
return policies::checked_narrowing_cast<result_type, Policy>(detail::digamma_imp(
static_cast<value_type>(x),
static_cast<const tag_type*>(0), forwarding_policy()), "boost::math::digamma<%1%>(%1%)");
}
template <class T>
inline typename tools::promote_args<T>::type
digamma(T x)
{
return digamma(x, policies::policy<>());
}
} // namespace math
} // namespace boost
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#endif
@@ -0,0 +1,73 @@
// (C) Copyright Gennadiy Rozental 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/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : basic_cstring i/o implementation
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_BASIC_CSTRING_IO_HPP
#define BOOST_TEST_UTILS_BASIC_CSTRING_IO_HPP
// Boost.Test
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
// STL
#include <iosfwd>
#include <string>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
#ifdef BOOST_CLASSIC_IOSTREAMS
template<typename CharT>
inline std::ostream&
operator<<( std::ostream& os, basic_cstring<CharT> const& str )
{
typedef typename ut_detail::bcs_base_char<CharT>::type char_type;
char_type const* const beg = reinterpret_cast<char_type const* const>( str.begin() );
char_type const* const end = reinterpret_cast<char_type const* const>( str.end() );
os << std::basic_string<char_type>( beg, end - beg );
return os;
}
#else
template<typename CharT1, typename Tr,typename CharT2>
inline std::basic_ostream<CharT1,Tr>&
operator<<( std::basic_ostream<CharT1,Tr>& os, basic_cstring<CharT2> const& str )
{
CharT1 const* const beg = reinterpret_cast<CharT1 const*>( str.begin() ); // !!
CharT1 const* const end = reinterpret_cast<CharT1 const*>( str.end() );
os << std::basic_string<CharT1,Tr>( beg, end - beg );
return os;
}
#endif
//____________________________________________________________________________//
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_BASIC_CSTRING_IO_HPP_071894GER
@@ -0,0 +1,60 @@
/*=============================================================================
Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_ACTOR_INCREMENT_ACTOR_HPP
#define BOOST_SPIRIT_ACTOR_INCREMENT_ACTOR_HPP
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/actor/ref_actor.hpp>
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////
// Summary:
// A semantic action policy that calls the ++ operator on a reference.
// (This doc uses convention available in actors.hpp)
//
// Actions:
// ++ref;
//
// Policy name:
// increment_action
//
// Policy holder, corresponding helper method:
// ref_actor, increment_a( ref );
//
// () operators: both.
//
// See also ref_actor for more details.
///////////////////////////////////////////////////////////////////////////
struct increment_action
{
template<
typename T
>
void act(T& ref_) const
{
++ref_;
}
};
///////////////////////////////////////////////////////////////////////////
// helper method that creates a increment_actor.
///////////////////////////////////////////////////////////////////////////
template<typename T>
inline ref_actor<T,increment_action> increment_a(T& ref_)
{
return ref_actor<T,increment_action>(ref_);
}
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}}
#endif
@@ -0,0 +1,27 @@
/*=============================================================================
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_EMPTY_10022005_1619)
#define FUSION_EMPTY_10022005_1619
#include <boost/fusion/support/config.hpp>
#include <boost/mpl/empty.hpp>
#include <boost/fusion/sequence/intrinsic/empty.hpp>
namespace boost { namespace mpl
{
template <typename Tag>
struct empty_impl;
template <>
struct empty_impl<fusion::fusion_sequence_tag>
{
template <typename Sequence>
struct apply : fusion::result_of::empty<Sequence> {};
};
}}
#endif
@@ -0,0 +1,134 @@
#ifndef BOOST_ARCHIVE_XML_WOARCHIVE_HPP
#define BOOST_ARCHIVE_XML_WOARCHIVE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// xml_woarchive.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#ifdef BOOST_NO_STD_WSTREAMBUF
#error "wide char i/o not supported on this platform"
#else
#include <cstddef> // size_t
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::size_t;
} // namespace std
#endif
#include <ostream>
//#include <boost/smart_ptr/scoped_ptr.hpp>
#include <boost/archive/detail/auto_link_warchive.hpp>
#include <boost/archive/basic_text_oprimitive.hpp>
#include <boost/archive/basic_xml_oarchive.hpp>
#include <boost/archive/detail/register_archive.hpp>
#include <boost/serialization/item_version_type.hpp>
//#include <boost/archive/detail/utf8_codecvt_facet.hpp>
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable : 4511 4512)
#endif
namespace boost {
namespace archive {
namespace detail {
template<class Archive> class interface_oarchive;
} // namespace detail
template<class Archive>
class BOOST_SYMBOL_VISIBLE xml_woarchive_impl :
public basic_text_oprimitive<std::wostream>,
public basic_xml_oarchive<Archive>
{
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
public:
#else
protected:
friend class detail::interface_oarchive<Archive>;
friend class basic_xml_oarchive<Archive>;
friend class save_access;
#endif
//void end_preamble(){
// basic_xml_oarchive<Archive>::end_preamble();
//}
template<class T>
void
save(const T & t){
basic_text_oprimitive<std::wostream>::save(t);
}
void
save(const version_type & t){
save(static_cast<const unsigned int>(t));
}
void
save(const boost::serialization::item_version_type & t){
save(static_cast<const unsigned int>(t));
}
BOOST_WARCHIVE_DECL void
save(const char * t);
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
BOOST_WARCHIVE_DECL void
save(const wchar_t * t);
#endif
BOOST_WARCHIVE_DECL void
save(const std::string &s);
#ifndef BOOST_NO_STD_WSTRING
BOOST_WARCHIVE_DECL void
save(const std::wstring &ws);
#endif
BOOST_WARCHIVE_DECL
xml_woarchive_impl(std::wostream & os, unsigned int flags);
BOOST_WARCHIVE_DECL
~xml_woarchive_impl();
public:
BOOST_WARCHIVE_DECL void
save_binary(const void *address, std::size_t count);
};
// we use the following because we can't use
// typedef xml_woarchive_impl<xml_woarchive_impl<...> > xml_woarchive;
// do not derive from this class. If you want to extend this functionality
// via inhertance, derived from xml_woarchive_impl instead. This will
// preserve correct static polymorphism.
class BOOST_SYMBOL_VISIBLE xml_woarchive :
public xml_woarchive_impl<xml_woarchive>
{
public:
xml_woarchive(std::wostream & os, unsigned int flags = 0) :
xml_woarchive_impl<xml_woarchive>(os, flags)
{}
~xml_woarchive(){}
};
} // namespace archive
} // namespace boost
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::xml_woarchive)
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
#endif // BOOST_NO_STD_WSTREAMBUF
#endif // BOOST_ARCHIVE_XML_OARCHIVE_HPP
@@ -0,0 +1,63 @@
//---------------------------------------------------------------------------//
// Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@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_ALGORITHM_PARTITION_COPY_HPP
#define BOOST_COMPUTE_ALGORITHM_PARTITION_COPY_HPP
#include <boost/compute/system.hpp>
#include <boost/compute/functional.hpp>
#include <boost/compute/command_queue.hpp>
#include <boost/compute/algorithm/copy_if.hpp>
namespace boost {
namespace compute {
/// Copies all of the elements in the range [\p first, \p last) for which
/// \p predicate returns \c true to the range beginning at \p first_true
/// and all of the elements for which \p predicate returns \c false to
/// the range beginning at \p first_false.
///
/// \see partition()
template<class InputIterator,
class OutputIterator1,
class OutputIterator2,
class UnaryPredicate>
inline std::pair<OutputIterator1, OutputIterator2>
partition_copy(InputIterator first,
InputIterator last,
OutputIterator1 first_true,
OutputIterator2 first_false,
UnaryPredicate predicate,
command_queue &queue = system::default_queue())
{
// copy true values
OutputIterator1 last_true =
::boost::compute::copy_if(first,
last,
first_true,
predicate,
queue);
// copy false values
OutputIterator2 last_false =
::boost::compute::copy_if(first,
last,
first_false,
not1(predicate),
queue);
// return iterators to the end of the true and the false ranges
return std::make_pair(last_true, last_false);
}
} // end compute namespace
} // end boost namespace
#endif // BOOST_COMPUTE_ALGORITHM_PARTITION_COPY_HPP
@@ -0,0 +1,365 @@
subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,napwid, &
lsubtract,nagain,iaptype,mygrid6,bcontest,sync0,f1,xdt,xbase,apsym, &
nharderrors,dmin,nbadcrc,ipass,iera,message,xsnr)
use timer_module, only: timer
include 'ft8_params.f90'
parameter(NRECENT=10,NP2=2812)
character message*22,msgsent*22
character*12 recent_calls(NRECENT)
character*6 mygrid6
logical bcontest
real a(5)
real s1(0:7,ND),s2(0:7,NN)
real ps(0:7)
real bmeta(3*ND),bmetap(3*ND)
real llr(3*ND),llra(3*ND),llr0(3*ND),llrap(3*ND) !Soft symbols
real dd0(15*12000)
integer*1 decoded(KK),apmask(3*ND),cw(3*ND)
integer*1 msgbits(KK)
integer apsym(KK)
integer mcq(28),mde(28),mrrr(16),m73(16),mrr73(16)
integer itone(NN)
integer icos7(0:6),ip(1)
integer nappasses(0:5) ! the number of decoding passes to use for each QSO state
integer naptypes(0:5,4) ! (nQSOProgress, decoding pass) maximum of 4 passes for now
complex cd0(3200)
complex ctwk(32)
complex csymb(32)
logical first,newdat,lsubtract,lapon,nagain
data icos7/2,5,6,0,4,1,3/
data mcq/1,1,1,1,1,0,1,0,0,0,0,0,1,0,0,0,0,0,1,1,0,0,0,1,1,0,0,1/
data mrrr/0,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1/
data m73/0,1,1,1,1,1,1,0,1,1,0,1,0,0,0,0/
data mde/1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,0,0,0,1,1,1,0,1,0,0,0,1/
data mrr73/0,0,0,0,0,0,1,0,0,0,0,1,0,1,0,1/
data first/.true./
save nappasses,naptypes
if(first) then
mcq=2*mcq-1
mde=2*mde-1
mrrr=2*mrrr-1
m73=2*m73-1
mrr73=2*mrr73-1
nappasses(0)=2
nappasses(1)=2
nappasses(2)=2
nappasses(3)=4
nappasses(4)=4
nappasses(5)=3
! iaptype
!------------------------
! 1 CQ ??? ???
! 2 MyCall ??? ???
! 3 MyCall DxCall ???
! 4 MyCall DxCall RRR
! 5 MyCall DxCall 73
! 6 MyCall DxCall RR73
! 7 ??? DxCall ???
naptypes(0,1:4)=(/1,2,0,0/)
naptypes(1,1:4)=(/2,3,0,0/)
naptypes(2,1:4)=(/2,3,0,0/)
naptypes(3,1:4)=(/3,4,5,6/)
naptypes(4,1:4)=(/3,4,5,6/)
naptypes(5,1:4)=(/3,1,2,0/) !?
first=.false.
endif
max_iterations=30
nharderrors=-1
fs2=12000.0/NDOWN
dt2=1.0/fs2
twopi=8.0*atan(1.0)
delfbest=0.
ibest=0
call timer('ft8_down',0)
call ft8_downsample(dd0,newdat,f1,cd0) !Mix f1 to baseband and downsample
call timer('ft8_down',1)
i0=nint((xdt+0.5)*fs2) !Initial guess for start of signal
smax=0.0
do idt=i0-8,i0+8 !Search over +/- one quarter symbol
call sync8d(cd0,idt,ctwk,0,sync)
if(sync.gt.smax) then
smax=sync
ibest=idt
endif
enddo
xdt2=ibest*dt2 !Improved estimate for DT
! Now peak up in frequency
i0=nint(xdt2*fs2)
smax=0.0
do ifr=-5,5 !Search over +/- 2.5 Hz
delf=ifr*0.5
dphi=twopi*delf*dt2
phi=0.0
do i=1,32
ctwk(i)=cmplx(cos(phi),sin(phi))
phi=mod(phi+dphi,twopi)
enddo
call sync8d(cd0,i0,ctwk,1,sync)
if( sync .gt. smax ) then
smax=sync
delfbest=delf
endif
enddo
a=0.0
a(1)=-delfbest
call twkfreq1(cd0,NP2,fs2,a,cd0)
xdt=xdt2
f1=f1+delfbest !Improved estimate of DF
call sync8d(cd0,i0,ctwk,2,sync)
j=0
do k=1,NN
i1=ibest+(k-1)*32
csymb=cmplx(0.0,0.0)
if( i1.ge.1 .and. i1+31 .le. NP2 ) csymb=cd0(i1:i1+31)
call four2a(csymb,32,1,-1,1)
s2(0:7,k)=abs(csymb(1:8))/1e3
enddo
! sync quality check
is1=0
is2=0
is3=0
do k=1,7
ip=maxloc(s2(:,k))
if(icos7(k-1).eq.(ip(1)-1)) is1=is1+1
ip=maxloc(s2(:,k+36))
if(icos7(k-1).eq.(ip(1)-1)) is2=is2+1
ip=maxloc(s2(:,k+72))
if(icos7(k-1).eq.(ip(1)-1)) is3=is3+1
enddo
! hard sync sum - max is 21
nsync=is1+is2+is3
if(nsync .le. 6) then ! bail out
nbadcrc=1
return
endif
j=0
do k=1,NN
if(k.le.7) cycle
if(k.ge.37 .and. k.le.43) cycle
if(k.gt.72) cycle
j=j+1
s1(0:7,j)=s2(0:7,k)
enddo
do j=1,ND
i4=3*j-2
i2=3*j-1
i1=3*j
ps=s1(0:7,j)
r1=max(ps(1),ps(3),ps(5),ps(7))-max(ps(0),ps(2),ps(4),ps(6))
r2=max(ps(2),ps(3),ps(6),ps(7))-max(ps(0),ps(1),ps(4),ps(5))
r4=max(ps(4),ps(5),ps(6),ps(7))-max(ps(0),ps(1),ps(2),ps(3))
bmeta(i4)=r4
bmeta(i2)=r2
bmeta(i1)=r1
bmetap(i4)=r4
bmetap(i2)=r2
bmetap(i1)=r1
if(nQSOProgress .eq. 0 .or. nQSOProgress .eq. 5) then
! When bits 88:115 are set as ap bits, bit 115 lives in symbol 39 along
! with no-ap bits 116 and 117. Take care of metrics for bits 116 and 117.
if(j.eq.39) then ! take care of bits that live in symbol 39
if(apsym(28).lt.0) then
bmetap(i2)=max(ps(2),ps(3))-max(ps(0),ps(1))
bmetap(i1)=max(ps(1),ps(3))-max(ps(0),ps(2))
else
bmetap(i2)=max(ps(6),ps(7))-max(ps(4),ps(5))
bmetap(i1)=max(ps(5),ps(7))-max(ps(4),ps(6))
endif
endif
endif
! When bits 116:143 are set as ap bits, bit 115 lives in symbol 39 along
! with ap bits 116 and 117. Take care of metric for bit 115.
! if(j.eq.39) then ! take care of bit 115
! iii=2*(apsym(29)+1)/2 + (apsym(30)+1)/2 ! known values of bits 116 & 117
! if(iii.eq.0) bmetap(i4)=ps(4)-ps(0)
! if(iii.eq.1) bmetap(i4)=ps(5)-ps(1)
! if(iii.eq.2) bmetap(i4)=ps(6)-ps(2)
! if(iii.eq.3) bmetap(i4)=ps(7)-ps(3)
! endif
! bit 144 lives in symbol 48 and will be 1 if it is set as an ap bit.
! take care of metrics for bits 142 and 143
if(j.eq.48) then ! bit 144 is always 1
bmetap(i4)=max(ps(5),ps(7))-max(ps(1),ps(3))
bmetap(i2)=max(ps(3),ps(7))-max(ps(1),ps(5))
endif
! bit 154 lives in symbol 52 and will be 0 if it is set as an ap bit
! take care of metrics for bits 155 and 156
if(j.eq.52) then ! bit 154 will be 0 if it is set as an ap bit.
bmetap(i2)=max(ps(2),ps(3))-max(ps(0),ps(1))
bmetap(i1)=max(ps(1),ps(3))-max(ps(0),ps(2))
endif
enddo
call normalizebmet(bmeta,3*ND)
call normalizebmet(bmetap,3*ND)
ss=0.84
llr0=2.0*bmeta/(ss*ss)
llra=2.0*bmetap/(ss*ss) ! llr's for use with ap
apmag=4.0
! pass #
!------------------------------
! 1 regular decoding
! 2 erase 24
! 3 erase 48
! 4 ap pass 1
! 5 ap pass 2
! 6 ap pass 3
! 7 ap pass 4, etc.
if(lapon) then
npasses=3+nappasses(nQSOProgress)
else
npasses=3
endif
do ipass=1,npasses
llr=llr0
if(ipass.eq.2) llr(1:24)=0.
if(ipass.eq.3) llr(1:48)=0.
if(ipass.le.3) then
apmask=0
llrap=llr
iaptype=0
endif
if(ipass .gt. 3) then
iaptype=naptypes(nQSOProgress,ipass-3)
if(iaptype.ge.3 .and. (abs(f1-nfqso).gt.napwid .and. abs(f1-nftx).gt.napwid) ) cycle
if(iaptype.eq.1 .or. iaptype.eq.2 ) then ! AP,???,???
apmask=0
apmask(88:115)=1 ! first 28 bits are AP
apmask(144)=1 ! not free text
llrap=llr
if(iaptype.eq.1) llrap(88:115)=apmag*mcq/ss
if(iaptype.eq.2) llrap(88:115)=apmag*apsym(1:28)/ss
llrap(116:117)=llra(116:117)
llrap(142:143)=llra(142:143)
llrap(144)=-apmag/ss
endif
if(iaptype.eq.3) then ! mycall, dxcall, ???
apmask=0
apmask(88:115)=1 ! mycall
apmask(116:143)=1 ! hiscall
apmask(144)=1 ! not free text
llrap=llr
llrap(88:143)=apmag*apsym(1:56)/ss
llrap(144)=-apmag/ss
endif
if(iaptype.eq.4 .or. iaptype.eq.5 .or. iaptype.eq.6) then
apmask=0
apmask(88:115)=1 ! mycall
apmask(116:143)=1 ! hiscall
apmask(144:159)=1 ! RRR or 73 or RR73
llrap=llr
llrap(88:143)=apmag*apsym(1:56)/ss
if(iaptype.eq.4) llrap(144:159)=apmag*mrrr/ss
if(iaptype.eq.5) llrap(144:159)=apmag*m73/ss
if(iaptype.eq.6) llrap(144:159)=apmag*mrr73/ss
endif
if(iaptype.eq.7) then ! ???, dxcall, ???
apmask=0
apmask(116:143)=1 ! hiscall
apmask(144)=1 ! not free text
llrap=llr
llrap(115)=llra(115)
llrap(116:143)=apmag*apsym(29:56)/ss
llrap(144)=-apmag/ss
endif
endif
cw=0
call timer('bpd174 ',0)
call bpdecode174(llrap,apmask,max_iterations,decoded,cw,nharderrors, &
niterations)
call timer('bpd174 ',1)
dmin=0.0
if(ndepth.eq.3 .and. nharderrors.lt.0) then
ndeep=3
if(abs(nfqso-f1).le.napwid .or. abs(nftx-f1).le.napwid) then
if((ipass.eq.2 .or. ipass.eq.3) .and. .not.nagain) then
ndeep=3
else
ndeep=4
endif
endif
if(nagain) ndeep=5
call timer('osd174 ',0)
call osd174(llrap,apmask,ndeep,decoded,cw,nharderrors,dmin)
call timer('osd174 ',1)
endif
nbadcrc=1
message=' '
xsnr=-99.0
if(count(cw.eq.0).eq.174) cycle !Reject the all-zero codeword
if(any(decoded(73:75).ne.0)) cycle !Reject if any of the 3 extra bits are nonzero
if(nharderrors.ge.0 .and. nharderrors+dmin.lt.60.0 .and. &
.not.(sync.lt.2.0 .and. nharderrors.gt.35) .and. &
.not.(ipass.gt.1 .and. nharderrors.gt.39) .and. &
.not.(ipass.eq.3 .and. nharderrors.gt.30) &
) then
call chkcrc12a(decoded,nbadcrc)
else
nharderrors=-1
cycle
endif
if(nbadcrc.eq.0) then
call extractmessage174(decoded,message,ncrcflag,recent_calls,nrecent)
call genft8(message,mygrid6,bcontest,msgsent,msgbits,itone)
if(lsubtract) call subtractft8(dd0,itone,f1,xdt2)
xsig=0.0
xnoi=0.0
do i=1,79
xsig=xsig+s2(itone(i),i)**2
ios=mod(itone(i)+4,7)
xnoi=xnoi+s2(ios,i)**2
enddo
xsnr=0.001
if(xnoi.gt.0 .and. xnoi.lt.xsig) xsnr=xsig/xnoi-1.0
xsnr=10.0*log10(xsnr)-27.0
xsnr2=db(xsig/xbase - 1.0) - 32.0
! write(52,3052) f1,xdt,xsig,xnoi,xbase,xsnr,xsnr2
!3052 format(7f10.2)
if(.not.nagain) xsnr=xsnr2
if(xsnr .lt. -24.0) xsnr=-24.0
return
endif
enddo
return
end subroutine ft8b
subroutine normalizebmet(bmet,n)
real bmet(n)
bmetav=sum(bmet)/real(n)
bmet2av=sum(bmet*bmet)/real(n)
var=bmet2av-bmetav*bmetav
if( var .gt. 0.0 ) then
bmetsig=sqrt(var)
else
bmetsig=sqrt(bmet2av)
endif
bmet=bmet/bmetsig
return
end subroutine normalizebmet
@@ -0,0 +1,96 @@
=== AP Decoding
With the QRA64 decoder Nico Palermo, IV3NWV, introduced a technique
for decoding with the aid of information that naturally accumulates
during a minimal QSO. This _a priori_ (AP) information can be
used to increase the sensitivity of the decoder.
When an operator decides to answer a CQ, he already knows his own
callsign and that of his potential QSO partner. He therefore knows
what to expect for at least 56 of the 72 message bits in a
standard-format response to his call. The _WSJT-X_ decoders for QRA64
and FT8 can use these AP bits to decode messages containing them with
higher sensitivity than otherwise possible.
We have implemented AP decoding in slightly different ways in QRA64
and FT8. To provide some explicit examples for users, we provide here
a brief description of the FT8 behavior.
The FT8 decoder always tries first to decode a signal without using
any AP information. If this attempt fails, and if *Enable AP* is
checked on the *Decode* menu, a second attempt hypothesizes that the
message contains callsigns MyCall and DxCall. If the QSO has
progressed to the point where signal reports have been exchanged, a
third attempt hypothesizes that the message contains the known
callsigns followed by RRR, RR73, or 73.
AP decoding attempts effectively set the AP bits to the hypothesized
values, as if they had been received perfectly. The decoder then
proceeds to determine whether the remaining message and parity bits
are consistent with the hypothesized AP bits. If a codeword is found
that the decoder judges to have high (but not overwhelmingly high)
probability of being correct, a ? character is appended when the
decoded message is displayed. Decodes thus marked are not sent to
{pskreporter} to avoid occasional misleading spots of false decodes.
Successful AP decodes are always labeled with an end-of-line indicator
of the form aP, where P is one of the single-digit AP decoding types
listed in Table 1. For example, an a2 designator says that the
successful decode used MyCall as hypothetically known information.
[[AP_INFO_TABLE]]
.AP information types
[width="35%",cols="h10,<m20",frame=topbot,options="header"]
|===============================================
|P | Message components
|1 | CQ &#160; &#160; ? &#160; &#160; ?
|2 | MyCall &#160; &#160; ? &#160; &#160; ?
|3 | MyCall DxCall &#160; &#160; ?
|4 | MyCall DxCall RRR
|5 | MyCall DxCall 73
|6 | MyCall DxCall RR73
|===============================================
=== Decoded Lines
Displayed information accompanying decoded messages generally includes UTC,
signal-to-noise ratio in dB, time offset DT in seconds, and
audio frequency in Hz. Some modes include additional information such
as frequency offset from nominal (DF), frequency drift (Drift or F1),
or distance (km or mi).
There may also be some cryptic characters with special meanings
summarized in the following Table:
[[DECODED_LINES_TABLE]]
.Notations used on decoded text lines
[width="50%",cols="h,3*^",frame=topbot,options="header"]
|===========================================
|Mode |Mode character|Sync character|End of line information
|FT8 | ~ | | ? &#160; aP
|JT4 | $ | *, # | f, fN, dNC
|JT9 | @ | |
|JT65 | # | |
|JT65 VHF| # | *, # | f, fN, dNC
|QRA64 | : | * | R
|ISCAT | | * | M N C T
|MSK144 | & | | N H E
|===========================================
Sync character::
`*` - Normal sync +
`#` - Alternate sync
End of line information::
`?` - Decoded with lower confidence +
`a` - Decoded with aid of some a priori (AP) information +
`C` - Confidence indicator [ISCAT and Deep Search; (0-9,*)] +
`d` - Deep Search algorithm +
`E` - Size of MSK eye diagram opening - if negative, the eye is closed +
`f` - Franke-Taylor or Fano algorithm +
`H` - Number of bit errors corrected +
`M` - Message length (characters) +
`N` - Number of Rx intervals or frames averaged +
`P` - Number indicating type of AP information (Table 1, above) +
`R` - Return code from QRA64 decoder +
`T` - Length of analyzed region (s)
@@ -0,0 +1,72 @@
// -----------------------------------------------------------
//
// Copyright (c) 2001-2002 Chuck Allison and Jeremy Siek
// Copyright (c) 2003-2006, 2008 Gennaro Prota
//
// Distributed under the 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_DYNAMIC_BITSET_CONFIG_HPP_GP_20040424
#define BOOST_DYNAMIC_BITSET_CONFIG_HPP_GP_20040424
#include "boost/config.hpp"
#include "boost/detail/workaround.hpp"
// support for pre 3.0 libstdc++ - thanks Phil Edwards!
#if defined (__STL_CONFIG_H) && !defined (__STL_USE_NEW_IOSTREAMS)
# define BOOST_OLD_IOSTREAMS
#endif
// no-op function to workaround gcc bug c++/8419
//
namespace boost { namespace detail {
template <typename T> T make_non_const(T t) { return t; }
}}
#if defined(__GNUC__)
# define BOOST_DYNAMIC_BITSET_WRAP_CONSTANT(expr) \
(boost::detail::make_non_const(expr))
#else
# define BOOST_DYNAMIC_BITSET_WRAP_CONSTANT(expr) (expr)
#endif
//
#if (defined __BORLANDC__ && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))) \
|| (defined BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
#define BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS
#endif
// if we can't use friends then we simply expose private members
//
#if defined(BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS)
#define BOOST_DYNAMIC_BITSET_PRIVATE public
#else
#define BOOST_DYNAMIC_BITSET_PRIVATE private
#endif
// A couple of macros to cope with libraries without locale
// support. The first macro must be used to declare a reference
// to a ctype facet. The second one to widen a char by using
// that ctype object. If facets and locales aren't available
// the first macro is a no-op and the second one just expands
// to its parameter c.
//
#if defined (BOOST_USE_FACET)
#define BOOST_DYNAMIC_BITSET_CTYPE_FACET(ch, name, loc) \
const std::ctype<ch> & name = \
BOOST_USE_FACET(std::ctype<ch>, loc) /**/
#define BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, c) \
(fac.widen(c))
#else
#define BOOST_DYNAMIC_BITSET_CTYPE_FACET(ch, name, loc) /**/
#define BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, c) c
#endif
#endif // include guard
@@ -0,0 +1,360 @@
#include <iostream>
#include <exception>
#include <stdexcept>
#include <string>
#include <locale.h>
#include <fftw3.h>
#include <QDateTime>
#include <QApplication>
#include <QRegularExpression>
#include <QObject>
#include <QSettings>
#include <QLibraryInfo>
#include <QSysInfo>
#include <QDir>
#include <QStandardPaths>
#include <QStringList>
#include <QLockFile>
#include <QStack>
#include <QSplashScreen>
#if QT_VERSION >= 0x050200
#include <QCommandLineParser>
#include <QCommandLineOption>
#endif
#include "revision_utils.hpp"
#include "MetaDataRegistry.hpp"
#include "SettingsGroup.hpp"
#include "TraceFile.hpp"
#include "MultiSettings.hpp"
#include "mainwindow.h"
#include "commons.h"
#include "lib/init_random_seed.h"
#include "Radio.hpp"
#include "FrequencyList.hpp"
#include "SplashScreen.hpp"
#include "MessageBox.hpp" // last to avoid nasty MS macro definitions
extern "C" {
// Fortran procedures we need
void four2a_(_Complex float *, int * nfft, int * ndim, int * isign, int * iform, int len);
}
namespace
{
struct RNGSetup
{
RNGSetup ()
{
// one time seed of pseudo RNGs from current time
auto seed = QDateTime::currentMSecsSinceEpoch ();
qsrand (seed); // this is good for rand() as well
}
} seeding;
class MessageTimestamper
{
public:
MessageTimestamper ()
{
prior_handlers_.push (qInstallMessageHandler (message_handler));
}
~MessageTimestamper ()
{
if (prior_handlers_.size ()) qInstallMessageHandler (prior_handlers_.pop ());
}
private:
static void message_handler (QtMsgType type, QMessageLogContext const& context, QString const& msg)
{
QtMessageHandler handler {prior_handlers_.top ()};
if (handler)
{
handler (type, context,
QDateTime::currentDateTimeUtc ().toString ("yy-MM-ddTHH:mm:ss.zzzZ: ") + msg);
}
}
static QStack<QtMessageHandler> prior_handlers_;
};
QStack<QtMessageHandler> MessageTimestamper::prior_handlers_;
}
int main(int argc, char *argv[])
{
// Add timestamps to all debug messages
MessageTimestamper message_timestamper;
init_random_seed ();
// make the Qt type magic happen
Radio::register_types ();
register_types ();
// Multiple instances communicate with jt9 via this
QSharedMemory mem_jt9;
QApplication a(argc, argv);
try
{
setlocale (LC_NUMERIC, "C"); // ensure number forms are in
// consistent format, do this after
// instantiating QApplication so
// that GUI has correct l18n
// Override programs executable basename as application name.
a.setApplicationName ("WSJT-X");
a.setApplicationVersion (version ());
#if QT_VERSION >= 0x050200
QCommandLineParser parser;
parser.setApplicationDescription ("\n" PROJECT_SUMMARY_DESCRIPTION);
auto help_option = parser.addHelpOption ();
auto version_option = parser.addVersionOption ();
// support for multiple instances running from a single installation
QCommandLineOption rig_option (QStringList {} << "r" << "rig-name"
, a.translate ("main", "Where <rig-name> is for multi-instance support.")
, a.translate ("main", "rig-name"));
parser.addOption (rig_option);
// support for start up configuration
QCommandLineOption cfg_option (QStringList {} << "c" << "config"
, a.translate ("main", "Where <configuration> is an existing one.")
, a.translate ("main", "configuration"));
parser.addOption (cfg_option);
QCommandLineOption test_option (QStringList {} << "test-mode"
, a.translate ("main", "Writable files in test location. Use with caution, for testing only."));
parser.addOption (test_option);
if (!parser.parse (a.arguments ()))
{
MessageBox::critical_message (nullptr, a.translate ("main", "Command line error"), parser.errorText ());
return -1;
}
else
{
if (parser.isSet (help_option))
{
MessageBox::information_message (nullptr, a.translate ("main", "Command line help"), parser.helpText ());
return 0;
}
else if (parser.isSet (version_option))
{
MessageBox::information_message (nullptr, a.translate ("main", "Application version"), a.applicationVersion ());
return 0;
}
}
QStandardPaths::setTestModeEnabled (parser.isSet (test_option));
// support for multiple instances running from a single installation
bool multiple {false};
if (parser.isSet (rig_option) || parser.isSet (test_option))
{
auto temp_name = parser.value (rig_option);
if (!temp_name.isEmpty ())
{
if (temp_name.contains (QRegularExpression {R"([\\/,])"}))
{
std::cerr << QObject::tr ("Invalid rig name - \\ & / not allowed").toLocal8Bit ().data () << std::endl;
parser.showHelp (-1);
}
a.setApplicationName (a.applicationName () + " - " + temp_name);
}
if (parser.isSet (test_option))
{
a.setApplicationName (a.applicationName () + " - test");
}
multiple = true;
}
// now we have the application name we can open the settings
MultiSettings multi_settings {parser.value (cfg_option)};
// find the temporary files path
QDir temp_dir {QStandardPaths::writableLocation (QStandardPaths::TempLocation)};
Q_ASSERT (temp_dir.exists ()); // sanity check
// disallow multiple instances with same instance key
QLockFile instance_lock {temp_dir.absoluteFilePath (a.applicationName () + ".lock")};
instance_lock.setStaleLockTime (0);
bool lock_ok {false};
while (!(lock_ok = instance_lock.tryLock ()))
{
if (QLockFile::LockFailedError == instance_lock.error ())
{
auto button = MessageBox::query_message (nullptr
, a.translate ("main", "Another instance may be running")
, a.translate ("main", "try to remove stale lock file?")
, QString {}
, MessageBox::Yes | MessageBox::Retry | MessageBox::No
, MessageBox::Yes);
switch (button)
{
case MessageBox::Yes:
instance_lock.removeStaleLockFile ();
break;
case MessageBox::Retry:
break;
default:
throw std::runtime_error {"Multiple instances must have unique rig names"};
}
}
}
#endif
#if WSJT_QDEBUG_TO_FILE
// Open a trace file
TraceFile trace_file {temp_dir.absoluteFilePath (a.applicationName () + "_trace.log")};
qDebug () << program_title (revision ()) + " - Program startup";
#endif
// Create a unique writeable temporary directory in a suitable location
bool temp_ok {false};
QString unique_directory {QApplication::applicationName ()};
do
{
if (!temp_dir.mkpath (unique_directory)
|| !temp_dir.cd (unique_directory))
{
MessageBox::critical_message (nullptr,
a.translate ("main", "Failed to create a temporary directory"),
a.translate ("main", "Path: \"%1\"").arg (temp_dir.absolutePath ()));
throw std::runtime_error {"Failed to create a temporary directory"};
}
if (!temp_dir.isReadable () || !(temp_ok = QTemporaryFile {temp_dir.absoluteFilePath ("test")}.open ()))
{
auto button = MessageBox::critical_message (nullptr,
a.translate ("main", "Failed to create a usable temporary directory"),
a.translate ("main", "Another application may be locking the directory"),
a.translate ("main", "Path: \"%1\"").arg (temp_dir.absolutePath ()),
MessageBox::Retry | MessageBox::Cancel);
if (MessageBox::Cancel == button)
{
throw std::runtime_error {"Failed to create a usable temporary directory"};
}
temp_dir.cdUp (); // revert to parent as this one is no good
}
}
while (!temp_ok);
SplashScreen splash;
{
// change this key if you want to force a new splash screen
// for a new version, the user will be able to re-disable it
// if they wish
QString splash_flag_name {"Splash_v1.7"};
if (multi_settings.common_value (splash_flag_name, true).toBool ())
{
QObject::connect (&splash, &SplashScreen::disabled, [&, splash_flag_name] {
multi_settings.set_common_value (splash_flag_name, false);
splash.close ();
});
splash.show ();
a.processEvents ();
}
}
int result;
do
{
#if WSJT_QDEBUG_TO_FILE
// announce to trace file and dump settings
qDebug () << "++++++++++++++++++++++++++++ Settings ++++++++++++++++++++++++++++";
for (auto const& key: multi_settings.settings ()->allKeys ())
{
auto const& value = multi_settings.settings ()->value (key);
if (value.canConvert<QVariantList> ())
{
auto const sequence = value.value<QSequentialIterable> ();
qDebug ().nospace () << key << ": ";
for (auto const& item: sequence)
{
qDebug ().nospace () << '\t' << item;
}
}
else
{
qDebug ().nospace () << key << ": " << value;
}
}
qDebug () << "---------------------------- Settings ----------------------------";
#endif
// Create and initialize shared memory segment
// Multiple instances: use rig_name as shared memory key
mem_jt9.setKey(a.applicationName ());
if(!mem_jt9.attach()) {
if (!mem_jt9.create(sizeof(struct dec_data))) {
splash.hide ();
MessageBox::critical_message (nullptr, a.translate ("main", "Shared memory error"),
a.translate ("main", "Unable to create shared memory segment"));
throw std::runtime_error {"Shared memory error"};
}
}
memset(mem_jt9.data(),0,sizeof(struct dec_data)); //Zero all decoding params in shared memory
unsigned downSampleFactor;
{
SettingsGroup {multi_settings.settings (), "Tune"};
// deal with Windows Vista and earlier input audio rate
// converter problems
downSampleFactor = multi_settings.settings ()->value ("Audio/DisableInputResampling",
#if defined (Q_OS_WIN)
// default to true for
// Windows Vista and older
QSysInfo::WV_VISTA >= QSysInfo::WindowsVersion ? true : false
#else
false
#endif
).toBool () ? 1u : 4u;
}
// run the application UI
MainWindow w(temp_dir, multiple, &multi_settings, &mem_jt9, downSampleFactor, &splash);
w.show();
splash.raise ();
QObject::connect (&a, SIGNAL (lastWindowClosed()), &a, SLOT (quit()));
result = a.exec();
}
while (!result && !multi_settings.exit ());
// clean up lazily initialized resources
{
int nfft {-1};
int ndim {1};
int isign {1};
int iform {1};
// free FFT plan resources
four2a_ (nullptr, &nfft, &ndim, &isign, &iform, 0);
}
fftwf_forget_wisdom ();
fftwf_cleanup ();
temp_dir.removeRecursively (); // clean up temp files
return result;
}
catch (std::exception const& e)
{
MessageBox::critical_message (nullptr, a.translate ("main", "Fatal error"), e.what ());
std::cerr << "Error: " << e.what () << '\n';
}
catch (...)
{
MessageBox::critical_message (nullptr, a.translate ("main", "Unexpected fatal error"));
std::cerr << "Unexpected fatal error\n";
throw; // hoping the runtime might tell us more about the exception
}
return -1;
}
@@ -0,0 +1,2 @@
#!/bin/bash
exit 0
@@ -0,0 +1,103 @@
//---------------------------------------------------------------------------//
// Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@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_ALGORITHM_DETAIL_SERIAL_SCAN_HPP
#define BOOST_COMPUTE_ALGORITHM_DETAIL_SERIAL_SCAN_HPP
#include <iterator>
#include <boost/compute/device.hpp>
#include <boost/compute/kernel.hpp>
#include <boost/compute/command_queue.hpp>
#include <boost/compute/detail/meta_kernel.hpp>
#include <boost/compute/detail/iterator_range_size.hpp>
namespace boost {
namespace compute {
namespace detail {
template<class InputIterator, class OutputIterator, class T, class BinaryOperator>
inline OutputIterator serial_scan(InputIterator first,
InputIterator last,
OutputIterator result,
bool exclusive,
T init,
BinaryOperator op,
command_queue &queue)
{
if(first == last){
return result;
}
typedef typename
std::iterator_traits<InputIterator>::value_type input_type;
typedef typename
std::iterator_traits<OutputIterator>::value_type output_type;
const context &context = queue.get_context();
// create scan kernel
meta_kernel k("serial_scan");
// Arguments
size_t n_arg = k.add_arg<ulong_>("n");
size_t init_arg = k.add_arg<output_type>("initial_value");
if(!exclusive){
k <<
k.decl<const ulong_>("start_idx") << " = 1;\n" <<
k.decl<output_type>("sum") << " = " << first[0] << ";\n" <<
result[0] << " = sum;\n";
}
else {
k <<
k.decl<const ulong_>("start_idx") << " = 0;\n" <<
k.decl<output_type>("sum") << " = initial_value;\n";
}
k <<
"for(ulong i = start_idx; i < n; i++){\n" <<
k.decl<const input_type>("x") << " = "
<< first[k.var<ulong_>("i")] << ";\n";
if(exclusive){
k << result[k.var<ulong_>("i")] << " = sum;\n";
}
k << " sum = "
<< op(k.var<output_type>("sum"), k.var<output_type>("x"))
<< ";\n";
if(!exclusive){
k << result[k.var<ulong_>("i")] << " = sum;\n";
}
k << "}\n";
// compile scan kernel
kernel scan_kernel = k.compile(context);
// setup kernel arguments
size_t n = detail::iterator_range_size(first, last);
scan_kernel.set_arg<ulong_>(n_arg, n);
scan_kernel.set_arg<output_type>(init_arg, static_cast<output_type>(init));
// execute the kernel
queue.enqueue_1d_range_kernel(scan_kernel, 0, 1, 1);
// return iterator pointing to the end of the result range
return result + n;
}
} // end detail namespace
} // end compute namespace
} // end boost namespace
#endif // BOOST_COMPUTE_ALGORITHM_DETAIL_SERIAL_SCAN_HPP
@@ -0,0 +1,141 @@
// 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/times.hpp" header
// -- DO NOT modify by hand!
namespace boost { namespace mpl {
template<
typename Tag1
, typename Tag2
>
struct times_impl
: if_c<
( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1)
> BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2)
)
, aux::cast2nd_impl< times_impl< Tag1,Tag1 >,Tag1, Tag2 >
, aux::cast1st_impl< times_impl< Tag2,Tag2 >,Tag1, Tag2 >
>::type
{
};
/// for Digital Mars C++/compilers with no CTPS/TTP support
template<> struct times_impl< na,na >
{
template< typename U1, typename U2 > struct apply
{
typedef apply type;
BOOST_STATIC_CONSTANT(int, value = 0);
};
};
template< typename Tag > struct times_impl< na,Tag >
{
template< typename U1, typename U2 > struct apply
{
typedef apply type;
BOOST_STATIC_CONSTANT(int, value = 0);
};
};
template< typename Tag > struct times_impl< Tag,na >
{
template< typename U1, typename U2 > struct apply
{
typedef apply type;
BOOST_STATIC_CONSTANT(int, value = 0);
};
};
template< typename T > struct times_tag
{
typedef typename T::tag type;
};
template<
typename BOOST_MPL_AUX_NA_PARAM(N1)
, typename BOOST_MPL_AUX_NA_PARAM(N2)
, typename N3 = na, typename N4 = na, typename N5 = na
>
struct times
: times< times< times< times< N1,N2 >, N3>, N4>, N5>
{
};
template<
typename N1, typename N2, typename N3, typename N4
>
struct times< N1,N2,N3,N4,na >
: times< times< times< N1,N2 >, N3>, N4>
{
BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(
5
, times
, ( N1, N2, N3, N4, na )
)
};
template<
typename N1, typename N2, typename N3
>
struct times< N1,N2,N3,na,na >
: times< times< N1,N2 >, N3>
{
BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(
5
, times
, ( N1, N2, N3, na, na )
)
};
template<
typename N1, typename N2
>
struct times< N1,N2,na,na,na >
: times_impl<
typename times_tag<N1>::type
, typename times_tag<N2>::type
>::template apply< N1,N2 >::type
{
BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(
5
, times
, ( N1, N2, na, na, na )
)
};
BOOST_MPL_AUX_NA_SPEC2(2, 5, times)
}}
namespace boost { namespace mpl {
template<>
struct times_impl< integral_c_tag,integral_c_tag >
{
template< typename N1, typename N2 > struct apply
: integral_c<
typename aux::largest_int<
typename N1::value_type
, typename N2::value_type
>::type
, ( BOOST_MPL_AUX_VALUE_WKND(N1)::value
* BOOST_MPL_AUX_VALUE_WKND(N2)::value
)
>
{
};
};
}}
@@ -0,0 +1,69 @@
#ifndef BOOST_BIND_ARG_HPP_INCLUDED
#define BOOST_BIND_ARG_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// bind/arg.hpp
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
//
// Distributed under the 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/bind/bind.html for documentation.
//
#include <boost/config.hpp>
#include <boost/is_placeholder.hpp>
namespace boost
{
template<bool Eq> struct _arg_eq
{
};
template<> struct _arg_eq<true>
{
typedef void type;
};
template< int I > struct arg
{
BOOST_CONSTEXPR arg()
{
}
template< class T > BOOST_CONSTEXPR arg( T const & /* t */, typename _arg_eq< I == is_placeholder<T>::value >::type * = 0 )
{
}
};
template< int I > BOOST_CONSTEXPR bool operator==( arg<I> const &, arg<I> const & )
{
return true;
}
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
template< int I > struct is_placeholder< arg<I> >
{
enum _vt { value = I };
};
template< int I > struct is_placeholder< arg<I> (*) () >
{
enum _vt { value = I };
};
#endif
} // namespace boost
#endif // #ifndef BOOST_BIND_ARG_HPP_INCLUDED
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

@@ -0,0 +1,16 @@
///////////////////////////////////////////////////////////////////////////////
/// \file functional.hpp
/// Proto callables for various things
//
// Copyright 2010 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_FUNCTIONAL_HPP_EAN_11_27_2010
#define BOOST_PROTO_FUNCTIONAL_HPP_EAN_11_27_2010
#include <boost/proto/functional/std.hpp>
#include <boost/proto/functional/fusion.hpp>
#include <boost/proto/functional/range.hpp>
#endif
@@ -0,0 +1,319 @@
// (C) Copyright John Maddock 2001 - 2003.
// (C) Copyright David Abrahams 2002 - 2003.
// (C) Copyright Aleksey Gurtovoy 2002.
// 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 for most recent version.
// Borland C++ compiler setup:
//
// versions check:
// we don't support Borland prior to version 5.4:
#if __BORLANDC__ < 0x540
# error "Compiler not supported or configured - please reconfigure"
#endif
// last known compiler version:
#if (__BORLANDC__ > 0x613)
//# if defined(BOOST_ASSERT_CONFIG)
# error "Unknown compiler version - please run the configure tests and report the results"
//# else
//# pragma message( "Unknown compiler version - please run the configure tests and report the results")
//# endif
#elif (__BORLANDC__ == 0x600)
# error "CBuilderX preview compiler is no longer supported"
#endif
//
// Support macros to help with standard library detection
#if (__BORLANDC__ < 0x560) || defined(_USE_OLD_RW_STL)
# define BOOST_BCB_WITH_ROGUE_WAVE
#elif __BORLANDC__ < 0x570
# define BOOST_BCB_WITH_STLPORT
#else
# define BOOST_BCB_WITH_DINKUMWARE
#endif
//
// Version 5.0 and below:
# if __BORLANDC__ <= 0x0550
// Borland C++Builder 4 and 5:
# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS
# if __BORLANDC__ == 0x0550
// Borland C++Builder 5, command-line compiler 5.5:
# define BOOST_NO_OPERATORS_IN_NAMESPACE
# endif
// Variadic macros do not exist for C++ Builder versions 5 and below
#define BOOST_NO_CXX11_VARIADIC_MACROS
# endif
// Version 5.51 and below:
#if (__BORLANDC__ <= 0x551)
# define BOOST_NO_CV_SPECIALIZATIONS
# define BOOST_NO_CV_VOID_SPECIALIZATIONS
# define BOOST_NO_DEDUCED_TYPENAME
// workaround for missing WCHAR_MAX/WCHAR_MIN:
#ifdef __cplusplus
#include <climits>
#include <cwchar>
#else
#include <limits.h>
#include <wchar.h>
#endif // __cplusplus
#ifndef WCHAR_MAX
# define WCHAR_MAX 0xffff
#endif
#ifndef WCHAR_MIN
# define WCHAR_MIN 0
#endif
#endif
// Borland C++ Builder 6 and below:
#if (__BORLANDC__ <= 0x564)
# if defined(NDEBUG) && defined(__cplusplus)
// fix broken <cstring> so that Boost.test works:
# include <cstring>
# undef strcmp
# endif
// fix broken errno declaration:
# include <errno.h>
# ifndef errno
# define errno errno
# endif
#endif
//
// new bug in 5.61:
#if (__BORLANDC__ >= 0x561) && (__BORLANDC__ <= 0x580)
// this seems to be needed by the command line compiler, but not the IDE:
# define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS
#endif
// Borland C++ Builder 2006 Update 2 and below:
#if (__BORLANDC__ <= 0x582)
# define BOOST_NO_SFINAE
# define BOOST_BCB_PARTIAL_SPECIALIZATION_BUG
# define BOOST_NO_TEMPLATE_TEMPLATES
# define BOOST_NO_PRIVATE_IN_AGGREGATE
# ifdef _WIN32
# define BOOST_NO_SWPRINTF
# elif defined(linux) || defined(__linux__) || defined(__linux)
// we should really be able to do without this
// but the wcs* functions aren't imported into std::
# define BOOST_NO_STDC_NAMESPACE
// _CPPUNWIND doesn't get automatically set for some reason:
# pragma defineonoption BOOST_CPPUNWIND -x
# endif
#endif
#if (__BORLANDC__ <= 0x613) // Beman has asked Alisdair for more info
// we shouldn't really need this - but too many things choke
// without it, this needs more investigation:
# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
# define BOOST_NO_IS_ABSTRACT
# define BOOST_NO_FUNCTION_TYPE_SPECIALIZATIONS
# define BOOST_NO_USING_TEMPLATE
# define BOOST_SP_NO_SP_CONVERTIBLE
// Temporary workaround
#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
#endif
// Borland C++ Builder 2008 and below:
# define BOOST_NO_INTEGRAL_INT64_T
# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL
# define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS
# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS
# define BOOST_NO_TWO_PHASE_NAME_LOOKUP
# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE
# define BOOST_NO_NESTED_FRIENDSHIP
# define BOOST_NO_TYPENAME_WITH_CTOR
#if (__BORLANDC__ < 0x600)
# define BOOST_ILLEGAL_CV_REFERENCES
#endif
//
// Positive Feature detection
//
// Borland C++ Builder 2008 and below:
#if (__BORLANDC__ >= 0x599)
# pragma defineonoption BOOST_CODEGEAR_0X_SUPPORT -Ax
#endif
//
// C++0x Macros:
//
#if !defined( BOOST_CODEGEAR_0X_SUPPORT ) || (__BORLANDC__ < 0x610)
# define BOOST_NO_CXX11_CHAR16_T
# define BOOST_NO_CXX11_CHAR32_T
# define BOOST_NO_CXX11_DECLTYPE
# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
# define BOOST_NO_CXX11_EXTERN_TEMPLATE
# define BOOST_NO_CXX11_RVALUE_REFERENCES
# define BOOST_NO_CXX11_SCOPED_ENUMS
# define BOOST_NO_CXX11_STATIC_ASSERT
#else
# define BOOST_HAS_ALIGNOF
# define BOOST_HAS_CHAR16_T
# define BOOST_HAS_CHAR32_T
# define BOOST_HAS_DECLTYPE
# define BOOST_HAS_EXPLICIT_CONVERSION_OPS
# define BOOST_HAS_REF_QUALIFIER
# define BOOST_HAS_RVALUE_REFS
# define BOOST_HAS_STATIC_ASSERT
#endif
#define BOOST_NO_CXX11_AUTO_DECLARATIONS
#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS
#define BOOST_NO_CXX11_CONSTEXPR
#define BOOST_NO_CXX11_DECLTYPE_N3276
#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
#define BOOST_NO_CXX11_DELETED_FUNCTIONS
#define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#define BOOST_NO_CXX11_LAMBDAS
#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS
#define BOOST_NO_CXX11_NULLPTR
#define BOOST_NO_CXX11_RANGE_BASED_FOR
#define BOOST_NO_CXX11_RAW_LITERALS
#define BOOST_NO_CXX11_RVALUE_REFERENCES
#define BOOST_NO_CXX11_SCOPED_ENUMS
#define BOOST_NO_SFINAE_EXPR
#define BOOST_NO_CXX11_TEMPLATE_ALIASES
#define BOOST_NO_CXX11_UNICODE_LITERALS // UTF-8 still not supported
#define BOOST_NO_CXX11_VARIADIC_TEMPLATES
#define BOOST_NO_CXX11_NOEXCEPT
#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
#define BOOST_NO_CXX11_USER_DEFINED_LITERALS
#define BOOST_NO_CXX11_ALIGNAS
#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
#define BOOST_NO_CXX11_INLINE_NAMESPACES
#define BOOST_NO_CXX11_REF_QUALIFIERS
#define BOOST_NO_CXX11_FINAL
#define BOOST_NO_CXX11_THREAD_LOCAL
// C++ 14:
#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304)
# define BOOST_NO_CXX14_AGGREGATE_NSDMI
#endif
#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304)
# define BOOST_NO_CXX14_BINARY_LITERALS
#endif
#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304)
# define BOOST_NO_CXX14_CONSTEXPR
#endif
#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304)
# define BOOST_NO_CXX14_DECLTYPE_AUTO
#endif
#if (__cplusplus < 201304) // There's no SD6 check for this....
# define BOOST_NO_CXX14_DIGIT_SEPARATORS
#endif
#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304)
# define BOOST_NO_CXX14_GENERIC_LAMBDAS
#endif
#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304)
# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES
#endif
#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304)
# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION
#endif
#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304)
# define BOOST_NO_CXX14_VARIABLE_TEMPLATES
#endif
#if __BORLANDC__ >= 0x590
# define BOOST_HAS_TR1_HASH
# define BOOST_HAS_MACRO_USE_FACET
#endif
//
// Post 0x561 we have long long and stdint.h:
#if __BORLANDC__ >= 0x561
# ifndef __NO_LONG_LONG
# define BOOST_HAS_LONG_LONG
# else
# define BOOST_NO_LONG_LONG
# endif
// On non-Win32 platforms let the platform config figure this out:
# ifdef _WIN32
# define BOOST_HAS_STDINT_H
# endif
#endif
// Borland C++Builder 6 defaults to using STLPort. If _USE_OLD_RW_STL is
// defined, then we have 0x560 or greater with the Rogue Wave implementation
// which presumably has the std::DBL_MAX bug.
#if defined( BOOST_BCB_WITH_ROGUE_WAVE )
// <climits> is partly broken, some macros define symbols that are really in
// namespace std, so you end up having to use illegal constructs like
// std::DBL_MAX, as a fix we'll just include float.h and have done with:
#include <float.h>
#endif
//
// __int64:
//
#if (__BORLANDC__ >= 0x530) && !defined(__STRICT_ANSI__)
# define BOOST_HAS_MS_INT64
#endif
//
// check for exception handling support:
//
#if !defined(_CPPUNWIND) && !defined(BOOST_CPPUNWIND) && !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS)
# define BOOST_NO_EXCEPTIONS
#endif
//
// all versions have a <dirent.h>:
//
#ifndef __STRICT_ANSI__
# define BOOST_HAS_DIRENT_H
#endif
//
// all versions support __declspec:
//
#if defined(__STRICT_ANSI__)
// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined
# define BOOST_SYMBOL_EXPORT
#endif
//
// ABI fixing headers:
//
#if __BORLANDC__ != 0x600 // not implemented for version 6 compiler yet
#ifndef BOOST_ABI_PREFIX
# define BOOST_ABI_PREFIX "boost/config/abi/borland_prefix.hpp"
#endif
#ifndef BOOST_ABI_SUFFIX
# define BOOST_ABI_SUFFIX "boost/config/abi/borland_suffix.hpp"
#endif
#endif
//
// Disable Win32 support in ANSI mode:
//
#if __BORLANDC__ < 0x600
# pragma defineonoption BOOST_DISABLE_WIN32 -A
#elif defined(__STRICT_ANSI__)
# define BOOST_DISABLE_WIN32
#endif
//
// MSVC compatibility mode does some nasty things:
// TODO: look up if this doesn't apply to the whole 12xx range
//
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
# define BOOST_NO_VOID_RETURNS
#endif
// Borland did not implement value-initialization completely, as I reported
// in 2007, Borland Report 51854, "Value-initialization: POD struct should be
// zero-initialized", http://qc.embarcadero.com/wc/qcmain.aspx?d=51854
// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues
// (Niels Dekker, LKEB, April 2010)
#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION
#define BOOST_COMPILER "Borland C++ version " BOOST_STRINGIZE(__BORLANDC__)
@@ -0,0 +1,16 @@
/*=============================================================================
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)
This is an auto-generated file. Do not edit!
==============================================================================*/
namespace boost { namespace fusion
{
struct void_;
template <
typename T0 = void_ , typename T1 = void_ , typename T2 = void_ , typename T3 = void_ , typename T4 = void_ , typename T5 = void_ , typename T6 = void_ , typename T7 = void_ , typename T8 = void_ , typename T9 = void_ , typename T10 = void_ , typename T11 = void_ , typename T12 = void_ , typename T13 = void_ , typename T14 = void_ , typename T15 = void_ , typename T16 = void_ , typename T17 = void_ , typename T18 = void_ , typename T19 = void_ , typename T20 = void_ , typename T21 = void_ , typename T22 = void_ , typename T23 = void_ , typename T24 = void_ , typename T25 = void_ , typename T26 = void_ , typename T27 = void_ , typename T28 = void_ , typename T29 = void_ , typename T30 = void_ , typename T31 = void_ , typename T32 = void_ , typename T33 = void_ , typename T34 = void_ , typename T35 = void_ , typename T36 = void_ , typename T37 = void_ , typename T38 = void_ , typename T39 = void_ , typename T40 = void_ , typename T41 = void_ , typename T42 = void_ , typename T43 = void_ , typename T44 = void_ , typename T45 = void_ , typename T46 = void_ , typename T47 = void_ , typename T48 = void_ , typename T49 = void_
>
struct list;
}}