Пример #1
0
/*
 * 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
}
Пример #2
0
/*
 * 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
}
Пример #3
0
/*
 * 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);
    }
}
Пример #4
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);
  }
}