/* get the value of the item input */
items = mxGetScalar(prhs[0]);
/* get the value of the item input */
capacity = mxGetScalar(prhs[1]);
/* create a pointer to the real data in the profit matrix */
ProfitMatrix = mxGetPr(prhs[2]);
/* get dimensions of the profit matrix */
ncolsprofit = mxGetN(prhs[2]);
nrowsprofit = mxGetM(prhs[2]);
/* create a pointer to the real data in the weight matrix */
WeightMatrix = mxGetPr(prhs[3]);
/* get dimensions of the weight matrix */
ncolsweight = mxGetN(prhs[3]);
/* create the output matrix */
plhs[0] = mxCreateDoubleMatrix(1,ncolsweight,mxREAL);
/* get a pointer to the real data in the output matrix */
SolutionVector = mxGetPr(plhs[0]);
/* call the computational routine */
quadknap(items,capacity,ProfitMatrix,WeightMatrix,SolutionVector);
}
Anschließend kompiliere ich mit mex quadknap.c und starte mit quadknap(100,c,p,w), wobei c ein Skalar, p eine 100x100 Matrix und w eine 1x100 Matrix ist.
In dem Quellcode quadknap.c habe ich ferner #include values.h und #include varargs.h auskommentiert, da er es sonst nicht kompiliert. values.h stellt nur Konstanten zur Verfügung. Ich habe MAXINT dann entsprechend ersetzt.
Beim Aufruf in MATLAB stürzt er mir jedenfalls komplett ab.
das Problem (mex-file sieht gut aus) ist, das quadknap mit int* für die Vektoren rechnet, Du aber double* übergibst.
Beste Möglichkeit: beim Aufruf in MATLAB auch Integer-Vektoren zu übergeben (also quadknap(100,c,int32(p),int32(w))), für die Skalare ist es nicht wichtig, da die nicht als Pointer übergeben werden, daher richtig gecastet werden.
Im MEX File musst Du dann
Hey,
danke dir. Leider geht es immer noch nicht. Das liegt aber denke ich daran, dass der C-code so nicht lauffähig ist. Es existiert in quadknap.c gar keine main-function. quadknap.c wird per
http://www.diku.dk/hjemmesider/ansatte/pisinger/testqkp.c
aurgerufen. Ich hab allerdings keine Ahnung wie ich dort eine main function schreibe. Leider ist dies keine MATLAB Frage mehr, sondern eine C-Frage und hier bin ich dann wohl falsch.
Vielleicht kennt sich der ein oder andere ja trotzdem aus.
ein Glück, das in quadknap keine Main-Funktion ist, sonst würde es nicht funktionieren (die mexFunction ist ja der entry-point, nicht main!).
Was verwendest Du als Compiler? In der Hilfe unter
MATLAB->External Interfaces->Creating C Language MEX Files->Debugging werden Methoden zum Debugging von MEX Dateien vorgestellt. Dann siehst Du zumindest, wo er auf die Nase fällt. Wenn Du das postest, kann man sicherlich helfen ...
Titus
Long
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 19.06.2009, 15:12
Titel:
Oops.
Ok, also ich benutze lcc, was anderes konnte ich bei mex -setup auch gar nicht auswählen. Kompilieren tut er das ohne zu meckern.
Ich habe leider kein Visual Studio, lade mir aber gerad die kostenlose Visual C++ 2008 Express Edition runter. Ich hoffe damit kann ich arbeiten. Wenns klappt werde ich die Augabe vom Debuggen hier posten.
WIM-Doc
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 20.05.2015, 15:43
Titel:
Wurde hierfür eine Lösung gefunden?
Stehe vor dem gleichen Problem, dass Matlab bei Aufruf der quadknap Routine abstürzt.
Außerdem habe ich Probleme bei der Rückgabe der Variablenwerte nach Matlab.
Das damals gepostete Programm war voller Fehler.
Bitte poste den Code, den Du verwendest und beschreibe die Probleme, die bei der Rückgabe der Variablenwerte auftreten. Ohne Code und Beschreibung der Probleme kann man nämlich keine Verbesserungsvorschläge machen.
Gruß, Jan
WIM Doc
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 21.05.2015, 14:28
Titel:
Hallo Jan,
danke für die Rückmeldung.
Ich versuche auch den C Code zum Quadratic Knapsack in Matlab einzubinden. Wie ja auch hier schon richtig erkannt wurde enthält dieser keine main function. Deshalb wollte ich den Code durch Einfügen einer mexFunction für die Kompilierung in eine mex-File umbilden.
Ziel des Ganzen wäre die Variablen n (=Zahl der Items), cap (=Kapazität des Rucksacks), ptab(=Profit-Matrix) und wtab (=Weights-Matrix) in Matlab zu definieren und die mex-File mit den Variablen als Inputs auszuführen.
In dieser Form: QKP(n, cap, ptab, wtab)
(Ich habe die mex-File in QKP.c umbenannt, um evtl. Problemen zu entgehen bei gleicher Benennung der mex-File und der Funktion quadknap in der mex-File)
Ich würde gerne die Variablen z (=Wert des optimalen Rucksacks) und xtab (=0-1 Vektor, der die Hinzunahme der Items anzeigt) als Outputs in Matlab zurückbekommen.
Den Original-Code (http://www.diku.dk/~pisinger/quadknap.c) habe ich an zwei Stellen verändert.
-Ich habe die header mex.h und matrix.h mit include hinzugefügt.
-Außerdem habe ich bei der Funktion quadknap die Variable xtab als zweiten return-Wert hinzugefügt
Code:
int quadknap(int no, int cap, int *ptab, int *wtab, int *xtab) {
Für die Assoziierung der Input-/Outputvariablen zu Pointern und mxArrays bin ich dem Beispiel-Code xtimesy.c aus den Matlab Beispielen gefolgt. Allerdings hatte ich in anderen Beispielen verschiedene Varianten gesehen.
Die Kompilierung funktioniert ohne Fehlermeldung. In der Form stürzt mir Matlab bei Aufruf der QKP mex-File mit QKP(n, cap, ptab, wtab) in Matlab auch nicht ab.
Allerdings treten folgende Probleme auf, die ich bisher nicht lösen konnte und bei denen ich für jeden Ratschlag dankbar bin:
- Wenn ich die QKP mex File ausführe bekomme ich in Matlab nur die leeren Arrays plhs[0] und plhs [1] zurück. Um genauer zu sein: Die Arrays sind nur mit Nullen befüllt. Ich habe auch versucht die Outputvariablen alternativ mit einfachen Funktionen zu befüllen (sprich quadknap weggelassen). Aber das Ergebnis bleibt das Gleiche. Deshalb vermute ich, dass bei der Zuordnung der Outputvariablen zu den Pointern ein Fehler liegt. Die Übergabe der Inputvariablen aus Matlab funktioniert dagegen schon (s. die Funktion mexCallMatlab, bei der ich mir die Input-Arrays aus C wieder in Matlab anzeigen lassen kann).
-Zweitens bin ich mir nicht sicher, ob die Quadknap Funktion, wie hier in der mexFunction aufgerufen,
Der Rückgabewert "return z" muss ein int sein (wegen: "int quadknap(...") und der RETURN BEfehl nimmt keinen zweiten Wert an. ", xtab" sorgt einfach nur dafür, dass die Variable "xtab" ausgewertet wird. Und da es keine Funktion ist, sondern eine Variable, passiert gar nichts.
Code:
% "no" ist ein DOUBLE, es wird aber ein mwSize! % Da versteht C keinen Spaß, im Gegensatz zu Matlab.
plhs[1] = mxCreateDoubleMatrix(1, no, mxREAL);
% z und xtab werden im Code gar nicht benutzt?
z = mxGetScalar(plhs[0]);
xtab = mxGetPr(plhs[1]);
% Ich rate, Du brauchst etwas wie:
int z;
quadknap(no, cap, ptab, wtab, x, &z, xtab);
*mxGetPr(plhs[0]) = (double) z;
C ist im Gegensatz zu Matlab hypersensibel. Man kann sehr leicht großen Unfug programmieren, der so häßliche Dinge tut wie "meistens" das richtige Ergebnis zu produzieren.
Gruß, Jan
WIM Doc
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 22.05.2015, 09:45
Titel:
Hallo Jan,
vielen Dank für die Hinweise und Verbesserungsvorschläge. Es hat auch schon teilweise zu einer Verbesserung geführt.
Ein paar konkrete Fragen hätte ich noch. In der quadknap Funktion im Code von Pisinger wird der Lösungsvektor xtab erstellt.
Du meintest aber, dass das keinen Sinn ergibt. Ich habe es versucht so umzusetzen, wie du es auch für z vorgeschlagen hast. Da ist Matlab allerdings abgestürzt.
Ohne z = ist mir Matlab abgestürzt. Es hat bewirkt, dass plhs[0] nicht mehr mit 0 befüllt ist, sondern tatsächlich mit einem Wert, also zumindest etwas übergeben wird. Das Ergebnis kann allerdings noch nicht korrekt sein. Deswegen meine Fragen: Gibt es eine Möglichkeit zu überprüfen, ob quadknap die richtigen Input-Werte übernimmt und verarbeitet?
Besten Dank!
Gruß,
Matthias
Einstellungen und Berechtigungen
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
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.