Skip to content

Commit

Permalink
caseo: capprox: approx inf by aseo for neural components
Browse files Browse the repository at this point in the history
  • Loading branch information
RenatoGeh committed Oct 9, 2023
1 parent 5bcc5a2 commit 264bc1c
Show file tree
Hide file tree
Showing 17 changed files with 388 additions and 134 deletions.
75 changes: 68 additions & 7 deletions pasp/approx.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,73 @@
#include "caseo.h"
#include "cground.h"

static bool _aseo_maxent(program_t *P, size_t n_samples, size_t scale, double **R) {
bool ok = false;
double *a, *b, *r = a = b = NULL;

/* Reuse weighted literals for ASEO. */
size_t n = num_prob_params(P);
clingo_weighted_literal_t *W = (clingo_weighted_literal_t*) malloc(n*sizeof(clingo_weighted_literal_t));
clingo_weighted_literal_t *U = (clingo_weighted_literal_t*) malloc(n*sizeof(clingo_weighted_literal_t));
if (!(W && U)) goto nomem;

/* Initialize probabilities in neural components. */
for (size_t i = 0; i < P->NR_n; ++i)
if (!update_pr_neural_rule(&P->NR[i])) goto cleanup;
for (size_t i = 0; i < P->NA_n; ++i)
if (!update_pr_neural_annot_disj(&P->NA[i])) goto cleanup;

/* Run first ASEO separately to get the number of models. */
models_t M = {0};
if (!aseo_reuse(P, n_samples, MAXENT_SEMANTICS, NULL, (int) scale, 0, W, U, &M,
approx_rec_query_maxent)) goto cleanup;
size_t n_M = M.n;

/* The resulting (flattened) array has dimension n*k x 1, where n is the number of queries and k
* is the number of examples in the neural dataset. */
size_t m_neural = (P->NA_n + P->NR_n > 0) ? P->m_test : 1;
r = (double*) malloc(n_M*m_neural*sizeof(double));
if (!r) goto cleanup;
*R = r;
/* Arrays a and b are the cumulated probabilities for each query. */
a = (double*) calloc(n_M, sizeof(double));
if (!a) goto cleanup;
b = (double*) calloc(n_M, sizeof(double));
if (!b) goto cleanup;

approx_query_maxent_ab(P, &M, a, b);
approx_query_maxent_r(P, &M, r, a, b);
models_free_contents(&M);
r += n_M;

for (size_t i = 1; i < m_neural; ++i) {
if (!aseo_reuse(P, n_samples, MAXENT_SEMANTICS, NULL, (int) scale, i, W, U, &M,
approx_rec_query_maxent)) {
models_free_contents(&M);
goto cleanup;
}
memset(a, 0, n_M*sizeof(double));
memset(b, 0, n_M*sizeof(double));
approx_query_maxent_ab(P, &M, a, b);
approx_query_maxent_r(P, &M, r, a, b);
models_free_contents(&M);
r += n_M;
}

ok = true;
goto cleanup;
nomem:
PyErr_SetString(PyExc_MemoryError, "could not allocate enough memory for ASEO!");
cleanup:
free(W); free(U);
free(a); free(b);
return ok;
}

static PyObject* _aseo(PyObject *self, PyObject *args, PyObject *kwargs) {
PyObject *py_P, *py_R = py_P = NULL;
program_t P = {0};
double *R = NULL;
models_t *M = NULL;
size_t n_samples, scale = 100;
bool quiet = false, status = true;
static char *kwlist[] = { "program", "n_samples", "scale", "quiet", "status", NULL };
Expand All @@ -26,17 +88,16 @@ static PyObject* _aseo(PyObject *self, PyObject *args, PyObject *kwargs) {
if (P.stable) if (!ground_all(P.stable, NULL)) goto cleanup;
}

M = aseo(&P, n_samples, MAXENT_SEMANTICS, NULL, (int) scale, approx_rec_query_maxent);
if (!M) goto cleanup;
if (!approx_query_maxent(&P, M, &R)) goto cleanup;
if (!_aseo_maxent(&P, n_samples, scale, &R)) goto cleanup;

npy_intp dims[3] = {P.Q_n, 1, 0};
py_R = PyArray_SimpleNewFromData(2, dims, NPY_DOUBLE, R);
bool has_neural = P.NA_n+P.NR_n > 0;
npy_intp dims[3] = {P.Q_n, 1, 1};
if (has_neural) { dims[0] = P.m_test; dims[1] = P.Q_n; dims[2] = 1; }
py_R = PyArray_SimpleNewFromData(has_neural ? 3 : 2, dims, NPY_DOUBLE, R);
if (!py_R) goto cleanup;
PyArray_ENABLEFLAGS((PyArrayObject*) py_R, NPY_ARRAY_OWNDATA);

cleanup:
models_free(M);
free_program_contents(&P);
return py_R;
}
Expand Down
38 changes: 23 additions & 15 deletions pasp/capprox.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,9 @@ bool approx_query_credal(const clingo_model_t *cM, program_t *P, models_t *M, ob
return false;
}

