예제 #1
0
    public static IEnumerable <Vector2> AkimaSpline(IEnumerable <Vector2> points, int count)
    {
        var points1 = new List <Vector2>(points);

        points1.Add(points1[1]);
        points1.Insert(0, points1[points1.Count - 3]);

        var    distances = new List <double>();
        double distance  = 0;

        for (int i = 0; i < points1.Count; i++)
        {
            if (i > 0)
            {
                distance += Distance(points1[i], points1[i - 1]);
            }
            distances.Add(distance);
        }

        var splineX = Interpolate.CubicSplineRobust(distances, points1.Select(v => (double)v.x));
        var splineY = Interpolate.CubicSplineRobust(distances, points1.Select(v => (double)v.y));

        // Distances without first and last points
        var dst = Enumerable.Range(0, count).Select(v => distances[1] + (distances[distances.Count - 2] - distances[1]) * v / (count - 1));

        return(dst.Select(v => new Vector2((float)splineX.Interpolate(v), (float)splineY.Interpolate(v))));
    }
        void ContinuumSearchRoutine(Edges edges)
        {
            MainWindow mainForm = this.Owner as MainWindow;

            int[] EdgesNumbers = new int[1024];
            int[] PeaksFlags   = new int[1024];
            int   NumberOfEdges;

            EdgesNumbers  = edges.EdgesNumbers;
            NumberOfEdges = edges.NumberOfEdges;
            PeaksFlags    = edges.PeaksFlags;

            double[] ContinuumX       = new double[1024];
            double[] ContinuumY       = new double[1024];
            double[] PeaksX           = new double[1024];
            double[] PeaksY           = new double[1024];
            int      ContinuumCounter = 0,
                     PeaksCounter     = 0;

            PeaksFlags[0] = -1;
            for (int counterI = 0; counterI < 1024; counterI++)
            {
                if (PeaksFlags[counterI] == -1)
                {
                    ContinuumX[ContinuumCounter] = counterI;
                    ContinuumY[ContinuumCounter] = SavitzkyGolaySmoothingBaseline[counterI];
                    ContinuumCounter++;
                }
                else
                {
                    PeaksX[PeaksCounter] = counterI;
                    PeaksY[PeaksCounter] = mainForm.WorkingSpectr.GammaSpectr[counterI];
                    PeaksCounter++;
                }
            }
            double[] cX = new double[ContinuumCounter];
            double[] cY = new double[ContinuumCounter];
            for (int i = 0; i < ContinuumCounter; i++)
            {
                cX[i] = ContinuumX[i];
                cY[i] = ContinuumY[i];
            }

            for (int counterI = 0; counterI < 1024; counterI++)
            {
                if (PeaksFlags[counterI] == 1)
                {
                    Baseline[counterI] = Interpolate.CubicSplineRobust(cX, cY).Interpolate(counterI);
                }
                else
                {
                    Baseline[counterI] = mainForm.WorkingSpectr.GammaSpectr[counterI];
                }
                mainForm.GammaSpectrChart.Series["baseline"].Points.Add(new SeriesPoint(counterI + 1, Baseline[counterI]));
            }
        }
