User Tools

Site Tools


k29:k29.3:k29.3.4:start

29.3.4 Polynomial class

The Polynomial class from gb.gsl implements a polynomial with real or complex coefficients. It acts like a read/write array and can be used like a function. The Polynomial class has two properties and three methods.

29.3.4.1 Polynomial class

A polynomial or, better, a polynomial function P(x) can be defined as follows

B1

  • The real or complex numbers ai are called coefficients.
  • The natural numbers n, n-1, n-2, …,1 and 0 are possible exponents.
  • The largest value of the exponents determines the degree of the polynomial.
  • The Ti is referred to as a term or monomial with Tk = akxk .
  • Polynomial and polynomial function P(x) are used synonymously.

29.3.4.2 Properties

The Polynomial class has two properties:

PropertyData typeDescription
CountIntegerReturns the number of coefficients.
DegreeIntegerReturns the degree of the polynomial as the value (n ≥ 0 , n Î N) of the largest exponent.

Table 29.3.4.2.1 : Properties of the Polynomial class

29.3.4.3 Methods

The Polynomial class has these three methods:

MethodReturn typeDescription
Eval ( x As Variant )VariantCalculates the value of a polynomial P(x) for the given argument x.
Solve ( [ Complex As Boolean ] )ArrayThe real roots of the polynomial with P(x)=0 are calculated and returned.
ToString ( [ Local As Boolean ] )StringThe polynomial is returned as a string representation.

Table 29.3.4.3.1 : Methods of the Polynomial class

Notes:

  • The return type of the Eval (..) method is of type Variant, because the value of a polynomial function P(x) can be a real or a complex number.
  • If no roots are found, an empty array is returned. If P(x) = 0 has the following structures, the roots are calculated exactly:
x³ + a*x² + b*x + c = 0  OR
a*x² + b*x + c = 0 
  • In all other cases, approximation methods are used that do not necessarily converge for the (internally) set start value! In these (divergent) cases, an error is triggered. The occurrence of several equal roots is not emphasised as something special, as for example in the equation (x-1)³ = 0, which has exactly three equal real roots as solutions.
  • All root values as solutions of P(x)=0 must be checked at the end (probe).
  • Often only one sufficiently exact solution is output for the solutions - for example for the equation x³-x=0 with x2= -7.0705015914994E-17 - while the other two solutions with x1=-1 and x3=+1 provide exact root values.
  • If the Local parameter has the value True, the numbers are output in the local notation, while the default value False formats the string so that it can be evaluated by the Eval(..) function.

29.3.4.4 Creating polynomials

There are several ways to generate polynomials:

  • Declaration of a variable of the data type polynomial with direct value assignment.
  • Declaration of a variable of data type polynomial and subsequent assignment of the coefficients in an array (with increasing powers and comma as separator), whereby missing terms must be represented by 0! The degree of the term results from its position in the array.
  • Conversion of a character string from a suitable (input) component into a polynomial.

Example of the implementation of the first two options using the Count and Degree properties and the ToString(..) method:

Dim pPolynom1 As Polynomial = [-8.88, 1, 0, 0, 0.44, -6.66] ' Option 1
Dim pPolynom2 As Polynomial ' Option 2.1
Dim aRoots As Complex[]
Dim iCount As Integer
 
Print "Polynom 1 = ";; pPolynom1
Print "Polynom 1 = ";; pPolynom1.ToString(True)
Print "Polynom 1 = ";; pPolynom1.ToString() ' False is standard parameter, input optional
Print pPolynom1.Degree  ' Degree of the polynomial
Print pPolynom1.Count   ' Number of terms of the polynomial
 
pPolynom2 = [-9, -9, 1, 1] ' Option 2.2
Print "Polynom 2 = ";; pPolynom2
Print "Polynom 2 = ";; pPolynom2.ToString(True)
Print "Polynom 2 = ";; pPolynom2.ToString()

This is the output in the console of the Gambas IDE:

[1] Polynom 1 =  -6,66x^5+0,44x^4+x-8,88
[2] Polynom 1 =  -6,66x^5+0,44x^4+x-8,88
[3] Polynom 1 =  -6.66*x^5+0.44*x^4+x-8.88
[4] 5
[5] 6
[6] Polynom 2 =  x^3+x^2-9x-9
[7] Polynom 2 =  x^3+x^2-9x-9
[8] Polynom 2 =  x^3+x^2-9*x-9

