Added a comparison of the dlib::matrix to Matlab and also just generally

improved the example as a whole.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%402701
This commit is contained in:
Davis King 2008-12-04 03:15:49 +00:00
parent 485ac90e7c
commit 30cfab2e05
1 changed files with 150 additions and 4 deletions

View File

@ -68,7 +68,7 @@ int main()
1.2,
7.8};
// load these matrices up with their data. Note that you can only load a matrix
// Load these matrices up with their data. Note that you can only load a matrix
// with a C style array if the matrix is statically dimensioned as the M and y
// matrices are. You couldn't do it for x since x = M_data would be ambiguous.
// (e.g. should the data be interpreted as a 3x3 matrix or a 9x1 matrix?)
@ -87,6 +87,17 @@ int main()
cout << "M*x - y: \n" << M*x - y << endl;
// Also note that we can create run-time sized column or row vectors like so
matrix<double,0,1> runtime_sized_column_vector;
matrix<double,1,0> runtime_sized_row_vector;
// and then they are sized by saying
runtime_sized_column_vector.set_size(3);
// Similarly, the x matrix can be resized by calling set_size(num rows, num columns). For example
x.set_size(3,4); // x now has 3 rows and 4 columns.
// 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
@ -119,6 +130,123 @@ int main()
// --------------------------------- Comparison with MATLAB ---------------------------------
// Here I list a set of Matlab commands and their equivalent expressions using the dlib matrix.
matrix<double> A, B, C, D, E;
matrix<int> Aint;
matrix<long> Blong;
// MATLAB: A = eye(3)
A = identity_matrix<double>(3);
// MATLAB: B = ones(3,4)
B = uniform_matrix<double>(3,4, 1);
// MATLAB: C = 1.4*A
C = 1.4*A;
// MATLAB: D = A.*C
D = pointwise_multiply(A,C);
// MATLAB: E = A * B
E = A*B;
// MATLAB: E = A + B
E = A + C;
// MATLAB: E = E'
E = trans(E); // Note that if you want a conjugate transpose then you need to say conj(trans(E))
// MATLAB: E = B' * B
E = trans(B)*B;
double var;
// MATLAB: var = A(1,2)
var = A(0,1); // dlib::matrix is 0 indexed rather than starting at 1 like Matlab.
// MATLAB: C = round(C)
C = round(C);
// MATLAB: C = floor(C)
C = floor(C);
// MATLAB: C = ceil(C)
C = ceil(C);
// MATLAB: C = diag(B)
C = diag(B);
// MATLAB: B = cast(A, "int32")
Aint = matrix_cast<int>(A);
// MATLAB: A = B(1,:)
A = rowm(B,0);
// MATLAB: A = B(:,1)
A = colm(B,0);
// MATLAB: A = [1:5]'
Blong = range(1,5);
// MATLAB: A = [1:5]
Blong = trans(range(1,5));
// MATLAB: A = [1:2:5]
Blong = trans(range(1,2,5));
// MATLAB: A = B([1:3], [1:2])
A = subm(B, range(0,2), range(0,1));
// or equivalently
A = subm(B, rectangle(0,0,1,2));
// MATLAB: A = B([1:3], [1:2:4])
A = subm(B, range(0,2), range(0,2,3));
// MATLAB: B(:,:) = 5
set_subm(B,get_rect(B)) = 5;
// or equivalently
set_all_elements(B,5);
// MATLAB: B([1:2],[1,2]) = 7
set_subm(B,range(0,1), range(0,1)) = 7;
// MATLAB: B([1:3],[2:3]) = A
set_subm(B,range(0,2), range(1,2)) = A;
// MATLAB: B(:,1) = 4
set_colm(B,0) = 4;
// MATLAB: B(:,1) = B(:,2)
set_colm(B,0) = colm(B,1);
// MATLAB: B(1,:) = 4
set_rowm(B,0) = 4;
// MATLAB: B(1,:) = B(2,:)
set_rowm(B,0) = rowm(B,1);
// MATLAB: var = det(E' * E)
var = det(trans(E)*E);
// MATLAB: C = pinv(E)
C = pinv(E);
// MATLAB: C = inv(E)
C = inv(E);
// MATLAB: [A,B,C] = svd(E)
svd(E,A,B,C);
// MATLAB: A = chol(E,'lower')
A = cholesky_decomposition(E);
// MATLAB: var = min(min(A))
var = min(A);
// ------------------------- Template Expressions -----------------------------
// Now I will discuss the "template expressions" technique and how it is
// used in the matrix object. First consider the following expression:
@ -139,8 +267,8 @@ int main()
you have to pay for the cost of constructing a temporary matrix object
and allocating its memory. Then you pay the additional cost of copying
it over to x. It also gets worse when you have more complex expressions
such as x = y + y + y + M*y which would involve the creation and copying
of 4 temporary matrices.
such as x = round(y + y + y + M*y) which would involve the creation and copying
of 5 temporary matrices.
All these inefficiencies are removed by using the template expressions
technique. The exact details of how the technique is performed are well
@ -164,7 +292,7 @@ int main()
This technique works for expressions of arbitrary complexity. So if you
typed x = y + y + y + M*y it would involve no temporary matrices being
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.
@ -209,11 +337,29 @@ int main()
tmp() just evaluates a matrix_exp and returns a real matrix object. So it
does the same thing as the above code that uses Mtemp.
Another example of this would be chains of matrix multiplies. For example:
*/
x = M*M*M*M;
// A much faster version of this expression would be
x = tmp(M*M)*tmp(M*M);
/*
Anyway, the point of the above discussion is that you shouldn't multiply
complex matrix expressions. You should instead assign the expression to
a matrix object and then use that object in the multiply. This will ensure
that your multiplies are always fast.
Note however, that the following two expressions are not afflicted with the
above problem:
*/
double value1 = trans(y)*M*y;
double value2 = trans(y)*M*M*y;
/*
These expressions can be evaluated without using temporaries or
needlessly recalculating things as in the case of the above
examples.
!*/
}