Mathematik mit VBA - Teil 2: komplexe Zahlen und Nullstellen ganzrationaler Funktionen

    • VBA: Sonstige

    Es gibt 25 Antworten in diesem Thema. Der letzte Beitrag () ist von Mono.

      Mathematik mit VBA - Teil 2: komplexe Zahlen und Nullstellen ganzrationaler Funktionen

      Folgende Elemente aus dem 1. Teil werden hier verwendet:
      (Mathematik mit VBA - Teil 1)

      Visual Basic-Quellcode

      1. Function Divisionsrest '(indirekt: wird von ggT benötigt)
      2. Function ggT '(wird von der Funktion Nullstellen_Array benötigt)



      Rechnen mit komplexen Zahlen

      Wenn man eine Zahl mit geradem Exponenten potenziert, erhält man als Ergebnis immer eine positive Zahl, z. B. 2²=4, (-2)²=4. Daher gibt es für eine gerade Wurzel einer negativen Zahl keine reelle Lösung. Es gibt jedoch die imaginäre Einheit i, die durch i²=-1 definiert ist.

      Eine komplexe Zahl erhält man, indem man zu einer reellen Zahl (Realteil) ein Vielfaches von i (Imaginärteil) addiert. Beispiele: 2*i (=Sqr(-4)), 1+1,5*i. In der komplexen Zahlenebene sind auf der „x-Achse“ die reellen Zahlen abgebildet, auf der „y-Achse“ die imaginären Zahlen. Realteil und Imaginärteil stellen also kartesische Koordinaten der komplexen Zahlenebene dar.

      Man kann eine komplexe Zahl aber auch durch Polarkoordinaten darstellen: Wenn man den Punkt in der Zahlenebene, der die komplexe Zahl darstellt, mit dem Null-Punkt verbindet, erhält man durch die Länge dieser Strecke den Betrag der komplexen Zahl. Der Winkel, den diese Strecke mit der positiven reellen Achse bildet, stellt das Argument der komplexen Zahl dar. Die Polarkoordinaten sind vor allem nützlich, wenn man Potenzen und Wurzeln von komplexen Zahlen berechnen will. Da für das Argument nur Winkel von 0° bis <360° (sprich 2*pi) Sinn machen, habe ich eine Funktion gemacht, die den Winkel in diesen Bereich verlagert (Winkel2pi).

      Hier zunächst grundlegende Datentypen und Funktionen:

      Visual Basic-Quellcode

      1. Type komplexK
      2. 'Typ für komplexe Zahlen mit Angabe von kartesischen Koordinaten.
      3. 'Entspricht der Form z=a+b*i (a=Realteil, b=Imaginärteil)
      4. Realteil As Double
      5. Imaginärteil As Double
      6. End Type
      7. Type komplexP
      8. 'Typ für komplexe Zahlen mit Angabe von Polarkoordinaten.
      9. 'Entspricht der Form z=r*(cos(phi)+sin(phi)*i) (r=Betrag, phi=Argument)
      10. Betrag As Double
      11. Argument As Double
      12. End Type


      Visual Basic-Quellcode

      1. Function pi() As Double
      2. pi = 4 * Atn(1)
      3. End Function
      4. Function Winkel2pi(Winkel As Double) As Double
      5. 'Sorgt dafür, dass "Winkel" im Bereich 0 <= Winkel < 2pi ist.
      6. Winkel2pi = (Winkel / (2 * pi) - Int(Winkel / (2 * pi))) * (2 * pi)
      7. End Function
      8. Function kompTextK(z As komplexK) As String
      9. 'Liefert einen String, der "z" in der Form a+b*i darstellt.
      10. '(ausgehend von kartesischen Koordinaten)
      11. Dim Text1 As String, Text2 As String, TextMitte As String
      12. If Abs(z.Realteil) < 10 ^ -15 Then z.Realteil = 0
      13. If Abs(z.Imaginärteil) < 10 ^ -15 Then z.Imaginärteil = 0
      14. If z.Realteil = 0 Then Text1 = "" Else Text1 = z.Realteil
      15. Select Case Abs(z.Imaginärteil)
      16. Case 0: Text2 = ""
      17. Case 1: Text2 = "i"
      18. Case Else: Text2 = Abs(z.Imaginärteil) & " · i"
      19. End Select
      20. Select Case Sgn(z.Imaginärteil)
      21. Case 0: TextMitte = ""
      22. Case 1: If Text1 = "" Then TextMitte = "" Else TextMitte = " + "
      23. Case -1: If Text1 = "" Then TextMitte = "-" Else TextMitte = " " & Chr(150) & " "
      24. End Select
      25. kompTextK = Text1 & TextMitte & Text2
      26. If kompTextK = "" Then kompTextK = "0"
      27. End Function
      28. Function kompTextP(z As komplexP) As String
      29. 'Liefert einen String, der "z" in der Form a+b*i darstellt.
      30. '(ausgehend von Polarkoordinaten)
      31. kompTextP = kompTextK(PnachK(z))
      32. End Function
      33. Function KnachP(z As komplexK) As komplexP
      34. 'Rechnet kartesische Koordinaten in Polarkoordinaten um.
      35. KnachP.Betrag = Sqr(z.Realteil ^ 2 + z.Imaginärteil ^ 2)
      36. If z.Realteil = 0 And z.Imaginärteil = 0 Then
      37. KnachP.Argument = Empty
      38. ElseIf z.Imaginärteil = 0 Then
      39. If z.Realteil > 0 Then KnachP.Argument = 0 Else KnachP.Argument = pi
      40. ElseIf z.Realteil = 0 Then
      41. If z.Imaginärteil > 0 Then KnachP.Argument = pi / 2 Else KnachP.Argument = pi * 3 / 2
      42. Else
      43. KnachP.Argument = Atn(z.Imaginärteil / z.Realteil)
      44. If z.Realteil < 0 Then KnachP.Argument = KnachP.Argument + pi
      45. KnachP.Argument = Winkel2pi(KnachP.Argument)
      46. End If
      47. End Function
      48. Function PnachK(z As komplexP) As komplexK
      49. 'Rechnet Polarkoordinaten in kartesische Koordinaten um.
      50. If z.Betrag < 0 Then MsgBox "Ungültiger Parameterwert", vbCritical: Stop
      51. If z.Betrag = 0 Then
      52. PnachK.Realteil = 0
      53. PnachK.Imaginärteil = 0
      54. Else
      55. PnachK.Realteil = z.Betrag * Cos(z.Argument)
      56. PnachK.Imaginärteil = z.Betrag * Sin(z.Argument)
      57. End If
      58. End Function
      59. Function konjugiertK(z As komplexK) As komplexK
      60. 'Liefert die konjugiert komplexe Zahl zu "z".
      61. konjugiertK.Realteil = z.Realteil
      62. konjugiertK.Imaginärteil = -z.Imaginärteil
      63. End Function
      64. Function konjugiertP(z As komplexP) As komplexP
      65. 'Liefert die konjugiert komplexe Zahl zu "z".
      66. konjugiertP = KnachP(konjugiertK(PnachK(z)))
      67. End Function

      Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „roddy“ ()

      Hier Rechenoperationen unter Verwendung von kartesischen Koordinaten:

      Visual Basic-Quellcode

      1. Function kompAddK(z1 As komplexK, z2 As komplexK) As komplexK
      2. 'Addiert "z1" mit "z2" (kartesiche Koordinaten).
      3. kompAddK.Realteil = z1.Realteil + z2.Realteil
      4. kompAddK.Imaginärteil = z1.Imaginärteil + z2.Imaginärteil
      5. End Function
      6. Function kompSubtrK(z1 As komplexK, z2 As komplexK) As komplexK
      7. 'Subtrahiert "z2" von "z1" (kartesiche Koordinaten).
      8. kompSubtrK.Realteil = z1.Realteil - z2.Realteil
      9. kompSubtrK.Imaginärteil = z1.Imaginärteil - z2.Imaginärteil
      10. End Function
      11. Function kompMultK(z1 As komplexK, z2 As komplexK) As komplexK
      12. 'Multipliziert "z1" mit "z2" (kartesiche Koordinaten).
      13. kompMultK.Realteil = z1.Realteil * z2.Realteil - z1.Imaginärteil * z2.Imaginärteil
      14. kompMultK.Imaginärteil = z1.Realteil * z2.Imaginärteil + z2.Realteil * z1.Imaginärteil
      15. End Function
      16. Function kompDivK(z1 As komplexK, z2 As komplexK) As komplexK
      17. 'Dividiert "z1" durch "z2" (kartesiche Koordinaten).
      18. kompDivK.Realteil = (z1.Realteil * z2.Realteil + z1.Imaginärteil * z2.Imaginärteil) / (z2.Realteil ^ 2 + z2.Imaginärteil ^ 2)
      19. kompDivK.Imaginärteil = (z1.Imaginärteil * z2.Realteil - z1.Realteil * z2.Imaginärteil) / (z2.Realteil ^ 2 + z2.Imaginärteil ^ 2)
      20. End Function
      21. Function kompPotenzK(z As komplexK, Exponent As Double) As komplexK
      22. 'Potenziert "z" mit "Exponent" (kartesische Koordinaten).
      23. kompPotenzK = PnachK(kompPotenzP(KnachP(z), Exponent))
      24. End Function
      25. Function kompWurzelK(z As komplexK, n As Integer) As komplexK()
      26. 'Liefert die "n"-ten Wurzeln von "z" (kartesische Koordinaten).
      27. Dim wP() As komplexP, wK() As komplexK, k As Integer
      28. wP = kompWurzelP(KnachP(z), n)
      29. ReDim wK(UBound(wP))
      30. For k = 0 To UBound(wP)
      31. wK(k) = PnachK(wP(k))
      32. Next
      33. kompWurzelK = wK
      34. End Function


      Und hier Rechenoperationen unter Verwendung von Polarkoordinaten:

      Visual Basic-Quellcode

      1. Function kompAddP(z1 As komplexP, z2 As komplexP) As komplexP
      2. 'Addiert "z1" mit "z2" (Polarkoordinaten).
      3. kompAddP = KnachP(kompAddK(PnachK(z1), PnachK(z2)))
      4. End Function
      5. Function kompSubtrP(z1 As komplexP, z2 As komplexP) As komplexP
      6. 'Subtrahiert "z2" von "z1" (Polarkoordinaten).
      7. kompSubtrP = KnachP(kompSubtrK(PnachK(z1), PnachK(z2)))
      8. End Function
      9. Function kompMultP(z1 As komplexP, z2 As komplexP) As komplexP
      10. 'Multipliziert "z1" mit "z2" (Polarkoordinaten).
      11. If z1.Betrag < 0 Or z2.Betrag < 0 Then MsgBox "Ungültiger Parameterwert", vbCritical: Stop
      12. kompMultP.Betrag = z1.Betrag * z2.Betrag
      13. If z1.Betrag = 0 Or z2.Betrag = 0 Then
      14. kompMultP.Argument = Empty
      15. Else
      16. kompMultP.Argument = Winkel2pi(Winkel2pi(z1.Argument) + Winkel2pi(z2.Argument))
      17. End If
      18. End Function
      19. Function kompDivP(z1 As komplexP, z2 As komplexP) As komplexP
      20. 'Dividiert "z1" durch "z2" (Polarkoordinaten).
      21. If z1.Betrag < 0 Or z2.Betrag < 0 Then MsgBox "Ungültiger Parameterwert", vbCritical: Stop
      22. kompDivP.Betrag = z1.Betrag / z2.Betrag
      23. If z1.Betrag = 0 Or z2.Betrag = 0 Then
      24. kompDivP.Argument = Empty
      25. Else
      26. kompDivP.Argument = Winkel2pi(Winkel2pi(z1.Argument) - Winkel2pi(z2.Argument))
      27. End If
      28. End Function
      29. Function kompPotenzP(z As komplexP, Exponent As Double) As komplexP
      30. 'Potenziert "z" mit "Exponent" (Polarkoordinaten).
      31. If z.Betrag < 0 Then MsgBox "Ungültiger Parameterwert", vbCritical: Stop
      32. kompPotenzP.Betrag = z.Betrag ^ Exponent
      33. If z.Betrag = 0 Then
      34. kompPotenzP.Argument = Empty
      35. Else
      36. kompPotenzP.Argument = Winkel2pi(Winkel2pi(z.Argument) * Exponent)
      37. End If
      38. End Function
      39. Function kompWurzelP(z As komplexP, n As Integer) As komplexP()
      40. 'Liefert die "n"-ten Wurzeln von "z" (Polarkoordinaten).
      41. Dim w() As komplexP, k As Integer
      42. If z.Betrag < 0 Or n = 0 Then MsgBox "Ungültiger Parameterwert", vbCritical: Stop
      43. ReDim w(Abs(n) - 1)
      44. For k = 0 To Abs(n) - 1
      45. w(k).Betrag = z.Betrag ^ (1 / n)
      46. If z.Betrag = 0 Then
      47. w(k).Argument = Empty
      48. Else
      49. w(k).Argument = Winkel2pi((Winkel2pi(z.Argument) + k * 2 * pi) / n)
      50. End If
      51. Next
      52. kompWurzelP = w
      53. End Function

      Nullstellen, Extremstellen und Wendepunkte von ganzrationalen Funktionen beliebigen Grades

      Um die Nullstellen von Funktionen bis 4. Grades zu berechnen, habe ich eigene Funktionen (Nullstellen0 bis Nullstellen4).

      Mit der Funktion „Nullstellen_ParamArray“ kann man die Koeffizienten in der Reihenfolge a0, a1, a2, … eingeben. Man kann auch die Funktion als Text eingeben. Beispiel: Nullstellen("5x^2-4x+3") liefert ein Array mit den Nullstellen der Funktion. Als Koeffizienten kann man auch Brüche eingeben, z. B. Nullstellen("1/2x^2-5/6x"). Bei diesen beiden Funktionen werden zunächst die Nullstellen mit x=0 abgespalten, wodurch der Grad der Funktion evtl. verringert wird (3x^3+5x^2 hat beispielsweise eine doppelte Nullstelle bei x=0; für die weitere Berechnung der Nullstellen braucht man nur noch 3x+5 betrachten). Danach wird noch ggf. eine Substitution durchgeführt. Bei 3x^4+2x^2-5 kann man x durch z^2 ersetzen, was Folgendes ergibt: 3z^2+2z-5. Von den sich daraus ergebenden Nullstellen braucht man dann jeweils nur die beiden Quadratwurzeln ziehen und hat dann die Nullstellen der Ausgangsfunktion.

      Ist der so entstandene Term (nach Substitution) ein Polynom vom Grad 0 bis 4, wird die entsprechende Funktion angewandt, z. B. Nullstellen2. Ist der Grad höher, wird solange durch Iteration eine Nullstelle bestimmt und diese abgespalten, bis der Grad 4 oder kleiner ist.

      Es werden alle Nullstellen (also auch komplexe) bestimmt. Bei einer ganzrationalen Funktion entspricht die Anzahl der Nullstellen dem Grad. Da dort komplexe Nullstellen immer paarweise mit der dazu konjugierten komplexen Zahl auftreten (z. B. 1+2i und 1-2i), wird dies beim Iterationsverfahren entsprechend berücksichtigt.

      Die Funktionen „KurvDisk_ParamArray“ und „Kurvendiskussion“, bei denen die Parameter so wie bei „Nullstellen_ParamArray“ bzw. „Nullstellen“ eingegeben werden, liefern einen String, der die Nullstellen, Extremstellen (Maxima, Minima, Sattelpunkte) und Wendepunkte auflistet.

      Visual Basic-Quellcode

      1. Enum NullstellenTyp
      2. mNullstelle = 0
      3. mMaximum = 1
      4. mMinimum = 2
      5. mSattelpunkt = 3
      6. mWendepunkt = 4
      7. End Enum
      8. Type ExtremwertTyp
      9. relMaxima() As komplexK
      10. relMinima() As komplexK
      11. Sattelpunkte() As komplexK
      12. End Type


      Visual Basic-Quellcode

      1. Function KoeffAusText(Funktion As String) As Double()
      2. 'Erstellt ein Koeffizientenarray aus einem Text der Form
      3. '45x^5-3,5x^2+2x-1 (Beispiel);
      4. '45x5-3,5x2+2x-1 (anderes Beispiel).
      5. '1/2x^2-x+5 (anderes Beispiel).
      6. Dim Text As String, Summanden() As String, i As Integer
      7. Dim Trennung() As String, Bruch() As String
      8. Dim koeff() As Double, Index As Integer
      9. ReDim koeff(0)
      10. Text = Replace(Replace(Replace(Funktion, " ", ""), "-", "+-"), "^", "")
      11. If Left(Text, 1) = "+" Then Text = Mid(Text, 2)
      12. If Text <> "" Then
      13. Summanden = Split(Text, "+")
      14. For i = 0 To UBound(Summanden)
      15. Trennung = Split(Summanden(i), "x")
      16. If UBound(Trennung) = 0 Then
      17. Index = 0
      18. Else
      19. If Trennung(1) = "" Then
      20. Index = 1
      21. Else
      22. If Not IsNumeric(Trennung(1)) Then
      23. MsgBox "Syntaxfehler!" & vbCrLf & vbCrLf & Summanden(i), vbCritical
      24. Stop
      25. ElseIf CInt(Trennung(1)) <> CDbl(Trennung(1)) Then
      26. MsgBox "Die Exponenten müssen ganzzahlig sein!" _
      27. & vbCrLf & vbCrLf & Summanden(i), vbCritical
      28. Stop
      29. Else
      30. Index = Trennung(1)
      31. If Index < 0 Then
      32. MsgBox "Die Exponenten dürfen nicht negativ sein!" _
      33. & vbCrLf & vbCrLf & Summanden(i), vbCritical
      34. Stop
      35. End If
      36. End If
      37. End If
      38. End If
      39. If UBound(koeff) < Index Then
      40. ReDim Preserve koeff(Index)
      41. End If
      42. If Trennung(0) = "" Then Trennung(0) = "1"
      43. If InStr(1, Trennung(0), "/") > 0 Then
      44. Bruch = Split(Trennung(0), "/")
      45. If UBound(Bruch) > 1 _
      46. Or Not IsNumeric(Bruch(0)) Or Not IsNumeric(Bruch(1)) Then
      47. MsgBox "Syntaxfehler!" & vbCrLf & vbCrLf & Summanden(i), vbCritical
      48. Stop
      49. End If
      50. Trennung(0) = Bruch(0) / Bruch(1)
      51. End If
      52. If Not IsNumeric(Trennung(0)) Then
      53. MsgBox "Syntaxfehler!" & vbCrLf & vbCrLf & Summanden(i), vbCritical
      54. Stop
      55. Else
      56. koeff(Index) = Trennung(0)
      57. End If
      58. Next
      59. End If
      60. KoeffAusText = koeff
      61. End Function
      62. Function NullstSort(x() As komplexK) As komplexK()
      63. 'Sortiert die Nullstellen.
      64. Dim i As Integer, j As Integer, k As Integer, z As komplexK
      65. If UBound(x) > 0 Then
      66. For i = 1 To UBound(x)
      67. For j = 1 To i - 1
      68. If x(i).Realteil < x(j).Realteil _
      69. Or (x(i).Realteil = x(j).Realteil And x(i).Imaginärteil < x(j).Imaginärteil) Then
      70. z = x(i)
      71. For k = i To j + 1 Step -1
      72. x(k) = x(k - 1)
      73. Next
      74. x(j) = z
      75. End If
      76. Next
      77. Next
      78. End If
      79. NullstSort = x
      80. End Function

      Visual Basic-Quellcode

      1. Function NullstellenListe(x() As komplexK, Typ As NullstellenTyp) As String
      2. 'Liefert einen String, in dem die Nullstellen aufgelistet sind.
      3. Dim i As Integer, Text As String
      4. If UBound(x) = 1 Then
      5. Select Case Typ
      6. Case mNullstelle: Text = "Nullstelle"
      7. Case mMaximum: Text = "relatives Maximum"
      8. Case mMinimum: Text = "relatives Minimum"
      9. Case mSattelpunkt: Text = "Sattelpunkt"
      10. Case mWendepunkt: Text = "Wendepunkt"
      11. End Select
      12. Else
      13. Select Case Typ
      14. Case mNullstelle: Text = "Nullstellen"
      15. Case mMaximum: Text = "relative Maxima"
      16. Case mMinimum: Text = "relative Minima"
      17. Case mSattelpunkt: Text = "Sattelpunkte"
      18. Case mWendepunkt: Text = "Wendepunkte"
      19. End Select
      20. End If
      21. Select Case UBound(x)
      22. Case -1: NullstellenListe = "unendlich viele " & Text
      23. Case 0: NullstellenListe = "keine " & Text
      24. Case Else
      25. NullstellenListe = UBound(x) & " " & Text & ":" & vbCrLf
      26. For i = 1 To UBound(x)
      27. NullstellenListe = NullstellenListe & vbCrLf & kompTextK(x(i))
      28. Next
      29. End Select
      30. End Function
      31. Function FWert(x As komplexK, Koeffizienten() As Double) As komplexK
      32. 'Liefert den Funktionswert der Funktion mit den "Koeffizienten" an der Stelle "x".
      33. Dim i As Double, koeff As komplexK
      34. FWert.Realteil = 0
      35. FWert.Imaginärteil = 0
      36. For i = 0 To UBound(Koeffizienten)
      37. koeff.Realteil = Koeffizienten(i)
      38. koeff.Imaginärteil = 0
      39. FWert = kompAddK(FWert, kompMultK(koeff, kompPotenzK(x, i)))
      40. Next
      41. End Function
      42. Function Nullstellen0(c As Double) As komplexK()
      43. 'Legt die Anzahl der Nullstellen für eine Funktion der Form f(x)=c fest.
      44. '(-1 steht in diesem Fall für unendlich.)
      45. Dim x() As komplexK
      46. If c = 0 Then ReDim x(-1 To -1) Else ReDim x(0)
      47. Nullstellen0 = x
      48. End Function
      49. Function Nullstellen1(m As Double, b As Double) As komplexK()
      50. 'Liefert die Nullstelle für eine Funktion der Form f(x)=mx+b.
      51. Dim x(1 To 1) As komplexK
      52. If m = 0 Then
      53. Nullstellen1 = Nullstellen0(b)
      54. Else
      55. x(1).Realteil = -b / m
      56. x(1).Imaginärteil = 0
      57. Nullstellen1 = NullstSort(x)
      58. End If
      59. End Function
      60. Function Nullstellen2(a As Double, b As Double, c As Double) As komplexK()
      61. 'Liefert die Nullstellen für eine Funktion der Form f(x)=ax^2+bx+c.
      62. Dim x(1 To 2) As komplexK
      63. Dim Radikand As komplexK, Wurzeln() As komplexK
      64. Dim i As Integer, Summand As komplexK, Nenner As komplexK
      65. If a = 0 Then
      66. Nullstellen2 = Nullstellen1(b, c)
      67. Else
      68. Radikand.Realteil = b ^ 2 - 4 * a * c
      69. Radikand.Imaginärteil = 0
      70. Wurzeln = kompWurzelK(Radikand, 2)
      71. Summand.Realteil = -b
      72. Summand.Imaginärteil = 0
      73. Nenner.Realteil = 2 * a
      74. Nenner.Imaginärteil = 0
      75. For i = 1 To 2
      76. x(i) = kompDivK(kompAddK(Summand, Wurzeln(i - 1)), Nenner)
      77. Next
      78. Nullstellen2 = NullstSort(x)
      79. End If
      80. End Function

      Visual Basic-Quellcode

      1. Function Nullstellen3(a As Double, b As Double, c As Double, d As Double) As komplexK()
      2. 'Liefert die Nullstellen für eine Funktion der Form f(x)=ax^3+bx^2+cx+d.
      3. Dim x(1 To 3) As komplexK, y(1 To 3) As komplexK
      4. Dim r As Double, s As Double, t As Double
      5. Dim p As Double, q As Double, Radikand As Double
      6. Dim uRadikand As Double, vRadikand As Double
      7. Dim u(1 To 3) As komplexK, v(1 To 3) As komplexK
      8. Dim uvRadikand As komplexP, arg As Double
      9. Dim Wurzeln() As komplexK, i As Integer
      10. Dim Abzug As komplexK
      11. If a = 0 Then
      12. Nullstellen3 = Nullstellen2(b, c, d)
      13. Else
      14. 'auf Normalform bringen: x^3+rx^2+sx+t=0
      15. r = b / a
      16. s = c / a
      17. t = d / a
      18. 'reduzierte kubische Gleichung: x=y-r/3 -> y^3+py+q=0
      19. p = s - r ^ 2 / 3
      20. q = 2 * r ^ 3 / 27 - s * r / 3 + t
      21. If q = 0 Then
      22. y(1).Realteil = 0
      23. y(1).Imaginärteil = 0
      24. Wurzeln = Nullstellen2(1, 0, p)
      25. For i = 2 To 3
      26. y(i) = Wurzeln(i - 1)
      27. Next
      28. Else
      29. Radikand = (q / 2) ^ 2 + (p / 3) ^ 3
      30. If Radikand >= 0 Then
      31. uRadikand = -q / 2 + Sqr(Radikand)
      32. vRadikand = -q / 2 - Sqr(Radikand)
      33. u(1).Realteil = Sgn(uRadikand) * Abs(uRadikand) ^ (1 / 3)
      34. u(1).Imaginärteil = 0
      35. v(1).Realteil = Sgn(vRadikand) * Abs(vRadikand) ^ (1 / 3)
      36. v(1).Imaginärteil = 0
      37. u(2).Realteil = -u(1).Realteil / 2
      38. u(2).Imaginärteil = u(1).Realteil * Sqr(3)
      39. v(2).Realteil = -v(1).Realteil / 2
      40. v(2).Imaginärteil = v(1).Realteil * Sqr(3)
      41. u(3).Realteil = -u(1).Realteil / 2
      42. u(3).Imaginärteil = -u(1).Realteil * Sqr(3)
      43. v(3).Realteil = -v(1).Realteil / 2
      44. v(3).Imaginärteil = -v(1).Realteil * Sqr(3)
      45. Else
      46. uvRadikand.Betrag = Sqr(-p ^ 3 / 27)
      47. arg = -q / (2 * uvRadikand.Betrag)
      48. uvRadikand.Argument = Atn(-arg / Sqr(-arg * arg + 1)) + 2 * Atn(1)
      49. Wurzeln = kompWurzelK(PnachK(uvRadikand), 3)
      50. For i = 1 To 3
      51. u(i).Realteil = Wurzeln(i - 1).Realteil
      52. u(i).Imaginärteil = 0
      53. v(i).Realteil = Wurzeln(i - 1).Realteil
      54. v(i).Imaginärteil = 0
      55. Next
      56. End If
      57. For i = 1 To 3
      58. y(i) = kompAddK(u(i), v(i))
      59. Next
      60. End If
      61. Abzug.Realteil = r / 3
      62. Abzug.Imaginärteil = 0
      63. For i = 1 To 3
      64. x(i) = kompSubtrK(y(i), Abzug)
      65. Next
      66. Nullstellen3 = NullstSort(x)
      67. End If
      68. End Function
      69. Function Nullstellen4(a4 As Double, a3 As Double, a2 As Double, a1 As Double, a0 As Double) As komplexK()
      70. 'Liefert die Nullstellen für eine Funktion der Form f(x)=a4x^4+a3x^3+a2x^2+a1x+a0.
      71. Dim x(1 To 4) As komplexK
      72. Dim a As Double, b As Double, c As Double, d As Double
      73. Dim Wurzeln() As komplexK, i As Integer, Index As Integer
      74. Dim y1 As Double, A12(1 To 2) As Double
      75. If a4 = 0 Then
      76. Nullstellen4 = Nullstellen3(a3, a2, a1, a0)
      77. Else
      78. 'auf Normalform bringen: x^4+ax^3+bx^2+cx+d=0
      79. a = a3 / a4
      80. b = a2 / a4
      81. c = a1 / a4
      82. d = a0 / a4
      83. 'kubische Gleichung: y^3-by^2+(ca-4d)y+4bd-da^2-c^2=0
      84. Wurzeln = Nullstellen3(1, -b, c * a - 4 * d, 4 * b * d - d * a ^ 2 - c ^ 2)
      85. Index = 1
      86. For i = 2 To 3
      87. If Abs(Wurzeln(i).Imaginärteil) < Abs(Wurzeln(Index).Imaginärteil) Then Index = i
      88. If Abs(Wurzeln(i).Imaginärteil) = Abs(Wurzeln(Index).Imaginärteil) _
      89. And Wurzeln(i).Realteil > Wurzeln(Index).Realteil Then Index = i
      90. Next
      91. y1 = Wurzeln(Index).Realteil
      92. A12(1) = Sqr(4 * y1 + a ^ 2 - 4 * b)
      93. A12(2) = -A12(1)
      94. For i = 1 To 2
      95. Wurzeln = Nullstellen2(1, (a + A12(i)) / 2, (y1 + (a * y1 - 2 * c) / A12(i)) / 2)
      96. x(2 * i - 1) = Wurzeln(1)
      97. x(2 * i) = Wurzeln(2)
      98. Next
      99. Nullstellen4 = NullstSort(x)
      100. End If
      101. End Function

      Visual Basic-Quellcode

      1. Function Ableitung(Koeffizienten() As Double) As Double()
      2. 'Liefert die Ableitung der Funktion mit den "Koeffizienten".
      3. Dim koeff() As Double, i As Integer
      4. If UBound(Koeffizienten) = 0 Then
      5. ReDim koeff(0)
      6. koeff(0) = 0
      7. Else
      8. ReDim koeff(UBound(Koeffizienten) - 1)
      9. For i = 0 To UBound(koeff)
      10. koeff(i) = (i + 1) * Koeffizienten(i + 1)
      11. Next
      12. End If
      13. Ableitung = koeff
      14. End Function
      15. Function AbspaltungReell(Nullstelle As Double, Koeffizienten() As Double) As Double()
      16. 'Spaltet eine reelle Nullstelle von der Funktion mit den "Koeffizienten" ab (Polynomdivision).
      17. Dim koeff() As Double, i As Integer, Rest As Double
      18. ReDim koeff(UBound(Koeffizienten) - 1)
      19. koeff(UBound(koeff)) = Koeffizienten(UBound(Koeffizienten))
      20. For i = UBound(koeff) - 1 To 0 Step -1
      21. koeff(i) = Koeffizienten(i + 1) + koeff(i + 1) * Nullstelle
      22. Next
      23. Rest = Koeffizienten(0) + koeff(0) * Nullstelle
      24. If Abs(Rest) > 10 ^ -15 Then
      25. If MsgBox(Nullstelle & vbCrLf & "ist keine Nullstelle:" & vbCrLf & vbCrLf _
      26. & "Divisionsrest: " & Rest & vbCrLf & vbCrLf _
      27. & "Soll die Nullstelle akzeptiert werden?", vbCritical + vbYesNo) = vbNo Then Stop
      28. End If
      29. AbspaltungReell = koeff
      30. End Function
      31. Function AbspaltungKomplex(Nullstelle As komplexK, Koeffizienten() As Double) As Double()
      32. 'Spaltet eine komplexe Nullstelle von der Funktion mit den "Koeffizienten" ab (Polynomdivision).
      33. Dim koeff() As Double, i As Integer, Rest As Double
      34. ReDim koeff(UBound(Koeffizienten) - 2)
      35. koeff(UBound(koeff)) = Koeffizienten(UBound(Koeffizienten))
      36. koeff(UBound(koeff) - 1) = _
      37. Koeffizienten(UBound(Koeffizienten) - 1) + 2 * koeff(UBound(koeff)) * Nullstelle.Realteil
      38. For i = UBound(koeff) - 2 To 0 Step -1
      39. koeff(i) = Koeffizienten(i + 2) _
      40. - koeff(i + 2) * (Nullstelle.Realteil ^ 2 + Nullstelle.Imaginärteil ^ 2) _
      41. + 2 * koeff(i + 1) * Nullstelle.Realteil
      42. Next
      43. Rest = Koeffizienten(1) _
      44. - koeff(1) * (Nullstelle.Realteil ^ 2 + Nullstelle.Imaginärteil ^ 2) _
      45. + 2 * koeff(0) * Nullstelle.Realteil
      46. If Abs(Rest) > 10 ^ -15 Then
      47. If MsgBox(kompTextK(Nullstelle) & vbCrLf & kompTextK(konjugiertK(Nullstelle)) & vbCrLf _
      48. & "sind keine Nullstellen:" & vbCrLf & vbCrLf & "Divisionsrest: " & Rest & vbCrLf & vbCrLf _
      49. & "Soll die Nullstelle akzeptiert werden?", vbCritical + vbYesNo) = vbNo Then Stop
      50. End If
      51. AbspaltungKomplex = koeff
      52. End Function
      53. Function NullstIteration(Startwert As komplexK, Koeffizienten() As Double) As komplexK
      54. 'Liefert eine Nullstelle der Funktion mit den "Koeffizienten",
      55. 'gewonnen durch Iteration, ausgehend vom "Startwert".
      56. Dim i As Integer, AblKoeff() As Double, AblWert As komplexK
      57. Dim x0 As komplexK, x1 As komplexK, neuerStart As komplexK
      58. x0 = Startwert
      59. AblKoeff = Ableitung(Koeffizienten)
      60. AblWert = FWert(x0, Ableitung(Koeffizienten))
      61. If AblWert.Realteil <> 0 Or AblWert.Imaginärteil <> 0 Then
      62. For i = 1 To 100
      63. x1 = kompSubtrK(x0, kompDivK(FWert(x0, Koeffizienten), FWert(x0, AblKoeff)))
      64. If Abs(x1.Realteil - x0.Realteil) < 10 ^ -15 And Abs(x1.Imaginärteil - x0.Imaginärteil) < 10 ^ -15 Then
      65. NullstIteration = x1
      66. Exit Function
      67. End If
      68. x0 = x1
      69. Next
      70. End If
      71. If Startwert.Imaginärteil = 0 Then
      72. neuerStart.Realteil = Startwert.Realteil
      73. neuerStart.Imaginärteil = 1
      74. Else
      75. neuerStart.Realteil = Startwert.Realteil + 1
      76. neuerStart.Imaginärteil = 0
      77. End If
      78. NullstIteration = NullstIteration(neuerStart, Koeffizienten)
      79. End Function

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „roddy“ ()

      Visual Basic-Quellcode

      1. Function Nullstellen_Array(Koeffizienten() As Double) As komplexK()
      2. 'Ermittelt die Nullstellen der Funktion mit den "Koeffizienten".
      3. Dim koeff() As Double, x() As komplexK, Index As Integer
      4. Dim i As Integer, SubstExp As Integer
      5. Dim koeff0() As Double, x0() As komplexK, Index0 As Integer
      6. Dim Startwert As komplexK
      7. Dim x1() As komplexK, Wurzeln() As komplexK, j As Integer
      8. koeff = Koeffizienten
      9. If UBound(koeff) = 0 Then
      10. Nullstellen_Array = Nullstellen0(koeff(0))
      11. Exit Function
      12. End If
      13. ReDim x(1 To UBound(koeff))
      14. Index = 0
      15. 'Abspaltung der Nullstellen mit x=0:
      16. While koeff(0) = 0
      17. If Index = UBound(x) Then
      18. Nullstellen_Array = Nullstellen0(0)
      19. Exit Function
      20. End If
      21. Index = Index + 1
      22. x(Index).Realteil = 0
      23. x(Index).Imaginärteil = 0
      24. koeff = AbspaltungReell(0, koeff)
      25. Wend
      26. 'Substitution mit z=x^SubstExp
      27. SubstExp = 0
      28. For i = 1 To UBound(koeff)
      29. If koeff(i) <> 0 Then
      30. If SubstExp = 0 Then
      31. SubstExp = i
      32. Else
      33. SubstExp = ggT(SubstExp, i)
      34. End If
      35. If SubstExp = 1 Then Exit For
      36. End If
      37. Next
      38. If SubstExp <= 1 Then
      39. koeff0 = koeff
      40. Else
      41. ReDim koeff0(UBound(koeff) / SubstExp)
      42. For i = 0 To UBound(koeff0)
      43. koeff0(i) = koeff(i * SubstExp)
      44. Next
      45. End If
      46. If UBound(koeff0) > 0 Then
      47. ReDim x0(1 To UBound(koeff0))
      48. Index0 = 0
      49. Startwert.Realteil = 0
      50. Startwert.Imaginärteil = 0
      51. While UBound(koeff0) > 4
      52. Index0 = Index0 + 1
      53. x0(Index0) = NullstIteration(Startwert, koeff0)
      54. If Abs(x0(Index0).Imaginärteil) < 10 ^ -15 Then
      55. koeff0 = AbspaltungReell(x0(Index0).Realteil, koeff0)
      56. Else
      57. Index0 = Index0 + 1
      58. x0(Index0) = konjugiertK(x0(Index0 - 1))
      59. koeff0 = AbspaltungKomplex(x0(Index0), koeff0)
      60. End If
      61. Wend
      62. Select Case UBound(koeff0)
      63. Case 4: x1 = Nullstellen4(koeff0(4), koeff0(3), koeff0(2), koeff0(1), koeff0(0))
      64. Case 3: x1 = Nullstellen3(koeff0(3), koeff0(2), koeff0(1), koeff0(0))
      65. Case 2: x1 = Nullstellen2(koeff0(2), koeff0(1), koeff0(0))
      66. Case 1: x1 = Nullstellen1(koeff0(1), koeff0(0))
      67. Case 0: x1 = Nullstellen0(koeff0(0))
      68. End Select
      69. For i = 1 To UBound(x1)
      70. Index0 = Index0 + 1
      71. x0(Index0) = x1(i)
      72. Next
      73. If Index0 <> UBound(x0) Then Stop
      74. For i = 1 To UBound(x0)
      75. Wurzeln = kompWurzelK(x0(i), SubstExp)
      76. For j = 1 To SubstExp
      77. Index = Index + 1
      78. x(Index) = Wurzeln(j - 1)
      79. Next
      80. Next
      81. End If
      82. If Index <> UBound(x) Then Stop
      83. Nullstellen_Array = NullstSort(x)
      84. End Function
      85. Function Nullstellen_ParamArray(ParamArray Koeffizienten() As Variant) As komplexK()
      86. 'Liefert die Nullstellen der Funktion mit den "Koeffizienten"
      87. Dim koeff() As Double, i As Integer
      88. ReDim koeff(UBound(Koeffizienten))
      89. For i = 0 To UBound(koeff)
      90. koeff(i) = Koeffizienten(i)
      91. Next
      92. Nullstellen_ParamArray = Nullstellen_Array(koeff)
      93. End Function
      94. Function Nullstellen(Funktion As String) As komplexK()
      95. 'Liefert die Nullstellen der "Funktion" der Form
      96. '45x^5-3,5x^2+2x-1 (Beispiel);
      97. '45x5-3,5x2+2x-1 (anderes Beispiel).
      98. Nullstellen = Nullstellen_Array(KoeffAusText(Funktion))
      99. End Function

      Visual Basic-Quellcode

      1. Function Extremstellen(Koeffizienten() As Double) As ExtremwertTyp
      2. 'Liefert die Extremstellen der Funktion mit den "Koeffizienten"
      3. Dim Ableitung1() As Double, Ableitung2() As Double
      4. Dim Extreme() As komplexK, Sammlung As ExtremwertTyp, i As Integer
      5. Ableitung1 = Ableitung(Koeffizienten)
      6. Ableitung2 = Ableitung(Ableitung1)
      7. Extreme = Nullstellen_Array(Ableitung1)
      8. With Sammlung
      9. ReDim .relMaxima(0), .relMinima(0), .Sattelpunkte(0)
      10. If UBound(Extreme) = -1 Then ReDim .Sattelpunkte(-1 To -1)
      11. For i = 1 To UBound(Extreme)
      12. Select Case Sgn(FWert(Extreme(i), Ableitung2).Realteil)
      13. Case -1
      14. If UBound(.relMaxima) = 0 Then
      15. ReDim .relMaxima(1)
      16. Else
      17. ReDim Preserve .relMaxima(UBound(.relMaxima) + 1)
      18. End If
      19. .relMaxima(UBound(.relMaxima)) = Extreme(i)
      20. Case 1
      21. If UBound(.relMinima) = 0 Then
      22. ReDim .relMinima(1)
      23. Else
      24. ReDim Preserve .relMinima(UBound(.relMinima) + 1)
      25. End If
      26. .relMinima(UBound(.relMinima)) = Extreme(i)
      27. Case 0
      28. If UBound(.Sattelpunkte) = 0 Then
      29. ReDim .Sattelpunkte(1)
      30. Else
      31. ReDim Preserve .Sattelpunkte(UBound(.Sattelpunkte) + 1)
      32. End If
      33. .Sattelpunkte(UBound(.Sattelpunkte)) = Extreme(i)
      34. End Select
      35. Next
      36. End With
      37. Extremstellen = Sammlung
      38. End Function
      39. Function Wendepunkte(Koeffizienten() As Double) As komplexK()
      40. 'Liefert die Wendepunkte der Funktion mit den "Koeffizienten"
      41. Wendepunkte = Nullstellen_Array(Ableitung(Ableitung(Koeffizienten)))
      42. End Function
      43. Function KurvDisk_Array(Koeffizienten() As Double) As String
      44. 'Liefert eine Liste mit Nullstellen, Extremstellen und Wendepunkten
      45. Dim Extreme As ExtremwertTyp
      46. KurvDisk_Array = NullstellenListe(Nullstellen_Array(Koeffizienten), mNullstelle)
      47. Extreme = Extremstellen(Koeffizienten)
      48. KurvDisk_Array = KurvDisk_Array & vbCrLf & vbCrLf & NullstellenListe(Extreme.relMaxima, mMaximum)
      49. KurvDisk_Array = KurvDisk_Array & vbCrLf & vbCrLf & NullstellenListe(Extreme.relMinima, mMinimum)
      50. KurvDisk_Array = KurvDisk_Array & vbCrLf & vbCrLf & NullstellenListe(Extreme.Sattelpunkte, mSattelpunkt)
      51. KurvDisk_Array = KurvDisk_Array & vbCrLf & vbCrLf & NullstellenListe(Wendepunkte(Koeffizienten), mWendepunkt)
      52. End Function
      53. Function KurvDisk_ParamArray(ParamArray Koeffizienten() As Variant) As String
      54. 'Liefert eine Liste mit Nullstellen, Extremstellen und Wendepunkten
      55. Dim koeff() As Double, i As Integer
      56. ReDim koeff(UBound(Koeffizienten))
      57. For i = 0 To UBound(koeff)
      58. koeff(i) = Koeffizienten(i)
      59. Next
      60. KurvDisk_ParamArray = KurvDisk_Array(koeff)
      61. End Function
      62. Function Kurvendiskussion(Funktion As String) As String
      63. 'Liefert eine Liste mit Nullstellen, Extremstellen und Wendepunkten
      64. 'aufgrund eines Textes der Form
      65. '45x^5-3,5x^2+2x-1 (Beispiel);
      66. '45x5-3,5x2+2x-1 (anderes Beispiel).
      67. '1/2x^2-x+5 (anderes Beispiel).
      68. Kurvendiskussion = KurvDisk_Array(KoeffAusText(Funktion))
      69. End Function
      Eigentlich brauchst du nur die Codes kopieren und in dein Code-Fenster einfügen.

      Trotzdem habe ich mal eine ZIP-Datei mit den Modulen, die den Code enthalten angehängt:

      VBA-Mathe Teil 2.zip

      Falls du spezielle Fragen zu dem Code hast, auch was davon man braucht um bestimmte Dinge zu erreichen, kann ich die gerne beantworten.


      Nebenbei: Ich bin gerade dabei, ein Klassenmodul zu schreiben, mit dessen Hilfe man eine bestimmte Größe eines Dreiecks ermitteln kann (z. B. eine Seite, eine Höhe, ein Winkel, der Flächeninhalt usw.), sofern man genügend Größen eingegeben hat, um die gesuchte Größe ermitteln zu können. Das soll dann z. B. so aussehen:

      Visual Basic-Quellcode

      1. Dim dr As New Dreieck
      2. dr.SeiteA = 5
      3. dr.HöheHa = 10
      4. MsgBox dr.Flächeninhalt


      Im Beispiel würde dann eine MsgBox mit dem Text "25" erscheinen.

      Dies soll aber genauso möglich sein:

      Visual Basic-Quellcode

      1. Dim dr As New Dreieck
      2. dr.Flächeninhalt = 25
      3. dr.SeiteA = 5
      4. MsgBox dr.HöheHa


      Die MsgBox würde dann "10" zurückgeben.


      Das wird dann Bestandteil von Teil 3 sein. Wann das soweit ist, kann ich noch nicht sagen.

      Aber eins kann ich sagen: Auszuknobeln, wie man das auf die Beine stellen kann, macht richtig Spaß.

      Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „roddy“ ()

      @ Darius:

      Nein, ich habe nicht Mathe studiert. Aber Mathe war immer mein bestes Fach. Mein Wissen habe ich aus der Schule (mittlere Reife), durch Anschauen von Telekolleg Mathematik und aus Mathe-Fachbüchern.

      Ich beschäftige mich in der Freizeit einfach gern mit Mathematik. Was mir dann als Nebeneffekt manchmal im Alltag und im Berufsleben hilft und nicht zu vergessen: beim VB-Programmieren, mein zweites großes Hobby.


      Mad Andy:

      dass wir den ganzen Sch... in der Schule (hauptsächlich 11., 12.) wissen müssen/mussten


      Nur so am Rande: Die Berechnungsverfahren zur Lösung von Gleichungen 3. und 4. Grades beispielsweise (Funktionen Nullstellen3 und Nullstellen4 in meinem Sourcecode) könnte ich nicht aus den Gedächtnis abrufen. Das ist dann auch für mich etwas zu kompliziert, mir das zu merken.
      Zur Info:

      Bei der Funktion "kompTextK" stand in Zeile 28 statt dem Malpunkt (·) ein ?. Nachdem ich auf "Bearbeiten" gegangen bin, und den Punkt nochmal drübergeschrieben habe, ist er jetzt da.

      Das ? ist auch irgendwie in die ZIP-Datei gelangt, die ich nun auch korrigiert habe.
      Ich weiß ist kein Thema in dem Forum hier aber glaubst du roddy es wäre möglich den SC in Java zu schreiben??

      da ich ungern deinen schönen Code verhunzen will indem ich den in (äusserst schlechtes) Java umwandel. Oder muss man da komplett anders rangehen kenn mich da nit so mit aus^^"
      Update-Info:

      Ähnliches Problem wie oben, nur mit einem Gedankenstrich (–), den ich bei der Darstellung von komplexen Zahlen als Minuszeichen verwende, z. B. in "1 – 5 · i". Ich hab an der betreffenden Stelle im Code "–" durch Chr(150) ersetzt.

      Ich muss in Zukunft vor dem Posten den Code nochmal durchgehen und Zeichen, die Probleme machen könnten, im Auge behalten und nach dem Posten kontrollieren.