Initial Commit

This commit is contained in:
Jordan Sherer
2018-02-08 21:28:33 -05:00
commit 678c1d3966
14352 changed files with 3176737 additions and 0 deletions
@@ -0,0 +1,82 @@
//---------------------------------------------------------------------------//
// 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_GATHER_HPP
#define BOOST_COMPUTE_ALGORITHM_GATHER_HPP
#include <boost/compute/command_queue.hpp>
#include <boost/compute/detail/iterator_range_size.hpp>
#include <boost/compute/detail/meta_kernel.hpp>
#include <boost/compute/exception.hpp>
#include <boost/compute/iterator/buffer_iterator.hpp>
#include <boost/compute/system.hpp>
#include <boost/compute/type_traits/type_name.hpp>
namespace boost {
namespace compute {
namespace detail {
template<class InputIterator, class MapIterator, class OutputIterator>
class gather_kernel : public meta_kernel
{
public:
gather_kernel() : meta_kernel("gather")
{}
void set_range(MapIterator first,
MapIterator last,
InputIterator input,
OutputIterator result)
{
m_count = iterator_range_size(first, last);
*this <<
"const uint i = get_global_id(0);\n" <<
result[expr<uint_>("i")] << "=" <<
input[first[expr<uint_>("i")]] << ";\n";
}
event exec(command_queue &queue)
{
if(m_count == 0) {
return event();
}
return exec_1d(queue, 0, m_count);
}
private:
size_t m_count;
};
} // end detail namespace
/// Copies the elements using the indices from the range [\p first, \p last)
/// to the range beginning at \p result using the input values from the range
/// beginning at \p input.
///
/// \see scatter()
template<class InputIterator, class MapIterator, class OutputIterator>
inline void gather(MapIterator first,
MapIterator last,
InputIterator input,
OutputIterator result,
command_queue &queue = system::default_queue())
{
detail::gather_kernel<InputIterator, MapIterator, OutputIterator> kernel;
kernel.set_range(first, last, input, result);
kernel.exec(queue);
}
} // end compute namespace
} // end boost namespace
#endif // BOOST_COMPUTE_ALGORITHM_GATHER_HPP
@@ -0,0 +1,86 @@
#include "NetworkServerLookup.hpp"
#include <stdexcept>
#include <QHostInfo>
#include <QString>
std::tuple<QHostAddress, quint16>
network_server_lookup (QString query
, quint16 default_service_port
, QHostAddress default_host_address
, QAbstractSocket::NetworkLayerProtocol required_protocol)
{
query = query.trimmed ();
QHostAddress host_address {default_host_address};
quint16 service_port {default_service_port};
QString host_name;
if (!query.isEmpty ())
{
int port_colon_index {-1};
if ('[' == query[0])
{
// assume IPv6 combined address/port syntax [<address>]:<port>
auto close_bracket_index = query.lastIndexOf (']');
host_name = query.mid (1, close_bracket_index - 1);
port_colon_index = query.indexOf (':', close_bracket_index);
}
else
{
port_colon_index = query.lastIndexOf (':');
host_name = query.left (port_colon_index);
}
host_name = host_name.trimmed ();
if (port_colon_index >= 0)
{
bool ok;
service_port = query.mid (port_colon_index + 1).trimmed ().toUShort (&ok);
if (!ok)
{
throw std::runtime_error {"network server lookup error: invalid port"};
}
}
}
if (!host_name.isEmpty ())
{
auto host_info = QHostInfo::fromName (host_name);
if (host_info.addresses ().isEmpty ())
{
throw std::runtime_error {"network server lookup error: host name lookup failed"};
}
bool found {false};
for (int i {0}; i < host_info.addresses ().size () && !found; ++i)
{
host_address = host_info.addresses ().at (i);
switch (required_protocol)
{
case QAbstractSocket::IPv4Protocol:
case QAbstractSocket::IPv6Protocol:
if (required_protocol != host_address.protocol ())
{
break;
}
// drop through
case QAbstractSocket::AnyIPProtocol:
found = true;
break;
default:
throw std::runtime_error {"network server lookup error: invalid required protocol"};
}
}
if (!found)
{
throw std::runtime_error {"network server lookup error: no suitable host address found"};
}
}
return std::make_tuple (host_address, service_port);
}
@@ -0,0 +1,132 @@
// 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_/advance_forward.hpp" header
// -- DO NOT modify by hand!
namespace boost { namespace mpl { namespace aux {
template< long N > struct advance_forward;
template<>
struct advance_forward<0>
{
template< typename Iterator > struct apply
{
typedef Iterator iter0;
typedef iter0 type;
};
/// ETI workaround
template<> struct apply<int>
{
typedef int type;
};
};
template<>
struct advance_forward<1>
{
template< typename Iterator > struct apply
{
typedef Iterator iter0;
typedef typename next<iter0>::type iter1;
typedef iter1 type;
};
/// ETI workaround
template<> struct apply<int>
{
typedef int type;
};
};
template<>
struct advance_forward<2>
{
template< typename Iterator > struct apply
{
typedef Iterator iter0;
typedef typename next<iter0>::type iter1;
typedef typename next<iter1>::type iter2;
typedef iter2 type;
};
/// ETI workaround
template<> struct apply<int>
{
typedef int type;
};
};
template<>
struct advance_forward<3>
{
template< typename Iterator > struct apply
{
typedef Iterator iter0;
typedef typename next<iter0>::type iter1;
typedef typename next<iter1>::type iter2;
typedef typename next<iter2>::type iter3;
typedef iter3 type;
};
/// ETI workaround
template<> struct apply<int>
{
typedef int type;
};
};
template<>
struct advance_forward<4>
{
template< typename Iterator > struct apply
{
typedef Iterator iter0;
typedef typename next<iter0>::type iter1;
typedef typename next<iter1>::type iter2;
typedef typename next<iter2>::type iter3;
typedef typename next<iter3>::type iter4;
typedef iter4 type;
};
/// ETI workaround
template<> struct apply<int>
{
typedef int type;
};
};
template< long N >
struct advance_forward
{
template< typename Iterator > struct apply
{
typedef typename apply_wrap1<
advance_forward<4>
, Iterator
>::type chunk_result_;
typedef typename apply_wrap1<
advance_forward<(
(N - 4) < 0
? 0
: N - 4
)>
, chunk_result_
>::type type;
};
};
}}}
@@ -0,0 +1,29 @@
#ifndef RANDOM
#define RANDOM 1
#include <cstdlib>
// #include <iostream>
class Random{
private:
unsigned long int seed; //previously LONG INT
unsigned long int seed_u;
public:
Random(void) {
this->seed=987654321u;
this->seed_u=123456789lu;
}
~Random(void){;}
void bubbleSort(int a[], int size);
double gauss(double sdev, double mean);
double uniform(double a, double b);
int uniform(int a, int b); // [a, b)
int nonUniform(int a, int b);
};
#endif
@@ -0,0 +1,252 @@
program ldpcsim300
! End-to-end test of the (300,60)/crc10 encoder and decoders.
use crc
use packjt
parameter(NRECENT=10)
character*12 recent_calls(NRECENT)
character*8 arg
integer*1, allocatable :: codeword(:), decoded(:), message(:)
integer*1, target:: i1Msg8BitBytes(9)
integer*1, target:: i1Dec8BitBytes(9)
integer*1 msgbits(60)
integer*1 apmask(300)
integer*1 cw(300)
integer*2 checksum
integer colorder(300)
integer nerrtot(300),nerrdec(300),nmpcbad(60)
logical checksumok,fsk,bpsk
real*8, allocatable :: rxdata(:)
real, allocatable :: llr(:)
real dllr(300),llrd(300)
data colorder/ &
0,1,2,3,4,5,6,7,8,9,10,11,123,12,13,14,15,16,17,18, &
19,20,21,22,23,24,25,138,26,145,27,28,29,30,31,32,33,34,35,36, &
37,154,38,39,40,41,42,43,44,144,46,47,48,49,50,51,52,53,143,54, &
125,56,57,58,124,59,120,140,157,160,55,60,61,62,156,162,141,64,65,153, &
181,183,66,170,67,68,69,130,70,164,71,72,73,74,75,63,76,77,135,78, &
79,80,176,169,82,83,84,167,180,85,136,158,129,166,175,142,134,146,121,165, &
88,89,192,90,45,91,92,93,182,189,94,95,96,173,81,97,98,178,122,126, &
132,99,100,152,186,193,101,102,151,103,104,172,159,168,150,190,147,148,201,107, &
205,177,108,198,197,174,127,109,185,110,202,87,199,171,179,187,139,137,106,131, &
206,194,112,149,155,113,128,184,196,86,114,203,212,195,208,105,188,161,163,191, &
200,209,214,204,115,218,133,111,207,117,213,216,211,217,116,215,219,220,210,221, &
118,222,223,225,224,228,226,229,231,227,233,119,234,235,232,230,237,239,236,238, &
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259, &
260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279, &
280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299/
do i=1,NRECENT
recent_calls(i)=' '
enddo
nerrtot=0
nerrdec=0
nmpcbad=0 ! Used to collect the number of errors in the message+crc part of the codeword
nargs=iargc()
if(nargs.ne.3) then
print*,'Usage: ldpcsim niter #trials s '
print*,'eg: ldpcsim 100 1000 0.84'
print*,'If s is negative, then value is ignored and sigma is calculated from SNR.'
return
endif
call getarg(1,arg)
read(arg,*) max_iterations
call getarg(2,arg)
read(arg,*) ntrials
call getarg(3,arg)
read(arg,*) s
fsk=.false.
bpsk=.true.
! don't count crc bits as data bits
N=300
K=60
! scale Eb/No for a (300,50) code
rate=real(50)/real(N)
write(*,*) "rate: ",rate
write(*,*) "niter= ",max_iterations," s= ",s
allocate ( codeword(N), decoded(K), message(K) )
allocate ( rxdata(N), llr(N) )
! The message should be packed into the first 7 bytes
i1Msg8BitBytes(1:6)=85
i1Msg8BitBytes(7)=64
! The CRC will be put into the last 2 bytes
i1Msg8BitBytes(8:9)=0
checksum = crc10 (c_loc (i1Msg8BitBytes), 9)
! For reference, the next 3 lines show how to check the CRC
i1Msg8BitBytes(8)=checksum/256
i1Msg8BitBytes(9)=iand (checksum,255)
checksumok = crc10_check(c_loc (i1Msg8BitBytes), 9)
if( checksumok ) write(*,*) 'Good checksum'
write(*,*) i1Msg8BitBytes(1:9)
mbit=0
do i=1, 7
i1=i1Msg8BitBytes(i)
do ibit=1,8
mbit=mbit+1
msgbits(mbit)=iand(1,ishft(i1,ibit-8))
enddo
enddo
i1=i1Msg8BitBytes(8) ! First 2 bits of crc10 are LSB of this byte
do ibit=1,2
msgbits(50+ibit)=iand(1,ishft(i1,ibit-2))
enddo
i1=i1Msg8BitBytes(9) ! Now shift in last 8 bits of the CRC
do ibit=1,8
msgbits(52+ibit)=iand(1,ishft(i1,ibit-8))
enddo
write(*,*) 'message'
write(*,'(9(8i1,1x))') msgbits
call encode300(msgbits,codeword)
call init_random_seed()
call sgran()
write(*,*) 'codeword'
write(*,'(38(8i1,1x))') codeword
write(*,*) "Es/N0 SNR2500 ngood nundetected nbadcrc sigma"
do idb = 20,-16,-1
!do idb = -16, -16, -1
db=idb/2.0-1.0
! sigma=1/sqrt( 2*rate*(10**(db/10.0)) ) ! to make db represent Eb/No
sigma=1/sqrt( 2*(10**(db/10.0)) ) ! db represents Es/No
ngood=0
nue=0
nbadcrc=0
nberr=0
do itrial=1, ntrials
! Create a realization of a noisy received word
do i=1,N
if( bpsk ) then
rxdata(i) = 2.0*codeword(i)-1.0 + sigma*gran()
elseif( fsk ) then
if( codeword(i) .eq. 1 ) then
r1=(1.0 + sigma*gran())**2 + (sigma*gran())**2
r2=(sigma*gran())**2 + (sigma*gran())**2
elseif( codeword(i) .eq. 0 ) then
r2=(1.0 + sigma*gran())**2 + (sigma*gran())**2
r1=(sigma*gran())**2 + (sigma*gran())**2
endif
rxdata(i)=0.35*(sqrt(r1)-sqrt(r2))
! rxdata(i)=0.35*(exp(r1)-exp(r2))
! rxdata(i)=0.12*(log(r1)-log(r2))
endif
enddo
nerr=0
do i=1,N
if( rxdata(i)*(2*codeword(i)-1.0) .lt. 0 ) nerr=nerr+1
enddo
nerrtot(nerr)=nerrtot(nerr)+1
nberr=nberr+nerr
! Correct signal normalization is important for this decoder.
! rxav=sum(rxdata)/N
! rx2av=sum(rxdata*rxdata)/N
! rxsig=sqrt(rx2av-rxav*rxav)
! rxdata=rxdata/rxsig
! To match the metric to the channel, s should be set to the noise standard deviation.
! For now, set s to the value that optimizes decode probability near threshold.
! The s parameter can be tuned to trade a few tenth's dB of threshold for an order of
! magnitude in UER
if( s .lt. 0 ) then
ss=sigma
else
ss=s
endif
llr=2.0*rxdata/(ss*ss)
apmask=0
! max_iterations is max number of belief propagation iterations
call bpdecode300(llr, apmask, max_iterations, decoded, niterations, cw)
if( niterations .lt. 0 ) then
norder=3
call osd300(llr, norder, decoded, niterations, cw)
endif
n2err=0
do i=1,N
if( cw(i)*(2*codeword(i)-1.0) .lt. 0 ) n2err=n2err+1
enddo
!write(*,*) nerr,niterations,n2err
damp=0.75
ndither=0
if( niterations .lt. 0 ) then
do i=1, ndither
do in=1,N
dllr(in)=damp*gran()
enddo
llrd=llr+dllr
call bpdecode300(llrd, apmask, max_iterations, decoded, niterations, cw)
if( niterations .ge. 0 ) exit
enddo
endif
! If the decoder finds a valid codeword, niterations will be .ge. 0.
if( niterations .ge. 0 ) then
! Check the CRC
do ibyte=1,6
itmp=0
do ibit=1,8
itmp=ishft(itmp,1)+iand(1,decoded((ibyte-1)*8+ibit))
enddo
i1Dec8BitBytes(ibyte)=itmp
enddo
i1Dec8BitBytes(7)=decoded(49)*128+decoded(50)*64
! Need to pack the received crc into bytes 8 and 9 for crc10_check
i1Dec8BitBytes(8)=decoded(51)*2+decoded(52)
i1Dec8BitBytes(9)=decoded(53)*128+decoded(54)*64+decoded(55)*32+decoded(56)*16
i1Dec8BitBytes(9)=i1Dec8BitBytes(9)+decoded(57)*8+decoded(58)*4+decoded(59)*2+decoded(60)*1
ncrcflag=0
if( crc10_check( c_loc( i1Dec8BitBytes ), 9 ) ) ncrcflag=1
if( ncrcflag .ne. 1 ) then
nbadcrc=nbadcrc+1
endif
nueflag=0
nerrmpc=0
do i=1,K ! find number of errors in message+crc part of codeword
if( msgbits(i) .ne. decoded(i) ) then
nueflag=1
nerrmpc=nerrmpc+1
endif
enddo
nmpcbad(nerrmpc)=nmpcbad(nerrmpc)+1 ! This histogram should inform our selection of CRC poly
if( ncrcflag .eq. 1 .and. nueflag .eq. 0 ) then
ngood=ngood+1
nerrdec(nerr)=nerrdec(nerr)+1
else if( ncrcflag .eq. 1 .and. nueflag .eq. 1 ) then
nue=nue+1;
endif
endif
enddo
snr2500=db+10*log10(1.389/2500.0)
pberr=real(nberr)/(real(ntrials*N))
write(*,"(f4.1,4x,f5.1,1x,i8,1x,i8,1x,i8,8x,f5.2,8x,e10.3)") db,snr2500,ngood,nue,nbadcrc,ss,pberr
enddo
open(unit=23,file='nerrhisto.dat',status='unknown')
do i=1,120
write(23,'(i4,2x,i10,i10,f10.2)') i,nerrdec(i),nerrtot(i),real(nerrdec(i))/real(nerrtot(i)+1e-10)
enddo
close(23)
open(unit=25,file='nmpcbad.dat',status='unknown')
do i=1,60
write(25,'(i4,2x,i10)') i,nmpcbad(i)
enddo
close(25)
end program ldpcsim300
@@ -0,0 +1,206 @@
subroutine iscat(cdat0,npts0,nh,npct,t2,pick,cfile6,minsync,ntol, &
NFreeze,MouseDF,mousebutton,mode4,nafc,nmore,psavg,maxlines,nlines,line)
! Decode an ISCAT signal
parameter (NMAX=30*3101)
parameter (NSZ=4*1400)
character cfile6*6 !File time
character c42*42
character msg*29,msg1*29,msgbig*29
character*80 line(100)
character csync*1
complex cdat0(NMAX)
complex cdat(NMAX)
real s0(288,NSZ)
real fs1(0:41,30)
real psavg(72) !Average spectrum of whole file
integer nsum(30)
integer ntol
integer icos(4)
logical pick,last
data icos/0,1,3,2/
data nsync/4/,nlen/2/,ndat/18/
data c42/'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ /.?@-'/
save cdat,s0
nlines = 0
fsample=3100.78125 !Sample rate after 9/32 downsampling
nsps=144/mode4
bigworst=-1.e30 !Silence compiler warnings ...
bigxsync=0.
bigsig=-1.e30
msglenbig=0
ndf0big=0
nfdotbig=0
bigt2=0.
bigavg=0.
bigtana=0.
if(nmore.eq.-999) bigsig=-1 !... to here
last=.false.
do inf=1,6 !Loop over data-segment sizes
nframes=2**inf
if(nframes*24*nsps.gt.npts0) then
nframes=npts0/(24*nsps)
last=.true.
endif
npts=nframes*24*nsps
do ia=1,npts0-npts,nsps*24 !Loop over start times stepped by 1 frame
ib=ia+npts-1
cdat(1:npts)=cdat0(ia:ib)
t3=(ia + 0.5*npts)/fsample + 0.9
if(pick) t3=t2+t3
! Compute symbol spectra and establish sync:
call synciscat(cdat,npts,nh,npct,s0,jsym,df,ntol,NFreeze, &
MouseDF,mousebutton,mode4,nafc,psavg,xsync,sig,ndf0,msglen, &
ipk,jpk,idf,df1)
nfdot=nint(idf*df1)
isync=xsync
if(msglen.eq.0 .or. isync.lt.max(minsync,0)) then
msglen=0
worst=1.
avg=1.
ndf0=0
cycle
endif
ipk3=0 !Silence compiler warning
nblk=nsync+nlen+ndat
fs1=0.
nsum=0
nfold=jsym/96
jb=96*nfold
k=0
n=0
do j=jpk,jsym,4 !Fold information symbols into fs1
k=k+1
km=mod(k-1,nblk)+1
if(km.gt.6) then
n=n+1
m=mod(n-1,msglen)+1
ii=nint(idf*float(j-jb/2)/float(jb))
do i=0,41
iii=ii+ipk+2*i
if(iii.ge.1 .and. iii.le.288) fs1(i,m)=fs1(i,m) + s0(iii,j)
enddo
nsum(m)=nsum(m)+1
endif
enddo
do m=1,msglen
fs1(0:41,m)=fs1(0:41,m)/nsum(m)
enddo
! Read out the message contents:
msg= ' '
msg1=' '
mpk=0
worst=9999.
sum=0.
do m=1,msglen
smax=0.
smax2=0.
do i=0,41
if(fs1(i,m).gt.smax) then
smax=fs1(i,m)
ipk3=i
endif
enddo
do i=0,41
if(fs1(i,m).gt.smax2 .and. i.ne.ipk3) smax2=fs1(i,m)
enddo
rr=0.
if(smax2.gt.0.0) rr=smax/smax2
sum=sum + rr
if(rr.lt.worst) worst=rr
if(ipk3.eq.40) mpk=m
msg1(m:m)=c42(ipk3+1:ipk3+1)
enddo
avg=sum/msglen
if(mpk.eq.1) then
msg=msg1(2:)
else if(mpk.lt.msglen) then
msg=msg1(mpk+1:msglen)//msg1(1:mpk-1)
else
msg=msg1(1:msglen-1)
endif
ttot=npts/3100.78125
if(worst.gt.bigworst) then
bigworst=worst
bigavg=avg
bigxsync=xsync
bigsig=sig
ndf0big=ndf0
nfdotbig=nfdot
msgbig=msg
msglenbig=msglen
bigt2=t3
bigtana=nframes*24*nsps/fsample
endif
isync = xsync
if(avg.gt.2.5 .and. xsync.ge.max(float(minsync),1.5) .and. &
maxlines.ge.2) then
nsig=nint(sig)
nworst=10.0*(worst-1.0)
navg=10.0*(avg-1.0)
if(nworst.gt.10) nworst=10
if(navg.gt.10) navg=10
tana=nframes*24*nsps/fsample
csync=' '
if(isync.ge.1) csync='*'
if(nlines.le.maxlines-1) nlines = nlines + 1
write(line(nlines),1020) cfile6,isync,nsig,t2,ndf0,nfdot,csync, &
msg(1:28),msglen,navg,nworst,tana,char(0)
endif
enddo
if(last) exit
enddo
worst=bigworst
avg=bigavg
xsync=bigxsync
sig=bigsig
ndf0=ndf0big
nfdot=nfdotbig
msg=msgbig
msglen=msglenbig
t2=bigt2
tana=bigtana
isync=xsync
nworst=10.0*(worst-1.0)
navg=10.0*(avg-1.0)
if(nworst.gt.10) nworst=10
if(navg.gt.10) navg=10
if(navg.le.0 .or. isync.lt.max(minsync,0)) then
msg=' '
nworst=0
navg=0
ndf0=0
nfdot=0
sig=-20
msglen=0
tana=0.
t2=0.
endif
csync=' '
if(isync.ge.1) csync='*'
nsig=nint(sig)
if(nlines.le.maxlines-1) nlines = nlines + 1
write(line(nlines),1020) cfile6,isync,nsig,t2,ndf0,nfdot,csync,msg(1:28), &
msglen,navg,nworst,tana,char(0)
1020 format(a6,2i4,f5.1,i5,i4,1x,a1,2x,a28,i4,i3,2x,i1,f5.1,a1)
return
end subroutine iscat
@@ -0,0 +1,87 @@
// (C) Copyright John Maddock 2001 - 2003.
// (C) Copyright Darin Adler 2001 - 2002.
// (C) Copyright Bill Kempf 2002.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for most recent version.
// Mac OS specific config options:
#define BOOST_PLATFORM "Mac OS"
#if __MACH__ && !defined(_MSL_USING_MSL_C)
// Using the Mac OS X system BSD-style C library.
# ifndef BOOST_HAS_UNISTD_H
# define BOOST_HAS_UNISTD_H
# endif
//
// Begin by including our boilerplate code for POSIX
// feature detection, this is safe even when using
// the MSL as Metrowerks supply their own <unistd.h>
// to replace the platform-native BSD one. G++ users
// should also always be able to do this on MaxOS X.
//
# include <boost/config/posix_features.hpp>
# ifndef BOOST_HAS_STDINT_H
# define BOOST_HAS_STDINT_H
# endif
//
// BSD runtime has pthreads, sigaction, sched_yield and gettimeofday,
// of these only pthreads are advertised in <unistd.h>, so set the
// other options explicitly:
//
# define BOOST_HAS_SCHED_YIELD
# define BOOST_HAS_GETTIMEOFDAY
# define BOOST_HAS_SIGACTION
# if (__GNUC__ < 3) && !defined( __APPLE_CC__)
// GCC strange "ignore std" mode works better if you pretend everything
// is in the std namespace, for the most part.
# define BOOST_NO_STDC_NAMESPACE
# endif
# if (__GNUC__ >= 4)
// Both gcc and intel require these.
# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE
# define BOOST_HAS_NANOSLEEP
# endif
#else
// Using the MSL C library.
// We will eventually support threads in non-Carbon builds, but we do
// not support this yet.
# if ( defined(TARGET_API_MAC_CARBON) && TARGET_API_MAC_CARBON ) || ( defined(TARGET_CARBON) && TARGET_CARBON )
# if !defined(BOOST_HAS_PTHREADS)
// MPTasks support is deprecated/removed from Boost:
//# define BOOST_HAS_MPTASKS
# elif ( __dest_os == __mac_os_x )
// We are doing a Carbon/Mach-O/MSL build which has pthreads, but only the
// gettimeofday and no posix.
# define BOOST_HAS_GETTIMEOFDAY
# endif
#ifdef BOOST_HAS_PTHREADS
# define BOOST_HAS_THREADS
#endif
// The remote call manager depends on this.
# define BOOST_BIND_ENABLE_PASCAL
# endif
#endif
@@ -0,0 +1,107 @@
module ft8_decode
type :: ft8_decoder
procedure(ft8_decode_callback), pointer :: callback
contains
procedure :: decode
end type ft8_decoder
abstract interface
subroutine ft8_decode_callback (this,sync,snr,dt,freq,nbadcrc,decoded)
import ft8_decoder
implicit none
class(ft8_decoder), intent(inout) :: this
real, intent(in) :: sync
integer, intent(in) :: snr
real, intent(in) :: dt
real, intent(in) :: freq
integer, intent(in) :: nbadcrc
character(len=22), intent(in) :: decoded
end subroutine ft8_decode_callback
end interface
contains
subroutine decode(this,callback,iwave,nfqso,newdat,nutc,nfa, &
nfb,nagain,ndepth,nsubmode,mycall12,hiscall12,hisgrid6)
!use wavhdr
use timer_module, only: timer
include 'fsk4hf/ft8_params.f90'
!type(hdr) h
class(ft8_decoder), intent(inout) :: this
procedure(ft8_decode_callback) :: callback
real s(NH1,NHSYM)
real candidate(3,200)
real dd(15*12000)
logical, intent(in) :: newdat, nagain
character*12 mycall12, hiscall12
character*6 hisgrid6
integer*2 iwave(15*12000)
integer apsym(KK)
character datetime*13,message*22
save s,dd
this%callback => callback
write(datetime,1001) nutc !### TEMPORARY ###
1001 format("000000_",i6.6)
if(index(hisgrid6," ").eq.0) hisgrid6="EN50"
call ft8apset(mycall12,hiscall12,hisgrid6,apsym)
dd=iwave
call timer('sync8 ',0)
call sync8(dd,nfa,nfb,nfqso,s,candidate,ncand)
call timer('sync8 ',1)
syncmin=2.0
do icand=1,ncand
sync=candidate(3,icand)
if(sync.lt.syncmin) cycle
f1=candidate(1,icand)
xdt=candidate(2,icand)
nsnr0=min(99,nint(10.0*log10(sync) - 25.5)) !### empirical ###
call timer('ft8b ',0)
call ft8b(dd,newdat,nfqso,ndepth,icand,sync,f1,xdt,apsym,nharderrors, &
dmin,nbadcrc,message,xsnr)
nsnr=xsnr
xdt=xdt-0.6
call timer('ft8b ',1)
if (associated(this%callback)) call this%callback(sync,nsnr,xdt, &
f1,nbadcrc,message)
! write(*,'(f7.2,i5,f7.2,f9.1,i5,f7.2,2x,a22)') sync,nsnr,xdt,f1,nharderrors,dmin,message
! write(13,1110) datetime,0,nsnr,xdt,f1,nharderrors,dmin,message
!1110 format(a13,2i4,f6.2,f7.1,i4,' ~ ',f6.2,2x,a22,' FT8')
! write(51,3051) xdt,f1,sync,dmin,nsnr,nharderrors,nbadcrc,message
!3051 format(4f9.1,3i5,2x,a22)
! flush(51)
enddo
!h=default_header(12000,NMAX)
!open(10,file='subtract.wav',status='unknown',access='stream')
!iwave=nint(dd)
!write(10) h,iwave
!close(10)
return
end subroutine decode
end module ft8_decode
subroutine ft8apset(mycall12,hiscall12,hisgrid6,apsym)
parameter(NAPM=4,KK=87)
character*12 mycall12,hiscall12
character*22 msg,msgsent
character*6 mycall,hiscall
character*6 hisgrid6
character*4 hisgrid
integer apsym(KK)
integer*1 msgbits(KK)
integer itone(KK)
mycall=mycall12(1:6)
hiscall=hiscall12(1:6)
hisgrid=hisgrid6(1:4)
msg=mycall//' '//hiscall//' '//hisgrid
call genft8(msg,msgsent,msgbits,itone)
apsym=2*msgbits-1
return
end subroutine ft8apset
@@ -0,0 +1,54 @@
wsprd is a decoder for K1JT's Weak Signal Propagation Reporter (WSPR) mode.
The program is written in C and is a command-line program that reads from a
.c2 file or .wav file and writes output to the console. It is used by WSJT-X
for wspr-mode decoding.
USAGE:
wsprd [options...] infile
OPTIONS:
-a <path> path to writeable data files, default="."
-c write .c2 file at the end of the first pass
-e x (x is transceiver dial frequency error in Hz)
-f x (x is transceiver dial frequency in MHz)
-H do not use (or update) the hash table
-m decode wspr-15 .wav file
-q quick mode - doesn't dig deep for weak signals
-s single pass mode, no subtraction (same as original wsprd)
-v verbose mode (shows dupes)
-w wideband mode - decode signals within +/- 150 Hz of center
-z x (x is fano metric table bias, default is 0.42)
infile can be either .wav or .c2
e.g.
./wsprd -wf 14.0956 140709_2258.wav
Note that for .c2 files, the frequency within the file overrides the command
line value.
FEATURES:
By default, wsprd reports signals that are within +/- 110 Hz of the
subband center frequency. The wideband option (-w) extends this to +/- 150 Hz.
wsprd maintains a hashtable and will decode all three types of wspr
messages. An option (-H) is available to turn off use of the hashtable.
The symbols are decoded using Phil Karn's sequential decoder routine,
fano.c.
NOTES:
This program attempts to maximize the number of successful decodes per transmit
interval by trying to decode virtually every peak in the averaged spectrum.
The program also implements two-pass decoding, whereby signals that are successfully
decoded are subtracted one-by-one during the first decoding pass. Then, the
decoder is run again. In many cases the subtraction process will uncover signals
that can then be successfully decoded on the second pass.
There will be occasional duplicate decodes when two closely spaced
peaks come from the same signal. The program removes dupes based on callsign
and frequency. Two decodes that have the same callsign and estimated frequencies
that are within 1 Hz will be treated as decodes of the same signal. This
dupechecking is turned off with the -v flag.
@@ -0,0 +1,199 @@
subroutine msk40spd(cbig,n,ntol,mycall,hiscall,bswl,nhasharray,recent_calls, &
nrecent,nsuccess,msgreceived,fc,fret,tret,navg)
! msk40 short-ping-decoder
use timer_module, only: timer
parameter (NSPM=240, MAXSTEPS=150, NFFT=NSPM, MAXCAND=5, NPATTERNS=6)
character*6 mycall,hiscall
character*22 msgreceived
character*12 recent_calls(nrecent)
complex cbig(n)
complex cdat(3*NSPM) !Analytic signal
complex c(NSPM)
complex ct(NSPM)
complex ctmp(NFFT)
integer, dimension(1) :: iloc
integer indices(MAXSTEPS)
integer npkloc(10)
integer navpatterns(3,NPATTERNS)
integer navmask(3)
integer nstart(MAXCAND)
integer nhasharray(nrecent,nrecent)
logical ismask(NFFT)
logical*1 bswl
real detmet(-2:MAXSTEPS+3)
real detmet2(-2:MAXSTEPS+3)
real detfer(MAXSTEPS)
real rcw(12)
real ferrs(MAXCAND)
real snrs(MAXCAND)
real tonespec(NFFT)
real tpat(NPATTERNS)
real*8 dt, df, fs, pi, twopi
logical first
data first/.true./
data navpatterns/ &
0,1,0, &
1,0,0, &
0,0,1, &
1,1,0, &
0,1,1, &
1,1,1/
data tpat/1.5,0.5,2.5,1.0,2.0,1.5/
save df,first,fs,pi,twopi,dt,tframe,rcw
if(first) then
nmatchedfilter=1
! define half-sine pulse and raised-cosine edge window
pi=4d0*datan(1d0)
twopi=8d0*datan(1d0)
fs=12000.0
dt=1.0/fs
df=fs/NFFT
tframe=NSPM/fs
do i=1,12
angle=(i-1)*pi/12.0
rcw(i)=(1-cos(angle))/2
enddo
first=.false.
endif
! fill the detmet, detferr arrays
nstep=(n-NSPM)/60 ! 20ms/4=5ms steps
detmet=0
detmet2=0
detfer=-999.99
nfhi=2*(fc+500)
nflo=2*(fc-500)
ihlo=nint((nfhi-2*ntol)/df)+1
ihhi=nint((nfhi+2*ntol)/df)+1
illo=nint((nflo-2*ntol)/df)+1
ilhi=nint((nflo+2*ntol)/df)+1
i2000=nint(nflo/df)+1
i4000=nint(nfhi/df)+1
do istp=1,nstep
ns=1+60*(istp-1)
ne=ns+NSPM-1
if( ne .gt. n ) exit
ctmp=cmplx(0.0,0.0)
ctmp(1:NSPM)=cbig(ns:ne)
! Coarse carrier frequency sync - seek tones at 2000 Hz and 4000 Hz in
! squared signal spectrum.
ctmp=ctmp**2
ctmp(1:12)=ctmp(1:12)*rcw
ctmp(NSPM-11:NSPM)=ctmp(NSPM-11:NSPM)*rcw(12:1:-1)
call four2a(ctmp,NFFT,1,-1,1)
tonespec=abs(ctmp)**2
ismask=.false.
ismask(ihlo:ihhi)=.true. ! high tone search window
iloc=maxloc(tonespec,ismask)
ihpk=iloc(1)
deltah=-real( (ctmp(ihpk-1)-ctmp(ihpk+1)) / (2*ctmp(ihpk)-ctmp(ihpk-1)-ctmp(ihpk+1)) )
ah=tonespec(ihpk)
ahavp=(sum(tonespec,ismask)-ah)/count(ismask)
trath=ah/(ahavp+0.01)
ismask=.false.
ismask(illo:ilhi)=.true. ! window for low tone
iloc=maxloc(tonespec,ismask)
ilpk=iloc(1)
deltal=-real( (ctmp(ilpk-1)-ctmp(ilpk+1)) / (2*ctmp(ilpk)-ctmp(ilpk-1)-ctmp(ilpk+1)) )
al=tonespec(ilpk)
alavp=(sum(tonespec,ismask)-al)/count(ismask)
tratl=al/(alavp+0.01)
fdiff=(ihpk+deltah-ilpk-deltal)*df
ferrh=(ihpk+deltah-i4000)*df/2.0
ferrl=(ilpk+deltal-i2000)*df/2.0
if( ah .ge. al ) then
ferr=ferrh
else
ferr=ferrl
endif
detmet(istp)=max(ah,al)
detmet2(istp)=max(trath,tratl)
detfer(istp)=ferr
enddo ! end of detection-metric and frequency error estimation loop
call indexx(detmet(1:nstep),nstep,indices) !find median of detection metric vector
xmed=detmet(indices(nstep/4))
detmet=detmet/xmed ! noise floor of detection metric is 1.0
ndet=0
do ip=1,MAXCAND ! Find candidates
iloc=maxloc(detmet(1:nstep))
il=iloc(1)
if( (detmet(il) .lt. 3.5) ) exit
if( abs(detfer(il)) .le. ntol ) then
ndet=ndet+1
nstart(ndet)=1+(il-1)*60+1
ferrs(ndet)=detfer(il)
snrs(ndet)=12.0*log10(detmet(il))/2-9.0
endif
detmet(il)=0.0
enddo
if( ndet .lt. 3 ) then
do ip=1,MAXCAND-ndet ! Find candidates
iloc=maxloc(detmet2(1:nstep))
il=iloc(1)
if( (detmet2(il) .lt. 12.0) ) exit
if( abs(detfer(il)) .le. ntol ) then
ndet=ndet+1
nstart(ndet)=1+(il-1)*60+1
ferrs(ndet)=detfer(il)
snrs(ndet)=12.0*log10(detmet2(il))/2-9.0
endif
detmet2(il)=0.0
enddo
endif
nsuccess=0
msgreceived=' '
npeaks=2
ntol0=29
deltaf=7.2
do icand=1,ndet ! Try to sync/demod/decode each candidate.
ib=max(1,nstart(icand)-NSPM)
ie=ib-1+3*NSPM
if( ie .gt. n ) then
ie=n
ib=ie-3*NSPM+1
endif
cdat=cbig(ib:ie)
fo=fc+ferrs(icand)
xsnr=snrs(icand)
do iav=1,NPATTERNS
navmask=navpatterns(1:3,iav)
call msk40sync(cdat,3,ntol0,deltaf,navmask,npeaks,fo,fest,npkloc, &
nsyncsuccess,c)
if( nsyncsuccess .eq. 0 ) cycle
do ipk=1,npeaks
do is=1,3
ic0=npkloc(ipk)
if( is.eq.2) ic0=max(1,ic0-1)
if( is.eq.3) ic0=min(NSPM,ic0+1)
ct=cshift(c,ic0-1)
call msk40decodeframe(ct,mycall,hiscall,xsnr,bswl,nhasharray, &
recent_calls,nrecent,msgreceived,ndecodesuccess)
if( ndecodesuccess .gt. 0 ) then
!write(*,*) icand, iav, ipk, is, tret, fret, msgreceived
tret=(nstart(icand)+NSPM/2)/fs
fret=fest
navg=sum(navmask)
nsuccess=ndecodesuccess
return
endif
enddo
enddo
enddo
enddo ! candidate loop
return
end subroutine msk40spd
@@ -0,0 +1,228 @@
//
// bind/bind_mf2_cc.hpp - member functions, type<> syntax
//
// Do not include this header directly.
//
// Copyright (c) 2001 Peter Dimov and Multi Media Ltd.
// Copyright (c) 2008 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
// See http://www.boost.org/libs/bind/bind.html for documentation.
//
// 0
template<class Rt2, class R, class T,
class A1>
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf0)<R, T>, typename _bi::list_av_1<A1>::type>
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (), A1 a1)
{
typedef _mfi::BOOST_BIND_MF_NAME(mf0)<R, T> F;
typedef typename _bi::list_av_1<A1>::type list_type;
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1));
}
template<class Rt2, class R, class T,
class A1>
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf0)<R, T>, typename _bi::list_av_1<A1>::type>
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) () const, A1 a1)
{
typedef _mfi::BOOST_BIND_MF_NAME(cmf0)<R, T> F;
typedef typename _bi::list_av_1<A1>::type list_type;
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1));
}
// 1
template<class Rt2, class R, class T,
class B1,
class A1, class A2>
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf1)<R, T, B1>, typename _bi::list_av_2<A1, A2>::type>
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1), A1 a1, A2 a2)
{
typedef _mfi::BOOST_BIND_MF_NAME(mf1)<R, T, B1> F;
typedef typename _bi::list_av_2<A1, A2>::type list_type;
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2));
}
template<class Rt2, class R, class T,
class B1,
class A1, class A2>
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf1)<R, T, B1>, typename _bi::list_av_2<A1, A2>::type>
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1) const, A1 a1, A2 a2)
{
typedef _mfi::BOOST_BIND_MF_NAME(cmf1)<R, T, B1> F;
typedef typename _bi::list_av_2<A1, A2>::type list_type;
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2));
}
// 2
template<class Rt2, class R, class T,
class B1, class B2,
class A1, class A2, class A3>
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf2)<R, T, B1, B2>, typename _bi::list_av_3<A1, A2, A3>::type>
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2), A1 a1, A2 a2, A3 a3)
{
typedef _mfi::BOOST_BIND_MF_NAME(mf2)<R, T, B1, B2> F;
typedef typename _bi::list_av_3<A1, A2, A3>::type list_type;
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3));
}
template<class Rt2, class R, class T,
class B1, class B2,
class A1, class A2, class A3>
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf2)<R, T, B1, B2>, typename _bi::list_av_3<A1, A2, A3>::type>
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2) const, A1 a1, A2 a2, A3 a3)
{
typedef _mfi::BOOST_BIND_MF_NAME(cmf2)<R, T, B1, B2> F;
typedef typename _bi::list_av_3<A1, A2, A3>::type list_type;
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3));
}
// 3
template<class Rt2, class R, class T,
class B1, class B2, class B3,
class A1, class A2, class A3, class A4>
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf3)<R, T, B1, B2, B3>, typename _bi::list_av_4<A1, A2, A3, A4>::type>
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3), A1 a1, A2 a2, A3 a3, A4 a4)
{
typedef _mfi::BOOST_BIND_MF_NAME(mf3)<R, T, B1, B2, B3> F;
typedef typename _bi::list_av_4<A1, A2, A3, A4>::type list_type;
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4));
}
template<class Rt2, class R, class T,
class B1, class B2, class B3,
class A1, class A2, class A3, class A4>
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf3)<R, T, B1, B2, B3>, typename _bi::list_av_4<A1, A2, A3, A4>::type>
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) const, A1 a1, A2 a2, A3 a3, A4 a4)
{
typedef _mfi::BOOST_BIND_MF_NAME(cmf3)<R, T, B1, B2, B3> F;
typedef typename _bi::list_av_4<A1, A2, A3, A4>::type list_type;
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4));
}
// 4
template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4,
class A1, class A2, class A3, class A4, class A5>
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf4)<R, T, B1, B2, B3, B4>, typename _bi::list_av_5<A1, A2, A3, A4, A5>::type>
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
{
typedef _mfi::BOOST_BIND_MF_NAME(mf4)<R, T, B1, B2, B3, B4> F;
typedef typename _bi::list_av_5<A1, A2, A3, A4, A5>::type list_type;
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5));
}
template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4,
class A1, class A2, class A3, class A4, class A5>
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf4)<R, T, B1, B2, B3, B4>, typename _bi::list_av_5<A1, A2, A3, A4, A5>::type>
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
{
typedef _mfi::BOOST_BIND_MF_NAME(cmf4)<R, T, B1, B2, B3, B4> F;
typedef typename _bi::list_av_5<A1, A2, A3, A4, A5>::type list_type;
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5));
}
// 5
template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4, class B5,
class A1, class A2, class A3, class A4, class A5, class A6>
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf5)<R, T, B1, B2, B3, B4, B5>, typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type>
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
{
typedef _mfi::BOOST_BIND_MF_NAME(mf5)<R, T, B1, B2, B3, B4, B5> F;
typedef typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type list_type;
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6));
}
template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4, class B5,
class A1, class A2, class A3, class A4, class A5, class A6>
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf5)<R, T, B1, B2, B3, B4, B5>, typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type>
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
{
typedef _mfi::BOOST_BIND_MF_NAME(cmf5)<R, T, B1, B2, B3, B4, B5> F;
typedef typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type list_type;
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6));
}
// 6
template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4, class B5, class B6,
class A1, class A2, class A3, class A4, class A5, class A6, class A7>
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf6)<R, T, B1, B2, B3, B4, B5, B6>, typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type>
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
{
typedef _mfi::BOOST_BIND_MF_NAME(mf6)<R, T, B1, B2, B3, B4, B5, B6> F;
typedef typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type list_type;
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7));
}
template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4, class B5, class B6,
class A1, class A2, class A3, class A4, class A5, class A6, class A7>
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf6)<R, T, B1, B2, B3, B4, B5, B6>, typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type>
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
{
typedef _mfi::BOOST_BIND_MF_NAME(cmf6)<R, T, B1, B2, B3, B4, B5, B6> F;
typedef typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type list_type;
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7));
}
// 7
template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4, class B5, class B6, class B7,
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf7)<R, T, B1, B2, B3, B4, B5, B6, B7>, typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type>
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
{
typedef _mfi::BOOST_BIND_MF_NAME(mf7)<R, T, B1, B2, B3, B4, B5, B6, B7> F;
typedef typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type;
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8));
}
template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4, class B5, class B6, class B7,
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf7)<R, T, B1, B2, B3, B4, B5, B6, B7>, typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type>
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
{
typedef _mfi::BOOST_BIND_MF_NAME(cmf7)<R, T, B1, B2, B3, B4, B5, B6, B7> F;
typedef typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type;
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8));
}
// 8
template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8,
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8>, typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type>
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
{
typedef _mfi::BOOST_BIND_MF_NAME(mf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8> F;
typedef typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type;
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9));
}
template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8,
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8>, typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type>
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
{
typedef _mfi::BOOST_BIND_MF_NAME(cmf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8> F;
typedef typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type;
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9));
}
@@ -0,0 +1,76 @@
// 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 ARG_FROM_PYTHON_DWA2002128_HPP
# define ARG_FROM_PYTHON_DWA2002128_HPP
# include <boost/python/detail/prefix.hpp>
# include <boost/python/converter/arg_from_python.hpp>
# if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \
|| BOOST_WORKAROUND(BOOST_INTEL_WIN, BOOST_TESTED_AT(800))
# include <boost/type_traits/remove_cv.hpp>
#endif
namespace boost { namespace python {
template <class T>
struct arg_from_python
: converter::select_arg_from_python<
# if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \
|| BOOST_WORKAROUND(BOOST_INTEL_WIN, BOOST_TESTED_AT(800))
typename boost::remove_cv<T>::type
# else
T
# endif
>::type
{
typedef typename converter::select_arg_from_python<
# if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \
|| BOOST_WORKAROUND(BOOST_INTEL_WIN, BOOST_TESTED_AT(800))
typename boost::remove_cv<T>::type
# else
T
# endif
>::type base;
arg_from_python(PyObject*);
};
// specialization for PyObject*
template <>
struct arg_from_python<PyObject*>
{
typedef PyObject* result_type;
arg_from_python(PyObject* p) : m_source(p) {}
bool convertible() const { return true; }
PyObject* operator()() const { return m_source; }
private:
PyObject* m_source;
};
template <>
struct arg_from_python<PyObject* const&>
{
typedef PyObject* const& result_type;
arg_from_python(PyObject* p) : m_source(p) {}
bool convertible() const { return true; }
PyObject*const& operator()() const { return m_source; }
private:
PyObject* m_source;
};
//
// implementations
//
template <class T>
inline arg_from_python<T>::arg_from_python(PyObject* source)
: base(source)
{
}
}} // namespace boost::python
#endif // ARG_FROM_PYTHON_DWA2002128_HPP
@@ -0,0 +1,116 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2006 Dan Marsden
Distributed under the 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(BOOST_FUSION_AT_KEY_20060304_1755)
#define BOOST_FUSION_AT_KEY_20060304_1755
#include <boost/fusion/support/config.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/fusion/sequence/intrinsic_fwd.hpp>
#include <boost/fusion/sequence/intrinsic/has_key.hpp>
#include <boost/fusion/algorithm/query/find.hpp>
#include <boost/fusion/iterator/deref_data.hpp>
#include <boost/fusion/support/tag_of.hpp>
#include <boost/fusion/support/category_of.hpp>
#include <boost/fusion/support/detail/access.hpp>
#include <boost/mpl/empty_base.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/or.hpp>
namespace boost { namespace fusion
{
// Special tags:
struct sequence_facade_tag;
struct boost_array_tag; // boost::array tag
struct mpl_sequence_tag; // mpl sequence tag
struct std_pair_tag; // std::pair tag
namespace extension
{
template <typename Tag>
struct at_key_impl
{
template <typename Seq, typename Key>
struct apply
{
typedef typename
result_of::deref_data<
typename result_of::find<Seq, Key>::type
>::type
type;
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
static type
call(Seq& seq)
{
return fusion::deref_data(fusion::find<Key>(seq));
}
};
};
template <>
struct at_key_impl<sequence_facade_tag>
{
template <typename Sequence, typename Key>
struct apply : Sequence::template at_key_impl<Sequence, Key> {};
};
template <>
struct at_key_impl<boost_array_tag>;
template <>
struct at_key_impl<mpl_sequence_tag>;
template <>
struct at_key_impl<std_pair_tag>;
}
namespace detail
{
template <typename Sequence, typename Key, typename Tag>
struct at_key_impl
: mpl::if_<
mpl::or_<
typename extension::has_key_impl<Tag>::template apply<Sequence, Key>
, traits::is_unbounded<Sequence>
>
, typename extension::at_key_impl<Tag>::template apply<Sequence, Key>
, mpl::empty_base
>::type
{};
}
namespace result_of
{
template <typename Sequence, typename Key>
struct at_key
: detail::at_key_impl<Sequence, Key, typename detail::tag_of<Sequence>::type>
{};
}
template <typename Key, typename Sequence>
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
inline typename
lazy_disable_if<
is_const<Sequence>
, result_of::at_key<Sequence, Key>
>::type
at_key(Sequence& seq)
{
return result_of::at_key<Sequence, Key>::call(seq);
}
template <typename Key, typename Sequence>
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
inline typename result_of::at_key<Sequence const, Key>::type
at_key(Sequence const& seq)
{
return result_of::at_key<Sequence const, Key>::call(seq);
}
}}
#endif
@@ -0,0 +1,17 @@
// Copyright David Abrahams 2003.
// Distributed under the 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 CONTEXT_RESULT_CONVERTER_DWA2003917_HPP
# define CONTEXT_RESULT_CONVERTER_DWA2003917_HPP
namespace boost { namespace python { namespace converter {
// A ResultConverter base class used to indicate that this result
// converter should be constructed with the original Python argument
// list.
struct context_result_converter {};
}}} // namespace boost::python::converter
#endif // CONTEXT_RESULT_CONVERTER_DWA2003917_HPP
@@ -0,0 +1,24 @@
Linux Windows
Program Time Decodes Time Decodes
-------------------------------------------------
wsprd (Mar 2013) 2413 1451 2718 1451
k9an-wsprd 1800 2122
k9an_wsprd -q 354 1939
wsprd 399 2190 356 2190
wsprd -q 214 2034 192 2034
wsprd* 1240 2215
wsprd# 1599 2220
-------------------------------------------------
* maxcycles=30000
# maxcycles=20000, iifac=1
-------------------------------------------------
Test data: 638 *.wav files (recorded by WSJT-X)
-------------------------------------------------
Linux machine: Core 2 Duo, E6750 CPU
Windows machine: 4-Core i5-2500 CPU
wsprd git commit: eecc274
-------------------------------------------------
@@ -0,0 +1,184 @@
// Copyright Alexander Nasonov & Paul A. Bristow 2006.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED
#define BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED
#include <climits>
#include <ios>
#include <limits>
#include <boost/config.hpp>
#include <boost/integer_traits.hpp>
#ifndef BOOST_NO_IS_ABSTRACT
// Fix for SF:1358600 - lexical_cast & pure virtual functions & VC 8 STL
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_abstract.hpp>
#endif
#if defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) || \
(defined(BOOST_MSVC) && (BOOST_MSVC<1310))
#define BOOST_LCAST_NO_COMPILE_TIME_PRECISION
#endif
#ifdef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
#include <boost/assert.hpp>
#else
#include <boost/static_assert.hpp>
#endif
namespace boost { namespace detail {
class lcast_abstract_stub {};
#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
// Calculate an argument to pass to std::ios_base::precision from
// lexical_cast. See alternative implementation for broken standard
// libraries in lcast_get_precision below. Keep them in sync, please.
template<class T>
struct lcast_precision
{
#ifdef BOOST_NO_IS_ABSTRACT
typedef std::numeric_limits<T> limits; // No fix for SF:1358600.
#else
typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_<
boost::is_abstract<T>
, std::numeric_limits<lcast_abstract_stub>
, std::numeric_limits<T>
>::type limits;
#endif
BOOST_STATIC_CONSTANT(bool, use_default_precision =
!limits::is_specialized || limits::is_exact
);
BOOST_STATIC_CONSTANT(bool, is_specialized_bin =
!use_default_precision &&
limits::radix == 2 && limits::digits > 0
);
BOOST_STATIC_CONSTANT(bool, is_specialized_dec =
!use_default_precision &&
limits::radix == 10 && limits::digits10 > 0
);
BOOST_STATIC_CONSTANT(std::streamsize, streamsize_max =
boost::integer_traits<std::streamsize>::const_max
);
BOOST_STATIC_CONSTANT(unsigned int, precision_dec = limits::digits10 + 1U);
BOOST_STATIC_ASSERT(!is_specialized_dec ||
precision_dec <= streamsize_max + 0UL
);
BOOST_STATIC_CONSTANT(unsigned long, precision_bin =
2UL + limits::digits * 30103UL / 100000UL
);
BOOST_STATIC_ASSERT(!is_specialized_bin ||
(limits::digits + 0UL < ULONG_MAX / 30103UL &&
precision_bin > limits::digits10 + 0UL &&
precision_bin <= streamsize_max + 0UL)
);
BOOST_STATIC_CONSTANT(std::streamsize, value =
is_specialized_bin ? precision_bin
: is_specialized_dec ? precision_dec : 6
);
};
#endif
template<class T>
inline std::streamsize lcast_get_precision(T* = 0)
{
#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
return lcast_precision<T>::value;
#else // Follow lcast_precision algorithm at run-time:
#ifdef BOOST_NO_IS_ABSTRACT
typedef std::numeric_limits<T> limits; // No fix for SF:1358600.
#else
typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_<
boost::is_abstract<T>
, std::numeric_limits<lcast_abstract_stub>
, std::numeric_limits<T>
>::type limits;
#endif
bool const use_default_precision =
!limits::is_specialized || limits::is_exact;
if(!use_default_precision)
{ // Includes all built-in floating-point types, float, double ...
// and UDT types for which digits (significand bits) is defined (not zero)
bool const is_specialized_bin =
limits::radix == 2 && limits::digits > 0;
bool const is_specialized_dec =
limits::radix == 10 && limits::digits10 > 0;
std::streamsize const streamsize_max =
(boost::integer_traits<std::streamsize>::max)();
if(is_specialized_bin)
{ // Floating-point types with
// limits::digits defined by the specialization.
unsigned long const digits = limits::digits;
unsigned long const precision = 2UL + digits * 30103UL / 100000UL;
// unsigned long is selected because it is at least 32-bits
// and thus ULONG_MAX / 30103UL is big enough for all types.
BOOST_ASSERT(
digits < ULONG_MAX / 30103UL &&
precision > limits::digits10 + 0UL &&
precision <= streamsize_max + 0UL
);
return precision;
}
else if(is_specialized_dec)
{ // Decimal Floating-point type, most likely a User Defined Type
// rather than a real floating-point hardware type.
unsigned int const precision = limits::digits10 + 1U;
BOOST_ASSERT(precision <= streamsize_max + 0UL);
return precision;
}
}
// Integral type (for which precision has no effect)
// or type T for which limits is NOT specialized,
// so assume stream precision remains the default 6 decimal digits.
// Warning: if your User-defined Floating-point type T is NOT specialized,
// then you may lose accuracy by only using 6 decimal digits.
// To avoid this, you need to specialize T with either
// radix == 2 and digits == the number of significand bits,
// OR
// radix = 10 and digits10 == the number of decimal digits.
return 6;
#endif
}
template<class T>
inline void lcast_set_precision(std::ios_base& stream, T*)
{
stream.precision(lcast_get_precision<T>());
}
template<class Source, class Target>
inline void lcast_set_precision(std::ios_base& stream, Source*, Target*)
{
std::streamsize const s = lcast_get_precision(static_cast<Source*>(0));
std::streamsize const t = lcast_get_precision(static_cast<Target*>(0));
stream.precision(s > t ? s : t);
}
}}
#endif // BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED
@@ -0,0 +1,39 @@
/*=============================================================================
Copyright (c) 2016 Lee Clagett
Distributed under the 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 FUSION_AND_07152016_1625
#define FUSION_AND_07152016_1625
#include <boost/config.hpp>
#include <boost/type_traits/integral_constant.hpp>
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#error fusion::detail::and_ requires variadic templates
#endif
namespace boost { namespace fusion { namespace detail {
template<typename ...Cond>
struct and_impl : false_type {};
template<typename ...T>
struct and_impl<integral_constant<T, true>...> : true_type {};
// This specialization is necessary to avoid MSVC-12 variadics bug.
template<bool ...Cond>
struct and_impl1 : and_impl<integral_constant<bool, Cond>...> {};
/* fusion::detail::and_ differs from mpl::and_ in the following ways:
- The empty set is valid and returns true
- A single element set is valid and returns the identity
- There is no upper bound on the set size
- The conditions are evaluated at once, and are not short-circuited. This
reduces instantations when returning true; the implementation is not
recursive. */
template<typename ...Cond>
struct and_ : and_impl1<Cond::value...> {};
}}}
#endif // FUSION_AND_07152016_1625
@@ -0,0 +1,153 @@
// Copyright David Abrahams 2001.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MAKE_FUNCTION_DWA20011221_HPP
# define MAKE_FUNCTION_DWA20011221_HPP
# include <boost/python/detail/prefix.hpp>
# include <boost/python/default_call_policies.hpp>
# include <boost/python/args.hpp>
# include <boost/python/detail/caller.hpp>
# include <boost/python/object/function_object.hpp>
# include <boost/mpl/size.hpp>
# include <boost/mpl/int.hpp>
namespace boost { namespace python {
namespace detail
{
// make_function_aux --
//
// These helper functions for make_function (below) do the raw work
// of constructing a Python object from some invokable entity. See
// <boost/python/detail/caller.hpp> for more information about how
// the Sig arguments is used.
template <class F, class CallPolicies, class Sig>
object make_function_aux(
F f // An object that can be invoked by detail::invoke()
, CallPolicies const& p // CallPolicies to use in the invocation
, Sig const& // An MPL sequence of argument types expected by F
)
{
return objects::function_object(
detail::caller<F,CallPolicies,Sig>(f, p)
);
}
// As above, except that it accepts argument keywords. NumKeywords
// is used only for a compile-time assertion to make sure the user
// doesn't pass more keywords than the function can accept. To
// disable all checking, pass mpl::int_<0> for NumKeywords.
template <class F, class CallPolicies, class Sig, class NumKeywords>
object make_function_aux(
F f
, CallPolicies const& p
, Sig const&
, detail::keyword_range const& kw // a [begin,end) pair of iterators over keyword names
, NumKeywords // An MPL integral type wrapper: the size of kw
)
{
enum { arity = mpl::size<Sig>::value - 1 };
typedef typename detail::error::more_keywords_than_function_arguments<
NumKeywords::value, arity
>::too_many_keywords assertion BOOST_ATTRIBUTE_UNUSED;
return objects::function_object(
detail::caller<F,CallPolicies,Sig>(f, p)
, kw);
}
// Helpers for make_function when called with 3 arguments. These
// dispatch functions are used to discriminate between the cases
// when the 3rd argument is keywords or when it is a signature.
//
// @group {
template <class F, class CallPolicies, class Keywords>
object make_function_dispatch(F f, CallPolicies const& policies, Keywords const& kw, mpl::true_)
{
return detail::make_function_aux(
f
, policies
, detail::get_signature(f)
, kw.range()
, mpl::int_<Keywords::size>()
);
}
template <class F, class CallPolicies, class Signature>
object make_function_dispatch(F f, CallPolicies const& policies, Signature const& sig, mpl::false_)
{
return detail::make_function_aux(
f
, policies
, sig
);
}
// }
}
// These overloaded functions wrap a function or member function
// pointer as a Python object, using optional CallPolicies,
// Keywords, and/or Signature.
//
// @group {
template <class F>
object make_function(F f)
{
return detail::make_function_aux(
f,default_call_policies(), detail::get_signature(f));
}
template <class F, class CallPolicies>
object make_function(F f, CallPolicies const& policies)
{
return detail::make_function_aux(
f, policies, detail::get_signature(f));
}
template <class F, class CallPolicies, class KeywordsOrSignature>
object make_function(
F f
, CallPolicies const& policies
, KeywordsOrSignature const& keywords_or_signature)
{
typedef typename
detail::is_reference_to_keywords<KeywordsOrSignature&>::type
is_kw;
return detail::make_function_dispatch(
f
, policies
, keywords_or_signature
, is_kw()
);
}
template <class F, class CallPolicies, class Keywords, class Signature>
object make_function(
F f
, CallPolicies const& policies
, Keywords const& kw
, Signature const& sig
)
{
return detail::make_function_aux(
f
, policies
, sig
, kw.range()
, mpl::int_<Keywords::size>()
);
}
// }
}}
#endif // MAKE_FUNCTION_DWA20011221_HPP
@@ -0,0 +1,18 @@
/*=============================================================================
Copyright (c) 2011 Eric Niebler
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_FUSION_JOINT_VIEW_FWD_HPP_INCLUDED)
#define BOOST_FUSION_JOINT_VIEW_FWD_HPP_INCLUDED
namespace boost { namespace fusion
{
struct joint_view_tag;
template <typename Sequence1, typename Sequence2>
struct joint_view;
}}
#endif
@@ -0,0 +1,221 @@
/* boost random/non_central_chi_squared_distribution.hpp header file
*
* Copyright Thijs van den Berg 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 for most recent version including documentation.
*
* $Id$
*/
#ifndef BOOST_RANDOM_NON_CENTRAL_CHI_SQUARED_DISTRIBUTION_HPP
#define BOOST_RANDOM_NON_CENTRAL_CHI_SQUARED_DISTRIBUTION_HPP
#include <boost/config/no_tr1/cmath.hpp>
#include <iosfwd>
#include <istream>
#include <boost/limits.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/uniform_real_distribution.hpp>
#include <boost/random/normal_distribution.hpp>
#include <boost/random/chi_squared_distribution.hpp>
#include <boost/random/poisson_distribution.hpp>
namespace boost {
namespace random {
/**
* The noncentral chi-squared distribution is a real valued distribution with
* two parameter, @c k and @c lambda. The distribution produces values > 0.
*
* This is the distribution of the sum of squares of k Normal distributed
* variates each with variance one and \f$\lambda\f$ the sum of squares of the
* normal means.
*
* The distribution function is
* \f$\displaystyle P(x) = \frac{1}{2} e^{-(x+\lambda)/2} \left( \frac{x}{\lambda} \right)^{k/4-1/2} I_{k/2-1}( \sqrt{\lambda x} )\f$.
* where \f$\displaystyle I_\nu(z)\f$ is a modified Bessel function of the
* first kind.
*
* The algorithm is taken from
*
* @blockquote
* "Monte Carlo Methods in Financial Engineering", Paul Glasserman,
* 2003, XIII, 596 p, Stochastic Modelling and Applied Probability, Vol. 53,
* ISBN 978-0-387-21617-1, p 124, Fig. 3.5.
* @endblockquote
*/
template <typename RealType = double>
class non_central_chi_squared_distribution {
public:
typedef RealType result_type;
typedef RealType input_type;
class param_type {
public:
typedef non_central_chi_squared_distribution distribution_type;
/**
* Constructs the parameters of a non_central_chi_squared_distribution.
* @c k and @c lambda are the parameter of the distribution.
*
* Requires: k > 0 && lambda > 0
*/
explicit
param_type(RealType k_arg = RealType(1), RealType lambda_arg = RealType(1))
: _k(k_arg), _lambda(lambda_arg)
{
BOOST_ASSERT(k_arg > RealType(0));
BOOST_ASSERT(lambda_arg > RealType(0));
}
/** Returns the @c k parameter of the distribution */
RealType k() const { return _k; }
/** Returns the @c lambda parameter of the distribution */
RealType lambda() const { return _lambda; }
/** Writes the parameters of the distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
{
os << parm._k << ' ' << parm._lambda;
return os;
}
/** Reads the parameters of the distribution from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{
is >> parm._k >> std::ws >> parm._lambda;
return is;
}
/** Returns true if the parameters have the same values. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{ return lhs._k == rhs._k && lhs._lambda == rhs._lambda; }
/** Returns true if the parameters have different values. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
RealType _k;
RealType _lambda;
};
/**
* Construct a @c non_central_chi_squared_distribution object. @c k and
* @c lambda are the parameter of the distribution.
*
* Requires: k > 0 && lambda > 0
*/
explicit
non_central_chi_squared_distribution(RealType k_arg = RealType(1), RealType lambda_arg = RealType(1))
: _param(k_arg, lambda_arg)
{
BOOST_ASSERT(k_arg > RealType(0));
BOOST_ASSERT(lambda_arg > RealType(0));
}
/**
* Construct a @c non_central_chi_squared_distribution object from the parameter.
*/
explicit
non_central_chi_squared_distribution(const param_type& parm)
: _param( parm )
{ }
/**
* Returns a random variate distributed according to the
* non central chi squared distribution specified by @c param.
*/
template<typename URNG>
RealType operator()(URNG& eng, const param_type& parm) const
{ return non_central_chi_squared_distribution(parm)(eng); }
/**
* Returns a random variate distributed according to the
* non central chi squared distribution.
*/
template<typename URNG>
RealType operator()(URNG& eng)
{
using std::sqrt;
if (_param.k() > 1) {
boost::random::normal_distribution<RealType> n_dist;
boost::random::chi_squared_distribution<RealType> c_dist(_param.k() - RealType(1));
RealType _z = n_dist(eng);
RealType _x = c_dist(eng);
RealType term1 = _z + sqrt(_param.lambda());
return term1*term1 + _x;
}
else {
boost::random::poisson_distribution<> p_dist(_param.lambda()/RealType(2));
boost::random::poisson_distribution<>::result_type _p = p_dist(eng);
boost::random::chi_squared_distribution<RealType> c_dist(_param.k() + RealType(2)*_p);
return c_dist(eng);
}
}
/** Returns the @c k parameter of the distribution. */
RealType k() const { return _param.k(); }
/** Returns the @c lambda parameter of the distribution. */
RealType lambda() const { return _param.lambda(); }
/** Returns the parameters of the distribution. */
param_type param() const { return _param; }
/** Sets parameters of the distribution. */
void param(const param_type& parm) { _param = parm; }
/** Resets the distribution, so that subsequent uses does not depend on values already produced by it.*/
void reset() {}
/** Returns the smallest value that the distribution can produce. */
RealType min BOOST_PREVENT_MACRO_SUBSTITUTION() const
{ return RealType(0); }
/** Returns the largest value that the distribution can produce. */
RealType max BOOST_PREVENT_MACRO_SUBSTITUTION() const
{ return (std::numeric_limits<RealType>::infinity)(); }
/** Writes the parameters of the distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, non_central_chi_squared_distribution, dist)
{
os << dist.param();
return os;
}
/** reads the parameters of the distribution from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, non_central_chi_squared_distribution, dist)
{
param_type parm;
if(is >> parm) {
dist.param(parm);
}
return is;
}
/** Returns true if two distributions have the same parameters and produce
the same sequence of random numbers given equal generators.*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(non_central_chi_squared_distribution, lhs, rhs)
{ return lhs.param() == rhs.param(); }
/** Returns true if two distributions have different parameters and/or can produce
different sequences of random numbers given equal generators.*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(non_central_chi_squared_distribution)
private:
/// @cond show_private
param_type _param;
/// @endcond
};
} // namespace random
} // namespace boost
#endif
@@ -0,0 +1,188 @@
// 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 BOOST_INDEX_RANGE_RG071801_HPP
#define BOOST_INDEX_RANGE_RG071801_HPP
#include <boost/config.hpp>
#include <utility>
#include <boost/limits.hpp>
// For representing intervals, also with stride.
// A degenerate range is a range with one element.
// Thanks to Doug Gregor for the really cool idea of using the
// comparison operators to express various interval types!
// Internally, we represent the interval as half-open.
namespace boost {
namespace detail {
namespace multi_array {
template <typename Index,typename SizeType>
class index_range {
public:
typedef Index index;
typedef SizeType size_type;
private:
static index from_start()
{ return (std::numeric_limits<index>::min)(); }
static index to_end()
{ return (std::numeric_limits<index>::max)(); }
public:
index_range()
{
start_ = from_start();
finish_ = to_end();
stride_ = 1;
degenerate_ = false;
}
explicit index_range(index pos)
{
start_ = pos;
finish_ = pos+1;
stride_ = 1;
degenerate_ = true;
}
explicit index_range(index start, index finish, index stride=1)
: start_(start), finish_(finish), stride_(stride),
degenerate_(false)
{ }
// These are for chaining assignments to an index_range
index_range& start(index s) {
start_ = s;
degenerate_ = false;
return *this;
}
index_range& finish(index f) {
finish_ = f;
degenerate_ = false;
return *this;
}
index_range& stride(index s) { stride_ = s; return *this; }
index start() const
{
return start_;
}
index get_start(index low_index_range = index_range::from_start()) const
{
if (start_ == from_start())
return low_index_range;
return start_;
}
index finish() const
{
return finish_;
}
index get_finish(index high_index_range = index_range::to_end()) const
{
if (finish_ == to_end())
return high_index_range;
return finish_;
}
index stride() const { return stride_; }
void set_index_range(index start, index finish, index stride=1)
{
start_ = start;
finish_ = finish;
stride_ = stride;
}
static index_range all()
{ return index_range(from_start(), to_end(), 1); }
bool is_degenerate() const { return degenerate_; }
index_range operator-(index shift) const
{
return index_range(start_ - shift, finish_ - shift, stride_);
}
index_range operator+(index shift) const
{
return index_range(start_ + shift, finish_ + shift, stride_);
}
index operator[](unsigned i) const
{
return start_ + i * stride_;
}
index operator()(unsigned i) const
{
return start_ + i * stride_;
}
// add conversion to std::slice?
public:
index start_, finish_, stride_;
bool degenerate_;
};
// Express open and closed interval end-points using the comparison
// operators.
// left closed
template <typename Index, typename SizeType>
inline index_range<Index,SizeType>
operator<=(Index s, const index_range<Index,SizeType>& r)
{
return index_range<Index,SizeType>(s, r.finish(), r.stride());
}
// left open
template <typename Index, typename SizeType>
inline index_range<Index,SizeType>
operator<(Index s, const index_range<Index,SizeType>& r)
{
return index_range<Index,SizeType>(s + 1, r.finish(), r.stride());
}
// right open
template <typename Index, typename SizeType>
inline index_range<Index,SizeType>
operator<(const index_range<Index,SizeType>& r, Index f)
{
return index_range<Index,SizeType>(r.start(), f, r.stride());
}
// right closed
template <typename Index, typename SizeType>
inline index_range<Index,SizeType>
operator<=(const index_range<Index,SizeType>& r, Index f)
{
return index_range<Index,SizeType>(r.start(), f + 1, r.stride());
}
} // namespace multi_array
} // namespace detail
} // namespace boost
#endif // BOOST_INDEX_RANGE_RG071801_HPP
@@ -0,0 +1,670 @@
#ifndef BOOST_WIN32_THREAD_PRIMITIVES_HPP
#define BOOST_WIN32_THREAD_PRIMITIVES_HPP
// win32_thread_primitives.hpp
//
// (C) Copyright 2005-7 Anthony Williams
// (C) Copyright 2007 David Deakins
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/detail/config.hpp>
#include <boost/predef/platform.h>
#include <boost/throw_exception.hpp>
#include <boost/assert.hpp>
#include <boost/thread/exceptions.hpp>
#include <boost/detail/interlocked.hpp>
#include <boost/detail/winapi/config.hpp>
//#include <boost/detail/winapi/synchronization.hpp>
#include <algorithm>
#if BOOST_PLAT_WINDOWS_RUNTIME
#include <thread>
#endif
#if defined( BOOST_USE_WINDOWS_H )
# include <windows.h>
namespace boost
{
namespace detail
{
namespace win32
{
typedef HANDLE handle;
typedef SYSTEM_INFO system_info;
typedef unsigned __int64 ticks_type;
typedef FARPROC farproc_t;
unsigned const infinite=INFINITE;
unsigned const timeout=WAIT_TIMEOUT;
handle const invalid_handle_value=INVALID_HANDLE_VALUE;
unsigned const event_modify_state=EVENT_MODIFY_STATE;
unsigned const synchronize=SYNCHRONIZE;
unsigned const wait_abandoned=WAIT_ABANDONED;
unsigned const create_event_initial_set = 0x00000002;
unsigned const create_event_manual_reset = 0x00000001;
unsigned const event_all_access = EVENT_ALL_ACCESS;
unsigned const semaphore_all_access = SEMAPHORE_ALL_ACCESS;
# ifdef BOOST_NO_ANSI_APIS
# if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
using ::CreateMutexW;
using ::CreateEventW;
using ::CreateSemaphoreW;
# else
using ::CreateMutexExW;
using ::CreateEventExW;
using ::CreateSemaphoreExW;
# endif
using ::OpenEventW;
using ::GetModuleHandleW;
# else
using ::CreateMutexA;
using ::CreateEventA;
using ::OpenEventA;
using ::CreateSemaphoreA;
using ::GetModuleHandleA;
# endif
#if BOOST_PLAT_WINDOWS_RUNTIME
using ::GetNativeSystemInfo;
using ::GetTickCount64;
#else
using ::GetSystemInfo;
using ::GetTickCount;
#endif
using ::CloseHandle;
using ::ReleaseMutex;
using ::ReleaseSemaphore;
using ::SetEvent;
using ::ResetEvent;
using ::WaitForMultipleObjectsEx;
using ::WaitForSingleObjectEx;
using ::GetCurrentProcessId;
using ::GetCurrentThreadId;
using ::GetCurrentThread;
using ::GetCurrentProcess;
using ::DuplicateHandle;
#if !BOOST_PLAT_WINDOWS_RUNTIME
using ::SleepEx;
using ::Sleep;
using ::QueueUserAPC;
using ::GetProcAddress;
#endif
}
}
}
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
# ifdef UNDER_CE
# ifndef WINAPI
# ifndef _WIN32_WCE_EMULATION
# define WINAPI __cdecl // Note this doesn't match the desktop definition
# else
# define WINAPI __stdcall
# endif
# endif
# ifdef __cplusplus
extern "C" {
# endif
typedef int BOOL;
typedef unsigned long DWORD;
typedef void* HANDLE;
# include <kfuncs.h>
# ifdef __cplusplus
}
# endif
# endif
# ifdef __cplusplus
extern "C" {
# endif
struct _SYSTEM_INFO;
# ifdef __cplusplus
}
#endif
namespace boost
{
namespace detail
{
namespace win32
{
# ifdef _WIN64
typedef unsigned __int64 ulong_ptr;
# else
typedef unsigned long ulong_ptr;
# endif
typedef void* handle;
typedef _SYSTEM_INFO system_info;
typedef unsigned __int64 ticks_type;
typedef int (__stdcall *farproc_t)();
unsigned const infinite=~0U;
unsigned const timeout=258U;
handle const invalid_handle_value=(handle)(-1);
unsigned const event_modify_state=2;
unsigned const synchronize=0x100000u;
unsigned const wait_abandoned=0x00000080u;
unsigned const create_event_initial_set = 0x00000002;
unsigned const create_event_manual_reset = 0x00000001;
unsigned const event_all_access = 0x1F0003;
unsigned const semaphore_all_access = 0x1F0003;
extern "C"
{
struct _SECURITY_ATTRIBUTES;
# ifdef BOOST_NO_ANSI_APIS
# if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
__declspec(dllimport) void* __stdcall CreateMutexW(_SECURITY_ATTRIBUTES*,int,wchar_t const*);
__declspec(dllimport) void* __stdcall CreateSemaphoreW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*);
__declspec(dllimport) void* __stdcall CreateEventW(_SECURITY_ATTRIBUTES*,int,int,wchar_t const*);
# else
__declspec(dllimport) void* __stdcall CreateMutexExW(_SECURITY_ATTRIBUTES*,wchar_t const*,unsigned long,unsigned long);
__declspec(dllimport) void* __stdcall CreateEventExW(_SECURITY_ATTRIBUTES*,wchar_t const*,unsigned long,unsigned long);
__declspec(dllimport) void* __stdcall CreateSemaphoreExW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*,unsigned long,unsigned long);
# endif
__declspec(dllimport) void* __stdcall OpenEventW(unsigned long,int,wchar_t const*);
__declspec(dllimport) void* __stdcall GetModuleHandleW(wchar_t const*);
# else
__declspec(dllimport) void* __stdcall CreateMutexA(_SECURITY_ATTRIBUTES*,int,char const*);
__declspec(dllimport) void* __stdcall CreateSemaphoreA(_SECURITY_ATTRIBUTES*,long,long,char const*);
__declspec(dllimport) void* __stdcall CreateEventA(_SECURITY_ATTRIBUTES*,int,int,char const*);
__declspec(dllimport) void* __stdcall OpenEventA(unsigned long,int,char const*);
__declspec(dllimport) void* __stdcall GetModuleHandleA(char const*);
# endif
#if BOOST_PLAT_WINDOWS_RUNTIME
__declspec(dllimport) void __stdcall GetNativeSystemInfo(_SYSTEM_INFO*);
__declspec(dllimport) ticks_type __stdcall GetTickCount64();
#else
__declspec(dllimport) void __stdcall GetSystemInfo(_SYSTEM_INFO*);
__declspec(dllimport) unsigned long __stdcall GetTickCount();
#endif
__declspec(dllimport) int __stdcall CloseHandle(void*);
__declspec(dllimport) int __stdcall ReleaseMutex(void*);
__declspec(dllimport) unsigned long __stdcall WaitForSingleObjectEx(void*,unsigned long,int);
__declspec(dllimport) unsigned long __stdcall WaitForMultipleObjectsEx(unsigned long nCount,void* const * lpHandles,int bWaitAll,unsigned long dwMilliseconds,int bAlertable);
__declspec(dllimport) int __stdcall ReleaseSemaphore(void*,long,long*);
__declspec(dllimport) int __stdcall DuplicateHandle(void*,void*,void*,void**,unsigned long,int,unsigned long);
#if !BOOST_PLAT_WINDOWS_RUNTIME
__declspec(dllimport) unsigned long __stdcall SleepEx(unsigned long,int);
__declspec(dllimport) void __stdcall Sleep(unsigned long);
typedef void (__stdcall *queue_user_apc_callback_function)(ulong_ptr);
__declspec(dllimport) unsigned long __stdcall QueueUserAPC(queue_user_apc_callback_function,void*,ulong_ptr);
__declspec(dllimport) farproc_t __stdcall GetProcAddress(void *, const char *);
#endif
# ifndef UNDER_CE
__declspec(dllimport) unsigned long __stdcall GetCurrentProcessId();
__declspec(dllimport) unsigned long __stdcall GetCurrentThreadId();
__declspec(dllimport) void* __stdcall GetCurrentThread();
__declspec(dllimport) void* __stdcall GetCurrentProcess();
__declspec(dllimport) int __stdcall SetEvent(void*);
__declspec(dllimport) int __stdcall ResetEvent(void*);
# else
using ::GetCurrentProcessId;
using ::GetCurrentThreadId;
using ::GetCurrentThread;
using ::GetCurrentProcess;
using ::SetEvent;
using ::ResetEvent;
# endif
}
}
}
}
#else
# error "Win32 functions not available"
#endif
#include <boost/config/abi_prefix.hpp>
namespace boost
{
namespace detail
{
namespace win32
{
namespace detail { typedef ticks_type (__stdcall *gettickcount64_t)(); }
#if !BOOST_PLAT_WINDOWS_RUNTIME
extern "C"
{
#ifdef _MSC_VER
long _InterlockedCompareExchange(long volatile *, long, long);
#pragma intrinsic(_InterlockedCompareExchange)
#elif defined(__MINGW64_VERSION_MAJOR)
long _InterlockedCompareExchange(long volatile *, long, long);
#else
// Mingw doesn't provide intrinsics
#define _InterlockedCompareExchange InterlockedCompareExchange
#endif
}
// Borrowed from https://stackoverflow.com/questions/8211820/userland-interrupt-timer-access-such-as-via-kequeryinterrupttime-or-similar
inline ticks_type __stdcall GetTickCount64emulation()
{
static volatile long count = 0xFFFFFFFF;
unsigned long previous_count, current_tick32, previous_count_zone, current_tick32_zone;
ticks_type current_tick64;
previous_count = (unsigned long) _InterlockedCompareExchange(&count, 0, 0);
current_tick32 = GetTickCount();
if(previous_count == 0xFFFFFFFF)
{
// count has never been written
unsigned long initial_count;
initial_count = current_tick32 >> 28;
previous_count = (unsigned long) _InterlockedCompareExchange(&count, initial_count, 0xFFFFFFFF);
current_tick64 = initial_count;
current_tick64 <<= 28;
current_tick64 += current_tick32 & 0x0FFFFFFF;
return current_tick64;
}
previous_count_zone = previous_count & 15;
current_tick32_zone = current_tick32 >> 28;
if(current_tick32_zone == previous_count_zone)
{
// The top four bits of the 32-bit tick count haven't changed since count was last written.
current_tick64 = previous_count;
current_tick64 <<= 28;
current_tick64 += current_tick32 & 0x0FFFFFFF;
return current_tick64;
}
if(current_tick32_zone == previous_count_zone + 1 || (current_tick32_zone == 0 && previous_count_zone == 15))
{
// The top four bits of the 32-bit tick count have been incremented since count was last written.
_InterlockedCompareExchange(&count, previous_count + 1, previous_count);
current_tick64 = previous_count + 1;
current_tick64 <<= 28;
current_tick64 += current_tick32 & 0x0FFFFFFF;
return current_tick64;
}
// Oops, we weren't called often enough, we're stuck
return 0xFFFFFFFF;
}
#else
#endif
inline detail::gettickcount64_t GetTickCount64_()
{
static detail::gettickcount64_t gettickcount64impl;
if(gettickcount64impl)
return gettickcount64impl;
// GetTickCount and GetModuleHandle are not allowed in the Windows Runtime,
// and kernel32 isn't used in Windows Phone.
#if BOOST_PLAT_WINDOWS_RUNTIME
gettickcount64impl = &GetTickCount64;
#else
farproc_t addr=GetProcAddress(
#if !defined(BOOST_NO_ANSI_APIS)
GetModuleHandleA("KERNEL32.DLL"),
#else
GetModuleHandleW(L"KERNEL32.DLL"),
#endif
"GetTickCount64");
if(addr)
gettickcount64impl=(detail::gettickcount64_t) addr;
else
gettickcount64impl=&GetTickCount64emulation;
#endif
return gettickcount64impl;
}
enum event_type
{
auto_reset_event=false,
manual_reset_event=true
};
enum initial_event_state
{
event_initially_reset=false,
event_initially_set=true
};
inline handle create_event(
#if !defined(BOOST_NO_ANSI_APIS)
const char *mutex_name,
#else
const wchar_t *mutex_name,
#endif
event_type type,
initial_event_state state)
{
#if !defined(BOOST_NO_ANSI_APIS)
handle const res = win32::CreateEventA(0, type, state, mutex_name);
#elif BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
handle const res = win32::CreateEventW(0, type, state, mutex_name);
#else
handle const res = win32::CreateEventExW(
0,
mutex_name,
type ? create_event_manual_reset : 0 | state ? create_event_initial_set : 0,
event_all_access);
#endif
return res;
}
inline handle create_anonymous_event(event_type type,initial_event_state state)
{
handle const res = create_event(0, type, state);
if(!res)
{
boost::throw_exception(thread_resource_error());
}
return res;
}
inline handle create_anonymous_semaphore_nothrow(long initial_count,long max_count)
{
#if !defined(BOOST_NO_ANSI_APIS)
handle const res=win32::CreateSemaphoreA(0,initial_count,max_count,0);
#else
#if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
handle const res=win32::CreateSemaphoreEx(0,initial_count,max_count,0,0);
#else
handle const res=win32::CreateSemaphoreExW(0,initial_count,max_count,0,0,semaphore_all_access);
#endif
#endif
return res;
}
inline handle create_anonymous_semaphore(long initial_count,long max_count)
{
handle const res=create_anonymous_semaphore_nothrow(initial_count,max_count);
if(!res)
{
boost::throw_exception(thread_resource_error());
}
return res;
}
inline handle duplicate_handle(handle source)
{
handle const current_process=GetCurrentProcess();
long const same_access_flag=2;
handle new_handle=0;
bool const success=DuplicateHandle(current_process,source,current_process,&new_handle,0,false,same_access_flag)!=0;
if(!success)
{
boost::throw_exception(thread_resource_error());
}
return new_handle;
}
inline void release_semaphore(handle semaphore,long count)
{
BOOST_VERIFY(ReleaseSemaphore(semaphore,count,0)!=0);
}
inline void get_system_info(system_info *info)
{
#if BOOST_PLAT_WINDOWS_RUNTIME
win32::GetNativeSystemInfo(info);
#else
win32::GetSystemInfo(info);
#endif
}
inline void sleep(unsigned long milliseconds)
{
if(milliseconds == 0)
{
#if BOOST_PLAT_WINDOWS_RUNTIME
std::this_thread::yield();
#else
::boost::detail::win32::Sleep(0);
#endif
}
else
{
#if BOOST_PLAT_WINDOWS_RUNTIME
::boost::detail::win32::WaitForSingleObjectEx(::boost::detail::win32::GetCurrentThread(), milliseconds, 0);
#else
::boost::detail::win32::Sleep(milliseconds);
#endif
}
}
#if BOOST_PLAT_WINDOWS_RUNTIME
class BOOST_THREAD_DECL scoped_winrt_thread
{
public:
scoped_winrt_thread() : m_completionHandle(invalid_handle_value)
{}
~scoped_winrt_thread()
{
if (m_completionHandle != ::boost::detail::win32::invalid_handle_value)
{
CloseHandle(m_completionHandle);
}
}
typedef unsigned(__stdcall * thread_func)(void *);
bool start(thread_func address, void *parameter, unsigned int *thrdId);
handle waitable_handle() const
{
BOOST_ASSERT(m_completionHandle != ::boost::detail::win32::invalid_handle_value);
return m_completionHandle;
}
private:
handle m_completionHandle;
};
#endif
class BOOST_THREAD_DECL handle_manager
{
private:
handle handle_to_manage;
handle_manager(handle_manager&);
handle_manager& operator=(handle_manager&);
void cleanup()
{
if(handle_to_manage && handle_to_manage!=invalid_handle_value)
{
BOOST_VERIFY(CloseHandle(handle_to_manage));
}
}
public:
explicit handle_manager(handle handle_to_manage_):
handle_to_manage(handle_to_manage_)
{}
handle_manager():
handle_to_manage(0)
{}
handle_manager& operator=(handle new_handle)
{
cleanup();
handle_to_manage=new_handle;
return *this;
}
operator handle() const
{
return handle_to_manage;
}
handle duplicate() const
{
return duplicate_handle(handle_to_manage);
}
void swap(handle_manager& other)
{
std::swap(handle_to_manage,other.handle_to_manage);
}
handle release()
{
handle const res=handle_to_manage;
handle_to_manage=0;
return res;
}
bool operator!() const
{
return !handle_to_manage;
}
~handle_manager()
{
cleanup();
}
};
}
}
}
#if defined(BOOST_MSVC) && (_MSC_VER>=1400) && !defined(UNDER_CE)
namespace boost
{
namespace detail
{
namespace win32
{
#if _MSC_VER==1400
extern "C" unsigned char _interlockedbittestandset(long *a,long b);
extern "C" unsigned char _interlockedbittestandreset(long *a,long b);
#else
extern "C" unsigned char _interlockedbittestandset(volatile long *a,long b);
extern "C" unsigned char _interlockedbittestandreset(volatile long *a,long b);
#endif
#pragma intrinsic(_interlockedbittestandset)
#pragma intrinsic(_interlockedbittestandreset)
inline bool interlocked_bit_test_and_set(long* x,long bit)
{
return _interlockedbittestandset(x,bit)!=0;
}
inline bool interlocked_bit_test_and_reset(long* x,long bit)
{
return _interlockedbittestandreset(x,bit)!=0;
}
}
}
}
#define BOOST_THREAD_BTS_DEFINED
#elif (defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN)) && defined(_M_IX86)
namespace boost
{
namespace detail
{
namespace win32
{
inline bool interlocked_bit_test_and_set(long* x,long bit)
{
#ifndef BOOST_INTEL_CXX_VERSION
__asm {
mov eax,bit;
mov edx,x;
lock bts [edx],eax;
setc al;
};
#else
bool ret;
__asm {
mov eax,bit
mov edx,x
lock bts [edx],eax
setc al
mov ret, al
};
return ret;
#endif
}
inline bool interlocked_bit_test_and_reset(long* x,long bit)
{
#ifndef BOOST_INTEL_CXX_VERSION
__asm {
mov eax,bit;
mov edx,x;
lock btr [edx],eax;
setc al;
};
#else
bool ret;
__asm {
mov eax,bit
mov edx,x
lock btr [edx],eax
setc al
mov ret, al
};
return ret;
#endif
}
}
}
}
#define BOOST_THREAD_BTS_DEFINED
#endif
#ifndef BOOST_THREAD_BTS_DEFINED
namespace boost
{
namespace detail
{
namespace win32
{
inline bool interlocked_bit_test_and_set(long* x,long bit)
{
long const value=1<<bit;
long old=*x;
do
{
long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,old|value,old);
if(current==old)
{
break;
}
old=current;
}
while(true) ;
return (old&value)!=0;
}
inline bool interlocked_bit_test_and_reset(long* x,long bit)
{
long const value=1<<bit;
long old=*x;
do
{
long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,old&~value,old);
if(current==old)
{
break;
}
old=current;
}
while(true) ;
return (old&value)!=0;
}
}
}
}
#endif
#include <boost/config/abi_suffix.hpp>
#endif
@@ -0,0 +1,105 @@
subroutine geodist(Eplat,Eplon,Stlat,Stlon,Az,Baz,Dist)
implicit none
real eplat, eplon, stlat, stlon, az, baz, dist
! JHT: In actual fact, I use the first two arguments for "My Location",
! the second two for "His location"; West longitude is positive.
! Taken directly from:
! Thomas, P.D., 1970, Spheroidal geodesics, reference systems,
! & local geometry, U.S. Naval Oceanographi!Office SP-138,
! 165 pp.
! assumes North Latitude and East Longitude are positive
! EpLat, EpLon = End point Lat/Long
! Stlat, Stlon = Start point lat/long
! Az, BAz = direct & reverse azimuith
! Dist = Dist (km); Deg = central angle, discarded
real BOA, F, P1R, P2R, L1R, L2R, DLR, T1R, T2R, TM, &
DTM, STM, CTM, SDTM,CDTM, KL, KK, SDLMR, L, &
CD, DL, SD, T, U, V, D, X, E, Y, A, FF64, TDLPM, &
HAPBR, HAMBR, A1M2, A2M1
real AL,BL,D2R,Pi2
data AL/6378206.4/ ! Clarke 1866 ellipsoid
data BL/6356583.8/
! real pi /3.14159265359/
data D2R/0.01745329251994/ ! degrees to radians conversion factor
data Pi2/6.28318530718/
if(abs(Eplat-Stlat).lt.0.02 .and. abs(Eplon-Stlon).lt.0.02) then
Az=0.
Baz=180.0
Dist=0
go to 999
endif
BOA = BL/AL
F = 1.0 - BOA
! Convert st/end pts to radians
P1R = Eplat * D2R
P2R = Stlat * D2R
L1R = Eplon * D2R
L2R = StLon * D2R
DLR = L2R - L1R ! DLR = Delta Long in Rads
T1R = ATan(BOA * Tan(P1R))
T2R = ATan(BOA * Tan(P2R))
TM = (T1R + T2R) / 2.0
DTM = (T2R - T1R) / 2.0
STM = Sin(TM)
CTM = Cos(TM)
SDTM = Sin(DTM)
CDTM = Cos(DTM)
KL = STM * CDTM
KK = SDTM * CTM
SDLMR = Sin(DLR/2.0)
L = SDTM * SDTM + SDLMR * SDLMR * (CDTM * CDTM - STM * STM)
CD = 1.0 - 2.0 * L
DL = ACos(CD)
SD = Sin(DL)
T = DL/SD
U = 2.0 * KL * KL / (1.0 - L)
V = 2.0 * KK * KK / L
D = 4.0 * T * T
X = U + V
E = -2.0 * CD
Y = U - V
A = -D * E
FF64 = F * F / 64.0
Dist = AL*SD*(T -(F/4.0)*(T*X-Y)+FF64*(X*(A+(T-(A+E) &
/2.0)*X)+Y*(-2.0*D+E*Y)+D*X*Y))/1000.0
TDLPM = Tan((DLR+(-((E*(4.0-X)+2.0*Y)*((F/2.0)*T+FF64* &
(32.0*T+(A-20.0*T)*X-2.0*(D+2.0)*Y))/4.0)*Tan(DLR)))/2.0)
HAPBR = ATan2(SDTM,(CTM*TDLPM))
HAMBR = Atan2(CDTM,(STM*TDLPM))
A1M2 = Pi2 + HAMBR - HAPBR
A2M1 = Pi2 - HAMBR - HAPBR
1 If ((A1M2 .ge. 0.0) .AND. (A1M2 .lt. Pi2)) GOTO 5
If (A1M2 .lt. Pi2) GOTO 4
A1M2 = A1M2 - Pi2
GOTO 1
4 A1M2 = A1M2 + Pi2
GOTO 1
! All of this gens the proper az, baz (forward and back azimuth)
5 If ((A2M1 .ge. 0.0) .AND. (A2M1 .lt. Pi2)) GOTO 9
If (A2M1 .lt. Pi2) GOTO 8
A2M1 = A2M1 - Pi2
GOTO 5
8 A2M1 = A2M1 + Pi2
GOTO 5
9 Az = A1M2 / D2R
BAZ = A2M1 / D2R
!Fix the mirrored coords here.
az = 360.0 - az
baz = 360.0 - baz
999 return
end subroutine geodist