示例#1
0
 private void GetDailyTemps()
 {
     double[]    tDays           = new double[500];
     double[]    tTemps          = new double[500];
     CubicSpline minInterpolator = CubicSpline.InterpolateNatural(tDays, tTemps);
     //minInterpolator.Interpolate(blah);
 }
    static void Main(string[] args)
    {
        var xvec = new DenseVector(new double[] { 0.0, 1.0, 2.0, 3.0, 4.0 });
        var yvec = new DenseVector(new double[] { 3.0, 2.7, 2.3, 1.6, 0.2 });

        Debug.WriteLine("Input Data Table");
        Debug.WriteLine($"{"x",column_width} {"y",column_width}");
        for (int i = 0; i < xvec.Count; i++)
        {
            Debug.WriteLine($"{xvec[i],column_width:G5} {yvec[i],column_width:G5}");
        }
        Debug.WriteLine(" ");
        var cs   = CubicSpline.InterpolateNatural(xvec, yvec);
        var x    = new DenseVector(15);
        var y    = new DenseVector(x.Count);
        var dydx = new DenseVector(x.Count);

        Debug.WriteLine("Interpoaltion Results Table");
        Debug.WriteLine($"{"x",column_width} {"y",column_width} {"dy/dx",column_width}");
        for (int i = 0; i < x.Count; i++)
        {
            x[i]    = (4.0 * i) / (x.Count - 1);
            y[i]    = cs.Interpolate(x[i]);
            dydx[i] = cs.Differentiate(x[i]);
            Debug.WriteLine($"{x[i],column_width:G5} {y[i],column_width:G5} {dydx[i],column_width:G5}");
        }
    }
示例#3
0
        public RTandInt Interpolate(double[] starttimes, double[] intensities)
        {
            List <double> intensityList  = new List <double>();
            List <double> starttimesList = new List <double>();

            //First step is interpolating a spline, then choosing the pointsat which to add values:
            CubicSpline interpolation = CubicSpline.InterpolateNatural(starttimes, intensities);

            //Now we work out how many to add so we reach at least 100 datapoints and add them:
            double stimesinterval = starttimes.Last() - starttimes[0];
            int    numNeeded      = 100 - starttimes.Count();
            double intervals      = stimesinterval / numNeeded;

            intensityList  = intensities.OfType <double>().ToList();
            starttimesList = starttimes.OfType <double>().ToList();
            for (int i = 0; i < numNeeded; i++)
            {
                double placetobe = starttimes[0] + (intervals * i);

                //insert newIntensity into the correct spot in the array
                for (int currentintensity = 0; currentintensity < 100; currentintensity++)
                {
                    if (starttimesList[currentintensity] < placetobe)
                    {
                        continue;
                    }
                    else
                    {
                        if (currentintensity > 0)
                        {
                            if (starttimesList[currentintensity] == placetobe)
                            {
                                placetobe = placetobe + 0.01;
                            }
                            double newIntensity = interpolation.Interpolate(placetobe);
                            intensityList.Insert(currentintensity, newIntensity);
                            starttimesList.Insert(currentintensity, placetobe);
                        }
                        else
                        {
                            if (starttimesList[currentintensity] == placetobe)
                            {
                                placetobe = placetobe - 0.01;
                            }
                            double newIntensity = interpolation.Interpolate(placetobe);
                            intensityList.Insert(currentintensity, newIntensity);
                            starttimesList.Insert(currentintensity, placetobe);
                        }

                        break;
                    }
                }
            }
            RTandInt ri = new RTandInt();

            ri.intensities = intensityList.Select(item => Convert.ToDouble(item)).ToArray();
            ri.starttimes  = starttimesList.Select(item => Convert.ToDouble(item)).ToArray();

            return(ri);
        }
示例#4
0
        public Func <double, double> CreateInterpolator(IEnumerable <double> xCoords, IEnumerable <double> yCoords)
        {
            if (xCoords == null)
            {
                throw new ArgumentNullException(nameof(xCoords));
            }
            if (yCoords == null)
            {
                throw new ArgumentNullException(nameof(yCoords));
            }
            if (xCoords.Count() != yCoords.Count())
            {
                throw new ArgumentException("xCoords and yCoords must have the same number of elements.");
            }

            if (xCoords.Count() == 1) // Trivial case of a single point
            {
                double singleY = yCoords.Single();
                return(x => singleY);
            }

            var cubicSpline = CubicSpline.InterpolateNatural(xCoords, yCoords);

            return(cubicSpline.Interpolate);
        }
