00001 #include "GLU_Composition.h"
00002 #include "GMatrix_Util.h"
00003
00004 #include <cmath>
00005
00006 using namespace GMathLib;
00007 using namespace GMathLib::GMatrix_Util;
00008
00009 GLU_Composition::GLU_Composition()
00010 : GObject(), combined_flag(GLU_Composition::LU_NOT_COMBINED), p_L(0), p_U(0), p_LU(0), p_P(0)
00011 {
00012 Class_Name("GLU_Composition");
00013 }
00014
00015 GLU_Composition::~GLU_Composition()
00016 {
00017
00018 delete_mx_object();
00019 }
00020
00021 void GLU_Composition::delete_mx_object()
00022 {
00023 if(combined_flag == GLU_Composition::LU_NOT_COMBINED){
00024 if(p_L != 0) delete p_L;
00025 if(p_U != 0) delete p_U;
00026 }else if(combined_flag == GLU_Composition::LU_COMBINED){
00027 if(p_LU != 0) delete p_LU;
00028 }
00029
00030 if(p_P != 0){
00031 delete p_P;
00032 }
00033 }
00034
00035 bool GLU_Composition::LU_Composition(GMatrix& A_mx, int lu_combined_flag)
00036 {
00037
00038
00039 int n = A_mx.Row();
00040 if( n != A_mx.Column() ){
00041 const std::string context = "A given matrix is not a square matrix.";
00042 IO::GError_Output::Puts(Class_Name() + "::LU_Composition", context);
00043
00044 return false;
00045 }
00046
00047
00048
00049 delete_mx_object();
00050
00051 combined_flag = lu_combined_flag;
00052
00053
00054
00055 if(combined_flag == GLU_Composition::LU_NOT_COMBINED){
00056 p_L = new GMatrix(n, n);
00057 p_U = new GMatrix(n, n);
00058
00059 GMatrix_Util::Identity_Matrix(*p_L);
00060 p_U->Fill(0.0);
00061
00062 }else if(combined_flag == GLU_Composition::LU_COMBINED){
00063 p_LU = new GMatrix(n, n);
00064 }
00065
00066 p_P = new GMatrix(n, n);
00067 p_P->Fill(0.0);
00068
00069
00070 GMatrix A_lu(n, n);
00071 GVector pvot_vec(n);
00072 A_lu.Copy(A_mx);
00073
00074 if(! lu_composition(A_lu, pvot_vec)){
00075 const std::string context = "LU composition has failed.";
00076 IO::GError_Output::Puts(Class_Name() + "::LU_Composition", context);
00077 return false;
00078 }
00079
00080
00081
00082 if(combined_flag == GLU_Composition::LU_NOT_COMBINED){
00083 for(int i=0; i < n; i++){
00084 for(int j=0; j < i; j++){
00085 p_L->Set(i, j, A_lu.Get(i,j));
00086 }
00087 }
00088
00089 for(int i=0; i < n; i++){
00090 for(int j=i; j < n; j++){
00091 p_U->Set(i, j, A_lu.Get(i, j));
00092 }
00093 }
00094
00095 }else if(combined_flag == GLU_Composition::LU_COMBINED){
00096 p_LU->Copy(A_lu);
00097 }
00098
00099
00100
00101 for(int i=0; i < n; i++){
00102 p_P->Set(i, pvot_vec.Get(i), 1.0);
00103 }
00104
00105
00106 return true;
00107 }
00108
00109
00110
00111
00112
00113
00114 bool GLU_Composition::lu_composition(GMatrix& A, GVector& pv){
00115 int N = A.Row();
00116 double aamax;
00117 double TINY = 1.0e-20;
00118
00119
00120 GVector sc_v(N);
00121
00122
00123 for(int i=0; i < N; i++){
00124 pv(i) = i;
00125 aamax = 0.0;
00126
00127 for(int j=0; j < N; j++){
00128 if(std::fabs(A(i, j)) > aamax){
00129 aamax = std::fabs(A(i, j));
00130 }
00131
00132 if( aamax == 0.0 ){
00133 const std::string context = "A given matrix is singular matrix.";
00134 IO::GError_Output::Puts(Class_Name() + "::lu_composition", context);
00135 return false;
00136 }
00137
00138
00139 sc_v(i) = 1.0 / aamax;
00140 }
00141 }
00142
00143
00144 double sum;
00145 double dum;
00146 int imax=0;
00147
00148 for(int j=0; j < N; j++){
00149
00150
00151 for(int i=0; i <= j-1; i++){
00152 sum = A(i, j);
00153 for(int k=0; k <= i-1; k++){
00154 sum += - A(i, k) * A(k, j);
00155 }
00156 A(i, j) = sum;
00157 }
00158
00159
00160 aamax = 0.0;
00161
00162
00163 for(int i=j; i < N; i++){
00164
00165 sum = A(i, j);
00166 for(int k=0; k <= j-1; k++){
00167 sum += - A(i, k) * A(k, j);
00168 }
00169 A(i, j) = sum;
00170
00171
00172 dum = sc_v(i) * std::fabs(sum);
00173 if( dum >= aamax ){
00174 imax = i;
00175 aamax = dum;
00176 }
00177 }
00178
00179
00180 if( j != imax ){
00181 for(int k=0; k < N; k++){
00182 dum = A(imax, k);
00183 A(imax, k) = A(j, k);
00184 A(j, k) = dum;
00185 }
00186
00187
00188 sc_v(imax) = sc_v(j);
00189
00190
00191 dum = pv(imax);
00192 pv(imax) = pv(j);
00193 pv(j) = dum;
00194 }
00195
00196
00197
00198 if( A(j, j) == 0.0 )
00199 A(j, j) = TINY;
00200
00201
00202 if( j != N-1){
00203 dum = 1.0 / A(j, j);
00204 for(int i=j+1; i < N; i++){
00205 A(i, j) = A(i, j) * dum;
00206 }
00207 }
00208 }
00209
00210 return true;
00211 }