1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355
|
/*! \page gmathlib GRASS Numerical math interface
<!-- doxygenized from "GRASS 5 Programmer's Manual"
by M. Neteler 8/2005
-->
\section gmathintro Numerical math interface with optional support of LAPACK/BLAS
<P>
Author: David D. Gray<br>
Additions: Brad Douglas
<P>
(under development)
<BR>
<P>
This chapter provides an explanation of how numerical algebra routines from
LAPACK/BLAS can be accessed through the GRASS GIS library "gmath". Most of
the functions are wrapper modules for linear algebra problems, a few are locally
implemented.
<BR>
<P>
Getting BLAS/LAPACK (one package) if not already provided by the system:
<BR><TT><A HREF="http://www.netlib.org/lapack/">http://www.netlib.org/lapack/</A></TT>
<BR><TT><A HREF="http://netlib.bell-labs.com/netlib/master/readme.html">http://netlib.bell-labs.com/netlib/master/readme.html</A></TT>
<BR>
<P>
Pre-compiled binaries of LAPACK/BLAS are provided on many Linux
distributions.
<P>
\section Implementation Implementation
<P>
The function name convention is as follows:
<P>
<OL>
<LI>G_matrix_*() : corresponding to Level3 BLAS (matrix -matrix) ,
</LI>
<LI>G_matvect_*() : corresponding to Level2 BLAS (vector-matrix) and
</LI>
<LI>G_vector_*() : corresponding to Level1 BLAS (vector-vector)
</LI>
</OL>
<P>
\section matrix_matrix_functions matrix -matrix functions
<P>
mat_struct *G_matrix_init (int rows, int cols, int ldim)<br>
Initialise a matrix structure Initialise a matrix structure. Set
the number of rows with
the first parameter and columns with the second. The third parameter, lead
dimension (>= no. of rows) needs attention by the programmer as it is
related to the Fortran workspace:
<P>
A 3x3 matrix would be stored as
<P>
[ x x x _ ][ x x x _ ][ x x x _ ]
<BR>
<P>
This work space corresponds to the sequence:
<P>
(1,1) (2,1) (3,1) and unused are (1,2) (2,2) ... and so on, ie. it is column major.
So although the programmer uses the normal parameter sequence of (row, col)
the entries traverse the data column by column instead of row by row. Each
block in the workspace must be large enough (here 4) to hold a whole column
(3) , and trailing spaces are unused. The number of rows (ie. size of a
column) is therefore not necessarily the same size as the block size
allocated to hold them (called the "lead dimension") . Some operations may
produce matrices a different size from the inputs, but still write to the
same workspace. This may seem awkward, but it does make for efficient code.
Unfortunately, this creates a responsibility on the programmer to specify the
lead dimension (>= no. of rows). In most cases the programmer can just use
the rows. So for 3 rows/2 cols it would be called:
<P>
G_matrix_init (3, 2, 3);
<P>
mat_struct *G_matrix_set (mat_struct *A, int rows, int cols, int ldim)<br>
Set parameters for a matrix structureSet parameters for a matrix
structure that is allocated but not yet initialised fully.
<P>
<B>Note:</B>
<BR>
<P>
G_matrix_set() is an alternative to G_matrix_init() . G_matrix_init()
initialises and returns a pointer to a dynamically allocated matrix
structure (ie. in the process heap) . G_matrix_set() sets the parameters for
an already created matrix structure. In both cases the data workspace still
has to be allocated dynamically.
<P>
Example 1:
<P>
\verbatim
mat_struct *A;
G_matrix_set (A, 4, 3, 4);
\endverbatim
<BR>
<P>
Example 2:
<P>
\verbatim
mat_struct A; /* Allocated on the local stack */
G_matrix_set (&A, 4, 3, 4) ;
\endverbatim
<BR>
<P>
mat_struct *G_matrix_add (mat_struct *mt1, mat_struct *mt2)<br>
Add two matrices. Add two matrices and return the result. The receiving structure
should not be initialised, as the matrix is created by the routine.
<P>
mat_struct *G_matrix_product (mat_struct *mt1, mat_struct *mt2)<br>
Multiply two matricesMultiply two matrices and return the result.
The receiving structure should not be initialised, as the matrix is created
by the routine.
<P>
mat_struct *G_matrix_scale (mat_struct *mt1, const double c)<br>
Scale matrix Scale the matrix by a given scalar value and return the
result. The receiving structure should not be initialised, as the matrix is
created by the routine.
<P>
mat_struct *G_matrix_subtract (mat_struct *mt1, mat_struct *mt2)<br>
Subtract two matrices. Subtract two matrices and return the result.
The receiving structure should not be initialised, as the matrix is created
by the routine.
<P>
mat_struct *G_matrix_copy (const mat_struct *A)<br>
Copy a matrix. Copy a matrix by exactly duplicating its structure.
<P>
mat_struct *G_matrix_transpose (mat_struct *mt)<br>
Transpose a matrix. Transpose a matrix by creating a new one and
populating with transposed element s.
<P>
void G_matrix_print (mat_struct *mt)<br>
Print out a matrix. Print out a representation of the matrix to
standard output.
<P>
int G_matrix_LU_solve (const mat_struct *mt1, mat_struct **xmat0, const
mat_struct *bmat, mat_type mtype)<br>
Solve a general system A.X=B. Solve a general
system A.X=B, where A is a NxN matrix, X and B are NxC matrices, and we are to
solve for C arrays in X given B. Uses LU decomposition.
<BR>
<P>
Links to LAPACK function dgesv_() and similar to perform the core routine.
(By default solves for a general non-symmetric matrix .)
<P>
mtype is a flag to indicate what kind of matrix (real/complex, Hermitian,
symmetric, general etc.) is used (NONSYM, SYM, HERMITIAN) .
<P>
<B>Warning:</B> NOT YET COMPLETE: only some solutions' options
available. Now, only general real matrix is supported.
<P>
mat_struct *G_matrix_inverse (mat_struct *mt)<br>
Matrix inversion using
LU decomposition Calls G_matrix_LU_solve() to obtain matrix inverse using
LU decomposition. Returns NULL on failure.
<P>
void G_matrix_free (mat_struct *mt)<br> Free up allocated matrix Free up
allocated matrix.
<P>
int G_matrix_set_element (mat_struct *mt, int rowval, int colval, double val)<br>
Set the value of the (i,j) th element Set the value of the
(i,j) th element to a double value. Index values are C-like ie. zero-based.
The row number is given first as is conventional. Returns -1 if the
accessed cell is outside the bounds.
<P>
double G_matrix_get_element (mat_struct *mt, int rowval, int colval)<br>
Retrieve value of the (i,j) th element Retrieve the value of the
(i,j) th element to a double value. Index values are C-like ie. zero-based.
<P>
<B>Note:</B> Does currently not set an error flag for bounds checking.
<P>
\section matrix_Vector_functions Matrix-Vector functions
<P>
vec_struct *G_matvect_get_column (mat_struct *mt, int
col) Retrieve a column of matrix Retrieve a column of the matrix to a vector
structure. The receiving structure should not be initialised, as the
vector is created by the routine. Col 0 is the first column.
<P>
vec_struct *G_matvect_get_row (mat_struct *mt, int
row) Retrieve a row of matrix Retrieve a row of the matrix to a vector
structure. The receiving structure should not be initialised, as the
vector is created by the routine. Row 0 is the first number.
<P>
int G_matvect_extract_vector (mat_struct *mt, vtype vt, int
indx) Convert matrix to vectorConvert the current matrix structure to
a vector structure. The vtype is RVEC or CVEC which specifies a row vector or
column vector. The indx indicates the row/column number (zero based) .
<P>
int G_matvect_retrieve_matrix (vec_struct *vc) Revert a
vector to matrix Revert a vector structure to a matrix .
<P>
\section Vector_Vector_functions Vector-Vector functions
vec_struct *G_vector_init (int cells, int ldim, vtype vt) Initialise
a vector structure Initialise a vector structure. The vtype is RVEC or
CVEC which specifies a row vector or column vector.
<P>
int G_vector_set (vec_struct *A, int cells, int ldim, vtype vt, int vindx) Set
parameters for vector structureSet parameters for a vector structure that is
allocated but not yet initialised fully. The vtype is RVEC or
CVEC which specifies a row vector or column vector.
<P>
vec_struct *G_vector_copy (const vec_struct *vc1, int
comp_flag) Copy a vectorCopy a vector to a new vector structure. This preserves
the underlying structure unless you specify DO_COMPACT comp_flag:
<P>
0 Eliminate unnecessary rows (cols) in matrix
<BR>
1 ... or not
<P>
double G_vector_norm_euclid (vec_struct *vc) Calculates euclidean
norm Calculates the euclidean norm of a row or column vector, using BLAS
routine dnrm2_()
<P>
double G_vector_norm_maxval (vec_struct *vc, int vflag) Calculates
maximum value Calculates the maximum value of a row or column vector.
The vflag setting defines which value to be calculated:
<P>
vflag:
<P>
1 Indicates maximum value
<BR> -1 Indicates minimum value
<BR>
0 Indicates absolute value [???]
<P>
<B>Note:</B> More functions and wrappers will be implemented soon (11/2000) .
<P>
\section Notes Notes
The numbers of rows and columns is stored in the matrix structure:
<P>
\verbatim
G_message (" M1 rows: %d, M1 cols: %d", m1->rows, m1->cols);
\endverbatim
<P>
Draft Notes:
<P>
* G_vector_free() can be done by G_matrix_free() .
<P>
\verbatim
#define G_vector_free(x) G_matrix_free( (x) )
\endverbatim
<P>
* Ax calculations can be done with G_matrix_multiply()
<P>
* Vector print can be done by G_matrix_print() .
<P>
\verbatim
#define G_vector_print(x) G_matrix_print( (x) )
\endverbatim
<P>
\section Example Example
The Makefile needs a reference to $(GMATHLIB) in LIBES line.
<P>
Example module:
<P>
\verbatim
#include <grass/config.h>
#include <grass/gis.h>
#include <grass/gmath.h>
int
main (int argc, char *argv[])
{
mat_struct *matrix;
double val;
/* init a 3x2 matrix */
matrix = G_matrix_init (3, 2, 3);
/* set cell element 0,0 in matrix to 2.2: */
G_matrix_set_element (matrix, 0, 0, 2.2);
/* retrieve this value */
val = G_matrix_get_element (matrix, 0, 0);
/* print it */
G_message ( "Value: %g", val);
/* Free the memory */
G_matrix_free (matrix);
return 0;
}
\endverbatim
<P>
See \ref Compiling_and_Installing_GRASS_Modules for a complete
discussion of Makefiles.
*/
|