Wigner-Ville分布算法的C++实现

头文件:

/*
 * Copyright (c) 2008-2011 Zhang Ming (M. Zhang), [email protected]
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 2 or any later version.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details. A copy of the GNU General Public License is available at:
 * http://www.fsf.org/licensing/licenses
 */


/*****************************************************************************
 *                                    wvd.h
 *
 * Wigner-Ville distribution of one dimension signal "sn".
 *
 * The "sn" can be either real signal or complex signal. The WVD coefficients
 * is an N-by-N REAL matrix, where N is the signal length.
 *
 * Zhang Ming, 2010-10, Xi'an Jiaotong University.
 *****************************************************************************/


#ifndef WVD_H
#define WVD_H


#include <vector.h>
#include <matrix.h>
#include <fft.h>
#include <vectormath.h>
#include <utilities.h>


namespace splab
{

    template<typename Type> Matrix<Type> wvd( const Vector<Type>& );
    template<typename Type> Matrix<Type> wvd( const Vector< complex<Type> >& );


    #include <wvd-impl.h>

}
// namespace splab


#endif
// WVD_H

实现文件:

/*
 * Copyright (c) 2008-2011 Zhang Ming (M. Zhang), [email protected]
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 2 or any later version.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details. A copy of the GNU General Public License is available at:
 * http://www.fsf.org/licensing/licenses
 */


/*****************************************************************************
 *                                wvd-impl.h
 *
 * Implementation for Wigner-Ville distribution.
 *
 * Zhang Ming, 2010-10, Xi'an Jiaotong University.
 *****************************************************************************/


/**
 * Compute WVD of 1D real signal "sn". The WVD coeffitions are stored
 * in "coefs", a complex matrix. The column represents time, and row
 * represents frequency.
 */
template <typename Type>
Matrix<Type> wvd( const Vector<Type> &sn )
{
    int N = sn.size(),
        dN = 2*N;

    Vector<Type> xn = fftInterp( sn, 2 );
    Vector<Type> fn( 3*dN );
    for( int i=dN; i<2*dN; ++i )
        fn[i] = xn[i-dN];

    Vector<Type> yn( dN );
    Matrix<Type> coefs( N, N );

    for( int n=1; n<=N; ++n )
    {
        for( int i=0; i<N; ++i )
            yn[i] = fn(dN+2*n+i) * fn(dN+2*n-i);
        for( int i=-N; i<0; ++i )
            yn[dN+i] = fn(dN+2*n+i) * fn(dN+2*n-i);

        coefs.setColumn( dyadDown(real(fft(yn)),0), n-1 );
    }

    return coefs;
}


/**
 * Compute WVD of 1D complex signal "cn". The WVD coeffitions are stored
 * in "coefs", a complex matrix. The column represents time, and row
 * represents frequency.
 */
template <typename Type>
Matrix<Type> wvd( const Vector< complex<Type> > &cn )
{
    int N = cn.size(),
        dN = 2*N;

    Vector< complex<Type> > xn = fftInterp( cn, 2 );
    Vector< complex<Type> > fn(3*dN);
    for( int i=dN; i<2*dN; ++i )
        fn[i] = xn[i-dN];

    Vector< complex<Type> > yn( dN );
    Matrix<Type> coefs( N, N );

    for( int n=1; n<=N; ++n )
    {
        for( int i=0; i<N; ++i )
            yn[i] = fn(dN+2*n+i) * conj(fn(dN+2*n-i));
        for( int i=-N; i<0; ++i )
            yn[dN+i] = fn(dN+2*n+i) * conj(fn(dN+2*n-i));

        coefs.setColumn( dyadDown(real(fft(yn)),0), n-1 );
    }

    return coefs;
}

测试代码:

/*****************************************************************************
 *                               wvd_test.cpp
 *
 * Wigner-Ville distribution testing.
 *
 * Zhang Ming, 2010-10, Xi'an Jiaotong University.
 *****************************************************************************/


#define BOUNDS_CHECK

#include <iostream>
#include <iomanip>
#include <timing.h>
#include <wvd.h>


using namespace std;
using namespace splab;


typedef double  Type;
const   int     Ls = 100;


int main()
{
	/******************************* [ signal ] ******************************/
	Vector<Type> t = linspace( Type(-0.5), Type(0.5-1.0/Ls), Ls );
	Vector< complex<Type> > sn(Ls);
	for( int i=0; i<Ls; ++i )
	{
	    Type tip2 = t[i]*t[i],
             freq = Type(TWOPI*25);
        sn[i] = exp(-32*tip2) * polar(Type(1),freq*t[i]) * polar(Type(1),freq*tip2);
	}
	cout << setiosflags(ios::fixed) << setprecision(4);

	/********************************* [ WVD ] *******************************/
	Type runtime = 0;
	Timing cnt;
	cout << "Computing Wigner-Wille distribution." << endl << endl;
	cnt.start();
    Matrix<Type> coefs = wvd( sn );
	cnt.stop();
	runtime = cnt.read();
	cout << "The running time = " << runtime << " (ms)" << endl << endl;

    Vector<Type> timeMarg = mean(coefs),
                 freqMarg = mean(trT(coefs));
	cout << "The time marginal condition is: " << timeMarg << endl;
	cout << "The frequency marginal condition is: " << freqMarg << endl;

	return 0;
}

运行结果:

Computing Wigner-Wille distribution.

The running time = 0.0150 (ms)

The time marginal condition is: size: 100 by 1
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0001
0.0001
0.0002
0.0003
0.0005
0.0008
0.0012
0.0017
0.0026
0.0038
0.0055
0.0079
0.0112
0.0156
0.0214
0.0292
0.0392
0.0519
0.0679
0.0877
0.1118
0.1409
0.1751
0.2148
0.2604
0.3115
0.3678
0.4290
0.4938
0.5612
0.6298
0.6978
0.7630
0.8239
0.8785
0.9246
0.9607
0.9857
0.9985
0.9984
0.9856
0.9608
0.9247
0.8784
0.8239
0.7630
0.6978
0.6298
0.5612
0.4937
0.4290
0.3679
0.3115
0.2604
0.2148
0.1751
0.1409
0.1119
0.0877
0.0679
0.0519
0.0391
0.0292
0.0215
0.0156
0.0112
0.0079
0.0055
0.0038
0.0026
0.0017
0.0012
0.0008
0.0005
0.0003
0.0002
0.0001
0.0001
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000

The frequency marginal condition is: size: 100 by 1
0.0000
0.0000
0.0000
0.0000
0.0000
0.0001
0.0003
0.0007
0.0016
0.0036
0.0078
0.0158
0.0308
0.0569
0.1001
0.1678
0.2677
0.4064
0.5877
0.8089
1.0600
1.3226
1.5707
1.7763
1.9121
1.9598
1.9121
1.7763
1.5707
1.3226
1.0600
0.8089
0.5877
0.4064
0.2677
0.1678
0.1001
0.0569
0.0308
0.0158
0.0078
0.0036
0.0016
0.0007
0.0003
0.0001
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000


Process returned 0 (0x0)   execution time : 0.203 s
Press any key to continue.

你可能感兴趣的:(Wigner-Ville分布算法的C++实现)