/* *_________________________________________________________________________* * POEMS: PARALLELIZABLE OPEN SOURCE EFFICIENT MULTIBODY SOFTWARE * * DESCRIPTION: SEE READ-ME * * FILE NAME: fastmatrixops.cpp * * AUTHORS: See Author List * * GRANTS: See Grants List * * COPYRIGHT: (C) 2005 by Authors as listed in Author's List * * LICENSE: Please see License Agreement * * DOWNLOAD: Free at www.rpi.edu/~anderk5 * * ADMINISTRATOR: Prof. Kurt Anderson * * Computational Dynamics Lab * * Rensselaer Polytechnic Institute * * 110 8th St. Troy NY 12180 * * CONTACT: anderk5@rpi.edu * *_________________________________________________________________________*/ #include #include "fastmatrixops.h" #include using namespace std; // // Cross Product (friend of Vect3) // void FastCross(Vect3& a, Vect3& b, Vect3& c){ c.elements[0] = a.elements[1]*b.elements[2] - a.elements[2]*b.elements[1]; c.elements[1] = a.elements[2]*b.elements[0] - a.elements[0]*b.elements[2]; c.elements[2] = a.elements[0]*b.elements[1] - a.elements[1]*b.elements[0]; } // // Simple Rotation (friend of Vect3 and Mat3x3) // void FastSimpleRotation(Vect3& v, double q, Mat3x3& C){ // intermediate quantities double cq = cos(q); double sq = sin(q); double one_m_cq = 1-cq; double l12 = v.elements[0]*v.elements[1]*one_m_cq; double l13 = v.elements[0]*v.elements[2]*one_m_cq; double l23 = v.elements[1]*v.elements[2]*one_m_cq; // the transformation C.elements[0][0] = v.elements[0]*v.elements[0]*one_m_cq+cq; C.elements[0][1] = l12-v.elements[2]*sq; C.elements[0][2] = l13+v.elements[1]*sq; C.elements[1][0] = l12+v.elements[2]*sq; C.elements[1][1] = v.elements[1]*v.elements[1]*one_m_cq+cq; C.elements[1][2] = l23-v.elements[0]*sq; C.elements[2][0] = l13-v.elements[1]*sq; C.elements[2][1] = l23+v.elements[0]*sq; C.elements[2][2] = v.elements[2]*v.elements[2]*one_m_cq+cq; } // // Quaternion Functions // void FastQuaternions(ColMatrix& q, Mat3x3& C){ double* e = q.elements; // normalize the quaternions double length = e[0]*e[0] + e[1]*e[1] + e[2]*e[2] + e[3]*e[3]; length = sqrt(length); e[0] = e[0]/length; e[1] = e[1]/length; e[2] = e[2]/length; e[3] = e[3]/length; // compute the transformation C.elements[0][0] = e[0]*e[0] + e[1]*e[1] - e[2]*e[2] - e[3]*e[3]; C.elements[1][1] = e[0]*e[0] - e[1]*e[1] + e[2]*e[2] - e[3]*e[3]; C.elements[2][2] = e[0]*e[0] - e[1]*e[1] - e[2]*e[2] + e[3]*e[3]; C.elements[0][1] = 2 * (e[1]*e[2] - e[0]*e[3]); C.elements[0][2] = 2 * (e[1]*e[3] + e[0]*e[2]); C.elements[1][2] = 2 * (e[2]*e[3] - e[0]*e[1]); C.elements[1][0] = 2 * (e[1]*e[2] + e[0]*e[3]); C.elements[2][0] = 2 * (e[1]*e[3] - e[0]*e[2]); C.elements[2][1] = 2 * (e[2]*e[3] + e[0]*e[1]); } void FastQuaternionDerivatives(ColMatrix& q, ColMatrix& omega, ColMatrix& qdot){ double* w = omega.elements; double* e = q.elements; qdot.elements[0] = 0.5 * (-w[0]*e[1] - w[1]*e[2] - w[2]*e[3]); qdot.elements[1] = 0.5 * ( w[0]*e[0] + w[2]*e[2] - w[1]*e[3]); qdot.elements[2] = 0.5 * ( w[1]*e[0] - w[2]*e[1] + w[0]*e[3]); qdot.elements[3] = 0.5 * ( w[2]*e[0] + w[1]*e[1] - w[0]*e[2]); } void FastInvQuaternions(Mat3x3& C, ColMatrix& q){ } // // Inverse // // friend of Matrix //void FastInverse(Matrix& A, Matrix& C){ // C = A^(-1) // C.rows[0][0] = 1/A.rows[0][0]; //} // // LDL^T Decomposition (from Golub and Van Loan) // // friend of Matrix void FastLDLT(Matrix& A, Matrix& C){ // C is the LD of the LDL^T decomposition of A (SPD) double Lv; int n = A.numrows; for(int j=0;j-1;i--){ C.rows[i][k] = C.rows[i][k] / LD.rows[i][i]; temp = 0.0; for(int j=n-1;j>i;j--){ temp += C.rows[j][k] * LD.rows[j][i]; } C.rows[i][k] = C.rows[i][k] - temp; } } } // friend of Matrix void FastLDLTSubsLH(Matrix& B, Matrix& LD, Matrix& C){ int n = B.numcols; int c = B.numrows; double temp; for(int k=0;k-1;i--){ C.rows[k][i] = C.rows[k][i] / LD.rows[i][i]; temp = 0.0; for(int j=n-1;j>i;j--){ temp += C.rows[k][j] * LD.rows[j][i]; } C.rows[k][i] = C.rows[k][i] - temp; } } } // friend of Mat6x6 void FastLDLTSubs(Mat6x6& LD, Mat6x6& B, Mat6x6& C){ double temp; for(int k=0;k<6;k++){ for(int i=0;i<6;i++){ temp = 0.0; for(int j=0;j-1;i--){ C.elements[i][k] = C.elements[i][k] / LD.elements[i][i]; temp = 0.0; for(int j=5;j>i;j--){ temp += C.elements[j][k] * LD.elements[j][i]; } C.elements[i][k] = C.elements[i][k] - temp; } } } // friend of Mat6x6 & Vect6 void FastLDLTSubs(Mat6x6& LD, Vect6& B, Vect6& C){ double temp; for(int i=0;i<6;i++){ temp = 0.0; for(int j=0;j-1;i--){ C.elements[i] = C.elements[i] / LD.elements[i][i]; temp = 0.0; for(int j=5;j>i;j--){ temp += C.elements[j] * LD.elements[j][i]; } C.elements[i] = C.elements[i] - temp; } } // friend of Matrix void FastLU(Matrix& A, Matrix& LU, int *indx){ // LU is the LU decomposition of A int i,imax=0,j,k; int n = A.numrows; double big, dum, sum, temp; double vv[10000]; LU = A; for (i=0;i big) big=temp; } vv[i]=1.0/big; } for (j=0;j= big) { big=dum; imax=i; } } if (j != imax) { for (k=0;k big) big=temp; } vv[i]=1.0/big; } for (j=0;j<3;j++){ for (i=0;i= big) { big=dum; imax=i; } } if (j != imax) { for (k=0;k<3;k++) { dum=LU.BasicGet(imax,k); LU.BasicSet(imax,k,LU.BasicGet(j,k)); LU.BasicSet(j,k,dum); } vv[imax]=vv[j]; } indx[j]=imax; if (j != 3-1) { dum=1.0/(LU.BasicGet(j,j)); for (i=j+1;i<3;i++) LU.BasicSet(i,j,LU.BasicGet(i,j)*dum); } } } // friend of Mat4x4 void FastLU(Mat4x4& A, Mat4x4& LU, int *indx){ // LU is the LU decomposition of A int i,imax=0,j,k; double big, dum, sum, temp; double vv[10000]; LU = A; for (i=0;i<4;i++){ big=0.0; for (j=0;j<4;j++){ temp=fabs(LU.BasicGet(i,j)); if (temp > big) big=temp; } vv[i]=1.0/big; } for (j=0;j<4;j++){ for (i=0;i= big) { big=dum; imax=i; } } if (j != imax) { for (k=0;k<4;k++) { dum=LU.BasicGet(imax,k); LU.BasicSet(imax,k,LU.BasicGet(j,k)); LU.BasicSet(j,k,dum); } vv[imax]=vv[j]; } indx[j]=imax; if (j != 4-1) { dum=1.0/(LU.BasicGet(j,j)); for (i=j+1;i<4;i++) LU.BasicSet(i,j,LU.BasicGet(i,j)*dum); } } } // friend of Mat6x6 void FastLU(Mat6x6& A, Mat6x6& LU, int *indx){ // LU is the LU decomposition of A int i,imax=0,j,k; double big, dum, sum, temp; double vv[10000]; LU = A; for (i=0;i<6;i++){ big=0.0; for (j=0;j<6;j++){ temp=fabs(LU.BasicGet(i,j)); if (temp > big) big=temp; } vv[i]=1.0/big; } for (j=0;j<6;j++){ for (i=0;i= big) { big=dum; imax=i; } } if (j != imax) { for (k=0;k<6;k++) { dum=LU.BasicGet(imax,k); LU.BasicSet(imax,k,LU.BasicGet(j,k)); LU.BasicSet(j,k,dum); } vv[imax]=vv[j]; } indx[j]=imax; if (j != 6-1) { dum=1.0/(LU.BasicGet(j,j)); for (i=j+1;i<6;i++) LU.BasicSet(i,j,LU.BasicGet(i,j)*dum); } } } // friend of Matrix void FastLUSubs(Matrix& LU, Matrix& B, Matrix& C, int *indx){ // Appropriate Forward and Back Substitution int i,ip,j,k; int n = B.numrows; int c = B.numcols; double temp; C = B; for (k=0;k=0;i--){ temp=C.rows[i][k]; for (j=i+1;j=0;i--){ temp=C.rows[i][k]; for (j=i+1;j=0;i--){ temp=C.rows[i][k]; for (j=i+1;j=0;i--){ temp=C.rows[i][k]; for (j=i+1;j=0;i--){ temp=C_temp.rows[k][i]; for (j=i+1;j