Click here to Skip to main content
15,892,575 members
Articles / Programming Languages / Visual C++ 10.0

Polynomial Equation Solver

Rate me:
Please Sign up or sign in to vote.
4.96/5 (46 votes)
29 Mar 2013CPOL17 min read 170.5K   12.9K   103  
Solves 1st, 2nd, 3rd and 4th degree polynominal by explicid fomulas for real coefficients and any degree by the numerical Jenkins-Traub algorithm with real and complex coefficients.
Imports System.Numerics
Imports System.Text.RegularExpressions
Imports System.Globalization

Class MainWindow

    'RegEx for Real and Complex numbers
    Dim Real As String = "(?<!([E][+-][0-9]+))([-]?\d+\.?\d*([E][+-]" & _
             "[0-9]+)?(?!([i0-9.E]))|[-]?\d*\.?\d+([E][+-][0-9]+)?)(?![i0-9.E])"
    Dim Img As String = "(?<!([E][+-][0-9]+))([-]?\d+\.?\d*([E][+-]" & _
            "[0-9]+)?(?![0-9.E])(?:i)|([-]?\d*\.?\d+)?([E][+-][0-9]+)?\s*(?:i)(?![0-9.E]))"

    Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
        Dim res As New List(Of Complex)

        Dim arrString As String() = TextBox1.Text.Split(New Char() {","c})
        Dim ComplexCoefficients(arrString.Length - 1) As Complex '() = New Complex()(arrString.Length - 1) {}
        Dim RealCoefficients() = New Double(arrString.Length - 1) {}
        Dim i As Integer = 0

        Dim lst As New List(Of Complex)

        Dim boolReal As New Boolean
        boolReal = True

        While i < arrString.Length
            Dim Number As New Complex
            Number = GenerateComplexNumberFromString(arrString(i))
            ComplexCoefficients(i) = Number
            RealCoefficients(i) = Number.Real

            If Number.Imaginary <> 0 Then boolReal = False

            i += 1
        End While

        Try
            If boolReal Then
                res = RealPolynomialRootFinder.FindRoots(RealCoefficients)
            Else
                res = ComplexPolynomialRootFinder.FindRoots(ComplexCoefficients)
            End If


            TextBox2.Text = ""
            For Each p As Complex In res
                'Give a more legiable format on the complex numbers
                TextBox2.Text &= String.Format(New ComplexFormatter(), "{0:I0}", p) & vbCrLf
            Next

        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try

    End Sub

    Private Function GenerateComplexNumberFromString(ByVal input As String) As Complex
        input = input.Replace(" ", "")

        Dim Number As String = "((?<Real>(" & Real & "))|(?<Imag>(" & Img & ")))"
        Dim Re, Im As Double
        Re = 0
        Im = 0

        For Each Match As Match In Regex.Matches(input, Number)


            If Not Match.Groups("Real").Value = String.Empty Then
                Re = Double.Parse(Match.Groups("Real").Value, CultureInfo.InvariantCulture)
            End If


            If Not Match.Groups("Imag").Value = String.Empty Then
                If Match.Groups("Imag").Value.ToString.Replace(" ", "") = "-i" Then
                    Im = Double.Parse("-1", CultureInfo.InvariantCulture)
                ElseIf Match.Groups("Imag").Value.ToString.Replace(" ", "") = "i" Then
                    Im = Double.Parse("1", CultureInfo.InvariantCulture)
                Else
                    Im = Double.Parse(Match.Groups("Imag").Value.ToString.Replace("i", ""), _
                                      CultureInfo.InvariantCulture)
                End If
            End If
        Next

        Dim result As New Complex(Re, Im)
        Return result
    End Function

    Private Sub TextBox1_TextChanged(sender As System.Object, e As System.Windows.Controls.TextChangedEventArgs)
        If TextBox1.Focus Then
            Dim imput As String = TextBox1.Text.Trim
            If Not imput = "" Then
                txtFormula.Text = ""
                Dim FormulaCoefficients() As String
                If imput.Contains(",") Then
                    FormulaCoefficients = imput.Split(",")
                    Dim ResultingExpression As New List(Of String)
                    Dim degree As Integer = 0
                    For i As Integer = FormulaCoefficients.Count - 1 To 0 Step -1

                        If FormulaCoefficients(i) <> "" Then
                            If Not FormulaCoefficients(i).Trim = "0" Then
                                If degree = 0 Then
                                    ResultingExpression.Add(" + (" & String.Format(New ComplexFormatter(), "{0:I0}", GenerateComplexNumberFromString(FormulaCoefficients(i))) & ")")

                                ElseIf degree = 1 Then
                                    ResultingExpression.Add(" + (" & String.Format(New ComplexFormatter(), "{0:I0}", GenerateComplexNumberFromString(FormulaCoefficients(i))) & ")*x")
                                Else
                                    ResultingExpression.Add(" + (" & String.Format(New ComplexFormatter(), "{0:I0}", GenerateComplexNumberFromString(FormulaCoefficients(i))) & ")*x^" & degree)
                                End If
                            End If
                        End If
                            degree += 1
                    Next

                    ' ResultingExpression(ResultingExpression.Count - 1) = ResultingExpression(ResultingExpression.Count - 1).Trim.Replace("+", "")

                    Dim output As String = ""
                    For j As Integer = ResultingExpression.Count - 1 To 0 Step -1
                        output &= ResultingExpression(j)
                    Next

                    txtFormula.Text = output & " = 0 "
                Else
                    txtFormula.Text = imput & " = 0 "
                End If

            Else
                txtFormula.Text = ""
            End If
        End If
    End Sub

