Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab中的高斯消去法_Matlab_Gaussian - Fatal编程技术网

Matlab中的高斯消去法

Matlab中的高斯消去法,matlab,gaussian,Matlab,Gaussian,我正在使用本书中的matlab代码: 代码如下: 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);

我正在使用本书中的matlab代码: 代码如下:

    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);

有没有我不知道的更快的代码?这个函数我调用了数百万次,花费了太多的时间。

MATLAB有一整套内置的线性代数例程-type
help slash
help lu
help chol
,让我们开始了解一些在MATLAB中高效求解线性方程组的常用方法

在后台,这些函数通常调用优化的
LAPACK
/
BLAS
库例程,这通常是在任何编程语言中执行线性代数的最快方法。与像MATLAB这样的“慢”语言相比,如果它们比m文件实现快几个数量级,这是意料之中的


希望这能有所帮助。

除非您特别希望实现自己的,否则您应该使用Matlab的反斜杠运算符(),或者,如果您需要这些因子。请注意,mldivide可以做的不仅仅是高斯消去法(例如,在适当的情况下,它可以做线性最小二乘法)

mldivide
lu
使用的算法来自C和Fortran库,您自己在Matlab中的实现将永远不会这么快。但是,如果您决定使用自己的实现并希望它更快,那么一个选择是寻找实现矢量化的方法(可能是开始)

需要注意的另一件事是:问题的实现没有任何作用,因此它的数值稳定性通常比旋转的实现更差,对于一些非奇异矩阵,它甚至会失败

高斯消去法存在不同的变体,但它们都是O(n3)算法。如果任何一种方法优于另一种方法,则取决于您的具体情况,您需要进一步研究。

对于n×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
让我们假设Ax=d 其中A和d是已知矩阵。 我们希望使用嵌入在matlab中的“LU分解”函数将“A”表示为“LU”,因此: 勒克斯=d 这可以通过以下方式在matlab中完成: [L,U]=lu(A) 在术语中,它返回U中的上三角矩阵和L中的置换下三角矩阵,从而a=LU。返回值L是下三角矩阵和置换矩阵的乘积。()

如果我们假设Ly=d,其中y=Ux。 由于x未知,因此y也未知,通过知道y,我们发现x如下: y=L\d; x=U\y

溶液储存在x中

这是求解线性方程组的最简单方法,前提是矩阵不是奇异的(即矩阵A和d的行列式不是零),否则,解的质量将不如预期的好,并可能产生错误的结果


如果矩阵是奇异的,因此无法反演,则应使用另一种方法来求解线性方程组。

我认为您可以使用matlab函数rref:

[R,jb]=rref(A,tol)

它生成一个简化的行梯队形式的矩阵。 就我而言,这不是最快的解决方案。 在我的例子中,下面的解决方案的速度快了大约30%

function C = gauss_elimination(A,B)
i = 1; % loop variable
X = [ A B ]; 
[ nX mX ] = size( X); % determining the size of matrix  

while i <= nX % start of loop 
    if X(i,i) == 0 % checking if the diagonal elements are zero or not
        disp('Diagonal element zero') % displaying the result if there exists zero 
        return
    end
    X = elimination(X,i,i); % proceeding forward if diagonal elements are non-zero
    i = i +1;
end

C = X(:,mX);

function X = elimination(X,i,j)
% Pivoting (i,j) element of matrix X and eliminating other column
% elements to zero
[ nX mX ] = size( X); 
a = X(i,j);
X(i,:) = X(i,:)/a;

for k =  1:nX % loop to find triangular form 
    if k == i
        continue
    end
    X(k,:) = X(k,:) - X(i,:)*X(k,j); 
end
函数C=高斯消元法(A,B) i=1;%循环变量 X=[ab]; [nX mX]=尺寸(X);%确定矩阵的大小 虽然我很担心这是“幼稚”的事实。这有什么幼稚之处,如何避免?
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
function C = gauss_elimination(A,B)
i = 1; % loop variable
X = [ A B ]; 
[ nX mX ] = size( X); % determining the size of matrix  

while i <= nX % start of loop 
    if X(i,i) == 0 % checking if the diagonal elements are zero or not
        disp('Diagonal element zero') % displaying the result if there exists zero 
        return
    end
    X = elimination(X,i,i); % proceeding forward if diagonal elements are non-zero
    i = i +1;
end

C = X(:,mX);

function X = elimination(X,i,j)
% Pivoting (i,j) element of matrix X and eliminating other column
% elements to zero
[ nX mX ] = size( X); 
a = X(i,j);
X(i,:) = X(i,:)/a;

for k =  1:nX % loop to find triangular form 
    if k == i
        continue
    end
    X(k,:) = X(k,:) - X(i,:)*X(k,j); 
end