示例#5
0
            protected void UpdateInterpolation()
            {
                int count = _keyFrames.Count;
                var xs    = new double[count];
                var ys    = new double[count];

                for (int i = 0; i < count; ++i)
                {
                    xs[i] = (double)_keyFrames[i].time;
                    ys[i] = (double)_keyFrames[i].value;
                }
                if (count <= 1)
                {
                    _interpolation = StepInterpolation.Interpolate(xs, ys);
                }
                else if (count <= 2)
                {
                    _interpolation = LinearSpline.Interpolate(xs, ys);
                }
                else if (count <= 3)
                {
                    _interpolation = MathNet.Numerics.Interpolate.Polynomial(xs, ys);
                }
                else if (count <= 4)
                {
                    _interpolation = CubicSpline.InterpolateNatural(xs, ys);
                }
                else
                {
                    _interpolation = CubicSpline.InterpolateAkima(xs, ys);
                }
            }
        public void NaturalFitsAtSamplePoints()
        {
            IInterpolation it = CubicSpline.InterpolateNatural(_t, _y);

            for (int i = 0; i < _y.Length; i++)
            {
                Assert.AreEqual(_y[i], it.Interpolate(_t[i]), "A Exact Point " + i);
            }
        }
        public void NaturalSupportsLinearCase(int samples)
        {
            LinearInterpolationCase.Build(out var x, out var y, out var xtest, out var ytest, samples);
            IInterpolation it = CubicSpline.InterpolateNatural(x, y);

            for (int i = 0; i < xtest.Length; i++)
            {
                Assert.AreEqual(ytest[i], it.Interpolate(xtest[i]), 1e-15, "Linear with {0} samples, sample {1}", samples, i);
            }
        }
示例#8
0
    public InterpolateFromCSVStrategy()
    {
        airfoils = new Dictionary <string, AirfoilData>();

        // Read data (drag and lift coefficient) from files
        foreach (var airfoil in airfoilsArr)
        {
            string dragCoefPath = Path.Combine(Application.streamingAssetsPath, airfoil + "_drag.csv");
            string liftCoefPath = Path.Combine(Application.streamingAssetsPath, airfoil + "_lift.csv");

            if (File.Exists(dragCoefPath) && File.Exists(liftCoefPath))
            {
                string[] dragLines     = File.ReadAllLines(dragCoefPath);
                double[] anglesForDrag = new double[dragLines.Length];
                double[] coefsForDrag  = new double[dragLines.Length];

                for (int i = 0; i < dragLines.Length; i++)
                {
                    var      line = dragLines[i];
                    string[] arr  = line.Split(',');

                    anglesForDrag[i] = double.Parse(arr[0], System.Globalization.CultureInfo.InvariantCulture);
                    coefsForDrag[i]  = double.Parse(arr[1], System.Globalization.CultureInfo.InvariantCulture);
                }

                CubicSpline dragCubicSpline = CubicSpline.InterpolateNatural(anglesForDrag, coefsForDrag);

                // Interpolating lift coefficient from tables in file
                string[] liftLines     = File.ReadAllLines(liftCoefPath);
                double[] anglesForLift = new double[liftLines.Length];
                double[] coefsForLift  = new double[liftLines.Length];

                for (int i = 0; i < liftLines.Length; i++)
                {
                    var      line = liftLines[i];
                    string[] arr  = line.Split(',');

                    anglesForLift[i] = double.Parse(arr[0], System.Globalization.CultureInfo.InvariantCulture);
                    coefsForLift[i]  = double.Parse(arr[1], System.Globalization.CultureInfo.InvariantCulture);
                }

                CubicSpline liftCubicSpline = CubicSpline.InterpolateNatural(anglesForLift, coefsForLift);
                airfoils.Add(airfoil, new AirfoilData(liftCubicSpline, dragCubicSpline));
            }
            else
            {
                Debug.LogError("Could not load drag or coefficient table file for " + airfoil);
            }
        }

        selectedAirfoil           = "naca0012";
        selectedLiftInterpolation = airfoils[selectedAirfoil].liftCubicSpline;
        selectedDragInterpolation = airfoils[selectedAirfoil].dragCubicSpline;
    }
