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