예제 #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="WalkingTrail"/> class. For Internal Use ONLY!
        /// </summary>
        /// <param name="observedPoints">The observed locations.</param>
        /// <param name="velocityMagnitude">The velocity magnitude.</param>
        internal WalkingTrail(UV[] observedPoints, double velocityMagnitude)
        {
            this._length      = new double[observedPoints.Length];
            this._trailLength = 0;
            this._length[0]   = 0;
            for (int i = 0; i < observedPoints.Length - 1; i++)
            {
                double d = observedPoints[i].DistanceTo(observedPoints[i + 1]);
                this._length[i + 1] = this._length[i] + d;
            }
            this._trailLength = this._length[this._length.Length - 1];
            double[] observation_time = new double[this._length.Length];
            observation_time[0] = 0;
            for (int i = 0; i < observedPoints.Length - 1; i++)
            {
                double deltaT = observedPoints[i].DistanceTo(observedPoints[i + 1]) / velocityMagnitude;
                observation_time[i + 1] = observation_time[i] + deltaT;
            }

            this._trailInput      = TrailInput.Location;
            this._observationTime = observation_time;
            this._startTime       = _observationTime[0];
            this._endTime         = _observationTime[_observationTime.Length - 1];
            this._duration        = _observationTime[_observationTime.Length - 1] - _observationTime[0];
            this._timeToLength    = Interpolate.CubicSplineRobust(this._observationTime, this._length);
            this._lengthToTime    = Interpolate.CubicSplineRobust(this._length, this._observationTime);

            //create interpolations
            double[] location_U_values = new double[this._observationTime.Length];
            double[] location_V_values = new double[this._observationTime.Length];
            for (int i = 0; i < this._observationTime.Length; i++)
            {
                location_U_values[i] = observedPoints[i].U;
                location_V_values[i] = observedPoints[i].V;
            }
            this._interpolate_location_U = Interpolate.CubicSplineRobust(this._observationTime, location_U_values);
            this._ULinearInterpolation   = Interpolate.Linear(this._observationTime, location_U_values);

            this._interpolate_location_V = Interpolate.CubicSplineRobust(this._observationTime, location_V_values);
            this._VLinearInterpolation   = Interpolate.Linear(this._observationTime, location_V_values);


            this._observedStates = new StateBase[this._observationTime.Length];
            //this._controlPoints = new UV[this._time.Length];
            for (int i = 0; i < this._observedStates.Length; i++)
            {
                UV location  = observedPoints[i];
                UV velocity  = this.getVelocity(this._observationTime[i]);
                UV direction = this.getDirection(this._observationTime[i]);
                //this._controlPoints[i] = location;
                this._observedStates[i] = new StateBase(location, direction, velocity);
            }
            this.loadNormalizedStates();
            loadApproximatedPolyline();
        }
예제 #4
0
        //---------------------------------------------------------------------------------------------------------------------

        public static IInterpolation[] PolyInterpol(DateTime time0, SatOrbitStateVector[] orbitStateVectors)
        {
            var time = Array.ConvertAll <SatOrbitStateVector, double>(orbitStateVectors, o => o.Time.Subtract(time0).TotalSeconds);

            Vector <double> x1 = DenseVector.OfArray(Array.ConvertAll <SatOrbitStateVector, double>(orbitStateVectors, o => o.Position[0]));
            Vector <double> y1 = DenseVector.OfArray(Array.ConvertAll <SatOrbitStateVector, double>(orbitStateVectors, o => o.Position[1]));
            Vector <double> z1 = DenseVector.OfArray(Array.ConvertAll <SatOrbitStateVector, double>(orbitStateVectors, o => o.Position[2]));

            Vector <double> vx1 = DenseVector.OfArray(Array.ConvertAll <SatOrbitStateVector, double>(orbitStateVectors, o => o.Velocity[0]));
            Vector <double> vy1 = DenseVector.OfArray(Array.ConvertAll <SatOrbitStateVector, double>(orbitStateVectors, o => o.Velocity[1]));
            Vector <double> vz1 = DenseVector.OfArray(Array.ConvertAll <SatOrbitStateVector, double>(orbitStateVectors, o => o.Velocity[2]));

            Vector <double> ax1 = DenseVector.Create(vx1.Count, 0.0);
            Vector <double> ay1 = DenseVector.Create(vy1.Count, 0.0);
            Vector <double> az1 = DenseVector.Create(vz1.Count, 0.0);

            for (int i = 0; i < vx1.Count; i++)
            {
                ax1[i] = vx1[i] * i + 1;
                ay1[i] = vy1[i] * i + 1;
                az1[i] = vz1[i] * i + 1;
            }

            IInterpolation[] coeff = new IInterpolation[9];

            coeff[0] = Interpolate.CubicSplineRobust(time, x1.ToArray());
            coeff[1] = Interpolate.CubicSplineRobust(time, y1.ToArray());
            coeff[2] = Interpolate.CubicSplineRobust(time, z1.ToArray());
            coeff[3] = Interpolate.CubicSplineRobust(time, vx1.ToArray());
            coeff[4] = Interpolate.CubicSplineRobust(time, vy1.ToArray());
            coeff[5] = Interpolate.CubicSplineRobust(time, vz1.ToArray());
            coeff[6] = Interpolate.CubicSplineRobust(time, ax1.ToArray());
            coeff[7] = Interpolate.CubicSplineRobust(time, ay1.ToArray());
            coeff[8] = Interpolate.CubicSplineRobust(time, az1.ToArray());

            return(coeff);
        }
