Changes in src/vector.cpp [ce5ac3:042f82]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/vector.cpp
rce5ac3 r042f82 49 49 * \param *y array to second vector 50 50 * \param *cell_size 6-dimensional array with (xx, xy, yy, xz, yz, zz) entries specifying the periodic cell 51 * \return \f$| x - y | ^2\f$51 * \return \f$| x - y |\f$ 52 52 */ 53 53 double Vector::PeriodicDistance(const Vector *y, const double *cell_size) const … … 84 84 }; 85 85 86 /** Calculates distance between this and another vector in a periodic cell. 87 * \param *y array to second vector 88 * \param *cell_size 6-dimensional array with (xx, xy, yy, xz, yz, zz) entries specifying the periodic cell 89 * \return \f$| x - y |^2\f$ 90 */ 91 double Vector::PeriodicDistanceSquared(const Vector *y, const double *cell_size) const 92 { 93 double res = DistanceSquared(y), tmp, matrix[NDIM*NDIM]; 94 Vector Shiftedy, TranslationVector; 95 int N[NDIM]; 96 matrix[0] = cell_size[0]; 97 matrix[1] = cell_size[1]; 98 matrix[2] = cell_size[3]; 99 matrix[3] = cell_size[1]; 100 matrix[4] = cell_size[2]; 101 matrix[5] = cell_size[4]; 102 matrix[6] = cell_size[3]; 103 matrix[7] = cell_size[4]; 104 matrix[8] = cell_size[5]; 105 // in order to check the periodic distance, translate one of the vectors into each of the 27 neighbouring cells 106 for (N[0]=-1;N[0]<=1;N[0]++) 107 for (N[1]=-1;N[1]<=1;N[1]++) 108 for (N[2]=-1;N[2]<=1;N[2]++) { 109 // create the translation vector 110 TranslationVector.Zero(); 111 for (int i=NDIM;i--;) 112 TranslationVector.x[i] = (double)N[i]; 113 TranslationVector.MatrixMultiplication(matrix); 114 // add onto the original vector to compare with 115 Shiftedy.CopyVector(y); 116 Shiftedy.AddVector(&TranslationVector); 117 // get distance and compare with minimum so far 118 tmp = DistanceSquared(&Shiftedy); 119 if (tmp < res) res = tmp; 120 } 121 return (res); 122 }; 123 86 124 /** Keeps the vector in a periodic cell, defined by the symmetric \a *matrix. 87 125 * \param *out ofstream for debugging messages … … 221 259 double Vector::Angle(const Vector *y) const 222 260 { 223 return acos(this->ScalarProduct(y)/Norm()/y->Norm()); 261 double angle = this->ScalarProduct(y)/Norm()/y->Norm(); 262 // -1-MYEPSILON occured due to numerical imprecision, catch ... 263 //cout << Verbose(2) << "INFO: acos(-1) = " << acos(-1) << ", acos(-1+MYEPSILON) = " << acos(-1+MYEPSILON) << ", acos(-1-MYEPSILON) = " << acos(-1-MYEPSILON) << "." << endl; 264 if (angle < -1) 265 angle = -1; 266 if (angle > 1) 267 angle = 1; 268 return acos(angle); 224 269 }; 225 270 … … 313 358 }; 314 359 315 /** Prints a 3dim vector to a stream.316 * \param ost output stream317 * \param v Vector to be printed318 * \return output stream319 */320 360 ostream& operator<<(ostream& ost,Vector& m) 321 361 { … … 375 415 }; 376 416 377 /** Do a matrix multiplication with \a *matrix' inverse.417 /** Calculate the inverse of a 3x3 matrix. 378 418 * \param *matrix NDIM_NDIM array 379 419 */ 380 void Vector::InverseMatrixMultiplication(double *A) 381 { 382 Vector C; 383 double B[NDIM*NDIM]; 420 double * Vector::InverseMatrix(double *A) 421 { 422 double *B = (double *) Malloc(sizeof(double)*NDIM*NDIM, "Vector::InverseMatrix: *B"); 384 423 double detA = RDET3(A); 385 424 double detAReci; 386 425 426 for (int i=0;i<NDIM*NDIM;++i) 427 B[i] = 0.; 387 428 // calculate the inverse B 388 429 if (fabs(detA) > MYEPSILON) {; // RDET3(A) yields precisely zero if A irregular … … 397 438 B[7] = -detAReci*RDET2(A[0],A[1],A[6],A[7]); // A_32 398 439 B[8] = detAReci*RDET2(A[0],A[1],A[3],A[4]); // A_33 440 } 441 return B; 442 }; 443 444 /** Do a matrix multiplication with \a *matrix' inverse. 445 * \param *matrix NDIM_NDIM array 446 */ 447 void Vector::InverseMatrixMultiplication(double *A) 448 { 449 Vector C; 450 double B[NDIM*NDIM]; 451 double detA = RDET3(A); 452 double detAReci; 453 454 // calculate the inverse B 455 if (fabs(detA) > MYEPSILON) {; // RDET3(A) yields precisely zero if A irregular 456 detAReci = 1./detA; 457 B[0] = detAReci*RDET2(A[4],A[5],A[7],A[8]); // A_11 458 B[1] = -detAReci*RDET2(A[1],A[2],A[7],A[8]); // A_12 459 B[2] = detAReci*RDET2(A[1],A[2],A[4],A[5]); // A_13 460 B[3] = -detAReci*RDET2(A[3],A[5],A[6],A[8]); // A_21 461 B[4] = detAReci*RDET2(A[0],A[2],A[6],A[8]); // A_22 462 B[5] = -detAReci*RDET2(A[0],A[2],A[3],A[5]); // A_23 463 B[6] = detAReci*RDET2(A[3],A[4],A[6],A[7]); // A_31 464 B[7] = -detAReci*RDET2(A[0],A[1],A[6],A[7]); // A_32 465 B[8] = detAReci*RDET2(A[0],A[1],A[3],A[4]); // A_33 399 466 400 467 // do the matrix multiplication … … 457 524 x2.CopyVector(y3); 458 525 x2.SubtractVector(y2); 459 if (( x1.Norm()==0) || (x2.Norm()==0)) {526 if ((fabs(x1.Norm()) < MYEPSILON) || (fabs(x2.Norm()) < MYEPSILON) || (fabs(x1.Angle(&x2)) < MYEPSILON)) { 460 527 cout << Verbose(4) << "Given vectors are linear dependent." << endl; 461 528 return false; … … 491 558 x2.CopyVector(y2); 492 559 Zero(); 493 if (( x1.Norm()==0) || (x2.Norm()==0)) {560 if ((fabs(x1.Norm()) < MYEPSILON) || (fabs(x2.Norm()) < MYEPSILON) || (fabs(x1.Angle(&x2)) < MYEPSILON)) { 494 561 cout << Verbose(4) << "Given vectors are linear dependent." << endl; 495 562 return false;
Note:
See TracChangeset
for help on using the changeset viewer.