29.3.4.5 Calculating the function value of a polynomial function P(x)

The calculation of the function value of a polymom function P(x) is shown for real and complex arguments:

Dim pPolynom2, pPolynom3 As Polynomial
 
pPolynom2 = [-9, -9, 1, 1]
Print "Polynom 2 = ";; pPolynom2.ToString(True)
Print "P2(2,34) = "; Eval(pPolynom2.ToString(False), ["x": 2.34]) 	'-- Real argument
Print
pPolynom3 = [-9i, 2, 1 - 2i]
Print "Polynom 3 = ";; pPolynom3.ToString(False)
Print "P3(1+i) = "; Eval(pPolynom3.ToString(False), ["x": 1 + 1i]) 	'-- Complex argument

Here are the outputs:

[1] Polynom 2 =  x^3+x^2-9x-9
[2] P2(2,34) = -11,771496
[3] 
[4] Polynom 3 =  (1-2i)*x^2+2*x-9i
[5] P3(1+i) = 6-5i

29.3.4.6 Calculating the zeros of a polynomial function

The calculation of the zeros of a polynomial function or the calculation of the solutions of a polynomial equation leads to P(x)=0.

  • The success of the Solve(..) method is dependent on this condition: All coefficients in the polynomial function P(x) are real numbers, otherwise an error is triggered!
  • If the Complex parameter is True, all complex roots are calculated and returned in an array. If the Complex parameter is False, then only the existing real roots are calculated and returned in an array.

The calculation of the solutions of P(x)=0 is shown for real and complex arguments:

Dim pPolynom2, pPolynom4 As Polynomial
Dim aRoots As Complex[]
Dim iCount As Integer
 
pPolynom2 = [-9, -9, 1, 1]
Print "Polynom 2 = ";; pPolynom2.ToString(True)
aRoots = pPolynom2.Solve(False) '-- Only real roots
  For iCount = 0 To aRoots.Max
      Print "Root_" & CInt(iCount + 1) & " = " & aRoots[iCount]
  Next
Print
pPolynom4 = [4, 0, 1]
Print "Polynom 4 = ";; pPolynom4.ToString(True)
aRoots = pPolynom4.Solve(True) '-- Only complex roots
  For iCount = 0 To aRoots.Max
      Print "Root_" & CInt(iCount + 1) & " = " & aRoots[iCount]
  Next

In the console of the Gambas IDE you then read:

Polynom 2 =  x^3+x^2-9x-9
Wurzel_1 = -3
Wurzel_2 = -1
Wurzel_3 = 3
 
Polynom 4 =  x^2+4
Wurzel_1 = -2i
Wurzel_2 = 2i

If you set aRoots = pPolynom4.Solve(True) for aRoots = pPolynom4.Solve(False), you get the empty set as the solution set - or an empty array in Gambas - because there are no real solutions for the power function P(x)=x⁴+4=0.

29.3.4.7 Example

The following example implements the third variant for generating a polynomial by converting a character string from a suitable (input) component - here InputBox - into a polynomial. At the heart of the third variant are the following two functions, which check whether a character string can be interpreted as a polynomial and also determine the coefficients of a polynomial function P(x) - provided the input character string can be interpreted as a polynomial - whereby only real coefficients are permitted:

Private Function ValPolynomial(sInput As String) As Polynomial '-- Tobias Boege 
Private Function IsPolynomial(sInput As String) As Boolean

Here is the complete, sufficiently commented source code:

' Gambas class file
 
Private $pP1 As Polynomial
Private $pP2 As Polynomial
Private $pResult As Polynomial
 
Public Sub Form_Open()
 
  FMain.Center
  FMain.Resizable = False
' txbInputPolynom1.Clear()
' txbInputPolynom2.Clear()
  txbInputPolynom1.SetFocus()
' http://de.wikipedia.org/wiki/Unicodeblock_Mathematische_Operatoren
  btnAddieren.Text = " Adding polynomials  " & String.Chr(8853) 
  btnSubtrahieren.Text = " Subtract polynomials  " & String.Chr(8854)
 
End
 