示例#9
0
        private decimal PlotValue(decimal[] DataPoints, decimal Position)
        {
            CubicSpline oCs = CubicSpline.InterpolateNatural(

                DataPoints.Select((s, i2) => new { i2, s })
                .Select(t => Convert.ToDouble(t.i2)).ToArray(),

                DataPoints.Select(s => Convert.ToDouble(s)).ToArray());

            return(Convert.ToDecimal(oCs.Interpolate(Convert.ToDouble(Position))));
        }
示例#10
0
        /// <summary>
        /// Interpolation of the interface points onto the equidistant Fourier points
        /// </summary>
        protected void InterpolateOntoFourierPoints(MultidimensionalArray interP, double[] samplP)
        {
            int numP = interP.Lengths[0];

            // set interpolation data
            double[] independentVal = new double[numP + 2];
            double[] dependentVal   = new double[numP + 2];
            for (int sp = 1; sp <= numP; sp++)
            {
                independentVal[sp] = interP[sp - 1, 0];
                dependentVal[sp]   = interP[sp - 1, 1];
            }
            // extend the interpolation data for sample points at the boundary of the domain
            independentVal[0]        = interP[numP - 1, 0] - DomainSize;
            dependentVal[0]          = interP[numP - 1, 1];
            independentVal[numP + 1] = interP[0, 0] + DomainSize;
            dependentVal[numP + 1]   = interP[0, 1];

            switch (this.InterpolationType)
            {
            case Interpolationtype.LinearSplineInterpolation:

                //LinearSplineInterpolation LinSpline = new LinearSplineInterpolation();
                //LinSpline.Initialize(independentVal, dependentVal);
                var LinSpline = LinearSpline.Interpolate(independentVal, dependentVal);

                for (int sp = 0; sp < numFp; sp++)
                {
                    samplP[sp] = LinSpline.Interpolate(FourierP[sp]);
                    //invDFT_coeff[sp] = (Complex)samplP[sp];
                }

                break;

            case Interpolationtype.CubicSplineInterpolation:

                //CubicSplineInterpolation CubSpline = new CubicSplineInterpolation();
                //CubSpline.Initialize(independentVal, dependentVal);
                var CubSpline = CubicSpline.InterpolateNatural(independentVal, dependentVal);

                for (int sp = 0; sp < numFp; sp++)
                {
                    samplP[sp] = CubSpline.Interpolate(FourierP[sp]);
                    //invDFT_coeff[sp] = (Complex)samplP[sp];
                }

                break;

            default:
                throw new NotImplementedException();
            }
        }
示例#11
0
 public double Interpolate(double x)
 {
     //double value = interpolation.Interpolate(x);
     if (_xRange.Length < 3 || _yRange.Length < 3)
     {
         //return LinearSpline.InterpolateSorted(_xRange, _yRange).Interpolate(x);
         return(LinearSpline.Interpolate(_xRange, _yRange).Interpolate(x));
     }
     else
     {
         return(CubicSpline.InterpolateNatural(_xRange, _yRange).Interpolate(x));
     }
 }
示例#12
0
    static void Main(string[] args)
    {
        // Type code here.
        var         xvec = new DenseVector(new double[] { 0.0, 1.0, 2.0, 3.0, 4.0 });
        var         yvec = new DenseVector(new double[] { 3.0, 2.7, 2.2, 1.6, 0.2 });
        CubicSpline cs   = CubicSpline.InterpolateNatural(xvec, yvec);

        Console.WriteLine($"{"x",column_width} {"y",column_width} {"dy/dx",column_width}");
        for (int i = 0; i < xvec.Count; i++)
        {
            double dydx = cs.Differentiate(xvec[i]);
            Console.WriteLine($"{xvec[i],column_width:G5} {yvec[i],column_width:G5} {dydx,column_width:G5}");
        }
    }
        private static float[] Interpolate(float[] samples, int newSize, int cubicSplineFactor)
        {
            var xCoordinates = Array.ConvertAll(Enumerable.Range(0, samples.Length).ToArray(), Convert.ToDouble);
            var yCoordinates = Array.ConvertAll(samples, Convert.ToDouble);

            var interpolatedSamples = new List <float>();
            var cubicSpline         = CubicSpline.InterpolateNatural(xCoordinates, yCoordinates);

            for (var n = 0; n < newSize * cubicSplineFactor; n++)
            {
                interpolatedSamples.Add((float)cubicSpline.Interpolate((double)n * samples.Length / (cubicSplineFactor * newSize)));
            }

            return(interpolatedSamples.ToArray());
        }
示例#14
0
        public void InterpolateCurveNatural()
        {
            List <SensitivityPoint> smoothCurve = new List <SensitivityPoint>();

            double[]    timestamp   = sensCurve.Select(sensCurve => sensCurve.timeStamp).ToArray();
            double[]    randomsense = sensCurve.Select(sensCurve => sensCurve.sensitivity).ToArray();
            CubicSpline spline      = CubicSpline.InterpolateNatural(timestamp, randomsense);

            for (double timecode = 0; timecode < this.lenght; timecode += timestep)
            {
                SensitivityPoint sensPoint = new SensitivityPoint(timecode, spline.Interpolate(timecode));
                smoothCurve.Add(sensPoint);
            }
            sensCurve = smoothCurve;
        }
示例#15
0
        private void FitSpline(FreeformPointLineSeries fpls)
        {
            m_chart.BeginUpdate();

            int iMarkerCount = fpls.SeriesEventMarkers.Count;

            double[] aMarkerValuesX = new double[iMarkerCount];
            double[] aMarkerValuesY = new double[iMarkerCount];

            for (int i = 0; i < iMarkerCount; i++)
            {
                SeriesEventMarker marker = fpls.SeriesEventMarkers[i];
                aMarkerValuesX[i] = marker.XValue;
                aMarkerValuesY[i] = marker.YValue;
            }

            //One solved point for each pixel in X-dimension

            double[] aXValues = new double[100];
            double   dXMin    = aMarkerValuesX[0];
            double   dXMax    = aMarkerValuesX[iMarkerCount - 1];
            double   dXStep   = (dXMax - dXMin) / (double)(100 - 1);

            for (int i = 0; i < 100; i++)
            {
                aXValues[i] = dXMin + dXStep * (double)i;
            }
            int iOrder = iMarkerCount - 1;

            //double[] aYValues = MathRoutines.PolynomialRegression(aMarkerValuesX, aMarkerValuesY, aXValues, iOrder);


            double[]    aYValues      = new double[100];
            CubicSpline naturalSpline = CubicSpline.InterpolateNatural(aMarkerValuesX, aMarkerValuesY);

            for (int i = 0; i < 100; i++)
            {
                aYValues[i] = naturalSpline.Interpolate(aXValues[i]);
            }
            if (aYValues != null)
            {
                fpls.Clear();
                fpls.AddPoints(aXValues, aYValues, false);
            }
            m_chart.EndUpdate();
        }
        public static double Differentiate(List <double> points, List <double> values, double diffPoint, int degree)
        {
            double recDifferentiation(List <double> newValues, int newDegree)
            {
                if (newDegree == 0)
                {
                    return(CubicSpline.InterpolateNatural(points, newValues).Differentiate(diffPoint));
                }
                else
                {
                    var cs = CubicSpline.InterpolateNatural(points, newValues);
                    newValues = points.Select(point => cs.Differentiate(point)).ToList();
                    return(recDifferentiation(newValues, newDegree - 1));
                }
            }

            return(recDifferentiation(values, degree));
        }