예제 #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="WalkingTrail"/> class.
        /// </summary>
        /// <param name="observation_time">The observation time.</param>
        /// <param name="observed_states">The observed states.</param>
        /// <param name="inputMode">The input mode.</param>
        /// <exception cref="ArgumentException">
        /// The size of observation time and observed states are not equal
        /// or
        /// The observation times are not in ascending order!
        /// or
        /// The observed states include null elements that cannot be used for generating a trail model
        /// or
        /// The observed states include null elements that cannot be used for generating a trail model
        /// or
        /// The observed states include null locations that cannot be used for generating a trail model
        /// </exception>
        public WalkingTrail(double[] observation_time, StateBase[] observed_states, TrailInput inputMode)
        {
            if (observation_time.Length != observed_states.Length)
            {
                throw new ArgumentException("The size of observation time and observed states are not equal");
            }
            for (int i = 0; i < observation_time.Length - 1; i++)
            {
                if (observation_time[i] >= observation_time[i + 1])
                {
                    throw new ArgumentException("The observation times are not in ascending order!");
                }
            }
            for (int i = 0; i < observed_states.Length; i++)
            {
                switch (inputMode)
                {
                case TrailInput.Location_Velocity_Direction:
                    if (observed_states[i].Velocity == null || observed_states[i].Direction == null || observed_states[i].Location == null)
                    {
                        throw new ArgumentException("The observed states include null elements that cannot be used for generating a trail model");
                    }
                    break;

                case TrailInput.Location_Direction:
                    if (observed_states[i].Direction == null || observed_states[i].Location == null)
                    {
                        throw new ArgumentException("The observed states include null elements that cannot be used for generating a trail model");
                    }
                    break;

                case TrailInput.Location:
                    if (observed_states[i].Location == null)
                    {
                        throw new ArgumentException("The observed states include null locations that cannot be used for generating a trail model");
                    }
                    break;
                }
            }

            this._trailInput      = inputMode;
            this._observationTime = observation_time;
            this._startTime       = _observationTime[0];
            this._endTime         = _observationTime[_observationTime.Length - 1];
            this._duration        = _observationTime[_observationTime.Length - 1] - _observationTime[0];

            this._length    = new double[observation_time.Length];
            this._length[0] = 0;
            for (int i = 0; i < observed_states.Length - 1; i++)
            {
                double d = observed_states[i].Location.DistanceTo(observed_states[i + 1].Location);
                this._length[i + 1] = this._length[i] + d;
            }
            this._trailLength  = this._length[this._length.Length - 1];
            this._timeToLength = Interpolate.CubicSplineRobust(this._observationTime, this._length);
            this._lengthToTime = Interpolate.CubicSplineRobust(this._length, this._observationTime);

            //create interpolations
            double[] location_U_values = new double[this._observationTime.Length];
            double[] location_V_values = new double[this._observationTime.Length];
            for (int i = 0; i < this._observationTime.Length; i++)
            {
                location_U_values[i] = observed_states[i].Location.U;
                location_V_values[i] = observed_states[i].Location.V;
            }
            this._interpolate_location_U = Interpolate.CubicSplineRobust(this._observationTime, location_U_values);
            this._ULinearInterpolation   = Interpolate.Linear(this._observationTime, location_U_values);

            this._interpolate_location_V = Interpolate.CubicSplineRobust(this._observationTime, location_V_values);
            this._VLinearInterpolation   = Interpolate.Linear(this._observationTime, location_V_values);

            double[] velocity_U_values;
            double[] velocity_V_values;

            double[] direction_U_values;
            double[] direction_V_values;

            switch (this._trailInput)
            {
            case TrailInput.Location_Velocity_Direction:
                velocity_U_values  = new double[this._observationTime.Length];
                velocity_V_values  = new double[this._observationTime.Length];
                direction_U_values = new double[this._observationTime.Length];
                direction_V_values = new double[this._observationTime.Length];
                for (int i = 0; i < this._observationTime.Length; i++)
                {
                    velocity_U_values[i] = observed_states[i].Velocity.U;
                    velocity_V_values[i] = observed_states[i].Velocity.V;
                    observed_states[i].Direction.Unitize();
                    direction_U_values[i] = observed_states[i].Direction.U;
                    direction_V_values[i] = observed_states[i].Direction.V;
                }
                this._interpolate_velocity_U  = Interpolate.CubicSplineRobust(this._observationTime, velocity_U_values);
                this._interpolate_velocity_V  = Interpolate.CubicSplineRobust(this._observationTime, velocity_V_values);
                this._interpolate_direction_U = Interpolate.CubicSplineRobust(this._observationTime, direction_U_values);
                this._interpolate_direction_V = Interpolate.CubicSplineRobust(this._observationTime, direction_V_values);
                break;

            case TrailInput.Location_Direction:
                direction_U_values = new double[this._observationTime.Length];
                direction_V_values = new double[this._observationTime.Length];
                for (int i = 0; i < this._observationTime.Length; i++)
                {
                    observed_states[i].Direction.Unitize();
                    direction_U_values[i] = observed_states[i].Direction.U;
                    direction_V_values[i] = observed_states[i].Direction.V;
                }
                this._interpolate_direction_U = Interpolate.CubicSplineRobust(this._observationTime, direction_U_values);
                this._interpolate_direction_V = Interpolate.CubicSplineRobust(this._observationTime, direction_V_values);
                break;

            case TrailInput.Location:
                //do nothing
                break;
            }
            this._observedStates = new StateBase[this._observationTime.Length];
            //this._controlPoints = new UV[this._time.Length];
            for (int i = 0; i < this._observedStates.Length; i++)
            {
                UV location = observed_states[i].Location;
                //this._controlPoints[i] = location;
                UV velocity = null;
                if (observed_states[i].Velocity == null)
                {
                    velocity = this.getVelocity(this._observationTime[i]);
                }
                else
                {
                    velocity = observed_states[i].Velocity;
                }
                UV direction = null;
                if (observed_states[i].Direction == null)
                {
                    direction = this.getDirection(this._observationTime[i]);
                }
                else
                {
                    direction = observed_states[i].Direction;
                }
                this._observedStates[i] = new StateBase(location, direction, velocity);
            }
            this.loadNormalizedStates();
            loadApproximatedPolyline();
        }
