Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
dlib
Commits
49f8b286
Commit
49f8b286
authored
Nov 17, 2013
by
Davis King
Browse files
Clarified matrix usage in the examples
parent
088a7206
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
47 additions
and
37 deletions
+47
-37
examples/matrix_ex.cpp
examples/matrix_ex.cpp
+27
-25
examples/matrix_expressions_ex.cpp
examples/matrix_expressions_ex.cpp
+20
-12
No files found.
examples/matrix_ex.cpp
View file @
49f8b286
...
...
@@ -34,25 +34,23 @@ int main()
// First lets declare these 3 matrices.
// 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
;
// Make a 3 by 3 matrix of doubles for the M matrix.
matrix
<
double
,
3
,
3
>
M
;
// Make a matrix of doubles that has unknown dimensions (the dimensions are
// 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
;
// Make a 3 by 3 matrix of doubles for the M matrix. In this case, M is
// sized at runtime and can therefore be resized later by calling M.set_size().
matrix
<
double
>
M
(
3
,
3
);
// You may be wondering why someone would want to specify the size of a matrix
// at compile time when you don't have to. The reason is two fold. First,
// there is often a substantial performance improvement, especially for small
// matrices, because the compiler is able to perform loop unrolling if it knows
// the sizes of matrices. Second, the dlib::matrix object checks these compile
// time sizes to ensure that the matrices are being used correctly. For example,
// if you attempt to compile the expression y = M; or x = y*y; you will get
// a compiler error on those lines since those are not legal matrix operations.
// 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.
// You may be wondering why someone would want to specify the size of a
// matrix at compile time when you don't have to. The reason is two fold.
// First, there is often a substantial performance improvement, especially
// for small matrices, because the compiler is able to perform loop
// unrolling if it knows the sizes of matrices. Second, the dlib::matrix
// object checks these compile time sizes to ensure that the matrices are
// being used correctly. For example, if you attempt to compile the
// expression y*y you will get a compiler error since that is not a legal
// matrix operation (the matrix dimensions don't make sense as a matrix
// 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()
7.8
;
// the solution can be obtained now by multiplying the inverse of M with y
x
=
inv
(
M
)
*
y
;
// The solution to y = M*x can be obtained by multiplying the inverse of M
// 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
;
...
...
@@ -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
;
// The above expression prints out the value 7.4. That is, the value of
// 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.
double
M_sum
=
0
;
...
...
@@ -114,11 +121,6 @@ int main()
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:
...
...
examples/matrix_expressions_ex.cpp
View file @
49f8b286
...
...
@@ -81,18 +81,26 @@ int main()
x(r,c) = y(r,c) + y(r,c);
This technique works for expressions of arbitrary complexity. So if you
typed x = round(y + y + y + M*y) it would involve no temporary matrices being
created at all. Each operator takes and returns only matrix_exp objects.
Thus, no computations are performed until the assignment operator requests
the values from the matrix_exp it receives as input.
There is, however, a slight complication in all of this. It is for statements
that involve the multiplication of a complex matrix_exp such as the following:
This technique works for expressions of arbitrary complexity. So if you typed
x = round(y + y + y + M*y) it would involve no temporary matrices being created
at all. Each operator takes and returns only matrix_exp objects. Thus, no
computations are performed until the assignment operator requests the values
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
the result of a matrix expression. Always store the output in a matrix object
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
);
/*
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment