예제 #1
0
        // calculate the power spectrum of the incoming signal stored in data field by estimating linear model and applying the lookupTable on the model
        public double[] estimatePowerSpectrum()
        {
            // init power spectrum
            double[] powerSpectrum = new double[numBins];

            // if filter is constructed properly and data filed is filled with suitable data
            if (allowRun && data != null && linModel != null)
            {
                // init variables
                int counter = 0;                                            // counter to fill powerspectrum array

                // multiply power by a factor of sqrt(2) to account for positive and negative frequencies.
                linModel = linModel * Math.Sqrt(2.0);

                // perform power spectrum estimation: cycle through bins, per bin calculate for each sample, ie frequencyresolution. (in BCI2000 this was transferspectrum.evaluate function, based loosely on function evlmem in Press et al.)
                for (int bin = 0; bin < numBins; ++bin)
                {
                    // init
                    powerSpectrum[bin] = 0.0;
                    int evalInBin = (int)bins[bin, 2];

                    // cycle through samples per bin
                    for (int eval = 0; eval < evalInBin; eval++)
                    {
                        // get power estimate for given frequency in lookupTable and store in power spectrum output array
                        Complex valueComplex = linModel.evaluate(lookupTable[counter]);
                        powerSpectrum[bin] += ((valueComplex.Real * valueComplex.Real) + (valueComplex.Imaginary * valueComplex.Imaginary));         // it's actually the squared magnitude rather than a norm
                        counter++;
                    }

                    // normalize spectral power to frequency resolution
                    powerSpectrum[bin] /= evalInBin;

                    // divide by two and take square root to get amplitudes
                    powerSpectrum[bin] = Math.Sqrt(powerSpectrum[bin] / 2);
                }

                // output power spectrum estimation
                //logger.Debug("Power spectrum estimation of data:");
                //logger.Debug("Frequency bin \t Power");
                //for (int i = 0; i < numBins; i++) {
                //    double startBin = (firstBinCenter + (binWidth * i)) - (binWidth / 2);
                //    double endBin = (firstBinCenter + (binWidth * i)) + (binWidth / 2);
                //    logger.Debug("{0} - {1} Hz \t {2}", startBin, endBin, powerSpectrum[i]);
                //}
            }
            else
            {
                logger.Error("ARFilter is not constructed properly or input data is not suitable. Power spectrum can not be determined. See log files for more information.");
            }

            // return powerspectrum
            return(powerSpectrum);
        }
예제 #2
0
        // create linear prediction model based on input signal (in 'Numerical Recipes'and in BCI2000 this function was called memCof)
        // NB. this alters the data contained in filter
        public void createLinPredModel()
        {
            if (allowRun && data != null)
            {
                // init variables
                const double eps   = Double.Epsilon;                        // minimal value that can be expressed in double type, used to check if value is close to zero
                double[]     wkm   = new double[modelOrder + 1];            //
                double[]     coeff = new double[modelOrder + 1];            // holds coefficients of to be created linear prediction model
                coeff[0] = 1.0;                                             // first coefficient of model is always 1

                int      N    = data.Length;                                // length of input signal
                double[] mWk1 = new double[N];                              //
                double[] mWk2 = new double[N];                              //
                Array.Copy(data, mWk1, N);                                  // copy one array instead of assigning to prevent both variables pointing to same memory location (arrays are reference types)
                mWk2 = data;

                double meanPower = 0;                                       // mean power of signal
                double q         = 1.0;                                     //


                // calculate mean power of input signal
                for (int t = 0; t < N; t++)
                {
                    meanPower += (mWk1[t] * mWk1[t]);
                }

                // initialize numerator and denominator
                double num = 0.0;
                double den = meanPower * 2;

                // normalize mean power
                meanPower /= N;

                // calculate coefficients
                for (int k = 1; k <= modelOrder; ++k)
                {
                    // reset numerator
                    num = 0;

                    // calculate numerator and denominator
                    for (int t = 0; t < N - k; t++)
                    {
                        num += mWk1[t + 1] * mWk2[t];
                    }
                    den = den * q - mWk1[0] * mWk1[0] - mWk2[N - k] * mWk2[N - k];

                    // if denominator is close to zero (ie smaller than epsilon), set num and den to .5 and 1 respectively
                    if (den < eps)
                    {
                        num = 0.5;
                        den = 1.0;
                    }
                    else
                    {
                        if (coeff[k] >= 1 || coeff[k] <= -1)
                        {
                            den = 0;
                            for (int t = 0; t < N - k; t++)
                            {
                                den += mWk1[t + 1] * mWk1[t + 1] + mWk2[t] * mWk2[t];
                            }
                        }
                    }

                    // set coefficient based on numerator and denominator
                    coeff[k] = 2 * num / den;

                    // update all coefficients
                    q          = 1.0 - coeff[k] * coeff[k];
                    meanPower *= q;
                    for (int i = 1; i < k; ++i)
                    {
                        coeff[i] = wkm[i] - coeff[k] * wkm[k - i];
                    }

                    // update wkm and mWk arrays
                    if (k < modelOrder)
                    {
                        for (int i = 1; i <= k; ++i)
                        {
                            wkm[i] = coeff[i];
                        }
                        for (int j = 0; j < N - k; ++j)
                        {
                            mWk1[j] = mWk1[j + 1] - wkm[k] * mWk2[j];
                            mWk2[j] = mWk2[j] - wkm[k] * mWk1[j + 1];
                        }
                    }
                }

                // if mean power is below zero, set to zero (power can not be negative)
                if (meanPower < 0.0)
                {
                    meanPower = 0.0;
                }

                // update coefficients
                for (int k = 1; k <= modelOrder; k++)
                {
                    coeff[k] *= -1;
                }

                // output linearmodel
                linModel = new RationalPolynomial(new Polynomial(Math.Sqrt(meanPower)), new Polynomial(coeff));
            }
            else
            {
                logger.Error("ARFilter is not constructed properly or input data is not suitable. Linear model can not be determined. See log files for more information.");
            }
        }