GURLS_EXPORT void eig(const gMat2D<float>& A, gVec<float>& Wr, gVec<float>& Wi) { if (A.cols() != A.rows()) throw gException("The input matrix A must be squared"); float* Atmp = new float[A.getSize()]; copy(Atmp, A.getData(), A.getSize()); char jobvl = 'N', jobvr = 'N'; int n = A.cols(), lda = A.cols(), ldvl = 1, ldvr = 1; int info, lwork = 4*n; float* work = new float[lwork]; sgeev_(&jobvl, &jobvr, &n, Atmp, &lda, Wr.getData(), Wi.getData(), NULL, &ldvl, NULL, &ldvr, work, &lwork, &info); delete[] Atmp; delete[] work; if(info != 0) { std::stringstream str; str << "Eigenvalues/eigenVectors computation failed, error code " << info << ";" << std::endl; throw gException(str.str()); } }
GURLS_EXPORT void dot(const gMat2D<float>& A, const gMat2D<float>& B, gMat2D<float>& C) { dot(A.getData(), B.getData(), C.getData(), A.rows(), A.cols(), B.rows(), B.cols(), C.rows(), C.cols(), CblasNoTrans, CblasNoTrans, CblasRowMajor); }
GURLS_EXPORT void dot(const gMat2D<double>& A, const gMat2D<double>& B, gMat2D<double>& C) { dot(A.getData(), B.getData(), C.getData(), A.rows(), A.cols(), B.rows(), B.cols(), C.rows(), C.cols(), CblasNoTrans, CblasNoTrans, CblasColMajor); }
void RecursiveRLSWrapper<T>::train(const gMat2D<T> &X, const gMat2D<T> &y) { this->opt->removeOpt("split"); this->opt->removeOpt("paramsel"); this->opt->removeOpt("optimizer"); this->opt->removeOpt("kernel"); SplitHo<T> splitTask; GurlsOptionsList* split = splitTask.execute(X, y, *(this->opt)); this->opt->addOpt("split", split); const gMat2D<unsigned long>& split_indices = split->getOptValue<OptMatrix<gMat2D<unsigned long> > >("indices"); const gMat2D<unsigned long>& split_lasts = split->getOptValue<OptMatrix<gMat2D<unsigned long> > >("lasts"); const unsigned long n = X.rows(); const unsigned long d = X.cols(); const unsigned long t = y.cols(); const unsigned long last = split_lasts.getData()[0]; const unsigned long nva = n-last; unsigned long* va = new unsigned long[nva]; copy(va, split_indices.getData()+last, nva); gMat2D<T>* Xva = new gMat2D<T>(nva, d); gMat2D<T>* yva = new gMat2D<T>(nva, t); subMatrixFromRows(X.getData(), n, d, va, nva, Xva->getData()); subMatrixFromRows(y.getData(), n, t, va, nva, yva->getData()); gMat2D<T>* XtX = new gMat2D<T>(d, d); gMat2D<T>* Xty = new gMat2D<T>(d, t); dot(X.getData(), X.getData(), XtX->getData(), n, d, n, d, d, d, CblasTrans, CblasNoTrans, CblasColMajor); dot(X.getData(), y.getData(), Xty->getData(), n, d, n, t, d, t, CblasTrans, CblasNoTrans, CblasColMajor); GurlsOptionsList* kernel = new GurlsOptionsList("kernel"); kernel->addOpt("XtX", new OptMatrix<gMat2D<T> >(*XtX)); kernel->addOpt("Xty", new OptMatrix<gMat2D<T> >(*Xty)); kernel->addOpt("Xva", new OptMatrix<gMat2D<T> >(*Xva)); kernel->addOpt("yva", new OptMatrix<gMat2D<T> >(*yva)); nTot = n; this->opt->addOpt("kernel", kernel); ParamSelHoPrimal<T> paramselTask; this->opt->addOpt("paramsel", paramselTask.execute(X, y, *(this->opt))); RLSPrimalRecInit<T> optimizerTask; this->opt->addOpt("optimizer", optimizerTask.execute(X, y, *(this->opt))); }
void BigArray<T>::getMatrix(unsigned long startingRow, unsigned long startingCol, gMat2D<T>&result) const { if(startingRow >= this->numrows || startingCol >= this->numcols) throw gException(Exception_Index_Out_of_Bound); if(startingRow+result.rows() > this->numrows || startingCol+result.cols() > this->numcols) throw gException(Exception_Index_Out_of_Bound); getMatrix(startingRow, startingCol, result.rows(), result.cols(), result.getData()); }
GURLS_EXPORT void eig(const gMat2D<float>& A, gVec<float>& Wr, gVec<float>& Wi) { if (A.cols() != A.rows()) { throw gException("The input matrix A must be squared"); } char jobvl = 'N', jobvr = 'N'; int n = A.cols(), lda = A.cols(), ldvl = 1, ldvr = 1; int info, lwork = 4*n; float* work = new float[lwork]; sgeev_(&jobvl, &jobvr, &n, const_cast<gMat2D<float>&>(A).getData(), &lda, Wr.getData(), Wi.getData(), NULL, &ldvl, NULL, &ldvr, work, &lwork, &info); delete[] work; }
GURLS_EXPORT void lu(gMat2D<float>& A, gVec<int>& pv) { unsigned int k = std::min<unsigned int>(A.cols(), A.rows()); if (pv.getSize() != k) { throw gException("The lenghth of pv must be equal to the minimun dimension of A"); } int info; int m = A.rows(); int n = A.cols(); int lda = A.cols(); sgetrf_(&m, &n, A.getData(), &lda, pv.getData(), &info); }
float RLSlinear::predictModel(gMat2D<float> &X, bool newGURLS) { if (modelLinearRLS==NULL) { cout << "Error: train model first!" << endl; return 0.0; } if (newGURLS==false) { gMat2D<float> empty; RLS.run(X,empty,*modelLinearRLS,"test"); } else { unsigned long nTest = X.rows(); unsigned long d = X.cols(); gMat2D<float> empty(nTest, 1); unsigned long t = empty.cols(); float* perfBuffer = new float[empty.cols()]; float* predBuffer = new float[empty.cols()*nTest]; test(*modelLinearRLS, X.getData(), empty.getData(), predBuffer, perfBuffer, nTest, d, t, "auto"); } // Retrieve prediction gMat2D<float>& pred = modelLinearRLS->getOptValue<OptMatrix<gMat2D<float> > >("pred"); return pred(0,0); }
GURLS_EXPORT void eig(const gMat2D<float>& A, gMat2D<float>& V, gVec<float>& Wr, gVec<float>& Wi) { if (A.cols() != A.rows()) { throw gException("The input matrix A must be squared"); } char jobvl = 'N', jobvr = 'V'; int n = A.cols(), lda = A.cols(), ldvl = 1, ldvr = A.cols(); int info, lwork = 4*n; float* work = new float[lwork]; gMat2D<float> Atmp = A; gMat2D<float> Vtmp = V; sgeev_(&jobvl, &jobvr, &n, Atmp.getData(), &lda, Wr.getData(), Wi.getData(), NULL, &ldvl, Vtmp.getData(), &ldvr, work, &lwork, &info); Vtmp.transpose(V); delete[] work; }
GURLS_EXPORT void inv(const gMat2D<float>& A, gMat2D<float>& Ainv, InversionAlgorithm alg){ Ainv = A; int k = std::min<int>(Ainv.cols(), Ainv.rows()); int info; int* ipiv = new int[k]; int m = Ainv.rows(); int n = Ainv.cols(); int lda = Ainv.cols(); float* work = new float[n]; sgetrf_(&m, &n, Ainv.getData(), &lda, ipiv, &info); sgetri_(&m, Ainv.getData(), &lda, ipiv, work, &n, &info); delete[] ipiv; delete[] work; }
GURLS_EXPORT void svd(const gMat2D<float>& A, gMat2D<float>& U, gVec<float>& W, gMat2D<float>& Vt) { float* Ubuf; float* Sbuf; float* Vtbuf; int Urows, Ucols; int Slen; int Vtrows, Vtcols; gurls::svd(A.getData(), Ubuf, Sbuf, Vtbuf, A.rows(), A.cols(), Urows, Ucols, Slen, Vtrows, Vtcols); U.resize(Urows, Ucols); copy(U.getData(), Ubuf, U.getSize()); W.resize(Slen); copy(W.getData(), Sbuf, Slen); Vt.resize(Vtrows, Vtcols); copy(Vt.getData(), Vtbuf, Vt.getSize()); delete [] Ubuf; delete [] Sbuf; delete [] Vtbuf; }
BigArray<T>::BigArray(std::wstring fileName, const gMat2D<T>& mat) { std::string fName = std::string(fileName.begin(), fileName.end()); init(fName, mat.rows(), mat.cols()); MPI_Barrier(MPI_COMM_WORLD); }
GURLS_EXPORT void cholesky(const gMat2D<float>& A, gMat2D<float>& L, bool upper) { float* chol = cholesky<float>(A.getData(), A.rows(), A.cols(), upper); copy(L.getData(), chol, A.getSize()); delete [] chol; }
GURLS_EXPORT void pinv(const gMat2D<float>& A, gMat2D<float>& Ainv, float RCOND) { int r, c; float* inv = pinv(A.getData(), A.rows(), A.cols(), r, c, &RCOND); Ainv.resize(r, c); gurls::copy(Ainv.getData(), inv, r*c); delete[] inv; }
void RLSlinear::trainModel(gMat2D<float> &X, gMat2D<float> &Y, bool newGURLS) { if(modelLinearRLS!=NULL) delete modelLinearRLS; if (newGURLS==false) { OptTaskSequence *seq = new OptTaskSequence(); OptProcess* process_train = new OptProcess(); OptProcess* process_predict = new OptProcess(); *seq << "kernel:linear" << "split:ho" << "paramsel:hodual"; *process_train << GURLS::computeNsave << GURLS::compute << GURLS::computeNsave; *process_predict << GURLS::load << GURLS::ignore << GURLS::load; *seq<< "optimizer:rlsdual"<< "pred:dual"; *process_train<<GURLS::computeNsave<<GURLS::ignore; *process_predict<<GURLS::load<<GURLS::computeNsave; GurlsOptionsList * processes = new GurlsOptionsList("processes", false); processes->addOpt("train",process_train); processes->addOpt("test",process_predict); modelLinearRLS = new GurlsOptionsList(className, true); modelLinearRLS->addOpt("seq", seq); modelLinearRLS->addOpt("processes", processes); RLS.run(X,Y,*modelLinearRLS,"train"); } else { unsigned long n = X.rows(); unsigned long d = X.cols(); unsigned long t = Y.cols(); // should be 1 modelLinearRLS = train(X.getData(), Y.getData(), n, d, t, "krls", "linear"); } }
GURLS_EXPORT void dot(const gMat2D<float>& A, const gVec<float>& x, gVec<float>& y) { if ( (A.cols() != x.getSize()) || (A.rows() != y.getSize())) throw gException(Exception_Inconsistent_Size); // y = alpha*A*x + beta*y float alpha = 1.0f; float beta = 0.0f; char transA = 'N'; int m = A.rows(); int n = A.cols(); int lda = m; int inc = 1; sgemv_(&transA, &m, &n, &alpha, const_cast<float*>(A.getData()), &lda, const_cast<float*>(x.getData()), &inc, &beta, y.getData(), &inc); }
GURLS_EXPORT void svd(const gMat2D<float>& A, gMat2D<float>& U, gVec<float>& W, gMat2D<float>& Vt) { char jobu = 'S', jobvt = 'S'; int m = A.rows(); int n = A.cols(); int k = std::min<int>(m, n); if ((int)W.getSize() < k) { throw gException("The length of vector W must be at least equal to the minimum dimension of the input matrix A"); } if ((int)U.rows() < m || (int)U.cols() < k) { throw gException("Please check the dimensions of the matrix U where to store the singular vectors"); } if ((int)Vt.rows() < k || (int)Vt.cols() < n) { throw gException("Please check the dimensions of the matrix Vt where to store the rigth singular vectors"); } int lda = A.cols(); int ldu = U.cols(); int ldvt = Vt.cols(); int info, lwork = std::max<int>(3*k+std::max<int>(m,n), 5*k); float* work = new float[lwork]; float* copy = new float[m*n]; A.asarray(copy, m*n); sgesvd_(&jobu, &jobvt, &n, &m, copy, &lda, W.getData(), Vt.getData(), &ldvt, U.getData(), &ldu, work, &lwork, &info); delete[] work; delete[] copy; }
GURLS_EXPORT void dot(const gMat2D<double>& A, const gVec<double>& x, gVec<double>& y){ if ( (A.cols() != x.getSize()) || (A.rows() != y.getSize())) throw gException(Exception_Inconsistent_Size); // y = alpha*A*x + beta*y double alpha = 1.0f; double beta = 0.0f; char transA = 'T'; // row major matrix int m = A.cols(); // row major matrix int n = A.rows(); // row major matrix int lda = m; // row major matrix int inc = 1; dgemv_(&transA, &m, &n, &alpha, const_cast<double*>(A.getData()), &lda, const_cast<double*>(x.getData()), &inc, &beta, y.getData(), &inc); }
GURLS_EXPORT void cholesky(const gMat2D<float>& A, gMat2D<float>& L, bool upper){ typedef float T; L = A; int LDA = A.rows(); int n = A.cols(); char UPLO = upper? 'U' : 'L'; int info; spotrf_(&UPLO,&n, L.getData(),&LDA,&info); // This is required because we adopted a column major order to store the // data into matrices gMat2D<T> tmp(L.rows(), L.cols()); if (!upper){ L.uppertriangular(tmp); } else { L.lowertriangular(tmp); } tmp.transpose(L); }
GURLS_EXPORT void lu(gMat2D<float>& A) { gVec<int> pv(std::min(A.cols(), A.rows())); lu(A, pv); }
BigArray<T>::BigArray(std::string fileName, const gMat2D<T>& mat) { init(fileName, mat.rows(), mat.cols()); MPI_Barrier(MPI_COMM_WORLD); }
void BigArray<T>::setMatrix(unsigned long startingRow, unsigned long startingCol, const gMat2D<T>&value) { setMatrix(startingRow, startingCol, value.getData(), value.rows(), value.cols()); }
GURLS_EXPORT void pinv(const gMat2D<float>& A, gMat2D<float>& Ainv, float RCOND){ /* subroutine SGELSS ( INTEGER M, INTEGER N, INTEGER NRHS, REAL,dimension( lda, * ) A, INTEGER LDA, REAL,dimension( ldb, * ) B, INTEGER LDB, REAL,dimension( * ) S, REAL RCOND, INTEGER RANK, REAL,dimension( * ) WORK, INTEGER LWORK, INTEGER INFO ) */ int M = A.rows(); int N = A.cols(); // The following step is required because we are currently storing // the matrices using a column-major order while LAPACK's // routines require row-major ordering float* a = new float[M*N]; const float* ptr_A = A.getData(); float* ptr_a = a; for (int j = 0; j < N ; j++){ for (int i = 0; i < M ; i++){ *ptr_a++ = *(ptr_A+i*N+j); } } int LDA = M; int LDB = std::max(M, N); int NRHS = LDB; float *b = new float[LDB*NRHS], *b_ptr = b; for (int i = 0; i < LDB*NRHS; i++){ *b_ptr++=0.f; } b_ptr = b; for (int i = 0; i < std::min(LDB, NRHS); i++, b_ptr+=(NRHS+1)){ *b_ptr = 1.f; } float* S = new float[std::min(M,N)]; float condnum = 0.f; // The condition number of A in the 2-norm = S(1)/S(min(m,n)). if (RCOND < 0){ RCOND = 0.f; } int RANK = -1; // std::min(M,N); int LWORK = -1; //2 * (3*LDB + std::max( 2*std::min(M,N), LDB)); float* WORK = new float[1]; /* INFO: = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value. > 0: the algorithm for computing the SVD failed to converge; if INFO = i, i off-diagonal elements of an intermediate bidiagonal form did not converge to zero. */ int INFO; /* Query and allocate the optimal workspace */ /*int res = */sgelss_( &M, &N, &NRHS, a, &LDA, b, &LDB, S, &RCOND, &RANK, WORK, &LWORK, &INFO); LWORK = static_cast<int>(WORK[0]); delete [] WORK; WORK = new float[LWORK]; /*res = */sgelss_( &M, &N, &NRHS, a, &LDA, b, &LDB, S, &RCOND, &RANK, WORK, &LWORK, &INFO); // TODO: check INFO on exit condnum = S[0]/(S[std::min(M, N)]-1); // gMat2D<float> *tmp = new gMat2D<float>(b, LDB, LDB, false); float *ainv = new float[N*M]; float* ptr_b = ainv; float* ptr_B = b; for (int i = 0; i < N ; i++){ for (int j = 0; j < M ; j++){ *(ptr_b+i*M+j) = *(ptr_B+j*NRHS+i); } } Ainv = * new gMat2D<float>(ainv, N, M, true); // gMat2D<float> *tmp = new gMat2D<float>(b, LDB, NRHS, false); // gMat2D<float> *tmp1 = new gMat2D<float>(NRHS, LDB); // tmp->transpose(*tmp1); // Ainv = * new gMat2D<float>(tmp1->getData(), N, M, true); // std::cout << "A = " << std::endl << A << std::endl; // std::cout << "pinv(A) = " << std::endl << Ainv << std::endl; delete [] S; delete [] WORK; delete [] a; // delete tmp, tmp1; delete [] b; }
GURLS_EXPORT void cholesky(const gMat2D<float>& A, gMat2D<float>& L, bool upper) { cholesky<float>(A.getData(), A.rows(), A.cols(), L.getData(), upper); }