bool approx_query_maxent(program_t *P, models_t *M, double **R) {
bool ok = false;
double *a, *b, *r = b = a = NULL;
void approx_query_maxent_ab(program_t *P, models_t *M, double *a, double *b) {
size_t n = M->n;

/* The resulting (flattened) array has dimension n*k x 1, where n is the number of queries and k
* is the number of examples in the neural dataset. */
r = (double*) malloc(M->n*sizeof(double));
if (!r) goto cleanup;
/* Arrays a and b are the cumulated probabilities for each query. */
a = (double*) calloc(M->n, sizeof(double));
if (!a) goto cleanup;
b = (double*) calloc(M->n, sizeof(double));
if (!b) goto cleanup;

/*printf("n = %lu, m = %lu\n", n, M->m);*/
for (size_t i = 0; i < n; ++i) {
size_t l = i+n;
Expand All @@ -83,15 +71,35 @@ bool approx_query_maxent(program_t *P, models_t *M, double **R) {
/*printf("b[%lu] += %d * %f / %lu = %f %f\n", i, counter_GET(&M->C, l, j), M->L[j]->pr, M->L[j]->n,*/
/*counter_GET(&M->C, l, j)*M->L[j]->pr/M->L[j]->n, b[i]);*/
}
r[i] = a[i]/b[i];
/*printf(" a[%lu] * b[%lu] = %f\n", i, i, r[i]);*/
}
}

*R = r;
void approx_query_maxent_r(program_t *P, models_t *M, double *r, double *a, double *b) {
for (size_t i = 0; i < M->n; ++i) r[i] = a[i]/b[i];
}

bool approx_query_maxent(program_t *P, models_t *M, double **R) {
bool ok = false;
double *a, *b, *r = a = b = NULL;

/* The resulting (flattened) array has dimension n*k x 1, where n is the number of queries and k
* is the number of examples in the neural dataset. */
r = (double*) malloc(M->n*sizeof(double));
if (!r) goto cleanup;
/* Arrays a and b are the cumulated probabilities for each query. */
a = (double*) calloc(M->n, sizeof(double));
if (!a) goto cleanup;
b = (double*) calloc(M->n, sizeof(double));
if (!b) goto cleanup;

approx_query_maxent_ab(P, M, a, b);
approx_query_maxent_r(P, M, r, a, b);

ok = true;
cleanup:
free(a); free(b);
if (!ok) free(r);
return ok;
}

5 changes: 4 additions & 1 deletion pasp/capprox.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ bool approx_rec_obs_maxent(const clingo_model_t *cM, program_t *P, models_t *M,
bool approx_rec_query_maxent(const clingo_model_t *cM, program_t *P, models_t *M, size_t model_idx,
observations_t *O, clingo_control_t *C);

bool approx_obs_maxent(program_t *P, models_t *M, observations_t *O, prob_obs_storage_t *Q);
bool approx_obs_maxent(program_t *P, models_t *M, observations_t *O, prob_storage_t *Q, bool derive);
bool approx_query_maxent(program_t *P, models_t *M, double **R);

void approx_query_maxent_ab(program_t *P, models_t *M, double *a, double *b);
void approx_query_maxent_r(program_t *P, models_t *M, double *r, double *a, double *b);

#endif
Loading

0 comments on commit 264bc1c

Please sign in to comment.