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

Simulink Discussion :

utiliser une fonction non compilables dans matlab function


Sujet :

Simulink

  1. #1
    Modérateur
    Avatar de le fab
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    1 883
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 883
    Points : 3 431
    Points
    3 431
    Par défaut utiliser une fonction non compilables dans matlab function
    Hello

    je précise que je tourne sous matlab 2011b
    j'ai besoin d'utiliser la fonction interp3 dans un bloc "matlab function" (ex embedded)

    en 2011b cette fonction n'est pas compilable (elle l'est en 2014a), du coup je suis obligé d'utiliser l'instruction "coder.extrinsic"

    problème : les aller retours simulink matlab induits rendent la simulation extrement lente
    je cherche donc à accélérer tout ca (et sans utiliser de bloc look up table)

    pour donner des ordres de grandeurs, 10000 interpolations durent :
    - 1 seconde avec un bloc look up table
    - 124 sec avec interp3
    - 81 sec avec interp3 et '*linear' comme méthode d'interpolation

    mon but est donc d'avoir qqch de compilable, cela me parait nécessaire pour retrouver de la rapidité

    j'ai regardé du coté d'une fonction "rapide" d'interpolation 3d dispo sur matlab central : lininterp3
    même en modifiant ce qui est nécessaire (suppression des warnings et modification des conditions sur vecteurs logiques) je n'arrive pas à faire tourner cette fonction simple sans l'instruction "coder.extrinsic" : erreur dans les multiplications de matrice en mode "compilé"
    (pour info en mode extrinsic elle dure 80sec pour 10000 interpolations)

    bref, je sèche

    une idée ?

    merci
    Fabien

  2. #2
    Expert confirmé
    Avatar de duf42
    Homme Profil pro
    Formateur en informatique
    Inscrit en
    Novembre 2007
    Messages
    3 111
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Formateur en informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 111
    Points : 4 661
    Points
    4 661
    Par défaut
    Salut,

    Pour information, quel est le message d'erreur que tu obtiens?

    Duf

  3. #3
    Modérateur
    Avatar de le fab
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    1 883
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 883
    Points : 3 431
    Points
    3 431
    Par défaut
    yop

    c'est bon je m'en suis sorti, j'ai réussi à rendre compilable la fonction lininterp3 dispo sur matlab centrale
    je met le code modifié pour ceux que ca interesse
    Code : 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
    94
    function v = lininterp3_bis(X, Y, Z, V, x, y, z)
    % linear interpolation, given set of X, Y, Z, and V values, and an x, y, z query
    % assumes X, Y, and Z values are in strictly increasing order
    %
    % Differences from matlab built-in :
    %       order of arguments switched
    %       much, much faster
    %       if coordinate is exactly on the spot, doesn't look at neighbors.  e.g. interpolate([blah, blah2], [0, NaN], blah) returns 0 instead of NaN
    %       extends values off the ends instead of giving NaN
    %       
    % modifiée 13/06/2014 Fabien GRand-Perret : focntion rendu compilable
    
    % if ((length(X) ~= size(V, 1)) || (length(Y) ~= size(V, 2)) || (length(Z) ~= size(V, 3))), error('[length(X), length(Y), length(Z)] does not match size(V)'); end
    
    %%
    %#codegen
    
    %% init
    pindexx = nan;
    indexx = nan;
    pindexy = nan;
    indexy = nan;
    pindexz = nan;
    indexz = nan;
    
    slopex = nan;
    slopey = nan;
    slopez = nan;
    
    Xp = nan;
    Yp = nan;
    Zp = nan;
    
    %%
    pindexx = find((x >= X), 1, 'last');
    indexx = find((x <= X), 1, 'first');
    
    if isempty(pindexx)
    %     warning('interpolating x value before beginning');
        pindexx = indexx;
        slopex = 0;
    elseif isempty(indexx)
    %     warning('interpolating x value after end');
        indexx = pindexx;
        slopex = 0;
    elseif all(pindexx == indexx)
        slopex = 0;
    else
        Xp = X(pindexx);
        slopex = (x - Xp) / (X(indexx) - Xp);
    end
    
    pindexy = find((y >= Y), 1, 'last');
    indexy = find((y <= Y), 1, 'first');
    
    if isempty(pindexy)
    %     warning('interpolating y value before beginning');
        pindexy = indexy;
        slopey = 0;
    elseif isempty(indexy)
    %     warning('interpolating y value after end');
        indexy = pindexy;
        slopey = 0;
    elseif all(pindexy == indexy)
        slopey = 0;
    else
        Yp = Y(pindexy);
        slopey = (y - Yp) / (Y(indexy) - Yp);
    end
    
    pindexz = find((z >= Z), 1, 'last');
    indexz = find((z <= Z), 1, 'first');
    
    if isempty(pindexz)
    %     warning('interpolating z value before beginning');
        pindexz = indexz;
        slopez = 0;
    elseif isempty(indexz)
    %     warning('interpolating z value after end');
        indexz = pindexz;
        slopez = 0;
    elseif all(pindexz == indexz)
        slopez = 0;
    else
        Zp = Z(pindexz);
        slopez = (z - Zp) / (Z(indexz) - Zp);
    end
    
    v = V(pindexx(1), pindexy(1), pindexz(1)) * (1 - slopex(1)) * (1 - slopey(1)) * (1 - slopez(1)) + V(indexx(1), pindexy(1), pindexz(1)) * slopex(1) * (1 - slopey(1)) * (1 - slopez(1)) ... 
      + V(pindexx(1),  indexy(1), pindexz(1)) * (1 - slopex(1)) *       slopey(1) * (1 - slopez(1)) + V(indexx(1),  indexy(1), pindexz(1)) * slopex(1) *       slopey(1) * (1 - slopez(1)) ... 
      + V(pindexx(1), pindexy(1),  indexz(1)) * (1 - slopex(1)) * (1 - slopey(1)) *       slopez(1) + V(indexx(1), pindexy(1),  indexz(1)) * slopex(1) * (1 - slopey(1)) *       slopez(1) ... 
      + V(pindexx(1),  indexy(1),  indexz(1)) * (1 - slopex(1)) *       slopey(1) *       slopez(1) + V(indexx(1),  indexy(1),  indexz(1)) * slopex(1) *       slopey(1) *       slopez(1) ;
    
    end
    le problème venait du dernier calcul, qui est juste une additions de multiplications scalaires
    mais la fonction multiplier (mtimes) me retournait une erreur lors de l'appel depuis la matlab fonction (et seulement depuis matlab function)

    cela venait du fait que l’interpréteur de matlab function n'était pas sur que tous les termes de ces multiplication était bien scalaire (alors que moi j'en étais sur ! )
    du coup j'ai rajouter les index (1) à chaque variable, comme ca il est content, c'est forcement des scalaires
    (y a peut être plus propre, mais ça marche)

    Fabien

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

Discussions similaires

  1. [WD-2013] Utiliser une fonction VBA excel dans vba word
    Par cedricM2o dans le forum Word
    Réponses: 2
    Dernier message: 05/05/2014, 16h14
  2. Utiliser une fonction ec C dans un code assembleur (ARM)
    Par serialC dans le forum Autres architectures
    Réponses: 1
    Dernier message: 26/12/2012, 15h51
  3. Réponses: 1
    Dernier message: 04/01/2012, 16h09
  4. Utiliser une méthode non-static dans une méthode static
    Par mcfly37 dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 18/08/2010, 11h41
  5. Utiliser une image non insérée dans le projet
    Par Gigi070 dans le forum Windows Presentation Foundation
    Réponses: 11
    Dernier message: 05/03/2010, 09h23

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