Calcolo serie tripla

di il
2 risposte

Calcolo serie tripla

Ciao,
ho un problema con una simulazione che mi dura troppo. Quello che devo fare è di calcolare una somma tripla, il problema credo che sia l'aver annidato troppi loop. Questa è la parte del mio codice che mi interessa

        
        Q = zeros(3);                                              
        
        for i = 2 : N+1
            for j = 2 : N+1
                for k = 2 : N+1
                    Q(1,1) = Q(1,1) + x(i,j,k).vettore(1)^2;
                    Q(2,2) = Q(2,2) + x(i,j,k).vettore(2)^2;
                    Q(3,3) = Q(3,3) + x(i,j,k).vettore(3)^2;
                    Q(1,2) = Q(1,2) + x(i,j,k).vettore(1)*x(i,j,k).vettore(2);
                    Q(1,3) = Q(1,3) + x(i,j,k).vettore(1)*x(i,j,k).vettore(3);
                    Q(2,3) = Q(2,3) + x(i,j,k).vettore(2)*x(i,j,k).vettore(3);
                end
            end
        end
        Q(2,1) = Q(1,2);
        Q(3,1) = Q(1,3);
        Q(3,2) = Q(2,3);
.
Premesso che N=10 e questo è gia in un ciclo da cui non posso assolutamente toglierlo, vorrei capire come fare a velocizzarlo perchè togliendolo completamente dal codice vedo che va molto veloce e quindi è probabimente la causa della lentezza. Per capirci meglio x è un array di strutture che contiene vettori di tre componenti caratterizzati dagli indici i,j,k.
Grazie mille.

2 Risposte

  • Re: Calcolo serie tripla

    Una possibile soluzione per velocizzare l'esecuzione del codice, consiste nell'eliminare i tre cicli for.

    Per eliminare i cicli for occorre estrarre i valori contenuti nei campi "vettore" della struttura "x" e costruire, con essi una matrice.
    Una volta disponibile l matrice, si può utilizzare la "vettorizzazione" dei calcoli offerta da MatLab.

    Il codice che segue, implementa la soluzione proposta.
    N=11;
    % Creazione struttura dati di input
    for i=1:N
       for j=1:N
          for k=1:N
    %          x(i,j,k).vettore=[i j k];
             x(i,j,k).vettore=rand(1,3);
          end
       end
    end
    % Inizializzazione delle matrici di output "new_Q" e "Q"
    new_Q = zeros(3);
    Q = zeros(3);
    % Ridefinizione della varaibile N per compensare gli indici dei loops
    N=N-1;
    % Inizializzazione misurazione tempo di esecuzione
    t_s=tic;
    % Estrazioine di tutti i vettori dalla struttura in un unico vettore
    tmp=[x(2:end,2:end,2:end).vettore];
    % Reshape del vettore per formare una matrice: ogni riga contiene i dati di
    % un "vettore"
    tmp1=reshape(tmp,3,length(tmp)/3).';
    % Calcolo dei valori corrispondenti agli elementi della matrice "Q"
    new_Q(1,1)=sum(tmp1(:,1).^2);
    new_Q(2,2)=sum(tmp1(:,2).^2);
    new_Q(3,3)=sum(tmp1(:,3).^2);
    
    new_Q(1,2)=sum(tmp1(:,1).*tmp1(:,2));
    new_Q(1,3)=sum(tmp1(:,1).*tmp1(:,3));
    new_Q(2,3)=sum(tmp1(:,2).*tmp1(:,3));
    
    new_Q(2,1) = new_Q(1,2);
    new_Q(3,1) = new_Q(1,3);
    new_Q(3,2) = new_Q(2,3);
    
    % Determinazine del tempo di esecuzione
    disp(['Durata calcolo matrice "Q" senza cicli for=' num2str(toc(t_s))])
    %
    % Calcolo originale con 3 cicli for
    %
    % Inizializzazione misurazione tempo di esecuzione
    t_s=tic;
    for i = 2 : N+1
       for j = 2 : N+1
          for k = 2 : N+1
             Q(1,1) = Q(1,1) + x(i,j,k).vettore(1)^2;
             Q(2,2) = Q(2,2) + x(i,j,k).vettore(2)^2;
             Q(3,3) = Q(3,3) + x(i,j,k).vettore(3)^2;
             Q(1,2) = Q(1,2) + x(i,j,k).vettore(1)*x(i,j,k).vettore(2);
             Q(1,3) = Q(1,3) + x(i,j,k).vettore(1)*x(i,j,k).vettore(3);
             Q(2,3) = Q(2,3) + x(i,j,k).vettore(2)*x(i,j,k).vettore(3);
          end
       end
    end
    Q(2,1) = Q(1,2);
    Q(3,1) = Q(1,3);
    Q(3,2) = Q(2,3);
    % Determinazine del tempo di esecuzione
    disp(['Durata calcolo matrice "Q" senza cicli for=' num2str(toc(t_s))])
    
    % Verifica dei risultati
    Q-new_Q
    
    
    Hope this helps.
  • Re: Calcolo serie tripla

    Perfetto grazie mille!!
Devi accedere o registrarti per scrivere nel forum
2 risposte