Changes in src/vector.cpp [4b94bb:112b09]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/vector.cpp
r4b94bb r112b09 12 12 #include "Helpers/Assert.hpp" 13 13 #include "Helpers/fast_functions.hpp" 14 #include "Exceptions/MathException.hpp"15 14 16 15 #include <iostream> 17 #include <gsl/gsl_blas.h>18 19 16 20 17 using namespace std; … … 27 24 Vector::Vector() 28 25 { 29 content = gsl_vector_calloc (NDIM);26 x[0] = x[1] = x[2] = 0.; 30 27 }; 31 28 … … 36 33 Vector::Vector(const Vector& src) 37 34 { 38 content = gsl_vector_alloc(NDIM); 39 gsl_vector_memcpy(content, src.content); 35 x[0] = src[0]; 36 x[1] = src[1]; 37 x[2] = src[2]; 40 38 } 41 39 … … 44 42 Vector::Vector(const double x1, const double x2, const double x3) 45 43 { 46 content = gsl_vector_alloc(NDIM); 47 gsl_vector_set(content,0,x1); 48 gsl_vector_set(content,1,x2); 49 gsl_vector_set(content,2,x3); 50 }; 51 52 Vector::Vector(gsl_vector *_content) : 53 content(_content) 54 {} 44 x[0] = x1; 45 x[1] = x2; 46 x[2] = x3; 47 }; 55 48 56 49 /** … … 60 53 // check for self assignment 61 54 if(&src!=this){ 62 gsl_vector_memcpy(content, src.content); 55 x[0] = src[0]; 56 x[1] = src[1]; 57 x[2] = src[2]; 63 58 } 64 59 return *this; … … 67 62 /** Desctructor of class vector. 68 63 */ 69 Vector::~Vector() { 70 gsl_vector_free(content); 71 }; 64 Vector::~Vector() {}; 72 65 73 66 /** Calculates square of distance between this and another vector. … … 79 72 double res = 0.; 80 73 for (int i=NDIM;i--;) 81 res += ( at(i)-y[i])*(at(i)-y[i]);74 res += (x[i]-y[i])*(x[i]-y[i]); 82 75 return (res); 83 76 }; … … 97 90 } 98 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 99 194 /** Calculates scalar product between this and another vector. 100 195 * \param *y array to second vector … … 104 199 { 105 200 double res = 0.; 106 gsl_blas_ddot(content, y.content, &res); 201 for (int i=NDIM;i--;) 202 res += x[i]*y[i]; 107 203 return (res); 108 204 }; … … 118 214 { 119 215 Vector tmp; 120 for(int i=NDIM;i--;) 121 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]; 122 219 (*this) = tmp; 123 220 }; … … 212 309 bool Vector::IsZero() const 213 310 { 214 return (fabs( at(0))+fabs(at(1))+fabs(at(2)) < MYEPSILON);311 return (fabs(x[0])+fabs(x[1])+fabs(x[2]) < MYEPSILON); 215 312 }; 216 313 … … 241 338 bool status = true; 242 339 for (int i=0;i<NDIM;i++) { 243 if (fabs( at(i)- a[i]) > MYEPSILON)340 if (fabs(x[i] - a[i]) > MYEPSILON) 244 341 status = false; 245 342 } … … 269 366 double& Vector::operator[](size_t i){ 270 367 ASSERT(i<=NDIM && i>=0,"Vector Index out of Range"); 271 return *gsl_vector_ptr (content, i);368 return x[i]; 272 369 } 273 370 274 371 const double& Vector::operator[](size_t i) const{ 275 372 ASSERT(i<=NDIM && i>=0,"Vector Index out of Range"); 276 return *gsl_vector_ptr (content, i);373 return x[i]; 277 374 } 278 375 … … 285 382 } 286 383 287 gsl_vector* Vector::get(){288 return content;384 double* Vector::get(){ 385 return x; 289 386 } 290 387 … … 401 498 { 402 499 for (int i=NDIM;i--;) 403 at(i) *= factor[i]; 404 }; 405 406 void Vector::ScaleAll(const Vector &factor){ 407 gsl_vector_mul(content, factor.content); 408 } 500 x[i] *= factor[i]; 501 }; 502 409 503 410 504 411 505 void Vector::Scale(const double factor) 412 506 { 413 gsl_vector_scale(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); 414 527 }; 415 528 … … 431 544 } 432 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 433 591 /** Creates this vector as the b y *factors' components scaled linear combination of the given three. 434 592 * this vector = x1*factors[0] + x2* factors[1] + x3*factors[2] … … 458 616 SubtractVector(x1); 459 617 for (int i=NDIM;i--;) 460 result = result || (fabs( at(i)) > MYEPSILON);618 result = result || (fabs(x[i]) > MYEPSILON); 461 619 462 620 return result; … … 519 677 void Vector::AddVector(const Vector &y) 520 678 { 521 gsl_vector_add(content, y.content); 679 for(int i=NDIM;i--;) 680 x[i] += y[i]; 522 681 } 523 682 … … 527 686 void Vector::SubtractVector(const Vector &y) 528 687 { 529 gsl_vector_sub(content, y.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; 530 709 } 531 710
Note:
See TracChangeset
for help on using the changeset viewer.