GRASS Programmer's Manual  6.5.svn(2012)-r51648
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
solvers_classic_iter.c
Go to the documentation of this file.
00001 
00002 /*****************************************************************************
00003 *
00004 * MODULE:       Grass PDE Numerical Library
00005 * AUTHOR(S):    Soeren Gebbert, Berlin (GER) Dec 2006
00006 *               soerengebbert <at> gmx <dot> de
00007 *               
00008 * PURPOSE:      linear equation system solvers
00009 *               part of the gpde library
00010 *               
00011 * COPYRIGHT:    (C) 2007 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 <math.h>
00020 #include <unistd.h>
00021 #include <stdio.h>
00022 #include <string.h>
00023 #include <grass/gis.h>
00024 #include <grass/glocale.h>
00025 #include <grass/gmath.h>
00026 
00027 
00048 int G_math_solver_sparse_jacobi(G_math_spvector ** Asp, double *x, double *b,
00049                                 int rows, int maxit, double sor, double error)
00050 {
00051     int i, j, k, center, finished = 0;
00052 
00053     double *Enew;
00054 
00055     double E, err = 0;
00056 
00057     Enew = G_alloc_vector(rows);
00058 
00059     for (k = 0; k < maxit; k++) {
00060         err = 0;
00061         {
00062             if (k == 0) {
00063                 for (j = 0; j < rows; j++) {
00064                     Enew[j] = x[j];
00065                 }
00066             }
00067             for (i = 0; i < rows; i++) {
00068                 E = 0;
00069                 center = 0;
00070                 for (j = 0; j < Asp[i]->cols; j++) {
00071                     E += Asp[i]->values[j] * x[Asp[i]->index[j]];
00072                     if (Asp[i]->index[j] == i)
00073                         center = j;
00074                 }
00075                 Enew[i] = x[i] - sor * (E - b[i]) / Asp[i]->values[center];
00076             }
00077             for (j = 0; j < rows; j++) {
00078                 err += (x[j] - Enew[j]) * (x[j] - Enew[j]);
00079 
00080                 x[j] = Enew[j];
00081             }
00082         }
00083 
00084         G_message(_("sparse Jacobi -- iteration %5i error %g\n"), k, err);
00085 
00086         if (err < error) {
00087             finished = 1;
00088             break;
00089         }
00090     }
00091 
00092     G_free(Enew);
00093 
00094     return finished;
00095 }
00096 
00097 
00118 int G_math_solver_sparse_gs(G_math_spvector ** Asp, double *x, double *b,
00119                             int rows, int maxit, double sor, double error)
00120 {
00121     int i, j, k, finished = 0;
00122 
00123     double *Enew;
00124 
00125     double E, err = 0;
00126 
00127     int center;
00128 
00129     Enew = G_alloc_vector(rows);
00130 
00131     for (k = 0; k < maxit; k++) {
00132         err = 0;
00133         {
00134             if (k == 0) {
00135                 for (j = 0; j < rows; j++) {
00136                     Enew[j] = x[j];
00137                 }
00138             }
00139             for (i = 0; i < rows; i++) {
00140                 E = 0;
00141                 center = 0;
00142                 for (j = 0; j < Asp[i]->cols; j++) {
00143                     E += Asp[i]->values[j] * Enew[Asp[i]->index[j]];
00144                     if (Asp[i]->index[j] == i)
00145                         center = j;
00146                 }
00147                 Enew[i] = x[i] - sor * (E - b[i]) / Asp[i]->values[center];
00148             }
00149             for (j = 0; j < rows; j++) {
00150                 err += (x[j] - Enew[j]) * (x[j] - Enew[j]);
00151 
00152                 x[j] = Enew[j];
00153             }
00154         }
00155 
00156         G_message(_("sparse SOR -- iteration %5i error %g\n"), k, err);
00157 
00158         if (err < error) {
00159             finished = 1;
00160             break;
00161         }
00162     }
00163 
00164     G_free(Enew);
00165 
00166     return finished;
00167 }
00168 
00169 
00190 int G_math_solver_jacobi(double **A, double *x, double *b, int rows,
00191                          int maxit, double sor, double error)
00192 {
00193     int i, j, k;
00194 
00195     double *Enew;
00196 
00197     double E, err = 0;
00198 
00199     Enew = G_alloc_vector(rows);
00200 
00201     for (j = 0; j < rows; j++) {
00202         Enew[j] = x[j];
00203     }
00204 
00205     for (k = 0; k < maxit; k++) {
00206         for (i = 0; i < rows; i++) {
00207             E = 0;
00208             for (j = 0; j < rows; j++) {
00209                 E += A[i][j] * x[j];
00210             }
00211             Enew[i] = x[i] - sor * (E - b[i]) / A[i][i];
00212         }
00213         err = 0;
00214         for (j = 0; j < rows; j++) {
00215             err += (x[j] - Enew[j]) * (x[j] - Enew[j]);
00216             x[j] = Enew[j];
00217         }
00218         G_message(_("Jacobi -- iteration %5i error %g\n"), k, err);
00219         if (err < error)
00220             break;
00221     }
00222 
00223     return 1;
00224 }
00225 
00226 
00247 int G_math_solver_gs(double **A, double *x, double *b, int rows, int maxit,
00248                      double sor, double error)
00249 {
00250     int i, j, k;
00251 
00252     double *Enew;
00253 
00254     double E, err = 0;
00255 
00256     Enew = G_alloc_vector(rows);
00257 
00258     for (j = 0; j < rows; j++) {
00259         Enew[j] = x[j];
00260     }
00261 
00262     for (k = 0; k < maxit; k++) {
00263         for (i = 0; i < rows; i++) {
00264             E = 0;
00265             for (j = 0; j < rows; j++) {
00266                 E += A[i][j] * Enew[j];
00267             }
00268             Enew[i] = x[i] - sor * (E - b[i]) / A[i][i];
00269         }
00270         err = 0;
00271         for (j = 0; j < rows; j++) {
00272             err += (x[j] - Enew[j]) * (x[j] - Enew[j]);
00273             x[j] = Enew[j];
00274         }
00275         G_message(_("SOR -- iteration %5i error %g\n"), k, err);
00276         if (err < error)
00277             break;
00278     }
00279 
00280     return 1;
00281 }