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 :

Obtenir une fonction en argument de sortie dépendant d'une fonction en argument d'entrée


Sujet :

MATLAB

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2012
    Messages : 8
    Points : 1
    Points
    1
    Par défaut Obtenir une fonction en argument de sortie dépendant d'une fonction en argument d'entrée
    Bonjour,

    Je souhaite créer une fonction (appelons la mapping) permettant d'utiliser la généralisation de la méthode de quadrature de Gauss pour un intervalle fermé [a;b].
    Plus simplement, la fonction mapping prend en arguments d'entrée une fonction f1 et deux réels a et b.
    mapping doit renvoyer en sortie une autre fonction f2 suivant la formule:
    http://upload.wikimedia.org/wikipedi...8d6a9c921a.png

    On a donc f2(x)= c* f1(c*x + d) avec c=(b-a)/2 et d=(a+b)/2

    J'ai utilisé différentes méthodes (definir des fonction inline, passer par des chaines de caractères, ...) mais je n'arrive pas à obtenir la solution espérée.

    Par exemple, lorsque j'utilise:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    function f2 = Mapping(f1,a,b)
    f2=@(x)f1(x);
    end
    et que j'execute:
    J'obtiens:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ans = 
     
        @(x)Func(x)
    et non: @(x)cos(x)

    Quelqu'un saurait-il remédier à ce problème ?

    En espérant avoir été assez clair,

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

    Simplement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    function f2 = Mapping(f1,a,b)
    f2 = f1;
    end

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2012
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    Merci pour votre réponse qui en effet fonctionne pour le simple exemple que j'ai demandé.
    Mais ce que je cherche à faire est un peu plus compliqué, supposons que j'appelle en entrée la fonction @(x) (3*x+2), je souhaiterais que cette fonction devienne en sortie @(x) 2*(3*(4*x+3)+2) par exemple.
    J'ai essayé votre solution avec un exemple très simple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    function f2 = Mapping(f1,a,b)
    f2 = 2*f1+1;
    end
    et en appelant mais cela ne fonctionne pas, la multpiplication et l'addition ne semble pas fonctionner avec les handle

  4. #4
    Membre éclairé
    Homme Profil pro
    Doctorant automatique
    Inscrit en
    Janvier 2012
    Messages
    446
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Doctorant automatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2012
    Messages : 446
    Points : 719
    Points
    719
    Par défaut
    Bonjour,

    Ce sujet m'intéresse par simple curiosité... (je n'ai donc pas la réponse dsl)

    Winjerome, ce que tu as dit fonctionne bien dans le cas où tu dois effectivement envoyer en sortie la même fonction qu'en entrée... sauf que là, ce n'est pas tout à fait le cas... il doit renvoyer en sortie une fonction qui dépend de celle en entrée... et là je vois mal comment l'appliquer à son cas par exemple...

    Cordialement,

    EDIT : ah ben voilà, pareil que lui, pas mieux (il a posté son message juste avant le mien ^^)

    EDIT2 : j'ai peut-être une idée avec les fonctions imbriquées... je vais y réfléchir, mais pas immédiatement, pas le temps
    Je ne réponds pas aux MP techniques. Le forum est là pour ça.
    La raison est simple : il est ennuyeux de répondre à une seule personne, alors que la réponse peut servir à tout le monde.
    Conclusion : n'hésitez pas à utiliser le forum pour poser vos questions.
    Matlab 2005 - ver.7.1.0.183 (R14) Service Pack 3

  5. #5
    Expert confirmé
    Avatar de tug83
    Homme Profil pro
    MATLAB Geek !
    Inscrit en
    Juin 2006
    Messages
    1 781
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Alpes de Haute Provence (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : MATLAB Geek !
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 781
    Points : 4 039
    Points
    4 039
    Par défaut
    Voilà un exemple de ce qu'il faut que tu écrives pour multiplier ta function handle f1 par 2 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    function f2 = Mapping(f1,a,b)
    f2=@(x) 2*f1(x)+1;
    end
    et par rapport au code dans ta première question
    te retournera:

    ce qui est juste si on fait:
    ou on obtient bien -1
    MATLAB 8.2 (R2013b)

    le blog des MATLAB geeks

  6. #6
    Invité
    Invité(e)
    Par défaut
    Pour suivre ta formule :
    Citation Envoyé par Feigou Voir le message
    On a donc f2(x)= c* f1(c*x + d) avec c=(b-a)/2 et d=(a+b)/2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function f2 = Mapping(f1,a,b)
     
    c = (b-a)/2; 
    d = (a+b)/2;
    f2=@(x) c* f1(c*x + d);
    end

  7. #7
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2012
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    Merci, cela fonctionne en effet au niveau de la programmation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>>a=Mapping(@(x) (3*x+2),1,2)
    a = 
        @(x) c* f1(c*x + d)
    >> a(5)
    ans =
         7
    Ce qui est le résultat attendu

    Une question encore: existe-il une façon de faire apparaitre les valeur de c,d et f1 dans la réponse fourni par matlab ? (car j'utilise Matlab comme outil mathématique pour éviter de répéter les mêmes calculs parfois fastidieux des centaines de fois à la main).
    J'ai l'impression qu'il n'est pas possible d'effectuer des fonctions à l'intérieur d'un handle (par exemple disp(c), evalf ou d'autres fonctions du type num2str).

  8. #8
    Membre éclairé
    Homme Profil pro
    Doctorant automatique
    Inscrit en
    Janvier 2012
    Messages
    446
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Doctorant automatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2012
    Messages : 446
    Points : 719
    Points
    719
    Par défaut
    Tu dois pouvoir le faire avec les fonctions imbriquées sans problème, du style (pas testé) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function f2 = Mapping(f1,a,b)
     
      c = (b-a)/2; 
      d = (a+b)/2;
      f2=@f
      function out = f(x) 
        out = c* f1(c*x + d);
        disp(c);
      end
    end
    Je ne réponds pas aux MP techniques. Le forum est là pour ça.
    La raison est simple : il est ennuyeux de répondre à une seule personne, alors que la réponse peut servir à tout le monde.
    Conclusion : n'hésitez pas à utiliser le forum pour poser vos questions.
    Matlab 2005 - ver.7.1.0.183 (R14) Service Pack 3

  9. #9
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2012
    Messages : 95
    Points : 150
    Points
    150
    Par défaut
    Il me semble que simplement en supprimant les "," tes valeurs s'afficheront:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function f2 = Mapping(f1,a,b)
     
    c = (b-a)/2 
    d = (a+b)/2
    f1
    f2=@(x) c* f1(c*x + d)
    end
    Ou alors je me trompe?
    Ma version Matlab:Matlab R2011b

  10. #10
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2012
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    Merci pour vos réponses.

    TRSRT, enlever les points virgules permet en effet d'afficher les valeurs de c et d, mais ces valeurs ne sont pas remplacées dans l'affichage de f2 qui reste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    f2 = 
        @(x) c* f1(c*x + d)
    tachmou ta solution fonctionne (comme celle de winjerome et tug83) lorsque l'on applique la fonction de sortie f2 en une valeur mais elle ne permet pas non plus de renvoyer la formule f2 "général". On obtient:
    (Mais merci je vais pouvoir comparer quelle est la méthode la plus rapide/efficace)

  11. #11
    Membre éclairé
    Homme Profil pro
    Doctorant automatique
    Inscrit en
    Janvier 2012
    Messages
    446
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Doctorant automatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2012
    Messages : 446
    Points : 719
    Points
    719
    Par défaut
    Ah, ok, je vois ce que tu veux faire.

    Il faut que tu passes par les classes matlab alors... c'est un peu spécial, et la méthode de programmation dépend de la version de matlab que tu as, mais pour la dernière version tu peux jeter un coup d'oeil : ce qui fait qu'à chaque fois que tu feras un appel à "Mapping", tu pourras afficher non pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    f2 = 
        @(x) c* f1(c*x + d)
    mais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    f2 = 
        @(x) 2* f1(2*x + 1)
    par exemple... après, à toi de voir si ça vaut vraiment la peine de t'embêter pour ça...


    personnellement, ma version de matlab me donne :

    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
     
    Here is @polynom/display.m. This method relies on the char method to produce a string representation of the polynomial, which is then displayed on the screen. This method produces output that is the same as standard MATLAB output. That is, the variable name is displayed followed by an equal sign, then a blank line, then a new line with the value. 
    function display(p)
    % POLYNOM/DISPLAY Command window display of a polynom
    disp(' ');
    disp([inputname(1),' = '])
    disp(' ');
    disp(['   ' char(p)])
    disp(' ');
     
     
     
    The statement 
    p = polynom([1 0 -2 -5])
     
     
     
    creates a polynom object. Since the statement is not terminated with a semicolon, the resulting output is 
    p =
        x^3 - 2*x - 5
    du coup tu pourrais même enlever le "@(x)" si tu veux

    [EDIT] : vas regarder "Displaying Objects in the Command Window"
    Je ne réponds pas aux MP techniques. Le forum est là pour ça.
    La raison est simple : il est ennuyeux de répondre à une seule personne, alors que la réponse peut servir à tout le monde.
    Conclusion : n'hésitez pas à utiliser le forum pour poser vos questions.
    Matlab 2005 - ver.7.1.0.183 (R14) Service Pack 3

  12. #12
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2012
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    Merci beaucoup, je crois avoir compris l'idée dans display. Le seul souci c'est que je veux non seulement appliqué cela pour les polynômes mais pour d'autres fonctions classiques (ln,exp,sin,cos,...). Mais d'après ce que j'ai compris "il suffit" de créer un display pour chacune de ces fonctions. C'est sur que c'est plutôt fastidieux donc je vais réfléchir si ca vaut le coup.

    Parce que je pense créer un grand nombre de fonction qui renverront d'autres fonctions en sorties (je fais des mathématiques numériques théoriques puis je les applique à des problèmes concrets de physiques) et il serait préférables de pouvoir observer ces fonctions plutôt que d'avoir des choses du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    a=
    @(x) f1(c*f2(d*f3(a+3*c)))) ...
    Idéalement même il faudrait que Matlab puisse non seulement afficher les fonctions mais les simplifie lorsque c'est possible.
    Je sais que ce genre de choses est possible en Fortran mais le labo où je suis en stage ne travaille que sur Matlab.

  13. #13
    Invité
    Invité(e)
    Par défaut
    Pour faire cela, il te faudra à mon avis passer par la Symbolic Math Toolbox.

    Une solution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function f2 = Mapping(f1,a,b)
     
    c = (b-a)/2;
    d = (a+b)/2;
    syms x
    f2 = inline(c* f1(c*x + d));
    end
    à utiliser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    f = Mapping(inline('cos(x)'),1,2)
     
    f =
     
         Inline function:
         f(x) = 1./2.*cos(1./2.*x+3./2)

  14. #14
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2012
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    Merci beaucoup winjerome ca marche parfaitement maintenant.
    Pour ceux que ca intéresse je copie mon programme. Je l'ai amélioré un peu de façon à ce que l'on puisse mettre en fonction d'entrée une fonction inline, une chaîne de caractère ou une fonction handle (@(x) ...):

    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
    function newFunc = Mappingintegral(Func,a,b)
    %Mappingintegral transforms an [a:b]-integral into a [-1:1]-integral.
    %Func is the x-function to integrate between a and b and newFunc is
    %the equivalent x-function but to integrate between -1 and 1. 
    %Func could be entered under different types, for example for f(x)=(3*x+2) on [1;4]:
    %   - inline function, i.e Mappingintegral(inline('3*x+2'),1,4)
    %   - character-chain, i.e Mappingintegral('3*x+2',1,4)
    %   - handle_function, i.e Mappingintegral(@(x) 3*x+2,1,4) 
     
        if isa(Func,'function_handle')
            Func=func2str(Func);
        end
     
        if isa(Func,'char')
            Func = strrep(Func,'@(x)','');
            Func=inline(Func);
        end 
     
        c = (b-a)/2;
        d = (a+b)/2;
        syms x
        newFunc = inline(c* Func(c*x + d));
     
    end
    Par contre il n'est pas possible d'entrer une fonction comme "@cos" (il faut passer par @(x) cos(x)) ce qui ne me pose pas de problème dans mon cas.
    La ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Func = strrep(Func,'@(x)','');
    est un peu grossière mais fonctionne assez bien.
    La fonction en entrée doit avoir x comme variable mais on peut aisément rajouter un argument à la fonction pour changer cette variable.

    Merci beaucoup à tous ceux qui m'ont aidé.

  15. #15
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Feigou Voir le message
    Par contre il n'est pas possible d'entrer une fonction comme "@cos" (il faut passer par @(x) cos(x)) ce qui ne me pose pas de problème dans mon cas.
    Dans ce cas directement sans passer par une chaine :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    c = (b-a)/2;
    d = (a+b)/2;
    syms x
     
    if isa(Func,'function_handle')
        newFunc = inline(c* Func(c*x + d));
    ...

  16. #16
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2012
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    Oui en effet Winjerome, merci c'est bien plus simple comme ça.
    Étant amené à manipuler beaucoup de fonctions, j'ai eu l'idée de créer deux fonctions: l'une pour transformer les handle_functions et les chaines de caractères en inline_functions (functoinline) et une deuxième qui fait le chemin inverse c'est-à-dire qu'elle transforme les inline_functions et les chaines de caractères en handle_functions (functohandle).
    Ainsi, il sera plus aisé de manipuler les fonctions sont se soucier de leur types et/ou en choississant le type le mieux adapter à ce que l'on veut faire

    La première marche parfaitement:
    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
    function result = functoinline(Func)
    %Transform a function given by a 'char' or by an 'handle_function' into an
    %'inline_function'. 
    %If Func is an 'inline_function' then result=Func
        syms x 
       %Transform Func into a 'inline_function' if Func is a 'handle_function' (@(x) ...)
        if isa(Func,'function_handle')
            Func=inline(Func(x));
        end
     
       %Transform Func into an 'inline_function' if Func is a 'char'
        if isa(Func,'char')
            Func=inline(Func);
        end 
     
        result=Func;
    end
    Concernant la deuxième, je suis confronté à un problème. J'ai réussi à transformer une inline_function en chaine de caractères (juste a l'aide de la fonction char) mais je je ne vois pas comment transformer une chaîne de caractère en handle.
    Voici mon idée:
    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
    function result = functohandle(Func)
    %Transform a function given by a 'char' or by an 'inline_function' into an
    %'handle_function'.
    %If Func is an 'handle_function' then result=Func.
        syms x
     
       %Transform Func into an 'char' if Func is an 'inline_function'
       if isa(Func,'inline')
            Func= char(Func); 
       end   
     
       if isa(Func,'char')
            Func = str2func(Func);
       end
     
       result=Func;
    end
    La commande str2func ne semble pas comprendre quand la chaîne de caractère en argument dépend de x (j'ai essayé de mettre la chaîne de caractère sous la forme: '3*x+2' et '@(x) 3*x+2' mais à la fin je n'arrive pas à affecter la fonction de sortie en une valeur que ce soit directement (f(5)) ou avec la fonction feval).
    Quelqu'un aurait-il une idée à ce sujet ?

  17. #17
    Invité
    Invité(e)
    Par défaut
    La syntaxe avec le @ devrait marcher
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >> fun = str2func('@(x) 3*x+2')
     
    fun = 
            @(x)3*x+2
     
    >> fun(5)
     
    ans =
            17

  18. #18
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2012
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    >> fun = str2func('@(x) 3*x+2')
     
    fun = 
     
        @(x) 3*x+2
     
    >> fun(5)
    ??? Undefined command/function '@(x) 3*x+2'.
    Bizarre en effet je comprend pas trop pourquoi ca ne marche pas chez moi

Discussions similaires

  1. Réponses: 3
    Dernier message: 30/06/2011, 13h11
  2. Réponses: 0
    Dernier message: 27/03/2009, 11h34
  3. Réponses: 7
    Dernier message: 13/02/2008, 10h22
  4. [PHP-JS] Variable PHP comme argument dans l'appel d'une fonction Javascript
    Par The Molo dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 26/04/2007, 09h00
  5. Réponses: 13
    Dernier message: 05/03/2007, 09h29

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