Gleichungen lösen

  • Wie kann ich in Autoit Gleichungen auflösen lassen?
    Ich suche schon seit ner Stunde und das einzige was ich gefunden hab war irgendwas mit einem Gauß'schen Eliminationsverfahren.

    Beispiel Gleichung die aufgelöst werden sollen:

    Code
    x+6=0
    -4x*(5+2x)*(3x-9)=0
  • Mahlzeit,
    also erstmal vorweg: ich berufe mich nur auf Erfahrungswerte / Vermutungen...

    Ich schätze, wenn du mithilfe von AutoIt die Lösung berechnen lassen willst, dann musst
    du dir einen Parser schreiben, der dann die Formel(n) in einzelne logische Bestandteile packt.
    Beispiel: Gleichung 1 wird genau dann 0, wenn x das additive Inverse von 6, also -6 annimmt.
    Zu Gleichung 2 fällt uns sofort ein, dass ein Produkt genau dann 0 wird, wenn mindestens einer
    der Faktoren 0 ist. Somit gilt es (wie oben) die einzelnen Faktoren 0 zu bekommen.
    -4 * x = 0 => x = 0
    5 + 2x = 0 <=> 2x = -5 => x = -5/2
    3x-9=0 <=> 3x = 9 => x = 3
    das ganze in einen logischen Kontext zu bringen stelle ich mir jedoch schwierig vor.
    Ganz schlecht ist es mit ausprobieren (= Bruteforce), da z.B. -5/2 nur schwer erfasst wird.
    PS: Vielleicht findest du ja schon eine Lösung im Forum, die dir hilft :)
    Wenn du das [Projekt] "größer" aufziehst, dann wäre ich sehr gespannt, was dabei rauskommt.
    Viel Glück :)

    Wer immer nur das tut, was er bereits kann - wird auch immer nur das bleiben, was er bereits ist!

  • Naja, GANZ billig kann man die Gleichung so lösen:

    [autoit]


    $gleichung="x+6 == 0"
    For $i=-1000 To 1000 Step 1
    If(Execute(StringReplace($gleichung,"x",$i/100))) Then MsgBox(64,"Lösung","x ist " & $i/100)
    ConsoleWrite(Execute(StringReplace($gleichung,"x",$i/100)) & @CRLF)
    ConsoleWrite(StringReplace($gleichung,"x",$i/100) & @CRLF)
    Next

    [/autoit]

    Twitter: @L3viathan2142
    Benutze AutoIt persönlich nicht mehr, da ich keinen Windows-Rechner mehr besitze.

  • Ich habe nun das hier gefunden:

    Spoiler anzeigen


    Bringt mir das irgendwas? Wie kann ich das genau verwenden?

  • Numerisch lässt es sich ziemlich einfach in AutoIt lösen:

    Spoiler anzeigen
    [autoit]

    Global Const $FLT_EPSILON = _GET_FLT_EPSILON()

    [/autoit] [autoit][/autoit] [autoit]

    ; Definition der Funktionen
    Global $sF1 = "-4*x*(5+2*x)*(3*x-9)"
    Global $sF2 = "0"

    [/autoit] [autoit][/autoit] [autoit]

    ; Definition des Suchbereiches
    Global $iStart = -1000
    Global $iEnd = 1000
    Global $iStep = 1.1

    [/autoit] [autoit][/autoit] [autoit]

    ; Größer/Kleiner Vergleichskriterium
    Global $bSw = _Fx($sF1, $iStart) > _Fx($sF2, $iStart)

    [/autoit] [autoit][/autoit] [autoit]

    For $x = $iStart To $iEnd Step $iStep ; Gehe den Bereich grob ab
    If $bSw <> (_Fx($sF1, $x) > _Fx($sF2, $x)) Then ; Wenn Wechsel der Größer/Kleiner Beziehung dann muss Schnittpunkt dazwischen liegen
    $bSw = Not $bSw
    $dX_Schnitt = Schnittsuche($sF1, $sF2, $x - $iStep, $x) ; Starte die feine Schnittpunktsuche im Intervall
    $dY_Schnitt = (_Fx($sF1, $dX_Schnitt) + _Fx($sF2, $dX_Schnitt)) / 2 ;Y-Wert als Mittelwert beider Funktionswerte bestimmen
    MsgBox(0, "Schnittpunkt gefunden", "x = " & Round($dX_Schnitt,15) & @CRLF & "y = " & Round($dY_Schnitt,14))
    EndIf
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Func _Fx(Const $sF, Const $dW)
    Return Number(Execute(StringReplace($sF, "x", "(" & $dW & ")")))
    EndFunc ;==>_Fx

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; Bestimmt die Schnittpunkte 2er Funktionen in einem Intervall iterativ mit dem Regula Falsi Algorithmus
    ; Hinweis: Sollte noch ungültige Ergebnisse liefern wenn einer der Grenzen = dem Schnittpunkt
    Func Schnittsuche(Const $sF1, Const $sF2, $dA, $dB, $iMaxIt = 100)
    ;by AspirinJunkie
    Local $xA = $dA, $xB = $dB
    Local $Ya, $Yb, $x, $Yx
    Local $xOld = $dB

    [/autoit] [autoit][/autoit] [autoit]

    For $n = 1 To $iMaxIt
    $Ya = _Fx($sF1, $xA) - _Fx($sF2, $xA) ;Differenz der Funktionen da Regula Falsi nach Nullstellen sucht
    $Yb = _Fx($sF1, $xB) - _Fx($sF2, $xB)
    $x = $xA - ($Ya * ($xB - $xA)) / ($Yb - $Ya)
    $Yx = _Fx($sF1, $x) - _Fx($sF2, $x)

    [/autoit] [autoit][/autoit] [autoit]

    If Abs($x - $xOld) < (4 * $FLT_EPSILON) Or Abs($Yx) < (5 * $FLT_EPSILON) Then ; Wenn Differenz der Durchgänge unter einer gewissen Genauigkeit liegt abbrechen
    Return $x
    Else ;Festlegung der neuen grenzen für den neuen Durchlauf
    $xOld = $x
    If $Ya > $Yx Then
    $xA = $x
    Else
    $xB = $x
    EndIf
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Next
    Return SetError(1, $iMaxIt, $x)
    EndFunc ;==>Schnittsuche

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; #FUNCTION#=================================================================================
    ; Name...........: _GET_FLT_EPSILON
    ; Description ...: Berechnet den binären Rundungsfehler und damit die Rechengenauigkeit
    ; Syntax.........: _GET_FLT_EPSILON
    ; Return values .: Epsilon
    ; Author ........: AspirinJunkie
    ;============================================================================================
    Func _GET_FLT_EPSILON()
    Local $x = 1
    Do
    $x /= 2
    Until 1 + $x <= 1
    Return $x
    EndFunc ;==>_GET_FLT_EPSILON

    [/autoit]

    Einmal editiert, zuletzt von AspirinJunkie (12. Februar 2011 um 14:26)

  • Hi,
    Newton mal sehr simpel umgesetzt:
    findet die nächste Nullstelle vom Startpunkt

    Spoiler anzeigen
    [autoit]

    ;funktion eintragen
    Func y($x)
    Return -4*$x*(5+2*$x)*(3*$x-9)
    EndFunc ;==>y

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $x1 = 11 ;irgendein startpunkt

    [/autoit] [autoit][/autoit] [autoit]

    Do
    $x0 = $x1
    $x1 = tangentenschnitt($x0);ergibt nächsten punkt auf der x-achse
    ; ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $x1 = ' & $x1 & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    Until Abs($x1 - $x0) < 1E-11

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite("Lösung y (" & $x1 & ") = "&y($x1)&@crlf)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func tangentenschnitt($x, $delta = 1E-13);tangente ermitteln und schnittpunkt mit der x-achse
    $y1 = y($x)
    $y2 = y($x + $delta)
    $m = ($y2 - $y1) / $delta
    $b = $y1 - $m * $x
    Return -$b / $m
    EndFunc ;==>tangentenschnitt

    [/autoit] [autoit][/autoit] [autoit][/autoit]

    -1#INF muss noch abgefangen werden, ggf auch eine startposition gefunden anhand der Funktion usw, aber schonmal ein Anfang für die Nullstellensuche

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    Einmal editiert, zuletzt von Andy (12. Februar 2011 um 15:40)