Пример #1
0
        public PairDouble evaluateResonanceFrequency(ChartTypes type, SignalUnits targetUnits, double approximationResonanceFrequency = 0.0)
        {
            int kNumSteps = 4096;
            // Only acceleration data is used to estimate the resonance frequency
            SignalUnits baseUnits = SignalUnits.UNKNOWN;

            if (data[SignalUnits.METERS_PER_SECOND2] != null)
            {
                baseUnits = SignalUnits.METERS_PER_SECOND2;
            }
            else if (data.ContainsKey(SignalUnits.METERS_PER_SECOND2_PER_FORCE) && data[SignalUnits.METERS_PER_SECOND2_PER_FORCE] != null)
            {
                baseUnits = SignalUnits.METERS_PER_SECOND2_PER_FORCE;
            }
            if (baseUnits == SignalUnits.UNKNOWN)
            {
                return(null);
            }
            double[,] complexData = data[baseUnits];
            int nData = frequency.Length;

            double[] realPart = new double[nData];
            double[] imagPart = new double[nData];
            for (int i = 0; i != nData; ++i)
            {
                realPart[i] = complexData[i, 0];
                imagPart[i] = complexData[i, 1];
            }
            LinearSpline          splineRealPart = LinearSpline.InterpolateSorted(frequency, realPart);
            LinearSpline          splineImagPart = LinearSpline.InterpolateSorted(frequency, imagPart);
            List <double>         resFrequencies = null;
            Func <double, double> fun            = null;
            Func <double, double> diffFun        = null;

            switch (type)
            {
            case ChartTypes.REAL_FREQUENCY:
                fun     = x => splineRealPart.Interpolate(x);
                diffFun = x => splineRealPart.Differentiate(x);
                break;

            case ChartTypes.IMAG_FREQUENCY:
                fun     = x => splineImagPart.Differentiate(x);
                diffFun = x => splineImagPart.Differentiate2(x);
                break;
            }
            if (fun == null || diffFun == null)
            {
                return(null);
            }
            double startFrequency = frequency[0];
            double endFrequency   = frequency[nData - 1];

            resFrequencies = findAllRootsBisection(fun, startFrequency, endFrequency, kNumSteps);
            if (resFrequencies == null || resFrequencies.Count == 0)
            {
                return(null);
            }
            double distance;
            double minDistance         = Double.MaxValue;
            int    indClosestResonance = 0;
            int    numFrequencies      = resFrequencies.Count;

            for (int i = 0; i != numFrequencies; ++i)
            {
                try
                {
                    resFrequencies[i] = NewtonRaphson.FindRootNearGuess(fun, diffFun, resFrequencies[i], startFrequency, endFrequency);
                }
                catch
                {
                }
                distance = Math.Abs(resFrequencies[i] - approximationResonanceFrequency);
                if (distance < minDistance)
                {
                    minDistance         = distance;
                    indClosestResonance = i;
                }
            }
            double resonanceFrequency = resFrequencies[indClosestResonance];

            // Evaluate the amplitude value by using data of the target type
            if (baseUnits != targetUnits)
            {
                complexData = data[targetUnits];
                for (int i = 0; i != nData; ++i)
                {
                    realPart[i] = complexData[i, 0];
                    imagPart[i] = complexData[i, 1];
                }
                splineRealPart = LinearSpline.InterpolateSorted(frequency, realPart);
                splineImagPart = LinearSpline.InterpolateSorted(frequency, imagPart);
            }
            double realPeak = splineRealPart.Interpolate(resonanceFrequency);
            double imagPeak = splineImagPart.Interpolate(resonanceFrequency);
            double ampPeak  = Math.Sqrt(Math.Pow(realPeak, 2.0) + Math.Pow(imagPeak, 2.0));

            return(new PairDouble(resonanceFrequency, ampPeak));
        }