int main() { int n = 100; std::vector<double> m(n*n); // fill "matrix" for (size_t i=0;i<size_t(n*n);i++) m[i] = 5*drand48(); // symmetrize: for (size_t i=0;i<size_t(n);i++) for (size_t j=i+1;j<size_t(n);j++) m[i+j*n] = m[j+i*n]; std::vector<double> eigs(n); char jobz='V'; char uplo='U'; int lda=n; std::vector<double> work(3); int info = 0; int lwork= -1; // query: dsyev_(&jobz,&uplo,&n,&(m[0]),&lda, &(eigs[0]),&(work[0]),&lwork, &info); if (info!=0) { std::cerr<<"diag: dsyev_: failed with info="<<info<<"\n"; return 1; } lwork = int(work[0])+1; work.resize(lwork+1); // real work: dsyev_(&jobz,&uplo,&n,&(m[0]),&lda, &(eigs[0]),&(work[0]),&lwork, &info); if (info!=0) { std::cerr<<"diag: dsyev_: failed with info="<<info<<"\n"; return 1; } }
/** * Diagonalize the block diagonal matrix. Needs lapack. Differs from MomHamiltonian::ExactDiagonalizeFull that * is diagonalize block per block and keeps the momentum associated with each eigenvalue. * @param calc_eigenvectors set to true to calculate the eigenvectors. The hamiltonian * matrix is then overwritten by the vectors. * @return a vector of pairs. The first member of the pair is the momentum, the second is * the eigenvalue. The vector is sorted to the eigenvalues. */ std::vector< std::pair<int,double> > MomHamiltonian::ExactMomDiagonalizeFull(bool calc_eigenvectors) { std::vector<double> eigs(dim); std::vector< std::pair<int, double> > energy; int offset = 0; for(int B=0; B<L; B++) { int dim = mombase[B].size(); Diagonalize(dim, blockmat[B].get(), &eigs[offset], calc_eigenvectors); for(int i=0; i<dim; i++) energy.push_back(std::make_pair(B,eigs[offset+i])); offset += dim; } std::sort(energy.begin(), energy.end(), [](const std::pair<int,double> & a, const std::pair<int,double> & b) -> bool { return a.second < b.second; }); return energy; }
void parallel_jacob_musictest(boost::numeric::ublas::matrix<float> M, std::string isWriteToConsole, std::ofstream fp_outs[1], int i) { int iter; auto begin = std::chrono::high_resolution_clock::now(); auto end = std::chrono::high_resolution_clock::now(); double duration = 0; matrix* A = 0; init_matrix(&A, M.size1()); make_matrix(*A, M); std::vector<float> e; // BEGIN TEST begin = std::chrono::high_resolution_clock::now(); find_eigenvalues_parallel_jacob_music(A, e, iter); end = std::chrono::high_resolution_clock::now(); // END TEST std::sort(e.begin(), e.end()); duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin).count() / 1000000.0; boost::numeric::ublas::vector<float> eigs(M.size1()); for (size_t i = 0; i < e.size(); i++) { eigs(i) = e[i]; } // INFO if (isWriteToConsole == "true") { std::string eig = "["; eig += std::to_string(M.size1()); eig += "]("; for (int i = 0; i < M.size1() - 1; i++) { eig += std::to_string(e[i]); eig += ","; } eig += std::to_string(e[M.size1() - 1]); eig += ")"; writeToAllStreams((boost::format("#%1%: \n") % i).str(), fp_outs); writeToAllStreams((boost::format("Name: %1% \nEigenvalues: %2% \nElapsed(ms): %3% \nIter: %4%") % "parallel_jacob_music"% eig%duration%iter).str(), fp_outs); writeToAllStreams("============================", fp_outs); } }
/** * Generate random samples chosen from the multivariate Gaussian * distribution with mean MU and covariance SIGMA. * * X ~ N(u, Lambda) => Y = B * X + v ~ N(B * u + v, B * Lambda * B') * Therefore, if X ~ N(0, Lambda), * then Y = B * X + MU ~ N(MU, B * Lambda * B'). * We only need to do the eigen decomposition: SIGMA = B * Lambda * B'. * * @param MU 1 x d mean vector * * @param SIGMA covariance matrix * * @param cases number of d dimensional random samples * * @return cases-by-d sample matrix subject to the multivariate * Gaussian distribution N(MU, SIGMA) * */ Matrix& mvnrnd(Matrix& MU, Matrix& SIGMA, int cases) { int d = MU.getColumnDimension(); if (MU.getRowDimension() != 1) { errf("MU is expected to be 1 x %d matrix!\n", d); } if (norm(SIGMA.transpose().minus(SIGMA)) > 1e-10) errf("SIGMA should be a %d x %d real symmetric matrix!\n", d); Matrix** eigenDecompostion = eigs(SIGMA, d, "lm"); Matrix& B = *eigenDecompostion[0]; Matrix& Lambda = *eigenDecompostion[1]; /*disp(B); disp(Lambda);*/ Matrix& X = *new DenseMatrix(d, cases); std::default_random_engine generator(time(NULL)); std::normal_distribution<double> normal(0.0, 1.0); double sigma = 0; for (int i = 0; i < d; i++) { sigma = Lambda.getEntry(i, i); if (sigma == 0) { X.setRowMatrix(i, zeros(1, cases)); continue; } if (sigma < 0) { errf("Covariance matrix should be positive semi-definite!\n"); exit(1); } for (int n = 0; n < cases; n++) { X.setEntry(i, n, normal(generator) * pow(sigma, 0.5)); } } Matrix& Y = plus(mtimes(B, X), repmat(MU.transpose(), 1, cases)).transpose(); return Y; }
int YAPCAReduce<eltype>::find_map(const ya_type1 &input, ya_type2 &output, ya_sizet dim, EigenOptions &eigopts) { // Target dimensionality YA_DEBUG_ERROR(dim<=input.cols(), "Not enough dimensions in input matrix"); eigopts.dim(dim); this->_high_dim=input.cols(); this->_low_dim=dim; // Column center the matrix column_means=sum(input)/static_cast<eltype>(input.rows()); YA_MatT input_cen(input.rows(),input.cols()); ya_sizet iC=input.cols(); for (ya_sizet i=0; i<iC; i++) input_cen(":",i)=input(":",i)-column_means(i); // Calculate covarience matrix #ifdef YA_PROGMETER YA_TimeKeeper tk; YA_ProgMeter pm; if (this->_verbose) { pm.start("Computing Forward and Reverse Maps:", 70, 0, false); tk.start(); } #endif VM_SymMat covmat=input_cen.T()*input_cen; eigs(covmat,eigen_vectors,this->eigen_values,eigopts); #ifdef YA_PROGMETER if (this->_verbose) { pm.finish(); tk.end(); cerr << "Done. " << tk << ".\n"; } #endif // Calculate the reduced output output=input_cen*eigen_vectors; return 0; }
void run_test(const Matrix &mat, int k, int m) { DenseGenMatProd<double> op(mat); GenEigsSolver<double, SelectionRule, DenseGenMatProd<double>> eigs(&op, k, m); eigs.init(); int nconv = eigs.compute(); int niter = eigs.num_iterations(); int nops = eigs.num_operations(); REQUIRE( nconv > 0 ); ComplexVector evals = eigs.eigenvalues(); ComplexMatrix evecs = eigs.eigenvectors(); ComplexMatrix err = mat * evecs - evecs * evals.asDiagonal(); INFO( "nconv = " << nconv ); INFO( "niter = " << niter ); INFO( "nops = " << nops ); INFO( "||AU - UD||_inf = " << err.array().abs().maxCoeff() ); REQUIRE( err.array().abs().maxCoeff() == Approx(0.0) ); }
bool isSafeNeighbor(int my_id, int neigh_id, int mytopology[TOTAL_ROBOT_NUM+1][TOTAL_ROBOT_NUM+1], int agents_num) { // calculate laplacian int myLaplacian[TOTAL_ROBOT_NUM+1][TOTAL_ROBOT_NUM+1]={{}}; int mytopology_aux[TOTAL_ROBOT_NUM+1][TOTAL_ROBOT_NUM+1]; for(int i=1; i<=agents_num; i++){ //REMOVE THIS CODE!!!!! for (int j=1; j<=agents_num; j++) { mytopology_aux[i][j] = mytopology[i][j]; } } //memcpy(mytopology_aux, mytopology, sizeof(mytopology)); mytopology_aux[neigh_id][my_id]=0; mytopology_aux[my_id][neigh_id]=0; calculateLaplacian(mytopology_aux, myLaplacian, agents_num); TNT::Array2D<double> Laplacian(agents_num,agents_num); // REMOVE THIS CODE: convert from 2D array to TNT::Array2D for(int i=1; i<=agents_num; i++){ for (int j=1; j<=agents_num; j++) { Laplacian[i-1][j-1] = myLaplacian[i][j]; } } JAMA::Eigenvalue<double> eigs(Laplacian); TNT::Array1D<double> eig_vals; eigs.getRealEigenvalues(eig_vals); std::cout<<"EIGENVALUES "<< my_id << " "; for (int i=0; i<agents_num; i++) std::cout<<eig_vals[i]<<" "; std::cout<<std::endl; if (eig_vals[1]<=0) return 0; else return 1; }
int sci_eigs(char *fname, void* pvApiCtx) { SciErr sciErr; int *piAddressVarOne = NULL; int iRowsOne = 0; int iColsOne = 0; double elemt1 = 0; double elemt2 = 0; double* Areal = NULL; doublecomplex* Acplx = NULL; int Asym = 1; int Acomplex = 0; int N = 0; int *piAddressVarTwo = NULL; int iTypeVarTwo = 0; int iRowsTwo = 0; int iColsTwo = 0; double* Breal = NULL; doublecomplex* Bcplx = NULL; int Bcomplex = 0; int matB = 0; int *piAddressVarThree = NULL; double dblNEV = 0; int iNEV = 0; int *piAddressVarFour = NULL; int iTypeVarFour = 0; int iRowsFour = 0; int iColsFour = 0; char* pstData = NULL; doublecomplex SIGMA; int *piAddressVarFive = NULL; double dblMAXITER = 0; int *piAddressVarSix = NULL; double dblTOL = 0; int *piAddressVarSeven = NULL; int TypeVarSeven = 0; int RowsSeven = 0; int ColsSeven = 0; double* dblNCV = NULL; int *piAddressVarEight = NULL; int iTypeVarEight = 0; double dblCHOLB = 0; int iCHOLB = 0; int *piAddressVarNine = NULL; int iTypeVarNine = 0; int iRowsNine = 0; int iColsNine = 0; double* RESID = NULL; doublecomplex* RESIDC = NULL; int *piAddressVarTen = NULL; int iINFO = 0; int RVEC = 0; // Output arguments double* eigenvalue = NULL; double* eigenvector = NULL; doublecomplex* eigenvalueC = NULL; doublecomplex* eigenvectorC = NULL; double* mat_eigenvalue = NULL; doublecomplex* mat_eigenvalueC = NULL; int INFO_EUPD = 0; int error = 0; int iErr = 0; int i = 0; int j = 0; CheckInputArgument(pvApiCtx, 1, 10); CheckOutputArgument(pvApiCtx, 0, 2); /**************************************** * First variable : A * *****************************************/ sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddressVarOne); if (sciErr.iErr) { printError(&sciErr, 0); Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1); return 1; } sciErr = getVarDimension(pvApiCtx, piAddressVarOne, &iRowsOne, &iColsOne); //check if A is a square matrix if (iRowsOne * iColsOne == 1 || iRowsOne != iColsOne) { Scierror(999, _("%s: Wrong type for input argument #%d: A square matrix expected.\n"), "eigs", 1); return 1; } N = iRowsOne; //check if A is complex if (isVarComplex(pvApiCtx, piAddressVarOne)) { sciErr = getComplexZMatrixOfDouble(pvApiCtx, piAddressVarOne, &iRowsOne, &iColsOne, &Acplx); Acomplex = 1; } else { sciErr = getMatrixOfDouble(pvApiCtx, piAddressVarOne, &iRowsOne, &iColsOne, &Areal); for (i = 0; i < iColsOne; i++) { for (j = 0; j < i; j++) { elemt1 = Areal[j + i * iColsOne]; elemt2 = Areal[j * iColsOne + i]; if (fabs(elemt1 - elemt2) > 0) { Asym = 0; break; } } if (Asym == 0) { break; } } } /**************************************** * Second variable : B * *****************************************/ sciErr = getVarAddressFromPosition(pvApiCtx, 2, &piAddressVarTwo); if (sciErr.iErr) { printError(&sciErr, 0); Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 2); return 1; } sciErr = getVarType(pvApiCtx, piAddressVarTwo, &iTypeVarTwo); if (sciErr.iErr || iTypeVarTwo != sci_matrix) { printError(&sciErr, 0); Scierror(999, _("%s: Wrong type for input argument #%d: An empty matrix or full or sparse square matrix expected.\n"), "eigs", 2); return 1; } sciErr = getVarDimension(pvApiCtx, piAddressVarTwo, &iRowsTwo, &iColsTwo); matB = iRowsTwo * iColsTwo; if (matB && (iRowsTwo != iRowsOne || iColsTwo != iColsOne)) { Scierror(999, _("%s: Wrong dimension for input argument #%d: B must have the same size as A.\n"), "eigs", 2); return 1; } if (isVarComplex(pvApiCtx, piAddressVarTwo)) { sciErr = getComplexZMatrixOfDouble(pvApiCtx, piAddressVarTwo, &iRowsTwo, &iColsTwo, &Bcplx); Bcomplex = 1; } else { sciErr = getMatrixOfDouble(pvApiCtx, piAddressVarTwo, &iRowsTwo, &iColsTwo, &Breal); } if (matB != 0) { if (Acomplex && !Bcomplex) { Bcplx = (doublecomplex*)MALLOC(N * N * sizeof(doublecomplex)); memset(Bcplx, 0, N * N * sizeof(doublecomplex)); Bcomplex = 1; for (i = 0 ; i < N * N ; i++) { Bcplx[i].r = Breal[i]; } } if (!Acomplex && Bcomplex) { Acplx = (doublecomplex*)MALLOC(N * N * sizeof(doublecomplex)); memset(Acplx, 0, N * N * sizeof(doublecomplex)); Acomplex = 1; for (i = 0 ; i < N * N ; i++) { Acplx[i].r = Areal[i]; } } } /**************************************** * NEV * *****************************************/ sciErr = getVarAddressFromPosition(pvApiCtx, 3, &piAddressVarThree); if (sciErr.iErr) { printError(&sciErr, 0); Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 3); FREE_AB; return 1; } iErr = getScalarDouble(pvApiCtx, piAddressVarThree, &dblNEV); if (iErr) { Scierror(999, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), "eigs", 3); FREE_AB; return 1; } if (isVarComplex(pvApiCtx, piAddressVarThree)) { Scierror(999, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), "eigs", 3); FREE_AB; return 1; } if (dblNEV != floor(dblNEV) || (dblNEV <= 0)) { Scierror(999, _("%s: Wrong type for input argument #%d: k must be a positive integer.\n"), "eigs", 3); FREE_AB; return 1; } if (!finite(dblNEV)) { Scierror(999, _("%s: Wrong value for input argument #%d: k must be in the range 1 to N.\n"), "eigs", 3); FREE_AB; return 1; } iNEV = (int)dblNEV; /**************************************** * SIGMA AND WHICH * *****************************************/ sciErr = getVarAddressFromPosition(pvApiCtx, 4, &piAddressVarFour); if (sciErr.iErr) { printError(&sciErr, 0); Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 4); FREE_AB; return 1; } sciErr = getVarType(pvApiCtx, piAddressVarFour, &iTypeVarFour); if (sciErr.iErr || (iTypeVarFour != sci_matrix && iTypeVarFour != sci_strings)) { Scierror(999, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), "eigs", 4); FREE_AB; return 1; } if (iTypeVarFour == sci_strings) { int iErr = getAllocatedSingleString(pvApiCtx, piAddressVarFour, &pstData); if (iErr) { FREE_AB; return 1; } if (strcmp(pstData, "LM") != 0 && strcmp(pstData, "SM") != 0 && strcmp(pstData, "LR") != 0 && strcmp(pstData, "SR") != 0 && strcmp(pstData, "LI") != 0 && strcmp(pstData, "SI") != 0 && strcmp(pstData, "LA") != 0 && strcmp(pstData, "SA") != 0 && strcmp(pstData, "BE") != 0) { if (!Acomplex && Asym) { Scierror(999, _("%s: Wrong value for input argument #%d: Unrecognized sigma value.\n Sigma must be one of '%s', '%s', '%s', '%s' or '%s'.\n" ), "eigs", 4, "LM", "SM", "LA", "SA", "BE"); freeAllocatedSingleString(pstData); return 1; } else { Scierror(999, _("%s: Wrong value for input argument #%d: Unrecognized sigma value.\n Sigma must be one of '%s', '%s', '%s', '%s', '%s' or '%s'.\n " ), "eigs", 4, "LM", "SM", "LR", "SR", "LI", "SI"); FREE_AB; freeAllocatedSingleString(pstData); return 1; } } if ((Acomplex || !Asym) && (strcmp(pstData, "LA") == 0 || strcmp(pstData, "SA") == 0 || strcmp(pstData, "BE") == 0)) { Scierror(999, _("%s: Invalid sigma value for complex or non symmetric problem.\n"), "eigs", 4); FREE_AB; freeAllocatedSingleString(pstData); return 1; } if (!Acomplex && Asym && (strcmp(pstData, "LR") == 0 || strcmp(pstData, "SR") == 0 || strcmp(pstData, "LI") == 0 || strcmp(pstData, "SI") == 0)) { Scierror(999, _("%s: Invalid sigma value for real symmetric problem.\n"), "eigs", 4); freeAllocatedSingleString(pstData); return 1; } SIGMA.r = 0; SIGMA.i = 0; } if (iTypeVarFour == sci_matrix) { sciErr = getVarDimension(pvApiCtx, piAddressVarFour, &iRowsFour, &iColsFour); if (iRowsFour * iColsFour != 1) { Scierror(999, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), "eigs", 4); FREE_AB; return 1; } if (getScalarComplexDouble(pvApiCtx, piAddressVarFour, &SIGMA.r, &SIGMA.i)) { printError(&sciErr, 0); Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 4); FREE_AB; return 1; } if (C2F(isanan)(&SIGMA.r) || C2F(isanan)(&SIGMA.i)) { Scierror(999, _("%s: Wrong type for input argument #%d: sigma must be a real.\n"), "eigs", 4); FREE_AB; return 1; } pstData = "LM"; } /**************************************** * MAXITER * *****************************************/ sciErr = getVarAddressFromPosition(pvApiCtx, 5, &piAddressVarFive); if (sciErr.iErr) { printError(&sciErr, 0); Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 5); FREE_AB; FREE_PSTDATA; return 0; } iErr = getScalarDouble(pvApiCtx, piAddressVarFive, &dblMAXITER); if (iErr) { Scierror(999, _("%s: Wrong type for input argument #%d: %s must be a scalar.\n"), "eigs", 5, "opts.maxiter"); FREE_AB; FREE_PSTDATA; return 1; } if ((dblMAXITER != floor(dblMAXITER)) || (dblMAXITER <= 0)) { Scierror(999, _("%s: Wrong type for input argument #%d: %s must be an integer positive value.\n"), "eigs", 5, "opts.maxiter"); FREE_AB; FREE_PSTDATA; return 1; } /**************************************** * TOL * *****************************************/ sciErr = getVarAddressFromPosition(pvApiCtx, 6, &piAddressVarSix); if (sciErr.iErr) { printError(&sciErr, 0); Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 6); FREE_AB; FREE_PSTDATA; return 1; } iErr = getScalarDouble(pvApiCtx, piAddressVarSix, &dblTOL); if (iErr) { Scierror(999, _("%s: Wrong type for input argument #%d: %s must be a real scalar.\n"), "eigs", 6, "opts.tol"); FREE_AB; FREE_PSTDATA; return 1; } if (C2F(isanan)(&dblTOL)) { Scierror(999, _("%s: Wrong type for input argument #%d: %s must be a real scalar.\n"), "eigs", 6, "opts.tol"); FREE_AB; FREE_PSTDATA; return 1; } /**************************************** * NCV * *****************************************/ sciErr = getVarAddressFromPosition(pvApiCtx, 7, &piAddressVarSeven); if (sciErr.iErr) { printError(&sciErr, 0); Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 7); FREE_AB; FREE_PSTDATA; return 1; } sciErr = getVarType(pvApiCtx, piAddressVarSeven, &TypeVarSeven); if (sciErr.iErr || TypeVarSeven != sci_matrix) { printError(&sciErr, 0); Scierror(999, _("%s: Wrong type for input argument #%d: %s must be an integer scalar.\n"), "eigs", 7, "opts.ncv"); FREE_AB; FREE_PSTDATA; return 1; } else { if (isVarComplex(pvApiCtx, piAddressVarSeven)) { Scierror(999, _("%s: Wrong type for input argument #%d: %s must be an integer scalar.\n"), "eigs", 7, "opts.ncv"); } else { sciErr = getVarDimension(pvApiCtx, piAddressVarSeven, &RowsSeven, &ColsSeven); if (RowsSeven * ColsSeven > 1) { Scierror(999, _("%s: Wrong type for input argument #%d: %s must be an integer scalar.\n"), "eigs", 7, "opts.ncv"); FREE_AB; FREE_PSTDATA; return 1; } if (RowsSeven * ColsSeven == 1) { sciErr = getMatrixOfDouble(pvApiCtx, piAddressVarSeven, &RowsSeven, &ColsSeven, &dblNCV); if (sciErr.iErr) { printError(&sciErr, 0); Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 7); FREE_AB; FREE_PSTDATA; return 1; } if (dblNCV[0] != floor(dblNCV[0])) { Scierror(999, _("%s: Wrong type for input argument #%d: %s must be an integer scalar.\n"), "eigs", 7, "opts.ncv"); FREE_AB; FREE_PSTDATA; return 1; } } } } /**************************************** * CHOLB * *****************************************/ sciErr = getVarAddressFromPosition(pvApiCtx, 8, &piAddressVarEight); if (sciErr.iErr) { printError(&sciErr, 0); Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 8); FREE_AB; FREE_PSTDATA; return 1; } sciErr = getVarType(pvApiCtx, piAddressVarEight, &iTypeVarEight); if (sciErr.iErr || (iTypeVarEight != sci_matrix && iTypeVarEight != sci_boolean)) { Scierror(999, _("%s: Wrong type for input argument #%d: %s must be an integer scalar or a boolean.\n"), "eigs", 8, "opts.cholB"); FREE_AB; FREE_PSTDATA; return 1; } if (iTypeVarEight == sci_boolean) { iErr = getScalarBoolean(pvApiCtx, piAddressVarEight, &iCHOLB); if (iErr) { Scierror(999, _("%s: Wrong type for input argument #%d: %s must be an integer scalar or a boolean.\n"), "eigs", 8, "opts.cholB"); FREE_AB; FREE_PSTDATA; return 1; } if (iCHOLB != 1 && iCHOLB != 0) { Scierror(999, _("%s: Wrong value for input argument #%d: %s must be %s or %s.\n"), "eigs", 8, "opts.cholB", "%f", "%t"); FREE_AB; FREE_PSTDATA; return 1; } dblCHOLB = (double) iCHOLB; } if (iTypeVarEight == sci_matrix) { iErr = getScalarDouble(pvApiCtx, piAddressVarEight, &dblCHOLB); if (iErr) { Scierror(999, _("%s: Wrong type for input argument #%d: %s must be an integer scalar or a boolean.\n"), "eigs", 8, "opts.cholB"); FREE_AB; FREE_PSTDATA; return 1; } if (dblCHOLB != 1 && dblCHOLB != 0) { Scierror(999, _("%s: Wrong value for input argument #%d: %s must be %s or %s.\n"), "eigs", 8, "opts.cholB", "%f", "%t"); FREE_AB; FREE_PSTDATA; return 1; } } if ( dblCHOLB ) // check that B is upper triangular with non zero element on the diagonal { if (!Bcomplex) { for (i = 0; i < N; i++) { for (j = 0; j <= i; j++) { if (i == j && Breal[i + j * N] == 0) { Scierror(999, _("%s: B is not positive definite. Try with sigma='SM' or sigma=scalar.\n"), "eigs"); FREE_PSTDATA; return 0; } else { if ( j < i && Breal[i + j * N] != 0 ) { Scierror(999, _("%s: If opts.cholB is true, B should be upper triangular.\n"), "eigs"); FREE_PSTDATA; return 0; } } } } } else { for (i = 0; i < N; i++) { for (j = 0; j <= i; j++) { if (i == j && Bcplx[i + i * N].r == 0 && Bcplx[i + i * N].i == 0) { Scierror(999, _("%s: B is not positive definite. Try with sigma='SM' or sigma=scalar.\n"), "eigs"); FREE_AB; FREE_PSTDATA; return 0; } else { if ( j < i && (Bcplx[i + j * N].r != 0 || Bcplx[i + j * N].i != 0) ) { Scierror(999, _("%s: If opts.cholB is true, B should be upper triangular.\n"), "eigs"); FREE_AB; FREE_PSTDATA; return 0; } } } } } } /**************************************** * RESID * *****************************************/ sciErr = getVarAddressFromPosition(pvApiCtx, 9, &piAddressVarNine); if (sciErr.iErr) { printError(&sciErr, 0); Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 9); FREE_AB; FREE_PSTDATA; return 1; } sciErr = getVarType(pvApiCtx, piAddressVarNine, &iTypeVarNine); if (sciErr.iErr || iTypeVarNine != sci_matrix) { printError(&sciErr, 0); Scierror(999, _("%s: Wrong type for input argument #%d: A real or complex matrix expected.\n"), "eigs", 9); FREE_AB; FREE_PSTDATA; return 1; } else { sciErr = getVarDimension(pvApiCtx, piAddressVarNine, &iRowsNine, &iColsNine); if (iRowsNine * iColsNine == 1 || iRowsNine * iColsNine != N) { Scierror(999, _("%s: Wrong dimension for input argument #%d: Start vector %s must be N by 1.\n"), "eigs", 9, "opts.resid"); FREE_AB; FREE_PSTDATA; return 1; } } if (!Acomplex && !Bcomplex) { if (isVarComplex(pvApiCtx, piAddressVarNine)) { Scierror(999, _("%s: Wrong type for input argument #%d: Start vector %s must be real for real problems.\n"), "eigs", 9, "opts.resid"); FREE_PSTDATA; return 1; } else { sciErr = getMatrixOfDouble(pvApiCtx, piAddressVarNine, &iRowsNine, &iColsNine, &RESID); if (sciErr.iErr) { printError(&sciErr, 0); Scierror(999, _("%s: Can not read input argument #%d.\n"), "eigs", 9); FREE_PSTDATA; return 1; } } } else { sciErr = getComplexZMatrixOfDouble(pvApiCtx, piAddressVarNine, &iRowsNine, &iColsNine, &RESIDC); if (sciErr.iErr) { printError(&sciErr, 0); Scierror(999, _("%s: Can not read input argument #%d.\n"), "eigs", 9); FREE_AB; FREE_PSTDATA; return 1; } } /**************************************** * INFO * *****************************************/ sciErr = getVarAddressFromPosition(pvApiCtx, 10, &piAddressVarTen); if (sciErr.iErr) { printError(&sciErr, 0); Scierror(999, _("%s: Can not read input argument #%d.\n"), "eigs", 9); FREE_AB; FREE_PSTDATA; return 1; } iErr = getScalarInteger32(pvApiCtx, piAddressVarTen, &iINFO); if (iErr) { Scierror(999, _("%s: Wrong type for input argument #%d: An integer expected.\n"), "eigs", 1); FREE_AB; FREE_PSTDATA; return 1; } // Initialization output arguments if (nbOutputArgument(pvApiCtx) > 1) { RVEC = 1; } if (Acomplex || Bcomplex || !Asym) { eigenvalueC = (doublecomplex*)CALLOC((iNEV + 1), sizeof(doublecomplex)); if (RVEC) { eigenvectorC = (doublecomplex*)CALLOC(N * (iNEV + 1), sizeof(doublecomplex)); } } else { eigenvalue = (double*)CALLOC(iNEV, sizeof(double)); /* we should allocate eigenvector only if RVEC is true, but dseupd segfaults if Z is not allocated even when RVEC is false, contrary to the docs.*/ eigenvector = (double*)CALLOC(iNEV * N, sizeof(double)); } error = eigs(Areal, Acplx, N, Acomplex, Asym, Breal, Bcplx, Bcomplex, matB, iNEV, SIGMA, pstData, &dblMAXITER, &dblTOL, dblNCV, RESID, RESIDC, &iINFO, &dblCHOLB, INFO_EUPD, eigenvalue, eigenvector, eigenvalueC, eigenvectorC, RVEC); FREE_AB; FREE_PSTDATA; switch (error) { case -1 : if (Asym && !Acomplex && !Bcomplex) { Scierror(999, _("%s: Wrong value for input argument #%d: For real symmetric problems, NCV must be k < NCV <= N.\n"), "eigs", 7); } else { if (!Asym && !Acomplex && !Bcomplex) { Scierror(999, _("%s: Wrong value for input argument #%d: For real non symmetric problems, NCV must be k + 2 < NCV <= N.\n"), "eigs", 7); } else { Scierror(999, _("%s: Wrong value for input argument #%d: For complex problems, NCV must be k + 1 < NCV <= N.\n"), "eigs", 7); } } ReturnArguments(pvApiCtx); return 1; case -2 : if (Asym && !Acomplex && !Bcomplex) { Scierror(999, _("%s: Wrong value for input argument #%d: For real symmetric problems, k must be an integer in the range 1 to N - 1.\n"), "eigs", 3); } else { Scierror(999, _("%s: Wrong value for input argument #%d: For real non symmetric or complex problems, k must be an integer in the range 1 to N - 2.\n"), "eigs", 3); } ReturnArguments(pvApiCtx); return 1; case -3 : Scierror(999, _("%s: Error with input argument #%d: B is not positive definite. Try with sigma='SM' or sigma=scalar.\n"), "eigs", 2); ReturnArguments(pvApiCtx); return 0; case -4 : if (!Acomplex && !Bcomplex) { if (Asym) { Scierror(999, _("%s: Error with %s: info = %d \n"), "eigs", "DSAUPD", iINFO); } else { Scierror(999, _("%s: Error with %s: info = %d \n"), "eigs", "DNAUPD", iINFO); } } else { Scierror(999, _("%s: Error with %s: info = %d \n"), "eigs", "ZNAUPD", iINFO); } ReturnArguments(pvApiCtx); return 1; case -5 : if (!Acomplex && !Bcomplex) { if (Asym) { Scierror(999, _("%s: Error with %s: unknown mode returned.\n"), "eigs", "DSAUPD"); } else { Scierror(999, _("%s: Error with %s: unknown mode returned.\n"), "eigs", "DNAUPD"); } } else { Scierror(999, _("%s: Error with %s: unknown mode returned.\n"), "eigs", "ZNAUPD"); } ReturnArguments(pvApiCtx); return 1; case -6 : if (!Acomplex && !Bcomplex) { if (Asym) { Scierror(999, _("%s: Error with %s: info = %d \n"), "eigs", "DSEUPD", INFO_EUPD); } else { Scierror(999, _("%s: Error with %s: info = %d \n"), "eigs", "DNEUPD", INFO_EUPD); } } else { Scierror(999, _("%s: Error with %s: info = %d \n"), "eigs", "ZNEUPD", INFO_EUPD); } ReturnArguments(pvApiCtx); FREE(mat_eigenvalue); return 1; } if (nbOutputArgument(pvApiCtx) <= 1) { if (eigenvalue) { sciErr = createMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 1, iNEV, 1, eigenvalue); FREE(eigenvalue); FREE(eigenvector); } else if (eigenvalueC) { sciErr = createComplexZMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 1, iNEV, 1, eigenvalueC); FREE(eigenvalueC); } if (sciErr.iErr) { printError(&sciErr, 0); Scierror(999, _("%s: Memory allocation error.\n"), fname); return 1; } AssignOutputVariable(pvApiCtx, 1) = nbInputArgument(pvApiCtx) + 1; } else { // create a matrix which contains the eigenvalues if (eigenvalue) { mat_eigenvalue = (double*)CALLOC(iNEV * iNEV, sizeof(double)); for (i = 0; i < iNEV; i++) { mat_eigenvalue[i * iNEV + i] = eigenvalue[i]; } sciErr = createMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 1, iNEV, iNEV, mat_eigenvalue); FREE(eigenvalue); FREE(mat_eigenvalue); } else if (eigenvalueC) { mat_eigenvalueC = (doublecomplex*)CALLOC(iNEV * iNEV, sizeof(doublecomplex)); for (i = 0; i < iNEV; i++) { mat_eigenvalueC[i * iNEV + i] = eigenvalueC[i]; } sciErr = createComplexZMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 1, iNEV, iNEV, mat_eigenvalueC); FREE(eigenvalueC); FREE(mat_eigenvalueC); } if (sciErr.iErr) { printError(&sciErr, 0); Scierror(999, _("%s: Memory allocation error.\n"), fname); return 1; } if (eigenvector) { sciErr = createMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 2, N, iNEV, eigenvector); FREE(eigenvector); } else if (eigenvectorC) { sciErr = createComplexZMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 2, N, iNEV, eigenvectorC); FREE(eigenvectorC); } if (sciErr.iErr) { printError(&sciErr, 0); Scierror(999, _("%s: Memory allocation error.\n"), fname); return 1; } AssignOutputVariable(pvApiCtx, 1) = nbInputArgument(pvApiCtx) + 1; AssignOutputVariable(pvApiCtx, 2) = nbInputArgument(pvApiCtx) + 2; } ReturnArguments(pvApiCtx); return 0; }
void _point_pca(const YA_BaseT &input, const ya_sizet k, EigenOptions &eigopts, ya_type2 &output, const bool residual, const int verbose_out, const int me, const int num_procs, const YA_ColI &counts, const YA_ColI &starts) { YA_DEBUG_ERROR(k>=0 && k<input.rows(), "More neighbors than datapoints for point_pca"); int verbose=verbose_out; #ifdef YA_MPI if (me!=0) verbose=0; else if (num_procs>1 && verbose>1) verbose=1; #ifdef YA_PROGMETER if (verbose) cout << "Performing point-PCA on " << num_procs << " processors.\n"; #endif #endif YA_MatI neighbors; YA_MatD dists; if (num_procs==1) { kneighbors(input,k,neighbors,dists,verbose); neighbors=YA_MatI(concat(vm_cast<ya_sizet>::sc(vmcount(input.rows()).T()), neighbors)); } else if (counts[me]>0) kneighbors(input(vmcount(starts[me],":",starts[me]+counts[me]-1),":"), input,k+1,neighbors,dists,verbose); #ifdef YA_MPI if (num_procs>1 && verbose_out>1) { #ifdef YA_PROGMETER YA_TimeKeeper mtk; if (verbose>0) { cerr << "Waiting on other procs..."; mtk.start(); } MPI_Barrier(MPI_COMM_WORLD); if (verbose>0) { mtk.end(); cerr << "Done. " << mtk << endl; } #endif if (me==0) cerr << "Neighbor Distance Stats:\n"; eltype dmin, dmax, dmean, dstd; mpi_vstat(dists(":",vmcount(k)+1),dmin,dmax,dmean,dstd); if (me==0) cerr << " Min: " << dmin << " Max: " << dmax << endl << " Mean: " << dmean << " Std: " << dstd << endl << endl; } #endif dists.clear(); output.setup(counts[me],input.cols()); #ifdef YA_PROGMETER YA_TimeKeeper tk; YA_ProgMeter pm; if (verbose) { tk.start(); pm.start("Performing Point PCA:",70,counts[0],false); } #endif #pragma omp parallel { YA_RowT column_means; YA_MatT input_cen; VM_SymMat covmat; YA_RowT eigens; #pragma omp for for (ya_sizet i=0; i<counts[me]; i++) { // Column center the matrix column_means=sum(input(neighbors(i,":"),":")/static_cast<eltype>(k+1)); input_cen=input(neighbors(i,":"),":")-rowrep(column_means,k+1); covmat=input_cen.T()*input_cen; eigs(covmat,eigens,eigopts); output(i,":")=eigens; #ifdef YA_PROGMETER if (verbose) pm.iterate(); #endif } } neighbors.clear(); #ifdef YA_PROGMETER if (verbose) { pm.finish(); tk.end(); cerr << "Done. " << tk << ".\n"; } YA_TimeKeeper mtk; if (num_procs>1) if (verbose>0) { cerr << "Waiting on other procs..."; mtk.start(); } #endif #ifdef YA_MPI if (num_procs>1) MPI_Barrier(MPI_COMM_WORLD); #endif #ifdef YA_PROGMETER if (num_procs>1 && verbose>0) { mtk.end(); cerr << "Done. " << mtk << endl; } #endif if (residual && counts[me]>0) { YA_VecT totals=sum(output.T()); output=output.dot_div(colrep(totals,output.cols())); ya_sizet iC=output.cols(); for (ya_sizet i=1; i<iC-1; i++) output(":",i)+=output(":",i-1); output(":",iC-1)=1.0; output=1.0-output; } }
void _point_pca_ep(const YA_BaseT &input, const eltype epsilon, EigenOptions &eigopts, vmtype2 &output, const bool residual, const int verbose_out, const int me, const int num_procs, const YA_ColI &counts, const YA_ColI &starts) { YA_DEBUG_ERROR(epsilon>0, "Epsilon must be greater than 0 for point_pca"); int verbose=verbose_out; #ifdef YA_MPI if (me!=0) verbose=0; else if (num_procs>1 && verbose>1) verbose=1; #ifdef YA_PROGMETER if (verbose) cout << "Performing point-PCA on " << num_procs << " processors.\n"; #endif #endif vector<YA_DynI> neighbors; vector<YA_Dyn<eltype> > dists; if (num_procs==1) { eneighbors(input,epsilon,neighbors,dists,verbose); int iR=input.rows(); for (ya_sizet i=0; i<iR; i++) neighbors[i].push_back(i); } else if (counts[me]>0) eneighbors(input(vmcount(starts[me],":",starts[me]+counts[me]-1),":"), input,epsilon,neighbors,dists,verbose); dists.clear(); #ifdef YA_MPI if (num_procs>1 && verbose_out>1) { #ifdef YA_PROGMETER YA_TimeKeeper mtk; if (verbose>0) { cerr << "Waiting on other procs..."; mtk.start(); } MPI_Barrier(MPI_COMM_WORLD); if (verbose>0) { mtk.end(); cerr << "Done. " << mtk << endl; } #endif if (me==0) cerr << "Neighbor Counts Stats:\n"; ya_sizet dmin, dmax; eltype dmean, dstd; ya_sizet n=neighbors.size(); YA_ColI ncounts; if (n>0) ncounts.setup(n); for (ya_sizet i=0; i<n; i++) ncounts(i)=neighbors[i].numel()-1; mpi_vstat(ncounts,dmin,dmax,dmean,dstd); if (me==0) cerr << " Min: " << dmin << " Max: " << dmax << endl << " Mean: " << dmean << " Std: " << dstd << endl << endl; } #endif output.setup(counts[me],input.cols()); #ifdef YA_PROGMETER YA_TimeKeeper tk; YA_ProgMeter pm; if (verbose) { tk.start(); pm.start("Performing Point PCA:",70,counts[0],false); } #endif #pragma omp parallel { YA_RowT column_means; YA_MatT input_cen; VM_SymMat covmat; YA_RowT eigens; ya_sizet NN=counts[me]; #pragma omp for for (ya_sizet i=0; i<NN; i++) { ya_sizet k=neighbors[i].numel(); column_means=sum(input(neighbors[i],":")/static_cast<eltype>(k)); input_cen=input(neighbors[i],":")-rowrep(column_means,k); covmat=input_cen.T()*input_cen; eigs(covmat,eigens,eigopts); output(i,":")=eigens; #ifdef YA_PROGMETER if (verbose) pm.iterate(); #endif } } neighbors.clear(); #ifdef YA_PROGMETER if (verbose) { pm.finish(); tk.end(); cerr << "Done. " << tk << ".\n"; } YA_TimeKeeper mtk; if (num_procs>1 && verbose) { cerr << "Waiting on other procs..."; mtk.start(); } #endif #ifdef YA_MPI if (num_procs>1) MPI_Barrier(MPI_COMM_WORLD); #endif #ifdef YA_PROGMETER if (num_procs>1 && verbose>0) { mtk.end(); cerr << "Done. " << mtk << endl; } #endif if (residual && counts[me]>0) { YA_VecT totals=sum(output.T()); output=output.dot_div(colrep(totals,output.cols())); ya_sizet iC=output.cols(); for (ya_sizet i=1; i<iC-1; i++) output(":",i)+=output(":",i-1); output(":",iC-1)=1.0; output=1.0-output; } }
void do_mytest() //double X[PROBDIM], int N, int IORD) { double GRAD[data.Nth]; // 1st derivatives double sGRAD[data.Nth]; // 1st derivatives double HES[data.Nth][data.Nth]; // hessian double sHES[data.Nth][data.Nth]; // hessian double X[data.Nth]; int i, j; double t1, t2; const int reps = 1; //200; double *theta = data.theta; double *XL = data.lowerbound; double *XU = data.upperbound; double *UH = data.diffstep; int N = data.Nth; int IORD = data.iord; double FEPS = 1e-6; int IPRINT = 0; int NOC; int IERR; for (i = 0; i < data.Nth; i++) X[i] = theta[i]; reset_nfc(); #if 1 // GRADIENT printf("\n================================================\n"); t1 = torc_gettime(); { for (i = 0; i < data.Nth; i++) sGRAD[i] = 0.0; int t; for (t = 0; t < reps; t++) { if (t > 0) { double c = 1e-5; double delta; if (drand48() < 0.5) delta = -1; else delta = 1; for (i = 0; i < data.Nth; i++) X[i] = theta[i] + c*delta; } c_pndlga(F,X,&N,XL,XU,UH,&FEPS,&IORD,&IPRINT,GRAD,&NOC,&IERR); //printf("gradient -> %d\n", t); for (i = 0; i < data.Nth; i++) sGRAD[i] += GRAD[i]; } for (i = 0; i < data.Nth; i++) GRAD[i] = sGRAD[i]/reps; } t2 = torc_gettime(); printf("t2-t1 = %lf seconds\n", t2-t1); #if 1 //VERBOSE printf("IORD = %d\n", IORD); printf("NOC = %d\n", NOC); printf("GRADIENT VECTOR :\n"); for (i = 0; i < N; i++) { printf("%12.4lf ", GRAD[i]); } printf("\n"); fflush(0); #endif #endif #if 1 // HESSIAN WITH FUNCTION CALLS if (IORD == 4) IORD = 2; printf("\n================================================\n"); t1 = torc_gettime(); { for (i = 0; i < N; i++) for (j = 0; j < N; j++) sHES[i][j] = 0.0; int t; for (t = 0; t < reps; t++) { if (t > 0) { double c = 1e-5; double delta; if (drand48() < 0.5) delta = -1; else delta = 1; for (i = 0; i < data.Nth; i++) X[i] = theta[i] + c*delta; } c_pndlhfa(F,X,&N,XL,XU,UH,&FEPS,&IORD,&IPRINT,(double *)HES,&N,&NOC,&IERR); //printf("hessian -> %d\n", t); for (i = 0; i < N; i++) for (j = i+1; j < N; j++) HES[j][i] = HES[i][j]; for (i = 0; i < N; i++) for (j = 0; j < N; j++) sHES[i][j] += HES[i][j]; } for (i = 0; i < N; i++) for (j = 0; j < N; j++) HES[j][i] = sHES[i][j]/reps; } t2 = torc_gettime(); printf("t2-t1 = %lf seconds\n", t2-t1); #if VERBOSE printf("IORD = %d\n", IORD); printf("NOC = %d\n", NOC); printf("HESSIAN MATRIX :\n"); for (i = 0; i < N; i++) { for (j = 0; j < N; j++) printf("%12.4lf ", HES[i][j]); printf("\n"); } printf("\n"); fflush(0); #endif #endif get_nfc(); printf("total function calls = %d\n", get_tfc()); printf("GRADIENT VECTOR :\n"); for (i = 0; i < N; i++) { printf("%15.8lf ", GRAD[i]); } printf("\n"); fflush(0); printf("HESSIAN MATRIX :\n"); for (i = 0; i < N; i++) { for (j = 0; j < N; j++) printf("%15.8lf ", HES[i][j]); printf("\n"); } printf("\n"); fflush(0); gsl_matrix *hessian_mat = gsl_matrix_alloc(data.Nth, data.Nth); for(i=0; i<data.Nth; i++){ for(j=0; j<data.Nth; j++){ gsl_matrix_set(hessian_mat, i, j, HES[i][j]); } } eigs(hessian_mat, data.Nth); if (data.posdef == -1) return; // -1 or 0 to 3 int res = check_mat_pos_def(hessian_mat, data.Nth); if (res == 0) { int m; //for (m = 0; m <=3; m++) { for (m = data.posdef; m <=data.posdef; m++) { printf(">>> METHOD %d <<<<\n", m); for(i=0; i<data.Nth; i++){ for(j=0; j<data.Nth; j++){ gsl_matrix_set(hessian_mat, i, j, HES[i][j]); } } gsl_matrix *hessian_mat2 = gsl_matrix_alloc(data.Nth, data.Nth); force_pos_def(hessian_mat, hessian_mat2, m, data.Nth); //gsl_matrix_fprintf(stdout, hessian_mat2, "%lf"); printf("mat2 = \n"); for(i=0; i<data.Nth; i++){ for(j=0; j<data.Nth; j++){ printf("%15.8lf ", gsl_matrix_get(hessian_mat2, i, j)); } printf("\n"); } eigs(hessian_mat2, data.Nth); //int res = check_mat_pos_def(hessian_mat2); } } }