示例#17
0
        protected override void DrawCore(DrawingContext context, DrawingAttributes overrides)
        {
            var   points        = DrawingAttributes.FitToCurve ? GetBezierStylusPoints() : StylusPoints;
            var   reducedPoints = GeometryHelper.DouglasPeuckerReduction(points.Select(sp => sp.ToPoint()).ToList(), 10d);
            var   spline        = CubicSpline.InterpolateNatural(reducedPoints.Select(p => p.X), reducedPoints.Select(p => p.Y));
            Point?prevPoint     = null;

            Points = new List <Point>();
            for (var i = points.Min(sp => sp.X); i <= points.Max(sp => sp.X); i++)
            {
                var curPoint = new Point(i, spline.Interpolate(i));
                Points.Add(curPoint);
                if (prevPoint != null)
                {
                    context.DrawLine(new Pen(Brushes.Black, 2), prevPoint.Value, curPoint);
                }
                prevPoint = curPoint;
            }
        }
示例#18
0
        public Trajectory GenerateTrajectory()
        {
            var xSpline      = CubicSpline.InterpolateNatural(_tData, _xData);
            var ySpline      = CubicSpline.InterpolateNatural(_tData, _yData);
            var zSpline      = CubicSpline.InterpolateNatural(_tData, _zData);
            var latSpline    = CubicSpline.InterpolateNatural(_tData, _latData);
            var longSpline   = CubicSpline.InterpolateNatural(_tData, _longData);
            var speedSpline  = CubicSpline.InterpolateNatural(_tData, _speedData);
            var thrustSpline = CubicSpline.InterpolateNatural(_tData, _thrustData);

            var trajectory = new Trajectory(xSpline, ySpline, zSpline, longSpline, latSpline, speedSpline, thrustSpline, _aircraft);

            trajectory.LowerLeftPoint  = new Point3D(_xData.Min(), _yData.Min(), 0, CoordinateUnit.metric);
            trajectory.UpperRightPoint = new Point3D(_xData.Max(), _yData.Max(), 0, CoordinateUnit.metric);
            trajectory.ReferencePoint  = _referencePoint;
            trajectory.Duration        = (int)_tData.Last();

            return(trajectory);
        }
示例#19
0
        //CubicSpline lookX, lookY, lookZ;

        /// <summary>
        /// Initialize our path with a sequence of locations and lookAt directions.
        /// </summary>
        public void Initialize(IEnumerable <Vector3D> locations, IEnumerable <Vector3D> lookAts)
        {
            int count = locations.Count();

            //if( lookAts.Count() != count )
            //	throw new System.ArgumentException();
            double[] times = Enumerable.Range(0, count).Select(i => (double)i / (count - 1)).ToArray();

            //.6, 0, -.8
            locX = CubicSpline.InterpolateBoundaries(times, locations.Select(v => v.X), SplineBoundaryCondition.FirstDerivative, .6, SplineBoundaryCondition.FirstDerivative, .6);
            locY = CubicSpline.InterpolateBoundaries(times, locations.Select(v => v.Y), SplineBoundaryCondition.FirstDerivative, 0, SplineBoundaryCondition.FirstDerivative, 0);
            locZ = CubicSpline.InterpolateBoundaries(times, locations.Select(v => v.Z), SplineBoundaryCondition.FirstDerivative, -.8, SplineBoundaryCondition.FirstDerivative, -.8);

            locX = CubicSpline.InterpolateNatural(times, locations.Select(v => v.X));
            locY = CubicSpline.InterpolateNatural(times, locations.Select(v => v.Y));
            locZ = CubicSpline.InterpolateNatural(times, locations.Select(v => v.Z));

            /*lookX = CubicSpline.InterpolateNatural( times, lookAts.Select( v => v.X ) );
            *  lookY = CubicSpline.InterpolateNatural( times, lookAts.Select( v => v.Y ) );
            *  lookZ = CubicSpline.InterpolateNatural( times, lookAts.Select( v => v.Z ) );*/
        }
示例#20
0
        public bool Interpolate(double[] xIn, double[] yIn, out CubicSpline spline, out string errMsg)
        {
            bool success = true;

            errMsg = "";
            spline = null;

            if (xIn.Length == yIn.Length)
            {
                var xvec = new DenseVector(xIn);
                var yvec = new DenseVector(yIn);

                spline = CubicSpline.InterpolateNatural(xvec, yvec);
            }
            else
            {
                errMsg  = "x and y vectors must be the same length";
                success = false;
            }

            return(success);
        }
