MATRIX QUICKSTART Manual
=========================

Matrix Versions-Nummern:
KHMatrixJavaLibrary Version: 1.13 (Stand 09.07.2011)
	(static public final String _khMatrixJavaLibrary_SoftwareVersion = "1.13"
            in:	 KHMatrixShared.java)
GUI Version: 1.12  (Stand 09.07.2011)
	(   protected final String matrixGUI_SoftwareVersion = "1.12"
	in KHMatrixFullExample.java und KHMatrixMediumExample.java)
KHMatrix native library version: 106 (Stand 09.07.2011)
#define SOFTWARE_VERSION 106   
	im C++ Projekt in KHMatrixDefines.h

Hinweis: Ab GUI-Version 1.15 (alle Forms mit Absolute Layout!)

Wie erzeuge ich die KHMatrixLib und die Beispiel-Programme?
==================================================================
Die KHMatrix Library läuft auf allen gängigen Betriebssystemen (Windows, Mac OS X, Linux, Solaris) und kann aus CPP-Programmen sowie aus Java Programmen heraus aufgerufen werden. Da die library in ANSI C++ geschrieben ist, gibt es keine nennenswerten Plattform Abhängigkeiten. Die eine Benutzeroberfläche in Java verwendet werden kann, gibt es auch für Graphik und Sound keine Plattformabhängigkeiten.

Für Windows mit Visual Studio 10 (Executable, ohne DLL)
Die Visual Studio 10 Projektdatei KHMatrixLib.sln im Ordner KHMatrixLib aufrufen und die Library anschließend erstellen.
Danach die gewünschten Visual Studio 10 Beispiel-Projektdateien (die sich im jeweiligen Beispiel Ordner befinden) auswählen und die Beispiel Programme erzeugen (für jedes Beispiel existiert eine eigene sln-Projekt-Datei). Wird an der KHMatrixLib etwas geändert, dann bemerken dies die Beispiel-Programme erst wenn 'Neu erstellen' gewählt wird.
Unter Mac OS X mit XCode (Executable, ohne DYLIB):
Die Datei KHMatrixDefines.h im Ordner KHMatrixLib editieren: //#define OPSYSTEM_MAC aktivieren und #define OPSYSTEM_WINDOWS deaktivieren. Bei Bedarf  #define MOTOROLA (für PPC) aktivieren. Alternativ diese #defines rauskommentieren und als Macros im Compiler setzen.
Die Xcode Projektdatei KHMatrixLib.xcodeproj im Ordner KHMatrixLib aufrufen und die KHMatrixLib erstellen.
Danach die gewünschten Xcode Projektdateien (die sich im jeweiligen Beispiel Ordner im Unterverzeichnis Xcode befinden) auswählen und die Beispiel Programme erzeugen. 
Code für die PPC Plattform kann erzeugt werden.

