Exemplo n.º 1
0
QPair<int,double> ConnectivityMeasures::calcCrossCorrelation(const RowVectorXd& vecFirst, const RowVectorXd& vecSecond)
{
    Eigen::FFT<double> fft;

    int N = std::max(vecFirst.cols(), vecSecond.cols());

    //Compute the FFT size as the "next power of 2" of the input vector's length (max)
    int b = ceil(log2(2.0 * N - 1));
    int fftsize = pow(2,b);
//    int end = fftsize - 1;
//    int maxlag = N - 1;

    //Zero Padd
    RowVectorXd xCorrInputVecFirst = RowVectorXd::Zero(fftsize);
    xCorrInputVecFirst.head(vecFirst.cols()) = vecFirst;

    RowVectorXd xCorrInputVecSecond = RowVectorXd::Zero(fftsize);
    xCorrInputVecSecond.head(vecSecond.cols()) = vecSecond;

    //FFT for freq domain to both vectors
    RowVectorXcd freqvec;
    RowVectorXcd freqvec2;

    fft.fwd(freqvec, xCorrInputVecFirst);
    fft.fwd(freqvec2, xCorrInputVecSecond);

    //Create conjugate complex
    freqvec2.conjugate();

    //Main step of cross corr
    for (int i = 0; i < fftsize; i++) {
        freqvec[i] = freqvec[i] * freqvec2[i];
    }

    RowVectorXd result;
    fft.inv(result, freqvec);

    //Will get rid of extra zero padding
    RowVectorXd result2 = result;//.segment(maxlag, N);

    QPair<int,int> minMaxRange;
    int idx = 0;
    result2.minCoeff(&idx);
    minMaxRange.first = idx;
    result2.maxCoeff(&idx);
    minMaxRange.second = idx;

//    std::cout<<"result2(minMaxRange.first)"<<result2(minMaxRange.first)<<std::endl;
//    std::cout<<"result2(minMaxRange.second)"<<result2(minMaxRange.second)<<std::endl;
//    std::cout<<"b"<<b<<std::endl;
//    std::cout<<"fftsize"<<fftsize<<std::endl;
//    std::cout<<"end"<<end<<std::endl;
//    std::cout<<"maxlag"<<maxlag<<std::endl;

    //Return val
    int resultIndex = minMaxRange.second;
    double maxValue = result2(resultIndex);

    return QPair<int,double>(resultIndex, maxValue);
}
Exemplo n.º 2
0
MatrixXd Spectrogram::make_spectrogram(VectorXd signal, qint32 window_size = 0)
{
    if(window_size == 0)
        window_size = signal.rows()/4;

    Eigen::FFT<double> fft;
    MatrixXd tf_matrix = MatrixXd::Zero(signal.rows()/2, signal.rows());

    for(qint32 translate = 0; translate < signal.rows(); translate++)
    {
        VectorXd envelope = gauss_window(signal.rows(), window_size, translate);

        VectorXd windowed_sig = VectorXd::Zero(signal.rows());
        VectorXcd fft_win_sig = VectorXcd::Zero(signal.rows());

        VectorXd real_coeffs = VectorXd::Zero(signal.rows()/2);

        for(qint32 sample = 0; sample < signal.rows(); sample++)
            windowed_sig[sample] = signal[sample] * envelope[sample];

        fft.fwd(fft_win_sig, windowed_sig);

        for(qint32 i= 0; i<signal.rows()/2; i++)
        {
            qreal value = pow(abs(fft_win_sig[i]), 2.0);
            real_coeffs[i] = value;
        }

        tf_matrix.col(translate) = real_coeffs;
    }
    return tf_matrix;
}
Exemplo n.º 3
0
RowVectorXd FilterData::applyFFTFilter(const RowVectorXd& data, bool keepOverhead, CompensateEdgeEffects compensateEdgeEffects) const
{
    #ifdef EIGEN_FFTW_DEFAULT
        fftw_make_planner_thread_safe();
    #endif

    if(data.cols()<m_dCoeffA.cols() && compensateEdgeEffects==MirrorData) {
        qDebug()<<QString("Error in FilterData: Number of filter taps(%1) bigger then data size(%2). Not enough data to perform mirroring!").arg(m_dCoeffA.cols()).arg(data.cols());
        return data;
    }

//    std::cout<<"m_iFFTlength: "<<m_iFFTlength<<std::endl;
//    std::cout<<"2*m_dCoeffA.cols() + data.cols(): "<<2*m_dCoeffA.cols() + data.cols()<<std::endl;

    if(2*m_dCoeffA.cols() + data.cols()>m_iFFTlength) {
        qDebug()<<"Error in FilterData: Number of mirroring/zeropadding size plus data size is bigger then fft length!";
        return data;
    }

    //Do zero padding or mirroring depending on user input
    RowVectorXd t_dataZeroPad = RowVectorXd::Zero(m_iFFTlength);

    switch(compensateEdgeEffects) {
        case MirrorData:
            t_dataZeroPad.head(m_dCoeffA.cols()) = data.head(m_dCoeffA.cols()).reverse();   //front
            t_dataZeroPad.segment(m_dCoeffA.cols(), data.cols()) = data;                    //middle
            t_dataZeroPad.tail(m_dCoeffA.cols()) = data.tail(m_dCoeffA.cols()).reverse();   //back
            break;

        case ZeroPad:
            t_dataZeroPad.head(data.cols()) = data;
            break;

        default:
            t_dataZeroPad.head(data.cols()) = data;
            break;
    }

    //generate fft object
    Eigen::FFT<double> fft;
    fft.SetFlag(fft.HalfSpectrum);

    //fft-transform data sequence
    RowVectorXcd t_freqData;
    fft.fwd(t_freqData,t_dataZeroPad);

    //perform frequency-domain filtering
    RowVectorXcd t_filteredFreq = m_dFFTCoeffA.array()*t_freqData.array();

    //inverse-FFT
    RowVectorXd t_filteredTime;
    fft.inv(t_filteredTime,t_filteredFreq);

    //Return filtered data
    if(!keepOverhead)
        return t_filteredTime.segment(m_dCoeffA.cols()/2, data.cols());

    return t_filteredTime.head(data.cols()+m_dCoeffA.cols());
}
Exemplo n.º 4
0
Vector<Pointf> DataSource::FFT(Getdatafun getdata, double tSample, bool frequency, int type, bool window) {
	int numData = int(GetCount());
    VectorXd timebuf(numData);
    int num = 0;
    for (int i = 0; i < numData; ++i) {
        double data = Membercall(getdata)(i);
        if (!IsNull(data)) {
			timebuf[i] = Membercall(getdata)(i);
			num++;
        }
    }
    Vector<Pointf> res;	
    if (num < 3)
        return res;
    timebuf.resize(num);
    
    double windowSum = 0;
    if (window) {
	    for (int i = 0; i < numData; ++i) {
	        double windowDat = 0.54 - 0.46*cos(2*M_PI*i/numData);
	        windowSum += windowDat;
	    	timebuf[i] *= windowDat;	// Hamming window
	    }
	} else
		windowSum = numData;
	
    VectorXcd freqbuf;
    try {
	    Eigen::FFT<double> fft;
	    fft.SetFlag(fft.HalfSpectrum);
	    fft.fwd(freqbuf, timebuf);
    } catch(...) {
        return res;
    }
    if (frequency) {
    	for (int i = 0; i < int(freqbuf.size()); ++i) {    
    		double xdata = i/(tSample*numData);
		
			switch (type) {
			case T_PHASE:	res << Pointf(xdata, std::arg(freqbuf[i]));				break;
			case T_FFT:		res << Pointf(xdata, 2*std::abs(freqbuf[i])/windowSum);	break;
			case T_PSD:		res << Pointf(xdata, 2*sqr(std::abs(freqbuf[i]))/(windowSum/tSample));
			}
    	}
    } else {
        for (int i = int(freqbuf.size()) - 1; i > 0; --i) {    
    		double xdata = (tSample*numData)/i;
		
			switch (type) {
			case T_PHASE:	res << Pointf(xdata, std::arg(freqbuf[i]));				break;
			case T_FFT:		res << Pointf(xdata, 2*std::abs(freqbuf[i])/windowSum);	break;
			case T_PSD:		res << Pointf(xdata, 2*sqr(std::abs(freqbuf[i]))/(windowSum/tSample));
			}
    	}
    }
    return res;
}
Exemplo n.º 5
0
void FilterData::fftTransformCoeffs()
{
    #ifdef EIGEN_FFTW_DEFAULT
        fftw_make_planner_thread_safe();
    #endif

    //zero-pad m_dCoeffA to m_iFFTlength
    RowVectorXd t_coeffAzeroPad = RowVectorXd::Zero(m_iFFTlength);
    t_coeffAzeroPad.head(m_dCoeffA.cols()) = m_dCoeffA;

    //generate fft object
    Eigen::FFT<double> fft;
    fft.SetFlag(fft.HalfSpectrum);

    //fft-transform filter coeffs
    m_dFFTCoeffA = RowVectorXcd::Zero(m_iFFTlength);
    fft.fwd(m_dFFTCoeffA,t_coeffAzeroPad);
}
Exemplo n.º 6
0
QList<QList<GaborAtom> > AdaptiveMp::matching_pursuit(MatrixXd signal, qint32 max_iterations, qreal epsilon, bool fix_phase = false, qint32 boost = 0,
                                                      qint32 simplex_it = 1E3, qreal simplex_reflection = 1.0, qreal simplex_expansion = 0.2 ,
                                                      qreal simplex_contraction = 0.5, qreal simplex_full_contraction = 0.5, bool trial_separation = false)
{
    //stop_running = false;
    std::cout << "\nAdaptive Matching Pursuit Algorithm started...\n";

    max_it = max_iterations;
    Eigen::FFT<double> fft;
    MatrixXd residuum = signal; //residuum initialised with signal
    qint32 sample_count = signal.rows();
    qint32 channel_count = signal.cols();

    signal_energy = 0;
    qreal residuum_energy = 0;
    qreal energy_threshold = 0;

    //calculate signal_energy
    for(qint32 channel = 0; channel < channel_count; channel++)
    {
        for(qint32 sample = 0; sample < sample_count; sample++)
            signal_energy += (signal(sample, channel) * signal(sample, channel));

        energy_threshold = 0.01 * epsilon * signal_energy;
        residuum_energy = signal_energy;
    }
    std::cout << "absolute energy of signal: " << residuum_energy << "\n";

    while(it < max_iterations && (energy_threshold < residuum_energy) && sample_count > 1)
    {
        channel_count = channel_count * (boost / 100.0); //reducing the number of observed channels in the algorithm to increase speed performance
        if(boost == 0 || channel_count == 0)
            channel_count = 1;

        //variables for dyadic sampling
        qreal s = 1;                             //scale
        qint32 j = 1;
        VectorXd max_scalar_product = VectorXd::Zero(channel_count);            //inner product for choosing the best matching atom
        qreal k = 0;                             //for modulation 2*pi*k/N
        qint32 p = floor(sample_count / 2);      //translation
        GaborAtom *gabor_Atom = new GaborAtom();
        gabor_Atom->sample_count = sample_count;
        gabor_Atom->energy = 0;
        qreal phase = 0;

        while(s < sample_count)
        {
            k = 0;                               //for modulation 2*pi*k/N
            p = floor(sample_count / 2);         //translation
            VectorXd envelope = GaborAtom::gauss_function(sample_count, s, p);
            VectorXcd fft_envelope = RowVectorXcd::Zero(sample_count);
            fft.fwd(fft_envelope, envelope);

            while(k < sample_count/2)
            {
                p = floor(sample_count/2);
                VectorXcd modulation = modulation_function(sample_count, k);
                VectorXcd modulated_resid = VectorXcd::Zero(sample_count);
                VectorXcd fft_modulated_resid = VectorXcd::Zero(sample_count);
                VectorXcd fft_m_e_resid = VectorXcd::Zero(sample_count);
                VectorXd corr_coeffs = VectorXd::Zero(sample_count);

                //iteration for multichannel, depending on boost setting
                for(qint32 chn = 0; chn < channel_count; chn++)
                {
                    qint32 max_index = 0;
                    qreal maximum = 0;
                    phase = 0;
                    p = floor(sample_count/2);//here is difference to dr. gratkowski´s code (he didn´t reset parameter p)

                    //complex correlation of signal and sinus-modulated gaussfunction
                    for(qint32 l = 0; l< sample_count; l++)
                        modulated_resid[l] = residuum(l, chn) * modulation[l];

                    fft.fwd(fft_modulated_resid, modulated_resid);

                    for( qint32 m = 0; m < sample_count; m++)
                        fft_m_e_resid[m] = fft_modulated_resid[m] * conj(fft_envelope[m]);

                    fft.inv(corr_coeffs, fft_m_e_resid);
                    maximum = corr_coeffs[0];

                    //find index of maximum correlation-coefficient to use in translation
                    for(qint32 i = 1; i < corr_coeffs.rows(); i++)
                        if(maximum < corr_coeffs[i])
                        {
                            maximum = corr_coeffs[i];
                            max_index = i;
                        }

                    //adapting translation p to create atomtranslation correctly
                    if(max_index >= p) p = max_index - p + 1;
                    else p = max_index + p;

                    VectorXd atom_parameters = calculate_atom(sample_count, s, p, k, chn, residuum, RETURNPARAMETERS, fix_phase);
                    qreal temp_scalar_product = 0;
                    if(trial_separation) temp_scalar_product = max_scalar_product[chn];
                    else temp_scalar_product = max_scalar_product[0];

                    if(abs(atom_parameters[4]) >= abs(temp_scalar_product))
                    {
                        //set highest scalarproduct, in comparison to best matching atom
                        gabor_Atom->scale              = atom_parameters[0];
                        gabor_Atom->translation        = atom_parameters[1];
                        gabor_Atom->modulation         = atom_parameters[2];
                        gabor_Atom->phase              = atom_parameters[3];
                        gabor_Atom->max_scalar_product = atom_parameters[4];
                        gabor_Atom->bm_channel         = chn;

                        if(trial_separation)
                        {
                            max_scalar_product[chn]    = atom_parameters[4];

                            if(atoms_in_chns.length() < channel_count)
                                atoms_in_chns.append(*gabor_Atom);
                            else
                                atoms_in_chns.replace(chn, *gabor_Atom);
                        }
                        else
                            max_scalar_product[0]      = atom_parameters[4];

                    }

                }
                k += pow(2.0,(-j))*sample_count/2;

            }
            j++;
            s = pow(2.0,j);
        }
        std::cout << "\n" << "===============" << " found parameters " << it + 1 << "===============" << ":\n\n"<<
                     "scale: " << gabor_Atom->scale << " trans: " << gabor_Atom->translation <<
                     " modu: " << gabor_Atom->modulation << " phase: " << gabor_Atom->phase << " sclr_prdct: " << gabor_Atom->max_scalar_product << "\n";

        //replace atoms with s==N and p = floor(N/2) by such atoms that do not have an envelope
        k = 0;
        s = sample_count;
        p = floor(sample_count / 2);
        j = floor(log10(sample_count)/log10(2));//log(sample_count) / log(2));
        phase = 0;

        //iteration for multichannel, depending on boost setting
        for(qint32 chn = 0; chn < channel_count; chn++)
        {
            k = 0;

            while(k < sample_count / 2)
            {
                VectorXd parameters_no_envelope = calculate_atom(sample_count, s, p, k, chn, residuum, RETURNPARAMETERS, fix_phase);

                qreal temp_scalar_product = 0;
                if(trial_separation) temp_scalar_product = max_scalar_product[chn];
                else temp_scalar_product = max_scalar_product[0];
                if(abs(parameters_no_envelope[4]) > abs(temp_scalar_product))
                {
                    //set highest scalarproduct, in comparison to best matching atom

                    gabor_Atom->scale              = parameters_no_envelope[0];
                    gabor_Atom->translation        = parameters_no_envelope[1];
                    gabor_Atom->modulation         = parameters_no_envelope[2];
                    gabor_Atom->phase              = parameters_no_envelope[3];
                    gabor_Atom->max_scalar_product = parameters_no_envelope[4];
                    gabor_Atom->bm_channel         = chn;

                    if(trial_separation)
                    {
                        max_scalar_product[chn]    = parameters_no_envelope[4];
                        atoms_in_chns.replace(chn, *gabor_Atom);
                    }
                    else
                        max_scalar_product[0]      = parameters_no_envelope[4];

                }
                k += pow(2.0,(-j))*sample_count/2;

            }

        }
        std::cout << "      after comparison to NoEnvelope " << ":\n"<< "scale: " << gabor_Atom->scale << " trans: " << gabor_Atom->translation <<
                     " modu: " << gabor_Atom->modulation << " phase: " << gabor_Atom->phase << " sclr_prdct: " << gabor_Atom->max_scalar_product << "\n\n";

        //simplexfunction to find minimum of target among parameters s, p, k

        if(trial_separation && simplex_it != 0)
        {
            for(qint32 chn = 0; chn < atoms_in_chns.length(); chn++)
            {
                *gabor_Atom = atoms_in_chns.at(chn);
                simplex_maximisation(simplex_it, simplex_reflection, simplex_expansion, simplex_contraction, simplex_full_contraction,
                                     gabor_Atom, max_scalar_product, sample_count, fix_phase, residuum, trial_separation, chn);

            }
        }
        else if(simplex_it != 0)
            simplex_maximisation(simplex_it, simplex_reflection, simplex_expansion, simplex_contraction, simplex_full_contraction,
                                 gabor_Atom, max_scalar_product, sample_count, fix_phase, residuum, trial_separation, gabor_Atom->bm_channel);

        //calc multichannel parameters phase and max_scalar_product
        channel_count = signal.cols();
        VectorXd best_match = VectorXd::Zero(sample_count);


        for(qint32 chn = 0; chn < channel_count; chn++)
        {

            if(trial_separation)
            {
                *gabor_Atom = atoms_in_chns.at(chn);
                gabor_Atom->energy = 0;
                best_match = gabor_Atom->create_real(gabor_Atom->sample_count, gabor_Atom->scale, gabor_Atom->translation,
                                                     gabor_Atom->modulation, gabor_Atom->phase);
            }
            else
            {
                VectorXd channel_params = calculate_atom(sample_count, gabor_Atom->scale, gabor_Atom->translation,
                                                         gabor_Atom->modulation, chn, residuum, RETURNPARAMETERS, fix_phase);
                gabor_Atom->phase_list.append(channel_params[3]);

                gabor_Atom->max_scalar_list.append(channel_params[4]);

                best_match = gabor_Atom->create_real(gabor_Atom->sample_count, gabor_Atom->scale, gabor_Atom->translation,
                                                     gabor_Atom->modulation, gabor_Atom->phase_list.at(chn));
            }

            //substract best matching Atom from Residuum in each channel
            for(qint32 j = 0; j < gabor_Atom->sample_count; j++)
            {
                if(!trial_separation)
                {
                    residuum(j,chn) -= gabor_Atom->max_scalar_list.at(chn) * best_match[j];
                    gabor_Atom->energy += pow(gabor_Atom->max_scalar_list.at(chn) * best_match[j], 2);
                }
                else
                {
                    residuum(j,chn) -= gabor_Atom->max_scalar_product * best_match[j];
                    gabor_Atom->energy += pow(gabor_Atom->max_scalar_product * best_match[j], 2);
                }
            }
            if(trial_separation)
            {
                atoms_in_chns.replace(chn, *gabor_Atom);            // change energy
                residuum_energy -= atoms_in_chns.at(chn).energy;// / channel_count;;
                current_energy  += atoms_in_chns.at(chn).energy;// / channel_count;;
            }
        }

        if(!trial_separation)
        {
            residuum_energy -= gabor_Atom->energy;
            current_energy  += gabor_Atom->energy;
        }
        else
            /*for(qint32 i = 0; i < atoms_in_chns.length(); i++)
            {
                residuum_energy -= atoms_in_chns.at(i).energy / channel_count;
                current_energy  += atoms_in_chns.at(i).energy / channel_count;
            }*/

        std::cout << "absolute energy of residue: " << residuum_energy << "\n";

        if(!trial_separation)
            atoms_in_chns.append(*gabor_Atom);

        atom_list.append(atoms_in_chns);

        atoms_in_chns.clear();
        delete gabor_Atom;
        it++;

        emit current_result(it, max_it, current_energy, signal_energy, residuum, atom_list, fix_dict_list);

        if( QThread::currentThread()->isInterruptionRequested())
        {
            send_warning(10);
            break;
        }

    }//end iterations
    std::cout << "\nAdaptive Matching Pursuit Algorithm finished.\n";
    emit finished_calc();
    return atom_list;
}
Exemplo n.º 7
0
// calc scalarproduct of Atom and Signal
FixDictAtom FixDictMp::correlation(Dictionary current_pdict, MatrixXd current_resid, qint32 boost)
{
    qint32 channel_count = current_resid.cols() * (boost / 100.0); //reducing the number of observed channels in the algorithm to increase speed performance
    if(boost == 0 || channel_count == 0)
        channel_count = 1;

    Eigen::FFT<double> fft;
    std::ptrdiff_t max_index;
    VectorXcd fft_atom = VectorXcd::Zero(current_resid.rows());

    FixDictAtom best_matching;
    qreal max_scalar_product = 0;

    for(qint32 i = 0; i < current_pdict.atoms.length(); i++)
    {
        VectorXd fitted_atom = VectorXd::Zero(current_resid.rows());
        qint32 p = floor(current_resid.rows() / 2);//translation

        VectorXd resized_atom = VectorXd::Zero(current_resid.rows());

        if(current_pdict.atoms.at(i).atom_samples.rows() > current_resid.rows())
            for(qint32 k = 0; k < current_resid.rows(); k++)
                resized_atom[k] = current_pdict.atoms.at(i).atom_samples[k + floor(current_pdict.atoms.at(i).atom_samples.rows() / 2) - floor(current_resid.rows() / 2)];
        else resized_atom = current_pdict.atoms.at(i).atom_samples;

        if(resized_atom.rows() < current_resid.rows())
            for(qint32 k = 0; k < resized_atom.rows(); k++)
                fitted_atom[(k + p - floor(resized_atom.rows() / 2))] = resized_atom[k];
        else fitted_atom = resized_atom;

        //normalization
        qreal norm = 0;
        norm = fitted_atom.norm();
        if(norm != 0) fitted_atom /= norm;

        fft.fwd(fft_atom, fitted_atom);

        for(qint32 chn = 0; chn < channel_count; chn++)
        {
            p = floor(current_resid.rows() / 2);//translation
            VectorXd corr_coeffs = VectorXd::Zero(current_resid.rows());
            VectorXcd fft_signal = VectorXcd::Zero(current_resid.rows());
            VectorXcd fft_sig_atom = VectorXcd::Zero(current_resid.rows());

            fft.fwd(fft_signal, current_resid.col(chn));

            for( qint32 m = 0; m < current_resid.rows(); m++)
                fft_sig_atom[m] = fft_signal[m] * conj(fft_atom[m]);

            fft.inv(corr_coeffs, fft_sig_atom);

            //find index of maximum correlation-coefficient to use in translation
            max_scalar_product = corr_coeffs.maxCoeff(&max_index);

            if(i == 0)
            {
                best_matching = current_pdict.atoms.at(i);
                best_matching.max_scalar_product = max_scalar_product;

                //adapting translation p to create atomtranslation correctly
                if(max_index >= p && current_resid.rows() % (2) == 0) p = max_index - p;
                else if(max_index >= p && current_resid.rows() % (2) != 0) p = max_index - p - 1;
                else p = max_index + p;

                best_matching.translation = p;
            }

            else if(abs(max_scalar_product) > abs(best_matching.max_scalar_product))
            {
                best_matching = current_pdict.atoms.at(i);
                best_matching.max_scalar_product = max_scalar_product;

                //adapting translation p to create atomtranslation correctly
                if(max_index >= p && current_resid.rows() % (2) == 0) p = max_index - p;
                else if(max_index >= p && current_resid.rows() % (2) != 0) p = max_index - p - 1;
                else p = max_index + p;

                best_matching.translation = p;
            }
        }
    }
    best_matching.atom_formula = current_pdict.atom_formula;
    best_matching.dict_source = current_pdict.source;
    best_matching.type = current_pdict.type;
    best_matching.sample_count = current_pdict.sample_count;

    return best_matching;
}