MATLAB: comment vectoriser les multiplications matricielles avec une entrée dépendante précédente

Comment éviter la boucle for dans le code suivant, en créant une structure polymère 2D avec un nouvel angle de flexion créé de façon aléatoire du segment suivant:
 
N=10;
K=200;
Xi=50;
l=0.311;
Fi=normrnd(0,sqrt(l/Xi),[1,1,K])
dna=zeros(2,K);
t=ones(2,K);
for i=2:K
A=[cos(Fi(i)) -sin(Fi(i));sin(Fi(i)) cos(Fi(i))]
t(:,i)=A*t(:,i-1);
dna(:,i)=dna(:,i-1)+t(:,i);
end
 

Meilleure réponse

  • La boucle for peut être supprimée, mais je doute qu’elle vous fasse gagner du temps.
     

    K = 200;
    Xi = 50;
    l = 0.311;
    t = [rand(2,1),zeros(2,K-1)]; % <-- You choose t(:,1)
    Fi = normrnd(0,sqrt(l/Xi),[1,1,K])
    Gi = cumsum(reshape(Fi(1,1,2:K),1,[]),2); % cumsum the angles in Fi
    sG = sin(Gi);
    cG = cos(Gi);
    t(1,2:K) = cG*t(1,1)-sG*t(2,1);
    t(2,2:K) = sG*t(1,1)+cG*t(2,1);
    dna = [zeros(2,1),cumsum(t(:,2:K),2)];

     

  • MATLAB: générer la matrice d’un processus aléatoire avec chaque ligne en utilisant différents paramètres et sans boucle for

    Par exemple, supposons que je veuille générer 5 vecteurs normalement distribués différents avec 10 échantillons chacun. Le premier vecteur aura un mu = 0, sigma = 1, le second un mu = 5, sigma = 3, etc. Ce que j’aimerais pouvoir faire serait quelque chose comme le code suivant:
    mu = [0, 3, 2, 5, 1]; sigma = [1, 5, 4, 10, 7]; myDistributions = random (‘norme’, mu, sigma, [5, 10]);
    et lui faire sortir une matrice 5 x 10 avec la première ligne en utilisant les paramètres mu = 0, sigma = 1; la deuxième ligne en utilisant les paramètres mu = 3, sigma = 5. etc.
    Je pense que je vais devoir mordre la balle et utiliser une boucle for si je veux le faire, mais j’espère avoir raté quelque chose d’autre qui peut être fait pour ce genre de chose.

    Meilleure réponse

  • Vous pouvez utiliser arrayfun pour cela:
     

    mu = [0, 3, 2, 5, 1];
    sigma = [1, 5, 4, 10, 7];
    A = arrayfun(@(x,y) random('norm', x, y, [1, 10]),mu,sigma,'UniformOutput',false)
    % Change from a cell to a matrix:
    A = cell2mat(A);

     

  • MATLAB: les dimensions de la matrice ne correspondent pas

    Salut à tous,
    Je me demande si vous pouvez m’aider avec ce problème.
    J’ai un code d’équation différentielle (dy / dt)qui est résolu en utilisant un solveur. À la fin, j’ai obtenu la dimension de yêtre 2868 × 11.
    Il existe également un autre paramètre appelé xinf, qui est défini comme
     
    xinf = 1/(1+exp(-(y(:,1)-Vx)/kx))
     
    Vx et kx sont tous deux constants. À la fin, xinga la dimension de 1 × 2868.
    Le problème survient lorsque j’ai besoin de calculer cette formule:
     
    Ix = gx*xinf.^3.*y(:,2).*(y(:,1)-Ex)
     
    Ex est une constante.
    Je reçois l’erreur disant que les dimensions de la matrice ne correspondent pas. J’ai essayé de transposer xinf, et bien que le code s’exécute, il ne produit pas la sortie souhaitée.
    Je me demandais si quelqu’un pouvait m’aider à résoudre ce problème? Peut-être une autre façon de procéder? Comme je semble avoir atteint une impasse.
    Merci d’avance!

    Meilleure réponse

  • Je suppose que vous vouliez dire que la division dans votre calcul xinf devait être élémentaire. Par exemple, changez le / en ./ comme suit:
     

    xinf = 1./(1+exp(-(y(:,1)-Vx)/kx))

     

  • MATLAB: Multiplication de 2 matrices de tailles différentes

    Bonjour à tous,
    J’ai une matrice 12 × 16, M,
     
    [ 0 0 1 0 0 0 0 -1 0 1 0 0 -1 0 0 0;0 0 0 1 0 0 1 0 0 0 0 0 -1 0 1 0;0 -1 0 0 -1 0 1 0 0 1 0 0 0 0 0 0;0 0 0 1 0 -1 0 0 0 0 1 0 0 1 0 0;0 0 1 0 0 0 0 0 -1 0 0 0 0 0 1 1;1 0 0 0 0 -1 0 0 0 1 0 0 0 0 1 0;0 0 0 1 0 0 0 -1 -1 0 0 -1 0 0 0 0;0 -1 0 0 0 -1 0 0 0 0 0 -1 0 0 0 1;1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1; 0 0 1 0 -1 0 0 0 0 0 0 -1 0 1 0 0; 0 -1 0 0 0 0 0 0 -1 0 1 0 -1 0 0 0;1 0 0 0 -1 0 0 -1 0 0 1 0 0 0 0 0]
     
    et une matrice 12 × 4 P,
     
    [0.8033 - 0.5956i -0.4224 - 0.9064i -0.7512 + 0.6600i -0.6502 - 0.7597i; -0.9993 + 0.0363i -0.9690 + 0.2473i 0.8134 + 0.5817i -0.7593 - 0.6507i; 0.6407 + 0.7678i -0.4739 - 0.8806i -0.9973 - 0.0735i 0.3493 + 0.9370i; 0.7352 + 0.6778i 0.9006 + 0.4346i -0.9478 + 0.3189i 0.9575 + 0.2883i;-0.1797 + 0.9837i 0.7638 - 0.6455i 0.6129 + 0.7902i -0.7013 + 0.7129i;0.8619 - 0.5071i -0.9843 + 0.1766i -0.3126 + 0.9499i -0.8056 + 0.5925i;-0.8067 + 0.5910i 0.4202 - 0.9074i 0.7392 - 0.6735i 0.6508 - 0.7592i;-0.8884 - 0.4590i -0.5747 - 0.8183i 0.8557 + 0.5174i 0.5900 - 0.8074i;-0.9836 + 0.1801i -0.3134 + 0.9496i 0.8707 - 0.4919i 0.6079 - 0.7940i; -0.8750 - 0.4841i -0.9497 + 0.3131i -0.8134 - 0.5817i 0.9811 - 0.1937i;-0.3354 + 0.9421i 0.5805 - 0.8143i -0.2518 + 0.9678i -0.8530 + 0.5218i;-0.6454 - 0.7638i -0.9661 + 0.2582i 0.6314 + 0.7755i 0.4847 - 0.8747i]
     
    où le nombre de colonnes dans P est le même que le nombre d’éléments non nuls dans chaque ligne de M. Je voudrais multiplier rapidement chaque ligne de M (éléments non nuls) par une ligne de P. Quelqu’un peut-il m’aider s’il vous plaît? Je vous remercie!

    Meilleure réponse

  •  

    A = M.';
    A = (reshape((A(A~=0)),4,12).').*P; % The element-by-element product

     

  • MATLAB: comment substituer des cellules NaN dans une colonne (de matrice) avec le nombre valide précédent

    Salut les gars, question assez facile je suppose…
    J’ai une très grande matrice pleine de valeurs NaN, des milliers dans chaque colonne. Je dois les remplacer par la première valeur la plus ancienne disponible ..
    Disons que j’ai une colonne comme celle-ci:
    1
    2
    4
    NaN
    2
    Dans ce cas, je devrais remplacer NaN par 2. J’ai quelques complexités, par exemple je n’ai peut-être pas de matrice rectangulaire et je pourrais avoir quelques nan à la fin de la colonne… dans ce cas je devrais remplacer le nan par la première valeur  » up « .. Exemple:
    1
    3
    2
    NaN
    NaN
    Dans ce cas, le NaN doit devenir les deux 2.
    Je joins un exemple d’un petit fichier .mat prêt à faire quelques essais.
    Merci beaucoup pour l’aide.

    Meilleure réponse

  • C’est le moyen le plus rapide que j’ai pu trouver. Pas très élégant ou probablement le moyen le plus optimal mais le voici. Je commencerais par trouver la dernière valeur non NaN et la remplacer par la dernière entrée de la colonne. Cela garantit que la toute dernière entrée est un nombre. Remplace ensuite chaque valeur NaN par le numéro suivant jusqu’à ce qu’il ne reste plus de valeurs NaN dans cette colonne. Passe ensuite à la colonne suivante.
     

    iexample = Example;
    for i =1:4
    temp = iexample(:,i);
    A = isnan(temp);
    A = find(A==0);
    temp(end) = temp(A(end));
    while sum(isnan(temp))~=0
    B = isnan(temp);
    B = find(B==1);
    temp(B)=temp(B+1);
    end
    iexample(:,i)=temp;
    end

     

  • MATLAB: Deux pour les boucles, une boucle se termine pour chaque étape d’une autre boucle… Ou une meilleure façon de faire pour trouver les différentes combinaisons d’éléments dans un vecteur qui somme à la valeur cible

    J’ai deux matrices 2 × 100 (M1 et M2) de la forme suivante:
     
    Variable1 100 200 300 400 500 600 700 800 900 1000
    Output1 .60 .61 .62 .63 .64 .65 .66 .68 .67 .65
    Variable2 100 200 300 400 500 600 700 800 900 1000
    Output2 .66 .67 .68 .67 .67 .66 .67 .68 .65 .67
     
    Je veux créer une nouvelle matrice contenant les combinaisons de variable1 et variable2 où elles se situent dans une plage spécifiée, par exemple Target = 1000 (+/- 10). Donc ça ressemblerait à ça…
     
    Variable1 100 200 300 400.....
    Variable2 900 800 700 600.....
    Sum of Outputs 1.25 1.29 1.29 1.29.....
     
    J’ai commencé avec ceci:
     
    TargetLocs=(M1(1,:)+M2(1,:)<(Target+10)) & (M1(1,:)+M2(1,:)>(Target-10))
     
    Cependant, cela ne trouve qu’un exemple, où variable1 = 500 et variable2 = 500, car il boucle à travers 1 colonne à la fois. Je pense donc que je dois avoir deux boucles, comme ci-dessous, où je passe en revue j = 1: longueur (M1) pour chaque valeur de i = 1: longueur (M1)… J’ai du mal à coder cela, et une partie de moi pense qu’il y a probablement une façon plus efficace de le faire?
     
    TargetLocs=(M1(1,(i))+M2(1,(j))<(Target+10)) & (M1(1,(i))+M2(1,(j))>(Target-10))
     

    Meilleure réponse

  •  

    v1 = 100:100:1000; v2 = 100:100:1000;
    [V1 V2] = meshgrid(v1, v2);
    ind = find(abs(V1 + V2 - 1000) < 10);
    o1 = [.60 .61 .62 .63 .64 .65 .66 .68 .67 .65];
    o2 = [.66 .67 .68 .67 .67 .66 .67 .68 .65 .67];
    [O1 O2] = meshgrid(o1, o2);
    sumO = O1 + O2;
    [i j] = ind2sub(size(V1), ind)
    disp([v1(i); v2(j); sumO(ind)'])

     

  • MATLAB: Comment échanger des lignes de matrice en fonction de la distance

    salut les gars, j’ai la matrice A suivante avec la distance D1 et la matrice B avec la distance D2.
    je veux un code pour échanger des lignes A avec des lignes B qui ont une distance plus élevée, comme déplacer la ligne 2 dans B vers la matrice A ligne 2 et supprimer l’ancienne ligne 2 dans A. la sortie devrait être:
    comment faire ça les gars?

    Meilleure réponse

  • Hum, je suis sûr d’avoir vu une question très similaire (même illustration) dans le passé. Est-ce des devoirs?
    trouverl’index des lignes que vous souhaitez échanger:
     
    idx = find(D2 > D1);
     
    Et utilisez-le pour copier les lignes de B dans A:
     
    A(idx, :) = B(idx, :);
     
    Ou, en utilisant l’indexation logique:
     

    A(D2>D1, :) = B(D2>D1);

     

  • MATLAB: Comment créer une matrice dans une boucle for spécifique

    J’utilise une boucle for avec la fonction « fminsearch » et je souhaite enregistrer les données dans une matrice, à chaque itération de la boucle for dans la cellule suivante, plutôt que de remplacer le nom de la variable à chaque itération.
    Voici le code que j’ai:
     
    options = optimset();
    for i=1:7
    best_fit_eff(i) = fminsearch(@curvefit, [1,1], options, dose, D_eff(:,i));
    end
     
    Et j’obtiens une erreur affichant « Dans une affectation A (I) = B, le nombre d’éléments dans B et moi doit être le même. »
    S’il supprime le (i) après best_fit_eff, il fonctionnerait correctement, mais Matlab ne conserverait que le meilleur ajustement de la 7e itération, mais je veux une matrice avec les meilleures valeurs d’ajustement de toutes les itérations. Quelqu’un peut-il m’aider s’il-vous-plaît?

    Meilleure réponse

  • J’ai en fait posé cette question il n’y a pas si longtemps. Ce que vous devez faire ici est de créer une autre variable dans la boucle for et de stocker la valeur de best_fit_eff dans le tableau après chaque itération. Voici le code que vous pourriez éventuellement utiliser pour contourner ce problème. De plus, il semble que votre best_fit_eff génère un vecteur avec deux valeurs supérieures à une, donc dans le code ci-dessous, j’ai attribué la première valeur à une variable appelée « param1 » et la deuxième valeur à « param2 ». Cela devrait fonctionner sans aucune erreur. Faites-moi savoir si ce n’est pas le cas!
     

    options = optimset();
    for i=1:7
    best_fit_eff = fminsearch(@curvefit,[1,1], options, dose, D_eff(:,i));
    param1(i) = best_fit_eff(1);
    param2(i) = best_fit_eff(2);
    end