Пример #1
0
        /// <summary>
        /// 获取线性调频信号中的 IQ数据
        /// </summary>
        /// <param name="isIdata"></param>
        /// <returns></returns>
        private double[] LFMSingnal(bool isIdata = true)
        {
            double T  = 10 * 1e-6; // 0.00001;
            double B  = 1 * 1e6;   // 1000000;
            double k  = B / T;     // 调频斜率
            double t  = 5 * 1e-6;  // 0.000005;% 空信号时长5us
            double fs = 4 * 1e9;   // 4000000000;

            // 生成200Msa线性调频信号 5us空 + 10us线性调频
            double fs1 = 200 * 1e6;
            int    n1  = (int)Math.Round(T * fs1); //采样点个数
            //double[] t1 = new double[n1];
            double tspan = T / n1;

            MathNet.Numerics.Complex32[] y1 = new MathNet.Numerics.Complex32[n1];
            for (int i = 0; i < n1; i++)
            {
                MathNet.Numerics.Complex32 tempComple = new MathNet.Numerics.Complex32(0, (float)(Math.PI * k * (i * tspan) * (i * tspan)));

                // double aa= tempComple* k;
                y1[i] = MathNet.Numerics.Complex32.Exp(tempComple);
            }



            double[] idata = y1.Select(a => (double)a.Real).ToArray();
            double[] qdata = y1.Select(a => (double)a.Imaginary).ToArray();

            // freqDomi("LFM_freq.csv",  idata, qdata, 200 * 1e6);
            double[] result = new double[1000 + n1];
            if (isIdata)
            {
                Array.Copy(idata, 0, result, 1000, n1);
                //result = idata;
            }
            else
            {
                Array.Copy(qdata, 0, result, 1000, n1);
                //result = qdata;
            }


            return(result);
            //y1 = exp(1j * pi * k * t1.^ 2);% LFM信号
            // MathNet.Numerics.Complex32.Exp()
        }
Пример #2
0
    /**
     * 广义互相关频域补零时延估计算法
     * @param zeroWaveData
     * 零应力波形
     * @param testWaveData
     * 测试应力波形
     * @param sampleTime
     * 采样间隔
     * @param interTimes
     * 插值倍数
     * @return TDETuple
     * [时延,互相关系数数组]
     * 时延,单位:s 拉应力时返回正数,压应力返回负数
     */
    public Tuple <double, double[]> GCC_FZPTDE(double[] zeroWaveData, double[] testWaveData, double sampleTime, int interTimes)
    {
        Tuple <double, double[]> TDETuple;
        double timeDelay = 9999.09;

        double[] abs_xCorr;
        if (zeroWaveData.Length != testWaveData.Length)
        {
            abs_xCorr = new double[128];
            TDETuple  = new Tuple <double, double[]>(timeDelay, abs_xCorr);
            return(TDETuple);
        }
        int realLength = zeroWaveData.Length;

        //将数据长度补零为2的幂
        int fftDataLen = 1 << ((int)(Math.Log(realLength - 1) / Math.Log(2)) + 1);

        double[] pad_zeroWaveData = new double[fftDataLen];     //zeropadding
        double[] pad_testWaveData = new double[fftDataLen];     //zeropadding
        Array.Copy(zeroWaveData, pad_zeroWaveData, realLength);
        Array.Copy(testWaveData, pad_testWaveData, realLength);

        //傅里叶变换
        MathNet.Numerics.Complex32[] zeroWaveFFTData = new MathNet.Numerics.Complex32[fftDataLen];
        MathNet.Numerics.Complex32[] testWaveFFTData = new MathNet.Numerics.Complex32[fftDataLen];
        for (int i = 0; i < fftDataLen; i++)      //转为复数
        {
            zeroWaveFFTData[i] = new MathNet.Numerics.Complex32((float)pad_zeroWaveData[i], 0);
            testWaveFFTData[i] = new MathNet.Numerics.Complex32((float)pad_testWaveData[i], 0);
        }
        Fourier.Forward(zeroWaveFFTData);    //傅里叶变换
        Fourier.Forward(testWaveFFTData);    //傅里叶变换

        //计算zeroWaveFFTData*(testWaveFFTData的共轭复数)
        MathNet.Numerics.Complex32[] xCorrFFT = new MathNet.Numerics.Complex32[fftDataLen * interTimes];
        MathNet.Numerics.Complex32   testWaveFFTDataConj;
        for (int i = 0; i < fftDataLen / 2; i++)   //正域赋值
        {
            testWaveFFTDataConj = MathNet.Numerics.Complex32.Conjugate(testWaveFFTData[i]);
            xCorrFFT[i]         = MathNet.Numerics.Complex32.Multiply(zeroWaveFFTData[i], testWaveFFTDataConj);
        }
        int n = 0;

        for (int i = fftDataLen / 2; i < fftDataLen; i++)    //负域赋值
        {
            n           = i + (fftDataLen * interTimes - fftDataLen);
            xCorrFFT[n] = MathNet.Numerics.Complex32.Multiply(zeroWaveFFTData[i], MathNet.Numerics.Complex32.Conjugate(testWaveFFTData[i]));
        }

        //逆傅里叶变换
        Fourier.Inverse(xCorrFFT);
        fftDataLen = fftDataLen * interTimes;
        abs_xCorr  = new double[fftDataLen];
        double scaling_factor = NormL2(zeroWaveData) * NormL2(testWaveData);     //归一化缩放因子为2范数积

        for (int i = 0; i < fftDataLen; i++)
        {
            abs_xCorr[i] = MathNet.Numerics.Complex32.Abs(xCorrFFT[i]);
            abs_xCorr[i] = abs_xCorr[i] * (Math.Sqrt((float)fftDataLen)) / scaling_factor;     //归一化
        }
        //查找abs_xCorr最大值对应位置
        int maxPos = MaxIndex(abs_xCorr);

        //计算时延 单位:s
        timeDelay = (fftDataLen - maxPos);
        if (timeDelay > (double)fftDataLen / 2)
        {
            timeDelay = -1 * maxPos;
        }
        timeDelay = timeDelay * sampleTime / interTimes;

        TDETuple = new Tuple <double, double[]>(timeDelay, abs_xCorr);
        return(TDETuple);
    }
Пример #3
0
    protected void UpdateSCI()
    {
        int nFFT = 32;

        while (maindisplaythread.IsAlive)
        {
            Thread.Sleep(3000);  // update rate (default 500ms)
            for (int i = 0; i < nirsdata.Count; i++)
            {
                try
                {
                    if (nirsdata[i].data[0].Count > nFFT + 15)
                    {
                        double   fs  = MainClass.devices[i].GetSampleRate();
                        double[] SCI = new double[realtimeEngine.mBLLmappings[i].distances.Length];

                        for (int ch = 0; ch < realtimeEngine.mBLLmappings[i].distances.Length; ch++)
                        {
                            MathNet.Numerics.Complex32[] w1 = new MathNet.Numerics.Complex32[nFFT];
                            MathNet.Numerics.Complex32[] w2 = new MathNet.Numerics.Complex32[nFFT];
                            int    ntps = nirsdata[i].data[realtimeEngine.mBLLmappings[i].measurementPairs[ch][0]].Count - 5;
                            double a    = 0;
                            double b    = 0;
                            int    cc   = 0;
                            for (int tpt = ntps - nFFT; tpt < ntps; tpt++)
                            {
                                w1[cc] = new MathNet.Numerics.Complex32((float)nirsdata[i].data[realtimeEngine.mBLLmappings[i].measurementPairs[ch][0]][tpt], 0f);
                                w2[cc] = new MathNet.Numerics.Complex32((float)nirsdata[i].data[realtimeEngine.mBLLmappings[i].measurementPairs[ch][1]][tpt], 0f);
                                a     += nirsdata[i].data[realtimeEngine.mBLLmappings[i].measurementPairs[ch][0]][tpt] * nirsdata[i].data[realtimeEngine.mBLLmappings[i].measurementPairs[ch][0]][tpt];
                                b     += nirsdata[i].data[realtimeEngine.mBLLmappings[i].measurementPairs[ch][1]][tpt] * nirsdata[i].data[realtimeEngine.mBLLmappings[i].measurementPairs[ch][1]][tpt];
                                cc++;
                            }
                            Fourier.Forward(w1);
                            Fourier.Forward(w2);
                            cc = 0;
                            for (double ii = -fs / 2; ii < fs / 2; ii += fs / nFFT)
                            {
                                if (Math.Abs(ii) < 0.5 | Math.Abs(ii) > 2)
                                {
                                    w1[cc] = new MathNet.Numerics.Complex32(0f, w1[cc].Imaginary);
                                    w2[cc] = new MathNet.Numerics.Complex32(0f, w2[cc].Imaginary);
                                }
                                w1[cc] = w1[cc] * w2[cc].Conjugate();
                            }
                            Fourier.Inverse(w1);
                            SCI[ch] = w1[(int)Math.Round((double)nFFT / 2)].Real / Math.Sqrt(a * b);
                        }

                        double[] avgDetVal = new double[nirsdata[i].probe.numDet];
                        int[]    cnt       = new int[nirsdata[i].probe.numDet];
                        for (int ch = 0; ch < nirsdata[i].probe.numDet; ch++)
                        {
                            cnt[ch]       = 0;
                            avgDetVal[ch] = 0;
                        }
                        for (int ch = 0; ch < nirsdata[i].probe.numChannels / nirsdata[i].probe.numWavelengths; ch++)
                        {
                            int dIDx = nirsdata[i].probe.ChannelMap[ch].detectorindex;
                            cnt[dIDx]++;
                            avgDetVal[dIDx] += SCI[ch];
                        }
                        for (int ch = 0; ch < MainClass.win._handles.detectors.Count; ch++)
                        {
                            Gdk.Color col;
                            if (SCI[ch] < .3)
                            {
                                col = new Gdk.Color(255, 0, 0);
                            }
                            else if (SCI[ch] < .6)
                            {
                                col = new Gdk.Color(255, 255, 0);
                            }
                            else
                            {
                                col = new Gdk.Color(0, 255, 0);
                            }

                            MainClass.win._handles.detectors[ch].led.Color = col;
                        }
                    }
                }
                catch {
                    Console.WriteLine("Updating SCI error");
                }
            }
        }
    }
