Basic types: ============ 1. The floating point type: Numeric 2. The integer type: INDEX Always use these two types for numbers, unless you have a very good reason to use something else. The program should run with Numeric beeing either float or double. With float it should be faster. If you change the INDEX type you have to be sure to be consistent with MTL. At the moment it is size_t. General MTL information: ======================== For detailed information see the thesis mentioned on http://www.lsc.nd.edu/research/mtl/publications.php3 (the document is http://www.lsc.nd.edu/downloads/research/mtl/papers/thesis.ps.gz). Is is easy to read and explains the MTL concept much better than is possible here. Assignments of vectors and matrices are shallow! That means if you really want to make a duplicate of the contents, you have to use the copy() algorithm. For copy, the target object (matrix or vector) must have the right dimensions. Dimensions are not adjusted automatically, you will just get a core dump. This has one very important consequence for types like ARRAY my_data; After you create such an object, all outer ARRAY elements will point to the same data! You have to initialize manually, by doing the following: for (INDEX i=0; i: =========== Is just like VECTOR, just that the type can be anything. MATRIX: ======= Conceptually a `container of containers'. We use row major order. The outer container contains the rows of the matrix. You use a `twoDiterator' to select the row and a plain `iterator' to select a column. Put differently, each row of a matrix behaves just like a VECTOR. 1. Define a matrix: MATRIX A(10,20); initialization at the same time is not possible. Use the setto() algorithm. 1.a. Resize a matrix: resize(A,15,20); I implemented this function myself, to make MATRIX more consistent with ARRAY and VECTOR. Resizing will destroy the contents of the matrix! This is the safe way to resize. Internally it does a `A = MATRIX(15,20)'. 2. Element access: You could use: A(i,j) = 1.0; THIS IS DANGEROUS, because in TNT the same notation meant a different thing (1-based indices). On the other hand, if you write template functions that should work also with the more exotic matrix-like types (for example trans(A) or A.sub_range()) then you must use this kind of indexing since [][] will lead to errors. Recommended access: A[i][j] = 1.0 This means the same thing in TNT, so it is safe. 3. Print matrix to output stream: print_all_matrix(cout,A); In most cases you can also use the << operator. See also what I wrote for print_vector. 4. Select a row of a matrix: print_vector(cout, A[3]); Unfortunately, although A[3] behaves like a vector, you cannot assign it to a VECTOR directly. The correct type for it is MATRIX::OneD. However, you can use it in all vector algorithms (like print_vector above). So you can copy it to a vector like this: VECTOR x(A.ncols()); copy(A[3],x); 5. Matrix algorithms: setto(A,alpha); // set all elements of A to alpha scale(A,alpha); // multiply all elements of A by alpha set_diagonal(A,alpha); // set diagonal elements to alpha transpose(A); // replace A by A transposed print_all_matrix(os,A); // print to stream os 6. Matrix vector algorithms: mult(A,x,y); // y = A*x mult(A,x,y,z); // z = A*x + y tri_solve(T,x); // x = T^-1 * x 7. Matrix matrix algorithms: copy(A,B); // copy A to B swap(A,B); // exchange A and B add(A,C); // C = A+C ele_mult(A,B,C); // elementwise multiplication of A and B, stored in C mult(A,B,C); // C = A*B (matrix multiplication) mult(A,B,C,E); // E = A*B + C tri_solve(?); // Calculate inverse 8. Adaptor helper functions: scaled(A,alpha) // scale by factor alpha trans(A) // transpose rows(A) // Access to rows for columns matrix columns(A) // Access to columns for row matrix (ARTS case) 9. Matrix associated types: MATRIX::shape // tag to describe shape (e.g., rectangular) MATRIX::orientation // in our case always row_tag MATRIX::sparsity // dense_tag or sparse_tag MATRIX::OneD // type of inner container (the individual rows, columns, or diagonals) MATRIX::submatrix_type // for submatrices MATRIX::value_type // in our case Numeric OneD and submatrix_type are very useful for row, column, or submatrix access (see usage examples in demonstrate_linalg.cc). Sparsity should be useful for the maybe_sparse types. 10. Matrix methods: A.sub_matrix(r0,r1,c0,c1) // Selects submatrix from row r0 to r1 and // columns c0 to c1. Indices behave in the // same way as for VECTOR subranges! A.nrows() // number of rows A.ncols() // number of columns A.nnz() // number of nonzero elements SPARSE_MATRIX: =========== You can use basically all algorithms and member functions of MATRIX. 1. Define: SPARSE_MATRIX S(n,m); // n,m are the dimensions, the number of nonzero elements is 0 at first 2. Set elements by: S[3][4] = 1; 3. Number of nonzero elements: S.nnz() // Special functions added for ARTS: For VECTOR and MATRIX: transf(x,sqrt,y) or y = transf(x,exp): The generic transformation function. You can use this to apply any mathematical function that takes only a single argument to all elements of a VECTOR or MATRIX x. This replaces the old exp, sqrt, etc. functions. interp_lin_vector() and interp_lin_matrix(): These are meant to replace the various linear interpolation functions. They are very flexible, because they are template functions. For example, you can use interp_lin_matrix to interpolate either the rows or the columns of the matrix, by using the trans() adapter on the input and output matrix argument. (This is used inside ARTS in one place, just do a grep for the function.) // Common bugs: 1. Assigning a scalar to a vector as in: VECTOR a; a = 1; At runtime this will lead to a segmentation fault later on in the program. Unfortunately this bug is hard to locate. There could be still a few instances of it creeping through ARTS. 2. Calling a MTL algorithm without making sure that the arguments have compatible dimensions. There is no safeguard against this in MTL! 3. Matrix indices not properly adapted to 0-based.