Ableiter

Du brauchst Grafiken, gute Programme oder Leute die dir helfen? Frag hier.
Benutzeravatar
Batze
Beiträge: 1492
Registriert: 03.06.2005 21:58
Wohnort: Berlin
Kontaktdaten:

Ableiter

Beitrag von Batze »

Also:
Aus reinem Interesse an dem Thema habe ich mal ein Programm zum differnzieren von Funktionen geschrieben (ich weiß das gibt es schon). Funktioniert vom Grundprinzip auch ganz gut. Allerdings ist es mir dann doch zu viel Arbeit das weiter zu machen und sowas wie die e-Funktion, die restlichen trigonometrischen Funktionen, auf einen Hauptnenner bringen usw. einzubauen. Aber vielleicht interessiert es ja jemanden, also poste ich den aktuellen Status mal hier (hoffe das ist dafür der richtige Bereich). Viel Spaß :wink:

Code: Alles auswählen

Enumeration 1                 ; Gadgets durchnummerieren
  #C_Input                    ; Eingabeschaltflächen
  #T_Input                    ;   Überschrift Eingabe
  #E_Input                    ;   Eingabe der Funktion die abgeleitet werden soll
  #C_ILatex                   ;   Input in Latex-Schreibweise darstellen
  
  #C_Output                   ; Ausgabeschaltflächen
  #T_Output                   ;   Überschrift Ausgabe
  #E_Output                   ;   Ausgabe der Funktion die abgeleitet wurde
  #C_OLatex                   ;   Output in Latex-Schreibweise darstellen
  
  #S_Splitter
  #B_Deriv
EndEnumeration

Enumeration 1                 ; Operatoren
  #Value                      ; Objekt ist Wert
  #Var                        ; Objekt ist Variable
  #X                          ; Objekt ist X
  
  #Add                        ; a '+' b      (a, b sind Objekte)
  #Subtract                   ; a '-' b
  #Multiply                   ; a '*' b
  #Divide                     ; a '/' b
  
  #Power                      ; a '^' b

  #EPower                     ; 'e^' a
  #Sin                        ; 'sin' a
  #Cos                        ; 'cos' a
  #Tan                        ; 'tan' a
  #ASin                       ; 'asin' a
  #ACos                       ; 'acos' a
  #ATan                       ; 'atan' a
  #Cot                        ; 'cot' a
  #Ln                         ; 'ln' a       (logarithmus naturalis)
 ; #Quad                       ; a '²'
 ; #Cubic                      ; a '³'
EndEnumeration


Structure MObj                ; Rechenobjekte
  *Parent.mobj                ; Objekt, dass das Objekt beinhaltet
  
  Type.l                      ; Welcher Operator / Typ
  *Child.MObj   [2]           ; Bis jetzt maximal 2 Objekte
EndStructure

Macro SetObjectText(Object, Text)
  PokeS(Object + SizeOf(MObj), Text)                        ; Wert im Objekt speichern
EndMacro
Macro GetObjectText(Object)
  PeekS(Object + SizeOf(MObj))                              ; Wert aus dem Objekt holen
EndMacro

;*************************************************************************************************************
;*************************************************************************************************************

Procedure CreateMObj(*Parent.MObj=0, Index=0, Size=0)       ; Mathe-Objekt erzeugen
  
  If Size > 0                                               ; Zusätzlicher Anhang
    *Obj.MObj = AllocateMemory(SizeOf(MObj)+Size+1)         ; Speicher dafür erzeugen (Textzeile)
  Else
    *Obj.MObj = AllocateMemory(SizeOf(MObj))                ; Speicher dafür erzeugen (Nur Objektdaten)
  EndIf
    
  If *Obj And *Parent                                       ; Wenn das geklappt hat und ein Elternobjekt angegeben ist
    *Obj\Parent = *Parent                                   ; Elternobjekt angeben
    *Parent\Child[Index] = *Obj                             ; Objekt eintragen
  EndIf
  
  ProcedureReturn *Obj                                      ; Objekt zurückgeben