Пример #4
0
 /// <summary>
 /// Converts the string representation of a complex number to a single-precision complex number equivalent.
 /// A return value indicates whether the conversion succeeded or failed.
 /// </summary>
 /// <param name="value">
 /// A string containing a complex number to convert.
 /// </param>
 /// <param name="result">
 /// The parsed value.
 /// </param>
 /// <returns>
 /// If the conversion succeeds, the result will contain a complex number equivalent to value.
 /// Otherwise the result will contain complex32.Zero.  This parameter is passed uninitialized.
 /// </returns>
 public static bool TryToComplex32(this string value, out Complex32 result)
 {
     return(Complex32.TryParse(value, out result));
 }
Пример #5
0
 /// <summary>
 /// Converts the string representation of a complex number to single-precision complex number equivalent.
 /// A return value indicates whether the conversion succeeded or failed.
 /// </summary>
 /// <param name="value">
 /// A string containing a complex number to convert.
 /// </param>
 /// <param name="formatProvider">
 /// An <see cref="IFormatProvider"/> that supplies culture-specific formatting information about value.
 /// </param>
 /// <param name="result">
 /// The parsed value.
 /// </param>
 /// <returns>
 /// If the conversion succeeds, the result will contain a complex number equivalent to value.
 /// Otherwise the result will contain Complex.Zero.  This parameter is passed uninitialized.
 /// </returns>
 public static bool TryToComplex32(this string value, IFormatProvider formatProvider, out Complex32 result)
 {
     return(Complex32.TryParse(value, formatProvider, out result));
 }
Пример #6
0
 /// <summary>
 /// Creates a <c>Complex32</c> number based on a string. The string can be in the
 /// following formats (without the quotes): 'n', 'ni', 'n +/- ni',
 /// 'ni +/- n', 'n,n', 'n,ni,' '(n,n)', or '(n,ni)', where n is a double.
 /// </summary>
 /// <returns>
 /// A complex number containing the value specified by the given string.
 /// </returns>
 /// <param name="value">
 /// the string to parse.
 /// </param>
 public static Complex32 ToComplex32(this string value)
 {
     return(Complex32.Parse(value));
 }
Пример #7
0
 /// <summary>
 /// Creates a <c>Complex32</c> number based on a string. The string can be in the
 /// following formats (without the quotes): 'n', 'ni', 'n +/- ni',
 /// 'ni +/- n', 'n,n', 'n,ni,' '(n,n)', or '(n,ni)', where n is a double.
 /// </summary>
 /// <returns>
 /// A complex number containing the value specified by the given string.
 /// </returns>
 /// <param name="value">
 /// the string to parse.
 /// </param>
 /// <param name="formatProvider">
 /// An <see cref="IFormatProvider"/> that supplies culture-specific
 /// formatting information.
 /// </param>
 public static Complex32 ToComplex32(this string value, IFormatProvider formatProvider)
 {
     return(Complex32.Parse(value, formatProvider));
 }
Пример #8
0
 /// <summary>
 /// Returns a Norm of the difference of two values of this type, which is
 /// appropriate for measuring how close together these two values are.
 /// </summary>
 public static double NormOfDifference(this Complex32 complex, Complex32 otherValue)
 {
     return((complex - otherValue).MagnitudeSquared);
 }
Пример #9
0
 /// <summary>
 /// Gets the squared magnitude of the <c>Complex</c> number.
 /// </summary>
 /// <param name="complex">The <see cref="Complex32"/> number to perform this operation on.</param>
 /// <returns>The squared magnitude of the <c>Complex</c> number.</returns>
 public static double MagnitudeSquared(this Complex32 complex)
 {
     return((complex.Real * complex.Real) + (complex.Imaginary * complex.Imaginary));
 }
Пример #10
0
 /// <summary>
 /// Returns a Norm of a value of this type, which is appropriate for measuring how
 /// close this value is to zero.
 /// </summary>
 public static double Norm(this Complex32 complex)
 {
     return(complex.MagnitudeSquared);
 }
Пример #11
0
 /// <summary>
 /// Compares two doubles and determines if they are equal to within the specified number of decimal places or not. If the numbers
 /// are very close to zero an absolute difference is compared, otherwise the relative difference is compared.
 /// </summary>
 /// <param name="a">The first value.</param>
 /// <param name="b">The second value.</param>
 /// <param name="decimalPlaces">The number of decimal places.</param>
 public static bool AlmostEqualRelative(this Complex32 a, Complex32 b, int decimalPlaces)
 {
     return(AlmostEqualNormRelative(a.Norm(), b.Norm(), a.NormOfDifference(b), decimalPlaces));
 }
Пример #12
0
 /// <summary>
 /// Checks whether two Compex numbers are almost equal.
 /// </summary>
 /// <param name="a">The first number</param>
 /// <param name="b">The second number</param>
 /// <returns>true if the two values differ by no more than 10 * 2^(-52); false otherwise.</returns>
 public static bool AlmostEqualRelative(this Complex32 a, Complex32 b)
 {
     return(AlmostEqualNormRelative(a.Norm(), b.Norm(), a.NormOfDifference(b), DefaultSingleAccuracy));
 }
Пример #13
0
 /// <summary>
 /// Compares two complex and determines if they are equal within
 /// the specified maximum error.
 /// </summary>
 /// <param name="a">The first value.</param>
 /// <param name="b">The second value.</param>
 /// <param name="maximumError">The accuracy required for being almost equal.</param>
 public static bool AlmostEqualRelative(this Complex32 a, Complex32 b, double maximumError)
 {
     return(AlmostEqualNormRelative(a.Norm(), b.Norm(), a.NormOfDifference(b), maximumError));
 }
Пример #14
0
 /// <summary>
 /// Compares two complex and determines if they are equal within
 /// the specified maximum error.
 /// </summary>
 /// <param name="a">The first value.</param>
 /// <param name="b">The second value.</param>
 /// <param name="maximumAbsoluteError">The accuracy required for being almost equal.</param>
 public static bool AlmostEqual(this Complex32 a, Complex32 b, double maximumAbsoluteError)
 {
     return(AlmostEqualNorm(a.Norm(), b.Norm(), a.NormOfDifference(b), maximumAbsoluteError));
 }