Für die NetBeans Entwicklungsumgebung (CPP- Versionen, *.exe + DLL / shared library):
- Windows (es wird der MinGW 64 Bit Windows Compiler benutzt (nicht GNU CPP, weil der nur 32 Bit 	Code unter Windows erzeugen kann): 
NetBeansProjekt KHMatrixDynamicLibNetBeansWIN_MinGW auswählen und für die gewünschte Platform (32 oder 64 Bit compilieren). Es wird die KHMatrix- DLL erzeugt.

Danach die gewünschten NetBeans C++ Beispiel-Projektdateien (die sich im jeweiligen Beispiel Ordner im Unterordner NetBeansC++Console befinden) und für die gewünschte Platform (32 oder 64 Bit kompilieren). Zum Testen am ist es am Einfachsten, die Beispielprogramme aus der IDE zu starten

- Mac OSX (es wird der GNU CPP Compiler benutzt) : 
NetBeansProjekt KHMatrixDynamicLibNetBeansMacOSX_GNUCC auswählen und für die gewünschte Platform (32 oder 64 Bit compilieren). Es wird die KHMatrix- dylib erzeugt. Code für PPC Plattform kann nicht erzeugt werden.

Danach die gewünschten NetBeans C++ Beispiel-Projektdateien (die sich im jeweiligen Beispiel Ordner im Unterordner NetBeansC++Console befinden) und für die gewünschte Platform (32 oder 64 Bit kompilieren). Zum Testen am ist es am Einfachsten, die Beispielprogramme aus der IDE zu starten
Vor dem Starten der NetBeans IDE sollte der dylib Pfad von der Console aus gesetzt werden. Z.Bsp:
DYLD_LIBRARY_PATH=$HOME/MatrixCP/JavaLib:$DYLD_LIBRARY_PATH 
export DYLD_LIBRARY_PATH

- Linux (es wird der GNU CPP Compiler benutzt) : 
NetBeansProjekt KHMatrixDynamicLibNetBeansLinux_GNUCC auswählen und für die gewünschte Platform (32 oder 64 Bit compilieren). Es wird die KHMatrix- shared library (*.so) erzeugt.

Danach die gewünschten NetBeans C++ Beispiel-Projektdateien (die sich im jeweiligen Beispiel Ordner im Unterordner NetBeansC++Console befinden) und für die gewünschte Platform (32 oder 64 Bit kompilieren). Zum Testen am ist es am Einfachsten, die Beispielprogramme aus der IDE zu starten
Vor dem Starten der NetBeans IDE sollte der LIB Pfad von der Console aus gesetzt werden. Z.Bsp:
LD_LIBRARY_PATH=$HOME/MatrixCP/JavaLib:$LD_LIBRARY_PATH 
export LD_LIBRARY_PATH

- Solaris (es wird der GNU CPP Compiler oder der Sun Studio Compiler benutzt): 
NetBeansProjekt KHMatrixDynamicLibNetBeansSolaris_GNUCC auswählen und für die gewünschte Platform (32 oder 64 Bit compilieren). Es wird die KHMatrix- shared library (*.so) erzeugt.

Danach die gewünschten NetBeans C++ Beispiel-Projektdateien (die sich im jeweiligen Beispiel Ordner im Unterordner NetBeansC++Console befinden) und für die gewünschte Platform (32 oder 64 Bit kompilieren). Zum Testen am ist es am Einfachsten, die Beispielprogramme aus der IDE zu starten
Vor dem Starten der NetBeans IDE sollte der LIB Pfad von der Console aus gesetzt werden. Z.Bsp:
LD_LIBRARY_PATH=$HOME/MatrixCP/JavaLib:$LD_LIBRARY_PATH 
export LD_LIBRARY_PATH

Die vorhandenen Projektdateien sind für 32 Bit und 64 Bit Programme und laufen auf allen Windows Versionen seit Windows XP. Unter Mac OS X compilierte Versionen laufen am Mac OSX 10.5 (XCode). Unter Mac OSX mit netBeans erzeugte Versionen laufen nur ab MacOs X 10.6 (Snow Leopard).

Für die NetBeans Entwicklungsumgebung (Java- Versionen, *.jar + DLL / shared library):
Für alle Rechner Plattformen (Windows, Mac OS X, Linux, Solaris) kann jeweils ein einziges für alle Plattformen funktionierendes Beispiel-Projekt verwendet werden. Die jeweiligen DLLs, dylibs oder shared libraries werden aus dem Java Hauptprogramm mit Hilfe von JNA (Java Native Access) aufgerufen. die Für jede Plattform gültige DLL/dylib(shared library) muss in libKHMatrixJava.xxx (xxx=dll,dylib oder so) umbenannt werden und in den Ordner 'javaLib' kopiert werden.
Genauso wie bei den CPP Beispiel-Programmen muss vor dem Start der NetBeans IDE der entsprechende Library Path gesetzt werden, damit Java die DLL/dylib/shared library  finden kann.
Am Besten werden auch die Java Testprogramme aus der NetBeans IDE heraus gestartet.

Für die Verwendung der Funktionen der KHMatrixLib aus Java heraus, wurde ein Satz von (statischen) Wrapper-Funktionen geschrieben, die es ermöglichen auch CPP Methoden zusammen mit vererbten Klassen und überlagerten Methoden zu verwenden. Die Namen der Wrpper Funktionen sind identisch mit den Funktionsnamen der KHMatrix-Library und beginnen mit "s_" und haben einen zusätzlichen Parameter, der dem 'this' Zeiger entspricht. Für die Matrix-Modelle 'Medium' und 'Base' bekommt der Warpper-Funktionsname noch die Ergänzung '_Medium' bzw '_Base'.
Die Verwendung von DLLs, dylibs und shared libraries mit Hilfe von Java JNA stellt für alle Plattformen kein Problem dar, mit Ausnahme der Windows-Plattform: Die 'gemangelten' CPP Funktionsnamen der KHMatrix DLL wurden von den JNA utilities falsch erzeugt. Dafür wurde ein patch-Prgramm geschrieben.

Beim Aufruf der KHMatrix library aus Java sollten grundsätzlich die 64 Bit Version der DLLs/dylibs/shared libraries verwendet werden. Ausnahme: Solaris: hier funktioniert nur die 32 Bit Version. Sollen dennoch 32 Bit Versionen verwendet werden, so muss auf dem jeweiöligen Rechner auch die 32 Bit Java VM installiert sein.

1.	Was ist die KHMatrixLib ?
===========================
Die KHMatrixLib (im folgenden einfach 'Matrix' genannt) ist eine Library, die es erlaubt, aus vorgegeben Daten, die irgendwie zeitlich kausal geordnet sind, und die eine Folge von Zuständen eines Systems representieren, ein Regelwerk (d.h. eine Menge von Regeln) zu erstellen, das die einzelnen Übergangswahrscheinlichkeiten des Systems von einem Zustand in den anderen beschreibt. Mit Hilfe dieser Übergangswahrscheinlichkeiten kann die Matrix eine beliebig lange Folge von Zuständen dieses Systems erzeugen.
Im Prinzip handelt es sich um eine verallgemeinerte Markow-Kette mit Übergangswahrscheinlichkeiten. Bei der Berechnung der Übergangswahrscheinlichkeiten kann jedoch die ganze 'Historie' eines Prozesses mit einfließen.  Außerdem kann die Matrix auch 'Beendigungswahrscheinlichkeiten' (d.h. die Wahrscheinlichkeit dass eine Folge von Zuständen endet) liefern, sowie das Gegenteil, d. h. die Erschaffung eines Zustandes ('ex nihilo') beim Start einer neuen Zustandsfolge. 
In ihrer einfachsten Form kann die Matrix auch einfach dazu benutzt werden, hochdimensional strukturierte Daten abzuspeichern (daher der Name 'Matrix', da es sich im Grunde genommen um nichts anderes als um eine hoch dimensionale Pointer-Matrix (mit variabler Dimensionslänge) handelt.

Die Matrix kann auf fast alle System angewendet werden. Die Voraussetzungen für die Anwendbarkeit sind sehr allgemein:
- Die Zustand des Systems zu einem bestimmten Zeitpunkt muss durch eine Menge von ganzen (auch negativen) Zahlen beschreibbar sein.
- Es sollte genug Material über das Verhalten des Systems vorhanden sein.
Ist die Matrix einmal mit Daten über ein System gefüttert worden, so kann man aus der Matrix wie aus einem unendlich langem ‚stream’ lesen. Bei geeigneter Wahl der Parameter wird dieser ‚stream’ immer auch neuartige Übergänge liefern, d.h. es handelt sich beim Lesen aus der Matrix durchaus um einen kreativen Prozess.
In der Matrix selbst werden keine Folgen von Zuständen gespeichert sondern ausschließlich Regeln, die sehr viel kürzer sind.
Beim Lesen aus der Matrix kann die Intelligenz der Matrix eingestellt werden. Bei hoher Intelligenz wird das Ergebnis nahe am Original sein, mit dem die Matrix gefüttert wurde; bei niedriger Intelligenz fließen immer mehr Zufallselemente mit ein.
Das Ergebnis des Outputs beim Lesen wirkt sehr viel intelligenter als es die Einfachheit der Regeln vermuten ließe. Irgendwie scheint die Matrix das Wissen über das Verhalten eines Systems nicht nur lokal in den Regeln zu speichern sondern holistisch in der Gesamtheit aller Regeln. Wenn man z. Bsp. einen Teil der Regeln entfernen wird, so wird sich das Ergebnis beim Lesen nicht sprungartig ändern. 

2.	Auf welchen Betriebssystemen läuft die Matrix?
============================================
Entwickelt mit C++ unter ANSI C ist die einfache Portierung auf jedes Betriebssystem gewährleistet. Getestet wurde die Matrix bisher unter Windows (32 Bit und 64 Bit), Mac OSX ab 10.4, Linux (32 Bit und 64 Bit), sowie Solaris 10.x. Für die 64 Bit Versionen wurde die Matrix als echte 64 Bit Annwendung kompiliert. Die Beispielprogramme sind ausschließlich Konsolen- Anwendungen. Unter Max OS X muss beim Debuggen unter Umständen das Konsolen Fenster extra geöffnet werden.

3.	Welche Entwicklungsumgebungen wurden benutzt?
===============================================
Unter Windows: Visual Studio 10, unter Mac OS X: Xcode 3.2, Ausserdem kann unter jedem Betriebsssystem die NetBeans IDE verwendet werden.
In den Beispielen befinden sich die VC 10 Projektdateien immer direkt im Beispiel-Ordner, die Xcode Projekt-Dateien befinden sich immer im Ordner Xcode. Da die Matrix auch unter Linux (und da speziell mit BlitzMax) laufen soll, wurde das Melodyne Framework nicht verwendet. Die Funktionalität der KHMatrixBase selbst wurde benutzt für einen Malloc-Debugger, der Speicherlecks u.a. Fehler aufspüren kann.

4.	Gibt es verschiedene Versionen der Matrix?
=======================================
Ja. Die Matrix ist nach dem Vererbungskonzept konzipiert. In der einfachsten Version ('KHMatrixBase') kann die Matrix noch nicht mit Regeln umgehen, es können nur Daten geschrieben und gelesen werden. (Beispiele im Ordner MatrixBase)
KHMatrixBase: 	Nur random read/ write und delete Aktionen (keine Übergangswahrscheinlichkeiten)
			(Beispiele im Ordner 'MatrixBase)
KHMatrixMedium:	Kann Regeln mit Übergangswahrscheinlichkeiten erstellen. Lesen im 'stream'  Modus möglich
			(Beispiele im Ordner 'MatrixMedium)
KHMatrix:		(Beispiele im Ordner 'MatrixFull').  Wie KHMatrixMedium, jedoch wird zu jeder Matrix eine sogenannte 'Symbol-Matrix' angelegt, in der die Regeln nicht mehr auf unterster Ebene verarbeitet werden, sondern auf einer höheren 'Symbol-Ebene'. Dies sei an einem einfachen Beispiel erkärt: Bei Matrizen, die mit Text gefüttert wurden, handeln die Regeln bei KHMatrixMedium von Buchstaben. In der Vollversion (KHMatrix) handeln die Regeln von Wort-Symbolen (ein WortSymbol entspricht dann einem Zahlenwert).
Hinweis: Die Verarbeitung auf Symbol Ebene wurde bisher nur für Text Matrizen implementiert, ist jedoch f. MIDI Matrizen geplant.
Der Beispiel Ordner MatrixBlitzMax enthält im wesentlichen die gleichen Beispiele wie MatrixFull. Die BlitzMax Beispiele dienen zum Test unter der Entwicklungsumgebung von BlitzMax unter Linux. Für die BlitzMax Plattform habe ich ein kleines API mit Wrapper-Funktionen geschrieben, so daß die KHMatrix Library auch unter BlitzMax verwendet werden kann.

Matrizen, die abgespeichert werden sollten die Endung '.phr' bekommen. Das hat historische Gründe (die Anfangszeit der Matrix liegt noch in meiner 'Melodyne-Zeit'. Damals habe ich mit Melodie-Phrasen beschäftigt (daher der Name 'Phrase-Matrix').
Matrizen, die unter einem einfacheren Modell abgespeichert wurden (z.Bsp. Basic oder Medium) können auch mit einer höheren Version (z.Bsp. der KHMatrix-Vollversion) gelesen werden D.h. Abwärtskompatibilität ist gewährleistet. Umgekehrt gilt dies jedoch nicht.

5:	Was sind die Anwendungsgebiete für die Matrix und was zeigen die Beispiele?
=====================================================================
Ganz Allgemein kann die Matrix auf jedes System 'losgelassen' werden, dessen Verhalten und Gesetzmäßigkeiten wir nicht verstehen, oder dessen Gesetzmäßigkeiten sehr komplex oder kompliziert sind. Das Ergebnis ist dann eine Matrix mit (typischerweise vielen Tausend) Regeln, mit denen beim Lesen aus der Matrix das Verhalten des Systems nachgebildet wird.
Ein typischer Fall dafür ist z. Bsp. ein Musikstück.
Die Matrix 'versteht' dann zwar das System nicht, aber sie tut so, als ob sie es verstünde. (Hier streiten sich KI-Experten über den Begriff  'Verstehen'). Vielleicht ist das ja kein Widerspruch. 
Der Ordner 'examples’ enthält eine Vielzahl von Beispielen für die Anwendung der Matrix.  (Einige Beispiel kommen in den zu den verschiedenen 'Ausbaustufen' 'Basic', 'Medium' und 'Full' gehörenden Ordnern mehrmals vor. Das zeigt nur die Abwärtskompatibilität, d.h. einfachere Funktionen können auch mit einem fortgeschritteneren Matrix Modell durchgeführt werden.

5.1. Anwendungsgebiet Text (im einfachsten Fall ANSI Text):
-------------------------------------------------------------------------------------------------
Einmal mit einer Geschichte oder einem Kapitel eines Buches gefüttert, kann die Matrix beliebig lange zu diesem Thema 'plaudern'. (Hinweis: Die aktuelle Matrix-Version hat eine einfache Spracherkennung zwischen Englisch und Deutsch und speichert die analysierten Regeln in getrennten Deutsch- und Englisch-Untermatrizen). Eine Vermischung zwischen verschiedenen Sprachen kann deshalb vermieden werden. Beispiele (Ordnernamen):

04_FeedNewMatrixWithAnsiFilesWriteNoMatrixConsoleOutput:
Zeigt, wie das Füttern der Matrix mit ANSI Text geht (in diesem Fall mit einer Text Datei). Die aus der Matrix gelesenen Textzeichen werden einfach auf die Konsole ausgegeben
05_FeedNewMatrixWithAnsiFilesWriteNoMatrixWriteOutputAnsiFile
(wie Beispiel 4, jedoch wird der aus der Matrix gelesene Text in einer Datei gespeichert). In diesem Fall wird die Matrix mehrmals
mit unterschiedlichen Texten und unterschiedlichen Sprachen gefüttert)
06_FeedNewSymbolMatrixWithAnsiFilesWriteNoMatrixWriteOutputAnsiFile
(wie Beispiel 5, jedoch wird hier auf Symbol-Ebene gegangen.). Es werden zwei zusätzliche Symbol-Matrizen erzeugt. Beim Lesen wird auf Symbol Ebene aus der Matrix gelesen. Aus den Symbolen (=Wörtern) werden automatisch wieder Buchstaben erzeugt.
07_FeedNewMatrixWithAnsiFilesWriteMatrix
(wie Beispiel 5, jedoch wird die erzeugte Matrix auf Platte geschrieben)
08_ReadExistingAnsiMatrixWriteNoMatrixConsoleOutput
Zeigt wie eine Matrix aus einer Matrix-Datei erzeugt wird. Aus dieser Matrix wird dann gelesen (Ausgabe auf Konsole)
09_FeedNewSymbolMatrixWithAnsiFilesWriteMatrix
(wie Beispiel 6 , jedoch wird die erzeugte Matrix auf Platte geschrieben)
10_ReadExistingSymbolAnsiMatrixWriteNoMatrixWriteOutputAnsiFile
(wie Beispiel 6, jedoch wird die Matrix nicht gefüttert sondern eine existierende Symbol-Matrix wird von Platte gelesen)

5.2. Anwendungsgebiet Zahlenfolgen (mit unbekanntem Bildungsgesetz)
-------------------------------------------------------------------------------------------------------------------

24_PrimeNumberTest01CoordDimension1
Zeigt, wie die Matrix mit einer Zahlenfolge mit unbekanntem Bildungsgesetz (den Primzahlen) gefüttert wird.
Nach der Eingabe einer Initiierungs-Sequenz von Primzahlen werden die nächsten Primzahlen aus der Matrix gelesen.
Hinweis: Die Primzahlen sind eine harte Nuss. Bis jetzt ist es noch nicht gelungen, die Folge von (beliebig großen) Primzahlen perfekt aus der Matrix zu lesen. Es gibt jedoch interessante Ergebnisse: So ist z. Bsp. die maximale Dimension der Matrix (d.h. die maximal vorkommende Regellänge) 15!. D.h. Der Wert einer Primzahl hängt maximal ab von den 15 vorausgegangenen Primzahlen.
Dummerweise wächst trotzdem die Anzahl der Regeln. Dieses Problem kann jedoch evtl. mit neuen ‚preProcessing’ Types gelöst werden...
26_PI_Decimals
hier wird die Matrix mit der Dezimalbruchentwicklung von PI gefüttert. Wenn man sich die Statistik der Matrix anschaut, dann sind mit den bisherigen Methoden keine Regeln zu finden, d. h. jede Ziffer kann mit der gleichen Wahrscheinlichkeit auf jede andere beliebige Ziffer folgen. Das war auch nicht anders zu erwarten, da irgend ein schlauer Mathematiker bewiesen hat, dass jede vorgegebene Sequenz von Ziffern irgendwo irgendwann mal in der tatsächlichen Dezimalbruchentwicklung von PI vorkommen wird.
25_PrimeNumberTest02CoordDimension4 
(wie Beispiel 24, jedoch wird die Matrix nicht mit einzelnen Zahlen gefüttert, sondern mit Quadrupeln von Primzahlen).
Hier wird die Eigenschaft 'prim' nicht durch eine Zahl, sondern durch 4 Zahlen definiert.
28_PrimeNumberTest03Modulus
hier wird die Matrix nicht mit Primzahlen (bzw. Primzahlen N-Tupeln) gefüttert, sondern mit den Modulus.Resten, die mit den ersten <N> Primzahlen entstehen
31_MersennePrimeNumberTest01CoordDimension1
(wie Beispiel 24, jedoch mit Mersenne-Primzahlen). Wer die erste Mersenne Primzahl mit 100 Millionen Stellen findet bekommt einen Preis von 100000 USD...
27_SigmaFunction
hier wird die Matrix mit den Werten einer zahlentheoretischen Funktion, die eng mit den Primzahlen zusammenhängt, gefüttert.
29_SinusTest
hier wird die Matrix mit Werten der Sinus Funktion gefüttert. Die Anzahl der resultierenden Regeln bleibt relativ klein und damit endlich (wie zu erwarten war)
30_PolynomTest
hier wird die Matrix mit den Zahlenwerten eines Polynoms (in diesem Fall ganz einfach X^2) gefüttert. Die Anzahl der erzeugten Regeln bei ‚preProcessingType’ 2 ist 1 (da schon schon nach nach den Differenzen zweiter Ordnung eine konstante Folge ensteht. 
31_MersennePrimeNumberTest01CoordDimension1
hier wird die Matrix mit den Mersenne Primzahl Exponenten gefüttert. Als geeigneter PreprocessingType wird 2 oder 3 vorgeschlagen
Ein Successor Test findet ebenfalls statt.
32_OcronTest01
OCRON (= Operator coded Representation Of Numbers). Test for a matrix with a single ID. 
OCRON Type 03 (3 operators: '2', '*' and 'P')
Creates an OCRON Matrix and generates a statistic report (written to matrixDebug.txt)
The Matrix is feeded with ocron3s created from the set of natural numbers
The end-of ocron symbol used here is '\n'
Reads also a specified number of successors ocrons from the matrix, which were displayed as numbers
(reconverted by (ocron3ToInt())
The created Ocron Sequence will be written saved a ANSI Textfile (ocron03NNumbers.txt)
The created matrix will be be written to disk.
If 'generateOnlyOcronFile' = 1, the program can also be used to create and save only the Ocron Sequence with a specified filename 
and perform no other tasks
32A_OcronTest01A
OCRON (= Operator coded Representation Of Numbers). Test for a matrix with a single ID.
Same as 32_OcronTest01, but here the matrix is feeded with the set of prime numbers
32B_OcronTest01B
OCRON (= Operator coded Representation Of Numbers). Test for a matrix with a single ID.
Same as 32_OcronTest01, but here the matrix is feeded with the set of Mersenne Prime number exponents
33_OcronTest02
OCRON (= Operator coded Representation Of Numbers). Test for a matrix with a single ID. 
OCRON Type 03 (3 operators: '2', '*' and 'P')
Does not create a an ocron sequence like the examples before, but reads an ocron sequence from an ANSI text file.
The user must know the 'end-of-Ocron' Symbol because it will be needed by the read routine.
The text file may only contain the ocron symbols and and an End-Of-Ocron Symbol (in this case '\n').
reads ocrons type 3 ('2','P', '*') (the code can easyly be extended to use type 4 and 5 ocrons ,'...'^' and 'Q')
Creates an OCRON Matrix and generates a statistic report (written to matrixDebug.txt)
The created matrix will not be be written to disk.
Reads also a specified number of successer ocrons from the matrix, which were displayed as numbers
(reconverted by (ocron3ToInt())
34_OcronTest03
OCRON (= Operator coded Representation Of Numbers). Test for a matrix with a single ID.
Does not create an ocron sequence and does not create a matrix file.
This examples reads ocrons from a previously created matrix file.
The End-Of-Ocron symbol of the ocrons in the matrix must be known (in this case '\n').
The type of ocron (3, 4 or 5) must also be known (int this cas '3).
The code can be easyly adopted for use of type 4 and 5 ocrons
Reads also a specified number of successer ocrons from the matrix, which were displayed as numbers
(reconverted by (ocron3ToInt())
35_OcronTest04
GOCRON (= Goedelized Operator coded Representation Of Numbers). Test for a matrix with a single ID. 
OCRON Type 03 will be taken (3 operators: '2', '*' and 'P')
Important: Before creating any ocron or gocron sequences, this test program uses a set of numbers
(in this case the set of natural numbers) in order to create a gocron code Table called gocronIndices:
gocronCodeIndices = createGocron3CodeIndices(naturalNumbers, ...)
This code table will also be written to matrixDebug.txt. it contains a table wit 4 rows:
'number' (in this case natural numbers),'gocron' (in Dez. system), gocronCodeIndex, ocron (as text) 
The gocronCodeIndex gives the index of the gocron if it would be sorted by its numeric value. One could try to
feed the matrix not with the ocrons, nor directly with thr gocrons (gocrons typically increase more rapidly than its orrogin numbers...)
but with the gocron code indices (which are typically in the same order og magnitude as the original numbers, preprocessing type 
for this exper8iment would typically be > 0.
After this step, it creates an GOCRON Matrix and generates a statistic report (written to matrixDebug.txt)
The matrix is feeded with a the sequence of gocronIndices. This sequence is gebnerated by the following steps:
- ocrons are cereated by using: createOcronSequenceFromIntegerSequence()
- gocrons are created by using: createGoedelSequenceFromOcron3Sequence()
	The created Gocron (goedel) Sequence will be written saved a ANSI Textfile (gocron03NNumbers.txt)
- take the index values of the gocrons from our previously generated coeTable (testnumbers here is the set of natural numbers):
	gocronIndexSequence[i] = gocronCodeIndices[testNumbers[i]].gocronCodeIndex
The end-of ocron symbol used here is '\n'. 
The suggested preprocessing type here is not 0, but 1, because gocrons / gocron-Indices are integers...
The created matrix will be be written to disk.
OTC: The successor evaluation (conversion from the read codeIndices to original numbers is not yet written!!!!!!!!
If 'generateOnlyGocronFile' = 1, the program can also be used to create and save only the Gocron Sequence with a specified filename 
and perform no other tasks
36_Ocron5Test01
OCRON (= Operator coded Representation Of Numbers). Test for a matrix with a single ID. 
OCRON Type 3,4, or 5 (5 operators: '2', '*', 'P', '^' and 'Q')
Creates an OCRON Matrix and generates a statistic report (written to matrixDebug.txt)
The Matrix is feeded with ocron5s created from the set of natural numbers
The end-of ocron symbol used here is '\n'
Reads also a specified number of successors ocrons from the matrix, which were displayed as numbers
(reconverted by (ocronToint())
The created Ocron Sequence will be written saved a ANSI Textfile (ocronNNumbers.txt)
The created matrix will be be written to disk.
If 'generateOnlyOcronFile' = 1, the program can also be used to create and save only the Ocron Sequence with a specified filename 
and perform no other tasks
37_Mersenne_Ocron5Test01
OCRON (= Operator coded Representation Of Numbers) Test for a matrix with a single ID. 
IDs 0,1,2 refer to the 3 Ocron types 3,4 and 5.
OCRON Type 05, 04, or 03 (3 operators: '2', '*' 'P', 'Q', '^')
Extensive test for Mersenne Prime search This test is performed for all three types of ocrons.
Creates an OCRON Matrix and generates a statistic report (written to matrixDebug.txt)
The Matrix is feeded with ocrons created from the set of Mersenne Primes. 
Ocrons are feeded without individually, without end of ocron symbols.
At first, 47 orcrons will be generated (without EOO symbol)
The created Ocron Sequence can also be written as a ANSI Textfile for debugging purposes
After creating and saving the matrix, or after reading the matrix, the evaluation begins:
The created matrix will be be written to disk.
The successor test will be performed for a big number of ocrons (typically 1000000 - 100000000)
Only hits of primenumbers (ocrons which represent a valid prime number are counting for the loop)
prime numbers (read from the matrix( abore the last mersenne number are output to console and/or matrixDebug.txt).
these are possible candidats for new mersenne numbers
// The whole test will be performed for a series of skill descending skill levels (from startlevel down toend levl) and Ocron types
A prime counting array 'primeCountArray[]' will be filled with the number of hits for the ith prime number
// the number of hits in the primeCountArray will also be evaluated for all three types of Ocrons.
38_OcronDegeneration
OCRON (= Operator coded Representation Of Numbers) Test for a matrix with a single ID. 
OCRON Type 3,4, 5 (operators: '2', '*','P', '^', and 'Q')
Creates an OCRON degeneration level Matrix and generates a statistic report (written to matrixDebug.txt)
For each number (ocron), the degeneration level and all degeneration ocrons will be printed to matrixDebug.txt
The Matrix is feeded with the degeneration levels ov the ocrons created from the set of natural numbers
Reads also a specified number of successer ocrons from the matrix, which were displayed as numbers
The created Ocron Sequence (incl. degeneration levels) can also be written as a ANSI Textfile for debugging purposes
The created matrix will be be written to disk.
39_OcronDegenerationMinimum
The same as example 38 but only number of degenerations for each number (=degen. level) will be printed.

40_OcronDegenerationConversionRules (matrixMedium and matrixFull)
Example 40: OCRON (= Operator coded Representation Of Numbers) Test for a matrix with a single ID. 
OCRON Type 3,4, 5 (operators: '2', '*','P', '^', and 'Q')
Creates an OCRON Matrix with ocron conversion rules and generates a statistic report (written to matrixDebug.txt)
The Matrix is feeded with all double combinations of degenerated ocrons belonging to a unique number
Each pair contains two ocrons which represent a simplyfying rule. Simplyfying rule means, that the converted
rule is not longer than the original rule.
Two sub matrices are created: one with conversion rules including rules for length of converted ocrons up to to original length
one for rules for length of converted ocrons less than original ocrons.
the ocron matrix can be created or the matrix can be read from disk.
numbers a increased from 1 up to <N>
The created matrix will be be written to disk.
41_OcronConversionTest  (matrixFull)
Example 41: reads data from a matrix containing ocron Conversion rules (generated by example 40).
The conversion rules are expectes to be found in two sub matrices: 
0 all rules, 1: only true simplyfying (= result ocron shorter than original ocron)
The convesion test is applied to ocron addition and ocron multiplication. It is clear that multiplication
gives always a valid ocron (resultOcron = <ocron1><ocron2>* )
For addition we consider the term  
2<resultOcron>^ = 2<ocron1>^2<ocron2>^*
and hope, that the term 2<ocron1>^2<ocron2>^* can be converted/simplyfied to 2<resultOcron>^
In the case of addition of 1 we consider: 2<ocron1>^2* 
The program asks for two numbers or two ocrons.
The result is displayed as ocron and number. A message will be diplayed if no result is found (in case of addition)
or if no conversion rule was found in the matrix.
42_VirtualOcronDegeneration  (matrixMedium)
Example 42: Test with virtual Ocrons (only consisting from '2', 'P', and '^', evaluated by embracing with ('2xxxxxx^'))
It turns our that some numbers cannot be expressed by virtual ocrons (e.g. 13 and multiples of 13)

5.3. Anwendungsgebiet Musikstücke (vorliegend im MIDI oder KERN Format)
------------------------------------------------------------------------------------------------------------------------
Einmal mit einem Musikstück oder einer ganzen Reihe von Musikstücken (vorzugsweise der gleichen Stilrichtung) gefüttert, kann die Matrix beliebig lange Musik spielen, die ähnlich klingt, wie die Musikstücke, mit denen sie gefüttert worden ist. (Hinweis: Die aktuelle Matrix-Version hat eine Takterkennung eingebaut und speichert die analysierten Regeln in getrennten Untermatrizen, die zur jeweiligen Taktart gehören. Genauer noch: Die Matrix kann auch trennen nach Instrument, Polyphonie (und somit für jedes Instrument eine eigene Matrix anlegen) sowie nach Stilrichtung. Im allgemeinsten Fall wird beim Füttern von Musikstücken eine ganze Reihe von Untermatrizen angelegt, in denen nur die Regeln, die zu einem bestimmten Satz von Takt, Instrument und Musikstilrichtung passen, so dass keine Vermischung von Daten passieren kann. Die Erkennung von Takt, Polyphonie und Instrument geschieht automatisch, der Musik-Stil kann jedoch (noch) nicht automatisch erkannt werden, sondern muss beim Füttern der Matrix mitgeteilt werden, so dass es nicht sinnvoll ist, die Matrix auf einmal mit MIDI Dateien verschiedener Stilrichtungen zu füttern.
Auch hier kann beim Lesen (in diesem Fall beim Abspielen) aus der Matrix der Intelligenz-Level eingestellt werden, so dass die erklingende Musik mehr oder wenig nahe am Original-Material liegt. Mann kann auch während des Abspielens den Intelligenz Level verstellen, so dass mehr 'Überaschungseffekte' entstehen. 
In den Beispielen kann das 'Abspielen' nur in Form des Schreibens einer Midi-Datei geschehen, da wegen der gewollten Einfachheit der Beispiele auf zu viel Overhead verzichtet wurde. Für die Implementierung eines MIDI Players, der aus der Matrix liest stehen jedoch geeignete Methoden (readMidiObjexFromMatrix() und readObjectFromMatrix()) zur Verfügung.

01_FeedNewMatrixWithMidiFilesWriteNoMatrixWriteOutputMidiFile
Zeigt, wie das Füttern der Matrix mit MIDI Daten geht (in diesem Fall mit einer Midi Datei). Die aus der Matrix gelesenen Midi Objekte (besser: die aus der Matrix abgespielte Musik) werden in eine Midi Datei gespeichert. Die erzeugte Midi Datei trägt den Dateinamen ‚matrixID<N>.mid’ (wobei <N> für die ID der Untermatrix steht, die ausgewählt wurde. Eine Matrix Datei wird in diesem Beispiel nicht erzeugt.
02_ReadExistingMatrixWriteNoMatrixWriteOutputMidiFile
(wie Beispiel 01, jedoch wird nicht gefüttert, sondern eine bereits existierende Matrix gelesen und hergenommen.
03_FeedNewMatrixWithMidiFilesWriteMatrix
(wie Beispiel 01, jedoch wird die generierte Matrix auf Platte gespeichert).
11_FeedNewMatrixWithKernFilesWriteMatrix_PreProc1004
hier wird die Matrix auf einmal mit über 200 KERN Files (in diesem Fall deutschen Kinderliedern aus einer Bibliothek der Stanford University) gefüttert. Das Ergebnis ist eine Vielzahl von Untermatrizen (da die Lieder viele verschiedene Taktarten enthalten).
Die Matrix wird nur abgespeichert, es werden keine Daten aus der Matrix gelesen. Als PreProcessing Type wird
KHPreProcessingTypeMidiGMQuadruple_NDMTS verwendet. Diese Einstellung ist für diese Art von Musik überdimensioniert, da weder polyphones Material noch unterschiedliche Instrumente vorliegen. Die Software erkennt dies und stuft den PreProcessingtype und den MatrixType automatisch zurück. (Meldung 'downgrading' falls debug level auf mind. 1 gestellt wurde). 
12_FeedNewMatrixWithKernFilesWriteMatrix_PreProc1003
wie Beispiel 11, jedoch mit PreProcessingType KHPreProcessingTypeMidiTriple_NDMT
13_FeedNewMatrixWithKernFilesWriteMatrix_PreProc1002
wie Beispiel 11, jedoch mit PreProcessingType KHMatrixTypeMIDINoteAndQuanta
14_FeedNewMatrixWithKernFilesWriteMatrix_PreProc_1
wie Beispiel 11, jedoch mit PreProcessingType 1 (= Differenzen 1.ter Ordnung)
15_ReadExistingKernMatrixWriteNoMatrixWriteOutputMidiFile
liest eine Kern Matrix Datei, liest aus einer der Untermatrizen dieser Matrix und schreibt eine Midi Datei. Die erzeugte Midi Datei trägt den Dateinamen matrixID<N>.mid (wobei <N> für die ID der Untermatrix steht, die ausgewählt wurde.
16_FeedNewMatrixWithKernFilesWriteMatrix_PreProc1003
liest eine polyphone Kern Datei mit mehreren Spuren (in diesem Fall das Brandenburgische Konzert' Nr. 2. in F-Dur)
Es wird eine MIDI Datei mit polyphonen Inhalt, jedoch nur für ein Instrument erzeugt.
Wegen des gewählten PreProcessing-Typs kann die MIDI Datei nur mit einem Instrument abgespielt werden (am Besten mit Klavier). 
17_FeedNewMatrixWithKernFilesWriteMatrix_PreProc1003
liest eine polyphone Kern Datei mit mehreren Spuren (in diesem Fall das Brandenburgische Konzert' Nr. 2. in F-Dur)
Es wird eine MIDI Datei mit polyphonen Inhalt und unterschiedlichen Sounds erzeugt. Da es nicht möglich ist aus KERN Files einen eindeutigen Sound (also eine GM Program change Nummer) zu extrahieren, muss dieses MIDI File vor dem Abspielen nachbearbeitet  (d.h. alle Spuren mit geeigneten Sounds versehen) werden. Die unbearbeiteten Sound IDs aus den Kern Files sind einfach die Track Nummern.

Natürlich kann die Matrix auch mit Musikstücken aus anderen Musik-Formaten gefüttert werden. Dazu ist jedoch ein bischen mehr Aufwand nötig und es muss mehr auf die Low-Level Routinen der Matrix zurückgegriffen werden.

5.4. Anwendungsgebiet: Nur Lesen und Schreiben von Matrix Elementen
--------------------------------------------------------------------------------------------------------------------
Für diese Anwendung wird man wohl die Basic Version der Matrix hernehmen, obwohl es prinzipiell auch mit der Medium und der Full-Version geht.
18_RandomReadWriteTest01IntegerCoordDimension1
Zeigt wie einzelne Elemente gelesen und geschrieben werden. Die Werte des Index-Vectors dürfen nicht größer als der Wert MAXMATRIXINDEX (500000) sein. Nur Random-Schreib und Lesetest.
Nach dem Schreiben wird ein ausführlicher Konsistenz Check der Matrix durchgeführt.
19_RandomReadWriteTest01IntegerCoordDimension1
Zeigt wie einzelne Elemente gelesen und geschrieben werden. Die Werte des Index-Vectors dürfen nicht groeßer als der Wert 
MAXMATRIXINDEX (500000) sein. Außer Lese- und Schreib-Operationen werden auch Delete-Operationen durchgeführt (ca. 20 Prozent aller Elemente werden wieder gelöscht).
Nach dem Schreiben und Löschen wird ein ausführlicher Konsistenz Check der Matrix durchgeführt.
20_RandomReadWriteTest01LargeIntegerCoordDimension1
(wie Beispiel 20) jedoch entfällt die Beschränkung der Koordinaten-Indizes auf den Wert MAXMATRIXINDEX (500000).
Die Indices dürfen hier beliebig groß (d.h. 2^32 -1) sein. 
21_RandomReadWriteTest01VeryLargeIntegerCoordDimension1
(wie Beispiel 20) jedoch entfällt die Beschränkung der Koordinaten-Indizes auf den Wert MAXMATRIXINDEX (500000).
Die Indices dürfen hier beliebig groß (genauer:. 2^64 -1) sein.
22_RandomReadWriteTest01IntegerCoordDimension1
(wie Beispiel 18, jedoch wird in mehrere Matrizen gleichzeitig geschrieben). Dies ist der ultimative Lese/Schreib/Lösch-Test für die Matrix.

6. 	Wie groß ist der Rechenaufwand und der Speicherbedarf?
==================================================
Das Füttern der Matrix geht sehr langsam. Das Lesen aus der Matrix geht unübertroffen schnell. Anders als bei Hash-Methoden (Stichwort 'ValueForKey') ist ein schneller Zugriff in beide Richtungen möglich. Schneller Zugriff beim Lesen bedeutet, dass die Anzahl der Operationen ungefähr proportional zur Dimension ist, und keinerlei Such Algorithmen angeworfen werden müssen.
Der Speicherbedarf in der aktuellen Version ist allerdings noch enorm, da bisher in dieser Richtung noch nicht optimiert wurde.
Beim Füttern mit einem Kapitel Text, ist man schnell bei ca. 1 GB RAM temporärem Speicherbedarf (der reduziert sich jedoch wieder typischerweise auf 10 bis 15 Prozent wenn man die sogenannten 'überdeterminierten Regeln' aus der Matrix entfernt).
Beim Abspeichern werden die Daten der Matrix nach einer Art ‚Run-Length’-Kodierung komprimiert, so dass der Speicherbedarf auf der Platte erträglich bleibt.

7. 	Wie wird eine Matrix erzeugt und initialisiert?
=========================================
mit createAndInitMatrix() oder createAndInitMatrixWithDebugParameters()
(oder den ensprechenden Versionen createAndInitMediumMatrix() und createAndBasicMatrix für die anderen Matrix Modelle. Die Parameterwerte und Eigenschaften einer leeren Matrix (die mit create...() erzeugt wurde) sind durch Default-Werte vorbesetzt. In den meisten Fällen müssen jedoch einige Eigenschaften anders besetzt werden. Dafür gibt es eine Reihe von Methoden, die alle mit setGlobalDefaultMatrixPropertiesFor... oder mit setDefaultMatrixPropertiesFor... 
beginnen. Bsp.: setGlobalDefaultMatrixPropertiesForMIDIElementsTriple_NDMT() oder setGlobalDefaultMatrixPropertiesForANSIText().
Damit werden alle Matrix Parameter auf die am besten geeigneten Werte gesetzt. Individuelle Anpassungen können dann immer noch mit einzelnen set..() und setGlobal..() Methoden gemacht werden.
Der Unterschied zwischen den set..() und den setGlobal..() Methoden besteht darin, dass die einfachen set-Methoden auf die Matrix mit der aktuellen Matrix-ID wirken (die können dann benutzt werden, wenn klar ist daß nicht automatisch mehrere Untermatrizen während des 'Fütterns' erzeugt werden, oder wenn dem User immer klar ist, um welcher Untermatrix er es zu tun hat), die setGlobal-Methoden jedoch erst greifen, wenn applyGlobalSettings() aufgerufen wird.
Manche 'Fütter-Methoden' (z. Bsp updateMatrixWithANSIFiles() oder updateMatrixWithMIDIFiles() legen jedoch bei Bedarf neue Untermatrizen an, die dann jeweils mit den Werten aus den setGlobal..() Methoden belegt werden.
WICHTIG: Die Anzahl der möglichen Untermatrizen muss ganz am Anfang gesetzt werden (mit setMaxNumberOfMatrices()) und kann danach (genauer nach dem ersten Schreibvorgang) nicht mehr verändert werden. Vor dem Füttern sollte man sich ungefähr darüber im Klaren sein, wieviele Untermatrizen etwa benötigt werden. 

8. 	Wie wird die Matrix gefüttert?
==============================
Vor dem Füttern kann die maximale Sequenzlänge (= max. Regellänge) begrenzt werden. Lange Sequenzen erhöhen die Rechenzeit und den Speicherbedarf quadratisch: Dies geschieht mit setGlobalMaxPhraseLengthForUpdateWithSequence()oder setMaxPhraseLengthForUpdateWithSequence()

Beim Füttern der Matrix ist es sinnvoll die Daten vor dem Füttern einem 'Preprocessing' zu unterziehen. Dies geschieht mit der Funktion setPreProcessingType()
Es sind verschiedenene Preprocessing-Types fest eingebaut. 

Für Text-Matrizen (KHMatrixTypeANSIText):
-------------------------------------------------------------------------
0 					(kein preProcessing)
KHPreProcessingTypeANSI		hier wird der Text vor dem Füttern gefiltert und optimiert (zu viele LFs entfernt ...)

Für Zahlen-Matrizen (KHMatrixTypeIntegerSeries):
--------------------------------------------
0 bis 999. 0 bedeutet kein Preprocessing. Eine Zahl <n>zwischen 1 und 999 bedeutet, daß aus einer Folge die Differenzenfolge <n>-ter Ordnung gebildet wird..

Für MIDI-Matrizen
---------------------------
Hinweis: Es gibt insgesamt 3 verschiedene Matrix-Typen für MIDI Daten, die in unterschiedlicher Differenziertheit den Zustand eines MIDI-Musikstückes representieren können:
MIDI MatrixTypen:
KHMatrixTypeMIDINoteAndQuanta (einfachster Fall: Wir werten nur NoteON und quanta- time aus)
KHMatrixTypeMIDITriple_NDMT (wir werten NoteOn und duration, d.h. die Notenlänge) aus
KHMatrixTypeMIDIGMQuadruple_NDMTS 
(wir werten  NoteOn und NoteOff, d.h. die Notenlänge, und den dazugehörigen Sound aus)

Für MIDI-Daten gibt es deshalb eine ganze Reihe von Preprocessing Typen:
MIDI PreProcessing Typen:
0:	(ist möglich, aber nicht zu empfehlen, da die absoluten Tonhöhen bei Meldien keine Rolle spielen sollten)
1:	Differenzen 1.ter Ordnung (es werden die Zeitdiffernzen und die Tonnummern Differenzen von Midinoten gebildet).
(nur begrenzt sinnvoll, da mit dieser Codierung der Taktbezug nicht verarbeitet werden kann)
2-999:	Ist wohl möglich, jedoch noch nie getestet worden.
KHPreProcessingTypeMidiDiffAndModTime: es werden die Differenzen 1. Ordnung der Notenwerte genommen. Der Zeitwert wird aus dem Modulus der quanta Values (Clock-Ticks) in Bezug auf die Taktgrenzen genommen. Damit haben wir Taktbezug.
Hinweis: nur geeignet für monophone Melodien, da keine Information über  Notendauern vorliegt.
KHPreProcessingTypeMidiTriple_NDMT: es werden die Differenzen 1. Ordnung der Notenwerte genommen. Der Zeitwert wird aus dem Modulus der quanta Values (Clock-Ticks) in Bezug auf die Taktgrenzen genommen. Damit haben wir Taktbezug.
Zusätzlich haben wir eine Notendauer. Geeignet für polyphones Material von einem Instrument.
KHPreProcessingTypeMidiGMQuadruple_NDMTS: es werden die Differenzen 1. Ordnung der Notenwerte genommen. Der Zeitwert wird aus dem Modulus der quanta Values (MIDI-Ticks) in Bezug auf die Taktgrenzen genommen. Damit haben wir Taktbezug. Eine SoundID aus 16 verschiedenen typischen Instrumenten klassen wird zusätzlich ausgewertet.
Dieser PreProcessingType ist zu empfehlen für polyphone Musikstücke mit unterschiedlicher Instrumentierung.

Das Füttern einer MIDI-Matrix geschieht entweder mit MIDI Dateien oder Kern (Musik-Format der Stanford University) Dateien.
Bei Midi Dateien wird angenommen, dass es sich um GM-MIDI Dateien handelt (z. Bsp. mit standardmäßigem channel 10 für Drums) 
Kern Dateien haben den Nachteil dass sich aus den Instrumenten angaben keine eindeutigen MIDI Sounds zuordnen lassen. Sie haben jedoch den Vorteil von Phrasierungs-Informationen, so dass eine zukünftige Matrix Version auch bei MIDI Material auf eine höhere Symbol-Ebene gehen kann...

9.	Wie wird aus der Matrix gelesen?
=================================
High Level Routinen: z. Bsp. mit readMidiObjexsAndWriteToMidiFile() oder readAnsiObjexsAndWriteToAnsiFile().
Low Level Routinen: readObjexFromMatrix(). Der Name ‚Objex’ kommt aus einer Verschmelzung von Object und Index. Normalerweise ist ein Index eine einfache Zahl. Die Matrix erlaubt jedoch die Eigenschaften eines Objektes mit mehr als nur einer Zahl darzustellen. Da die Objekteigenschaften als ‚key’ benutzt werden (das sind sozusagen die Koordinaten, mit denen in die Matrix 'hineingelangt' wird, ist es intuitiv naheliegend von einem Objex zu sprechen (einen Objekt, dessen Eigenschaften durch die Indices, mit denen die Matrix angesprochen wird, definiert wird). Man könnte hier auch von verallgemeinerten Koordinaten sprechen.
Etwas verwirrend ist am Anfang evtl. die Tatsache, das readObjex..() nicht etwa einen Zahlenwert oder ähnliches aus der Matrix liest sondern eher einen Zustandsvektor, der aus Matrix-Indices besteht.
Informationstheoretisch könnte man sagen, dass die Zustandsinformationen, die in der Matrix gespeichert sind, sozusagen nicht digital sind sondern eher 'analog'. Da die Information ja nicht als Zahlenwert an irgend einer Speicheradresse gespeichert wird, sondern die Information liegt ja gerade in den Indices, also in den Abstanden (= analog) zwischen den einzelnen Elementen.
(Zurücklehnen, genießen und wirken lassen :-)) 

Die aus der Matrix gelesenen Objekte können mit den oben genannten Routinen abgespeichert werden.
Midi Dateien werden immer als ‚single-track’ Midi Files abgespeichert. Bei polyphonem Material mit mehreren Instrumenten, kann jedoch diese Spur mit einem Sequencer-Programm problemlos wieder in einzelne Instrumenten-Tracks zerlegt werden.
Der aktuelle System-Zustand der Matrix wird in der sogenannten KernelSequence gehalten. Wird vor dem Lesen der Matrix die KernelSequence mit einem oder mehreren Anfangswerten initialisiert, dann wird beim Lesen mit diesem Anfangswerten begonnen.
Wird die Kernelsequence vor dem Lesen nicht initialisiert, so wird mit einem wahrscheinlichstem Anfangswert begonnen.
Hinweis: Die Kernelsequence aktualisiert sich bei jedem Lesevorgang automatisch selbst und enthält so immer den aktuellsten Zustand.
Hinweis: Bei bestimmten Parameter Kombinationen kann es sein, dass die Lesesequenz in einem Loop 'hängen bleibt' und sich periodisch wiederholt und nicht mehr aus diesem loop herauskommt. Wann dieser Fall eintritt, lässt sich im Voraus nicht sagen, aber er ist umso unwahrscheinlicher, je größer die Matrix ist und je höher der eingestellte Intelligenz Level ist. Das Benutzen der 'Successor-Method' 1 (immer der exakt wahrscheinlichste Nachfolgerwert wird hergenommen) begünstigt auch das Auftreten solcher 'Hänge-Loops'.
Am Besten wird immer die SuccessorMethod 3 benutzt.
Um das Zurückrechnen der mit dem enstrechenden PreProcessingType bearbeiteten Daten muss man sich nicht kümmern. Für jeden Preprocessing-Typ gibt es eine 'inverse' Methode, die automatisch beim Lesen aus der Matrix aufgerufen wird. Hinweis: Die Matrix selbst enthält nur Regeln für 'preProcessed' Daten.
Wichtig beim Lesen (sollte vor dem Lesen oder währen des Lesens gesetzt werden) noch:

SetSkillOutputLevel(level)

Teilt der Matrix mit, wie intelligent sei beim Lesen sein soll. Werte für level: 1  bis max. benutze Sequenzlänge.

10. 	Wie kann man die Matrix debuggen?
====================================
In dem man den Debug-Level auf mindestens 1 oder höher stellt. Bei Debug level 0 werden nur Fehlermeldungen auf das Output Device ausgegeben. Je höher der Debug Level (max. 9), um so mehr Informationen werden auf das Output Device ausgegeben.
Bei debug level -1 wird gar nichts ausgegeben.
Ausserdem existiert ein Malloc-Debugger, der mit dem setzen eines #defines in KHMatrixDefines.h aktiviert werden kann.

11.	Wie kann man einen Progress Bar realisieren?
===========================================
in dem man eine eigene ProgressDisplayFunction schreibt und diese dann mit setMatrixProgressDisplayFunction() 
bekannt gibt. (Callback Funktion)
Leider ist in der Matrix diese Funktion nur als statische Funktion realisiert und nicht an die Klasse gebunden. Das sollte noch geändert werden.

12. 	Wie kommt man an die statistischen Eigenschaften der Matrix?
========================================================
Mit printMatrixOverallInfo(). Wichtig: Manche (statistische) Eigenschaften werden erst gesetzt, wenn ein performMatrixLinearTest() oder performMatrixConistencyTest() gemacht wird.

13. 	Welche Dateiformate können gelesen bzw. geschrieben werden?
==========================================================
Lesen: 	Matrix-Dateien (*.phr), 
Input-Dateien, mit denen die Matrix 'gefüttert' wird: Midi-Dateien (*.mid), Kern-Dateien (*.krn), Test-Dateien (*.txt)
Schreiben: Matrix-Dateien (*.phr), 
Output-Dateien in Verbindung mit ANSI/MIDI Read-Methoden: Midi-Dateien (*.mid), Text-Dateien (*.txt)

14. 	Wie erzeugt die Matrix Objekte einer Sequenz wenn eine mehrdeutige Regel? auftaucht?
========================================================================
Es wird ein wahrscheinlichster Wert (der dennoch zufällig sein kann, siehe ‚successor method’ unten) genommen. Die Ergebnisse sind dennoch reproduzierbar, da die Matrix für jede Unter-Matrix einen eigenen Zufallsgenerator verwendet).

15. 	Was bedeuten die in den Beispielen benutzen Methoden und Funktionen im Einzelnen?
=========================================================================

Grundsätzlich gilt: viele Set-Methoden können nur für eine leere Matrix aufgerufen werden, da sonst eine inkonsistente Matrix entstehen würde.

void myProgressDisplayFunction(KHProgressCallBackData *progessData):
Eine vom Anwender geschrieben CallBack Funktion, die als Fortschrittsanzeige dient. ProgressData zeigt auf eine Struktur, die Informationen darüber enthält, was gerade passiert sowie über den prozentualen Anteil des abgelaufenen Prozesses.

statische Create und Delete Funktionen:
setMatrixProgressDisplayFunction(myProgressDisplayFunction):
Gibt der Matrix die Progress-Funktion bekannt und bewirkt, dass diese als Callback Funktion aufgerufen wird.

createAndInitMatrixWithDebugParameters(debugDevice,debugLevel,debugDirectory):
Erzeugt eine leere Matrix.
Erlaubte Werte für debugDevice: 0 (kein device), 1: Nur Console, 2: Nur in Debug-Datei "matrixDebug.txt", 3: Beides (1+2)
debugLevel: -1 (keine Meldungen), 0: Nur Fehler-Meldungen, 1-9: Warnings und sonstige Meldungen
debugDirectory: Verzeichnis, in dem die Debug-Datei erstellt wird.
Hinweis: Die Debug-Datei wird nicht gelöscht. Bei jedem neuen Aufruf werden die Meldungen an eine bereits existierende Datei angehängt. Sie sollte deshalb von Zeit zu Zeit gelöscht werden.

createAndInitMatrixMediumWithDebugParameters()
wie createAndInitMatrixWithDebugParameters,  jedoch für das Medium Matrix Modell.

createAndInitMatrixBaseWithDebugParameters()
wie createAndInitMatrixWithDebugParameters,  jedoch für das Base Matrix Modell.

Hinweis: Eine Matrix kann auch mit den Routinen :
createAndInitMatrix() createAndInitMatrixMedium() sowie createAndInitMatrixBase()
erzeugt werden. Dann gelten die in KHMatrixDefines.h gesetzten Defaultwerte für debugDevice, debugLevel, debugDirectory.
Die können auch nachträglich noch mit den entsprechenden Set-Methoden gesetzt werden.

createAndInitMatrixWithFile(fileName, debugLevel)
Erzeugt eine Matrix mit Hilfe einer Matrixdatei. Die Parameter sind klar.

Hinweis: Auch hier gibt es für die Matrix-Modelle die entsprechenden Routinen:
createAndInitMatrixMediumWithFile(..) sowie createAndInitMatrixBaseWithFile(..)

deleteMatrix(matrix),deleteMatrixMedium(matrix),deleteMatrixBase(matrix):
Loescht die angegebene Matrix und gibt allen Speicherplatz wieder frei. 

Methoden, die am Anfang aufgerufen werden sollten (oder solange eine Matrix noch leer ist):

setMaxNumberOfMatrices():
Setzt die maximale Anzahl von Untermatrizen. Da Untermatrizen bei Bedarf automatisch erzeugt werden können, ist dieser Wert am Anfang genügend hoch zu setzen.
Wenn nicht gesetzt gilt ein Defaultwert von 2 Matrizen

setAllowLargeIndices():
Setzt einen Wert (0, 1 oder 2) der angibt, ob große oder auch sehr große (64 Bit) Indices erlaubt sind. Ist im Moment nur in Verbindung mit dem Matrix Modell 'Basic' möglich. 

setCoordinateDimension():
Setzt die Coordinaten-Dimension (d.h. die Anzahl von Werten mit denen ein Zustand beschrieben wird)

Methoden, die ein ganzes Template für einen bestimmten Matrix Type erzeugen:

setGlobalDefaultMatrixPropertiesForANSIText();
Erzeugt einen optimierten Satz von Matrix-Parametern für die 'Fütterung' der Matrix mit ANSI Text. Dieser Satz von Parametern wird dann angewendet, wenn eine (Unter)Matrix erstmals mit Daten gefüttert wird oder wenn eine neue Unter Matrix bei Bedarf angelegt wird.

setGlobalDefaultMatrixPropertiesForSymbols():
wie vorherige Funktion, jedoch für Symbol Matrizen
setGlobalDefaultMatrixPropertiesForMIDIElementsCDim2NoteNumberAndQuanta():
wie vorherige Funktion, jedoch für Matrix Typ KHMatrixTypeMIDINoteAndQuanta und preProcessing type 1
setGlobalDefaultMatrixPropertiesForMIDIElementsCDim2NoteNumberAndModQuanta():
wie vorherig jedoch für Matrix Typ KHMatrixTypeMIDINoteAndQuanta und preProcessing-type KHPreProcessingTypeMidiDiffAndModTime
setGlobalDefaultMatrixPropertiesForMIDIElementsTriple_NDMT()
wie vorherig jedoch für Matrix Typ KHMatrixTypeMIDITriple_NDMT und preProcessing-type KHPreProcessingTypeMidiTriple_NDMT
setGlobalDefaultMatrixPropertiesForMIDIElementsGMQuadruple_NDMTS()
wie vorherig jedoch für Matrix Typ KHMatrixTypeMIDIGMQuadruple_NDMTS und preProcessing type KHPreProcessingTypeMidiGMQuadruple_NDMTS
setGlobalDefaultMatrixPropertiesForIntegerSeries():
wie vorherige Funktion, jedoch für Matrix Typ KHMatrixTypeIntegerSeries

Hinweis: Die entsprechenden Methoden 'setDefaultMatrixProperties...(), also ohne 'Global' wirken unmittelbar auf die aktuelle Matrix.
die Methode applyGlobalMatrixProperties() bewirkt, dass alle Einstellungen, die mit globalen Set-Methoden gemacht wurden, auf die aktuelle Matrix angewendet werden.

Methoden, beim Füttern mit ANSI Text:

setGlobalUsePhrasesForUpdateMatrixWithLongANSIText() und setUsePhrasesForUpdateMatrixWithLongANSIText():
Bewirkt, dass beim Füttern mit ANSI Text nicht der ganze Text auf einmal gefüttert wird, sondern jeweils satzweise. Dies hat Einfluss auf die Beendigungswahrscheinlichkeiten der Matrix, da jeweils beim Ende eines Textes eine Beendigungswahrscheinlichkeit des entsprechenden Matrixelementes mit beeinflusst wird (im Detail: es wird der counter 'writeCountWithoutSuccessor' inkrementiert). Wenn diese Option eingeschaltet ist, werden keine Regeln erzeugt, die über Satzgrenzen hinweg führen. Trotzdem ist es wegen der Beendigungswahrscheinlichkeiten sinnvoll diese Option zu wählen zumal beim Benutzen der Symbolebene, die Beschränkung der Regeln auf Satzgrenzen wegfallen kann.
Hinweis: Die Beendigungswahrscheinlichkeiten können beim Lesen aus der Matrix wiederum benutzt werden oder auch ignoriert werden (enableStopItem, s. unten)
Hinweis: Beim Ausschalten dieser Option werden Beendigungswahrscheinlichkeiten nur ein einziges mal, nämlich am Ende der Gesamtsequenz gesetzt.
Hinweis: Darüber hinaus gilt, dass die Beeendigungswahrscheinlichkeiten auch nur dann verändert werden, wenn 'useEndOfSequence' (s. unten) gesetzt ist.

setGlobalUseStartOfSequence() und setUseStartOfSequence()
Das Pendant zu den Beendigungs-Wahrscheinlichkeiten und zu setUseEndOfSequence: Am Anfang einer 'FütterSequenz' wird die Start-Wahrscheinlichkeit (die Erzeugung 'ex nihilo') einer Sequenz verändert.   (Im Detail: es wird der counter 'writeCountWithoutPredecessor' incrementiert). 
Hinweis: Die Startwahrscheinlichkeiten können beim Lesen aus der Matrix wiederum benutzt werden oder auch ignoriert werden (siehe restartWithTrueStartItem(), s. unten)

setGlobalUseEndOfSequence() und setUseEndOfSequence()
Das Pendant zu den Start-Wahrscheinlichkeiten und zu setUseStartOfSequence: Am Ende einer 'FütterSequenz' wird die Beendigungs-Wahrscheinlichkeit einer Sequenz verändert.   (Im Detail: es wird der counter 'writeCountWithoutSuccessor' incrementiert). 
Hinweis: Die Beendigungswahrscheinlichkeiten können beim Lesen aus der Matrix wiederum benutzt werden oder auch ignoriert werden (setEnableStopItem), s. unten)

setGlobalLanguage() und setLanguage()
damit wird einer (leeren) Matrix eine Sprach-ID zugeordnet.

Sonstige Methoden:

saveMatrixToDisk(fileName)
Speichert die Matrix (inklusive aller Untermatrizen) unter dem angegebenen Dateinamen ab.

setGlobalMaxPhraseLengthForUpdateWithSequence() oder setMaxPhraseLengthForUpdateWithSequence():
Beschränkt die maximal mögliche Regellängen auf diesen Wert. Default ist 64.

setGlobalNameOfUpdateFile() und setNameOfUpdateFile()
(Nur zu Dokumentations- und statistischen Zwecken): Setzt den Namen einer evtl. vorhandenen Datei aus der die Matrix gefüttert wurde.

setMatrixDescription()
(Nur zu Dokumentations- und statistischen Zwecken): Eine Beschreibung der Matrix wird mit übernommen.

setMatrixAILevel(level) 
Im Moment sind nur Levels 0 und 1 erlaubt. Bei 1 wird beim 'Füttern eine zusätzliche Symbol-Matrix angelegt. 

showBasicProperties()
Gibt eine tabellarische Übersicht aller aktuell vorhandenen Unter-Matrizen aus mit den wichtigsten Eigenschaften. ( Sieht in jedem Matrix-Modell etwas anders aus). Im Matrix-Modell Full bedeuten:
Spalte 1: (ID) matrixID (klar)
Spalte 2: (typ) matrix Typ (0=undefined, 1=MIDI (2 Werte), 2=Integer oder Symbol, 3=ANSI Text, 4=MIDI (3 Werte), 5=MIDI (4 Werte)
Spalte 2: (lng) matrix language: 0=undefined,1=German,2=English,3=French,4=Spanish
Spalte 3: (cDim) coordDimension: Werte > 0
Spalte 4: (msTyp) midiSubType: 	0=undefined, 1=monophon, 2=polyphon, 3=percussion, 4=multiChannel
Spalte 5: (signat) time signature (z. Bsp 4/4, 6/8, 3/4 usw.)
Spalte 6: (pProc) PreProcessing Type ( zur Erklärung der verschiedenen Typen, s. oben)
Spalte 7: (phrLen) PhraseLength: Beim letzten 'Füttern' verwendetete maximale Sequenzlänge)
Spalte 8: (count) Anzahl von geschriebenen Matrix-Elementen (normalerweise identisch mit Anzahl der Regeln in der Matrix)
Spalte 9:(Ovdet) 1: removeOverdeterminedElements() wurde aufgerufen, 0: wurde nicht aufgerufen: Matrix ist noch überdeterminiert
Spalte 11:(mStl) (music-Style). Hinweis Eine Liste von StyleIDS ist noch nicht definiert worden.
Spalte 11:(sID) (SoundID). 

Im Moment sind folgende 16 SoundIDs definiert:
	KHMatrixSoundIDUndefined =0,
	KHMatrixSoundIDPiano,
	KHMatrixSoundIDChromaticPercussion,
	KHMatrixSoundIDOrgans,
	KHMatrixSoundIDGuitars,
	KHMatrixSoundIDBass,
	KHMatrixSoundIDSoloStrings,
	KHMatrixSoundIDStrings,
	KHMatrixSoundIDBrass,
	KHMatrixSoundIDDrum = 9, // GM-Drums, channel 10
	KHMatrixSoundIDReed,
	KHMatrixSoundIDFlute,
	KHMatrixSoundIDSynthLead,
	KHMatrixSoundIDSynthPad,
	KHMatrixSoundIDPercussion,	// not used in matrix
	KHMatrixSoundIDEffect		// not used in matrix

Im Moment sind folgende musicStyleIDs definiert (diese Liste wird noch erheblich erweitert werden)
	KHMatrixMusicStyleUndefined =0,
	KHMatrixMusicStyleRock,
	KHMatrixMusicStylePop,
	KHMatrixMusicStyleJazz,
	KHMatrixMusicStyleClassic

setCurrentMatrixID(matrixID)
Setzt die MatrixID und wählt somit eine der vorhandenen Untermatrizen als die aktuelle Matrix aus.

(int) perform1stMemoryTest(type,&numberOfWriteElementsInMatrix, &numberOfEndElementsInMatrix,trim)
Führt einen ausführlichen Konsistenzcheck der Matrix durch. Wenn type = 1, wird eine 'linearer' Test durchgeführt, bei Type = 2 ein rekursiver Test.
Zurückgegeben wird ein Return-Code, der angibt, ob der Test erfolgreich war (>0 erfolgreich, <= 0 Fehler)
Die beiden anderen Rückgabe-Parameter sind klar.
Bei einem linearen Test wird die Matrix sozusagen physikalisch von vorn bis hinten (also linear) Element für Element durchsucht und auf Konsistenz geprüft.
Bei einem rekursiven Test werden alle möglichen Indizes in allen Dimensionen von einem Minimal- bis zu einem Maximalwert durchlaufen und auf Konsistenz überprüft.
Der rekursive Test kann bei höher dimensionalen Matrizen sehr lange dauern.

removeOverDeterminedElements()
Entfernt alle 'überdeterminierten' (somit überflüssigen Regeln) aus der Matrix. Die Matrix schrumpft damit typischerweise auf 10 bis 15 Prozent der ursprünglichen Größe.
Sollte unbedingt dann aufgerufen werden, wenn klar ist, dass mit dieser Matrix keine weiteren updates ('Fütterungsvorgänge') stattfinden werden, oder wenn die Matrix aufgrund ihrer Größe unhandlich wird. Das Lesen aus einer überdeterminierten Matrix sollte eigentlich die gleichen Ergebnisse liefern wie das Lesen aus der Matrix, bei der die überdeterminierten Regeln entfernt wurden. Letzte Tests, die das definitiv beweisen, wurden jedoch noch nicht durchgeführt. Wer sicher gehen möchte, sollte eine Matrix, solange sie noch geupdatet werden soll, möglichst lange im 'überdeterminierten' Status belassen.

dbPrintSuccessorObjex(*successorObjex)
Gibt alle Eigenschaften eines Objexs (z, Bsp. MIDI Objekt) in passender Weise auf die Console aus.
Ist die aktuelle Matrix eine Symbolmatrix wird automatisch vor der Ausgabe das Symbol in eine Sequenz von Basic-Level-Elementen umgewandelt.

Methoden zum 'Füttern der Matrix (high level):
updateMatrixWithANSIFiles(nameOfAnsiUpdateFileOrDirectory,recurseIntoSubDirectories,&numberOfMatrixItems)
updateMatrixWithANSIFile(nameOfAnsiUpdateFile)
nameof...: (klar), wenn recurseIntoSubDirecectories = 1 werden rekursiv auch alle enthaltenen Unterverzeichnisse durchsucht und alle gefundenen ANSI Files (Endung '.txt') mit ausgewertet.

updateMatrixWithMIDIFiles(nameOfAnsiUpdateFileOrDirectory,recurseIntoSubDirectories,&numberOfMatrixItems)
updateMatrixWithMIDIFile(nameOfAnsiUpdateFile)
wie vorherig, jedoch für MIDI Dateien

updateMatrixWithKERNFiles(nameOfAnsiUpdateFileOrDirectory,recurseIntoSubDirectories,&numberOfMatrixItems)
updateMatrixWithKERNFile(nameOfAnsiUpdateFile)
wie vorherig, jedoch für KERN Dateien

Für das Füttern mit MIDI oder KERN Files ist noch wichtig:
setGlobalMidiTrackAnalyze(ctrl)
ctrl = 0: Füttert die Matrix individuell mit jedem einzelnen Track 
ctrl = 1: Füttert die Matrix nur mit einem ‚MixDown-Track’ aus allen Spuren, 
ctrl = 2: Macht beides (0  und 1)

Methoden zum 'Füttern der Matrix (low level):
int updateMatrixWithSequence(matrixType, preProcessingType, *sequence, numberOfSequenceItems);
int updateMatrixWithCombinedSequence(*originalSequence, numberOfOriginalSequenceItems,...) 
int updateMatrixWith2DimSequence(matrixType,preProcessingType,….);
int updateMatrixWithLongMIDISequence(* sequence, numberOfItems,…);
int updateMatrixWithLongINTSequenceExt(*sequence, numberOfTestItems, matrixType, coordDimension, preProcessingType, allowLargeIndices);
int updateMatrixWithLongINTSequence(* testSequence, numberOfTestItems);
int updateMatrixWithLongANSISequence(* testSequence, numberOfTestItems);
int updateMatrixWithCombinedSequenceDebug(...)

Methoden zum Lesen aus der Matrix: (high Level)

Vor dem LeseVorgang kann die Kernelsequenz initialisiert werden:
initializeKernelSequenceWithOriginalSequence(*indexVector, lengthOfIndexVector, overwriteInitialSequence)
Die Parameter im Einzelnen bedeuten:
Index-Vector: Vektor mit den Indizes (‚Flat’-Version, d.h. z. Bsp bei coordinateDimension 4 ist lengthOfIndexVector 4 mal so groß wie die Anzahl der Initialisierungsobjekte)
OverwriteInitialSequence sollte beim allerersten mal 1 sein. Wird öfter initializeKernelSequenceWithOriginalSequence aufgerufen, so kann es sein, dass man nur die 'preProcessed' Kernelsequence initialisieren möchte, nicht jedoch die originale KernelSequence. Dann sollte man overwriteInitialSequence = 0 wählen.
Hinweis: Kann beim Lesen aus der Matrix kein Nachfolger bestimmt werden, so gibt es einen 'reset' der KernelSequence. Der Parameter 'restartWithTrueStartItem' widerum bestimmt wie in einem solchen reset verfahren werden soll: Soll einfach ein wahrscheinlichstes Nachfolgerobjekt oder ein 'true' Start Objekt hergenommen werden? Bei einem 'restartWithTrueStartItem' ist es entscheidend, wie die originale KernelSequenz aussieht...
Man muss das alles nicht vollständig verstehen, um mit der Matrix zu arbeiten, für den Anfang genügt es, einfach wie in den Beispielen zu verfahren...
Hinweis: Die Initialisierung der Kernelsequenz kann auch entfallen. Dann wird die Lesesequenz einfach mit dem wahrscheinlichstem Objekt begonnen.

int readAnsiObjexsAndWriteToAnsiFile(numberOfAnsiObjects, *ansiFileName)
Liest die angegebene Anzahl von ANSI Characters aus der Matrix und schreibt diesen Text anschließend in die Datei mit dem angegebenen Namen.

int readMidiObjexsAndWriteToMidiFile(numberOfMidiObjects, char *midiFileName);
Liest die angegebene Anzahl von Midi Objekten aus der Matrix und schreibt diese anschließend in eine Midi-Datei mit dem angegebenen Namen.

Wichtig beim Lesen sind noch:
setSucessorMethod(successorMethod)
method = 1: Es wird immer der wahrscheinlichste Nachfolger genommen ( liefert immer das gleiche Ergebnis)
method = 2: (Fehlerhaft, nicht nehmen!)
method = 3: Es wird mit Hilfe der entsprechenden Wahrscheinlichkeitsverteilung ein (mit dieser Verteilung gewichteter) Zufallswert genommen.
Empfehlung Methode 3.
Die Methode 3 liefert keine zufällige Werte. Da die Matrix für jede Untermatrix einen eigenen Zufallsgenerator besitzt, sind jedoch auch diese Werte reproduzierbar und liefern auf jedem Betriebssystem die gleichen, reproduzierbaren Ergebnisse.

Wichtig beim Lesen (sollte vor dem Lesen oder währen des Lesens gesetzt werden) noch:

SetSkillOutputLevel(level)

Methoden zum Lesen aus der Matrix: (low Level)

int *getFirstOriginalObjectItemFromMatrix(updateKernelSequence, successorMethod, *probability, *stopProbability)
int *getNextOriginalObjectItemFromMatrix(updateKernelSequence, successorMethod, *probability, *stopProbability)
int *readObjexFromMatrix(*probability, *stopProbability)

Hier nochmal alle wichtigen Methoden der (Fulltype) Matrix:

int  getAddUpdateInfo(void);
	holt ein Flag das bestimmt, ob nach dem 'Füttern' ein UpdateInfo angehängt werden soll:
(der Matrix kann ein sogenanntes updateInfo hinzugefügt werden. Damit kann im Nachhinein nachfolzogen werden, mit welchen Daten ein Matrix Update durchgeführt wurde (nur zu statistischen u. Dokumentationszwecken)
void setAddUpdateInfo(int addUpdateInfo);
Ein Flag ( 0 oder 1) das bestimmt, ob nach dem 'Füttern' ein UpdateInfo angehängt werden soll:
int getAllowLargeIndices(void); (s. oben)
setAllowLargeIndices(int allowLargeIndices); (s. oben)
int getCoordinateDimension(void);
void setCoordinateDimension(int coordinateDimension);  
int getCurrentMatrixID(void);
void setCurrentMatrixID(int matrixID);
int getCurrentMatrixIDLevelDown(void);
// holt die MatrixID der SymbolMatrix, die zu der aktuellenMatrix gehört; (= -1 falls keine Symbol Matrix existiert)
void setCurrentMatrixIDLevelDown(int levelDownID);
int getCurrentMatrixIDLevelUp(void);
// holt die Matrix ID der basi level Matrix, die zu der aktuellen (Symbol)-Matrix gehört.
void setCurrentMatrixIDLevelUp(int levelUpID);
int getIsPhraseMatrix(void);
void setIsPhraseMatrix(int isPhraseMatrix);
int  getKeepSymbolsWhenRemoveOverdeterminedElements(void);
void setKeepSymbolsWhenRemoveOverdeterminedElements(int keepSymbolsWhenRemoveOverdeterminedElements);
int getMatrixAILevel(void);
void setMatrixAILevel(int matrixAILevel);
int  getMatrixBlockSize(void);
char *getMatrixDescription(void);
void setMatrixDescription(char * description);
int getMatrixType(void); 
void setMatrixType(int matrixType); 
int getMaximalMatrixIndex(void); 
void setMaximalMatrixIndex(int maximalMatrixIndex);
// ist normalerweise auf 500000 begrenzt. Kann hiermit erhöht werden. VORSICHT: Kann den Speicherbedarf beträchtlich erhähen	
int getMaxPhraseLengthForUpdateWithSequence(void);
void setMaxPhraseLengthForUpdateWithSequence(int maxLength);
int getMemorySearchMethod(void);
void setMemorySearchMethod(int searchMethod); 
// die searchMethod steuert, wie beim Matrix Beschreiben freier, geeigneter  Speicherplatz gefunden wird
// searchmethod 0-3, 0: schnell aber verschwenderisch mit Speicher, ... sehr effizient mit Speicher, jedoch sehr langsam:
char *getNameOfUpdateFile(void);
void setNameOfUpdateFile(char * nameOfUpdateFile);
int getNumberOfMatrices(void);
void setNumberOfMatrices(int numberOfMatrices);
int getMaxNumberOfMatrices(void);
void setMaxNumberOfMatrices(int maxNumberOfMatrices);
int getNumberOfMatrixElements(void);
int getNumberOfMatrixWriteEvents(void);
int getNumberOfMatrixDeleteEvents(void);
int getNumberOfWriteCounts(void);
int  getNumberOfWriteElements(void);
int getPreProcessingType(void);
void setPreProcessingType(int preProcessingType);
long long getUserRandomValue(void);
void setUserRandomValue(long long randomSeedValue); 
int getUserRandomType(void); 
void setUserRandomType(int randomType);
int  getRestartWithTrueStartItem(void);
void setRestartWithTrueStartItem(int restartWithTrueStartItem);
int  getSkillOutputLevel(void);
void setSkillOutputLevel(int skillOutputLevel);
int getUseEndOfSequence(void);
void setUseEndOfSequence(int useEndOfSequence);
int getUseStartOfSequence(void);
void setUseStartOfSequence(int useStartOfSequence);
int getUsePhrasesForUpdateMatrixWithLongANSIText(void);
void setUsePhrasesForUpdateMatrixWithLongANSIText(int useStartOfSequence);
// Debug und Test
int perform1stMemoryTest(int kindOfTest, int *numberOfWriteElementsInMatrix, int *numberOfEndElementsInMatrix, int trimMatrix);
void showBasicProperties();
int performMatrixLinearTest(int *numberOfWriteElementsInMatrix, int *numberOfEndElementsInMatrix, int trim);
void printMatrixOverallInfo(void);
void setMatrixDebugOutputDevice(int outputDevice);
void setMatrixDebugDirectory(char * debugDirectory);
void dbPrintSuccessorObjex(int *successorObjex, int opt);
// Sonstige
void setInitialMatrixBlocksize(int blocksize);
// Lesen/Schreiben von einzelnen Elementen
int existMatrixData(int *indexVector, int lengthOfIndexVector); 
int existMatrixData32(int *indexVector, int lengthOfIndexVector);
long long  readMatrixData(int *indexVector, int lengthOfIndexVector, int *returnCode, int *writeCount, int *writeCountWithSuccessor, int *writeCountWithoutPredecessor);
long long  readMatrixData32(int *indexVector, int lengthOfIndexVector, int *returnCode, int *writeCount, int *writeCountWithSuccessor, int *writeCountWithoutPredecessor);
int writeMatrixElement(int *indexVector, int lengthOfIndexVector, long long value); 
int writeMatrixElement32(int *indexVector, int lengthOfIndexVector, long long value); 
long long readMatrixElement(int *indexVector, int lengthOfIndexVector, int *returnCode);
long long readMatrixElement32(int *indexVector, int lengthOfIndexVector, int *returnCode);
int deleteMatrixElement(int* indexVector, int lengthOfIndexVector, int deleteControl); 
int deleteMatrixElement32(int* indexVector, int lengthOfIndexVector, int deleteControl);
	/////////////////// Fuettern der Matrix 
int updateMatrixWithMIDIFile(char *nameOfUpdateFile, int *numberOfSequenceItems);
int updateMatrixWithMIDIFiles(char *nameOfDirectoryOrUpdateFile, int recurseIntoSubdirectories, int *numberOfTotalSequenceItems);
int updateMatrixWithKERNFile(char *nameOfUpdateFile, int *numberOfSequenceItems);
int updateMatrixWithKERNFiles(char *nameOfDirectoryOrUpdateFile, int recurseIntoSubdirectories, int *numberOfTotalSequenceItems);
int updateMatrixWithANSIFile(char *nameOfUpdateFile, int *numberOfSequenceItems); 
int updateMatrixWithANSIFiles(char *nameOfDirectoryOrUpdateFile, int recurseIntoSubdirectories, int *numberOfTotalSequenceItems); 
int updateMatrixWithLongINTSequence(int * testSequence, int numberOfTestItems); 
int updateMatrixWithLongINTSequenceExt(int * sequence, int numberOfSequenceItems,int matrixType,int coordDimension,int preProcessingType,int allowLargeIndices); //KHMatrixMedium, KHMatrix
int updateMatrixWithLongANSISequence(int * sequence, int numberOfSequenceItems);
int updateMatrixWithLongMIDISequence(int * testSequence, int numberOfTestItems, int *symbolMarkers); 
int removeOverDeterminedElements(void);
int removeLongElements(int maxLengthOfElement);
/////////////////// Fuettern der Matrix (second level):
int updateMatrixFromBasicLevel(int *sequence, int numberOfSequenceItems);
/////////////////// Successor-Methoden :
int getEnableStopItem(void);
void setEnableStopItem(int enableStopItem);
int getSuccessorMethod(void);
void setSucessorMethod(int successorMethod);
int initializeKernelSequenceWithOriginalSequence(int *indexVector, int lengthOfIndexVector, int overwriteInitialSequence);
int *readObjexFromMatrix(double *probability, double *stopProbability);
int readMidiObjexsAndWriteToMidiFile(int numberOfMidiObjects, char *midiFileName);
int readAnsiObjexsAndWriteToAnsiFile(int numberOfAnsiObjects, char *ansiFileName);
/ returns a flat indexvector with length : coordDimension*numberofElements
int *createPreviousLevelElementsFromOriginalSymbol(int symbol, int *numberOfElements); 
int **createPreviousLevelObjexsFromOriginalSymbol(int symbol, int *numberOfObjexs); 
/////////////////// Archivierung :
int saveMatrixToDisk(char *fileName); // if updateInfo = 1, info about the update will be appended at the end of the matrix file
///////////////////////////////////////////
// Set Matrix properties with a set of parameters (template)
void setDefaultMatrixPropertiesForSymbols(char *nameOfUpdateFile);
void setDefaultMatrixPropertiesForMIDIElementsCDim2NoteNumberAndQuanta(char *nameOfUpdateFile);
void setDefaultMatrixPropertiesForMIDIElementsCDim2NoteNumberAndModQuanta(char *nameOfUpdateFile);
void setDefaultMatrixPropertiesForANSIText(char *nameOfUpdateFile);
void setDefaultMatrixPropertiesForIntegerSeries(char *nameOfUpdateFile);
void setGlobalDefaultMatrixPropertiesForSymbols(void);
void setGlobalDefaultMatrixPropertiesForMIDIElementsCDim2NoteNumberAndQuanta(void);
void setGlobalDefaultMatrixPropertiesForMIDIElementsCDim2NoteNumberAndModQuanta(void);
void setGlobalDefaultMatrixPropertiesForMIDIElementsTriple_NDMT(void);
void setGlobalDefaultMatrixPropertiesForMIDIElementsGMQuadruple_NDMTS(void);

void setGlobalDefaultMatrixPropertiesForANSIText(void);
void setGlobalSymbolDefaultMatrixPropertiesForSymbols(void);
void setGlobalDefaultMatrixPropertiesForIntegerSeries(void);
////////////////////////////////////// set / get methods for individual, global parameters: 
void setGlobalKeepSymbolsWhenRemoveOverdeterminedElements(int keepSymbolsWhenRemoveOverdeterminedElements);
///////////////////////////////////////////////////////////////////////////////
void setGlobalIsPhraseMatrix(int isPhraseMatrix);
void setGlobalPreProcessingType(int preProcessingType);
void setGlobalNameOfUpdateFile(char *nameOfUpdateFile);
void setGlobalMaxPhraseLengthForUpdateWithSequence(int maxPhraseLengthForUpdateWithSequence);
void setGlobalSymbolMaxPhraseLengthForUpdateWithSequence(int maxPhraseLengthForUpdateWithSequence);
void setGlobalUseStartOfSequence(int useStartOfSequence);
void setGlobalSymbolUseStartOfSequence(int useStartOfSequence);
void setGlobalUseEndOfSequence(int useEndOfSequence);
void setGlobalSymbolUseEndOfSequence(int useStartOfSequence);
void setGlobalUsePhrasesForUpdateMatrixWithLongANSIText(int usePhrasesForUpdateMatrixWithLongANSIText);
void setGlobalSkillOutputLevel(int skillOutputLevel);
void setGlobalSuccessorMethod(int successorMethod);
void setGlobalRestartWithTrueStartItem(int restartWithTrueStartItem);
void setGlobalEnableStopItem(int enableStopItem);
void setGlobalIncludeOverdeterminedRules(int includeOverdeterminedRules);
void setGlobalAddUpdateInfo(int addUpdateInfo);
void setGlobalMidiTimeSignatureNom(int midiTimeSignatureNom);
void setGlobalMidiTimeSignatureDenom(int midiTimeSignatureDenom);
void setGlobalLanguage(int language);
void setGlobalMidiSubType(int midiSubType);
void setGlobalMidiSoundID(int midiSoundID);
void setGlobalMidiNoteOnQuantization(int noteOnQuantization);
void setGlobalMidiDurationQuantization(int durationQuantization);
void setGlobalMidiTrackAnalyze(int midiTrackAnalyze);
void setGlobalMusicStyle(int musicStyle);
///////////////////////////////////////////////////////////////////////////////
void setGlobalMatrixType(int matrixType );
void setGlobalAllowLargeIndices(int allowLargeIndices);
void setGlobalCoordinateDimension(int coordinateDimension);
void setGlobalMemorySearchMethod(int memorySearchMethod);

// Apply global paramaters to durrent matrix: 
void applyGlobalMatrixProperties(void);