GRASS 8 Programmer's Manual 8.6.0dev(2026)-56a9afeb9f
Loading...
Searching...
No Matches
la.c
Go to the documentation of this file.
1/******************************************************************************
2 * la.c
3 * wrapper modules for linear algebra problems
4 * linking to BLAS / LAPACK (and others?)
5
6 * @Copyright David D.Gray <ddgray@armadce.demon.co.uk>
7 * 26th. Sep. 2000
8 * Last updated:
9 * 2006-11-23
10 * 2015-01-20
11
12 * This file is part of GRASS. It is free software. You can
13 * redistribute it and/or modify it under the terms of
14 * the GNU General Public License as published by the Free Software
15 * Foundation; either version 2 of the License, or (at your option)
16 * any later version.
17
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22
23 ******************************************************************************/
24
25#include <grass/config.h>
26
27#if defined(HAVE_LIBBLAS) && defined(HAVE_LIBLAPACK)
28
29#include <math.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33
34#if defined(_MSC_VER)
35#include <complex.h>
36#define LAPACK_COMPLEX_CUSTOM
37#define lapack_complex_float _Fcomplex
38#define lapack_complex_double _Dcomplex
39#endif
40
41#include <lapacke.h>
42#if defined(HAVE_CBLAS_ATLAS_H)
43#include <cblas-atlas.h>
44#else
45#include <cblas.h>
46#endif // HAVE_CBLAS_ATLAS_H
47
48#include <grass/gis.h>
49#include <grass/glocale.h>
50#include <grass/la.h>
51
52static int egcmp(const void *pa, const void *pb);
53
54/*!
55 * \fn mat_struct *G_matrix_init(int rows, int cols, int ldim)
56 *
57 * \brief Initialize a matrix structure
58 *
59 * Initialize a matrix structure
60 *
61 * \param rows
62 * \param cols
63 * \param ldim
64 * \return mat_struct
65 */
66mat_struct *G_matrix_init(int rows, int cols, int ldim)
67{
69
70 if (rows < 1 || cols < 1 || ldim < rows) {
71 G_warning(_("Matrix dimensions out of range"));
72 return NULL;
73 }
74
76 tmp_arry->rows = rows;
77 tmp_arry->cols = cols;
78 tmp_arry->ldim = ldim;
79 tmp_arry->type = MATRIX_;
80 tmp_arry->v_indx = -1;
81
82 tmp_arry->vals = (double *)G_calloc(ldim * cols, sizeof(double));
83 tmp_arry->is_init = 1;
84
85 return tmp_arry;
86}
87
88/*!
89 * \fn int G_matrix_zero (mat_struct *A)
90 *
91 * \brief Clears (or resets) the matrix values to 0
92 *
93 * \param A
94 * \return 0 on error; 1 on success
95 */
97{
98 if (!A->vals)
99 return 0;
100
101 memset(A->vals, 0, (A->ldim * A->cols) * sizeof(double));
102
103 return 1;
104}
105
106/*!
107 * \fn int G_matrix_set(mat_struct *A, int rows, int cols, int ldim)
108 *
109 * \brief Set parameters for an initialized matrix
110 *
111 * Set parameters for matrix <b>A</b> that is allocated,
112 * but not yet fully initialized. Is an alternative to G_matrix_init().
113 *
114 * \param A
115 * \param rows
116 * \param cols
117 * \param ldim
118 * \return int
119 */
120int G_matrix_set(mat_struct *A, int rows, int cols, int ldim)
121{
122 if (rows < 1 || cols < 1 || ldim < 0) {
123 G_warning(_("Matrix dimensions out of range"));
124 return -1;
125 }
126
127 A->rows = rows;
128 A->cols = cols;
129 A->ldim = ldim;
130 A->type = MATRIX_;
131 A->v_indx = -1;
132
133 A->vals = (double *)G_calloc(ldim * cols, sizeof(double));
134 A->is_init = 1;
135
136 return 0;
137}
138
139/*!
140 * \fn mat_struct *G_matrix_copy (const mat_struct *A)
141 *
142 * \brief Copy a matrix
143 *
144 * Copy matrix <b>A</b> by exactly duplicating its contents.
145 *
146 * \param A
147 * \return mat_struct
148 */
150{
151 mat_struct *B;
152
153 if (!A->is_init) {
154 G_warning(_("Matrix is not initialised fully."));
155 return NULL;
156 }
157
158 if ((B = G_matrix_init(A->rows, A->cols, A->ldim)) == NULL) {
159 G_warning(_("Unable to allocate space for matrix copy"));
160 return NULL;
161 }
162
163 memcpy(&B->vals[0], &A->vals[0],
164 (size_t)A->cols * A->ldim * sizeof(double));
165
166 return B;
167}
168
169/*!
170 * \fn mat_struct *G_matrix_add (mat_struct *mt1, mat_struct *mt2)
171 *
172 * \brief Adds two matrices
173 *
174 * Adds two matrices <b>mt1</b> and <b>mt2</b> and returns a
175 * resulting matrix. The return structure is automatically initialized.
176 *
177 * \param mt1
178 * \param mt2
179 * \return mat_struct
180 */
185
186/*!
187 * \fn mat_struct *G_matrix_subtract (mat_struct *mt1, mat_struct *mt2)
188 *
189 * \brief Subtract two matrices
190 *
191 * Subtracts two matrices <b>mt1</b> and <b>mt2</b> and returns
192 * a resulting matrix. The return matrix is automatically initialized.
193 *
194 * \param mt1
195 * \param mt2
196 * \return mat_struct
197 */
202
203/*!
204 * \fn mat_struct *G_matrix_scalar_mul(double scalar, mat_struct *matrix,
205 * mat_struct *out)
206 *
207 * \brief Calculates the scalar-matrix multiplication
208 *
209 * Calculates the scalar-matrix multiplication
210 *
211 * \param scalar
212 * \param matrix
213 * \param out
214 * \return mat_struct
215 */
218{
219 int m, n, i, j;
220
221 if (matrix == NULL) {
222 G_warning(_("Input matrix is uninitialized"));
223 return NULL;
224 }
225
226 if (out == NULL)
227 out = G_matrix_init(matrix->rows, matrix->cols, matrix->rows);
228
229 if (out->rows != matrix->rows || out->cols != matrix->cols)
230 out = G_matrix_resize(out, matrix->rows, matrix->cols);
231
232 m = matrix->rows;
233 n = matrix->cols;
234
235 for (i = 0; i < m; i++) {
236 for (j = 0; j < n; j++) {
237 double value = scalar * G_matrix_get_element(matrix, i, j);
238
239 G_matrix_set_element(out, i, j, value);
240 }
241 }
242
243 return (out);
244}
245
246/*!
247 * \fn mat_struct *G_matrix_scale (mat_struct *mt1, const double c)
248 *
249 * \brief Scale a matrix by a scalar value
250 *
251 * Scales matrix <b>mt1</b> by scalar value <b>c</b>. The
252 * resulting matrix is automatically initialized.
253 *
254 * \param mt1
255 * \param c
256 * \return mat_struct
257 */
259{
260 return G__matrix_add(mt1, NULL, c, 0);
261}
262
263/*!
264 * \fn mat_struct *G__matrix_add (mat_struct *mt1, mat_struct *mt2, const double
265 * c1, const double c2)
266 *
267 * \brief General add/subtract/scalar multiply routine
268 *
269 * General add/subtract/scalar multiply routine. <b>c2</b> may be
270 * zero, but <b>c1</b> must be non-zero.
271 *
272 * \param mt1
273 * \param mt2
274 * \param c1
275 * \param c2
276 * \return mat_struct
277 */
279 const double c2)
280{
282 int i, j; /* loop variables */
283
284 if (c1 == 0) {
285 G_warning(_("First scalar multiplier must be non-zero"));
286 return NULL;
287 }
288
289 if (c2 == 0) {
290 if (!mt1->is_init) {
291 G_warning(_("One or both input matrices uninitialised"));
292 return NULL;
293 }
294 }
295
296 else {
297
298 if (!((mt1->is_init) && (mt2->is_init))) {
299 G_warning(_("One or both input matrices uninitialised"));
300 return NULL;
301 }
302
303 if (mt1->rows != mt2->rows || mt1->cols != mt2->cols) {
304 G_warning(_("Matrix order does not match"));
305 return NULL;
306 }
307 }
308
309 if ((mt3 = G_matrix_init(mt1->rows, mt1->cols, mt1->ldim)) == NULL) {
310 G_warning(_("Unable to allocate space for matrix sum"));
311 return NULL;
312 }
313
314 if (c2 == 0) {
315
316 for (i = 0; i < mt3->rows; i++) {
317 for (j = 0; j < mt3->cols; j++) {
318 mt3->vals[i + mt3->ldim * j] =
319 c1 * mt1->vals[i + mt1->ldim * j];
320 }
321 }
322 }
323
324 else {
325
326 for (i = 0; i < mt3->rows; i++) {
327 for (j = 0; j < mt3->cols; j++) {
328 mt3->vals[i + mt3->ldim * j] =
329 c1 * mt1->vals[i + mt1->ldim * j] +
330 c2 * mt2->vals[i + mt2->ldim * j];
331 }
332 }
333 }
334
335 return mt3;
336}
337
338/*!
339 * \fn mat_struct *G_matrix_product (mat_struct *mt1, mat_struct *mt2)
340 *
341 * \brief Returns product of two matrices
342 *
343 * Returns a matrix with the product of matrix <b>mt1</b> and
344 * <b>mt2</b>. The return matrix is automatically initialized.
345 *
346 * \param mt1
347 * \param mt2
348 * \return mat_struct
349 */
351{
353 double unity = 1., zero = 0.;
354 int rows, cols, interdim, lda, ldb;
355
356 if (!((mt1->is_init) || (mt2->is_init))) {
357 G_warning(_("One or both input matrices uninitialised"));
358 return NULL;
359 }
360
361 if (mt1->cols != mt2->rows) {
362 G_warning(_("Matrix order does not match"));
363 return NULL;
364 }
365
366 if ((mt3 = G_matrix_init(mt1->rows, mt2->cols, mt1->ldim)) == NULL) {
367 G_warning(_("Unable to allocate space for matrix product"));
368 return NULL;
369 }
370
371 /* Call the driver */
372
373 rows = (int)mt1->rows;
374 interdim = (int)mt1->cols;
375 cols = (int)mt2->cols;
376
377 lda = (int)mt1->ldim;
378 ldb = (int)mt2->ldim;
379
381 unity, mt1->vals, lda, mt2->vals, ldb, zero, mt3->vals, lda);
382
383 return mt3;
384}
385
386/*!
387 * \fn mat_struct *G_matrix_transpose (mat_struct *mt)
388 *
389 * \brief Transpose a matrix
390 *
391 * Transpose matrix <b>m1</b> by creating a new one and
392 * populating with transposed elements. The return matrix is
393 * automatically initialized.
394 *
395 * \param mt
396 * \return mat_struct
397 */
399{
401 int ldim, ldo;
402 double *dbo, *dbt, *dbx, *dby;
403 int cnt, cnt2;
404
405 /* Word align the workspace blocks */
406 if (mt->cols % 2 == 0)
407 ldim = mt->cols;
408 else
409 ldim = mt->cols + 1;
410
411 mt1 = G_matrix_init(mt->cols, mt->rows, ldim);
412
413 /* Set initial values for reading arrays */
414 dbo = &mt->vals[0];
415 dbt = &mt1->vals[0];
416 ldo = mt->ldim;
417
418 for (cnt = 0; cnt < mt->cols; cnt++) {
419 dbx = dbo;
420 dby = dbt;
421
422 for (cnt2 = 0; cnt2 < ldo - 1; cnt2++) {
423 *dby = *dbx;
424 dby += ldim;
425 dbx++;
426 }
427
428 *dby = *dbx;
429
430 if (cnt < mt->cols - 1) {
431 dbo += ldo;
432 dbt++;
433 }
434 }
435
436 return mt1;
437}
438
439/*!
440 * \fn int G_matrix_LU_solve (const mat_struct *mt1, mat_struct **xmat0,
441 * const mat_struct *bmat, mat_type mtype)
442 *
443 * \brief Solve a general system A.X = B
444 *
445 * Solve a general system A.X = B, where A is a NxN matrix, X and B are
446 * NxC matrices, and we are to solve for C arrays in X given B. Uses LU
447 * decomposition.<br>
448 * Links to LAPACK function dgesv_() and similar to perform the core routine.
449 * (By default solves for a general non-symmetric matrix.)<br>
450 * mtype is a flag to indicate what kind of matrix (real/complex, Hermitian,
451 * symmetric, general etc.) is used (NONSYM, SYM, HERMITIAN).<br>
452 * <b>Warning:</b> NOT YET COMPLETE: only some solutions' options
453 * available. Now, only general real matrix is supported.
454 *
455 * \param mt1
456 * \param xmat0
457 * \param bmat
458 * \param mtype
459 * \return int
460 */
461
462/*** NOT YET COMPLETE: only some solutions' options available ***/
463
466{
467 mat_struct *wmat, *xmat, *mtx;
468
469 if (mt1->is_init == 0 || bmat->is_init == 0) {
470 G_warning(_("Input: one or both data matrices uninitialised"));
471 return -1;
472 }
473
474 if (mt1->rows != mt1->cols || mt1->rows < 1) {
475 G_warning(_("Principal matrix is not properly dimensioned"));
476 return -1;
477 }
478
479 if (bmat->cols < 1) {
480 G_warning(_("Input: you must have at least one array to solve"));
481 return -1;
482 }
483
484 /* Now create solution matrix by copying the original coefficient matrix */
485 if ((xmat = G_matrix_copy(bmat)) == NULL) {
486 G_warning(_("Could not allocate space for solution matrix"));
487 return -1;
488 }
489
490 /* Create working matrix for the coefficient array */
491 if ((mtx = G_matrix_copy(mt1)) == NULL) {
492 G_warning(_("Could not allocate space for working matrix"));
493 return -1;
494 }
495
496 /* Copy the contents of the data matrix, to preserve the
497 original information
498 */
499 if ((wmat = G_matrix_copy(bmat)) == NULL) {
500 G_warning(_("Could not allocate space for working matrix"));
501 return -1;
502 }
503
504 /* Now call appropriate LA driver to solve equations */
505 switch (mtype) {
506
507 case NONSYM: {
508 int *perm, res_info;
509 int num_eqns, nrhs, lda, ldb;
510
511 perm = (int *)G_malloc(wmat->rows * sizeof(int));
512
513 /* Set fields to pass to fortran routine */
514 num_eqns = (int)mt1->rows;
515 nrhs = (int)wmat->cols;
516 lda = (int)mt1->ldim;
517 ldb = (int)wmat->ldim;
518
519 /* Call LA driver */
521 lda, perm, wmat->vals, ldb);
522
523 /* Copy the results from the modified data matrix, taking account
524 of pivot permutations ???
525 */
526
527 /*
528 for(indx1 = 0; indx1 < num_eqns; indx1++) {
529 iperm = perm[indx1];
530 ptin = &wmat->vals[0] + indx1;
531 ptout = &xmat->vals[0] + iperm;
532
533 for(indx2 = 0; indx2 < nrhs - 1; indx2++) {
534 *ptout = *ptin;
535 ptin += wmat->ldim;
536 ptout += xmat->ldim;
537 }
538
539 *ptout = *ptin;
540 }
541 */
542
543 memcpy(xmat->vals, wmat->vals,
544 (size_t)wmat->cols * wmat->ldim * sizeof(double));
545
546 /* Free temp arrays */
547 G_free(perm);
550
551 if (res_info > 0) {
552 G_warning(
553 _("Matrix (or submatrix is singular). Solution undetermined"));
554 return 1;
555 }
556 else if (res_info < 0) {
557 G_warning(_("Problem in LA routine."));
558 return -1;
559 }
560 break;
561 }
562 default: {
563 G_warning(_("Procedure not yet available for selected matrix type"));
564 return -1;
565 }
566 } /* end switch */
567
568 *xmat0 = xmat;
569
570 return 0;
571}
572
573/*!
574 * \fn mat_struct *G_matrix_inverse (mat_struct *mt)
575 *
576 * \brief Returns the matrix inverse
577 *
578 * Calls G_matrix_LU_solve() to obtain matrix inverse using LU
579 * decomposition. Returns NULL on failure.
580 *
581 * \param mt
582 * \return mat_struct
583 */
585{
586 mat_struct *mt0, *res;
587 int i, j, k; /* loop */
588
589 if (mt->rows != mt->cols) {
590 G_warning(_("Matrix is not square. Cannot determine inverse"));
591 return NULL;
592 }
593
594 if ((mt0 = G_matrix_init(mt->rows, mt->rows, mt->ldim)) == NULL) {
595 G_warning(_("Unable to allocate space for matrix"));
596 return NULL;
597 }
598
599 /* Set `B' matrix to unit matrix */
600 for (i = 0; i < mt0->rows - 1; i++) {
601 mt0->vals[i + i * mt0->ldim] = 1.0;
602
603 for (j = i + 1; j < mt0->cols; j++) {
604 mt0->vals[i + j * mt0->ldim] = mt0->vals[j + i * mt0->ldim] = 0.0;
605 }
606 }
607
608 mt0->vals[mt0->rows - 1 + (mt0->rows - 1) * mt0->ldim] = 1.0;
609
610 /* Solve system */
611 if ((k = G_matrix_LU_solve(mt, &res, mt0, NONSYM)) == 1) {
612 G_warning(_("Matrix is singular"));
614 return NULL;
615 }
616 else if (k < 0) {
617 G_warning(_("Problem in LA procedure."));
619 return NULL;
620 }
621 else {
623 return res;
624 }
625}
626
627/*!
628 * \fn void G_matrix_free (mat_struct *mt)
629 *
630 * \brief Free up allocated matrix
631 *
632 * Free up allocated matrix.
633 *
634 * \param mt
635 * \return void
636 */
638{
639 if (mt->is_init)
640 G_free(mt->vals);
641
642 G_free(mt);
643}
644
645/*!
646 * \fn void G_matrix_print (mat_struct *mt)
647 *
648 * \brief Print out a matrix
649 *
650 * Print out a representation of the matrix to standard output.
651 *
652 * \param mt
653 * \return void
654 */
656{
657 int i, j;
658 char buf[2048], numbuf[64];
659
660 for (i = 0; i < mt->rows; i++) {
661 G_strlcpy(buf, "", sizeof(buf));
662
663 for (j = 0; j < mt->cols; j++) {
664 snprintf(numbuf, sizeof(numbuf), "%14.6f",
666 strcat(buf, numbuf);
667 if (j < mt->cols - 1)
668 strcat(buf, ", ");
669 }
670
671 G_message("%s", buf);
672 }
673
674 fprintf(stderr, "\n");
675}
676
677/*!
678 * \fn int G_matrix_set_element (mat_struct *mt, int rowval, int colval, double
679 * val)
680 *
681 * \brief Set the value of the (i, j)th element
682 *
683 * Set the value of the (i, j)th element to a double value. Index values
684 * are C-like ie. zero-based. The row number is given first as is
685 * conventional. Returns -1 if the accessed cell is outside the bounds.
686 *
687 * \param mt
688 * \param rowval
689 * \param colval
690 * \param val
691 * \return int
692 */
693int G_matrix_set_element(mat_struct *mt, int rowval, int colval, double val)
694{
695 if (!mt->is_init) {
696 G_warning(_("Element array has not been allocated"));
697 return -1;
698 }
699
700 if (rowval >= mt->rows || colval >= mt->cols || rowval < 0 || colval < 0) {
701 G_warning(_("Specified element is outside array bounds"));
702 return -1;
703 }
704
705 mt->vals[rowval + colval * mt->ldim] = (double)val;
706
707 return 0;
708}
709
710/*!
711 * \fn double G_matrix_get_element (mat_struct *mt, int rowval, int colval)
712 *
713 * \brief Retrieve value of the (i,j)th element
714 *
715 * Retrieve the value of the (i, j)th element to a double value. Index
716 * values are C-like ie. zero-based.
717 * <b>Note:</b> Does currently not set an error flag for bounds checking.
718 *
719 * \param mt
720 * \param rowval
721 * \param colval
722 * \return double
723 */
725{
726 double val;
727
728 /* Should do some checks, but this would require an error control
729 system: later? */
730
731 return (val = (double)mt->vals[rowval + colval * mt->ldim]);
732}
733
734/*!
735 * \fn vec_struct *G_matvect_get_column (mat_struct *mt, int col)
736 *
737 * \brief Retrieve a column of the matrix to a vector structure
738 *
739 * Retrieve a column of matrix <b>mt</b> to a returning vector structure
740 *
741 * \param mt
742 * \param col
743 * \return vec_struct
744 */
746{
747 int i; /* loop */
749
750 if (col < 0 || col >= mt->cols) {
751 G_warning(_("Specified matrix column index is outside range"));
752 return NULL;
753 }
754
755 if (!mt->is_init) {
756 G_warning(_("Matrix is not initialised"));
757 return NULL;
758 }
759
760 if ((vc1 = G_vector_init(mt->rows, mt->ldim, CVEC)) == NULL) {
761 G_warning(_("Could not allocate space for vector structure"));
762 return NULL;
763 }
764
765 for (i = 0; i < mt->rows; i++)
768
769 return vc1;
770}
771
772/*!
773 * \fn vec_struct *G_matvect_get_row (mat_struct *mt, int row)
774 *
775 * \brief Retrieve a row of the matrix to a vector structure
776 *
777 * Retrieves a row from matrix <b>mt</b> and returns it in a vector
778 * structure.
779 *
780 * \param mt
781 * \param row
782 * \return vec_struct
783 */
785{
786 int i; /* loop */
788
789 if (row < 0 || row >= mt->cols) {
790 G_warning(_("Specified matrix row index is outside range"));
791 return NULL;
792 }
793
794 if (!mt->is_init) {
795 G_warning(_("Matrix is not initialised"));
796 return NULL;
797 }
798
799 if ((vc1 = G_vector_init(mt->cols, mt->ldim, RVEC)) == NULL) {
800 G_warning(_("Could not allocate space for vector structure"));
801 return NULL;
802 }
803
804 for (i = 0; i < mt->cols; i++)
806 G_matrix_get_element(mt, row, i));
807
808 return vc1;
809}
810
811/*!
812 * \fn int G_matvect_extract_vector (mat_struct *mt, vtype vt, int indx)
813 *
814 * \brief Convert matrix to vector
815 *
816 * Convert the matrix <b>mt</b> to a vector structure. The vtype,
817 * <b>vt</b>, is RVEC or CVEC which specifies a row vector or column
818 * vector. The index, <b>indx</b>, indicates the row/column number (zero based).
819 *
820 * \param mt
821 * \param vt
822 * \param indx
823 * \return int
824 */
826{
827 if (vt == RVEC && indx >= mt->rows) {
828 G_warning(_("Specified row index is outside range"));
829 return -1;
830 }
831
832 else if (vt == CVEC && indx >= mt->cols) {
833 G_warning(_("Specified column index is outside range"));
834 return -1;
835 }
836
837 switch (vt) {
838
839 case RVEC: {
840 mt->type = ROWVEC_;
841 mt->v_indx = indx;
842 break;
843 }
844
845 case CVEC: {
846 mt->type = COLVEC_;
847 mt->v_indx = indx;
848 break;
849 }
850
851 default: {
852 G_warning(_("Unknown vector type."));
853 return -1;
854 }
855 }
856
857 return 0;
858}
859
860/*!
861 * \fn int G_matvect_retrieve_matrix (vec_struct *vc)
862 *
863 * \brief Revert a vector to matrix
864 *
865 * Revert vector <b>vc</b> to a matrix.
866 *
867 * \param vc
868 * \return int
869 */
871{
872 /* We have to take the integrity of the vector structure
873 largely on trust
874 */
875
876 vc->type = MATRIX_;
877 vc->v_indx = -1;
878
879 return 0;
880}
881
882/*!
883 * \fn vec_struct *G_matvect_product(mat_struct *A, vec_struct *b, vec_struct
884 * *out)
885 *
886 * \brief Calculates the matrix-vector product
887 *
888 * Calculates the product of a matrix and a vector
889 *
890 * \param A
891 * \param b
892 * \return vec_struct
893 */
895{
896 unsigned int i, m, n, j;
897 register double sum;
898
899 /* G_message("A=%d,%d,%d", A->cols, A->rows, A->ldim); */
900 /* G_message("B=%d,%d,%d", b->cols, b->rows, b->ldim); */
901 if (A->cols != b->cols) {
902 G_warning(_("Input matrix and vector have differing dimensions1"));
903
904 return NULL;
905 }
906 if (!out) {
907 G_warning(_("Output vector is uninitialized"));
908 return NULL;
909 }
910 /* if (out->ldim != A->rows) { */
911 /* G_warning (_("Output vector has incorrect dimension")); */
912 /* exit(1); */
913 /* return NULL; */
914 /* } */
915
916 m = A->rows;
917 n = A->cols;
918
919 for (i = 0; i < m; i++) {
920 sum = 0.0;
921 /* int width = A->rows; */
922
923 for (j = 0; j < n; j++) {
924
925 sum +=
927 /*sum += A->vals[i + j * width] * b->vals[j]; */
928 out->vals[i] = sum;
929 }
930 }
931 return (out);
932}
933
934/*!
935 * \fn vec_struct *G_vector_init (int cells, int ldim, vtype vt)
936 *
937 * \brief Initialize a vector structure
938 *
939 * Returns an initialized vector structure with <b>cell</b> cells,
940 * of dimension <b>ldim</b>, and of type <b>vt</b>.
941 *
942 * \param cells
943 * \param ldim
944 * \param vt
945 * \return vec_struct
946 */
947vec_struct *G_vector_init(int cells, int ldim, vtype vt)
948{
950
951 if ((cells < 1) || (vt == RVEC && ldim < 1) ||
952 (vt == CVEC && ldim < cells) || ldim < 0) {
953 G_warning("Vector dimensions out of range.");
954 return NULL;
955 }
956
958
959 if (vt == RVEC) {
960 tmp_arry->rows = 1;
961 tmp_arry->cols = cells;
962 tmp_arry->ldim = ldim;
963 tmp_arry->type = ROWVEC_;
964 }
965
966 else if (vt == CVEC) {
967 tmp_arry->rows = cells;
968 tmp_arry->cols = 1;
969 tmp_arry->ldim = ldim;
970 tmp_arry->type = COLVEC_;
971 }
972
973 tmp_arry->v_indx = 0;
974
975 tmp_arry->vals = (double *)G_calloc(ldim * tmp_arry->cols, sizeof(double));
976 tmp_arry->is_init = 1;
977
978 return tmp_arry;
979}
980
981/*!
982 * \fn void G_vector_free (vec_struct *v)
983 *
984 * \brief Free an allocated vector structure
985 *
986 * Free an allocated vector structure.
987 *
988 * \param v
989 * \return void
990 */
992{
993 if (v->is_init)
994 G_free(v->vals);
995
996 G_free(v);
997}
998
999/*!
1000 * \fn vec_struct *G_vector_sub (vec_struct *v1, vec_struct *v2, vec_struct
1001 * *out)
1002 *
1003 * \brief Subtract two vectors
1004 *
1005 * Subtracts two vectors, <b>v1</b> and <b>v2</b>, and returns and
1006 * populates vector <b>out</b>.
1007 *
1008 * \param v1
1009 * \param v2
1010 * \param out
1011 * \return vec_struct
1012 */
1014{
1015 int idx1, idx2, idx0;
1016 int i;
1017
1018 if (!out->is_init) {
1019 G_warning(_("Output vector is uninitialized"));
1020 return NULL;
1021 }
1022
1023 if (v1->type != v2->type) {
1024 G_warning(_("Vectors are not of the same type"));
1025 return NULL;
1026 }
1027
1028 if (v1->type != out->type) {
1029 G_warning(_("Output vector is of incorrect type"));
1030 return NULL;
1031 }
1032
1033 if (v1->type == MATRIX_) {
1034 G_warning(_("Matrices not allowed"));
1035 return NULL;
1036 }
1037
1038 if ((v1->type == ROWVEC_ && v1->cols != v2->cols) ||
1039 (v1->type == COLVEC_ && v1->rows != v2->rows)) {
1040 G_warning(_("Vectors have differing dimensions"));
1041 return NULL;
1042 }
1043
1044 if ((v1->type == ROWVEC_ && v1->cols != out->cols) ||
1045 (v1->type == COLVEC_ && v1->rows != out->rows)) {
1046 G_warning(_("Output vector has incorrect dimension"));
1047 return NULL;
1048 }
1049
1050 idx1 = (v1->v_indx > 0) ? v1->v_indx : 0;
1051 idx2 = (v2->v_indx > 0) ? v2->v_indx : 0;
1052 idx0 = (out->v_indx > 0) ? out->v_indx : 0;
1053
1054 if (v1->type == ROWVEC_) {
1055 for (i = 0; i < v1->cols; i++)
1057 G_matrix_get_element(v1, idx1, i) -
1058 G_matrix_get_element(v2, idx2, i));
1059 }
1060 else {
1061 for (i = 0; i < v1->rows; i++)
1063 G_matrix_get_element(v1, i, idx1) -
1064 G_matrix_get_element(v2, i, idx2));
1065 }
1066
1067 return out;
1068}
1069
1070/*!
1071 * \fn int G_vector_set (vec_struct *A, int cells, int ldim, vtype vt, int
1072 * vindx)
1073 *
1074 * \brief Set parameters for vector structure
1075 *
1076 * Set parameters for a vector structure that is
1077 * allocated but not yet initialised fully. The vtype is RVEC or
1078 * CVEC which specifies a row vector or column vector.
1079 *
1080 * \param A
1081 * \param cells
1082 * \param ldim
1083 * \param vt
1084 * \param vindx
1085 * \return int
1086 */
1087int G_vector_set(vec_struct *A, int cells, int ldim, vtype vt, int vindx)
1088{
1089 if ((cells < 1) || (vt == RVEC && ldim < 1) ||
1090 (vt == CVEC && ldim < cells) || ldim < 0) {
1091 G_warning(_("Vector dimensions out of range"));
1092 return -1;
1093 }
1094
1095 if ((vt == RVEC && vindx >= A->cols) || (vt == CVEC && vindx >= A->rows)) {
1096 G_warning(_("Row/column out of range"));
1097 return -1;
1098 }
1099
1100 if (vt == RVEC) {
1101 A->rows = 1;
1102 A->cols = cells;
1103 A->ldim = ldim;
1104 A->type = ROWVEC_;
1105 }
1106 else {
1107 A->rows = cells;
1108 A->cols = 1;
1109 A->ldim = ldim;
1110 A->type = COLVEC_;
1111 }
1112
1113 if (vindx < 0)
1114 A->v_indx = 0;
1115 else
1116 A->v_indx = vindx;
1117
1118 A->vals = (double *)G_calloc(ldim * A->cols, sizeof(double));
1119 A->is_init = 1;
1120
1121 return 0;
1122}
1123
1124/*!
1125 * \fn double G_vector_norm_euclid (vec_struct *vc)
1126 *
1127 * \brief Calculates euclidean norm
1128 *
1129 * Calculates the euclidean norm of a row or column vector, using BLAS
1130 * routine dnrm2_().
1131 *
1132 * \param vc
1133 * \return double
1134 */
1136{
1137 int incr, Nval;
1138 double *startpt;
1139
1140 if (!vc->is_init)
1141 G_fatal_error(_("Matrix is not initialised"));
1142
1143 if (vc->type == ROWVEC_) {
1144 Nval = (int)vc->cols;
1145 incr = (int)vc->ldim;
1146 if (vc->v_indx < 0)
1147 startpt = vc->vals;
1148 else
1149 startpt = vc->vals + vc->v_indx;
1150 }
1151 else {
1152 Nval = (int)vc->rows;
1153 incr = 1;
1154 if (vc->v_indx < 0)
1155 startpt = vc->vals;
1156 else
1157 startpt = vc->vals + vc->v_indx * vc->ldim;
1158 }
1159
1160 /* Call the BLAS routine dnrm2_() */
1161 return cblas_dnrm2(Nval, startpt, incr);
1162}
1163
1164/*!
1165 * \fn double G_vector_norm_maxval (vec_struct *vc, int vflag)
1166 *
1167 * \brief Calculates maximum value
1168 *
1169 * Calculates the maximum value of a row or column vector.
1170 * The vflag setting defines which value to be calculated:
1171 * vflag:
1172 * 1 Indicates maximum value<br>
1173 * -1 Indicates minimum value<br>
1174 * 0 Indicates absolute value [???]
1175 *
1176 * \param vc
1177 * \param vflag
1178 * \return double
1179 */
1181{
1182 double xval, *startpt, *curpt;
1183 double cellval;
1184 int ncells, incr;
1185
1186 if (!vc->is_init)
1187 G_fatal_error(_("Matrix is not initialised"));
1188
1189 if (vc->type == ROWVEC_) {
1190 ncells = (int)vc->cols;
1191 incr = (int)vc->ldim;
1192 if (vc->v_indx < 0)
1193 startpt = vc->vals;
1194 else
1195 startpt = vc->vals + vc->v_indx;
1196 }
1197 else {
1198 ncells = (int)vc->rows;
1199 incr = 1;
1200 if (vc->v_indx < 0)
1201 startpt = vc->vals;
1202 else
1203 startpt = vc->vals + vc->v_indx * vc->ldim;
1204 }
1205
1206 xval = *startpt;
1207 curpt = startpt;
1208
1209 while (ncells > 0) {
1210 if (curpt != startpt) {
1211 switch (vflag) {
1212
1213 case MAX_POS: {
1214 if (*curpt > xval)
1215 xval = *curpt;
1216 break;
1217 }
1218
1219 case MAX_NEG: {
1220 if (*curpt < xval)
1221 xval = *curpt;
1222 break;
1223 }
1224
1225 case MAX_ABS: {
1226 cellval = (double)(*curpt);
1227 if (hypot(cellval, cellval) > (double)xval)
1228 xval = *curpt;
1229 }
1230 } /* switch */
1231 } /* if(curpt != startpt) */
1232
1233 curpt += incr;
1234 ncells--;
1235 }
1236
1237 return (double)xval;
1238}
1239
1240/*!
1241 * \fn double G_vector_norm1 (vec_struct *vc)
1242 *
1243 * \brief Calculates the 1-norm of a vector
1244 *
1245 * Calculates the 1-norm of a vector
1246 *
1247 * \param vc
1248 * \return double
1249 */
1251{
1252 double result = 0.0;
1253 int idx;
1254 int i;
1255
1256 if (!vc->is_init) {
1257 G_warning(_("Matrix is not initialised"));
1258 return NAN;
1259 }
1260
1261 idx = (vc->v_indx > 0) ? vc->v_indx : 0;
1262
1263 if (vc->type == ROWVEC_) {
1264 for (i = 0; i < vc->cols; i++)
1265 result += fabs(G_matrix_get_element(vc, idx, i));
1266 }
1267 else {
1268 for (i = 0; i < vc->rows; i++)
1269 result += fabs(G_matrix_get_element(vc, i, idx));
1270 }
1271
1272 return result;
1273}
1274
1275/*!
1276 * \fn vec_struct *G_vector_product (vec_struct *v1, vec_struct *v2, vec_struct
1277 * *out)
1278 *
1279 * \brief Calculates the vector product
1280 *
1281 * Calculates the vector product of two vectors
1282 *
1283 * \param v1
1284 * \param v2
1285 * \param out Output vector
1286 * \return vec_struct
1287 */
1289{
1290 int idx1, idx2, idx0;
1291 int i;
1292
1293 if (!out->is_init) {
1294 G_warning(_("Output vector is uninitialized"));
1295 return NULL;
1296 }
1297
1298 if (v1->type != v2->type) {
1299 G_warning(_("Vectors are not of the same type"));
1300 return NULL;
1301 }
1302
1303 if (v1->type != out->type) {
1304 G_warning(_("Output vector is not the same type as others"));
1305 return NULL;
1306 }
1307
1308 if (v1->type == MATRIX_) {
1309 G_warning(_("Matrices not allowed"));
1310 return NULL;
1311 }
1312
1313 if ((v1->type == ROWVEC_ && v1->cols != v2->cols) ||
1314 (v1->type == COLVEC_ && v1->rows != v2->rows)) {
1315 G_warning(_("Vectors have differing dimensions"));
1316 return NULL;
1317 }
1318
1319 if ((v1->type == ROWVEC_ && v1->cols != out->cols) ||
1320 (v1->type == COLVEC_ && v1->rows != out->rows)) {
1321 G_warning(_("Output vector has incorrect dimension"));
1322 return NULL;
1323 }
1324
1325 idx1 = (v1->v_indx > 0) ? v1->v_indx : 0;
1326 idx2 = (v2->v_indx > 0) ? v2->v_indx : 0;
1327 idx0 = (out->v_indx > 0) ? out->v_indx : 0;
1328
1329 if (v1->type == ROWVEC_) {
1330 for (i = 0; i < v1->cols; i++)
1332 G_matrix_get_element(v1, idx1, i) *
1333 G_matrix_get_element(v2, idx2, i));
1334 }
1335 else {
1336 for (i = 0; i < v1->rows; i++)
1338 G_matrix_get_element(v1, i, idx1) *
1339 G_matrix_get_element(v2, i, idx2));
1340 }
1341
1342 return out;
1343}
1344
1345/*!
1346 * \fn vec_struct *G_vector_copy (const vec_struct *vc1, int comp_flag)
1347 *
1348 * \brief Returns a vector copied from <b>vc1</b>. Underlying structure
1349 * is preserved unless DO_COMPACT flag.
1350 *
1351 * \param vc1
1352 * \param comp_flag
1353 * \return vec_struct
1354 */
1356{
1358 int incr1, incr2;
1359 double *startpt1, *startpt2, *curpt1, *curpt2;
1360 int cnt;
1361
1362 if (!vc1->is_init) {
1363 G_warning(_("Vector structure is not initialised"));
1364 return NULL;
1365 }
1366
1367 tmp_arry = (vec_struct *)G_malloc(sizeof(vec_struct));
1368
1369 if (comp_flag == DO_COMPACT) {
1370 if (vc1->type == ROWVEC_) {
1371 tmp_arry->rows = 1;
1372 tmp_arry->cols = vc1->cols;
1373 tmp_arry->ldim = 1;
1374 tmp_arry->type = ROWVEC_;
1375 tmp_arry->v_indx = 0;
1376 }
1377 else if (vc1->type == COLVEC_) {
1378 tmp_arry->rows = vc1->rows;
1379 tmp_arry->cols = 1;
1380 tmp_arry->ldim = vc1->ldim;
1381 tmp_arry->type = COLVEC_;
1382 tmp_arry->v_indx = 0;
1383 }
1384 else {
1385 G_warning("Type is not vector.");
1386 return NULL;
1387 }
1388 }
1389 else if (comp_flag == NO_COMPACT) {
1390 tmp_arry->v_indx = vc1->v_indx;
1391 tmp_arry->rows = vc1->rows;
1392 tmp_arry->cols = vc1->cols;
1393 tmp_arry->ldim = vc1->ldim;
1394 tmp_arry->type = vc1->type;
1395 }
1396 else {
1397 G_warning("Copy method must be specified: [DO,NO]_COMPACT.\n");
1398 return NULL;
1399 }
1400
1401 tmp_arry->vals =
1402 (double *)G_calloc(tmp_arry->ldim * tmp_arry->cols, sizeof(double));
1403 if (comp_flag == DO_COMPACT) {
1404 if (tmp_arry->type == ROWVEC_) {
1405 startpt1 = tmp_arry->vals;
1406 startpt2 = vc1->vals + vc1->v_indx;
1407 curpt1 = startpt1;
1408 curpt2 = startpt2;
1409 incr1 = 1;
1410 incr2 = vc1->ldim;
1411 cnt = vc1->cols;
1412 }
1413 else if (tmp_arry->type == COLVEC_) {
1414 startpt1 = tmp_arry->vals;
1415 startpt2 = vc1->vals + vc1->v_indx * vc1->ldim;
1416 curpt1 = startpt1;
1417 curpt2 = startpt2;
1418 incr1 = 1;
1419 incr2 = 1;
1420 cnt = vc1->rows;
1421 }
1422 else {
1423 G_warning("Structure type is not vector.");
1424 return NULL;
1425 }
1426 }
1427 else if (comp_flag == NO_COMPACT) {
1428 startpt1 = tmp_arry->vals;
1429 startpt2 = vc1->vals;
1430 curpt1 = startpt1;
1431 curpt2 = startpt2;
1432 incr1 = 1;
1433 incr2 = 1;
1434 cnt = vc1->ldim * vc1->cols;
1435 }
1436 else {
1437 G_warning("Copy method must be specified: [DO,NO]_COMPACT.\n");
1438 return NULL;
1439 }
1440
1441 while (cnt > 0) {
1442 memcpy(curpt1, curpt2, sizeof(double));
1443 curpt1 += incr1;
1444 curpt2 += incr2;
1445 cnt--;
1446 }
1447
1448 tmp_arry->is_init = 1;
1449
1450 return tmp_arry;
1451}
1452
1453/*!
1454 * \fn int G_matrix_read (FILE *fp, mat_struct *out)
1455 *
1456 * \brief Read a matrix from a file stream
1457 *
1458 * Populates matrix structure <b>out</b> with matrix read from file
1459 * stream <b>fp</b>. Matrix <b>out</b> is automatically initialized.
1460 * Returns -1 on error and 0 on success.
1461 *
1462 * \param fp
1463 * \param out
1464 * \return int
1465 */
1467{
1468 char buff[100];
1469 int rows, cols;
1470 int i, j, row;
1471 double val;
1472
1473 /* skip comments */
1474 for (;;) {
1475 if (!G_getl(buff, sizeof(buff), fp))
1476 return -1;
1477 if (buff[0] != '#')
1478 break;
1479 }
1480
1481 if (sscanf(buff, "Matrix: %d by %d", &rows, &cols) != 2) {
1482 G_warning(_("Input format error"));
1483 return -1;
1484 }
1485
1486 G_matrix_set(out, rows, cols, rows);
1487
1488 for (i = 0; i < rows; i++) {
1489 if (fscanf(fp, "row%d:", &row) != 1 || row != i) {
1490 G_warning(_("Input format error"));
1491 return -1;
1492 }
1493 for (j = 0; j < cols; j++) {
1494 if (fscanf(fp, "%lf:", &val) != 1) {
1495 G_warning(_("Input format error"));
1496 return -1;
1497 }
1498
1499 G_matrix_set_element(out, i, j, val);
1500 }
1501 }
1502
1503 return 0;
1504}
1505
1506/*!
1507 * \fn mat_struct *G_matrix_resize(mat_struct *in, int rows, int cols)
1508 *
1509 * \brief Resizes a matrix
1510 *
1511 * Resizes a matrix
1512 *
1513 * \param in
1514 * \param rows
1515 * \param cols
1516 * \return mat_struct
1517 */
1518mat_struct *G_matrix_resize(mat_struct *in, int rows, int cols)
1519{
1521
1522 matrix = G_matrix_init(rows, cols, rows);
1523 int i, j, p /*, index = 0 */;
1524
1525 for (i = 0; i < rows; i++)
1526 for (j = 0; j < cols; j++)
1528 /* matrix->vals[index++] = in->vals[i + j * cols]; */
1529
1530 int old_size = in->rows * in->cols;
1531 int new_size = rows * cols;
1532
1533 if (new_size > old_size)
1534 for (p = old_size; p < new_size; p++)
1535 G_matrix_set_element(matrix, i, j, 0.0);
1536
1537 return (matrix);
1538}
1539
1540/*!
1541 * \fn int G_matrix_stdin(mat_struct *out)
1542 *
1543 * \brief Read a matrix from standard input
1544 *
1545 * Populates matrix <b>out</b> with matrix read from stdin. Matrix
1546 * <b>out</b> is automatically initialized. Returns -1 on failure or 0
1547 * on success.
1548 *
1549 * \param out
1550 * \return int
1551 */
1553{
1554 return G_matrix_read(stdin, out);
1555}
1556
1557/*!
1558 * \fn int G_matrix_eigen_sort (vec_struct *d, mat_struct *m)
1559 *
1560 * \brief Sort eigenvectors according to eigenvalues
1561 *
1562 * Sort eigenvectors according to eigenvalues. Returns 0.
1563 *
1564 * \param d
1565 * \param m
1566 * \return int
1567 */
1569{
1570 mat_struct tmp;
1571 int i, j;
1572 int idx;
1573
1574 G_matrix_set(&tmp, m->rows + 1, m->cols, m->ldim + 1);
1575
1576 idx = (d->v_indx > 0) ? d->v_indx : 0;
1577
1578 /* concatenate (vertically) m and d into tmp */
1579 for (i = 0; i < m->cols; i++) {
1580 for (j = 0; j < m->rows; j++)
1581 G_matrix_set_element(&tmp, j + 1, i, G_matrix_get_element(m, j, i));
1582 if (d->type == ROWVEC_)
1583 G_matrix_set_element(&tmp, 0, i, G_matrix_get_element(d, idx, i));
1584 else
1585 G_matrix_set_element(&tmp, 0, i, G_matrix_get_element(d, i, idx));
1586 }
1587
1588 /* sort the combined matrix */
1589 qsort(tmp.vals, tmp.cols, tmp.ldim * sizeof(double), egcmp);
1590
1591 /* split tmp into m and d */
1592 for (i = 0; i < m->cols; i++) {
1593 for (j = 0; j < m->rows; j++)
1594 G_matrix_set_element(m, j, i, G_matrix_get_element(&tmp, j + 1, i));
1595 if (d->type == ROWVEC_)
1596 G_matrix_set_element(d, idx, i, G_matrix_get_element(&tmp, 0, i));
1597 else
1598 G_matrix_set_element(d, i, idx, G_matrix_get_element(&tmp, 0, i));
1599 }
1600
1601 G_free(tmp.vals);
1602
1603 return 0;
1604}
1605
1606static int egcmp(const void *pa, const void *pb)
1607{
1608 double a = *(double *const)pa;
1609 double b = *(double *const)pb;
1610
1611 if (a > b)
1612 return 1;
1613 if (a < b)
1614 return -1;
1615
1616 return 0;
1617}
1618
1619#endif // HAVE_LIBLAPACK HAVE_LIBBLAS
1620
#define NULL
Definition ccmath.h:32
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:147
#define G_calloc(m, n)
Definition defs/gis.h:140
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
#define G_malloc(n)
Definition defs/gis.h:139
void G_message(const char *,...) __attribute__((format(printf
int G_getl(char *, int, FILE *)
Gets a line of text from a file.
Definition getl.c:33
size_t G_strlcpy(char *, const char *, size_t)
Safe string copy function.
Definition strlcpy.c:52
#define _(str)
Definition glocale.h:10
vec_struct * G_matvect_get_column(mat_struct *mt, int col)
Retrieve a column of the matrix to a vector structure.
Definition la.c:745
mat_struct * G_matrix_copy(const mat_struct *A)
Copy a matrix.
Definition la.c:149
vec_struct * G_vector_sub(vec_struct *v1, vec_struct *v2, vec_struct *out)
Subtract two vectors.
Definition la.c:1013
double G_vector_norm_maxval(vec_struct *vc, int vflag)
Calculates maximum value.
Definition la.c:1180
mat_struct * G__matrix_add(mat_struct *mt1, mat_struct *mt2, const double c1, const double c2)
Definition la.c:278
vec_struct * G_vector_product(vec_struct *v1, vec_struct *v2, vec_struct *out)
Calculates the vector product.
Definition la.c:1288
mat_struct * G_matrix_subtract(mat_struct *mt1, mat_struct *mt2)
Subtract two matrices.
Definition la.c:198
int G_matvect_retrieve_matrix(vec_struct *vc)
Revert a vector to matrix.
Definition la.c:870
double G_vector_norm_euclid(vec_struct *vc)
Calculates euclidean norm.
Definition la.c:1135
vec_struct * G_vector_init(int cells, int ldim, vtype vt)
Initialize a vector structure.
Definition la.c:947
mat_struct * G_matrix_inverse(mat_struct *mt)
Returns the matrix inverse.
Definition la.c:584
double G_matrix_get_element(mat_struct *mt, int rowval, int colval)
Retrieve value of the (i,j)th element.
Definition la.c:724
mat_struct * G_matrix_scale(mat_struct *mt1, const double c)
Scale a matrix by a scalar value.
Definition la.c:258
int G_matrix_stdin(mat_struct *out)
Read a matrix from standard input.
Definition la.c:1552
mat_struct * G_matrix_resize(mat_struct *in, int rows, int cols)
Resizes a matrix.
Definition la.c:1518
void G_matrix_print(mat_struct *mt)
Print out a matrix.
Definition la.c:655
mat_struct * G_matrix_scalar_mul(double scalar, mat_struct *matrix, mat_struct *out)
Calculates the scalar-matrix multiplication.
Definition la.c:216
vec_struct * G_matvect_product(mat_struct *A, vec_struct *b, vec_struct *out)
Calculates the matrix-vector product.
Definition la.c:894
mat_struct * G_matrix_add(mat_struct *mt1, mat_struct *mt2)
Adds two matrices.
Definition la.c:181
int G_matvect_extract_vector(mat_struct *mt, vtype vt, int indx)
Convert matrix to vector.
Definition la.c:825
int G_matrix_LU_solve(const mat_struct *mt1, mat_struct **xmat0, const mat_struct *bmat, mat_type mtype)
Solve a general system A.X = B.
Definition la.c:464
mat_struct * G_matrix_init(int rows, int cols, int ldim)
Initialize a matrix structure.
Definition la.c:66
int suppress_empty_translation_unit_compiler_warning
Definition la.c:1621
double G_vector_norm1(vec_struct *vc)
Calculates the 1-norm of a vector.
Definition la.c:1250
int G_matrix_read(FILE *fp, mat_struct *out)
Read a matrix from a file stream.
Definition la.c:1466
vec_struct * G_matvect_get_row(mat_struct *mt, int row)
Retrieve a row of the matrix to a vector structure.
Definition la.c:784
int G_matrix_eigen_sort(vec_struct *d, mat_struct *m)
Sort eigenvectors according to eigenvalues.
Definition la.c:1568
vec_struct * G_vector_copy(const vec_struct *vc1, int comp_flag)
Returns a vector copied from vc1. Underlying structure is preserved unless DO_COMPACT flag.
Definition la.c:1355
void G_vector_free(vec_struct *v)
Free an allocated vector structure.
Definition la.c:991
void G_matrix_free(mat_struct *mt)
Free up allocated matrix.
Definition la.c:637
mat_struct * G_matrix_product(mat_struct *mt1, mat_struct *mt2)
Returns product of two matrices.
Definition la.c:350
int G_vector_set(vec_struct *A, int cells, int ldim, vtype vt, int vindx)
Definition la.c:1087
mat_struct * G_matrix_transpose(mat_struct *mt)
Transpose a matrix.
Definition la.c:398
int G_matrix_set_element(mat_struct *mt, int rowval, int colval, double val)
Definition la.c:693
int G_matrix_set(mat_struct *A, int rows, int cols, int ldim)
Set parameters for an initialized matrix.
Definition la.c:120
int G_matrix_zero(mat_struct *A)
Clears (or resets) the matrix values to 0.
Definition la.c:96
Wrapper headers for BLAS/LAPACK.
#define DO_COMPACT
Definition la.h:35
vtype
Definition la.h:44
@ CVEC
Definition la.h:44
@ RVEC
Definition la.h:44
#define MAX_NEG
Definition la.h:32
#define MAX_ABS
Definition la.h:33
mat_type
Definition la.h:42
@ NONSYM
Definition la.h:42
#define NO_COMPACT
Definition la.h:36
#define MAX_POS
Definition la.h:31
@ COLVEC_
Definition la.h:43
@ MATRIX_
Definition la.h:43
@ ROWVEC_
Definition la.h:43
double b
Definition r_raster.c:39
Definition la.h:53
int v_indx
Definition la.h:56
mat_spec type
Definition la.h:55
int rows
Definition la.h:59
int is_init
Definition la.h:63
int ldim
Definition la.h:60
double * vals
Definition la.h:62
int cols
Definition la.h:59