static void mPower (double *A, int eA, double *V, int *eV, int m, int n) { double *B; int eB, i; if (n == 1) { for (i = 0; i < m * m; i++) V[i] = A[i]; *eV = eA; return; } mPower (A, eA, V, eV, m, n / 2); B = (double *) malloc ((m * m) * sizeof (double)); mMultiply (V, V, B, m); eB = 2 * (*eV); if (B[(m / 2) * m + (m / 2)] > NORM) renormalize (B, m, &eB); if (n % 2 == 0) { for (i = 0; i < m * m; i++) V[i] = B[i]; *eV = eB; } else { mMultiply (A, B, V, m); *eV = eA + eB; } if (V[(m / 2) * m + (m / 2)] > NORM) renormalize (V, m, eV); free (B); }
// pow(10, *eV) * V := (pow(10, eA) * A) ^ n // where dim(A) = (m,m) void mPower(double *A,int eA,double *V,int *eV,int m,int n) { double *B; int eB,i; // Base case (n = 1): copy A to V and eA to eV if(n==1) { for(i=0;i<m*m;i++) V[i]=A[i]; *eV=eA; return; } // Recursive step: // pow(10, *eV) * V := (pow(10,eA) * A) ^ floor(n/2)) mPower(A,eA,V,eV,m,n/2); B=(double*)malloc((m*m)*sizeof(double)); // pow(10, eB) * B := (pow(10, *eV) * V) ^ 2 mMultiply(V,V,B,m); eB=2*(*eV); if(n%2==0) { // if original N was even, finish by copying B to V and eB to eV for(i=0;i<m*m;i++) V[i]=B[i]; *eV=eB; } else { // if original N was odd, finish by multiplying: // pow(10, *eV) * V := (pow(10, eA) * A) * (pow(10, eB) * B) mMultiply(A,B,V,m); *eV = eA + eB; } // Finally, if center element of V is too big, move some of its exponent into *eV if (V[(m/2)*m+(m/2)] > 1e140) { for (i=0; i<m*m; i++) V[i] = V[i] * 1e-140; *eV += 140; } free(B); }
void QuaternionManipulator::qtest2() { HEADER("TEST 2 : Rotation of 90 degrees about the y-axis with matrix") Vector axis = {0.0f, 1.0f, 0.0f, 1.0f}; Quaternion q = qFromAngleAxis(90.0f, axis); qPrint(" q", q); Vector vi = {7.0f, 0.0f, 0.0f, 1.0f}; vPrint("vi", vi); Vector ve = {0.0f, 0.0f, -7.0f, 1.0f}; vPrint("ve", ve); Matrix m; qGLMatrix(q,m); Vector vf = mMultiply(m, vi); vPrint("vf", vf); assert(vEqual(vf, ve)); }