Function PolyFact(ByVal MatX As Range, ByVal I As Long, Optional ByVal R As Variant = 3)
'Factorisation d'un polynome de la forme
'Y = C1*X^n + Ci*X^(n-1) + ... + Cn.
'en Y=(X+Xo)(X+Xi)...(X+Xn)
'i = numero de la solution Xi
'r = arrondi des résultats à l'affichage
'Traitement de l'arrondi
R = CLng(R)
'Tailles matrices
Dim l As Long, C As Long, N As Long
l = MatX.Rows.Count
C = MatX.Columns.Count
'Erreur de taille
If C > 1 Then PolyFact = "#COLONNE!": Exit Function
N = l - 1
If N = 0 Then PolyFact = "#DEGRE!": Exit Function
If I > N Then PolyFact = "#INDICE!": Exit Function
'Variable et tableau
ReDim A(N), B(N), sig(N), reel(N), imagi(N)
'Tableau des coeffs
Dim t As Long
For t = N To 0 Step -1
A(t) = MatX.Cells(t + 1)
Next t
'Résolution Bairstow
Dim S As Double, P As Double, D As Double, DS As Double
Dim DP As Double, S1 As Double, P1 As Double, Er As Double
Dim delta As Double, k As Long
If N > 2 Then
Do
S = 0: P = 0
Do
B(0) = A(0): B(1) = A(1) + S * B(0): B(2) = A(2) + S * B(1) - P * B(0)
sig(0) = 0: sig(1) = B(0): sig(2) = B(1) + S * sig(1)
For k = 3 To N
B(k) = A(k) + S * B(k - 1) - P * B(k - 2)
sig(k) = B(k - 1) + S * sig(k - 1) - P * sig(k - 2)
Next k
D = sig(N) * sig(N - 2) - sig(N - 1) ^ 2
If D = 0 Then D = 1
DS = B(N - 1) * sig(N - 1) - B(N) * sig(N - 2)
If DS = 0 Then DS = 1 + 0.000000000001
DP = B(N - 1) * sig(N) - B(N) * sig(N - 1)
If DP = 0 Then DP = 1
S1 = S + DS / D: P1 = P + DP / D
Er = (Abs(S1 - S) + Abs(P1 - P)) / (Abs(S1) + Abs(P1))
S = S1: P = P1
Loop Until Er < 0.000000001
GoSub resolution
N = N - 2
For t = 0 To N: A(t) = B(t): Next t
Loop Until N <= 2
End If
If N = 2 Then
S = -A(1) / A(0): P = A(2) / A(0)
GoSub resolution
Else
reel(1) = -A(1) / A(0): imagi(1) = 0
End If
'Affichage de la solution
reel(I) = WorksheetFunction.Round(-reel(I), R)
imagi(I) = WorksheetFunction.Round(-imagi(I), R)
Select Case reel(I)
Case Is <> 0
Select Case imagi(I)
Case Is < 0
PolyFact = reel(I) & imagi(I) & "i"
Case Is > 0
PolyFact = reel(I) & "+" & imagi(I) & "i"
Case Else
PolyFact = reel(I)
End Select
Case Else
Select Case imagi(I)
Case Is <> 0
PolyFact = imagi(I) & "i"
Case Else
PolyFact = "0"
End Select
End Select
Exit Function
'Résolution du polynôme du second degré
resolution:
delta = S ^ 2 - 4 * P
If delta >= 0 Then
reel(N) = 0.5 * (S + Sqr(delta) * Sgn(S))
reel(N - 1) = P / reel(N)
imagi(N) = 0
imagi(N - 1) = 0
Else
reel(N) = S / 2
reel(N - 1) = S / 2
imagi(N) = Sqr(-delta) / 2
imagi(N - 1) = -imagi(N)
End If
Return
End Function