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-File: Eingabe auf "int" überprüfen

 

ThomasW.

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 03.07.2011, 10:42     Titel: mex-File: Eingabe auf "int" überprüfen
  Antworten mit Zitat      
Hallo!

Ich möchte gerne die Eingabe in mein mex-file auf den Typ "int" überprüfen. Es gibt ja einen Haufen Funktionen, die ähnliches tun, wie etwa "mxIsInt16" etc.
Woher weiß ich aber, ob ein ganz normaler int, den der Benutzer eingibt, ein 16-bit int mit Vorzeichen ist?

Ich möchte irgendwie alle ints abfangen Cool

Danke!


ThomasW.

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 03.07.2011, 11:44     Titel:
  Antworten mit Zitat      
Sorry. Muss noch ein bisschen mehr in diesem Zusammenhang fragen. Komme irgendwie nicht zurecht - mag an meinem fehlenden Verständnis liegen, was pointer angeht Sad

Ich möchte ein Programm schreiben, was ganz simpel die Primzahlen bis zur eingegebenen Zahl berechnet.

Dafür habe ich schon mal das hier gemacht:
Code:

#include "mex.h"

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
    int i;
    int *input;
    if(nrhs == 0){
        mexErrMsgTxt("Please specify a number");
    }
   
    /*check if input is an integer*/
   
   
    input = mxGetData(prhs[0]);
    /*find the prime numbers up to the given number*/
   //for(i = 0; i < *input; i++){
        mexPrintf("ist %i \n",*input);
   //}
}


Ausgabe ist 0.
Wenn ich mache: input = mxGetData(prhs); ist die Ausgabe irgendeine extrem hohe Zahl.
Verstehe den Unterschied nicht so recht. Was genau ist prhs[0]? Das ist doch das erste Element im Array. Brauche ich da überhaupt so etwas wie mxGetData?

Confused
Thomas
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 03.07.2011, 23:37     Titel: Re: mex-File: Eingabe auf "int" überprüfen
  Antworten mit Zitat      
Hallo ThomasW,

Zitat:
Ich möchte gerne die Eingabe in mein mex-file auf den Typ "int" überprüfen. Es gibt ja einen Haufen Funktionen, die ähnliches tun, wie etwa "mxIsInt16" etc.
Woher weiß ich aber, ob ein ganz normaler int, den der Benutzer eingibt, ein 16-bit int mit Vorzeichen ist?

Die Frage ist nicht klar. Bitte erkläre nochmal: Welche Zahl in welchem Format soll als Input akzeptiert werden?

Zur zweiten Frage: "prhs" ist der Vektor der Input-Argumente. Das erste Input-Argument "prhs[0]" ist ein Matlab-Array. Dieses Array enthält einen Header, in dem z.B. die Dimensionen, der Name, der Type etc. steht. Um an die eigentlichen Nutzdaten zu gelangen, benötigt man mxGetPr (für ein DOUBLE array) oder mxGetData (für alle anderen elementaren Typen, also nicht CELL oder STRUCT). mxGetData(phrs[0]) liefert also einen Zeiger auf das erste Daten-Element.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Titus
Forum-Meister

Forum-Meister


Beiträge: 871
Anmeldedatum: 19.07.07
Wohnort: Aachen
Version: ---
     Beitrag Verfasst am: 04.07.2011, 12:48     Titel:
  Antworten mit Zitat      
Hallo,

es könnte sein, dass hier zwei Sachen durcheinander gehen: wenn Du in MATLAB schreibst:
Code:
X = 42;
 

dann ist das zwar ein Integer (ganze Zahl) aber kein Integer (im Sinne des Datentyps). Der Datentyp ist immer noch double! Normalerweise ist das auch O.K. Explizit mit Integern arbeitest Du:
Code:

Dann kommt bei input auch ein int* und nicht, wenn die Funktion mit X aufgerufen wird, eigentlich ein double*.
Du könntest im Code z.B. prüfen:
Code:
if (input[0]!=double(floor(input[0]))) {
mexErrorMsg("Das war keine ganze Zahl ...");
}
 


Titus
Private Nachricht senden Benutzer-Profile anzeigen
 
ThomasW.

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 04.07.2011, 21:41     Titel:
  Antworten mit Zitat      
Hallo Jan!

Zitat:

Die Frage ist nicht klar. Bitte erkläre nochmal: Welche Zahl in welchem Format soll als Input akzeptiert werden?


Jede ganze Zahl.

Zitat:

Zur zweiten Frage: "prhs" ist der Vektor der Input-Argumente. Das erste Input-Argument "prhs[0]" ist ein Matlab-Array. Dieses Array enthält einen Header, in dem z.B. die Dimensionen, der Name, der Type etc. steht. Um an die eigentlichen Nutzdaten zu gelangen, benötigt man mxGetPr (für ein DOUBLE array) oder mxGetData (für alle anderen elementaren Typen, also nicht CELL oder STRUCT). mxGetData(phrs[0]) liefert also einen Zeiger auf das erste Daten-Element.


