inline typename T1::pod_type op_norm::mat_norm_2(const SpProxy<T1>& P, const typename arma_real_only<typename T1::elem_type>::result* junk) { arma_extra_debug_sigprint(); arma_ignore(junk); // norm = sqrt( largest eigenvalue of (A^H)*A ), where ^H is the conjugate transpose // http://math.stackexchange.com/questions/4368/computing-the-largest-eigenvalue-of-a-very-large-sparse-matrix typedef typename T1::elem_type eT; typedef typename T1::pod_type T; const unwrap_spmat<typename SpProxy<T1>::stored_type> tmp(P.Q); const SpMat<eT>& A = tmp.M; const SpMat<eT> B = trans(A); const SpMat<eT> C = (A.n_rows <= A.n_cols) ? (A*B) : (B*A); Col<T> eigval; eigs_sym(eigval, C, 1); return (eigval.n_elem > 0) ? std::sqrt(eigval[0]) : T(0); }
void fmat_pca_from_covariance(int d,const float *cov, float *singvals, float * pcamat) { float *evals=singvals; if(!singvals) evals=fvec_new(d); if(eigs_sym(d,cov,evals,pcamat)!=0) { free(pcamat); pcamat=NULL; goto error; } eigs_reorder(d,evals,pcamat,1); /* 1 = descending */ error: if(!singvals) free(evals); }
int main() { int i, j, k, d = 10,d2=5; float * a = fvec_new (d * d); float * b = fvec_new (d * d); float * b0 = fvec_new (d * d); #define B0(i,j) b0[(i)+(j)*d] #define A(i,j) a[(i)+(j)*d] #define B(i,j) b[(i)+(j)*d] float * lambda = fvec_new (d); float * v = fvec_new (d * d); float *v_part=fvec_new (d * d2); for (i = 0 ; i < d ; i++) for (j = 0 ; j <= i ; j++) { A(i,j) = A(j,i) = drand48(); B0(i,j)=drand48(); B0(j,i)=drand48(); /* B(i,j) = B(j,i) = drand48(); */ } /* make a positive definite b (with b=b0*b0') */ for (i = 0 ; i < d ; i++) for (j = 0 ; j < d ; j++) { double accu=0; for(k=0;k<d;k++) accu+=B0(i,k)*B0(j,k); B(i,j)=accu; } printf ("a = "); fmat_print(a,d,d); printf ("\nb = "); fmat_print(b,d,d); printf ("Solution of the eigenproblem Av=lambda v\n"); printf ("\n"); int ret=eigs_sym (d, a, lambda, v); assert(ret==0); printf ("\n"); printf("Eigenvectors:\n"); fmat_print(v,d,d); fprintf(stdout, "lambda = "); fvec_print (lambda, d); printf ("\n"); printf("Partial eigenvalues/vectors:\n"); printf ("\n"); ret=eigs_sym_part (d, a, d2, lambda, v_part); assert(ret>0); if(ret<d2) printf("!!! only %d / %d eigenvalues converged\n",ret,d2); printf ("\n"); printf("Eigenvectors:\n"); fmat_print(v_part,d,d2); fprintf(stdout, "lambda = "); fvec_print (lambda, d2); printf ("\n"); printf ("Solution of the generalized eigenproblem Av=lambda B v\n"); printf ("\n"); ret=geigs_sym (d, a, b, lambda, v); assert(ret==0); printf ("\n"); fmat_print(v,d,d); fprintf(stdout, "lambda = "); fvec_print (lambda, d); printf ("\n"); free (a); free (lambda); free (v); return 0; }