MatrixClass
A class to handle Matrices¶
This class is intended for handling float
matrices, to re-arrange and perform operations on them, similar to a MATLAB enviroment. I haven't seen something like this for mbed, so I decided I'll make one.
I created this class using <vector>'s. I write it and debugged it in Netbeans so it can be used in any C++ program, tested with gcc. The idea is to be able to work with Neural Networks and Kinematics eventually.
I'm also working on a MatrixMath class, to give basic matrix operations to Matrix
objects. So far this class provides TRANSPOSE, DETERMINANT and INVERSE operations over a Matrix object, in a near future (hopefully) I'll add more and more operations.
This is my biggest and best C++ program, any advice or improvement is well recieved.
I hope the documentation is easy to understand, there are a few other functions I didn't cover here, and an example program here to better ilustrate the class. Matrix_Class
Ok so the Class I'm talking about is this:
Import libraryMatrix
Matrix Library. v1.6.4
Creating a Matrix object¶
To create a Matrix you need to define the number of Rows and Columns. Or use another Matrix to create an exact copy.
//This will create a 3 by 3 matrix //all elements initialized to zero. Matrix myMatrix(3,3); //This will call the Copy constructor Matrix anotherMatrix( myMatrix ); //Or just initialize a matrix to later determine its dimmensions Matrix temp;
Change the dimmensions of a Matrix¶
Say you want to resize a matrix, add more space or reduce it. In that case you use the function Resize.
But if you want to increment a new Row to the middle of the matrix, or a new column? Then you use the static function AddRow/AddCol and to delete one the functions are DeleteRow/DeleteCol.
myMatrix.Resize( 4,4 ) //Expanded Matrix dimensions Matrix::AddRow( anotherMatrix, 2 ); // Moves Rows 2,3,... down and creates a new Row where 2 used to be. Matrix::DeleteCol( anotherMatrix, 3 ); // Deletes Column 3.
Filling a Matrix¶
Now that you have a Matrix with dimensions, you can input data to it using:
//The fastest way if you know your data is myMatrix << 1 << 2 <<3 << 4 << 5 <<6 << 7 << 8 <<9; // Or ask the user to fill it. This function is VIRTUAL myMatrix.FillMatrix(); // Or change a specific element myMatrix.add( 2, 2, 0 ); // Re-writes element at position Row[2]Col[2] to a vlaue of 0 // In this case changes 5 to 0
Important
Matrix indexing starts with one, not zero, so to say the first element of Matrix is in position Row[1]Col[1].
Also, FillMatrix() is a virtual function to use with whatever Comunication protocol you want, but take a look at my implementation first for details.
The << operator
You may have noticed that the INPUT (<<) operator fills the Matrix as if it were an array, this is because the Matrix dimensions (Row, Col) have already been defined, this operand will NOT work in declared only matrices[ Matrix obj;
].
If you Resize a Matrix [ objM.Resize( n, m )
], The operand will point to the first element, so you can refill your entire matrix again.
this only works with a recently defined Matrix[ Matrix objM( n,m )
], a Resized Matrix or a Cleared Matrix[ objM.Clear()
]. If you perform transformations to your matrix the operand will have unexpected behavior. See documentation for more info.
Matrix Operations¶
Your matrices now have data, let's see what operations you can perform on them.
temp = -myMatrix + 5; // Multiplies each element in Matrix by (-1) then adds // (5) to each one. anotherMatrix *= myMatrix; // Performs Cross Product multiplication between itself and myMatrix. anotherMatrix -= myMatrix; // Decrements element-by-element. Both matrices must be same dimensions. if( anotherMatrix == myMatrix ) ) // Checks element-by-element, returns true if printf( "These two matrices are equal!\n" ); // matrices are identical. temp.Clear(); // Makes all elements in matrix zero. if( temp.isZero() ) // Will be true 'cause all elements are zero. printf( "This matrix is empty!\n" ); myMatrix.print(); // This will Oputput the matrix to the default USB RxTx port // serial 9600 8,n,1
Information
Operators also support obj1 = obj2 * obj3;
obj1 = obj2 * 0.5;
obj2 = obj1 - 5;
There are more SATATIC functions to provide more flexibility with the matrix.
WARNING!
If you haven't noticed yet the Assignment operator overwrites a Matrix, that is to say destroys whatever data the old matrix contained and puts new data into it.
So don't rely that because two Matrices are different dimensions the assignment will not occur, it will.
Your code <here>¶
This covers the basic of matrix handling and operations, but it's time to use all this and create your own programs, and these functions will help you do that.
int lengthX, lenghtY; lengthX = myMatrix.getCols(); //returns the number of columns. lengthY = myMatrix.getRows(); //returns the number of rows. int firstNumber; firstNumber = myMatrix.getNumber( 1, 1 ); //First element of Matrix. Matrix vectorM = Matrix::ToPackedArray( myMatrix ); // Flaterns Matrix. vectorM = Matrix::ExtractRow( myMatrix, 1 ); //Extracts first Row. Similar Function for Column if( vectorM.isVector() ) printf( "This is either a SingleRow or SingleColumn Matrix");
Information
As a convention I've been using a Upper case letter for functions that return a Matrix object, and lower case for those whom return floats or ints.
Scope¶
I'm looking forward to make a classTemplate with similar characteristics but for all sort of data types. I'll write another class on top of these for Kinematics, very simple at first... coding a Jacobian function will be quite a challenge.
API Versions
If you make use of this class let me know, so I can maintain the API and don't break your code with an update. But as version 1.6.2 of this class I will be maintaining the functionality.
Example Program¶
Import library
00001 #include "mbed.h" 00002 #include "Matrix.h" 00003 #include "MatrixMath.h" 00004 00005 int main() { 00006 00007 DigitalOut myled(LED1); 00008 Timer t,t2; 00009 00010 t.start(); 00011 00012 //--- 00013 Matrix myMatrix(3,3); 00014 Matrix anotherMatrix; 00015 00016 // Fill Matrix with data. 00017 myMatrix << 1 << 2 << 3 00018 << 4 << 5 << 6 00019 << 7 << 8 << 9; 00020 00021 printf( "\nmyMatrix:\n\n"); 00022 myMatrix.print(); 00023 printf( "\n" ); 00024 00025 00026 // Matrix operations // 00027 00028 // Add 5 to negative Matrix 00029 anotherMatrix = - myMatrix + 5; 00030 00031 printf( "Result Matrix: anotherMatrix = - myMatrix + 5\n\n" ); 00032 anotherMatrix.print(); 00033 printf( "\n" ); 00034 00035 // Matrix Multiplication * 00036 anotherMatrix *= myMatrix; 00037 00038 printf( "\nanotherMatrix = anotherMatrix * myMatrix\n\n" ); 00039 anotherMatrix.print(); 00040 printf( "\n" ); 00041 00042 // Scalar Matrix Multiplication anotherMatrix *= 0.5 00043 anotherMatrix *= 0.5; 00044 00045 printf( "\nResult Matrix *= 0.5:\n\n" ); 00046 anotherMatrix.print(); 00047 printf( " _______________________________ \n" ); 00048 00049 00050 printf("\n\n *** MEMBER OPERATIONS *** \n\n"); 00051 00052 //Copy myMatrix 00053 Matrix temp( myMatrix ); 00054 00055 // Resize Matrix 00056 temp.Resize(4,4); 00057 printf("\nAdded one Column, one Row to the limits of myMatrix saved in temp Matrix\n"); 00058 temp.print(); 00059 00060 //Delete those new elements, we don't need them anyway. 00061 Matrix::DeleteRow( temp, 4 ); 00062 Matrix::DeleteCol( temp, 4 ); 00063 00064 printf("\nBack to normal\n"); 00065 temp.print(); 00066 00067 00068 // Make room at the begining of Matrix 00069 Matrix::AddRow( temp, 1 ); 00070 Matrix::AddCol( temp, 1 ); 00071 00072 printf("\nAdded Just one Row and column to the beginning\n"); 00073 temp.print(); 00074 00075 // Take the second Row as a new Matrix 00076 anotherMatrix = Matrix::ExportRow( temp, 2 ); 00077 printf("\nExport Second Row \n"); 00078 anotherMatrix.print(); 00079 00080 // The second Column as a new Matrix, then transpose it to make it a Row 00081 anotherMatrix = Matrix::ExportCol( temp, 2 ); 00082 anotherMatrix = MatrixMath::Transpose( anotherMatrix ); 00083 printf("\nAnd Export Second Column and Transpose it \n"); 00084 anotherMatrix.print(); 00085 00086 // This will Check to see if your are reduce to a single Row or Column 00087 temp = Matrix::ToPackedVector( myMatrix ); 00088 printf("\nInitial Matrix turned into a single Row\n"); 00089 temp.print(); 00090 00091 // Matrix Math // 00092 printf("\n\n *** Matrix Inverse and Determinant ***\n"); 00093 00094 Matrix BigMat( 8, 8 ); 00095 00096 BigMat << 1 << 0.3 << 1.0 << 1 << 3 << 0.5 << 7.12 << 899 00097 << 2 << 3.2 << 4.1 << 0 << 4 << 0.8 << 9.26 << 321 00098 << 5 << 6.0 << 1 << 1 << 2 << 7.4 << 3.87 << 562 00099 << 1 << 0.0 << 2.7 << 1 << 1 << 4.6 << 1.21 << 478 00100 << 2 << 3.7 << 48 << 2 << 0 << 77 << 0.19 << 147 00101 << 1 << 1.0 << 3.8 << 7 << 1 << 9.9 << 7.25 << 365 00102 << 9 << 0.9 << 2.7 << 8 << 0 << 13 << 4.16 << 145 00103 << 7 << 23 << 28 << 9 << 9 << 1.7 << 9.16 << 156; 00104 00105 printf( "\nBigMat:\n"); 00106 BigMat.print(); 00107 printf( "\n" ); 00108 00109 t2.start(); 00110 float determ = MatrixMath::det( BigMat ); 00111 00112 Matrix myInv = MatrixMath::Inv( BigMat ); 00113 t2.stop(); 00114 00115 printf( "\nBigMat's Determinant is: %f \n", determ); 00116 printf( "\n" ); 00117 00118 printf( "\nBigMat's Inverse is:\n"); 00119 myInv.print(); 00120 printf( "\n" ); 00121 00122 //*** Homogenous Transformations **// 00123 00124 printf( "\n\n *** TRANSFORMATIONS *** \n\n"); 00125 00126 Matrix rot; 00127 00128 printf( " RotX 0.5 rad \n" ); 00129 rot = MatrixMath::RotX(0.5); 00130 rot.print(); 00131 printf( " _______________________________ \n\n" ); 00132 00133 printf( " RotY 0.5 rad \n" ); 00134 rot = MatrixMath::RotY(0.5); 00135 rot.print(); 00136 printf( " _______________________________ \n\n" ); 00137 00138 printf( " RotZ 0.5 rad \n" ); 00139 rot = MatrixMath::RotZ(0.5); 00140 rot.print(); 00141 printf( " _______________________________ \n\n" ); 00142 00143 printf( " Transl 5x 3y 4z\n" ); 00144 rot = MatrixMath::Transl( 5, 3, 4 ); 00145 rot.print(); 00146 printf( " _______________________________ \n\n" ); 00147 00148 //--- 00149 00150 t.stop(); 00151 00152 float bigtime = t2.read(); 00153 float average = 12.149647 - bigtime; 00154 00155 printf( "\n\nThe time for all those operations in mbed was : %f seconds\n", t.read() ); 00156 printf( "\nOnly operations witout any print takes: 12.149647 seconds\n" ); 00157 printf( "\nDue to the 8x8 matrix alone takes: %f \n",bigtime ); 00158 printf( "\nSo normal 4x4 matrix ops: %f\n", average ); 00159 00160 while(1) { 00161 myled = 1; 00162 wait(0.2); 00163 myled = 0; 00164 wait(0.2); 00165 } 00166 }