Allink
v0.1
|
00001 #include "../include/Matematica.h" 00002 #include <iostream> 00003 #include <fstream> 00004 void Matrice::Shout(const char * s, ...){ 00005 #ifdef MAT_DEBUG 00006 va_list args; 00007 va_start(args, s); 00008 fprintf(stderr, "Matrice] "); 00009 vfprintf(stderr, s, args); 00010 fprintf(stderr, "\n"); 00011 va_end(args); 00012 #else 00013 return; 00014 #endif 00015 } 00016 // Matrice::Matrice(int newNSize, int newNRow) { // the only public ctor 00017 // if (newNSize <= 0) newNSize = 5; 00018 // NSize = newNSize; 00019 // if ((newNRow <= newNSize)&&(newNRow>0)) 00020 // NRow = newNRow; 00021 // else 00022 // NRow = newNSize; 00023 // // since allocate() will first call delete[] on data: 00024 // //data = new double [NSize*NSize]; 00025 // data = (double *)calloc(NSize*NSize,sizeof(double)); 00026 // NCol = NRow = NSize; 00027 // // allocate(); 00028 // } 00029 //----------------Constructors------------------------ 00030 Matrice::Matrice(int ExtNRow, int ExtNCol){ 00031 Shout("Matrice(row,col)"); 00032 NRow = ExtNRow; 00033 NCol = ExtNCol; 00034 NZed = 0; 00035 NSize = NCol*NRow; 00036 NDim = 2; 00037 data = (double *)calloc(NSize,sizeof(double)); 00038 } 00039 Matrice::Matrice(int ExtNRow, int ExtNCol, double *pointer){ 00040 Shout("Matrice(row,col)"); 00041 NRow = ExtNRow; 00042 NCol = ExtNCol; 00043 NSize = NCol*NRow; 00044 NDim = 2; 00045 data = (double *)malloc(sizeof(double)); 00046 data = pointer; 00047 } 00048 Matrice::Matrice(int ExtNRow){ // the only public data = (double *)calloc(NSize*NSize,sizeof(double)); 00049 Shout("Matrice(row=col)"); 00050 NRow = ExtNRow; 00051 NCol = 0; 00052 NZed = 0; 00053 NSize = NRow; 00054 NDim = 1; 00055 data = (double *)calloc(NSize,sizeof(double)); 00056 } 00057 Matrice::Matrice(int ExtNRow,int ExtNCol,int ExtNZed){ 00058 Shout("Matrice(row,col)"); 00059 NRow = ExtNRow; 00060 NCol = ExtNCol; 00061 NZed = ExtNZed; 00062 NSize = NCol*NRow*NZed; 00063 NDim = 3; 00064 data = (double *)calloc(NSize,sizeof(double)); 00065 } 00066 Matrice::Matrice(SPLINE Wg){ 00067 Shout("Matrice(SPLINE)"); 00068 NRow = NCol = 3; 00069 NZed = 0; 00070 NSize = NRow * NCol; 00071 data = (double *)calloc(NSize,sizeof(double)); 00072 double MenoDue = - .75*Wg.a3 + 1.5*Wg.a4; 00073 //MenoDue += .125*Wg.a1 - .125*Wg.a2; //O(h^4) 00074 double MenoUno = -.5*Wg.a1 + Wg.a2 + 1.5*Wg.a3 - 6.*Wg.a4; 00075 //MenoUno += -.125*Wg.a1 - .5*Wg.a2; 00076 double Zero = Wg.a0 - 2.*Wg.a2 + 9.*Wg.a4; 00077 //Zero += 0.75*Wg.a2; 00078 double PiuUno = .5*Wg.a1 + Wg.a2 - 1.5*Wg.a3 - 6.*Wg.a4; 00079 //PiuUno += .25*Wg.a1 + .5*Wg.a2; 00080 double PiuDue = .75*Wg.a3 + 1.5*Wg.a4; 00081 //PiuDue += -.125*Wg.a1 -.125*Wg.a2; 00082 double Norm=0.; 00083 for(int r=0;r<NCol;r++){ 00084 data[NRow*0+r] = MenoUno; 00085 data[NRow*1+r] = Zero; 00086 data[NRow*2+r] = PiuUno; 00087 } 00088 for(int r=0;r<NRow;r++) 00089 for(int c=0;c<NCol;c++) 00090 //Norm += data[NSize*r+c] > 0. ? data[NSize*r+c] : 0; 00091 Norm += ASS(data[NRow*c+r]); 00092 for(int r=0;r<NRow;r++) 00093 for(int c=0;c<NCol;c++) 00094 data[NRow*c+r] /= Norm*.5; 00095 NCol = NRow; 00096 NSize = NCol * NRow; 00097 NDim = 2; 00098 } 00099 Matrice::Matrice(double *Axis,double Angle,int ExtNRow){ 00100 double c = cos(Angle); 00101 double s = sin(Angle); 00102 double t = 1. - c; 00103 double Norm = 0.; 00104 for(int d=0;d<3;d++){ 00105 Norm += SQR(Axis[d]); 00106 } 00107 Norm = Norm > 0. ? sqrt(Norm) : 1.; 00108 double x = Axis[0]/Norm; 00109 double y = Axis[1]/Norm; 00110 double z = Axis[2]/Norm; 00111 NDim = 2; 00112 NZed = 0; 00113 if(ExtNRow == 4){ 00114 NCol = NRow = 4; 00115 NSize = NCol * NRow; 00116 data = (double *)calloc(NSize,sizeof(double)); 00117 data[NRow*0+0] = t*x*x + c; 00118 data[NRow*0+1] = t*x*y + z*s; 00119 data[NRow*0+2] = t*x*z - y*s; 00120 data[NRow*0+3] = 0.; 00121 00122 data[NRow*1+0] = t*x*y - z*s; 00123 data[NRow*1+1] = t*y*y + c; 00124 data[NRow*1+2] = t*y*z + x*s; 00125 data[NRow*1+3] = 0.; 00126 00127 data[NRow*2+0] = t*x*z + y*s; 00128 data[NRow*2+1] = t*y*z - x*s; 00129 data[NRow*2+2] = t*z*z + c; 00130 data[NRow*2+3] = 0.; 00131 00132 data[NRow*3+0] = 0.; 00133 data[NRow*3+1] = 0.; 00134 data[NRow*3+2] = 0.; 00135 data[NRow*3+3] = 1.; 00136 } 00137 else{ 00138 NCol = NRow = 3; 00139 NSize = NCol * NRow; 00140 data = (double *)calloc(NSize,sizeof(double)); 00141 data[NRow*0+0] = t*x*x + c; 00142 data[NRow*0+1] = t*x*y + z*s; 00143 data[NRow*0+2] = t*x*z - y*s; 00144 00145 data[NRow*1+0] = t*x*y - z*s; 00146 data[NRow*1+1] = t*y*y + c; 00147 data[NRow*1+2] = t*y*z + x*s; 00148 00149 data[NRow*2+0] = t*x*z + y*s; 00150 data[NRow*2+1] = t*y*z - x*s; 00151 data[NRow*2+2] = t*z*z + c; 00152 } 00153 } 00154 Matrice::Matrice(Quadri q,int dim){ 00155 //FIXME: the determinant is not zero! 00156 NDim = 2; 00157 NZed = 0; 00158 if(dim == 4){ 00159 NCol = NRow = 4; 00160 NSize = NCol * NRow; 00161 data = (double *)calloc(NSize,sizeof(double)); 00162 data[NRow*0+0] = q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z; 00163 data[NRow*0+1] = 2.*q.x*q.y + 2.*q.w*q.z; 00164 data[NRow*0+2] = 2.*q.x*q.z - 2.*q.w*q.y; 00165 data[NRow*0+3] = 0.; 00166 00167 data[NRow*1+0] = 2.*q.x*q.y - 2.*q.w*q.z; 00168 data[NRow*1+1] = q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z; 00169 data[NRow*1+2] = 2.*q.y*q.z + 2.*q.w*q.x; 00170 data[NRow*1+3] = 0.; 00171 00172 data[NRow*2+0] = 2.*q.x*q.z + 2.*q.w*q.y; 00173 data[NRow*2+1] = 2.*q.y*q.z - 2.*q.w*q.x; 00174 data[NRow*2+2] = q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z; 00175 data[NRow*2+3] = 0.; 00176 00177 data[NRow*3+0] = 0.; 00178 data[NRow*3+1] = 0.; 00179 data[NRow*3+2] = 0.; 00180 data[NRow*3+3] = q.w*q.w + q.x*q.x + q.y*q.y + q.z*q.z; 00181 } 00182 else{ 00183 NCol = NRow = 3; 00184 NSize = NCol * NRow; 00185 data = (double *)calloc(NSize,sizeof(double)); 00186 data[NRow*0+0] = 1. - 2.*SQR(q.y) - 2.*SQR(q.z); 00187 data[NRow*0+1] = 2.*q.x*q.y + 2.*q.w*q.z; 00188 data[NRow*0+2] = 2.*q.x*q.z - 2.*q.w*q.y; 00189 00190 data[NRow*1+0] = 2.*q.x*q.y - 2.*q.w*q.z; 00191 data[NRow*1+1] = 1. - 2.*SQR(q.x) - 2.*SQR(q.z); 00192 data[NRow*1+2] = 2.*q.y*q.z + 2.*q.w*q.x; 00193 00194 data[NRow*2+0] = 2.*q.x*q.z + 2.*q.w*q.y; 00195 data[NRow*2+1] = 2.*q.y*q.z - 2.*q.w*q.x; 00196 data[NRow*2+2] = 1. - 2.*SQR(q.x) - 2.*SQR(q.y); 00197 } 00198 } 00199 Matrice::Matrice(double Roll,double Pitch,double Yaw,int ExtNRow){ 00200 //Defining Rrpy(r,p,y) := RzrRypRxy 00201 double CR = cos(Roll); 00202 double SR = sin(Roll); 00203 double CP = cos(Pitch); 00204 double SP = sin(Pitch); 00205 double CY = cos(Yaw); 00206 double SY = sin(Yaw); 00207 NDim = 2; 00208 NZed = 0; 00209 if(ExtNRow == 4){ 00210 NCol = NRow = 4; 00211 NSize = NCol * NRow; 00212 data = (double *)calloc(NSize,sizeof(double)); 00213 data[NRow*0+0] = CY*CP; 00214 data[NRow*0+1] = SY*CP; 00215 data[NRow*0+2] = -SP; 00216 data[NRow*0+3] = 0.; 00217 00218 data[NRow*1+0] = CY*SP*SR - SY*CR; 00219 data[NRow*1+1] = SY*SP*SR + CY*CR; 00220 data[NRow*1+2] = CP*SR; 00221 data[NRow*1+3] = 0.; 00222 00223 data[NRow*2+0] = CY*SP*CR + SY*SR; 00224 data[NRow*2+1] = SY*SP*CR - CY*SR; 00225 data[NRow*2+2] = CP*CR; 00226 data[NRow*2+3] = 0.; 00227 00228 data[NRow*3+0] = 0.; 00229 data[NRow*3+1] = 0.; 00230 data[NRow*3+2] = 0.; 00231 data[NRow*3+3] = 1.; 00232 // Other definition of the angles (to check) 00233 // data[NRow*0+0] = CR*CP*CY - SR*SY; 00234 // data[NRow*0+1] = CR*CP*SY - SR*CY; 00235 // data[NRow*0+2] = -CR*SP; 00236 // data[NRow*0+3] = 0.; 00237 00238 // data[NRow*1+0] = -SR*CP*CY - CR*SY; 00239 // data[NRow*1+1] = -SR*CP*SY + CR*CY; 00240 // data[NRow*1+2] = SR*SP; 00241 // data[NRow*1+3] = 0.; 00242 00243 // data[NRow*2+0] = SP*CY; 00244 // data[NRow*2+1] = SP*SY; 00245 // data[NRow*2+2] = CP; 00246 // data[NRow*2+3] = 0.; 00247 00248 // data[NRow*3+0] = 0.; 00249 // data[NRow*3+1] = 0.; 00250 // data[NRow*3+2] = 0.; 00251 // data[NRow*3+3] = 1.; 00252 } 00253 if(ExtNRow == 3){ 00254 NCol = NRow = 3; 00255 NSize = NCol * NRow; 00256 data = (double *)calloc(NSize,sizeof(double)); 00257 data[NRow*0+0] = CR*CP; 00258 data[NRow*0+1] = SR*CP; 00259 data[NRow*0+2] = -SP; 00260 00261 data[NRow*1+0] = CR*SP*SY - SR*CY; 00262 data[NRow*1+1] = SR*SP*SY + CR*SY; 00263 data[NRow*1+2] = CP*SY; 00264 00265 data[NRow*2+0] = CR*SP*CY+SR*SY; 00266 data[NRow*2+1] = SR*SP*CY-CR*SY; 00267 data[NRow*2+2] = CR*CY; 00268 } 00269 } 00270 Matrice::Matrice(double *M,int Row,int Col){ 00271 NRow = Row; 00272 NCol = Col; 00273 NZed = 0; 00274 NSize = NRow*NCol; 00275 //data = M; 00276 NDim = 2; 00277 data = (double *)calloc(NSize,sizeof(double)); 00278 for(int c=0;c<NCol;c++) 00279 for(int r=0;r<NRow;r++) 00280 data[NRow*c+r] = M[NRow*c+r]; 00281 } 00282 Matrice::Matrice(SPLINE Wg,int Dim){ 00283 Shout("Matrice(SPLINE,dim)"); 00284 NCol = NRow = 5; 00285 NZed = 0; 00286 NSize = NCol * NRow; 00287 data = (double *)calloc(NSize,sizeof(double)); 00288 FillDiffOperator(Wg,Dim); 00289 } 00290 Matrice::~Matrice() { 00291 // delete[] data; 00292 free(data); 00293 } 00294 void Matrice::RandomFill(double Max){ 00295 Shout("RandomFill"); 00296 for(int r=0;r<NRow;r++) 00297 for(int c=0;c<NCol;c++) 00298 data[NRow*c+r] = Max*drand48();//Casuale(); 00299 } 00300 void Matrice::FillDiffOperator(SPLINE Wg,int Dim){ 00301 Shout("Matrice(SPLINE,dim)"); 00302 double MenoDue = - .75*Wg.a3 + 2.*Wg.a4;//1.5 00303 //MenoDue += .125*Wg.a1 - .125*Wg.a2; //O(h^4) 00304 MenoDue -= 1./12.*Wg.a2; //O(h^4) 00305 double MenoUno = -.5*Wg.a1 + Wg.a2 + 1.5*Wg.a3 - 8.*Wg.a4;//6 00306 //MenoUno += -.125*Wg.a1 - .5*Wg.a2; 00307 MenoUno += 1./3.*Wg.a2; //O(h^4) 00308 double Zero = Wg.a0 - 2.*Wg.a2 + 12.*Wg.a4;//9 00309 //Zero += 0.75*Wg.a2; 00310 Zero -= 0.5*Wg.a2; //O(h^4) 00311 double PiuUno = .5*Wg.a1 + Wg.a2 - 1.5*Wg.a3 - 8.*Wg.a4; 00312 //PiuUno += .25*Wg.a1 + .5*Wg.a2; 00313 PiuUno += 1./3.*Wg.a2; 00314 double PiuDue = .75*Wg.a3 + 2.*Wg.a4; 00315 //PiuDue += -.125*Wg.a1 -.125*Wg.a2; 00316 PiuDue -= 1./12.*Wg.a2; //O(h^4) 00317 double Norm=0.; 00318 if (Dim == 0){ 00319 for(int r=0;r<NCol;r++){ 00320 data[NRow*0+r] = MenoDue; 00321 data[NRow*1+r] = MenoUno; 00322 data[NRow*2+r] = Zero; 00323 data[NRow*3+r] = PiuUno; 00324 data[NRow*4+r] = PiuDue; 00325 } 00326 } 00327 else if(Dim == 1){ 00328 int r=2; 00329 data[NRow*0+r] = MenoDue; 00330 data[NRow*1+r] = MenoUno; 00331 data[NRow*2+r] = Zero; 00332 data[NRow*3+r] = PiuUno; 00333 data[NRow*4+r] = PiuDue; 00334 } 00335 else if (Dim == 2){ 00336 int r=2; 00337 data[NRow*0+r] = MenoDue; 00338 data[NRow*1+r] = MenoUno; 00339 data[NRow*2+r] = Zero; 00340 data[NRow*3+r] = PiuUno; 00341 data[NRow*4+r] = PiuDue; 00342 int c=2; 00343 data[NRow*c+0] = MenoDue; 00344 data[NRow*c+1] = MenoUno; 00345 data[NRow*c+2] += Zero; 00346 data[NRow*c+3] = PiuUno; 00347 data[NRow*c+4] = PiuDue; 00348 } 00349 else if (Dim == 3){ 00350 for(int r=0;r<NCol;r++){ 00351 data[NRow*0+r] = MenoDue; 00352 data[NRow*1+r] = MenoUno; 00353 data[NRow*2+r] = Zero; 00354 data[NRow*3+r] = PiuUno; 00355 data[NRow*4+r] = PiuDue; 00356 } 00357 } 00358 } 00359 void Matrice::FillCanny(){ 00360 if(NRow != 5){ 00361 printf("I don't know the expresion for matrices of NRow != 5\n"); 00362 return ; 00363 } 00364 if(NCol != 5){ 00365 printf("I don't know the expresion for matrices of NRow != 5\n"); 00366 return ; 00367 } 00368 Set(0,0,2.); Set(0,1,4.); Set(0,2,5.); Set(0,3,4.); Set(0,4,2.); 00369 Set(1,0,4.); Set(1,1,9.); Set(1,2,12.); Set(1,3,9.); Set(1,4,4.); 00370 Set(2,0,5.); Set(2,1,12.); Set(2,2,15.); Set(2,3,12.); Set(2,4,5.); 00371 Set(3,0,4.); Set(3,1,9.); Set(3,2,12.); Set(3,3,9.); Set(3,4,4.); 00372 Set(4,0,2.); Set(4,1,4.); Set(4,2,5.); Set(4,3,4.); Set(4,4,2.); 00373 Multiply(1./159.); 00374 } 00375 void Matrice::FillGaussian(double Sigma,double CutOff){ 00376 int Half = NRow/2; 00377 double Norm = 0.; 00378 if(NDim == 3){ 00379 for(int r=0;r<NRow;r++){ 00380 double x = CutOff*(r-Half)/(double)NRow; 00381 for(int c=0;c<NCol;c++){ 00382 double y = CutOff*(c-Half)/(double)NCol; 00383 for(int q=0;q<NCol;q++){ 00384 double z = CutOff*(q-Half)/(double)NCol; 00385 double r2 = SQR(x) + SQR(y) + SQR(z); 00386 double Gauss = exp(-r2*.5/SQR(Sigma)); 00387 data[(NRow*c+r)*NCol+q] = Gauss; 00388 Norm += Gauss; 00389 } 00390 } 00391 } 00392 } 00393 else if(NDim == 2){ 00394 for(int r=0;r<NRow;r++){ 00395 double x = CutOff*(r-Half)/(double)NRow; 00396 for(int c=0;c<NCol;c++){ 00397 double y = CutOff*(c-Half)/(double)NCol; 00398 double r2 = SQR(x) + SQR(y); 00399 double Gauss = exp(-r2*.5/SQR(Sigma)); 00400 data[NRow*c+r] = Gauss; 00401 Norm += Gauss; 00402 } 00403 } 00404 } 00405 else if(NDim == 1){ 00406 for(int r=0;r<NRow;r++){ 00407 double x = CutOff*(r-Half)/(double)NRow; 00408 double r2 = SQR(x); 00409 double Gauss = exp(-r2*.5/SQR(Sigma)); 00410 data[r] = Gauss; 00411 Norm += Gauss; 00412 } 00413 } 00414 Multiply(1./Norm); 00415 } 00416 void Matrice::FillGaussian5(){ 00417 if(NRow != 5 && NCol != 5){ 00418 printf("Invalid number of rows and cols %dx%d != 7x7\n",NRow,NCol); 00419 return; 00420 } 00421 data[NRow*0+0] = 1; 00422 data[NRow*0+1] = 4; 00423 data[NRow*0+2] = 7; 00424 data[NRow*0+3] = 4; 00425 data[NRow*0+4] = 1; 00426 00427 data[NRow*1+0] = 4; 00428 data[NRow*1+1] = 16; 00429 data[NRow*1+2] = 26; 00430 data[NRow*1+3] = 16; 00431 data[NRow*1+4] = 4; 00432 00433 data[NRow*2+0] = 7; 00434 data[NRow*2+1] = 26; 00435 data[NRow*2+2] = 41; 00436 data[NRow*2+3] = 26; 00437 data[NRow*2+4] = 7; 00438 00439 data[NRow*3+0] = 4; 00440 data[NRow*3+1] = 16; 00441 data[NRow*3+2] = 26; 00442 data[NRow*3+3] = 16; 00443 data[NRow*3+4] = 4; 00444 00445 data[NRow*4+0] = 1; 00446 data[NRow*4+1] = 4; 00447 data[NRow*4+2] = 7; 00448 data[NRow*4+3] = 4; 00449 data[NRow*4+4] = 1; 00450 00451 Multiply(1./273.); 00452 } 00453 00454 00455 //---------------Manage-entries------------------- 00456 double Matrice ::Val(int row){ 00457 #ifdef MATR_DEBUG 00458 if ( (row>=NRow) || (row<0) ) 00459 { printf("Values %d %d out of range %d %d\n",row,NRow); 00460 return 1.; } 00461 #endif 00462 return data[row]; 00463 } 00464 double Matrice ::Val(int row,int col){ 00465 #ifdef MATR_DEBUG 00466 if ( (row>=NRow) || (col>=NCol) 00467 || (row<0) || (col<0) ) 00468 { printf("Values %d %d out of range %d %d\n",row,col,NRow,NCol); 00469 return 1.; } 00470 #endif 00471 return data[ NRow*col+row ]; 00472 } 00473 double Matrice ::Val(int row,int col,int zed){ 00474 return data[ (NRow*col+row)*NCol+zed ]; 00475 } 00476 bool Matrice ::Set(int row, int column, double newvalue) { 00477 #ifdef MATR_DEBUG 00478 if ( (row >= NRow) || (column >= NCol) 00479 || (row<0) || (column<0) ) return false; 00480 #endif 00481 data[ NRow*column + row ] = newvalue; 00482 return true; 00483 } 00484 bool Matrice ::Add(int row, int column, double Value) { 00485 #ifdef MATR_DEBUG 00486 if ( (row >= NRow) || (column >= NCol) 00487 || (row<0) || (column<0) ) return false; 00488 #endif 00489 data[ NRow*column + row ] += Value; 00490 return true; 00491 } 00492 void Matrice ::Print(){ 00493 if(NDim == 3){ 00494 for(int q=0;q<NZed;q++){ 00495 printf("%d)\n",q); 00496 for(int r=0;r<NRow;r++){ 00497 printf("|"); 00498 for(int c=0;c<NCol;c++){ 00499 printf("%.2g ",data[(NRow*c+r)*NCol+q]); 00500 } 00501 printf("|\n"); 00502 } 00503 printf("\n"); 00504 } 00505 return; 00506 } 00507 else if(NDim == 1){ 00508 printf("|"); 00509 for(int r=0;r<NRow;r++){ 00510 printf("%.2g ",data[r]); 00511 } 00512 printf("|\n"); 00513 printf("\n"); 00514 return; 00515 } 00516 for(int r=0;r<NRow;r++){ 00517 printf("|"); 00518 for(int c=0;c<NCol;c++){ 00519 printf("%.2g ",data[NRow*c+r]); 00520 } 00521 printf("|\n"); 00522 } 00523 printf("\n"); 00524 } 00525 //---------------inversion-(-stolen,-to-be-checked-)--------- 00526 void Matrice ::comparetoidentity() { 00527 int worstdiagonal = 0; 00528 double maxunitydeviation = 0.0; 00529 double currentunitydeviation; 00530 for ( int i = 0; i < NRow; i++ ) { 00531 currentunitydeviation = data[i+i*NRow] - 1.; 00532 if ( currentunitydeviation < 0.0) currentunitydeviation *= -1.; 00533 if ( currentunitydeviation > maxunitydeviation ) { 00534 maxunitydeviation = currentunitydeviation; 00535 worstdiagonal = i; 00536 } 00537 } 00538 int worstoffdiagonalrow = 0; 00539 int worstoffdiagonalcolumn = 0; 00540 double maxzerodeviation = 0.0; 00541 double currentzerodeviation ; 00542 for ( int i = 0; i < NRow; i++ ) { 00543 for ( int j = 0; j < NRow; j++ ) { 00544 if ( i == j ) continue; // we look only at non-diagonal terms 00545 currentzerodeviation = data[i+j*NRow]; 00546 if ( currentzerodeviation < 0.0) currentzerodeviation *= -1.0; 00547 if ( currentzerodeviation > maxzerodeviation ) { 00548 maxzerodeviation = currentzerodeviation; 00549 worstoffdiagonalrow = i; 00550 worstoffdiagonalcolumn = j; 00551 } 00552 00553 } 00554 } 00555 cout << "Worst diagonal value deviation from unity: " 00556 << maxunitydeviation << " at row/column " << worstdiagonal << endl; 00557 cout << "Worst off-diagonal value deviation from zero: " 00558 << maxzerodeviation << " at row = " << worstoffdiagonalrow 00559 << ", column = " << worstoffdiagonalcolumn << endl; 00560 } 00561 void Matrice ::settoproduct(Matrice& left, Matrice& right) { 00562 // NRow = left.getNRow(); 00563 // if ( NSize < left.getNRow() ) { 00564 // NSize = left.getNRow(); 00565 // allocate(); 00566 // } 00567 for ( int i = 0; i < NRow; i++ ) 00568 for ( int j = 0; j < NRow; j++ ) { 00569 double sum = 0.0; 00570 double leftvalue, rightvalue; 00571 bool success; 00572 for (int c = 0; c < NRow; c++) { 00573 left.getvalue(i,c,leftvalue,success); 00574 right.getvalue(c,j,rightvalue,success); 00575 sum += leftvalue * rightvalue; 00576 } 00577 Set(i,j,sum); 00578 } 00579 } 00580 void Matrice ::copymatrix(Matrice& source) { 00581 // NRow = source.getNRow(); 00582 // if ( NSize < source.getNRow() ) { 00583 // NSize = source.getNRow(); 00584 // allocate(); 00585 // } 00586 for ( int i = 0; i < NRow; i++ ) 00587 for ( int j = 0; j < NRow; j++ ) { 00588 double value; 00589 bool success; 00590 source.getvalue(i,j,value,success); 00591 data[i+j*NRow] = value; 00592 } 00593 } 00594 void Matrice ::setNRow(int newNRow) { 00595 // if ( newNRow > NSize ) 00596 // { 00597 // NSize = newNRow ; // * 2; // wastes memory but saves 00598 // // time otherwise required for 00599 // // operation new[] 00600 // allocate(); 00601 // } 00602 // if (newNRow >= 0) NRow = newNRow; 00603 } 00604 int Matrice ::getNRow() { return NRow; } 00605 void Matrice ::getvalue(int row, int column, double& returnvalue, bool& success) { 00606 #ifdef MATR_DEBUG 00607 if ( (row>=NRow) || (column>=NCol) 00608 || (row<0) || (column<0) ) 00609 { success = false; 00610 return; } 00611 #endif 00612 returnvalue = data[ row + column*NRow ]; 00613 success = true; 00614 } 00615 void Matrice::Invert() { 00616 #ifdef MATR_DEBUG //CHECKIT 00617 if (NRow <= 0) return; // sanity check 00618 if (NRow == 1) return; // must be of dimension >= 2 00619 #endif 00620 for (int i=1; i < NRow; i++) data[i] /= data[0]; // normalize row 0 00621 for (int i=1; i < NRow; i++) { 00622 for (int j=i; j < NRow; j++) { // do a column of L 00623 double sum = 0.0; 00624 for (int k = 0; k < i; k++) 00625 sum += data[j+k*NRow] * data[k+i*NRow]; 00626 data[j+i*NRow] -= sum; 00627 } 00628 if (i == NRow-1) continue; 00629 for (int j=i+1; j < NRow; j++) { // do a row of U 00630 double sum = 0.0; 00631 for (int k = 0; k < i; k++) 00632 sum += data[i+k*NRow]*data[k+j*NRow]; 00633 data[i+j*NRow] = 00634 (data[i+j*NRow]-sum) / data[i+i*NRow]; 00635 } 00636 } 00637 for ( int i = 0; i < NRow; i++ ) // invert L 00638 for ( int j = i; j < NRow; j++ ) { 00639 double x = 1.0; 00640 if ( i != j ) { 00641 x = 0.0; 00642 for ( int k = i; k < j; k++ ) 00643 x -= data[j+k*NRow]*data[k+i*NRow]; 00644 } 00645 data[j+i*NRow] = x / data[j+j*NRow]; 00646 } 00647 for ( int i = 0; i < NRow; i++ ) // invert U 00648 for ( int j = i; j < NRow; j++ ) { 00649 if ( i == j ) continue; 00650 double sum = 0.0; 00651 for ( int k = i; k < j; k++ ) 00652 sum += data[k+j*NRow]*( (i==k) ? 1.0 : data[i+k*NRow] ); 00653 data[i+j*NRow] = -sum; 00654 } 00655 for ( int i = 0; i < NRow; i++ ) // final inversion 00656 for ( int j = 0; j < NRow; j++ ) { 00657 double sum = 0.0; 00658 for ( int k = ((i>j)?i:j); k < NRow; k++ ) 00659 sum += ((j==k)?1.0:data[j+k*NRow])*data[k+i*NRow]; 00660 data[j+i*NRow] = sum; 00661 } 00662 }; 00663 //-------------Other-operations----------------- 00664 int Matrice ::Solve(double *Known,double *UnKnown){ 00665 Shout("Solve"); 00666 #ifdef MATR_DEBUG 00667 #endif 00668 Matrice Lower(NCol,NCol); 00669 Matrice Upper(NCol,NCol); 00670 double *AlmostKnown = (double *)calloc(NCol,sizeof(double)); 00671 if(!AlmostKnown) {printf("Not allocated\n");return 0;} 00672 /* assegna i valori della diagonale di L */ 00673 for(int r = 0; r < NRow ; r ++){ 00674 Lower.Set(r,r,1.); 00675 } 00676 /* calcola gli elementi fuori della diagonale */ 00677 for(int j = 0; j < NCol ; j ++){ 00678 for(int i = 0; i <= j ; i++){ 00679 Upper.Set(i,j,Val(i,j)); 00680 for (int k = 0; k <= i - 1; k++) { 00681 Upper.Add(i,j,-Lower.Val(i,k)*Upper.Val(k,j)); 00682 } 00683 } 00684 for (int i = j + 1; i < NCol ; i++) { 00685 Lower.Set(i,j,Val(i,j)); 00686 for (int k = 0; k <= j - 1; k ++) { 00687 Lower.Add(i,j,-Lower.Val(i,k)*Upper.Val(k,j)); 00688 }//FIXME 00689 double Diag = POS(Upper.Val(j,j)) > 0. ? Lower.Val(i,j)/Upper.Val(j,j) : 1.; 00690 Lower.Set(i,j,Diag); 00691 } 00692 }//Solve the Uz = y 00693 //Upper = NULL; 00694 for(int r=0;r<NRow;r++){ 00695 AlmostKnown[r] = Known[r]; 00696 for(int c=r-1;c>=0;c--){ 00697 AlmostKnown[r] -= AlmostKnown[c]*Lower.Val(r,c); 00698 //printf("Coeff[%d][%d]=%lf %lf\n",r,c,UnKnown[r],Lower.Val(r,c)); 00699 } 00700 if(POS(Lower.Val(r,r))> 0.) 00701 AlmostKnown[r] /= POS(Lower.Val(r,r))>0. ? Lower.Val(r,r) : 1.; 00702 else 00703 AlmostKnown[r] = 0.; 00704 //printf("Coeff[%d][%d]=%lf %lf\n",r,r,AlmostKnown[r],Lower.Val(r,r)); 00705 } 00706 //Lower.Print(); 00707 for(int r=NRow-1;r>=0;r--){ 00708 UnKnown[r] = AlmostKnown[r]; 00709 for(int c=r+1;c<NCol;c++){ 00710 UnKnown[r] -= UnKnown[c]*Upper.Val(r,c); 00711 // printf("Coeff[%d][%d]=%lf %lf\n",r,c,AlmostKnown[r],Upper.Val(r,c)); 00712 } 00713 if(POS(Upper.Val(r,r))> 0.) 00714 UnKnown[r] /= Upper.Val(r,r); 00715 else 00716 UnKnown[r] = 0.; 00717 //printf("Coeff[%d][%d]=%lf %lf\n",r,r,UnKnown[r],Upper.Val(r,r)); 00718 }//finish solving Lx = z 00719 //Upper.Print(); 00720 free(AlmostKnown); 00721 return 1; 00722 }; 00723 void Matrice::Apply(double *Known,double *UnKnown){ 00724 Shout("Apply"); 00725 for(int r=0;r<NRow;r++){ 00726 for(int c=0;c<NCol;c++){ 00727 UnKnown[r] += Known[c]*data[r+c*NRow]; 00728 } 00729 } 00730 }; 00731 double Matrice::Det(){ 00732 Shout("Det"); 00733 Matrice Lower(NCol); 00734 Matrice Upper(NCol); 00735 /* assegna i valori della diagonale di L */ 00736 for (int r = 0; r < NCol ; r ++) { 00737 Lower.Set(r,r,1.); 00738 } 00739 /* calcola gli elementi fuori della diagonale */ 00740 for (int j = 0; j < NCol ; j ++) { 00741 for (int i = 0; i <= j ; i++) { 00742 Upper.Set(i,j,Val(i,j)); 00743 for (int k = 0; k <= i - 1; k++) { 00744 Upper.Add(i,j,-Lower.Val(i,k)*Upper.Val(k,j)); 00745 } 00746 } 00747 for (int i = j + 1; i < NCol ; i++) { 00748 Lower.Set(i,j,Val(i,j)); 00749 for (int k = 0; k <= j - 1; k ++) { 00750 Lower.Add(i,j,-Lower.Val(i,k)*Upper.Val(k,j)); 00751 } 00752 Lower.Set(i,j,Lower.Val(i,j)/Upper.Val(j,j)); 00753 } 00754 } 00755 double Det = 1.; 00756 for(int r=0;r<NCol;r++) 00757 Det *= Upper.Val(r,r); 00758 return Det; 00759 }; 00760 void Matrice::Transpose(){ 00761 Shout("Transpose"); 00762 double *Temp = (double *)calloc(NCol*NRow,sizeof(double)); 00763 for(int r=0;r<NRow;r++){ 00764 for(int c=0;c<NCol;c++){ 00765 Temp[r+c*NRow] = data[r+c*NRow]; 00766 } 00767 } 00768 for(int r=0;r<NRow;r++){ 00769 for(int c=0;c<NCol;c++){ 00770 data[r+c*NRow] = Temp[c+r*NRow]; 00771 } 00772 } 00773 free(Temp); 00774 } 00775 void Matrice::Clear(){ 00776 Shout("Clear"); 00777 for(int r=0;r<NRow;r++){ 00778 for(int c=0;c<NCol;c++){ 00779 data[r+c*NRow] = 0.; 00780 } 00781 } 00782 } 00783 void Matrice::Normalize(){ 00784 Shout("Normalize"); 00785 double Max=0.; 00786 double Min=0.; 00787 for(int r=0;r<NRow;r++){ 00788 for(int c=0;c<NCol;c++){ 00789 if(Max < data[r+c*NRow]) 00790 Max = data[r+c*NRow]; 00791 if(Min > data[r+c*NRow]) 00792 Min = data[r+c*NRow]; 00793 } 00794 } 00795 if(fabs(Min) > 0.0e-5){ 00796 for(int r=0;r<NRow;r++) 00797 for(int c=0;c<NCol;c++) 00798 data[r+c*NRow] = data[r+c*NRow]/(Max-Min)-Min; 00799 00800 } 00801 else { 00802 for(int r=0;r<NRow;r++) 00803 for(int c=0;c<NCol;c++) 00804 data[r+c*NRow] = data[r+c*NRow]/Max; 00805 } 00806 } 00807 void Matrice::Multiply(double Val){ 00808 for(int s=0;s<NSize;s++) 00809 data[s] *= Val; 00810 // for(int r=0;r<NRow;r++) 00811 // for(int c=0;c<NCol;c++) 00812 // data[r+c*NRow] = data[r+c*NRow]*Val; 00813 } 00814 void Matrice::CopyOn(Matrice *B){ 00815 for(int r=0;r<NRow;r++) 00816 for(int c=0;c<NCol;c++) 00817 B->Set(r,c,data[r+c*NRow]); 00818 } 00819 Matrice Matrice::operator+ (Matrice& A){ 00820 if(NCol != A.NCol || NRow != A.NCol){ 00821 printf("Incompatible matrices. Dim: %d/%d\n",NSize,A.NSize); 00822 return 0; 00823 } 00824 Matrice Resp(NRow,NCol); 00825 for(int r=0;r<NRow;r++) 00826 for(int c=0;c<NCol;c++) 00827 Resp.Set(r,c,Val(r,c)+A.Val(r,c)); 00828 return Resp; 00829 } 00830 Matrice Matrice::operator* (Matrice &A){ 00831 if(NCol != A.NRow || NRow != A.NCol){ 00832 printf("Incompatible matrices. Dim: %d/%d\n",NSize,A.NSize); 00833 return 0; 00834 } 00835 Matrice Resp(NRow,A.NCol); 00836 for(int r=0;r<NRow;r++) 00837 for(int c=0;c<A.NCol;c++){ 00838 double Temp=0.; 00839 for(int i=0;i<NRow;i++) 00840 //Temp += Val(r,i)*A.Val(i,c); 00841 Temp += Resp.data[r+i*NRow]*A.data[i+c*NRow]; 00842 Resp.Set(r,c,Temp); 00843 } 00844 Resp.Print(); 00845 return Resp; 00846 } 00847 Matrice Matrice::operator= (Matrice& A){ 00848 if(NRow != A.NRow || NCol != A.NCol){ 00849 printf("Incompatible matrices. Dim: %d/%d\n",NSize,A.NSize); 00850 return 0; 00851 } 00852 for(int r=0;r<NRow;r++) 00853 for(int c=0;c<NCol;c++) 00854 Set(r,c,A.Val(r,c)); 00855 return *this; 00856 } 00857 Matrice Matrice::operator* (const double& Molt)const{ 00858 for(int r=0;r<NRow;r++) 00859 for(int c=0;c<NCol;c++) 00860 data[r+c*NRow] *= Molt; 00861 return *this; 00862 } 00863 Matrice Matrice::operator^(Matrice& A)const{ 00864 assert( NCol == A.NRow || NRow == A.NCol); 00865 printf("Still to be written!!!\n"); 00866 Matrice B(NCol,NRow); 00867 return B; 00868 } 00869 Vettore Matrice::operator* (const Vettore& u)const { 00870 if(NCol != u.NDim){ 00871 printf("Incompatible matrices. Dim: %d/%d\n",NSize,u.NDim); 00872 return 0; 00873 } 00874 Vettore Resp(NRow); 00875 for(int r=0;r<NRow;r++){ 00876 double Temp=0.; 00877 for(int c=0;c<NCol;c++) 00878 Temp += data[r+c*NRow]*u.x[c]; 00879 Resp.x[r] = Temp; 00880 } 00881 return Resp; 00882 } 00883 void Matrice::Mult(Matrice &A,Matrice &B){ 00884 if(B.NCol != A.NRow || B.NRow != A.NCol){ 00885 printf("Incompatible matrices. Dim: %d/%d\n",B.NSize,A.NSize); 00886 return ; 00887 } 00888 for(int r=0;r<A.NRow;r++) 00889 for(int c=0;c<B.NCol;c++){ 00890 double Temp=0.; 00891 for(int i=0;i<A.NRow;i++) 00892 Temp += A.Val(r,i)*B.Val(i,c); 00893 Set(r,c,Temp); 00894 } 00895 } 00896 void Matrice::Mult(Matrice &A){ 00897 if(NCol != A.NRow || NRow != A.NCol){ 00898 printf("Incompatible matrices. Dim: %d/%d\n",NSize,A.NSize); 00899 return ; 00900 } 00901 for(int r=0;r<A.NRow;r++) 00902 for(int c=0;c<NCol;c++){ 00903 double Temp=0.; 00904 for(int i=0;i<A.NRow;i++) 00905 Temp += A.Val(r,i)*Val(i,c); 00906 Set(r,c,Temp); 00907 } 00908 } 00909 Vettore Matrice::Mult(Matrice &A,Vettore &v){ 00910 Vettore Resp(NRow); 00911 for(int r=0;r<NRow;r++){ 00912 double Temp=0.; 00913 for(int c=0;c<NCol;c++) 00914 Temp += A.data[r+c*NRow]*v.x[c]; 00915 Resp.x[r] = Temp; 00916 } 00917 return Resp; 00918 } 00919 Vettore Matrice::Mult(Vettore &v){ 00920 Vettore Resp(NRow); 00921 for(int r=0;r<NRow;r++){ 00922 double Temp=0.; 00923 for(int c=0;c<NCol;c++) 00924 Temp += data[r+c*NRow]*v.x[c]; 00925 Resp.x[r] = Temp; 00926 } 00927 return Resp; 00928 } 00929 void Matrice::Mult(Vettore &v,Vettore &u){ 00930 for(int r=0;r<NRow;r++){ 00931 double Temp=0.; 00932 for(int c=0;c<NCol;c++) 00933 Temp += data[r+c*NRow]*v.x[c]; 00934 u.x[r] = Temp; 00935 } 00936 } 00937 void Matrice::ConvoluteMatrix(double *Plot,int NGrid,int NDim,int IfMinImConv){ 00938 if(NDim == 1){ 00939 if(!IfMinImConv) ConvoluteMatrix1(Plot,NGrid); 00940 else ConvoluteMatrix1MinImConv(Plot,NGrid); 00941 } 00942 else if(NDim == 2){ 00943 if(!IfMinImConv) ConvoluteMatrix2(Plot,NGrid); 00944 else ConvoluteMatrix2MinImConv(Plot,NGrid); 00945 } 00946 else if(NDim == 3){ 00947 ConvoluteMatrix3(Plot,NGrid); 00948 } 00949 } 00950 //without minimum image convention 00951 void Matrice::ConvoluteMatrix1(double *Plot,int NGrid){ 00952 double *Plot2 = (double *)calloc(NGrid,sizeof(double)); 00953 int NMat2 = (int)pNRow()/2; 00954 for(int gx=0;gx<NGrid;gx++){ 00955 if(gx <= NMat2 || gx >= NGrid - NMat2){ 00956 Plot2[gx] = Plot[gx]; 00957 continue; 00958 } 00959 for(int mx=0;mx<pNRow();mx++){ 00960 int g1x = gx + mx - NMat2; 00961 if(g1x >= NGrid){ 00962 Plot2[gx] = Plot[gx]; 00963 break; 00964 } 00965 if(g1x < 0){ 00966 Plot2[gx] = Plot[gx]; 00967 break; 00968 } 00969 Plot2[gx] += Plot[g1x]*Val(mx); 00970 } 00971 } 00972 for(int gx=0;gx<NGrid;gx++){ 00973 Plot[gx] = Plot2[gx]; 00974 } 00975 free(Plot2); 00976 } 00977 //with minimum image convention 00978 void Matrice::ConvoluteMatrix1MinImConv(double *Plot,int NGrid){ 00979 double *Plot2 = (double *)calloc(NGrid,sizeof(double)); 00980 int NMat2 = (int)pNRow()/2; 00981 for(int gx=0;gx<NGrid;gx++){ 00982 if(gx <= NMat2 || gx >= NGrid - NMat2){ 00983 Plot2[gx] = Plot[gx]; 00984 continue; 00985 } 00986 for(int mx=0;mx<pNRow();mx++){ 00987 int g1x = gx + mx - NMat2; 00988 if(g1x >= NGrid) g1x -= NGrid; 00989 if(g1x < 0) g1x + NGrid; 00990 Plot2[gx] += Plot[g1x]*Val(mx); 00991 } 00992 } 00993 for(int gx=0;gx<NGrid;gx++){ 00994 Plot[gx] = Plot2[gx]; 00995 } 00996 free(Plot2); 00997 } 00999 void Matrice::ConvoluteMatrix2(double *Plot,int NGrid){ 01000 double *Plot2 = (double *)calloc(SQR(NGrid),sizeof(double)); 01001 int NMat2 = (int)pNCol()/2; 01002 for(int gx=0;gx<NGrid;gx++){ 01003 for(int gy=0;gy<NGrid;gy++){ 01004 for(int mx=0;mx<pNRow();mx++){ 01005 int g1x = gx + mx - NMat2; 01006 if(g1x >= NGrid){ 01007 Plot2[gx*NGrid+gy] = Plot[gx*NGrid+gy]; 01008 break; 01009 } 01010 if(g1x < 0) { 01011 Plot2[gx*NGrid+gy] = Plot[gx*NGrid+gy]; 01012 break; 01013 } 01014 for(int my=0;my<pNCol();my++){ 01015 int g1y = gy + my - NMat2; 01016 if(g1y >= NGrid){ 01017 Plot2[gx*NGrid+gy] = Plot[gx*NGrid+gy]; 01018 break; 01019 } 01020 if(g1y < 0){ 01021 Plot2[gx*NGrid+gy] = Plot[gx*NGrid+gy]; 01022 break; 01023 } 01024 Plot2[gx*NGrid+gy] += Plot[g1x*NGrid+g1y]*Val(mx,my); 01025 } 01026 } 01027 } 01028 } 01029 for(int gx=0;gx<NGrid;gx++){ 01030 for(int gy=0;gy<NGrid;gy++){ 01031 Plot[gx*NGrid+gy] = Plot2[gx*NGrid+gy]; 01032 } 01033 } 01034 free(Plot2); 01035 } 01037 void Matrice::ConvoluteMatrix2MinImConv(double *Plot,int NGrid){ 01038 double *Plot2 = (double *)calloc(SQR(NGrid),sizeof(double)); 01039 int NMat2 = (int)pNCol()/2; 01040 for(int gx=0;gx<NGrid;gx++){ 01041 for(int gy=0;gy<NGrid;gy++){ 01042 for(int mx=0;mx<pNRow();mx++){ 01043 int g1x = gx + mx - NMat2; 01044 if(g1x >= NGrid) continue;//g1x -= NGrid; 01045 if(g1x < 0) continue;//g1x + NGrid; 01046 for(int my=0;my<pNCol();my++){ 01047 int g1y = gy + my - NMat2; 01048 if(g1y >= NGrid) continue;//g1y -= NGrid; 01049 if(g1y < 0) continue;//g1y + NGrid; 01050 Plot2[gx*NGrid+gy] += Plot[g1x*NGrid+g1y]*Val(mx,my); 01051 } 01052 } 01053 } 01054 } 01055 for(int gx=0;gx<NGrid;gx++){ 01056 for(int gy=0;gy<NGrid;gy++){ 01057 Plot[gx*NGrid+gy] = Plot2[gx*NGrid+gy]; 01058 } 01059 } 01060 free(Plot2); 01061 } 01062 //with minimum image convention 01063 void Matrice::ConvoluteMatrix3(double *Plot,int NGrid){ 01064 double *Plot2 = (double *)calloc(CUBE(NGrid),sizeof(double)); 01065 int NMat2 = (int)pNCol()/2; 01066 printf("NMat2 %d\n",NMat2); 01067 for(int gx=0;gx<NGrid;gx++){ 01068 for(int gy=0;gy<NGrid;gy++){ 01069 for(int gz=0;gz<NGrid;gz++){ 01070 for(int mx=0;mx<pNRow();mx++){ 01071 int g1x = gx + mx - NMat2; 01072 if(g1x >= NGrid) g1x -= NGrid; 01073 if(g1x < 0) g1x += NGrid; 01074 for(int my=0;my<pNCol();my++){ 01075 int g1y = gy + my - NMat2; 01076 if(g1y >= NGrid) g1y -= NGrid; 01077 if(g1y < 0) g1y += NGrid; 01078 for(int mz=0;mz<pNZed();mz++){ 01079 int g1z = gz + mz - NMat2; 01080 if(g1z >= NGrid) g1z -= NGrid; 01081 if(g1z < 0) g1z += NGrid; 01082 Plot2[(gx*NGrid+gy)*NGrid+gz] += Plot[(g1x*NGrid+g1y)*NGrid+g1z]*Val(mx,my,mz); 01083 } 01084 } 01085 } 01086 } 01087 } 01088 } 01089 for(int gx=0;gx<NGrid;gx++){ 01090 for(int gy=0;gy<NGrid;gy++){ 01091 for(int gz=0;gz<NGrid;gz++){ 01092 Plot[(gx*NGrid+gy)*NGrid+gz] = Plot2[(gx*NGrid+gy)*NGrid+gz]; 01093 } 01094 } 01095 } 01096 free(Plot2); 01097 }