code:
                    White Paper: FT8 for DXpeditions
		  -----------------------------------
		  Joe Taylor, K1JT - October 27, 2017

Assumptions:

1. WSJT-X will have two distinct options that enable the maximum-rate
QSO exchanges described below.  Fox must select "Fox"; all Hounds must
select "Hound".

2. There will be an announced basic dial frequency for each band, say
f0=14082 kHz for 20m.  This is the basic Channel.

3. Fox always transmits in the 1st sequence, 200-800 Hz above f0.

4. Hounds call in 2nd sequence, 1000-5000 Hz above f0. Hounds
transmitting below f0+1000 Hz will not be answered.

5. If found necessary, additional Channels may be defined in which
Hounds can transmit.  (However, I suggest that CQ-by-call-area may
be easier to implement and use; and the software could be made to
prevent Hounds in the wrong area from transmitting.)

6. Ideally, Fox and Hounds should all use CAT control configured with
*Split Operation* set to *Rig* or *Fake It*, and transceiver dial
frequencies should best be calibrated to within a few Hz.  (WSJT-X
provides tools that make this fairly easy to do.)

When Fox is running a pileup, QSOs will look something like the
following exchanges.  Here I've assumed the Fox callsign is KH1DX,
his locator AJ10:

------------------------------------------------------------------------
    Fox                              Hounds
------------------------------------------------------------------------
1.  CQ KH1DX AJ10
2.                                   KH1DX K1ABC FN42, KH1DX W9XYZ EN37, ...
3.  K1ABC KH1DX -13
4.                                   KH1DX K1ABC R-11
5.  K1ABC RR73; W9XYZ <KH1DX> -17
6.                                   ... no copy from W9XYZ ...
7.  W9XYZ KH1DX -17
8.                                   ... no copy from W9XYZ ...
9.  G4AAA KH1DX -11
10.                                  KH1DX G4AAA R-03
11. G4AAA RR73; DL3BBB <KH1DX> -12
12.                                  KH1DX DL3BBB R-09
13. DL3BBB RR73; DE <KH1DX>
14. ...
------------------------------------------------------------------------

All messages except those containing "<...>" are standard FT8 messages
(i3bit=0, iFreeText=0).  Hounds transmit only standard messages.

Fox transmits standard messages and also special messages with
i3bit=1.  The special messages contain a callsign whose completed QSO
is being acknowledged; a callsign for the next station to be worked; a
hash code corresponding to the Fox callsign; and a signal report.
Users will see the Fox callsign enclosed in angle brackets, <KH1DX>.
The 72-bit message payload contains two 28-bit callsigns, a 10-bit
hash code, and a 6-bit signal report.  If no call has been queued up
by Fox for the next QSO, the acknowledgment message takes the
abbreviated form shown in line 13 above.

When a Hound receives a message with i3bit=1, the decoder interprets
the remaining 72 bits as described above.  If the 10-bit hash code
matches that for Fox's callsign, the message is displayed as in the
QSO exchanges shown above.  Otherwise the message is considered a
false decode and is not displayed.

Station Setup and Operation for FOX
-----------------------------------

A wide Rx bandwidth (up to 5 kHz) is selected.  The basic dial
frequency is set 1 kHz above f0 (thus 14083 kHz in my example) and the
audio TxFreq somewhere between -200 and -800 Hz.  (Yes, negative
numbers are OK.  *Split Operation* will reset the Tx dial frequency as
needed and will keep the generated Tx audio frequency between 1500 and
2000 Hz.)  Hounds with audio TxFreq set to N Hz will be received by Fox
at N-1000 Hz.

WSJT-X at Fox will maintain and display a list of all decoded Hounds
calling Fox in the past 2 to 4 Rx cycles.  The list might look
something like this (but typically will be much longer):

----------------------------
Call        Grid  Rpt  Freq
----------------------------
AA2UK       FM29  -11   240
AD9H        EN61  +02  1260
K0TPP       EM48  -15  1980
N2BJ        EN61  +11   540
N4NDR       EL98  -17  4620
NX4E        EM70  +00  3780
ON3LA       JN29  -10  3300
PD9BG       JO21  -21  2100
PJ4/KA1XYZ  FK60  -07  1020
VE1SKY      FN74  +03  1620
WB2REM      EL97  -13  3060
...
----------------------------

Fox can choose to have the list sorted on any column.

Fox selects a Hound to call next by clicking on a line.  Or he can hit
"F1" to have the program select a caller according to one of these
criteria (maybe others as well?):

 - Weakest caller
 - Strongest caller
 - Strongest one below -N dB (with N selectable)
 - Choose a call at random
 - Random choice with S/N between snrMin and snrMax dB.

After a particular Hound has been called, Fox's Auto-Sequencer looks
for a response containing "R+rpt" originating from that same callsign.
If such a message is received, Fox's next transmission will be the
special "acknowledge-and-call-next" type, with i3bit=1.  If the
expected message is not received, as in example line 6 above, the
report is sent to the same station again.  If the second attempt fails
and another Hound callsign has been queued up, the QSO is aborted and
the next Hound is called.

Station Setup and Operation for Hounds
--------------------------------------

Dial frequency is set to f0, 14082 kHz in my example. Rx bandwidth and
displayed range on the Wide Graph can be anything convenient, say 200
to 2600 Hz.  (Signal from Fox will be expected between 200 and 800
Hz.)  Enter callsign and locator of Fox on WSJT-X main window as *DX
Call* and *DX Grid*.  Choose a TxFreq offset of 1000 + 60*N for some N
in the range 1 to 80 (maybe even higher?).  Move TxFreq as desired,
hoping to find a clear slot, by using Shift+F11 and Shift+F12.

 - Hit F1 to call Fox in your next Tx sequence.  Yes, you must hit F1
   repeatedly, in order to keep calling.

 - The Auto-sequencer will watch for a decoded message that contains
   "MyCall DXcall rpt" or "MyCall <DXcall> rpt".  When one of these is
   received, your next transmission will be "DXcall MyCall R+rpt",
   sent automatically.

 - After you send the "R+rpt" message, AutoSeq will watch for a
   message that starts with "MyCall RR73; ...".  When that is
   received, you're in his log, and you'll be prompted to log the QSO.

Random thoughts
---------------

Fox's decoder has access to signals in a 4 kHz (maybe even 5 kHz?)
window.  At 60 Hz intervals, that's enough for around 65 (or 80?)
non-overlapping Hound signals.  If the pileup becomes too deep, more
spectrum might be used; but note that WSJT-X can't access more than 5
kHz at one time.  A better solution might be for Fox to call "CQ n
KH1DX AJ10", where n is a single digit indicating call area.  The
decoder could then limit the list of eligible calls to those in the
specified call area.  After decoding such a CQ, the software at Hound
could refuse to transmit unless MyCall falls in the specified call
area.  (Other special CQ formats can be imagined that would limit the
eligible Hound callsigns even further.)

We haven't thought much, yet, about logging issues for Fox.  I imagine
we could do what's necessary to join a N1MM+ logging network, if that's
deemed desirable.

A few questions:

Q1: Should the Auto-Sequencer allow for other cases in which a QSO has
been initiated by Fox, but one of next two messages is not copied by
either Fox or Hound?  For example, what if K1ABC does not copy message
#5?  Should he keep sending his message "KH1DX K1ABC R-11" ?  If Fox
receives this message again, should he acknowledge again?  And poor
W9XYZ, who never received an acknowledgment, will probably keep
sending "KH1DX W9XYZ R-19", or whatever.  If Fox eventually copies the
message, should the program remember that W9XYZ had been called, and
thus send him an acknowledgment?

Q2: Should we provide a stack for several to-be-called callsigns,
rather than just one?  Should re-ordering of calls in the stack be
permitted?

Q3: Can we handle WSJT-X "Type 1" and "Type 2" compound callsigns, for
Hounds?


code:
//  (C) Copyright John Maddock 2007.
//  Use, modification and distribution are subject to the
//  Boost Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
//  This file is machine generated, do not edit by hand

// Polynomial evaluation using second order Horners rule
#ifndef BOOST_MATH_TOOLS_POLY_EVAL_20_HPP
#define BOOST_MATH_TOOLS_POLY_EVAL_20_HPP

namespace boost{ namespace math{ namespace tools{ namespace detail{

template <class T, class V>
inline V evaluate_polynomial_c_imp(const T*, const V&, const mpl::int_<0>*) BOOST_MATH_NOEXCEPT(V)
{
   return static_cast<V>(0);
}

template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V&, const mpl::int_<1>*) BOOST_MATH_NOEXCEPT(V)
{
   return static_cast<V>(a[0]);
}

template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<2>*) BOOST_MATH_NOEXCEPT(V)
{
   return static_cast<V>(a[1] * x + a[0]);
}

template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<3>*) BOOST_MATH_NOEXCEPT(V)
{
   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
}

template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<4>*) BOOST_MATH_NOEXCEPT(V)
{
   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
}

template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<5>*) BOOST_MATH_NOEXCEPT(V)
{
   V x2 = x * x;
   return static_cast<V>((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x);
}

template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<6>*) BOOST_MATH_NOEXCEPT(V)
{
   V x2 = x * x;
   return static_cast<V>(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]);
}

template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<7>*) BOOST_MATH_NOEXCEPT(V)
{
   V x2 = x * x;
   return static_cast<V>(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x);
}

