static void updateSentenceCounts(MatrixXi& counts, const Sentence& sentence) { int last_tag = -1; for (const pair<Tag, string>& taggedWord : sentence.words) { int tag = taggedWord.first; assert (last_tag+1 < counts.rows()); assert(tag+1 < counts.cols()); counts(tag+1, last_tag+1) += 1; last_tag = tag; } // Now update transition to final state. counts(counts.cols()-1, last_tag+1) += 1; }
void Utils::saveImage(MatrixXi rawData, string outputFile) { QImage* img = new QImage(rawData.cols(), rawData.rows(), QImage::Format_RGB16); for (int y = 0; y < img->height(); y++) { VectorXi a = rawData.row(y); memcpy(img->scanLine(y), (void*)&a, img->bytesPerLine()); } QString file = QString::fromUtf8(outputFile.c_str()); img->save(file); }
MatrixXi get_submatrix(const MatrixXi& M, const VectorXi& ind) { MatrixXi Msub(ind.sum(),M.cols()); int k = 0; for(int i=0;i<M.rows();i++){ if(ind(i) == 1){ Msub.row(k) = M.row(i); k++; } } return Msub; }
void parameters::Mstep(datafile dat, model mod){ const MatrixXi & omega=mod.Get_model(),mat=dat.Get_mat_datafile(); const VectorXd & eff=dat.Get_eff_datafile(); for (int k=0;k<m_proba.cols();k++){ m_propor(k)= (eff.array()*(m_proba.col(k)).array()/m_proba.rowwise().sum().array()).sum() / eff.sum(); for (int b=0;b<mat.cols();b++){ if ((omega.row(k).array()==b).any()){ const VectorXi & who=mod.Get_var_block(k,b); m_param[k][b].Mstep(who,mat,m_proba_block[k].col(b),m_proba.col(k).array()/m_proba.rowwise().sum().array(),eff); } } } }
static void countsToProbs(MatrixXd& probs, const MatrixXi counts) { // Now form probability matrix from counts for (size_t col = 0; col < counts.cols(); col++) { double sum = 0; for (size_t row = 0; row < counts.rows(); row++) { sum += counts(row, col); } assert(sum > 0); for (size_t row = 0; row < counts.rows(); row++) { probs(row, col) = counts(row, col) / sum; // NaN != NaN, this tests that it's not NaN assert(probs(row, col) == probs(row, col)); assert(probs(row, col) >= 0); assert(probs(row, col) <= 1); } } }
// function used internally, which computes lasso fits for subsets containing a // small number of observations (typically only 3) and returns the indices of // the respective h observations with the smallest absolute residuals MatrixXi sparseSubsets(const MatrixXd& x, const VectorXd& y, const double& lambda, const int& h, const MatrixXi& subsets, const bool& normalize, const bool& useIntercept, const double& eps, const bool& useGram) { const int nsamp = subsets.cols(); MatrixXi indices(h, nsamp); for(int k = 0; k < nsamp; k++) { // compute lasso fit double intercept, crit; VectorXd coefficients, residuals; fastLasso(x, y, lambda, true, subsets.col(k), normalize, useIntercept, eps, useGram, false, intercept, coefficients, residuals, crit); // find h observations with smallest absolute residuals indices.col(k) = findSmallest(residuals.cwiseAbs(), h); } return indices; }
Density_2(const MatrixXd& X, const VectorXd& f, const MatrixXi& tri) : gen(clock()) { size_t N = X.rows(); assert(X.cols() == 2); assert(f.cols() == 1); assert(f.rows() == N); assert(tri.cols() == 3); CGAL::Triangulation_incremental_builder_2<T> builder(_t); builder.begin_triangulation(); // add vertices std::vector<T::Vertex_handle> vertices(N); for (size_t i = 0; i < N; ++i) { Point p(X(i,0),X(i,1)); vertices[i] = builder.add_vertex(Point(X(i,0), X(i,1))); vertices[i]->info() = i; } // add faces size_t Nt = tri.rows(); for (size_t i = 0; i < Nt; ++i) { int a = tri(i,0), b = tri(i,1), c = tri(i,2); builder.add_face(vertices[a], vertices[b], vertices[c]); } builder.end_triangulation(); // compute functions for (T::Finite_faces_iterator it = _t.finite_faces_begin (); it != _t.finite_faces_end(); ++it) { size_t a = it->vertex(0)->info(); size_t b = it->vertex(1)->info(); size_t c = it->vertex(2)->info(); _functions[it] = Function(vertices[a]->point(), f[a], vertices[b]->point(), f[b], vertices[c]->point(), f[c]); } }
MatrixXf CharacterController::GenerateXapv(const std::vector<int> &activeParts) { // pvDim without auto& allClipinfo = m_cpxClipinfo; auto& pvFacade = allClipinfo.PvFacade; int pvDim = pvFacade.GetAllPartDimension(); assert(pvDim > 0); MatrixXf Xabpv(allClipinfo.ClipFrames(), size(activeParts) * pvDim); ArrayXi incX(pvDim); incX.setLinSpaced(0, pvDim - 1); MatrixXi apMask = VectorXi::Map(activeParts.data(), activeParts.size()).replicate(1, pvDim).transpose(); apMask.array() = apMask.array() * pvDim + incX.replicate(1, apMask.cols()); auto maskVec = VectorXi::Map(apMask.data(), apMask.size()); selectCols(pvFacade.GetAllPartsSequence(), maskVec, &Xabpv); Pca<MatrixXf> pcaXabpv(Xabpv); int dXabpv = pcaXabpv.reducedRank(g_CharacterPcaCutoff); Xabpv = pcaXabpv.coordinates(dXabpv); XabpvT = pcaXabpv.components(dXabpv); uXabpv = pcaXabpv.mean(); if (g_EnableDebugLogging) { ofstream fout(g_CharacterAnalyzeDir / (m_pCharacter->Name + "_Xabpv.pd.csv")); fout << Xabpv.format(CSVFormat); fout.close(); } return Xabpv; }
// load an over-segmentation or pixel labeling void drwnLoadPixelLabels(cv::Mat& pixelLabels, const char *filename) { DRWN_ASSERT(filename != NULL); string ext = drwn::strExtension(string(filename)); std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower); if (ext.compare("png") == 0) { // load 8- or 16-bit png cv::Mat tmp = cv::imread(string(filename), CV_LOAD_IMAGE_ANYDEPTH); DRWN_ASSERT_MSG(tmp.data != NULL, filename); DRWN_LOG_DEBUG("drwnLoadPixelLabels read " << toString(tmp)); //! \bug 8-bit png files with colour tables are automatically //! converted to greyscale images. We'd like to just load their //! indexes. if (tmp.depth() != IPL_DEPTH_16U) { DRWN_LOG_WARNING_ONCE("Darwin does not currently support 8-bit PNG files; using drwnMultiSegConfig.regionDefinitions to convert."); const MatrixXi labels = gMultiSegRegionDefs.convertImageToLabels(filename); if (pixelLabels.data == NULL) { pixelLabels = cv::Mat(labels.rows(), labels.cols(), CV_32SC1); } DRWN_ASSERT_MSG((labels.rows() == pixelLabels.rows) && (labels.cols() == pixelLabels.cols), "size mismatch"); for (int y = 0; y < labels.rows(); y++) { for (int x = 0; x < labels.cols(); x++) { pixelLabels.at<int>(y, x) = labels(y, x); } } return; } if (pixelLabels.data == NULL) { pixelLabels = cv::Mat(tmp.rows, tmp.cols, CV_32SC1); } DRWN_ASSERT_MSG((tmp.rows == pixelLabels.rows) && (tmp.cols == pixelLabels.cols), "size mismatch"); tmp.convertTo(pixelLabels, CV_32S); } else if (ext.compare("txt") == 0) { // integer text file ifstream ifs(filename); DRWN_ASSERT_MSG(!ifs.fail(), filename); int w = drwnCountFields(&ifs); DRWN_LOG_DEBUG(filename << " has width " << w); list<int> values; while (1) { int v; ifs >> v; if (ifs.fail()) break; values.push_back(v); } int h = values.size() / w; DRWN_LOG_DEBUG(filename << " has height " << h); if (pixelLabels.data == NULL) { pixelLabels = cv::Mat(h, w, CV_32SC1); } DRWN_ASSERT_MSG((pixelLabels.rows = h) && (pixelLabels.cols = w), "size mismatch"); int *p = pixelLabels.ptr<int>(0); list<int>::const_iterator it = values.begin(); while (it != values.end()) { *p++ = *it++; } } else {
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { // trw_bprop_helper2(model, psi_ij_rho, psi_i, rho, maxiter, n, m1, m2, b_i,... // dm1, dm2, dn, dpsi_i, dpsi_ij); int i=0; int nnodes = mapdouble(mxGetField(prhs[i],0,"nnodes"))(0); int ncliques = mapdouble(mxGetField(prhs[i],0,"ncliques"))(0); int nvals = mapdouble(mxGetField(prhs[i],0,"nvals"))(0); MatrixXi pairs = mapdouble(mxGetField(prhs[i],0,"pairs")).cast<int>(); pairs.array() -= 1; MatrixXi N1 = mapdouble(mxGetField(prhs[i],0,"N1")).cast<int>(); N1.array() -= 1; MatrixXi N2 = mapdouble(mxGetField(prhs[i],0,"N2")).cast<int>(); N2.array() -= 1; MatrixXi tree2clique = mapdouble(mxGetField(prhs[i],0,"tree2clique")).cast<int>(); tree2clique.array() -= 1; MatrixXi treeschedule = mapdouble(mxGetField(prhs[i],0,"treeschedule")).cast<int>(); treeschedule.array() -= 1; i++; MatrixMd psi_ij = mapdouble(prhs[i++]); MatrixMd psi_i = mapdouble(prhs[i++]); double rho = mapdouble(prhs[i++])(0); int maxiter = mapdouble(prhs[i++])(0); MatrixMd n = mapdouble(prhs[i++]); MatrixMd m1 = mapdouble(prhs[i++]); MatrixMd m2 = mapdouble(prhs[i++]); MatrixMd b_i = mapdouble(prhs[i++]); MatrixMd mstor = mapdouble(prhs[i++]); MatrixMd dm1 = mapdouble(prhs[i++]); MatrixMd dm2 = mapdouble(prhs[i++]); MatrixMd dn = mapdouble(prhs[i++]); MatrixMd dpsi_i = mapdouble(prhs[i++]); MatrixMd dpsi_ij = mapdouble(prhs[i++]); MatrixMd b_ij0 = mapdouble(prhs[i++]); MatrixMd db_ij0 = mapdouble(prhs[i++]); int dorec = mapdouble(prhs[i++]).cast<int>()(0); MatrixMi w = mapint32(prhs[i++]); #pragma omp parallel for num_threads(NTHREAD) for(int c=0; c<ncliques; c++) { int i = pairs(c, 0); int j = pairs(c, 1); for(int yi=0; yi<nvals; yi++) { for(int yj=0; yj<nvals; yj++) { int index = yi + yj*nvals; //b_ij0(index,c) = b_ij0(index,c)*psi_i(yi,i)*psi_i(yj,j)*n(yi,i)*n(yj,j)/m1(yi,c)/m2(yj,c); dpsi_i(yi, i) = dpsi_i(yi, i) + db_ij0(index, c)*b_ij0(index, c)/psi_i(yi, i); dpsi_i(yj, j) = dpsi_i(yj, j) + db_ij0(index, c)*b_ij0(index, c)/psi_i(yj, j); dn(yi, i) = dn(yi, i) + db_ij0(index, c)*b_ij0(index, c)/n(yi, i); dn(yj, j) = dn(yj, j) + db_ij0(index, c)*b_ij0(index, c)/n(yj, j); dm1(yi, c) = dm1(yi, c) - db_ij0(index, c)*b_ij0(index, c)/m1(yi, c); dm2(yj, c) = dm2(yj, c) - db_ij0(index, c)*b_ij0(index, c)/m2(yj, c); } } } #pragma omp parallel for num_threads(NTHREAD) for(int i=0; i<b_i.cols(); i++) { for(int yi=0; yi<nvals; yi++) { for(int k=0; k<N1.cols(); k++) { int d = N1(i, k); if(d==-2) continue; //n(yi, i) *= m1(yi, d); dm1(yi,d) += rho * dn(yi,i)*n(yi,i)/m1(yi,d); } for(int k=0; k<N2.cols(); k++) { int d = N2(i, k); if(d==-2) continue; //n(yi, i) *= m2(yi, d); dm2(yi,d) += rho * dn(yi,i)*n(yi,i)/m2(yi,d); } } } //tree_ncliques = sum(double(model.tree2clique>0),1); //ntree = length(tree_ncliques); int ntree = tree2clique.cols(); MatrixXi tree_ncliques = MatrixXi::Zero(ntree,1); for(int tree=0; tree<tree2clique.cols(); tree++) for(i=0; i<tree2clique.rows(); i++) if(tree2clique(i,tree) != -1) tree_ncliques(tree)++; int reps; double conv; for(reps=0; reps<maxiter; reps++) { // must re-order blocks //for(int block=0; block<treeschedule.cols(); block++){ for(int block=treeschedule.cols()-1; block>=0; block--) { // need not re-order trees, but why not... // helps if someone specifies not parallel trees // for(int treenum=treeschedule.rows()-1; treenum>=0; treenum--){ #pragma omp parallel for schedule(dynamic) num_threads(NTHREAD) for(int treenum=0; treenum<treeschedule.rows(); treenum++) { MatrixXd S (nvals,nvals); MatrixXd m0(nvals,1); int tree = treeschedule(treenum,block); if(tree==-1) continue; int ncliques = tree_ncliques(tree); for(int c0=2*ncliques-1; c0>=0; c0--) { int c, mode; if(c0<ncliques) { c = tree2clique(c0,tree); mode = 1; } else { c = tree2clique(ncliques - 1 - (c0-ncliques),tree); mode = 2; } //cout << "BW c " << c << " mode " << mode << endl; int i = pairs(c,0); int j = pairs(c,1); if( mode==1 ) { for(int yi=0; yi<nvals; yi++) n(yi, i) = 1; for(int k=0; k<N1.cols(); k++) { int d = N1(i, k); if(d==-2) continue; for(int yi=0; yi<nvals; yi++) n(yi, i) *= m1(yi, d); } for(int k=0; k<N2.cols(); k++) { int d = N2(i, k); if(d==-2) continue; for(int yi=0; yi<nvals; yi++) n(yi, i) *= m2(yi, d); } // n.col(i) = n.col(i).array().pow(rho); if(rho==1) { //nothing } else if(rho==.5) { n.col(i) = n.col(i).array().sqrt(); } else n.col(i) = n.col(i).array().pow(rho); // compute m(y_j) for(int yj=0; yj<nvals; yj++) { m0(yj) = 0; for(int yi=0; yi<nvals; yi++) { int index = yi + yj*nvals; S(yi,yj) = psi_ij(index, c)*psi_i(yi, i)*n(yi, i)/m1(yi, c); m0(yj) += S(yi,yj); } } double k = S.sum(); MatrixXd dm0 = dm2.col(c)/k; dm0.array() -= (dm2.col(c).array()*m0.array()).sum()/(k*k); MatrixXd dn = 0*n.col(i); for(int yj=0; yj<nvals; yj++) { for(int yi=0; yi<nvals; yi++) { int index = yi + yj*nvals; dpsi_ij(index,c) += dm0(yj)*S(yi,yj)/psi_ij(index,c); dpsi_i(yi,i) += dm0(yj)*S(yi,yj)/psi_i(yi,i); dn(yi) += dm0(yj)*S(yi,yj)/n(yi,i); dm1(yi,c) -= dm0(yj)*S(yi,yj)/m1(yi,c); } } for(int yi=0; yi<nvals; yi++) { for(int k=0; k<N1.cols(); k++) { int d = N1(i, k); if(d==-2) continue; dm1(yi,d) += rho*dn(yi)*n(yi,i)/m1(yi,d); } for(int k=0; k<N2.cols(); k++) { int d = N2(i, k); if(d==-2) continue; dm2(yi,d) += rho*dn(yi)*n(yi,i)/m2(yi,d); } } dm2.col(c) *= 0.0; if( dorec ) for(int yj=nvals-1; yj>=0; yj--) { w(tree)=w(tree)-1; m2(yj,c)=mstor(w(tree),tree); } } else if( mode==2 ) { for( int yj=0; yj<nvals; yj++) n(yj, j) = 1; for(int k=0; k<N1.cols(); k++) { int d = N1(j, k); if(d==-2) continue; for( int yj=0; yj<nvals; yj++) n(yj, j) *= m1(yj, d); } for(int k=0; k<N2.cols(); k++) { int d = N2(j, k); if(d==-2) continue; for( int yj=0; yj<nvals; yj++) n(yj, j) *= m2(yj, d); } // n.col(j) = n.col(j).array().pow(rho); if(rho==1) { //nothing } else if(rho==.5) { n.col(j) = n.col(j).array().sqrt(); } else n.col(j) = n.col(j).array().pow(rho); for(int yi=0; yi<nvals; yi++) { m0(yi) = 0; for(int yj=0; yj<nvals; yj++) { int index = yi + yj*nvals; S(yi,yj) = psi_ij(index, c)*psi_i(yj, j)*n(yj, j)/m2(yj, c); m0(yi) += S(yi,yj); } } double k = S.sum(); MatrixXd dm0 = dm1.col(c)/k; dm0.array() -= (dm1.col(c).array()*m0.array()).sum()/(k*k); MatrixXd dn = 0*n.col(i); for(int yj=0; yj<nvals; yj++) { for(int yi=0; yi<nvals; yi++) { int index = yi + yj*nvals; dpsi_ij(index,c) += dm0(yi)*S(yi,yj)/psi_ij(index,c); dpsi_i(yj,j) += dm0(yi)*S(yi,yj)/psi_i(yj,j); dn(yj) += dm0(yi)*S(yi,yj)/n(yj,j); dm2(yj,c) -= dm0(yi)*S(yi,yj)/m2(yj,c); } } for(int yj=0; yj<nvals; yj++) { for(int k=0; k<N1.cols(); k++) { int d = N1(j, k); if(d==-2) continue; dm1(yj, d) += rho*dn(yj)*n(yj, j)/m1(yj, d); } for(int k=0; k<N2.cols(); k++) { int d = N2(j, k); if(d==-2) continue; dm2(yj, d) += rho*dn(yj)*n(yj, j)/m2(yj, d); } } dm1.col(c) *= 0.0; if( dorec ) for(int yi=nvals-1; yi>=0; yi--) { w(tree)=w(tree)-1; m1(yi,c)=mstor(w(tree),tree); } } } } } } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { // This is useful for debugging whether Matlab is caching the mex binary //mexPrintf("%s %s\n",__TIME__,__DATE__); igl::matlab::MexStream mout; std::streambuf *outbuf = std::cout.rdbuf(&mout); #else int main(int argc, char * argv[]) { #endif using namespace std; using namespace Eigen; using namespace igl; using namespace igl::matlab; using namespace igl::cgal; MatrixXd V; MatrixXi F; igl::cgal::RemeshSelfIntersectionsParam params; string prefix; bool use_obj_format = false; #ifdef MEX if(nrhs < 2) { mexErrMsgTxt("nrhs < 2"); } parse_rhs_double(prhs,V); parse_rhs_index(prhs+1,F); mexErrMsgTxt(V.cols()==3,"V must be #V by 3"); mexErrMsgTxt(F.cols()==3,"F must be #F by 3"); if(nrhs>2) { int i = 2; while(i<nrhs) { if(!mxIsChar(prhs[i])) { mexErrMsgTxt("Parameter names should be char strings"); } // Cast to char const char * name = mxArrayToString(prhs[i]); if(strcmp("DetectOnly",name) == 0) { validate_arg_scalar(i,nrhs,prhs,name); validate_arg_logical(i,nrhs,prhs,name); mxLogical * v = (mxLogical *)mxGetData(prhs[++i]); params.detect_only = *v; }else if(strcmp("FirstOnly",name) == 0) { validate_arg_scalar(i,nrhs,prhs,name); validate_arg_logical(i,nrhs,prhs,name); mxLogical * v = (mxLogical *)mxGetData(prhs[++i]); params.first_only = *v; }else { mexErrMsgTxt(C_STR("Unsupported parameter: "<<name)); } i++; } } #else if(argc <= 1) { cerr<<"Usage:"<<endl<<" selfintersect [path to .off/.obj mesh] " "[0 or 1 for detect only]"<<endl; return 1; } // Apparently CGAL doesn't have a good data structure triangle soup. Their // own examples use (V,F): // http://www.cgal.org/Manual/latest/doc_html/cgal_manual/AABB_tree/Chapter_main.html#Subsection_64.3.7 // // Load mesh string filename(argv[1]); if(!read_triangle_mesh(filename,V,F)) { //cout<<REDRUM("Reading "<<filename<<" failed.")<<endl; return false; } cout<<GREENGIN("Read "<<filename<<" successfully.")<<endl; { // dirname, basename, extension and filename string dirname,b,ext; pathinfo(filename,dirname,b,ext,prefix); prefix = dirname + "/" + prefix; transform(ext.begin(), ext.end(), ext.begin(), ::tolower); use_obj_format = ext == "obj"; } if(argc>2) { //http://stackoverflow.com/a/9748431/148668 char *p; long d = strtol(argv[2], &p, 10); if (errno != 0 || *p != '\0') { cerr<<"detect only param should be 0 or 1"<<endl; }else { params.detect_only = d!=0; } } #endif MatrixXi IF; VectorXi J,IM; if(F.rows()>0) { // Check that there aren't any combinatorially or geometrically degenerate triangles VectorXd A; doublearea(V,F,A); if(A.minCoeff()<=0) { #ifdef MEX mexErrMsgTxt("Geometrically degenerate face found."); #else cerr<<"Geometrically degenerate face found."<<endl; return 1; #endif } VectorXi F12,F23,F31; F12 = F.col(0)-F.col(1); F23 = F.col(1)-F.col(2); F31 = F.col(2)-F.col(0); if( F12.minCoeff() == 0 || F23.minCoeff() == 0 || F31.minCoeff() == 0) { #ifdef MEX mexErrMsgTxt("Combinatorially degenerate face found."); #else cerr<<"Geometrically degenerate face found."<<endl; return 1; #endif } // Now mesh self intersections { MatrixXd tempV; MatrixXi tempF; remesh_self_intersections(V,F,params,tempV,tempF,IF,J,IM); //cout<<BLUEGIN("Found and meshed "<<IF.rows()<<" pair"<<(IF.rows()==1?"":"s") // <<" of self-intersecting triangles.")<<endl; V=tempV; F=tempF; #ifndef MEX cout<<"writing pair list to "<<(prefix+"-IF.dmat")<<endl; writeDMAT((prefix+"-IF.dmat").c_str(),IF); cout<<"writing map to F list to "<<(prefix+"-J.dmat")<<endl; writeDMAT((prefix+"-J.dmat").c_str(),J); cout<<"writing duplicat index map to "<<(prefix+"-IM.dmat")<<endl; writeDMAT((prefix+"-IM.dmat").c_str(),IM); if(!params.detect_only) { if(use_obj_format) { cout<<"writing mesh to "<<(prefix+"-selfintersect.obj")<<endl; writeOBJ(prefix+"-selfintersect.obj",V,F); }else { cout<<"writing mesh to "<<(prefix+"-selfintersect.off")<<endl; writeOFF(prefix+"-selfintersect.off",V,F); } } #endif } // Double-check output #ifdef DEBUG // There should be *no* combinatorial duplicates { MatrixXi tempF; unique_simplices(F,tempF); if(tempF.rows() < F.rows()) { cout<<REDRUM("Error: selfintersect created "<< F.rows()-tempF.rows()<<" combinatorially duplicate faces")<<endl; }else { assert(tempF.rows() == F.rows()); cout<<GREENGIN("selfintersect created no duplicate faces")<<endl; } F = tempF; } #endif } #ifdef MEX // Prepare left-hand side switch(nlhs) { case 5: { // Treat indices as reals plhs[4] = mxCreateDoubleMatrix(IM.rows(),IM.cols(), mxREAL); double * IMp = mxGetPr(plhs[4]); VectorXd IMd = (IM.cast<double>().array()+1).matrix(); copy(&IMd.data()[0],&IMd.data()[0]+IMd.size(),IMp); // Fallthrough } case 4: { // Treat indices as reals plhs[3] = mxCreateDoubleMatrix(J.rows(),J.cols(), mxREAL); double * Jp = mxGetPr(plhs[3]); VectorXd Jd = (J.cast<double>().array()+1).matrix(); copy(&Jd.data()[0],&Jd.data()[0]+Jd.size(),Jp); // Fallthrough } case 3: { // Treat indices as reals plhs[2] = mxCreateDoubleMatrix(IF.rows(),IF.cols(), mxREAL); double * IFp = mxGetPr(plhs[2]); MatrixXd IFd = (IF.cast<double>().array()+1).matrix(); copy(&IFd.data()[0],&IFd.data()[0]+IFd.size(),IFp); // Fallthrough } case 2: { // Treat indices as reals plhs[1] = mxCreateDoubleMatrix(F.rows(),F.cols(), mxREAL); double * Fp = mxGetPr(plhs[1]); MatrixXd Fd = (F.cast<double>().array()+1).matrix(); copy(&Fd.data()[0],&Fd.data()[0]+Fd.size(),Fp); // Fallthrough } case 1: { plhs[0] = mxCreateDoubleMatrix(V.rows(),V.cols(), mxREAL); double * Vp = mxGetPr(plhs[0]); copy(&V.data()[0],&V.data()[0]+V.size(),Vp); break; } default:break; } // Restore the std stream buffer Important! std::cout.rdbuf(outbuf); #else return 0; #endif }
/** * The function main marks the entry point of the program. * By default, main has the storage class extern. * * @param [in] argc (argument count) is an integer that indicates how many arguments were entered on the command line when the program was started. * @param [in] argv (argument vector) is an array of pointers to arrays of character objects. The array objects are null-terminated strings, representing the arguments that were entered on the command line when the program was started. * @return the value that was set to exit() (which is 0 if exit() is called via quit()). */ int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // QFile t_fileIn("./MNE-sample-data/MEG/sample/sample_audvis_raw.fif"); // QFile t_fileIn("./MNE-sample-data/MEG/test_output.fif"); QFile t_fileIn("./MNE-sample-data/MEG/sample/sample_write/test_output.fif"); QFile t_fileOut("./MNE-sample-data/MEG/sample/sample_write/test_output2.fif"); // QFile t_fileOut("./MNE-sample-data/MEG/test_output2.fif"); // // Setup for reading the raw data // FiffRawData raw(t_fileIn); // // Set up pick list: MEG + STI 014 - bad channels // // bool want_meg = true; bool want_eeg = false; bool want_stim = false; QStringList include; include << "STI 014"; // MatrixXi picks = Fiff::pick_types(raw.info, want_meg, want_eeg, want_stim, include, raw.info.bads); MatrixXi picks = raw.info.pick_types(want_meg, want_eeg, want_stim, include, raw.info.bads); // prefer member function if(picks.cols() == 0) { include.clear(); include << "STI101" << "STI201" << "STI301"; // picks = Fiff::pick_types(raw.info, want_meg, want_eeg, want_stim, include, raw.info.bads); picks = raw.info.pick_types(want_meg, want_eeg, want_stim, include, raw.info.bads);// prefer member function if(picks.cols() == 0) { printf("channel list may need modification\n"); return -1; } } // RowVectorXd cals; FiffStream::SPtr outfid = Fiff::start_writing_raw(t_fileOut,raw.info, cals/*, picks*/); // // Set up the reading parameters // fiff_int_t from = raw.first_samp; fiff_int_t to = raw.last_samp; float quantum_sec = 10.0f;//read and write in 10 sec junks fiff_int_t quantum = ceil(quantum_sec*raw.info.sfreq); // // To read the whole file at once set // //quantum = to - from + 1; // // // Read and write all the data // bool first_buffer = true; fiff_int_t first, last; MatrixXd data; MatrixXd times; for(first = from; first < to; first+=quantum) { last = first+quantum-1; if (last > to) { last = to; } if (!raw.read_raw_segment(data,times,first,last/*,picks*/)) { printf("error during read_raw_segment\n"); return -1; } // // You can add your own miracle here // printf("Writing..."); if (first_buffer) { if (first > 0) outfid->write_int(FIFF_FIRST_SAMPLE,&first); first_buffer = false; } outfid->write_raw_buffer(data,cals); printf("[done]\n"); } outfid->finish_writing_raw(); printf("Finished\n"); return 0;//a.exec(); }
int main(int argc, char *argv[]) { const char *inLabelExt = ".txt"; const char *outScoreFile = NULL; bool bShowConfusion = false; // process commandline arguments DRWN_BEGIN_CMDLINE_PROCESSING(argc, argv) DRWN_CMDLINE_STR_OPTION("-inLabels", inLabelExt) DRWN_CMDLINE_STR_OPTION("-outScores", outScoreFile) DRWN_CMDLINE_BOOL_OPTION("-confusion", bShowConfusion) DRWN_END_CMDLINE_PROCESSING(usage()); if (DRWN_CMDLINE_ARGC != 1) { usage(); return -1; } drwnCodeProfiler::tic(drwnCodeProfiler::getHandle("main")); // read list of evaluation images const char *evalList = DRWN_CMDLINE_ARGV[0]; DRWN_LOG_MESSAGE("Reading evaluation list from " << evalList << "..."); vector<string> baseNames = drwnReadFile(evalList); DRWN_LOG_MESSAGE("...read " << baseNames.size() << " images"); const int nLabels = gMultiSegRegionDefs.maxKey() + 1; drwnConfusionMatrix confusion(nLabels); vector<double> scores(baseNames.size()); // process results DRWN_LOG_MESSAGE("Processing results (" << inLabelExt << ")..."); int hProcessImage = drwnCodeProfiler::getHandle("processImage"); for (int i = 0; i < (int)baseNames.size(); i++) { drwnCodeProfiler::tic(hProcessImage); string lblFilename = gMultiSegConfig.filename("lblDir", baseNames[i], "lblExt"); string resFilename = gMultiSegConfig.filebase("outputDir", baseNames[i]) + string(inLabelExt); DRWN_LOG_STATUS("..." << baseNames[i] << " (" << (i + 1) << " of " << baseNames.size() << ")"); // read ground-truth labels MatrixXi actualLabels; //drwnReadUnknownMatrix(actualLabels, lblFilename.c_str()); drwnLoadPixelLabels(actualLabels, lblFilename.c_str(), nLabels); // read inferred labels MatrixXi predictedLabels(actualLabels.rows(), actualLabels.cols()); drwnReadMatrix(predictedLabels, resFilename.c_str()); DRWN_ASSERT((predictedLabels.rows() == actualLabels.rows()) && (predictedLabels.cols() == actualLabels.cols())); // accumulate results for this image drwnConfusionMatrix imageConfusion(nLabels); for (int y = 0; y < actualLabels.rows(); y++) { for (int x = 0; x < actualLabels.cols(); x++) { if (actualLabels(y, x) < 0) continue; imageConfusion.accumulate(actualLabels(y, x), predictedLabels(y, x)); } } scores[i] = imageConfusion.accuracy(); // add to dataset results confusion.accumulate(imageConfusion); drwnCodeProfiler::toc(hProcessImage); } // display results if (bShowConfusion) { confusion.printRowNormalized(cout, "--- Class Confusion Matrix ---"); confusion.printPrecisionRecall(cout, "--- Recall/Precision (by Class) ---"); confusion.printF1Score(cout, "--- F1-Score (by Class) ---"); confusion.printJaccard(cout, "--- Intersection/Union Metric (by Class) ---"); } DRWN_LOG_MESSAGE("Overall class accuracy: " << confusion.accuracy() << " (" << evalList << ")"); DRWN_LOG_MESSAGE("Average class accuracy: " << confusion.avgRecall() << " (" << evalList << ")"); DRWN_LOG_MESSAGE("Average jaccard score: " << confusion.avgJaccard() << " (" << evalList << ")"); // write scores if (outScoreFile != NULL) { ofstream ofs(outScoreFile); DRWN_ASSERT_MSG(!ofs.fail(), outScoreFile); for (int i = 0; i < (int)scores.size(); i++) { ofs << scores[i] << "\n"; } ofs.close(); } // clean up and print profile information drwnCodeProfiler::toc(drwnCodeProfiler::getHandle("main")); drwnCodeProfiler::print(); return 0; }
void drwnNNGraphImageData::setLabels(const MatrixXi& labels) { DRWN_ASSERT(((size_t)labels.rows() == height()) && ((size_t)labels.cols() == width())); _labels = labels; }
bool EdgeReduce(MatrixXd & data, MatrixXi &G, MatrixXd &Gval, int &order, double lamda) { bool flag = false; for (int i = 0; i < G.rows(); i++) { for (int j = 0; j < G.cols(); j++) { if (G(i, j) != 0) { if (order == 0) { double cmiv = cmi(data.row(i), data.row(j)); Gval(i, j) = Gval(j, i) = cmiv; if (cmiv < lamda) { G(i, j) = G(j, i) = 0; flag = true; } } else { vector<int> adj; for (int k = 0; k < G.rows(); k++) { if (G(i, k) != 0 && G(j, k) != 0) { adj.push_back(k); } } if (adj.size() >= order) { double cmiv = 0; vector<int>pos; vector< vector<int>> combntnslist; dfs_combntnslist(adj.size() - 1, order - 1, pos, combntnslist); MatrixXd v1 = data.row(i); MatrixXd v2 = data.row(j); MatrixXd vcs(order, v1.cols()); for (int k = 0; k < combntnslist.size(); k++) { for (int w = 0; w <order; w++) { vcs.row(order - 1 - w) = data.row(adj[combntnslist[k][w]]); } double a = MI2(v1, v2, vcs); cmiv = max(cmiv, a); } Gval(i, j) = Gval(j, i) = cmiv; if (cmiv < lamda) { G(i, j) = G(j, i) = 0; } flag = true; } } } } } return flag; }
void igl::collapse_small_triangles( const Eigen::MatrixXd & V, const Eigen::MatrixXi & F, const double eps, Eigen::MatrixXi & FF) { using namespace Eigen; using namespace std; // Compute bounding box diagonal length double bbd = bounding_box_diagonal(V); MatrixXd l; edge_lengths(V,F,l); VectorXd dblA; doublearea(l,dblA); // Minimum area tolerance const double min_dblarea = 2.0*eps*bbd*bbd; Eigen::VectorXi FIM = colon<int>(0,V.rows()-1); int num_edge_collapses = 0; // Loop over triangles for(int f = 0;f<F.rows();f++) { if(dblA(f) < min_dblarea) { double minl = 0; int minli = -1; // Find shortest edge for(int e = 0;e<3;e++) { if(minli==-1 || l(f,e)<minl) { minli = e; minl = l(f,e); } } double maxl = 0; int maxli = -1; // Find longest edge for(int e = 0;e<3;e++) { if(maxli==-1 || l(f,e)>maxl) { maxli = e; maxl = l(f,e); } } // Be sure that min and max aren't the same maxli = (minli==maxli?(minli+1)%3:maxli); // Collapse min edge maintaining max edge: i-->j // Q: Why this direction? int i = maxli; int j = ((minli+1)%3 == maxli ? (minli+2)%3: (minli+1)%3); assert(i != minli); assert(j != minli); assert(i != j); FIM(F(f,i)) = FIM(F(f,j)); num_edge_collapses++; } } // Reindex faces MatrixXi rF = F; // Loop over triangles for(int f = 0;f<rF.rows();f++) { for(int i = 0;i<rF.cols();i++) { rF(f,i) = FIM(rF(f,i)); } } FF.resize(rF.rows(),rF.cols()); int num_face_collapses=0; // Only keep uncollapsed faces { int ff = 0; // Loop over triangles for(int f = 0;f<rF.rows();f++) { bool collapsed = false; // Check if any indices are the same for(int i = 0;i<rF.cols();i++) { for(int j = i+1;j<rF.cols();j++) { if(rF(f,i)==rF(f,j)) { collapsed = true; num_face_collapses++; break; } } } if(!collapsed) { FF.row(ff++) = rF.row(f); } } // Use conservative resize FF.conservativeResize(ff,FF.cols()); } //cout<<"num_edge_collapses: "<<num_edge_collapses<<endl; //cout<<"num_face_collapses: "<<num_face_collapses<<endl; if(num_edge_collapses == 0) { // There must have been a "collapsed edge" in the input assert(num_face_collapses==0); // Base case return; } //// force base case //return; MatrixXi recFF = FF; return collapse_small_triangles(V,recFF,eps,FF); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //mexPrintf("Compiled at %s on %s\n",__TIME__,__DATE__); if(nrhs != 2 && nrhs != 3) { mexErrMsgTxt("The number of input arguments must be 2 or 3."); } //mexPrintf("%s %s\n",__TIME__,__DATE__); igl::MexStream mout; std::streambuf *outbuf = std::cout.rdbuf(&mout); #else int main(int argc, char * argv[]) { #endif using namespace std; using namespace Eigen; using namespace igl; MatrixXd V; MatrixXi F; VectorXi IM; string prefix; bool use_obj_format = false; double eps = FLOAT_EPS; #ifdef MEX // This parses first two arguements parse_rhs_double(prhs,V); parse_rhs_index(prhs+1,F); mexErrMsgTxt(V.cols()==3,"V must be #V by 3"); mexErrMsgTxt(F.cols()==3,"F must be #F by 3"); if(nrhs==3) { if(mxGetM(prhs[2]) != 1 || mxGetN(prhs[2]) != 1) { mexErrMsgTxt("3rd argument should be scalar"); } eps = *mxGetPr(prhs[2]); } #else if(argc <= 1 || argc>3) { cerr<<"Usage:"<<endl<< " collapse_small_triangles [path to mesh]"<<endl<< "or "<<endl<< " collapse_small_triangles [path to mesh] [eps]"<<endl; return 1; } // Load mesh string filename(argv[1]); if(!read_triangle_mesh(filename,V,F)) { cout<<REDRUM("Reading "<<filename<<" failed.")<<endl; return false; } cout<<GREENGIN("Read "<<filename<<" successfully.")<<endl; { // dirname, basename, extension and filename string dirname,b,ext; pathinfo(filename,dirname,b,ext,prefix); prefix = dirname + "/" + prefix; transform(ext.begin(), ext.end(), ext.begin(), ::tolower); use_obj_format = ext == "obj"; } if(argc == 3) { if(sscanf(argv[2], "%lf", &eps)!=1) { cout<<REDRUM("Parsing "<<argv[2]<<" failed.")<<endl; return 1; }else { cout<<"eps: "<<eps<<endl; } }else { cout<<"Default eps: "<<eps<<endl; } #endif // let's first try to merge small triangles { MatrixXd tempV; MatrixXi tempF; collapse_small_triangles(V,F,eps,tempF); //if(F.rows() == tempF.rows()) //{ // cout<<GREENGIN("No small triangles detected.")<<endl; //}else //{ // cout<<BLUEGIN("Collapsed all small triangles, reducing "<<F.rows()<< // " input triangles to "<<tempF.rows()<<" triangles.")<<endl; //} F=tempF; #ifndef MEX if(use_obj_format) { cout<<"writing mesh to "<<(prefix+"-collapse.obj")<<endl; writeOBJ(prefix+"-collapse.obj",V,F); }else { cout<<"writing mesh to "<<(prefix+"-collapse.off")<<endl; writeOFF(prefix+"-collapse.off",V,F); } #endif } #ifdef MEX // Prepare left-hand side nlhs = 1; // Treat indices as reals plhs[0] = mxCreateDoubleMatrix(F.rows(),F.cols(), mxREAL); double * Fp = mxGetPr(plhs[0]); MatrixXd Fd = (F.cast<double>().array()+1).matrix(); copy(&Fd.data()[0],&Fd.data()[0]+Fd.size(),Fp); // Restore the std stream buffer Important! std::cout.rdbuf(outbuf); #else return 0; #endif }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { // This is useful for debugging whether Matlab is caching the mex binary //mexPrintf("%s %s\n",__TIME__,__DATE__); igl::matlab::MexStream mout; std::streambuf *outbuf = std::cout.rdbuf(&mout); using namespace std; using namespace Eigen; using namespace igl; using namespace igl::matlab; using namespace igl::copyleft::cgal; MatrixXd V; MatrixXi F; igl::copyleft::cgal::RemeshSelfIntersectionsParam params; string prefix; bool use_obj_format = false; if(nrhs < 2) { mexErrMsgTxt("nrhs < 2"); } parse_rhs_double(prhs,V); parse_rhs_index(prhs+1,F); mexErrMsgTxt(V.cols()==3,"V must be #V by 3"); mexErrMsgTxt(F.cols()==3,"F must be #F by 3"); if(nrhs>2) { int i = 2; while(i<nrhs) { if(!mxIsChar(prhs[i])) { mexErrMsgTxt("Parameter names should be char strings"); } // Cast to char const char * name = mxArrayToString(prhs[i]); if(strcmp("DetectOnly",name) == 0) { validate_arg_scalar(i,nrhs,prhs,name); validate_arg_logical(i,nrhs,prhs,name); mxLogical * v = (mxLogical *)mxGetData(prhs[++i]); params.detect_only = *v; }else if(strcmp("FirstOnly",name) == 0) { validate_arg_scalar(i,nrhs,prhs,name); validate_arg_logical(i,nrhs,prhs,name); mxLogical * v = (mxLogical *)mxGetData(prhs[++i]); params.first_only = *v; }else if(strcmp("StitchAll",name) == 0) { validate_arg_scalar(i,nrhs,prhs,name); validate_arg_logical(i,nrhs,prhs,name); mxLogical * v = (mxLogical *)mxGetData(prhs[++i]); params.stitch_all = *v; }else { mexErrMsgTxt(C_STR("Unsupported parameter: "<<name)); } i++; } } MatrixXi IF; VectorXi J,IM; if(F.rows()>0) { // Check that there aren't any combinatorially or geometrically degenerate triangles VectorXd A; doublearea(V,F,A); if(A.minCoeff()<=0) { mexErrMsgTxt("Geometrically degenerate face found."); } if( (F.array().col(0) == F.array().col(1)).any() || (F.array().col(1) == F.array().col(2)).any() || (F.array().col(2) == F.array().col(0)).any()) { mexErrMsgTxt("Combinatorially degenerate face found."); } // Now mesh self intersections { MatrixXd tempV; MatrixXi tempF; remesh_self_intersections(V,F,params,tempV,tempF,IF,J,IM); //cout<<BLUEGIN("Found and meshed "<<IF.rows()<<" pair"<<(IF.rows()==1?"":"s") // <<" of self-intersecting triangles.")<<endl; V=tempV; F=tempF; } // Double-check output #ifdef DEBUG // There should be *no* combinatorial duplicates { MatrixXi tempF; unique_simplices(F,tempF); if(tempF.rows() < F.rows()) { cout<<REDRUM("Error: selfintersect created "<< F.rows()-tempF.rows()<<" combinatorially duplicate faces")<<endl; }else { assert(tempF.rows() == F.rows()); cout<<GREENGIN("selfintersect created no duplicate faces")<<endl; } F = tempF; } #endif } // Prepare left-hand side switch(nlhs) { case 5: { // Treat indices as reals plhs[4] = mxCreateDoubleMatrix(IM.rows(),IM.cols(), mxREAL); double * IMp = mxGetPr(plhs[4]); VectorXd IMd = (IM.cast<double>().array()+1).matrix(); copy(&IMd.data()[0],&IMd.data()[0]+IMd.size(),IMp); // Fallthrough } case 4: { // Treat indices as reals plhs[3] = mxCreateDoubleMatrix(J.rows(),J.cols(), mxREAL); double * Jp = mxGetPr(plhs[3]); VectorXd Jd = (J.cast<double>().array()+1).matrix(); copy(&Jd.data()[0],&Jd.data()[0]+Jd.size(),Jp); // Fallthrough } case 3: { // Treat indices as reals plhs[2] = mxCreateDoubleMatrix(IF.rows(),IF.cols(), mxREAL); double * IFp = mxGetPr(plhs[2]); MatrixXd IFd = (IF.cast<double>().array()+1).matrix(); copy(&IFd.data()[0],&IFd.data()[0]+IFd.size(),IFp); // Fallthrough } case 2: { // Treat indices as reals plhs[1] = mxCreateDoubleMatrix(F.rows(),F.cols(), mxREAL); double * Fp = mxGetPr(plhs[1]); MatrixXd Fd = (F.cast<double>().array()+1).matrix(); copy(&Fd.data()[0],&Fd.data()[0]+Fd.size(),Fp); // Fallthrough } case 1: { plhs[0] = mxCreateDoubleMatrix(V.rows(),V.cols(), mxREAL); double * Vp = mxGetPr(plhs[0]); copy(&V.data()[0],&V.data()[0]+V.size(),Vp); break; } default:break; } // Restore the std stream buffer Important! std::cout.rdbuf(outbuf); }
void computeIntersection(const MatrixXi &thisIndex, const MatrixXi &index, int h, ArrayXf &new_w) { int dataSize = index.rows(); int M = index.cols(); for (int i = 0 ; i < dataSize; i++) new_w(i) = intersect(thisIndex.transpose(), index.row(i).transpose(), M, h); }
int Simulation::initializeSimulation(double deltaT, int iterations, char method, MatrixXi& TT, MatrixXd& TV, MatrixXd& B, vector<int>& moveVertices, vector<int> fixVertices, double youngs, double poissons){ iters = iterations; if (method =='e'){ integrator = new Verlet(); cout<<"Initialized Verlet"<<endl; }else if(method == 'i'){ integrator = new ImplicitEuler(); cout<<"Initialized Implicit Euler"<<endl; } else if(method == 'n'){ integrator = new ImplicitNewmark(); cout<<"Initialized Implicit Newmark"<<endl; } else{ cout<<"Method not supported yet"<<endl; exit(0); } VectorXd force; force.resize(3*TV.rows()); force.setZero(); setInitPosition(force, fixVertices, moveVertices); if(moveVertices.size()>0 or fixVertices.size()>0){ //cout << "DOING STUFFS" << endl; MatrixXd newTV; newTV.resize(TV.rows(), TV.cols()); newTV.setZero(); MatrixXi newTT; newTT.resize(TT.rows(), TT.cols()); newTT.setZero(); //cout << "MoveVertsSize :: " << moveVertices.size() << endl; //TODO: Make this shit more efficient //Hash maps or something vector<int> vertexNewIndices; for(int i=0; i<TV.rows(); i++){ bool flag =false; for(unsigned int j=0; j<fixVertices.size(); j++){ if(i==fixVertices[j]){ flag = true; } } for(unsigned int j=0; j<moveVertices.size(); j++){ if(i==moveVertices[j]){ flag = true; } } // if vertex not fixed or moved, re-index to front //[v, v, v, v...., f, f, f...., m, m, m...,m] if(!flag){ vertexNewIndices.push_back(i); } } //re-index fixed verts for(unsigned int j=0; j<fixVertices.size(); j++){ vertexNewIndices.push_back(fixVertices[j]); } //re-index move verts for(unsigned int j=0; j<moveVertices.size(); j++){ vertexNewIndices.push_back(moveVertices[j]); } //these are the new indices for the fixed verts vector<int> newfixIndices; for(unsigned int i= vertexNewIndices.size() - (moveVertices.size() + fixVertices.size()); i<(vertexNewIndices.size()-moveVertices.size()); i++){ newfixIndices.push_back(i); } //new indices for the moving verts vector<int> newMoveIndices; for(unsigned int i= vertexNewIndices.size() - moveVertices.size(); i<vertexNewIndices.size(); i++){ newMoveIndices.push_back(i); } //cout << "NewMoveIndicesSize :: " << newMoveIndices.size() << endl; VectorXd new_force; new_force.resize(3*TV.rows()); reIndexTVandTT(vertexNewIndices, fixVertices.size(), moveVertices.size(), TV, TT, force, newTV, newTT, new_force); igl::barycenter(newTV, newTT, B); //Initialize Solid Mesh M.initializeMesh(newTT, newTV, youngs, poissons); if(moveVertices.size() != 0){ // cout<<"Move vertices "<<moveVertices.size()<<endl; // cout<<"fix verts "<<fixVertices.size()<<endl; binarySearchYoungs(newMoveIndices, newTV, newTT, fixVertices.size(), B); // syntheticTests(newMoveIndices, newTV, newTT, fixVertices.size(), B); } integrator->initializeIntegrator(deltaT, M, newTV, newTT); this->external_force = new_force; integrator->fixVertices(newfixIndices); int ignorePastIndex = newTV.rows() - newfixIndices.size(); staticSolveNewtonsForces(newTV, newTT, B, new_force, ignorePastIndex); }else{ //cout << "Doing Other Stuffs" << endl; igl::barycenter(TV, TT, B); M.initializeMesh(TT, TV, youngs, poissons); integrator->initializeIntegrator(deltaT, M, TV, TT); this->external_force = force; integrator->fixVertices(fixVertices); } return 1; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { // This is useful for debugging whether Matlab is caching the mex binary //mexPrintf("%s %s\n",__TIME__,__DATE__); igl::matlab::MexStream mout; std::streambuf *outbuf = std::cout.rdbuf(&mout); using namespace std; using namespace Eigen; using namespace igl; using namespace igl::matlab; MatrixXd P,V,C; VectorXi I; VectorXd sqrD; MatrixXi F; if(nrhs < 3) { mexErrMsgTxt("nrhs < 3"); } parse_rhs_double(prhs,P); parse_rhs_double(prhs+1,V); parse_rhs_index(prhs+2,F); mexErrMsgTxt(P.cols()==3 || P.cols()==2,"P must be #P by (3|2)"); mexErrMsgTxt(V.cols()==3 || V.cols()==2,"V must be #V by (3|2)"); mexErrMsgTxt(V.cols()==P.cols(),"dim(V) must be dim(P)"); mexErrMsgTxt(F.cols()==3 || F.cols()==2 || F.cols()==1,"F must be #F by (3|2|1)"); point_mesh_squared_distance(P,V,F,sqrD,I,C); // Prepare left-hand side switch(nlhs) { case 3: { // Treat indices as reals plhs[2] = mxCreateDoubleMatrix(C.rows(),C.cols(), mxREAL); double * Cp = mxGetPr(plhs[2]); copy(&C.data()[0],&C.data()[0]+C.size(),Cp); // Fallthrough } case 2: { // Treat indices as reals plhs[1] = mxCreateDoubleMatrix(I.rows(),I.cols(), mxREAL); double * Ip = mxGetPr(plhs[1]); VectorXd Id = (I.cast<double>().array()+1).matrix(); copy(&Id.data()[0],&Id.data()[0]+Id.size(),Ip); // Fallthrough } case 1: { plhs[0] = mxCreateDoubleMatrix(sqrD.rows(),sqrD.cols(), mxREAL); double * sqrDp = mxGetPr(plhs[0]); copy(&sqrD.data()[0],&sqrD.data()[0]+sqrD.size(),sqrDp); break; } default:break; } // Restore the std stream buffer Important! std::cout.rdbuf(outbuf); }