GRASS Programmer's Manual  6.5.svn(2012)-r51648
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
sparse_matrix.c
Go to the documentation of this file.
00001 
00002 /*****************************************************************************
00003  *
00004  * MODULE:       Grass Gmath Library
00005  * AUTHOR(S):    Soeren Gebbert, Berlin (GER) Dec 2006
00006  *              soerengebbert <at> gmx <dot> de
00007  *               
00008  * PURPOSE:      functions to manage linear equation systems
00009  *              part of the gmath library
00010  *               
00011  * COPYRIGHT:    (C) 2000 by the GRASS Development Team
00012  *
00013  *               This program is free software under the GNU General Public
00014  *               License (>=v2). Read the file COPYING that comes with GRASS
00015  *               for details.
00016  *
00017  *****************************************************************************/
00018 
00019 #include <stdlib.h>
00020 #include <math.h>
00021 #include <grass/gmath.h>
00022 #include <grass/gis.h>
00023 
00035 int G_math_add_spvector(G_math_spvector ** Asp, G_math_spvector * spvector,
00036                         int row)
00037 {
00038     if (Asp != NULL) {
00039         G_debug(5,
00040                 "Add sparse vector %p to the sparse linear equation system at row %i\n",
00041                 spvector, row);
00042         Asp[row] = spvector;
00043     }
00044     else {
00045         return -1;
00046     }
00047 
00048     return 1;
00049 }
00050 
00058 G_math_spvector **G_math_alloc_spmatrix(int rows)
00059 {
00060     G_math_spvector **spmatrix;
00061 
00062     G_debug(4, "Allocate memory for a sparse matrix with %i rows\n", rows);
00063 
00064     spmatrix = (G_math_spvector **) G_calloc(rows, sizeof(G_math_spvector *));
00065 
00066     return spmatrix;
00067 }
00068 
00076 G_math_spvector *G_math_alloc_spvector(int cols)
00077 {
00078     G_math_spvector *spvector;
00079 
00080     G_debug(4, "Allocate memory for a sparse vector with %i cols\n", cols);
00081 
00082     spvector = (G_math_spvector *) G_calloc(1, sizeof(G_math_spvector));
00083 
00084     spvector->cols = cols;
00085     spvector->index = (unsigned int *)G_calloc(cols, sizeof(unsigned int));
00086     spvector->values = (double *)G_calloc(cols, sizeof(double));
00087 
00088     return spvector;
00089 }
00090 
00098 void G_math_free_spvector(G_math_spvector * spvector)
00099 {
00100     if (spvector) {
00101         if (spvector->values)
00102             G_free(spvector->values);
00103         if (spvector->index)
00104             G_free(spvector->index);
00105         G_free(spvector);
00106 
00107         spvector = NULL;
00108     }
00109 
00110     return;
00111 }
00112 
00121 void G_math_free_spmatrix(G_math_spvector ** spmatrix, int rows)
00122 {
00123     int i;
00124 
00125     if (spmatrix) {
00126         for (i = 0; i < rows; i++)
00127             G_math_free_spvector(spmatrix[i]);
00128 
00129         G_free(spmatrix);
00130         spmatrix = NULL;
00131     }
00132 
00133     return;
00134 }
00135 
00146 void G_math_print_spmatrix(G_math_spvector ** Asp, int rows)
00147 {
00148     int i, j, k, out;
00149 
00150     for (i = 0; i < rows; i++) {
00151         for (j = 0; j < rows; j++) {
00152             out = 0;
00153             for (k = 0; k < Asp[i]->cols; k++) {
00154                 if (Asp[i]->index[k] == j) {
00155                     fprintf(stdout, "%4.5f ", Asp[i]->values[k]);
00156                     out = 1;
00157                 }
00158             }
00159             if (!out)
00160                 fprintf(stdout, "%4.5f ", 0.0);
00161         }
00162         fprintf(stdout, "\n");
00163     }
00164 
00165     return;
00166 }
00167 
00168 
00179 double **G_math_Asp_to_A(G_math_spvector ** Asp, int rows)
00180 {
00181     int i, j;
00182 
00183     double **A = NULL;
00184 
00185     A = G_alloc_matrix(rows, rows);
00186 
00187 #pragma omp parallel for schedule (static) private(i, j)
00188     for (i = 0; i < rows; i++) {
00189         for (j = 0; j < Asp[i]->cols; j++) {
00190             A[i][Asp[i]->index[j]] = Asp[i]->values[j];
00191         }
00192     }
00193     return A;
00194 }
00195 
00207 G_math_spvector **G_math_A_to_Asp(double **A, int rows, double epsilon)
00208 {
00209     int i, j;
00210 
00211     int nonull, count = 0;
00212 
00213     G_math_spvector **Asp = NULL;
00214 
00215     Asp = G_math_alloc_spmatrix(rows);
00216 
00217 #pragma omp parallel for schedule (static) private(i, j, nonull, count)
00218     for (i = 0; i < rows; i++) {
00219         nonull = 0;
00220         /*Count the number of non zero entries */
00221         for (j = 0; j < rows; j++) {
00222             if (A[i][j] > epsilon)
00223                 nonull++;
00224         }
00225         /*Allocate the sparse vector and insert values */
00226         G_math_spvector *v = G_math_alloc_spvector(nonull);
00227 
00228         count = 0;
00229         for (j = 0; j < rows; j++) {
00230             if (A[i][j] > epsilon) {
00231                 v->index[count] = j;
00232                 v->values[count] = A[i][j];
00233                 count++;
00234             }
00235         }
00236         /*Add vector to sparse matrix */
00237         G_math_add_spvector(Asp, v, i);
00238     }
00239     return Asp;
00240 }