void somp(const Matrix<T>* XT, const Matrix<T>& D, SpMatrix<T>* spalphaT, const int Ngroups, const int LL, const T* eps, const bool adapt, const int numThreads) { if (LL <= 0) return; const int K = D.n(); const int L = MIN(D.m(),MIN(LL,K)); if (!D.isNormalized()) { cerr << "Current implementation of OMP does not support non-normalized dictionaries" << endl; return; } /// compute the Gram Matrix G=D'D Matrix<T> G; D.XtX(G); int NUM_THREADS=init_omp(numThreads); int i; #pragma omp parallel for private(i) for (i = 0; i< Ngroups; ++i) { const Matrix<T>& X = XT[i]; const int M = X.n(); SpMatrix<T>& spalpha = spalphaT[i]; spalpha.clear(); Vector<int> rv; Matrix<T> vM; T thrs = adapt ? eps[i] : M*(*eps); coreSOMP(X,D,G,vM,rv,L,thrs); spalpha.convert2(vM,rv,K); } }
inline void callFunction(mxArray* plhs[], const mxArray*prhs[], const int nlhs) { if (!mexCheckType<T>(prhs[2])) mexErrMsgTxt("type of argument 3 is not consistent"); if (mxIsSparse(prhs[2])) mexErrMsgTxt("argument 3 should not be sparse"); if (!mxIsStruct(prhs[3])) mexErrMsgTxt("argument 4 should be a struct"); Vector<T> y; getVector(prhs[0],y); INTM n = y.n(); const mwSize* dimsX=mxGetDimensions(prhs[1]); INTM p=static_cast<INTM>(dimsX[0]); INTM nX=static_cast<INTM>(dimsX[1]); if (nX != n) mexErrMsgTxt("second argument should be p x n"); Matrix<T> w0; getMatrix(prhs[2],w0); int pw = w0.m(); if (pw != p) mexErrMsgTxt("third argument should be p x nlambda"); mxArray *pr_lambdas = mxGetField(prhs[3],0,"lambda"); if (!pr_lambdas) mexErrMsgTxt("Missing field lambda"); Vector<T> lambdas; getVector(pr_lambdas,lambdas); int nlambdas=lambdas.n(); if (nlambdas != w0.n()) mexErrMsgTxt("third argument should be p x nlambda"); plhs[0]=createMatrix<T>(p,nlambdas); Matrix<T> w; getMatrix(plhs[0],w); ParamSurrogate<T> param; param.num_threads = getScalarStructDef<int>(prhs[3],"numThreads",-1); const int seed=getScalarStructDef<int>(prhs[3],"seed",0); param.strategy=getScalarStructDef<int>(prhs[3],"strategy",3); srandom(seed); param.epochs = getScalarStruct<long>(prhs[3],"epochs"); const bool seq = getScalarStructDef<bool>(prhs[3],"warm_restart",false); param.minibatches = getScalarStructDef<int>(prhs[3],"minibatches",1); param.normalized = getScalarStructDef<bool>(prhs[3],"normalized",false); param.verbose = getScalarStructDef<bool>(prhs[3],"verbose",false); ParamFISTA<T> paramprox; getStringStruct(prhs[3],"regul",paramprox.name_regul,paramprox.length_names); paramprox.regul = regul_from_string(paramprox.name_regul); paramprox.a=getScalarStructDef<T>(prhs[3],"eps",0); if (paramprox.regul==INCORRECT_REG) mexErrMsgTxt("Unknown regularization"); getStringStruct(prhs[3],"loss",paramprox.name_loss,paramprox.length_names); paramprox.loss = loss_from_string(paramprox.name_loss); if (paramprox.loss==INCORRECT_LOSS) mexErrMsgTxt("Unknown loss"); if (param.num_threads == -1) { #ifdef _OPENMP init_omp(MIN(MAX_THREADS,omp_get_num_procs())); #endif } else { #ifdef _OPENMP init_omp(param.num_threads); #endif } Matrix<T> optim; if (nlhs==2) { plhs[1]=createMatrix<T>(3,nlambdas); getMatrix<T>(plhs[1],optim); } else { optim.resize(3,nlambdas); } if (mxIsSparse(prhs[1])) { double* X_v; mwSize* X_r, *X_pB, *X_pE; INTM* X_r2, *X_pB2, *X_pE2; T* X_v2; X_v=static_cast<double*>(mxGetPr(prhs[1])); X_r=mxGetIr(prhs[1]); X_pB=mxGetJc(prhs[1]); X_pE=X_pB+1; createCopySparse<T>(X_v2,X_r2,X_pB2,X_pE2, X_v,X_r,X_pB,X_pE,n); SpMatrix<T> X(X_v2,X_r2,X_pB2,X_pE2,p,n,X_pB2[n]); if (seq) { incrementalProximalSeq(y,X,w0,w,paramprox,param,lambdas,optim); } else { incrementalProximal(y,X,w0,w,paramprox,param,lambdas,optim); } deleteCopySparse<T>(X_v2,X_r2,X_pB2,X_pE2,X_v,X_r); } else { T* prX = reinterpret_cast<T*>(mxGetPr(prhs[1])); Matrix<T> X(prX,p,n); if (seq) { incrementalProximalSeq(y,X,w0,w,paramprox,param,lambdas,optim); } else { incrementalProximal(y,X,w0,w,paramprox,param,lambdas,optim); } } }