Changes in src/vector.cpp [9d5ddf:112b09]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/vector.cpp
r9d5ddf r112b09 8 8 9 9 #include "vector.hpp" 10 #include "VectorContent.hpp"11 10 #include "verbose.hpp" 12 11 #include "World.hpp" 13 12 #include "Helpers/Assert.hpp" 14 13 #include "Helpers/fast_functions.hpp" 15 #include "Exceptions/MathException.hpp"16 14 17 15 #include <iostream> 18 #include <gsl/gsl_blas.h>19 20 16 21 17 using namespace std; … … 28 24 Vector::Vector() 29 25 { 30 content = new VectorContent();26 x[0] = x[1] = x[2] = 0.; 31 27 }; 32 28 … … 37 33 Vector::Vector(const Vector& src) 38 34 { 39 content = new VectorContent(); 40 gsl_vector_memcpy(content->content, src.content->content); 35 x[0] = src[0]; 36 x[1] = src[1]; 37 x[2] = src[2]; 41 38 } 42 39 … … 45 42 Vector::Vector(const double x1, const double x2, const double x3) 46 43 { 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 {} 44 x[0] = x1; 45 x[1] = x2; 46 x[2] = x3; 47 }; 56 48 57 49 /** … … 61 53 // check for self assignment 62 54 if(&src!=this){ 63 gsl_vector_memcpy(content->content, src.content->content); 55 x[0] = src[0]; 56 x[1] = src[1]; 57 x[2] = src[2]; 64 58 } 65 59 return *this; … … 68 62 /** Desctructor of class vector. 69 63 */ 70 Vector::~Vector() { 71 delete content; 72 }; 64 Vector::~Vector() {}; 73 65 74 66 /** Calculates square of distance between this and another vector. … … 80 72 double res = 0.; 81 73 for (int i=NDIM;i--;) 82 res += ( at(i)-y[i])*(at(i)-y[i]);74 res += (x[i]-y[i])*(x[i]-y[i]); 83 75 return (res); 84 76 }; … … 98 90 } 99 91 92 /** Calculates distance between this and another vector in a periodic cell. 93 * \param *y array to second vector 94 * \param *cell_size 6-dimensional array with (xx, xy, yy, xz, yz, zz) entries specifying the periodic cell 95 * \return \f$| x - y |\f$ 96 */ 97 double Vector::PeriodicDistance(const Vector &y, const double * const cell_size) const 98 { 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 cells 112 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 vector 116 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 with 121 Shiftedy = y + TranslationVector; 122 // get distance and compare with minimum so far 123 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 vector 131 * \param *cell_size 6-dimensional array with (xx, xy, yy, xz, yz, zz) entries specifying the periodic cell 132 * \return \f$| x - y |^2\f$ 133 */ 134 double Vector::PeriodicDistanceSquared(const Vector &y, const double * const cell_size) const 135 { 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 cells 149 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 vector 153 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 with 158 Shiftedy = y + TranslationVector; 159 // get distance and compare with minimum so far 160 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 messages 168 * 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 periodically 181 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 100 194 /** Calculates scalar product between this and another vector. 101 195 * \param *y array to second vector … … 105 199 { 106 200 double res = 0.; 107 gsl_blas_ddot(content->content, y.content->content, &res); 201 for (int i=NDIM;i--;) 202 res += x[i]*y[i]; 108 203 return (res); 109 204 }; … … 119 214 { 120 215 Vector tmp; 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]; 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]; 123 219 (*this) = tmp; 124 220 }; … … 213 309 bool Vector::IsZero() const 214 310 { 215 return (fabs( at(0))+fabs(at(1))+fabs(at(2)) < MYEPSILON);311 return (fabs(x[0])+fabs(x[1])+fabs(x[2]) < MYEPSILON); 216 312 }; 217 313 … … 242 338 bool status = true; 243 339 for (int i=0;i<NDIM;i++) { 244 if (fabs( at(i)- a[i]) > MYEPSILON)340 if (fabs(x[i] - a[i]) > MYEPSILON) 245 341 status = false; 246 342 } … … 270 366 double& Vector::operator[](size_t i){ 271 367 ASSERT(i<=NDIM && i>=0,"Vector Index out of Range"); 272 return *gsl_vector_ptr (content->content, i);368 return x[i]; 273 369 } 274 370 275 371 const double& Vector::operator[](size_t i) const{ 276 372 ASSERT(i<=NDIM && i>=0,"Vector Index out of Range"); 277 return *gsl_vector_ptr (content->content, i);373 return x[i]; 278 374 } 279 375 … … 286 382 } 287 383 288 VectorContent* Vector::get(){289 return content;384 double* Vector::get(){ 385 return x; 290 386 } 291 387 … … 402 498 { 403 499 for (int i=NDIM;i--;) 404 at(i) *= factor[i]; 405 }; 406 407 void Vector::ScaleAll(const Vector &factor){ 408 gsl_vector_mul(content->content, factor.content->content); 409 } 500 x[i] *= factor[i]; 501 }; 502 410 503 411 504 412 505 void Vector::Scale(const double factor) 413 506 { 414 gsl_vector_scale(content->content,factor); 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); 415 527 }; 416 528 … … 432 544 } 433 545 546 /** Do a matrix multiplication. 547 * \param *matrix NDIM_NDIM array 548 */ 549 void Vector::MatrixMultiplication(const double * const M) 550 { 551 // do the matrix multiplication 552 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 array 559 */ 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 B 567 if (fabs(detA) > MYEPSILON) {; // RDET3(A) yields precisely zero if A irregular 568 detAReci = 1./detA; 569 B[0] = detAReci*RDET2(A[4],A[5],A[7],A[8]); // A_11 570 B[1] = -detAReci*RDET2(A[1],A[2],A[7],A[8]); // A_12 571 B[2] = detAReci*RDET2(A[1],A[2],A[4],A[5]); // A_13 572 B[3] = -detAReci*RDET2(A[3],A[5],A[6],A[8]); // A_21 573 B[4] = detAReci*RDET2(A[0],A[2],A[6],A[8]); // A_22 574 B[5] = -detAReci*RDET2(A[0],A[2],A[3],A[5]); // A_23 575 B[6] = detAReci*RDET2(A[3],A[4],A[6],A[7]); // A_31 576 B[7] = -detAReci*RDET2(A[0],A[1],A[6],A[7]); // A_32 577 B[8] = detAReci*RDET2(A[0],A[1],A[3],A[4]); // A_33 578 579 // do the matrix multiplication 580 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 434 591 /** Creates this vector as the b y *factors' components scaled linear combination of the given three. 435 592 * this vector = x1*factors[0] + x2* factors[1] + x3*factors[2] … … 459 616 SubtractVector(x1); 460 617 for (int i=NDIM;i--;) 461 result = result || (fabs( at(i)) > MYEPSILON);618 result = result || (fabs(x[i]) > MYEPSILON); 462 619 463 620 return result; … … 520 677 void Vector::AddVector(const Vector &y) 521 678 { 522 gsl_vector_add(content->content, y.content->content); 679 for(int i=NDIM;i--;) 680 x[i] += y[i]; 523 681 } 524 682 … … 528 686 void Vector::SubtractVector(const Vector &y) 529 687 { 530 gsl_vector_sub(content->content, y.content->content); 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; 531 709 } 532 710
Note:
See TracChangeset
for help on using the changeset viewer.