[previous] [home] [search] Marcus' HP28S Page [contact] [up] [next] 

HP28S openedContents

Infos about HP28S

The HP28s is a programmable pocket calculator released by Hewlett-Packard in 1988. I bought it in the same year and it replaced my loyal companion FX602p. For that time it had a huge memory of 32KByte. All my programs fit into. All retyping was bygone (except when exchanging the batteries too slowly). Furthermore it was able to operate with complex numbers, vectors and matrices, which was extremely useful. Some more advanced linear algebra operations (see below), I programmed myself as they were not integrated. HP28s also possessed some symbolic math capabilities, which was novel for that time, but too limited to be useful. It reminded me on Mumath (anybody remembering this?), but even more limited. The numerical integration and equation solvers were, on the other hand, more than useful. Like all HP calculator (at least at that time) it had Reverse Polish (=postfix) Notation (RPN). At the beginning a bit strange, but once you get used to it, you'll never want to miss it, especially if you have an infinite stack! Although the programming language RPL (Reverse Polish Lisp) had if-then-else, for-next, do-until, and while-repeat elements, it was due to RPN similar to Forth, resulting in very compact and fast programs, but completely unreadable (as you will see below)!

My Programs

In the following you find a list of programs, mostly scientific, I have written during my undergraduate time at the university. They run on the HP28S and also on the predecessor HP28C and probably also on the successor HP48x. I programmed some more advanced linear algebra operations, including Eigenvalues and vectors, pseudo-inverse, Schmidts orthogonalization, rank, characteristic polynomial, and exponentiation of a matrix ! Furthermore I implemented fast Fourier transformation, and fast polynomial multiplication, which can be used for multiplying large numbers with n digits in time O(n·log(n)). Some smaller combinatoric tools, including permutations, Fibonacci numbers, prime-factor decomposition, chain-fractions, Gödelization, multinomial coefficients. Most useful was a tool for recovering numerator and denominator of a number given in decimal representation, as calculation with fractions was missing in HP28S. Programs for computing the solution curve of n-1 algebraic or differential equations with n degrees on freedom, Newton iteration for finding the zeros of n equations with n degrees on freedom, and for minimizing n-dimensional functions have also been implemented. On the graphical side I implemented programs for drawing implicit and parametrizised functions, and a 3D car race with 1 image per second update. I wrote more programs for the HP28S, but these are the important ones. Fortunately I carefully wrote all programs up. Unfortunately I documented them in German. Try a robot translation if you have problems in figuring out what is going on.

 © 2000 by ... [previous] [home] [search] [science] [calculators] [personal] [contact] [up] [next] ... Marcus Hutter 

Listings

+-----------------------------------------------------------+
|          P R O G R A M M E   F U E R   H P 2 8 S          |
+-----------------------------------------------------------|
|          Copyright 1988 by Marcus Hutter  5.4.90          |
+-----------------------------------------------------------+


+-----------------------------------------------------------+
|          0. I N H A L T S V E R Z E I C H N I S           |
+-----------------------------------------------------------+


0. Inhaltsverzeichnis ................................... __

1. Allgemeines .......................................... __
   1.1 Hinweise zur Eingabe von Programmen
   1.2 Weitere Hinweise
   1.3 Gemeinsame Hinweise für Programme
   1.4 Copyright & Hilfe

2. HOME   Hauptmenü .................................... __
   2.1 Täglich benötigte Funktionen
   2.2 Nützliche Subroutinen
   2.3 Sonstiges

3. UTIL   Utilities ..................................... __
   3.1 Matrizen
   3.2 Vektoren
   3.3 Polynome
   3.4 Real-Zahlen
   3.5 Ganze Zahlen
   3.6 Elemente
   3.7 Sonstige

4. GRAPH  Graphik-Programme ............................. __

5. PHY    Physikalische Konstanten ...................... __

6. CAR    Autorennen .................................... __
   6.1 Autorennen
   6.2 Straßenerzeugung
   6.3 Car-Daten

7. ....   ............................................... __

8. TEST   Test-/Halbfertige Programme ................... __
   8.1 Lösungs/Iterations-Algorithmen
   8.2 Sonstige Utilities

9. ALT    Alte, ausgediente Programme ................... __


+-----------------------------------------------------------+
|                 1. A L L G E M E I N E S                  |
+-----------------------------------------------------------+

1.1 Hinweise zur Eingabe von Programmen
---------------------------------------
Die Programme sind soweit wie möglich so ausgedruckt, wie sie
einzugeben sind. D.h. Leerzeichen trennen die einzelnen Befehle,
Ein zusammenhängender Teil (ohne Space) bedeutet EINEN Befehl
auf dem HP28S; z.B. bedeutet << Programmanfang ( im Gegensatz zu
< < was zwei Kleinerzeichen bedeutet).

Die Befehlseqünz 'Programmname' STO ist meistens weggelassen,
da sie sich aus der Überschrift oder aus dem Zusammenhang
ergibt. Häufig wird die Notation "VAR: Inhalt" verwendet, was
als "Inhalt 'VAR' STO" zu lesen ist.

1.2 Weitere Hinweise
--------------------
Die folgenden Hauptüberschriften stellen das Directory dar, in
dem die Programme abgelegt werden sollten. Einzig zwingend ist,
daß die Unterprogramme im PATH des Hauptprogrammes stehen,
damit auf diese zugegriffen werden kann. z.B. müssen die "nütz-
lichen Subroutinen" unter 2.2 im HOME-Directory stehen.


1.3 Gemeinsame Hinweise für Programme
--------------------------------------
Bei einigen Programmen muss, ohne daß dies erwähnt wird
folgendes beachtet werden:

- Die LAST-Funktion wird verwendet; zur korrekten Funktion
  des Porgramms muss diese also aktiviert sein.
- Bei 10-stelligen Real-/Komplex-Zahlen in Beispielen werden
  meist nur die ersten 2 oder 3 angegeben.
- Die Genauigkeitsschranke eps=1E-8 wird benutzt, d.h. dass
  Ergebnis auf 8 Stellen berechnet werden oder/und dass das
  Programm Werte auf 8 Dezimalen erwartet. Weitere Informa-
  tionen ^2.3 eps.
- Funktionen werden direkt auf dem Stack als Parameter
  übergeben. Speichern Sie längere Funktionen unter einem
  NAMEN ab, und übergeben Sie << NAMEN >> .
- Benötigt man die Funktion für ein Programm voraussichtlich
  öfters so wird diese in F gespeichert (ähnlich zu EQ).
- Mit "n.n.opt" markierte Programme sind noch nicht optimiert
  und/oder reagieren empfindlich auf Spezialfälle.
- Beendigung ist durch beliebigen Tastendruck nach kurzer
  Verzögerungszeit (außer ATTN = ON) möglich.
- Graphik-Programme rufen nach Beendigung meist DGTIZ auf.

1.4 Copyright & Hilfe
---------------------
Dieser File/Ausdruck darf korrigiert, verbessert, erweitert,
kostenlos (nicht-gewerblich) weitergegeben werden, solange
der Urheber-Name erhalten bleibt und der Inhalt nicht ver-
unstaltet wird. Jegliche Haftung für den Inhalt ist ausge-
schlossen, da sich die Programme teilweise noch in der Test-
phase befinden.
Wer gute Programme oder anderes nützliches für den HP28S
besitzt oder Fragen bzgl. des Inhalts hat kann mich unter
Tel: 089/903 9627 Germany erreichen.


+-----------------------------------------------------------+
|                  2. H O M E - Directory                   |
+-----------------------------------------------------------+

2.1 Täglich benötigte Funktionen
--------------------------------

SCM    (Set Custom-Menu)
------------------------
Besetzt das Cusom-Menu mit der Standardbelegung (Häufigst
benutzte Befehle) und zeigt Zeile 1 an.

1. Zeile: GRAPH UTIL  PHY   TEST  CAR   HOME   (Menüs)
2. Zeile: MANU   .    FACT  SQGL  BRC    .     (Programme)
3. Zeile: PUSH  POP   TOP                      (2.Stack)

<< { GRAPH UTIL  PHY   TEST  CAR   HOME
    MANU   .    FACT  SQGL  BRC    .
    PUSH POP TOP BPOP }
  MENU >>


