diff options
author | Thomas White <taw@physics.org> | 2023-07-07 15:02:45 +0200 |
---|---|---|
committer | Thomas White <taw@physics.org> | 2023-07-28 13:22:05 +0200 |
commit | 4f7c412d650e8493e0a356f4159be650cffb4d0b (patch) | |
tree | 23aec2e098197b121f27bbbcf5af2a4c419c1027 /libcrystfel/src/utils.c | |
parent | 1857f41d235359d9ed6c018b63ccda63edba9d2f (diff) |
Factorise matrix operations
This makes the code much clearer. Note that two opposing sign errors
have been fixed in the gradient calculation.
Diffstat (limited to 'libcrystfel/src/utils.c')
-rw-r--r-- | libcrystfel/src/utils.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/libcrystfel/src/utils.c b/libcrystfel/src/utils.c index ae423eed..262a32cc 100644 --- a/libcrystfel/src/utils.c +++ b/libcrystfel/src/utils.c @@ -109,6 +109,65 @@ void show_vector(gsl_vector *v) } +gsl_matrix *matrix_mult(gsl_matrix *A, gsl_matrix *B) +{ + gsl_matrix *r = gsl_matrix_calloc(A->size1, A->size2); + gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, A, B, 0.0, r); + return r; +} + + +gsl_matrix *matrix_mult3(gsl_matrix *A, gsl_matrix *B, gsl_matrix *C) +{ + gsl_matrix *tmp = matrix_mult(B, C); + gsl_matrix *r = matrix_mult(A, tmp); + gsl_matrix_free(tmp); + return r; +} + + +gsl_matrix *matrix_invert(gsl_matrix *m) +{ + gsl_permutation *perm; + gsl_matrix *inv; + int s; + + perm = gsl_permutation_alloc(m->size1); + if ( perm == NULL ) { + ERROR("Couldn't allocate permutation\n"); + gsl_matrix_free(m); + return NULL; + } + + inv = gsl_matrix_alloc(m->size1, m->size2); + if ( inv == NULL ) { + ERROR("Couldn't allocate inverse\n"); + gsl_matrix_free(m); + gsl_permutation_free(perm); + return NULL; + } + + if ( gsl_linalg_LU_decomp(m, perm, &s) ) { + ERROR("Couldn't decompose matrix\n"); + gsl_matrix_free(m); + gsl_permutation_free(perm); + return NULL; + } + + if ( gsl_linalg_LU_invert(m, perm, inv) ) { + ERROR("Couldn't invert cell matrix:\n"); + gsl_matrix_free(m); + gsl_permutation_free(perm); + return NULL; + } + + gsl_permutation_free(perm); + gsl_matrix_free(m); + + return inv; +} + + static int check_eigen(gsl_vector *e_val, int verbose) { int i; |