wolffd@0: /* triangulate.c written by Ilya Shpitser */ wolffd@0: wolffd@0: #include wolffd@0: wolffd@0: #ifdef UNIX wolffd@0: #include "matlab.h" wolffd@0: #endif wolffd@0: wolffd@0: #include "matrix.h" wolffd@0: #include "mex.h" wolffd@0: wolffd@0: #include "elim.h" wolffd@0: #include "map.h" wolffd@0: #include "misc.h" wolffd@0: wolffd@0: void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){ wolffd@0: wolffd@0: int dims [2]; wolffd@0: int i, j, k, m, n; wolffd@0: long index; wolffd@0: double * G_pr; wolffd@0: double * stage_pr; wolffd@0: double * answer_G_pr, * fill_ins_pr; wolffd@0: double * matlab_clique_pr; wolffd@0: mxArray * matlab_clique; wolffd@0: Elimination e; wolffd@0: float ** adj_mat; wolffd@0: int ** order = (int **) NULL; wolffd@0: Iterator iter, iter2; wolffd@0: word w, w2; wolffd@0: int ** fill_ins; wolffd@0: Map cliques; wolffd@0: Map clique; wolffd@0: mxArray * fill_ins_mat; wolffd@0: int * nodes; wolffd@0: mxArray * full; wolffd@0: wolffd@0: // (original) full = mlfFull((mxArray *) prhs[0]); wolffd@0: full = (mxArray *) mlfFull((mxArray *) prhs[0]); // added typecasting wolffd@0: /* Obtain graph matrix information. */ wolffd@0: m = mxGetM(full); wolffd@0: n = mxGetN(full); wolffd@0: G_pr = mxGetPr(full); wolffd@0: wolffd@0: if(n < 1 || m < 1){ wolffd@0: return; wolffd@0: } wolffd@0: wolffd@0: /* Allocate and populate the log weight adjacency matrix corresponding wolffd@0: to the input graph. */ wolffd@0: adj_mat = (float **) malloc(sizeof(float *) * m); wolffd@0: adj_mat[0] = (float *) malloc(sizeof(float) * m * n); wolffd@0: for(i = 1; i < m; i++){ wolffd@0: adj_mat[i] = adj_mat[i - 1] + n; wolffd@0: } wolffd@0: /* We no longer have log weight info, but we have a (total) ordering on wolffd@0: the nodes already, so we do not need this information. */ wolffd@0: for(i = 0; i < m; i++){ wolffd@0: for(j = 0; j < n; j++){ wolffd@0: index = j * m + i; wolffd@0: if(G_pr[index] > 0){ wolffd@0: adj_mat[i][j] = 1; wolffd@0: } else { wolffd@0: adj_mat[i][j] = 0; wolffd@0: } wolffd@0: } wolffd@0: } wolffd@0: wolffd@0: /* Convert the total elimination ordering into a partial order argument wolffd@0: for the elimination routine. The elimination routine's purpose in this wolffd@0: mode of operation is to return cliques and fill-in edges. */ wolffd@0: if(nrhs > 1){ wolffd@0: order = (int **) malloc(sizeof(int *) * m); wolffd@0: order[0] = (int *) malloc(sizeof(int) * m * n); wolffd@0: for(i = 1; i < m; i++){ wolffd@0: order[i] = order[i - 1] + n; wolffd@0: } wolffd@0: for(i = 0; i < m; i++){ wolffd@0: for(j = 0; j < n; j++){ wolffd@0: order[i][j] = 0; wolffd@0: } wolffd@0: } wolffd@0: stage_pr = mxGetPr(prhs[1]); wolffd@0: for(i = 0; i < mxGetN(prhs[1]) - 1; i++){ wolffd@0: order[(int) stage_pr[i] - 1][(int) stage_pr[i + 1] - 1] = 1; wolffd@0: } wolffd@0: } wolffd@0: wolffd@0: /* Find the elimination ordering. */ wolffd@0: e = find_elim(n, adj_mat, order, -1); wolffd@0: wolffd@0: /* Allocate memory for the answer, and set the answer. */ wolffd@0: plhs[0] = mxCreateDoubleMatrix(m, n, mxREAL); wolffd@0: answer_G_pr = mxGetPr(plhs[0]); wolffd@0: cliques = get_cliques(e); wolffd@0: /* wolffd@0: dims[0] = 1; wolffd@0: dims[1] = get_size_Map(cliques); wolffd@0: plhs[1] = mxCreateCellArray(2, (const int *) dims);*/ wolffd@0: plhs[1] = mxCreateCellMatrix(get_size_Map(cliques), 1); wolffd@0: fill_ins = get_fill_ins(e); wolffd@0: fill_ins_mat = mxCreateDoubleMatrix(m, n, mxREAL); wolffd@0: fill_ins_pr = mxGetPr(fill_ins_mat); wolffd@0: wolffd@0: for(i = 0; i < n; i++){ wolffd@0: for(j = 0; j < m; j++){ wolffd@0: index = j * m + i; wolffd@0: answer_G_pr[index] = G_pr[index]; wolffd@0: if(fill_ins[i][j] > 0){ wolffd@0: answer_G_pr[index] = 1; wolffd@0: fill_ins_pr[index] = 1; wolffd@0: } wolffd@0: } wolffd@0: } wolffd@0: mxDestroyArray(full); wolffd@0: // (original) plhs[2] = mlfSparse(fill_ins_mat, NULL, NULL, NULL, NULL, NULL); wolffd@0: plhs[2] = (mxArray *) mlfSparse(fill_ins_mat, NULL, NULL, NULL, NULL, NULL); // added typecasting wolffd@0: mxDestroyArray(fill_ins_mat); wolffd@0: nodes = (int *) malloc(sizeof(int) * n); wolffd@0: k = 0; wolffd@0: iter = get_Iterator(cliques); wolffd@0: while(!is_empty(iter)){ wolffd@0: w = next_key(iter); wolffd@0: clique = (Map) w.v; wolffd@0: matlab_clique = mxCreateDoubleMatrix(1, get_size_Map(clique), mxREAL); wolffd@0: matlab_clique_pr = mxGetPr(matlab_clique); wolffd@0: for(i = 0; i < n; i++){ wolffd@0: nodes[i] = 0; wolffd@0: } wolffd@0: iter2 = get_Iterator(clique); wolffd@0: while(!is_empty(iter2)){ wolffd@0: w2 = next_key(iter2); wolffd@0: nodes[w2.i] = w2.i + 1; wolffd@0: } wolffd@0: j = 0; wolffd@0: for(i = 0; i < n; i++){ wolffd@0: if(nodes[i] > 0){ wolffd@0: matlab_clique_pr[j++] = nodes[i]; wolffd@0: } wolffd@0: } wolffd@0: mxSetCell(plhs[1], k++, matlab_clique); wolffd@0: } wolffd@0: free(nodes); wolffd@0: wolffd@0: /* Finally, free the allocated memory. */ wolffd@0: destroy_Elimination(e); wolffd@0: if(adj_mat){ wolffd@0: if(adj_mat[0]){ wolffd@0: free(adj_mat[0]); wolffd@0: } wolffd@0: free(adj_mat); wolffd@0: } wolffd@0: if(order){ wolffd@0: if(order[0]){ wolffd@0: free(order[0]); wolffd@0: } wolffd@0: free(order); wolffd@0: } wolffd@0: }