Extreme Optimization™: Complexity made simple.

Math and Statistics
Libraries for .NET

  • Home
  • Features
    • Math Library
    • Vector and Matrix Library
    • Statistics Library
    • Performance
    • Usability
  • Documentation
    • Introduction
    • Math Library User's Guide
    • Vector and Matrix Library User's Guide
    • Data Analysis Library User's Guide
    • Statistics Library User's Guide
    • Reference
  • Resources
    • Downloads
    • QuickStart Samples
    • Sample Applications
    • Frequently Asked Questions
    • Technical Support
  • Blog
  • Order
  • Company
    • About us
    • Testimonials
    • Customers
    • Press Releases
    • Careers
    • Partners
    • Contact us
Introduction
Deployment Guide
Nuget packages
Configuration
Using Parallelism
Expand Mathematics Library User's GuideMathematics Library User's Guide
Expand Vector and Matrix Library User's GuideVector and Matrix Library User's Guide
Expand Data Analysis Library User's GuideData Analysis Library User's Guide
Expand Statistics Library User's GuideStatistics Library User's Guide
Expand Data Access Library User's GuideData Access Library User's Guide
Expand ReferenceReference
  • Extreme Optimization
    • Features
    • Solutions
    • Documentation
    • QuickStart Samples
    • Sample Applications
    • Downloads
    • Technical Support
    • Download trial
    • How to buy
    • Blog
    • Company
    • Resources
  • Documentation
    • Introduction
    • Deployment Guide
    • Nuget packages
    • Configuration
    • Using Parallelism
    • Mathematics Library User's Guide
    • Vector and Matrix Library User's Guide
    • Data Analysis Library User's Guide
    • Statistics Library User's Guide
    • Data Access Library User's Guide
    • Reference
  • Mathematics Library User's Guide
    • General Classes
    • Mathematical Functions
    • Complex Numbers
    • Arbitrary Precision Arithmetic
    • Automatic Differentiation
    • Curves and Interpolation
    • Curve Fitting
    • Solving Equations
    • Optimization
    • Calculus
    • Fast Fourier Transforms
    • Random Numbers
    • Generic Arithmetic
    • Appendices
  • Curves and Interpolation
    • Curve Basics
    • Polynomials
    • Chebyshev Series
    • Barycentric Series
    • Piecewise Curves and Cubic Splines
    • Cubic Splines
    • Comparing Curve classes and delegates
  • Polynomials

Polynomials

Extreme Optimization Numerical Libraries for .NET Professional

A polynomial is a linear function that is a combination of the argument raised to different integer powers. Polynomials are among the most common mathematical objects. The Extreme Optimization Numerical Libraries for .NET has extensive support for common polynomials and Chebyshev polynomials.

The PolynomialBase class

All polynomial classes are derived from PolynomialBase This class defines a number of properties shared by all polynomial classes. PolynomialBase is itself derived from LinearCombination.

The Parameters of a polynomial are the coefficients of the polynomial.

The Degree of a polynomial is the highest power that appears in the sum. The number of parameters of the polynomial equals the degree plus one.

General polynomials are implemented by the Polynomial class.

Constructing polynomials

The Polynomial class has three constructors: The first constructor takes the degree of the polynomial as its only argument. All coefficients are initially set to zero. The second constructor takes an array of Double values containing the coefficients. The third constructor takes a single VectorT argument. This vector should contain the coefficients of the polynomial, starting with the constant term. The following example illustrates three different ways of constructing the polynomial

x3 - 5x2 + 9x + 2

