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.
A polynomial or, better, a polynomial function P(x) can be defined as follows
The Polynomial class has two properties:
Property | Data type | Description |
---|---|---|
Count | Integer | Returns the number of coefficients. |
Degree | Integer | Returns 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
The Polynomial class has these three methods:
Method | Return type | Description |
---|---|---|
Eval ( x As Variant ) | Variant | Calculates the value of a polynomial P(x) for the given argument x. |
Solve ( [ Complex As Boolean ] ) | Array | The real roots of the polynomial with P(x)=0 are calculated and returned. |
ToString ( [ Local As Boolean ] ) | String | The polynomial is returned as a string representation. |
Table 29.3.4.3.1 : Methods of the Polynomial class
Notes:
x³ + a*x² + b*x + c = 0 OR a*x² + b*x + c = 0
There are several ways to generate polynomials:
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
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
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 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.
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:
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
Chapter & Projects