WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

MEX - Matlab stürzt ab, Matrix zu groß?

 

Wusel Dusel
Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 21.02.11
Wohnort: Münchner Umland
Version: R2009B
     Beitrag Verfasst am: 21.02.2011, 11:54     Titel: MEX - Matlab stürzt ab, Matrix zu groß?
  Antworten mit Zitat      
Hallo Forum,

Ich möchte eine .txt Datei einlesen. Da dies mit Matlab zu lange dauert bzw. Matlab bei langen .txt Datein sich aufhängt, wollte ich das mit einer .c Datei machen, welche ich über mex aufrufe. Das klappt soweit auch ganz gut, allerdings nur bis zu einer Matrizengröße von 10000x32. Es geht um das einlesen von GPS-Satellitendaten, daher soll zu jeder Epoche (Zeitpunkt) für jeden der 32 Satelliten der aktuelle Wert in die Matrix geschrieben werden. Wie gesagt klappt das auch bis ca. 10.000 Epochen wunderbar, aber dann meldet Matlab einen Fehler ("Matlab funktionert nicht mehr"). Meine Vermutung ist, dass die ausgebebene Matrix "ausmatrix" bzw. dann in Matlab "SAT" für Matlab zu groß ist. SAT hat auch eine viel zu hohe Prezession, mir würden auch 4 Nachkommastellen vollkommen genügen, aber ich schaffs nicht, diese herunterzustellen. Wie ihr an meiner Beschreibung wahrscheinlich schon erraten habt, kenn ich mich auch nicht wirklich gut aus, darum wär ich für jede Hilfe äußerst dankbar, bin am verzweifeln. Google konnte leider auch nicht helfen.
Die Funktion rufe ich mit :

[T_SAMP MJL_START n SAT]=readteqc(file);

auf. Es geht mir um SAT, die eben genannte Matzix ist. Mein c-Code ist unten.

Vielen Dank und schöne Grüße
Maxi
Code:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "mex.h"

FILE *fIn;

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    char *FileName;
    char GetString[200], test[20];
    int   l=1, FileNameLength, epochs, satnum, i,  k, j;
    float T_SAMP,  START_TIME;
    double data[]={0},  ausmatrix[10000][32]={0}, datenmatrix[10000][16]={0}, satmatrix[10000][16]={0};
   
    mxArray *mlDouble;
   
    FileNameLength = (mxGetM(prhs[0])*mxGetN(prhs[0]))+1;
    FileName =(char *)mxCalloc(FileNameLength, sizeof(char));
    mxGetString(prhs[0], FileName, FileNameLength);
    /* Try to open file. */
   
    fIn = fopen(FileName, "r");
    if (fIn==NULL)
        mexErrMsgTxt("Could not open file.");
   
    /* Check for valid RINEX file.*/
   
    fgets(GetString, 82, fIn);
   
    if(strstr(GetString, "COMPACT") == 0) {
        printf("\n%s", GetString);
        mexErrMsgTxt("Invalid TEQC-Format.");
    }
    /* Header einlesen */
    while (l=1) {
       
        fgets(GetString, 200, fIn);
        if(GetString[0]==84)   /*wenn mit T startet*/
        { sscanf(GetString, "%s %f", test, &T_SAMP);
        /*  printf("%f \n", T_SAMP);    */}
        if(GetString[1]==84)   /*wenn mit T startet*/
        { sscanf(GetString, "%s %f", test, &START_TIME);
       /*   printf("%f \n", START_TIME);  * /
          /*  Look for the 2st 'T' in 'END OF HEADER' */
          break;}
    }
    /* Output T_SAMP.*/
    data[0]=T_SAMP;
    mlDouble = mxCreateDoubleMatrix(1, 1, mxREAL);
    memcpy(mxGetPr(mlDouble), data, sizeof(data));
    plhs[0]=mlDouble;
   
    data[0]=START_TIME;
    mlDouble = mxCreateDoubleMatrix(1, 1, mxREAL);
    memcpy(mxGetPr(mlDouble), data, sizeof(data));
    plhs[1]=mlDouble;
   
    /* Daten einlesen */
    epochs=0;
   /* printf("\n%s", GetString);*/
   
    while (fgets(GetString, 200, fIn)) {
        sscanf(GetString, "%i", &satnum);
       
        for(i=0;i<satnum;i++)
        { satmatrix[epochs][i]=atoi(&GetString[3*(1+i)]);
           /*  printf(" %i\n", satmatrix[i][epochs]);*/}
        fgets(GetString, 200, fIn);
       
        for(i=0;i<satnum;i++)
        {   datenmatrix[epochs][i]=atof(&GetString[10*i]);}
             /* printf("%f\n", datenmatrix[i][epochs]);*/
       
        epochs++;
    }
   
    fclose(fIn);
    /* ausgabemetrix schreiben*/
    for (k=0;k<epochs;k++)
    {  j=0;
       for (i=1;i<=32;i++)
        {if (satmatrix[k][j]==i)
         {ausmatrix[k][i-1]=datenmatrix[k][j];
          j++;
         }
        }
    }
     
    data[0]=epochs;
    mlDouble = mxCreateDoubleMatrix(1, 1, mxREAL);
    memcpy(mxGetPr(mlDouble), data, sizeof(data));
    plhs[2]=mlDouble;
  /*  
    mlDouble = mxCreateDoubleMatrix(16,epochs, mxREAL);
    memcpy(mxGetPr(mlDouble), satmatrix, epochs*16*sizeof(double));
    plhs[3]=mlDouble;
 
    mlDouble = mxCreateDoubleMatrix(16,epochs, mxREAL);
    memcpy(mxGetPr(mlDouble), datenmatrix, epochs*16*sizeof(double));
    plhs[4]=mlDouble;
   */
    mlDouble = mxCreateDoubleMatrix(32,10000,mxREAL);
    memcpy(mxGetPr(mlDouble), ausmatrix, 32*10000*sizeof(double));
    plhs[3]=mlDouble;
}
[/code]
Private Nachricht senden Benutzer-Profile anzeigen


