float Inverse(CLAYMATRIX& mOut, const CLAYMATRIX& rhs){CLAYMATRIX m(rhs);DWORD is[4];DWORD js[4];float fDet = 1.0f;int f = 1;for (int k = 0; k <>{// 第一步,全选主元float fMax = 0.0f;for (DWORD i = k; i <>{for (DWORD j = k; j <>{const float f = Abs(m(i, j));if (f > fMax){fMax = f;is[k] = i;js[k] = j;}}}if (Abs(fMax) <>return 0;if (is[k] != k){f = -f;swap(m(k, 0), m(is[k], 0));swap(m(k, 1), m(is[k], 1));swap(m(k, 2), m(is[k], 2));swap(m(k, 3), m(is[k], 3));}if (js[k] != k){f = -f;swap(m(0, k), m(0, js[k]));swap(m(1, k), m(1, js[k]));swap(m(2, k), m(2, js[k]));swap(m(3, k), m(3, js[k]));}// 计算行列值fDet *= m(k, k);// 计算逆矩阵// 第二步m(k, k) = 1.0f / m(k, k);// 第三步for (DWORD j = 0; j <>{if (j != k)m(k, j) *= m(k, k);}// 第四步for (DWORD i = 0; i <>{if (i != k){for (j = 0; j <>{if (j != k)m(i, j) = m(i, j) - m(i, k) * m(k, j);}}}// 第五步for (i = 0; i <>{if (i != k)m(i, k) *= -m(k, k);}}for (k = 3; k >= 0; k --){if (js[k] != k){swap(m(k, 0), m(js[k], 0));swap(m(k, 1), m(js[k], 1));swap(m(k, 2), m(js[k], 2));swap(m(k, 3), m(js[k], 3));}if (is[k] != k){swap(m(0, k), m(0, is[k]));swap(m(1, k), m(1, is[k]));swap(m(2, k), m(2, is[k]));swap(m(3, k), m(3, is[k]));}}mOut = m;return fDet * f;}
Tuesday, March 24, 2009
Friday, March 6, 2009
Pseudocode of Gaussian Elimination
i := 1
j := 1
while (i ≤ m and j ≤ n) do
Find pivot in column j, starting in row i:
maxi := i
for k := i+1 to m do
if abs(A[k,j]) > abs(A[maxi,j]) then
maxi := k
end if
end for
if A[maxi,j] ≠ 0 then
swap rows i and maxi, but do not change the value of i
Now A[i,j] will contain the old value of A[maxi,j].
divide each entry in row i by A[i,j]
Now A[i,j] will have the value 1.
for u := i+1 to m do
subtract A[u,j] * row i from row u
Now A[u,j] will be 0, since A[u,j] - A[i,j] * A[u,j] = A[u,j] - 1 * A[u,j] = 0.
end for
i := i + 1
end if
j := j + 1
end while
Algorithm for Gauss-Jordan elimination in Matlab
function [A, k] = rref (A, tolerance)
## Supress empty list warnings
eleo = empty_list_elements_ok;
unwind_protect
empty_list_elements_ok = 1;
[rows,cols] = size (A);
if (nargin < 2)
tolerance = eps * max (rows, cols) * norm (A, inf);
endif
used = zeros(1,cols);
r = 1;
for c=1:cols
## Find the pivot row
[m, pivot] = max (abs (A (r:rows, c)));
pivot = r + pivot - 1;
if (m <= tolerance)
## Skip column c, making sure the approximately zero terms are
## actually zero.
A (r:rows, c) = zeros (rows-r+1, 1);
else
## keep track of bound variables
used (1, c) = 1;
## Swap current row and pivot row
A ([pivot, r], c:cols) = A ([r, pivot], c:cols);
## Normalize pivot row
A (r, c:cols) = A (r, c:cols) / A (r, c);
## Eliminate the current column
ridx = [1:r-1, r+1:rows];
A (ridx, c:cols) = A (ridx, c:cols) - A (ridx, c) * A(r, c:cols);
## Check if done
if (r++ == rows) break; endif
endif
endfor
k = find(used);
unwind_protect_cleanup
## Restore state
empty_list_elements_ok = eleo;
end_unwind_protect
endfunction