Xmipp  v3.23.11-Nereus
Classes | Macros | Functions | Variables
Common Lines (find common lines between projections)
Collaboration diagram for Common Lines (find common lines between projections):

Classes

class  CommonLine
 Commonline. More...
 
class  ProgCommonLine
 CommonLine Parameters. More...
 
class  CommonLineInfo
 

Macros

#define POW2(x)   (x*x)
 

Functions

void randomQuaternions (int k, DMatrix &qArray)
 
void saveMatrix (const char *fn, DMatrix &array)
 
void quaternionToMatrix (const DVector &q, DMatrix &rotMatrix)
 
void quaternionCommonLines (const DMatrix &quaternions, CommonLineInfo &clInfo)
 
void commonlineMatrixCheat (const DMatrix &quaternions, size_t nRays, DMatrix &clMatrix, DMatrix &clCorr)
 
void anglesRotationMatrix (size_t nRays, int i, int j, DMatrix &U)
 
int tripletRotationMatrix (const DMatrix &clMatrix, size_t nRays, int k1, int k2, int k3, DMatrix &R)
 
void computeSyncMatrix (const DMatrix &clMatrix, size_t nRays, DMatrix &sMatrix)
 
void rotationsFromSyncMatrix (const DMatrix &sMatrix)
 

Variables

constexpr signed int SMALL_TRIANGLE = -101
 

Detailed Description

Macro Definition Documentation

◆ POW2

#define POW2 (   x)    (x*x)

Definition at line 143 of file common_lines.h.

Function Documentation

◆ anglesRotationMatrix()

void anglesRotationMatrix ( size_t  nRays,
int  i,
int  j,
DMatrix U 
)

◆ commonlineMatrixCheat()

void commonlineMatrixCheat ( const DMatrix quaternions,
size_t  nRays,
DMatrix clMatrix,
DMatrix clCorr 
)

Definition at line 769 of file common_lines.cpp.

771 {
772  int n = quaternions.Xdim();
773 
774  clMatrix.initConstant(n, n, 0);
775  clCorr.initZeros(n, n);
776 
777  CommonLineInfo clInfo(nRays);
778 
779  for (int i = 0; i < n - 1; ++i)
780  for (int j = i + 1; j < n; ++j)
781  {
782  clInfo.setImages(i, j);
783  quaternionCommonLines(quaternions, clInfo);
784  dMij(clMatrix, i, j) = clInfo.getIndex(0);
785  dMij(clMatrix, j, i) = clInfo.getIndex(1);
786  dMij(clCorr, i, j) = 1.0e-8;
787  }
788 
789 }//function commonlineMatrixCheat
size_t Xdim() const
Definition: matrix2d.h:575
void quaternionCommonLines(const DMatrix &quaternions, CommonLineInfo &clInfo)
void initConstant(T val)
Definition: matrix2d.h:602
#define i
#define dMij(m, i, j)
Definition: matrix2d.h:139
#define j
void initZeros()
Definition: matrix2d.h:626
int * n

◆ computeSyncMatrix()

void computeSyncMatrix ( const DMatrix clMatrix,
size_t  nRays,
DMatrix sMatrix 
)

Definition at line 900 of file common_lines.cpp.

901 {
902  int K = clMatrix.Xdim();
903  DMatrix J, R, S(3,3);
904  J.initIdentity(3);
905  dMij(J, 2, 2) = -1;
906  int kk;
907  int result = 0;
908 
909  sMatrix.initIdentity(2*K);
910 
911  for (int k1 = 0; k1 < K - 1; ++k1)
912  {
913  for (int k2 = k1 + 1; k2 < K; ++k2)
914  {
915  kk = 0; //% Each triplet (k1,k2,k3) defines some rotation matrix from
916  // % image k1 to image k2. kk counts the number of such
917  // % rotations, that is, the number of thrid images k3 that give
918  // % rise to a rotation from image k1 to image k2. Not all
919  // % images k3 give rise to such a rotation, since, for example
920  // % the resuling triangle can be too small.
921 
922  //For now average all rotation matrixes, maybe later on
923  // we will need to store all of them for a better estimation
924  // than just average
925  S.initZeros();
926 
927  for (int k3 = 0; k3 < K; ++k3)
928  if (k3 != k1 && k3 != k2)
929  {
930  result = tripletRotationMatrix(clMatrix, nRays, k1, k2, k3, R);
931  if (result >= 0)
932  {
933  S += R;
934  ++kk;
935  }
936  std::cerr << "DEBUG_JM: triplet: " << formatString("%d %d, %d", k1, k2, k3) << std::endl;
937  std::cerr << "DEBUG_JM: R: " << R << std::endl;
938  }
939  if (kk > 0)
940  S /= kk;
941  putRotationMatrix(S, k1, k2, sMatrix);
942  putRotationMatrix(S.transpose(), k2, k1, sMatrix);
943  }
944  }
945 }//function computeSyncMatrix
size_t Xdim() const
Definition: matrix2d.h:575
void putRotationMatrix(const DMatrix &R, int k1, int k2, DMatrix &syncMatrix)
Definition: mask.h:36
int tripletRotationMatrix(const DMatrix &clMatrix, size_t nRays, int k1, int k2, int k3, DMatrix &R)
#define dMij(m, i, j)
Definition: matrix2d.h:139
String formatString(const char *format,...)
constexpr int K
void initIdentity()
Definition: matrix2d.h:673

◆ quaternionCommonLines()

void quaternionCommonLines ( const DMatrix quaternions,
CommonLineInfo clInfo 
)

Definition at line 645 of file common_lines.cpp.

648 {
649  DVector qa1(4);
650  DVector qa2(4); //quaternions k1 and k2
651  DMatrix R1, R2; //rotation matrixes
652 
653  for (int i = 0; i < 4; ++i)
654  {
655  qa1(i) = quaternions(i, clInfo.getImage(0));
656  qa2(i) = quaternions(i, clInfo.getImage(1));
657  }
658  quaternionToMatrix(qa1, R1);
659  quaternionToMatrix(qa2, R2);
660  //Should be the inversve, but transpose is fine here
661  // R1.selfInverse();
662  // R2.selfInverse();
663  R1 = R1.transpose();
664  R2 = R2.transpose();
665 
666  // % Rotated coordinate system is the columns of the rotation matrix.
667  // % We use explicit multiplication to show which column corresponds to x,
668  // % which to y, and which to z. See commonline_euler for the difference.
669  // X1=R1*([1 0 0].');
670  // Y1=R1*([0 1 0].');
671  // Z1=R1*([0 0 1].');
672  //
673  // X2=R2*([1 0 0].');
674  // Y2=R2*([0 1 0].');
675  // Z2=R2*([0 0 1].');
676  //
677  // Z3=[Z1(2)*Z2(3)-Z1(3)*Z2(2);...
678  // Z1(3)*Z2(1)-Z1(1)*Z2(3);...
679  // Z1(1)*Z2(2)-Z1(2)*Z2(1)];
680  DVector X1, Y1, Z1, X2, Y2, Z2;
681  DVector &Z3 = clInfo.vector;
682  R1.getCol(0, X1);
683  R1.getCol(1, Y1);
684  R1.getCol(2, Z1);
685 
686  R2.getCol(0, X2);
687  R2.getCol(1, Y2);
688  R2.getCol(2, Z2);
689 
690  XX(Z3) = YY(Z1) * ZZ(Z2) - ZZ(Z1) * YY(Z2);
691  YY(Z3) = ZZ(Z1) * XX(Z2) - XX(Z1) * ZZ(Z2);
692  ZZ(Z3) = XX(Z1) * YY(Z2) - YY(Z1) * XX(Z2);
693 
694  double normZ3 = Z3.module();
695 
696  if (normZ3 < 1.0e-8)
697  REPORT_ERROR(ERR_NUMERICAL, "GCAR:normTooSmall','Images have same orientation");
698 
699  Z3 /= normZ3;
700  DVector Z3_t(Z3);
701  Z3_t.selfTranspose();
702 
703  // % Compute coordinates of the common-line in each local coordinate system.
704  // XY1=[X1 Y1];
705  // XY2=[X2 Y2];
706  // c1=(Z3.')*XY1;
707  // c2=(Z3.')*XY2;
708  DMatrix XY1(3, 2), XY2(3, 2);
709  XY1.setCol(0, X1);
710  XY1.setCol(1, Y1);
711  XY2.setCol(0, X2);
712  XY2.setCol(1, Y2);
713  DVector c1 = Z3_t * XY1;
714  DVector c2 = Z3_t * XY2;
715  // % Verify that the common-line is indeed common to both planes. The
716  // % following warning should never happen! Just to make sure nothing went
717  // % terribly wrong.
718  // ev1=XY1*c1(:)-Z3;
719  // ev2=XY2*c2(:)-Z3;
720  c1.selfTranspose();
721  c2.selfTranspose();
722  DVector ev1 = XY1 * c1 - Z3;
723  DVector ev2 = XY2 * c2 - Z3;
724 
725  double normEv1 = ev1.module() / normZ3;
726  double normEv2 = ev2.module() / normZ3;
727 
728  if (normEv1 > 1.0e-12 || normEv2 > 1.0e-12)
730  formatString("GCAR:largeErrors: Common line is not common. Error1 = %f, Error2 = %f", normEv1, normEv2));
731  // % Compute angle of the common line at each projection's coordinate system
732  // theta1=atan2(c1(2),c1(1));
733  // theta2=atan2(c2(2),c2(1));
734  //
735  // PI=4*atan(1.0);
736  // theta1=theta1+PI; % Shift from [-pi,pi] to [0,2*pi].
737  // theta2=theta2+PI;
738  //std::cerr << "DEBUG_JM: c1: " << c1 <<std::endl;
739  //std::cerr << "DEBUG_JM: c2: " << c2 << std::endl;
740  double theta1 = atan2(YY(c1), XX(c1)) + PI;
741  double theta2 = atan2(YY(c2), XX(c2)) + PI;
742  //
743  clInfo.setIndex(0, theta1);
744  clInfo.setIndex(1, theta2);
745 }//function quaternionCommonLines
double module() const
Definition: matrix1d.h:983
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
void setIndex(int i, double theta)
Definition: common_lines.h:184
int getImage(int i)
Definition: common_lines.h:168
Matrix2D< T > transpose() const
Definition: matrix2d.cpp:1314
void selfTranspose()
Definition: matrix1d.h:944
#define i
Definition: mask.h:36
#define XX(v)
Definition: matrix1d.h:85
void quaternionToMatrix(const DVector &q, DMatrix &rotMatrix)
Error related to numerical calculation.
Definition: xmipp_error.h:179
#define YY(v)
Definition: matrix1d.h:93
void getCol(size_t j, Matrix1D< T > &v) const
Definition: matrix2d.cpp:890
Definition: ctf.h:38
String formatString(const char *format,...)
#define PI
Definition: tools.h:43
#define ZZ(v)
Definition: matrix1d.h:101

◆ quaternionToMatrix()

void quaternionToMatrix ( const DVector q,
DMatrix rotMatrix 
)

Definition at line 601 of file common_lines.cpp.

