mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
release of tvmet (inactive for 2 years and developer unreachable) as the basis for eigen2, because it provides seemingly good expression template mechanisms, we want that, and it would take years to reinvent that wheel. We'll see. So this commit imports the last tvmet release.
408 lines
11 KiB
Plaintext
408 lines
11 KiB
Plaintext
/*
|
|
* $Id: usage.dox,v 1.14 2004/07/03 17:09:23 opetzold Exp $
|
|
*/
|
|
|
|
/**
|
|
\page usage Usage
|
|
|
|
<p>Contents:</p>
|
|
-# \ref include
|
|
-# \ref construct
|
|
-# \ref c_arrays
|
|
-# \ref compare
|
|
-# \ref pod
|
|
-# \ref stl
|
|
-# \ref matrix_access
|
|
-# \ref expr_print
|
|
|
|
|
|
|
|
|
|
\section include Include files
|
|
|
|
The Tiny %Vector and %Matrix template library has many include files spread
|
|
throughout the %tvmet include directory. As a user, you need only include
|
|
<tt><%tvmet/Vector></tt> for vector operations and/or
|
|
<tt><%tvmet/Matrix></tt> for matrix operations.
|
|
|
|
\par Example:
|
|
\code
|
|
#include <tvmet/Matrix.h>
|
|
#include <tvmet/Vector.h>
|
|
|
|
using namespace tvmet;
|
|
\endcode
|
|
|
|
Simple, isn't it? Don't forget to use the namespace tvmet, but keep in mind
|
|
that using the using directive inside headers will pollute the namespace. If
|
|
you write this in a header file, the namespace for all subsequent header
|
|
files (those which include the one you're writing) will also be polluted.
|
|
(This is not a %tvmet specific phenomenon.) Therefore, write the using
|
|
statement in the C++ file.
|
|
|
|
|
|
|
|
|
|
|
|
\section construct Construction and Initializing
|
|
|
|
Due to the nature of
|
|
<a href=http://extreme.indiana.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html>
|
|
Expression Templates</a> (ET) you can't write code like
|
|
|
|
\par Example:
|
|
\code
|
|
tvmet::Vector<double, 3> v1(1,2,3); // OK
|
|
tvmet::Vector<double, 3> v2 = v1; // not possible
|
|
\endcode
|
|
|
|
The operator= function assigns an expression to the Vector which means that
|
|
the object must be constructed before you may assign something to it. The
|
|
solution is to write this as:
|
|
|
|
\par Example:
|
|
\code
|
|
using namespace tvmet;
|
|
|
|
Vector<double, 3> v1(1,2,3);
|
|
Vector<double, 3> v2; // construct the Vector<T,Sz> object at first
|
|
v2 = v1; // ... and assign the contents of v1 to v2
|
|
Vector<double, 3> v3(v1); // ... or simple use the copy constructor
|
|
|
|
std::cout << v3 << std::endl;
|
|
\endcode
|
|
|
|
since the object v2 needs to be constructed before the object's operator=()
|
|
can be called.
|
|
|
|
The same rule applies to the Matrix class. You can only assign vectors and
|
|
matrices of the same dimension or you will get a compile error. This also
|
|
applies to the argument list for the constructor of the classes.
|
|
|
|
Initializing can be done as shown above or by using a comma separated list:
|
|
|
|
\par Example:
|
|
\code
|
|
using namespace tvmet;
|
|
|
|
Matrix<double, 3, 2> m1; // yes, non-square matrices are possible as well
|
|
m1 = 1, 4,
|
|
2, 5,
|
|
3, 6;
|
|
\endcode
|
|
|
|
Matrix element initialization always performed column wise! If the length
|
|
of the comma separated list is longer than the storage size, you will get
|
|
a compile time error. (tvmet is designed to prevent this -- it will prevent
|
|
you from accidentally overwriting memory which does not belong to the
|
|
matrix you are initializing.) You can use a comma separated list to
|
|
initialize vectors as well.
|
|
|
|
If you want a clean (zero-valued) vector or matrix you can simple write:
|
|
|
|
\par Example:
|
|
\code
|
|
using namespace tvmet;
|
|
|
|
Vector<double, 3> v4(0);
|
|
Matrix<double, 3, 4> m2(0);
|
|
\endcode
|
|
|
|
All elements of v4 and m2 are initialized with zero (or whatever value you
|
|
provide at construction time). Keep in mind that the uninitialized %Matrix
|
|
and %Vector classes will have random data when the are created (since they
|
|
use a static array for internal storage) unless you initialize them!
|
|
|
|
Another way to initialize a vector or matrix follows:
|
|
|
|
\par Example:
|
|
\code
|
|
using namespace tvmet;
|
|
|
|
Vector<double, 3> v5(1,2,3);
|
|
Vector<double, 3> v6(v5);
|
|
Vector<double, 3> v7(v5+v6);
|
|
\endcode
|
|
|
|
This is useful for temporary results. The result will be immediately
|
|
assigned to the new vector elements using the expression passed to the
|
|
constructor.
|
|
|
|
Yet another way of initializing a vector or matrix is similar to the above.
|
|
We assign an expression to it:
|
|
|
|
\par Example:
|
|
\code
|
|
using namespace tvmet;
|
|
|
|
Matrix<double, 3, 3> m3, m4, m5;
|
|
m3 = 1, 2, 3,
|
|
4, 5, 6,
|
|
7, 8, 9;
|
|
m4 = m3;
|
|
m5 = m3 + m4;
|
|
\endcode
|
|
|
|
If you have your data inside arrays you can use tvmet's iterator interface
|
|
to initialize a vector or matrix with it:
|
|
|
|
\par Example:
|
|
\code
|
|
T data[] = { 1,4,7,
|
|
2,5,8,
|
|
3,6,9 };
|
|
|
|
std::size_t sz = sizeof(data)/sizeof(T);
|
|
T* first = data;
|
|
T* last = data + sz;
|
|
|
|
tvmet::Matrix<double, 3, 3> m(first, last);
|
|
\endcode
|
|
|
|
The data will be copied into the matrix itself. When the constructor has
|
|
finished, there will be no stored reference to the array pointer.
|
|
|
|
Starting with tvmet release 1.6.0 you can create an identity matrix
|
|
simply by using the function identity(). Note, we have to specify the
|
|
matrix type, since ADL can't work here.
|
|
|
|
\par Example:
|
|
\code
|
|
typedef Matrix<double,3,3> matrix_type;
|
|
...
|
|
matrix_type E( identity<matrix_type>() );
|
|
\endcode
|
|
|
|
|
|
|
|
|
|
\section c_arrays Use of C style Arrays with tvmet
|
|
|
|
Sometimes you have some data arranged in a C style array for matrices
|
|
and vectors. As with tvmet release 1.6.0 you can wrap an expression
|
|
around using the functions vector_ref(const T* mem) and
|
|
matrix_ref(const T* mem) where mem is the pointer to the C array.
|
|
|
|
The returned expressions (XprVector or XprMatrix) can be used
|
|
as usual like tvmet's vectors and matrices. This means, you
|
|
can use all mathematical functions on it.
|
|
|
|
\par Example:
|
|
\code
|
|
static float lhs[3][3] = {
|
|
{-1, 0, 1}, { 1, 0, 1}, {-1, 0, -1}
|
|
};
|
|
static float rhs[3][3] = {
|
|
{ 0, 1, 1}, { 0, 1, -1}, { 0, -1, 1}
|
|
};
|
|
...
|
|
|
|
typedef Matrix<float, 3, 3> matrix_type;
|
|
|
|
matrix_type M( prod(matrix_ref<float, 3, 3>(&lhs[0][0]),
|
|
matrix_ref<float, 3, 3>(&rhs[0][0])) );
|
|
\endcode
|
|
|
|
This allows to initialize tvmet's vectors and matrices by
|
|
an alternative way as described at \ref construct.
|
|
|
|
|
|
\section compare Compare Vectors and Matrices
|
|
|
|
If you expect to find global comparison operators for comparing Vectors
|
|
and Matrices, you are right -- these are provided. But, the return
|
|
value probably isn't what you expect: a boolean value. Instead, the operator
|
|
returns an expression (e.g. XprVector<>). The contents of this expression
|
|
type is a element wise logical operation (depends on the given operator
|
|
like ==, <, >, etc...)! To get a boolean value you need to evaluate the
|
|
expression using all_elements() or any_elements(), as follows:
|
|
|
|
\par Example:
|
|
\code
|
|
using namespace tvmet;
|
|
using namespace std;
|
|
|
|
Vector<double, 3> v1, v2, bv;
|
|
|
|
v1 = 1,2,3;
|
|
v2 = 1,3,3;
|
|
|
|
bv = v1 == v2;
|
|
|
|
cout << bv << endl;
|
|
cout << "v1 == v2 is "
|
|
<< ( all_elements( v1 == v2 ) ? "true" : "false" )
|
|
<< endl;
|
|
\endcode
|
|
|
|
This gives
|
|
|
|
\par [continued]
|
|
\code
|
|
Vector<d, 3>[1, 0, 1]
|
|
v1 == v2 is false
|
|
\endcode
|
|
|
|
The reason for this is the element wise operation on all elements (for both
|
|
Vectors and Matrices). Comparing two vectors will result in a "boolean Vector"
|
|
expression. Using all_elements/any_elements evaluates the result into a
|
|
single boolean by repeatedly applying the comparison for each element.
|
|
|
|
An other example on comparing is shown below:
|
|
|
|
\par Example:
|
|
\code
|
|
if(all_elements(X == Y)) { cout << "matrices are identical" << endl; }
|
|
if(any_elements(X == Y)) { cout << "at least one element is equal" << endl; }
|
|
if(any_elements(X != Y)) { cout << "not all elements are equal" << endl; }
|
|
\endcode
|
|
|
|
%tvmet prior release 1.2.1 did have a boolean version eval for comparing.
|
|
The functional and semantic meaning were not clear at all. Therefore I
|
|
decided to remove it.
|
|
|
|
\sa \ref operators
|
|
|
|
|
|
|
|
|
|
|
|
\section pod Data Types like std::complex<>
|
|
|
|
As we can see above we can use POD (plain old data) types like <tt>double</tt> and
|
|
<tt>int</tt> as data type of a %Vector or %Matrix. However, we are not limited to
|
|
this - we can use e.g. <tt>std::complex<></tt> as well:
|
|
|
|
\par Example:
|
|
\code
|
|
using namespace tvmet;
|
|
|
|
Vector<std::complex<double>,3> v1, v2;
|
|
Matrix<std::complex<double>,3,3> m1;
|
|
\endcode
|
|
|
|
And operate on these...
|
|
|
|
\par [continued]
|
|
\code
|
|
v1 = 1,2,3;
|
|
m1 = 1,4,7,
|
|
2,5,8,
|
|
3,6,9;
|
|
v2 = m1 * v1;
|
|
\endcode
|
|
|
|
Be careful. <tt>std::complex<></tt> isn't tested well on regression tests.
|
|
|
|
|
|
|
|
|
|
\section stl STL support
|
|
|
|
Since version 0.2.0 %tvmet has supported an iterator interface conform to
|
|
the STL and since version 0.5.0 reverse STL iterators have been supported,
|
|
too.
|
|
|
|
With these, you can mix the %tvmet Vector and Matrix containers with the
|
|
STL algorithms.
|
|
|
|
For example, if you don't like %tvmet's ostream operator, you can create
|
|
your own implementation like this:
|
|
|
|
\par Example:
|
|
\code
|
|
tvmet::Vector<double, 6> v(1,2,3,4,5,6);
|
|
std::cout << v << std::endl;
|
|
|
|
std::cout << "The Vector is:" << std::endl;
|
|
std::copy(v.begin(), v.end(), std::ostream_iterator<double>(std::cout, "\n"));
|
|
\endcode
|
|
|
|
Or, you create a random matrix and print it as shown here:
|
|
|
|
\par Example:
|
|
\code
|
|
tvmet::Matrix<double,6,6> m;
|
|
|
|
std::generate(m.begin(), m.end(), rand);
|
|
std::cout << m << std::endl;
|
|
\endcode
|
|
|
|
|
|
|
|
|
|
|
|
\section matrix_access Matrix access by rows and columns
|
|
|
|
If you need a specific row or column of a given matrix you can get access to
|
|
it by using the functions row and col. They will return an XprVector<T>.
|
|
Unfortunately, you do not get any write access to the vector elements - only
|
|
reading is permitted due to the expression template concept used here. For
|
|
write access, you have to use matrix indexing with the parentheses operator.
|
|
|
|
\par Example:
|
|
\code
|
|
using namespace tvmet;
|
|
|
|
typedef Matrix<double 5, 3> matrix_type;
|
|
typedef Vector<double, 5> matrix_rowvector;
|
|
typedef Vector<double, 3> matrix_colvector;
|
|
|
|
matrix_type M;
|
|
M = ....
|
|
|
|
matrix_rowvector row2 = row(M, 2);
|
|
matrix_colvector col3 = col(M, 3);
|
|
...
|
|
\endcode
|
|
|
|
|
|
|
|
|
|
|
|
\section expr_print Expression printing
|
|
|
|
Expression printing is a nice feature for debugging expressions. (For more
|
|
about expression templates and expression tree please have a look
|
|
<a href=http://extreme.indiana.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html>here</a>).
|
|
|
|
You can write out a simple matrix-vector multiplication of a vector
|
|
<tt>v1</tt> and a matrix <tt>m1</tt> of the dimension of 3 as follows:
|
|
|
|
\par Example:
|
|
\code
|
|
std::cout << m1 * v1 << std::endl;
|
|
\endcode
|
|
|
|
which will be expanded to:
|
|
|
|
\par [continued]
|
|
\code
|
|
XprVector<
|
|
XprMVProduct<
|
|
d, 3, 3, 3, 1, d, 1
|
|
>
|
|
3
|
|
>
|
|
\endcode
|
|
|
|
The "d" is a g++ placeholder for double. (This may vary from compiler to
|
|
compiler since it is an implementation detail of runtime type information
|
|
[rtti] determined by the compiler's manufacturer). The purpose of this
|
|
feature is to check the right evaluation of expressions into the tree on
|
|
complicated mathematical expressions.
|
|
|
|
A rich source of examples are the regression tests. They show all of the
|
|
supported operations and functions (if there is a regression test for this
|
|
of course). Some examples are in the examples directory.
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
// Local Variables:
|
|
// mode:c++
|
|
// End:
|