Public Sub btnConvert_Click()  
 
  If txbInputPolynom1.Text Then 
     txbOutputPolynom.Clear()
     Try txbOutputPolynom.Text = ValPolynomial(txbInputPolynom1.Text).ToString()
     If Error Then
        Message.Error("The string for P1(x) cannot be interpreted as a polynomial!")
        txbInputPolynom1.SetFocus
     Endif
  Endif
End
 
Public Sub txbInputPolynom1_Activate()
  btnConvert_Click()
End
 
Public Sub txbInputPolynom1_KeyPress()
  CheckInput("+-,.^0123456789x")
End
 
Public Sub txbInputPolynom2_KeyPress()
  CheckInput("+-,.^0123456789x")
End
 
Public Sub btnIsPolynomial_Click()
 
  If txbInputPolynom1.Text Then 
  If IsPolynomial(txbInputPolynom1.Text) = True Then
     Message.Info("The input string for P1(x) can be interpreted as a polynomial!")
  Else
     Message.Error("The input string for P1(x) can NOT be interpreted as a polynomial!")
        txbInputPolynom1.SetFocus
     Endif
  Endif
 
End
 
Public Sub btnAddieren_Click()
  If txbInputPolynom1.Text And txbInputPolynom2.Text Then 
  If (IsPolynomial(txbInputPolynom1.Text) = True) And (IsPolynomial(txbInputPolynom2.Text) = True) Then
        $pP1 = ValPolynomial(txbInputPolynom1.Text)
        $pP2 = ValPolynomial(txbInputPolynom2.Text)
        $pResult = $pP1 + $pP2
        txbOutputPolynom.Text = $pResult.ToString()
     Else
        Message.Error("At least one input string cannot be interpreted as a polynomial!")
     Endif
  Endif
End 
 
Public Sub btnSubtrahieren_Click()
  If txbInputPolynom1.Text And txbInputPolynom2.Text Then 
     If (IsPolynomial(txbInputPolynom1.Text) = True) And (IsPolynomial(txbInputPolynom2.Text) = True) Then
        $pP1 = ValPolynomial(txbInputPolynom1.Text)
        $pP2 = ValPolynomial(txbInputPolynom2.Text)
        $pResult = $pP1 - $pP2
        txbOutputPolynom.Text = $pResult.ToString()
     Else
        Message.Error("At least one input string cannot be interpreted as a polynomial!")
     Endif
  Endif
End
 
Public Sub btnVergleichen_Click()
  If txbInputPolynom1.Text And txbInputPolynom2.Text Then 
     If (IsPolynomial(txbInputPolynom1.Text) = True) And (IsPolynomial(txbInputPolynom2.Text) = True) Then
        If ValPolynomial(txbInputPolynom1.Text) = ValPolynomial(txbInputPolynom2.Text) Then
           txbOutputPolynom.Text = "P1(x) und P2(x) sind gleich!"
        Else
           txbOutputPolynom.Text = "P1(x) and P2(x) are NOT the same!"
        Endif
     Else
        Message.Error("At least one input string cannot be interpreted as a polynomial!")
     Endif 
  Endif
End
 
'*********************************************************************************************************
 
Public Sub txbInputPolynom1_Change()
  txbOutputPolynom.Clear
End
 
Public Sub txbInputPolynom2_Change()
  txbOutputPolynom.Clear
End
 
Public Sub CheckInput(sAllowed As String) '-- Concept Charles Guerin 
 
  Select Case Key.Code
    Case Key.Left, Key.Right, Key.BackSpace, Key.Delete, Key.End, Key.Home, Key.Enter, Key.Return
      Return
    Default
      If Key.Text And If InStr(sAllowed, Key.Text) Then
         Return
      Endif
  End Select
  Stop Event
 
End
 
Private Function ValPolynomial(sInput As String) As Polynomial
  Dim hRegexp As New RegExp
  Dim hPolynom As New Polynomial(1)
  Dim fKoeffizient As Float
  Dim iExponent As Integer
  Dim sMiddle As String
 
' Replace the decimal separator of the current locale - here de - with the dot
  sInput = Replace$(sInput, Left$(Format$(0, ".0")), ".")
' Normalise the input: The first term (monomial) in the polynomial requires a sign
  If Left$(sInput) Not Like "[+-]" Then sInput = "+" & sInput
  hRegexp.Compile("([+-][0-9]+(\\.[0-9]+)?)(x)?(\\^([0-9]+))?|[+-]x(\\^([0-9]+))?")
  hRegexp.Exec(sInput)
 
  While hRegexp.Offset <> -1