EndProcedure

;*************************************************************************************************************

Procedure DestroyMObj(*MObj.MObj)                           ; Mathe-Objekt entfernen
  
  For i=0 To 1                                              ; Parameter durchgehen
  
    If *MObj\Child [i]                                      ; Wenn es ein Unterobjekt gibt ...
      DestroyMObj(*MObj\Child [i])                          ; Unterobjekt ebenfalls freigeben
    EndIf
    
    If *MObj\Parent And *MObj\Parent\Child [i] = *MObj      ; Wenn das Child vom Parent i gerade dieses hier ist ...
      *MObj\Parent\Child [i] = 0                            ; Child i existiert nicht mehr
    EndIf
  
  Next
  
  FreeMemory(*MObj)                                         ; Speicherbereich des Objekts freigeben
    
  ProcedureReturn 0                                         ; Erfolgreich
EndProcedure

;*************************************************************************************************************

Procedure CopyMObj(*Old.MObj, *Parent.MObj, Index=0)        ; Objekt kopieren
 
  *New.MObj = AllocateMemory(MemorySize(*Old))              ; Neuen Speicherbereich mit selber Dimension
  CopyMemory(*Old, *New, MemorySize(*Old))                  ; Alte Daten kopieren
  
  *New\Parent = *Parent                                     ; Parent ändern

  If *New\Parent                                            ; Wenn es ein Vaterobjekt gibt ...
    *New\Parent\Child [Index] = *New                        ; Child Index eintragen ...
  EndIf
  
  
  For i=0 To 1                                              ; Parameter durchgehen
    
    If *Old\Child[i] <> 0                                   ; Objekt i ist da -> ...
      CopyMObj(*Old\Child[i], *New, i)                      ; Auch dieses kopieren
    EndIf
        
  Next
  
  ProcedureReturn *New
EndProcedure

;*************************************************************************************************************

Procedure ResizeMObj(*MObj.MObj, Size=0)                    ; Objektgröße ändern (um z.B. den Typ zu ändern)
  
  *New.MObj = ReAllocateMemory(*MObj, SizeOf(MObj)+Size+1)  ; Speicherbereich ändern
  
  If *New                                                   ; Wenn das geklappt hat
    
    For i=0 To 1                                            ; Alle Parameter durchgehen
    
      If *New\Parent And *New\Parent\Child [i] = *MObj      ; Wenn das Child i des Parents die alte Addresse ist ...
        *New\Parent\Child [i] = *New                        ; Neue Addresse eintragen
      EndIf
      
      If *New\Child [i]                                     ; Wenn es ein Child gibt
        *New\Child[i]\Parent = *New                         ; Vater auf neue Addresse ändern
      EndIf
      
    Next
    
  EndIf
  
  ProcedureReturn *New                                      ; Neue Addresse zurückgeben
EndProcedure

;*************************************************************************************************************

Procedure ReplaceMObj(*Old.MObj, *New.MObj)                 ; Objekt einfügen (löscht altes nicht)
  
  If *Old\Parent                                            ; Wenn es ein Elternobjekt gibt
    If     *Old\Parent\Child[0] = *Old                      ; Wenn das Child das aktuelle ist
      *Old\Parent\Child[0] = *New
    ElseIf *Old\Parent\Child[1] = *Old                      ; Wenn das Child das aktuelle ist
      *Old\Parent\Child[1] = *New
    EndIf 
  EndIf
  *New\Parent = *Old\Parent  
    
  ProcedureReturn *New                                      ; Neues einfügen
EndProcedure
;*************************************************************************************************************
;*************************************************************************************************************

