// Matrix power by squaring: P = A^b (A is garbage on exit) static void matpow_by_squaring(double *A, int n, int b, double *P) { double *TMP; mateye(n, P); // Trivial cases if (b == 0) return; if (b == 1) { matcopy(n, A, P); return; } // General case TMP = malloc(n*n*sizeof(double)); while (b) { if (b&1) { matprod(n, P, A, TMP); matcopy(n, TMP, P); } b >>= 1; matprod(n, A, A, TMP); matcopy(n, TMP, A); } free(TMP); }
/* Generate the transpose of a dynamic Iliffe matrix. */ int transpose (dmat A, dmat ATrans) { int i, j, rowsize, colsize, error; double **a = A.el, **atrans = ATrans.el, temp; dmat TMP; rowsize = A.ub1 - A.lb1; colsize = A.ub2 - A.lb2; if (rowsize < 0 || rowsize != ATrans.ub2 - ATrans.lb2 || colsize < 0 || colsize != ATrans.ub1 - ATrans.lb1) { errno = EDOM; return (-1); } if (A.mat_sto == ATrans.mat_sto && A.lb1 == ATrans.lb1 && A.lb2 == ATrans.lb2) { for (i = 0; i <= rowsize; i++) for (j = i + 1; j <= colsize; j++) { temp = a[A.lb1 + i][A.lb2 + j]; atrans[A.lb1 + i][A.lb2 + j] = a[A.lb1 + j][A.lb2 + i]; atrans[A.lb1 + j][A.lb2 + i] = temp; } } else if (A.mat_sto == ATrans.mat_sto) { TMP = newdmat (ATrans.lb1, ATrans.ub1, ATrans.lb2, ATrans.ub2, &error); if (error) return (-2); for (i = 0; i <= rowsize; i++) for (j = 0; j <= colsize; j++) { TMP.el[ATrans.lb1 + j][ATrans.lb2 + i] = a[A.lb1 + i][A.lb2 + j]; } matcopy (TMP, ATrans); freemat (TMP); } else { for (i = 0; i <= rowsize; i++) for (j = 0; j <= colsize; j++) atrans[ATrans.lb1 + j][ATrans.lb2 + i] = a[A.lb1 + i][A.lb2 + j]; } return (0); }
void mattrans(float a[4][4]) { float r[4][4]; int i,j; for(i=0;i<4;i++) { for(j=0;j<4;j++) { r[i][j] = a[j][i]; } } matcopy(a,r); }
void matxmat(float out[4][4],float m0[4][4],float m1[4][4]) { float r[4][4]; int i,j,k; for(i=0;i<4;i++) { for(j=0;j<4;j++) { r[i][j] = 0; for(k=0;k<4;k++) { r[i][j] += m0[i][k]*m1[k][j]; } } } matcopy(out,r); return; }
void matinv4x4(float A[4][4]) { float r[4][4]; int i,j; float det = matadjoint(r,A); if (det == 0.0) return; for(i=0;i<4;i++) { for(j=0;j<4;j++) { r[i][j] /= det; } } matcopy(A,r); return; }
// Condition estimate: // Return ratio of largest/smallest singular values. //--------------------------------------------------------- double cond(ZMat& mat) //--------------------------------------------------------- { double rcond = 1.; ZVec work(2*mat.num_cols(), "work"); DVec rwork(2*mat.num_cols(), "rwork"); int info; ZMat matcopy(mat); IVec ipiv(mat.num_rows(), "ipiv"); ZGETRF(mat.num_rows(), mat.num_cols(), matcopy.data(), mat.num_rows(), ipiv.data(), info); // fprintf(stdout, "zgetrf: info=%d \n", info); // must fix this double anorm = 1.0; ZGECON('I', mat.num_cols(), matcopy.data(), mat.num_rows(), anorm, rcond, work.data(), rwork.data(), info); // fprintf(stdout, "zgecon: info=%d rcond=%lf\n", info, rcond); return 1./rcond; }