CLST, PUSH, POP, TOP, BPUSH, BPOP, BTOP, ST  (Stack/Qüü)
----------------------------------------------------------
Dies sind Befehle für einen alternativen Stack (LIFO) bzw. eine
Qüü (FIFO), hauptsächlich für interaktiven Gebrauch gedacht.
Die Elemente werden in ST in Listenform gespeichert.

CLST  löscht den ST
PUSH  Fügt Stackelement vorne an ST an
POP   Holt (& löscht damit) erstes Element von ST
TOP   Holt (ohne zu löschen) erstes Element von ST
BPUSH Fügt Stackelement hinten an ST an
BPOP  Holt (& löscht damit) letztes Element von ST
BTOP  Holt (ohne zu löschen) letztes Element von ST
ST    Enthält die Alternativ-Stack-Elemente

Zur Realisierung eines Alternativ-Stacks werden benötigt:
PUSH, POP  (ev. CLST, TOP)

Zur Realisierung einer Warteschlange werden benötigt:
PUSH, BPOP (oder BPUSH, POP) (ev. weitere)

CLST:  << { } 'ST' STO >>
PUSH:  << ST + 'ST' STO >>
POP:   << ST 1 GET ST 2 OVER SIZE SUB 'ST' STO >>
TOP:   << ST 1 GET >>
BPUSH: << ST SWAP + 'ST' STO >>
BPOP:  << ST DUP SIZE GET LAST 1 - 1 SWAP SUB 'ST' STO >>
BTOP:  << ST DUP SIZE GET >>
ST:    { }

Beispiel: Sie haben 4 Elemente auf dem (Real)-Stack e4,e3,e2,e1
und wollen (e4+e3)*(e2+e1) berechnen.

 +    :wie gewohnt e2 und e1 addieren    Stack:  e4 e3 e2+e1
PUSH  :lästige Zwischensumme entfernen  Stack:  e4 e3
 +    :e4 und e3 addieren                Stack:  e4+e3
POP   :e2+e1 wieder-holen                Stack:  e4+e3 e2+s1
 *    :Summen multiplizieren             Stack:  (e4+e3)*(e2+e1)


SQGL e3,e2,e1 --> a2,a1  (Quadratische Gleichung)
-------------------------------------------------
Berechnet die Lösungen X1,X2 der Gleichung e3*X^2+e2*X+e1=0
Für diesen Spezialfall ist SQGL schneller zu handhaben, als die
QUAD-Funktion im SOLVE-Menü.

<< 3 PICK / SWAP ROT 2 * / NEG DUP SQ ROT - sqrt + LAST - >>

Beispiel: Lösungen der Gleichung xý+3x+2=0:
Eingabe: 1 3 2 SQGL       Ausgabe: -1 -2     ==> X1=-1, X2=-2


SORT  e2,e1 --> a2,a1
---------------------
Sortiert die Elemente e2,e1 der Größe nach. SORT leaßt sich
auf alle mit > vergleichbaren Objekte anwenden.

<< DUP2 IF > THEN SWAP END >>

Beispiel: "HOHL" "HALLE" SORT --> "HALLO" "HOHL" (Alpha-Ordnung)


BRC  e1 --> a2,a1  (Bruch)  (ben. KB)
--------------------------
Funktion ^BRC (Stand-alone-Version)

<< KB DROP SWAP DROP ROT DROP >>


BRC  e1 --> a2,a1  (Bruch)  (ben. eps)
--------------------------
Wandelt die reelle Zahl e1 in einen Bruch um, wobei a2=Zähler
und a1=Nenner. Zusätzlich wird e1 --> a.

<< 'a' STO 1 a IP 0 1 a eps XPON NEG SCI
  WHILE OVER a * RND FP REPEAT
    FP INV DUP IP DUP
    6 PICK * 7 ROLL + 5 ROLLD
    3 PICK * 4 ROLL + SWAP
  END
  DROP SWAP DROP ROT DROP STD >>

Beispiel:  .588235294118 BRC --> 10 17    d.h. 10/17


2.2 Nützliche Sub-Routinen
---------------------------

KB  e1 --> a5,a4,a3,a2,a1  (Kettenbruch)  (ben. eps) (n.n.opt)
----------------------------------------
a5,a4,a3,a2 sind ganze Zahl mit folgender Beziehung:
e1 = (a4+r*a5)/(a2+r*a3), wobei a4/a2 eine Näherung von e1 auf
8 Stellen ist, a5/a3 die nächst schlechtere Näherung und
0<=r<1. a1 ist die Liste der Köffizienten der Kettenbruchent-
wickung von e1. Zusätzlich wird e1 --> a. Abbruch erfolgt bei
Erreichen der Genauigkeit eps=1E-8 .

<< 'a' STO 1 a IP 0 1 3 PICK 1 ->LIST a eps XOPN NEG SCI
  WHILE 3 PICK a * RND FP REPEAT
    FP INV DUP IP ROT OVER + ROT ROT DUP
    7 PICK * 8 ROLL + 6 ROLLD
    4 PICK * 5 ROLL + 3 ROLLD
  END
  DROP STD >>

Beispiel: .714285714286 --> 2 5 3 7 {0 1 2 2}
     d.h. .714285714286 = 5/7 = 0+1/(1+1/(2+1/2))


REV  e1 --> a1  (Reverse)
-------------------------
Spiegelt den String oder die Liste e1 nach a1.

<< DUP 1 0 SUB OVER SIZE 1
  FOR i OVER i DUP SUB + -1 STEP SWAP DROP >>

Beispiel: "Hallo"  REV  -->  "ollaH"
Beispiel: {1 3 7}  REV  -->  {7 3 1}


DISV  e1  (Display Vector)    (ben. V->M)
--------------------------
Zeigt Vektor e1 mit n.ter Komponente in Zeile n an.

<< V->M 1 DISP >>
                                 [[ 1 ]
Beispiel: [1 2 3]  DISV zeigt     [ 2 ]    an.
                                  [ 3 ]]

VCON  e1 --> a1  (Vector-Construct)
-----------------------------------
Erzeugt Nullvektor der Länge e1 nach a1.

<< 1 ->LIST 0 CON >>

Beispiel: 5  VCON  -->  [0 0 0 0 0]


VKIT  e2,e1 --> a1  (Vector-Kit)
--------------------------------
Hängt Vektor e1 hinten an Vektor e2 nach a1 an.

<< SWAP ARRY-> 1 GET DUP 2 + ROLL ARRY->
  1 GET DUP 2 + ROLL + ->ARRY >>

Beispiel: [2 3 5] [7 11]  VKIT  -->  [2 3 5 7 11]


VSIZ  e1 --> a1  (Vector-Size)
------------------------------
Länge des Vektors e1 als Zahl nach a1

<< SIZE LIST-> DROP >>

Beispiel: [1 2 3]  VSIZ  -->  3


V->M  e1 --> a1  (Vektor --> Matrix)
------------------------------------
Wandelt den (Zeilen)-Vektor in eine einspaltige Matrix.

<< SIZE LAST SWAP 1 + RDM >>
                                        [[12]
Beispiel: [ 12 34 56]    V->M    -->     [34]
                                         [56]]

RNDV  e1 --> a1    (Random-Vector)
----------------------------------
Liefert einen Zufallsvektor der Länge e1, dessen Komponenten
zwischen 0 und 1 liegen.

<< 1 OVER START RAND SWAP NEXT ->ARRY >>

Beispiel: 3 RNDV --> z.B. [.337 .905 .877]


Pabc    (Purge a,b,c)
---------------------
Löscht die Hilfsvariablen a, b und c

<< { a b c } PURGE >>


2.3 Sonstiges
-------------

CHKS  e1 --> a1  (Check-Sum)
----------------------------
Berechnet eine Prüfsumme der Variablen mit Namen e1 nach a1.

<< RCLF HEX 16 STWS SWAP RCL ->STR DUP # 0h 1 ROT SIZE
  FOR j OVER j j SUB NUM R->B XOR RL NEXT
  ->STR 3 OVER SIZE 1 - SUB ROT STOF SWAP DROP >>

Beispiel: Prüfsumme des Programms CHKS
          'CHKS'  CHKS  -->  "129"


L->ME  e1 --> a1,a2  (Ln-Zahl in Mant. & Exponent)
--------------------------------------------------
Ist e1 der Logarithmus einer (häufig großen) Zahl, so wird
a1 die Mantisse und a2 der Exponent.

<< 10 LN / DUP FP ALOG SWAP IP >>

Beispiel: 999! = 4.023537E+2564 kann berechnet werden mittels
          999  LNFAC  L->ME  -->  4.023537 2564


R5  e1 --> a1  (Round 5)
------------------------
Oft ist es nötig, Zahlen, die durch Rundung ungenau
geworden sind, wieder ganz zu machen. Dazu bietet sich R5
an, das auf 5 Stellen nach dem Komma rundet. Dabei ist e1 eine
reele/komplexe Zahl oder ein Array.

<< 5 FIX RND STD >>

Beispiel: [ 1.9999997 1.234567]  R5  -->  [2 1.23457]


NULS: String, der 200 CHR$(0) enthält: Erzeugung durch:
----       "" 1 200 START 0 CHR + NEXT 'NULS' STO

eps  (epsilon)
--------------
Setzen Sie eps auf 1E-8. Einige Programme benutzen die Genauig-
keitsschranke eps, d.h. die Ergebnisse werden auf 8 Stellen
berechnet oder/und das Programm erwartet Werte auf 8 Dezimalen.
Sind die Daten also z.B. aus physikalischen Gründen ungenau,
keine große Genauigkeit erfordert oder die numerische Stabili-
tät kritisch (was das korrekte Funktionieren des Programms
beeinflussen kann), so sollte eps vergrößert werden. Wird ein
Ergebnis genaür erwünscht, so ist eps zu verkleinern, was
aber mit Vorsicht zu genießen ist.  Richtlinien:

eps: 1E-8 für normale Anforderungen
eps: 1E-6 für kritische Anwendungen
eps: 1E-10 wenn erwünscht und 1E-8 erfolgreich war



+-----------------------------------------------------------+
|                  3. U T I L - Directory                   |
+-----------------------------------------------------------+

3.1. Matrizen-Utilies
---------------------
Ist nichts weiter vermerkt, so sind unter "Matrizen" beliebige
m*n Matrizen zu verstehen. n=Spaltenzahl, m=Zeilenzahl. Im kom-
plexen ist unter orthogonal unitär und unter symmetrisch herme-
tisch zu verstehen. Die Algorithmen sind vor allem für Matrizen
mit nicht vollem Rang ausgelegt.

EVA  e1  (Eigenvektor; Alle)  (ben. EV1,RNDV,DISV,V->M)
----------------------------
Berechnet von der normalen (z.B.symmetrischen) positiv
definiten Matrix e1 sämtliche Eigenwerte in die Liste EW
und die dazugehörigen Eigenvektoren in die Liste EV.
Die EV sind auf Länge 1 normiert. Für nur symmetrische
Matrizen addiere man einfach a*IDN zu e1 dazu, a genügend
groß. Die EV bleiben erhalten, die EW sind um a verschoben.

<< { } DUP 'EV' STO 'EW' STO
   DUP SIZE 1 GET DUP RNDV ROT ROT 1 SWAP
   START OVER EV1 DUP DISV EV OVER + 'EV' STO
     DUP2 * OVER DOT DUP 4 DISP EW OVER + 'EW' STO
     SWAP V->M SWAP OVER * TRN * -
   NEXT DROP2 >>

          [[ 25 -10  6]
Beispiel:  [ 34 -10  6]   EVA liefert die Eigenwerte
           [  8  -2  3]]
EW = { 9 6 3 } zu den Eigenvektoren
EV = { [.43 .86 .29] [.57 .80 .15] [.62 .76 .20] }


EV1  e1,e2 --> e1,a1  (1 Eigenvektor)  (ben. DISV,eps)
-------------------------------------
Berechnet den größten Eigenvektor der Matrix e1 iterativ
ausgehend vom Vektor e2 nach a1 mit Norm 1.

<< DUP2
   DO ROT DROP SWAP SQ DUP CNRM / DUP 3 PICK * DUP CNRM / DUP
DISV 4 PICK SWAP *
   UNTIL 3 PICK OVER - CNRM eps < END
   DROP2 DUP ABS / >>

Beispiel:
[[ 25 -10  6]   [1             [[ 25 -10  6]    [.429
 [ 34 -10  6]    1   EV1  -->   [ 34 -10  6]     .857
 [  8  -2  3]]   1]             [  8  -2  3]]    .286]


PSINV  e1 --> a1  (Pseudo-Inverse)  (ben. M->O)
----------------------------------
Berechnet die Pseudoinverse von e1 nach a1.

<< DUP M->O SWAP OVER TRN SWAP * DUP DUP TRN * / * TRN >>

Beispiel: [[ 1 -2  3 -4]              [[-3 -7  5]
           [-4  3 -2  1]    PSINV -->  [ 3  7 15] / 40
           [ 1  1  1  1]]              [ 7  3 15]
                                       [-7 -3  5]]

ORTHO  e1 --> a1  (Orthogonalraum)  (ben. M->O)
----------------------------------
Ist e1 eine m*n Matrix mit 0 < Rang(e1) < n , so spannen die
Spaltenvektoren von e1 einen Unterraum auf. Die Spaltenvektoren
von a1 werden so berechnet, daß sie den zu e1 senkrechten Raum
aufspannen und ausserdem selbst orthonormal sind.

<< M->O DUP TRN * DUP IDN - M->O >>

Beispiel: [[ 1  4  1]              [[-.408 -.365]
           [ 2  3  1]   ORHTO -->   [ .816  .183]
           [ 3  2  1]               [-.408  .730]
           [ 4  1  1]]              [   0  -.574]]

Beispiel: Lösung eines homogenen LGS Ax=0 und eines inhomogenen
          LGS Ax=b mittels (-b|A)(1|x)'=0 (oder konventionell).


RANG  e1 --> a1  (Rang)  (ben. M->OR)
-----------------------
Berechnet den Rang der Matrix e1, d.h. die Zahl der lin.
unabhängigen Spalten oder Zeilen.

<< M->O SIZE 2 GET >>

Beispiel: [[ 1 2 3 4]
           [ 4 3 2 1]   RANG -->   2
           [ 1 1 1 1]]


M->O  e1 --> a2,a1  (Matrix -> Orhtogonal)  (ben. V->M,eps)
------------------------------------------
Wenn e1 eine n*m Matrix mit Rang k ist, so wird diese in eine
orthogonale n*k Matrix a2 und eine linke untere k*m Dreiecks-
matrix zerlegt, so dass e1=a2*a1. Dabei werden Vektoren als lin.
abhängig angesehen, wenn deren relative Abweichung < eps=1E-8
ist. Sind die Daten also z.B. aus physikalischen Gründen unge-
nau so sollte eps auf ca. 10-100 * Datengenauigkeit erhöht
werden. Soll a1 eine rechte obere Dreiecks-Matrix sein, so
benutze man statt M->O die Befehlsseqünz MREV M->O MREV.

<< DUP CNRM / DUP SIZE LIST-> DROP OVER IDN
  OVER 1 ->LIST 0 CON { }  -> a n m s u q
  << 1 m FOR i s a u i 1 PUT * * DUP ABS
    IF DUP eps > THEN / s OVER V->M DUP TRN * -
      's' STO q SWAP + 'q' STO ELSE DROP2 END
    NEXT 1 q SIZE DUP 'm' STO
    FOR i 'q' i GET ARRY-> DROP NEXT
    m n 2 ->LIST ->ARRY TRN CONJ >> >>

Beispiel:
[[ 1 2 3]             [[-.762 -.429]
 [ 4 5 6]   M->O  -->  [ .173 -.857]
 [ 2 2 2]]             [ .624 -.286]]


M->P  e1 --> a1  (Matrix zu char. Polynom)  (ben. VKIT,RNDV)
------------------------------------------
Berechnet zur quad. Matrix M mit nur einf. Eigenwerten das
charakteristische Polynom P(M,x)=det(x*I-M) als Köffizienten-
vektor (^PMUL) nach a1.