template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<8>*) BOOST_MATH_NOEXCEPT(V)
{
   V x2 = x * x;
   return static_cast<V>((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
}

template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<9>*) BOOST_MATH_NOEXCEPT(V)
{
   V x2 = x * x;
   return static_cast<V>((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
}

template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<10>*) BOOST_MATH_NOEXCEPT(V)
{
   V x2 = x * x;
   return static_cast<V>(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
}

template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<11>*) BOOST_MATH_NOEXCEPT(V)
{
   V x2 = x * x;
   return static_cast<V>(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
}

template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<12>*) BOOST_MATH_NOEXCEPT(V)
{
   V x2 = x * x;
   return static_cast<V>((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
}

template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<13>*) BOOST_MATH_NOEXCEPT(V)
{
   V x2 = x * x;
   return static_cast<V>((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
}

template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<14>*) BOOST_MATH_NOEXCEPT(V)
{
   V x2 = x * x;
   return static_cast<V>(((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
}

template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<15>*) BOOST_MATH_NOEXCEPT(V)
{
   V x2 = x * x;
   return static_cast<V>(((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
}

template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<16>*) BOOST_MATH_NOEXCEPT(V)
{
   V x2 = x * x;
   return static_cast<V>((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
}

template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<17>*) BOOST_MATH_NOEXCEPT(V)
{
   V x2 = x * x;
   return static_cast<V>((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
}

template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<18>*) BOOST_MATH_NOEXCEPT(V)
{
   V x2 = x * x;
   return static_cast<V>(((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
}

template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<19>*) BOOST_MATH_NOEXCEPT(V)
{
   V x2 = x * x;
   return static_cast<V>(((((((((a[18] * x2 + a[16]) * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
}

template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<20>*) BOOST_MATH_NOEXCEPT(V)
{
   V x2 = x * x;
   return static_cast<V>((((((((((a[19] * x2 + a[17]) * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((((a[18] * x2 + a[16]) * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
}

}}}} // namespaces

#endif // include guard

license: mit


code:
//
//  Copyright (c) 2002-2003
//  Toon Knapen, Kresimir Fresl, Joerg Walter
//
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//
//

#ifndef _BOOST_UBLAS_RAW_
#define _BOOST_UBLAS_RAW_

namespace boost { namespace numeric { namespace ublas { namespace raw {

    // We need data_const() mostly due to MSVC 6.0.
    // But how shall we write portable code otherwise?

    template < typename V >
    BOOST_UBLAS_INLINE
    int size( const V &v ) ;

    template < typename V >
    BOOST_UBLAS_INLINE
    int size( const vector_reference<V> &v ) ;

    template < typename M >
    BOOST_UBLAS_INLINE
    int size1( const M &m ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    int size2( const M &m ) ;

    template < typename M >
    BOOST_UBLAS_INLINE
    int size1( const matrix_reference<M> &m ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    int size2( const matrix_reference<M> &m ) ;

    template < typename M >
    BOOST_UBLAS_INLINE
    int leading_dimension( const M &m, row_major_tag ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    int leading_dimension( const M &m, column_major_tag ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    int leading_dimension( const M &m ) ;

    template < typename M >
    BOOST_UBLAS_INLINE
    int leading_dimension( const matrix_reference<M> &m ) ;

    template < typename V >
    BOOST_UBLAS_INLINE
    int stride( const V &v ) ;

    template < typename V >
    BOOST_UBLAS_INLINE
    int stride( const vector_range<V> &v ) ;
    template < typename V >
    BOOST_UBLAS_INLINE
    int stride( const vector_slice<V> &v ) ;

    template < typename M >
    BOOST_UBLAS_INLINE
    int stride( const matrix_row<M> &v ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    int stride( const matrix_column<M> &v ) ;

    template < typename M >
    BOOST_UBLAS_INLINE
    int stride1( const M &m ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    int stride2( const M &m ) ;

    template < typename M >
    BOOST_UBLAS_INLINE
    int stride1( const matrix_reference<M> &m ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    int stride2( const matrix_reference<M> &m ) ;

    template < typename T, std::size_t M, std::size_t N >
    BOOST_UBLAS_INLINE
    int stride1( const c_matrix<T, M, N> &m ) ;
    template < typename T, std::size_t M, std::size_t N >
    BOOST_UBLAS_INLINE
    int stride2( const c_matrix<T, M, N> &m ) ;

    template < typename M >
    BOOST_UBLAS_INLINE
    int stride1( const matrix_range<M> &m ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    int stride1( const matrix_slice<M> &m ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    int stride2( const matrix_range<M> &m ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    int stride2( const matrix_slice<M> &m ) ;

    template < typename MV >
    BOOST_UBLAS_INLINE
    typename MV::array_type::array_type::const_pointer data( const MV &mv ) ;
    template < typename MV >
    BOOST_UBLAS_INLINE
    typename MV::array_type::array_type::const_pointer data_const( const MV &mv ) ;
    template < typename MV >
    BOOST_UBLAS_INLINE
    typename MV::array_type::pointer data( MV &mv ) ;

    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::array_type::const_pointer data( const vector_reference<V> &v ) ;
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::array_type::const_pointer data_const( const vector_reference<V> &v ) ;
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::pointer data( vector_reference<V> &v ) ;

    template < typename T, std::size_t N >
    BOOST_UBLAS_INLINE
    typename c_vector<T, N>::array_type::array_type::const_pointer data( const c_vector<T, N> &v ) ;
    template < typename T, std::size_t N >
    BOOST_UBLAS_INLINE
    typename c_vector<T, N>::array_type::array_type::const_pointer data_const( const c_vector<T, N> &v ) ;
    template < typename T, std::size_t N >
    BOOST_UBLAS_INLINE
    typename c_vector<T, N>::pointer data( c_vector<T, N> &v ) ;

    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::array_type::const_pointer data( const vector_range<V> &v ) ;
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::array_type::const_pointer data( const vector_slice<V> &v ) ;
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::array_type::const_pointer data_const( const vector_range<V> &v ) ;
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::array_type::const_pointer data_const( const vector_slice<V> &v ) ;
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::pointer data( vector_range<V> &v ) ;
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::pointer data( vector_slice<V> &v ) ;

    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::array_type::const_pointer data( const matrix_reference<M> &m ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::array_type::const_pointer data_const( const matrix_reference<M> &m ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::pointer data( matrix_reference<M> &m ) ;

    template < typename T, std::size_t M, std::size_t N >
    BOOST_UBLAS_INLINE
    typename c_matrix<T, M, N>::array_type::array_type::const_pointer data( const c_matrix<T, M, N> &m ) ;
    template < typename T, std::size_t M, std::size_t N >
    BOOST_UBLAS_INLINE
    typename c_matrix<T, M, N>::array_type::array_type::const_pointer data_const( const c_matrix<T, M, N> &m ) ;
    template < typename T, std::size_t M, std::size_t N >
    BOOST_UBLAS_INLINE
    typename c_matrix<T, M, N>::pointer data( c_matrix<T, M, N> &m ) ;

    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::array_type::const_pointer data( const matrix_row<M> &v ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::array_type::const_pointer data( const matrix_column<M> &v ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::array_type::const_pointer data_const( const matrix_row<M> &v ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::array_type::const_pointer data_const( const matrix_column<M> &v ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::pointer data( matrix_row<M> &v ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::pointer data( matrix_column<M> &v ) ;

    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::array_type::const_pointer data( const matrix_range<M> &m ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::array_type::const_pointer data( const matrix_slice<M> &m ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::array_type::const_pointer data_const( const matrix_range<M> &m ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::array_type::const_pointer data_const( const matrix_slice<M> &m ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::pointer data( matrix_range<M> &m ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::pointer data( matrix_slice<M> &m ) ;

    template < typename MV >
    BOOST_UBLAS_INLINE
    typename MV::array_type::array_type::const_pointer base( const MV &mv ) ;

    template < typename MV >
    BOOST_UBLAS_INLINE
    typename MV::array_type::array_type::const_pointer base_const( const MV &mv ) ;
    template < typename MV >
    BOOST_UBLAS_INLINE
    typename MV::array_type::pointer base( MV &mv ) ;

    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::array_type::const_pointer base( const vector_reference<V> &v ) ;
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::array_type::const_pointer base_const( const vector_reference<V> &v ) ;
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::pointer base( vector_reference<V> &v ) ;

    template < typename T, std::size_t N >
    BOOST_UBLAS_INLINE
    typename c_vector<T, N>::array_type::array_type::const_pointer base( const c_vector<T, N> &v ) ;
    template < typename T, std::size_t N >
    BOOST_UBLAS_INLINE
    typename c_vector<T, N>::array_type::array_type::const_pointer base_const( const c_vector<T, N> &v ) ;
    template < typename T, std::size_t N >
    BOOST_UBLAS_INLINE
    typename c_vector<T, N>::pointer base( c_vector<T, N> &v ) ;

    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::array_type::const_pointer base( const vector_range<V> &v ) ;
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::array_type::const_pointer base( const vector_slice<V> &v ) ;
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::array_type::const_pointer base_const( const vector_range<V> &v ) ;
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::array_type::const_pointer base_const( const vector_slice<V> &v ) ;
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::pointer base( vector_range<V> &v ) ;
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::pointer base( vector_slice<V> &v ) ;

    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::array_type::const_pointer base( const matrix_reference<M> &m ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::array_type::const_pointer base_const( const matrix_reference<M> &m ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::pointer base( matrix_reference<M> &m ) ;

    template < typename T, std::size_t M, std::size_t N >
    BOOST_UBLAS_INLINE
    typename c_matrix<T, M, N>::array_type::array_type::const_pointer base( const c_matrix<T, M, N> &m ) ;
    template < typename T, std::size_t M, std::size_t N >
    BOOST_UBLAS_INLINE
    typename c_matrix<T, M, N>::array_type::array_type::const_pointer base_const( const c_matrix<T, M, N> &m ) ;
    template < typename T, std::size_t M, std::size_t N >
    BOOST_UBLAS_INLINE
    typename c_matrix<T, M, N>::pointer base( c_matrix<T, M, N> &m ) ;

    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::array_type::const_pointer base( const matrix_row<M> &v ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::array_type::const_pointer base( const matrix_column<M> &v ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::array_type::const_pointer base_const( const matrix_row<M> &v ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::array_type::const_pointer base_const( const matrix_column<M> &v ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::pointer base( matrix_row<M> &v ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::pointer base( matrix_column<M> &v ) ;

    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::array_type::const_pointer base( const matrix_range<M> &m ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::array_type::const_pointer base( const matrix_slice<M> &m ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::array_type::const_pointer base_const( const matrix_range<M> &m ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::array_type::const_pointer base_const( const matrix_slice<M> &m ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::pointer base( matrix_range<M> &m ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::pointer base( matrix_slice<M> &m ) ;

    template < typename MV >
    BOOST_UBLAS_INLINE
    typename MV::size_type start( const MV &mv ) ;

    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::size_type start( const vector_range<V> &v ) ;
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::size_type start( const vector_slice<V> &v ) ;

    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::size_type start( const matrix_row<M> &v ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::size_type start( const matrix_column<M> &v ) ;

    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::size_type start( const matrix_range<M> &m ) ;
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::size_type start( const matrix_slice<M> &m ) ;

    template < typename V >
    BOOST_UBLAS_INLINE
    int size( const V &v ) {
        return v.size() ;
    }

    template < typename V >
    BOOST_UBLAS_INLINE
    int size( const vector_reference<V> &v ) {
        return size( v ) ;
    }

    template < typename M >
    BOOST_UBLAS_INLINE
    int size1( const M &m ) {
        return m.size1() ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    int size2( const M &m ) {
        return m.size2() ;
    }

    template < typename M >
    BOOST_UBLAS_INLINE
    int size1( const matrix_reference<M> &m ) {
        return size1( m.expression() ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    int size2( const matrix_reference<M> &m ) {
        return size2( m.expression() ) ;
    }

    template < typename M >
    BOOST_UBLAS_INLINE
    int leading_dimension( const M &m, row_major_tag ) {
        return m.size2() ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    int leading_dimension( const M &m, column_major_tag ) {
        return m.size1() ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    int leading_dimension( const M &m ) {
        return leading_dimension( m, typename M::orientation_category() ) ;
    }

    template < typename M >
    BOOST_UBLAS_INLINE
    int leading_dimension( const matrix_reference<M> &m ) {
        return leading_dimension( m.expression() ) ;
    }

    template < typename V >
    BOOST_UBLAS_INLINE
    int stride( const V &v ) {
        return 1 ;
    }

    template < typename V >
    BOOST_UBLAS_INLINE
    int stride( const vector_range<V> &v ) {
        return stride( v.data() ) ;
    }
    template < typename V >
    BOOST_UBLAS_INLINE
    int stride( const vector_slice<V> &v ) {
        return v.stride() * stride( v.data() ) ;
    }

    template < typename M >
    BOOST_UBLAS_INLINE
    int stride( const matrix_row<M> &v ) {
        return stride2( v.data() ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    int stride( const matrix_column<M> &v ) {
        return stride1( v.data() ) ;
    }

    template < typename M >
    BOOST_UBLAS_INLINE
    int stride1( const M &m ) {
        typedef typename M::functor_type functor_type;
        return functor_type::one1( m.size1(), m.size2() ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    int stride2( const M &m ) {
        typedef typename M::functor_type functor_type;
        return functor_type::one2( m.size1(), m.size2() ) ;
    }

    template < typename M >
    BOOST_UBLAS_INLINE
    int stride1( const matrix_reference<M> &m ) {
        return stride1( m.expression() ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    int stride2( const matrix_reference<M> &m ) {
        return stride2( m.expression() ) ;
    }

    template < typename T, std::size_t M, std::size_t N >
    BOOST_UBLAS_INLINE
    int stride1( const c_matrix<T, M, N> &m ) {
        return N ;
    }
    template < typename T, std::size_t M, std::size_t N >
    BOOST_UBLAS_INLINE
    int stride2( const c_matrix<T, M, N> &m ) {
        return 1 ;
    }

    template < typename M >
    BOOST_UBLAS_INLINE
    int stride1( const matrix_range<M> &m ) {
        return stride1( m.data() ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    int stride1( const matrix_slice<M> &m ) {
        return m.stride1() * stride1( m.data() ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    int stride2( const matrix_range<M> &m ) {
        return stride2( m.data() ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    int stride2( const matrix_slice<M> &m ) {
        return m.stride2() * stride2( m.data() ) ;
    }

    template < typename MV >
    BOOST_UBLAS_INLINE
    typename MV::array_type::array_type::array_type::const_pointer data( const MV &mv ) {
        return &mv.data().begin()[0] ;
    }
    template < typename MV >
    BOOST_UBLAS_INLINE
    typename MV::array_type::array_type::const_pointer data_const( const MV &mv ) {
        return &mv.data().begin()[0] ;
    }
    template < typename MV >
    BOOST_UBLAS_INLINE
    typename MV::array_type::pointer data( MV &mv ) {
        return &mv.data().begin()[0] ;
    }

    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::array_type::const_pointer data( const vector_reference<V> &v ) {
        return data( v.expression () ) ;
    }
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::array_type::const_pointer data_const( const vector_reference<V> &v ) {
        return data_const( v.expression () ) ;
    }
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::pointer data( vector_reference<V> &v ) {
        return data( v.expression () ) ;
    }

    template < typename T, std::size_t N >
    BOOST_UBLAS_INLINE
    typename c_vector<T, N>::array_type::array_type::const_pointer data( const c_vector<T, N> &v ) {
        return v.data() ;
    }
    template < typename T, std::size_t N >
    BOOST_UBLAS_INLINE
    typename c_vector<T, N>::array_type::array_type::const_pointer data_const( const c_vector<T, N> &v ) {
        return v.data() ;
    }
    template < typename T, std::size_t N >
    BOOST_UBLAS_INLINE
    typename c_vector<T, N>::pointer data( c_vector<T, N> &v ) {
        return v.data() ;
    }

    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::array_type::const_pointer data( const vector_range<V> &v ) {
        return data( v.data() ) + v.start() * stride (v.data() ) ;
    }
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::array_type::const_pointer data( const vector_slice<V> &v ) {
        return data( v.data() ) + v.start() * stride (v.data() ) ;
    }
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::array_type::const_pointer data_const( const vector_range<V> &v ) {
        return data_const( v.data() ) + v.start() * stride (v.data() ) ;
    }
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::const_pointer data_const( const vector_slice<V> &v ) {
        return data_const( v.data() ) + v.start() * stride (v.data() ) ;
    }
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::pointer data( vector_range<V> &v ) {
        return data( v.data() ) + v.start() * stride (v.data() ) ;
    }
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::pointer data( vector_slice<V> &v ) {
        return data( v.data() ) + v.start() * stride (v.data() ) ;
    }

    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::const_pointer data( const matrix_reference<M> &m ) {
        return data( m.expression () ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::const_pointer data_const( const matrix_reference<M> &m ) {
        return data_const( m.expression () ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::pointer data( matrix_reference<M> &m ) {
        return data( m.expression () ) ;
    }

    template < typename T, std::size_t M, std::size_t N >
    BOOST_UBLAS_INLINE
    typename c_matrix<T, M, N>::array_type::const_pointer data( const c_matrix<T, M, N> &m ) {
        return m.data() ;
    }
    template < typename T, std::size_t M, std::size_t N >
    BOOST_UBLAS_INLINE
    typename c_matrix<T, M, N>::array_type::const_pointer data_const( const c_matrix<T, M, N> &m ) {
        return m.data() ;
    }
    template < typename T, std::size_t M, std::size_t N >
    BOOST_UBLAS_INLINE
    typename c_matrix<T, M, N>::pointer data( c_matrix<T, M, N> &m ) {
        return m.data() ;
    }

    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::const_pointer data( const matrix_row<M> &v ) {
        return data( v.data() ) + v.index() * stride1( v.data() ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::const_pointer data( const matrix_column<M> &v ) {
        return data( v.data() ) + v.index() * stride2( v.data() ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::const_pointer data_const( const matrix_row<M> &v ) {
        return data_const( v.data() ) + v.index() * stride1( v.data() ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::const_pointer data_const( const matrix_column<M> &v ) {
        return data_const( v.data() ) + v.index() * stride2( v.data() ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::pointer data( matrix_row<M> &v ) {
        return data( v.data() ) + v.index() * stride1( v.data() ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::pointer data( matrix_column<M> &v ) {
        return data( v.data() ) + v.index() * stride2( v.data() ) ;
    }

    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::const_pointer data( const matrix_range<M> &m ) {
        return data( m.data() ) + m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::const_pointer data( const matrix_slice<M> &m ) {
        return data( m.data() ) + m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::const_pointer data_const( const matrix_range<M> &m ) {
        return data_const( m.data() ) + m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::const_pointer data_const( const matrix_slice<M> &m ) {
        return data_const( m.data() ) + m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::pointer data( matrix_range<M> &m ) {
        return data( m.data() ) + m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::pointer data( matrix_slice<M> &m ) {
        return data( m.data() ) + m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
    }

    template < typename MV >
    BOOST_UBLAS_INLINE
    typename MV::array_type::const_pointer base( const MV &mv ) {
        return &mv.data().begin()[0] ;
    }
    template < typename MV >
    BOOST_UBLAS_INLINE
    typename MV::array_type::const_pointer base_const( const MV &mv ) {
        return &mv.data().begin()[0] ;
    }
    template < typename MV >
    BOOST_UBLAS_INLINE
    typename MV::array_type::pointer base( MV &mv ) {
        return &mv.data().begin()[0] ;
    }

    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::const_pointer base( const vector_reference<V> &v ) {
        return base( v.expression () ) ;
    }
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::const_pointer base_const( const vector_reference<V> &v ) {
        return base_const( v.expression () ) ;
    }
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::pointer base( vector_reference<V> &v ) {
        return base( v.expression () ) ;
    }

    template < typename T, std::size_t N >
    BOOST_UBLAS_INLINE
    typename c_vector<T, N>::array_type::const_pointer base( const c_vector<T, N> &v ) {
        return v.data() ;
    }
    template < typename T, std::size_t N >
    BOOST_UBLAS_INLINE
    typename c_vector<T, N>::array_type::const_pointer base_const( const c_vector<T, N> &v ) {
        return v.data() ;
    }
    template < typename T, std::size_t N >
    BOOST_UBLAS_INLINE
    typename c_vector<T, N>::pointer base( c_vector<T, N> &v ) {
        return v.data() ;
    }

    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::const_pointer base( const vector_range<V> &v ) {
        return base( v.data() ) ;
    }
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::const_pointer base( const vector_slice<V> &v ) {
        return base( v.data() ) ;
    }
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::const_pointer base_const( const vector_range<V> &v ) {
        return base_const( v.data() ) ;
    }
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::const_pointer base_const( const vector_slice<V> &v ) {
        return base_const( v.data() ) ;
    }
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::pointer base( vector_range<V> &v ) {
        return base( v.data() ) ;
    }
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::array_type::pointer base( vector_slice<V> &v ) {
        return base( v.data() ) ;
    }

    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::const_pointer base( const matrix_reference<M> &m ) {
        return base( m.expression () ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::const_pointer base_const( const matrix_reference<M> &m ) {
        return base_const( m.expression () ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::pointer base( matrix_reference<M> &m ) {
        return base( m.expression () ) ;
    }

    template < typename T, std::size_t M, std::size_t N >
    BOOST_UBLAS_INLINE
    typename c_matrix<T, M, N>::array_type::const_pointer base( const c_matrix<T, M, N> &m ) {
        return m.data() ;
    }
    template < typename T, std::size_t M, std::size_t N >
    BOOST_UBLAS_INLINE
    typename c_matrix<T, M, N>::array_type::const_pointer base_const( const c_matrix<T, M, N> &m ) {
        return m.data() ;
    }
    template < typename T, std::size_t M, std::size_t N >
    BOOST_UBLAS_INLINE
    typename c_matrix<T, M, N>::pointer base( c_matrix<T, M, N> &m ) {
        return m.data() ;
    }

    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::const_pointer base( const matrix_row<M> &v ) {
        return base( v.data() ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::const_pointer base( const matrix_column<M> &v ) {
        return base( v.data() ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::const_pointer base_const( const matrix_row<M> &v ) {
        return base_const( v.data() ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::const_pointer base_const( const matrix_column<M> &v ) {
        return base_const( v.data() ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::pointer base( matrix_row<M> &v ) {
        return base( v.data() ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::pointer base( matrix_column<M> &v ) {
        return base( v.data() ) ;
    }

    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::const_pointer base( const matrix_range<M> &m ) {
        return base( m.data() ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::const_pointer base( const matrix_slice<M> &m ) {
        return base( m.data() ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::const_pointer base_const( const matrix_range<M> &m ) {
        return base_const( m.data() ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::const_pointer base_const( const matrix_slice<M> &m ) {
        return base_const( m.data() ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::pointer base( matrix_range<M> &m ) {
        return base( m.data() ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::array_type::pointer base( matrix_slice<M> &m ) {
        return base( m.data() ) ;
    }

    template < typename MV >
    BOOST_UBLAS_INLINE
    typename MV::size_type start( const MV &mv ) {
        return 0 ;
    }

    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::size_type start( const vector_range<V> &v ) {
        return v.start() * stride (v.data() ) ;
    }
    template < typename V >
    BOOST_UBLAS_INLINE
    typename V::size_type start( const vector_slice<V> &v ) {
        return v.start() * stride (v.data() ) ;
    }

    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::size_type start( const matrix_row<M> &v ) {
        return v.index() * stride1( v.data() ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::size_type start( const matrix_column<M> &v ) {
        return v.index() * stride2( v.data() ) ;
    }

    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::size_type start( const matrix_range<M> &m ) {
        return m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
    }
    template < typename M >
    BOOST_UBLAS_INLINE
    typename M::size_type start( const matrix_slice<M> &m ) {
        return m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
    }

}}}}

#endif


code:
#ifndef BOOST_MPL_MAP_MAP10_HPP_INCLUDED
#define BOOST_MPL_MAP_MAP10_HPP_INCLUDED

// Copyright Aleksey Gurtovoy 2000-2004
// Copyright David Abrahams 2003-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)
//
// See http://www.boost.org/libs/mpl for documentation.

// $Id$
// $Date$
// $Revision$

#if !defined(BOOST_MPL_PREPROCESSING_MODE)
#   include <boost/mpl/map/map0.hpp>
#endif

#include <boost/mpl/aux_/config/use_preprocessed.hpp>

#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
    && !defined(BOOST_MPL_PREPROCESSING_MODE)

#   define BOOST_MPL_PREPROCESSED_HEADER map10.hpp
#   include <boost/mpl/map/aux_/include_preprocessed.hpp>

#else

#   include <boost/preprocessor/iterate.hpp>

namespace boost { namespace mpl {

#   define BOOST_PP_ITERATION_PARAMS_1 \
    (3,(1, 10, <boost/mpl/map/aux_/numbered.hpp>))
#   include BOOST_PP_ITERATE()

}}

#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS

#endif // BOOST_MPL_MAP_MAP10_HPP_INCLUDED


code:
//  error_code support implementation file  ----------------------------------//

//  Copyright Beman Dawes 2002, 2006
//  Copyright (c) Microsoft Corporation 2014
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

//  See library home page at http://www.boost.org/libs/system

//----------------------------------------------------------------------------//

#include <boost/config/warning_disable.hpp>

#include <boost/system/config.hpp>
#include <boost/system/error_code.hpp>
#include <boost/cerrno.hpp>
#include <vector>
#include <cstdlib>
#include <cassert>

#include <cstring> // for strerror/strerror_r

# if defined( BOOST_WINDOWS_API )
#   include <windows.h>
#   if !BOOST_PLAT_WINDOWS_RUNTIME
#     include <boost/system/detail/local_free_on_destruction.hpp>
#   endif
#   ifndef ERROR_INCORRECT_SIZE
#     define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS
#   endif
# endif

//----------------------------------------------------------------------------//
namespace boost
{
    namespace system
    {

namespace
{

  //  standard error categories  ---------------------------------------------//

  class generic_error_category : public error_category
  {
  public:
    generic_error_category(){}
    const char *   name() const BOOST_SYSTEM_NOEXCEPT;
    std::string    message( int ev ) const;
  };

  class system_error_category : public error_category
  {
  public:
    system_error_category(){}
    const char *        name() const BOOST_SYSTEM_NOEXCEPT;
    std::string         message( int ev ) const;
    error_condition     default_error_condition( int ev ) const BOOST_SYSTEM_NOEXCEPT;
  };

  //  generic_error_category implementation  ---------------------------------//

  const char * generic_error_category::name() const BOOST_SYSTEM_NOEXCEPT
  {
    return "generic";
  }

  std::string generic_error_category::message( int ev ) const
  {
    using namespace boost::system::errc;
#if defined(__PGI)
      using boost::system::errc::invalid_argument;
#endif

    static std::string unknown_err( "Unknown error" );
  // strerror_r is preferred because it is always thread safe,
  // however, we fallback to strerror in certain cases because:
  //   -- Windows doesn't provide strerror_r.
  //   -- HP and Sun do provide strerror_r on newer systems, but there is
  //      no way to tell if is available at runtime and in any case their
  //      versions of strerror are thread safe anyhow.
  //   -- Linux only sometimes provides strerror_r.
  //   -- Tru64 provides strerror_r only when compiled -pthread.
  //   -- VMS doesn't provide strerror_r, but on this platform, strerror is
  //      thread safe.
  # if defined(BOOST_WINDOWS_API) || defined(__hpux) || defined(__sun)\
     || (defined(__linux) && (!defined(__USE_XOPEN2K) || defined(BOOST_SYSTEM_USE_STRERROR)))\
     || (defined(__osf__) && !defined(_REENTRANT))\
     || (defined(__INTEGRITY))\
     || (defined(__vms))\
     || (defined(__QNXNTO__))
      const char * c_str = std::strerror( ev );
      return  c_str
        ? std::string( c_str )
        : unknown_err;
  # else  // use strerror_r
      char buf[64];
      char * bp = buf;
      std::size_t sz = sizeof(buf);
  #  if defined(__CYGWIN__) || defined(__USE_GNU)
      // Oddball version of strerror_r
      const char * c_str = strerror_r( ev, bp, sz );
      return  c_str
        ? std::string( c_str )
        : unknown_err;
  #  else
      // POSIX version of strerror_r
      int result;
      for (;;)
      {
        // strerror_r returns 0 on success, otherwise ERANGE if buffer too small,
        // invalid_argument if ev not a valid error number
  #  if defined (__sgi)
        const char * c_str = strerror( ev );
        result = 0;
      return  c_str
        ? std::string( c_str )
        : unknown_err;
  #  else
        result = strerror_r( ev, bp, sz );
  #  endif
        if (result == 0 )
          break;
        else
        {
  #  if defined(__linux)
          // Linux strerror_r returns -1 on error, with error number in errno
          result = errno;
  #  endif
          if ( result !=  ERANGE ) break;
          if ( sz > sizeof(buf) ) std::free( bp );
          sz *= 2;
          if ( (bp = static_cast<char*>(std::malloc( sz ))) == 0 )
            return std::string( "ENOMEM" );
        }
      }
      std::string msg;
#   ifndef BOOST_NO_EXCEPTIONS
      try
#   endif
      {
        msg = ( ( result == invalid_argument ) ? "Unknown error" : bp );
      }

#   ifndef BOOST_NO_EXCEPTIONS
      // See ticket #2098
      catch(...)
      {
        // just eat the exception
      }
#   endif

      if ( sz > sizeof(buf) ) std::free( bp );
      sz = 0;
      return msg;
  #  endif   // else POSIX version of strerror_r
  # endif  // else use strerror_r
  }
  //  system_error_category implementation  --------------------------------//

  const char * system_error_category::name() const BOOST_SYSTEM_NOEXCEPT
  {
    return "system";
  }

  error_condition system_error_category::default_error_condition( int ev ) const BOOST_SYSTEM_NOEXCEPT
  {
    using namespace boost::system::errc;
#if defined(__PGI)
      using boost::system::errc::invalid_argument;
#endif

# if defined(BOOST_WINDOWS_API)
#   if defined(WINAPI_FAMILY) && ((WINAPI_FAMILY & WINAPI_PARTITION_APP) != 0)
    // When using the Windows Runtime, most system errors are reported as HRESULTs.
    // We want to map the common Win32 errors to their equivalent error condition,
    // whether or not they are reported via an HRESULT.
    if ( ev < 0 ) // Check for failed HRESULTs only.
      if ( HRESULT_FACILITY( ev ) == FACILITY_WIN32 )
        ev = HRESULT_CODE( ev );
#   endif
# endif

    switch ( ev )
    {
    case 0: return make_error_condition( success );
# if defined(BOOST_POSIX_API)
    // POSIX-like O/S -> posix_errno decode table  ---------------------------//
    case E2BIG: return make_error_condition( argument_list_too_long );
    case EACCES: return make_error_condition( permission_denied );
    case EADDRINUSE: return make_error_condition( address_in_use );
    case EADDRNOTAVAIL: return make_error_condition( address_not_available );
    case EAFNOSUPPORT: return make_error_condition( address_family_not_supported );
    case EAGAIN: return make_error_condition( resource_unavailable_try_again );
#   if EALREADY != EBUSY  //  EALREADY and EBUSY are the same on QNX Neutrino
    case EALREADY: return make_error_condition( connection_already_in_progress );
#   endif
    case EBADF: return make_error_condition( bad_file_descriptor );
    case EBADMSG: return make_error_condition( bad_message );
    case EBUSY: return make_error_condition( device_or_resource_busy );
    case ECANCELED: return make_error_condition( operation_canceled );
    case ECHILD: return make_error_condition( no_child_process );
    case ECONNABORTED: return make_error_condition( connection_aborted );
    case ECONNREFUSED: return make_error_condition( connection_refused );
    case ECONNRESET: return make_error_condition( connection_reset );
    case EDEADLK: return make_error_condition( resource_deadlock_would_occur );
    case EDESTADDRREQ: return make_error_condition( destination_address_required );
    case EDOM: return make_error_condition( argument_out_of_domain );
    case EEXIST: return make_error_condition( file_exists );
    case EFAULT: return make_error_condition( bad_address );
    case EFBIG: return make_error_condition( file_too_large );
    case EHOSTUNREACH: return make_error_condition( host_unreachable );
    case EIDRM: return make_error_condition( identifier_removed );
    case EILSEQ: return make_error_condition( illegal_byte_sequence );
    case EINPROGRESS: return make_error_condition( operation_in_progress );
    case EINTR: return make_error_condition( interrupted );
    case EINVAL: return make_error_condition( invalid_argument );
    case EIO: return make_error_condition( io_error );
    case EISCONN: return make_error_condition( already_connected );
    case EISDIR: return make_error_condition( is_a_directory );
    case ELOOP: return make_error_condition( too_many_symbolic_link_levels );
    case EMFILE: return make_error_condition( too_many_files_open );
    case EMLINK: return make_error_condition( too_many_links );
    case EMSGSIZE: return make_error_condition( message_size );
    case ENAMETOOLONG: return make_error_condition( filename_too_long );
    case ENETDOWN: return make_error_condition( network_down );
    case ENETRESET: return make_error_condition( network_reset );
    case ENETUNREACH: return make_error_condition( network_unreachable );
    case ENFILE: return make_error_condition( too_many_files_open_in_system );
    case ENOBUFS: return make_error_condition( no_buffer_space );
    case ENODATA: return make_error_condition( no_message_available );
    case ENODEV: return make_error_condition( no_such_device );
    case ENOENT: return make_error_condition( no_such_file_or_directory );
    case ENOEXEC: return make_error_condition( executable_format_error );
    case ENOLCK: return make_error_condition( no_lock_available );
    case ENOLINK: return make_error_condition( no_link );
    case ENOMEM: return make_error_condition( not_enough_memory );
    case ENOMSG: return make_error_condition( no_message );
    case ENOPROTOOPT: return make_error_condition( no_protocol_option );
    case ENOSPC: return make_error_condition( no_space_on_device );
    case ENOSR: return make_error_condition( no_stream_resources );
    case ENOSTR: return make_error_condition( not_a_stream );
    case ENOSYS: return make_error_condition( function_not_supported );
    case ENOTCONN: return make_error_condition( not_connected );
    case ENOTDIR: return make_error_condition( not_a_directory );
  # if ENOTEMPTY != EEXIST // AIX treats ENOTEMPTY and EEXIST as the same value
    case ENOTEMPTY: return make_error_condition( directory_not_empty );
  # endif // ENOTEMPTY != EEXIST
  # if ENOTRECOVERABLE != ECONNRESET // the same on some Broadcom chips
    case ENOTRECOVERABLE: return make_error_condition( state_not_recoverable );
  # endif // ENOTRECOVERABLE != ECONNRESET
    case ENOTSOCK: return make_error_condition( not_a_socket );
    case ENOTSUP: return make_error_condition( not_supported );
    case ENOTTY: return make_error_condition( inappropriate_io_control_operation );
    case ENXIO: return make_error_condition( no_such_device_or_address );
  # if EOPNOTSUPP != ENOTSUP
    case EOPNOTSUPP: return make_error_condition( operation_not_supported );
  # endif // EOPNOTSUPP != ENOTSUP
    case EOVERFLOW: return make_error_condition( value_too_large );
  # if EOWNERDEAD != ECONNABORTED // the same on some Broadcom chips
    case EOWNERDEAD: return make_error_condition( owner_dead );
  # endif // EOWNERDEAD != ECONNABORTED
    case EPERM: return make_error_condition( operation_not_permitted );
    case EPIPE: return make_error_condition( broken_pipe );
    case EPROTO: return make_error_condition( protocol_error );
    case EPROTONOSUPPORT: return make_error_condition( protocol_not_supported );
    case EPROTOTYPE: return make_error_condition( wrong_protocol_type );
    case ERANGE: return make_error_condition( result_out_of_range );
    case EROFS: return make_error_condition( read_only_file_system );
    case ESPIPE: return make_error_condition( invalid_seek );
    case ESRCH: return make_error_condition( no_such_process );
    case ETIME: return make_error_condition( stream_timeout );
    case ETIMEDOUT: return make_error_condition( timed_out );
    case ETXTBSY: return make_error_condition( text_file_busy );
  # if EAGAIN != EWOULDBLOCK
    case EWOULDBLOCK: return make_error_condition( operation_would_block );
  # endif // EAGAIN != EWOULDBLOCK
    case EXDEV: return make_error_condition( cross_device_link );
  #else
    // Windows system -> posix_errno decode table  ---------------------------//
    // see WinError.h comments for descriptions of errors
    case ERROR_ACCESS_DENIED: return make_error_condition( permission_denied );
    case ERROR_ALREADY_EXISTS: return make_error_condition( file_exists );
    case ERROR_BAD_UNIT: return make_error_condition( no_such_device );
    case ERROR_BUFFER_OVERFLOW: return make_error_condition( filename_too_long );
    case ERROR_BUSY: return make_error_condition( device_or_resource_busy );
    case ERROR_BUSY_DRIVE: return make_error_condition( device_or_resource_busy );
    case ERROR_CANNOT_MAKE: return make_error_condition( permission_denied );
    case ERROR_CANTOPEN: return make_error_condition( io_error );
    case ERROR_CANTREAD: return make_error_condition( io_error );
    case ERROR_CANTWRITE: return make_error_condition( io_error );
    case ERROR_CURRENT_DIRECTORY: return make_error_condition( permission_denied );
    case ERROR_DEV_NOT_EXIST: return make_error_condition( no_such_device );
    case ERROR_DEVICE_IN_USE: return make_error_condition( device_or_resource_busy );
    case ERROR_DIR_NOT_EMPTY: return make_error_condition( directory_not_empty );
    case ERROR_DIRECTORY: return make_error_condition( invalid_argument ); // WinError.h: "The directory name is invalid"
    case ERROR_DISK_FULL: return make_error_condition( no_space_on_device );
    case ERROR_FILE_EXISTS: return make_error_condition( file_exists );
    case ERROR_FILE_NOT_FOUND: return make_error_condition( no_such_file_or_directory );
    case ERROR_HANDLE_DISK_FULL: return make_error_condition( no_space_on_device );
    case ERROR_INVALID_ACCESS: return make_error_condition( permission_denied );
    case ERROR_INVALID_DRIVE: return make_error_condition( no_such_device );
    case ERROR_INVALID_FUNCTION: return make_error_condition( function_not_supported );
    case ERROR_INVALID_HANDLE: return make_error_condition( invalid_argument );
    case ERROR_INVALID_NAME: return make_error_condition( invalid_argument );
    case ERROR_LOCK_VIOLATION: return make_error_condition( no_lock_available );
    case ERROR_LOCKED: return make_error_condition( no_lock_available );
    case ERROR_NEGATIVE_SEEK: return make_error_condition( invalid_argument );
    case ERROR_NOACCESS: return make_error_condition( permission_denied );
    case ERROR_NOT_ENOUGH_MEMORY: return make_error_condition( not_enough_memory );
    case ERROR_NOT_READY: return make_error_condition( resource_unavailable_try_again );
    case ERROR_NOT_SAME_DEVICE: return make_error_condition( cross_device_link );
    case ERROR_OPEN_FAILED: return make_error_condition( io_error );
    case ERROR_OPEN_FILES: return make_error_condition( device_or_resource_busy );
    case ERROR_OPERATION_ABORTED: return make_error_condition( operation_canceled );
    case ERROR_OUTOFMEMORY: return make_error_condition( not_enough_memory );
    case ERROR_PATH_NOT_FOUND: return make_error_condition( no_such_file_or_directory );
    case ERROR_READ_FAULT: return make_error_condition( io_error );
    case ERROR_RETRY: return make_error_condition( resource_unavailable_try_again );
    case ERROR_SEEK: return make_error_condition( io_error );
    case ERROR_SHARING_VIOLATION: return make_error_condition( permission_denied );
    case ERROR_TOO_MANY_OPEN_FILES: return make_error_condition( too_many_files_open );
    case ERROR_WRITE_FAULT: return make_error_condition( io_error );
    case ERROR_WRITE_PROTECT: return make_error_condition( permission_denied );
    case WSAEACCES: return make_error_condition( permission_denied );
    case WSAEADDRINUSE: return make_error_condition( address_in_use );
    case WSAEADDRNOTAVAIL: return make_error_condition( address_not_available );
    case WSAEAFNOSUPPORT: return make_error_condition( address_family_not_supported );
    case WSAEALREADY: return make_error_condition( connection_already_in_progress );
    case WSAEBADF: return make_error_condition( bad_file_descriptor );
    case WSAECONNABORTED: return make_error_condition( connection_aborted );
    case WSAECONNREFUSED: return make_error_condition( connection_refused );
    case WSAECONNRESET: return make_error_condition( connection_reset );
    case WSAEDESTADDRREQ: return make_error_condition( destination_address_required );
    case WSAEFAULT: return make_error_condition( bad_address );
    case WSAEHOSTUNREACH: return make_error_condition( host_unreachable );
    case WSAEINPROGRESS: return make_error_condition( operation_in_progress );
    case WSAEINTR: return make_error_condition( interrupted );
    case WSAEINVAL: return make_error_condition( invalid_argument );
    case WSAEISCONN: return make_error_condition( already_connected );
    case WSAEMFILE: return make_error_condition( too_many_files_open );
    case WSAEMSGSIZE: return make_error_condition( message_size );
    case WSAENAMETOOLONG: return make_error_condition( filename_too_long );
    case WSAENETDOWN: return make_error_condition( network_down );
    case WSAENETRESET: return make_error_condition( network_reset );
    case WSAENETUNREACH: return make_error_condition( network_unreachable );
    case WSAENOBUFS: return make_error_condition( no_buffer_space );
    case WSAENOPROTOOPT: return make_error_condition( no_protocol_option );
    case WSAENOTCONN: return make_error_condition( not_connected );
    case WSAENOTSOCK: return make_error_condition( not_a_socket );
    case WSAEOPNOTSUPP: return make_error_condition( operation_not_supported );
    case WSAEPROTONOSUPPORT: return make_error_condition( protocol_not_supported );
    case WSAEPROTOTYPE: return make_error_condition( wrong_protocol_type );
    case WSAETIMEDOUT: return make_error_condition( timed_out );
    case WSAEWOULDBLOCK: return make_error_condition( operation_would_block );
  #endif
    default: return error_condition( ev, system_category() );
    }
  }

# if !defined( BOOST_WINDOWS_API )

  std::string system_error_category::message( int ev ) const
  {
    return generic_category().message( ev );
  }
# else

  std::string system_error_category::message( int ev ) const
  {
#if defined(UNDER_CE) || BOOST_PLAT_WINDOWS_RUNTIME || defined(BOOST_NO_ANSI_APIS)
    std::wstring buf(128, wchar_t());
    for (;;)
    {
        DWORD retval = ::FormatMessageW(
            FORMAT_MESSAGE_FROM_SYSTEM |
            FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL,
            ev,
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
            &buf[0],
            buf.size(),
            NULL
        );

        if (retval > 0)
        {
            buf.resize(retval);
            break;
        }
        else if ( ::GetLastError() != ERROR_INSUFFICIENT_BUFFER )
        {
            return std::string("Unknown error");
        }
        else
        {
            buf.resize(buf.size() + buf.size() / 2);
        }
    }

    int num_chars = (buf.size() + 1) * 2;
    LPSTR narrow_buffer = (LPSTR)_alloca( num_chars );
    if (::WideCharToMultiByte(CP_ACP, 0, buf.c_str(), -1, narrow_buffer, num_chars, NULL, NULL) == 0)
    {
        return std::string("Unknown error");
    }

    std::string str( narrow_buffer );
#else
    LPVOID lpMsgBuf = 0;
    DWORD retval = ::FormatMessageA(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        ev,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
        (LPSTR) &lpMsgBuf,
        0,
        NULL
    );
    detail::local_free_on_destruction lfod(lpMsgBuf);
    if (retval == 0)
        return std::string("Unknown error");

    std::string str( static_cast<LPCSTR>(lpMsgBuf) );
# endif
    while ( str.size()
      && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') )
        str.erase( str.size()-1 );
    if ( str.size() && str[str.size()-1] == '.' )
      { str.erase( str.size()-1 ); }
    return str;
  }
# endif

} // unnamed namespace

# ifndef BOOST_SYSTEM_NO_DEPRECATED
    BOOST_SYSTEM_DECL error_code throws; // "throw on error" special error_code;
                                         //  note that it doesn't matter if this
                                         //  isn't initialized before use since
                                         //  the only use is to take its
                                         //  address for comparison purposes
# endif

# ifdef BOOST_ERROR_CODE_HEADER_ONLY
#   define BOOST_SYSTEM_LINKAGE inline
# else
#   define BOOST_SYSTEM_LINKAGE BOOST_SYSTEM_DECL
# endif

    BOOST_SYSTEM_LINKAGE const error_category & system_category() BOOST_SYSTEM_NOEXCEPT
    {
      static const system_error_category  system_category_const;
      return system_category_const;
    }

    BOOST_SYSTEM_LINKAGE const error_category & generic_category() BOOST_SYSTEM_NOEXCEPT
    {
      static const generic_error_category generic_category_const;
      return generic_category_const;
    }

  } // namespace system
} // namespace boost


code:
# Set paths
EXE_DIR = ..\\..\\wsjtx_install
QT_DIR = C:/wsjt-env/Qt5/5.2.1/mingw48_32
FFTW3_DIR = ..

INCPATH = -I${QT_DIR}/include/QtCore -I${QT_DIR}/include

# Compilers
CC = gcc
CXX = g++
FC = gfortran
AR = ar cr
RANLIB = ranlib
MKDIR = mkdir -p
CP = cp
RM = rm -f

FFLAGS = -O2 -fbounds-check -Wall -Wno-conversion
CFLAGS = -O2 -I.

# Default rules
%.o: %.c
	${CC} ${CFLAGS} -c $<
%.o: %.f
	${FC} ${FFLAGS} -c $<
%.o: %.F
	${FC} ${FFLAGS} -c $<
%.o: %.f90
	${FC} ${FFLAGS} -c $<
%.o: %.F90
	${FC} ${FFLAGS} -c $<

all:	 jt9w

OBJS1 = jt9w.o smo.o sync9w.o pctile.o shell.o lorentzian.o fchisq0.o \
      softsym9w.o four2a.o interleave9.o jt9fano.o fano232.o packjt.o \
      deg2grid.o grid2deg.o fmtmsg.o db.o decode9w.o

jt9w: $(OBJS1)
	$(FC) -o jt9w $(OBJS1) -lfftw3f

OBJS2 = t1.o four2a.o db.o
t1:   $(OBJS2)
	$(FC) -o t1 $(OBJS2) -lfftw3f

OBJS3 = t2.o four2a.o db.o
t2:   $(OBJS3)
	$(FC) -o t2 $(OBJS3) -lfftw3f

OBJS4 = t3.o four2a.o db.o
t3:   $(OBJS4)
	$(FC) -o t3 $(OBJS4) -lfftw3f

.PHONY : clean

clean:
	$(RM) *.o JTMSKcode JTMSKcode.exe