#ifndef _MATRIX_
#define _MATRIX_

#include <exec/resident.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/ports.h>
#include <exec/tasks.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <functions.h>
#include <string.h>

/* Folgende Struktur steht als Ergebnis nach INFO_M1,INFO_M2,GLS zur Verfügung */
struct MInfo {
 double Rang;  /* Rang der Matrix */
 double Spur;  /* Spur der Matrix */
 double Det;   /* Determinante der Matrix */
};

/* Folgende Structur steht als Ergebnis nach 'STATIS' zur Verfügung */
struct MStatistic {
 long Rang;               /* Rang der Matrix */
 double Spur;             /* Spur der Matrix */
 double Det;              /* Determinante der Matrix */
 double Summe;            /* Summe der Einträge */
 int Dichte;              /* Benutzte Koeffizienten in Prozent */
 double Produkt;          /* Produkt aller Einträge die nicht Null sind */
 long Nil;                /* Grad der Nilpotenz - kleiner 0 nicht Nilpotent */
 long ZDim;               /* Benutzte Zeilen */
 long SDim;               /* Benutzte Spalten */
 unsigned int Symmetrisch  :1; /* Die Matrix besitzt die entsprechende */
 unsigned int Normal       :1; /* Eigenschaft, wenn das zugehörige */
 unsigned int Orthogonal   :1; /* Bit gesetzt ist */
 unsigned int Diagonal     :1; 
 unsigned int Triagonal    :1;
 unsigned int Selbstinvers :1;
 unsigned int Projektion   :1;
 unsigned int Selbstadj    :1; /* Selbstadjungiert */
 unsigned int Definit      :2; /* Die Matrix ist positiv, negativ etc. */
};
/* Folgende Werte nimmt der Eintrag Definit obiger Structur an. */
#define POSITIV		1
#define NEGATIV 	2
#define SEMI		4
#define UNDEFINIT 	0

/* Diese Union enthält Einträge, die an MATRIX! übergeben werden können */
union value {
 double d; /* Bei skalarer Multiplikation, Eigenraumberechnung, ESVRel 
              und der öfter eingesetzten K-Norm. */
 long l;   /* Beim Tensorprodukt, Matrixpotenz, GSV, ESV, ESVRel sowie
              LR und QR Algorithmus zur Eigenwert Berechnung. */
 char *s;};/* Beim Laden und Speichern von Matrizen als Zeiger auf Pfad
              und Name der Datei bzw. bei der LR-Zerlegung als
              Zeiger auf den Buchstaben der die Matrix bezeichnet
              unter der die Permutationsmatrix abgespeichert werden soll. */

/* Diese Structur ist über den Zeiger 'UserData' in der Windowstruktur
   des MATRIX!-fensters zu erreichen. Über Sie können alle Daten gelesen
   und geschrieben werden sowie Verhaltensweisen des Programmes gesteuert
   oder abgelesen werden. */
struct Kommunikation { 
 double *v[7]; /* Zeiger auf alle Vektoren, die dem Benutzer in MATRIX!
                  zur Verfügung stehen. 0 entspricht a usw. 
                  Beachten Sie bitte, daß bei einer Deklaration double *v[7]
                  C die Zeiger v[0] bis v[6] einschließlich zur Verfügung
                  stellt. Greifen Sie also nicht auf v[7] zu!!!*/
 double *m[7]; /* Zeiger auf alle Matrizen, die dem Benutzer in MATRIX!
                  zur Verfügung stehen. 0 entspricht A usw. 
                  Beachten Sie bitte, daß bei einer Deklaration double *m[7]
                  C die Zeiger m[0] bis m[6] einschließlich zur Verfügung
                  stellt. Greifen Sie also nicht auf m[7] zu!!!*/
 char *string; /* Zeiger auf den Inhalt der Statuszeile */
 struct MStatistic *MStat; /* Zeiger auf das Ergebnis der 'STATIS' Funktion
                  Die einzelnen Einträge werden oberhalb erklärt. */
 struct MInfo *MInfo; /* Zeiger auf das Ergebnis der Funktionen INFO_M1,
                  INFO_M2 und GLS */
 char *printer; /* Zeiger auf den Namen der Datei, in die die Ausgabe umgelenkt
                   wird. Dieser kann von hier aus geändert werden. */
 long dim;     /* Die Größe der Matrizen und Vektoren, mit denen MATRIX! arbeitet
                  kann hier abgelesen oder eingestellt werden. Um sie dann
                  tatsächlich zu bekommen, muß dann die Funktion GETVARMEM 
                  gestartet werden. Anschließend sollte die Größe hier
                  überprüft werden, die das Programm wirklich eingestellt hat. */
 SHORT Manz;   /* Gibt an wieviele Matrizen MATRIX! zum Arbeiten zur Verfügung
                  stellt. Steht hier z.B. eine 3, dürfen m[3] bis m[6] nicht
                  benutzt werden. */
 SHORT Vanz;   /* Hier steht die entsprechende Anzahl an Vektoren */
 union value val; /* Dient zur übergabe von Funktionsparametern an MATRIX! */
 BOOL set; /* Ist dieses Flag TRUE, werden Eingaben nicht durch Requester
              von Ihnen eingegeben, sondern aus dem Union val entnommen.
              Dies hat auf die Funktionen LOAD_M1,LOAD_M2,LOAD_V,LOAD_A,SAVE_M1,
              SAVE_M2,SAVE_V,SAVE_A,T_PROD,POTENZ,SMULTI_M1,SMULTI_M2,SMULTI_V
              und EV Einfluß. */
 BOOL busy; /* Ist dieses Flag von MATRIX! gesetzt,rechnet es noch. 
               Ergebnisse sollten also erst aus den Matrizen (usw.) gelesen
               werden, wenn dieses Flag nicht gesetzt ist. */
 BOOL lock; /* Sie müssen dieses Flag setzen, wenn Sie mit MATRIX! 
               kommunizieren wollen, damit MATRIX! weiß, daß es von Außen
               gesteuert wird. Ist dieses Flag gesetzt, kann MATRIX! nicht beendet
               werden. Weiterhin läßt sich das MATRIX!-fenster nach dem 
               Iconifizieren nicht mehr vergrößern. Wenn Sie also MATRIX!
               extern mit der Funktion ICON Iconifizieren, können Sie sicher
               sein, daß MATRIX! keine Eingaben über sein Fenster erhält.
               Sie müssen diese Flag löschen, wenn Sie MATRIX! nicht mehr
               steuern wollen. */
 BOOL output; /* Ist dises Flag gesetzt, werden alle Ergebnisse und
               Veränderungen im MATRIX!-fenster angezeigt. Wenn Sie dieses
               Flag löschen, sparen Sie also Zeit. */
 struct Task *extask; /* Dies ist der Zeiger auf Ihren eigenen Task, damit
                         MATRIX! Sie benachrichtigen kann, wenn die Rechnung
                         fertig ist. */
 ULONG maske; /* Diese Maske sendet MATRIX!, wenn es die Rechnung beendet hat. */
 double Double; /* Hier finden Sie die Ergebnisse aus den Normberechnungen */
 double ID;}; /* Diese Variable darf nicht verändert werden! Sie dient zum
   auffinden von MATRIX! durch die Library. */
/* Nun folgen die Definitionen der einzelnen MATRIX!-Funktionen zur Übergabe an
   die Funktion Make.
   M1 steht dabei für die oberer Matrix, M2 für die untere und V für den Vektor.
   Die Funktionen sind nach den Namen der Schalter in MATRIX! benannt.*/

#define INFO_M1 	0 /* Das Ergebnis liegt in MInfo vor. */
#define TRANS_M1 	2
#define INVERS_M1	3
#define CLR_M1	 	4
#define PRINT_M1 	5
#define BILIN		6
#define INFO_M2 	7 /* Das Ergebnis liegt in MInfo vor. */
#define TRANS_M2 	9
#define INVERS_M2 	10
#define CLR_M2  	11
#define PRINT_M2 	12
#define ONB		13
#define M1_A		14 /* In Matrix 1 wird Matrix A aktiviert */
#define M1_B		15
#define M1_C		16
#define M1_D		17
#define M1_E		18
#define M1_F		19
#define M1_G		20
#define M2_A		21 /* In Matrix 2 wird Matrix A aktiviert */
#define M2_B		22
#define M2_C		23
#define M2_D		24
#define M2_E		25
#define M2_F		26
#define M2_G		27
#define V_A		42 /* Vektor a wird aktiviert */
#define V_B		43
#define V_C		44
#define V_D		45
#define V_E		46
#define V_F		47
#define V_G		48
#define VDEST_A		75 /* Veltor a wird zum Zielvektor erklärt */
#define VDEST_B		76
#define VDEST_C		77
#define VDEST_D		78
#define VDEST_E		79
#define VDEST_F		80
#define VDEST_G		81
#define MDEST_A		68 /* Matrix A wird zur Zielmatrix erklärt */
#define MDEST_B		69
#define MDEST_C		70
#define MDEST_D		71
#define MDEST_E		72
#define MDEST_F		73
#define MDEST_G		74
#define M_PROD_M1_M2	28
#define M_DIVI		30
#define ADDIER_M	31
#define SUBTRA		32
#define HOCH		33
#define RUNTER		34
         /* Die folgenden Funktionen sind durch '* X = ' zu erreichen */
