eg_dmatrix.c

Go to the documentation of this file.
00001 /* EGlib "Efficient General Library" provides some basic structures and
00002  * algorithms commons in many optimization algorithms.
00003  *
00004  * Copyright (C) 2005 Daniel Espinoza and Marcos Goycoolea.
00005  * 
00006  * This library is free software; you can redistribute it and/or modify it
00007  * under the terms of the GNU Lesser General Public License as published by the
00008  * Free Software Foundation; either version 2.1 of the License, or (at your
00009  * option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful, but 
00012  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
00013  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
00014  * License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this library; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
00019  * */
00020 #include "eg_dmatrix.h"
00021 /** @file
00022  * @ingroup EGdMatrix */
00023 /** @addtogroup EGdMatrix */
00024 /** @{ */
00025 /* ========================================================================= */
00026 int EGdMatrixGaussianElimination (EGdMatrix_t * const dmatrix,
00027                                   const unsigned do_col_perm,
00028                                   const unsigned do_row_perm,
00029                                   unsigned *const ext_rank,
00030                                   EGlpNum_t zero_tol,
00031                                   int *const ext_status)
00032 {
00033   const size_t col_sz = dmatrix->col_sz;
00034   const size_t row_sz = dmatrix->row_sz;
00035   int *const col_ord = dmatrix->col_ord;
00036   int *const row_ord = dmatrix->row_ord;
00037   EGlpNum_t **const rowval = dmatrix->matrow;
00038   EGlpNum_t pivot,
00039     tmpval;
00040   int rval = 0,
00041     tmpint = 0,
00042     tmpint2 = 0;
00043   int status = EG_ALGSTAT_SUCCESS;
00044   size_t rank = 0;
00045   size_t prow,
00046     pcol;
00047   register unsigned i,
00048     j;
00049   EGlpNumInitVar (pivot);
00050   EGlpNumInitVar (tmpval);
00051   /* main loop */
00052   while (1)
00053   {
00054     /* test if we are done */
00055     if (rank == col_sz || rank == row_sz)
00056       break;
00057     /* choose wich pivot to do */
00058     pcol = rank;
00059     prow = rank;
00060     EGlpNumCopyAbs (pivot, rowval[row_ord[prow]][col_ord[pcol]]);
00061     /* in this case we are forced to choose as pivot element a_kk */
00062     if (!do_col_perm && !do_row_perm)
00063     {
00064       if (!EGlpNumIsNeqZero (pivot, zero_tol))
00065       {
00066         status = EG_ALGSTAT_NUMERROR;
00067         break;
00068       }
00069     }
00070     /* in this case we choose the best possible pivot value as the largest
00071      * entry in the remaining sub-matrix */
00072     else if (do_col_perm && do_row_perm)
00073     {
00074       for (i = rank; i < row_sz; i++)
00075         for (j = rank; j < col_sz; j++)
00076         {
00077           EGlpNumCopyAbs (tmpval, rowval[row_ord[i]][col_ord[j]]);
00078           if (EGlpNumIsLess (pivot, tmpval))
00079           {
00080             pcol = j;
00081             prow = i;
00082             EGlpNumCopy (pivot, tmpval);
00083           }
00084         }
00085       if (!EGlpNumIsNeqZero (pivot, zero_tol))
00086       {
00087         status = EG_ALGSTAT_PARTIAL;
00088         break;
00089       }
00090     }
00091     /* in this case we choose the best possible value as the largest entry in
00092      * the remaining row */
00093     else if (do_col_perm && !do_row_perm)
00094     {
00095       tmpint = row_ord[prow];
00096       for (j = rank; j < col_sz; j++)
00097       {
00098         EGlpNumCopyAbs (tmpval, rowval[tmpint][col_ord[j]]);
00099         if (EGlpNumIsLess (pivot, tmpval))
00100         {
00101           pcol = j;
00102           EGlpNumCopy (pivot, tmpval);
00103         }
00104       }
00105       if (!EGlpNumIsNeqZero (pivot, zero_tol))
00106       {
00107         status = EG_ALGSTAT_NUMERROR;
00108         break;
00109       }
00110     }
00111     /* in this case we choose the best possible value as the largest entry in
00112      * the remaining column */
00113     else
00114     {
00115       tmpint = col_ord[pcol];
00116       for (i = rank; i < row_sz; i++)
00117       {
00118         EGlpNumCopyAbs (tmpval, rowval[row_ord[i]][tmpint]);
00119         if (EGlpNumIsLess (pivot, tmpval))
00120         {
00121           prow = i;
00122           EGlpNumCopy (pivot, tmpval);
00123         }
00124       }
00125       if (!EGlpNumIsNeqZero (pivot, zero_tol))
00126       {
00127         status = EG_ALGSTAT_NUMERROR;
00128         break;
00129       }
00130     }
00131     /* exchange row/columns if neccesary */
00132     if (pcol != rank)
00133     {
00134       tmpint = col_ord[rank];
00135       col_ord[rank] = col_ord[pcol];
00136       col_ord[pcol] = tmpint;
00137     }
00138     if (prow != rank)
00139     {
00140       tmpint = row_ord[rank];
00141       row_ord[rank] = row_ord[prow];
00142       row_ord[prow] = tmpint;
00143     }
00144     /* now we are done choosing a non-zero pivot, and permutating columns 
00145      * and or rows */
00146     EGlpNumCopy (pivot, rowval[row_ord[rank]][col_ord[rank]]);
00147     /* now we do de pivot */
00148     tmpint = row_ord[rank];
00149     for (i = rank + 1; i < row_sz; i++)
00150     {
00151       tmpint2 = row_ord[i];
00152       EGlpNumCopy (tmpval, rowval[tmpint2][col_ord[rank]]);
00153       /* check wether we don't need to update this row */
00154       if (EGlpNumIsNeqZero (tmpval, zero_tol))
00155       {
00156         /* compute the row multiplier */
00157         EGlpNumDivTo (tmpval, pivot);
00158         /* set row_i = row_i - tmpval row_rank */
00159         EGlpNumCopy (rowval[tmpint2][col_ord[rank]], zeroLpNum);
00160         for (j = rank + 1; j < col_sz; j++)
00161           EGlpNumSubInnProdTo (rowval[tmpint2][col_ord[j]], tmpval,
00162                                rowval[tmpint][col_ord[j]]);
00163       }
00164     }
00165     /* increase the proven rank */
00166     rank++;
00167   }
00168   /* ending */
00169   EGlpNumClearVar (tmpval);
00170   EGlpNumClearVar (pivot);
00171   *ext_rank = rank;
00172   *ext_status = status;
00173   return rval;
00174 }
00175 
00176 /* ========================================================================= */
00177 /** @} */

Generated on Mon Jan 30 08:48:52 2006 for EGlib by  doxygen 1.4.5