示例#21
0
        private ChartValues <ObservablePoint> GetPlotData()
        {
            ChartValues <ObservablePoint> chartdata = new ChartValues <ObservablePoint>();
            CubicSpline cs = new CubicSpline(dataptArray, c0, c1, c2, c3);

            cs = CubicSpline.InterpolateNatural(xdata, ydata);
            c0 = HelperLibrary.PropertyHelper.GetPrivateFieldValue <double[]>(cs, "_c0");
            c1 = HelperLibrary.PropertyHelper.GetPrivateFieldValue <double[]>(cs, "_c1");
            c2 = HelperLibrary.PropertyHelper.GetPrivateFieldValue <double[]>(cs, "_c2");
            c3 = HelperLibrary.PropertyHelper.GetPrivateFieldValue <double[]>(cs, "_c3");

            for (int i = 0; i < c0.Length; i++)
            {
                List <double[]> tmp = new List <double[]>();
                tmp = CubicIntervalData(xdata[i], xdata[i + 1], c3[i], c2[i], c1[i], c0[i]);
                foreach (double[] pt in tmp)
                {
                    chartdata.Add(new ObservablePoint(pt[0], pt[1]));
                }
            }

            return(chartdata);
        }
示例#22
0
        /// <summary>
        /// Interpolation of no equidistant sample point onto equidistant Fourier points
        /// </summary>
        public static void InterpolateOntoFourierPoints(MultidimensionalArray samplP, double DomainSize, double[] samplFp)
        {
            int numSp = samplP.Lengths[0];

            // set interpolation data (delete multiple independent values)
            ArrayList independentList = new ArrayList();
            ArrayList dependentList   = new ArrayList();

            for (int sp = 0; sp < numSp; sp++)
            {
                if (independentList.Contains(samplP[sp, 0]) == false)
                {
                    independentList.Add(samplP[sp, 0]);
                    dependentList.Add(samplP[sp, 1]);
                }
            }
            // extend the interpolation data for sample points at the boundary of the domain
            independentList.Insert(0, samplP[numSp - 1, 0] - DomainSize);
            independentList.Insert(independentList.Count, samplP[0, 0] + DomainSize);
            dependentList.Insert(0, samplP[numSp - 1, 1]);
            dependentList.Insert(dependentList.Count, samplP[0, 1]);

            double[] independentVal = (double[])independentList.ToArray(typeof(double));
            double[] dependentVal   = (double[])dependentList.ToArray(typeof(double));

            // set Fourier points
            int numSFp = samplFp.Length;

            double[] FourierP = new double[numSFp];
            for (int i = 0; i < numSFp; i++)
            {
                FourierP[i] = (DomainSize / numSFp) * i;
            }


            switch (InterpolationType)
            {
            case Interpolationtype.LinearSplineInterpolation:

                //LinearSplineInterpolation LinSpline = new LinearSplineInterpolation();
                //LinSpline.Initialize(independentVal, dependentVal);
                var LinSpline = LinearSpline.Interpolate(independentVal, dependentVal);


                for (int Fp = 0; Fp < numSFp; Fp++)
                {
                    samplFp[Fp] = LinSpline.Interpolate(FourierP[Fp]);
                }

                break;

            case Interpolationtype.CubicSplineInterpolation:
                //CubicSplineInterpolation CubSpline = new CubicSplineInterpolation();
                //CubSpline.Initialize(independentVal, dependentVal);
                var CubSpline = CubicSpline.InterpolateNatural(independentVal, dependentVal);

                for (int Fp = 0; Fp < numSFp; Fp++)
                {
                    samplFp[Fp] = CubSpline.Interpolate(FourierP[Fp]);
                }

                break;

            default:
                throw new NotImplementedException();
            }
        }
示例#23
0
        public void NaturalFitsAtArbitraryPoints(double t, double x, double maxAbsoluteError)
        {
            IInterpolation it = CubicSpline.InterpolateNatural(_t, _y);

            Assert.AreEqual(x, it.Interpolate(t), maxAbsoluteError, "Interpolation at {0}", t);
        }
