예제 #1
0
        /// <summary>
        ///     Construct a linear spline using a set of input points.
        ///     <example>For example:
        ///     <code>
        ///         SortedList<double, double> splinePoints = new SortedList<double, double>();
        ///         splinePoints.Add(0.0f, 1.1f);
        ///         splinePoints.Add(0.3f, 0.4f);
        ///         splinePoints.Add(1.0f, 2.0f);
        ///         LinearSpline1D spline = new LinearSpline1D(splinePoints);
        ///     </code>
        ///     creates a linear spline that passes through three points: (0.0, 1.1), (0.3, 0.4) and (1.0, 2.0).
        ///     </example>
        /// </summary>
        /// <param name="points">A list of points that is sorted by the x-coordinate. This collection is copied.</param>
        /// <exception cref="ArgumentException">
        ///     A linear spline must have at least two points to be properly defined. If <c>points</c> contains less than
        ///     two points, the spline is undefined, so an <c>ArgumentException</c> is thrown.
        /// </exception>
        public LinearSpline1D(SortedList <double, double> points)
        {
            if (points.Count < 2)
            {
                if (points.Count == 1)
                {
                    throw new ArgumentException("List contains only a single point. A spline must have at least two points.", nameof(points));
                }
                else
                {
                    throw new ArgumentException("List is empty. A spline must have at least two points.", nameof(points));
                }
            }

            Points = new SortedPointsList <double>(points);
            DebugUtil.AssertAllFinite(Points, nameof(Points));

            // Calculate the coefficients for each segment of the spline:
            _parameters = new double[points.Count];

            // Recursively find the _parameters:
            for (int i = 1; i < points.Count; i++)
            {
                double dx = Points.Key[i] - Points.Key[i - 1];
                double dy = Points.Value[i] - Points.Value[i - 1];

                _parameters[i] = dy / dx;
            }
            DebugUtil.AssertAllFinite(_parameters, nameof(_parameters));
        }
예제 #2
0
        /// <summary>
        ///     Construct a linear spline using a set of input points.
        ///     <example>For example:
        ///     <code>
        ///         SortedList{double, double} splinePoints = new SortedList{double, double}();
        ///         splinePoints.Add(0.0f, 1.1f);
        ///         splinePoints.Add(0.3f, 0.4f);
        ///         splinePoints.Add(1.0f, 2.0f);
        ///         LinearSpline1D spline = new LinearSpline1D(splinePoints);
        ///     </code>
        ///     creates a linear spline that passes through three points: (0.0, 1.1), (0.3, 0.4) and (1.0, 2.0).
        ///     </example>
        /// </summary>
        /// <param name="points">A list of points that is sorted by the x-coordinate. This collection is copied.</param>
        /// <exception cref="ArgumentException">
        ///     A linear spline must have at least two points to be properly defined. If <c>points</c> contains less than
        ///     two points, the spline is undefined, so an <c>ArgumentException</c> is thrown.
        /// </exception>
        public LinearSpline1D(SortedList <double, double> points)
        {
            if (points.Count < 2)
            {
                if (points.Count == 1)
                {
                    throw new ArgumentException("List contains only a single point. A spline must have at least two points.", nameof(points));
                }
                else
                {
                    throw new ArgumentException("List is empty. A spline must have at least two points.", nameof(points));
                }
            }

            Points = new SortedPointsList <double>(points);
            DebugUtil.AssertAllFinite(Points, nameof(Points));
        }