Berlin

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 21.02.2011, 12:18     Titel:
  Antworten mit Zitat      
Rechne doch einfach die Daten in Integerwerte um.
Also die Ausgabe- Matrix als Integer deklarieren und die Werte einfach mit 10000 multiplizieren.

Berlin
 
Wusel Dusel
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 21.02.11
Wohnort: Münchner Umland
Version: R2009B
     Beitrag Verfasst am: 21.02.2011, 14:07     Titel:
  Antworten mit Zitat      
Hi Berlin,
Vielen Dank für deine Antwort. Habs probiert, Matlab bricht aber immer noch bei über 10.000 ab. Evtl. hab ich aber auch was falsch gemacht: Ich hab
Code:
{ausmatrix[k][i-1]=datenmatrix[k][j];

zu
Code:
{ausmatrix[k][i-1]=(int)(datenmatrix[k][j]*10000);


geändert und aus matrix als int deklariert
Code:
( int  ausmatrix[10000][32]={0} ),
. Ich hätt die Matrix dann in matlab wieder durch 10000 geteilt.

Hab auch unten bei der Ausgabe mit
Code:
memcpy(mxGetPr(mlDouble), ausmatrix, 32*10000*sizeof(double));

zu
Code:
   memcpy(mxGetPr(mlDouble), ausmatrix, 10000*32*sizeof(int));


geändert bzw. alle möglichen Kombinationen ausprobiert, aber im Ergebnis bliebs das gleiche. Ich versteh auch nicht wirklich,was da geschieht, ich hab mir das mehr aus nem anderen ähnlichen Einlesecode mit try& error zusammengebastelt, daher bitte nicht wundern, wenn ich da saublöde Fehler mach.
Vielen Dank nochmal
Maxi
Private Nachricht senden Benutzer-Profile anzeigen
 
Wusel Dusel
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 21.02.11
Wohnort: Münchner Umland
Version: R2009B
     Beitrag Verfasst am: 24.02.2011, 16:14     Titel:
  Antworten mit Zitat      
Servus
Ich hab jetzt weiter rumprobiert, auch mit mxCreateNumericMatrix, nur int ausgeben usw. aber es lief alles immer darauf hinaus, dass für ausmatrix 32x18000 noch funktioniert , eine 32x 19000 Matrix aber nicht mehr. Hat irgend jemand eine Idee, an was das liegen und wie ich das umgehen könnte. Im Anhang ist der c-file sowie eine Beispieldatei, die es einzulesen gilt. aufgerufen wird das mit:
Code:
[t_samp,mjl,epochen,MATRIX]=readteqc('hangar10.txt');

(zuerst mex teqcread.c nicht vergessen)

Wäre wirklich über JEDEN Tip dankbar

Viele Grüße Maxi

Kleiner Nachtrag: ich hab jetzt alle Matrizen als int definiert und übergebe an Matlab int32, dadurch konnte die Matrizen Größe auf ca. 12x35000 gesteigert werden. Dieser Code ist jetz im Anhang

readteqc.c
 Beschreibung:

Download
 Dateiname:  readteqc.c
 Dateigröße:  3.16 KB
 Heruntergeladen:  517 mal
hangar10.txt
 Beschreibung:

Download
 Dateiname:  hangar10.txt
 Dateigröße:  2.1 MB
 Heruntergeladen:  485 mal
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 25.02.2011, 15:26     Titel:
  Antworten mit Zitat      
Hallo Wusel Dusel,

Gibt es eine Fehlermeldung? Wen ja, welche genau? Wenn nein, in welcher Zeile stürzt die C-Funktion ab?
Du kannst einfach ein paar mexPrintf-Befehle einstreuen und nach der letzten Message suchen, die vor dem Absturz ins Command-Window geschrieben wird.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Wusel Dusel
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 21.02.11
Wohnort: Münchner Umland
Version: R2009B
     Beitrag Verfasst am: 25.02.2011, 15:48     Titel:
  Antworten mit Zitat      
Hi Jan,
Danke für deinen Post. Leider gibt er keine Fehlermeldung mehr aus, nur ein neues Fenster öffnet sich mit" Matlab funktioniert nicht mehr" (unter Windows 7) bzw. Matlab wird einfach geschlossen (unter XP). Dementsprechend gibt er leider auch keine printf-Sachen mehr aus.
Die Größe der Matrix scheint auch nicht Versions oder PC-abhängig zu sein, da ich es auf nem anderen PC probiert hab mit WinXP und Matlab R2008b und es überall bis 12x37000 geht, 12x 38000 geht aber nicht mehr.
Gibts den noch ne "Zwischenstufe" zwischen int32 und int16 da int32 eigentlich viel zu genau ist, aber int16 ein bisschen zu klein?

Grüße Maxi
Private Nachricht senden Benutzer-Profile anzeigen
 
Wusel Dusel
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 21.02.11
Wohnort: Münchner Umland
Version: R2009B
     Beitrag Verfasst am: 02.03.2011, 14:31     Titel:
  Antworten mit Zitat      
So ich hab's jetz mit nem anderen Compiler versucht (bisher wars der standard-compiler Lcc-win32 C 2.4.1 in C:\PROGRA~1\MATLAB\R2009b\sys\lcc). Hab den Microsoft Visual C++ 2008 Express in C:\Program Files\Microsoft Visual Studio 9.0 versucht. Er compilt auch brav aber dann bricht er BIS 37000 epochen ab ("Matlab funktioniert nicht mehr") und AB 38000 epochen bringt er den Fehler "Caught MathWorks::System::FatalException".

Jetzt fällt mir aber schön langsam nix mehr ein, was ich probieren könnt. Falls jemand nur ne leise Ahnung hat, womit das zusammenhängen könnte, wär ich extrem dankbar. Würde ihn auch bei den Danksagungen meiner Diplomarbeit erwähnen.

Viele Grüße und Kölle alaaf
Maxi
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 03.03.2011, 00:07     Titel:
  Antworten mit Zitat      
Hallo Wusel Dusel,

Dein Programm ist schwer zulesen. Kannst Du nochmal eine bereinigte Version posten, in denen z.B. die blockweise auskommentierten Zeilen weggelassen sind?
Oder auch dies liesse sich vereinfachen:
Code:
   data[0]=epochs;
    mlDouble = mxCreateDoubleMatrix(1, 1, mxREAL);
    memcpy(mxGetPr(mlDouble), data, sizeof(data));
    plhs[2]=mlDouble;

Einfacher:
Code:
plhs[2] = mxCreateDoubleScalar(epochs);

Wenn danach der Code übersichtlicher ist, wird das Fehlersuchen einfacher.

Es ist unbedingt nötig, dass Du heraus bekommst, in welcher Zeile das Programm abbricht. Wenn Du es per mexPrintf nicht schaffst, versuche in ein File zu schreiben. Das Wechseln des Datentyps wird wenig bringen, da ein solcher Crash einen echten Grund hat.

Gruß, Janh
Private Nachricht senden Benutzer-Profile anzeigen
 
Wusel Dusel
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 21.02.11
Wohnort: Münchner Umland
Version: R2009B
     Beitrag Verfasst am: 03.03.2011, 11:26     Titel:
  Antworten mit Zitat      
Hi Jan,
erstmal danke für deinen Tip mit der Vereinfachung. Ich hab den Code jetzt auf das nötigste reduziert (glaube ich wenigstens) und etwas auskommentiert.
Ich hab auch versucht, dass der .c-Code für jeden Schritt der while Schleife den Wert in eine .txt Datei schreibt. Funktioniert auch wieder wunderbar bis 37000, aber ab 38000 bricht er ab, ohne irgendwas hineinzuschreiben. Habe den .txt-Schreibbefehl auch mal ganz an den Anfang des Codes gesetzt, so dass er eine 1 in die .txt-Datei schreiben soll, auch dass fand nicht mehr statt (bei über 38000).
Ist es dann ein Problem der Initialisierung?

Vielen Dank nochmal und frohes Faschingstreiben
Maxi

Code:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "mex.h"

FILE *fIn;

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    char *FileName ;
    char GetString[200],test[20];
    int   l=1, FileNameLength, epochs=0, satnum, i,  k, j, satmatrix[37000][12]={0},   datenmatrix[37000][12]={0}, ausmatrix[37000][32]={0} ;
    float T_SAMP,  START_TIME, zwischen;
   
   
    mxArray *mlDouble;
   
    FileNameLength = (mxGetM(prhs[0])*mxGetN(prhs[0]))+1;
    FileName =(char *)mxCalloc(FileNameLength, sizeof(char));
    mxGetString(prhs[0], FileName, FileNameLength);
   
    /* open file */
    fIn = fopen(FileName, "r");
   
     /* HEADER einlesen */
    while (l=1) {                                        /*immer erfüllt*/
       
        fgets(GetString, 200, fIn);
        if(GetString[0]==84)                             /*wenn mit T startet*/
        { sscanf(GetString, "%s %f", test, &T_SAMP);}
       
        if(GetString[1]==84)                            /*wenn zweiter Buchstabe ein T ist*/
        { sscanf(GetString, "%s %f", test, &START_TIME);
          break;}                                       /*Header ist zu Ende, Schleife verlassen*/
    }
    /* Output T_SAMP und MJL*/
    plhs[0] = mxCreateDoubleScalar(T_SAMP);
   
    plhs[1] = mxCreateDoubleScalar(START_TIME);
   
    /* Daten einlesen */
    while (fgets(GetString, 200, fIn)) {
        sscanf(GetString, "%i", &satnum);                /*satnum ist die Numer des Satelliten*/
       
        for(i=0;i<satnum;i++)
        { satmatrix[epochs][i]=atoi(&GetString[3*(1+i)]);}
       
        fgets(GetString, 200, fIn);
       
        for(i=0;i<satnum;i++)
        { zwischen=atof(&GetString[10*i]);               /*zwischen ist ein Hilfskonstrukt, um die floats in Integers zu verwandeln*/
          datenmatrix[epochs][i]=(int)(zwischen*1000);}  /*im MATLAB code wird die Matrix dann wieder durch 1000 geteilt*/
        epochs++;                                        /*Anzahl der Epochen, also jede Zweite Zeile (Epoche=Messpunkt)*/
    }
   
    fclose(fIn);
   
    /* Ausgabematrix schreiben*/
                                                          /*mixt satmatrix und datenmatrix, so dass z.B. die Daten zu Satellit 16 in Zeile 16 stehen und satmatrix nicht mehr benötigt wird*/
    for (k=0;k<epochs;k++)
    {  j=0;
       for (i=1;i<=32;i++)
       {if (satmatrix[k][j]==i)
        {ausmatrix[k][i-1]=(datenmatrix[k][j]);
         j++;
        }}}
   
     /* Ausgabe*/
    plhs[2] = mxCreateDoubleScalar(epochs);
   
    mlDouble = mxCreateNumericMatrix(32, epochs, mxINT32_CLASS, mxREAL);
    memcpy(mxGetPr(mlDouble), ausmatrix, 32*epochs*sizeof(mxINT32_CLASS));
    plhs[3]=mlDouble;
}
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 03.03.2011, 13:31     Titel:
  Antworten mit Zitat      
Hallo Wusel Dusel,

Zitat:
Ich hab auch versucht, dass der .c-Code für jeden Schritt der while Schleife den Wert in eine .txt Datei schreibt.

Es gibt mehrere WHILE-Schleifen in Deinem Code. Könnte ich wissen, welche du meinst?
Bis 37000 läuft das Programm, bei 38000 läuft es nicht? Was passiert den bei 37001 bis 37999? Wenn Du das Problem lösen möchtest, wäre es sehr hilfreich, wenn Du die genau Zahl wüßtest. Das sind immerhin nur 10 Versuche, wenn Du das Intervall immer halbierst. Tritt das Problem vor dem Schrieben der Ausgabe-Matrix auf? Dann lasse doch auch die "* Ausgabematrix schreiben*/ " und "/* Ausgabe */ "-Teile zunächst mal weg. Reduziere Dein Programm so lange, bis wirklich nur noch die Zeilen übrig bleiben, die den Fehler produzieren. Du kannst auch probieren das File-Einlesen wegzulassen: nimm einfach immer den gleichen String. Wenn das auch nicht läuft, hat es schonmal nichts mit den FGETS-Zeilen zu tun.

Das gepostete Programm läuft natürlich nur bis 37000, da du ja am Anfang auch nur 37000 Zeilen reservierst. Ich rate zwar mal, dass Du das dann manuell im Code änderst, aber wissen kann ich das nicht. Es sieht auf jeden Fall so aus, als würdest Du in nicht-reservierten Speicher schreiben.

Ich habe nun alle Tricks verraten, die ich auch anwenden würde. Den Rest überlasse ich Dir oder anderen goMatlab'ern.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Wusel Dusel
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 21.02.11
Wohnort: Münchner Umland
Version: R2009B
     Beitrag Verfasst am: 03.03.2011, 17:33     Titel:
  Antworten mit Zitat      
Servus Jan

Äh ja, das mit den Programmteilen weglassen war eigenltich ziemlich naheliegend... da hab ich den Wald vor lauter Bäumen nicht gesehen. Also er bricht auch ab, wenn nur initialisiert wird und ansonsten gar nix mehr im code steht. Die genaue Zahl ist 37358, ab 37359 hängt er sich auf und du hast recht ich habs jedesmal im Code geändert.

Jetz weiß ich ja doch ziemlich genau wo der Fehler liegt und ich weiß, wie ich da beim nächsten mal bei solchen Problemen vorgehe.
Herzlichen Dank nochmal für deine Mühen

Maxi

Kleiner Nachtrag: Durch geschicktere Programmierung (spar mir satmatrix und datenmatrix) schaff ich's jetz immerhin auf ca. 65000 Epochen, is ja auch schon was.
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2025 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.