Initial Commit
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user