%module loess %include "typemaps.i" %{ #define SWIG_FILE_WITH_INIT #include #define EARRLEN 1000 #include "loess.h" extern void loess(struct loess_struct *lo); extern void loess_summary(struct loess_struct *lo); // not implemented // extern void predict(double *eval, int m, struct loess_struct *lo, struct pred_struct *pre, int se); %} %include "numpy.i" %init %{ import_array(); %} %apply (double *IN_ARRAY1, int DIM1) {(double *v, int n)}; %apply (int *IN_ARRAY1, int DIM1) {(int *v, int n)}; %apply (double **ARGOUTVIEWM_ARRAY1, int *DIM1) {(double **w, int *n)}; %apply (int **ARGOUTVIEWM_ARRAY1, int *DIM1) {(int **w, int *n)}; %include "loess.h" extern void loess(struct loess_struct *lo); extern void loess_summary(struct loess_struct *lo); // not implemented // extern void predict(double *eval, int m, struct loess_struct *lo, struct pred_struct *pre, int se); %exception { errno = 0; $action if (errno != 0) { switch(errno) { case ENOMEM: PyErr_Format(PyExc_MemoryError, "memory allocation failed."); break; case EARRLEN: PyErr_Format(PyExc_ValueError, "unexpected array length."); break; default: PyErr_Format(PyExc_Exception, "unknown exception."); } SWIG_fail; } } %extend loess_struct { //// constructor of a loess_struct // // @param n: number of data points. // // @param p: number of factors (independent variables). maximum 8. loess_struct(int n, int p) { struct loess_struct *lo; lo = (struct loess_struct *) malloc(sizeof(loess_struct)); int i, max_kd; max_kd = n > 200 ? n : 200; lo->in.y = (double *) malloc(n * sizeof(double)); lo->in.x = (double *) malloc(n * p * sizeof(double)); lo->in.weights = (double *) malloc(n * sizeof(double)); for(i = 0; i < (n * p); i++) lo->in.x[i] = 0.0; for(i = 0; i < n; i++) { lo->in.y[i] = 0.0; lo->in.weights[i] = 1.0; } lo->in.n = n; lo->in.p = p; lo->model.span = 0.75; lo->model.degree = 2; lo->model.normalize = TRUE; for(i = 0; i < 8; i++) lo->model.parametric[i] = lo->model.drop_square[i] = FALSE; lo->model.family = "gaussian"; lo->control.surface = "interpolate"; lo->control.statistics = "approximate"; lo->control.cell = 0.2; lo->control.trace_hat = "wait.to.decide"; lo->control.iterations = 4; lo->out.fitted_values = (double *) malloc(n * sizeof(double)); lo->out.fitted_residuals = (double *) malloc(n * sizeof(double)); lo->out.pseudovalues = (double *) malloc(n * sizeof(double)); lo->out.diagonal = (double *) malloc(n * sizeof(double)); lo->out.robust = (double *) malloc(n * sizeof(double)); lo->out.divisor = (double *) malloc(p * sizeof(double)); lo->kd_tree.parameter = (int *) malloc(7 * sizeof(int)); lo->kd_tree.a = (int *) malloc(max_kd * sizeof(int)); lo->kd_tree.xi = (double *) malloc(max_kd * sizeof(double)); lo->kd_tree.vert = (double *) malloc(p * 2 * sizeof(double)); lo->kd_tree.vval = (double *) malloc((p + 1) * max_kd * sizeof(double)); return lo; } ~loess_struct() { free($self->in.x); free($self->in.y); free($self->in.weights); free($self->out.fitted_values); free($self->out.fitted_residuals); free($self->out.pseudovalues); free($self->out.diagonal); free($self->out.robust); free($self->out.divisor); free($self->kd_tree.parameter); free($self->kd_tree.a); free($self->kd_tree.xi); free($self->kd_tree.vert); free($self->kd_tree.vval); free($self); } void set_x(double *v, int n) { int n_exp = $self->in.n * $self->in.p; if (n == n_exp) { int i; for(i = 0; i < n; i++) $self->in.x[i] = v[i]; } else { errno = EARRLEN; } } void set_y(double *v, int n) { int n_exp = $self->in.n; if (n == n_exp) { int i; for(i = 0; i < n; i++) $self->in.y[i] = v[i]; } else { errno = EARRLEN; } } void set_parametric(int *v, int n) { int n_exp = $self->in.p; if (n == n_exp) { int i; for(i = 0; i < n; i++) $self->model.parametric[i] = v[i]; } else { errno = EARRLEN; } } void set_drop_square(int *v, int n) { int n_exp = $self->in.p; if (n == n_exp) { int i; for(i = 0; i < n; i++) $self->model.drop_square[i] = v[i]; } else { errno = EARRLEN; } } void get_x(double **w, int *n) { int ni = $self->in.n * $self->in.p; double *temp; temp = (double *)malloc(ni * sizeof(double)); if (temp == NULL) errno = ENOMEM; int i; for(i = 0; i < ni; i++) temp[i] = $self->in.x[i]; *w = temp; *n = ni; } void get_y(double **w, int *n) { int ni = $self->in.n; double *temp; temp = (double *)malloc(ni * sizeof(double)); if (temp == NULL) errno = ENOMEM; int i; for(i = 0; i < ni; i++) temp[i] = $self->in.y[i]; *w = temp; *n = ni; } void get_weights(double **w, int *n) { int ni = $self->in.n; double *temp; temp = (double *)malloc(ni * sizeof(double)); if (temp == NULL) errno = ENOMEM; int i; for(i = 0; i < ni; i++) temp[i] = $self->in.weights[i]; *w = temp; *n = ni; } void get_fitted_values(double **w, int *n) { int ni = $self->in.n; double *temp; temp = (double *)malloc(ni * sizeof(double)); if (temp == NULL) errno = ENOMEM; int i; for(i = 0; i < ni; i++) temp[i] = $self->out.fitted_values[i]; *w = temp; *n = ni; } void get_fitted_residuals(double **w, int *n) { int ni = $self->in.n; double *temp; temp = (double *)malloc(ni * sizeof(double)); if (temp == NULL) errno = ENOMEM; int i; for(i = 0; i < ni; i++) temp[i] = $self->out.fitted_residuals[i]; *w = temp; *n = ni; } void get_parametric(int **w, int *n) { int ni = $self->in.p; int *temp; temp = (int *)malloc(ni * sizeof(int)); if (temp == NULL) errno = ENOMEM; int i; for(i = 0; i < ni; i++) temp[i] = $self->model.parametric[i]; *w = temp; *n = ni; } void get_drop_square(int **w, int *n) { int ni = $self->in.p; int *temp; temp = (int *)malloc(ni * sizeof(int)); if (temp == NULL) errno = ENOMEM; int i; for(i = 0; i < ni; i++) temp[i] = $self->model.drop_square[i]; *w = temp; *n = ni; } };