예제 #3
0
        /// <summary>
        ///     Construct a quadratic spline using a set of input points.
        ///     <example>For example:
        ///     <code>
        ///         SortedList<double, double> splinePoints = new SortedList<double, double>();
        ///         splinePoints.Add(0.0f, 1.1f);
        ///         splinePoints.Add(0.3f, 0.4f);
        ///         splinePoints.Add(1.0f, 2.0f);
        ///         QuadraticSpline1D spline = new QuadraticSpline1D(splinePoints);
        ///     </code>
        ///     creates a quadratic spline that passes through three points: (0.0, 1.1), (0.3, 0.4) and (1.0, 2.0).
        ///     </example>
        /// </summary>
        /// <param name="points">A list of points that is sorted by the x-coordinate. This collection is copied.</param>
        /// <exception cref="ArgumentException">
        ///     A spline must have at least two points to be properly defined. If <c>points</c> contains less than two
        ///     points, the spline is undefined, so an <c>ArgumentException</c> is thrown.
        /// </exception>
        public QuadraticSpline1D(SortedList <double, double> points)
        {
            if (points.Count < 2)
            {
                if (points.Count == 1)
                {
                    throw new ArgumentException("List contains only a single point. A spline must have at least two points.", nameof(points));
                }
                else
                {
                    throw new ArgumentException("List is empty. A spline must have at least two points.", nameof(points));
                }
            }

            Points = new SortedPointsList <double>(points);

            // Calculate the coefficients of the spline:
            _parameters = new double[points.Count];

            // Find the first segment parameter, which will be a straight line:
            {
                double dx = Points.Key[1] - Points.Key[0];
                double dy = Points.Value[1] - Points.Value[0];

                _parameters[0] = dy / dx;
            }

            // Recursively find the other _parameters:
            for (int i = 1; i < points.Count; i++)
            {
                double dx = Points.Key[i] - Points.Key[i - 1];
                double dy = Points.Value[i] - Points.Value[i - 1];

                _parameters[i] = -_parameters[i - 1] + 2.0f * dy / dx;
            }
        }
예제 #4
0
		/// <summary>
		///     Construct a cubic spline using a set of input points.
		/// 	<example>For example:
		/// 	<code>
		/// 		SortedList<float, float> splinePoints = new SortedList<float, float>();
		/// 		splinePoints.Add(0.0f, 1.1f);
		/// 		splinePoints.Add(0.3f, 0.4f);
		/// 		splinePoints.Add(1.0f, 2.0f);
		/// 		CubicSpline1D spline = new CubicSpline1D(splinePoints);
		/// 	</code>
		/// 	creates a cubic spline that passes through three points: (0.0, 1.1), (0.3, 0.4) and (1.0, 2.0).
		/// 	</example>
		/// </summary>
		/// <param name="points">A list of points that is sorted by the x-coordinate. This collection is copied.</param>
		/// <exception cref="ArgumentException">
		/// 	A cubic spline must have at least two points to be properly defined. If <c>points</c> contains less than
		/// 	two points, the spline is undefined, so an <c>ArgumentException</c> is thrown.
		/// </exception>
		public CubicSpline1D(SortedList<float, float> points)
		{
			if (points.Count < 2)
			{
				if (points.Count == 1)
				{
					throw new ArgumentException("List contains only a single point. A spline must have at least two points.", "points");
				}
				else
				{
					throw new ArgumentException("List is empty. A spline must have at least two points.", "points");
				}
			}
			
			Points = new SortedPointsList<float>(points);
			
			// Calculate the coefficients of the spline:
			float[] a = new float[points.Count];
			float[] b = new float[points.Count];
			float[] c = new float[points.Count];
			float[] d = new float[points.Count];
			
			// Set up the boundary condition for a natural spline:
			{
				float x2 = 1.0f/(Points.Key[1] - Points.Key[0]);
				float y2 = Points.Value[1] - Points.Value[0];
				
				a[0] = 0.0f;
				b[0] = 2.0f*x2;
				c[0] = x2;
				d[0] = 3.0f*(y2*x2*x2);
			}
			
			// Set up the tridiagonal matrix linear system:
			for (int i = 1; i < points.Count-1; i++) 
			{
				float x1 = 1.0f/(Points.Key[i] - Points.Key[i-1]);
				float x2 = 1.0f/(Points.Key[i+1] - Points.Key[i]);
				
				float y1 = Points.Value[i] - Points.Value[i-1];
				float y2 = Points.Value[i+1] - Points.Value[i];
				
				a[i] = x1;
				b[i] = 2.0f*(x1 + x2);
				c[i] = x2;
				d[i] = 3.0f*(y1*x1*x1 + y2*x2*x2);
			}
			
			// Set up the boundary condition for a natural spline:
			{
				float x1 = 1.0f/(Points.Key[points.Count-1] - Points.Key[points.Count-2]);
				float y1 = (Points.Value[points.Count-1] - Points.Value[points.Count-2]);
				
				a[points.Count-1] = x1;
				b[points.Count-1] = 2.0f*x1;
				c[points.Count-1] = 0.0f;
				d[points.Count-1] = 3.0f*(y1*x1*x1);
			}
			
			// Solve the linear system using the Thomas algorithm:
			this.parameters = ThomasAlgorithm(a, b, c, d);
		}