libnxter  0.1
Matrix.nxc
Go to the documentation of this file.
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3  Matrix.nxc
4  Copyright (C) 2008 Naba Kumar <naba@gnome.org>
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20 
27 #ifndef __MATRIX_H_
28 #define __MATRIX_H_
29 
30 //#define ENABLE_DEBUG
31 //#define ENABLE_TEST
32 #include "Debug.nxc"
33 //#define ASSERT(a,b)
34 //#define TEST(a,b)
35 
36 #define LONG_MAX 2147483647 /* 2^31 - 1 */
37 
45 #define MIJ(m,i,j) m.elements[(i) * m.cols + (j)]
46 
58 #define MI(m,i) m.elements[i]
59 
64 struct Matrix
65 {
66  long elements[];
67  int rows;
68  int cols;
69  int size;
70 };
71 
76 void MatrixInit(Matrix &matrix, int rows, int cols)
77 {
78  matrix.rows = rows;
79  matrix.cols = cols;
80  matrix.size = rows * cols;
81  ArrayInit(matrix.elements, 0, matrix.size);
82 }
83 
91 void MatrixInitElements(Matrix &matrix, int rows, int cols, long &elements[])
92 {
93  matrix.rows = rows;
94  matrix.cols = cols;
95  matrix.size = rows * cols;
96  ArrayBuild(matrix.elements, elements);
97 }
98 
104 void MatrixInitIdentity(Matrix &matrix, int rows, int cols)
105 {
106  matrix.rows = rows;
107  matrix.cols = cols;
108  matrix.size = rows * cols;
109  ArrayInit(matrix.elements, 0, matrix.size);
110  for (int i = 0, j = 0; i < rows; i++, j++)
111  matrix.elements[i * cols + j] = 1;
112 }
113 
119 void MatrixInitDiagonal(Matrix &matrix, int rows, int cols, long value)
120 {
121  matrix.rows = rows;
122  matrix.cols = cols;
123  matrix.size = rows * cols;
124  ArrayInit(matrix.elements, 0, matrix.size);
125  for (int i = 0, j = 0; i < rows; i++, j++)
126  matrix.elements[i * cols + j] = value;
127 }
128 
133 inline long MatrixGet(Matrix &matrix, int row, int col)
134 {
135  return matrix.elements[matrix.cols * row + col];
136 }
137 
142 inline void MatrixSet(Matrix &matrix, int row, int col, long value)
143 {
144  matrix.elements[matrix.cols * row + col] = value;
145 }
146 
152 bool MatrixCompare (Matrix &matrixA, Matrix &matrixB)
153 {
154  if (matrixA.rows != matrixB.rows || matrixA.cols != matrixB.cols)
155  return false;
156 
157  for (int i = 0; i < matrixA.size; i++)
158  if (MI(matrixA, i) != MI(matrixB, i))
159  return false;
160  return true;
161 }
162 
166 bool MatrixIsNull (Matrix &matrix)
167 {
168  long flag;
169  for (int i = 0; i < matrix.size; i++)
170  flag |= MI(matrix, i);
171  if (flag) return false;
172  return true;
173 }
174 
179 void MatrixTranspose (Matrix &matrix)
180 {
181  ASSERT(matrix.rows == matrix.cols, "Matrix is not square");
182 
183  for (int i = 0; i < matrix.rows; i++)
184  for (int j = i; j < matrix.cols; j++)
185  if (i != j)
186  {
187  long tmp1 = MatrixGet(matrix, i, j);
188  long tmp2 = MatrixGet(matrix, j, i);
189  MatrixSet(matrix, i, j, tmp2);
190  MatrixSet(matrix, j, i, tmp1);
191  }
192 }
193 
198 long MatrixMaxima (Matrix &matrix)
199 {
200  long maxima = 0;
201  for (int i = 0; i < matrix.size; i++)
202  {
203  long element = Abs(MI(matrix, i));
204  if (element > maxima)
205  maxima = element;
206  }
207  return maxima;
208 }
209 
215 long MatrixMinima (Matrix &matrix)
216 {
217  long minima = LONG_MAX;
218  for (int i = 0; i < matrix.size; i++)
219  {
220  long element = Abs(MI(matrix, i));
221  if (element && element < minima)
222  minima = element;
223  }
224  return minima;
225 }
226 
230 inline void MatrixShiftLeft (Matrix &matrix, int numShift)
231 {
232  if (numShift)
233  for (int i = 0; i < matrix.size; i++)
234  MI(matrix, i) <<= numShift;
235 }
236 
240 inline void MatrixShiftRight (Matrix &matrix, int numShift)
241 {
242  if (numShift)
243  for (int i = 0; i < matrix.size; i++)
244  MI(matrix, i) >>= numShift;
245 }
246 
250 inline void MatrixAdd (Matrix &matrixA, Matrix &matrixB)
251 {
252  ASSERT(matrixA.rows == matrixB.rows && matrixB.cols == matrixB.cols,
253  "Matrix Addtion invalid size");
254 
255  for (int i = 0; i < matrixA.size; i++)
256  MI(matrixA, i) = MI(matrixA, i) + MI(matrixB, i);
257 }
258 
262 inline void MatrixSubtract (Matrix &matrixA, Matrix &matrixB)
263 {
264  ASSERT(matrixA.rows == matrixB.rows && matrixB.cols == matrixB.cols,
265  "Matrix Addtion invalid size");
266 
267  for (int i = 0; i < matrixA.size; i++)
268  MI(matrixA, i) = MI(matrixA, i) - MI(matrixB, i);
269 }
270 
276 void MatrixMultiply (Matrix &matrixA, Matrix &matrixB, Matrix &matrixC)
277 {
278  ASSERT(matrixA.cols == matrixB.rows, "Mismatch matrix sizes");
279 
280  MatrixInit(matrixC, matrixA.rows, matrixB.cols);
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++)
284  MatrixSet(matrixC, i, j, (MatrixGet(matrixC, i, j) +
285  MatrixGet(matrixA, i, k) * MatrixGet(matrixB, k, j)));
286 }
287 
292 inline void MatrixScale (Matrix &matrix, long scale)
293 {
294  for (int i = 0; i < matrix.size; i++)
295  MI(matrix, i) *= scale;
296 }
297 
301 inline void MatrixReduce (Matrix &matrix, long scale)
302 {
303  for (int i = 0; i < matrix.size; i++)
304  MI(matrix, i) /= scale;
305 }
306 
312 void MatrixMinor(Matrix &matrix, int minorI, int minorJ, Matrix &matrixM)
313 {
314  int mI = 0, mJ = 0;
315 
316  ASSERT(matrix.rows == matrix.cols, "Matrix is not square");
317  ASSERT(matrix.rows > 1, "Matrix is not > 1x1");
318 
319  MatrixInit(matrixM, matrix.rows - 1, matrix.cols - 1);
320  for (int i = 0; i < matrix.rows; i++)
321  {
322  if (i == minorI) continue;
323  for (int j = 0; j < matrix.cols; j++)
324  {
325  if (j == minorJ) continue;
326  MatrixSet(matrixM, mI, mJ, MatrixGet(matrix, i, j));
327  mJ++;
328  }
329  mJ = 0;
330  mI++;
331  }
332 }
333 
339 {
340  ASSERT(matrix.rows == matrix.cols, "Matrix is not square");
341  ASSERT(matrix.rows > 0 && matrix.rows <= 3, "Invalid matrix size");
342 
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);
347  return
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) ;
354 }
355 
366 long MatrixCofactorIJ (Matrix &matrixIn, int i, int j)
367 {
368  struct RecurseData
369  {
370  int i; int j; /* Inputs to the frame */
371  long minorDet; int x; int flip; int row; /* Intermediate variables in frame */
372  long cofactorIJ; /* Output from the frame */
373  };
374  RecurseData stack[10];
375  RecurseData frame;
376 
377  /* Separate stack for matrices because NXC doesn't seem to work
378  * with array of struct of struct so can't use RecurseData for them.
379  */
380  Matrix matrixStack[];
381  Matrix minor, matrix;
382 
383  ASSERT(matrixIn.rows == matrixIn.cols, "Matrix is not square");
384  ASSERT(matrixIn.rows >= 1, "Matrix is not >= 1x1");
385  if (matrixIn.rows == 1)
386  return 1;
387 
388  int l = 0;
389  /* Depth of the recursion tree is N */
390  ArrayInit(stack, frame, matrixIn.rows);
391  ArrayInit(matrixStack, matrix, matrixIn.rows);
392 
393  /* Set frame 0 */
394  frame.i = i;
395  frame.j = j;
396  stack[0] = frame;
397  matrixStack[0] = matrixIn;
398  matrix = matrixIn; //matrixStack[l];
399 
400 recurseEnter:
401  /* C(i,j) = (-1)^(i+j) |M(i,j)| */
402 
403  frame.minorDet = 0;
404 
405  /* flip = (-1)^(i + j) */
406  if ((frame.i + frame.j) & 1) frame.flip = -1;
407  else frame.flip = 1;
408 
409  /* Get Minor(i,j) */
410  MatrixMinor(matrix, frame.i, frame.j, minor);
411 
412  /* Compute minor determinant |M| */
413  if (minor.rows < 4)
414  {
415  frame.minorDet = MatrixDeterminant3(minor);
416  }
417  else
418  {
419  /* |M| = m(0,1) * Cm(0,1) + m(0,2) * Cm(0,2) + .. + m(0,n) * Cm(0,n) */
420  for (frame.row = 0; frame.row < minor.rows; frame.row++)
421  {
422  frame.x = MatrixGet(minor, 0, frame.row);
423 
424  /* Push frame: Prepare for recursion. */
425  stack[l] = frame;
426  int rowSave = frame.row;
427  /* Push end */
428 
429  /* Set next frame */
430  l++;
431  frame.i = 0;
432  frame.j = rowSave;
433  matrixStack[l] = minor;
434  matrix = minor;
435 
436  goto recurseEnter;
437  /* Doing: retCofactorIJ = MatrixCofactorIJ(minor, 0, row) */
438 
439 recurseExit:
440  /* Result of last frame */
441  long retCofactorIJ = frame.cofactorIJ;
442  minor = matrixStack[l];
443 
444  /* Pop frame from stack */
445  l--;
446  matrix = matrixStack[l];
447  frame = stack[l];
448  /* Pop end */
449 
450  frame.minorDet += frame.x * retCofactorIJ;
451  }
452  }
453  frame.cofactorIJ = frame.minorDet * frame.flip;
454  if (l > 0) goto recurseExit;
455  return frame.cofactorIJ;
456 }
457 
461 void MatrixCofactor (Matrix &matrix, Matrix &retCofactor)
462 {
463  ASSERT(matrix.rows == matrix.cols, "Matrix is not square");
464  ASSERT(matrix.rows >= 1, "Matrix size is not >= 1x1");
465 
466  MatrixInit(retCofactor, matrix.rows, matrix.cols);
467  for (int i = 0; i < matrix.rows; i++)
468  for (int j = 0; j < matrix.cols; j++)
469  {
470  long cofac = MatrixCofactorIJ(matrix, i, j);
471  MatrixSet(retCofactor, i, j, cofac);
472  }
473 }
474 
485 long MatrixDeterminant (Matrix &matrix)
486 {
487  if (matrix.rows < 4)
488  return MatrixDeterminant3(matrix);
489 
490  ASSERT(matrix.rows == matrix.cols, "Matrix is not square");
491 
492  /* |A| = a(0,1) * C(0,1) + a(0,2) * C(0,2) + ... + a(0,n) * C(0,n) */
493 
494  long det = 0;
495  for (int i = 0; i < matrix.rows; i++)
496  det += MatrixGet(matrix, 0, i) * MatrixCofactorIJ(matrix, 0, i);
497  return det;
498 }
499 
504 void MatrixAdjugate (Matrix &matrix, Matrix &retAdjugate)
505 {
506  MatrixCofactor(matrix, retAdjugate);
507  MatrixTranspose(retAdjugate);
508 }
509 
514 void MatrixPrint (Matrix &matrix, string title, int pauseSecs)
515 {
516  ClearScreen();
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);
522  if (pauseSecs > 0)
523  Wait(1000 * pauseSecs);
524 }
525 
526 inline bool checkMultiplyOverflow(long a, long b)
527 {
528  while (a > 0) {a <<= 1; b >>= 1;}
529  if (b) /* overflow */
530  return true;
531  return false;
532 }
533 
554 long MatrixInverse (Matrix matrix, long precision, Matrix &retInverse)
555 {
556  ASSERT(matrix.rows > 0, "Matrix invalid size");
557  ASSERT(precision > 0, "Invalid precision");
558 
599  long retScale = precision;
600 
601  /* Determine dynamic range of the input matrix */
602  long maxima = MatrixMaxima(matrix);
603  long dynamicRange = 1;
604  dynamicRange <<= (31/matrix.rows);
605  dynamicRange--; /* 2^(31/N) - 1 */
606 
607  /* Reduce the input to fit in above dynamic range */
608  int shiftCount = 0;
609  while (maxima > dynamicRange) { maxima >>= 1; shiftCount++; }
610  MatrixShiftRight(matrix, shiftCount);
611 
612  /* Find matrix adjugate and determinant for computing inverse. */
613  MatrixAdjugate(matrix, retInverse);
614  long det = MatrixDeterminant(matrix);
615 
616  /* Neutralize the dynamic range adjustments: First try increasing
617  * scale factor as much as it can hold and then the rest in the matrix.
618  * We shift the precision right
619  * (effectively, dividing it by 2 each time) until it is 1 and at
620  * the same time decrease shiftCount for residual factor.
621  */
622  while (retScale >= 0 && shiftCount > 0)
623  { retScale <<= 1; shiftCount--; }
624  if (retScale < 0) { shiftCount++; retScale >>= 1; }
625  if (shiftCount > 0) MatrixShiftRight(retInverse, shiftCount);
626 
627  /* Find the largest integer in matrix. */
628  maxima = MatrixMaxima(retInverse);
629 
630  if (checkMultiplyOverflow(maxima, precision))
631  det /= precision; /* Overflow detected: Apply the scale on det */
632  else
633  MatrixScale(retInverse, precision); /* No overflow */
634  MatrixReduce(retInverse, det);
635  return retScale;
636 }
637 
638 /* Tests */
639 
640 #ifdef ENABLE_TEST
641 
642 int elementsA[] = {
643 -3, 2, -5,
644 -1, 0, -2,
645  3, -4, 1,
646 };
647 
648 int elementsA1[] = {
649 -3,
650 };
651 
652 int elementsA2[] = {
653 -3, 2,
654 -1, 4,
655 };
656 
657 int elementsA3[] = {
658 -2, 2, -3,
659 -1, 1, 3,
660  2, 0, -1,
661 };
662 
663 int elementsA4[] = {
664  2, 5, 1, -3,
665 -2, -3, 2, 6,
666  1, 0, 2, 1,
667  0, 2, 2, 1,
668 };
669 
670 int elementsA5[] = {
671 1, 2, 3, 4, 5,
672 2, -1, 0, 3, 0,
673 2, 1, 4, 2, 2,
674 0, 3, -1, 5, 1,
675 6, 0, 7, 3, 1
676 };
677 
678 int elementsB[] = {
679  4, 1, -6,
680 -1, -3, 1,
681 -3, 2, 2,
682 };
683 
684 int elementsC[] = {
685  1, 0, 2,
686 -1, 3, 1,
687 };
688 
689 int elementsD[] = {
690 3, 1,
691 2, 1,
692 1, 0,
693 };
694 
695 int r_elementsA_trans[] = {
696 -3, -1, 3,
697  2, 0, -4,
698 -5, -2, 1,
699 };
700 
701 int r_elementsAB_add[] = {
702  1, 3, -11,
703 -2, -3, -1,
704  0, -2, 3,
705 };
706 
707 int r_elementsAB_sub[] = {
708 -7, 1, 1,
709  0, 3, -3,
710  6, -6, -1,
711 };
712 
713 int r_elementsA_scale5[] = {
714 -15, 10, -25,
715  -5, 0, -10,
716  15, -20, 5,
717 };
718 
719 int r_elementsCD_multi[] = {
720 5, 1,
721 4, 2,
722 };
723 
724 int r_elementsA_minor00[] = {
725  0, -2,
726 -4, 1,
727 };
728 
729 int r_elementsA_minor11[] = {
730 -3, -5,
731  3, 1,
732 };
733 
734 int r_elementsA_adj[] = {
735 -8, 18, -4,
736 -5, 12, -1,
737  4, -6, 2,
738 };
739 
740 int r_elementsA3_inv[] = {
741  -55, 111, 500,
742  277, 444, 500,
743 -111, 222, 0,
744 };
745 
746 int r_elementsA4_adj[] = {
747 -20, -14, -5, 29,
748 -10, -7, 6, 6,
749 19, 15, -8, -25,
750 -18, -16, 4, 21,
751 };
752 
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,
759 };
760 
764 void TestMatrix()
765 {
766  Matrix A, A1, A2, A3, A4, A5, B, C, D, R, E, T;
767  MatrixInitElements(A, 3, 3, elementsA);
768  MatrixInitElements(A1, 1, 1, elementsA1);
769  MatrixInitElements(A2, 2, 2, elementsA2);
770  MatrixInitElements(A3, 3, 3, elementsA3);
771  MatrixInitElements(A4, 4, 4, elementsA4);
772  MatrixInitElements(A5, 5, 5, elementsA5);
773  MatrixInitElements(B, 3, 3, elementsB);
774  MatrixInitElements(C, 2, 3, elementsC);
775  MatrixInitElements(D, 3, 2, elementsD);
776 
777  /* Test Transpose */
778  MatrixTranspose(A);
779  MatrixInitElements(E, 3, 3, r_elementsA_trans);
780  TEST(MatrixCompare(E, A), "Matrix Transpose");
781  //MatrixPrint(A);
782  MatrixTranspose(A);
783 
784  /* Test Addition */
785  R = A;
786  MatrixAdd(R, B);
787  MatrixInitElements(E, 3, 3, r_elementsAB_add);
788  TEST(MatrixCompare(E, R), "Matrix Addition");
789  //MatrixPrint(R);
790 
791  /* Test Subtraction */
792  R = A;
793  MatrixSubtract(R, B);
794  MatrixInitElements(E, 3, 3, r_elementsAB_sub);
795  TEST(MatrixCompare(E, R), "Matrix Subtraction");
796  //MatrixPrint(R);
797 
798  /* Test Scaling */
799  R = A;
800  MatrixScale(R, 5);
801  MatrixInitElements(E, 3, 3, r_elementsA_scale5);
802  TEST(MatrixCompare(E, R), "Matrix Scaling");
803  //MatrixPrint(R);
804 
805  /* Test Reduce */
806  MatrixReduce(R, 5);
807  TEST(MatrixCompare(A, R), "Matrix Reduction");
808  //MatrixPrint(R);
809 
810  /* Test Multiply */
811  MatrixMultiply(C, D, R);
812  MatrixInitElements(E, 2, 2, r_elementsCD_multi);
813  TEST(MatrixCompare(E, R), "Matrix Multiply");
814  //MatrixPrint(R);
815 
816  /* Test Minor A(0,0) */
817  MatrixMinor(A, 0, 0, R);
818  MatrixInitElements(E, 2, 2, r_elementsA_minor00);
819  TEST(MatrixCompare(E, R), "Matrix Minor 00");
820  //MatrixPrint(R);
821 
822  /* Test Minor A(1,1) */
823  MatrixMinor(A, 1, 1, R);
824  MatrixInitElements(E, 2, 2, r_elementsA_minor11);
825  TEST(MatrixCompare(E, R), "Matrix Minor 11");
826  //MatrixPrint(R);
827 
828  /* Test Determinants */
829  TEST((MatrixDeterminant(A1) == -3), "Matrix determinant");
830  TEST((MatrixDeterminant(A2) == -10), "Matrix determinant");
831  TEST((MatrixDeterminant(A3) == 18), "Matrix determinant");
832 
833  /* Test Cofactor (i,j) */
834  TEST((MatrixCofactorIJ(A, 0, 0) == -8), "Matrix Cofac 00");
835  TEST((MatrixCofactorIJ(A, 0, 1) == -5), "Matrix Cofac 01");
836  TEST((MatrixCofactorIJ(A, 0, 2) == 4), "Matrix Cofac 02");
837 
838  /* Test C(ij), Cofactor and Adjugate */
839  MatrixAdjugate(A, R);
840  MatrixInitElements(E, 3, 3, r_elementsA_adj);
841  TEST(MatrixCompare(E, R), "Matrix Adjugate");
842  //MatrixPrint(R);
843 
844  /* Test Inverse */
845  long scale = MatrixInverse(A3, 1000, R);
846  MatrixInitElements(E, 3, 3, r_elementsA3_inv);
847  TEST(MatrixCompare(E, R), "Matrix Inverse");
848  //MatrixPrint(R, "A3 Inv = ", 5);
849 
850 #if 0
851  MatrixAdjugate(A4, R);
852  MatrixInitElements(E, 4, 4, r_elementsA4_adj);
853  TEST(MatrixCompare(E, R), "Matrix Adjugate");
854  //MatrixPrint(R);
855 
856  MatrixAdjugate(A5, R);
857  MatrixInitElements(E, 5, 5, r_elementsA5_adj);
858  TEST(MatrixCompare(E, R), "Matrix Adjugate");
859  //MatrixPrint(R);
860 
861  int tick1 = CurrentTick();
862  for (int i = 0; i < 1; i++)
863  {
864  MatrixAdjugate(A, R);
865  }
866  int tick2 = CurrentTick();
867  NumOut(0, LCD_LINE1, (tick2 - tick1), true);
868  //MatrixPrint(R);
869 #endif
870 
871  TextOut(0, LCD_LINE1, "Matrix passed");
872 }
873 #endif /* ENABLE_TEST */
874 #endif /* _MATRIX_H_ */
875 
long MatrixDeterminant(Matrix &matrix)
Finds the determinant of a matrix. For matrix smaller than 4x4, it is exactly same as MatrixDetermina...
Definition: Matrix.nxc:485
long MatrixInverse(Matrix matrix, long precision, Matrix &retInverse)
Finds the inverse of a matrix. The inverted matix is scalled by the returned scale factor...
Definition: Matrix.nxc:554
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...
Definition: Matrix.nxc:119
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...
Definition: Matrix.nxc:312
The matrix class. Don't access the members directly. Use the macros MIJ() or MI() or the methods prov...
Definition: Matrix.nxc:64
bool MatrixIsNull(Matrix &matrix)
Returns true if the matrix is NULL, i.e. all elemants are 0.
Definition: Matrix.nxc:166
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...
Definition: Matrix.nxc:142
void MatrixCofactor(Matrix &matrix, Matrix &retCofactor)
Finds the cofactor matrix of a given matrix. Cofactor matrix is a matrix with each element (i...
Definition: Matrix.nxc:461
void MatrixInit(Matrix &matrix, int rows, int cols)
Initializes a matrix to a matrix of size rows x cols and fills it with 0s.
Definition: Matrix.nxc:76
void MatrixScale(Matrix &matrix, long scale)
Scales all elements in matrix A by given scale factor. i.e. A *= scale.
Definition: Matrix.nxc:292
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...
Definition: Matrix.nxc:504
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...
Definition: Matrix.nxc:276
int size
Definition: Matrix.nxc:69
void MatrixAdd(Matrix &matrixA, Matrix &matrixB)
Adds matrix B to matrix A. i.e. A += B.
Definition: Matrix.nxc:250
void MatrixShiftLeft(Matrix &matrix, int numShift)
Binary shifts all elements of the matrix right by the amount numShift.
Definition: Matrix.nxc:230
Debugging utility macros.
int rows
Definition: Matrix.nxc:67
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...
Definition: Matrix.nxc:91
void MatrixSubtract(Matrix &matrixA, Matrix &matrixB)
Subtracts matrix B from matrix A. i.e. A -= B.
Definition: Matrix.nxc:262
void MatrixShiftRight(Matrix &matrix, int numShift)
Binary shifts all elements of the matrix left by the amount numShift.
Definition: Matrix.nxc:240
long elements[]
Definition: Matrix.nxc:66
bool MatrixCompare(Matrix &matrixA, Matrix &matrixB)
Compares the two matrixes. A and B, and returns true if they are equal otherwise returns false...
Definition: Matrix.nxc:152
void MatrixTranspose(Matrix &matrix)
Converts the given matrix into its Transpose, i.e. the matrix is flipped along its diagonal (top-left...
Definition: Matrix.nxc:179
void MatrixReduce(Matrix &matrix, long scale)
Reduces (i.e. scales down) all elements in matrix A by given reduction factor. i.e. A /= scale.
Definition: Matrix.nxc:301
long MatrixMinima(Matrix &matrix)
Returns the smallest value of 'absolute' values of elements in the matrix, discounting 0s...
Definition: Matrix.nxc:215
#define MI(m, i)
Gives direct one-dimentional access to an element in matrix m, at the index i. Index i is calculated ...
Definition: Matrix.nxc:58
int cols
Definition: Matrix.nxc:68
long MatrixCofactorIJ(Matrix &matrixIn, int i, int j)
Computes and returns the cofactor of row i and col j of matrixIn.
Definition: Matrix.nxc:366
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()...
Definition: Matrix.nxc:133
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...
Definition: Matrix.nxc:104
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.
Definition: Matrix.nxc:514
long MatrixDeterminant3(Matrix &matrix)
Direct diterminat computation for matrix <= 3x3 size. For larger size, see MatrixDiterminant() below...
Definition: Matrix.nxc:338
long MatrixMaxima(Matrix &matrix)
Returns the largest value of 'absolute' values of elements in the matrix. It is useful to determine t...
Definition: Matrix.nxc:198