コード例 #1
0
        /// <summary>
        /// This function computes the the multiplication of the transpose of the trajectory matrix H by an arbitrary vector v, i.e. H' * v.
        /// Since the trajectory matrix is a Hankel matrix, using the Discrete Fourier Transform,
        /// the multiplication is carried out in O(N.log(N)) instead of O(N^2), wheere N is the series length.
        /// For details, refer to Algorithm 3 in http://arxiv.org/pdf/0911.4498.pdf.
        /// </summary>
        /// <param name="vector">The input vector</param>
        /// <param name="result">The output vector allocated by the caller</param>
        /// <param name="add">Whether the multiplication result should be added to the current value in result</param>
        /// <param name="srcIndex">The starting index for the vector argument</param>
        /// <param name="dstIndex">The starting index for the result</param>
        private void FftMultiplyTranspose(Single[] vector, Single[] result, bool add = false, int srcIndex = 0, int dstIndex = 0)
        {
            _ectx.Assert(srcIndex >= 0);
            _ectx.Assert(dstIndex >= 0);
            _ectx.Assert(Utils.Size(vector) >= _windowSize + srcIndex);
            _ectx.Assert(Utils.Size(result) >= _k + dstIndex);

            int i;

            // Computing the FFT of the trajectory matrix
            if (!_isSeriesFftCached)
            {
                CacheInputSeriesFft();
            }

            // Computing the FFT of the input vector
            for (i = 0; i < _k - 1; ++i)
            {
                _inputRe[i] = 0;
            }

            for (i = _k - 1; i < _seriesLength; ++i)
            {
                _inputRe[i] = vector[_seriesLength - i - 1 + srcIndex];
            }

            FftUtils.ComputeForwardFft(_inputRe, _allZerosIm, _outputRe, _outputIm, _inputRe.Length);

            // Computing the element-by-element product in the Fourier space
            double re;
            double im;

            for (i = 0; i < _seriesLength; ++i)
            {
                re = _outputRe[i];
                im = _outputIm[i];

                _outputRe[i] = _cachedSeriesFftRe[i] * re - _cachedSeriesFftIm[i] * im;
                _outputIm[i] = _cachedSeriesFftRe[i] * im + _cachedSeriesFftIm[i] * re;
            }

            // Computing the inverse FFT of the result
            FftUtils.ComputeBackwardFft(_outputRe, _outputIm, _outputRe, _outputIm, _inputRe.Length);

            // Generating the output
            if (add)
            {
                for (i = 0; i < _k; ++i)
                {
                    result[i + dstIndex] += RoundUpToReal(_outputRe[_windowSize - 1 + i], _outputIm[_windowSize - 1 + i]);
                }
            }
            else
            {
                for (i = 0; i < _k; ++i)
                {
                    result[i + dstIndex] = RoundUpToReal(_outputRe[_windowSize - 1 + i], _outputIm[_windowSize - 1 + i]);
                }
            }
        }
                private protected override sealed void SpectralResidual(Single input, FixedSizeQueue <Single> data, ref VBufferEditor <double> result)
                {
                    // Step 1: Get backadd wave
                    List <Single> backAddList = BackAdd(data);

                    // Step 2: FFT transformation
                    int length = backAddList.Count;

                    float[] fftRe = new float[length];
                    float[] fftIm = new float[length];
                    FftUtils.ComputeForwardFft(backAddList.ToArray(), Enumerable.Repeat(0.0f, length).ToArray(), fftRe, fftIm, length);

                    // Step 3: Calculate mags of FFT
                    List <Single> magList = new List <Single>();

                    for (int i = 0; i < length; ++i)
                    {
                        magList.Add(MathUtils.Sqrt((fftRe[i] * fftRe[i] + fftIm[i] * fftIm[i])));
                    }

                    // Step 4: Calculate spectral
                    List <Single> magLogList      = magList.Select(x => x != 0 ? MathUtils.Log(x) : 0).ToList();
                    List <Single> filteredLogList = AverageFilter(magLogList, Parent.AvergingWindowSize);
                    List <Single> spectralList    = new List <Single>();

                    for (int i = 0; i < magLogList.Count; ++i)
                    {
                        spectralList.Add(MathUtils.ExpSlow(magLogList[i] - filteredLogList[i]));
                    }

                    // Step 5: IFFT transformation
                    float[] transRe = new float[length];
                    float[] transIm = new float[length];
                    for (int i = 0; i < length; ++i)
                    {
                        if (magLogList[i] != 0)
                        {
                            transRe[i] = fftRe[i] * spectralList[i] / magList[i];
                            transIm[i] = fftIm[i] * spectralList[i] / magList[i];
                        }
                        else
                        {
                            transRe[i] = 0;
                            transIm[i] = 0;
                        }
                    }

                    float[] ifftRe = new float[length];
                    float[] ifftIm = new float[length];
                    FftUtils.ComputeBackwardFft(transRe, transIm, ifftRe, ifftIm, length);

                    // Step 6: Calculate mag and ave_mag of IFFT
                    List <Single> ifftMagList = new List <Single>();

                    for (int i = 0; i < length; ++i)
                    {
                        ifftMagList.Add(MathUtils.Sqrt((ifftRe[i] * ifftRe[i] + ifftIm[i] * ifftIm[i])));
                    }
                    List <Single> filteredIfftMagList = AverageFilter(ifftMagList, Parent.JudgementWindowSize);

                    // Step 7: Calculate score and set result
                    var score = CalculateSocre(ifftMagList[data.Count - 1], filteredIfftMagList[data.Count - 1]);

                    score           /= 10.0f;
                    result.Values[1] = score;

                    score = Math.Min(score, 1);
                    score = Math.Max(score, 0);
                    var detres = score > Parent.AlertThreshold ? 1 : 0;

                    result.Values[0] = detres;

                    var mag = ifftMagList[data.Count - 1];

                    result.Values[2] = mag;
                }
