Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/vector.cpp

    • Property mode changed from 100644 to 100755
    r2985c8 rcc2ee5  
    11/** \file vector.cpp
    2  * 
     2 *
    33 * Function implementations for the class vector.
    4  * 
    5  */
    6  
     4 *
     5 */
     6
    77#include "molecules.hpp"
    8  
     8
    99
    1010/************************************ Functions for class vector ************************************/
     
    2121 */
    2222Vector::~Vector() {};
     23
     24/** Calculates square of distance between this and another vector.
     25 * \param *y array to second vector
     26 * \return \f$| x - y |^2\f$
     27 */
     28double Vector::DistanceSquared(const Vector *y) const
     29{
     30  double res = 0.;
     31  for (int i=NDIM;i--;)
     32    res += (x[i]-y->x[i])*(x[i]-y->x[i]);
     33  return (res);
     34};
    2335
    2436/** Calculates distance between this and another vector.
    2537 * \param *y array to second vector
    26  * \return \f$| x - y |^2\f$
     38 * \return \f$| x - y |\f$
    2739 */
    2840double Vector::Distance(const Vector *y) const
     
    3143  for (int i=NDIM;i--;)
    3244    res += (x[i]-y->x[i])*(x[i]-y->x[i]);
    33   return (res); 
     45  return (sqrt(res));
    3446};
    3547
     
    6981        if (tmp < res) res = tmp;
    7082      }
    71   return (res); 
     83  return (res);
    7284};
    7385
     
    112124  for (int i=NDIM;i--;)
    113125    res += x[i]*y->x[i];
    114   return (res); 
    115 };
     126  return (res);
     127};
     128
     129
     130/** Calculates VectorProduct between this and another vector.
     131 *  -# returns the Product in place of vector from which it was initiated
     132 *  -# ATTENTION: Only three dim.
     133 *  \param *y array to vector with which to calculate crossproduct
     134 *  \return \f$ x \times y \f&
     135 */
     136void Vector::VectorProduct(const Vector *y)
     137{
     138  Vector tmp;
     139  tmp.x[0] = x[1]* (y->x[2]) - x[2]* (y->x[1]);
     140  tmp.x[1] = x[2]* (y->x[0]) - x[0]* (y->x[2]);
     141  tmp.x[2] = x[0]* (y->x[1]) - x[1]* (y->x[0]);
     142  this->CopyVector(&tmp);
     143
     144};
     145
    116146
    117147/** projects this vector onto plane defined by \a *y.
    118  * \param *y array to normal vector of plane
     148 * \param *y normal vector of plane
    119149 * \return \f$\langle x, y \rangle\f$
    120150 */
     
    123153  Vector tmp;
    124154  tmp.CopyVector(y);
    125   tmp.Scale(Projection(y));
     155  tmp.Normalize();
     156  tmp.Scale(ScalarProduct(&tmp));
    126157  this->SubtractVector(&tmp);
    127158};
     
    144175  for (int i=NDIM;i--;)
    145176    res += this->x[i]*this->x[i];
    146   return (sqrt(res)); 
     177  return (sqrt(res));
    147178};
    148179
     
    178209 */
    179210void Vector::Init(double x1, double x2, double x3)
    180 { 
     211{
    181212  x[0] = x1;
    182213  x[1] = x2;
     
    188219 * \return \f$\acos\bigl(frac{\langle x, y \rangle}{|x||y|}\bigr)\f$
    189220 */
    190 double Vector::Angle(Vector *y) const
    191 {
    192   return acos(this->ScalarProduct(y)/Norm()/y->Norm()); 
     221double Vector::Angle(const Vector *y) const
     222{
     223  return acos(this->ScalarProduct(y)/Norm()/y->Norm());
    193224};
    194225
     
    238269
    239270/** Sums two vectors \a  and \b component-wise.
    240  * \param a first vector 
     271 * \param a first vector
    241272 * \param b second vector
    242273 * \return a + b
     
    251282
    252283/** Factors given vector \a a times \a m.
    253  * \param a vector 
     284 * \param a vector
    254285 * \param m factor
    255286 * \return a + b
     
    282313};
    283314
    284 ofstream& operator<<(ofstream& ost,Vector& m)
    285 {
    286         m.Output(&ost);
     315/** Prints a 3dim vector to a stream.
     316 * \param ost output stream
     317 * \param v Vector to be printed
     318 * \return output stream
     319 */
     320ostream& operator<<(ostream& ost,Vector& m)
     321{
     322  ost << "(";
     323  for (int i=0;i<NDIM;i++) {
     324    ost << m.x[i];
     325    if (i != 2)
     326      ost << ",";
     327  }
     328  ost << ")";
    287329        return ost;
    288330};
     
    309351};
    310352
    311 /** Translate atom by given vector. 
     353/** Translate atom by given vector.
    312354 * \param trans[] translation vector.
    313355 */
     
    316358  for (int i=NDIM;i--;)
    317359    x[i] += trans->x[i];
    318 }; 
     360};
    319361
    320362/** Do a matrix multiplication.
     
    355397    B[7] = -detAReci*RDET2(A[0],A[1],A[6],A[7]);    // A_32
    356398    B[8] =  detAReci*RDET2(A[0],A[1],A[3],A[4]);    // A_33
    357  
     399
    358400    // do the matrix multiplication
    359401    C.x[0] = B[0]*x[0]+B[3]*x[1]+B[6]*x[2];
     
    379421{
    380422  for(int i=NDIM;i--;)
    381     x[i] = factors[0]*x1->x[i] + factors[1]*x2->x[i] + factors[2]*x3->x[i]; 
    382 };
    383 
    384 /** Mirrors atom against a given plane. 
     423    x[i] = factors[0]*x1->x[i] + factors[1]*x2->x[i] + factors[2]*x3->x[i];
     424};
     425
     426/** Mirrors atom against a given plane.
    385427 * \param n[] normal vector of mirror plane.
    386428 */
     
    398440  Output((ofstream *)&cout);
    399441  cout << endl;
    400 }; 
     442};
    401443
    402444/** Calculates normal vector for three given vectors (being three points in space).
     
    430472  this->x[2] = (x1.x[0]*x2.x[1] - x1.x[1]*x2.x[0]);
    431473  Normalize();
    432  
     474
    433475  return true;
    434476};
     
    488530/** Creates this vector as one of the possible orthonormal ones to the given one.
    489531 * Just scan how many components of given *vector are unequal to zero and
    490  * try to get the skp of both to be zero accordingly. 
     532 * try to get the skp of both to be zero accordingly.
    491533 * \param *vector given vector
    492534 * \return true - success, false - failure (null vector given)
     
    509551      Components[Last++] = j;
    510552  cout << Verbose(4) << Last << " Components != 0: (" << Components[0] << "," << Components[1] << "," << Components[2] << ")" << endl;
    511        
     553
    512554  switch(Last) {
    513555    case 3:  // threecomponent system
     
    522564    case 1: // one component system
    523565      // set sole non-zero component to 0, and one of the other zero component pendants to 1
    524       x[(Components[0]+2)%NDIM] = 0.;   
    525       x[(Components[0]+1)%NDIM] = 1.;   
    526       x[Components[0]] = 0.;   
     566      x[(Components[0]+2)%NDIM] = 0.;
     567      x[(Components[0]+1)%NDIM] = 1.;
     568      x[Components[0]] = 0.;
    527569      return true;
    528570      break;
     
    541583{
    542584//  cout << Verbose(3) << "For comparison: ";
    543 //  cout << "A " << A->Projection(this) << "\t"; 
    544 //  cout << "B " << B->Projection(this) << "\t"; 
    545 //  cout << "C " << C->Projection(this) << "\t"; 
     585//  cout << "A " << A->Projection(this) << "\t";
     586//  cout << "B " << B->Projection(this) << "\t";
     587//  cout << "C " << C->Projection(this) << "\t";
    546588//  cout << endl;
    547589  return A->Projection(this);
     
    553595 * \return true if success, false if failed due to linear dependency
    554596 */
    555 bool Vector::LSQdistance(Vector **vectors, int num) 
     597bool Vector::LSQdistance(Vector **vectors, int num)
    556598{
    557599        int j;
    558                                
     600
    559601        for (j=0;j<num;j++) {
    560602                cout << Verbose(1) << j << "th atom's vector: ";
     
    565607  int np = 3;
    566608        struct LSQ_params par;
    567    
     609
    568610   const gsl_multimin_fminimizer_type *T =
    569611     gsl_multimin_fminimizer_nmsimplex;
     
    571613   gsl_vector *ss, *y;
    572614   gsl_multimin_function minex_func;
    573  
     615
    574616   size_t iter = 0, i;
    575617   int status;
    576618   double size;
    577  
     619
    578620   /* Initial vertex size vector */
    579621   ss = gsl_vector_alloc (np);
    580622   y = gsl_vector_alloc (np);
    581  
     623
    582624   /* Set all step sizes to 1 */
    583625   gsl_vector_set_all (ss, 1.0);
    584  
     626
    585627   /* Starting point */
    586628   par.vectors = vectors;
    587629         par.num = num;
    588        
     630
    589631         for (i=NDIM;i--;)
    590                 gsl_vector_set(y, i, (vectors[0]->x[i] - vectors[1]->x[i])/2.); 
    591          
     632                gsl_vector_set(y, i, (vectors[0]->x[i] - vectors[1]->x[i])/2.);
     633
    592634   /* Initialize method and iterate */
    593635   minex_func.f = &LSQ;
    594636   minex_func.n = np;
    595637   minex_func.params = (void *)&par;
    596  
     638
    597639   s = gsl_multimin_fminimizer_alloc (T, np);
    598640   gsl_multimin_fminimizer_set (s, &minex_func, y, ss);
    599  
     641
    600642   do
    601643     {
    602644       iter++;
    603645       status = gsl_multimin_fminimizer_iterate(s);
    604  
     646
    605647       if (status)
    606648         break;
    607  
     649
    608650       size = gsl_multimin_fminimizer_size (s);
    609651       status = gsl_multimin_test_size (size, 1e-2);
    610  
     652
    611653       if (status == GSL_SUCCESS)
    612654         {
    613655           printf ("converged to minimum at\n");
    614656         }
    615  
     657
    616658       printf ("%5d ", (int)iter);
    617659       for (i = 0; i < (size_t)np; i++)
     
    622664     }
    623665   while (status == GSL_CONTINUE && iter < 100);
    624  
     666
    625667  for (i=(size_t)np;i--;)
    626668    this->x[i] = gsl_vector_get(s->x, i);
     
    688730 * \param alpha first angle
    689731 * \param beta second angle
    690  * \param c norm of final vector 
     732 * \param c norm of final vector
    691733 * \return a vector with \f$\langle x1,x2 \rangle=A\f$, \f$\langle x1,y \rangle = B\f$ and with norm \a c.
    692  * \bug this is not yet working properly 
     734 * \bug this is not yet working properly
    693735 */
    694736bool Vector::SolveSystem(Vector *x1, Vector *x2, Vector *y, double alpha, double beta, double c)
     
    706748  if (fabs(x1->x[0]) < MYEPSILON) { // check for zero components for the later flipping and back-flipping
    707749    if (fabs(x1->x[1]) > MYEPSILON) {
    708       flag = 1;   
     750      flag = 1;
    709751    } else if (fabs(x1->x[2]) > MYEPSILON) {
    710752       flag = 2;
     
    739781  // now comes the case system
    740782  D1 = -y->x[0]/x1->x[0]*x1->x[1]+y->x[1];
    741   D2 = -y->x[0]/x1->x[0]*x1->x[2]+y->x[2]; 
     783  D2 = -y->x[0]/x1->x[0]*x1->x[2]+y->x[2];
    742784  D3 = y->x[0]/x1->x[0]*A-B1;
    743785  cout << Verbose(2) << "D1 " << D1 << "\tD2 " << D2 << "\tD3 " << D3 << "\n";
    744786  if (fabs(D1) < MYEPSILON) {
    745     cout << Verbose(2) << "D1 == 0!\n"; 
     787    cout << Verbose(2) << "D1 == 0!\n";
    746788    if (fabs(D2) > MYEPSILON) {
    747       cout << Verbose(3) << "D2 != 0!\n"; 
     789      cout << Verbose(3) << "D2 != 0!\n";
    748790      x[2] = -D3/D2;
    749791      E1 = A/x1->x[0] + x1->x[2]/x1->x[0]*D3/D2;
     
    755797      cout << Verbose(3) << "F1 " << F1 << "\tF2 " << F2 << "\tF3 " << F3 << "\n";
    756798      if (fabs(F1) < MYEPSILON) {
    757         cout << Verbose(4) << "F1 == 0!\n"; 
     799        cout << Verbose(4) << "F1 == 0!\n";
    758800        cout << Verbose(4) << "Gleichungssystem linear\n";
    759         x[1] = F3/(2.*F2); 
     801        x[1] = F3/(2.*F2);
    760802      } else {
    761803        p = F2/F1;
    762804        q = p*p - F3/F1;
    763         cout << Verbose(4) << "p " << p << "\tq " << q << endl; 
     805        cout << Verbose(4) << "p " << p << "\tq " << q << endl;
    764806        if (q < 0) {
    765807          cout << Verbose(4) << "q < 0" << endl;
     
    782824    cout << Verbose(2) << "F1 " << F1 << "\tF2 " << F2 << "\tF3 " << F3 << "\n";
    783825    if (fabs(F1) < MYEPSILON) {
    784       cout << Verbose(3) << "F1 == 0!\n"; 
     826      cout << Verbose(3) << "F1 == 0!\n";
    785827      cout << Verbose(3) << "Gleichungssystem linear\n";
    786       x[2] = F3/(2.*F2);     
     828      x[2] = F3/(2.*F2);
    787829    } else {
    788830      p = F2/F1;
    789831      q = p*p - F3/F1;
    790       cout << Verbose(3) << "p " << p << "\tq " << q << endl; 
     832      cout << Verbose(3) << "p " << p << "\tq " << q << endl;
    791833      if (q < 0) {
    792834        cout << Verbose(3) << "q < 0" << endl;
     
    832874    }
    833875    cout << Verbose(2) << i << ": sign matrix is " << sign[0] << "\t" << sign[1] << "\t" << sign[2] << "\n";
    834     // apply sign matrix 
     876    // apply sign matrix
    835877    for (j=NDIM;j--;)
    836878      x[j] *= sign[j];
     
    838880    ang = x2->Angle (this);
    839881    cout << Verbose(1) << i << "th angle " << ang << "\tbeta " << cos(beta) << " :\t";
    840     if (fabs(ang - cos(beta)) < MYEPSILON) { 
     882    if (fabs(ang - cos(beta)) < MYEPSILON) {
    841883      break;
    842884    }
Note: See TracChangeset for help on using the changeset viewer.