File: matrix.h

package info (click to toggle)
phast 1.4%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 12,412 kB
  • sloc: ansic: 54,180; makefile: 354; sh: 337; perl: 321
file content (360 lines) | stat: -rw-r--r-- 8,736 bytes parent folder | download | duplicates (2)
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
356
357
358
359
360
/***************************************************************************
 * PHAST: PHylogenetic Analysis with Space/Time models
 * Copyright (c) 2002-2005 University of California, 2006-2010 Cornell 
 * University.  All rights reserved.
 *
 * This source code is distributed under a BSD-style license.  See the
 * file LICENSE.txt for details.
 ***************************************************************************/

/** \file matrix.h
   Structure to hold Matrices of real numbers (doubles) and functions to perform basic matrix operations on them
   \ingroup base
*/

#ifndef MAT_H
#define MAT_H

#include <vector.h>
#include <external_libs.h>

/** Equality threshold -- consider equal if this close */
#define EQ_THRESHOLD 1e-10

/** Matrix structure -- just a 2d array of doubles and its dimensions */
struct matrix_struct {
  double **data;			/**< underlying array of doubles */
  int nrows;			/**< number of rows */
  int ncols;			/**< number of columns */
};
/** Matrix type */
typedef struct matrix_struct Matrix;

/** \name Matrix create/free operations. */

/** \{ */

/** Allocate new matrix.

  @param nrows Number of rows.
  @param ncols Number of columns.

  @see mat_new_from_array.
*/
Matrix *mat_new(int nrows, int ncols);
/** Allocate new matrix using supplied array as storage.

  @param array Pre allocated storage array.
  @param nrows Number of rows.
  @param ncols Number of columns.
  
  @see mat_new, mat_free.
*/
Matrix *mat_new_from_array(double **array, int nrows, int ncols);

/** Allocate matrix, reading entries from file.

  Entries are read row by row.

  @param F Input file stream.
  @param nrows Number of rows.
  @param ncols Number of columns.
  
  @see mat_read.
*/
Matrix *mat_new_from_file(FILE *F, int nrows, int ncols);

/** Allocate a new matrix identical to given input matrix.

  @param src Input matrix.
  @result Newly allocated copy of src
  @see mat_copy.
*/
Matrix *mat_create_copy(Matrix *src);

/** Free matrix.

  @note It will release storage array even if matrix was created using
        mat_new_from_array.

  @param m Input matrix.
*/
void mat_free(Matrix *m);

/** Resize matrix.

  Resize will preserve values that fall within the new dimensions.
  Value that fall outside the dimensions of the source matrix are undefined.
  
  @param m Matrix to be resized.
  @param nrows New row count.
  @param ncols New column count.
*/
void mat_resize(Matrix *m, int nrows, int ncols);

/** \} */

/** \name Matrix initialization operations. */

/** \{ */

/** Set matrix entries to match identity matrix.

  @param m Input matrix.
  
  @see mat_set, mat_set_zero, mat_set_all.
*/
void mat_set_identity(Matrix *m);
/** Set all matrix entries to zero.

  @param m Input matrix.
  @see mat_set, mat_set_identity, mat_set_all.
*/
void mat_zero(Matrix *m);
/** Set all matrix entries to the specified value.

  @param m Input matrix.
  @param val Value to be stored.
  @see mat_set, mat_set_identity, mat_set_all.
*/
void mat_set_all(Matrix *m, double val);
/** Copy all matrix entries from source to destination matrix.

  @note Matrices must have the same dimensions.

  @param src Source matrix.
  @param dest Destination matrix.
  
  @see mat_create_copy.
*/
void mat_copy(Matrix *dest, Matrix *src);

/** Read matrix entries from file.

  Entries are read row by row.

  @param m Pre allocated destination matrix.
  @param F Input file stream.
  
  @see mat_new_from_file, mat_print.
*/
void mat_read(Matrix *m, FILE *F);

/** \} */

/** Retrieve value.

  @param m Input matrix.
  @param row Row index.
  @param col Column index.
  @result Element m[row][col]
  @see mat_get_row, mat_get_col
*/
static PHAST_INLINE 
double mat_get(Matrix *m, int row, int col) {
  return m->data[row][col];
}
/** Retrieve matrix row.

  Allocates a new vector and copies row values from input matrix.

  @param m Input matrix.
  @param row Row index.
  @result Row 'row' or m, m[row]
  @see mat_get, mat_get_col.
*/
Vector *mat_get_row(Matrix *m, int row);
/** Retrieve matrix column.

  Allocates a new vector and copies column values from input matrix.
  
  @param m Input matrix.
  @param col Column index.
  @result Column 'col' of m, m[*][col]
  @see mat_get_row, mat_get.
*/
Vector *mat_get_col(Matrix *m, int col);
/** Store value in matrix.

  @param m Input matrix.
  @param row Row index.
  @param col Column index.
  @param val Value to be stored.
  
  @see mat_set_identity,mat_zero, mat_set_all.
*/
static PHAST_INLINE
void mat_set(Matrix *m, int row, int col, double val) {
  m->data[row][col] = val;
}

