34 #include <cxmessages.h>
38 #include <cpl_error.h>
52 _giraffe_swap(cxdouble *a, cxdouble *b)
54 register cxdouble tmp = *a;
65 _giraffe_tiny(cxdouble a)
67 return a < 0. ? (a > -1.e-30) : (a < 1.e-30);
70 #ifdef GIRAFFE_USE_giraffe_matrix_gausspiv
87 _giraffe_matrix_gausspiv(cxdouble *ptra, cxdouble *ptrc, cxint n)
104 ptrb = (cxdouble *)cx_calloc(n * n,
sizeof(cxdouble));
106 for(i = 0; i < n; i++) {
107 ptrb[i * n + i] = 1.0;
110 for (i = 1; i <= n; i++) {
113 max = CX_ABS(*(ptra + n * i - n));
116 for (j = i; j <= n; j++) {
117 if (CX_ABS(*(ptra + n * j + i - n - 1)) > max) {
119 max = CX_ABS(*(ptra + n * j + i - n - 1));
125 for (j = i;j <= n;j++) {
126 r = *(ptra + n * maj + j - n - 1);
127 *(ptra + n * maj + j - n - 1) = *(ptra + n * i + j - n - 1);
128 *(ptra + n * i + j - n - 1) = r;
131 for(l = 0; l < n; l++) {
132 r = *(ptrb + l * n + maj - 1);
133 *(ptrb + l * n + maj - 1) = *(ptrb + l * n + i - 1);
134 *(ptrb + l * n + i - 1) = r;
139 for (j = i + 1; j <= n; j++) {
140 t = (*(ptra + (n + 1) * i - n - 1));
141 if (_giraffe_tiny(t) == TRUE) {
144 r = (*(ptra + n * j + i - n - 1)) / t;
145 for(l = 0; l < n; l++) {
146 *(ptrb + l * n + j - 1) -= r * (*(ptrb + l * n + i - 1));
148 for (k = i; k <= n; k++) {
149 *(ptra + n * j + k - n - 1) -=
150 r * (*(ptra + n * i + k - n - 1));
156 for(l = 0; l < n; l++) {
157 for (i = n; i >= 1; i--) {
158 t = (*(ptra + (n + 1) * i - n - 1));
159 if (_giraffe_tiny(t) == TRUE) {
162 *(ptrc + l + (i - 1) * n) = (*(ptrb + l * n + i - 1)) / t;
164 for (j = i - 1;j > 0;j--) {
165 *(ptrb + l * n + j - 1) -=
166 (*(ptra + n * j + i - n - 1)) *
167 (*(ptrc + l + (i - 1) * n));
243 const cxdouble *pt = NULL;
249 cx_assert(matrix != NULL);
251 size = cpl_matrix_get_ncol(matrix) * cpl_matrix_get_nrow(matrix);
254 pt = cpl_matrix_get_data_const(matrix);
258 sigma += diff * diff;
261 return sqrt(sigma / (cxdouble)size2);
284 const cpl_matrix *matrix_fit)
295 const cxdouble *pta = NULL;
296 const cxdouble *ptf = NULL;
302 cx_assert(matrix != NULL);
303 cx_assert(matrix_fit != NULL);
305 ancol = cpl_matrix_get_ncol(matrix);
306 anrow = cpl_matrix_get_nrow(matrix);
307 fncol = cpl_matrix_get_ncol(matrix_fit);
308 fnrow = cpl_matrix_get_nrow(matrix_fit);
310 if ((ancol * anrow) != (fncol * fnrow)) {
314 size = ancol * anrow;
317 pta = cpl_matrix_get_data_const(matrix);
318 ptf = cpl_matrix_get_data_const(matrix_fit);
321 diff = *pta++ - *ptf++;
322 sigma += diff * diff;
325 return sqrt(sigma / (cxdouble) size2);
348 cpl_image *image = NULL;
352 cxint nx = cpl_matrix_get_ncol(matrix);
353 cxint ny = cpl_matrix_get_nrow(matrix);
356 image = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
360 cxdouble *pixels = cpl_image_get_data_double(image);
362 memcpy(pixels, cpl_matrix_get_data_const(matrix),
363 sz *
sizeof(cxdouble));
371 #define PIX_STACK_SIZE 50
393 register cxint j_stack;
398 register cxdouble *pix_arr = NULL;
400 cxint i_stack[PIX_STACK_SIZE] ;
403 pix_arr = cpl_matrix_get_data(mA);
404 ir = cpl_matrix_get_nrow(mA) * cpl_matrix_get_ncol(mA);
410 for (j = l + 1 ; j <= ir ; j++) {
412 for (i = j - 1 ; i >= 1 ; i--) {
413 if (pix_arr[i - 1] <= a) {
416 pix_arr[i] = pix_arr[i - 1];
423 ir = i_stack[j_stack-- - 1];
424 l = i_stack[j_stack-- - 1];
428 _giraffe_swap(&pix_arr[k - 1], &pix_arr[l]);
429 if (pix_arr[l] > pix_arr[ir - 1]) {
430 _giraffe_swap(&pix_arr[l], &pix_arr[ir - 1]);
432 if (pix_arr[l - 1] > pix_arr[ir - 1]) {
433 _giraffe_swap(&pix_arr[l - 1], &pix_arr[ir - 1]);
435 if (pix_arr[l] > pix_arr[l - 1]) {
436 _giraffe_swap(&pix_arr[l], &pix_arr[l - 1]);
444 }
while (pix_arr[i - 1] < a);
448 }
while (pix_arr[j - 1] > a);
453 _giraffe_swap(&pix_arr[i - 1], &pix_arr[j - 1]);
455 pix_arr[l - 1] = pix_arr[j - 1];
458 if (j_stack > PIX_STACK_SIZE) {
462 if (ir - i + 1 >= j - l) {
463 i_stack[j_stack - 1] = ir;
464 i_stack[j_stack - 2] = i;
468 i_stack[j_stack - 1] = j - 1;
469 i_stack[j_stack - 2] = l;
479 #undef PIX_STACK_SIZE
514 cpl_matrix* m1 = NULL;
515 cpl_matrix* m2 = NULL;
516 cpl_matrix* m3 = NULL;
517 cpl_matrix* mX = NULL;
520 cx_assert(mA != NULL);
521 cx_assert(mB != NULL);
522 cx_assert(cpl_matrix_get_ncol(mA) == cpl_matrix_get_ncol(mB));
524 m1 = cpl_matrix_transpose_create(mA);
525 m2 = cpl_matrix_product_create(mA, m1);
526 m3 = cpl_matrix_invert_create(m2);
529 cpl_matrix_delete(m2);
532 cpl_matrix_delete(m1);
538 cpl_matrix_delete(m2);
540 m2 = cpl_matrix_product_create(mB, m1);
542 cpl_matrix_delete(m1);
545 mX = cpl_matrix_product_create(m2, m3);
547 cpl_matrix_delete(m2);
550 cpl_matrix_delete(m3);
588 const cpl_matrix* Cb, cpl_matrix* Cx)
591 const char*
const _id =
"giraffe_matrix_solve_cholesky";
596 cpl_matrix* AT = NULL;
597 cpl_matrix* ATC = NULL;
598 cpl_matrix* ATCA = NULL;
599 cpl_matrix* ATCb = NULL;
600 cpl_matrix* C = NULL;
601 cpl_matrix* X = NULL;
602 cpl_matrix* x = NULL;
604 cpl_error_code status = CPL_ERROR_NONE;
607 if ((A == NULL) || (b == NULL)) {
609 cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
614 m = cpl_matrix_get_nrow(A);
615 n = cpl_matrix_get_ncol(A);
617 if ((cpl_matrix_get_nrow(b) != m) || (cpl_matrix_get_ncol(b) != 1)) {
619 cpl_error_set(_id, CPL_ERROR_INCOMPATIBLE_INPUT);
626 if ((cpl_matrix_get_nrow(Cb) != m) || (cpl_matrix_get_ncol(Cb) != m)) {
627 cpl_error_set(_id, CPL_ERROR_INCOMPATIBLE_INPUT);
635 if ((cpl_matrix_get_nrow(Cx) != n) || (cpl_matrix_get_ncol(Cx) != n)) {
636 cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
650 if (cpl_matrix_is_diagonal(Cb, CX_MINDOUBLE) == TRUE) {
652 register cxint i = 0;
654 C = cpl_matrix_new(m, m);
656 for (i = 0; i < m; ++i) {
658 register cxdouble value = cpl_matrix_get(Cb, i, i);
660 if (value <= CX_MINDOUBLE) {
662 cpl_matrix_delete(C);
668 cpl_matrix_set(C, i, i, 1. / value);
674 C = cpl_matrix_invert_create(Cb);
678 cpl_error_set(_id, CPL_ERROR_SINGULAR_MATRIX);
696 C = cpl_matrix_new(m, m);
697 cpl_matrix_fill_diagonal(C, 1., 0);
702 AT = cpl_matrix_transpose_create(A);
703 ATC = cpl_matrix_product_create(AT, C);
705 cpl_matrix_delete(AT);
708 cpl_matrix_delete(C);
712 ATCA = cpl_matrix_product_create(ATC, A);
713 ATCb = cpl_matrix_product_create(ATC, b);
715 cpl_matrix_delete(ATC);
723 status = cpl_matrix_decomp_chol(ATCA);
725 if (status != CPL_ERROR_NONE) {
727 cpl_matrix_delete(ATCA);
730 cpl_matrix_delete(ATCb);
748 X = cpl_matrix_new(n, n + 1);
750 cpl_matrix_fill_diagonal(X, 1., 0);
751 cpl_matrix_copy(X, ATCb, 0, n);
753 cpl_matrix_delete(ATCb);
757 status = cpl_matrix_solve_chol(ATCA, X);
759 cpl_matrix_delete(ATCA);
762 if (status != CPL_ERROR_NONE) {
763 cpl_matrix_delete(X);
773 x = cpl_matrix_extract_column(X, n);
776 cpl_matrix_copy(Cx, X, 0, 0);
779 cpl_matrix_delete(X);
809 cxdouble *pd_matrix = NULL;
811 cx_assert(matrix != NULL);
813 pd_matrix = cpl_matrix_get_data(matrix);
814 nc_matrix = cpl_matrix_get_ncol(matrix);
815 nr_matrix = cpl_matrix_get_nrow(matrix);
817 memset(pd_matrix, 0, nr_matrix * nc_matrix *
sizeof(cxdouble));
854 const cxdouble *pd_m = NULL;
856 cx_string *buffer = NULL;
857 cx_string *tmp = NULL;
859 if (matrix == NULL) {
863 pd_m = cpl_matrix_get_data_const(matrix);
865 nr = cpl_matrix_get_nrow(matrix);
866 nc = cpl_matrix_get_ncol(matrix);
872 buffer = cx_string_new();
873 tmp = cx_string_new();
876 for (i = 0; i < nc; i++) {
877 cx_string_sprintf(tmp,
" %d", i);
878 cx_string_append(buffer, cx_string_get(tmp));
881 cpl_msg_debug(
"",
"%s", cx_string_get(buffer));
884 for (k = 0, i = 0; i < nr; i++) {
885 cx_string_sprintf(buffer,
" %d", i);
886 for (j = 0; j < nc; j++, k++) {
887 cx_string_sprintf(tmp,
" %+18.12f", pd_m[k]);
888 cx_string_append(buffer, cx_string_get(tmp));
891 cpl_msg_debug(
"",
"%s", cx_string_get(buffer));
894 cx_string_delete(tmp);
895 cx_string_delete(buffer);
cxdouble giraffe_matrix_sigma_mean(const cpl_matrix *matrix, cxdouble mean)
Compute sigma of matrix elements, with a given mean value.
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.
cxint giraffe_matrix_sort(cpl_matrix *mA)
Sort in place the matrix elements in ascending order.
cpl_matrix * giraffe_matrix_leastsq(const cpl_matrix *mA, const cpl_matrix *mB)
Computes the solution of an equation using a pseudo-inverse.
void giraffe_matrix_dump(const cpl_matrix *matrix, cxint max_rows)
Output a maximum number of rows of the input matrix.
cxdouble giraffe_matrix_sigma_fit(const cpl_matrix *matrix, const cpl_matrix *matrix_fit)
Compute sigma of matrix fit.
cxint giraffe_matrix_clear(cpl_matrix *matrix)
Set all elements of a matrix to zero.
cpl_image * giraffe_matrix_create_image(const cpl_matrix *matrix)
Converts a matrix into an image.