コード例 #3
0
        /// <summary>
        /// This function computes the efficient Hankelization of the matrix sigma * u * v' using Fast Fourier Transform in in O((L + K) * log(L + K)).
        /// For details, refer to Algorithm 4 in http://arxiv.org/pdf/0911.4498.pdf.
        /// </summary>
        /// <param name="u">The u vector</param>
        /// <param name="v">The v vector</param>
        /// <param name="sigma">The scalar coefficient</param>
        /// <param name="result">The output series</param>
        /// <param name="add">Whether the hankelization result should be added to the current value in result</param>
        /// <param name="uIndex">The starting index for the u vector argument</param>
        /// <param name="vIndex">The starting index for the v vector argument</param>
        /// <param name="dstIndex">The starting index for the result</param>
        /// <param name="start">The staring index of the series to be reconstructed (by default zero)</param>
        /// <param name="end">The ending index of the series to be reconstructed (by default series length)</param>
        private void FftRankOneHankelization(Single[] u, Single[] v, Single sigma, Single[] result, bool add = false,
                                             int uIndex = 0, int vIndex = 0, int dstIndex = 0, int?start = null, int?end = null)
        {
            int s;
            int e;
            int us;
            int ue;
            int vs;
            int ve;
            int i;

            s = start ?? 0;
            e = end ?? _seriesLength - 1;

            ComputeBoundryIndices(s, e, out us, out ue, out vs, out ve);
            _ectx.Assert(0 <= ue && ue < _windowSize);
            _ectx.Assert(0 <= us && us <= ue);
            _ectx.Assert(0 <= ve && ve < _k);
            _ectx.Assert(0 <= vs && vs <= ve);

            var len = e - s + 1;

            _ectx.Assert(uIndex >= 0);
            _ectx.Assert(vIndex >= 0);
            _ectx.Assert(dstIndex >= 0);
            _ectx.Assert(Utils.Size(u) >= _windowSize + uIndex);
            _ectx.Assert(Utils.Size(v) >= _k + vIndex);
            _ectx.Assert(Utils.Size(result) >= len + dstIndex);
            _ectx.Assert(!Single.IsNaN(sigma));
            _ectx.Assert(!Single.IsInfinity(sigma));

            if (!_isSeriesFftCached)
            {
                CacheInputSeriesFft();
            }

            // Computing the FFT of u
            for (i = us; i <= ue; ++i)
            {
                _inputRe[i - us] = u[i + uIndex];
            }

            for (i = ue + 1; i < len + us; ++i)
            {
                _inputRe[i - us] = 0;
            }

            FftUtils.ComputeForwardFft(_inputRe, _allZerosIm, _outputRe, _outputIm, len);

            // Computing the FFT of v
            for (i = vs; i <= ve; ++i)
            {
                _inputRe[i - vs] = v[i + vIndex];
            }

            for (i = ve + 1; i < len + vs; ++i)
            {
                _inputRe[i - vs] = 0;
            }

            FftUtils.ComputeForwardFft(_inputRe, _allZerosIm, _inputRe, _allZerosIm, len);

            // Computing the element-by-element product in the Fourier space
            double re;
            double im;

            for (i = 0; i < len; ++i)
            {
                re = _outputRe[i];
                im = _outputIm[i];

                _outputRe[i] = _inputRe[i] * re - _allZerosIm[i] * im;
                _outputIm[i] = _inputRe[i] * im + _allZerosIm[i] * re;
            }

            // Setting _allZerosIm to 0's again
            for (i = 0; i < _seriesLength; ++i)
            {
                _allZerosIm[i] = 0;
            }

            // Computing the inverse FFT of the result
            FftUtils.ComputeBackwardFft(_outputRe, _outputIm, _outputRe, _outputIm, len);

            // Generating the output
            int a = Math.Min(ue - us + 1, ve - vs + 1);

            if (add)
            {
                for (i = 0; i < a; ++i)
                {
                    result[i + dstIndex] += RoundUpToReal(_outputRe[i], _outputIm[i], sigma / (i + 1));
                }

                for (i = a; i < len - a + 1; ++i)
                {
                    result[i + dstIndex] += RoundUpToReal(_outputRe[i], _outputIm[i], sigma / a);
                }

                for (i = len - a + 1; i < len; ++i)
                {
                    result[i + dstIndex] += RoundUpToReal(_outputRe[i], _outputIm[i], sigma / (len - i));
                }
            }
            else
            {
                for (i = 0; i < a; ++i)
                {
                    result[i + dstIndex] = RoundUpToReal(_outputRe[i], _outputIm[i], sigma / (i + 1));
                }

                for (i = a; i < len - a + 1; ++i)
                {
                    result[i + dstIndex] = RoundUpToReal(_outputRe[i], _outputIm[i], sigma / a);
                }

                for (i = len - a + 1; i < len; ++i)
                {
                    result[i + dstIndex] = RoundUpToReal(_outputRe[i], _outputIm[i], sigma / (len - i));
                }
            }
        }