/** Print matrix to file.

  Entries are separated by spaces. If the minimum value of the matrix
  is less than 1E-3, matrix is printed in exponential notation.

  @param m Input matrix.
  @param F Output file stream.
  
  @see mat_read.
*/
void mat_print(Matrix *m, FILE *F);

/** \name Matrix math operations. */

/** \{ */

/** Compare two matrices.
  @param A 1st matrix.
  @param B 2nd matrix.
  @result Returns 1 if A and B are same dimensions and data in every 
  row and column are the same.  Otherwise returns 0.
 */
int mat_equal(Matrix *A, Matrix *B);

/** Create transposed version of input matrix.

  @param src Input matrix.
  @result Transpose of src matrix
*/
Matrix *mat_transpose(Matrix *src);
/** Rescale matrix entries by given value.

  @param m Input matrix.
  @param scale_factor Value to use as scale factor.
*/
void mat_scale(Matrix *m, double scale_factor);

/** Multiply two matrices.

  \code 
  // equivalent to this, but with matrices
  prod = m1 * m2;
  \endcode

  \note Destination matrix must be different from source matrices.

  @param prod Pre allocated result matrix.
  @param m1 Input matrix one.
  @param m2 Input matrix two.
*/
void mat_mult(Matrix *prod, Matrix *m1, Matrix *m2);
/** Multiply matrix with vector. 

  \code 
  // equivalent to this, but with matrices
  prod = m * v;
  \endcode
  
  @param prod pre allocated result vector.
  @param m Input matrix.
  @param v Input vector.
*/
void mat_vec_mult(Vector *prod, Matrix *m, Vector *v);
/** Matrix increment.

  \code 
  // equivalent to this, but with matrices
  thism += addm;
  \endcode
  
  @param thism Result matrix.
  @param addm Input matrix.

  \sa mat_minus_eq.
*/
void mat_plus_eq(Matrix *thism, Matrix *addm);
/** Matrix decrement.

  \code 
  // equivalent to this, but with matrices
  thism -= subm;
  \endcode
  
  @param thism Result matrix.
  @param subm Input matrix.

  \sa mat_plus_eq.
*/
void mat_minus_eq(Matrix *thism, Matrix *subm);
/** Linear combination of matrices.

  \code 
  // equivalent to this, but with matrices
  dest = coef1 * src1 + coef2 * src2;
  \endcode
  
  @param dest Result matrix.
  @param src1 Input matrix one.
  @param coef1 Coefficient of input matrix one.
  @param src2 Input matrix two.
  @param coef2 Coefficient of input matrix two.

*/
void mat_linear_comb(Matrix *dest, Matrix *src1, double coef1, 
                     Matrix *src2, double coef2);


/** Linear combination of an arbitrary number of matrices.

@code
// equivalent to this, but with matrices
dest=0;
for (i=0; i < n; i++)
  dest += coef[i]*src[i]
@endcode

@param dest Result matrix.
@param n Number of src matrices.
@param src An array of n input matrices.
@param coef A vector of n coefficients.

*/
void mat_linear_comb_many(Matrix *dest, int n, Matrix **src,
			  double *coef);

/** Invert square, real, non-symmetric matrix

  Uses LU decomposition (LAPACK routines dgetrf and dgetri).
  
  @param M_inv Pre allocated destination matrix.
  @param M Input matrix.
  @result 0 on success, 1 on failure
  @warning Calling this is function will terminate program if program was not compiled
  with LAPACK support.
*/
int mat_invert(Matrix *M_inv, Matrix *M);

/** Pre and post multiply a diagonal matrix.

   Compute A = B * C * D where A, B, C, D are square matrices of the
   same dimension, and C is diagonal.  C is described by a vector
   representing its diagonal elements.
   
   @param A Pre allocated result matrix.
   @param B Input matrix B.
   @param C Input vector representing diagonal of matrix C.
   @param D Input matrix C.
*/
void mat_mult_diag(Matrix *A, Matrix *B, Vector *C, Matrix *D);

#ifndef SKIP_LAPACK

/** Convert a matrix into Lapack's column-major format.
    @param m (input) A matrix.
    @param arr (output) A representation of m in Lapack's columns-major 
               format.
*/
void mat_to_lapack(Matrix *m, LAPACK_DOUBLE *arr);

/** Convert back from Lapack's column-major format to a Matrix.
    @param m (output) A matrix
    @param arr (input) A representation of a matrix in Lapack's
               column-major format.
 */
void mat_from_lapack(Matrix *m, LAPACK_DOUBLE *arr);
#endif

/* \} */

#endif