예제 #6
0
 public static IInterpolation nuaturalSpline(double[] x, double[] y)
 {
     return(Interpolate.CubicSplineRobust(x, y));
 }
예제 #7
0
파일: Kneedle.cs 프로젝트: dc0d32/Kneedle
        /**
         * <summary>
         * <para>
         * Calculates knee points using the Kneedle algorithm. Returns the x value corresponding to the knee
         * point when successful, null otherwise.
         * </para>
         * <para>
         * Reference:
         *      Finding a ‘kneedle’in a haystack: Detecting knee points in system behavior.
         *      Satopaa, V and Albrecht, J and Irwin, D and Raghavan, B
         *      <see cref="https://raghavan.usc.edu/papers/kneedle-simplex11.pdf"/>
         * </para>
         *
         *  <list type="bullet">
         *  <param name="x">x: X axis values of the points. Points must be sorted in ascending order w.r.t. X axis.</param>
         *  <param name="y">y: Y axis values of the points.</param>
         *  <param name="direction">direction: If the curve is increasing or decreasing. Make sure to set this value according to the input curve.</param>
         *  <param name="concavity">concavity: Whether the curve has positive or negative curvature. In other words, concave or convex. Whether the tangent rotates clockwise or counterclockwise. Make sure to set this value according to the input curve.</param>
         *  <param name="sensitivity">sensitivity: Adjusts the knee detection threshold. Defaults to 1 as per the paper.</param>
         *  <param name="forceLinearInterpolation">forceLinearInterpolation: Interpolation is done using robust cubic splines. For some inputs, spline can overshoot. This param forces linear interpolation instead of cubic spline.</param>
         *  </list>
         *
         * Can return null when the algorithm fails to identify a knee/elbow for various reasons:
         *      - the number of data points is too small
         *      - there are no local maxima on the diffs, which means either the curve is a line, or the
         *        parameters provided are incompatible with the curve
         *
         *  <list type="bullet">
         *  2019-01-08: rename curvature enum to be easy to interpret and remember (Prashant Borole)
         *  2019-01-07: initial version (Prashant Borole)
         *  </list>
         *  </summary>
         */
        public static double?CalculateKneePoints(double[] x, double[] y, CurveDirection direction, Curvature concavity, double sensitivity = 1, bool forceLinearInterpolation = true)
        {
            if (x == null || y == null || x.Length != y.Length || x.Length < 2)
            {
                return(null);
            }

            var numPoints = x.Length;

            MathNet.Numerics.Interpolation.IInterpolation interpolator = null;
            if (numPoints > 5 && !forceLinearInterpolation)
            {
                interpolator = Interpolate.CubicSplineRobust(x, y);
            }
            else
            {
                interpolator = Interpolate.Linear(x, y);
            }
            var x_spaced = Generate.LinearSpaced(numPoints, x.Min(), x.Max());
            var y_spaced = Generate.Map(x_spaced, interpolator.Interpolate);

            var x_norm = MinMaxNormalize(x_spaced);
            var y_norm = MinMaxNormalize(y_spaced);

            var x_diff = x_norm;
            var y_diff = new double[numPoints];

            if (direction == CurveDirection.Decreasing)
            {
                for (int i = 0; i < numPoints; i++)
                {
                    y_diff[i] = x_norm[i] + y_norm[i];
                }
                if (concavity == Curvature.Counterclockwise)
                {
                    for (int i = 0; i < numPoints; i++)
                    {
                        y_diff[i] = 1 - y_diff[i];
                    }
                }
            }
            else
            {
                // increasing
                for (int i = 0; i < numPoints; i++)
                {
                    y_diff[i] = y_norm[i] - x_norm[i];
                }
                if (concavity == Curvature.Counterclockwise)
                {
                    for (int i = 0; i < numPoints; i++)
                    {
                        y_diff[i] = Math.Abs(y_diff[i]);
                    }
                }
            }


            // find local maxima
            var xmx_idxs = FindLocalExtrema(y_diff, true);

            if (xmx_idxs.Count == 0)
            {
                return(null);
            }
            var xmx = xmx_idxs.Select(idx => x_diff[idx]).ToArray();
            var ymx = xmx_idxs.Select(idx => y_diff[idx]).ToArray();

            // minima
            var xmn_idxs = FindLocalExtrema(y_diff, false);
            var xmn      = xmn_idxs.Select(idx => x_diff[idx]).ToArray();
            var ymn      = xmn_idxs.Select(idx => y_diff[idx]).ToArray();

            var tmx = Threshold(ymx, x_norm, sensitivity);

            // now find the knee point between each of the local maxima
            var    curMaximaIdx = 0;
            var    xmn_idxs_set = new HashSet <int>(xmn_idxs);
            double?knee         = null;

            for (int x_i = xmx_idxs[0] + 1; x_i < x.Length; x_i++)
            {
                if (curMaximaIdx < xmx_idxs.Count - 1 && x_i == xmx_idxs[curMaximaIdx + 1])
                {
                    curMaximaIdx++;
                    x_i++;
                    continue;
                }

                if (xmn_idxs_set.Contains(x_i))
                {
                    if (x_i < x.Length - 1 && y_diff[x_i + 1] > y_diff[x_i])
                    {
                        tmx[curMaximaIdx] = 0;
                    }
                }

                if (y_diff[x_i] < tmx[curMaximaIdx] || tmx[curMaximaIdx] < 0)
                {
                    knee = x[xmx_idxs[curMaximaIdx]];
                }
            }

            return(knee);
        }
        void QuintanaContinuumSearchRoutine(Edges edges)
        {
            MainWindow mainForm = this.Owner as MainWindow;

            int[] EdgesNumbers = new int[1024];
            int[] PeaksFlags   = new int[1024];
            int   NumberOfEdges;

            EdgesNumbers  = edges.EdgesNumbers;
            NumberOfEdges = edges.NumberOfEdges;
            PeaksFlags    = edges.PeaksFlags;

            //НЕСООТВЕТСВТУЮТ ГРАНИЦЫ ПИКОВ И ЧИСЛО ИМПУЛЬСОВ В НИХ: СТОЯТ ЗАЧЕНИЯ НА ОДИН КАНАЛ ПОСЛЕ
            double[] cX = new double[NumberOfEdges];
            double[] cY = new double[NumberOfEdges];
            for (int i = 0; i < NumberOfEdges; i++)
            {
                cX[i] = EdgesNumbers[i];
                cY[i] = mainForm.WorkingSpectr.GammaSpectr[(int)cX[i]];
            }

            int finish = 0;

            while (finish != 1)
            {
                finish = 1;
                mainForm.GammaSpectrChart.Series["baseline"].Points.Clear();
                for (int i = 0; i < 1024; i++)
                {
                    Baseline[i] = Interpolate.CubicSplineRobust(cX, cY).Interpolate(i);
                }
                for (int i = 0; i < NumberOfEdges - 1; i++)
                {
                    double R = 0,
                           S = 0;
                    if (PeaksFlags[(int)cX[i] + 1] == 1)
                    {
                        continue;
                    }
                    for (int j = (int)cX[i] + 1; j < (int)cX[i + 1]; j++)
                    {
                        R += Math.Abs((mainForm.WorkingSpectr.GammaSpectr[j - 1] - Baseline[j - 1]) / Math.Sqrt(Math.Abs(mainForm.WorkingSpectr.GammaSpectr[j - 1])) *
                                      (mainForm.WorkingSpectr.GammaSpectr[j] - Baseline[j]) / Math.Sqrt(Math.Abs(mainForm.WorkingSpectr.GammaSpectr[j])));
                        S += Math.Pow(mainForm.WorkingSpectr.GammaSpectr[j] - Baseline[j], 2);
                    }
                    if ((cX[i + 1] - cX[i]) * R / S > double.Parse(textBox1.Text.Replace('.', ',')))
                    {
                        List <double> lst = cX.OfType <double>().ToList();
                        lst.Insert(i + 1, Math.Round((cX[i + 1] + cX[i]) / 2));
                        Array.Resize(ref cX, cX.Length + 1);
                        cX = lst.ToArray();
                        List <double> lst2 = cY.OfType <double>().ToList();
                        lst2.Insert(i + 1, mainForm.WorkingSpectr.GammaSpectr[(int)Math.Round((cX[i + 1] + cX[i]) / 2)]);
                        Array.Resize(ref cY, cY.Length + 1);
                        cY = lst2.ToArray();
                        NumberOfEdges++;
                        finish = 0;
                    }
                }
            }
            for (int counterI = 0; counterI < 1024; counterI++)
            {
                if (PeaksFlags[counterI] == 1)
                {
                    Baseline[counterI] = Interpolate.CubicSplineRobust(cX, cY).Interpolate(counterI);
                }
                else
                {
                    Baseline[counterI] = mainForm.WorkingSpectr.GammaSpectr[counterI];
                }
                mainForm.GammaSpectrChart.Series["baseline"].Points.Add(new SeriesPoint(counterI + 1, Baseline[counterI]));
            }
        }