예제 #1
0
 /// <summary>
 /// Default constructor, just initializes the data storage.
 /// </summary>
 private CPointFunction2D()
 {
     this.values            = new Matrix();
     this.coordinatesX      = new Vector();
     this.coordinatesY      = new Vector();
     this.interpolationType = EInterpolationType.LINEAR;
     this.extrapolationType = ExtrapolationType.CONSTANT;
 }
예제 #2
0
 static string ExtrapolationTypeToString(ExtrapolationType eExtrapolationType)
 {
     if (eExtrapolationType == ExtrapolationType.LINEAR) {
         return "LINEAR";
     } else if (eExtrapolationType == ExtrapolationType.NEAR) {
         return "NEAR";
     }
     throw new MyException ("Extrapolation is not recognized");
 }
예제 #3
0
 /// <summary>
 /// Initializes the object based on the serialized data.
 /// </summary>
 /// <param name="info">The SerializationInfo that holds the serialized object data.</param>
 /// <param name="context">The StreamingContext that contains contextual
 /// information about the source.</param>
 public PFunction2D(SerializationInfo info, StreamingContext context)
     : base(info, context)
 {
     this.coordinatesX             = (IRightValue[])ObjectSerialization.GetValue2(info, "_coordinatesX", typeof(IRightValue[]));
     this.coordinatesY             = (IRightValue[])ObjectSerialization.GetValue2(info, "_coordinatesY", typeof(IRightValue[]));
     this.values                   = (IRightValue[, ])ObjectSerialization.GetValue2(info, "_Values", typeof(IRightValue[, ]));
     this.interpolationType        = (EInterpolationType)ObjectSerialization.GetValue2(info, "_InterpolationType", typeof(EInterpolationType));
     this.extrapolationType        = (ExtrapolationType)ObjectSerialization.GetValue2(info, "_ExtrapolationType", typeof(ExtrapolationType));
     this.leastSquaresCoefficients = (int)ObjectSerialization.GetValue2(info, "_LeastSquaresCoefficients", typeof(int));
 }
예제 #4
0
        /// <summary>
        /// Basic constructor to make a new object of type, in a similar
        /// means to other functions.
        /// </summary>
        /// <param name="context">The project this function is created in, if available.</param>
        public PFunction2D(Project context)
            : base(EModelParameterType.POINT_FUNCTION, context)
        {
            // Set some default values.
            this.interpolationType        = EInterpolationType.LINEAR;
            this.extrapolationType        = ExtrapolationType.CONSTANT;
            this.leastSquaresCoefficients = 2;

            // We make a function with coordinates 0 1 and all values to 0 by default.
            FillWithDefaultData();
        }
        public IExtrapolation GetExtrapolator(ExtrapolationType extrapolationType)
        {
            switch (extrapolationType)
            {
            case ExtrapolationType.Constant:
                return(new ConstantExtrapolation(KnownNodes.LastOrDefault()));

            default:
                throw new NotImplementedException($"Interpolation type {extrapolationType} not implemented!");
            }
        }
예제 #6
0
        public void Init(float startTime, float duration, T startValue, T baseSpeed, T speed, ExtrapolationType extrapolationType)
        {
            _extrapolationType = extrapolationType;
            _startTime         = startTime;
            _duration          = duration;
            _startValue        = startValue;
            _baseSpeed         = baseSpeed;
            _speed             = speed;

            _currentTime  = -1;
            _currentValue = startValue;
        }
예제 #7
0
        /// <summary>
        /// Constructs a new CPointFunction2D through evaluation of IRightValues
        /// in order to fill the data used to evaluate the function.
        /// </summary>
        /// <param name="coordinatesX">
        /// An array of <see cref="IRightValue"/> whose result is ordered from
        /// lower to greater and will represent the x parameter of the function.
        /// </param>
        /// <param name="coordinatesY">
        /// An array of <see cref="IRightValue"/> whose result is ordered from
        /// lower to greater and will represent the y parameter of the function.
        /// </param>
        /// <param name="values">
        /// A bi-dimensional array containing the defined data points for
        /// all the coordinates specified by coordinatesX and coordinatesY.
        /// </param>
        /// <param name="interpolationType">
        /// The interpolation to apply when evaluating the function
        /// in case the requested coordinates aren't represented, but inside them.
        /// </param>
        /// <param name="extrapolationType">
        /// The extrapolation to apply when evaluating the function,
        /// in case the requested coordinates are outside the represented ones.
        /// </param>
        public CPointFunction2D(IRightValue[] coordinatesX,
                                IRightValue[] coordinatesY,
                                IRightValue[,] values,
                                EInterpolationType interpolationType,
                                ExtrapolationType extrapolationType)
            : this()
        {
            this.interpolationType = interpolationType;
            this.extrapolationType = extrapolationType;

            // Check if the interpolation and extrapolation methods are available.
            if (extrapolationType == ExtrapolationType.USEMODEL &&
                interpolationType != EInterpolationType.LEAST_SQUARES)
            {
                throw new Exception("Use model extrapolation method is " +
                                    "supported only for Least Squares");
            }

            // Sets the sizes depending on the passed arrays length.
            SetSizes(coordinatesX.Length, coordinatesY.Length);

            // First copy the parsed elements for the x coordinates.
            for (int i = coordinatesX.Length - 1; i >= 0; i--)
            {
                this[i, -1] = coordinatesX[i].V();
            }

            // Then copy the parsed elements for the y coordinates.
            for (int i = coordinatesY.Length - 1; i >= 0; i--)
            {
                this[-1, i] = coordinatesY[i].V();
            }

            // Finally populate the values matrix with the provided data.
            for (int x = 0; x < values.GetLength(0); x++)
            {
                for (int y = 0; y < values.GetLength(1); y++)
                {
                    this[x, y] = values[x, y].V();
                }
            }

            UpdateModel();
        }
예제 #8
0
        public ExtrapolationModifier(ExtrapolationType extrapolationType, IDictionary <double, double> knownNodes)
        {
            var factory = new ExtrapolationFactory(knownNodes);

            Extrapolator = factory.GetExtrapolator(extrapolationType);
        }
예제 #9
0
        /// <summary>
        /// Constructs a new CPointFunction2D through evaluation of IRightValues
        /// in order to fill the data used to evaluate the function.
        /// </summary>
        /// <param name="coordinatesX">
        /// An array of <see cref="IRightValue"/> whose result is ordered from
        /// lower to greater and will represent the x parameter of the function.
        /// </param>
        /// <param name="coordinatesY">
        /// An array of <see cref="IRightValue"/> whose result is ordered from
        /// lower to greater and will represent the y parameter of the function.
        /// </param>
        /// <param name="values">
        /// A bi-dimensional array containing the defined data points for
        /// all the coordinates specified by coordinatesX and coordinatesY.
        /// </param>
        /// <param name="interpolationType">
        /// The interpolation to apply when evaluating the function
        /// in case the requested coordinates aren't represented, but inside them.
        /// </param>
        /// <param name="extrapolationType">
        /// The extrapolation to apply when evaluating the function,
        /// in case the requested coordinates are outside the represented ones.
        /// </param>
        public CPointFunction2D(IRightValue[] coordinatesX,
                                IRightValue[] coordinatesY,
                                IRightValue[,] values,
                                EInterpolationType interpolationType,
                                ExtrapolationType extrapolationType)
            : this()
        {
            this.interpolationType = interpolationType;
            this.extrapolationType = extrapolationType;

            // Check if the interpolation and extrapolation methods are available.
            if (extrapolationType == ExtrapolationType.USEMODEL &&
               interpolationType != EInterpolationType.LEAST_SQUARES)
            {
                throw new Exception("Use model extrapolation method is " +
                                    "supported only for Least Squares");
            }

            // Sets the sizes depending on the passed arrays length.
            SetSizes(coordinatesX.Length, coordinatesY.Length);

            // First copy the parsed elements for the x coordinates.
            for (int i = coordinatesX.Length - 1; i >= 0; i--)
            {
                this[i, -1] = coordinatesX[i].V();
            }

            // Then copy the parsed elements for the y coordinates.
            for (int i = coordinatesY.Length - 1; i >= 0; i--)
            {
                this[-1, i] = coordinatesY[i].V();
            }

            // Finally populate the values matrix with the provided data.
            for (int x = 0; x < values.GetLength(0); x++)
            {
                for (int y = 0; y < values.GetLength(1); y++)
                {
                    this[x, y] = values[x, y].V();
                }
            }

            UpdateModel();
        }
예제 #10
0
 /// <summary>
 /// Default constructor, just initializes the data storage.
 /// </summary>
 private CPointFunction2D()
 {
     this.values = new Matrix();
     this.coordinatesX = new Vector();
     this.coordinatesY = new Vector();
     this.interpolationType = EInterpolationType.LINEAR;
     this.extrapolationType = ExtrapolationType.CONSTANT;
 }