示例#24
0
 public void FewSamples()
 {
     Assert.That(() => CubicSpline.InterpolateNatural(Array.Empty <double>(), Array.Empty <double>()), Throws.ArgumentException);
     Assert.That(() => CubicSpline.InterpolateNatural(new double[1], new double[1]), Throws.ArgumentException);
     Assert.That(CubicSpline.InterpolateNatural(new[] { 1.0, 2.0 }, new[] { 2.0, 2.0 }).Interpolate(1.0), Is.EqualTo(2.0));
 }
示例#25
0
        public Vector <double>[] bvpsolver_zzz(Func <double, Vector <double>, Vector <double> > system,
                                               double ya, double yb,
                                               double xa, double xb,
                                               int N)
        {
            //先求解方程得到初始斜率的估计值,再进行打靶法迭代。--zzz
            Vector <double>[] res;
            Vector <double>   y0;

            double s_guess, s_guess_pre;
            double fais, fais_pre;
            double dfai, ds;
            int    count = 0;

            //计算20组s_guess和fais,然后样条插值得到连续函数,再通过解方程,得到使fais=0的初始s_guess
            int M = 50;

            double[] sLst = Vector <double> .Build.Dense(M, i => yb / M *i).ToArray();

            double[] faisLst = new double[M];
            count = 0;
            while (count < M)
            {
                y0 = Vector <double> .Build.DenseOfArray(new[] { ya, sLst[count] });

                // observer_pr ob_pr = this->write_targetFunc_end;
                res            = RungeKutta.FourthOrder(y0, xa, xb, N, system);
                faisLst[count] = res[N - 1][0] - yb;
                count++;
            }
            //样条插值得到连续函数
            var cubicSpl = CubicSpline.InterpolateNatural(sLst, faisLst);

            /*如果初始值离解太远,牛顿法会不收敛。故采用Mathnet包中的RobustNewtonRaphson
             * double s_cur = 0, s_next;
             * count = 0;
             * while (count < 1000)
             * {
             *  fais = cubicSpl.Interpolate(s_cur);
             *  dfaids = cubicSpl.Differentiate(s_cur);
             *  if (fais < 1e-5 && fais > -1e-5)
             *  {
             *      break;
             *  }
             *
             *  s_next = s_cur - fais / dfaids;
             *  s_cur = s_next;
             *  count += 1;
             * }*/

            //解方程fais=0,得到初始斜率s_guess。该法先尝试牛顿法,如失败会采用二分法(bisection)。
            s_guess = RobustNewtonRaphson.FindRoot(cubicSpl.Interpolate, cubicSpl.Differentiate, 0, yb, 1e-5);

            //利用解得的s_guess,构造s_guess_pre,目的是求导数dfai/ds。
            if (s_guess == 0)
            {
                s_guess_pre = 1e-2;
            }
            else
            {
                s_guess_pre = s_guess * 0.99;
            }
            //求s_guess_pre对应的fais_pre,目的是求导数dfai/ds。
            y0 = Vector <double> .Build.DenseOfArray(new[] { ya, s_guess_pre });

            res      = RungeKutta.FourthOrder(y0, xa, xb, N, system);
            fais_pre = res[N - 1][0] - yb;

            count = 0;
            while (count < 50)
            {
                y0 = Vector <double> .Build.DenseOfArray(new[] { ya, s_guess });

                res  = RungeKutta.FourthOrder(y0, xa, xb, N, system);
                fais = res[N - 1][0] - yb;

                dfai = fais - fais_pre;
                ds   = s_guess - s_guess_pre;
                if (fais < 1e-5 && fais > -1e-5)
                {
                    break;
                }

                fais_pre    = fais;
                s_guess_pre = s_guess;
                s_guess     = s_guess - fais * ds / dfai;
                count++;
            }

            return(res);
        }
示例#26
0
        internal static void Departing(this FlightContext context)
        {
            /*
             * First check plausible scenarios. The easiest to track is an aerotow.
             *
             * If not, wait until the launch is completed.
             */

            if (context.Flight.LaunchMethod == LaunchMethods.None)
            {
                var departure = context.Flight.PositionUpdates
                                .Where(q => q.Heading != 0 && !double.IsNaN(q.Heading))
                                .OrderBy(q => q.TimeStamp)
                                .Take(5)
                                .ToList();

                if (departure.Count > 4)
                {
                    context.Flight.DepartureHeading = Convert.ToInt16(departure.Average(q => q.Heading));

                    if (context.Flight.DepartureHeading == 0)
                    {
                        context.Flight.DepartureHeading = 360;
                    }

                    // Only start method recognition after the heading has been determined
                    context.Flight.LaunchMethod = LaunchMethods.Unknown | LaunchMethods.Aerotow | LaunchMethods.Winch | LaunchMethods.Self;
                }
                else
                {
                    return;
                }
            }

            if (context.Flight.DepartureTime != null &&
                (context.CurrentPosition.TimeStamp - (context.Flight.PositionUpdates.FirstOrDefault(q => q.Speed > 30)?.TimeStamp ?? context.CurrentPosition.TimeStamp)).TotalSeconds < 10)
            {
                return;
            }

            // We can safely try to extract the correct path

            if (context.Flight.LaunchMethod.HasFlag(LaunchMethods.Unknown | LaunchMethods.Aerotow))
            {
                var encounters = context.TowEncounter().ToList();

                if (encounters.Count(q => q?.Type == EncounterType.Tug || q?.Type == EncounterType.Tow) > 1)
                {
                    return;
                }

                var encounter = encounters.SingleOrDefault(q => q?.Type == EncounterType.Tug || q?.Type == EncounterType.Tow);

                if (encounter != null)
                {
                    context.Flight.LaunchMethod = LaunchMethods.Aerotow
                                                  | (encounter.Type == EncounterType.Tug
                            ? LaunchMethods.OnTow
                            : LaunchMethods.TowPlane
                                                     );

                    context.Flight.Encounters.Add(encounter);

                    context.StateMachine.Fire(FlightContext.Trigger.TrackAerotow);

                    return;
                }
                else if (encounters.Any(q => q == null))
                {
                    return;
                }

                context.Flight.LaunchMethod &= ~LaunchMethods.Aerotow;
            }

            if (context.Flight.LaunchMethod.HasFlag(LaunchMethods.Unknown))
            {
                var x = new DenseVector(context.Flight.PositionUpdates.Select(w => (w.TimeStamp - context.Flight.DepartureTime.Value).TotalSeconds).ToArray());
                var y = new DenseVector(context.Flight.PositionUpdates.Select(w => w.Altitude).ToArray());

                var interpolation = CubicSpline.InterpolateNatural(x, y);

                var r  = new List <double>();
                var r2 = new List <double>();

                for (var i = 0; i < (context.CurrentPosition.TimeStamp - context.Flight.DepartureTime.Value).TotalSeconds; i++)
                {
                    r.Add(interpolation.Differentiate(i));
                    r2.Add(interpolation.Differentiate2(i));
                }

                // When the initial climb has completed
                if (interpolation.Differentiate((context.CurrentPosition.TimeStamp - context.Flight.DepartureTime.Value).TotalSeconds) < 0)
                {
                    // Skip the first element because heading is 0 when in rest
                    var averageHeading = context.Flight.PositionUpdates.Skip(1).Average(q => q.Heading);

                    // ToDo: Add check to see whether there is another aircraft nearby
                    if (context.Flight.PositionUpdates
                        .Skip(1)
                        .Where(q => interpolation.Differentiate((context.CurrentPosition.TimeStamp - context.Flight.DepartureTime.Value).TotalSeconds) > 0)
                        .Select(q => Geo.GetHeadingError(averageHeading, q.Heading))
                        .Any(q => q > 20) ||
                        Geo.DistanceTo(
                            context.Flight.PositionUpdates.First().Location,
                            context.CurrentPosition.Location) > 3000)
                    {
                        context.Flight.LaunchMethod = LaunchMethods.Self;
                    }
                    else
                    {
                        context.Flight.LaunchMethod = LaunchMethods.Winch;
                    }

                    context.Flight.LaunchFinished = context.CurrentPosition.TimeStamp;
                    context.InvokeOnLaunchCompletedEvent();
                    context.StateMachine.Fire(FlightContext.Trigger.LaunchCompleted);
                }
            }
        }