26 #include <cxmessages.h>
30 #include <cpl_error.h>
44 _giraffe_swap(cxdouble *a, cxdouble *b)
46 register cxdouble tmp = *a;
57 _giraffe_tiny(cxdouble a)
59 return a < 0. ? (a > -1.e-30) : (a < 1.e-30);
62 #ifdef GIRAFFE_USE_giraffe_matrix_gausspiv
79 _giraffe_matrix_gausspiv(cxdouble *ptra, cxdouble *ptrc, cxint n)
96 ptrb = (cxdouble *)cx_calloc(n * n,
sizeof(cxdouble));
98 for(i = 0; i < n; i++) {
99 ptrb[i * n + i] = 1.0;
102 for (i = 1; i <= n; i++) {
105 max = CX_ABS(*(ptra + n * i - n));
108 for (j = i; j <= n; j++) {
109 if (CX_ABS(*(ptra + n * j + i - n - 1)) > max) {
111 max = CX_ABS(*(ptra + n * j + i - n - 1));
117 for (j = i;j <= n;j++) {
118 r = *(ptra + n * maj + j - n - 1);
119 *(ptra + n * maj + j - n - 1) = *(ptra + n * i + j - n - 1);
120 *(ptra + n * i + j - n - 1) = r;
123 for(l = 0; l < n; l++) {
124 r = *(ptrb + l * n + maj - 1);
125 *(ptrb + l * n + maj - 1) = *(ptrb + l * n + i - 1);
126 *(ptrb + l * n + i - 1) = r;
131 for (j = i + 1; j <= n; j++) {
132 t = (*(ptra + (n + 1) * i - n - 1));
133 if (_giraffe_tiny(t) == TRUE) {
136 r = (*(ptra + n * j + i - n - 1)) / t;
137 for(l = 0; l < n; l++) {
138 *(ptrb + l * n + j - 1) -= r * (*(ptrb + l * n + i - 1));
140 for (k = i; k <= n; k++) {
141 *(ptra + n * j + k - n - 1) -=
142 r * (*(ptra + n * i + k - n - 1));
148 for(l = 0; l < n; l++) {
149 for (i = n; i >= 1; i--) {
150 t = (*(ptra + (n + 1) * i - n - 1));
151 if (_giraffe_tiny(t) == TRUE) {
154 *(ptrc + l + (i - 1) * n) = (*(ptrb + l * n + i - 1)) / t;
156 for (j = i - 1;j > 0;j--) {
157 *(ptrb + l * n + j - 1) -=
158 (*(ptra + n * j + i - n - 1)) *
159 (*(ptrc + l + (i - 1) * n));
235 const cxdouble *pt = NULL;
241 cx_assert(matrix != NULL);
243 size = cpl_matrix_get_ncol(matrix) * cpl_matrix_get_nrow(matrix);
246 pt = cpl_matrix_get_data_const(matrix);
250 sigma += diff * diff;
253 return sqrt(sigma / (cxdouble)size2);
276 const cpl_matrix *matrix_fit)
287 const cxdouble *pta = NULL;
288 const cxdouble *ptf = NULL;
294 cx_assert(matrix != NULL);
295 cx_assert(matrix_fit != NULL);
297 ancol = cpl_matrix_get_ncol(matrix);
298 anrow = cpl_matrix_get_nrow(matrix);
299 fncol = cpl_matrix_get_ncol(matrix_fit);
300 fnrow = cpl_matrix_get_nrow(matrix_fit);
302 if ((ancol * anrow) != (fncol * fnrow)) {
306 size = ancol * anrow;
309 pta = cpl_matrix_get_data_const(matrix);
310 ptf = cpl_matrix_get_data_const(matrix_fit);
313 diff = *pta++ - *ptf++;
314 sigma += diff * diff;
317 return sqrt(sigma / (cxdouble) size2);
340 cpl_image *image = NULL;
344 cxint nx = cpl_matrix_get_ncol(matrix);
345 cxint ny = cpl_matrix_get_nrow(matrix);
348 image = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
352 cxdouble *pixels = cpl_image_get_data_double(image);
354 memcpy(pixels, cpl_matrix_get_data_const(matrix),
355 sz *
sizeof(cxdouble));
363 #define PIX_STACK_SIZE 50
385 register cxint j_stack;
390 register cxdouble *pix_arr = NULL;
392 cxint i_stack[PIX_STACK_SIZE] ;
395 pix_arr = cpl_matrix_get_data(mA);
396 ir = cpl_matrix_get_nrow(mA) * cpl_matrix_get_ncol(mA);
402 for (j = l + 1 ; j <= ir ; j++) {
404 for (i = j - 1 ; i >= 1 ; i--) {
405 if (pix_arr[i - 1] <= a) {
408 pix_arr[i] = pix_arr[i - 1];
415 ir = i_stack[j_stack-- - 1];
416 l = i_stack[j_stack-- - 1];
420 _giraffe_swap(&pix_arr[k - 1], &pix_arr[l]);
421 if (pix_arr[l] > pix_arr[ir - 1]) {
422 _giraffe_swap(&pix_arr[l], &pix_arr[ir - 1]);
424 if (pix_arr[l - 1] > pix_arr[ir - 1]) {
425 _giraffe_swap(&pix_arr[l - 1], &pix_arr[ir - 1]);
427 if (pix_arr[l] > pix_arr[l - 1]) {
428 _giraffe_swap(&pix_arr[l], &pix_arr[l - 1]);
436 }
while (pix_arr[i - 1] < a);
440 }
while (pix_arr[j - 1] > a);
445 _giraffe_swap(&pix_arr[i - 1], &pix_arr[j - 1]);
447 pix_arr[l - 1] = pix_arr[j - 1];
450 if (j_stack > PIX_STACK_SIZE) {
454 if (ir - i + 1 >= j - l) {
455 i_stack[j_stack - 1] = ir;
456 i_stack[j_stack - 2] = i;
460 i_stack[j_stack - 1] = j - 1;
461 i_stack[j_stack - 2] = l;
471 #undef PIX_STACK_SIZE
506 cpl_matrix* m1 = NULL;
507 cpl_matrix* m2 = NULL;
508 cpl_matrix* m3 = NULL;
509 cpl_matrix* mX = NULL;
512 cx_assert(mA != NULL);
513 cx_assert(mB != NULL);
514 cx_assert(cpl_matrix_get_ncol(mA) == cpl_matrix_get_ncol(mB));
516 m1 = cpl_matrix_transpose_create(mA);
517 m2 = cpl_matrix_product_create(mA, m1);
518 m3 = cpl_matrix_invert_create(m2);
521 cpl_matrix_delete(m2);
524 cpl_matrix_delete(m1);
530 cpl_matrix_delete(m2);
532 m2 = cpl_matrix_product_create(mB, m1);
534 cpl_matrix_delete(m1);
537 mX = cpl_matrix_product_create(m2, m3);
539 cpl_matrix_delete(m2);
542 cpl_matrix_delete(m3);
580 const cpl_matrix* Cb, cpl_matrix* Cx)
583 const char*
const _id =
"giraffe_matrix_solve_cholesky";
588 cpl_matrix* AT = NULL;
589 cpl_matrix* ATC = NULL;
590 cpl_matrix* ATCA = NULL;
591 cpl_matrix* ATCb = NULL;
592 cpl_matrix* C = NULL;
593 cpl_matrix* X = NULL;
594 cpl_matrix* x = NULL;
596 cpl_error_code status = CPL_ERROR_NONE;
599 if ((A == NULL) || (b == NULL)) {
601 cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
606 m = cpl_matrix_get_nrow(A);
607 n = cpl_matrix_get_ncol(A);
609 if ((cpl_matrix_get_nrow(b) != m) || (cpl_matrix_get_ncol(b) != 1)) {
611 cpl_error_set(_id, CPL_ERROR_INCOMPATIBLE_INPUT);
618 if ((cpl_matrix_get_nrow(Cb) != m) || (cpl_matrix_get_ncol(Cb) != m)) {
619 cpl_error_set(_id, CPL_ERROR_INCOMPATIBLE_INPUT);
627 if ((cpl_matrix_get_nrow(Cx) != n) || (cpl_matrix_get_ncol(Cx) != n)) {
628 cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
642 if (cpl_matrix_is_diagonal(Cb, CX_MINDOUBLE) == TRUE) {
644 register cxint i = 0;
646 C = cpl_matrix_new(m, m);
648 for (i = 0; i < m; ++i) {
650 register cxdouble value = cpl_matrix_get(Cb, i, i);
652 if (value <= CX_MINDOUBLE) {
654 cpl_matrix_delete(C);
660 cpl_matrix_set(C, i, i, 1. / value);
666 C = cpl_matrix_invert_create(Cb);
670 cpl_error_set(_id, CPL_ERROR_SINGULAR_MATRIX);
688 C = cpl_matrix_new(m, m);
689 cpl_matrix_fill_diagonal(C, 1., 0);
694 AT = cpl_matrix_transpose_create(A);
695 ATC = cpl_matrix_product_create(AT, C);
697 cpl_matrix_delete(AT);
700 cpl_matrix_delete(C);
704 ATCA = cpl_matrix_product_create(ATC, A);
705 ATCb = cpl_matrix_product_create(ATC, b);
707 cpl_matrix_delete(ATC);
715 status = cpl_matrix_decomp_chol(ATCA);
717 if (status != CPL_ERROR_NONE) {
719 cpl_matrix_delete(ATCA);
722 cpl_matrix_delete(ATCb);
740 X = cpl_matrix_new(n, n + 1);
742 cpl_matrix_fill_diagonal(X, 1., 0);
743 cpl_matrix_copy(X, ATCb, 0, n);
745 cpl_matrix_delete(ATCb);
749 status = cpl_matrix_solve_chol(ATCA, X);
751 cpl_matrix_delete(ATCA);
754 if (status != CPL_ERROR_NONE) {
755 cpl_matrix_delete(X);
765 x = cpl_matrix_extract_column(X, n);
768 cpl_matrix_copy(Cx, X, 0, 0);
771 cpl_matrix_delete(X);
801 cxdouble *pd_matrix = NULL;
803 cx_assert(matrix != NULL);
805 pd_matrix = cpl_matrix_get_data(matrix);
806 nc_matrix = cpl_matrix_get_ncol(matrix);
807 nr_matrix = cpl_matrix_get_nrow(matrix);
809 memset(pd_matrix, 0, nr_matrix * nc_matrix *
sizeof(cxdouble));
846 const cxdouble *pd_m = NULL;
848 cx_string *buffer = NULL;
849 cx_string *tmp = NULL;
851 if (matrix == NULL) {
855 pd_m = cpl_matrix_get_data_const(matrix);
857 nr = cpl_matrix_get_nrow(matrix);
858 nc = cpl_matrix_get_ncol(matrix);
864 buffer = cx_string_new();
865 tmp = cx_string_new();
868 for (i = 0; i < nc; i++) {
869 cx_string_sprintf(tmp,
" %d", i);
870 cx_string_append(buffer, cx_string_get(tmp));
873 cpl_msg_debug(
"",
"%s", cx_string_get(buffer));
876 for (k = 0, i = 0; i < nr; i++) {
877 cx_string_sprintf(buffer,
" %d", i);
878 for (j = 0; j < nc; j++, k++) {
879 cx_string_sprintf(tmp,
" %+18.12f", pd_m[k]);
880 cx_string_append(buffer, cx_string_get(tmp));
883 cpl_msg_debug(
"",
"%s", cx_string_get(buffer));
886 cx_string_delete(tmp);
887 cx_string_delete(buffer);
cxint giraffe_matrix_clear(cpl_matrix *matrix)
Set all elements of a matrix to zero.
void giraffe_matrix_dump(const cpl_matrix *matrix, cxint max_rows)
Output a maximum number of rows of the input matrix.
cpl_image * giraffe_matrix_create_image(const cpl_matrix *matrix)
Converts a matrix into an image.
cxdouble giraffe_matrix_sigma_fit(const cpl_matrix *matrix, const cpl_matrix *matrix_fit)
Compute sigma of matrix fit.
cpl_matrix * giraffe_matrix_solve_cholesky(const cpl_matrix *A, const cpl_matrix *b, const cpl_matrix *Cb, cpl_matrix *Cx)
Solve a linear system using the Cholesky decomposition.
cpl_matrix * giraffe_matrix_leastsq(const cpl_matrix *mA, const cpl_matrix *mB)
Computes the solution of an equation using a pseudo-inverse.
cxint giraffe_matrix_sort(cpl_matrix *mA)
Sort in place the matrix elements in ascending order.
cxdouble giraffe_matrix_sigma_mean(const cpl_matrix *matrix, cxdouble mean)
Compute sigma of matrix elements, with a given mean value.