예제 #11
0
        /// <summary>
        /// Constructs a new CPointFunction2D through evaluation of IRightValues
        /// in order to fill the data used to evaluate the function.
        /// </summary>
        /// <param name="cordinatesX">
        /// An array of IRightValue whose result is ordered from lower to greater and will
        /// represent the x parameter of the function.
        /// </param>
        /// <param name="cordinatesY">
        /// An array of IRightValue whose result is ordered from lower to greater and will
        /// represent the y parameter of the function.
        /// </param>
        /// <param name="values">
        /// A bi-dimensional array containing the defined data points for
        /// all the coordinates specified by cordinatesX and cordinatesY.
        /// </param>
        /// <param name="interpolationType">
        /// The interpolation to apply when evaluating the function
        /// in case the requested coordinates aren't represented, but inside them.
        /// </param>
        /// <param name="extrapolationType">
        /// The extrapolation to apply when evaluating the function,
        /// in case the requested coordinates are outside the represented ones.
        /// </param>
        public CPointFunction2D(IRightValue[] cordinatesX,
                                IRightValue[] cordinatesY,
                                IRightValue[,] values,
                                EInterpolationType interpolationType,
                                ExtrapolationType extrapolationType)
            : this()
        {
            this.interpolationType = interpolationType;
            this.extrapolationType = extrapolationType;

            // Sets the sizes depending on the passed arrays length.
            SetSizes(cordinatesX.Length, cordinatesY.Length);

            // First copy the parsed elements for the x coordinates.
            for (int i = cordinatesX.Length - 1; i >= 0; i--)
            {
                this[i, -1] = cordinatesX[i].V();
            }

            // Then copy the parsed elements for the y coordinates.
            for (int i = cordinatesY.Length - 1; i >= 0; i--)
            {
                this[-1, i] = cordinatesY[i].V();
            }

            // Finally populate the values matrix with the provided data.
            for (int x = 0; x < values.GetLength(0); x++)
            {
                for (int y = 0; y < values.GetLength(1); y++)
                {
                    this[x, y] = values[x, y].V();
                }
            }
        }
