Changeset e0c5b1 for molecuilder/src/vector.cpp
- Timestamp:
- Dec 3, 2008, 2:12:05 PM (17 years ago)
- Children:
- 3e20fe
- Parents:
- f5b58e
- File:
-
- 1 edited
-
molecuilder/src/vector.cpp (modified) (34 diffs)
Legend:
- Unmodified
- Added
- Removed
-
molecuilder/src/vector.cpp
rf5b58e re0c5b1 1 1 /** \file vector.cpp 2 * 2 * 3 3 * Function implementations for the class vector. 4 * 5 */ 6 4 * 5 */ 6 7 7 #include "molecules.hpp" 8 8 9 9 10 10 /************************************ Functions for class vector ************************************/ … … 31 31 for (int i=NDIM;i--;) 32 32 res += (x[i]-y->x[i])*(x[i]-y->x[i]); 33 return (res); 33 return (res); 34 34 }; 35 35 … … 69 69 if (tmp < res) res = tmp; 70 70 } 71 return (res); 71 return (res); 72 72 }; 73 73 … … 112 112 for (int i=NDIM;i--;) 113 113 res += x[i]*y->x[i]; 114 return (res); 114 return (res); 115 115 }; 116 116 … … 121 121 * \param *y array to vector with which to calculate crossproduct 122 122 * \return \f$ x \times y \f& 123 */ 123 */ 124 124 void Vector::VectorProduct(const Vector *y) 125 125 { 126 126 Vector tmp; 127 tmp [0] = x[1]*y->x[2] - x[2]*y->x[1];128 tmp [1] = x[2]*y->x[0] - x[0]*y->x[2];129 tmp [2] = x[0]*y->x[1] - x[1]*Y->x[0];127 tmp.x[0] = x[1]* (y->x[2]) - x[2]* (y->x[1]); 128 tmp.x[1] = x[2]* (y->x[0]) - x[0]* (y->x[2]); 129 tmp.x[2] = x[0]* (y->x[1]) - x[1]* (y->x[0]); 130 130 this->CopyVector(&tmp); 131 131 … … 134 134 135 135 /** projects this vector onto plane defined by \a *y. 136 * \param *y array tonormal vector of plane136 * \param *y normal vector of plane 137 137 * \return \f$\langle x, y \rangle\f$ 138 138 */ … … 141 141 Vector tmp; 142 142 tmp.CopyVector(y); 143 tmp.Scale(Projection(y)); 143 tmp.Normalize(); 144 tmp.Scale(ScalarProduct(&tmp)); 144 145 this->SubtractVector(&tmp); 145 146 }; … … 162 163 for (int i=NDIM;i--;) 163 164 res += this->x[i]*this->x[i]; 164 return (sqrt(res)); 165 return (sqrt(res)); 165 166 }; 166 167 … … 196 197 */ 197 198 void Vector::Init(double x1, double x2, double x3) 198 { 199 { 199 200 x[0] = x1; 200 201 x[1] = x2; … … 202 203 }; 203 204 204 /** Calculates the angle between this and another vector. 205 /** Calculates the angle between this and another vector. 205 206 * \param *y array to second vector 206 207 * \return \f$\acos\bigl(frac{\langle x, y \rangle}{|x||y|}\bigr)\f$ … … 208 209 double Vector::Angle(Vector *y) const 209 210 { 210 return acos(this->ScalarProduct(y)/Norm()/y->Norm()); 211 return acos(this->ScalarProduct(y)/Norm()/y->Norm()); 211 212 }; 212 213 … … 256 257 257 258 /** Sums two vectors \a and \b component-wise. 258 * \param a first vector 259 * \param a first vector 259 260 * \param b second vector 260 261 * \return a + b … … 269 270 270 271 /** Factors given vector \a a times \a m. 271 * \param a vector 272 * \param a vector 272 273 * \param m factor 273 274 * \return a + b … … 327 328 }; 328 329 329 /** Translate atom by given vector. 330 /** Translate atom by given vector. 330 331 * \param trans[] translation vector. 331 332 */ … … 334 335 for (int i=NDIM;i--;) 335 336 x[i] += trans->x[i]; 336 }; 337 }; 337 338 338 339 /** Do a matrix multiplication. … … 373 374 B[7] = -detAReci*RDET2(A[0],A[1],A[6],A[7]); // A_32 374 375 B[8] = detAReci*RDET2(A[0],A[1],A[3],A[4]); // A_33 375 376 376 377 // do the matrix multiplication 377 378 C.x[0] = B[0]*x[0]+B[3]*x[1]+B[6]*x[2]; … … 397 398 { 398 399 for(int i=NDIM;i--;) 399 x[i] = factors[0]*x1->x[i] + factors[1]*x2->x[i] + factors[2]*x3->x[i]; 400 }; 401 402 /** Mirrors atom against a given plane. 400 x[i] = factors[0]*x1->x[i] + factors[1]*x2->x[i] + factors[2]*x3->x[i]; 401 }; 402 403 /** Mirrors atom against a given plane. 403 404 * \param n[] normal vector of mirror plane. 404 405 */ … … 416 417 Output((ofstream *)&cout); 417 418 cout << endl; 418 }; 419 }; 419 420 420 421 /** Calculates normal vector for three given vectors (being three points in space). … … 448 449 this->x[2] = (x1.x[0]*x2.x[1] - x1.x[1]*x2.x[0]); 449 450 Normalize(); 450 451 451 452 return true; 452 453 }; … … 506 507 /** Creates this vector as one of the possible orthonormal ones to the given one. 507 508 * Just scan how many components of given *vector are unequal to zero and 508 * try to get the skp of both to be zero accordingly. 509 * try to get the skp of both to be zero accordingly. 509 510 * \param *vector given vector 510 511 * \return true - success, false - failure (null vector given) … … 527 528 Components[Last++] = j; 528 529 cout << Verbose(4) << Last << " Components != 0: (" << Components[0] << "," << Components[1] << "," << Components[2] << ")" << endl; 529 530 530 531 switch(Last) { 531 532 case 3: // threecomponent system … … 540 541 case 1: // one component system 541 542 // set sole non-zero component to 0, and one of the other zero component pendants to 1 542 x[(Components[0]+2)%NDIM] = 0.; 543 x[(Components[0]+1)%NDIM] = 1.; 544 x[Components[0]] = 0.; 543 x[(Components[0]+2)%NDIM] = 0.; 544 x[(Components[0]+1)%NDIM] = 1.; 545 x[Components[0]] = 0.; 545 546 return true; 546 547 break; … … 559 560 { 560 561 // cout << Verbose(3) << "For comparison: "; 561 // cout << "A " << A->Projection(this) << "\t"; 562 // cout << "B " << B->Projection(this) << "\t"; 563 // cout << "C " << C->Projection(this) << "\t"; 562 // cout << "A " << A->Projection(this) << "\t"; 563 // cout << "B " << B->Projection(this) << "\t"; 564 // cout << "C " << C->Projection(this) << "\t"; 564 565 // cout << endl; 565 566 return A->Projection(this); … … 571 572 * \return true if success, false if failed due to linear dependency 572 573 */ 573 bool Vector::LSQdistance(Vector **vectors, int num) 574 bool Vector::LSQdistance(Vector **vectors, int num) 574 575 { 575 576 int j; 576 577 577 578 for (j=0;j<num;j++) { 578 579 cout << Verbose(1) << j << "th atom's vector: "; … … 583 584 int np = 3; 584 585 struct LSQ_params par; 585 586 586 587 const gsl_multimin_fminimizer_type *T = 587 588 gsl_multimin_fminimizer_nmsimplex; … … 589 590 gsl_vector *ss, *y; 590 591 gsl_multimin_function minex_func; 591 592 592 593 size_t iter = 0, i; 593 594 int status; 594 595 double size; 595 596 596 597 /* Initial vertex size vector */ 597 598 ss = gsl_vector_alloc (np); 598 599 y = gsl_vector_alloc (np); 599 600 600 601 /* Set all step sizes to 1 */ 601 602 gsl_vector_set_all (ss, 1.0); 602 603 603 604 /* Starting point */ 604 605 par.vectors = vectors; 605 606 par.num = num; 606 607 607 608 for (i=NDIM;i--;) 608 gsl_vector_set(y, i, (vectors[0]->x[i] - vectors[1]->x[i])/2.); 609 609 gsl_vector_set(y, i, (vectors[0]->x[i] - vectors[1]->x[i])/2.); 610 610 611 /* Initialize method and iterate */ 611 612 minex_func.f = &LSQ; 612 613 minex_func.n = np; 613 614 minex_func.params = (void *)∥ 614 615 615 616 s = gsl_multimin_fminimizer_alloc (T, np); 616 617 gsl_multimin_fminimizer_set (s, &minex_func, y, ss); 617 618 618 619 do 619 620 { 620 621 iter++; 621 622 status = gsl_multimin_fminimizer_iterate(s); 622 623 623 624 if (status) 624 625 break; 625 626 626 627 size = gsl_multimin_fminimizer_size (s); 627 628 status = gsl_multimin_test_size (size, 1e-2); 628 629 629 630 if (status == GSL_SUCCESS) 630 631 { 631 632 printf ("converged to minimum at\n"); 632 633 } 633 634 634 635 printf ("%5d ", (int)iter); 635 636 for (i = 0; i < (size_t)np; i++) … … 640 641 } 641 642 while (status == GSL_CONTINUE && iter < 100); 642 643 643 644 for (i=(size_t)np;i--;) 644 645 this->x[i] = gsl_vector_get(s->x, i); … … 706 707 * \param alpha first angle 707 708 * \param beta second angle 708 * \param c norm of final vector 709 * \param c norm of final vector 709 710 * \return a vector with \f$\langle x1,x2 \rangle=A\f$, \f$\langle x1,y \rangle = B\f$ and with norm \a c. 710 * \bug this is not yet working properly 711 * \bug this is not yet working properly 711 712 */ 712 713 bool Vector::SolveSystem(Vector *x1, Vector *x2, Vector *y, double alpha, double beta, double c) … … 724 725 if (fabs(x1->x[0]) < MYEPSILON) { // check for zero components for the later flipping and back-flipping 725 726 if (fabs(x1->x[1]) > MYEPSILON) { 726 flag = 1; 727 flag = 1; 727 728 } else if (fabs(x1->x[2]) > MYEPSILON) { 728 729 flag = 2; … … 757 758 // now comes the case system 758 759 D1 = -y->x[0]/x1->x[0]*x1->x[1]+y->x[1]; 759 D2 = -y->x[0]/x1->x[0]*x1->x[2]+y->x[2]; 760 D2 = -y->x[0]/x1->x[0]*x1->x[2]+y->x[2]; 760 761 D3 = y->x[0]/x1->x[0]*A-B1; 761 762 cout << Verbose(2) << "D1 " << D1 << "\tD2 " << D2 << "\tD3 " << D3 << "\n"; 762 763 if (fabs(D1) < MYEPSILON) { 763 cout << Verbose(2) << "D1 == 0!\n"; 764 cout << Verbose(2) << "D1 == 0!\n"; 764 765 if (fabs(D2) > MYEPSILON) { 765 cout << Verbose(3) << "D2 != 0!\n"; 766 cout << Verbose(3) << "D2 != 0!\n"; 766 767 x[2] = -D3/D2; 767 768 E1 = A/x1->x[0] + x1->x[2]/x1->x[0]*D3/D2; … … 773 774 cout << Verbose(3) << "F1 " << F1 << "\tF2 " << F2 << "\tF3 " << F3 << "\n"; 774 775 if (fabs(F1) < MYEPSILON) { 775 cout << Verbose(4) << "F1 == 0!\n"; 776 cout << Verbose(4) << "F1 == 0!\n"; 776 777 cout << Verbose(4) << "Gleichungssystem linear\n"; 777 x[1] = F3/(2.*F2); 778 x[1] = F3/(2.*F2); 778 779 } else { 779 780 p = F2/F1; 780 781 q = p*p - F3/F1; 781 cout << Verbose(4) << "p " << p << "\tq " << q << endl; 782 cout << Verbose(4) << "p " << p << "\tq " << q << endl; 782 783 if (q < 0) { 783 784 cout << Verbose(4) << "q < 0" << endl; … … 800 801 cout << Verbose(2) << "F1 " << F1 << "\tF2 " << F2 << "\tF3 " << F3 << "\n"; 801 802 if (fabs(F1) < MYEPSILON) { 802 cout << Verbose(3) << "F1 == 0!\n"; 803 cout << Verbose(3) << "F1 == 0!\n"; 803 804 cout << Verbose(3) << "Gleichungssystem linear\n"; 804 x[2] = F3/(2.*F2); 805 x[2] = F3/(2.*F2); 805 806 } else { 806 807 p = F2/F1; 807 808 q = p*p - F3/F1; 808 cout << Verbose(3) << "p " << p << "\tq " << q << endl; 809 cout << Verbose(3) << "p " << p << "\tq " << q << endl; 809 810 if (q < 0) { 810 811 cout << Verbose(3) << "q < 0" << endl; … … 850 851 } 851 852 cout << Verbose(2) << i << ": sign matrix is " << sign[0] << "\t" << sign[1] << "\t" << sign[2] << "\n"; 852 // apply sign matrix 853 // apply sign matrix 853 854 for (j=NDIM;j--;) 854 855 x[j] *= sign[j]; … … 856 857 ang = x2->Angle (this); 857 858 cout << Verbose(1) << i << "th angle " << ang << "\tbeta " << cos(beta) << " :\t"; 858 if (fabs(ang - cos(beta)) < MYEPSILON) { 859 if (fabs(ang - cos(beta)) < MYEPSILON) { 859 860 break; 860 861 }
Note:
See TracChangeset
for help on using the changeset viewer.