<< -> a
  << a SIZE 1 GET DUP RNDV 1 ROT
    START ARRY-> LAST SWAP DROP a SWAP * NEXT
    NEG a SIZE SWAP 'a' STO ->ARRY TRN a SWAP /
    [1] VKIT >>

Beispiel: P([[1 2] ,x) = det([[x-1 2]) = xý-5x-2
             [3 4]]           [3 x-4]

Eingabe:  [[1 2]  M->P  -->  [-2 -5 1]
           [3 4]


LKORR  e1 --> a1  (Lineare Korrektur)
-------------------------------------
Die Lösung linearer Gleichnugssysteme Ax=b (A=quadrat. nicht-
singuläre Matrix, x,b=Vekoren oder Matrizen)
führt bei Anwednung von  b A / häufig zu Rundungsfeh-
lern, die mithilfe von LKORR korrigiert werden können. LKORR
muss direkt nach b A / aufgerufen werden, damit LAST richtig b
und A liefert, welche LKORR für den Korrekturprozess benötigt.

<< LAST SWAP OVER 4 PICK RSD SWAP / + >>

Beispiel: [1,1] [[1,2]  / --> [-.9999999992 .9999999996]
                 [3,4]]
    Dann: LKORR --> [-1 1], dem exakten Ergebnis


MREV  e1 --> a1  (Matrix-Reverse)  (ben. REV)
---------------------------------
e1 wird rechts-links nach a1 gespiegelt, ist e1 eine Matrix,
dann außerdem noch oben-unten.

<< ARRY-> LIST->
  IF 1 == THEN ->LIST REV LIST-> ->ARRY
  ELSE * LAST 2 ->LIST 'a' STO
  ->LIST REV LIST-> DROP a ->ARRY Pabc >>

Beispiel: [ 5 6 5 1 3 0 9]  MREV  -->   [ 9 0 3 1 5 6 5]

Beispiel: [[1 2 3 4]        MREV  -->  [[ 8 7 6 5]
           [5 6 7 8]]                   [ 4 3 2 1]]


DIFF  e3,e2,e1 --> a1  (Differenzieren,Jakobimatrix)
----------------------------------------------------
DIFF berechnet die Jakobimatrix mal e2 einer Funktion e1.
F(e3+e2) ÷ F(e3) + F'(e3)*e2  für kleine e2.
e1 wird ein Vektor übergeben und liefert einen Vektor ab.

<< 0 -> v dv f fv
  << v dv + f EVAL 'fv' STO 1 v SIZE 1 GET
    FOR i fv dv i 0 PUT v + f EVAL
      - dv i GET / ARRY-> DROP NEXT
    v SIZE fv SIZE + ->ARRY TRN CONJ >>

Beispiel: F(x,y)=[sin(x)*cos(y) (x+1)*(y+2)]   F'(0,0)=[[1 0]
F: << ARRY-> DROP -> x y                                 [2 1]]
     << x SIN y COS * x 1 + y 2 + * {2} ->ARRY >> >>

Eingabe: [0 0] [1E-5 1E-5] 'F'  DIFF  -->  [[1 0]
                                            [2 1]]

3.2 Vektor-Utilities
--------------------

Y->NY  e1 --> a1  (Y-Coord to Numbered Y-Coord.)
------------------------------------------------
Jede Komponente Yn des Vektors e1 wird in a1 durch [Yn n]
ersetzt.

<< ARRY-> 1 GET 1 SWAP
  FOR i i NEXT
  2 OVER 2 ->LIST ->ARRY TRN >>

Beispiel: Eine Reihe zeitlich äquidistanter Messwerte
  [2 5 7 3 4 ] soll mit den Zeitindices 1 bis 5 versehen
  und graphisch angezeigt werden. [[2 1]
                                   [5 2]
Eingabe: [2 5 7 3 4 ]  Y->NY  -->  [7 3]
                                   [3 4]
                                   [4 5]]
Im PLOT-Menü: STOsigma 2 1 COLsigma SCLsigma DRWsigma


FFT  e1 --> a1  (Fast-Fourier-Transformation)  (ben. FT2)
---------------------------------------------
e1 ist ein Vektor äquidistanter Stützwerte einer 2pi-period.
Funktion. a1 wird der komplexe Vektor der Fourierköffizienten.
Bem: Die Länge der Vektoren sollte eine hohe 2er-Potenz sein,
damit FFT,FFTI und FT2 schnell arbeiten können.

<< -1 'FTF' STO 0 FT2 DUP SIZE 1 GET / >>

Beispiel: Trig. Interpol. der Pkte. x : 0 pi/2 pi 3pi/2
                              f(x+2kpi): 2  4  6  8
  [2 4 6 8]  FFT  -->  [5 -1+i -1 -1-i]
  d.h. f(x)= 5 + (-1+i)*e^xi - e^2xi + (-1-i)*e^3xi
  bzw. f(x)= 5 - 2*cos(x) - 2*sin(x) - cos(2x)
  interpoliert obige Stützwerte.

FFTI  e1 --> a1  (FFT-Inverse)  (ben. FT2)
------------------------------
e1 ist ein komplexer Vektor von Fourierköffizienten.
a1 wird ein Vektor gleicher Länge von äquidistanten Stütz-
werten dieser 2pi-period. Funktion.

<< 1 'FTF' STO 0 FT2 >>

Beispiel: f(x)= 5 - 2*cos(x) - 2*sin(x) - cos(2x)
     bzw. f(x)= 5 + (-1+i)*e^xi - e^2xi + (-1-i)*e^3xi
  [5 -1+i -1 -1-i]  FFTI -->  [2 4 6 8]
  d.h.          x : 0 pi/2 pi 3pi/2
          f(x+2kpi): 2  4  6  8


FT2  e2,e1 --> a1  (FFT-Subroutine)  (ben. FT1 FTF VKIT)
-----------------------------------
Wenn FTF=-1 (1) wird mit e2 FFT (FFTI) wie oben ausgeführt.
e1 ist ein (bei Aufruf norm. auf 0 zu setzender) Rekursions-
parameter, der die Komponenten des Ergebnisvektors abschließend
noch um den Winkel e1 dreht. Das Ergebnis istbei der Vorwärts-
transformation noch nicht durch die Länge des Vektors geteilt.

<< 2 / SWAP DUP SIZE 1 GET 2 /
  IF DUP DUP 2 > SWAP FP NOT AND
  THEN {2} + RDM [1 0] * LAST DROP [0 1] * 3 PICK
    .5 + FT2 SWAP 3 PICK FT2 SWAP + LAST - ROT FTF
    ATAN 8 * * 1 SWAP R->C P->R * VKIT
  ELSE DROP SWAP FT1 END >>


FT1  e2,e1 --> a1  (FFT-Subroutine)  (ben. HORN FTF VKIT)
-----------------------------------
exakt wie FT2, nur statt FFT wird die normale Fourier-
Transformation verwendet. Sollte (wenn überhaupt) nur für
Vektoren ungerader Länge benutzt werden.

<< SWAP DUP SIZE LIST-> DROP FTF
  ATAN 8 * OVER / -> g v n w
  << 0 n 1 -
    FOR i v 1 w i * R->C P->R HORN
      1 w i * g * 2 * R->C P->R * NEXT
    n ->ARRY >> >>

FTF: FFT-Flag: -1=Vorwärtstransf.,  d.h. Werte --> Köff.
                1=Rückwärtstransf., d.h. Köff. --> Werte
     Wird von FFT und FFTI passend besetzt.


3.3 Polynom-Utilities
---------------------
Polynome werden durch Vektoren der Köffizienten dargestellt,
wobei die i+1. Komponente dem i. Köffizienten entspricht.
[a0 a1 .. an] = a0 + a1*x + .. + an*x^n

PMUL  e2,e1 --> a1    (Polynom-Multiply)  (ben. VSIZ)
----------------------------------------  (n.n.opt)
Sind e2 und e1 Polynome, so ist a1 das Produkt beider (e1,e2,a1
in obiger Vektornotation).
Bem: Wesentlich effizienter PMUL mit FFT !

<< -> p q
  << p VSIZ q VSIZ + 1 - VCON 1 p VSIZ
    FOR i 1 q VSIZ
      FOR k p i GET q k GET * i k + 1 -
        3 PICK OVER GET ROT + PUT
    NEXT NEXT >> >>

Beispiel: (x^2+2*x-3) * (2*x^2+3) = (2*x^4+4*x^3-3*x^2+6*x-9)
           [-3 2 1] [3 0 2]  PMUL  --> [-9 6 -3 4 2]


HORN  e2,e1 --> a1    (Hornerschema)
------------------------------------
Wertet Polynom e2 geg. als Köffizientenvektor an der
Stelle e1 nach a1 aus.

<< SWAP ARRY-> LIST-> DROP DUP 2 + ROLL ROT ROT 2 SWAP
  START OVER * ROT + NEXT SWAP DROP >>


3.4 Real-Zahlen-Utilities
-------------------------

EXPA  e1 --> a1  (exp array)
----------------------------
Berechnet exp(e1), wobei e1 eine quadratische Matrix ist.

<< DUP ABS LN 2 LN / IP 4 + SWAP OVER .5 SWAP ^ *
  DUP 'a' STO DUP IDN 'b' STO 1 8
  FOR I I / DUP 'b' STO+ a * NEXT
  DROP b 1 ROT
  START SQ NEXT
  Pabc >>

Besipiel:  [[1 0]   EXPA  -->  [[ e  0]
            [0 2]]              [ 0 e^2]]


UTPP e1,e2 --> a1 (Poisson-Verteilung)
--------------------------------------
                        k  -my i
e1=my, e2=k, a1=P(X<=k) = sigma e  my /i!
                       i=0

<< 1 SWAP 1 FOR k OVER k / * 1 + -1 STEP SWAP EXP / >>


NEQsigma  e1,e2 --> a1  (Non-Equal-Statistic)
-----------------------------------------
Aus einer Urne mit e1 unterscheidbaren Kugeln werden e2 Kugeln
zufällig mit zurücklegen gezogen. a1 ist die Wahrscheinlich-
keit, dass man keine Kugel doppelt zieht.  Oder:
Auf e1 Plätze werden e2 Kugeln zufällig verteilt. a1 ist die
Wahrscheinlichkeit, dass kein Platz doppelt besetzt ist.

<< PERM LAST ^ / >>

Beispiel: Die Wahrscheinlichkeit, dass von 22 Leuten keine am
gleichen Tag Geburtstag haben ist: 365 22 NEQsigma --> 52%


LNFAC  e1 --> a1  (ln(e1!))
--------------------------
In der Kombinatorik braucht man oft die Kapazität des
Taschenrechners überschreitende Fakultäten, obwohl das
Endergebnis im Maschinenbereich liegt. LNFAC liefert den
Logarithmus der Fakultät von e1 nach a1.

<< IF DUP 254 < THEN FACT LN
   ELSE DUP LN 1 - SWAP .5 + * 2 pi * LN 1 + 2 / + END >>

Beispiel: Berechnung von 300!/(100!)^3 = exp(ln300!-3*ln100!)
300 LNFAC 3 100 LNFAC * - EXP --> 3.76E140


3.5. Ganz-Zahlen-Utilities
--------------------------

FIB   e1 --> a1  (Fibonacci)
----------------------------
Liefert die e1. Fibonacci-Zahl f(e1). Definitionsgemäß ist
f(0)=0, f(1)=1, f(n)=f(n-1)+f(n-2), für die es auch eine
direkte Formel gibt:

<< 1.61803398875 SWAP ^  5 sqrt / .5 + IP >>

Beispiel: 10 FIB --> 55       20 FIB --> 6765


PRFZ  e1 --> a1  (Primfaktorenzerlegung)
----------------------------------------
Zerlegt die Zahl e1 in die Liste von Primfaktoren --> a1

<< CLLCD { } SWAP DUP sqrt SWAP 2
  DO DUP2
    IF MOD THEN 1 +
    ELSE DUP 4 ROLLD / SWAP DROP DUP sqrt SWAP ROT
         4 ROLL OVER + DUP 1 DISP 4 ROLLD
    END
  UNTIL DUP 4 PICK > END
  ROT DROP2 + CLMF >>

Beispiel: 12345 PRFZ --> { 3 5 823 }


KURZ  e2,e1 --> a2,a1  (Kürzen) (ben. GGT)
-------------------------------
Kürzt den Bruch e2/e1 --> a2/a1

<< DUP2 GGT DUP ROT ROT / ROT ROT / SWAP >>

Beispiel: 123 456 KURZ --> 41 152


KGV  e2,e1 --> a1  (kleinstes gem. Vielfaches) (ben. GGT)
----------------------------------------------
Berechnet das kleinste gem. Vielfache von e2 und e1 --> a1

<< DUP2 GGT / * >>

Beispiel: 10 15 KGV --> 30


GGT  e2,e1 --> a1  (größter gemeinsamer Teiler)
-----------------------------------------------
Berechnet den größten gem. Teiler von e2 und e1 --> a1

<< WHILE SWAP OVER MOD DUP REPEAT END DROP >>

Beispiel: 10 15 GGT --> 5


->KB  e1 --> a1  (->Kettenbruch) (ben. KB)
--------------------------------
Wandelt e1 in Kettenbruch, Köffizientenliste --> a1.
Genaüres ^KB.

<< KB 5 ROLLD 4 DROPN >>

Beispiel: 0.7  ->KB  -->  {0,1,1,2,3}


KB->  e1 --> a1  (Kettenbruch->)
--------------------------------
Wandelt Kettenbruch (e1=Köffizientenliste) in reelle Zahl a1

<< LIST-> 2 SWAP START INV + NEXT >>

Beispiel: {0 1 2 3}  KB->  -->  0.7


->G  e2,e1 --> a1  (Gödelisierung)
----------------------------------
Verknüft 2 nat0 Zahlen e1 und e2 zu einer nat0 Zahl, derart
dass (mittels G->) e1 und e2 wieder rekonstruiert werden können.
(nat0 = natürlich incl. Null)
Bijektive Gödelisierungs-Vorschrift: g(x,y) = ((x+y)ý+x+3y)/2

<< + LAST 3 * + SWAP SQ + 2 / >>

Beispiel: 123 456  ->G  -->  168366  G->  -->  123 456


G->  e1 --> a1,a2  (Ent-Gödelisierung)
--------------------------------------
Entgödelisiert e1 (^->G) nach a1 und a2.

<< DUP 8 * 1 + sqrt 1 - 2 / IP SWAP OVER
  DUP 1 + * 2 / - - LAST SWAP DROP >>


XCOM  e3,e2,e1 --> a1  (Erweiteter Binomialköff.)  (n.n.opt)
--------------------------------------------------
Sei z(n) die Anzahl der Möglichkeiten die Zahl n als Summe
von e2 Zahlen zwischen 0 und e1-1 darzustellen.
Ergebnis: [ 0*0 .. 0*(e1-1) z(0) .. z(e3) ] --> a1

Beispiel: 3 2 3  XCOM  -->  [0 0 0 1 2 3 2]
Die ersten 3 Nuller des Vektors sind Bedeutungslos
4. Komponente = z(0) = 1, da 0=0+0
5. Komponente = z(1) = 2, da 1=0+1 oder 1=1+0
6. Komponente = z(2) = 3, da 2=0+2 oder 2=2+0 oder 2=1+1
7. Komponente = z(3) = 2, da 3=1+2 oder 3=2+1


3.6 Element-Utilities
---------------------

RIDO  e2,e1 --> a1  (Real-Imaginär-DO)
----------------------------------------
Führe Funktion e1 mit Real- und Imaginärteil von e2 aus, wenn
e2 komplex, sonst einfach mit e2.

<< SWAP IF DUP TYPE 1 ==
  THEN C->R 3 PICK EVAL SWAP ROT EVAL SWAP R->C
  ELSE SWAP EVAL END >>

Beispiel: (3,4) << SQ >>  RIDO  -->  (9,16)

ELDO  e2,e1 --> a1  (Element-DO)  (ben. abDO,Pabc)
--------------------------------
Führt mit jedem Element von e2, wenn e2 Liste oder Array,
ansonsten mit ganz e2, das Programm e1 aus.
Genaüres ^abDO

<< DUP 'a' STO 'b' STO abDO Pabc >>

Beispiel: [ 1 2 3 4]  << SQ >>      ELDO  -->  [ 1 4 9 16]
Beispiel:  {X X X X} << DROP DUP >> ELDO  -->   {1 2 3 4}


ATDO  e2,e1 --> a1  (Atom-DO)  (ben. abDO,Pabc)
-----------------------------
Funktion wie ELDO, nur: Ist Element e von e2 wieder eine Liste
oder ein Array, dann rufe rekursiv e,e1 ATDO auf.

<< 'b' STO << abDO >> 'a' STO abDO Pabc >>

Beispiel: {[[4 9]],{1,16},-1} << sqrt >>  ATDO  -->
          {[[2 3]],{1,4},(0.1)}


abDO  e1 --> a1  (UP von ELDO,ATDO)
---------------
Ist e1 eine Liste oder ein Array, so wird mit jedem Element von
e1 die Operation a ausgeführt (Element wird im Stack über-
geben) und des Ergebnis an die entsprechende Stelle in a1 ge-
schrieben; Ist e1 weder Liste, noch Array, so wird ganz e1 an b
übergeben, d.h. e1 b ausgeführt.

<< IF DUP TYPE 3 / IP 1 ==         | Stackinhalt beim
  THEN DUP SIZE DUP ROT ROT       | ausführen von a:
    DO DUP2 GET a PUTI            | 4: s= Länge der Liste
    UNTIL DUP 4 PICK == END       | 3: l= Liste
    DROP SWAP DROP                | 2: i= Elementnummer
  ELSE b END >>                    | 1: i.tes Element der Liste
                                  | Analog für Arrays

Anmerkung zu abDO,ELDO,ATDO,RIDO:
Es wird stets vorausgesetzt, dass die Funktion nur ein Element
vom Stack nimmt und 1 Element auf den Stack zurückgibt.


IPFP  e1 --> a1 a2    (Integer-Part Fractional-Part)
----------------------------------------------------
a1 wird Integerpart von e1, a2 wird Fractionalpart von e1.

<< IP LAST FP >>

Beispiel: 12.34  IPFP  -->  12  .34


3.7 Sonstige Utilities
----------------------

ZMUS    (Zufallsmusik)
----------------------
Erzeugt Zufallsmusik bis Tastendruck.

<< DO RAND 1000 * .1 BEEP UNTIL KEY END DROP >>



+-----------------------------------------------------------+
|                 4. G R A P H - Directory                  |
+-----------------------------------------------------------+

IDR  e4,e3,e2,e1  (Implizit Draw)  (n.n.opt)
---------------------------------
Bem: Statt IDR kann auch das verallg. VDR verwendet werden.
IDR zeichnet die implizite Funktion F(X,Y)=0. X Y werden F auf
dem Stack übergeben, F liefert eine reelle Zahl als Funktions-
wert. e4 e3 sind die Startkoordinaten X Y, die auf dem Graphen
von F liegen sollten, d.h. F(e4,e3)=0, e2 e1 die Startrichtungen
und müssen +1 für rechts/oben bzw -1 für links/unten sein.
Bei Tastendruck bricht IDR nach einiger Zeit ab.

<< PPGET PY * 'DY' STO PX * 'DX STO
  'Y' STO 'X' STO CLLCD DRAX
  DO
    DO DX 'X' STO+ X Y F X Y DY + F OVER - /
      NEG 'DY' STO* DY 'Y' STO+ X Y R->C PIXEL
    UNTIL DY ABS PY > END
    PY DY ABS / DUP 'DX' STO* 'DY' STO*
    DO DY 'Y' STO+ X Y F X DX + Y F OVER - /
      NEG 'DX' STO* DX 'X' STO+ X Y R->C PIXEL
    UNTIL DX ABS PX > END
    PX DX ABS / DUP 'DY' STO* 'DX' STO*
  UNTIL KEY END
  DROP DGTIZ >>

Beispiel: IDR erlaubt die Lemniskate zu zeichnen. Diese ist
implizit gegeben durch F(x,y)=(x^2+y^2)^2+2*(x-y)=0 . Eingabe

(-1.5 -.5) PMIN (1.5 .5) PMAX
<< SQ SWAP SQ DUP2 + SQ ROT ROT - 2 * + >> 'F' STO
 0 0 1 1 IDR  -->  Bild der Lemniskate

Brechen Sie das Programm ab, wenn sich die Lemniskate
geschlossen hat.


PDR  e2,e1  (Parametrisiert-Draw)  (n.n.opt)
---------------------------------
Bem: Statt PDR kann auch das verallg. VDR benutzt werden.
Zeichnet die Parametrisierte Funktion F. Parameter T wird der
Funktion F auf dem Stack übergeben im Bereich von e2 bis e1;
F liefert X Y Koordinate auf den Stack.

<< CLLCD PPGET SWAP DUP2 - .00001 * 'DT' STO DUP F
  DO ROT DT + DUP F OVER
    6 ROLL - ABS PX / OVER
    6 ROLL - ABS PY / MAX 'DT' SWAP STO/ DUP2 R->C PIXEL
  UNTIL 4 PICK 4 PICK - DT * 0 < END 4 DROPN
  DGTIZ >>

Beispiel: Die Liseiouschen Figuren sind in natürlicher Weise
als parametrisierte Kurve x=sin(n*t), y=cos(k*t) gegeben, also

F: << DUP n * SIN SWAP k * COS >>

Ein schönes Bild ergibt sich für n=3, k=7.
Eingabe: (-1,-1) PMIN  (1,1) PMAX  DEG  0 360 PDR


FILL   (ben. PPGET,F)
----
Jedem Pixel der Anzeige ist ein Koordinatenpaar zugeordnet
(abhängig von PPAR). Nacheinander werden die Koordinatenpaare X
Y für jeden Anzeigenpunkt der Funktion F auf dem Stack über-
geben und der Punkt gesetzt, falls des Ergebnis von F0. Die
Punkte werden so nacheinander gewählt, dass ausgehend von einem
grob-gerasterten Bild ein immer feineres mit schliesslich voller
Auflösung entsteht. Abbruch ist durch eine beliebige Taste
innerhalb einiger Sekunden möglich.

<< CLLCD PPGET 0 0
  DO DUP2 PY * BY + SWAP PX * LX + RX
    FOR X IF X OVER F THEN X OVER R->C PIXEL END PX 13 * STEP
    DROP SWAP 1 + 13 MOD SWAP 7 + 32 MOD
  UNTIL IF KEY THEN DROP 1 ELSE DUP2 OR NOT END END
  DROP2 DGTIZ >>

Beispiel: Höhenline der Lemniskate zeichnen

F: << SQ SWAP SQ DUP2 + SQ ROT ROT - 2 * +
     1 + sqrt 4 * IP 2 MOD >>

Koordinatenbereich einstellen: (-2,-.7) PMIN (2,.7) PMAX
FILL aufrufen und ca. 10 Minuten warten.


FILL2   (ben. PPGET,F)
-----
Bem: Statt FILL2 kann auch das verbesserte FILL benutzt werden.
Funktionalität wie FILL, nur dass die Pixels nacheinander von
unten nach oben und so von rechts nach links durchlaufen werden.

<< CLLCD PPGET RX LX
  FOR X BY TY
    FOR Y IF X Y F THEN X Y R->C PIXEL END PY
    STEP PX NEG
  STEP DGTIZ >>

Beispiel: Das mit FILL2 dargestellte Phasendiagramm des schwingen-
den Pandels als Höhenlinien der Energiefunktion, liefert nach
ca. 10 Minuten ein schönes Bild. Eingabe:

<< SQ SWAP COS - 1 + sqrt 8 * IP 2 MOD >> 'F' STO FILL2


PPGET    (Plot-Parameter-Get)
-----------------------------
Setzt NX NY auf die Anzahl der X Y Pixel, PX PY auf Pixelbreite
-höhe, LX RX auf den linken- rechten Rand und BY TY auf den
unteren- oberen Rand. Die Daten dafür stammen aus PPAR.

<< PPAR 2 GET DUP C->R 'TY' STO 'RX' STO
  PPAR 1 GET DUP C->R 'BY' STO 'LX' STO
  - PPAR 4 GET 32 OVER / 'NY' STO 137 OVER / 'NX' STO
  * C->R 31.2 / 'PY' STO 136.2 / 'PX' STO >>


CLPIX e1   (Clear Pixel)
------------------------
Wie PIXEL, nur wird der durch e1 angegebene Pixel gelöscht

<< LCD-> SWAP CLLCD PIXEL LCD-> NOT AND ->LCD >>



+-----------------------------------------------------------+
|                   5. P H Y - Directory                    |
+-----------------------------------------------------------+

Häufig benutzte physikalische Konstanten in SI-Einheit, wobei
die Einheiten nicht mit in den Variablen gespeichert sind,
sondern nur der Zahlenwert.

c   = 299792000    m/s       = Lichtgeschwindigkeit
el  = 1.6022E-19   C         = Elementarladung
me  = 9.1095E-31   kg        = Elekronenmasse
mp  = 1.67265E-27  kg        = Protonenmasse
h   = 6.6262E-34   Js        = Planksche Konstante
L   = 6.022E26     /kmol     = Loschmidt-Konstante
eps = 8.8542E-12   C/Vm      = Elektrische Feldkonstante
my   = 4piE-7       Vs/Am     = Magnetische Feldkonstante
G   = 6.672E-11    m^3/kgs^2 = Gravitationskonstante



+-----------------------------------------------------------+
|                   6. C A R - Directory                    |
+-----------------------------------------------------------+

Benötigt REV und NULS aus HOME-Directory.

6.1 Autorennen
--------------

CDEM    (Car-Demo)
------------------
Autorennen-Demo  (Da Autorennen noch nicht fertig)

<< 0 'K1' STO 0 'K2' STO 5 'K3' STO 200 'X' STO
  DO K2 K3 +
  IF DUP 9 > THEN 2 - END
  IF DUP 1 < THEN 2 + END
  1 MAX 9 MIN 'K3' STO K1 'K2' STO
  RAND .5 - K1 + -1 MAX 1 MIN 'K1' STO CAR2 ->LCD
  UNTIL KEY END DROP CLMF >>


CAR2  --> a1
------------
Berechnet aus Strassendaten X,K1,K2,K3 das dazugehöige Bild in
den String a1.

<< X CVS K3 GET - LAST 0 MIN -
  NULS 'CL3' K3 GET + NULS + SWAP DUP 136 + SUB
  K3 K2 + 1 MAX 9 MIN ROT CVS 3 PICK GET - LAST 0 MIN -
  NULS 'CL2' 5 PICK GET + NULS + SWAP DUP 136 + SUB
  4 ROLL + ROT K1 + 1 MAX 9 MIN ROT CVS 3 PICK GET 0 MIN -
  NULS 'CL1' 4 ROLL GET + NULS + SWAP DUP 136 + SUB
  SWAP + >>


6.2 Straßen-Erzeugung
----------------------

CCS   (Car-Construct-Street)
----------------------------
Erzeugt alle Daten, die während der Laufzeit von CAR benötigt
werden und anschließend mit CLV PURGE gelöscht werden können.
Nicht CLV wird gelöscht, sondern die Variablen in der Liste
CLV !

<< 1 3
  FOR z { } 1 9
    FOR k CVS k GET z OVER CCL SWAP NEG 0 MAX CVS 10 k - GET
      z OVER CCL REV SWAP NEG 0 MAX ROT + CSB z * + SWAP
      DUP2 SIZE SWAP NULS 3 ROLLD SUB SWAP + ROT NULS OVER
      SIZE 5 ROLL SUB + OR DUP ->LCD +
    NEXT CLV z GET STO
  NEXT >>


CCL  e1,e2 --> a1  (Car-Construct-Line)
---------------------------------------
Erzeugt Straßenlinienstück für CCS. e1 gibt die Zeile, e2 die
Schräge des Linienstücks an. Linie (String) --> a1.

<< 8 OVER / DUP CCT SWAP ABS INV 4 ROLL CLB * MAX
  LAST CLB - MAX OVER - 4 ROLL +
  8 SWAP / DUP CCT ROT ROT DROP NULS 1 ROT SUB SWAP + NOT
  SWAP NULS OVER SIZE 1 + 4 PICK SIZE SUB NOT + AND >>


CCT  e1 --> a1   (Car-Construct-Triangle)
-----------------------------------------
Erzeugt Straßendreieck mit Schräge e1 in den String a1.

<< DUP ABS DUP .49999 + ""
  WHILE OVER 7.5 <
  REPEAT OVER 4 PICK + SWAP ROT CTR SWAP SWAP DUP SUB + END
  4 ROLLD DROP2 IF 0 < THEN REV NOT END >>


6.3 Car-Daten
-------------

CVS: [-23 5 15 20 23 26 31 41 69]
Schrägen für die einzelnen Kurvenstärken

CLV: { CL1 CL2 CL3 K1 K2 K3 X }
Liste der von CCS & CDEM erzeugten Variablen

CTR: Treppen-String: Erzeugung durch:
128 CHR 192 CHR + 224 CHR + 240 CHR + 248 CHR +
252 CHR + 254 CHR + 'CTR' STO

CLB: 5  = 1/3 der Linienbreite ganz unten
CSB: 46 = 1/3 der Straßenbreite ganz unten



+-----------------------------------------------------------+
|                  8. T E S T - Directory                   |
+-----------------------------------------------------------+

8.1 Lösungs/Iterations-Algorithmen
-----------------------------------

VDR   (Vektor-Draw)  (ben. NIS,DISV)
-------------------
Berechnet die Lösungskurve von n-1 algebraischen- oder Diffe-
renzial-gleichungen, die von n Variablen abhängen.

Gegeben sei eine Funktion F folgender Gestalt:
F(x,y,...,dx,dy,...), wobei F von n Variablen und ev. n Diffe-
renzialen abhängt und aus n-1 reelwertigen Funktionen besteht.
Diese muss in der Variable F in folgender Gestalt gespeichert
werden:
F  e1,e2 --> a1, wobei e1 der Variablenvektor [x,y,...] und e2
[dx,dy,...] der Differenzialvektor der Länge n sind. a1 ist der
Bildvektor [F1,F2,...] der Länge n-1.
VDR berechnet die Lösungskurve von F=0.

Vorgehensweise:

Eingabe der Funktion F:
  Passen Sie ihr Problem auf die HP-Syntax an und geben Sie dann
  die Funktion in F ein (Siehe Beispiel am Ende)
Startwert:
  Setzen Sie V exakt auf den Startvektor, DV ungefähr auf den
  Start-Richtungs-Vektor und DDV ungefähr auf den Start-Krüm-
  mungs-Vektor oder DV und DDV einfach auf Zufallswerte.
  (DV,DDV müssen klein sein, da dies Differenziale sind)
Iterationsgenauigkeit:
  MW gibt den Winkel in Bogenmaß an, um den zwei aufeinander-
  folgende Richtungsvektoren maximal abweichen dürfen. Zur
  korrekten Funktionsweise dieses Vrfahrens ist notwendig, dass
  x,y,... die selbe Größenordnung haben. Ein guter Wert für
  algebraische Gleichungen ist MW=0.1= 6deg , für Differenzial-
  gleichungen MW=0.05= 3deg.
Sonstiges:
  Die Lösungsvektoren werden in sigmaDAT gespeichert. Bei Start
  von VDR wird sigmaDAT nicht gelöscht. Dies müssen Sie erfor-
  derlichenfalls selber tun.
Start der Iteration:
  VDR zeigt den aktüllen Lösungspunkt als Spaltenvektor an.
  Abbruch von VDR durch eine beliebige Taste, möglichst nicht
  ON benutzen.
Anzeige des Ergebnisses:
  Die in sigmaDAT gespeicherten Lösungvektoren können wie
  statistische Daten angezeigt werden (Siehe Manual) oder sonst
  irgendwie weiterverarbeitet werden. (Siehe Beispiel)


VDR:    (Vector-Draw)  (ben. NIS,DISV)
<< DO V DISV NIS DDV + DUP DV +
     OVER ABS OVER ABS SWAP / MW * 2 MIN .5 MAX ROT
     IF OVER .5 <=
     THEN 'V' DV STO- 1000 .1 BEEP
     ELSE DUP 'V' STO+ V sigma+ END
     OVER SQ * 'DDV' STO * 'DV' STO
   UNTIL KEY END DROP >>

Einfaches Beispiel: F(X,Y)=X^2+Y^2-1=0 gibt den Einheitskreis

F: << DROP ARRY-> DROP -> X Y
     << 'X^2+Y^2-1' ->NUM >> 1 ->ARRY >>

Test, [1,0] [x,x] F --> [0] , d.h. [1,0] liegt auf dem Kreis.
V: [1,0]     DV: [0,.1]     DDV: [-.01,.1]     MW: .1
sigmaDAT und sigmaPAR löschen und VDR aufrufen.

Beobachten Sie die Koordinatenpaare, die die Werte des Einheits-
kreises durchlaufen müßten und brechen Sie VDR bei Umlauf um
den ganzen Kreis ab. Gehen Sie nun ins PLOT-Menü und zeigen Sie
die berechneten Werte mit SCLsigma DRWsigma an. Es entsteht ein
durch die Anzeige bedingter stark verzerrter Kreis.

Kompliziertes Beispiel:
Lösung der Besseldgl: x^2*y''+x*y'+(x^2-n^2)*y=0
Da nur 1. Ableitungen eingegeben werden können werden aus der
DGL 2.Ordnung 2 DGL 1. Ordnung gemacht:

x^2*ys'+x*y'+(x^2-n^2)*y=0 und ys=y' ergibt endgültig:
x^2*dys+x*dy+(x^2-n^2)*y*dx=0 und ys*dx=dy

Anmerkung: Es wurde mit dx durchmultipliziert, um ungünstige
           Divisionen zu vermeiden.

F: << ARRY-> DROP 4 ROLL ARRY-> DROP -> dx dy dys x y ys
     << 'x*x*dys+x*dy+(x*x-n*n)*y' ->NUM
        'ys*dx=dy' ->NUM >> 2 ->ARRY >>

N: 1   V: [0,0,1]   DV: [.1,.1,.1]   DDV: [.1,-.1,.1]   MW: .1
Der Rest verläuft analog zum 1. Beispiel.


NI  (Newton-Iteration) (ben. NIS,DISV)
----------------------
F ist ein Gleichungssystem, wie unter VDR beschrieben, nur etwas
flexibler mit k Gleichungen die von n Unbekannten abhängen. NI
findet iterativ eine Nullstelle, falls es mehere gibt, normaler-
weise die am nächsten an V gelegene, wobei V, V+DV, V+DV+DDV
drei Anfangsschätzwerte sind.

<< DO V DISV NIS DDV 'DV' STO 'DDV' STO UNTIL KEY END DROP >>

Besipiel: Lösung von X^2+Y^2=1 & X=Y

F: << DROP ARRY-> DROP -> X Y
     << 'X^2+Y^2=1' ->NUM 'X=Y' ->NUM >> 2 ->ARRY >>

V:DV:DDV: [1,2] sind die Anfangsschätzwerte.
Starten Sie NI solange, bis das Ergebnis die gewünschte Ge-
nauigkeit hat, oder bis NI durch einen Fehler abgebrochen wird.
Letzteres ist der Fall, wenn eine Komponente von DDV Null, d.h.
eine Koordinate bereits exakt ist.


NIS  --> a1  (Newton-Iterations-Step)
-------------------------------------
Kernroutine von NI und VDR. Ein Newton-Iterations-Step.
Sind V, V+DV, V+DV+DDV Schätzwerte in aufsteigender Güte, dann
ist V+DV+DDV+a1 ein besserer Schätzwert.
Außerdem wird V+DV --> V.

<< DV 'V' STO+ V DDV + DV DDV + F 'FV' STO 1 V SIZE 1 GET
   FOR k DDV k 0 PUT DUP V + SWAP DV +
     F FV - DDV k GET / ARRY-> DROP
   NEXT V SIZE FV SIZE +
   IF LAST SAME
   THEN ->ARRY TRN FV SWAP /
   ELSE ->ARRY DUP TRN LAST * FV SWAP / * END
>>


MNI  (Modifizierte Newton-Iteration)  (ben. MNIS,DISV)
------------------------------------
Funktionalität wie NI.

<< V 0 F 'FV' STO
   DO MNIS V DISV UNTIL KEY END >>


MNIS   (Modifizierter Newton-Iterations-Step)  (ben. V->M)
---------------------------------------------
Sind V und V+DV Schätzwerte einer Nullstelle von F, (F wie in
NIS) und DFI Schätzwert der inversen Ableitungsmatrix in V, so
werden nach MNIS V,V+DV und DFI bessere Schätzwerte.

<< 'V' DFI FV * DUP 'DV' STO STO- V 0 F FV OVER 'FV' STO - DFI
  SWAP * DV + LAST DOT / V->M DFI TRN DV * V->M TRN
  * 'DFI' SWAP STO- >>


NST  e2,e1 --> a1  (Nullstellen)  (ben. eps)
--------------------------------
Bem: Statt NST kann auch das verbesserte NI benutzt werden.
Berechnet Nullstellen der Funktion F, wobei F einen Vektor der
Länge n erwartet und liefert. Anders interpretiert:
NST berechnet die Lösung von n Gleichungen mit n Unbekannten.
e2 und e1 sind Vektor-Schätzwerte, a1 = ein Lösungsvektor.

<< CLLCD DUP SIZE LIST-> -> a b n Fa
  << DO a F 'Fa' STO 1 n
       FOR k
         k 1 ->LIST b OVER GET a 3 PICK GET a 4 ROLL 4 PICK
         PUT F Fa - ROT ROT - / ARRY-> DROP
       NEXT
       n DUP 2 ->LIST ->ARRY TRN Fa SWAP / DUP ABS SWAP
       a eps 1 + * 'b' STO a SWAP - DUP ABS SWAP 'a' STO
       a 1 DISP
     UNTIL / eps < END
     a CLMF >> >>

Beispiel: Berechnung des Schnittpunktes von Kreis X^2+Y^2=1 mit
Grade X=Y. D.h. Suche Nullstelle der Funktion
F: [X,Y] --> [X^2+Y^2-1 , X-Y] wird gelöst durch die Eingaben:

<< ARRY-> DROP -> X Y << X SQ Y SQ + 1 - X Y - {2} ->ARRY >> >>
'F' STO [1,2] [3,4] NST


8.2 Sonstige Utilities
-------------------------

LPEQ  e1,e2 --> a1  (Loop-Equal)
--------------------------------
Führt solange das Programm e2 aus, solange es das 1. Stack-
element verändert und zeigt die Zwischenergebnisse in Zeile 1
an.

<< SWAP
   DO DUP 1 DISP DUP2 SWAP EVAL SWAP OVER
   UNTIL SAME END SWAP DROP CLMF >>

Beispiel 1: '(X+Y)^4' << EXPAN EXPAN COLCT >> LPEQ multipliziert
den ersten Ausdruck vollständig aus.
Beispiel 2: 1 << INV 1 + >> LPEQ --> 1.618 dem goldenen Schnitt


LOOPE e1  (Loop-Error)  (ben. LOOP)
----------------------
Führt solange das Programm e2 aus, bis ein Fehler auftritt oder
eine Taste gedrückt wird.

<< IFERR LOOP THEN END >>

Beispiel: << + >> LOOPE addiert alle Elemente des Stacks, bis
der nur noch ein Element im Stack oder ein nicht-addierbarer Typ
auftritt.


LOOP  e1
--------
führt solange das Programm e2 aus, bis eine Taste gedrückt
wird.

<< - f << DO f EVAL UNTIL KEY END >> DROP >>

Beispiel: << RAND 2000 * .1 BEEP >> LOOP ergibt Zufallsmusik


Ende der HP28S Programme    Copyright 6.4.90 by Marcus Hutter
-------------------------------------------------------------
 © 2000 by ... [previous] [home] [search] [science] [calculators] [personal] [contact] [up] [next] ... Marcus Hutter