602 {
603  // function rot_matrix = q_to_rot(q)
604  // %
605  // % Convert a quaternion into a rotation matrix.
606  // %
607 #define q0 dMi(q, 0)
608 #define q1 dMi(q, 1)
609 #define q2 dMi(q, 2)
610 #define q3 dMi(q, 3)
611 
612  rotMatrix.resize(3, 3);
613 
614  rotMatrix(0, 0) = POW2(q0) + POW2(q1) - POW2(q2) - POW2(q3);
615  rotMatrix(0, 1) = 2 * q1 * q2 - 2 * q0 * q3;
616  rotMatrix(0, 2) = 2 * q0 * q2 + 2 * q1 * q3;
617 
618  rotMatrix(1, 0) = 2 * q1 * q2 + 2 * q0 * q3;
619  rotMatrix(1, 1) = POW2(q0) - POW2(q1) + POW2(q2) - POW2(q3);
620  rotMatrix(1, 2) = -2 * q0 * q1 + 2 * q2 * q3;
621 
622  rotMatrix(2, 0) = -2 * q0 * q2 + 2 * q1 * q3;
623  rotMatrix(2, 1) = 2 * q0 * q1 + 2 * q2 * q3;
624  rotMatrix(2, 2) = POW2(q0) - POW2(q1) - POW2(q2) + POW2(q3);
625 
626  //saveMatrix("rot_matrix.txt", rotMatrix);
627 }
#define q0
#define q1
#define q2
#define POW2(x)
Definition: common_lines.h:143
void resize(size_t Ydim, size_t Xdim, bool noCopy=false)
Definition: matrix2d.cpp:1022
#define q3

◆ randomQuaternions()

void randomQuaternions ( int  k,
DMatrix qArray 
)

Definition at line 546 of file common_lines.cpp.

547 {
548  // function q=qrand(K)
549  // %
550  // % q=qrand(K)
551  // %
552  // % Generate K random uniformly distributed quaternions.
553  // % Each quaternions is a four-elements column vector. Returns a matrix of
554  // % size 4xK.
555  // %
556  // % The 3-sphere S^3 in R^4 is a double cover of the rotation group SO(3),
557  // % SO(3) = RP^3.
558  // % We identify unit norm quaternions a^2+b^2+c^2+d^2=1 with group elements.
559  // % The antipodal points (-a,-b,-c,-d) and (a,b,c,d) are identified as the
560  // % same group elements, so we take a>=0.
561  // %
562  quaternions.initGaussian(4, k);
563  //quaternions.resize(4, k);
564  //quaternions.initRandom(0., 1.);
565  saveMatrix("random_numbers.txt", quaternions);
566 
567  DVector q(4);
568 
569  for (int j = 0; j < k; ++j)
570  {
571  //Get the j-column that is the quaternion
572  quaternions.getCol(j, q);
573  q.selfNormalize();
574  if (XX(q) < 0)
575  q *= -1;
576  quaternions.setCol(j, q);
577  }
578  saveMatrix("random_quaternions.txt", quaternions);
579 }
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
#define XX(v)
Definition: matrix1d.h:85
#define j
Definition: ctf.h:38
void saveMatrix(const char *fn, DMatrix &matrix)

◆ rotationsFromSyncMatrix()

void rotationsFromSyncMatrix ( const DMatrix sMatrix)

Definition at line 947 of file common_lines.cpp.

