AerialVehicleControl.jl
cont_matrix_math.c
Go to the documentation of this file.
1 /*******************************************************************************
2 * Copyright (C) Marcus Greiff 2020
3 *
4 * @file cont_matrix_math.h
5 * @author Marcus Greiff
6 * @date June 2020
7 *******************************************************************************/
8 #include "cont_matrix_math.h"
9 
10 #if defined(LINK_LAPACK)
11 
12 /* Load the necessary functions from LAPACK */
13 
14 extern void dgemm_(char * transa, char * transb, int * m, int * n, int * k,
15  double * alpha, double * A, int * lda, double * B, int * ldb,
16  double * beta, double * C, int * ldc);
17 
18 extern void dpotrf_(char * uplo, int * n, double * A, int * lda, int * info);
19 
20 extern void dposv_(char* uplo, int* n, int* nrhs, double* a, int* lda,
21  double* b, int* ldb, int* info);
22 
23 extern void dsyev_(char* jobz, char* uplo, int* n, double* a, int* lda,
24  double* w, double* work, int* lwork, int* info);
25 #endif
26 
28  matrix_double_t *Amat,
29  matrix_double_t *Bmat,
30  matrix_double_t *Cmat
31 ){
32  int i;
33  /* Input data check */
34  if ((Amat->numRows != Bmat->numRows) ||
35  (Bmat->numRows != Cmat->numRows) ||
36  (Amat->numCols != Bmat->numCols) ||
37  (Bmat->numCols != Cmat->numCols)) return 0;
38  /* Perform matrix addition */
39  for (i = 0; i < Amat->numRows*Amat->numCols; i++) Cmat->pData[i] = Amat->pData[i] + Bmat->pData[i];
40  return 1;
41 }
42 
44  matrix_double_t *Amat,
45  matrix_double_t *Bmat
46 ){
47  int i;
48  /* Input data check */
49  if ((Amat->numRows != Bmat->numRows) ||
50  (Amat->numCols != Bmat->numCols)) return 0;
51  /* Perform matrix addition */
52  for (i = 0; i < Amat->numRows*Amat->numCols; i++) Amat->pData[i] += Bmat->pData[i];
53  return 1;
54 }
55 
57  matrix_double_t *Amat,
58  matrix_double_t *Bmat,
59  matrix_double_t *Cmat
60 ){
61  int i;
62  /* Input data check */
63  if ((Amat->numRows != Bmat->numRows) ||
64  (Bmat->numRows != Cmat->numRows) ||
65  (Amat->numCols != Bmat->numCols) ||
66  (Bmat->numCols != Cmat->numCols)) return 0;
67  /* Perform matrix addition */
68  for (i = 0; i < Amat->numRows*Amat->numCols; i++) Cmat->pData[i] = Amat->pData[i] - Bmat->pData[i];
69  return 1;
70 }
71 
73  matrix_double_t *Amat,
74  matrix_double_t *Bmat
75 ){
76  int i;
77  /* Input data check */
78  if ((Amat->numRows != Bmat->numRows) ||
79  (Amat->numCols != Bmat->numCols)) return 0;
80  /* Perform matrix addition */
81  for (i = 0; i < Amat->numRows*Amat->numCols; i++) Amat->pData[i] -= Bmat->pData[i];
82  return 1;
83 }
84 
86  matrix_double_t *Amat,
87  matrix_double_t *Bmat,
88  matrix_double_t *Cmat
89 ){
90 #if defined(LINK_LAPACK)
91  double alpha = 1.0, beta = 0.0;
92 #else
93  int i, j, k;
94 #endif
95  if ((Amat->numRows != Cmat->numRows) ||
96  (Bmat->numCols != Cmat->numCols) ||
97  (Amat->numCols != Bmat->numRows)) return 0;
98 #if defined(LINK_LAPACK)
99  dgemm_(
100  "N",
101  "N",
102  &Amat->numRows,
103  &Bmat->numCols,
104  &Amat->numCols,
105  &alpha,
106  Amat->pData,
107  &Amat->numRows,
108  Bmat->pData,
109  &Bmat->numRows,
110  &beta,
111  Cmat->pData,
112  &Cmat->numRows
113  );
114 #else
115  /* TODO: Make this more efficient when not using LAPACK*/
116  matrix_zero(Cmat);
117  for (i = 0; i < Amat->numRows; i++ ){
118  for (k = 0; k < Amat->numCols; k++ ){
119  for (j = 0; j < Bmat->numCols; j++ ){
120  matrix_set(Cmat, i, j, matrix_get(Amat, i, k) * matrix_get(Bmat, k, j) + matrix_get(Cmat, i, j));
121  }
122  }
123  }
124 #endif
125  return 1;
126 }
127 
129  matrix_double_t *Amat,
130  matrix_double_t *ATmat
131 ){
132  int i, j;
133  if ((Amat->numRows != ATmat->numCols) ||
134  (Amat->numCols != ATmat->numRows)) return 0;
135  for (i = 0; i < Amat->numRows; i++ ){
136  for (j = 0; j < Amat->numCols; j++ ){
137  ATmat->pData[i*Amat->numCols + j] = Amat->pData[j*Amat->numRows + i];
138  }
139  }
140  return 1;
141 }
142 
144  matrix_double_t *Amat,
145  matrix_double_t *Bmat
146 ){
147  int info = 0;
148  if ((Amat->numRows != Amat->numCols) ||
149  (Amat->numRows != Bmat->numRows) ||
150  (Bmat->numCols < 1)) return 0;
151 
152 #if defined(LINK_LAPACK)
153  dposv_(
154  "L",
155  &Amat->numCols,
156  &Bmat->numCols,
157  Amat->pData,
158  &Amat->numRows,
159  Bmat->pData,
160  &Bmat->numRows,
161  &info
162  );
163 #else
164  TRACE(5,("The PSD linear system solver has not yet been implemented dependency free", info));
165 #endif
166 
167  if (0 == info){
168  return 1;
169  } else {
170  if (0 < info) TRACE(5,("The %i-th argument in dposv had an illegal value\n", -info));
171  if (0 > info) TRACE(5,("The leading minor of order %i is not positive definite\n", info));
172  return 0;
173  }
174 }
175 
177  matrix_double_t *Amat,
178  matrix_double_t *eigVals
179 ){
180  int info, lwork;
181  double* work;
182  double wkopt;
183  matrix_double_t tmpm;
184 
185  /* Check that the input dimensionlity is correct */
186  if ((Amat->numRows != Amat->numCols) ||
187  (eigVals->numRows != Amat->numCols) ||
188  (eigVals->numCols != 1)) {
189  TRACE(5,("Input dimensionality error\n"));
190  return 0;
191  }
192  /* Check that the matrix is symmetric
193  if (0 == isSymmetric(Amat)) return 0;*/
194 
195  matrix_allocate(&tmpm, Amat->numRows, Amat->numCols);
196  matrix_copy(Amat, &tmpm);
197 
198  /* Query and allocate the optimal workspace */
199  lwork = -1;
200  dsyev_(
201  "N",
202  "L",
203  &tmpm.numCols,
204  tmpm.pData,
205  &tmpm.numCols,
206  eigVals->pData,
207  &wkopt,
208  &lwork,
209  &info
210  );
211 
212  lwork = (int)wkopt;
213  if (0 >= lwork) {
214  TRACE(5,("Could not compute the optimal work size\n"));
215  return 0;
216  }
217  assert(lwork > 0);
218 
219  work = (double*)malloc( lwork*sizeof(double) );
220 
221  /* Solve eigenproblem */
222  dsyev_(
223  "N",
224  "L",
225  &tmpm.numCols,
226  tmpm.pData,
227  &tmpm.numCols,
228  eigVals->pData,
229  work,
230  &lwork,
231  &info
232  );
233 
234  free(work);
235  free(tmpm.pData);
236 
237  if (0 == info){
238  return 1;
239  } else {
240  if (0 < info) TRACE(5,("The %i-th argument in dposv had an illegal value\n", -info));
241  if (0 > info) TRACE(5,("The the algorithm failed to converge; %i off-diagonal elements of an intermediate tridiagonal form did not converge to zero\n", info));
242  return 0;
243  }
244 }
245 
247 { assert(1 == matrix_double_addition(Amat, Bmat, Cmat)); }
248 
250 { assert(1 == matrix_double_addition_inplace(Amat, Bmat)); }
251 
253 { assert(1 == matrix_double_subtraction(Amat, Bmat, Cmat)); }
254 
256 { assert(1 == matrix_double_subtraction_inplace(Amat, Bmat)); }
257 
259 { assert(1 == matrix_double_multiplication(Amat, Bmat, Cmat)); }
260 
262 { assert(1 == matrix_double_transposition(Amat, ATmat)); }
263 
265 { assert(1 == matrix_double_solve_posdef(Amat, Bmat)); }
266 
268 { assert(1 == matrix_double_symmetric_real_eigenvalues(Amat, Bmat)); }
matrix_double_s::pData
double * pData
Definition: cont_types.h:59
mat_sub
void mat_sub(matrix_double_t *Amat, matrix_double_t *Bmat, matrix_double_t *Cmat)
Matrix subtraction, C <– A - B, and asserts that this is done correctly.
Definition: cont_matrix_math.c:252
matrix_allocate
void matrix_allocate(matrix_double_t *matrix, int numRows, int numCols)
Allocate memory for a matrix struct of given dimensions.
Definition: cont_types.c:65
mat_add_inplace
void mat_add_inplace(matrix_double_t *Amat, matrix_double_t *Bmat)
In-place matrix addition, A <– A + B, asserts that this is done correctly.
Definition: cont_matrix_math.c:249
matrix_double_s::numRows
int numRows
Definition: cont_types.h:57
matrix_double_solve_posdef
int matrix_double_solve_posdef(matrix_double_t *Amat, matrix_double_t *Bmat)
Solve the linear system AX=B, writing X into B, for PSD real A.
Definition: cont_matrix_math.c:143
matrix_double_addition_inplace
int matrix_double_addition_inplace(matrix_double_t *Amat, matrix_double_t *Bmat)
In-place matrix addition, A <– A + B.
Definition: cont_matrix_math.c:43
matrix_zero
void matrix_zero(matrix_double_t *matrix)
Set all antries of a matrix to zero.
Definition: cont_types.c:49
mat_eigvals
void mat_eigvals(matrix_double_t *Amat, matrix_double_t *Bmat)
Computethe eigenvalues of a real symmetric A to B, asserts that this is done correctly.
Definition: cont_matrix_math.c:267
cont_matrix_math.h
matrix_double_s
Matrix object used for all matrix manipulation.
Definition: cont_types.h:50
matrix_double_subtraction_inplace
int matrix_double_subtraction_inplace(matrix_double_t *Amat, matrix_double_t *Bmat)
In-place subtraction addition, A <– A - B.
Definition: cont_matrix_math.c:72
matrix_double_transposition
int matrix_double_transposition(matrix_double_t *Amat, matrix_double_t *ATmat)
Matrix transposition, A^T <– transpose(A)
Definition: cont_matrix_math.c:128
matrix_double_addition
int matrix_double_addition(matrix_double_t *Amat, matrix_double_t *Bmat, matrix_double_t *Cmat)
Matrix addition, C <– A + B.
Definition: cont_matrix_math.c:27
matrix_double_subtraction
int matrix_double_subtraction(matrix_double_t *Amat, matrix_double_t *Bmat, matrix_double_t *Cmat)
Matrix subtraction, C <– A - B.
Definition: cont_matrix_math.c:56
matrix_double_s::numCols
int numCols
Definition: cont_types.h:58
mat_sol
void mat_sol(matrix_double_t *Amat, matrix_double_t *Bmat)
Compute, without changing A, the eigenvalues of a real symmetric A to B, asserts that this is done co...
Definition: cont_matrix_math.c:264
mat_trans
void mat_trans(matrix_double_t *Amat, matrix_double_t *ATmat)
Matrix transposition, A^T <– transpose(A), asserts that this is done correctly.
Definition: cont_matrix_math.c:261
matrix_double_multiplication
int matrix_double_multiplication(matrix_double_t *Amat, matrix_double_t *Bmat, matrix_double_t *Cmat)
Matrix multiplication, C <– A * B.
Definition: cont_matrix_math.c:85
matrix_set
void matrix_set(matrix_double_t *mat, int row, int column, double value)
Set an entry of a matrix (irrespective of the used memory layout)
Definition: cont_types.c:40
matrix_copy
void matrix_copy(matrix_double_t *Amat, matrix_double_t *Bmat)
Copy one metrix into another Bmat <– Amat, overwriting Bmat.
Definition: cont_types.c:54
mat_add
void mat_add(matrix_double_t *Amat, matrix_double_t *Bmat, matrix_double_t *Cmat)
Matrix addition, C <– A + B, asserts that this is done correctly.
Definition: cont_matrix_math.c:246
matrix_double_symmetric_real_eigenvalues
int matrix_double_symmetric_real_eigenvalues(matrix_double_t *Amat, matrix_double_t *eigVals)
Compute, without changing A, the eigenvalues of a real symmetric A to B.
Definition: cont_matrix_math.c:176
mat_mul
void mat_mul(matrix_double_t *Amat, matrix_double_t *Bmat, matrix_double_t *Cmat)
and asserts that this is done correctly
Definition: cont_matrix_math.c:258
mat_sub_inplace
void mat_sub_inplace(matrix_double_t *Amat, matrix_double_t *Bmat)
In-place subtraction addition, A <– A - B, asserts that this is done correctly.
Definition: cont_matrix_math.c:255
matrix_get
double matrix_get(matrix_double_t *mat, int row, int column)
Get an entry of a matrix (irrespective of the used memory layout)
Definition: cont_types.c:32