Ich habe es jetzt mit input = (int)(mxGetScalar(prhs[0])); geschafft das zu tun, was ich wollte.
Wenn ich dich richtig verstehe, sagst du, dass
input = (int)(mxGetPr(prhs[0]));
auch funktionieren sollte? Da komme ich genau so ans Datenfeld?

Hallo Titus!
Danke Dir, ich denke das löst mein Problem! Wink


Hall Alle Wink

Habe nun aber noch ein anderes Problem. Nehmen wir an, ich möchte alle ganzen Teiler der eingegebenen Zahl finden und diese als Vektor in MATLAB ausgeben. Ich finde nun jedes einzelne Element in einer For-Schleife. Wie krieg ich die in mein Ausgabearray rein? Habe gedacht ich könnte vielleicht mxCreateNumericArray verwenden. Allerdings weiß ich ja vorher nicht, wie viele Teiler ich finden werde und weiß daher nicht, wie lang mein Array werden soll. Was wäre hier die geschickteste Lösung?

Danke!
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 04.07.2011, 22:07     Titel:
  Antworten mit Zitat      
Hallo ThomasW,

Zitat:
Jede ganze Zahl.

Jede ganze positive reelle Zahl, wobei Inf und NaN ausgeschlossen ist? Dann ist das von Dir gewählte mxGetScalar richtig.

Zitat:
input = (int)(mxGetPr(prhs[0]));
auch funktionieren sollte?

Nein! Das funktioniert zwar für DOUBLEs ganz genauso. Aber wenn Du die Funktion mit einem SINGLE oder (u)INT8/16/32/64-Wert aufrufst, führt das entweder zu einem falschen (besser: unerwarteten) Ergebnis, oder die Mex-Funktion stürtzt ab und reißt die ganze Matlab-Session mit. mxGetScalar wandelt SINGLEs und die INTeger-Typen automatisch um.

Ich hoffe Du kennst das Sieb des Erastothenes, so dass Du nicht alle Zahlen zwischen 2 und SQRT(N) zum Teilbarkeitstest verwendest. Wenn Du im Vorhinein nicht weißt, wie groß das benötigte Array sein muss, gibt es zwei Möglichkeiten: Entweder der erzeugst ein Array, das die Maximal-Zahl der möglichen Resultate aufnimmt und kürzt es am Schluss. Oder Du benutzt ein Array, das mitwächst. Bei letzterem muss man mit großer Vorsicht arbeiten, da das Allozieren von Speicher extrem langsam sein kann. Einen Vektor also in jeder Iteration on ein Element anwachsen zu lassen ist dramatisch ineffizient. Wenn man das aber in tausender-Schritten macht, ist man schon weit besser dran.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
ThomasW.

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 04.07.2011, 22:48     Titel:
  Antworten mit Zitat      
Hallo Jan,

Zitat:

Nein! Das funktioniert zwar für DOUBLEs ganz genauso. Aber wenn Du die Funktion mit einem SINGLE oder (u)INT8/16/32/64-Wert aufrufst, führt das entweder zu einem falschen (besser: unerwarteten) Ergebnis, oder die Mex-Funktion stürtzt ab und reißt die ganze Matlab-Session mit. mxGetScalar wandelt SINGLEs und die INTeger-Typen automatisch um.


Du meinst das stürzt dann ab, weil ich kein SINGLE (was genau ist das eigentlich?) nach (int) casten kann? Oder was ist genau der Grund?


Zitat:

Ich hoffe Du kennst das Sieb des Erastothenes, so dass Du nicht alle Zahlen zwischen 2 und SQRT(N) zum Teilbarkeitstest verwendest. Wenn Du im Vorhinein nicht weißt, wie groß das benötigte Array sein muss, gibt es zwei Möglichkeiten: Entweder der erzeugst ein Array, das die Maximal-Zahl der möglichen Resultate aufnimmt und kürzt es am Schluss. Oder Du benutzt ein Array, das mitwächst. Bei letzterem muss man mit großer Vorsicht arbeiten, da das Allozieren von Speicher extrem langsam sein kann. Einen Vektor also in jeder Iteration on ein Element anwachsen zu lassen ist dramatisch ineffizient. Wenn man das aber in tausender-Schritten macht, ist man schon weit besser dran.


Es geht mir nicht um die Effizienz des Algorithmus an sich, sondern schon eher um eine effiziente Implementierung des primitiven Algorithmus um die Teiler zu finden.

Ich habe jetzt soetwas hier versucht:
Code:

int i;
int counter = 0;

for(i=1;i <=eingabe;i++){
    if((eingabe % i) == 0){
        plhs[counter] = mxCreateDoubleScalar(i);
        counter++;
    }
}
 


Das funktioniert allerdings nicht. Irgendwas ist an der Art und Weise, wie ich versuche Output ins plhs Array zu schreiben, falsch....
 
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.