# Implement finding extrema for cubic splines

I wanted to find extrema for a spline and had to implement it by myself, using the CubicSpline.cs of MathNet.Numerics. Unfortunately the Class is constructes thus, that I could not access the spline parameters which would have allowed my to simply write an extension method.

I propose the following addition to the class "CubicSpline":

public enum eExtremePointType

{

Minimum, Maximum

}

public class cExtremePointResult

{

public eExtremePointType Type { get; private set; }

public double x { get; private set; }

public double y [get;private set;}

public cExtremePointResult(double in_x, double in_y, eExtremePointType in_type)

{

x=in_x;

y=in_y;

Type=in_type;

}

}

/// <summary>

/// Calculate all absolute maxima and minima of the spline between its support points

/// </summary>

/// <returns>IEnumerable of extreme points ordered ascending by x</returns>

public IEnumerable<cExtremePointResult> GetExtrema()

{

List<cExtremePointResult> extrema = new List<cExtremePointResult>(); // Initialize result list

for (int i = 0; i < _x.Length - 1; i++) // For every interval between two support points

{

foreach (double x in PQFormula(2 * _c2[i] / (3 * _c3[i]), _c1[i] / (3 * _c3[i]))) // Get the zeroes of the first derivate of the cubic function between those points => first condition for extreme points

{

Debug.Print(x.ToString()+"|"+(x+_x[i]).ToString());

if (!double.IsNaN(x)) // Filter out invalid zeroes (linke division by 0 or root of negative values in pq-formula

{

if (x+_x[i] >= _x[i] && x+_x[i] <= _x[i + 1]) // check wether zero is in current interval between support points

{

// Add point to list of extrema. Evaluating the second derivate gives the information wether it is a maximum or a minimum we have found

extrema.Add(new cExtremePointResult(x + _x[i], Interpolate(x + _x[i]), Differentiate2(x + _x[i]) > 0 ? eExtremePointType.Minimum : eExtremePointType.Maximum));

}

}

}

}

return extrema.OrderBy(x => x.Point.X); // Order results ascending by x

}

/// <summary>

/// Solve qudaratic function with pq formula: https://en.wikipedia.org/wiki/Quadratic_equation#Reduced_quadratic_equation

/// </summary>

/// <param name="p">Parameter p</param>

/// <param name="q">Parameter q</param>

/// <returns>Enumerable of zeroes of the quadratic function</returns>

IEnumerable<double> PQFormula(double p, double q)

{

// We want to return distinct to prevent us having one point twice (think zero of x²)

return (new List<double>() { -p / 2.0 + Math.Sqrt((p / 2.0) * (p / 2.0) - q), -p / 2.0 - Math.Sqrt((p / 2.0) * (p / 2.0) - q) }).Distinct();

}

This code works like a charm for me and I would appreciate if it could be integrated in the CubicSpline class to prevent me having to have two Spline classes basically doing the same except the extrema handling

**3**votes