MATLAB: Ajustement de courbe non linéaire dans MATLAB

Salut les gars! On me donne des données énormes. J’essaie d’adapter un ensemble de données dans un modèle de forme fonctionnelle comme décrit ci-dessous:
z (x, y) = c0. * x ^ 0 * y ^ 2 + c1. * x ^ 1 * y ^ 1 + c2. * x ^ 2 * y ^ 1
où c0, c1, c2 sont les coefficients à trouver.
Ma tentative consiste à utiliser la fonction nlinfit pour le résoudre.
Jusqu’à présent, j’ai essayé:
% je viens d’ajouter une petite partie de mes données
a = [0,001, 0,001, 0,001, 0,001, 0,001, 0,001, 0,001, 0,001, 0,001, 0,001,0,011, 0,011, 0,011, 0,011, 0,011, 0,011, 0,011, 0,011, 0,011, 0,011];
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
y = x. * a;
z = [-.304860225, .170315374, .343019354, .370114906, .373180536, .36719579, .363397853, .363417755, .366962504, .379710865, -.304860225, .170315374, .343019354, .36, 346 .36719579, .363397853, .363417755, .366962504, .379710865];
modèle = c0. * (x (:). ^ 0). * (y (:). ^ 2) + c1. * (x (:). ^ 1). * (y (:). ^ 1) + c2. * (x (:). ^ 2). * (y (:). ^ 0)
[c0 c1 c2] = [0,001 0,007 0,788]
C = nlinfit ([x, y], z, «modèle», [0,001 0,007 0,788])
% Ici x, y sont des variables indépendantes et z est une variable dépendante.
Comment définir ces valeurs initiales pour les coefficients? Je ne sais pas comment passer les arguments. J’obtiens cette erreur « ??? Fonction non définie ou variable ‘c0′ ». Aidez-moi !!!
Merci d’avance, Syeda