C#
VB
C++
F#
Copy
Polynomial p1 = new Polynomial(3);
p1[3] = 1;
p1[2] = -5;
p1[1] = 9;
p1[0] = 2;
var coefficients = Vector.Create(2.0, 9.0, -5.0, 1.0);
Polynomial p2 = new Polynomial(coefficients);
Polynomial p3 = new Polynomial(new[] { 1.0, -5.0, 9.0, 2.0 }, true);
Dim p1 As Polynomial = New Polynomial(3)
p1(3) = 1
p1(2) = -5
p1(1) = 9
p1(0) = 2
Dim coefficients = Vector.Create(2.0, 9.0, -5.0, 1.0)
Dim p2 As Polynomial = New Polynomial(coefficients)
Dim p3 As Polynomial = New Polynomial({1.0, -5.0, 9.0, 2.0}, True)

No code example is currently available or this language may not be supported.

let p1 = Polynomial(3)
p1.[3] <- 1.0
p1.[2] <- -5.0
p1.[1] <- 9.0
p1.[0] <- 2.0
let coefficients = Vector.Create(2.0, 9.0, -5.0, 1.0)
let p2 = Polynomial(coefficients)
let p3 = Polynomial([| 1.0; -5.0; 9.0; 2.0 |], true)

Notice that the coefficients in the constructors for p2 and p3 are listed in order of degree. The nth element of the array or VectorT is the coefficient of degree n.

You can also create a polynomial using one of several static methods.

The GetInterpolatingPolynomial method returns the polynomial that interpolates a set of points. The x-coordinates of the points must be distinct. The x and y-coordinates must be given as two separate Double arrays. The following creates the interpolating polynomial through a set of four points:

C#
VB
C++
F#
Copy
double[] xValues = new double[] { 1, 2, 3, 4 };
double[] yValues = new double[] { 1, 4, 10, 8 };
Polynomial p4;
p4 = Polynomial.GetInterpolatingPolynomial(xValues, yValues);
Dim xValues = New Double() {1, 2, 3, 4}
Dim yValues = New Double() {1, 4, 10, 8}
Dim p4 = Polynomial.GetInterpolatingPolynomial(xValues, yValues)

No code example is currently available or this language may not be supported.

let xValues = [| 1.0; 2.0; 3.0; 4.0 |]
let yValues = [| 1.0; 4.0; 10.0; 8.0 |]
let p4 = Polynomial.GetInterpolatingPolynomial(xValues, yValues)

The FromRoots method constructs a Polynomial whose roots are given by the arguments passed to the method. The roots are provided as a Double array. They can be in any order. The same root can appear multiple times. The following constructs a polynomial with roots 1, 2 (twice), and 4:

C#
VB
C++
F#
Copy
double[] roots = new double[] { 1, 2, 2, 4 };
Polynomial p5 = Polynomial.FromRoots(roots);
Dim roots = New Double() {1, 2, 2, 4}
Dim p5 As Polynomial = Polynomial.FromRoots(roots)

No code example is currently available or this language may not be supported.

let roots = [| 1.0; 2.0; 2.0; 4.0 |]
let p5 = Polynomial.FromRoots(roots)

The LeastSquaresFit method constructs a Polynomial that is the least squares fit of a specified degree through a given set of points.

C#
VB
C++
F#
Copy
double[] xValues = new double[7];
double[] yValues = new double[7];
double angle = 0;
for (int index = 0; index < 7; index++)
{
    xValues[index] = Math.Cos(angle);
    yValues[index] = -Math.Sin(angle);
    angle = angle + Constants.Pi / 6;
}
Polynomial p6 = Polynomial.LeastSquaresFit(xValues, yValues, 4);
Dim xValues(6) As Double
Dim yValues(6) As Double
Dim angle As Double = 0
For index As Integer = 0 To 6
    xValues(index) = Math.Cos(angle)
    yValues(index) = -Math.Sin(angle)
    angle = angle + Constants.Pi / 6
Next

Dim p6 As Polynomial = Polynomial.LeastSquaresFit(xValues, yValues, 4)

No code example is currently available or this language may not be supported.

let xValues = Vector.Create(7,
                fun i -> cos((float i) * Constants.Pi / 6.0))
let yValues = Vector.Create(7,
                fun i -> cos((float i) * Constants.Pi / 6.0))
let p6 = Polynomial.LeastSquaresFit(xValues, yValues, 4)
Working with polynomials

Polynomial implements all methods and properties of the Curve class, and has some extras.

The ValueAt method returns the value of the polynomial at a specified point. SlopeAt returns the derivative. Separate methods, ComplexValueAt and ComplexSlopeAt, take ComplexT arguments and return a complex number.

C#
VB
C++
F#
Copy
Console.WriteLine("p1.ValueAt(2) = {0}", p1.ValueAt(2));
Console.WriteLine("p1.SlopeAt(2) = {0}", p1.SlopeAt(2));
Complex<double> z = new Complex<double>(1, -2);
Console.WriteLine("p1.ValueAt(1-2i) = {0}", p1.ComplexValueAt(z));
Console.WriteLine("p1.ValueAt(2) = {0}", p1.ValueAt(2))
Console.WriteLine("p1.SlopeAt(2) = {0}", p1.SlopeAt(2))
Dim z = New Complex(Of Double)(1, -2)
Console.WriteLine("p1.ValueAt(1-2i) = {0}", p1.ComplexValueAt(z))

No code example is currently available or this language may not be supported.

Console.WriteLine("p1.ValueAt(2) = {0}", p1.ValueAt(2.0))
Console.WriteLine("p1.SlopeAt(2) = {0}", p1.SlopeAt(2.0))
let z = Complex<double>(1.0, -2.0)
Console.WriteLine("p1.ValueAt(1-2i) = {0}", p1.ComplexValueAt(z))

The GetDerivative method returns the polynomial that is the derivative of a polynomial. If the derivative is a constant, a line, or a quadratic curve, an instance of the corresponding type is returned.

C#
VB
C++
F#
Copy
Curve derivative = p1.GetDerivative();
Console.WriteLine("Slope at 2 (derivative) = {0}",
    derivative.ValueAt(2));
Console.WriteLine("Type of derivative: {0}",
    derivative.GetType().FullName);
Dim derivative As Curve = p1.GetDerivative()
Console.WriteLine("Slope at 2 (derivative) = {0}",
    derivative.ValueAt(2))
Console.WriteLine("Type of derivative: {0}",
    derivative.GetType().FullName)

No code example is currently available or this language may not be supported.

let derivative = p1.GetDerivative()
Console.WriteLine("Slope at 2 (derivative) = {0}",
    derivative.ValueAt(2.0))
Console.WriteLine("Type of derivative: {0}",
    derivative.GetType().FullName)

Integral evaluates the definite integral over a specified interval. The integral is calculated directly using the coefficients of the polynomial. No numerical approximations are used.

The parameters of a polynomial correspond to the coefficients of the polynomial. To make it easier to work with polynomial coefficients, an indexer property has been defined, which can be used to get and set individual coefficients directly. In Visual Basic .NET and other languages that don't support indexers, the indexed property Coefficient should be used instead.

C#
VB
C++
F#
Copy
// We create the polynomial x^3 + x^2 - x - 2:
Polynomial p = new Polynomial(new[] { 1.0, 1.0, -1.0, -2.0 }, true);
// The coefficient of x^1=x is '-1':
Console.WriteLine(p[1]);
// We can change the value of this coefficient.
p[1] = 0;
' We create the polynomial x^3 + x^2 - x - 2:
Dim p As Polynomial = New Polynomial({1, 1, -1, -2}, True)
' The coefficient of x^1=x is '-1':
Console.WriteLine(p(1))
' We can change the value of this coefficient.
p(1) = 0

No code example is currently available or this language may not be supported.

// We create the polynomial x^3 + x^2 - x - 2:
let p = Polynomial([| 1.0; 1.0; -1.0; -2.0 |], true)
// The coefficient of x^1=x is '-1':
Console.WriteLine(p.[1])
// We can change the value of this coefficient.
p.[1] <- 0.0
Operations on polynomials

