web-dev-qa-db-fra.com

Elimination gaussienne à Matlab

J'utilise le code matlab de ce livre: http://books.google.com/books/about/Probability_Markov_chains_queues_and_sim.html?id=HdAQdzAjl60C Voici le code:

    function [pi] = GE(Q)

    A = Q';
    n = size(A);
    for i=1:n-1
      for j=i+1:n
         A(j,i) = -A(j,i)/A(i,i);
      end
         for j =i+1:n
            for k=i+1:n
        A(j,k) = A(j,k)+ A(j,i) * A(i,k);
         end
      end
      end

     x(n) = 1;
      for i = n-1:-1:1
        for j= i+1:n
          x(i) = x(i) + A(i,j)*x(j);
        end
       x(i) = -x(i)/A(i,i);
      end

      pi = x/norm(x,1);

Y at-il un code plus rapide que je ne suis pas au courant? J'appelle cela des millions de fois, et cela prend trop de temps.

5
sosruko

MATLAB a tout un ensemble de routines d’algèbre linéaire intégrées - tapez help slash, help lu ou help chol pour commencer à utiliser quelques-uns des moyens courants de résoudre efficacement les équations linéaires dans MATLAB.

Sous le capot, ces fonctions appellent généralement des routines de bibliothèque LAPACK/BLAS optimisées, qui constituent généralement le moyen le plus rapide de faire de l’algèbre linéaire dans n’importe quel langage de programmation. Par rapport à un langage "lent" tel que MATLAB, il ne serait pas surprenant qu’ils soient beaucoup plus rapides que l’implémentation d’un fichier m.

J'espère que cela t'aides.

9
Darren Engwirda

À moins que vous ne cherchiez spécifiquement à implémenter les vôtres, vous devriez utiliser l'opérateur de barre oblique inverse de Matlab ( mldivide ) ou, si vous voulez les facteurs, lu . Notez que mldivide peut faire plus que l’élimination gaussienne (par exemple, il fait les moindres carrés linéaires, le cas échéant).

Les algorithmes utilisés par mldivide et lu proviennent des bibliothèques C et Fortran, et votre propre implémentation dans Matlab ne sera jamais aussi rapide. Si, toutefois, vous êtes déterminé à utiliser votre propre implémentation et souhaitez l’accélérer, une option consiste à rechercher des moyens de vectoriser votre implémentation (par exemple, démarrez ici ).

Une autre chose à noter: l'implémentation de la question ne fait aucun pivotant , donc sa stabilité numérique sera généralement pire qu'une implémentation qui pivote et elle échouera même pour certaines matrices non singulières.

Il existe différentes variantes d’élimination gaussienne, mais elles sont toutes O ( n3 ) algorithmes. Si une approche est meilleure qu’une autre, elle dépend de votre situation particulière et doit faire l’objet d’une enquête plus approfondie.

8
David Alber
function x = naiv_gauss(A,b);
n = length(b); x = zeros(n,1);
for k=1:n-1 % forward elimination
      for i=k+1:n
           xmult = A(i,k)/A(k,k);
           for j=k+1:n
             A(i,j) = A(i,j)-xmult*A(k,j);
           end
           b(i) = b(i)-xmult*b(k);
      end
end
 % back substitution
x(n) = b(n)/A(n,n);
for i=n-1:-1:1
   sum = b(i);
   for j=i+1:n
     sum = sum-A(i,j)*x(j);
   end
   x(i) = sum/A(i,i);
end
end
5
achini

Supposons que Ax = d Où A et d sont des matrices connues. Nous voulons représenter "A" par "L U" à l'aide de la fonction "Décomposition de LU" intégrée dans matlab ainsi: Lux = d Ceci peut être effectué dans matlab suivant: [L, U] = lu (A) renvoie une matrice triangulaire supérieure en U et une matrice triangulaire inférieure permutée en L telle que A = L U. La valeur de retour L est un produit de matrices triangulaires et de permutation inférieures. ( https://www.mathworks.com/help/matlab/ref/lu.html )

Alors si nous supposons Ly = d où y = Ux. Puisque x est inconnu, donc y est également inconnu, en sachant que nous trouvons x comme suit: y = L\d; x = U\y

et la solution est stockée dans x.

C’est le moyen le plus simple de résoudre un système d’équations linéaires à condition que les matrices ne soient pas singulières (c’est-à-dire que le déterminant de la matrice A et d n’est pas nul), sinon la qualité de la solution ne serait pas aussi bonne que prévu et risquerait résultats.

si les matrices sont singulières, il est donc impossible d’inverser ces méthodes, il faut utiliser une autre méthode pour résoudre le système des équations linéaires.

1
Feras Alsheet
function Sol = GaussianElimination(A,b)


[i,j] = size(A);

for j = 1:i-1


    for i = j+1:i


        Sol(i,j) = Sol(i,:) -( Sol(i,j)/(Sol(j,j)*Sol(j,:)));


    end


end


disp(Sol);


end
0
ntox

Pour l'approche naïve (c'est-à-dire sans permutation de lignes) pour une matrice n par n:

function A = naiveGauss(A)

% find's the size

n = size(A);
n = n(1);

B = zeros(n,1);

% We have 3 steps for a 4x4 matrix so we have
% n-1 steps for an nxn matrix
for k = 1 : n-1     
    for i = k+1 : n
        % step 1: Create multiples that would make the top left 1
        % printf("multi = %d / %d\n", A(i,k), A(k,k), A(i,k)/A(k,k) )
        for j = k : n
            A(i,j) = A(i,j) - (A(i,k)/A(k,k)) *  A(k,j);
        end
        B(i) = B(i) - (A(i,k)/A(k,k))  * B(k);
    end
end
0
Sean