#define GAUß		2000
  /* Das Ergebnis liegt in MInfo und natürlich den Matrizen und Vektoren vor.*/
#define GAUßPLUS	2001
/* #define GSV		2002
#define ESV		2003 Siehe weiter unten */
#define GLSQR		2004
#define GAUTRI		2006

#define M_PROD_M_V	36
#define L_OPTI		37
#define ADDALL		38
#define MULALL		39
#define COPY_M_V	40
#define COPY_V_M	41
#define CLR_V		49
#define PRINT_V		51
#define E_TO_M2		53
#define	STATIS		54 /* Das Ergebnis ist unter MStat in der
                              Kommunikationsstruktur zu finden. */
         /* Die folgenden Funktionen sind durch '  EW  ' zu erreichen */
/*
#define EW_QR		3002
#define EW_LR		3003   Siehe weiter unten */
#define JACOBI		3001
#define EW_TRIDIA	3004
#define POLY		3000
         /* Die folgenden Funktionen sind durch 'NORM=1' zu erreichen */
#define NNSNORM		4000
#define NNZSNORM	4002
#define NNSSNORM	4003
#define NNFNORM		4001
#define NNKNORM		4004
         /* Die folgenden Funktionen sind durch 'ZERLEG' zu erreichen */
#define	LR		1001
#define QR		1000
#define HESSEN		1004
#define CHOLESKY	1003
#define SYMZER		1002

/* Die folgenden Makros als Parameter für ganze_zahl in Make_long übergeben
   beim Aufruf von LR. Also z.B.:
   Make_long(LR,PTOC); 
   legt die Permutationsmatrix die bei der LR-Zerlegung entsteht in Matrix C ab. */
#define PTOA		(long)((char *)"A")
#define PTOB		(long)((char *)"B")
#define PTOC		(long)((char *)"C")
#define PTOD		(long)((char *)"D")
#define PTOE		(long)((char *)"E")
#define PTOF		(long)((char *)"F")
#define PTOG		(long)((char *)"G")

#define	STATUS		59
#define	FREE		60 
#define	CLRALL		61
#define PRINT_A		62
#define	PRINT_STATUS	63 /* Druckt den Inhalt der Statuszeile */
#define ICON		64 /* Iconifiziert das MATRIX!-Fenster */
#define	ADDIER_V	65
#define	S_PROD		66 /* Das Ergebnis ist in Double */
#define	TRANS_V		67


/* Die nächsten Parameter sind die möglichen Übergabewerte für den Parameter
   Operation von Make_real. */

#define SMULTI_M1 	1 /* Eingabe wird in val.d der Kommunikation Struktur
                             erwartet.(Wenn set=TRUE) */
#define SMULTI_M2 	8 /* Eingabe wird in val.d der Kommunikation Struktur
                             erwartet.(Wenn set=TRUE) */
#define SMULTI_V	50 /* Eingabe wird in val.d der Kommunikation Struktur
                             erwartet.(Wenn set=TRUE) */
#define	EV		57 /* Eingabe wird in val.d der Kommunikation Struktur
                             erwartet.(Wenn set=TRUE) */


/* Die nächsten 2 Definitionen sind die möglichen Parameter für Make_long */

#define T_PROD		29    /* Eingabe wird in val.l der Kommunikation Struktur
                                 erwartet.(Wenn set=TRUE) */
#define	POTENZ		52    /* Eingabe wird in val.l der Kommunikation Struktur
                                 erwartet.(Wenn set=TRUE) */
#define EW_QR		3002  /* Eingabe wird in val.l der Kommunikation Struktur
                                 erwartet.(Wenn set=TRUE) */
#define EW_LR		3003  /* Eingabe wird in val.l der Kommunikation Struktur
                                 erwartet.(Wenn set=TRUE) */
#define GSV		2002  /* Eingabe wird in val.l der Kommunikation Struktur
                                 erwartet.(Wenn set=TRUE) */
#define ESV		2003  /* Eingabe wird in val.l der Kommunikation Struktur
                                 erwartet.(Wenn set=TRUE) */


/* Die folgenden Definition dienen der Steuerung der Dateiopertionen mittels
   Make_datei. Zunächst für den Parameter 'Objekt':         */

#define MATRIX1		160 /* Bestimmt Matrix1 zum Objekt mit dem die
                               Dateiopertion durchgeführt wird. */
#define MATRIX2		161 /* Bestimmt Matrix2 zum Objekt mit dem die
                               Dateiopertion durchgeführt wird. */
#define VEKTOR		162 /* Bestimmt den Vektor zum Objekt mit dem die
                               Dateiopertion durchgeführt wird. */
#define ALLE		163 /* Dateiopertion beziehen sich auf alle Matrizen
                               und Vektoren. */

/* und nun für den Parameter 'Operation' */

#define LOAD		164 /* In das bestimmte Objekt wird etws geladen. */
#define SAVE		165 /* Das bestimmte Objekt wird abgespeichert */
#define DELETE		166 /* Ein Objekt geeigneten Typs wird gelöscht. */


/* Diese Definitionen werden intern in ChangeDim und FreeM benötigt
   könne aber auch selbst mittels Make genutzt werden */

#define BUILDUP		144 /* Diese spezielle Funktion dient dazu,
 das Display nach der externen Nutzung von MATRIX! wieder herzustellen.
 Sie sollte direkt nach dem Löschen des lock Flags aufgerufen werden. */
#define CHANGEDIM	143 /* Dient zum Ändern der Größe der Matrizen.
                            Die gewünschte Größe wird in dim eingetragen. */


/* Diese Definitionen werden für Make_menu definiert. 
   Die Namen entsprechen dem Text in den Menüs */

#define ZAHLEN_ALS_REELLE_ZAHLEN	0x0001
#define ZAHLEN_ALS_BRUECHE_1		0x0801
#define ZAHLEN_ALS_BRUECHE_2		0x1001
#define ANZAHL_AN_VEKTOREN		0x0021 /* Übergabe einer Zahl in l */
#define ANZAHL_AN_MATRIZEN		0x0821 /* Übergabe einer Zahl in l */
#define HILFE				0xf841
#define PROTOKOLL			0xf861
#define BLOCKWEISE			0xf881
#define ASCIIDATEI			0xf8a1
#define ZIFFER_NULL			0xf8c1
#define STABIL				0xf8e1
#define TOLERANZ			0xf901 /* Übergabe einer Zahl in l */
#define SAVE_PREFS			0xf921
#define LOAD_PREFS			0xf941 
 /* Alle möglicherweise auftauchenden Requester werden automatisch 
positiv beantwortet. (Matrixgröße, Matrixhöchstzahl ..) */
#define HINTERGRUND			0xf961
 /* Die Ergebnisse der folgendem Funktionen sind in Double zu finden. */
#define SUMMENNORM			0xf802
#define EUKLIDNORM			0xf822
#define P_NORM_V			0xf842 /* Übergabe einer Zahl in l */
#define MAXIMUMSNORM			0xf862
#define SPALTENSUMMENNORM		0xf803
#define ZEILENSUMMENNORM		0xf823
#define SPEKTRALNORM			0xf843
#define FROBENIUSNORM			0xf863
#define P_NORM_M			0xf883 /* Übergabe einer Zahl in l */
 /* Nun die Menüpunkte für die Konditionszahl */
#define KOND_SPALTENSUMMENNORM		0x00a3
#define KOND_ZEILENSUMMENNORM		0x08a3
#define KOND_SPEKTRALNORM		0x10a3
#define KOND_FROBENIUSNORM		0x18a3
#define KOND_P_NORM_M			0x20a3 /* Übergabe einer Zahl in l */

/* Die folgenden Definitionen sind die beiden möglichen Übergabewerte
   an die Funktion LoginM aus der MATRIX!lib.library */

#define OUTPUT 		1
#define NOOUTPUT 	0


/* und dies sind die möglichen Rückgabewerte falls ein Fehler auftritt */

#define NO_INTUITION	1
#define NO_WB_SCREEN	2
#define NO_MATRIX	3
#define NO_REPLYPORT	4
#define MATRIX_ENDING	5
#define NO_SIGNAL	6
#define PRE_LOCKED	7

/* Nun werden noch die Funktionen definiert: */

int LoginM(int OutFlag);
void FreeM(void);
int Make(int Operation);
int ChangeDim(long DIM);
void Make_long(int Operation,long ganze_zahl);
void Make_real(int Operation,double *reelle_zahl);
void Make_datei(int Operation,int Objekt,char *name);
int Make_menu(int Operation,long l);
double MAT(char a,long x,long y);
double VEK(char a,long y);
void AUSGABE(char *i);

#pragma amicall(MatrixlibBase, 0x1e, LoginM(d0))
#pragma amicall(MatrixlibBase, 0x24, FreeM())
#pragma amicall(MatrixlibBase, 0x2a, Make(d0))
#pragma amicall(MatrixlibBase, 0x30, ChangeDim(d0))
#pragma amicall(MatrixlibBase, 0x36, Make_long(d0,d1))
#pragma amicall(MatrixlibBase, 0x3c, Make_real(d0,a0))
#pragma amicall(MatrixlibBase, 0x42, Make_datei(d0,d1,a0))
#pragma amicall(MatrixlibBase, 0x48, Make_menu(d0,d1))

/* Die Funktion der folgenden Macros wird in MATRIX!lib.c erklärt. */
#define MAT(A,C,D) (MatrixlibBase->Out->m[A-65][((D)-1)*MatrixlibBase->Out->dim+(C)-1] )
#define VEK(A,C) (MatrixlibBase->Out->v[A-97][(C)-1])
#define AUSGABE(A)  strcpy(MatrixlibBase->Out->printer,A)
#define MSTATRANG 		MatrixlibBase->Out->MStat->Rang
#define MSTATSUMME 		MatrixlibBase->Out->MStat->Summe
#define MSTATPRODUKT 		MatrixlibBase->Out->MStat->Produkt
#define MSTATDICHTE 		MatrixlibBase->Out->MStat->Dichte
#define MSTATSPUR 		MatrixlibBase->Out->MStat->Spur
#define MSTATDET 		MatrixlibBase->Out->MStat->Det
#define MSTATNIL		MatrixlibBase->Out->MStat->Nil
#define MSTATZDIM 		MatrixlibBase->Out->MStat->ZDim
#define MSTATSDIM 		MatrixlibBase->Out->MStat->SDim
#define MSTATSYMMETRISCH 	MatrixlibBase->Out->MStat->Symmetrisch
#define MSTATNORMAL 		MatrixlibBase->Out->MStat->Normal
#define MSTATORTHOGONAL 	MatrixlibBase->Out->MStat->Orthogonal
#define MSTATDIAGONAL 		MatrixlibBase->Out->MStat->Diagonal 
#define MSTATTRIAGONAL 		MatrixlibBase->Out->MStat->Triagonal
#define MSTATSELBSTINVERS 	MatrixlibBase->Out->MStat->Selbstinvers
#define MSTATPROJEKTION		MatrixlibBase->Out->MStat->Projektion
#define MSTATSELBSTADJUNGIERT	MatrixlibBase->Out->MStat->Selbstadj
#define MSTATDEFINIT	 	MatrixlibBase->Out->MStat->Definit
#define MINFODET 		MatrixlibBase->Out->MInfo->Det
#define MINFORANG 		MatrixlibBase->Out->MInfo->Rang
#define MINFOSPUR 		MatrixlibBase->Out->MInfo->Spur
#define STATUSZEILE		MatrixlibBase->Out->string
#define ERGEBNIS		MatrixlibBase->Out->Double

/* Als letztes noch die MATRIX!library-Struktur auf die man beim öffnen
   der Library einen Zeiger bekommt. Außer dem Eintrag Out dienen die
   Einträge der internen Verwaltung der Library. */
   
struct MatrixlibBase {
	struct Library		ml_Lib;
	unsigned long		ml_SegList;
	BOOL			log;
        struct MsgPort		*ReplyPort;
        struct MsgPort		*MATRIXPort;
	struct Kommunikation	*Out;
/* Dies ist der Zeiger auf die von MATRIX! zur Kommunikation eingerichtete
   Struktur die oberhalb beschrieben wurde.
   Über Sie laufen alle Datenaustausche ab.*/
	struct Gadget		Gad;
	struct IntuiMessage	MyMess;
	struct IntuitionBase	*IntBase;
	long			bit;
};

#endif