' If no coefficient is entered in the term, then coefficient = 1,
' If no exponent is entered in the term, then exponent = 1,
' If the argument x is not contained in the term, then exponent = 0.
    If hRegexp[0].Text Like "[+-]x*" Then
      fKoeffizient = IIf(hRegexp.Text Begins "+", 1.0, -1.0)
      If hRegexp.Count = 7 Then
        iExponent = CInt(Right$(hRegexp[6].Text, -1))
      Else
        iExponent = 1
      Endif
    Else
      fKoeffizient = CFloat(hRegexp[1].Text)
      If hRegexp.Count = 5 Then
        iExponent = CInt(Right$(hRegexp[4].Text, -1))
      Else If hRegexp.Count = 3 Then
        iExponent = 1
      Else
        iExponent = 0
      Endif
    Endif
    hPolynom[iExponent] += fKoeffizient
    sMiddle =  Mid$(sInput, hRegexp.Offset
    sInput = Mid$(sInput, 1, hRegexp.Offset) & sMiddle + Len(hRegexp[0].Text) + 1)
    If Not sInput Then Return hPolynom
    hRegexp.Exec(sInput)
  Wend
 
  Finally
    Return Null
End
 
Private Function IsPolynomial(sInput As String) As Boolean
  Dim sPattern, sTerm As String
  Dim aResult, aTmp As New String[]
  Dim iI, iJ As Integer
  Dim sExpression As String
 
  sInput = Trim(sInput)
  sInput = Replace$(sInput, Left$(Format$(0, ".0")), ".")
' Separate all terms linked by +
  aResult = Split(sInput, "+", "", True)
' While loop instead of For loop, because aResult is modified in the loop
  iI = 0
  While iI < aResult.Count
' First replicate the sign on the term (-> restore)
    sExpression = IIf(aResult[iI] Not Begins "-", "+", "") & aResult[iI]
  ' The polynomial P(x) is then replaced by an array of simple terms
    aResult.Remove(iI)
  ' Then separate all terms linked by -
    aTmp = Split(sExpression, "-", "", True)
    For iJ = 0 To aTmp.Max
      aTmp[iJ] = IIf(aTmp[iJ] Not Begins "+", "-", "") & aTmp[iJ]
    Next
  ' Finally, the array of simple terms takes the place of sExpression
    aResult.Insert(aTmp, iI)
    iI += aTmp.Count
  Wend
 
  sPattern = "^[+-]?([0-9]+(\\.[0-9]+)?)?(x([\\^][0-9]+)?)?$"
 
  For Each sTerm In aResult
    If sTerm Not Match sPattern Then
       Return False
    Endif ' Match Pattern
  Next ' sTerm
 
  Return True
 
End

The example also demonstrates the addition, subtraction and comparison of two polynomials:

B

Figure 29.3.4.7.1: Generating polynomials

The function

Private Function ValPolynomial(sInput As String) As Polynomial ' Tobias Boege 

function also contains an internal check (→ While hRegexp.Offset <> -1) as to whether the character string passed as an argument can be interpreted as a polynomial. This is not necessary here because only valid character strings are passed to this function in the programme presented.

You can use the above function

Private Function IsPolynomial(sInput As String) As Boolean

with the following function:

' IsPolynomial() uses the same procedure as ValPolynomial() above.
' It is therefore not significantly faster than the comparison ValPolynomial = zero.
Private Function IsPolynomial(sInput As String) As Boolean 
  sInput = Replace$(sInput, Left$(Format$(0, ".0")), ".") 
  If Left$(sInput) Not Like "[+-]" Then sInput = "+" & sInput 
 
  $hRegexp.Exec(sInput) 
  While $hRegexp.Offset <> -1 
    sInput = Mid$(sInput, 1, $hRegexp.Offset) & Mid$(sInput, $hRegexp.Offset + Len($hRegexp[0].Text) + 1) 
    If Not sInput Then Return True 
    $hRegexp.Exec(sInput) 
  Wend 
 
  Finally 
    Return False 
End

Download

Chapter & Projects

Download

The website uses a temporary session cookie. This technically necessary cookie is deleted when the browser is closed. You can find information on cookies in our privacy policy.
k29/k29.3/k29.3.4/start.txt · Last modified: 17.02.2024 by emma

Page Tools