IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MATLAB Discussion :

[MATLAB Engine] Remplir un mxArray à partir des valeurs d'un tableau à allocation dynamique [Débutant]


Sujet :

MATLAB

  1. #1
    Membre du Club
    Inscrit en
    Juillet 2010
    Messages
    70
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 70
    Points : 49
    Points
    49
    Par défaut [MATLAB Engine] Remplir un mxArray à partir des valeurs d'un tableau à allocation dynamique
    Bonjour,

    Débutant sous C++, je cherche à afficher une matrice écrite en C++ par allocation dynamique avec Engine MATLAB (plot). Je dois donc être capable d'assigner les valeurs d'une matrice (2D) écrite en C++ à un objet de type mxArray.

    J'ai écrit un bout de code. Ça ne marche pas :-/

    Apparemment, le problème vient de l'utilisation que je fais de la fonction memcpy. Les matrices que j'ai écrites en allocation dynamiques (fonction créer, passage par référence) sont bien remplies d’après d'autres tests que j'ai fait, par contre, les mxArrays ne fonctionnent pas bien. Quand j'émule MATLAB sous Visual Studio, "Z=[]" et X donne "Empty matrix: 1-by-0"

    Si en revanche, j'utilise la fonction memcpy avec des tableaux statiques, les matrices dans MATLAB sont ok (à un coefficient infini près : les valeurs nulles font -10 et les non nulles 0 la matrice totale étant affectée d'un coeff e+62)

    Je ne peux pas utiliser des tableaux statiques dans la mesure ou la taille de la matrice est amenée à évoluer...

    Si quelqu'un a une petite idée pour m'aider, je lui en serais reconnaissant.

    voici mon code :
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
     
    //#include "appelMatlab.h"
    #include "creer_Tableau.h"
    #include <iostream>
    #include "engine.h"
    #include "AllocationDynamique.h"
     
     
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    //#include "engine.h"
    #define  BUFSIZE 256
     
    void main(){
     
    	char buffer[BUFSIZE+1];
    	buffer[BUFSIZE] = '\0';
     
    	double** v = NULL;
    	int** g = NULL;
    	double** z = NULL;
     
    	int taillev=0;
    	int tailleg=0;
     
    	creer(0, 1, 0, 1, 0.1, taillev, tailleg, v, g, z);
     
    	Engine *ep;
     
    	if (!(ep = engOpen(""))) {
    		fprintf(stderr, "\nCan't start MATLAB engine\n");// Call engOpen with a NULL string. This starts a MATLAB process on the current host using the command "matlab".
    		return;
    	}
     
    	cout << "Creation des matrices vides de X, Y et Z" << endl;
     
    	mxArray *X=NULL;
    	X = mxCreateDoubleMatrix(1, taillev, mxREAL);
     
    	mxArray *Y=NULL;
    	Y = mxCreateDoubleMatrix(1, tailleg, mxREAL);
     
    	mxArray *Z=NULL;
    	Z = mxCreateDoubleMatrix(taillev, tailleg, mxREAL);
     
    	cout << "Remplissage dans Matlab des matrices vides de X, Y et Z" << endl;
     
    	memcpy((void *)mxGetPr(X), (void *)v, sizeof(double)*1*taillev);
    	memcpy((void *)mxGetPr(Y), (void *)g, sizeof(double)*1*tailleg);
    	memcpy((void *)mxGetPr(Z), (void *)z, sizeof(double)*taillev*tailleg);
     
     
    	cout << "ici" << z[1][1] << endl;
     
    	cout << "Placement dans Matlab des matrices, X, Y et Z" << endl;
    	engPutVariable(ep, "X", X);//Place the variable X into the MATLAB workspace
    	engPutVariable(ep, "Y", Y);
    	engPutVariable(ep, "Z", Z);
     
    	cout << "dessiner les matrices dans Matlab" << endl;
    	engEvalString(ep, "surf(X,Y,Z);");
     
    	engOutputBuffer(ep, buffer, BUFSIZE);
    	char str[BUFSIZE+1];
     
    	cout << " tape un truc" << endl;
    	fgets(str, BUFSIZE, stdin);//Get a string input from the user
    	engEvalString(ep, str);//Evaluate input with engEvalString
    	printf("%s", buffer);//Echo the output from the command. 
     
    	fgetc(stdin);
     
    	mxDestroyArray(X);
    	mxDestroyArray(Y);
    	mxDestroyArray(Z);
     
    	desalloueTabStatDeuxDimDouble(1, v);
    	desalloueTabStatDeuxDimInt(1, g);
    	desalloueTabStatDeuxDimDouble(taillev, z);
     
    	fgetc(stdin);
    	engClose(ep);//close MATLAB engine
     
     
    	return;//exit
    }

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    sont des entêtes C, en C++ on utilise celles sans .h et un c devant :
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #include <cstdlib>
    #include <cstdio>
    #include <cstring>

    Pour ce qui est de ton problème, as-tu vérifié les valeurs de taillev et tailleg au retour de ta fonction creer ?
    Dernière modification par Invité ; 06/08/2012 à 12h39.

  3. #3
    Membre du Club
    Inscrit en
    Juillet 2010
    Messages
    70
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 70
    Points : 49
    Points
    49
    Par défaut
    Bonjour,

    Merci pour votre aide!

    Citation Envoyé par Winjerome Voir le message
    Bonjour,
    Pour ce qui est de ton problème, as-tu vérifié les valeurs de taillev et tailleg au retour de ta fonction creer ?
    effectivement, les tailles ressorties par la fonction n'étaient pas bonnes.

    En revanche, si les dimensions des matrices X : 1*taillev et Y : 1*tailleg sont bien respectées, celle de la matrice Z : taillev*tailleg n'est pas bonne, et ce dans le cas allocution dynamique comme dans le cas statique.

    par ailleurs, les valeurs ressorties par les matrices X, Y et Z (dans Matlab) ne correponsdent toujours pas aux valeurs des matrices v, g, et z dont elles sont issues dans le cas ou v, g et z sont passées par allocution dynamique.

  4. #4
    Membre du Club
    Inscrit en
    Juillet 2010
    Messages
    70
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 70
    Points : 49
    Points
    49
    Par défaut
    Bonjour,
    après recherche sur le web, j'ai trouvé une solution
    elle consiste à procéder de cette façon :

    1) créer le pointeur v** par allocation dynamique
    2) définir :
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    mxArray *X=NULL;
    X = mxCreateDoubleMatrix(1, taillev, mxREAL);

    3)
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    double *vvv = mxGetPr(X);
    4) puis identification de *vvv et de v**
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for(i = 0 ; i < 1 ; i++){
    	for(j = 0 ; j < taillev ; j++){
    		vvv[j+i*tailleg] =v[i][j];
    	}
    	cout << endl;
    }

    5) désallouer v mais pas vvv qui est automatiquement désalloué quand X est détruit

    soit le code suivant :
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    int	i=0, j=0;
    	double vd=1;
    	double vf=10;
    	double uv=0.5;
    	int gd=1;
    	int gf=16;
     
    	int taillev=0;
    	int tailleg=0;
    	double** v = NULL;
    	int** g = NULL;
    	double** z = NULL;
     
    	char buffer[BUFSIZE+1];
    	buffer[BUFSIZE] = '\0';
     
    	creer(vd, vf, gd, gf, uv, taillev, tailleg, v, g, z);
     
    	cout << "taillev = " << taillev << " et " << "tailleg = " << tailleg << endl;
     
    	Engine *ep;
     
    	if (!(ep = engOpen(""))) {
    		fprintf(stderr, "\nCan't start MATLAB engine\n");// Call engOpen with a NULL string. This starts a MATLAB process on the current host using the command "matlab".
    		return;
    	}
     
    	cout << "Creation des matrices vides de X, Y et Z" << endl;
     
    	mxArray *X=NULL;
    	X = mxCreateDoubleMatrix(1, taillev, mxREAL);
     
    	mxArray *Y=NULL;
    	Y = mxCreateDoubleMatrix(1, tailleg, mxREAL);
     
    	mxArray *Z=NULL;
    	Z = mxCreateDoubleMatrix(tailleg, taillev, mxREAL);
     
    	cout << "Remplissage dans Matlab des matrices vides de X, Y et Z" << endl;
     
    	double *vvv = mxGetPr(X);
    	double *ggg = mxGetPr(Y);
    	double *zzz = mxGetPr(Z);
     
    	for(i = 0 ; i < 1 ; i++){
    		for(j = 0 ; j < taillev ; j++){
    			vvv[j+i*taillev] =v[i][j];
    		}
    		cout << endl;
        }
     
    	for(i = 0 ; i < 1 ; i++){
    		for(j = 0 ; j < tailleg ; j++){
    			ggg[j+i*tailleg] =g[i][j];
    		}
    		cout << endl;
        }
     
    	for(i = 0 ; i < taillev ; i++){
    		for(j = 0 ; j < tailleg ; j++){
    			zzz[j+i*tailleg] =z[i][j];
    		}
    		cout << endl;
        }
     
    	engOutputBuffer(ep, buffer, BUFSIZE);
    	char str[BUFSIZE+1];
     
    	cout << "Placement dans Matlab des matrices, X, Y et Z" << endl;
    	engPutVariable(ep, "X", X);//Place the variable X into the MATLAB workspace
    	engPutVariable(ep, "Y", Y);
    	engPutVariable(ep, "Z", Z);
     
    	cout << "dessiner les matrices dans Matlab" << endl;
    	engEvalString(ep, "surf(Y,X,Z);");
     
    	cout << " tape un truc" << endl;
    	fgets(str, BUFSIZE, stdin);//Get a string input from the user
    	engEvalString(ep, str);//Evaluate input with engEvalString
    	printf("%s", buffer);//Echo the output from the command. 
     
    	mxDestroyArray(X);
    	mxDestroyArray(Y);
    	mxDestroyArray(Z);
     
    	desalloueTabStatDeuxDimDouble(1, v);
    	desalloueTabStatDeuxDimInt(1, g);
    	desalloueTabStatDeuxDimDouble(taillev, z);
     
    	engClose(ep);//close MATLAB engine
     
     
    	return;//exit

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2010] remplir Combobox à partir des valeurs de deux combobox
    Par Shini28 dans le forum Excel
    Réponses: 0
    Dernier message: 13/01/2015, 14h27
  2. Réponses: 7
    Dernier message: 18/05/2011, 12h09
  3. Réponses: 1
    Dernier message: 23/05/2007, 11h49
  4. Comment ajouter des champs a partir des valeurs d'un autre champ ?
    Par zerkz dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 06/05/2007, 12h05
  5. Réponses: 1
    Dernier message: 23/01/2006, 18h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo