/* * The mex function runs a connected components problem. */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mwIndex mrows, ncols; mwIndex n,nz; /* sparse matrix */ mwIndex *ia, *ja; double *a; /* output data */ double *cn; double *rt; /* used to switch between algorithm types */ int weight_type; /* = 0 if unweighted, = 1 if a vector of weights, = 2 if given by the matrix */ /* * The current calling pattern is * core_numbers_mex(A,weight) * where weight = 0 to use the unweighted version * weight = 'matrix' to use the values in the matrix * weight = vector to use a vector of weights */ const mxArray* arg_matrix; const mxArray* arg_weight; int required_arguments = 2; if (nrhs != required_arguments) { mexErrMsgIdAndTxt("matlab_bgl:invalidMexArgument", "the function requires %i arguments, not %i\n", required_arguments, nrhs); } arg_matrix = prhs[0]; arg_weight = prhs[1]; if (mxGetNumberOfElements(arg_weight) == 1) { /* make sure it is valid */ if ((int)mxGetScalar(arg_weight) != 0) { mexErrMsgIdAndTxt("matlab_bgl:invalidParameter", "unknown weight option %g\n", mxGetScalar(arg_weight)); } weight_type = 0; a = NULL; } else if (mxIsChar(arg_weight)) { weight_type = 2; a = mxGetPr(arg_matrix); } else if (mxIsDouble(arg_weight)) { weight_type = 1; a = mxGetPr(arg_weight); } else { mexErrMsgIdAndTxt("matlab_bgl:invalidParameter", "unrecognized weight option"); return; } /* The first input must be a sparse matrix. */ mrows = mxGetM(arg_matrix); ncols = mxGetN(arg_matrix); if (mrows != ncols || !mxIsSparse(arg_matrix) || ((!mxIsDouble(arg_matrix) || mxIsComplex(arg_matrix)) && (weight_type == 2)) ) { mexErrMsgTxt("Input must be a square sparse matrix."); } n = mrows; /* recall that we've transposed the matrix */ ja = mxGetIr(prhs[0]); ia = mxGetJc(prhs[0]); nz = ia[n]; /* check the reweighting array to make sure it is acceptable */ if (weight_type == 1 && mxGetNumberOfElements(arg_weight) < nz) { mexErrMsgIdAndTxt("matlab_bgl:invalidParameter", "the weight array must have length >= nnz(A)"); } plhs[0] = mxCreateDoubleMatrix(n,1,mxREAL); plhs[1] = mxCreateDoubleMatrix(n,1,mxREAL); cn = mxGetPr(plhs[0]); rt = mxGetPr(plhs[1]); #ifdef _DEBUG mexPrintf("core_numbers..."); #endif if (weight_type == 0) { core_numbers(n, ja, ia, (mwIndex*)cn, (int*)rt); } else { weighted_core_numbers(n, ja, ia, a, cn, (int*)rt); } #ifdef _DEBUG mexPrintf("done!\n"); #endif if (weight_type == 0) { expand_index_to_double((mwIndex*)cn,cn,n,0.0); } expand_int_to_double((int*)rt,rt,n,0.0); #ifdef _DEBUG mexPrintf("return\n"); #endif }
/* * The mex function runs a shortest path problem. */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mwIndex mrows, ncols; mwIndex n,nz; /* sparse matrix */ mwIndex *ia, *ja; double *a; /* true if this function is reweighted */ int reweighted = 0; double dinf; /* output data */ double *D; int rval; /* sp type string */ int buflen; char *algname; int status; /* * The current calling pattern is * matlab_bgl_all_sp_mex(A,algname,dinf,reweight) * algname is a string with either 'johnson', 'floyd_warshall' * reweight is either a string or a length nnz vector * * if reweight is a length nnz vector, then we use that as the values * for the matrix, if its a string, then we use the values from the * the matrix. */ const mxArray* arg_matrix; const mxArray* arg_algname; const mxArray* arg_dinf; const mxArray* arg_reweight; if (nrhs != 4) { mexErrMsgTxt("4 inputs required."); } arg_matrix = prhs[0]; arg_algname = prhs[1]; arg_dinf = prhs[2]; arg_reweight = prhs[3]; /* First test if they are going to reweight or not */ if (!mxIsChar(arg_reweight)) { reweighted = 1; } /* The first input must be a sparse matrix. */ mrows = mxGetM(arg_matrix); ncols = mxGetN(arg_matrix); if (!reweighted && (mrows != ncols || !mxIsSparse(arg_matrix) || !mxIsDouble(arg_matrix) || mxIsComplex(arg_matrix))) { mexErrMsgTxt("A non-reweighted input matrix must be a noncomplex square sparse matrix."); } else if (reweighted && (mrows != ncols || !mxIsSparse(arg_matrix))) { mexErrMsgTxt("A reweighted input matrix must be a square sparse matrix."); } n = mrows; /* Get the sparse matrix */ /* recall that we've transposed the matrix */ ja = mxGetIr(arg_matrix); ia = mxGetJc(arg_matrix); nz = ia[n]; if (!reweighted) { a = mxGetPr(arg_matrix); } else { /* check the reweighting array to make sure it is acceptable */ if (mxGetNumberOfElements(arg_reweight) < nz) mexErrMsgTxt("The reweight array must have length at least nnz(A)"); if (!mxIsDouble(arg_reweight)) mexErrMsgTxt("The reweight array must be of type double."); a = mxGetPr(arg_reweight); } /* Get the uninitialized value */ dinf = mxGetScalar(arg_dinf); /* Get the algorithm type */ if (mxIsChar(arg_algname) != 1) mexErrMsgTxt("Input 2 must be a string (algname)."); /* Input must be a row vector. */ if (mxGetM(arg_algname) != 1) mexErrMsgTxt("Input 2 must be a row vector."); /* Get the length of the input string. */ buflen = (mxGetM(arg_algname) * mxGetN(arg_algname)) + 1; /* Allocate memory for input and output strings. */ algname = mxCalloc(buflen, sizeof(char)); status = mxGetString(arg_algname, algname, buflen); if (status != 0) mexErrMsgTxt("Not enough space for algname input."); plhs[0] = mxCreateDoubleMatrix(n,n,mxREAL); /* create the output vectors */ D = mxGetPr(plhs[0]); #ifdef _DEBUG mexPrintf("all_sp_%s...",algname); #endif if (strcmp(algname, "johnson") == 0) { rval = johnson_all_sp(n, ja, ia, a, D, dinf); } else if (strcmp(algname, "floyd_warshall") == 0) { double *pred = NULL; if (nlhs > 1) { plhs[1] = mxCreateDoubleMatrix(n,n,mxREAL); pred = mxGetPr(plhs[1]); } rval = floyd_warshall_all_sp(n, ja, ia, a, D, dinf, (mbglIndex*)pred); if (pred) { mwIndex i; expand_index_to_double((mwIndex*)pred, pred, n*n, 1.0); /* zero out entries on the diagonal */ for (i=0; i<n; i++) { pred[i+i*n]=0.0; } } } else { mexErrMsgTxt("Unknown algname."); return; } #ifdef _DEBUG mexPrintf("done!\n"); #endif if (rval != 0) { mexErrMsgTxt("Negative weight cycle detected, check the input."); } #ifdef _DEBUG mexPrintf("return\n"); #endif }
/* * The mex function runs a max-flow min-cut problem. */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int i; int mrows, ncols; int n,nz; /* sparse matrix */ mwIndex *ia, *ja; /* output data */ double *a, *ci; mwIndex *int_a; if (nrhs != 1) { mexErrMsgTxt("1 inputs required."); } /* The first input must be a sparse matrix. */ mrows = mxGetM(prhs[0]); ncols = mxGetN(prhs[0]); if (mrows != ncols || !mxIsSparse(prhs[0]) || !mxIsDouble(prhs[0]) || mxIsComplex(prhs[0])) { mexErrMsgTxt("Input must be a noncomplex square sparse matrix."); } n = mrows; /* Get the sparse matrix */ /* recall that we've transposed the matrix */ ja = mxGetIr(prhs[0]); ia = mxGetJc(prhs[0]); nz = ia[n]; plhs[0] = mxCreateDoubleMatrix(n,1,mxREAL); a = mxGetPr(plhs[0]); ci = NULL; if (nlhs > 1) { plhs[1] = mxCreateDoubleMatrix(nz,1,mxREAL); ci = mxGetPr(plhs[1]); } int_a = (mwIndex*)a; for (i=0; i<n; i++) { int_a[i] = MWINDEX_MAX; } biconnected_components(n, ja, ia, (mwIndex*)a, (mwIndex*)ci); expand_index_to_double_zero_special((mwIndex*)a, a, n, 1.0, MWINDEX_MAX); if (nlhs > 1) { expand_index_to_double((mwIndex*)ci, ci, nz, 1.0); } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mwIndex n, nz, *ia, *ja; /* sparse matrix */ int test_type = 0, rval=-1; load_graph_arg(nrhs, prhs, 0, -1, -1, 0, &n, &nz, &ia, &ja, NULL); test_type = (int)load_scalar_double_arg(nrhs, prhs, 1); /* [is_planar ksubgraph embedding] = planar_test_mex(A,0) * [is_kuratowski] = planar_test_mex(A,1) * [is_straight_line] = planar_test_mex(A,2,X) */ plhs[0]= mxCreateDoubleMatrix(1,1,mxREAL); if (test_type == 0) { /* get planar subgraph information */ int is_planar = 0; if (nlhs <= 1) { /* just test for the planar graph */ rval= boyer_myrvold_planarity_test(n, ja, ia, &is_planar, NULL, NULL, NULL, NULL, NULL); } else if (nlhs <= 3) { /* test for the planar graph and the kuratowski subgraph */ double *ki, *kj; mwIndex nedges= n>5 ? 3*n-6 : 10; plhs[1]= mxCreateDoubleMatrix(nedges,1,mxREAL); ki=mxGetPr(plhs[1]); plhs[2]= mxCreateDoubleMatrix(nedges,1,mxREAL); kj=mxGetPr(plhs[2]); nedges= 0; rval= boyer_myrvold_planarity_test(n, ja, ia, &is_planar, (mwIndex*)ki, (mwIndex*)kj, &nedges, NULL, NULL); expand_index_to_double((mwIndex*)ki, ki, nedges, 1.0); expand_index_to_double((mwIndex*)kj, kj, nedges, 1.0); mxSetM(plhs[1], nedges); mxSetM(plhs[2], nedges); } else if (nlhs > 3) { /* test for the planar graph and the edge order */ double *eip, *eie; double *ki, *kj; mwIndex nedges= n>5 ? 3*n-6 : 10; plhs[1]= mxCreateDoubleMatrix(nedges,1,mxREAL); ki=mxGetPr(plhs[1]); plhs[2]= mxCreateDoubleMatrix(nedges,1,mxREAL); kj=mxGetPr(plhs[2]); nedges= 0; plhs[3]= mxCreateDoubleMatrix(n+1,1,mxREAL); eip= mxGetPr(plhs[3]); plhs[4]= mxCreateDoubleMatrix(nz,1,mxREAL); eie= mxGetPr(plhs[4]); rval= boyer_myrvold_planarity_test(n, ja, ia, &is_planar, (mwIndex*)ki, (mwIndex*)kj, &nedges, (mwIndex*)eip, (mwIndex*)eie); expand_index_to_double((mwIndex*)ki, ki, nedges, 1.0); expand_index_to_double((mwIndex*)kj, kj, nedges, 1.0); mxSetM(plhs[1], nedges); mxSetM(plhs[2], nedges); expand_index_to_double((mwIndex*)eip, eip, n+1, 1.0); expand_index_to_double((mwIndex*)eie, eie, nz, 1.0); } expand_int_to_double(&is_planar, mxGetPr(plhs[0]), 1, 0.0); } else if (test_type == 1) { /* test for a kuratowski subgraph */ int is_ksubgraph= 0; rval= is_kuratowski_subgraph(n, ja, ia, &is_ksubgraph); expand_int_to_double(&is_ksubgraph, mxGetPr(plhs[0]), 1, 0.0); } else if (test_type == 2) { /** Test for a straight line embedding */ int is_sldrawing= 0; double* X= load_matrix_double_arg(nrhs,prhs,2,"X",1,NULL,NULL,1,n,2); rval= is_straight_line_drawing(n, ja, ia, X, &is_sldrawing); if (rval==-11) { mexErrMsgIdAndTxt("matlab_bgl:callFailed", "is_straight_line_drawing requires positive positions."); } expand_int_to_double(&is_sldrawing, mxGetPr(plhs[0]), 1, 0.0); } if (rval != 0) { mexErrMsgIdAndTxt("matlab_bgl:callFailed", "The libmbgl call failed with rval=%i", rval); } }