The result of adding or subtracting two polynomials is a new polynomial. Similarly, the result of multiplying two polynomials is a new polynomial.

The Polynomial class implements these operations through overloaded operators. Static methods are available for languages that don't support operator overloading. The following table summarizes these operations:

Polynomial operators and their static (Shared) method equivalents

Operator

Static method equivalent

Description

+p

(no equivalent)

Returns the polynomial p.

-p

Negate

Returns the negation of the polynomial p.

p1 + p2

Add

Adds the polynomials p1 and p2.

p1 - p2

Subtract

Subtracts the polynomials p1 and p2.

p1 * p2

Multiply

Multiplies the polynomials p1 and p2.

a * p

Multiply

Multiplies the polynomial p by the real number a.

p1 / p2

Divide

Divides the polynomial p1 by p2.

p / a

Divide

Divides the polynomial p by the real number a.

p1 % p2

Modulus

Returns the remainder when dividing the polynomial p1 by p2.

The following example shows how to use these operators:

C#
VB
C++
F#
Copy
Polynomial a = new Polynomial(new[] { 2.0, -2.0, 4.0 }, true);
Polynomial b = new Polynomial(new[] { 1.0, -3.0 }, true);
Polynomial c;
Console.WriteLine("a = {0}", a.ToString());
Console.WriteLine("b = {0}", b.ToString());
c = a + b;
Console.WriteLine("a + b = {0}", c.ToString());
c = a - b;
Console.WriteLine("a - b = {0}", c.ToString());
c = a * b;
Console.WriteLine("a * b = {0}", c.ToString());
c = a / b;
Console.WriteLine("a / b = {0}", c.ToString());
c = a % b;
Console.WriteLine("a % b = {0}", c.ToString());
Dim a As Polynomial = New Polynomial({2, -2, 4}, True)
Dim b As Polynomial = New Polynomial({1, -3}, True)
Dim c As Polynomial
Console.WriteLine("a = {0}", a.ToString())
Console.WriteLine("b = {0}", b.ToString())
c = a + b
Console.WriteLine("a + b = {0}", c.ToString())
c = a - b
Console.WriteLine("a - b = {0}", c.ToString())
c = a * b
Console.WriteLine("a * b = {0}", c.ToString())
c = a / b
Console.WriteLine("a / b = {0}", c.ToString())
c = a Mod b
Console.WriteLine("a % b = {0}", c.ToString())

No code example is currently available or this language may not be supported.

let a = Polynomial([| 2.0; -2.0; 4.0 |], true)
let b = Polynomial([| 1.0; -3.0 |], true)
let mutable c : Polynomial = a
Console.WriteLine("a = {0}", a.ToString())
Console.WriteLine("b = {0}", b.ToString())
c <- a + b
Console.WriteLine("a + b = {0}", c.ToString())
c <- a - b
Console.WriteLine("a - b = {0}", c.ToString())
c <- a * b
Console.WriteLine("a * b = {0}", c.ToString())
c <- a / b
Console.WriteLine("a / b = {0}", c.ToString())
c <- a % b
Console.WriteLine("a % b = {0}", c.ToString())

As with integers, division of polynomials is not always exact. The division operator returns a polynomial such that the degree of the remainder of the division is less than the degree of the divisor.

The Divide method has an Divide that allows you to obtain both the quotient and remainder at the same time. This method takes a third out parameter that will hold the remainder.

C#
VB
C++
F#
Copy
Polynomial d;
c = Polynomial.Divide(a, b, out d);
Console.WriteLine("Using Divide method:");
Console.WriteLine("  a / b = {0}", c.ToString());
Console.WriteLine("  a % b = {0}", d.ToString());
Dim d As Polynomial
c = Polynomial.Divide(a, b, d)
Console.WriteLine("Imports  Divide method:")
Console.WriteLine("  a / b = {0}", c.ToString())
Console.WriteLine("  a % b = {0}", d.ToString())

