285 lines
7.3 KiB
OpenEdge ABL
285 lines
7.3 KiB
OpenEdge ABL
%module loess
|
|
%include "typemaps.i"
|
|
|
|
%{
|
|
#define SWIG_FILE_WITH_INIT
|
|
#include <errno.h>
|
|
#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;
|
|
}
|
|
|
|
};
|