Procedure.s OperatorName(Operator.l)                                    ; Namen des Operators ermitteln
  Protected Name$ = ""
  Select Operator
    Case #Add      : Name$ = "+"                  ; a '+' b      (a, b sind Objekte)
    Case #Subtract : Name$ = "-"                  ; a '-' b
    Case #Multiply : Name$ = "*"                  ; a '*' b
    Case #Divide   : Name$ = "/"                  ; a '/' b
    Case #EPower   : Name$ = "e^"                 ; 'e^' a
    Case #Power    : Name$ = "^"                  ; a '^' b
    Case #Sin      : Name$ = "sin"                ; 'sin' a
    Case #Cos      : Name$ = "cos"                ; 'cos' a
    Case #Tan      : Name$ = "tan"                ; 'tan' a
    Case #ASin     : Name$ = "asin"               ; 'asin' a
    Case #ACos     : Name$ = "acos"               ; 'acos' a
    Case #ATan     : Name$ = "atan"               ; 'atan' a
    Case #Cot      : Name$ = "cot"                ; 'cot' a
    Case #X        : Name$ = "x"                  ; 'x'
  EndSelect
  ProcedureReturn Name$
EndProcedure

;*************************************************************************************************************

Procedure OpenMainWindow(W=400, H=300)                                  ; Hauptfenster öffnen
  OpenWindow(0,   0,   0, W, H, "Ableiter", #PB_Window_ScreenCentered | #PB_Window_Invisible | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget)
  CreateGadgetList(WindowID(0))
    ContainerGadget (#C_Input,     0,    0,  W-10,   60)
      TextGadget    (#T_Input,     0,    0,    60,   15, "Funktion:")
      CheckBoxGadget(#C_ILatex,   65,    0,    70,   15, "Latexcode")
      EditorGadget  (#E_Input,     0,   20,  W-10,  100)
    CloseGadgetList()

    ContainerGadget (#C_Output,    0,    0,  W-10,   60)
      TextGadget    (#T_Output,    0,    5,    60,   15, "Ableitung:")
      CheckBoxGadget(#C_OLatex,   65,    5,    70,   15, "Latexcode")
      EditorGadget  (#E_Output,    0,   25,  W-10,  100, #PB_Editor_ReadOnly)
    CloseGadgetList()
    
    SplitterGadget  (#S_Splitter,  5,    5, W-10, H-35, #C_Input, #C_Output, #PB_Splitter_Separator) ; Größen Veränderbar
    SetGadgetState  (#S_Splitter,  (H-35)/2)
    ButtonGadget    (#B_Deriv,     5, H-25,  100,   20, "Ableiten")
      
  HideWindow(0, 0)                                          ; Fenster anzeigen
  
EndProcedure

;*************************************************************************************************************

Procedure ResizeGadgets(Mode.l)
  
    W = WindowWidth(0)
    H = WindowHeight(0)
  If Mode
    If W < 150                                                               ; Minimalbreite
      ResizeWindow(0, #PB_Ignore, #PB_Ignore, 150, #PB_Ignore)
    EndIf
    If H < 90                                                               ; Minimalhöhe
      ResizeWindow(0, #PB_Ignore, #PB_Ignore, #PB_Ignore, 90)
    EndIf
    ResizeGadget(#S_Splitter,   5,    5, W-10,  H-35)
    ResizeGadget(#B_Deriv,      5, H-25,  100,    20)
  EndIf
  
  ResizeGadget(#E_Input,      0,   20, W-10,  GadgetHeight(#C_Input)  - 25)
  ResizeGadget(#E_Output,     0,   25, W-10,  GadgetHeight(#C_Output) - 30)
  ;HideGadget(#C_Input, 1)
  ;HideGadget(#C_Output, 1)
  
EndProcedure

;*************************************************************************************************************

Procedure Simplyfy(*MObj.MObj)                            ; Objekt vereinfachen
  Debug "*MObj: ---------------"
  Debug "Parent   = " + Str(*MObj\Parent)
  Debug "Type     = " + Str(*MObj\Type  )
  Debug "Child[0] = " + Str(*MObj\Child[0])
  Debug "Child[1] = " + Str(*MObj\Child[1])
  
  Select *MObj\Type                                         ; Typ ermitteln
  
  
    Case #Add, #Subtract
      Simplyfy(*MObj\Child[0])                              ; Erstes Objekt vereinfachen
      Simplyfy(*MObj\Child[1])                              ; Zweites Objekt vereinfachen
      If     *MObj\Child[0]\Type = #Value And GetObjectText(*MObj\Child[0]) = "0"           ; A+0 = A, A-0 = A
        *Old.MObj = *MObj                                                                   ; Addresse speichern
        *MObj = ReplaceMObj(*Old, *Old\Child[1])                                            ; Aktuelles mit dem darin ersetzen
        *Old\Child[1] = 0                                                                   ; Objekt ist nicht mehr zur Verfügung
        DestroyMObj(*Old)                                                                   ; Die alte Summe mit der 0 entfernen
      ElseIf *MObj\Child[1]\Type = #Value And GetObjectText(*MObj\Child[1]) = "0"           ; A+0 = A, A-0 = A
        *Old.MObj = *MObj                                                                   ; Addresse speichern
        *MObj = ReplaceMObj(*Old, *Old\Child[0])                                            ; Aktuelles mit dem darin ersetzen
        *Old\Child[0] = 0                                                                   ; Objekt ist nicht mehr zur Verfügung
        DestroyMObj(*Old)                                                                   ; Die alte Summe mit der 0 entfernen
      EndIf
        
   
    Case #Multiply
      Simplyfy(*MObj\Child[0])                              ; Erstes Objekt vereinfachen
      Simplyfy(*MObj\Child[1])                              ; Zweites Objekt vereinfachen
      If     *MObj\Child[0]\Type = #Value And GetObjectText(*MObj\Child[0]) = "1"           ; 1*A = A
        *Old.MObj = *MObj                                                                   ; Addresse speichern
        *MObj = ReplaceMObj(*Old, *Old\Child[1])                                            ; Aktuelles mit dem darin ersetzen
        *Old\Child[1] = 0                                                                   ; Objekt ist nicht mehr zur Verfügung
        DestroyMObj(*Old)                                                                   ; Das alte Produkt mit der 1 entfernen
      ElseIf *MObj\Child[1]\Type = #Value And GetObjectText(*MObj\Child[1]) = "1"           ; A*1 = A
        *Old.MObj = *MObj                                                                   ; Addresse speichern
        *MObj = ReplaceMObj(*Old, *Old\Child[0])                                            ; Aktuelles mit dem darin ersetzen
        *Old\Child[0] = 0                                                                   ; Objekt ist nicht mehr zur Verfügung
        DestroyMObj(*Old)                                                                   ; Das alte Produkt mit der 1 entfernen
      Else
        If     *MObj\Child[0]\Type = #Value And GetObjectText(*MObj\Child[0]) = "0"         ; 0*A = 0
          *Old.MObj = *MObj                                                                 ; Addresse speichern
          *MObj = ReplaceMObj(*Old, *Old\Child[0])                                          ; Aktuelles mit dem darin ersetzen
          *Old\Child[0] = 0                                                                 ; Objekt ist nicht mehr zur Verfügung
          DestroyMObj(*Old)                                                                 ; Das alte Produkt mit dem A entfernen
        ElseIf *MObj\Child[1]\Type = #Value And GetObjectText(*MObj\Child[1]) = "0"         ; A*0 = 0
          *Old.MObj = *MObj                                                                 ; Addresse speichern
          *MObj = ReplaceMObj(*Old, *Old\Child[1])                                          ; Aktuelles mit dem darin ersetzen
          *Old\Child[1] = 0                                                                 ; Objekt ist nicht mehr zur Verfügung
          DestroyMObj(*Old)                                                                 ; Das alte Produkt mit der A entfernen
        EndIf
      EndIf
  
    
    Case #Divide
      Simplyfy(*MObj\Child[0])                              ; Erstes Objekt vereinfachen
      Simplyfy(*MObj\Child[1])                              ; Zweites Objekt vereinfachen
      If *MObj\Child[1]\Type = #Value And GetObjectText(*MObj\Child[1]) = "1"        ; A/1
        *Old.MObj = *MObj                                                            ; Addresse speichern
        *MObj = ReplaceMObj(*Old, *Old\Child[0])                                     ; Aktuelles mit dem darin ersetzen
        *Old\Child[0] = 0                                                            ; Objekt ist nicht mehr zur Verfügung
        DestroyMObj(*Old)                                                            ; Den alten Quotienten mit der 1 entfernen
      EndIf
      

  EndSelect
  
  ProcedureReturn *MObj
  
EndProcedure

;*************************************************************************************************************

Procedure BWith(Text$, Pos, Find$, Wordproof=0)                              ; Begins with
  If UCase(Find$) = UCase( Mid(Text$, Pos, Len(Find$)) )                     ; Gefunden
    
    If Wordproof = 1
      If Pos > 1            : A = PeekC(@Text$+Pos-2) : EndIf                ; Vorheriges Zeichen
      If Pos < Len(Text$)-1 : B = PeekC(@Text$+Pos+Len(Find$)-1) : EndIf     ; Nächstes Zeichen
      If ( B => 'a' And B <= 'z' ) Or ( B => 'A' And B <= 'Z' ) Or ( A => 'a' And B <= 'z' ) Or ( A => 'A' And B <= 'Z' )   ; Wenn drumherrum ein Buchstabe ...
        ProcedureReturn 0                                                    ; Trotzdem nicht richtig
      Else                                                                   ; Sonst ...
        ProcedureReturn 1                                                    ; richtig
      EndIf
    Else
      ProcedureReturn 1                                                      ; richtig
    EndIf
    
  Else
  
    ProcedureReturn 0
  
  EndIf
EndProcedure

;*************************************************************************************************************

Procedure FindBracketEnd(Text$, Pos, Open$, Close$)
  NextOpen  = Pos
  NextClose = Pos
  
  ; ( (a( b(( ))b )a) )
  Repeat
    NextOpen  = FindString(Text$, Open$,  NextOpen +1)
    NextClose = FindString(Text$, Close$, NextClose+1)
  Until NextOpen > NextClose Or NextOpen = 0
  
  If NextClose = 0
    NextClose = Len(Text$)+1
  EndIf
  ProcedureReturn NextClose
EndProcedure

Procedure FindEnd(Text$, Pos)                                              ; Endposition finden
  For X=Pos To Len(Text$)
    Char$ = Mid(Text$, X, 1)                                               ; Aktuelles Zeichen
    If Char$ = "("                                                         ; Eine der 'Klammer auf'
      X = FindBracketEnd(Text$, X, "(",")")                                ; Klammer zu finden
      Break
    ElseIf Char$ = " " Or Char$ = #TAB$                                    ; Nichts
      If NoSpace                                                           ; Wenn es keine führenden Leerzeichen sind
        X-1                                                                ; Das gehört schon nicht mehr dazu
        Break
      EndIf
    Else
      NoSpace = 1                                                          ; Ausnahmsweise mal kein Leerzeichen
    EndIf
  Next
  
  ProcedureReturn X                                                        ; Position zurückgeben
EndProcedure

;*************************************************************************************************************

Procedure.s ObjectToText(*MObj.MObj)                                    ; Objekt in Text umwandeln
  Op$ = OperatorName(*MObj\Type)                                        ; 
  Debug "["+Op$+"]"
  Select *MObj\Type                                                     ; Art des Objekts ermitteln
    Case #Add To #Divide                                                ; 2-Stufige Operation
      T$ = "(" + ObjectToText(*MObj\Child[0]) + " " + Op$ + " " + ObjectToText(*MObj\Child[1]) + ")"
    Case #X
      T$ = "x"                                                          ; X
    Case #Sin To #Cos                                                   ; 1-Stellige Operatoren
      T$ = Op$ + "(" + ObjectToText(*MObj\Child[0]) + ")"
    Case #Value, #Var                                                   ; Direkte Werte
      T$ = GetObjectText(*MObj)                                         ; Text ermitteln  
  EndSelect
  Debug T$
  
  ProcedureReturn T$                                                    ; Text zurückgeben
EndProcedure

;*************************************************************************************************************

Procedure TextToObject(Text$, *Parent.MObj=0, Index=0)                  ; Text in Objekt umwandeln
  Text$ = Trim(Text$)                                                   ; Überschüssige Leerzeichen weglassen
  
  While Left(Text$, 1) = "("                                            ; Außenklammern entfernen
    BracketEnd = FindBracketEnd(Text$, 1, "(",")")
    If BracketEnd => Len(Text$)                                         ; Nur wenn Klammer um alles ist
      Text$ = Trim(Mid(Text$, 2, BracketEnd-2))                         ; Die Klammer entfernen
    Else
      Break                                                             ; Abbrechen, da fertig
    EndIf
  Wend
  
  
  
  For Op=#Add To #Divide                                                ; echte 2-Seitige Operatoren
    Op$ = OperatorName(Op)                                              ; Namen ermitteln
  
    For X = 1 To Len(Text$)                                             ; Text durchgehen
      Char$ = Mid(Text$, X, 1)                                          ; Aktuelles Zeichen
    
      If Char$ = "("                                                    ; Eine der 'Klammer auf'
        X = FindBracketEnd(Text$, X, "(",")") + 1                       ; Klammer zu finden und danach weitermachen
      EndIf
    
      If BWith(Text$, X, Op$)                                           ; Wenn der Operator gefunden wurde
        *Actual.MObj = CreateMObj(*Parent, Index)                       ; Objekt hinzufügen
        Debug "Objekt Erstellen: -------------------------"
        Debug "Operator    = " + Op$
        Debug "Parameter 1 = " + Left(Text$,        X-1)
        Debug "Parameter 2 = " + Mid (Text$, X+Len(Op$))
        *Actual\Type   = Op                                             ; Operator eintragen
        TextToObject(Left(Text$,        X-1),  *Actual, 0)              ; Alles davor  ist erster  Parameter
        TextToObject(Mid (Text$, X+Len(Op$)),  *Actual, 1)              ; Alles danach ist zweiter Parameter
        ProcedureReturn *Actual                                         ; Fertig
      EndIf
    Next
  
  Next
  
  
  
  For Op=#Sin To #Cos
    Op$ = OperatorName(Op)                                              ; Namen ermitteln
    For X = 1 To Len(Text$)                                             ; Text durchgehen
      Char$ = Mid(Text$, X, 1)                                          ; Aktuelles Zeichen
    
      If Char$ = "("                                                    ; Eine der 'Klammer auf'
        X = FindBracketEnd(Text$, X, "(",")")+1                         ; Klammer zu finden
      EndIf
    
      If BWith(Text$, X, Op$, 1)                                        ; Wenn der Operator gefunden wurde
        *Actual.MObj = CreateMObj(*Parent, Index)                       ; Objekt hinzufügen
        Debug "Objekt Erstellen: -------------------------"
        Debug "Operator    = " + Op$        
        Debug "Parameter   = " + Mid (Text$, X+Len(Op$))
        *Actual\Type   = Op                                             ; Operator speichern
        TextToObject(Mid (Text$, X+Len(Op$)),  *Actual, 0)              ; Alles danach ist Parameter
        ProcedureReturn *Actual                                         ; Fertig
      EndIf
    Next
    
  Next
  
  Debug "Objekt Erstellen: -------------------------"
  Debug "Wert = [ " + Text$ + " ]"
  *Actual.MObj = CreateMObj(*Parent, Index, Len(Text$))                   ; Objekt erzeugen
  SetObjectText(*Actual, Text$)                                           ; Text abspeichern
  
  If Asc(Text$) => '0' And Asc(Text$) <= '9'
    *Actual\Type = #Value                                                 ; Zahl (z.B.: 105948.0144)
  ElseIf UCase(Text$) = "X"
    *Actual\Type = #X                                                     ; X
  Else
    *Actual\Type = #Var                                                   ; Variable
  EndIf
   
  ProcedureReturn *Actual                                                 ; Fertig



  
  ProcedureReturn 0                                                       ; Fehlgeschlagen  
EndProcedure

;*************************************************************************************************************

Procedure Diff(*MObj.MObj, *Parent.MObj=0, Index=0)                     ; Objekt ableiten
  
  
  Select *MObj\Type                                                     ; Verschieden ableiten
    
    
    ; Summenregel: (f + g)' = f' + g' ************************************************************************
    Case #Add                                                              ; Addieren zweier Objekte
      *Diffed.MObj      = CreateMObj(*Parent, Index)                       ; Neues Erzeugen
                          Diff    (*MObj\Child[0], *Diffed, 0)             ; f'
      *Diffed\Type      = #Add                                             ;     +
                          Diff    (*MObj\Child[1], *Diffed, 1)             ;         g'
      Debug "+"


    ; Summenregel: (f - g)' = f' - g' ************************************************************************
    Case #Subtract                                                         ; Subtrahieren zweier Objekte
      *Diffed.MObj      = CreateMObj(*Parent, Index)                       ; Neues Erzeugen
                          Diff    (*MObj\Child[0], *Diffed, 0)             ; f'
      *Diffed\Type      = #Subtract                                        ;     -
                          Diff    (*MObj\Child[1], *Diffed, 1)             ;         g'
      Debug "-"
      

    ; Produktregel: (f * g)' = (f' * g) + (f * g') ***********************************************************
    Case #Multiply                                                         ; Multiplizieren zweier Objekte
      *Diffed.MObj      = CreateMObj(*Parent, Index)                       ; Neues Erzeugen
      
        *D_0.MObj       = CreateMObj(*Diffed,     0)
                          Diff    (*MObj\Child[0], *D_0,    0)             ; ( f'
        *D_0\Type       = #Multiply                                        ;      *
                          CopyMObj(*MObj\Child[1], *D_0,    1)             ;         g )
                
      *Diffed\Type      = #Add                                             ;              +
      
        *D_1.MObj       = CreateMObj(*Diffed,     1)
                          CopyMObj(*MObj\Child[0], *D_1,    0)             ;                 ( f
        *D_1\Type       = #Multiply                                        ;                      *
                          Diff    (*MObj\Child[1], *D_1,    1)             ;                         g' )
      Debug "*"


    ; Quotientenregel: (g / h)' = ((g' * h) - (g * h')) / (h*h) **********************************************
    Case #Divide                                                           ; Dividieren zweier Objekte
      *Diffed.MObj      = CreateMObj(*Parent, Index)                       ; Neues Erzeugen
      
        *D_0.MObj       = CreateMObj(*Diffed,     0)

          *D_00.MObj    = CreateMObj(*D_0,        0)
                          Diff    (*MObj\Child[0], *D_00,   0)             ; ( g'
          *D_00\Type    = #Multiply                                        ;      *
                          CopyMObj(*MObj\Child[1], *D_00,   1)             ;         h )
        
        *D_0\Type       = #Subtract                                        ;                -
        
          *D_01.MObj    = CreateMObj(*D_0,        1)
                          CopyMObj(*MObj\Child[0], *D_01,   0)             ;                    ( g
          *D_01\Type    = #Multiply                                        ;                         *
                          Diff    (*MObj\Child[1], *D_01,   1)             ;                            h' )
        
      *Diffed\Type      = #Divide                                          ; ----------------------------------
      
        *D_1.MObj       = CreateMObj(*Diffed,     1)
                          CopyMObj(*MObj\Child[1], *D_1, 0)                ;            ( h
        *D_1\Type       = #Multiply                                        ;                 *
                          CopyMObj(*MObj\Child[1], *D_1, 1)                ;                    h )
      Debug "/"
    
    
    ; Sinus, Kettenregel: (sin h)' = (cos h) * h' ************************************************************
    Case #Sin                                                              ; Sinus berechnen
      *Diffed.MObj      = CreateMObj(*Parent, Index)                       ; Neues Erzeugen
      
        *D_0.MObj       = CreateMObj(*Diffed,     0)
        *D_0\Type       = #Cos                                             ;    ( Cos
                          CopyMObj(*MObj\Child[0], *D_0, 0)                ;           h )
      
      *Diffed\Type      = #Multiply                                        ;                 *
      
                          Diff    (*MObj\Child[0], *Diffed, 1)             ;                      h'
      Debug "Sin"
      

    ; Cosinus, Kettenregel: (cos h)' = ( (-1 * (sin h)) * h') ************************************************
    Case #Cos                                                              ; Cosinus berechnen
      *Diffed.MObj      = CreateMObj(*Parent, Index)                       ; Neues Erzeugen
      
        *D_0.MObj       = CreateMObj(*Diffed,     0)
        
          *D_00.MObj    = CreateMObj(*D_0,        0, 2)
          *D_00\Type    = #Value
                          SetObjectText(*D_00, "-1")                       ;  -1
                          
        *D_0\Type       = #Multiply                                        ;      *
      
          *D_01.MObj    = CreateMObj(*D_0,        1)
          *D_01\Type    = #Sin                                             ;          ( Sin
                          CopyMObj(*MObj\Child[0], *D_01, 0)               ;                 h )
      
      *Diffed\Type      = #Multiply                                        ;                      *
      
                          Diff    (*MObj\Child[0], *Diffed, 1)             ;                          h'
      Debug "Cos"
      
    
    ; Konstante Funktion: (a)' = 0 ***************************************************************************
    Case #Var, #Value                                                      ; Wert oder Variable
      *Diffed.MObj      = CreateMObj(*Parent, Index, 1)                    ; Neues Erzeugen
      *Diffed\Type      = #Value                                           ; 
                          SetObjectText(*Diffed, "0")                      ; 0
      Debug "1, a"
    
    
    ; Einzige Funktion die er ableiten kann: x' = 1 **********************************************************
    Case #X                                                                ; X
      *Diffed.MObj      = CreateMObj(*Parent, Index, 1)                    ; Neues Erzeugen
      *Diffed\Type      = #Value                                           ; 
                          SetObjectText(*Diffed, "1")                      ; 1
      Debug "X"
      
      
  EndSelect
  
  ProcedureReturn *Diffed
  
EndProcedure

;*************************************************************************************************************
;*************************************************************************************************************

OpenMainWindow()

Repeat
  WEvent = WaitWindowEvent()
  
  If     WEvent = #PB_Event_SizeWindow
    ResizeGadgets(1)
  ElseIf WEvent = #PB_Event_Gadget
    Select EventGadget()
      Case #S_Splitter : ResizeGadgets(0)
      Case #B_Deriv    : *Object.MObj = TextToObject(GetGadgetText(#E_Input))
                         If *Object
                           *Diffed.MObj = Diff(*Object)
                           *Diffed      = Simplyfy(*Diffed)
                           SetGadgetText(#E_Output, ObjectToText(*Diffed) )
                           
                           DestroyMObj(*Object)
                           DestroyMObj(*Diffed)
                         EndIf
                         
    EndSelect
  EndIf

Until WEvent = #PB_Event_CloseWindow

End
Hier sind meine Codes (aber die Seite geht gerade nicht):
http://www.basicpure.de.vu
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Beitrag von DarkDragon »

Hallo,

Leider muss ich sagen, dass

Code: Alles auswählen

3 * x^2 + 5
abgeleitet nicht, so wie dein Tool behauptet 0 ist.
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Benutzeravatar
Batze
Beiträge: 1492
Registriert: 03.06.2005 21:58
Wohnort: Berlin
Kontaktdaten:

Beitrag von Batze »

Mein programm kann x^2 nicht. Für das ist 'x^2' im Moment einfach nur eine seltsame Variable. womit er dann korrekterweise 0 herrausbekommt.
Also, nochmal: das ist noch nicht fertig, da fehlt noch einiges um es wirklich nutzbar zu machen.
Hier sind meine Codes (aber die Seite geht gerade nicht):
http://www.basicpure.de.vu
Antworten