void implicit_linear(int nlhs, mxArray * plhs[], int nrhs, const mxArray * prhs[]) { dd_MatrixPtr H; dd_rowset rows; dd_ErrorType err; if (nrhs == 1 && nlhs <= 2 && mxIsStruct(prhs[0])) { H = FT_get_H_MatrixPtr(prhs[0]); dd_set_global_constants(); /* First, this must be called. */ rows = dd_ImplicitLinearityRows(H, &err); if (err == dd_NoError) { int total, element, i; double* pr; total = set_card(rows); plhs[0] = mxCreateDoubleMatrix(total, 1, mxREAL); pr = mxGetPr(plhs[0]); for (i=1, element=0; i<=rows[0]; i++){ if (set_member(i, rows)) { pr[element++] = (double)i; } } } else { dd_WriteErrorMessages(stdout,err); mexErrMsgTxt("CDD returned an error, see above(!) for details"); } dd_FreeMatrix(H); set_free(rows); return; } else { mexErrMsgTxt("hull expects a V input struct and produces an H output struct"); } }
SEXP impliedLinearity(SEXP m, SEXP h) { GetRNGstate(); if (! isMatrix(m)) error("'m' must be matrix"); if (! isLogical(h)) error("'h' must be logical"); if (LENGTH(h) != 1) error("'h' must be scalar"); if (! isString(m)) error("'m' must be character"); SEXP m_dim; PROTECT(m_dim = getAttrib(m, R_DimSymbol)); int nrow = INTEGER(m_dim)[0]; int ncol = INTEGER(m_dim)[1]; UNPROTECT(1); if (nrow <= 1) error("no use if only one row"); if (ncol <= 3) error("no use if only one col"); for (int i = 0; i < nrow; i++) { const char *foo = CHAR(STRING_ELT(m, i)); if (strlen(foo) != 1) error("column one of 'm' not zero-or-one valued"); if (! (foo[0] == '0' || foo[0] == '1')) error("column one of 'm' not zero-or-one valued"); } if (! LOGICAL(h)[0]) for (int i = nrow; i < 2 * nrow; i++) { const char *foo = CHAR(STRING_ELT(m, i)); if (strlen(foo) != 1) error("column two of 'm' not zero-or-one valued"); if (! (foo[0] == '0' || foo[0] == '1')) error("column two of 'm' not zero-or-one valued"); } dd_set_global_constants(); /* note actual type of "value" is mpq_t (defined in cddmp.h) */ mytype value; dd_init(value); dd_MatrixPtr mf = dd_CreateMatrix(nrow, ncol - 1); /* note our matrix has one more column than Fukuda's */ /* representation */ if(LOGICAL(h)[0]) mf->representation = dd_Inequality; else mf->representation = dd_Generator; mf->numbtype = dd_Rational; /* linearity */ for (int i = 0; i < nrow; i++) { const char *foo = CHAR(STRING_ELT(m, i)); if (foo[0] == '1') set_addelem(mf->linset, i + 1); /* note conversion from zero-origin to one-origin indexing */ } /* matrix */ for (int j = 1, k = nrow; j < ncol; j++) for (int i = 0; i < nrow; i++, k++) { const char *rat_str = CHAR(STRING_ELT(m, k)); if (mpq_set_str(value, rat_str, 10) == -1) { dd_FreeMatrix(mf); dd_clear(value); dd_free_global_constants(); error("error converting string to GMP rational"); } mpq_canonicalize(value); dd_set(mf->matrix[i][j - 1], value); /* note our matrix has one more column than Fukuda's */ } dd_ErrorType err = dd_NoError; dd_rowset out = dd_ImplicitLinearityRows(mf, &err); if (err != dd_NoError) { rr_WriteErrorMessages(err); set_free(out); dd_FreeMatrix(mf); dd_clear(value); dd_free_global_constants(); error("failed"); } SEXP foo; PROTECT(foo = rr_set_fwrite(out)); set_free(out); dd_FreeMatrix(mf); dd_clear(value); dd_free_global_constants(); PutRNGstate(); UNPROTECT(1); return foo; }