End Class

Public Class ComplexFormatter
    Implements IFormatProvider, ICustomFormatter

    Public Function GetFormat(ByVal formatType As Type) As Object _
                    Implements IFormatProvider.GetFormat
        If formatType Is GetType(ICustomFormatter) Then
            Return Me
        Else
            Return Nothing
        End If
    End Function

    Public Function Format(ByVal fmt As String, ByVal arg As Object,
                           ByVal provider As IFormatProvider) As String _
                    Implements ICustomFormatter.Format
        If TypeOf arg Is Complex Then
            Dim c1 As Complex = DirectCast(arg, Complex)
            ' Check if the format string has a precision specifier.
            Dim precision As Integer
            Dim fmtString As String = String.Empty
            If fmt.Length > 1 Then
                Try
                    precision = Int32.Parse(fmt.Substring(1))
                Catch e As FormatException
                    precision = 0
                End Try
                fmtString = "N" + precision.ToString()
            End If
            If fmt.Substring(0, 1).Equals("I", StringComparison.OrdinalIgnoreCase) Then
                Dim s As String = ""
                If c1.Imaginary = 0 And c1.Real = 0 Then
                    s = "0"
                ElseIf c1.Imaginary = 0 Then
                    s = c1.Real.ToString("r")
                ElseIf c1.Real = 0 Then
                    s = c1.Imaginary.ToString("r") & "i"
                Else
                    If c1.Imaginary >= 0 Then
                        s = [String].Format("{0}+{1}i", c1.Real.ToString("r"), c1.Imaginary.ToString("r"))
                    Else
                        s = [String].Format("{0}-{1}i", c1.Real.ToString("r"), Math.Abs(c1.Imaginary).ToString("r"))
                    End If
                End If
                Return s.Replace(",", ".")
            ElseIf fmt.Substring(0, 1).Equals("J", StringComparison.OrdinalIgnoreCase) Then
                Return c1.Real.ToString(fmtString) + " + " + c1.Imaginary.ToString(fmtString) + "j"
            Else
                Return c1.ToString(fmt, provider)
            End If
        Else
            If TypeOf arg Is IFormattable Then
                Return DirectCast(arg, IFormattable).ToString(fmt, provider)
            ElseIf arg IsNot Nothing Then
                Return arg.ToString()
            Else
                Return String.Empty
            End If
        End If
    End Function
End Class

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Chief Technology Officer
Norway Norway
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions