36 #define LONG_MAX 2147483647
45 #define MIJ(m,i,j) m.elements[(i) * m.cols + (j)]
58 #define MI(m,i) m.elements[i]
80 matrix.
size = rows * cols;
95 matrix.
size = rows * cols;
96 ArrayBuild(matrix.
elements, elements);
108 matrix.
size = rows * cols;
110 for (
int i = 0, j = 0; i < rows; i++, j++)
123 matrix.
size = rows * cols;
125 for (
int i = 0, j = 0; i < rows; i++, j++)
126 matrix.
elements[i * cols + j] = value;
157 for (
int i = 0; i < matrixA.
size; i++)
158 if (
MI(matrixA, i) !=
MI(matrixB, i))
169 for (
int i = 0; i < matrix.
size; i++)
170 flag |=
MI(matrix, i);
171 if (flag)
return false;
181 ASSERT(matrix.
rows == matrix.
cols,
"Matrix is not square");
183 for (
int i = 0; i < matrix.
rows; i++)
184 for (
int j = i; j < matrix.
cols; j++)
201 for (
int i = 0; i < matrix.
size; i++)
203 long element = Abs(
MI(matrix, i));
204 if (element > maxima)
217 long minima = LONG_MAX;
218 for (
int i = 0; i < matrix.
size; i++)
220 long element = Abs(
MI(matrix, i));
221 if (element && element < minima)
233 for (
int i = 0; i < matrix.
size; i++)
234 MI(matrix, i) <<= numShift;
243 for (
int i = 0; i < matrix.
size; i++)
244 MI(matrix, i) >>= numShift;
253 "Matrix Addtion invalid size");
255 for (
int i = 0; i < matrixA.
size; i++)
256 MI(matrixA, i) =
MI(matrixA, i) +
MI(matrixB, i);
265 "Matrix Addtion invalid size");
267 for (
int i = 0; i < matrixA.
size; i++)
268 MI(matrixA, i) =
MI(matrixA, i) -
MI(matrixB, i);
278 ASSERT(matrixA.
cols == matrixB.
rows,
"Mismatch matrix sizes");
281 for (
int i = 0; i < matrixA.
rows; i++)
282 for (
int j = 0; j < matrixB.
cols; j++)
283 for (
int k = 0; k < matrixA.
cols; k++)
294 for (
int i = 0; i < matrix.
size; i++)
295 MI(matrix, i) *= scale;
303 for (
int i = 0; i < matrix.
size; i++)
304 MI(matrix, i) /= scale;
316 ASSERT(matrix.
rows == matrix.
cols,
"Matrix is not square");
317 ASSERT(matrix.
rows > 1,
"Matrix is not > 1x1");
320 for (
int i = 0; i < matrix.
rows; i++)
322 if (i == minorI)
continue;
323 for (
int j = 0; j < matrix.
cols; j++)
325 if (j == minorJ)
continue;
340 ASSERT(matrix.
rows == matrix.
cols,
"Matrix is not square");
341 ASSERT(matrix.
rows > 0 && matrix.
rows <= 3,
"Invalid matrix size");
343 if (matrix.
rows == 1)
344 return MI(matrix, 0);
345 if (matrix.
rows == 2)
346 return MI(matrix, 0) *
MI(matrix, 3) -
MI(matrix, 2) *
MI(matrix, 1);
348 MI(matrix, 0) *
MI(matrix, 4) *
MI(matrix, 8) -
349 MI(matrix, 0) *
MI(matrix, 5) *
MI(matrix, 7) -
350 MI(matrix, 1) *
MI(matrix, 3) *
MI(matrix, 8) +
351 MI(matrix, 1) *
MI(matrix, 5) *
MI(matrix, 6) +
352 MI(matrix, 2) *
MI(matrix, 3) *
MI(matrix, 7) -
353 MI(matrix, 2) *
MI(matrix, 4) *
MI(matrix, 6) ;
371 long minorDet;
int x;
int flip;
int row;
374 RecurseData stack[10];
383 ASSERT(matrixIn.
rows == matrixIn.
cols,
"Matrix is not square");
384 ASSERT(matrixIn.
rows >= 1,
"Matrix is not >= 1x1");
385 if (matrixIn.
rows == 1)
390 ArrayInit(stack, frame, matrixIn.
rows);
391 ArrayInit(matrixStack, matrix, matrixIn.
rows);
397 matrixStack[0] = matrixIn;
406 if ((frame.i + frame.j) & 1) frame.flip = -1;
420 for (frame.row = 0; frame.row < minor.
rows; frame.row++)
422 frame.x =
MatrixGet(minor, 0, frame.row);
426 int rowSave = frame.row;
433 matrixStack[l] = minor;
441 long retCofactorIJ = frame.cofactorIJ;
442 minor = matrixStack[l];
446 matrix = matrixStack[l];
450 frame.minorDet += frame.x * retCofactorIJ;
453 frame.cofactorIJ = frame.minorDet * frame.flip;
454 if (l > 0)
goto recurseExit;
455 return frame.cofactorIJ;
463 ASSERT(matrix.
rows == matrix.
cols,
"Matrix is not square");
464 ASSERT(matrix.
rows >= 1,
"Matrix size is not >= 1x1");
467 for (
int i = 0; i < matrix.
rows; i++)
468 for (
int j = 0; j < matrix.
cols; j++)
490 ASSERT(matrix.
rows == matrix.
cols,
"Matrix is not square");
495 for (
int i = 0; i < matrix.
rows; i++)
517 TextOut(0, LCD_LINE1,
"----------------------");
518 TextOut(0, LCD_LINE1, title);
519 for (
int i = 1; i <= matrix.
rows; i++)
520 for (
int j = 0; j < matrix.
cols; j++)
521 NumOut(30 * j, 63 - (8 * i),
MatrixGet(matrix, i - 1, j),
false);
523 Wait(1000 * pauseSecs);
526 inline bool checkMultiplyOverflow(
long a,
long b)
528 while (a > 0) {a <<= 1; b >>= 1;}
556 ASSERT(matrix.
rows > 0,
"Matrix invalid size");
557 ASSERT(precision > 0,
"Invalid precision");
599 long retScale = precision;
603 long dynamicRange = 1;
604 dynamicRange <<= (31/matrix.
rows);
609 while (maxima > dynamicRange) { maxima >>= 1; shiftCount++; }
622 while (retScale >= 0 && shiftCount > 0)
623 { retScale <<= 1; shiftCount--; }
624 if (retScale < 0) { shiftCount++; retScale >>= 1; }
630 if (checkMultiplyOverflow(maxima, precision))
695 int r_elementsA_trans[] = {
701 int r_elementsAB_add[] = {
707 int r_elementsAB_sub[] = {
713 int r_elementsA_scale5[] = {
719 int r_elementsCD_multi[] = {
724 int r_elementsA_minor00[] = {
729 int r_elementsA_minor11[] = {
734 int r_elementsA_adj[] = {
740 int r_elementsA3_inv[] = {
746 int r_elementsA4_adj[] = {
753 int r_elementsA5_adj[] = {
754 118, -102, -392, 18, 176,
755 44, -120, -184, 54, 94,
756 -88, 54, 275, -15, -95,
757 -64, 90, 200, 6, -86,
758 100, -36, -173, -21, 53,
766 Matrix A, A1, A2, A3, A4, A5, B, C, D, R, E, T;
861 int tick1 = CurrentTick();
862 for (
int i = 0; i < 1; i++)
866 int tick2 = CurrentTick();
867 NumOut(0, LCD_LINE1, (tick2 - tick1),
true);
871 TextOut(0, LCD_LINE1,
"Matrix passed");
long MatrixDeterminant(Matrix &matrix)
Finds the determinant of a matrix. For matrix smaller than 4x4, it is exactly same as MatrixDetermina...
long MatrixInverse(Matrix matrix, long precision, Matrix &retInverse)
Finds the inverse of a matrix. The inverted matix is scalled by the returned scale factor...
void MatrixInitDiagonal(Matrix &matrix, int rows, int cols, long value)
Initializes a matrix to a diagonal matrix of size rows x cols, with all elements except diagonal elem...
void MatrixMinor(Matrix &matrix, int minorI, int minorJ, Matrix &matrixM)
Computes a minor matrix, designated Minor (i,j), for the given matrix and returns it in matrixM...
The matrix class. Don't access the members directly. Use the macros MIJ() or MI() or the methods prov...
bool MatrixIsNull(Matrix &matrix)
Returns true if the matrix is NULL, i.e. all elemants are 0.
void MatrixSet(Matrix &matrix, int row, int col, long value)
Sets the given value to the element in matrix given by row x col. This is exactly same as assigning t...
void MatrixCofactor(Matrix &matrix, Matrix &retCofactor)
Finds the cofactor matrix of a given matrix. Cofactor matrix is a matrix with each element (i...
void MatrixInit(Matrix &matrix, int rows, int cols)
Initializes a matrix to a matrix of size rows x cols and fills it with 0s.
void MatrixScale(Matrix &matrix, long scale)
Scales all elements in matrix A by given scale factor. i.e. A *= scale.
void MatrixAdjugate(Matrix &matrix, Matrix &retAdjugate)
Finds the adjugate (aka ajoint) of a matrix. Adjugate of a matrix is basically a transpose of its cof...
void MatrixMultiply(Matrix &matrixA, Matrix &matrixB, Matrix &matrixC)
Multiplies matrix A with B and stores the result in matrix C. i.e. C = A * B. Matrix C must not be sa...
void MatrixAdd(Matrix &matrixA, Matrix &matrixB)
Adds matrix B to matrix A. i.e. A += B.
void MatrixShiftLeft(Matrix &matrix, int numShift)
Binary shifts all elements of the matrix right by the amount numShift.
Debugging utility macros.
void MatrixInitElements(Matrix &matrix, int rows, int cols, long &elements[])
Initializes a matrix to a matrix of size rows x cols and fills it with elements from given array...
void MatrixSubtract(Matrix &matrixA, Matrix &matrixB)
Subtracts matrix B from matrix A. i.e. A -= B.
void MatrixShiftRight(Matrix &matrix, int numShift)
Binary shifts all elements of the matrix left by the amount numShift.
bool MatrixCompare(Matrix &matrixA, Matrix &matrixB)
Compares the two matrixes. A and B, and returns true if they are equal otherwise returns false...
void MatrixTranspose(Matrix &matrix)
Converts the given matrix into its Transpose, i.e. the matrix is flipped along its diagonal (top-left...
void MatrixReduce(Matrix &matrix, long scale)
Reduces (i.e. scales down) all elements in matrix A by given reduction factor. i.e. A /= scale.
long MatrixMinima(Matrix &matrix)
Returns the smallest value of 'absolute' values of elements in the matrix, discounting 0s...
#define MI(m, i)
Gives direct one-dimentional access to an element in matrix m, at the index i. Index i is calculated ...
long MatrixCofactorIJ(Matrix &matrixIn, int i, int j)
Computes and returns the cofactor of row i and col j of matrixIn.
long MatrixGet(Matrix &matrix, int row, int col)
Returns the value of element in matrix given by row x col. This is exactly same as macro MIJ()...
void MatrixInitIdentity(Matrix &matrix, int rows, int cols)
Initializes a matrix to an Identity matrix of size rows x cols, with all elements except diagonal ele...
void MatrixPrint(Matrix &matrix, string title, int pauseSecs)
Prints the matrix on screen with the given title and follows it with a wait of pauseSecs. Useful for debugging.
long MatrixDeterminant3(Matrix &matrix)
Direct diterminat computation for matrix <= 3x3 size. For larger size, see MatrixDiterminant() below...
long MatrixMaxima(Matrix &matrix)
Returns the largest value of 'absolute' values of elements in the matrix. It is useful to determine t...