Ejemplo n.º 1
0
int
main (void) {

	test_new ();
	test_import ();
	test_split ();
	test_replace ();
	test_copy ();
	test_cut ();
	test_search ();
	test_tail_head ();
	return 0;
}
Ejemplo n.º 2
0
/*
 * The mex function runs a max-flow min-cut problem.
 */
void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
    mbglIndex i,j,k;
    
    mbglIndex mrows, ncols;
    
    mbglIndex n,nz;
    
    /* sparse matrix */
    mwIndex *A_row, *A_col;
    double *A_val;
    
    /* source/sink */
    mbglIndex u, v;
    
    /* algorithm name */
    char *algname;
    
    /* flow matrix connectivity */
    mbglIndex *pi_flow, *j_flow;
    
    /* capacity and residual structures */
    int *cap, *res;
    
    /* reverse edge map */
    mbglIndex *rev_edge_map;
    
    /* result */
    int flow;
    
    /* output */
    double *pflowval;
    double *pmincut;
    
    double *pri;
    double *prj;
    double *prv;
    
    /* 
     * The current calling pattern is
     * matching_mex(A,verify,initial_match_name,augmenting_path_name)
     */
    
    const mxArray* arg_matrix;
    const mxArray* arg_source;
    const mxArray* arg_sink;
    const mxArray* arg_algname;    
    int required_arguments = 4;
    
    if (nrhs != required_arguments) {
        mexErrMsgIdAndTxt("matlab_bgl:invalidMexArgument",
            "the function requires %i arguments, not %i\n", 
            required_arguments, nrhs);
    }
    
    arg_matrix = prhs[0];
    arg_source = prhs[1];
    arg_sink = prhs[2];
    arg_algname = prhs[3];
    
    u = (mbglIndex)load_scalar_arg(arg_source,1);
    v = (mbglIndex)load_scalar_arg(arg_sink,2);
    algname = load_string_arg(arg_algname,3);
    
    /* 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])) 
    {
        mexErrMsgIdAndTxt("matlab_bgl:invalidMexArgument",
            "the matrix must be sparse, square, and double valued");
    }
    
    n = mrows;
    
    /* Get the sparse matrix */
    A_val = mxGetPr(prhs[0]);
    A_row = mxGetIr(prhs[0]);
    A_col = mxGetJc(prhs[0]);
    
    nz = A_col[n];
    
    /* Quick input check */
    if (u > n || u < 1) {
        mexErrMsgIdAndTxt("matlab_bgl:invalidMexArgument",
            "invalid source vertex: %i\n", u);
    } 
    
    if (v > n || v < 1) {
        mexErrMsgIdAndTxt("matlab_bgl:invalidMexArgument",
            "invalid sink vertex: %i\n", v);
    }
    
    u = u-1;
    v = v-1;
    
    /* build flow connectivity structure */
    build_matrix(n,A_row,A_col,A_val, 
        &pi_flow, &j_flow, &cap, &rev_edge_map);
    
    /* allocate the residual map */
    res = mxCalloc(sizeof(int),pi_flow[n]);
    
    /*i = 0;
    for (k=0; k < pi_flow[n]; k++)
    {
        // get the correct row
        while (k >= pi_flow[i+1]) { ++i; }
        mexPrintf("(%i,%i) (%i,%i)\n", i,j_flow[k],cap[k],res[k]);
    }*/
    
    /* mexPrintf("Calling flow (%i,%i)...\n", u, v); */
    #ifdef _DEBUG
    mexPrintf("max_flow(%s)...", algname);
    #endif 
    if (strcmp(algname,"push_relabel") == 0) {
        push_relabel_max_flow(n,j_flow,pi_flow,
            u,v,cap,res,rev_edge_map,&flow);
    } else if (strcmp(algname, "edmunds_karp") == 0) {
        edmonds_karp_max_flow(n,j_flow,pi_flow,
            u,v,cap,res,rev_edge_map,&flow);
    } else if (strcmp(algname, "kolmogorov") == 0) {
        boykov_kolmogorov_max_flow(n,j_flow,pi_flow,
            u,v,cap,res,rev_edge_map,&flow);
    } else {
        mexErrMsgIdAndTxt("matlab_bgl:invalidMexArgument",
            "algname option %s is invalid\n", 
            algname);
    }
    
    #ifdef _DEBUG
    mexPrintf("done!\n");
    #endif 
    
    /*i = 0;
    for (k=0; k < pi_flow[n]; k++)
    {
        // get the correct row
        while (k >= pi_flow[i+1]) { ++i; }
        mexPrintf("(%i,%i) (%i,%i)\n", i,j_flow[k],cap[k],res[k]);
    }*/
    
    if (nlhs >= 1)
    {
        plhs[0] = mxCreateDoubleMatrix(1,1, mxREAL);
        pflowval = mxGetPr(plhs[0]);
        pflowval[0] = (double)flow;
    }
    
    if (nlhs >= 2)
    {
        int *pimincut;
        
        plhs[1] = mxCreateDoubleMatrix(n,1,mxREAL);
        pmincut = mxGetPr(plhs[1]);
        
        pimincut = (int*)pmincut;
        
        build_cut(u, n, pi_flow, j_flow, cap, res, pimincut);
        
        test_cut(flow,pimincut,n,A_row,A_col,A_val);
        
        /* now expand mincut to the full dataset, we need to
         * do this operation backwards because pimincut has integer
         * entries specified and we are expanding them to double.
         */
        expand_int_to_double(pimincut,pmincut,n,0.0);
    }
    
    if (nlhs >= 3)
    {
        plhs[2] = mxCreateDoubleMatrix(nz,1,mxREAL);
        plhs[3] = mxCreateDoubleMatrix(nz,1,mxREAL);
        plhs[4] = mxCreateDoubleMatrix(nz,1,mxREAL);
        
        pri = mxGetPr(plhs[2]);
        prj = mxGetPr(plhs[3]);
        prv = mxGetPr(plhs[4]);
        
        /* j will be our index into the new matrix. */
        j = 0;
        
        for (i=0;i<n;i++)
        {
            for (k=pi_flow[i];k<pi_flow[i+1];k++)
            {
                if (cap[k] != 0)
                {
                    /* since cap[k] != 0, this is a real edge */
                    pri[j] = i+1;
                    prj[j] = j_flow[k]+1;
                    prv[j] = res[k];
                    j++;
                }
            }
        }
        
        if (j != nz)
        {
            mexPrintf("error... j != nz...\n");
        }
    }
    
    #ifdef _DEBUG
    mexPrintf("return\n");
    #endif 
}