948 {
949  int K = sMatrix.Xdim() / 2;
950  int Kx3 = 3 * K;
951 
952  DMatrix U, V, V1(3, K), V2(3, K);
953  DVector W;
954  IVector indexes;
955  sMatrix.svd(U, W, V);
956  indexes.resizeNoCopy(W);
957  indexes.enumerate();
958 
959  //std::cerr << "DEBUG_JM: W: " << W << std::endl;
960 
961 #define SORTED_INDEX(i) dMi(indexes, i)
962 #define SORTED_ELEM(M, i) dMi(M, SORTED_INDEX(i))
963 
964  //Order by insertion sort
965  int iAux;
967  for (int j = i; j > 0 && SORTED_ELEM(W, j) > SORTED_ELEM(W, j-1); --j)
968  VEC_SWAP(indexes, j, j-1, iAux);
969 
970 // std::cerr << "DEBUG_JM: VEC_XSIZE(indexes): " << VEC_XSIZE(indexes) << std::endl;
971 // std::cerr << "DEBUG_JM: 10 bigger eigenvalues:" <<std::endl;
972 // std::cerr << "DEBUG_JM: indexes: " << indexes << std::endl;
973 // for (int i = 0; i < VEC_XSIZE(indexes); ++i)
974 // std::cerr << SORTED_ELEM(W, i) << std::endl;
975 
976  for (int i = 0; i < K; ++i)
977  {
978  iAux = 2 * i;
979  for (int j = 0; j < 3; ++j)
980  {
981  dMij(V1, j, i) = dMij(V, iAux, SORTED_INDEX(j));
982  dMij(V2, j, i) = dMij(V, iAux+1, SORTED_INDEX(j));
983  }
984  }
985 
986  std::cerr << "DEBUG_JM: V1: " << V1 << std::endl;
987  std::cerr << "DEBUG_JM: V2: " << V2 << std::endl;
988 
989  //% 3*K equations in 9 variables (3 x 3 matrix entries).
990  DMatrix equations(Kx3, 9);
991  int index;
992 
993  for (int k = 0; k < K; ++k)
994  for (int i = 0; i < 3; ++i)
995  for (int j = 0; j < 3; ++j)
996  {
997  index = 3 * i + j;
998  iAux = 3 * k;
999  dMij(equations, iAux, index) = dMij(V1, i, k) * dMij(V1, j, k);
1000  dMij(equations, iAux+1, index) = dMij(V2, i, k) * dMij(V2, j, k);
1001  dMij(equations, iAux+2, index) = dMij(V1, i, k) * dMij(V2, j, k);
1002  }
1003 // std::cerr << "DEBUG_JM: equations: " << equations << std::endl;
1004  PseudoInverseHelper pih;
1005 
1006  DMatrix &trunc_equations = pih.A;
1007  trunc_equations.resizeNoCopy(Kx3, 6);
1008  //Use vector W to select columns from equations
1009  int cols[6] = {0, 1, 2, 4, 5, 8};
1010  for (int i = 0; i < 6; ++i)
1011  {
1012  equations.getCol(cols[i], W);
1013  trunc_equations.setCol(i, W);
1014  }
1015 
1016  DVector &b = pih.b;
1017  b.initConstant(Kx3, 1.);
1018  for (int i = 2; i < Kx3; i+=3)
1019  dMi(b, i) = 0.;
1020 
1021  //% Find the least squares approximation
1022  DVector ATA_vec;
1023  DMatrix ATA(3, 3);
1024 
1025  //C
1026  solveLinearSystem(pih, ATA_vec);
1027 
1028 // std::cerr << "DEBUG_JM: trunc_equations: " << trunc_equations << std::endl;
1029 // saveMatrix("truncated.txt", trunc_equations);
1030 // std::cerr << "DEBUG_JM: b: " << b << std::endl;
1031 // std::cerr << "DEBUG_JM: ATA_vec: " << ATA_vec << std::endl;
1032 
1033  dMij(ATA, 0, 0) = dMi(ATA_vec, 0);
1034  dMij(ATA, 0, 1) = dMi(ATA_vec, 1);
1035  dMij(ATA, 0, 2) = dMi(ATA_vec, 2);
1036  dMij(ATA, 1, 0) = dMi(ATA_vec, 1);
1037  dMij(ATA, 1, 1) = dMi(ATA_vec, 3);
1038  dMij(ATA, 1, 2) = dMi(ATA_vec, 4);
1039  dMij(ATA, 2, 0) = dMi(ATA_vec, 2);
1040  dMij(ATA, 2, 1) = dMi(ATA_vec, 4);
1041  dMij(ATA, 2, 2) = dMi(ATA_vec, 5);
1042 
1043  std::cerr << "DEBUG_JM: ATA: " << ATA << std::endl;
1044 
1045  DMatrix A, R1, R2;
1046  cholesky(ATA, A);
1047  A = A.transpose();
1048 
1049  std::cerr << "DEBUG_JM: A: " << A << std::endl;
1050 
1051  R1 = A * V1;
1052  R2 = A * V2;
1053  //DMatrix R3(R1);
1054  DVector v1, v2, v3(3);
1055  std::vector<DMatrix> rotations(K);
1056 
1057  MetaDataVec MD("images.xmd");
1058  auto idIt(MD.ids().begin());
1059  for (int i = 0; i < K; ++i)
1060  {
1061  DMatrix &R = rotations[i];
1062  R.resizeNoCopy(3, 3);
1063  R1.getCol(i, v1);
1064  R2.getCol(i, v2);
1065  vectorProduct(v1, v2, v3);
1066  //R3.setCol(i, v3);
1067  R.setCol(0, v1);
1068  R.setCol(1, v2);
1069  R.setCol(2, v3);
1070  //% Enforce R to be a rotation (in case the error is large)
1071  R.svd(U, W, V);
1072  R = U * V.transpose();
1073 
1074  double rot, tilt, psi;
1075  //
1076  Euler_matrix2angles(R.transpose(), rot, tilt, psi);
1077  MD.setValue(MDL_ANGLE_ROT,rot,*idIt);
1078  MD.setValue(MDL_ANGLE_TILT,tilt,*idIt);
1079  MD.setValue(MDL_ANGLE_PSI,psi,*idIt);
1080  ++idIt;
1081 
1082  std::cerr << "DEBUG_JM: R" << i << " : " << R << std::endl;
1083  }
1084  MD.write("imagesReconstruction.xmd");
1085 }//function rotationsFromSyncMatrix
size_t Xdim() const
Definition: matrix2d.h:575
#define SORTED_INDEX(i)
Rotation angle of an image (double,degrees)
#define VEC_SWAP(v, i, j, aux)
Definition: matrix1d.h:248
Tilting angle of an image (double,degrees)
Special label to be used when gathering MDs in MpiMetadataPrograms.
void enumerate()
Definition: matrix1d.cpp:98
Matrix2D< T > transpose() const
Definition: matrix2d.cpp:1314
Matrix1D< T > vectorProduct(const Matrix1D< T > &v1, const Matrix1D< T > &v2)
Definition: matrix1d.h:1165
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
void resizeNoCopy(int Ydim, int Xdim)
Definition: matrix2d.h:534
Definition: mask.h:36
#define FOR_ALL_ELEMENTS_IN_MATRIX1D(v)
Definition: matrix1d.h:72
doublereal * b
double v1
Matrix1D< double > b
void cholesky(const Matrix2D< double > &M, Matrix2D< double > &L)
Definition: matrix2d.cpp:160
viol index
Matrix2D< double > A
#define dMij(m, i, j)
Definition: matrix2d.h:139
void setCol(size_t j, const Matrix1D< T > &v)
Definition: matrix2d.cpp:929
#define SORTED_ELEM(M, i)
void solveLinearSystem(PseudoInverseHelper &h, Matrix1D< double > &result)
#define dMi(v, i)
Definition: matrix1d.h:246
#define j
void getCol(size_t j, Matrix1D< T > &v) const
Definition: matrix2d.cpp:890
void svd(Matrix2D< double > &U, Matrix1D< double > &W, Matrix2D< double > &V) const
Definition: matrix2d.h:1124
Definition: ctf.h:38
double psi(const double x)
void write(const FileName &fn) const
Definition: matrix2d.cpp:113
void Euler_matrix2angles(const Matrix2D< double > &A, double &alpha, double &beta, double &gamma, bool homogeneous)
Definition: geometry.cpp:839
void resizeNoCopy(int Xdim)
Definition: matrix1d.h:458
constexpr int K
void initConstant(T val)
Definition: matrix1d.cpp:83

