/* * $Id: usage.dox,v 1.14 2004/07/03 17:09:23 opetzold Exp $ */ /** \page usage Usage

Contents:

-# \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 <%tvmet/Vector> for vector operations and/or <%tvmet/Matrix> for matrix operations. \par Example: \code #include #include 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 Expression Templates (ET) you can't write code like \par Example: \code tvmet::Vector v1(1,2,3); // OK tvmet::Vector 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 v1(1,2,3); Vector v2; // construct the Vector object at first v2 = v1; // ... and assign the contents of v1 to v2 Vector 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 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 v4(0); Matrix 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 v5(1,2,3); Vector v6(v5); Vector 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 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 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 matrix_type; ... matrix_type E( identity() ); \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 matrix_type; matrix_type M( prod(matrix_ref(&lhs[0][0]), matrix_ref(&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 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[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 double and int as data type of a %Vector or %Matrix. However, we are not limited to this - we can use e.g. std::complex<> as well: \par Example: \code using namespace tvmet; Vector,3> v1, v2; Matrix,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. std::complex<> 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 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(std::cout, "\n")); \endcode Or, you create a random matrix and print it as shown here: \par Example: \code tvmet::Matrix 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. 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 matrix_type; typedef Vector matrix_rowvector; typedef Vector 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 here). You can write out a simple matrix-vector multiplication of a vector v1 and a matrix m1 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: