00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "eg_dmatrix.h"
00021
00022
00023
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
00052 while (1)
00053 {
00054
00055 if (rank == col_sz || rank == row_sz)
00056 break;
00057
00058 pcol = rank;
00059 prow = rank;
00060 EGlpNumCopyAbs (pivot, rowval[row_ord[prow]][col_ord[pcol]]);
00061
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
00071
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
00092
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
00112
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
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
00145
00146 EGlpNumCopy (pivot, rowval[row_ord[rank]][col_ord[rank]]);
00147
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
00154 if (EGlpNumIsNeqZero (tmpval, zero_tol))
00155 {
00156
00157 EGlpNumDivTo (tmpval, pivot);
00158
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
00166 rank++;
00167 }
00168
00169 EGlpNumClearVar (tmpval);
00170 EGlpNumClearVar (pivot);
00171 *ext_rank = rank;
00172 *ext_status = status;
00173 return rval;
00174 }
00175
00176
00177