◆ saveMatrix()

void saveMatrix ( const char *  fn,
DMatrix array 
)

Definition at line 581 of file common_lines.cpp.

582 {
583  std::fstream fs;
584  fs.open(fn, std::fstream::trunc | std::fstream::out);
585  fs.precision(16);
586 
587  for (size_t j = 0; j < MAT_YSIZE(matrix); ++j)
588  {
589  for (size_t i = 0; i < MAT_XSIZE(matrix); ++i)
590  {
591  fs << std::scientific << dMij(matrix, j, i) << "\t";
592  //std::cerr << dAij(matrix, j, i) << " ";
593  }
594  fs << std::endl;
595  //std::cerr << std::endl;
596  }
597  fs.close();
598  //std::cerr << "DEBUG_JM: leaving saveMatrix" <<std::endl;
599 }
#define MAT_YSIZE(m)
Definition: matrix2d.h:124
#define i
#define dMij(m, i, j)
Definition: matrix2d.h:139
#define j
int trunc(double x)
Definition: ap.cpp:7248
#define MAT_XSIZE(m)
Definition: matrix2d.h:120

◆ tripletRotationMatrix()

int tripletRotationMatrix ( const DMatrix clMatrix,
size_t  nRays,
int  k1,
int  k2,
int  k3,
DMatrix R 
)