예제 #12
0
        /// <exception cref="ArgumentException">Condition.</exception>
        /// <exception cref="OverflowException">The array is multidimensional and contains more than <see cref="F:System.Int32.MaxValue" /> elements.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="source" /> is null.</exception>
        /// <exception cref="InvalidOperationException"><paramref name="source" /> contains no elements.</exception>
        /// <exception cref="Exception">A delegate callback throws an exception.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="index" /> is less than 0.-or-<paramref name="index" /> is equal to or greater than <see cref="P:System.Collections.Generic.List`1.Count" />. </exception>
        public static Func <double, double> CreateInterpolant(double[] xs, double[] ys,
                                                              ExtrapolationType extrapolationType)
        {
            var length = xs.Length;

            if (length != ys.Length)
            {
                throw new ArgumentException($"length of xs ({length}) must be equal to length of ys ({ys.Length})");
            }
            switch (length)
            {
            case 0:
                return(x => 0.0);

            case 1:
                return(x => ys[0]);

            default:
                var indices = new int[length];
                for (var i = 0; i < length; ++i)
                {
                    indices[i] = i;
                }
                Array.Sort(indices, (a, b) => xs[a] < xs[b] ? -1 : 1);
                double   xMin = 0.0, xMax = 0.0, yMin = 0.0, yMax = 0.0;
                double[] newXs = new double[xs.Length], newYs = new double[ys.Length];
                for (var i = 0; i < length; i++)
                {
                    newXs[i] = xs[indices[i]];
                    xMin     = Math.Min(xMin, newXs[i]);
                    xMax     = Math.Max(xMax, newXs[i]);
                    newYs[i] = ys[indices[i]];
                    yMin     = Math.Min(yMin, newYs[i]);
                    yMax     = Math.Max(yMax, newYs[i]);
                }
                // Get consecutive differences and slopes
                double[] dxs = new double[length - 1], ms = new double[length - 1];
                for (var i = 0; i < length - 1; i++)
                {
                    double dx = newXs[i + 1] - newXs[i], dy = newYs[i + 1] - newYs[i];
                    dxs[i] = dx;
                    ms[i]  = dy / dx;
                }
                // Get degree-1 coefficients
                var c1S = new double[dxs.Length + 1];
                c1S[0] = ms[0];
                for (var i = 0; i < dxs.Length - 1; i++)
                {
                    double m = ms[i], mNext = ms[i + 1];
                    if (m * mNext <= 0)
                    {
                        c1S[i + 1] = 0;
                    }
                    else
                    {
                        double dx = dxs[i], dxNext = dxs[i + 1], common = dx + dxNext;
                        c1S[i + 1] = 3 * common / ((common + dxNext) / m + (common + dx) / mNext);
                    }
                }
                c1S[c1S.Length - 1] = ms[ms.Length - 1];
                // Get degree-2 and degree-3 coefficients
                double[] c2S = new double[c1S.Length - 1], c3S = new double[c1S.Length - 1];
                for (var i = 0; i < c1S.Length - 1; i++)
                {
                    double c1 = c1S[i], m = ms[i], invDx = 1 / dxs[i], common = c1 + c1S[i + 1] - m - m;
                    c2S[i] = (m - c1 - common) * invDx;
                    c3S[i] = common * invDx * invDx;
                }
                // Return interpolant function
                double Interpolant(double x)
                {
                    // The rightmost point in the dataset should give an exact result
                    var i = newXs.Length - 1;

                    if (Math.Abs(x - newXs[i]) < Tolerance)
                    {
                        return(newYs[i]);
                    }
                    // Search for the interval x is in, returning the corresponding y if x is one of the original newXs
                    var low  = 0;
                    var high = c3S.Length - 1;

                    while (low <= high)
                    {
                        var mid   = low + (high - low) / 2;
                        var xHere = newXs[mid];
                        if (xHere < x)
                        {
                            low = mid + 1;
                        }
                        else if (xHere > x)
                        {
                            high = mid - 1;
                        }
                        else
                        {
                            return(newYs[mid]);
                        }
                    }
                    i = Math.Max(0, high);
                    // Interpolate
                    double diff = x - newXs[i], diffSq = diff * diff;

                    return(newYs[i] + c1S[i] * diff + c2S[i] * diffSq + c3S[i] * diff * diffSq);
                }

                double RangeCheckedInterpolant(double x)
                {
                    if (x >= xMin && x <= xMax)
                    {
                        return(Interpolant(x));
                    }
                    switch (extrapolationType)
                    {
                    case ExtrapolationType.None:
                        return(Interpolant(x));

                    case ExtrapolationType.Linear:
                        return(yMin + (x - xMin) / (xMax - xMin) * yMax);

                    case ExtrapolationType.Constant:
                        return(x < xMin ? yMin : yMax);

                    default:
                        return(double.NaN);
                    }
                }

                return(RangeCheckedInterpolant);
            }
        }
예제 #13
0
        /// <summary>
        /// Basic constructor to make a new object of type, in a similar
        /// means to other functions.
        /// </summary>
        /// <param name="context">The project this function is created in, if available.</param>
        public PFunction2D(Project context)
            : base(EModelParameterType.POINT_FUNCTION, context)
        {
            // Set some default values.
            this.interpolationType = EInterpolationType.LINEAR;
            this.extrapolationType = ExtrapolationType.CONSTANT;
            this.leastSquaresCoefficients = 2;

            // We make a function with coordinates 0 1 and all values to 0 by default.
            FillWithDefaultData();
        }
예제 #14
0
 /// <summary>
 /// Initializes the object based on the serialized data.
 /// </summary>
 /// <param name="info">The SerializationInfo that holds the serialized object data.</param>
 /// <param name="context">The StreamingContext that contains contextual
 /// information about the source.</param>
 public PFunction2D(SerializationInfo info, StreamingContext context)
     : base(info, context)
 {
     this.coordinatesX = (IRightValue[])ObjectSerialization.GetValue2(info, "_coordinatesX", typeof(IRightValue[]));
     this.coordinatesY = (IRightValue[])ObjectSerialization.GetValue2(info, "_coordinatesY", typeof(IRightValue[]));
     this.values = (IRightValue[,])ObjectSerialization.GetValue2(info, "_Values", typeof(IRightValue[,]));
     this.interpolationType = (EInterpolationType)ObjectSerialization.GetValue2(info, "_InterpolationType", typeof(EInterpolationType));
     this.extrapolationType = (ExtrapolationType)ObjectSerialization.GetValue2(info, "_ExtrapolationType", typeof(ExtrapolationType));
     this.leastSquaresCoefficients = (int)ObjectSerialization.GetValue2(info, "_LeastSquaresCoefficients", typeof(int));
 }