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
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,40 @@
/*=============================================================================
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_ERASE_10022005_1835)
#define FUSION_ERASE_10022005_1835
#include <boost/fusion/support/config.hpp>
#include <boost/mpl/erase.hpp>
#include <boost/fusion/support/tag_of.hpp>
#include <boost/fusion/algorithm/transformation/erase.hpp>
#include <boost/fusion/sequence/convert.hpp>
namespace boost { namespace mpl
{
template <typename Tag>
struct erase_impl;
template <>
struct erase_impl<fusion::fusion_sequence_tag>
{
template <typename Sequence, typename First, typename Last>
struct apply
{
typedef typename
fusion::result_of::erase<Sequence, First, Last>::type
result;
typedef typename
fusion::result_of::convert<
typename fusion::detail::tag_of<Sequence>::type, result>::type
type;
};
};
}}
#endif
@@ -0,0 +1,60 @@
#ifndef BOOST_SERIALIZATION_ASSUME_ABSTRACT_HPP
#define BOOST_SERIALIZATION_ASSUME_ABSTRACT_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// assume_abstract_class.hpp:
// (C) Copyright 2008 Robert Ramey
// 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.
// this is useful for compilers which don't support the boost::is_abstract
#include <boost/type_traits/is_abstract.hpp>
#include <boost/mpl/bool_fwd.hpp>
#ifndef BOOST_NO_IS_ABSTRACT
// if there is an intrinsic is_abstract defined, we don't have to do anything
#define BOOST_SERIALIZATION_ASSUME_ABSTRACT(T)
// but forward to the "official" is_abstract
namespace boost {
namespace serialization {
template<class T>
struct is_abstract : boost::is_abstract< T > {} ;
} // namespace serialization
} // namespace boost
#else
// we have to "make" one
namespace boost {
namespace serialization {
template<class T>
struct is_abstract : boost::false_type {};
} // namespace serialization
} // namespace boost
// define a macro to make explicit designation of this more transparent
#define BOOST_SERIALIZATION_ASSUME_ABSTRACT(T) \
namespace boost { \
namespace serialization { \
template<> \
struct is_abstract< T > : boost::true_type {}; \
template<> \
struct is_abstract< const T > : boost::true_type {}; \
}} \
/**/
#endif // BOOST_NO_IS_ABSTRACT
#endif //BOOST_SERIALIZATION_ASSUME_ABSTRACT_HPP
@@ -0,0 +1,206 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2014
// (C) Copyright Microsoft Corporation 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/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_MPL_HPP
#define BOOST_INTRUSIVE_DETAIL_MPL_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/move/detail/type_traits.hpp>
#include <cstddef>
namespace boost {
namespace intrusive {
namespace detail {
using boost::move_detail::is_same;
using boost::move_detail::add_const;
using boost::move_detail::remove_const;
using boost::move_detail::remove_cv;
using boost::move_detail::remove_reference;
using boost::move_detail::add_reference;
using boost::move_detail::remove_pointer;
using boost::move_detail::add_pointer;
using boost::move_detail::true_type;
using boost::move_detail::false_type;
using boost::move_detail::enable_if_c;
using boost::move_detail::enable_if;
using boost::move_detail::disable_if_c;
using boost::move_detail::disable_if;
using boost::move_detail::is_convertible;
using boost::move_detail::if_c;
using boost::move_detail::if_;
using boost::move_detail::is_const;
using boost::move_detail::identity;
using boost::move_detail::alignment_of;
using boost::move_detail::is_empty;
using boost::move_detail::addressof;
using boost::move_detail::integral_constant;
using boost::move_detail::enable_if_convertible;
using boost::move_detail::disable_if_convertible;
using boost::move_detail::bool_;
using boost::move_detail::true_;
using boost::move_detail::false_;
using boost::move_detail::yes_type;
using boost::move_detail::no_type;
using boost::move_detail::apply;
using boost::move_detail::eval_if_c;
using boost::move_detail::eval_if;
using boost::move_detail::unvoid_ref;
using boost::move_detail::add_const_if_c;
template<std::size_t S>
struct ls_zeros
{
static const std::size_t value = (S & std::size_t(1)) ? 0 : (1 + ls_zeros<(S>>1u)>::value);
};
template<>
struct ls_zeros<0>
{
static const std::size_t value = 0;
};
template<>
struct ls_zeros<1>
{
static const std::size_t value = 0;
};
// Infrastructure for providing a default type for T::TNAME if absent.
#define BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(TNAME) \
template <typename T, typename DefaultType> \
struct boost_intrusive_default_type_ ## TNAME \
{ \
template <typename X> \
static char test(int, typename X::TNAME*); \
\
template <typename X> \
static int test(...); \
\
struct DefaultWrap { typedef DefaultType TNAME; }; \
\
static const bool value = (1 == sizeof(test<T>(0, 0))); \
\
typedef typename \
::boost::intrusive::detail::if_c \
<value, T, DefaultWrap>::type::TNAME type; \
}; \
//
#define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \
typename INSTANTIATION_NS_PREFIX \
boost_intrusive_default_type_ ## TNAME< T, TIMPL >::type \
//
#define BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(TNAME)\
template <typename T, typename DefaultType> \
struct boost_intrusive_eval_default_type_ ## TNAME \
{ \
template <typename X> \
static char test(int, typename X::TNAME*); \
\
template <typename X> \
static int test(...); \
\
struct DefaultWrap \
{ typedef typename DefaultType::type TNAME; }; \
\
static const bool value = (1 == sizeof(test<T>(0, 0))); \
\
typedef typename \
::boost::intrusive::detail::eval_if_c \
< value \
, ::boost::intrusive::detail::identity<T> \
, ::boost::intrusive::detail::identity<DefaultWrap> \
>::type::TNAME type; \
}; \
//
#define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \
typename INSTANTIATION_NS_PREFIX \
boost_intrusive_eval_default_type_ ## TNAME< T, TIMPL >::type \
//
#define BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(TRAITS_PREFIX, TYPEDEF_TO_FIND) \
template <class T>\
struct TRAITS_PREFIX##_bool\
{\
template<bool Add>\
struct two_or_three {yes_type _[2 + Add];};\
template <class U> static yes_type test(...);\
template <class U> static two_or_three<U::TYPEDEF_TO_FIND> test (int);\
static const std::size_t value = sizeof(test<T>(0));\
};\
\
template <class T>\
struct TRAITS_PREFIX##_bool_is_true\
{\
static const bool value = TRAITS_PREFIX##_bool<T>::value > sizeof(yes_type)*2;\
};\
//
#define BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(TRAITS_NAME, FUNC_NAME) \
template <typename U, typename Signature> \
class TRAITS_NAME \
{ \
private: \
template<Signature> struct helper;\
template<typename T> \
static ::boost::intrusive::detail::yes_type test(helper<&T::FUNC_NAME>*); \
template<typename T> static ::boost::intrusive::detail::no_type test(...); \
public: \
static const bool value = sizeof(test<U>(0)) == sizeof(::boost::intrusive::detail::yes_type); \
}; \
//
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME, FUNC_NAME) \
template <typename Type> \
struct TRAITS_NAME \
{ \
struct BaseMixin \
{ \
void FUNC_NAME(); \
}; \
struct Base : public Type, public BaseMixin { Base(); }; \
template <typename T, T t> class Helper{}; \
template <typename U> \
static ::boost::intrusive::detail::no_type test(U*, Helper<void (BaseMixin::*)(), &U::FUNC_NAME>* = 0); \
static ::boost::intrusive::detail::yes_type test(...); \
static const bool value = sizeof(::boost::intrusive::detail::yes_type) == sizeof(test((Base*)(0))); \
};\
//
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(TRAITS_NAME, FUNC_NAME) \
BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME##_ignore_signature, FUNC_NAME) \
\
template <typename Type, class> \
struct TRAITS_NAME \
: public TRAITS_NAME##_ignore_signature<Type> \
{};\
//
} //namespace detail
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_DETAIL_MPL_HPP
@@ -0,0 +1,43 @@
//---------------------------------------------------------------------------//
// 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_IS_PARTITIONED_HPP
#define BOOST_COMPUTE_ALGORITHM_IS_PARTITIONED_HPP
#include <boost/compute/system.hpp>
#include <boost/compute/command_queue.hpp>
#include <boost/compute/algorithm/find_if.hpp>
#include <boost/compute/algorithm/find_if_not.hpp>
namespace boost {
namespace compute {
/// Returns \c true if the values in the range [\p first, \p last)
/// are partitioned according to \p predicate.
template<class InputIterator, class UnaryPredicate>
inline bool is_partitioned(InputIterator first,
InputIterator last,
UnaryPredicate predicate,
command_queue &queue = system::default_queue())
{
return ::boost::compute::find_if(
::boost::compute::find_if_not(first,
last,
predicate,
queue),
last,
predicate,
queue) == last;
}
} // end compute namespace
} // end boost namespace
#endif // BOOST_COMPUTE_ALGORITHM_PARTITION_HPP
@@ -0,0 +1,69 @@
#ifndef BOOST_CORE_CHECKED_DELETE_HPP
#define BOOST_CORE_CHECKED_DELETE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/checked_delete.hpp
//
// Copyright (c) 2002, 2003 Peter Dimov
// Copyright (c) 2003 Daniel Frey
// Copyright (c) 2003 Howard Hinnant
//
// Distributed under the 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/core/doc/html/core/checked_delete.html for documentation.
//
namespace boost
{
// verify that types are complete for increased safety
template<class T> inline void checked_delete(T * x)
{
// intentionally complex - simplification causes regressions
typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
(void) sizeof(type_must_be_complete);
delete x;
}
template<class T> inline void checked_array_delete(T * x)
{
typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
(void) sizeof(type_must_be_complete);
delete [] x;
}
template<class T> struct checked_deleter
{
typedef void result_type;
typedef T * argument_type;
void operator()(T * x) const
{
// boost:: disables ADL
boost::checked_delete(x);
}
};
template<class T> struct checked_array_deleter
{
typedef void result_type;
typedef T * argument_type;
void operator()(T * x) const
{
boost::checked_array_delete(x);
}
};
} // namespace boost
#endif // #ifndef BOOST_CORE_CHECKED_DELETE_HPP
@@ -0,0 +1,230 @@
// Copyright David Abrahams 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)
#ifndef ITERATOR_DWA2002510_HPP
# define ITERATOR_DWA2002510_HPP
# include <boost/python/detail/prefix.hpp>
# include <boost/python/class.hpp>
# include <boost/python/return_value_policy.hpp>
# include <boost/python/return_by_value.hpp>
# include <boost/python/handle.hpp>
# include <boost/python/make_function.hpp>
# include <boost/python/object/iterator_core.hpp>
# include <boost/python/object/class_detail.hpp>
# include <boost/python/object/function_object.hpp>
# include <boost/mpl/vector/vector10.hpp>
# include <boost/mpl/if.hpp>
# include <boost/python/detail/raw_pyobject.hpp>
# include <boost/type.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/type_traits/add_reference.hpp>
# include <boost/type_traits/add_const.hpp>
# include <boost/detail/iterator.hpp>
namespace boost { namespace python { namespace objects {
// CallPolicies for the next() method of iterators. We don't want
// users to have to explicitly specify that the references returned by
// iterators are copied, so we just replace the result_converter from
// the default_iterator_call_policies with a permissive one which
// always copies the result.
typedef return_value_policy<return_by_value> default_iterator_call_policies;
// Instantiations of these are wrapped to produce Python iterators.
template <class NextPolicies, class Iterator>
struct iterator_range
{
iterator_range(object sequence, Iterator start, Iterator finish);
typedef boost::detail::iterator_traits<Iterator> traits_t;
struct next
{
typedef typename mpl::if_<
is_reference<
typename traits_t::reference
>
, typename traits_t::reference
, typename traits_t::value_type
>::type result_type;
result_type
operator()(iterator_range<NextPolicies,Iterator>& self)
{
if (self.m_start == self.m_finish)
stop_iteration_error();
return *self.m_start++;
}
# if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
// CWPro8 has a codegen problem when this is an empty class
int garbage;
# endif
};
typedef next next_fn;
object m_sequence; // Keeps the sequence alive while iterating.
Iterator m_start;
Iterator m_finish;
};
namespace detail
{
// Get a Python class which contains the given iterator and
// policies, creating it if necessary. Requires: NextPolicies is
// default-constructible.
template <class Iterator, class NextPolicies>
object demand_iterator_class(char const* name, Iterator* = 0, NextPolicies const& policies = NextPolicies())
{
typedef iterator_range<NextPolicies,Iterator> range_;
// Check the registry. If one is already registered, return it.
handle<> class_obj(
objects::registered_class_object(python::type_id<range_>()));
if (class_obj.get() != 0)
return object(class_obj);
typedef typename range_::next_fn next_fn;
typedef typename next_fn::result_type result_type;
return class_<range_>(name, no_init)
.def("__iter__", identity_function())
.def(
#if PY_VERSION_HEX >= 0x03000000
"__next__"
#else
"next"
#endif
, make_function(
next_fn()
, policies
, mpl::vector2<result_type,range_&>()
));
}
// A function object which builds an iterator_range.
template <
class Target
, class Iterator
, class Accessor1
, class Accessor2
, class NextPolicies
>
struct py_iter_
{
py_iter_(Accessor1 const& get_start, Accessor2 const& get_finish)
: m_get_start(get_start)
, m_get_finish(get_finish)
{}
// Extract an object x of the Target type from the first Python
// argument, and invoke get_start(x)/get_finish(x) to produce
// iterators, which are used to construct a new iterator_range<>
// object that gets wrapped into a Python iterator.
iterator_range<NextPolicies,Iterator>
operator()(back_reference<Target&> x) const
{
// Make sure the Python class is instantiated.
detail::demand_iterator_class("iterator", (Iterator*)0, NextPolicies());
return iterator_range<NextPolicies,Iterator>(
x.source()
, m_get_start(x.get())
, m_get_finish(x.get())
);
}
private:
Accessor1 m_get_start;
Accessor2 m_get_finish;
};
template <class Target, class Iterator, class NextPolicies, class Accessor1, class Accessor2>
inline object make_iterator_function(
Accessor1 const& get_start
, Accessor2 const& get_finish
, NextPolicies const& /*next_policies*/
, Iterator const& (*)()
, boost::type<Target>*
, int
)
{
return make_function(
py_iter_<Target,Iterator,Accessor1,Accessor2,NextPolicies>(get_start, get_finish)
, default_call_policies()
, mpl::vector2<iterator_range<NextPolicies,Iterator>, back_reference<Target&> >()
);
}
template <class Target, class Iterator, class NextPolicies, class Accessor1, class Accessor2>
inline object make_iterator_function(
Accessor1 const& get_start
, Accessor2 const& get_finish
, NextPolicies const& next_policies
, Iterator& (*)()
, boost::type<Target>*
, ...)
{
return make_iterator_function(
get_start
, get_finish
, next_policies
, (Iterator const&(*)())0
, (boost::type<Target>*)0
, 0
);
}
}
// Create a Python callable object which accepts a single argument
// convertible to the C++ Target type and returns a Python
// iterator. The Python iterator uses get_start(x) and get_finish(x)
// (where x is an instance of Target) to produce begin and end
// iterators for the range, and an instance of NextPolicies is used as
// CallPolicies for the Python iterator's next() function.
template <class Target, class NextPolicies, class Accessor1, class Accessor2>
inline object make_iterator_function(
Accessor1 const& get_start
, Accessor2 const& get_finish
, NextPolicies const& next_policies
, boost::type<Target>* = 0
)
{
typedef typename Accessor1::result_type iterator;
typedef typename add_const<iterator>::type iterator_const;
typedef typename add_reference<iterator_const>::type iterator_cref;
return detail::make_iterator_function(
get_start
, get_finish
, next_policies
, (iterator_cref(*)())0
, (boost::type<Target>*)0
, 0
);
}
//
// implementation
//
template <class NextPolicies, class Iterator>
inline iterator_range<NextPolicies,Iterator>::iterator_range(
object sequence, Iterator start, Iterator finish)
: m_sequence(sequence), m_start(start), m_finish(finish)
{
}
}}} // namespace boost::python::objects
#endif // ITERATOR_DWA2002510_HPP
@@ -0,0 +1,195 @@
/* ENCODE.C - Encode message blocks. */
/* Copyright (c) 1995-2012 by Radford M. Neal.
*
* Permission is granted for anyone to copy, use, modify, and distribute
* these programs and accompanying documents for any purpose, provided
* this copyright notice is retained and prominently displayed, and note
* is made of any changes made to these programs. These programs and
* documents are distributed without any warranty, express or implied.
* As the programs were written for research purposes only, they have not
* been tested to the degree that would be advisable in any important
* application. All use of these programs is entirely at the user's own
* risk.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "rand.h"
#include "alloc.h"
#include "blockio.h"
#include "open.h"
#include "mod2sparse.h"
#include "mod2dense.h"
#include "mod2convert.h"
#include "rcode.h"
#include "enc.h"
void usage(void);
/* MAIN PROGRAM. */
int main
( int argc,
char **argv
)
{
char *source_file, *encoded_file;
char *pchk_file, *gen_file;
mod2dense *u, *v;
FILE *srcf, *encf;
char *sblk, *cblk, *chks;
int i, n;
/* Look at initial flag arguments. */
blockio_flush = 0;
while (argc>1)
{
if (strcmp(argv[1],"-f")==0)
{ if (blockio_flush!=0) usage();
blockio_flush = 1;
}
else
{ break;
}
argc -= 1;
argv += 1;
}
/* Look at remaining arguments. */
if (!(pchk_file = argv[1])
|| !(gen_file = argv[2])
|| !(source_file = argv[3])
|| !(encoded_file = argv[4])
|| argv[5])
{ usage();
}
if ((strcmp(pchk_file,"-")==0)
+ (strcmp(gen_file,"-")==0)
+ (strcmp(source_file,"-")==0) > 1)
{ fprintf(stderr,"Can't read more than one stream from standard input\n");
exit(1);
}
/* Read parity check file */
read_pchk(pchk_file);
if (N<=M)
{ fprintf(stderr,
"Can't encode if number of bits (%d) not greater than number of checks (%d)\n",
N,M);
exit(1);
}
/* Read generator matrix file. */
read_gen(gen_file,0,0);
/* Allocate needed space. */
if (type=='d')
{ u = mod2dense_allocate(N-M,1);
v = mod2dense_allocate(M,1);
}
if (type=='m')
{ u = mod2dense_allocate(M,1);
v = mod2dense_allocate(M,1);
}
/* Open source file. */
srcf = open_file_std(source_file,"r");
if (srcf==NULL)
{ fprintf(stderr,"Can't open source file: %s\n",source_file);
exit(1);
}
/* Create encoded output file. */
encf = open_file_std(encoded_file,"w");
if (encf==NULL)
{ fprintf(stderr,"Can't create file for encoded data: %s\n",encoded_file);
exit(1);
}
sblk = chk_alloc (N-M, sizeof *sblk);
cblk = chk_alloc (N, sizeof *cblk);
chks = chk_alloc (M, sizeof *chks);
/* Encode successive blocks. */
for (n = 0; ; n++)
{
/* Read block from source file. */
if (blockio_read(srcf,sblk,N-M)==EOF)
{ break;
}
/* Compute encoded block. */
switch (type)
{ case 's':
{ sparse_encode (sblk, cblk);
break;
}
case 'd':
{ dense_encode (sblk, cblk, u, v);
break;
}
case 'm':
{ mixed_encode (sblk, cblk, u, v);
break;
}
}
/* Check that encoded block is a code word. */
mod2sparse_mulvec (H, cblk, chks);
for (i = 0; i<M; i++)
{ if (chks[i]==1)
{ fprintf(stderr,"Output block %d is not a code word! (Fails check %d)\n",n,i);
abort();
}
}
/* Write encoded block to encoded output file. */
blockio_write(encf,cblk,N);
if (ferror(encf))
{ break;
}
}
// fprintf(stderr,
// "Encoded %d blocks, source block size %d, encoded block size %d\n",n,N-M,N);
if (ferror(encf) || fclose(encf)!=0)
{ fprintf(stderr,"Error writing encoded blocks to %s\n",encoded_file);
exit(1);
}
return 0;
}
/* PRINT USAGE MESSAGE AND EXIT. */
void usage(void)
{ fprintf(stderr,
"Usage: encode [ -f ] pchk-file gen-file source-file encoded-file\n");
exit(1);
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1,500 @@
// (C) 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_SPECIAL_NEXT_HPP
#define BOOST_MATH_SPECIAL_NEXT_HPP
#ifdef _MSC_VER
#pragma once
#endif
#include <boost/math/special_functions/math_fwd.hpp>
#include <boost/math/policies/error_handling.hpp>
#include <boost/math/special_functions/fpclassify.hpp>
#include <boost/math/special_functions/sign.hpp>
#include <boost/math/special_functions/trunc.hpp>
#include <float.h>
#if !defined(_CRAYC) && !defined(__CUDACC__) && (!defined(__GNUC__) || (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ > 3)))
#if (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(__SSE2__)
#include "xmmintrin.h"
#define BOOST_MATH_CHECK_SSE2
#endif
#endif
namespace boost{ namespace math{
namespace detail{
template <class T>
inline T get_smallest_value(mpl::true_ const&)
{
//
// numeric_limits lies about denorms being present - particularly
// when this can be turned on or off at runtime, as is the case
// when using the SSE2 registers in DAZ or FTZ mode.
//
static const T m = std::numeric_limits<T>::denorm_min();
#ifdef BOOST_MATH_CHECK_SSE2
return (_mm_getcsr() & (_MM_FLUSH_ZERO_ON | 0x40)) ? tools::min_value<T>() : m;;
#else
return ((tools::min_value<T>() / 2) == 0) ? tools::min_value<T>() : m;
#endif
}
template <class T>
inline T get_smallest_value(mpl::false_ const&)
{
return tools::min_value<T>();
}
template <class T>
inline T get_smallest_value()
{
#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1310)
return get_smallest_value<T>(mpl::bool_<std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::has_denorm == 1)>());
#else
return get_smallest_value<T>(mpl::bool_<std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::has_denorm == std::denorm_present)>());
#endif
}
//
// Returns the smallest value that won't generate denorms when
// we calculate the value of the least-significant-bit:
//
template <class T>
T get_min_shift_value();
template <class T>
struct min_shift_initializer
{
struct init
{
init()
{
do_init();
}
static void do_init()
{
get_min_shift_value<T>();
}
void force_instantiate()const{}
};
static const init initializer;
static void force_instantiate()
{
initializer.force_instantiate();
}
};
template <class T>
const typename min_shift_initializer<T>::init min_shift_initializer<T>::initializer;
template <class T>
inline T get_min_shift_value()
{
BOOST_MATH_STD_USING
static const T val = ldexp(tools::min_value<T>(), tools::digits<T>() + 1);
min_shift_initializer<T>::force_instantiate();
return val;
}
template <class T, class Policy>
T float_next_imp(const T& val, const Policy& pol)
{
BOOST_MATH_STD_USING
int expon;
static const char* function = "float_next<%1%>(%1%)";
int fpclass = (boost::math::fpclassify)(val);
if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE))
{
if(val < 0)
return -tools::max_value<T>();
return policies::raise_domain_error<T>(
function,
"Argument must be finite, but got %1%", val, pol);
}
if(val >= tools::max_value<T>())
return policies::raise_overflow_error<T>(function, 0, pol);
if(val == 0)
return detail::get_smallest_value<T>();
if((fpclass != (int)FP_SUBNORMAL) && (fpclass != (int)FP_ZERO) && (fabs(val) < detail::get_min_shift_value<T>()) && (val != -tools::min_value<T>()))
{
//
// Special case: if the value of the least significant bit is a denorm, and the result
// would not be a denorm, then shift the input, increment, and shift back.
// This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set.
//
return ldexp(float_next(T(ldexp(val, 2 * tools::digits<T>())), pol), -2 * tools::digits<T>());
}
if(-0.5f == frexp(val, &expon))
--expon; // reduce exponent when val is a power of two, and negative.
T diff = ldexp(T(1), expon - tools::digits<T>());
if(diff == 0)
diff = detail::get_smallest_value<T>();
return val + diff;
}
}
template <class T, class Policy>
inline typename tools::promote_args<T>::type float_next(const T& val, const Policy& pol)
{
typedef typename tools::promote_args<T>::type result_type;
return detail::float_next_imp(static_cast<result_type>(val), pol);
}
#if 0 //def BOOST_MSVC
//
// We used to use ::_nextafter here, but doing so fails when using
// the SSE2 registers if the FTZ or DAZ flags are set, so use our own
// - albeit slower - code instead as at least that gives the correct answer.
//
template <class Policy>
inline double float_next(const double& val, const Policy& pol)
{
static const char* function = "float_next<%1%>(%1%)";
if(!(boost::math::isfinite)(val) && (val > 0))
return policies::raise_domain_error<double>(
function,
"Argument must be finite, but got %1%", val, pol);
if(val >= tools::max_value<double>())
return policies::raise_overflow_error<double>(function, 0, pol);
return ::_nextafter(val, tools::max_value<double>());
}
#endif
template <class T>
inline typename tools::promote_args<T>::type float_next(const T& val)
{
return float_next(val, policies::policy<>());
}
namespace detail{
template <class T, class Policy>
T float_prior_imp(const T& val, const Policy& pol)
{
BOOST_MATH_STD_USING
int expon;
static const char* function = "float_prior<%1%>(%1%)";
int fpclass = (boost::math::fpclassify)(val);
if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE))
{
if(val > 0)
return tools::max_value<T>();
return policies::raise_domain_error<T>(
function,
"Argument must be finite, but got %1%", val, pol);
}
if(val <= -tools::max_value<T>())
return -policies::raise_overflow_error<T>(function, 0, pol);
if(val == 0)
return -detail::get_smallest_value<T>();
if((fpclass != (int)FP_SUBNORMAL) && (fpclass != (int)FP_ZERO) && (fabs(val) < detail::get_min_shift_value<T>()) && (val != tools::min_value<T>()))
{
//
// Special case: if the value of the least significant bit is a denorm, and the result
// would not be a denorm, then shift the input, increment, and shift back.
// This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set.
//
return ldexp(float_prior(T(ldexp(val, 2 * tools::digits<T>())), pol), -2 * tools::digits<T>());
}
T remain = frexp(val, &expon);
if(remain == 0.5)
--expon; // when val is a power of two we must reduce the exponent
T diff = ldexp(T(1), expon - tools::digits<T>());
if(diff == 0)
diff = detail::get_smallest_value<T>();
return val - diff;
}
}
template <class T, class Policy>
inline typename tools::promote_args<T>::type float_prior(const T& val, const Policy& pol)
{
typedef typename tools::promote_args<T>::type result_type;
return detail::float_prior_imp(static_cast<result_type>(val), pol);
}
#if 0 //def BOOST_MSVC
//
// We used to use ::_nextafter here, but doing so fails when using
// the SSE2 registers if the FTZ or DAZ flags are set, so use our own
// - albeit slower - code instead as at least that gives the correct answer.
//
template <class Policy>
inline double float_prior(const double& val, const Policy& pol)
{
static const char* function = "float_prior<%1%>(%1%)";
if(!(boost::math::isfinite)(val) && (val < 0))
return policies::raise_domain_error<double>(
function,
"Argument must be finite, but got %1%", val, pol);
if(val <= -tools::max_value<double>())
return -policies::raise_overflow_error<double>(function, 0, pol);
return ::_nextafter(val, -tools::max_value<double>());
}
#endif
template <class T>
inline typename tools::promote_args<T>::type float_prior(const T& val)
{
return float_prior(val, policies::policy<>());
}
template <class T, class U, class Policy>
inline typename tools::promote_args<T, U>::type nextafter(const T& val, const U& direction, const Policy& pol)
{
typedef typename tools::promote_args<T, U>::type result_type;
return val < direction ? boost::math::float_next<result_type>(val, pol) : val == direction ? val : boost::math::float_prior<result_type>(val, pol);
}
template <class T, class U>
inline typename tools::promote_args<T, U>::type nextafter(const T& val, const U& direction)
{
return nextafter(val, direction, policies::policy<>());
}
namespace detail{
template <class T, class Policy>
T float_distance_imp(const T& a, const T& b, const Policy& pol)
{
BOOST_MATH_STD_USING
//
// Error handling:
//
static const char* function = "float_distance<%1%>(%1%, %1%)";
if(!(boost::math::isfinite)(a))
return policies::raise_domain_error<T>(
function,
"Argument a must be finite, but got %1%", a, pol);
if(!(boost::math::isfinite)(b))
return policies::raise_domain_error<T>(
function,
"Argument b must be finite, but got %1%", b, pol);
//
// Special cases:
//
if(a > b)
return -float_distance(b, a, pol);
if(a == b)
return 0;
if(a == 0)
return 1 + fabs(float_distance(static_cast<T>((b < 0) ? T(-detail::get_smallest_value<T>()) : detail::get_smallest_value<T>()), b, pol));
if(b == 0)
return 1 + fabs(float_distance(static_cast<T>((a < 0) ? T(-detail::get_smallest_value<T>()) : detail::get_smallest_value<T>()), a, pol));
if(boost::math::sign(a) != boost::math::sign(b))
return 2 + fabs(float_distance(static_cast<T>((b < 0) ? T(-detail::get_smallest_value<T>()) : detail::get_smallest_value<T>()), b, pol))
+ fabs(float_distance(static_cast<T>((a < 0) ? T(-detail::get_smallest_value<T>()) : detail::get_smallest_value<T>()), a, pol));
//
// By the time we get here, both a and b must have the same sign, we want
// b > a and both postive for the following logic:
//
if(a < 0)
return float_distance(static_cast<T>(-b), static_cast<T>(-a), pol);
BOOST_ASSERT(a >= 0);
BOOST_ASSERT(b >= a);
int expon;
//
// Note that if a is a denorm then the usual formula fails
// because we actually have fewer than tools::digits<T>()
// significant bits in the representation:
//
frexp(((boost::math::fpclassify)(a) == (int)FP_SUBNORMAL) ? tools::min_value<T>() : a, &expon);
T upper = ldexp(T(1), expon);
T result = 0;
expon = tools::digits<T>() - expon;
//
// If b is greater than upper, then we *must* split the calculation
// as the size of the ULP changes with each order of magnitude change:
//
if(b > upper)
{
result = float_distance(upper, b);
}
//
// Use compensated double-double addition to avoid rounding
// errors in the subtraction:
//
T mb, x, y, z;
if(((boost::math::fpclassify)(a) == (int)FP_SUBNORMAL) || (b - a < tools::min_value<T>()))
{
//
// Special case - either one end of the range is a denormal, or else the difference is.
// The regular code will fail if we're using the SSE2 registers on Intel and either
// the FTZ or DAZ flags are set.
//
T a2 = ldexp(a, tools::digits<T>());
T b2 = ldexp(b, tools::digits<T>());
mb = -(std::min)(T(ldexp(upper, tools::digits<T>())), b2);
x = a2 + mb;
z = x - a2;
y = (a2 - (x - z)) + (mb - z);
expon -= tools::digits<T>();
}
else
{
mb = -(std::min)(upper, b);
x = a + mb;
z = x - a;
y = (a - (x - z)) + (mb - z);
}
if(x < 0)
{
x = -x;
y = -y;
}
result += ldexp(x, expon) + ldexp(y, expon);
//
// Result must be an integer:
//
BOOST_ASSERT(result == floor(result));
return result;
}
}
template <class T, class U, class Policy>
inline typename tools::promote_args<T, U>::type float_distance(const T& a, const U& b, const Policy& pol)
{
typedef typename tools::promote_args<T, U>::type result_type;
return detail::float_distance_imp(static_cast<result_type>(a), static_cast<result_type>(b), pol);
}
template <class T, class U>
typename tools::promote_args<T, U>::type float_distance(const T& a, const U& b)
{
return boost::math::float_distance(a, b, policies::policy<>());
}
namespace detail{
template <class T, class Policy>
T float_advance_imp(T val, int distance, const Policy& pol)
{
BOOST_MATH_STD_USING
//
// Error handling:
//
static const char* function = "float_advance<%1%>(%1%, int)";
int fpclass = (boost::math::fpclassify)(val);
if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE))
return policies::raise_domain_error<T>(
function,
"Argument val must be finite, but got %1%", val, pol);
if(val < 0)
return -float_advance(-val, -distance, pol);
if(distance == 0)
return val;
if(distance == 1)
return float_next(val, pol);
if(distance == -1)
return float_prior(val, pol);
if(fabs(val) < detail::get_min_shift_value<T>())
{
//
// Special case: if the value of the least significant bit is a denorm,
// implement in terms of float_next/float_prior.
// This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set.
//
if(distance > 0)
{
do{ val = float_next(val, pol); } while(--distance);
}
else
{
do{ val = float_prior(val, pol); } while(++distance);
}
return val;
}
int expon;
frexp(val, &expon);
T limit = ldexp((distance < 0 ? T(0.5f) : T(1)), expon);
if(val <= tools::min_value<T>())
{
limit = sign(T(distance)) * tools::min_value<T>();
}
T limit_distance = float_distance(val, limit);
while(fabs(limit_distance) < abs(distance))
{
distance -= itrunc(limit_distance);
val = limit;
if(distance < 0)
{
limit /= 2;
expon--;
}
else
{
limit *= 2;
expon++;
}
limit_distance = float_distance(val, limit);
if(distance && (limit_distance == 0))
{
return policies::raise_evaluation_error<T>(function, "Internal logic failed while trying to increment floating point value %1%: most likely your FPU is in non-IEEE conforming mode.", val, pol);
}
}
if((0.5f == frexp(val, &expon)) && (distance < 0))
--expon;
T diff = 0;
if(val != 0)
diff = distance * ldexp(T(1), expon - tools::digits<T>());
if(diff == 0)
diff = distance * detail::get_smallest_value<T>();
return val += diff;
}
}
template <class T, class Policy>
inline typename tools::promote_args<T>::type float_advance(T val, int distance, const Policy& pol)
{
typedef typename tools::promote_args<T>::type result_type;
return detail::float_advance_imp(static_cast<result_type>(val), distance, pol);
}
template <class T>
inline typename tools::promote_args<T>::type float_advance(const T& val, int distance)
{
return boost::math::float_advance(val, distance, policies::policy<>());
}
}} // namespaces
#endif // BOOST_MATH_SPECIAL_NEXT_HPP
@@ -0,0 +1,59 @@
// ----------------------------------------------------------------------------
// format.hpp : primary header
// ----------------------------------------------------------------------------
// Copyright Samuel Krempp 2003. 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/format for library home page
// ----------------------------------------------------------------------------
#ifndef BOOST_FORMAT_HPP
#define BOOST_FORMAT_HPP
#include <vector>
#include <string>
#include <boost/detail/workaround.hpp>
#include <boost/config.hpp>
#ifndef BOOST_NO_STD_LOCALE
#include <locale>
#endif
// *** Compatibility framework
#include <boost/format/detail/compat_workarounds.hpp>
#ifdef BOOST_NO_LOCALE_ISIDIGIT
#include <cctype> // we'll use the non-locale <cctype>'s std::isdigit(int)
#endif
// **** Forward declarations ----------------------------------
#include <boost/format/format_fwd.hpp> // basic_format<Ch,Tr>, and other frontends
#include <boost/format/internals_fwd.hpp> // misc forward declarations for internal use
// **** Auxiliary structs (stream_format_state<Ch,Tr> , and format_item<Ch,Tr> )
#include <boost/format/internals.hpp>
// **** Format class interface --------------------------------
#include <boost/format/format_class.hpp>
// **** Exceptions -----------------------------------------------
#include <boost/format/exceptions.hpp>
// **** Implementation -------------------------------------------
#include <boost/format/format_implementation.hpp> // member functions
#include <boost/format/group.hpp> // class for grouping arguments
#include <boost/format/feed_args.hpp> // argument-feeding functions
#include <boost/format/parsing.hpp> // format-string parsing (member-)functions
// **** Implementation of the free functions ----------------------
#include <boost/format/free_funcs.hpp>
// *** Undefine 'local' macros :
#include <boost/format/detail/unset_macros.hpp>
#endif // BOOST_FORMAT_HPP
@@ -0,0 +1,293 @@
// 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/aux_/iter_fold_impl.hpp" header
// -- DO NOT modify by hand!
namespace boost { namespace mpl { namespace aux {
/// forward declaration
template<
int N
, typename First
, typename Last
, typename State
, typename ForwardOp
>
struct iter_fold_impl;
template< int N >
struct iter_fold_chunk;
template<> struct iter_fold_chunk<0>
{
template<
typename First
, typename Last
, typename State
, typename ForwardOp
>
struct result_
{
typedef First iter0;
typedef State state0;
typedef state0 state;
typedef iter0 iterator;
};
/// ETI workaround
template<> struct result_< int,int,int,int >
{
typedef int state;
typedef int iterator;
};
};
template<> struct iter_fold_chunk<1>
{
template<
typename First
, typename Last
, typename State
, typename ForwardOp
>
struct result_
{
typedef First iter0;
typedef State state0;
typedef typename apply2< ForwardOp,state0,iter0 >::type state1;
typedef typename mpl::next<iter0>::type iter1;
typedef state1 state;
typedef iter1 iterator;
};
/// ETI workaround
template<> struct result_< int,int,int,int >
{
typedef int state;
typedef int iterator;
};
};
template<> struct iter_fold_chunk<2>
{
template<
typename First
, typename Last
, typename State
, typename ForwardOp
>
struct result_
{
typedef First iter0;
typedef State state0;
typedef typename apply2< ForwardOp,state0,iter0 >::type state1;
typedef typename mpl::next<iter0>::type iter1;
typedef typename apply2< ForwardOp,state1,iter1 >::type state2;
typedef typename mpl::next<iter1>::type iter2;
typedef state2 state;
typedef iter2 iterator;
};
/// ETI workaround
template<> struct result_< int,int,int,int >
{
typedef int state;
typedef int iterator;
};
};
template<> struct iter_fold_chunk<3>
{
template<
typename First
, typename Last
, typename State
, typename ForwardOp
>
struct result_
{
typedef First iter0;
typedef State state0;
typedef typename apply2< ForwardOp,state0,iter0 >::type state1;
typedef typename mpl::next<iter0>::type iter1;
typedef typename apply2< ForwardOp,state1,iter1 >::type state2;
typedef typename mpl::next<iter1>::type iter2;
typedef typename apply2< ForwardOp,state2,iter2 >::type state3;
typedef typename mpl::next<iter2>::type iter3;
typedef state3 state;
typedef iter3 iterator;
};
/// ETI workaround
template<> struct result_< int,int,int,int >
{
typedef int state;
typedef int iterator;
};
};
template<> struct iter_fold_chunk<4>
{
template<
typename First
, typename Last
, typename State
, typename ForwardOp
>
struct result_
{
typedef First iter0;
typedef State state0;
typedef typename apply2< ForwardOp,state0,iter0 >::type state1;
typedef typename mpl::next<iter0>::type iter1;
typedef typename apply2< ForwardOp,state1,iter1 >::type state2;
typedef typename mpl::next<iter1>::type iter2;
typedef typename apply2< ForwardOp,state2,iter2 >::type state3;
typedef typename mpl::next<iter2>::type iter3;
typedef typename apply2< ForwardOp,state3,iter3 >::type state4;
typedef typename mpl::next<iter3>::type iter4;
typedef state4 state;
typedef iter4 iterator;
};
/// ETI workaround
template<> struct result_< int,int,int,int >
{
typedef int state;
typedef int iterator;
};
};
template< int N >
struct iter_fold_chunk
{
template<
typename First
, typename Last
, typename State
, typename ForwardOp
>
struct result_
{
typedef iter_fold_impl<
4
, First
, Last
, State
, ForwardOp
> chunk_;
typedef iter_fold_impl<
( (N - 4) < 0 ? 0 : N - 4 )
, typename chunk_::iterator
, Last
, typename chunk_::state
, ForwardOp
> res_;
typedef typename res_::state state;
typedef typename res_::iterator iterator;
};
};
template<
typename First
, typename Last
, typename State
, typename ForwardOp
>
struct iter_fold_step;
template<
typename Last
, typename State
>
struct iter_fold_null_step
{
typedef Last iterator;
typedef State state;
};
template<>
struct iter_fold_chunk< -1 >
{
template<
typename First
, typename Last
, typename State
, typename ForwardOp
>
struct result_
{
typedef typename if_<
typename is_same< First,Last >::type
, iter_fold_null_step< Last,State >
, iter_fold_step< First,Last,State,ForwardOp >
>::type res_;
typedef typename res_::state state;
typedef typename res_::iterator iterator;
};
/// ETI workaround
template<> struct result_< int,int,int,int >
{
typedef int state;
typedef int iterator;
};
};
template<
typename First
, typename Last
, typename State
, typename ForwardOp
>
struct iter_fold_step
{
typedef iter_fold_chunk< -1 >::template result_<
typename mpl::next<First>::type
, Last
, typename apply2< ForwardOp,State,First >::type
, ForwardOp
> chunk_;
typedef typename chunk_::state state;
typedef typename chunk_::iterator iterator;
};
template<
int N
, typename First
, typename Last
, typename State
, typename ForwardOp
>
struct iter_fold_impl
: iter_fold_chunk<N>
::template result_< First,Last,State,ForwardOp >
{
};
}}}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,558 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright 2013 Nikhar Agrawal
// Copyright 2013 Christopher Kormanyos
// Copyright 2014 John Maddock
// Copyright 2013 Paul Bristow
// Distributed under the 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_POLYGAMMA_DETAIL_2013_07_30_HPP_
#define _BOOST_POLYGAMMA_DETAIL_2013_07_30_HPP_
#include <cmath>
#include <limits>
#include <boost/cstdint.hpp>
#include <boost/math/policies/policy.hpp>
#include <boost/math/special_functions/bernoulli.hpp>
#include <boost/math/special_functions/trunc.hpp>
#include <boost/math/special_functions/zeta.hpp>
#include <boost/math/special_functions/digamma.hpp>
#include <boost/math/special_functions/sin_pi.hpp>
#include <boost/math/special_functions/cos_pi.hpp>
#include <boost/math/special_functions/pow.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/int.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_convertible.hpp>
#ifdef _MSC_VER
#pragma once
#pragma warning(push)
#pragma warning(disable:4702) // Unreachable code (release mode only warning)
#endif
namespace boost { namespace math { namespace detail{
template<class T, class Policy>
T polygamma_atinfinityplus(const int n, const T& x, const Policy& pol, const char* function) // for large values of x such as for x> 400
{
// See http://functions.wolfram.com/GammaBetaErf/PolyGamma2/06/02/0001/
BOOST_MATH_STD_USING
//
// sum == current value of accumulated sum.
// term == value of current term to be added to sum.
// part_term == value of current term excluding the Bernoulli number part
//
if(n + x == x)
{
// x is crazy large, just concentrate on the first part of the expression and use logs:
if(n == 1) return 1 / x;
T nlx = n * log(x);
if((nlx < tools::log_max_value<T>()) && (n < (int)max_factorial<T>::value))
return ((n & 1) ? 1 : -1) * boost::math::factorial<T>(n - 1) * pow(x, -n);
else
return ((n & 1) ? 1 : -1) * exp(boost::math::lgamma(T(n), pol) - n * log(x));
}
T term, sum, part_term;
T x_squared = x * x;
//
// Start by setting part_term to:
//
// (n-1)! / x^(n+1)
//
// which is common to both the first term of the series (with k = 1)
// and to the leading part.
// We can then get to the leading term by:
//
// part_term * (n + 2 * x) / 2
//
// and to the first term in the series
// (excluding the Bernoulli number) by:
//
// part_term n * (n + 1) / (2x)
//
// If either the factorial would overflow,
// or the power term underflows, this just gets set to 0 and then we
// know that we have to use logs for the initial terms:
//
part_term = ((n > (int)boost::math::max_factorial<T>::value) && (T(n) * n > tools::log_max_value<T>()))
? T(0) : static_cast<T>(boost::math::factorial<T>(n - 1, pol) * pow(x, -n - 1));
if(part_term == 0)
{
// Either n is very large, or the power term underflows,
// set the initial values of part_term, term and sum via logs:
part_term = static_cast<T>(boost::math::lgamma(n, pol) - (n + 1) * log(x));
sum = exp(part_term + log(n + 2 * x) - boost::math::constants::ln_two<T>());
part_term += log(T(n) * (n + 1)) - boost::math::constants::ln_two<T>() - log(x);
part_term = exp(part_term);
}
else
{
sum = part_term * (n + 2 * x) / 2;
part_term *= (T(n) * (n + 1)) / 2;
part_term /= x;
}
//
// If the leading term is 0, so is the result:
//
if(sum == 0)
return sum;
for(unsigned k = 1;;)
{
term = part_term * boost::math::bernoulli_b2n<T>(k, pol);
sum += term;
//
// Normal termination condition:
//
if(fabs(term / sum) < tools::epsilon<T>())
break;
//
// Increment our counter, and move part_term on to the next value:
//
++k;
part_term *= T(n + 2 * k - 2) * (n - 1 + 2 * k);
part_term /= (2 * k - 1) * 2 * k;
part_term /= x_squared;
//
// Emergency get out termination condition:
//
if(k > policies::get_max_series_iterations<Policy>())
{
return policies::raise_evaluation_error(function, "Series did not converge, closest value was %1%", sum, pol);
}
}
if((n - 1) & 1)
sum = -sum;
return sum;
}
template<class T, class Policy>
T polygamma_attransitionplus(const int n, const T& x, const Policy& pol, const char* function)
{
// See: http://functions.wolfram.com/GammaBetaErf/PolyGamma2/16/01/01/0017/
// Use N = (0.4 * digits) + (4 * n) for target value for x:
BOOST_MATH_STD_USING
const int d4d = static_cast<int>(0.4F * policies::digits_base10<T, Policy>());
const int N = d4d + (4 * n);
const int m = n;
const int iter = N - itrunc(x);
if(iter > (int)policies::get_max_series_iterations<Policy>())
return policies::raise_evaluation_error<T>(function, ("Exceeded maximum series evaluations evaluating at n = " + boost::lexical_cast<std::string>(n) + " and x = %1%").c_str(), x, pol);
const int minus_m_minus_one = -m - 1;
T z(x);
T sum0(0);
T z_plus_k_pow_minus_m_minus_one(0);
// Forward recursion to larger x, need to check for overflow first though:
if(log(z + iter) * minus_m_minus_one > -tools::log_max_value<T>())
{
for(int k = 1; k <= iter; ++k)
{
z_plus_k_pow_minus_m_minus_one = pow(z, minus_m_minus_one);
sum0 += z_plus_k_pow_minus_m_minus_one;
z += 1;
}
sum0 *= boost::math::factorial<T>(n);
}
else
{
for(int k = 1; k <= iter; ++k)
{
T log_term = log(z) * minus_m_minus_one + boost::math::lgamma(T(n + 1), pol);
sum0 += exp(log_term);
z += 1;
}
}
if((n - 1) & 1)
sum0 = -sum0;
return sum0 + polygamma_atinfinityplus(n, z, pol, function);
}
template <class T, class Policy>
T polygamma_nearzero(int n, T x, const Policy& pol, const char* function)
{
BOOST_MATH_STD_USING
//
// If we take this expansion for polygamma: http://functions.wolfram.com/06.15.06.0003.02
// and substitute in this expression for polygamma(n, 1): http://functions.wolfram.com/06.15.03.0009.01
// we get an alternating series for polygamma when x is small in terms of zeta functions of
// integer arguments (which are easy to evaluate, at least when the integer is even).
//
// In order to avoid spurious overflow, save the n! term for later, and rescale at the end:
//
T scale = boost::math::factorial<T>(n, pol);
//
// "factorial_part" contains everything except the zeta function
// evaluations in each term:
//
T factorial_part = 1;
//
// "prefix" is what we'll be adding the accumulated sum to, it will
// be n! / z^(n+1), but since we're scaling by n! it's just
// 1 / z^(n+1) for now:
//
T prefix = pow(x, n + 1);
if(prefix == 0)
return boost::math::policies::raise_overflow_error<T>(function, 0, pol);
prefix = 1 / prefix;
//
// First term in the series is necessarily < zeta(2) < 2, so
// ignore the sum if it will have no effect on the result anyway:
//
if(prefix > 2 / policies::get_epsilon<T, Policy>())
return ((n & 1) ? 1 : -1) *
(tools::max_value<T>() / prefix < scale ? policies::raise_overflow_error<T>(function, 0, pol) : prefix * scale);
//
// As this is an alternating series we could accelerate it using
// "Convergence Acceleration of Alternating Series",
// Henri Cohen, Fernando Rodriguez Villegas, and Don Zagier, Experimental Mathematics, 1999.
// In practice however, it appears not to make any difference to the number of terms
// required except in some edge cases which are filtered out anyway before we get here.
//
T sum = prefix;
for(unsigned k = 0;;)
{
// Get the k'th term:
T term = factorial_part * boost::math::zeta(T(k + n + 1), pol);
sum += term;
// Termination condition:
if(fabs(term) < fabs(sum * boost::math::policies::get_epsilon<T, Policy>()))
break;
//
// Move on k and factorial_part:
//
++k;
factorial_part *= (-x * (n + k)) / k;
//
// Last chance exit:
//
if(k > policies::get_max_series_iterations<Policy>())
return policies::raise_evaluation_error<T>(function, "Series did not converge, best value is %1%", sum, pol);
}
//
// We need to multiply by the scale, at each stage checking for oveflow:
//
if(boost::math::tools::max_value<T>() / scale < sum)
return boost::math::policies::raise_overflow_error<T>(function, 0, pol);
sum *= scale;
return n & 1 ? sum : T(-sum);
}
//
// Helper function which figures out which slot our coefficient is in
// given an angle multiplier for the cosine term of power:
//
template <class Table>
typename Table::value_type::reference dereference_table(Table& table, unsigned row, unsigned power)
{
return table[row][power / 2];
}
template <class T, class Policy>
T poly_cot_pi(int n, T x, T xc, const Policy& pol, const char* function)
{
BOOST_MATH_STD_USING
// Return n'th derivative of cot(pi*x) at x, these are simply
// tabulated for up to n = 9, beyond that it is possible to
// calculate coefficients as follows:
//
// The general form of each derivative is:
//
// pi^n * SUM{k=0, n} C[k,n] * cos^k(pi * x) * csc^(n+1)(pi * x)
//
// With constant C[0,1] = -1 and all other C[k,n] = 0;
// Then for each k < n+1:
// C[k-1, n+1] -= k * C[k, n];
// C[k+1, n+1] += (k-n-1) * C[k, n];
//
// Note that there are many different ways of representing this derivative thanks to
// the many trigomonetric identies available. In particular, the sum of powers of
// cosines could be replaced by a sum of cosine multiple angles, and indeed if you
// plug the derivative into Mathematica this is the form it will give. The two
// forms are related via the Chebeshev polynomials of the first kind and
// T_n(cos(x)) = cos(n x). The polynomial form has the great advantage that
// all the cosine terms are zero at half integer arguments - right where this
// function has it's minumum - thus avoiding cancellation error in this region.
//
// And finally, since every other term in the polynomials is zero, we can save
// space by only storing the non-zero terms. This greatly complexifies
// subscripting the tables in the calculation, but halves the storage space
// (and complexity for that matter).
//
T s = fabs(x) < fabs(xc) ? boost::math::sin_pi(x, pol) : boost::math::sin_pi(xc, pol);
T c = boost::math::cos_pi(x, pol);
switch(n)
{
case 1:
return -constants::pi<T, Policy>() / (s * s);
case 2:
{
return 2 * constants::pi<T, Policy>() * constants::pi<T, Policy>() * c / boost::math::pow<3>(s, pol);
}
case 3:
{
int P[] = { -2, -4 };
return boost::math::pow<3>(constants::pi<T, Policy>(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<4>(s, pol);
}
case 4:
{
int P[] = { 16, 8 };
return boost::math::pow<4>(constants::pi<T, Policy>(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<5>(s, pol);
}
case 5:
{
int P[] = { -16, -88, -16 };
return boost::math::pow<5>(constants::pi<T, Policy>(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<6>(s, pol);
}
case 6:
{
int P[] = { 272, 416, 32 };
return boost::math::pow<6>(constants::pi<T, Policy>(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<7>(s, pol);
}
case 7:
{
int P[] = { -272, -2880, -1824, -64 };
return boost::math::pow<7>(constants::pi<T, Policy>(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<8>(s, pol);
}
case 8:
{
int P[] = { 7936, 24576, 7680, 128 };
return boost::math::pow<8>(constants::pi<T, Policy>(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<9>(s, pol);
}
case 9:
{
int P[] = { -7936, -137216, -185856, -31616, -256 };
return boost::math::pow<9>(constants::pi<T, Policy>(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<10>(s, pol);
}
case 10:
{
int P[] = { 353792, 1841152, 1304832, 128512, 512 };
return boost::math::pow<10>(constants::pi<T, Policy>(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<11>(s, pol);
}
case 11:
{
int P[] = { -353792, -9061376, -21253376, -8728576, -518656, -1024};
return boost::math::pow<11>(constants::pi<T, Policy>(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<12>(s, pol);
}
case 12:
{
int P[] = { 22368256, 175627264, 222398464, 56520704, 2084864, 2048 };
return boost::math::pow<12>(constants::pi<T, Policy>(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<13>(s, pol);
}
#ifndef BOOST_NO_LONG_LONG
case 13:
{
long long P[] = { -22368256LL, -795300864LL, -2868264960LL, -2174832640LL, -357888000LL, -8361984LL, -4096 };
return boost::math::pow<13>(constants::pi<T, Policy>(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<14>(s, pol);
}
case 14:
{
long long P[] = { 1903757312LL, 21016670208LL, 41731645440LL, 20261765120LL, 2230947840LL, 33497088LL, 8192 };
return boost::math::pow<14>(constants::pi<T, Policy>(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<15>(s, pol);
}
case 15:
{
long long P[] = { -1903757312LL, -89702612992LL, -460858269696LL, -559148810240LL, -182172651520LL, -13754155008LL, -134094848LL, -16384 };
return boost::math::pow<15>(constants::pi<T, Policy>(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<16>(s, pol);
}
case 16:
{
long long P[] = { 209865342976LL, 3099269660672LL, 8885192097792LL, 7048869314560LL, 1594922762240LL, 84134068224LL, 536608768LL, 32768 };
return boost::math::pow<16>(constants::pi<T, Policy>(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<17>(s, pol);
}
case 17:
{
long long P[] = { -209865342976LL, -12655654469632LL, -87815735738368LL, -155964390375424LL, -84842998005760LL, -13684856848384LL, -511780323328LL, -2146926592LL, -65536 };
return boost::math::pow<17>(constants::pi<T, Policy>(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<18>(s, pol);
}
case 18:
{
long long P[] = { 29088885112832LL, 553753414467584LL, 2165206642589696LL, 2550316668551168LL, 985278548541440LL, 115620218667008LL, 3100738912256LL, 8588754944LL, 131072 };
return boost::math::pow<18>(constants::pi<T, Policy>(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<19>(s, pol);
}
case 19:
{
long long P[] = { -29088885112832LL, -2184860175433728LL, -19686087844429824LL, -48165109676113920LL, -39471306959486976LL, -11124607890751488LL, -965271355195392LL, -18733264797696LL, -34357248000LL, -262144 };
return boost::math::pow<19>(constants::pi<T, Policy>(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<20>(s, pol);
}
case 20:
{
long long P[] = { 4951498053124096LL, 118071834535526400LL, 603968063567560704LL, 990081991141490688LL, 584901762421358592LL, 122829335169859584LL, 7984436548730880LL, 112949304754176LL, 137433710592LL, 524288 };
return boost::math::pow<20>(constants::pi<T, Policy>(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<21>(s, pol);
}
#endif
}
//
// We'll have to compute the coefficients up to n,
// complexity is O(n^2) which we don't worry about for now
// as the values are computed once and then cached.
// However, if the final evaluation would have too many
// terms just bail out right away:
//
if((unsigned)n / 2u > policies::get_max_series_iterations<Policy>())
return policies::raise_evaluation_error<T>(function, "The value of n is so large that we're unable to compute the result in reasonable time, best guess is %1%", 0, pol);
#ifdef BOOST_HAS_THREADS
static boost::detail::lightweight_mutex m;
boost::detail::lightweight_mutex::scoped_lock l(m);
#endif
static int digits = tools::digits<T>();
static std::vector<std::vector<T> > table(1, std::vector<T>(1, T(-1)));
int current_digits = tools::digits<T>();
if(digits != current_digits)
{
// Oh my... our precision has changed!
table = std::vector<std::vector<T> >(1, std::vector<T>(1, T(-1)));
digits = current_digits;
}
int index = n - 1;
if(index >= (int)table.size())
{
for(int i = (int)table.size() - 1; i < index; ++i)
{
int offset = i & 1; // 1 if the first cos power is 0, otherwise 0.
int sin_order = i + 2; // order of the sin term
int max_cos_order = sin_order - 1; // largest order of the polynomial of cos terms
int max_columns = (max_cos_order - offset) / 2; // How many entries there are in the current row.
int next_offset = offset ? 0 : 1;
int next_max_columns = (max_cos_order + 1 - next_offset) / 2; // How many entries there will be in the next row
table.push_back(std::vector<T>(next_max_columns + 1, T(0)));
for(int column = 0; column <= max_columns; ++column)
{
int cos_order = 2 * column + offset; // order of the cosine term in entry "column"
BOOST_ASSERT(column < (int)table[i].size());
BOOST_ASSERT((cos_order + 1) / 2 < (int)table[i + 1].size());
table[i + 1][(cos_order + 1) / 2] += ((cos_order - sin_order) * table[i][column]) / (sin_order - 1);
if(cos_order)
table[i + 1][(cos_order - 1) / 2] += (-cos_order * table[i][column]) / (sin_order - 1);
}
}
}
T sum = boost::math::tools::evaluate_even_polynomial(&table[index][0], c, table[index].size());
if(index & 1)
sum *= c; // First coeffient is order 1, and really an odd polynomial.
if(sum == 0)
return sum;
//
// The remaining terms are computed using logs since the powers and factorials
// get real large real quick:
//
T power_terms = n * log(boost::math::constants::pi<T>());
if(s == 0)
return sum * boost::math::policies::raise_overflow_error<T>(function, 0, pol);
power_terms -= log(fabs(s)) * (n + 1);
power_terms += boost::math::lgamma(T(n));
power_terms += log(fabs(sum));
if(power_terms > boost::math::tools::log_max_value<T>())
return sum * boost::math::policies::raise_overflow_error<T>(function, 0, pol);
return exp(power_terms) * ((s < 0) && ((n + 1) & 1) ? -1 : 1) * boost::math::sign(sum);
}
template <class T, class Policy>
struct polygamma_initializer
{
struct init
{
init()
{
// Forces initialization of our table of coefficients and mutex:
boost::math::polygamma(30, T(-2.5f), Policy());
}
void force_instantiate()const{}
};
static const init initializer;
static void force_instantiate()
{
initializer.force_instantiate();
}
};
template <class T, class Policy>
const typename polygamma_initializer<T, Policy>::init polygamma_initializer<T, Policy>::initializer;
template<class T, class Policy>
inline T polygamma_imp(const int n, T x, const Policy &pol)
{
BOOST_MATH_STD_USING
static const char* function = "boost::math::polygamma<%1%>(int, %1%)";
polygamma_initializer<T, Policy>::initializer.force_instantiate();
if(n < 0)
return policies::raise_domain_error<T>(function, "Order must be >= 0, but got %1%", static_cast<T>(n), pol);
if(x < 0)
{
if(floor(x) == x)
{
//
// Result is infinity if x is odd, and a pole error if x is even.
//
if(lltrunc(x) & 1)
return policies::raise_overflow_error<T>(function, 0, pol);
else
return policies::raise_pole_error<T>(function, "Evaluation at negative integer %1%", x, pol);
}
T z = 1 - x;
T result = polygamma_imp(n, z, pol) + constants::pi<T, Policy>() * poly_cot_pi(n, z, x, pol, function);
return n & 1 ? T(-result) : result;
}
//
// Limit for use of small-x-series is chosen
// so that the series doesn't go too divergent
// in the first few terms. Ordinarily this
// would mean setting the limit to ~ 1 / n,
// but we can tolerate a small amount of divergence:
//
T small_x_limit = (std::min)(T(T(5) / n), T(0.25f));
if(x < small_x_limit)
{
return polygamma_nearzero(n, x, pol, function);
}
else if(x > 0.4F * policies::digits_base10<T, Policy>() + 4.0f * n)
{
return polygamma_atinfinityplus(n, x, pol, function);
}
else if(x == 1)
{
return (n & 1 ? 1 : -1) * boost::math::factorial<T>(n, pol) * boost::math::zeta(T(n + 1), pol);
}
else if(x == 0.5f)
{
T result = (n & 1 ? 1 : -1) * boost::math::factorial<T>(n, pol) * boost::math::zeta(T(n + 1), pol);
if(fabs(result) >= ldexp(tools::max_value<T>(), -n - 1))
return boost::math::sign(result) * policies::raise_overflow_error<T>(function, 0, pol);
result *= ldexp(T(1), n + 1) - 1;
return result;
}
else
{
return polygamma_attransitionplus(n, x, pol, function);
}
}
} } } // namespace boost::math::detail
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#endif // _BOOST_POLYGAMMA_DETAIL_2013_07_30_HPP_
@@ -0,0 +1,50 @@
// Copyright Neil Groves 2009. 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)
//
//
// For more information, see http://www.boost.org/libs/range/
//
#ifndef BOOST_RANGE_ALGORITHM_COUNT_HPP_INCLUDED
#define BOOST_RANGE_ALGORITHM_COUNT_HPP_INCLUDED
#include <boost/concept_check.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/concepts.hpp>
#include <boost/range/difference_type.hpp>
#include <algorithm>
namespace boost
{
namespace range
{
/// \brief template function count
///
/// range-based version of the count std algorithm
///
/// \pre SinglePassRange is a model of the SinglePassRangeConcept
template< class SinglePassRange, class Value >
inline BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange>::type
count(SinglePassRange& rng, const Value& val)
{
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
return std::count(boost::begin(rng), boost::end(rng), val);
}
/// \overload
template< class SinglePassRange, class Value >
inline BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange const>::type
count(const SinglePassRange& rng, const Value& val)
{
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
return std::count(boost::begin(rng), boost::end(rng), val);
}
} // namespace range
using range::count;
} // namespace boost
#endif // include guard
@@ -0,0 +1,183 @@
// -*- Mode: C++ -*-
///////////////////////////////////////////////////////////////////////////
// Some code in this file and accompanying files is based on work by
// Moe Wheatley, AE4Y, released under the "Simplified BSD License".
// For more details see the accompanying file LICENSE_WHEATLEY.TXT
///////////////////////////////////////////////////////////////////////////
#ifndef PLOTTER_H
#define PLOTTER_H
#ifdef QT5
#include <QtWidgets>
#else
#include <QtGui>
#endif
#include <QFrame>
#include <QImage>
#include <QVector>
#include <cstring>
#define VERT_DIVS 7 //specify grid screen divisions
#define HORZ_DIVS 20
extern bool g_single_decode;
class QAction;
class CPlotter : public QFrame
{
Q_OBJECT
public:
explicit CPlotter(QWidget *parent = 0);
~CPlotter();
QSize minimumSizeHint() const;
QSize sizeHint() const;
void draw(float swide[], bool bScroll, bool bRed); //Update the waterfall
void SetRunningState(bool running);
void setPlotZero(int plotZero);
int plotZero();
void setPlotGain(int plotGain);
int plotGain();
int plot2dGain();
void setPlot2dGain(int n);
int plot2dZero();
void setPlot2dZero(int plot2dZero);
void setStartFreq(int f);
int startFreq();
int plotWidth();
void UpdateOverlay();
void setDataFromDisk(bool b);
void setRxRange(int fMin);
void setBinsPerPixel(int n);
int binsPerPixel();
void setWaterfallAvg(int n);
void setRxFreq(int n);
void DrawOverlay();
int rxFreq();
void setFsample(int n);
void setNsps(int ntrperiod, int nsps);
void setTxFreq(int n);
void setMode(QString mode);
void setSubMode(int n);
void setModeTx(QString modeTx);
void SetPercent2DScreen(int percent);
int Fmax();
void setDialFreq(double d);
void setCurrent(bool b) {m_bCurrent = b;}
bool current() const {return m_bCurrent;}
void setCumulative(bool b) {m_bCumulative = b;}
bool cumulative() const {return m_bCumulative;}
void setLinearAvg(bool b) {m_bLinearAvg = b;}
bool linearAvg() const {return m_bLinearAvg;}
void setBreadth(qint32 w) {m_w = w;}
qint32 breadth() const {return m_w;}
float fSpan() const {return m_fSpan;}
void setColours(QVector<QColor> const& cl);
void setFlatten(bool b1, bool b2);
void setTol(int n);
void setRxBand(QString band);
void setReference(bool b) {m_bReference = b;}
bool Reference() const {return m_bReference;}
void drawRed(int ia, int ib, float swide[]);
void setVHF(bool bVHF);
void setRedFile(QString fRed);
bool scaleOK () const {return m_bScaleOK;}
signals:
void freezeDecode1(int n);
void setFreq1(int rxFreq, int txFreq);
protected:
//re-implemented widget event handlers
void paintEvent(QPaintEvent *event) override;
void resizeEvent(QResizeEvent* event) override;
void mouseReleaseEvent (QMouseEvent * event) override;
void mouseDoubleClickEvent (QMouseEvent * event) override;
private:
void MakeFrequencyStrs();
int XfromFreq(float f);
float FreqfromX(int x);
QAction * m_set_freq_action;
bool m_bScaleOK;
bool m_bCurrent;
bool m_bCumulative;
bool m_bLinearAvg;
bool m_bReference;
bool m_bReference0;
bool m_bVHF;
float m_fSpan;
qint32 m_plotZero;
qint32 m_plotGain;
qint32 m_plot2dGain;
qint32 m_plot2dZero;
qint32 m_binsPerPixel;
qint32 m_waterfallAvg;
qint32 m_w;
qint32 m_Flatten;
qint32 m_nSubMode;
qint32 m_ia;
qint32 m_ib;
QPixmap m_WaterfallPixmap;
QPixmap m_2DPixmap;
QPixmap m_ScalePixmap;
QPixmap m_OverlayPixmap;
QSize m_Size;
QString m_Str;
QString m_HDivText[483];
QString m_mode;
QString m_modeTx;
QString m_rxBand;
QString m_redFile;
bool m_Running;
bool m_paintEventBusy;
bool m_dataFromDisk;
double m_fftBinWidth;
double m_dialFreq;
double m_xOffset;
float m_sum[2048];
qint32 m_dBStepSize;
qint32 m_FreqUnits;
qint32 m_hdivs;
qint32 m_line;
qint32 m_fSample;
qint32 m_xClick;
qint32 m_freqPerDiv;
qint32 m_nsps;
qint32 m_Percent2DScreen;
qint32 m_Percent2DScreen0;
qint32 m_h;
qint32 m_h1;
qint32 m_h2;
qint32 m_TRperiod;
qint32 m_rxFreq;
qint32 m_txFreq;
qint32 m_fMin;
qint32 m_fMax;
qint32 m_startFreq;
qint32 m_tol;
char m_sutc[6];
};
extern QVector<QColor> g_ColorTbl;
extern "C" {
void flat4_(float swide[], int* iz, int* nflatten);
}
#endif // PLOTTER_H
@@ -0,0 +1,31 @@
# /* **************************************************************************
# * *
# * (C) Copyright Edward Diener 2013.
# * Distributed under the 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_TUPLE_PUSH_BACK_HPP
# define BOOST_PREPROCESSOR_TUPLE_PUSH_BACK_HPP
#
# include <boost/preprocessor/config/config.hpp>
#
# if BOOST_PP_VARIADICS
#
# include <boost/preprocessor/array/push_back.hpp>
# include <boost/preprocessor/array/to_tuple.hpp>
# include <boost/preprocessor/tuple/to_array.hpp>
#
# /* BOOST_PP_TUPLE_PUSH_BACK */
#
# define BOOST_PP_TUPLE_PUSH_BACK(tuple, elem) \
BOOST_PP_ARRAY_TO_TUPLE(BOOST_PP_ARRAY_PUSH_BACK(BOOST_PP_TUPLE_TO_ARRAY(tuple), elem)) \
/**/
#
# endif // BOOST_PP_VARIADICS
#
# endif // BOOST_PREPROCESSOR_TUPLE_PUSH_BACK_HPP
@@ -0,0 +1,126 @@
// (C) Copyright John Maddock 2007.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// This file is machine generated, do not edit by hand
// Polynomial evaluation using Horners rule
#ifndef BOOST_MATH_TOOLS_POLY_EVAL_17_HPP
#define BOOST_MATH_TOOLS_POLY_EVAL_17_HPP
namespace boost{ namespace math{ namespace tools{ namespace detail{
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T*, const V&, const mpl::int_<0>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>(0);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V&, const mpl::int_<1>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>(a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<2>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>(a[1] * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<3>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<4>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<5>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<6>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<7>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<8>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<9>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<10>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<11>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<12>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<13>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<14>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>(((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<15>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<16>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>(((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<17>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
}
}}}} // namespaces
#endif // include guard
@@ -0,0 +1,180 @@
subroutine genmsk144(msg0,mygrid,ichk,bcontest,msgsent,i4tone,itype)
! s8 + 48bits + s8 + 80 bits = 144 bits (72ms message duration)
!
! Encode an MSK144 message
! Input:
! - msg0 requested message to be transmitted
! - ichk if ichk=1, return only msgsent
! if ichk.ge.10000, set imsg=ichk-10000 for short msg
! - msgsent message as it will be decoded
! - i4tone array of audio tone values, 0 or 1
! - itype message type
! 1 = standard message "Call_1 Call_2 Grid/Rpt"
! 2 = type 1 prefix
! 3 = type 1 suffix
! 4 = type 2 prefix
! 5 = type 2 suffix
! 6 = free text (up to 13 characters)
! 7 = short message "<Call_1 Call2> Rpt"
use iso_c_binding, only: c_loc,c_size_t
use packjt
use hashing
character*22 msg0
character*22 message !Message to be generated
character*22 msgsent !Message as it will be received
character*6 mygrid,g1,g2,g3,g4
integer*4 i4Msg6BitWords(13) !72-bit message as 6-bit words
integer*4 i4tone(144) !
integer*1, target:: i1Msg8BitBytes(10) !80 bits represented in 10 bytes
integer*1 codeword(128) !Encoded bits before re-ordering
integer*1 msgbits(80) !72-bit message + 8-bit hash
integer*1 bitseq(144) !Tone #s, data and sync (values 0-1)
integer*1 i1hash(4)
integer*1 s8(8)
logical*1 bcontest
real*8 pp(12)
real*8 xi(864),xq(864),pi,twopi
data s8/0,1,1,1,0,0,1,0/
equivalence (ihash,i1hash)
logical first,isgrid
data first/.true./
save
isgrid(g1)=g1(1:1).ge.'A' .and. g1(1:1).le.'R' .and. g1(2:2).ge.'A' .and. &
g1(2:2).le.'R' .and. g1(3:3).ge.'0' .and. g1(3:3).le.'9' .and. &
g1(4:4).ge.'0' .and. g1(4:4).le.'9' .and. g1(1:4).ne.'RR73'
if(first) then
first=.false.
nsym=128
pi=4.0*atan(1.0)
twopi=8.*atan(1.0)
do i=1,12
pp(i)=sin((i-1)*pi/12)
enddo
endif
if(msg0(1:1).eq.'@') then !Generate a fixed tone
read(msg0(2:5),*,end=1,err=1) nfreq !at specified frequency
go to 2
1 nfreq=1000
2 i4tone(1)=nfreq
else
message=msg0
do i=1,22
if(ichar(message(i:i)).eq.0) then
message(i:)=' '
exit
endif
enddo
do i=1,22 !Strip leading blanks
if(message(1:1).ne.' ') exit
message=message(i+1:)
enddo
if(message(1:1).eq.'<') then
call genmsk40(message,msgsent,ichk,i4tone,itype)
if(itype.lt.0) go to 999
i4tone(41)=-40
go to 999
endif
if(bcontest) then
i0=index(message,' R ') + 3 !Check for ' R ' in message
g1=message(i0:i0+3)//' '
if(isgrid(g1)) then !Check for ' R grid'
call grid2deg(g1,dlong,dlat)
dlong=dlong+180.0
if(dlong.gt.180.0) dlong=dlong-360.0
dlat=-dlat
call deg2grid(dlong,dlat,g2) !g2=antipodes grid
message=message(1:i0-3)//g2(1:4) !Send message with g2
endif
endif
call packmsg(message,i4Msg6BitWords,itype) !Pack into 12 6-bit bytes
call unpackmsg(i4Msg6BitWords,msgsent) !Unpack to get msgsent
if(bcontest) then
i1=index(msgsent(8:22),' ') + 8
g3=msgsent(i1:i1+3)//' '
if(isgrid(g3)) then
call azdist(mygrid,g3,0.d0,nAz,nEl,nDmiles,nDkm,nHotAz,nHotABetter)
if(ndkm.gt.10000) then
call grid2deg(g3,dlong,dlat)
dlong=dlong+180.0
if(dlong.gt.180.0) dlong=dlong-360.0
dlat=-dlat
call deg2grid(dlong,dlat,g4)
msgsent=msgsent(1:i1-1)//'R '//g4(1:4)
endif
endif
endif
if(ichk.eq.1) go to 999
i4=0
ik=0
im=0
do i=1,12
nn=i4Msg6BitWords(i)
do j=1, 6
ik=ik+1
i4=i4+i4+iand(1,ishft(nn,j-6))
i4=iand(i4,255)
if(ik.eq.8) then
im=im+1
i1Msg8BitBytes(im)=i4
ik=0
endif
enddo
enddo
ihash=nhash(c_loc(i1Msg8BitBytes),int(9,c_size_t),146)
ihash=2*iand(ihash,32767) !Generate the 8-bit hash
i1Msg8BitBytes(10)=i1hash(1) !CRC to byte 10
mbit=0
do i=1, 10
i1=i1Msg8BitBytes(i)
do ibit=1,8
mbit=mbit+1
msgbits(mbit)=iand(1,ishft(i1,ibit-8))
enddo
enddo
call encode_msk144(msgbits,codeword)
!Create 144-bit channel vector:
!8-bit sync word + 48 bits + 8-bit sync word + 80 bits
bitseq=0
bitseq(1:8)=s8
bitseq(9:56)=codeword(1:48)
bitseq(57:64)=s8
bitseq(65:144)=codeword(49:128)
bitseq=2*bitseq-1
xq(1:6)=bitseq(1)*pp(7:12) !first bit is mapped to 1st half-symbol on q
do i=1,71
is=(i-1)*12+7
xq(is:is+11)=bitseq(2*i+1)*pp
enddo
xq(864-5:864)=bitseq(1)*pp(1:6) !last half symbol
do i=1,72
is=(i-1)*12+1
xi(is:is+11)=bitseq(2*i)*pp
enddo
! Map I and Q to tones.
i4tone=0
do i=1,72
i4tone(2*i-1)=(bitseq(2*i)*bitseq(2*i-1)+1)/2;
i4tone(2*i)=-(bitseq(2*i)*bitseq(mod(2*i,144)+1)-1)/2;
enddo
endif
! Flip polarity
i4tone=-i4tone+1
999 return
end subroutine genmsk144
@@ -0,0 +1,96 @@
// (C) Copyright John Maddock 2007.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// This file is machine generated, do not edit by hand
// Polynomial evaluation using Horners rule
#ifndef BOOST_MATH_TOOLS_POLY_EVAL_12_HPP
#define BOOST_MATH_TOOLS_POLY_EVAL_12_HPP
namespace boost{ namespace math{ namespace tools{ namespace detail{
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T*, const V&, const mpl::int_<0>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>(0);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V&, const mpl::int_<1>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>(a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<2>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>(a[1] * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<3>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<4>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<5>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<6>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<7>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<8>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<9>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<10>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<11>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<12>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
}
}}}} // namespaces
#endif // include guard
@@ -0,0 +1,165 @@
// Copyright 2002 The Trustees of Indiana University.
// 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)
// Boost.MultiArray Library
// Authors: Ronald Garcia
// Jeremy Siek
// Andrew Lumsdaine
// See http://www.boost.org/libs/multi_array for documentation.
#ifndef ITERATOR_RG071801_HPP
#define ITERATOR_RG071801_HPP
//
// iterator.hpp - implementation of iterators for the
// multi-dimensional array class
//
#include "boost/multi_array/base.hpp"
#include "boost/iterator/iterator_facade.hpp"
#include <algorithm>
#include <cstddef>
#include <iterator>
namespace boost {
namespace detail {
namespace multi_array {
/////////////////////////////////////////////////////////////////////////
// iterator components
/////////////////////////////////////////////////////////////////////////
template <class T>
struct operator_arrow_proxy
{
operator_arrow_proxy(T const& px) : value_(px) {}
T* operator->() const { return &value_; }
// This function is needed for MWCW and BCC, which won't call operator->
// again automatically per 13.3.1.2 para 8
operator T*() const { return &value_; }
mutable T value_;
};
template <typename T, typename TPtr, typename NumDims, typename Reference,
typename IteratorCategory>
class array_iterator;
template <typename T, typename TPtr, typename NumDims, typename Reference,
typename IteratorCategory>
class array_iterator
: public
iterator_facade<
array_iterator<T,TPtr,NumDims,Reference,IteratorCategory>
, typename associated_types<T,NumDims>::value_type
, IteratorCategory
, Reference
>
, private
value_accessor_generator<T,NumDims>::type
{
friend class iterator_core_access;
typedef detail::multi_array::associated_types<T,NumDims> access_t;
typedef iterator_facade<
array_iterator<T,TPtr,NumDims,Reference,IteratorCategory>
, typename detail::multi_array::associated_types<T,NumDims>::value_type
, boost::random_access_traversal_tag
, Reference
> facade_type;
typedef typename access_t::index index;
typedef typename access_t::size_type size_type;
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
template <typename, typename, typename, typename, typename>
friend class array_iterator;
#else
public:
#endif
index idx_;
TPtr base_;
const size_type* extents_;
const index* strides_;
const index* index_base_;
public:
// Typedefs to circumvent ambiguities between parent classes
typedef typename facade_type::reference reference;
typedef typename facade_type::value_type value_type;
typedef typename facade_type::difference_type difference_type;
array_iterator() {}
array_iterator(index idx, TPtr base, const size_type* extents,
const index* strides,
const index* index_base) :
idx_(idx), base_(base), extents_(extents),
strides_(strides), index_base_(index_base) { }
template <typename OPtr, typename ORef, typename Cat>
array_iterator(
const array_iterator<T,OPtr,NumDims,ORef,Cat>& rhs
, typename boost::enable_if_convertible<OPtr,TPtr>::type* = 0
)
: idx_(rhs.idx_), base_(rhs.base_), extents_(rhs.extents_),
strides_(rhs.strides_), index_base_(rhs.index_base_) { }
// RG - we make our own operator->
operator_arrow_proxy<reference>
operator->() const
{
return operator_arrow_proxy<reference>(this->dereference());
}
reference dereference() const
{
typedef typename value_accessor_generator<T,NumDims>::type accessor;
return accessor::access(boost::type<reference>(),
idx_,
base_,
extents_,
strides_,
index_base_);
}
void increment() { ++idx_; }
void decrement() { --idx_; }
template <class IteratorAdaptor>
bool equal(IteratorAdaptor& rhs) const {
const std::size_t N = NumDims::value;
return (idx_ == rhs.idx_) &&
(base_ == rhs.base_) &&
( (extents_ == rhs.extents_) ||
std::equal(extents_,extents_+N,rhs.extents_) ) &&
( (strides_ == rhs.strides_) ||
std::equal(strides_,strides_+N,rhs.strides_) ) &&
( (index_base_ == rhs.index_base_) ||
std::equal(index_base_,index_base_+N,rhs.index_base_) );
}
template <class DifferenceType>
void advance(DifferenceType n) {
idx_ += n;
}
template <class IteratorAdaptor>
typename facade_type::difference_type
distance_to(IteratorAdaptor& rhs) const {
return rhs.idx_ - idx_;
}
};
} // namespace multi_array
} // namespace detail
} // namespace boost
#endif // ITERATOR_RG071801_HPP
@@ -0,0 +1,76 @@
// Boost.Range library
//
// Copyright Thorsten Ottosen 2003-2004. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org/libs/range/
//
#ifndef BOOST_RANGE_CONST_ITERATOR_HPP
#define BOOST_RANGE_CONST_ITERATOR_HPP
#if defined(_MSC_VER)
# pragma once
#endif
#include <boost/range/config.hpp>
#include <boost/range/range_fwd.hpp>
#include <boost/range/detail/extract_optional_type.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <cstddef>
#include <utility>
namespace boost
{
//////////////////////////////////////////////////////////////////////////
// default
//////////////////////////////////////////////////////////////////////////
namespace range_detail
{
BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( const_iterator )
template< typename C >
struct range_const_iterator_helper
: extract_const_iterator<C>
{};
//////////////////////////////////////////////////////////////////////////
// pair
//////////////////////////////////////////////////////////////////////////
template< typename Iterator >
struct range_const_iterator_helper<std::pair<Iterator,Iterator> >
{
typedef Iterator type;
};
//////////////////////////////////////////////////////////////////////////
// array
//////////////////////////////////////////////////////////////////////////
template< typename T, std::size_t sz >
struct range_const_iterator_helper< T[sz] >
{
typedef const T* type;
};
} // namespace range_detail
template<typename C, typename Enabler=void>
struct range_const_iterator
: range_detail::range_const_iterator_helper<
BOOST_DEDUCED_TYPENAME remove_reference<C>::type
>
{
};
} // namespace boost
#endif
@@ -0,0 +1,184 @@
subroutine osd300(llr,norder,decoded,niterations,cw)
!
! An ordered-statistics decoder for the (300,60) code.
!
include "ldpc_300_60_params.f90"
integer*1 gen(K,N)
integer*1 genmrb(K,N),g2(N,K)
integer*1 temp(K),m0(K),me(K),mi(K)
integer indices(N),nxor(N)
integer*1 cw(N),ce(N),c0(N),hdec(N)
integer*1 decoded(K)
integer indx(N)
real llr(N),rx(N),absrx(N)
logical first
data first/.true./
save first,gen
if( first ) then ! fill the generator matrix
gen=0
do i=1,M
do j=1,15
read(g(i)(j:j),"(Z1)") istr
do jj=1, 4
irow=(j-1)*4+jj
if( btest(istr,4-jj) ) gen(irow,i)=1
enddo
enddo
enddo
do irow=1,K
gen(irow,M+irow)=1
enddo
first=.false.
endif
! re-order received vector to place systematic msg bits at the end
rx=llr(colorder+1)
! hard decode the received word
hdec=0
where(rx .ge. 0) hdec=1
! use magnitude of received symbols as a measure of reliability.
absrx=abs(rx)
call indexx(absrx,N,indx)
! re-order the columns of the generator matrix in order of decreasing reliability.
do i=1,N
genmrb(1:K,i)=gen(1:K,indx(N+1-i))
indices(i)=indx(N+1-i)
enddo
! do gaussian elimination to create a generator matrix with the most reliable
! received bits in positions 1:K in order of decreasing reliability (more or less).
! reliability will not be strictly decreasing because column re-ordering is needed
! to put the generator matrix in systematic form. the "indices" array tracks
! column permutations caused by reliability sorting and gaussian elimination.
do id=1,K ! diagonal element indices
do icol=id,K+20 ! The 20 is ad hoc - beware
iflag=0
if( genmrb(id,icol) .eq. 1 ) then
iflag=1
if( icol .ne. id ) then ! reorder column
temp(1:K)=genmrb(1:K,id)
genmrb(1:K,id)=genmrb(1:K,icol)
genmrb(1:K,icol)=temp(1:K)
itmp=indices(id)
indices(id)=indices(icol)
indices(icol)=itmp
endif
do ii=1,K
if( ii .ne. id .and. genmrb(ii,id) .eq. 1 ) then
genmrb(ii,1:N)=mod(genmrb(ii,1:N)+genmrb(id,1:N),2)
endif
enddo
exit
endif
enddo
enddo
g2=transpose(genmrb)
! The hard decisions for the K MRB bits define the order 0 message, m0.
! Encode m0 using the modified generator matrix to find the "order 0" codeword.
! Flip various combinations of bits in m0 and re-encode to generate a list of
! codewords. Test all such codewords against the received word to decide which
! codeword is most likely to be correct.
hdec=hdec(indices) ! hard decisions from received symbols
m0=hdec(1:K) ! zero'th order message
absrx=absrx(indices)
rx=rx(indices)
s1=sum(absrx(1:K))
s2=sum(absrx(K+1:N))
xlam=5.0
rho=s1/(s1+xlam*s2)
call mrbencode(m0,c0,g2,N,K)
nxor=ieor(c0,hdec)
nhardmin=sum(nxor)
dmin=sum(nxor*absrx)
thresh=rho*dmin
cw=c0
nt=0
nrejected=0
do iorder=1,norder
mi(1:K-iorder)=0
mi(K-iorder+1:K)=1
iflag=0
do while(iflag .ge. 0 )
dpat=sum(mi*absrx(1:K))
nt=nt+1
if( dpat .lt. thresh ) then ! reject unlikely error patterns
me=ieor(m0,mi)
call mrbencode(me,ce,g2,N,K)
nxor=ieor(ce,hdec)
dd=sum(nxor*absrx)
if( dd .lt. dmin ) then
dmin=dd
cw=ce
nhardmin=sum(nxor)
thresh=rho*dmin
endif
else
nrejected=nrejected+1
endif
! get the next test error pattern, iflag will go negative
! when the last pattern with weight iorder has been generated
call nextpat(mi,k,iorder,iflag)
enddo
enddo
!write(*,*) 'nhardmin ',nhardmin
!write(*,*) 'total patterns ',nt,' number rejected ',nrejected
! re-order the codeword to place message bits at the end
cw(indices)=cw
hdec(indices)=hdec
decoded=cw(M+1:N)
nerr=0
do i=1,N
if( hdec(i) .ne. cw(i) ) nerr=nerr+1
enddo
niterations=nerr
return
end subroutine osd300
subroutine mrbencode(me,codeword,g2,N,K)
integer*1 me(K),codeword(N),g2(N,K)
! fast encoding for low-weight test patterns
codeword=0
do i=1,K
if( me(i) .eq. 1 ) then
codeword=ieor(codeword,g2(1:N,i))
endif
enddo
return
end subroutine mrbencode
subroutine nextpat(mi,k,iorder,iflag)
integer*1 mi(k),ms(k)
! generate the next test error pattern
ind=-1
do i=1,k-1
if( mi(i).eq.0 .and. mi(i+1).eq.1) ind=i
enddo
if( ind .lt. 0 ) then ! no more patterns of this order
iflag=ind
return
endif
ms=0
ms(1:ind-1)=mi(1:ind-1)
ms(ind)=1
ms(ind+1)=0
if( ind+1 .lt. k ) then
nz=iorder-sum(ms)
ms(k-nz+1:k)=1
endif
mi=ms
iflag=ind
return
end subroutine nextpat
@@ -0,0 +1,34 @@
subroutine fitcal(x,y,r,iz,a,b,sigmaa,sigmab,rms)
implicit real*8 (a-h,o-z)
real*8 x(iz),y(iz),r(iz)
sx=0.d0
sy=0.d0
sxy=0.d0
sx2=0.d0
do i=1,iz
sx=sx + x(i)
sy=sy + y(i)
sxy=sxy + x(i)*y(i)
sx2=sx2 + x(i)*x(i)
enddo
delta=iz*sx2 - sx*sx
a=(sx2*sy - sx*sxy)/delta
b=(iz*sxy - sx*sy)/delta
sq=0.d0
do i=1,iz
r(i)=y(i) - (a + b*x(i))
sq=sq + r(i)**2
enddo
rms=0.
sigmaa=0.
sigmab=0.
if(iz.ge.3) then
rms=sqrt(sq/(iz-2))
sigmaa=sqrt(rms*rms*sx2/delta)
sigmab=sqrt(iz*rms*rms/delta)
endif
return
end subroutine fitcal
@@ -0,0 +1,19 @@
/*=============================================================================
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_IS_VIEW_03202006_0018)
#define FUSION_IS_VIEW_03202006_0018
namespace boost { namespace fusion { namespace detail
{
template <typename T>
struct fusion_is_view
{
typedef typename T::is_view type;
};
}}}
#endif
@@ -0,0 +1,54 @@
/*=============================================================================
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_TRANSFORM_07052005_1057)
#define FUSION_TRANSFORM_07052005_1057
#include <boost/fusion/support/config.hpp>
#include <boost/fusion/view/transform_view/transform_view.hpp>
namespace boost { namespace fusion
{
struct void_;
namespace result_of
{
template <typename Sequence1, typename Sequence2, typename F = void_>
struct transform
{
typedef transform_view<Sequence1, Sequence2, F> type;
};
template <typename Sequence, typename F>
#if defined(BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS)
struct transform<Sequence, F, void_>
#else
struct transform<Sequence, F>
#endif
{
typedef transform_view<Sequence, F> type;
};
}
template <typename Sequence, typename F>
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
inline typename result_of::transform<Sequence const, F>::type
transform(Sequence const& seq, F f)
{
return transform_view<Sequence const, F>(seq, f);
}
template <typename Sequence1, typename Sequence2, typename F>
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
inline typename result_of::transform<Sequence1 const, Sequence2 const, F>::type
transform(Sequence1 const& seq1, Sequence2 const& seq2, F f)
{
return transform_view<Sequence1 const, Sequence2 const, F>(seq1, seq2, f);
}
}}
#endif
@@ -0,0 +1,183 @@
// 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/list/list30_c.hpp" header
// -- DO NOT modify by hand!
namespace boost { namespace mpl {
template<
typename T
, T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10
, T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20
>
struct list21_c
: l_item<
long_<21>
, integral_c< T,C0 >
, list20_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20 >
>
{
typedef list21_c type;
typedef T value_type;
};
template<
typename T
, T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10
, T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20
, T C21
>
struct list22_c
: l_item<
long_<22>
, integral_c< T,C0 >
, list21_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21 >
>
{
typedef list22_c type;
typedef T value_type;
};
template<
typename T
, T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10
, T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20
, T C21, T C22
>
struct list23_c
: l_item<
long_<23>
, integral_c< T,C0 >
, list22_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22 >
>
{
typedef list23_c type;
typedef T value_type;
};
template<
typename T
, T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10
, T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20
, T C21, T C22, T C23
>
struct list24_c
: l_item<
long_<24>
, integral_c< T,C0 >
, list23_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23 >
>
{
typedef list24_c type;
typedef T value_type;
};
template<
typename T
, T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10
, T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20
, T C21, T C22, T C23, T C24
>
struct list25_c
: l_item<
long_<25>
, integral_c< T,C0 >
, list24_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24 >
>
{
typedef list25_c type;
typedef T value_type;
};
template<
typename T
, T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10
, T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20
, T C21, T C22, T C23, T C24, T C25
>
struct list26_c
: l_item<
long_<26>
, integral_c< T,C0 >
, list25_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25 >
>
{
typedef list26_c type;
typedef T value_type;
};
template<
typename T
, T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10
, T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20
, T C21, T C22, T C23, T C24, T C25, T C26
>
struct list27_c
: l_item<
long_<27>
, integral_c< T,C0 >
, list26_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26 >
>
{
typedef list27_c type;
typedef T value_type;
};
template<
typename T
, T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10
, T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20
, T C21, T C22, T C23, T C24, T C25, T C26, T C27
>
struct list28_c
: l_item<
long_<28>
, integral_c< T,C0 >
, list27_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27 >
>
{
typedef list28_c type;
typedef T value_type;
};
template<
typename T
, T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10
, T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20
, T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28
>
struct list29_c
: l_item<
long_<29>
, integral_c< T,C0 >
, list28_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28 >
>
{
typedef list29_c type;
typedef T value_type;
};
template<
typename T
, T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10
, T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20
, T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29
>
struct list30_c
: l_item<
long_<30>
, integral_c< T,C0 >
, list29_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29 >
>
{
typedef list30_c type;
typedef T value_type;
};
}}