Rosetta
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
rms.cc
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 
10 /// @file numeric/model_quality/rms.hh
11 /// @brief RMS functions imported from rosetta++
12 /// @author James Thompson
13 /// @date Wed Aug 22 12:10:37 2007
14 
15 
16 // Rosetta Headers
17 
18 // numeric libraries
19 #include <numeric/xyzVector.hh>
20 #include <numeric/xyz.functions.hh>
24 #include <numeric/types.hh>
25 
26 #include <utility/vector1.hh>
27 
28 // ObjexxFCL libraries
29 #include <ObjexxFCL/FArray1D.hh>
30 #include <ObjexxFCL/FArray2D.hh>
31 
32 // C++ libraries
33 #include <complex>
34 
35 
36 namespace numeric {
37 namespace model_quality {
38 
43 using ObjexxFCL::FArray2;
44 using ObjexxFCL::FArray1;
45 
50 ) {
51  assert( p1_coords.size() == p2_coords.size() );
52  Size const natoms( p1_coords.size() );
53 
54  FArray2D< numeric::Real > p1a( 3, p1_coords.size() );
55  FArray2D< numeric::Real > p2a( 3, p2_coords.size() );
56 
57  for ( Size i = 1; i <= natoms; ++i ) {
58  for ( Size k = 1; k <= 3; ++k ) { // k = X, Y and Z
59  p1a(k,i) = p1_coords[i](k);
60  p2a(k,i) = p2_coords[i](k);
61  }
62  }
63  return rms_wrapper( natoms, p1a, p2a );
64 }
65 
68  int natoms,
71 ) {
72  // rotate and translate coordinates to minimize rmsd
73  FArray1D< numeric::Real > ww(natoms,1.0);
74  Real bogus = 0;
75  rmsfitca2(natoms,p1a,p2a,ww,natoms,bogus);
76 
77  // manually calculate rmsd
78  numeric::Real tot = 0;
79  for ( int i = 1; i <= natoms; ++i ) {
80  for ( int j = 1; j <= 3; ++j ) {
81  tot += std::pow( p1a(i,j) - p2a(i,j), 2 );
82  }
83  }
84 
85  return std::sqrt(tot/natoms);
86 }
87 
88 // Calculate an RMS based on aligned set of points in p1a and p2a composed
89 // each representing a list of natoms.
92  int natoms,
95 ) {
96  FArray1D< numeric::Real > ww( natoms, 1.0 );
97  FArray2D< numeric::Real > uu( 3, 3, 0.0 );
98  numeric::Real ctx;
99 
100  findUU( p1a, p2a, ww, natoms, uu, ctx );
101 
102  float fast_rms;
103  calc_rms_fast( fast_rms, p1a, p2a, ww, natoms, ctx );
104  return fast_rms;
105 } // rms_wrapper
106 
107 ////////////////////////////////////////////////////////////////////////////////
108 ///
109 /// @brief
110 /// companion function for findUU ( it is optional ) computes the minimum
111 /// RMS deviation beteen XX and YY as though it rotated the arrays, without
112 /// actually rotating them.
113 ///
114 /// @details
115 ///
116 /// @param rms_out [in/out]? - the real-valued output value of the rms deviation
117 /// @param XX - [in/out]? - first set of points representing xyz coordinates
118 /// @param YY - [in/out]? - second set of points representing xyz coordinates
119 /// @param WW - [in/out]? - relative weight for each point
120 /// @param npoints - [in/out]? - number of points
121 /// @param ctx - [in/out]? - magic number computed during find UU that is needed
122 /// for this calculation
123 ///
124 /// @global_read
125 ///
126 /// @global_write
127 ///
128 /// @remarks
129 /// the XX, YY, WW must be the same as call to findUU (remember that findUU
130 /// offsets the XX and YY weighted COM to the origin!)
131 ///
132 /// @references
133 ///
134 /// @author
135 ///
136 /////////////////////////////////////////////////////////////////////////////////
137 void
139  float & rms_out,
143  int npoints,
144  numeric::Real ctx
145 )
146 {
147  xx.dimension( 3, npoints );
148  yy.dimension( 3, npoints );
149  ww.dimension( npoints );
150 
151  numeric::Real rms = 0.0;
152 
153  for ( int k = 1; k <= npoints; ++k ) {
154  numeric::Real const ww_k = ww(k);
155  for ( int j = 1; j <= 3; ++j ) {
156  numeric::Real const xx_jk = xx(j,k);
157  numeric::Real const yy_jk = yy(j,k);
158  rms += ww_k * ( ( xx_jk * xx_jk ) + ( yy_jk * yy_jk ) );
159  }
160  }
161 
162  rms -= 2 * ctx;
163  // abs on next line catches small difference of large numbers that turn out
164  // to be accidental small but negative
165  rms_out = std::sqrt(std::abs(rms/npoints)); // return a float
166 } // calc_rms_fast
167 
168 ////////////////////////////////////////////////////////////////////////////////
169 ///
170 /// @brief
171 /// intended to rotate one protein xyz array onto another one such that
172 /// the point-by-point rms is minimized.
173 ///
174 /// @details
175 /// 1) ORIGINAL PAPER HAD ERROR IN HANDEDNESS OF VECTORS, LEADING
176 /// TO INVERSION MATRICIES ON OCCASION. OOPS. NOW FIXED.
177 /// SEE ACTA CRYST(1978) A34 PAGE 827 FOR REVISED MATH
178 /// 2) TRAP DIVIDE BY ZERO ERRORS WHEN NO ROTATIONS REQUIRED.
179 /// 3) ADDED WEIGHTS (WEIGHTS NOW WORK)
180 /// 4) ADDED FAST RMS CALC AUXILIRARY ROUTINE.
181 /// 5) CHANGED TO numeric::Real TO DEAL WITH HIGHLY DISSIMILAR BUT LARGE PROTEINS.
182 ///
183 /// switched order of array subscripts so that can use logical array sizes
184 /// XX and YY are lists of Npoints XYZ vectors (3xNpoint matrix) to be co-aligned
185 /// these matrices are returned slightly modified: they are translated so their origins
186 /// are at the center of mass (see Weights below ).
187 /// WW is the weight or importance of each point (weighted RMS) vector of size Npoints
188 /// The center of mass is figured including this variable.
189 /// UU is a 3x3 symmetric orthonornal rotation matrix that will rotate YY onto XX such that
190 /// the weighted RMS distance is minimized.
191 ///
192 /// @param[in] XX - in - XX,YY are 2D arrays of x,y,z position of each atom
193 /// @param[in] YY - in -
194 /// @param[in] WW - in - a weight matrix for the points
195 /// @param[in] Npoints - in - the number of XYZ points (need not be physical array size)
196 /// @param[out] UU - out - 3x3 rotation matrix.
197 /// @param[out] sigma3 - out - TO BE PASSED TO OPTIONAL FAST_RMS CALC ROUTINE.
198 ///
199 /// @global_read
200 ///
201 /// @global_write
202 ///
203 /// @remarks
204 /// SIDEEFECTS: the Matrices XX, YY are Modified so that their weighted center
205 /// of mass is moved to (0,0,0).
206 ///
207 /// CAVEATS:
208 /// 1) it is CRITICAL that the first physical dimension of XX and YY is 3
209 ///
210 /// 2) an iterative approx algorithm computes the diagonalization of
211 /// a 3x3 matrix. if this program needs a speed up this could be
212 /// made into an analytic but uggggly diagonalization function.
213 ///
214 /// @references
215 /// Mathethematical Basis from paper:
216 /// (Wolfgang Kabsch) acta Cryst (1976) A32 page 922
217 ///
218 /// @author
219 /// Charlie Strauss 1999
220 /// Revised april 22
221 ///
222 /////////////////////////////////////////////////////////////////////////////////
223 void
227  FArray1< numeric::Real > const & WW,
228  int Npoints,
230  numeric::Real & sigma3
231 )
232 {
233  using numeric::xyzMatrix;
234  using numeric::xyzVector;
235 
236  ObjexxFCL::FArray1D_int sort( 3 );
237  FArray2D< numeric::Real > eVec( 3, 3 );
238  FArray2D< numeric::Real > bb( 3, 3 );
239  FArray1D< numeric::Real > w_w( 3 );
240  FArray2D< numeric::Real > m_moment( 3, 3 );
241  FArray2D< numeric::Real > rr_moment( 3, 3 );
242  numeric::Real temp1;
243  numeric::Real temp2;
244  //numeric::Real temp3;
246 
247  if ( Npoints < 1 ) {
248 
249  // return identity rotation matrix to moron
250  for ( int i = 1; i <= 3; ++i ) {
251  for ( int k = 1; k <= 3; ++k ) {
252  UU(i,k) = 0.0;
253  if ( i == k ) UU(i,i) = 1.0;
254  }
255  }
256  sigma3 = 0.0;
257  return;
258  }
259 
260  // align center of mass to origin
261  for ( int k = 1; k <= 3; ++k ) {
262  temp1 = 0.0;
263  temp2 = 0.0;
264  numeric::Real temp3 = 0.0;
265  for ( int j = 1; j <= Npoints; ++j ) {
266  temp1 += XX(k,j) * WW(j);
267  temp2 += YY(k,j) * WW(j);
268  temp3 += WW(j);
269  }
270  if ( temp3 > 0.001 ) temp1 /= temp3;
271  if ( temp3 > 0.001 ) temp2 /= temp3;
272 
273  for ( int j = 1; j <= Npoints; ++j ) {
274  XX(k,j) -= temp1;
275  YY(k,j) -= temp2;
276  }
277  }
278 
279  // Make cross moments matrix INCLUDE THE WEIGHTS HERE
280  for ( int k = 1; k <= 3; ++k ) {
281  for ( int j = 1; j <= 3; ++j ) {
282  temp1 = 0.0;
283  for ( int i = 1; i <= Npoints; ++i ) {
284  temp1 += WW(i) * YY(k,i) * XX(j,i);
285  }
286  m_moment(k,j) = temp1;
287  }
288  }
289 
290  // Multiply CROSS MOMENTS by transpose
291  BlankMatrixMult(m_moment,3,3,1,m_moment,3,0,rr_moment);
292 
293  // Copy to/from xyzMatrix/xyzVector since rest of functions use FArrays
294  xyzMatrix< numeric::Real > xyz_rr_moment( xyzMatrix< numeric::Real >::cols( &rr_moment( 1,1 ) ) );
297 
298  // Find eigenvalues, eigenvectors of symmetric matrix rr_moment
299  xyz_w_w = eigenvector_jacobi( xyz_rr_moment, (numeric::Real) 1E-9, xyz_eVec );
300 
301  // Copy eigenvalues/vectors back to FArray
302  for ( int i = 1; i <= 3; ++i ) {
303  w_w( i ) = xyz_w_w( i );
304  for ( int j = 1; j <= 3; ++j ) {
305  eVec( i, j ) = xyz_eVec( i, j );
306  }
307  }
308 
309  // explicitly coded 3 level index sort using eigenvalues
310  for ( int i = 1; i <= 3; ++i ) {
311  sort(i) = i;
312  }
313 
314  if ( w_w(1) < w_w(2) ) {
315  sort(2) = 1;
316  sort(1) = 2;
317  }
318 
319  if ( w_w(sort(2)) < w_w(3) ) {
320  sort(3) = sort(2);
321  sort(2) = 3;
322 
323  if ( w_w(sort(1)) < w_w(3) ) {
324  sort(2) = sort(1);
325  sort(1) = 3;
326  }
327  }
328 
329  // sort is now an index to order of eigen values
330 
331  if ( w_w(sort(2)) == 0.0 ) { // holy smokes, two eigen values are zeros
332  // return identity rotation matrix to moron
333  for ( int i = 1; i <= 3; ++i ) {
334  for ( int k = 1; k <= 3; ++k ) {
335  UU(i,k) = 0.0;
336  }
337  UU(i,i) = 1.0;
338  }
339  if ( w_w(sort(1)) < 0.0 ) {
340  w_w(sort(1)) = std::abs(w_w(sort(1)));
341  }
342  sigma3 = std::sqrt(w_w(sort(1)));
343 
344  return; // make like a prom dress and slip off
345  }
346 
347  // sort eigen values
348  temp1 = w_w(sort(1));
349  temp2 = w_w(sort(2));
350  w_w(3) = w_w(sort(3));
351  w_w(2) = temp2;
352  w_w(1) = temp1;
353  // sort first two eigen vectors (dont care about third)
354  for ( int i = 1; i <= 3; ++i ) {
355  temp1 = eVec(i,sort(1));
356  temp2 = eVec(i,sort(2));
357  eVec(i,1) = temp1;
358  eVec(i,2) = temp2;
359  }
360 
361 
362  // april 20: the fix not only fixes bad eigen vectors but solves a problem of
363  // forcing a right-handed coordinate system
364 
365  fixEigenvector(eVec);
366  // at this point we now have three good eigenvectors in a right hand
367  // coordinate system.
368 
369  // make bb basis vectors = moments*eVec
370 
371  BlankMatrixMult(m_moment,3,3,0,eVec,3,0,bb);
372  // std::cerr << "m_moment" << std::endl;
373  // squirrel away a free copy of the third eigenvector before normalization/fix
374  for ( int j = 1; j <= 3; ++j ) {
375  Ra(j) = bb(j,3);
376  }
377 
378  // normalize first two bb-basis vectors
379  // dont care about third since were going to replace it with b1xb2
380  // this also avoids problem of possible zero third eigen value
381  for ( int j = 1; j <= 2; ++j ) {
382  temp1 = 1.0/std::sqrt(w_w(j)); // zero checked for above
383  for ( int k = 1; k <= 3; ++k ) { // x,y,z
384  bb(k,j) *= temp1;
385  }
386  }
387 
388  // fix things so that bb eigenvecs are right handed
389 
390  fixEigenvector(bb); // need to fix this one too
391  // find product of eVec and bb matrices
392 
393  BlankMatrixMult(eVec,3,3,0,bb,3,1,UU);
394  // result is returned in UU.
395 
396  // and lastly determine a value used in another function to compute the rms
397  sigma3 = 0.0;
398  for ( int j = 1; j <= 3; ++j ) {
399  sigma3 += bb(j,3)*Ra(j);
400  }
401  //cems the std::abs() fixes some round off error situations where the w_w values are
402  //cems very small and accidentally negative. (theoretically they are positive,
403  //cems but in practice round off error makes them negative)
404  if ( sigma3 < 0.0 ) {
405  sigma3 = std::sqrt(std::abs(w_w(1))) + std::sqrt(std::abs(w_w(2))) -
406  std::sqrt(std::abs(w_w(3)));
407  } else {
408  sigma3 = std::sqrt(std::abs(w_w(1))) + std::sqrt(std::abs(w_w(2))) +
409  std::sqrt(std::abs(w_w(3)));
410  }
411 
412 } // findUU
413 
414 /// @brief This is a helper function for using the above implementation of findUU. There is some cost to the
415 /// conversion but everything else is probably slower and also you don't have to use FArrays everywhere
416 void
421  int Npoints,
423  numeric::Real & sigma3
424 )
425 {
426  FArray2D< numeric::Real > XX_Farray(numeric::vector_of_xyzvectors_to_FArray<numeric::Real>(XX));
427  FArray2D< numeric::Real > YY_Farray(numeric::vector_of_xyzvectors_to_FArray<numeric::Real>(YY));
428  FArray1D< numeric::Real > WW_Farray(WW.size());
429  FArray2D< numeric::Real > UU_Farray(numeric::xyzmatrix_to_FArray<numeric::Real>(UU));
430 
431  for ( numeric::Size index = 1; index <= WW.size(); ++index ) {
432  WW_Farray(index) = WW[index];
433  }
434 
435  findUU(XX_Farray,YY_Farray,WW_Farray,Npoints,UU_Farray,sigma3);
436 
437  //XX, YY, and UU were updated, convert those back. WW is const so don't bother
438 
441  UU = numeric::FArray_to_xyzmatrix(UU_Farray);
442 
443 
444 }
445 
446 ////////////////////////////////////////////////////////////////////////////////
447 ///
448 /// @brief
449 ///
450 /// @details
451 ///
452 /// @param A - [in/out]? -
453 /// @param n - [in/out]? -
454 /// @param np - [in/out]? -
455 /// @param transposeA - [in/out]? -
456 /// @param B - [in/out]? -
457 /// @param m - [in/out]? -
458 /// @param transposeB - [in/out]? -
459 /// @param AxB_out - [in/out]? -
460 ///
461 /// @global_read
462 ///
463 /// @global_write
464 ///
465 /// @remarks
466 ///
467 /// @references
468 ///
469 /// @author
470 ///
471 /////////////////////////////////////////////////////////////////////////////////
472 void
475  int n,
476  int np,
477  int transposeA,
479  int m,
480  int transposeB,
482 )
483 {
484  A.dimension( np, n );
485  B.dimension( np, m );
486  AxB_out.dimension( m, n );
487 
488  // fills output matrix with zeros before calling matrix multiply
489  AxB_out = 0.0;
490 
491  MatrixMult(A,n,np,transposeA,B,m,transposeB,AxB_out);
492 } // BlankMatrixMult
493 
494 ////////////////////////////////////////////////////////////////////////////////
495 ///
496 /// @brief
497 ///
498 /// @details
499 /// multiplys matrices A (npXn) and B (npXn). results in AxB.out
500 /// IF THE MATRICES are SQUARE. you can also multiply the transposes of these matrices
501 /// to do so set the transposeA or transposeB flags to 1, otherwise they should be zero.
502 ///
503 /// @param A - [in/out]? -
504 /// @param n - [in/out]? -
505 /// @param np - [in/out]? -
506 /// @param transposeA - [in/out]? -
507 /// @param B - [in/out]? -
508 /// @param m - [in/out]? -
509 /// @param transposeB - [in/out]? -
510 /// @param AxB_out - [in/out]? -
511 ///
512 /// @global_read
513 ///
514 /// @global_write
515 ///
516 /// @remarks
517 /// transpose only works correctly for square matricies!
518 ///
519 /// this function does SUMS to the old value of AxB_out...
520 /// you might want to call BlankMatrixMult instead (see above) 4/30/01 jjg
521 ///
522 ///this function works on numeric::Real values
523 ///float version below. jjg
524 ///
525 /// @references
526 ///
527 /// @author
528 /// charlie strauss 1999
529 ///
530 /////////////////////////////////////////////////////////////////////////////////
531 void
534  int n,
535  int np,
536  int transposeA,
538  int m,
539  int transposeB,
541 )
542 {
543  A.dimension( np, n );
544  B.dimension( np, m );
545  AxB_out.dimension( m, n );
546 
547 
548  if ( transposeA == 0 ) {
549  if ( transposeB == 0 ) {
550  for ( int k = 1; k <= m; ++k ) {
551  for ( int j = 1; j <= n; ++j ) {
552  for ( int i = 1; i <= np; ++i ) {
553  AxB_out(k,j) += A(k,i)*B(i,j);
554  }
555  }
556  }
557  } else {
558  for ( int k = 1; k <= m; ++k ) {
559  for ( int j = 1; j <= n; ++j ) {
560  for ( int i = 1; i <= np; ++i ) {
561  AxB_out(k,j) += A(k,i)*B(j,i);
562  }
563  }
564  }
565  }
566  } else {
567  if ( transposeB == 0 ) {
568  for ( int k = 1; k <= m; ++k ) {
569  for ( int j = 1; j <= n; ++j ) {
570  for ( int i = 1; i <= np; ++i ) {
571  AxB_out(k,j) += A(i,k)*B(i,j);
572  }
573  }
574  }
575  } else {
576  for ( int k = 1; k <= m; ++k ) {
577  for ( int j = 1; j <= n; ++j ) {
578  for ( int i = 1; i <= np; ++i ) {
579  AxB_out(k,j) += A(i,k)*B(j,i);
580  }
581  }
582  }
583  }
584  }
585 } // MatrixMult
586 
587 ////////////////////////////////////////////////////////////////////////////////
588 ///
589 /// @brief
590 ///
591 /// @details
592 /// m_v is a 3x3 matrix of 3 eigen vectors
593 /// replaces the third eigenvector by taking cross product of
594 /// of the first two eigenvectors
595 ///
596 /// @param m_v - [in/out]? -
597 ///
598 /// @global_read
599 ///
600 /// @global_write
601 ///
602 /// @remarks
603 ///
604 /// @references
605 ///
606 /// @author
607 ///
608 /////////////////////////////////////////////////////////////////////////////////
609 void
611 {
612  m_v.dimension( 3, 3 );
613 
614  numeric::Real const m_v_13 = m_v(2,1)*m_v(3,2) - m_v(3,1)*m_v(2,2);
615  numeric::Real const m_v_23 = m_v(3,1)*m_v(1,2) - m_v(1,1)*m_v(3,2);
616  numeric::Real const m_v_33 = m_v(1,1)*m_v(2,2) - m_v(2,1)*m_v(1,2);
617  // normalize it to 1 (should already be one but lets be safe)
618  numeric::Real const norm = std::sqrt( 1 /
619  ( ( m_v_13 * m_v_13 ) + ( m_v_23 * m_v_23 ) + ( m_v_33 * m_v_33 ) ) );
620 
621  m_v(1,3) = m_v_13 * norm;
622  m_v(2,3) = m_v_23 * norm;
623  m_v(3,3) = m_v_33 * norm;
624 } // fixEigenvector
625 
626 void
628  int npoints,
632  int natsel,
633  double & esq,
634  double const & offset_val,
635  bool const realign
636 )
637 {
638  xx.dimension( 3, npoints );
639  yy.dimension( 3, npoints );
640  ww.dimension( npoints );
641 
642 
643  double det;
644  int i,j,k;
645  double temp1,temp3;
646  FArray1D< double > ev( 3 );
647  FArray2D< double > m_moment( 3, 3 );
648  FArray2D< double > rr_moment( 3, 3 );
649  double rms_ctx;
650  double rms_sum;
651  double handedness;
652  FArray1D< double > t( 3 );
653 
654  FArray2D< double > R( 3, 3 );
655  double XPC, YPC, ZPC, XEC, YEC, ZEC;
656  // //COMMON /TRANSFORM/ XPC,YPC,ZPC,XEC,YEC,ZEC,R
657 
658  // align center of mass to origin
659 
660  COMAS(xx,ww,npoints,XPC,YPC,ZPC);
661  COMAS(yy,ww,npoints,XEC,YEC,ZEC);
662  temp3 = 0.0;
663  for ( i = 1; i <= npoints; ++i ) {
664  temp3 += ww(i);
665  // this is outrageous, but there are cases (e.g. in a single-residue pose) where
666  // all the z's are at 0, and this makes the det zero.
667  xx(3,i) -= offset_val;
668  yy(3,i) += offset_val;
669  }
670 
671  // Make cross moments matrix INCLUDE THE WEIGHTS HERE
672  for ( k = 1; k <= 3; ++k ) {
673  for ( j = 1; j <= 3; ++j ) {
674  temp1 = 0.0;
675  for ( i = 1; i <= npoints; ++i ) {
676  temp1 += ww(i)*yy(k,i)*xx(j,i);
677  }
678  m_moment(k,j) = temp1 /(temp3); // rescale by temp3
679  }
680  }
681  det = det3(m_moment); // will get handedness of frame from determinant
682 
683  if ( std::abs(det) <= 1.0E-24 ) {
684  // // std::cerr << "Warning:degenerate cross moments: det=" << det << std::endl;
685  // // might think about returning a zero rms, to avoid any chance of Floating Point Errors?
686 
687  esq = 0.0;
688  return;
689 
690  }
691  handedness = numeric::sign_transfered(det, 1.0);
692  // // weird but documented fortran "feature" of sign(a,b) (but not SIGN) is that if fails if a < 0
693 
694  // // multiply cross moments by itself
695 
696  for ( i = 1; i <= 3; ++i ) {
697  for ( j = i; j <= 3; ++j ) {
698  rr_moment(j,i) = rr_moment(i,j) = // well it is symmetric afterall
699  m_moment(1,i)*m_moment(1,j) +
700  m_moment(2,i)*m_moment(2,j) +
701  m_moment(3,i)*m_moment(3,j);
702  }
703  }
704 
705  // // compute eigen values of cross-cross moments
706 
707  rsym_eigenval(rr_moment,ev);
708 
709  // // reorder eigen values so that ev(3) is the smallest eigenvalue
710 
711  if ( ev(2) > ev(3) ) {
712  if ( ev(3) > ev(1) ) {
713  temp1 = ev(3);
714  ev(3) = ev(1);
715  ev(1) = temp1;
716  }
717  } else {
718  if ( ev(2) > ev(1) ) {
719  temp1 = ev(3);
720  ev(3) = ev(1);
721  ev(1) = temp1;
722  } else {
723  temp1 = ev(3);
724  ev(3) = ev(2);
725  ev(2) = temp1;
726  }
727  }
728 
729  // // ev(3) is now the smallest eigen value. the other two are not
730  // // sorted. this is prefered order for rotation matrix
731 
732 
733  rsym_rotation(m_moment,rr_moment,ev,R);
734 
735  //$$$ for ( i = 1; i <= npoints; ++i ) {
736  //$$$ for ( j = 1; j <= 3; ++j ) {
737  //$$$ temp1 = 0.0;
738  //$$$ for ( k = 1; k <= 3; ++k ) {
739  //$$$ temp1 += R(j,k)*yy(k,i);
740  //$$$ }
741  //$$$ t(j) = temp1;
742  //$$$ }
743  //$$$ yy(1,i) = t(1);
744  //$$$ yy(2,i) = t(2);
745  //$$$ yy(3,i) = t(3);
746  //$$$ }
747 
748  for ( i = 1; i <= npoints; ++i ) {
749  if ( realign ) { //Undo the offset:
750  xx(3,i) += offset_val;
751  yy(3,i) -= offset_val;
752  }
753  for ( j = 1; j <= 3; ++j ) { // compute rotation
754  t(j) = R(j,1)*yy(1,i) + R(j,2)*yy(2,i) + R(j,3)*yy(3,i);
755  }
756  yy(1,i) = t(1);
757  yy(2,i) = t(2);
758  yy(3,i) = t(3);
759  }
760  // // now we must catch the special case of the rotation with inversion.
761  // // we cannot allow inversion rotations.
762  // // fortunatley, and curiously, the optimal non-inverted rotation matrix
763  // // will have the similar eigen values.
764  // // we just have to make a slight change in how we handle things depending on determinant
765 
766  rms_ctx = std::sqrt(std::abs(ev(1))) + std::sqrt(std::abs(ev(2))) +
767  handedness*std::sqrt(std::abs(ev(3)));
768 
769  rms_ctx *= temp3;
770 
771  // // the std::abs() are theoretically unneccessary since the eigen values of a real symmetric
772  // // matrix are non-negative. in practice sometimes small eigen vals end up just negative
773  rms_sum = 0.0;
774  for ( i = 1; i <= npoints; ++i ) {
775  for ( j = 1; j <= 3; ++j ) {
776  rms_sum += ww(i)*( ( yy(j,i) * yy(j,i) ) + ( xx(j,i) * xx(j,i) ) );
777  }
778  }
779  // rms_sum = rms_sum; // /temp3 (will use natsel instead)
780 
781  // // and combine the outer and cross terms into the final calculation.
782  // // (the std::abs() just saves us a headache when the roundoff error accidantally makes the sum negative)
783 
784  esq = std::sqrt( std::abs( rms_sum - ( 2.0 * rms_ctx ) ) / natsel );
785 
786 } // rmsfitca2
787 
788 
789 void
791  int npoints, // number of points to fit
796  double & esq
797 )
798 {
799 
800  xx0.dimension( 3, npoints );
801  xx.dimension ( 3, npoints );
802  yy0.dimension( 3, npoints );
803  yy.dimension ( 3, npoints );
804 
805  // local
806  double det;
807  double temp1,mass;
808  FArray1D< double > come( 3 );
809  FArray1D< double > comp( 3 );
810  FArray1D< double > ev( 3 );
811  FArray2D< double > m_moment( 3, 3 );
812  FArray2D< double > rr_moment( 3, 3 );
813  double rms_ctx,rms2_sum;
814  double handedness;
815 
816  FArray2D< double > r( 3, 3 );
817  FArray1D< double > t( 3 );
818 
819 
820  // compute center of mass
821  numeric::model_quality::RmsData* rmsdata = RmsData::instance(); // get a pointer to the singleton class
822 
823  mass = rmsdata->count();
824  double xre = rmsdata->xre();
825  double xrp = rmsdata->xrp();
826  FArray1D< double > xse = rmsdata->xse();
827  FArray1D< double > xsp = rmsdata->xsp();
828  FArray2D< double > xm = rmsdata->xm();
829 
830  // std::cerr << mass << " " << xre << " " << xrp << " " << xse(1) << " " << xse(2) << " " << xse(3) << " "
831  // << xsp(1) << " " << xsp(2) << " " << xsp(3) << " " << xm(1,1) << " " << xm(1, 2) << std::endl;
832 
833 
834  come(1) = xse(1)/mass; // x_com
835  come(2) = xse(2)/mass; // y_com
836  come(3) = xse(3)/mass; // z_com
837 
838  comp(1) = xsp(1)/mass; // x_com
839  comp(2) = xsp(2)/mass; // y_com
840  comp(3) = xsp(3)/mass; // z_com
841 
842 
843  // Make cross moments matrix
844 
845  for ( int k = 1; k <= 3; ++k ) {
846  for ( int j = 1; j <= 3; ++j ) {
847  m_moment(k,j) = xm(k,j)/mass - come(k)*comp(j); // flopped com
848  }
849  }
850 
851  det = det3(m_moment); // get handedness of frame from determinant
852 
853  if ( std::abs(det) <= 1.0E-24 ) {
854  // //std::cerr << "Warning:degenerate cross moments: det=" << det << std::endl;
855  // // might think about returning a zero rms, to avoid any chance of
856  // // Floating Point Errors?
857 
858  esq = 0.0;
859  return;
860 
861  }
862  handedness = numeric::sign_transfered(det, 1.0); // changed name of call from sign to sign_transfered in mini!
863  /// OL and order of arguments -- damn
864 
865  // std::cerr << handedness << std::endl;
866  // // weird but documented "feature" of sign(a,b) (but not SIGN) is
867  // // that if fails if a < 0
868 
869  // // multiply cross moments by itself
870 
871  for ( int i = 1; i <= 3; ++i ) {
872  for ( int j = i; j <= 3; ++j ) {
873  rr_moment(j,i) = rr_moment(i,j) =
874  m_moment(1,i)*m_moment(1,j) +
875  m_moment(2,i)*m_moment(2,j) +
876  m_moment(3,i)*m_moment(3,j);
877  }
878  }
879 
880  // // compute eigen values of cross-cross moments
881 
882  rsym_eigenval(rr_moment,ev);
883 
884 
885  // // reorder eigen values so that ev(3) is the smallest eigenvalue
886 
887  if ( ev(2) > ev(3) ) {
888  if ( ev(3) > ev(1) ) {
889  temp1 = ev(3);
890  ev(3) = ev(1);
891  ev(1) = temp1;
892  }
893  } else {
894  if ( ev(2) > ev(1) ) {
895  temp1 = ev(3);
896  ev(3) = ev(1);
897  ev(1) = temp1;
898  } else {
899  temp1 = ev(3);
900  ev(3) = ev(2);
901  ev(2) = temp1;
902  }
903  }
904 
905  // // ev(3) is now the smallest eigen value. the other two are not
906  // // sorted. This is prefered order for computing the rotation matrix
907 
908  rsym_rotation(m_moment,rr_moment,ev,r);
909 
910  // // now we rotate and offset all npoints
911 
912 
913  for ( int i = 1; i <= npoints; ++i ) {
914  for ( int k = 1; k <= 3; ++k ) { // remove center of mass
915  yy(k,i) = yy0(k,i)-come(k);
916  xx(k,i) = xx0(k,i)-comp(k);
917  }
918  for ( int j = 1; j <= 3; ++j ) { // compute rotation
919  // // temp1 = 0.0;
920  // // for ( k = 1; k <= 3; ++k ) {
921  // // temp1 += r(j,k)*yy(k,i);
922  // // }
923  // // t(j) = temp1;
924  t(j) = r(j,1)*yy(1,i) + r(j,2)*yy(2,i) + r(j,3)*yy(3,i);
925 
926  }
927  yy(1,i) = t(1);
928  yy(2,i) = t(2);
929  yy(3,i) = t(3);
930  }
931 
932  // // now we must catch the special case of the rotation with inversion.
933  // // fortunatley, and curiously, the optimal non-inverted rotation
934  // // matrix will have a similar relation between rmsd and the eigen values.
935  // // we just have to make a slight change in how we handle things
936  // // depending on determinant
937 
938  rms_ctx = std::sqrt(std::abs(ev(1))) + std::sqrt(std::abs(ev(2))) +
939  handedness*std::sqrt(std::abs(ev(3)));
940  // std::cerr << handedness << std::endl;
941  // // the std::abs() are theoretically unneccessary since the eigen values
942  // // of a real symmetric matrix are non-negative.
943  // // in practice sometimes small eigen vals end up as tiny negatives.
944 
945  temp1 = ( come(1) * come(1) ) + ( come(2) * come(2) ) + ( come(3) * come(3) ) +
946  ( comp(1) * comp(1) ) + ( comp(2) * comp(2) ) + ( comp(3) * comp(3) );
947 
948  rms2_sum = (xre + xrp)/mass - temp1;
949 
950  // // and combine the outer and cross terms into the final calculation.
951  // // (the std::abs() just saves us a headache when the roundoff error
952  // // accidantally makes the sum negative)
953 
954  esq = std::sqrt(std::abs(rms2_sum-2.0*rms_ctx));
955 
956 } // rmsfitca3
957 
958 double
960 {
961 
962  m.dimension( 3, 3 );
963 
964  return
965  m(1,3)*( m(2,1)*m(3,2) - m(2,2)*m(3,1) ) -
966  m(2,3)*( m(1,1)*m(3,2) - m(1,2)*m(3,1) ) +
967  m(3,3)*( m(1,1)*m(2,2) - m(1,2)*m(2,1) );
968 }
969 
970 
971 void
975 )
976 {
977  m.dimension( 3, 3 );
978  ev.dimension( 3 );
979 
980 
981  double xx,yy,zz,xy,xz,yz;
982  double a,b,c,s0;
983  std::complex< double > f1,f2,f3,f4,f5;
984 
985  static std::complex< double > const unity = std::complex< double >(1.0,0.0);
986  static std::complex< double > const sqrt_3i =
987  std::sqrt( 3.0 ) * std::complex< double >(0.0,1.0);
988 
989  // first, for lexical sanity, name some temporary variables
990  xx = m(1,1);
991  yy = m(2,2);
992  zz = m(3,3);
993  xy = m(1,2);
994  xz = m(1,3);
995  yz = m(2,3);
996 
997  // coefficients of characterisitic polynomial
998  a = xx+yy+zz;
999  b = -xx*zz-xx*yy-yy*zz+xy*xy+xz*xz+yz*yz;
1000  c = xx*yy*zz-xz*xz*yy-xy*xy*zz-yz*yz*xx+2*xy*xz*yz;
1001 
1002  // For numerical dynamic range we rescale the variables here
1003  // with rare exceptions this is unnessary but it doesn't add much to the calculation time.
1004  // this also allows use of double if desired. cems
1005  // for complex< float > the rescaling trigger should be 1e15 (or less)
1006  // for complex< double > the rescaling trigger should be 1e150 (or less)
1007  // note we completely ignore the possiblity of needing rescaling to avoid
1008  // underflow due to too small numbers. left as an excercise to the reader.
1009 
1010  double norm = std::max(std::abs(a),std::max(std::abs(b),std::abs(c)));
1011  if ( norm > 1.0E50 ) { // rescaling trigger
1012  a /= norm;
1013  b /= norm * norm;
1014  c /= norm * norm * norm;
1015  } else {
1016  norm = 1.0;
1017  }
1018  // we undo the scaling by de-scaling the eigen values at the end
1019 
1020  // Power constants
1021  double const a2 = a * a;
1022  double const a3 = a * a * a;
1023 
1024  // eigenvals are the roots of the characteristic polymonial 0 = c + b*e + a*e^2 - e^3
1025  // solving for the three roots now:
1026  // dont try to follow this in detail: its just a tricky
1027  // factorization of the formulas for cubic equation roots.
1028 
1029  s0 = ( -12.0 * ( b * b * b ) ) - ( 3.0 * ( b * b ) * a2 ) +
1030  ( 54.0 * c * b * a ) + ( 81.0 * ( c * c ) ) + ( 12.0 * c * a3 );
1031  // butt ugly term
1032 
1033  f1 = b*a/6.0 + c/2.0 + a3/27.0 + std::sqrt(s0*unity)/18.0;
1034 
1035  f2 = std::pow( f1, (1.0/3.0) ); // note f1 is a complex number
1036 
1037  f3 = (-b/3.0 - a2/9.0)/f2;
1038 
1039  f4 = f2-f3;
1040 
1041  f5 = sqrt_3i * (f2+f3); // just our imaginary friend, mr. i
1042 
1043  s0 = a/3.0;
1044  ev(1) = f4.real();
1045  // note implicitly take real part, imag part "should" be zero
1046  ev(1) = norm*(ev(1)+s0 );
1047  // do addition after type conversion in previous line.
1048  ev(2) = (-f4+f5).real(); // note real part, imag part is zero
1049  ev(2) = norm*(ev(2)*0.5 + s0 );
1050  ev(3) = (-f4-f5).real(); // note real part, imag part is zero
1051  ev(3) = norm*(ev(3)*0.5 + s0);
1052 
1053 }
1054 
1055 void
1061 )
1062 {
1063  mm.dimension( 3, 3 );
1064  m.dimension( 3, 3 );
1065  ev.dimension( 3 );
1066  rot.dimension( 3, 3 );
1067 
1068 
1069  FArray2D< double > temp( 3, 3 );
1070  FArray2D< double > mvec( 3, 3 );
1071 
1072  rsym_evector(m,ev,mvec);
1073 
1074  for ( int i = 1; i <= 2; ++i ) { // dont need no stinkin third component
1075  double norm = 1.0 / std::sqrt(std::abs(ev(i) )); // abs just fixes boo boos
1076  // if one was nervous here one could explicitly
1077  // compute the norm of temp.
1078  for ( int j = 1; j <= 3; ++j ) {
1079  temp(j,i) = 0.0;
1080  for ( int k = 1; k <= 3; ++k ) {
1081  temp(j,i) += mvec(k,i)*mm(j,k);
1082  }
1083  temp(j,i) *= norm;
1084  }
1085  }
1086 
1087  temp(1,3) = temp(2,1)*temp(3,2) - temp(2,2)*temp(3,1);
1088  temp(2,3) = -temp(1,1)*temp(3,2) + temp(1,2)*temp(3,1);
1089  temp(3,3) = temp(1,1)*temp(2,2) - temp(1,2)*temp(2,1);
1090 
1091  for ( int i = 1; i <= 3; ++i ) {
1092  for ( int j = 1; j <= 3; ++j ) {
1093  rot(j,i) = 0.0;
1094  for ( int k = 1; k <= 3; ++k ) {
1095  rot(j,i) += temp(i,k)*mvec(j,k);
1096  }
1097  }
1098  }
1099 }
1100 
1101 
1102 void
1107 )
1108 {
1109  m.dimension( 3, 3 );
1110  ev.dimension( 3 );
1111  mvec.dimension( 3, 3 );
1112 
1113  // local
1114  double xx,yy,xy,zx,yz; //zz
1115  double e1,e2,e3,znorm;
1116 
1117 
1118  // first, for sanity only, name some temporary variables
1119  //zz = m(3,3);
1120  xy = m(1,2);
1121  zx = m(1,3);
1122  yz = m(2,3);
1123 
1124  if ( ev(1) != ev(2) ) { // test for degenerate eigen values
1125 
1126  for ( int i = 1; i <= 2; ++i ) {
1127  // only computer first two eigen vectors using this method
1128  // note you could compute all three this way if you wanted to,
1129  // but you would run into problems with degenerate eigen values.
1130 
1131  xx = m(1,1)-ev(i);
1132  yy = m(2,2)-ev(i);
1133  // I marvel at how simple this is when you know the eigen values.
1134  e1 = xy*yz-zx*yy;
1135  e2 = xy*zx-yz*xx;
1136  e3 = xx*yy-xy*xy;
1137 
1138  znorm = std::sqrt( ( e1 * e1 ) + ( e2 * e2 ) + ( e3 * e3 ) );
1139 
1140  mvec(1,i) = e1/znorm;
1141  mvec(2,i) = e2/znorm;
1142  mvec(3,i) = e3/znorm;
1143 
1144  }
1145 
1146  // now compute the third eigenvector
1147  mvec(1,3) = mvec(2,1)*mvec(3,2) - mvec(2,2)*mvec(3,1);
1148  mvec(2,3) = -mvec(1,1)*mvec(3,2) + mvec(1,2)*mvec(3,1);
1149  mvec(3,3) = mvec(1,1)*mvec(2,2) - mvec(1,2)*mvec(2,1);
1150 
1151  // pathologically nervous people would explicitly normalize this vector too.
1152 
1153  return;
1154 
1155  } else {
1156 
1157  if ( ev(2) != ev(3) ) {
1158  std::cerr << " hey is this the right thing to be doing??? " << std::endl;
1159 
1160  for ( int i = 2; i <= 3; ++i ) {
1161  // Okay, since 1 and 2 are degenerate we will use 2 and 3 instead.
1162 
1163  xx = m(1,1)-ev(i);
1164  yy = m(2,2)-ev(i);
1165  // I marvel at how simple this is when you know the eigen values.
1166  e1 = xy*yz-zx*yy;
1167  e2 = xy*zx-yz*xx;
1168  e3 = xx*yy-xy*xy;
1169  // yes you sharp eyed person, its not quite symmetric here too.
1170  // life is odd.
1171 
1172  znorm = std::sqrt( ( e1 * e1 ) + ( e2 * e2 ) + ( e3 * e3 ) );
1173 
1174  mvec(1,i) = e1/znorm;
1175  mvec(2,i) = e2/znorm;
1176  mvec(3,i) = e3/znorm;
1177 
1178  }
1179 
1180  // now compute the third eigenvector
1181  mvec(1,1) = mvec(2,2)*mvec(3,3) - mvec(2,3)*mvec(3,2);
1182  mvec(2,1) = -mvec(1,2)*mvec(3,3) + mvec(1,3)*mvec(3,2);
1183  mvec(3,1) = mvec(1,2)*mvec(2,3) - mvec(1,3)*mvec(2,2);
1184 
1185  // pathologically nervous people would explicitly normalize this vector too.
1186 
1187  return;
1188 
1189  } else {
1190 
1191  std::cerr << "warning: all eigen values are equal" << std::endl;
1192 
1193  for ( int i = 1; i <= 3; ++i ) {
1194  mvec(1,i) = 0.0;
1195  mvec(2,i) = 0.0;
1196  mvec(3,i) = 0.0;
1197  mvec(i,i) = 1.0;
1198  }
1199  return;
1200  }
1201  }
1202 } // rsym_evector
1203 
1204 
1205 } // rms
1206 } // numeric
ocstream cerr(std::cerr)
Wrapper around std::cerr.
Definition: ocstream.hh:290
xyzVector< T > eigenvector_jacobi(xyzMatrix< T > const &a, T const &tol, xyzMatrix< T > &J)
Classic Jacobi algorithm for the eigenvalues and eigenvectors of a real symmetric matrix...
int count()
returns the number of points in this RmsData
Definition: RmsData.hh:77
void fixEigenvector(FArray2A< numeric::Real > m_v)
Definition: rms.cc:610
RMS functions imported from rosetta++.
Coordinate norm(Coordinate const &a)
Definition: vector.cc:40
platform::Size Size
Definition: types.hh:42
void calc_rms_fast(float &rms_out, FArray2A< numeric::Real > xx, FArray2A< numeric::Real > yy, FArray1A< numeric::Real > ww, int npoints, numeric::Real ctx)
companion function for findUU ( it is optional ) computes the minimum RMS deviation beteen XX and YY ...
Definition: rms.cc:138
FArray1A & dimension(IR const &I_a)
Dimension by IndexRanges.
Definition: FArray1A.hh:680
FArray2A: Fortran-Compatible 2D Argument Array.
Definition: FArray2.hh:29
FArray1A: Fortran-Compatible 1D Argument Array.
Definition: FArray1.hh:32
FArray1: Fortran-Compatible 1D Array Abstract Base Class.
Definition: FArray1.fwd.hh:27
std::string E(int const w, int const d, float const &t)
Exponential Format: float.
Definition: format.cc:312
utility::vector1< xyzVector< T > > FArray_to_vector_of_xyzvectors(ObjexxFCL::FArray2D< T > const &input)
convert an FArray2D to a vector of xyzVectors
void rsym_eigenval(ObjexxFCL::FArray2A< double > m, ObjexxFCL::FArray1A< double > ev)
computes the eigen values of a real symmetric 3x3 matrix
Definition: rms.cc:972
Fstring::size_type index(Fstring const &s, Fstring const &ss)
First Index Position of a Substring in an Fstring.
Definition: Fstring.hh:2180
xyzVector: Fast (x,y,z)-coordinate numeric vector
FArray2A & dimension(IR const &I1_a, IR const &I2_a)
Dimension by IndexRange.
Definition: FArray2A.hh:737
ObjexxFCL::FArray1D< double > xsp()
Definition: RmsData.hh:81
FArray2: Fortran-Compatible 2D Array Abstract Base Class.
Definition: FArray2.fwd.hh:27
static RmsData * instance()
Definition: RmsData.cc:26
T abs(T const &x)
std::abs( x ) == | x |
Definition: Fmath.hh:295
std::vector with 1-based indexing
Definition: vector1.fwd.hh:44
RmsData is a class intended to replace the global rms_obj namespace from rosetta++. Initial implementation is with a singleton design pattern to mimic a global namespace from rosetta++.
Definition: RmsData.hh:31
ObjexxFCL::FArray2D< double > xm()
Definition: RmsData.hh:89
numeric::Real rms_wrapper_slow_and_correct(int natoms, FArray2D< numeric::Real > p1a, FArray2D< numeric::Real > p2a)
Definition: rms.cc:67
rosetta project type declarations. Should be kept updated with core/types.hh. This exists because num...
tuple rms
Definition: loops_kic.py:130
double Real
Definition: types.hh:39
void MatrixMult(FArray2A< numeric::Real > A, int n, int np, int transposeA, FArray2A< numeric::Real > B, int m, int transposeB, FArray2A< numeric::Real > AxB_out)
Definition: rms.cc:532
DimensionExpressionPow pow(Dimension const &dim1, Dimension const &dim2)
pow( Dimension, Dimension )
void BlankMatrixMult(FArray2A< numeric::Real > A, int n, int np, int transposeA, FArray2A< numeric::Real > B, int m, int transposeB, FArray2A< numeric::Real > AxB_out)
Definition: rms.cc:473
numeric::Real rms_wrapper(int natoms, FArray2D< numeric::Real > p1a, FArray2D< numeric::Real > p2a)
Definition: rms.cc:91
vector1: std::vector with 1-based indexing
xyzMatrix: Fast 3x3 xyz matrix template
void findUU(FArray2< numeric::Real > &XX, FArray2< numeric::Real > &YY, FArray1< numeric::Real > const &WW, int Npoints, FArray2< numeric::Real > &UU, numeric::Real &sigma3)
intended to rotate one protein xyz array onto another one such that the point-by-point rms is minimiz...
Definition: rms.cc:224
numeric::xyzMatrix< T > FArray_to_xyzmatrix(ObjexxFCL::FArray2D< T > const &input)
convert a 3x3 FArray 2D to an xyzMatrix
Numeric functions.
double det3(FArray2A< double > m)
determinant of a 3x3 matrix
Definition: rms.cc:959
xyzVector and xyzMatrix functions
void rmsfitca2(int npoints, ObjexxFCL::FArray2A< double > xx, ObjexxFCL::FArray2A< double > yy, ObjexxFCL::FArray1A< double > ww, int natsel, double &esq, double const &offset_val, bool const realign)
computes the rms between two weighted point vectors.
Definition: rms.cc:627
ObjexxFCL::FArray1D< double > xse()
Definition: RmsData.hh:85
Fast (x,y,z)-coordinate numeric vector.
void rmsfitca3(int npoints, ObjexxFCL::FArray2A< double > xx0, ObjexxFCL::FArray2A< double > xx, ObjexxFCL::FArray2A< double > yy0, ObjexxFCL::FArray2A< double > yy, double &esq)
Definition: rms.cc:790
static T max(T x, T y)
Definition: Svm.cc:19
void COMAS(ObjexxFCL::FArray1A_double C, ObjexxFCL::FArray1A_double WT, int NAT, double &XC, double &YC, double &ZC)
Definition: maxsub.cc:504
T sign_transfered(S const &sigma, T const &x)
Sign transfered value.
numeric::Real calc_rms(utility::vector1< xyzVector< Real > > p1_coords, utility::vector1< xyzVector< Real > > p2_coords)
Definition: rms.cc:47
std::string A(int const w, char const c)
char Format
Definition: format.cc:175
void rsym_evector(ObjexxFCL::FArray2A< double > m, ObjexxFCL::FArray1A< double > ev, ObjexxFCL::FArray2A< double > mvec)
Author: charlie strauss (cems) 2001 given original matrix plus its eigen values compute the eigen vec...
Definition: rms.cc:1103
void rsym_rotation(ObjexxFCL::FArray2A< double > mm, ObjexxFCL::FArray2A< double > m, ObjexxFCL::FArray1A< double > ev, ObjexxFCL::FArray2A< double > rot)
finds a (proper) rotation matrix that minimizes the rms.
Definition: rms.cc:1056
IntegerOptionKey const j
FArray2D: Fortran-Compatible 2D Array.
Definition: FArray2.hh:27
FileVectorOptionKey const t
FArray1D: Fortran-Compatible 1D Array.
Definition: FArray1.hh:30