ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/math/MatVec3.c
(Generate patch)

Comparing trunk/src/math/MatVec3.c (file contents):
Revision 2 by gezelter, Fri Sep 24 04:16:43 2004 UTC vs.
Revision 1390 by gezelter, Wed Nov 25 20:02:06 2009 UTC

# Line 1 | Line 1
1 + /*
2 + * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3 + *
4 + * The University of Notre Dame grants you ("Licensee") a
5 + * non-exclusive, royalty free, license to use, modify and
6 + * redistribute this software in source and binary code form, provided
7 + * that the following conditions are met:
8 + *
9 + * 1. Redistributions of source code must retain the above copyright
10 + *    notice, this list of conditions and the following disclaimer.
11 + *
12 + * 2. Redistributions in binary form must reproduce the above copyright
13 + *    notice, this list of conditions and the following disclaimer in the
14 + *    documentation and/or other materials provided with the
15 + *    distribution.
16 + *
17 + * This software is provided "AS IS," without a warranty of any
18 + * kind. All express or implied conditions, representations and
19 + * warranties, including any implied warranty of merchantability,
20 + * fitness for a particular purpose or non-infringement, are hereby
21 + * excluded.  The University of Notre Dame and its licensors shall not
22 + * be liable for any damages suffered by licensee as a result of
23 + * using, modifying or distributing the software or its
24 + * derivatives. In no event will the University of Notre Dame or its
25 + * licensors be liable for any lost revenue, profit or data, or for
26 + * direct, indirect, special, consequential, incidental or punitive
27 + * damages, however caused and regardless of the theory of liability,
28 + * arising out of the use of or inability to use software, even if the
29 + * University of Notre Dame has been advised of the possibility of
30 + * such damages.
31 + *
32 + * SUPPORT OPEN SCIENCE!  If you use OpenMD or its source code in your
33 + * research, please cite the appropriate papers when you publish your
34 + * work.  Good starting points are:
35 + *                                                                      
36 + * [1]  Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).            
37 + * [2]  Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).          
38 + * [3]  Sun, Lin & Gezelter, J. Chem. Phys. 128, 24107 (2008).          
39 + * [4]  Vardeman & Gezelter, in progress (2009).                        
40 + */
41 +
42   #include <stdio.h>
43   #include <math.h>
44   #include <stdlib.h>
45 < #include "MatVec3.h"
45 > #include "math/MatVec3.h"
46  
47   /*
48   * Contains various utilities for dealing with 3x3 matrices and
49   * length 3 vectors
50   */
51  
52 < void identityMat3(double A[3][3]) {
52 > void identityMat3(RealType A[3][3]) {
53    int i;
54    for (i = 0; i < 3; i++) {
55      A[i][0] = A[i][1] = A[i][2] = 0.0;
# Line 16 | Line 57 | void identityMat3(double A[3][3]) {
57    }
58   }
59  
60 < void swapVectors3(double v1[3], double v2[3]) {
60 > void swapVectors3(RealType v1[3], RealType v2[3]) {
61    int i;
62    for (i = 0; i < 3; i++) {
63 <    double tmp = v1[i];
63 >    RealType tmp = v1[i];
64      v1[i] = v2[i];
65      v2[i] = tmp;
66    }
67   }
68  
69 < double normalize3(double x[3]) {
70 <  double den;
69 > RealType normalize3(RealType x[3]) {
70 >  RealType den;
71    int i;
72    if ( (den = norm3(x)) != 0.0 ) {
73      for (i=0; i < 3; i++)
# Line 37 | Line 78 | double normalize3(double x[3]) {
78    return den;
79   }
80  
81 < void matMul3(double a[3][3], double b[3][3], double c[3][3]) {
82 <  double r00, r01, r02, r10, r11, r12, r20, r21, r22;
81 > void matMul3(RealType a[3][3], RealType b[3][3], RealType c[3][3]) {
82 >  RealType r00, r01, r02, r10, r11, r12, r20, r21, r22;
83    
84    r00 = a[0][0]*b[0][0] + a[0][1]*b[1][0] + a[0][2]*b[2][0];
85    r01 = a[0][0]*b[0][1] + a[0][1]*b[1][1] + a[0][2]*b[2][1];
# Line 57 | Line 98 | void matMul3(double a[3][3], double b[3][3], double c[
98    c[2][0] = r20; c[2][1] = r21; c[2][2] = r22;
99   }
100  
101 < void matVecMul3(double m[3][3], double inVec[3], double outVec[3]) {
102 <  double a0, a1, a2;
101 > void matVecMul3(RealType m[3][3], RealType inVec[3], RealType outVec[3]) {
102 >  RealType a0, a1, a2;
103    
104    a0 = inVec[0];  a1 = inVec[1];  a2 = inVec[2];
105    
# Line 67 | Line 108 | void matVecMul3(double m[3][3], double inVec[3], doubl
108    outVec[2] = m[2][0]*a0 + m[2][1]*a1 + m[2][2]*a2;
109   }
110  
111 < double matDet3(double a[3][3]) {
111 > RealType matDet3(RealType a[3][3]) {
112    int i, j, k;
113 <  double determinant;
113 >  RealType determinant;
114    
115    determinant = 0.0;
116    
# Line 83 | Line 124 | double matDet3(double a[3][3]) {
124    return determinant;
125   }
126  
127 < void invertMat3(double a[3][3], double b[3][3]) {
127 > void invertMat3(RealType a[3][3], RealType b[3][3]) {
128    
129    int  i, j, k, l, m, n;
130 <  double determinant;
130 >  RealType determinant;
131    
132    determinant = matDet3( a );
133    
# Line 109 | Line 150 | void invertMat3(double a[3][3], double b[3][3]) {
150    }
151   }
152  
153 < void transposeMat3(double in[3][3], double out[3][3]) {
154 <  double temp[3][3];
153 > void transposeMat3(RealType in[3][3], RealType out[3][3]) {
154 >  RealType temp[3][3];
155    int i, j;
156    
157    for (i = 0; i < 3; i++) {
# Line 125 | Line 166 | void transposeMat3(double in[3][3], double out[3][3])
166    }
167   }
168  
169 < void printMat3(double A[3][3] ){
169 > void printMat3(RealType A[3][3] ){
170    
171    fprintf(stderr, "[ %g, %g, %g ]\n[ %g, %g, %g ]\n[ %g, %g, %g ]\n",          
172            A[0][0] , A[0][1] , A[0][2],
# Line 133 | Line 174 | void printMat3(double A[3][3] ){
174            A[2][0] , A[2][1] , A[2][2]) ;
175   }
176  
177 < void printMat9(double A[9] ){
177 > void printMat9(RealType A[9] ){
178    
179    fprintf(stderr, "[ %g, %g, %g ]\n[ %g, %g, %g ]\n[ %g, %g, %g ]\n",          
180            A[0], A[1], A[2],
# Line 141 | Line 182 | void printMat9(double A[9] ){
182            A[6], A[7], A[8]);
183   }
184  
185 < double matTrace3(double m[3][3]){
186 <  double trace;
185 > RealType matTrace3(RealType m[3][3]){
186 >  RealType trace;
187    trace = m[0][0] + m[1][1] + m[2][2];
188    
189    return trace;
190   }
191  
192 < void crossProduct3(double a[3],double b[3], double out[3]){
192 > void crossProduct3(RealType a[3],RealType b[3], RealType out[3]){
193    
194    out[0] = a[1] * b[2] - a[2] * b[1];
195    out[1] = a[2] * b[0] - a[0] * b[2] ;
# Line 156 | Line 197 | void crossProduct3(double a[3],double b[3], double out
197    
198   }
199  
200 < double dotProduct3(double a[3], double b[3]){
200 > RealType dotProduct3(RealType a[3], RealType b[3]){
201    return a[0]*b[0] + a[1]*b[1]+ a[2]*b[2];
202   }
203  
204 < //----------------------------------------------------------------------------
205 < // Extract the eigenvalues and eigenvectors from a 3x3 matrix.
206 < // The eigenvectors (the columns of V) will be normalized.
207 < // The eigenvectors are aligned optimally with the x, y, and z
208 < // axes respectively.
204 > /*----------------------------------------------------------------------------*/
205 > /* Extract the eigenvalues and eigenvectors from a 3x3 matrix.*/
206 > /* The eigenvectors (the columns of V) will be normalized. */
207 > /* The eigenvectors are aligned optimally with the x, y, and z*/
208 > /* axes respectively.*/
209  
210 < void diagonalize3x3(const double A[3][3], double w[3], double V[3][3]) {
210 > void diagonalize3x3(const RealType A[3][3], RealType w[3], RealType V[3][3]) {
211    int i,j,k,maxI;
212 <  double tmp, maxVal;
212 >  RealType tmp, maxVal;
213  
214 <  // do the matrix[3][3] to **matrix conversion for Jacobi
215 <  double C[3][3];
216 <  double *ATemp[3],*VTemp[3];
214 >  /* do the matrix[3][3] to **matrix conversion for Jacobi*/
215 >  RealType C[3][3];
216 >  RealType *ATemp[3],*VTemp[3];
217    for (i = 0; i < 3; i++)
218      {
219        C[i][0] = A[i][0];
# Line 182 | Line 223 | void diagonalize3x3(const double A[3][3], double w[3],
223        VTemp[i] = V[i];
224      }
225    
226 <  // diagonalize using Jacobi
226 >  /* diagonalize using Jacobi*/
227    JacobiN(ATemp,3,w,VTemp);
228    
229 <  // if all the eigenvalues are the same, return identity matrix
229 >  /* if all the eigenvalues are the same, return identity matrix*/
230    if (w[0] == w[1] && w[0] == w[2])
231      {
232        identityMat3(V);
233        return;
234      }
235    
236 <  // transpose temporarily, it makes it easier to sort the eigenvectors
236 >  /* transpose temporarily, it makes it easier to sort the eigenvectors*/
237    transposeMat3(V,V);
238    
239 <  // if two eigenvalues are the same, re-orthogonalize to optimally line
240 <  // up the eigenvectors with the x, y, and z axes
239 >  /* if two eigenvalues are the same, re-orthogonalize to optimally line*/
240 >  /* up the eigenvectors with the x, y, and z axes*/
241    for (i = 0; i < 3; i++)
242      {
243 <      if (w[(i+1)%3] == w[(i+2)%3]) // two eigenvalues are the same
243 >      if (w[(i+1)%3] == w[(i+2)%3]) /* two eigenvalues are the same*/
244          {
245 <          // find maximum element of the independant eigenvector
245 >          /* find maximum element of the independant eigenvector*/
246            maxVal = fabs(V[i][0]);
247            maxI = 0;
248            for (j = 1; j < 3; j++)
# Line 212 | Line 253 | void diagonalize3x3(const double A[3][3], double w[3],
253                    maxI = j;
254                  }
255              }
256 <          // swap the eigenvector into its proper position
256 >          /* swap the eigenvector into its proper position*/
257            if (maxI != i)
258              {
259                tmp = w[maxI];
# Line 220 | Line 261 | void diagonalize3x3(const double A[3][3], double w[3],
261                w[i] = tmp;
262                swapVectors3(V[i],V[maxI]);
263              }
264 <          // maximum element of eigenvector should be positive
264 >          /* maximum element of eigenvector should be positive*/
265            if (V[maxI][maxI] < 0)
266              {
267                V[maxI][0] = -V[maxI][0];
# Line 228 | Line 269 | void diagonalize3x3(const double A[3][3], double w[3],
269                V[maxI][2] = -V[maxI][2];
270              }
271            
272 <          // re-orthogonalize the other two eigenvectors
272 >          /* re-orthogonalize the other two eigenvectors*/
273            j = (maxI+1)%3;
274            k = (maxI+2)%3;
275            
# Line 240 | Line 281 | void diagonalize3x3(const double A[3][3], double w[3],
281            normalize3(V[k]);
282            crossProduct3(V[k],V[maxI],V[j]);
283  
284 <          // transpose vectors back to columns
284 >          /* transpose vectors back to columns*/
285            transposeMat3(V,V);
286            return;
287          }
288      }
289    
290 <  // the three eigenvalues are different, just sort the eigenvectors
291 <  // to align them with the x, y, and z axes
290 >  /* the three eigenvalues are different, just sort the eigenvectors*/
291 >  /* to align them with the x, y, and z axes*/
292    
293 <  // find the vector with the largest x element, make that vector
294 <  // the first vector
293 >  /* find the vector with the largest x element, make that vector*/
294 >  /* the first vector*/
295    maxVal = fabs(V[0][0]);
296    maxI = 0;
297    for (i = 1; i < 3; i++)
# Line 261 | Line 302 | void diagonalize3x3(const double A[3][3], double w[3],
302            maxI = i;
303          }
304      }
305 <  // swap eigenvalue and eigenvector
305 >  /* swap eigenvalue and eigenvector*/
306    if (maxI != 0)
307      {
308        tmp = w[maxI];
# Line 269 | Line 310 | void diagonalize3x3(const double A[3][3], double w[3],
310        w[0] = tmp;
311        swapVectors3(V[maxI],V[0]);
312      }
313 <  // do the same for the y element
313 >  /* do the same for the y element*/
314    if (fabs(V[1][1]) < fabs(V[2][1]))
315      {
316        tmp = w[2];
# Line 278 | Line 319 | void diagonalize3x3(const double A[3][3], double w[3],
319        swapVectors3(V[2],V[1]);
320      }
321    
322 <  // ensure that the sign of the eigenvectors is correct
322 >  /* ensure that the sign of the eigenvectors is correct*/
323    for (i = 0; i < 2; i++)
324      {
325        if (V[i][i] < 0)
# Line 288 | Line 329 | void diagonalize3x3(const double A[3][3], double w[3],
329            V[i][2] = -V[i][2];
330          }
331      }
332 <  // set sign of final eigenvector to ensure that determinant is positive
332 >  /* set sign of final eigenvector to ensure that determinant is positive*/
333    if (matDet3(V) < 0)
334      {
335        V[2][0] = -V[2][0];
# Line 296 | Line 337 | void diagonalize3x3(const double A[3][3], double w[3],
337        V[2][2] = -V[2][2];
338      }
339    
340 <  // transpose the eigenvectors back again
340 >  /* transpose the eigenvectors back again*/
341    transposeMat3(V,V);
342   }
343  
# Line 305 | Line 346 | void diagonalize3x3(const double A[3][3], double w[3],
346  
347   #define MAX_ROTATIONS 20
348  
349 < // Jacobi iteration for the solution of eigenvectors/eigenvalues of a nxn
350 < // real symmetric matrix. Square nxn matrix a; size of matrix in n;
351 < // output eigenvalues in w; and output eigenvectors in v. Resulting
352 < // eigenvalues/vectors are sorted in decreasing order; eigenvectors are
353 < // normalized.
354 < int JacobiN(double **a, int n, double *w, double **v) {
349 > /* Jacobi iteration for the solution of eigenvectors/eigenvalues of a nxn*/
350 > /* real symmetric matrix. Square nxn matrix a; size of matrix in n;*/
351 > /* output eigenvalues in w; and output eigenvectors in v. Resulting*/
352 > /* eigenvalues/vectors are sorted in decreasing order; eigenvectors are*/
353 > /* normalized.*/
354 > int JacobiN(RealType **a, int n, RealType *w, RealType **v) {
355  
356    int i, j, k, iq, ip, numPos;
357    int ceil_half_n;
358 <  double tresh, theta, tau, t, sm, s, h, g, c, tmp;
359 <  double bspace[4], zspace[4];
360 <  double *b = bspace;
361 <  double *z = zspace;
358 >  RealType tresh, theta, tau, t, sm, s, h, g, c, tmp;
359 >  RealType bspace[4], zspace[4];
360 >  RealType *b = bspace;
361 >  RealType *z = zspace;
362    
363  
364 <  // only allocate memory if the matrix is large
364 >  /* only allocate memory if the matrix is large*/
365    if (n > 4)
366      {
367 <      b = (double *) calloc(n, sizeof(double));
368 <      z = (double *) calloc(n, sizeof(double));
367 >      b = (RealType *) calloc(n, sizeof(RealType));
368 >      z = (RealType *) calloc(n, sizeof(RealType));
369      }
370    
371 <  // initialize
371 >  /* initialize*/
372    for (ip=0; ip<n; ip++)
373      {
374        for (iq=0; iq<n; iq++)
# Line 342 | Line 383 | int JacobiN(double **a, int n, double *w, double **v)
383        z[ip] = 0.0;
384      }
385    
386 <  // begin rotation sequence
386 >  /* begin rotation sequence*/
387    for (i=0; i<MAX_ROTATIONS; i++)
388      {
389        sm = 0.0;
# Line 358 | Line 399 | int JacobiN(double **a, int n, double *w, double **v)
399            break;
400          }
401        
402 <      if (i < 3)                                // first 3 sweeps
402 >      if (i < 3)                                /* first 3 sweeps*/
403          {
404            tresh = 0.2*sm/(n*n);
405          }
# Line 373 | Line 414 | int JacobiN(double **a, int n, double *w, double **v)
414              {
415                g = 100.0*fabs(a[ip][iq]);
416                
417 <              // after 4 sweeps
417 >              /* after 4 sweeps*/
418                if (i > 3 && (fabs(w[ip])+g) == fabs(w[ip])
419                    && (fabs(w[iq])+g) == fabs(w[iq]))
420                  {
# Line 405 | Line 446 | int JacobiN(double **a, int n, double *w, double **v)
446                    w[iq] += h;
447                    a[ip][iq]=0.0;
448                    
449 <                  // ip already shifted left by 1 unit
449 >                  /* ip already shifted left by 1 unit*/
450                    for (j = 0;j <= ip-1;j++)
451                      {
452                        MAT_ROTATE(a,j,ip,j,iq)
453                          }
454 <                  // ip and iq already shifted left by 1 unit
454 >                  /* ip and iq already shifted left by 1 unit*/
455                    for (j = ip+1;j <= iq-1;j++)
456                      {
457                        MAT_ROTATE(a,ip,j,j,iq)
458                          }
459 <                  // iq already shifted left by 1 unit
459 >                  /* iq already shifted left by 1 unit*/
460                    for (j=iq+1; j<n; j++)
461                      {
462                        MAT_ROTATE(a,ip,j,iq,j)
# Line 436 | Line 477 | int JacobiN(double **a, int n, double *w, double **v)
477          }
478      }
479    
480 <  //// this is NEVER called
480 >  /*// this is NEVER called*/
481    if ( i >= MAX_ROTATIONS )
482      {
483        sprintf( painCave.errMsg,
# Line 446 | Line 487 | int JacobiN(double **a, int n, double *w, double **v)
487        return 0;
488      }
489    
490 <  // sort eigenfunctions                 these changes do not affect accuracy
491 <  for (j=0; j<n-1; j++)                  // boundary incorrect
490 >  /* sort eigenfunctions                 these changes do not affect accuracy */
491 >  for (j=0; j<n-1; j++)                  /* boundary incorrect*/
492      {
493        k = j;
494        tmp = w[k];
495 <      for (i=j+1; i<n; i++)             // boundary incorrect, shifted already
495 >      for (i=j+1; i<n; i++)             /* boundary incorrect, shifted already*/
496          {
497 <          if (w[i] >= tmp)                   // why exchage if same?
497 >          if (w[i] >= tmp)                   /* why exchage if same?*/
498              {
499                k = i;
500                tmp = w[k];
# Line 471 | Line 512 | int JacobiN(double **a, int n, double *w, double **v)
512              }
513          }
514      }
515 <  // insure eigenvector consistency (i.e., Jacobi can compute vectors that
516 <  // are negative of one another (.707,.707,0) and (-.707,-.707,0). This can
517 <  // reek havoc in hyperstreamline/other stuff. We will select the most
518 <  // positive eigenvector.
515 >  /* insure eigenvector consistency (i.e., Jacobi can compute vectors that*/
516 >  /* are negative of one another (.707,.707,0) and (-.707,-.707,0). This can*/
517 >  /* reek havoc in hyperstreamline/other stuff. We will select the most*/
518 >  /* positive eigenvector.*/
519    ceil_half_n = (n >> 1) + (n & 1);
520    for (j=0; j<n; j++)
521      {
# Line 485 | Line 526 | int JacobiN(double **a, int n, double *w, double **v)
526                numPos++;
527              }
528          }
529 <      //    if ( numPos < ceil(double(n)/double(2.0)) )
529 >      /*    if ( numPos < ceil(RealType(n)/RealType(2.0)) )*/
530        if ( numPos < ceil_half_n)
531          {
532            for(i=0; i<n; i++)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines