00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef LU_H
00027 #define LU_H
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 #include <cmath>
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 namespace SPUC
00081 {
00082
00083 template <class MaTRiX, class VecToRsubscript>
00084 int LU_factor( MaTRiX &A, VecToRsubscript &indx)
00085 {
00086 assert(A.lbound() == 1);
00087 assert(indx.lbound() == 1);
00088
00089 int M = A.dim1();
00090 int N = A.dim2();
00091
00092 if (M == 0 || N==0) return 0;
00093 if (indx.dim() != M)
00094 indx.newsize(M);
00095
00096 int i=0,j=0,k=0;
00097 int jp=0;
00098
00099 typename MaTRiX::element_type t;
00100
00101 int minMN = (M < N ? M : N) ;
00102
00103 for (j=1; j<= minMN; j++)
00104 {
00105
00106
00107
00108 jp = j;
00109 t = fabs(A(j,j));
00110 for (i=j+1; i<=M; i++)
00111 if ( fabs(A(i,j)) > t)
00112 {
00113 jp = i;
00114 t = fabs(A(i,j));
00115 }
00116
00117 indx(j) = jp;
00118
00119
00120
00121
00122 if ( A(jp,j) == 0 )
00123 return 1;
00124
00125
00126 if (jp != j)
00127 for (k=1; k<=N; k++)
00128 {
00129 t = A(j,k);
00130 A(j,k) = A(jp,k);
00131 A(jp,k) =t;
00132 }
00133
00134 if (j<M)
00135 {
00136
00137
00138
00139 typename MaTRiX::element_type recp = 1.0 / A(j,j);
00140
00141 for (k=j+1; k<=M; k++)
00142 A(k,j) *= recp;
00143 }
00144
00145
00146 if (j < minMN)
00147 {
00148
00149
00150
00151
00152
00153
00154 int ii,jj;
00155
00156 for (ii=j+1; ii<=M; ii++)
00157 for (jj=j+1; jj<=N; jj++)
00158 A(ii,jj) -= A(ii,j)*A(j,jj);
00159 }
00160 }
00161
00162 return 0;
00163 }
00164
00165
00166
00167
00168 template <class MaTRiX, class VecToR, class VecToRsubscripts>
00169 int LU_solve(const MaTRiX &A, const VecToRsubscripts &indx, VecToR &b)
00170 {
00171 assert(A.lbound() == 1);
00172 assert(indx.lbound() == 1);
00173 assert(b.lbound() == 1);
00174
00175 int i,ii=0,ip,j;
00176 int n = b.dim();
00177 typename MaTRiX::element_type sum = 0.0;
00178
00179 for (i=1;i<=n;i++)
00180 {
00181 ip=indx(i);
00182 sum=b(ip);
00183 b(ip)=b(i);
00184 if (ii)
00185 for (j=ii;j<=i-1;j++)
00186 sum -= A(i,j)*b(j);
00187 else if (sum) ii=i;
00188 b(i)=sum;
00189 }
00190 for (i=n;i>=1;i--)
00191 {
00192 sum=b(i);
00193 for (j=i+1;j<=n;j++)
00194 sum -= A(i,j)*b(j);
00195 b(i)=sum/A(i,i);
00196 }
00197
00198 return 0;
00199 }
00200
00201 }
00202
00203 #endif
00204