Negative output means error -101 Triangle too small

Definition at line 835 of file common_lines.cpp.

837 {
838  DMatrix G(3, 3), Q;
839  // % Find Q12, Q13, Q23
840  double factor = TWOPI / nRays;
841  double a = cos(factor * (cl(3,2)-cl(3,1)));
842  double b = cos(factor * (cl(2,3)-cl(2,1)));
843  double c = cos(factor * (cl(1,3)-cl(1,2)));
844 
845  if (1 + 2 * a * b * c - (POW2(a) + POW2(b) + POW2(c))<1.0e-5)
846  return SMALL_TRIANGLE;
847 
848  G.initIdentity();
849  // Compute G matrix according to (4.2)
850  dMij(G, 0, 1) = a;
851  dMij(G, 0, 2) = b;
852  dMij(G, 1, 0) = a;
853  dMij(G, 1, 2) = c;
854  dMij(G, 2, 0) = b;
855  dMij(G, 2, 1) = c;
856 
857  cholesky(G, Q);
858 
859  //Our cholesky gives us the lower triangular matrix
860  //so we need to transpose to have the same as in Yoel code
861  //that's why we take now rows instead of columns
862  DVector Q12, Q13, Q23;
863  Q.getRow(0, Q23);
864  Q.getRow(1, Q13);
865  Q.getRow(2, Q12);
866  Q12.setCol();
867  Q13.setCol();
868  Q23.setCol();
869 
870  DMatrix R1, R2;
871  anglesRotationMatrix( nRays, (int)cl(1, 2), (int)cl(1, 3), Q12, Q13, R1);
872  anglesRotationMatrix( nRays, (int)cl(2, 1), (int)cl(2, 3), Q12, Q23, R2);
873  // Compute rotation matrix according to (4.6)
874  R = R1.transpose() * R2;
875 
876  return 0;
877 }//function tripleRotationMatrix
doublereal * c
constexpr signed int SMALL_TRIANGLE
Definition: common_lines.h:204
void anglesRotationMatrix(size_t nRays, int clI, int clJ, const DVector &Q1, const DVector &Q2, DMatrix &R)
#define TWOPI
Definition: xmipp_macros.h:111
Matrix2D< T > transpose() const
Definition: matrix2d.cpp:1314
void setCol()
Definition: matrix1d.h:554
Definition: mask.h:36
#define cl(i, j)
doublereal * b
void cholesky(const Matrix2D< double > &M, Matrix2D< double > &L)
Definition: matrix2d.cpp:160
#define dMij(m, i, j)
Definition: matrix2d.h:139
Definition: ctf.h:38
void getRow(size_t i, Matrix1D< T > &v) const
Definition: matrix2d.cpp:871
#define POW2(x)
Definition: common_lines.h:143
doublereal * a

Variable Documentation

◆ SMALL_TRIANGLE

constexpr signed int SMALL_TRIANGLE = -101

Definition at line 204 of file common_lines.h.