我正在使用本书中的matlab代码:http://books.google.com/books/about/Probability_Markov_chains_queues_and_sim.html?id=HdAQdzAjl60C 这是代码:
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);
是否有更快的代码我不知道?我称这个功能已经有数百万次了,而且需要花费太多时间。
答案 0 :(得分:9)
MATLAB有一整套内置线性代数例程 - 类型help slash
,help lu
或help chol
,以便开始使用一些有效求解线性方程的常用方法MATLAB。
这些函数通常会调用优化的LAPACK
/ BLAS
库例程,这通常是在任何编程语言中执行线性代数的最快方法。与像MATLAB这样的“慢”语言相比,如果它们比m文件实现快几个数量级则不会出乎意料。
希望这有帮助。
答案 1 :(得分:8)
除非您特别想要实现自己的,否则您应该使用Matlab的反斜杠运算符(mldivide
),或者,如果您需要因子lu
。请注意,mldivide可以做的不仅仅是高斯消除(例如,在适当时它会做线性最小二乘)。
mldivide
和lu
使用的算法来自C和Fortran库,而您在Matlab中的实现永远不会那么快。但是,如果您决定使用自己的实现并希望它更快,那么一种选择是寻找实现矢量化的方法(可能从here开始)。
另外需要注意的一点是:问题的实现没有做任何pivoting,因此它的数值稳定性通常会比实现旋转的实现更糟糕,而且对于某些非奇异矩阵它甚至会失败。 / p>
存在高斯消元的不同变体,但它们都是O( n 3 )算法。如果任何一种方法比另一方更好取决于您的具体情况,那么您需要进行更多调查。
答案 2 :(得分:5)
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
答案 3 :(得分:1)
假设Ax = d 其中A和d是已知矩阵。 我们想代表" A"作为" L U"使用" LU分解"因此嵌入在matlab中的函数: LUx = d 这可以在matlab中完成: [L,U] = lu(A) 在术语上,它返回U中的上三角矩阵和L中的置换下三角矩阵,使得A = L U.返回值L是下三角和置换矩阵的乘积。 (https://www.mathworks.com/help/matlab/ref/lu.html)
然后,如果我们假设Ly = d,其中y = Ux。 由于x是未知的,因此y也是未知的,通过知道我们找到x如下: ÿ= L \ d; X = U \ý
,解决方案存储在x。
中这是求解线性方程组的最简单方法,条件是矩阵不是奇异的(即矩阵A和d的行列式不是零),否则,解的质量就不如预期的那么好。可能会产生错误的结果。
如果矩阵是奇异的,因此不能反转,则应采用另一种方法求解线性方程组。
答案 4 :(得分:0)
对于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
答案 5 :(得分:0)
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
答案 6 :(得分:0)
我认为您可以使用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