Meilleure réponse

  • La solution est triviale car vous avez un système d’équations linéaire pour les 3 coefficients
     

    A*c = b;
    c = A\b

     

  • MATLAB: ajustement des données à une fonction intégrale personnalisée

    Salut à tous,
    J’ai du mal à adapter mes données mesurées à une fonction intégrale. J’ai déjà essayé cela avec la boîte à outils d’ajustement de courbe et « lsqnonlin » de la boîte à outils d’optimisation.
    Disons que j’ai l’ensemble de données suivant:
    x = [228,1194 179,7485 149,5914 121,6736 91,7255 60,6427 40,8913 23,9615 14,4217 11,9658 9,7682 7,4930 5,4940 3,8771 2,6096];
    y = [0,7440 0,7349 0,7276 0,7049 0,6939 0,6607 0,6417 0,6069 0,5868 0,5818 0,5781 0,5748 0,5704 0,5606 0,5611];
    Je souhaite adapter l’équation suivante à l’ensemble de données:
    y =
    où a, b, c, d sont les coefficients à ajuster. je pense que mon problème est la partie intégration de la fonction d’adaptation
    J’ai essayé différentes approches.
    1) Avec la boîte à outils d’ajustement de courbe
     
    %% data set
    x = [228.1194 179.7485 149.5914 121.6736 91.7255 60.6427 40.8913 23.9615 14.4217 11.9658 9.7682 7.4930 5.4940 3.8771 2.6096];
    y = [0.7440 0.7349 0.7276 0.7049 0.6939 0.6607 0.6417 0.6069 0.5868 0.5818 0.5781 0.5748 0.5704 0.5606 0.5611];
    plot(x,y,'x');
    fun= @(a,b,c,d,x) 1/2/x*(integral(b * (log(1 + a/b * (exp(x/c) - 1))) *exp(-x/d) * (1/(x/c)), 0, 2*x));
    g = fittype('(1/2/x*integral(b * (log(1 + a/b * (exp(x/c) - 1))) *exp(-x/d) * (1/(x/c)), 0, 2*x))',...
    'dependent', {'y'},'independent', {'x'}, 'coefficients', {'a','b','c','d'});
    [fitobject,gof] = fit(x, y, g);
     
    C’est le message d’erreur:
    Erreur lors de l’utilisation de fittype / testCustomModelEvaluation (ligne 12)
    Expression (intégrale (b * (log (1 + a / b * (exp (x / c) – 1)))) * exp (-x / d) * (1 / (x / c)), 0, 2 * x)) n’est pas une expression MATLAB valide, a un caractère non scalaire
    ou ne peut être évalué:
    Error in fittype expression ==> (integral(b .* (log(1 + a./b .* (exp(x./c) – 1))) .*exp(-x./d) .* (1./(x./c)), 0, 2.*x))
    ??? Le premier argument d’entrée doit être un descripteur de fonction.
    […]
    2) Approche « lsqnonlin »
     
    xdata = [228.1194 179.7485 149.5914 121.6736 91.7255 60.6427 40.8913 23.9615 14.4217 11.9658 9.7682 7.4930 5.4940 3.8771 2.6096];
    ydata = [0.7440 0.7349 0.7276 0.7049 0.6939 0.6607 0.6417 0.6069 0.5868 0.5818 0.5781 0.5748 0.5704 0.5606 0.5611];
    plot(xdata,ydata,'x');
    fun= @(x,xdata) 1/2/xdata*(integral(x(2) * (log(1 + x(1)/x(2) * (exp(xdata/x(3)) - 1))) *exp(-xdata/x(4)) * (1/(xdata/x(3))), 0, 2*xdata)) - ydata;
    x0 = [0.65, 0.8, 8, 100000];
    x = lsqnonlin(fun, x0);
     
    Message d’erreur:
    Pas assez d’arguments d’entrée.
    Error in try2>@(x,xdata)1/2/xdata*(integral(x(2)*(log(1+x(1)/x(2)*(exp(xdata/x(3))-1)))*exp(-xdata/x(4))*(1/(xdata/x(3))),0,2*xdata))-ydata
    Erreur dans lsqnonlin (ligne 196)
    initVals.F = feval (funfcn {3}, xCurrent, varargin {:});
    Erreur dans try2 (ligne 18)
    x = lsqnonlin (amusant, x0);
    Causé par:
    Échec de l’évaluation initiale de la fonction objective. LSQNONLIN ne peut pas continuer.
    Une autre façon que j’ai essayée en premier était celle-ci, où je résolvais le problème avec une boucle et devinais simplement les paramètres:
     
    xdata = [228.1194 179.7485 149.5914 121.6736 91.7255 60.6427 40.8913 23.9615 14.4217 11.9658 9.7682 7.4930 5.4940 3.8771 2.6096];
    ydata = [0.7440 0.7349 0.7276 0.7049 0.6939 0.6607 0.6417 0.6069 0.5868 0.5818 0.5781 0.5748 0.5704 0.5606 0.5611];
    plot(xdata,ydata,'x');
    hold on
    x = [0.558, 0.78, 25, 100000];
    fun = @(xdata) (x(2) .* (log(1 + x(1)./x(2) .* (exp(xdata./x(3)) - 1))) .* exp(-xdata./x(4)) .* (1./(xdata./x(3))));
    for i=1:length(xdata)
    y_fit(i) = integral(fun, 0, 2*xdata(i));
    y_fit2(i) = 1/(2*xdata(i)) *y_fit(i);
    end
    plot(xdata,y_fit2,'o');
     
    J’ai trouvé des questions similaires sur le forum mais je n’ai pas pu les adapter à mon cas. Je suis très reconnaissant pour tout conseil / indice.
    Merci d’avance

    Meilleure réponse

  • Essayez le code suivant. Comparez les équations avec votre code pour voir les différences. De plus, la raison de l’utilisation de arrayfun () est un peu complexe, et je me sens un peu paresseux pour écrire une longue explication: P, donc je vous laisse le soin de lire la documentation et d’étudier attentivement ce code pour savoir pourquoi tout est être fait comme ça. Si vous avez une confusion, vous pouvez demander dans le commentaire.
     

    xdata = [228.1194 179.7485 149.5914 121.6736 91.7255 60.6427 40.8913 23.9615 14.4217 11.9658 9.7682 7.4930 5.4940 3.8771 2.6096];
    ydata = [0.7440 0.7349 0.7276 0.7049 0.6939 0.6607 0.6417 0.6069 0.5868 0.5818 0.5781 0.5748 0.5704 0.5606 0.5611];
    integral_term = @(a,b,c,d,X) integral(@(x) b.*(log(1 + a./b.*(exp(x./c)-1))).*exp(-x/d).*(1./(x/c)), 0, 2*X);
    fun = @(x,xdata) 1/(2*xdata)*integral_term(x(1),x(2),x(3),x(4), xdata);
    fun2 = @(x,Xdata) arrayfun(@(xdata) fun(x,xdata), Xdata);
    x0 = [0.65, 0.8, 8, 100000];
    x = lsqcurvefit(fun2, x0, xdata.', ydata.');
    plot(xdata, ydata, '+', xdata, fun2(x, xdata), '-');

     

  • MATLAB: régression de courbe dans l’espace 3D et calcul de vitesse en tout point

    J’essaie de trouver l’équation de la courbe (3d) pour pouvoir calculer la vitesse à n’importe quel point dans l’espace, je n’ai trouvé aucune fonction que je pourrais effectuer pour ajuster la courbe (comme l’ajustement pour la 2D), Mon l’ensemble de données provient de fichiers Excel avec plus de 500 x 9 doubles, une partie du fichier suit ci-dessous et chaque fichier a un nombre différent de lignes.
    X Y Z Vel
    61.2566 -150.047 411 303.7
    61.2521 -150.044 381 300
    61.2478 -150.042 351 298.2
    61.2435 -150.039 320 292.6
    61.2392 -150.037 297 294.5
    Merci pour toute aide…
    Juliano

    Meilleure réponse

  • Si vous souhaitez interpoler les points 3D, voyez griddata ():https://www.mathworks.com/help/releases/R2020a/matlab/ref/griddata.html
    Voir aussi dispersedinterpolant ():https://www.mathworks.com/help/releases/R2020a/matlab/ref/scatteredinterpolant.html
  • MATLAB: Ajustement de surface multidimensionnel à n variables indépendantes.

    Bonjour à tous. J’ai un ensemble de 16 variables indépendantes. Sur la base de ces 16 variables indépendantes, je mène une expérience et observe une sortieytel queest une fonction inconnue. Je mène l’expérience plusieurs fois et collecte des données. Puis-je ajuster une surface multidimensionnelle sur ces données pour trouver une structure approximative desous forme continue, tout comme un ajustement de courbe à une dimension? Puis-je utiliser la commande fit ou lsqcurvefit à cette fin? Merci beaucoup pour votre temps.

    Meilleure réponse

  • Quelques malentendus courants dans ce …
    Tout d’abord, vous ne pouvez pas utiliser l’ajustement sur des problèmes avec plus de 2 paramètres indépendants. 16 n’est pas une option, et je ne doute pas, ce sera bientôt. Vous pourriez, en théorie, utiliser lsqcurvefit, avec une mise en garde massive.
    L’utilisation de lsqcurvefit EXIGE, ABSOLUMENT nécessite un modèle. Avez-vous un modèle proposé? Cela ne semble pas être vrai. Donc, à moins que votre surface ne soit banale, peut-être un hyperplan, alors où allez-vous? Et si votre surface était quelque chose de très trivial comme ça, alors vous pourriez utiliser la barre oblique inverse pour résoudre le problème en théorie.
    Pourriez-vous utiliser un outil comme mon polyfitn (trouvé sur l’échange de fichiers)? J’imagine que quelqu’un finira par vous le recommander. Cependant, à moins que votre modèle ne soit vraiment linéaire, il deviendra compliqué et désordonné. Par exemple, un modèle polynomial entièrement quadratique à 16 variables aura quelque chose comme
     

    n = 16;
    1 + n + n*(n+1)/2
    ans =
    153