No code example is currently available or this language may not be supported.

let (c, d) = Polynomial.Divide(a, b)
Console.WriteLine("Using Divide method:")
Console.WriteLine("  a / b = {0}", c.ToString())
Console.WriteLine("  a % b = {0}", d.ToString())

Note also that Constant, Line, and Quadratic objects can be used in polynomial expressions, as they inherit from Polynomial.

Finding roots of polynomials

A polynomial of degree n has at most n real roots, some of which may occur several times. The FindRoots method attempts to find all the real roots of a polynomial. For example, the polynomial x3 + x2 - 2 has one real root at x = 1:

C#
VB
C++
F#
Copy
Polynomial polynomial1 = new Polynomial(new[] { -2.0, 0.0, 1.0, 1.0 });
double[] roots = polynomial1.FindRoots();
Console.WriteLine("Number of roots of p: {0}", roots.Length);
Console.WriteLine("Value of root 1 = {0}", roots[0]);
Dim polynomial1 As Polynomial = New Polynomial({1, 1, 0, -2}, True)
Dim roots = polynomial1.FindRoots()
Console.WriteLine("Number of roots of p: {0}", roots.Length)
Console.WriteLine("Value of Dim 1 As root = {0}", roots(0))

No code example is currently available or this language may not be supported.

let polynomial1 = Polynomial([| 1.0; 1.0; 0.0; -2.0 |], true)
let roots = polynomial1.FindRoots()
Console.WriteLine("Number of roots of p: {0}", roots.Length)
Console.WriteLine("Value of root 1 = {0}", roots.[0])

In the complex domain, a polynomial of degree n always has n roots. The Polynomial class defines the FindComplexRoots method, which returns an array of ComplexT numbers that are the approximate roots of the polynomial.

C#
VB
C++
F#
Copy
Polynomial polynomial2 = new Polynomial(new[] { -2.0, 0.0, 1.0, 1.0 });
Complex<double>[] roots = polynomial2.FindComplexRoots();
Console.WriteLine("Number of roots of p: {0}", roots.Length);
Console.WriteLine("Value of root 1 = {0}", roots[0]);
Console.WriteLine("Value of root 2 = {0}", roots[1]);
Console.WriteLine("Value of root 3 = {0}", roots[2]);
Dim polynomial2 As Polynomial = New Polynomial({1, 1, 0, -2}, True)
Dim roots() As Complex(Of Double) = polynomial2.FindComplexRoots()
Console.WriteLine("Number of roots of p: {0}", roots.Length)
Console.WriteLine("Value of root 1 = {0}", roots(0))
Console.WriteLine("Value of root 2 = {0}", roots(1))
Console.WriteLine("Value of root 3 = {0}", roots(2))

No code example is currently available or this language may not be supported.

let polynomial2 = Polynomial([| 1.0; 1.0; -1.0; -2.0 |], true)
let roots = polynomial2.FindComplexRoots();
Console.WriteLine("Number of roots of p: {0}", roots.Length);
Console.WriteLine("Value of root 1 = {0}", roots.[0]);
Console.WriteLine("Value of root 2 = {0}", roots.[1]);
Console.WriteLine("Value of root 3 = {0}", roots.[2]);

The roots are returned in order of increasing real part and, if the real parts are equal, increasing imaginary part.

Copyright (c) 2004-2021 ExoAnalytics Inc.

Send comments on this topic to support@extremeoptimization.com

Copyright © 2004-2021, Extreme Optimization. All rights reserved.
Extreme Optimization, Complexity made simple, M#, and M Sharp are trademarks of ExoAnalytics Inc.
Microsoft, Visual C#, Visual Basic, Visual Studio, Visual Studio.NET, and the Optimized for Visual Studio logo
are registered trademarks of Microsoft Corporation.