Changes in src/vector.cpp [112b09:9d5ddf]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/vector.cpp
r112b09 r9d5ddf 8 8 9 9 #include "vector.hpp" 10 #include "VectorContent.hpp" 10 11 #include "verbose.hpp" 11 12 #include "World.hpp" 12 13 #include "Helpers/Assert.hpp" 13 14 #include "Helpers/fast_functions.hpp" 15 #include "Exceptions/MathException.hpp" 14 16 15 17 #include <iostream> 18 #include <gsl/gsl_blas.h> 19 16 20 17 21 using namespace std; … … 24 28 Vector::Vector() 25 29 { 26 x[0] = x[1] = x[2] = 0.;30 content = new VectorContent(); 27 31 }; 28 32 … … 33 37 Vector::Vector(const Vector& src) 34 38 { 35 x[0] = src[0]; 36 x[1] = src[1]; 37 x[2] = src[2]; 39 content = new VectorContent(); 40 gsl_vector_memcpy(content->content, src.content->content); 38 41 } 39 42 … … 42 45 Vector::Vector(const double x1, const double x2, const double x3) 43 46 { 44 x[0] = x1; 45 x[1] = x2; 46 x[2] = x3; 47 }; 47 content = new VectorContent(); 48 gsl_vector_set(content->content,0,x1); 49 gsl_vector_set(content->content,1,x2); 50 gsl_vector_set(content->content,2,x3); 51 }; 52 53 Vector::Vector(VectorContent *_content) : 54 content(_content) 55 {} 48 56 49 57 /** … … 53 61 // check for self assignment 54 62 if(&src!=this){ 55 x[0] = src[0]; 56 x[1] = src[1]; 57 x[2] = src[2]; 63 gsl_vector_memcpy(content->content, src.content->content); 58 64 } 59 65 return *this; … … 62 68 /** Desctructor of class vector. 63 69 */ 64 Vector::~Vector() {}; 70 Vector::~Vector() { 71 delete content; 72 }; 65 73 66 74 /** Calculates square of distance between this and another vector. … … 72 80 double res = 0.; 73 81 for (int i=NDIM;i--;) 74 res += ( x[i]-y[i])*(x[i]-y[i]);82 res += (at(i)-y[i])*(at(i)-y[i]); 75 83 return (res); 76 84 }; … … 90 98 } 91 99 92 /** Calculates distance between this and another vector in a periodic cell.93 * \param *y array to second vector94 * \param *cell_size 6-dimensional array with (xx, xy, yy, xz, yz, zz) entries specifying the periodic cell95 * \return \f$| x - y |\f$96 */97 double Vector::PeriodicDistance(const Vector &y, const double * const cell_size) const98 {99 double res = distance(y), tmp, matrix[NDIM*NDIM];100 Vector Shiftedy, TranslationVector;101 int N[NDIM];102 matrix[0] = cell_size[0];103 matrix[1] = cell_size[1];104 matrix[2] = cell_size[3];105 matrix[3] = cell_size[1];106 matrix[4] = cell_size[2];107 matrix[5] = cell_size[4];108 matrix[6] = cell_size[3];109 matrix[7] = cell_size[4];110 matrix[8] = cell_size[5];111 // in order to check the periodic distance, translate one of the vectors into each of the 27 neighbouring cells112 for (N[0]=-1;N[0]<=1;N[0]++)113 for (N[1]=-1;N[1]<=1;N[1]++)114 for (N[2]=-1;N[2]<=1;N[2]++) {115 // create the translation vector116 TranslationVector.Zero();117 for (int i=NDIM;i--;)118 TranslationVector[i] = (double)N[i];119 TranslationVector.MatrixMultiplication(matrix);120 // add onto the original vector to compare with121 Shiftedy = y + TranslationVector;122 // get distance and compare with minimum so far123 tmp = distance(Shiftedy);124 if (tmp < res) res = tmp;125 }126 return (res);127 };128 129 /** Calculates distance between this and another vector in a periodic cell.130 * \param *y array to second vector131 * \param *cell_size 6-dimensional array with (xx, xy, yy, xz, yz, zz) entries specifying the periodic cell132 * \return \f$| x - y |^2\f$133 */134 double Vector::PeriodicDistanceSquared(const Vector &y, const double * const cell_size) const135 {136 double res = DistanceSquared(y), tmp, matrix[NDIM*NDIM];137 Vector Shiftedy, TranslationVector;138 int N[NDIM];139 matrix[0] = cell_size[0];140 matrix[1] = cell_size[1];141 matrix[2] = cell_size[3];142 matrix[3] = cell_size[1];143 matrix[4] = cell_size[2];144 matrix[5] = cell_size[4];145 matrix[6] = cell_size[3];146 matrix[7] = cell_size[4];147 matrix[8] = cell_size[5];148 // in order to check the periodic distance, translate one of the vectors into each of the 27 neighbouring cells149 for (N[0]=-1;N[0]<=1;N[0]++)150 for (N[1]=-1;N[1]<=1;N[1]++)151 for (N[2]=-1;N[2]<=1;N[2]++) {152 // create the translation vector153 TranslationVector.Zero();154 for (int i=NDIM;i--;)155 TranslationVector[i] = (double)N[i];156 TranslationVector.MatrixMultiplication(matrix);157 // add onto the original vector to compare with158 Shiftedy = y + TranslationVector;159 // get distance and compare with minimum so far160 tmp = DistanceSquared(Shiftedy);161 if (tmp < res) res = tmp;162 }163 return (res);164 };165 166 /** Keeps the vector in a periodic cell, defined by the symmetric \a *matrix.167 * \param *out ofstream for debugging messages168 * Tries to translate a vector into each adjacent neighbouring cell.169 */170 void Vector::KeepPeriodic(const double * const matrix)171 {172 // int N[NDIM];173 // bool flag = false;174 //vector Shifted, TranslationVector;175 // Log() << Verbose(1) << "Begin of KeepPeriodic." << endl;176 // Log() << Verbose(2) << "Vector is: ";177 // Output(out);178 // Log() << Verbose(0) << endl;179 InverseMatrixMultiplication(matrix);180 for(int i=NDIM;i--;) { // correct periodically181 if (at(i) < 0) { // get every coefficient into the interval [0,1)182 at(i) += ceil(at(i));183 } else {184 at(i) -= floor(at(i));185 }186 }187 MatrixMultiplication(matrix);188 // Log() << Verbose(2) << "New corrected vector is: ";189 // Output(out);190 // Log() << Verbose(0) << endl;191 // Log() << Verbose(1) << "End of KeepPeriodic." << endl;192 };193 194 100 /** Calculates scalar product between this and another vector. 195 101 * \param *y array to second vector … … 199 105 { 200 106 double res = 0.; 201 for (int i=NDIM;i--;) 202 res += x[i]*y[i]; 107 gsl_blas_ddot(content->content, y.content->content, &res); 203 108 return (res); 204 109 }; … … 214 119 { 215 120 Vector tmp; 216 tmp[0] = x[1]* y[2] - x[2]* y[1]; 217 tmp[1] = x[2]* y[0] - x[0]* y[2]; 218 tmp[2] = x[0]* y[1] - x[1]* y[0]; 121 for(int i=NDIM;i--;) 122 tmp[i] = at((i+1)%NDIM)*y[(i+2)%NDIM] - at((i+2)%NDIM)*y[(i+1)%NDIM]; 219 123 (*this) = tmp; 220 124 }; … … 309 213 bool Vector::IsZero() const 310 214 { 311 return (fabs( x[0])+fabs(x[1])+fabs(x[2]) < MYEPSILON);215 return (fabs(at(0))+fabs(at(1))+fabs(at(2)) < MYEPSILON); 312 216 }; 313 217 … … 338 242 bool status = true; 339 243 for (int i=0;i<NDIM;i++) { 340 if (fabs( x[i]- a[i]) > MYEPSILON)244 if (fabs(at(i) - a[i]) > MYEPSILON) 341 245 status = false; 342 246 } … … 366 270 double& Vector::operator[](size_t i){ 367 271 ASSERT(i<=NDIM && i>=0,"Vector Index out of Range"); 368 return x[i];272 return *gsl_vector_ptr (content->content, i); 369 273 } 370 274 371 275 const double& Vector::operator[](size_t i) const{ 372 276 ASSERT(i<=NDIM && i>=0,"Vector Index out of Range"); 373 return x[i];277 return *gsl_vector_ptr (content->content, i); 374 278 } 375 279 … … 382 286 } 383 287 384 double* Vector::get(){385 return x;288 VectorContent* Vector::get(){ 289 return content; 386 290 } 387 291 … … 498 402 { 499 403 for (int i=NDIM;i--;) 500 x[i] *= factor[i]; 501 }; 502 404 at(i) *= factor[i]; 405 }; 406 407 void Vector::ScaleAll(const Vector &factor){ 408 gsl_vector_mul(content->content, factor.content->content); 409 } 503 410 504 411 505 412 void Vector::Scale(const double factor) 506 413 { 507 for (int i=NDIM;i--;) 508 x[i] *= factor; 509 }; 510 511 /** Given a box by its matrix \a *M and its inverse *Minv the vector is made to point within that box. 512 * \param *M matrix of box 513 * \param *Minv inverse matrix 514 */ 515 void Vector::WrapPeriodically(const double * const M, const double * const Minv) 516 { 517 MatrixMultiplication(Minv); 518 // truncate to [0,1] for each axis 519 for (int i=0;i<NDIM;i++) { 520 //x[i] += 0.5; // set to center of box 521 while (x[i] >= 1.) 522 x[i] -= 1.; 523 while (x[i] < 0.) 524 x[i] += 1.; 525 } 526 MatrixMultiplication(M); 414 gsl_vector_scale(content->content,factor); 527 415 }; 528 416 … … 544 432 } 545 433 546 /** Do a matrix multiplication.547 * \param *matrix NDIM_NDIM array548 */549 void Vector::MatrixMultiplication(const double * const M)550 {551 // do the matrix multiplication552 at(0) = M[0]*x[0]+M[3]*x[1]+M[6]*x[2];553 at(1) = M[1]*x[0]+M[4]*x[1]+M[7]*x[2];554 at(2) = M[2]*x[0]+M[5]*x[1]+M[8]*x[2];555 };556 557 /** Do a matrix multiplication with the \a *A' inverse.558 * \param *matrix NDIM_NDIM array559 */560 bool Vector::InverseMatrixMultiplication(const double * const A)561 {562 double B[NDIM*NDIM];563 double detA = RDET3(A);564 double detAReci;565 566 // calculate the inverse B567 if (fabs(detA) > MYEPSILON) {; // RDET3(A) yields precisely zero if A irregular568 detAReci = 1./detA;569 B[0] = detAReci*RDET2(A[4],A[5],A[7],A[8]); // A_11570 B[1] = -detAReci*RDET2(A[1],A[2],A[7],A[8]); // A_12571 B[2] = detAReci*RDET2(A[1],A[2],A[4],A[5]); // A_13572 B[3] = -detAReci*RDET2(A[3],A[5],A[6],A[8]); // A_21573 B[4] = detAReci*RDET2(A[0],A[2],A[6],A[8]); // A_22574 B[5] = -detAReci*RDET2(A[0],A[2],A[3],A[5]); // A_23575 B[6] = detAReci*RDET2(A[3],A[4],A[6],A[7]); // A_31576 B[7] = -detAReci*RDET2(A[0],A[1],A[6],A[7]); // A_32577 B[8] = detAReci*RDET2(A[0],A[1],A[3],A[4]); // A_33578 579 // do the matrix multiplication580 at(0) = B[0]*x[0]+B[3]*x[1]+B[6]*x[2];581 at(1) = B[1]*x[0]+B[4]*x[1]+B[7]*x[2];582 at(2) = B[2]*x[0]+B[5]*x[1]+B[8]*x[2];583 584 return true;585 } else {586 return false;587 }588 };589 590 591 434 /** Creates this vector as the b y *factors' components scaled linear combination of the given three. 592 435 * this vector = x1*factors[0] + x2* factors[1] + x3*factors[2] … … 616 459 SubtractVector(x1); 617 460 for (int i=NDIM;i--;) 618 result = result || (fabs( x[i]) > MYEPSILON);461 result = result || (fabs(at(i)) > MYEPSILON); 619 462 620 463 return result; … … 677 520 void Vector::AddVector(const Vector &y) 678 521 { 679 for(int i=NDIM;i--;) 680 x[i] += y[i]; 522 gsl_vector_add(content->content, y.content->content); 681 523 } 682 524 … … 686 528 void Vector::SubtractVector(const Vector &y) 687 529 { 688 for(int i=NDIM;i--;) 689 x[i] -= y[i]; 690 } 691 692 /** 693 * Checks whether this vector is within the parallelepiped defined by the given three vectors and 694 * their offset. 695 * 696 * @param offest for the origin of the parallelepiped 697 * @param three vectors forming the matrix that defines the shape of the parallelpiped 698 */ 699 bool Vector::IsInParallelepiped(const Vector &offset, const double * const parallelepiped) const 700 { 701 Vector a = (*this)-offset; 702 a.InverseMatrixMultiplication(parallelepiped); 703 bool isInside = true; 704 705 for (int i=NDIM;i--;) 706 isInside = isInside && ((a[i] <= 1) && (a[i] >= 0)); 707 708 return isInside; 530 gsl_vector_sub(content->content, y.content->content); 709 531 } 710 532
Note:
See TracChangeset
for help on using the changeset viewer.