Commit 49f8b286 authored by Davis King's avatar Davis King

Clarified matrix usage in the examples

parent 088a7206
...@@ -34,25 +34,23 @@ int main() ...@@ -34,25 +34,23 @@ int main()
// First lets declare these 3 matrices. // First lets declare these 3 matrices.
// This declares a matrix that contains doubles and has 3 rows and 1 column. // This declares a matrix that contains doubles and has 3 rows and 1 column.
// Moreover, it's size is a compile time constant since we put it inside the <>.
matrix<double,3,1> y; matrix<double,3,1> y;
// Make a 3 by 3 matrix of doubles for the M matrix. // Make a 3 by 3 matrix of doubles for the M matrix. In this case, M is
matrix<double,3,3> M; // sized at runtime and can therefore be resized later by calling M.set_size().
// Make a matrix of doubles that has unknown dimensions (the dimensions are matrix<double> M(3,3);
// decided at runtime unlike the above two matrices which are bound at compile
// time). We could declare x the same way as y but I'm doing it differently
// for the purposes of illustration.
matrix<double> x;
// You may be wondering why someone would want to specify the size of a matrix // You may be wondering why someone would want to specify the size of a
// at compile time when you don't have to. The reason is two fold. First, // matrix at compile time when you don't have to. The reason is two fold.
// there is often a substantial performance improvement, especially for small // First, there is often a substantial performance improvement, especially
// matrices, because the compiler is able to perform loop unrolling if it knows // for small matrices, because the compiler is able to perform loop
// the sizes of matrices. Second, the dlib::matrix object checks these compile // unrolling if it knows the sizes of matrices. Second, the dlib::matrix
// time sizes to ensure that the matrices are being used correctly. For example, // object checks these compile time sizes to ensure that the matrices are
// if you attempt to compile the expression y = M; or x = y*y; you will get // being used correctly. For example, if you attempt to compile the
// a compiler error on those lines since those are not legal matrix operations. // expression y*y you will get a compiler error since that is not a legal
// So if you know the size of a matrix at compile time then it is always a good // matrix operation (the matrix dimensions don't make sense as a matrix
// idea to let the compiler know about it. // multiplication). So if you know the size of a matrix at compile time
// then it is always a good idea to let the compiler know about it.
...@@ -67,8 +65,11 @@ int main() ...@@ -67,8 +65,11 @@ int main()
7.8; 7.8;
// the solution can be obtained now by multiplying the inverse of M with y // The solution to y = M*x can be obtained by multiplying the inverse of M
x = inv(M)*y; // with y. As an aside, you should *NEVER* use the auto keyword to capture
// the output from a matrix expression. So don't do this: auto x = inv(M)*y;
// To understand why, read the matrix_expressions_ex.cpp example program.
matrix<double> x = inv(M)*y;
cout << "x: \n" << x << endl; cout << "x: \n" << x << endl;
...@@ -90,11 +91,17 @@ int main() ...@@ -90,11 +91,17 @@ int main()
// The elements of a matrix are accessed using the () operator like so // The elements of a matrix are accessed using the () operator like so:
cout << M(0,1) << endl; cout << M(0,1) << endl;
// The above expression prints out the value 7.4. That is, the value of // The above expression prints out the value 7.4. That is, the value of
// the element at row 0 and column 1. // the element at row 0 and column 1.
// If we have a matrix that is a row or column vector. That is, it contains either
// a single row or a single column then we know that any access is always either
// to row 0 or column 0 so we can omit that 0 and use the following syntax.
cout << y(1) << endl;
// The above expression prints out the value 1.2
// Let's compute the sum of elements in the M matrix. // Let's compute the sum of elements in the M matrix.
double M_sum = 0; double M_sum = 0;
...@@ -114,11 +121,6 @@ int main() ...@@ -114,11 +121,6 @@ int main()
cout << "sum of all elements in M is " << sum(M) << endl; cout << "sum of all elements in M is " << sum(M) << endl;
// If we have a matrix that is a row or column vector. That is, it contains either
// a single row or a single column then we know that any access is always either
// to row 0 or column 0 so we can omit that 0 and use the following syntax.
cout << y(1) << endl;
// The above expression prints out the value 1.2
// Note that you can always print a matrix to an output stream by saying: // Note that you can always print a matrix to an output stream by saying:
......
...@@ -81,18 +81,26 @@ int main() ...@@ -81,18 +81,26 @@ int main()
x(r,c) = y(r,c) + y(r,c); x(r,c) = y(r,c) + y(r,c);
This technique works for expressions of arbitrary complexity. So if you This technique works for expressions of arbitrary complexity. So if you typed
typed x = round(y + y + y + M*y) it would involve no temporary matrices being x = round(y + y + y + M*y) it would involve no temporary matrices being created
created at all. Each operator takes and returns only matrix_exp objects. at all. Each operator takes and returns only matrix_exp objects. Thus, no
Thus, no computations are performed until the assignment operator requests computations are performed until the assignment operator requests the values
the values from the matrix_exp it receives as input. from the matrix_exp it receives as input. This also means that statements such as:
auto x = round(y + y + y + M*y)
will not work properly because x would be a matrix expression that references
parts of the expression round(y + y + y + M*y) but those expression parts will
immediately go out of scope so x will contain references to non-existing sub
matrix expressions. This is very bad, so you should never use auto to store
There is, however, a slight complication in all of this. It is for statements the result of a matrix expression. Always store the output in a matrix object
that involve the multiplication of a complex matrix_exp such as the following: like so:
matrix<double> x = round(y + y + y + M*y)
In terms of implementation, there is a slight complication in all of this. It
is for statements that involve the multiplication of a complex matrix_exp such
as the following:
*/ */
x = M*(M+M+M+M+M+M+M); x = M*(M+M+M+M+M+M+M);
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment