[Scipy-svn] r2847 - trunk/Lib/sandbox/pyloess/sandbox/src

scipy-svn@scip... scipy-svn@scip...
Wed Mar 14 07:48:23 CDT 2007


Author: pierregm
Date: 2007-03-14 07:46:49 -0500 (Wed, 14 Mar 2007)
New Revision: 2847

Modified:
   trunk/Lib/sandbox/pyloess/sandbox/src/c_loess.pxd
   trunk/Lib/sandbox/pyloess/sandbox/src/cloess.c
   trunk/Lib/sandbox/pyloess/sandbox/src/cloess.h
   trunk/Lib/sandbox/pyloess/sandbox/src/cloess.pyx
   trunk/Lib/sandbox/pyloess/sandbox/src/loess.c
   trunk/Lib/sandbox/pyloess/sandbox/src/loess.h
   trunk/Lib/sandbox/pyloess/sandbox/src/loessc.c
   trunk/Lib/sandbox/pyloess/sandbox/src/misc.c
Log:
sandbox: Thanks to Francesc Altec suggestion, the loess routines now run without crashing...However, they are not yet fully tested.

Modified: trunk/Lib/sandbox/pyloess/sandbox/src/c_loess.pxd
===================================================================
--- trunk/Lib/sandbox/pyloess/sandbox/src/c_loess.pxd	2007-03-14 12:34:56 UTC (rev 2846)
+++ trunk/Lib/sandbox/pyloess/sandbox/src/c_loess.pxd	2007-03-14 12:46:49 UTC (rev 2847)
@@ -2,30 +2,26 @@
 
 cdef extern from "loess.h":
     ctypedef struct c_loess_inputs "loess_inputs":
-        long    n
-        long    p
-        double  *y
-        double  *x
-        double  *weights
+        long   n
+        long   p
+        double *y
+        double *x
+        double *weights
     ctypedef struct c_loess_model "loess_model":
-        double  span
-        long    degree
-        long    normalize
-        long    parametric[8]
-        long    drop_square[8]
-        char    *family
+        double span
+        int    degree
+        int    normalize
+        int    parametric[8]
+        int    drop_square[8]
+        char   *family
     ctypedef struct c_loess_control "loess_control":
-        char    *surface
-        char    *statistics
-        double  cell
-        char    *trace_hat
-        long    iterations
+        char   *surface
+        char   *statistics
+        double cell
+        char   *trace_hat
+        int    iterations
     ctypedef struct c_loess_kd_tree "loess_kd_tree":
-        long    *parameter
-        long    *a
-        double  *xi
-        double  *vert
-        double  *vval
+        pass
     ctypedef struct c_loess_outputs "loess_outputs":
         double  *fitted_values
         double  *fitted_residuals
@@ -44,44 +40,29 @@
         c_loess_control control
         c_loess_kd_tree kd_tree
         c_loess_outputs outputs
-    #typedef struct {
-    #    double  *fit;
-    #    double  *se_fit;
-    #    double  residual_scale;
-    #    double  df;
-    #} predicted;
-    #
-    #struct anova_struct {
-    #    double  dfn;
-    #    double  dfd;
-    #    double  F_value;
-    #    double  Pr_F;
-    #};
-    #
-    #struct ci_struct {
-    #    double    *fit;
-    #    double    *upper;
-    #    double  *lower;
-    #};
-cdef extern from "loess.h":    
+    ctypedef struct c_prediction "prediction": 
+        double  *fit
+        double  *se_fit
+        double  residual_scale
+        double  df
+    ctypedef struct c_anova "anova_struct":
+        double  dfn
+        double  dfd
+        double  F_value
+        double  Pr_F
+    ctypedef struct c_conf_inv "conf_inv":
+        double  *fit
+        double  *upper
+        double  *lower
+    
+cdef extern from "cloess.h":    
     void loess_setup(double *x, double *y, long n, long p, c_loess *lo)
     void loess_fit(c_loess *lo)
-    void loess_(double *y, double *x_, int *size_info, double *weights, 
-        double *span, int *degree, int *parametric, int *drop_square, 
-        int *normalize, char **statistics, char **surface, double *cell, 
-        char **trace_hat_in, int *iterations, double *fitted_values, 
-        double *fitted_residuals, double *enp, double *s, double *one_delta, 
-        double *two_delta, double *pseudovalues, double *trace_hat_out, 
-        double *diagonal, double *robust, double *divisor, long *parameter, 
-        long *a, double *xi, double *vert, double *vval)
     void loess_free_mem(c_loess *lo)
     void loess_summary(c_loess *lo)
-    void condition(char **surface, char *new_stat, char **trace_hat_in)
-    int comp(double *d1, double *d2)
-
-    void loess_raw(double *y, double *x, double *weights, double *robust, int *d,
-         int*n, double *span, int *degree, int *nonparametric,
-         int *drop_square, int *sum_drop_sqr, double *cell, char **surf_stat,
-         double *surface, long *parameter, long *a, double *xi, double *vert,
-         double *vval, double *diagonal, double *trL, double *one_delta,
-         double *two_delta, int *setLf)
+    #
+    void predict(double *eval, int m, c_loess *lo, c_prediction *pre, int se)
+    void pred_free_mem(c_prediction *pre)
+    #
+    void anova(c_loess *one, c_loess *two, c_anova *out)
+    void pointwise(c_prediction *pre, int m, double coverage, c_conf_inv *ci)
\ No newline at end of file

Modified: trunk/Lib/sandbox/pyloess/sandbox/src/cloess.c
===================================================================
--- trunk/Lib/sandbox/pyloess/sandbox/src/cloess.c	2007-03-14 12:34:56 UTC (rev 2846)
+++ trunk/Lib/sandbox/pyloess/sandbox/src/cloess.c	2007-03-14 12:46:49 UTC (rev 2847)
@@ -1,4 +1,4 @@
-/* Generated by Pyrex 0.9.5.1a on Mon Mar 12 15:39:59 2007 */
+/* Generated by Pyrex 0.9.5.1a on Wed Mar 14 08:14:04 2007 */
 
 #include "Python.h"
 #include "structmember.h"
@@ -14,6 +14,7 @@
 #include "stdlib.h"
 #include "numpy/arrayobject.h"
 #include "loess.h"
+#include "cloess.h"
 
 
 typedef struct {PyObject **p; char *s;} __Pyx_InternTabEntry; /*proto*/
@@ -25,16 +26,18 @@
 static char *__pyx_filename;
 static char **__pyx_f;
 
+static int __Pyx_GetStarArgs(PyObject **args, PyObject **kwds, char *kwd_list[], int nargs, PyObject **args2, PyObject **kwds2); /*proto*/
+
 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
 
 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
 
-static int __Pyx_PrintItem(PyObject *); /*proto*/
-static int __Pyx_PrintNewline(void); /*proto*/
+static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
 
 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
 
-static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
+static int __Pyx_PrintItem(PyObject *); /*proto*/
+static int __Pyx_PrintNewline(void); /*proto*/
 
 static int __Pyx_InternStrings(__Pyx_InternTabEntry *t); /*proto*/
 
@@ -62,66 +65,58 @@
 
 struct __pyx_obj_6cloess_loess_inputs {
   PyObject_HEAD
-  loess_inputs _inputs;
-  long nobs;
-  long nvar;
-  PyArrayObject *x;
-  PyArrayObject *y;
-  PyArrayObject *weights;
+  loess_inputs (*_base);
 };
 
 
 struct __pyx_obj_6cloess_loess_control {
   PyObject_HEAD
-  loess_control _control;
-  char (*surface);
-  char (*statistics);
-  char (*trace_hat);
-  double cell;
-  int iterations;
+  loess_control (*_base);
 };
 
 
+struct __pyx_obj_6cloess_loess_kd_tree {
+  PyObject_HEAD
+  loess_kd_tree (*_base);
+};
+
+
+struct __pyx_obj_6cloess_loess_model {
+  PyObject_HEAD
+  loess_model (*_base);
+  long npar;
+};
+
+
 struct __pyx_obj_6cloess_loess_outputs {
   PyObject_HEAD
-  loess_outputs _outputs;
-  PyArrayObject *fitted_values;
-  PyArrayObject *fitted_residuals;
-  PyArrayObject *pseudovalues;
-  PyArrayObject *diagonal;
-  PyArrayObject *robust;
-  PyArrayObject *divisor;
-  double enp;
-  double s;
-  double one_delta;
-  double two_delta;
-  double trace_hat;
+  loess_outputs (*_base);
+  long nobs;
 };
 
 
-struct __pyx_obj_6cloess_loess_kd_tree {
+struct __pyx_obj_6cloess_loess_anova {
   PyObject_HEAD
-  loess_kd_tree _kdtree;
-  PyArrayObject *parameter;
-  PyArrayObject *a;
-  PyArrayObject *xi;
-  PyArrayObject *vert;
-  PyArrayObject *vval;
+  anova_struct (*_base);
+  long nest;
 };
 
 
-struct __pyx_obj_6cloess_loess_model {
+struct __pyx_obj_6cloess_confidence_interval {
   PyObject_HEAD
-  loess_model _model;
-  double span;
-  int degree;
-  int normalize;
-  char (*family);
-  PyObject *parametric_flags;
-  PyObject *drop_square_flags;
+  conf_inv (*_base);
+  PyObject *nest;
 };
 
 
+struct __pyx_obj_6cloess_loess_predicted {
+  PyObject_HEAD
+  prediction (*_base);
+  long nest;
+  struct __pyx_obj_6cloess_confidence_interval *conf_interval;
+};
+
+
 struct __pyx_obj_6cloess_loess {
   PyObject_HEAD
   loess _base;
@@ -130,324 +125,900 @@
   struct __pyx_obj_6cloess_loess_control *control;
   struct __pyx_obj_6cloess_loess_kd_tree *kd_tree;
   struct __pyx_obj_6cloess_loess_outputs *outputs;
+  struct __pyx_obj_6cloess_loess_predicted *predicted;
 };
 
 static PyTypeObject *__pyx_ptype_6cloess_loess_inputs = 0;
 static PyTypeObject *__pyx_ptype_6cloess_loess_control = 0;
-static PyTypeObject *__pyx_ptype_6cloess_loess_outputs = 0;
 static PyTypeObject *__pyx_ptype_6cloess_loess_kd_tree = 0;
 static PyTypeObject *__pyx_ptype_6cloess_loess_model = 0;
+static PyTypeObject *__pyx_ptype_6cloess_loess_outputs = 0;
+static PyTypeObject *__pyx_ptype_6cloess_loess_anova = 0;
+static PyTypeObject *__pyx_ptype_6cloess_confidence_interval = 0;
+static PyTypeObject *__pyx_ptype_6cloess_loess_predicted = 0;
 static PyTypeObject *__pyx_ptype_6cloess_loess = 0;
-static PyObject *__pyx_k2;
-static double __pyx_k3;
-static int __pyx_k4;
-static int __pyx_k5;
-static PyObject *__pyx_k6;
 static PyObject *__pyx_k7;
+static PyObject *__pyx_k8;
 static PyObject *__pyx_k9;
-static PyObject *__pyx_k10;
+static PyObject *(__pyx_f_6cloess_floatarray_from_data(PyObject *,PyObject *,double (*))); /*proto*/
+static PyObject *(__pyx_f_6cloess_boolarray_from_data(PyObject *,PyObject *,int (*))); /*proto*/
 
 
 /* Implementation of cloess */
 
+static char (__pyx_k1[]) = "Weights";
+static char (__pyx_k2[]) = "Number of observations.";
+static char (__pyx_k3[]) = "Number of independent variables.";
+static char (__pyx_k4[]) = "Normalize the variables. Only useful if more than one variable...";
+static char (__pyx_k5[]) = "Equivalent number of parameters.";
 
 static PyObject *__pyx_n_c_python;
 static PyObject *__pyx_n_c_numpy;
-static PyObject *__pyx_n__N;
+static PyObject *__pyx_n_numpy;
 static PyObject *__pyx_n_c_loess;
-static PyObject *__pyx_n_numpy;
 static PyObject *__pyx_n_False;
-static PyObject *__pyx_n_gaussian;
 
-static PyObject *__pyx_n_ndim;
-static PyObject *__pyx_n_ValueError;
-static PyObject *__pyx_n_len;
+static PyObject *__pyx_n_empty;
+static PyObject *__pyx_n_float;
+static PyObject *__pyx_n_dtype;
 static PyObject *__pyx_n_size;
+static PyObject *__pyx_n_shape;
 
-static PyObject *__pyx_k11p;
-static PyObject *__pyx_k12p;
-static PyObject *__pyx_k13p;
-static PyObject *__pyx_k14p;
 
-static char (__pyx_k11[]) = "DEBUG: Initializing loess_inputs...";
-static char (__pyx_k12[]) = "Argument 'x' should be 2D at most!";
-static char (__pyx_k13[]) = "Invalid size of the 'weights' vector!";
-static char (__pyx_k14[]) = " OK.";
-
-static int __pyx_f_6cloess_12loess_inputs___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static int __pyx_f_6cloess_12loess_inputs___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyObject *__pyx_v_x = 0;
-  PyObject *__pyx_v_y = 0;
-  PyObject *__pyx_v_weights = 0;
-  double (*__pyx_v_w_dat);
-  npy_intp __pyx_v_n;
-  npy_intp __pyx_v_p;
-  npy_intp (*__pyx_v_dims);
+static PyObject *__pyx_f_6cloess_floatarray_from_data(PyObject *__pyx_v_rows,PyObject *__pyx_v_cols,double (*__pyx_v_data)) {
+  PyArrayObject *__pyx_v_a_ndr;
+  double (*__pyx_v_a_dat);
   PyObject *__pyx_v_i;
-  int __pyx_r;
+  PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
   PyObject *__pyx_2 = 0;
-  int __pyx_3;
+  PyObject *__pyx_3 = 0;
   PyObject *__pyx_4 = 0;
-  npy_intp __pyx_5;
+  PyObject *__pyx_5 = 0;
   long __pyx_6;
-  static char *__pyx_argnames[] = {"x","y","weights",0};
-  __pyx_v_weights = __pyx_k2;
-  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "OO|O", __pyx_argnames, &__pyx_v_x, &__pyx_v_y, &__pyx_v_weights)) return -1;
-  Py_INCREF(__pyx_v_self);
-  Py_INCREF(__pyx_v_x);
-  Py_INCREF(__pyx_v_y);
-  Py_INCREF(__pyx_v_weights);
+  long __pyx_7;
+  int __pyx_8;
+  int __pyx_9;
+  Py_INCREF(__pyx_v_rows);
+  Py_INCREF(__pyx_v_cols);
+  __pyx_v_a_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
   __pyx_v_i = Py_None; Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":27 */
-  if (__Pyx_PrintItem(__pyx_k11p) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; goto __pyx_L1;}
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":28 */
-  __pyx_1 = PyArray_FROMANY(__pyx_v_x,NPY_DOUBLE,1,1,NPY_OWNDATA); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; goto __pyx_L1;}
-  Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_1)));
-  Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->x));
-  ((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->x = ((PyArrayObject *)__pyx_1);
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":22 */
+  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
+  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_n_empty); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":29 */
-  __pyx_1 = PyArray_FROMANY(__pyx_v_y,NPY_DOUBLE,1,1,NPY_OWNDATA); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; goto __pyx_L1;}
-  Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_1)));
-  Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->y));
-  ((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->y = ((PyArrayObject *)__pyx_1);
+  __pyx_1 = PyNumber_Multiply(__pyx_v_rows, __pyx_v_cols); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_3, 0, __pyx_1);
+  __pyx_1 = 0;
+  __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_3);
+  __pyx_3 = 0;
+  __pyx_3 = PyDict_New(); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
+  __pyx_4 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
+  __pyx_5 = PyObject_GetAttr(__pyx_4, __pyx_n_float); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+  if (PyDict_SetItem(__pyx_3, __pyx_n_dtype, __pyx_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  __pyx_4 = PyEval_CallObjectWithKeywords(__pyx_2, __pyx_1, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  if (!__Pyx_TypeTest(__pyx_4, __pyx_ptype_7c_numpy_ndarray)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)__pyx_v_a_ndr));
+  __pyx_v_a_ndr = ((PyArrayObject *)__pyx_4);
+  __pyx_4 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":31 */
-  __pyx_1 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->x), __pyx_n_ndim); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; goto __pyx_L1;}
-  __pyx_2 = PyInt_FromLong(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; goto __pyx_L1;}
-  if (PyObject_Cmp(__pyx_1, __pyx_2, &__pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; goto __pyx_L1;}
-  __pyx_3 = __pyx_3 > 0;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":23 */
+  __pyx_v_a_dat = ((double (*))__pyx_v_a_ndr->data);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":24 */
+  __pyx_5 = PyObject_GetAttr(((PyObject *)__pyx_v_a_ndr), __pyx_n_size); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; goto __pyx_L1;}
+  __pyx_7 = PyInt_AsLong(__pyx_5); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; goto __pyx_L1;}
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  for (__pyx_6 = 0; __pyx_6 < __pyx_7; ++__pyx_6) {
+    __pyx_2 = PyInt_FromLong(__pyx_6); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; goto __pyx_L1;}
+    Py_DECREF(__pyx_v_i);
+    __pyx_v_i = __pyx_2;
+    __pyx_2 = 0;
+
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":25 */
+    __pyx_8 = PyInt_AsLong(__pyx_v_i); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; goto __pyx_L1;}
+    __pyx_9 = PyInt_AsLong(__pyx_v_i); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; goto __pyx_L1;}
+    (__pyx_v_a_dat[__pyx_9]) = (__pyx_v_data[__pyx_8]);
+  }
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":26 */
+  __pyx_1 = PyInt_FromLong(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_v_cols, __pyx_1, &__pyx_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; goto __pyx_L1;}
+  __pyx_8 = __pyx_8 > 0;
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
-  if (__pyx_3) {
+  if (__pyx_8) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":32 */
-    __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; goto __pyx_L1;}
-    __Pyx_Raise(__pyx_1, __pyx_k12p, 0);
-    Py_DECREF(__pyx_1); __pyx_1 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; goto __pyx_L1;}
-    goto __pyx_L2;
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":27 */
+    __pyx_3 = PyTuple_New(2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; goto __pyx_L1;}
+    Py_INCREF(__pyx_v_rows);
+    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_rows);
+    Py_INCREF(__pyx_v_cols);
+    PyTuple_SET_ITEM(__pyx_3, 1, __pyx_v_cols);
+    if (PyObject_SetAttr(((PyObject *)__pyx_v_a_ndr), __pyx_n_shape, __pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; goto __pyx_L1;}
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    goto __pyx_L4;
   }
-  __pyx_L2:;
+  __pyx_L4:;
 
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":28 */
+  Py_INCREF(((PyObject *)__pyx_v_a_ndr));
+  __pyx_r = ((PyObject *)__pyx_v_a_ndr);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  Py_XDECREF(__pyx_4);
+  Py_XDECREF(__pyx_5);
+  __Pyx_AddTraceback("cloess.floatarray_from_data");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_a_ndr);
+  Py_DECREF(__pyx_v_i);
+  Py_DECREF(__pyx_v_rows);
+  Py_DECREF(__pyx_v_cols);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_n_int;
+static PyObject *__pyx_n_astype;
+static PyObject *__pyx_n_bool;
+
+
+static PyObject *__pyx_f_6cloess_boolarray_from_data(PyObject *__pyx_v_rows,PyObject *__pyx_v_cols,int (*__pyx_v_data)) {
+  PyArrayObject *__pyx_v_a_ndr;
+  int (*__pyx_v_a_dat);
+  PyObject *__pyx_v_i;
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  PyObject *__pyx_4 = 0;
+  PyObject *__pyx_5 = 0;
+  long __pyx_6;
+  long __pyx_7;
+  int __pyx_8;
+  int __pyx_9;
+  Py_INCREF(__pyx_v_rows);
+  Py_INCREF(__pyx_v_cols);
+  __pyx_v_a_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  __pyx_v_i = Py_None; Py_INCREF(Py_None);
+
   /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":33 */
-  __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_len); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
+  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
+  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_n_empty); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = PyNumber_Multiply(__pyx_v_rows, __pyx_v_cols); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_3, 0, __pyx_1);
+  __pyx_1 = 0;
   __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
-  Py_INCREF(((PyObject *)((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->x));
-  PyTuple_SET_ITEM(__pyx_1, 0, ((PyObject *)((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->x));
-  __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_3);
+  __pyx_3 = 0;
+  __pyx_3 = PyDict_New(); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
+  __pyx_4 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
+  __pyx_5 = PyObject_GetAttr(__pyx_4, __pyx_n_int); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+  if (PyDict_SetItem(__pyx_3, __pyx_n_dtype, __pyx_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  __pyx_4 = PyEval_CallObjectWithKeywords(__pyx_2, __pyx_1, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_5 = PyInt_AsLong(__pyx_4); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
-  Py_DECREF(__pyx_4); __pyx_4 = 0;
-  __pyx_v_n = __pyx_5;
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  if (!__Pyx_TypeTest(__pyx_4, __pyx_ptype_7c_numpy_ndarray)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)__pyx_v_a_ndr));
+  __pyx_v_a_ndr = ((PyArrayObject *)__pyx_4);
+  __pyx_4 = 0;
 
   /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":34 */
-  __pyx_2 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->x), __pyx_n_size); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; goto __pyx_L1;}
-  __pyx_1 = PyInt_FromLong(__pyx_v_n); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; goto __pyx_L1;}
-  __pyx_4 = PyNumber_Divide(__pyx_2, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; goto __pyx_L1;}
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_v_a_dat = ((int (*))__pyx_v_a_ndr->data);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":35 */
+  __pyx_5 = PyObject_GetAttr(((PyObject *)__pyx_v_a_ndr), __pyx_n_size); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; goto __pyx_L1;}
+  __pyx_7 = PyInt_AsLong(__pyx_5); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; goto __pyx_L1;}
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  for (__pyx_6 = 0; __pyx_6 < __pyx_7; ++__pyx_6) {
+    __pyx_2 = PyInt_FromLong(__pyx_6); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; goto __pyx_L1;}
+    Py_DECREF(__pyx_v_i);
+    __pyx_v_i = __pyx_2;
+    __pyx_2 = 0;
+
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":36 */
+    __pyx_8 = PyInt_AsLong(__pyx_v_i); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; goto __pyx_L1;}
+    __pyx_9 = PyInt_AsLong(__pyx_v_i); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; goto __pyx_L1;}
+    (__pyx_v_a_dat[__pyx_9]) = (__pyx_v_data[__pyx_8]);
+  }
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":37 */
+  __pyx_1 = PyInt_FromLong(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_v_cols, __pyx_1, &__pyx_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; goto __pyx_L1;}
+  __pyx_8 = __pyx_8 > 0;
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_5 = PyInt_AsLong(__pyx_4); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; goto __pyx_L1;}
+  if (__pyx_8) {
+
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":38 */
+    __pyx_3 = PyTuple_New(2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; goto __pyx_L1;}
+    Py_INCREF(__pyx_v_rows);
+    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_rows);
+    Py_INCREF(__pyx_v_cols);
+    PyTuple_SET_ITEM(__pyx_3, 1, __pyx_v_cols);
+    if (PyObject_SetAttr(((PyObject *)__pyx_v_a_ndr), __pyx_n_shape, __pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; goto __pyx_L1;}
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":39 */
+  __pyx_4 = PyObject_GetAttr(((PyObject *)__pyx_v_a_ndr), __pyx_n_astype); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; goto __pyx_L1;}
+  __pyx_5 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; goto __pyx_L1;}
+  __pyx_2 = PyObject_GetAttr(__pyx_5, __pyx_n_bool); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; goto __pyx_L1;}
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_2);
+  __pyx_2 = 0;
+  __pyx_3 = PyObject_CallObject(__pyx_4, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; goto __pyx_L1;}
   Py_DECREF(__pyx_4); __pyx_4 = 0;
-  __pyx_v_p = __pyx_5;
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_r = __pyx_3;
+  __pyx_3 = 0;
+  goto __pyx_L0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":36 */
-  ((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->nobs = ((long )__pyx_v_n);
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  Py_XDECREF(__pyx_4);
+  Py_XDECREF(__pyx_5);
+  __Pyx_AddTraceback("cloess.boolarray_from_data");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_a_ndr);
+  Py_DECREF(__pyx_v_i);
+  Py_DECREF(__pyx_v_rows);
+  Py_DECREF(__pyx_v_cols);
+  return __pyx_r;
+}
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":37 */
-  ((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->nvar = ((long )__pyx_v_p);
+static PyObject *__pyx_f_6cloess_12loess_inputs_1x___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_12loess_inputs_1x___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":38 */
-  (__pyx_v_dims[0]) = __pyx_v_n;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":50 */
+  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->n); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; goto __pyx_L1;}
+  __pyx_2 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->p); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; goto __pyx_L1;}
+  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->x); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_r = __pyx_3;
+  __pyx_3 = 0;
+  goto __pyx_L0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":40 */
-  __pyx_3 = __pyx_v_weights == Py_None;
-  if (__pyx_3) {
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  __Pyx_AddTraceback("cloess.loess_inputs.x.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":41 */
-    __pyx_2 = PyArray_EMPTY(1,__pyx_v_dims,NPY_DOUBLE,NPY_ALIGNED); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; goto __pyx_L1;}
-    Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_2)));
-    Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->weights));
-    ((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->weights = ((PyArrayObject *)__pyx_2);
-    Py_DECREF(__pyx_2); __pyx_2 = 0;
+static PyObject *__pyx_f_6cloess_12loess_inputs_1y___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_12loess_inputs_1y___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  Py_INCREF(__pyx_v_self);
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":42 */
-    __pyx_v_w_dat = ((double (*))((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->weights->data);
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":54 */
+  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->n); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; goto __pyx_L1;}
+  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; goto __pyx_L1;}
+  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->y); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_r = __pyx_3;
+  __pyx_3 = 0;
+  goto __pyx_L0;
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":43 */
-    __pyx_5 = (__pyx_v_dims[0]);
-    for (__pyx_6 = 0; __pyx_6 < __pyx_5; ++__pyx_6) {
-      __pyx_1 = PyInt_FromLong(__pyx_6); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; goto __pyx_L1;}
-      Py_DECREF(__pyx_v_i);
-      __pyx_v_i = __pyx_1;
-      __pyx_1 = 0;
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  __Pyx_AddTraceback("cloess.loess_inputs.y.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
 
-      /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":44 */
-      __pyx_3 = PyInt_AsLong(__pyx_v_i); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; goto __pyx_L1;}
-      (__pyx_v_w_dat[__pyx_3]) = 1;
-    }
-    goto __pyx_L3;
-  }
-  /*else*/ {
+static PyObject *__pyx_f_6cloess_12loess_inputs_7weights___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_12loess_inputs_7weights___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  Py_INCREF(__pyx_v_self);
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":46 */
-    __pyx_4 = PyArray_FROMANY(__pyx_v_weights,NPY_DOUBLE,1,1,NPY_OWNDATA); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; goto __pyx_L1;}
-    Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_4)));
-    Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->weights));
-    ((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->weights = ((PyArrayObject *)__pyx_4);
-    Py_DECREF(__pyx_4); __pyx_4 = 0;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":59 */
+  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->n); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; goto __pyx_L1;}
+  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; goto __pyx_L1;}
+  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->weights); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_r = __pyx_3;
+  __pyx_3 = 0;
+  goto __pyx_L0;
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":47 */
-    __pyx_2 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->weights), __pyx_n_ndim); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; goto __pyx_L1;}
-    __pyx_1 = PyInt_FromLong(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; goto __pyx_L1;}
-    if (PyObject_Cmp(__pyx_2, __pyx_1, &__pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; goto __pyx_L1;}
-    __pyx_3 = __pyx_3 > 0;
-    Py_DECREF(__pyx_2); __pyx_2 = 0;
-    Py_DECREF(__pyx_1); __pyx_1 = 0;
-    if (!__pyx_3) {
-      __pyx_4 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->weights), __pyx_n_size); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; goto __pyx_L1;}
-      __pyx_2 = PyInt_FromLong(__pyx_v_n); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; goto __pyx_L1;}
-      if (PyObject_Cmp(__pyx_4, __pyx_2, &__pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; goto __pyx_L1;}
-      __pyx_3 = __pyx_3 != 0;
-      Py_DECREF(__pyx_4); __pyx_4 = 0;
-      Py_DECREF(__pyx_2); __pyx_2 = 0;
-    }
-    if (__pyx_3) {
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  __Pyx_AddTraceback("cloess.loess_inputs.weights.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
 
-      /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":48 */
-      __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; goto __pyx_L1;}
-      __Pyx_Raise(__pyx_1, __pyx_k13p, 0);
-      Py_DECREF(__pyx_1); __pyx_1 = 0;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; goto __pyx_L1;}
-      goto __pyx_L6;
-    }
-    __pyx_L6:;
+static PyObject *__pyx_n_ndim;
+static PyObject *__pyx_n_ValueError;
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":49 */
-    __pyx_v_w_dat = ((double (*))((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->weights->data);
+static PyObject *__pyx_k12p;
+
+static char (__pyx_k12[]) = "Invalid size of the 'weights' vector!";
+
+static int __pyx_f_6cloess_12loess_inputs_7weights___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_w); /*proto*/
+static int __pyx_f_6cloess_12loess_inputs_7weights___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_w) {
+  PyArrayObject *__pyx_v_w_ndr;
+  int __pyx_r;
+  PyObject *__pyx_1 = 0;
+  int __pyx_2;
+  PyObject *__pyx_3 = 0;
+  Py_INCREF(__pyx_v_self);
+  Py_INCREF(__pyx_v_w);
+  __pyx_v_w_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":64 */
+  __pyx_1 = PyArray_FROMANY(__pyx_v_w,NPY_DOUBLE,1,1,NPY_OWNDATA); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; goto __pyx_L1;}
+  Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_1)));
+  Py_DECREF(((PyObject *)__pyx_v_w_ndr));
+  __pyx_v_w_ndr = ((PyArrayObject *)__pyx_1);
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":65 */
+  __pyx_1 = PyObject_GetAttr(((PyObject *)__pyx_v_w_ndr), __pyx_n_ndim); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;}
+  __pyx_3 = PyInt_FromLong(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_1, __pyx_3, &__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;}
+  __pyx_2 = __pyx_2 > 0;
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  if (!__pyx_2) {
+    __pyx_1 = PyObject_GetAttr(((PyObject *)__pyx_v_w_ndr), __pyx_n_size); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;}
+    __pyx_3 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->n); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;}
+    if (PyObject_Cmp(__pyx_1, __pyx_3, &__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;}
+    __pyx_2 = __pyx_2 != 0;
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
   }
-  __pyx_L3:;
+  if (__pyx_2) {
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":51 */
-  ((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_inputs.n = ((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->nobs;
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":66 */
+    __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; goto __pyx_L1;}
+    __Pyx_Raise(__pyx_1, __pyx_k12p, 0);
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; goto __pyx_L1;}
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":52 */
-  ((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_inputs.p = ((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->nvar;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":67 */
+  ((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->weights = ((double (*))__pyx_v_w_ndr->data);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":53 */
-  ((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_inputs.x = ((double (*))((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->x->data);
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_3);
+  __Pyx_AddTraceback("cloess.loess_inputs.weights.__set__");
+  __pyx_r = -1;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_w_ndr);
+  Py_DECREF(__pyx_v_self);
+  Py_DECREF(__pyx_v_w);
+  return __pyx_r;
+}
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":54 */
-  ((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_inputs.y = ((double (*))((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->y->data);
+static PyObject *__pyx_f_6cloess_12loess_inputs_4nobs___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_12loess_inputs_4nobs___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":55 */
-  ((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_inputs.weights = ((double (*))((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->weights->data);
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":72 */
+  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->n); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":62 */
-  if (__Pyx_PrintItem(__pyx_k14p) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; goto __pyx_L1;}
-  if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; goto __pyx_L1;}
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("cloess.loess_inputs.nobs.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":63 */
+static PyObject *__pyx_f_6cloess_12loess_inputs_4nvar___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_12loess_inputs_4nvar___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":77 */
+  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->p); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("cloess.loess_inputs.nvar.__get__");
   __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6cloess_13loess_control_7surface___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_13loess_control_7surface___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":87 */
+  __pyx_1 = PyString_FromString(((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->surface); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
   goto __pyx_L0;
 
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("cloess.loess_control.surface.__get__");
   __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static int __pyx_f_6cloess_13loess_control_7surface___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_surface); /*proto*/
+static int __pyx_f_6cloess_13loess_control_7surface___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_surface) {
+  int __pyx_r;
+  char (*__pyx_1);
+  Py_INCREF(__pyx_v_self);
+  Py_INCREF(__pyx_v_surface);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":89 */
+  __pyx_1 = PyString_AsString(__pyx_v_surface); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; goto __pyx_L1;}
+  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->surface = __pyx_1;
+
+  __pyx_r = 0;
   goto __pyx_L0;
   __pyx_L1:;
+  __Pyx_AddTraceback("cloess.loess_control.surface.__set__");
+  __pyx_r = -1;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  Py_DECREF(__pyx_v_surface);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6cloess_13loess_control_10statistics___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_13loess_control_10statistics___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":93 */
+  __pyx_1 = PyString_FromString(((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->statistics); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
   Py_XDECREF(__pyx_1);
-  Py_XDECREF(__pyx_2);
-  Py_XDECREF(__pyx_4);
-  __Pyx_AddTraceback("cloess.loess_inputs.__init__");
+  __Pyx_AddTraceback("cloess.loess_control.statistics.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static int __pyx_f_6cloess_13loess_control_10statistics___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_statistics); /*proto*/
+static int __pyx_f_6cloess_13loess_control_10statistics___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_statistics) {
+  int __pyx_r;
+  char (*__pyx_1);
+  Py_INCREF(__pyx_v_self);
+  Py_INCREF(__pyx_v_statistics);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":95 */
+  __pyx_1 = PyString_AsString(__pyx_v_statistics); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; goto __pyx_L1;}
+  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->statistics = __pyx_1;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1:;
+  __Pyx_AddTraceback("cloess.loess_control.statistics.__set__");
   __pyx_r = -1;
   __pyx_L0:;
-  Py_DECREF(__pyx_v_i);
   Py_DECREF(__pyx_v_self);
-  Py_DECREF(__pyx_v_x);
-  Py_DECREF(__pyx_v_y);
-  Py_DECREF(__pyx_v_weights);
+  Py_DECREF(__pyx_v_statistics);
   return __pyx_r;
 }
 
-static PyObject *__pyx_k15p;
-static PyObject *__pyx_k19p;
+static PyObject *__pyx_f_6cloess_13loess_control_9trace_hat___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_13loess_control_9trace_hat___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
 
-static char (__pyx_k15[]) = "DEBUG: Initializing loess_control...";
-static char (__pyx_k16[]) = "interpolate";
-static char (__pyx_k17[]) = "approximate";
-static char (__pyx_k18[]) = "wait.to.decide";
-static char (__pyx_k19[]) = "OK.";
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":99 */
+  __pyx_1 = PyString_FromString(((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->trace_hat); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
 
-static int __pyx_f_6cloess_13loess_control___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static int __pyx_f_6cloess_13loess_control___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("cloess.loess_control.trace_hat.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static int __pyx_f_6cloess_13loess_control_9trace_hat___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_trace_hat); /*proto*/
+static int __pyx_f_6cloess_13loess_control_9trace_hat___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_trace_hat) {
   int __pyx_r;
-  static char *__pyx_argnames[] = {0};
-  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "", __pyx_argnames)) return -1;
+  char (*__pyx_1);
   Py_INCREF(__pyx_v_self);
+  Py_INCREF(__pyx_v_trace_hat);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":76 */
-  if (__Pyx_PrintItem(__pyx_k15p) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":101 */
+  __pyx_1 = PyString_AsString(__pyx_v_trace_hat); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; goto __pyx_L1;}
+  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->trace_hat = __pyx_1;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":77 */
-  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->surface = __pyx_k16;
-  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_control.surface = __pyx_k16;
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1:;
+  __Pyx_AddTraceback("cloess.loess_control.trace_hat.__set__");
+  __pyx_r = -1;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  Py_DECREF(__pyx_v_trace_hat);
+  return __pyx_r;
+}
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":78 */
-  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->statistics = __pyx_k17;
-  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_control.statistics = __pyx_k17;
+static PyObject *__pyx_f_6cloess_13loess_control_10iterations___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_13loess_control_10iterations___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":79 */
-  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->cell = 0.2;
-  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_control.cell = 0.2;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":105 */
+  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->iterations); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":80 */
-  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->trace_hat = __pyx_k18;
-  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_control.trace_hat = __pyx_k18;
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("cloess.loess_control.iterations.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":81 */
-  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->iterations = 4;
-  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_control.iterations = 4;
+static int __pyx_f_6cloess_13loess_control_10iterations___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_iterations); /*proto*/
+static int __pyx_f_6cloess_13loess_control_10iterations___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_iterations) {
+  int __pyx_r;
+  int __pyx_1;
+  Py_INCREF(__pyx_v_self);
+  Py_INCREF(__pyx_v_iterations);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":82 */
-  if (__Pyx_PrintItem(__pyx_k19p) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; goto __pyx_L1;}
-  if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":107 */
+  __pyx_1 = PyInt_AsLong(__pyx_v_iterations); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; goto __pyx_L1;}
+  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->iterations = __pyx_1;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":83 */
   __pyx_r = 0;
   goto __pyx_L0;
+  __pyx_L1:;
+  __Pyx_AddTraceback("cloess.loess_control.iterations.__set__");
+  __pyx_r = -1;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  Py_DECREF(__pyx_v_iterations);
+  return __pyx_r;
+}
 
+static PyObject *__pyx_f_6cloess_13loess_control_4cell___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_13loess_control_4cell___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":111 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->cell); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("cloess.loess_control.cell.__get__");
   __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static int __pyx_f_6cloess_13loess_control_4cell___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_cell); /*proto*/
+static int __pyx_f_6cloess_13loess_control_4cell___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_cell) {
+  int __pyx_r;
+  double __pyx_1;
+  Py_INCREF(__pyx_v_self);
+  Py_INCREF(__pyx_v_cell);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":113 */
+  __pyx_1 = PyFloat_AsDouble(__pyx_v_cell); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; goto __pyx_L1;}
+  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->cell = __pyx_1;
+
+  __pyx_r = 0;
   goto __pyx_L0;
   __pyx_L1:;
-  __Pyx_AddTraceback("cloess.loess_control.__init__");
+  __Pyx_AddTraceback("cloess.loess_control.cell.__set__");
   __pyx_r = -1;
   __pyx_L0:;
   Py_DECREF(__pyx_v_self);
+  Py_DECREF(__pyx_v_cell);
   return __pyx_r;
 }
 
+static PyObject *__pyx_n_get;
+static PyObject *__pyx_n_surface;
+static PyObject *__pyx_n_statistics;
+static PyObject *__pyx_n_trace_hat;
+static PyObject *__pyx_n_iterations;
+static PyObject *__pyx_n_cell;
+static PyObject *__pyx_n_parametric_flags;
+
+
+static PyObject *__pyx_f_6cloess_13loess_control_update(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_6cloess_13loess_control_update(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_cellargs = 0;
+  PyObject *__pyx_v_surface;
+  PyObject *__pyx_v_statistics;
+  PyObject *__pyx_v_trace_hat;
+  PyObject *__pyx_v_iterations;
+  PyObject *__pyx_v_cell;
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  int __pyx_4;
+  static char *__pyx_argnames[] = {0};
+  if (__Pyx_GetStarArgs(&__pyx_args, &__pyx_kwds, __pyx_argnames, 0, 0, &__pyx_v_cellargs) < 0) return 0;
+  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "", __pyx_argnames)) {
+    Py_XDECREF(__pyx_args);
+    Py_XDECREF(__pyx_kwds);
+    Py_XDECREF(__pyx_v_cellargs);
+    return 0;
+  }
+  Py_INCREF(__pyx_v_self);
+  __pyx_v_surface = Py_None; Py_INCREF(Py_None);
+  __pyx_v_statistics = Py_None; Py_INCREF(Py_None);
+  __pyx_v_trace_hat = Py_None; Py_INCREF(Py_None);
+  __pyx_v_iterations = Py_None; Py_INCREF(Py_None);
+  __pyx_v_cell = Py_None; Py_INCREF(Py_None);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":116 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; goto __pyx_L1;}
+  Py_INCREF(__pyx_n_surface);
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_surface);
+  Py_INCREF(Py_None);
+  PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_v_surface);
+  __pyx_v_surface = __pyx_3;
+  __pyx_3 = 0;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":117 */
+  __pyx_4 = __pyx_v_surface != Py_None;
+  if (__pyx_4) {
+
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":118 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_surface, __pyx_v_surface) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; goto __pyx_L1;}
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":120 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; goto __pyx_L1;}
+  Py_INCREF(__pyx_n_statistics);
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_statistics);
+  Py_INCREF(Py_None);
+  PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_v_statistics);
+  __pyx_v_statistics = __pyx_3;
+  __pyx_3 = 0;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":121 */
+  __pyx_4 = __pyx_v_statistics != Py_None;
+  if (__pyx_4) {
+
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":122 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_statistics, __pyx_v_statistics) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 122; goto __pyx_L1;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":124 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; goto __pyx_L1;}
+  Py_INCREF(__pyx_n_trace_hat);
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_trace_hat);
+  Py_INCREF(Py_None);
+  PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_v_trace_hat);
+  __pyx_v_trace_hat = __pyx_3;
+  __pyx_3 = 0;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":125 */
+  __pyx_4 = __pyx_v_trace_hat != Py_None;
+  if (__pyx_4) {
+
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":126 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_trace_hat, __pyx_v_trace_hat) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 126; goto __pyx_L1;}
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":128 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; goto __pyx_L1;}
+  Py_INCREF(__pyx_n_iterations);
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_iterations);
+  Py_INCREF(Py_None);
+  PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_v_iterations);
+  __pyx_v_iterations = __pyx_3;
+  __pyx_3 = 0;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":129 */
+  __pyx_4 = __pyx_v_iterations != Py_None;
+  if (__pyx_4) {
+
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":130 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_iterations, __pyx_v_iterations) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 130; goto __pyx_L1;}
+    goto __pyx_L5;
+  }
+  __pyx_L5:;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":132 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; goto __pyx_L1;}
+  Py_INCREF(__pyx_n_cell);
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_cell);
+  Py_INCREF(Py_None);
+  PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_v_cell);
+  __pyx_v_cell = __pyx_3;
+  __pyx_3 = 0;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":133 */
+  __pyx_4 = __pyx_v_cell != Py_None;
+  if (__pyx_4) {
+
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":134 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_parametric_flags, __pyx_v_cell) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; goto __pyx_L1;}
+    goto __pyx_L6;
+  }
+  __pyx_L6:;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  __Pyx_AddTraceback("cloess.loess_control.update");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_XDECREF(__pyx_v_cellargs);
+  Py_DECREF(__pyx_v_surface);
+  Py_DECREF(__pyx_v_statistics);
+  Py_DECREF(__pyx_v_trace_hat);
+  Py_DECREF(__pyx_v_iterations);
+  Py_DECREF(__pyx_v_cell);
+  Py_DECREF(__pyx_v_self);
+  Py_XDECREF(__pyx_args);
+  Py_XDECREF(__pyx_kwds);
+  return __pyx_r;
+}
+
 static PyObject *__pyx_n_join;
 
+static PyObject *__pyx_k18p;
+static PyObject *__pyx_k19p;
 static PyObject *__pyx_k20p;
 static PyObject *__pyx_k21p;
 static PyObject *__pyx_k22p;
 static PyObject *__pyx_k23p;
 static PyObject *__pyx_k24p;
-static PyObject *__pyx_k25p;
-static PyObject *__pyx_k26p;
 
-static char (__pyx_k20[]) = "Control          :";
-static char (__pyx_k21[]) = "Surface type     : %s";
-static char (__pyx_k22[]) = "Statistics       : %s";
-static char (__pyx_k23[]) = "Trace estimation : %s";
-static char (__pyx_k24[]) = "Cell size        : %s";
-static char (__pyx_k25[]) = "Nb iterations    : %s";
-static char (__pyx_k26[]) = "\n";
+static char (__pyx_k18[]) = "Control          :";
+static char (__pyx_k19[]) = "Surface type     : %s";
+static char (__pyx_k20[]) = "Statistics       : %s";
+static char (__pyx_k21[]) = "Trace estimation : %s";
+static char (__pyx_k22[]) = "Cell size        : %s";
+static char (__pyx_k23[]) = "Nb iterations    : %s";
+static char (__pyx_k24[]) = "\n";
 
 static PyObject *__pyx_f_6cloess_13loess_control___str__(PyObject *__pyx_v_self); /*proto*/
 static PyObject *__pyx_f_6cloess_13loess_control___str__(PyObject *__pyx_v_self) {
@@ -462,25 +1033,25 @@
   Py_INCREF(__pyx_v_self);
   __pyx_v_strg = Py_None; Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":86 */
-  __pyx_1 = PyString_FromString(((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->surface); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; goto __pyx_L1;}
-  __pyx_2 = PyNumber_Remainder(__pyx_k21p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":138 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_surface); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; goto __pyx_L1;}
+  __pyx_2 = PyNumber_Remainder(__pyx_k19p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyString_FromString(((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->statistics); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; goto __pyx_L1;}
-  __pyx_3 = PyNumber_Remainder(__pyx_k22p, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; goto __pyx_L1;}
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_statistics); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; goto __pyx_L1;}
+  __pyx_3 = PyNumber_Remainder(__pyx_k20p, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyString_FromString(((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->trace_hat); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; goto __pyx_L1;}
-  __pyx_4 = PyNumber_Remainder(__pyx_k23p, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; goto __pyx_L1;}
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_trace_hat); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; goto __pyx_L1;}
+  __pyx_4 = PyNumber_Remainder(__pyx_k21p, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->cell); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; goto __pyx_L1;}
-  __pyx_5 = PyNumber_Remainder(__pyx_k24p, __pyx_1); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; goto __pyx_L1;}
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_cell); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; goto __pyx_L1;}
+  __pyx_5 = PyNumber_Remainder(__pyx_k22p, __pyx_1); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->iterations); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; goto __pyx_L1;}
-  __pyx_6 = PyNumber_Remainder(__pyx_k25p, __pyx_1); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; goto __pyx_L1;}
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_iterations); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; goto __pyx_L1;}
+  __pyx_6 = PyNumber_Remainder(__pyx_k23p, __pyx_1); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyList_New(6); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; goto __pyx_L1;}
-  Py_INCREF(__pyx_k20p);
-  PyList_SET_ITEM(__pyx_1, 0, __pyx_k20p);
+  __pyx_1 = PyList_New(6); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; goto __pyx_L1;}
+  Py_INCREF(__pyx_k18p);
+  PyList_SET_ITEM(__pyx_1, 0, __pyx_k18p);
   PyList_SET_ITEM(__pyx_1, 1, __pyx_2);
   PyList_SET_ITEM(__pyx_1, 2, __pyx_3);
   PyList_SET_ITEM(__pyx_1, 3, __pyx_4);
@@ -495,12 +1066,12 @@
   __pyx_v_strg = __pyx_1;
   __pyx_1 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":92 */
-  __pyx_2 = PyObject_GetAttr(__pyx_k26p, __pyx_n_join); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; goto __pyx_L1;}
-  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":144 */
+  __pyx_2 = PyObject_GetAttr(__pyx_k24p, __pyx_n_join); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; goto __pyx_L1;}
   Py_INCREF(__pyx_v_strg);
   PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_strg);
-  __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; goto __pyx_L1;}
+  __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; goto __pyx_L1;}
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_3); __pyx_3 = 0;
   __pyx_r = __pyx_4;
@@ -524,525 +1095,608 @@
   return __pyx_r;
 }
 
-static PyObject *__pyx_n_pesudovalues;
+static PyObject *__pyx_f_6cloess_11loess_model_4span___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_11loess_model_4span___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
 
-static PyObject *__pyx_k27p;
-static PyObject *__pyx_k28p;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":183 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->span); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 183; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
 
-static char (__pyx_k27[]) = "DEBUG: Initializing loess_outputs...";
-static char (__pyx_k28[]) = "OK.";
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("cloess.loess_model.span.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
 
-static int __pyx_f_6cloess_13loess_outputs___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static int __pyx_f_6cloess_13loess_outputs___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyObject *__pyx_v_n = 0;
-  PyObject *__pyx_v_p = 0;
-  npy_intp (*__pyx_v_rows);
-  npy_intp (*__pyx_v_cols);
+static int __pyx_f_6cloess_11loess_model_4span___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_span); /*proto*/
+static int __pyx_f_6cloess_11loess_model_4span___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_span) {
   int __pyx_r;
+  double __pyx_1;
+  Py_INCREF(__pyx_v_self);
+  Py_INCREF(__pyx_v_span);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":185 */
+  __pyx_1 = PyFloat_AsDouble(__pyx_v_span); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; goto __pyx_L1;}
+  ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->span = __pyx_1;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1:;
+  __Pyx_AddTraceback("cloess.loess_model.span.__set__");
+  __pyx_r = -1;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  Py_DECREF(__pyx_v_span);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6cloess_11loess_model_6degree___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_11loess_model_6degree___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
-  static char *__pyx_argnames[] = {"n","p",0};
-  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "OO", __pyx_argnames, &__pyx_v_n, &__pyx_v_p)) return -1;
   Py_INCREF(__pyx_v_self);
-  Py_INCREF(__pyx_v_n);
-  Py_INCREF(__pyx_v_p);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":106 */
-  (__pyx_v_rows[0]) = ((int )__pyx_v_n);
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":189 */
+  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->degree); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":107 */
-  (__pyx_v_cols[0]) = ((int )__pyx_v_p);
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("cloess.loess_model.degree.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":108 */
-  if (__Pyx_PrintItem(__pyx_k27p) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; goto __pyx_L1;}
+static PyObject *__pyx_f_6cloess_11loess_model_9normalize___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_11loess_model_9normalize___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":110 */
-  __pyx_1 = PyArray_EMPTY(1,__pyx_v_rows,NPY_DOUBLE,NPY_ALIGNED); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; goto __pyx_L1;}
-  Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_1)));
-  Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->fitted_values));
-  ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->fitted_values = ((PyArrayObject *)__pyx_1);
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":194 */
+  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_bool); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; goto __pyx_L1;}
+  __pyx_2 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->normalize); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_3, 0, __pyx_2);
+  __pyx_2 = 0;
+  __pyx_2 = PyObject_CallObject(__pyx_1, __pyx_3); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  __pyx_r = __pyx_2;
+  __pyx_2 = 0;
+  goto __pyx_L0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":111 */
-  __pyx_1 = PyArray_EMPTY(1,__pyx_v_rows,NPY_DOUBLE,NPY_ALIGNED); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; goto __pyx_L1;}
-  Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_1)));
-  Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->fitted_residuals));
-  ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->fitted_residuals = ((PyArrayObject *)__pyx_1);
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  __Pyx_AddTraceback("cloess.loess_model.normalize.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":112 */
-  __pyx_1 = PyArray_EMPTY(1,__pyx_v_rows,NPY_DOUBLE,NPY_ALIGNED); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; goto __pyx_L1;}
-  if (PyObject_SetAttr(__pyx_v_self, __pyx_n_pesudovalues, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; goto __pyx_L1;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
+static int __pyx_f_6cloess_11loess_model_9normalize___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_normalize); /*proto*/
+static int __pyx_f_6cloess_11loess_model_9normalize___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_normalize) {
+  int __pyx_r;
+  int __pyx_1;
+  Py_INCREF(__pyx_v_self);
+  Py_INCREF(__pyx_v_normalize);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":113 */
-  __pyx_1 = PyArray_EMPTY(1,__pyx_v_rows,NPY_DOUBLE,NPY_ALIGNED); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; goto __pyx_L1;}
-  Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_1)));
-  Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->diagonal));
-  ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->diagonal = ((PyArrayObject *)__pyx_1);
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":196 */
+  __pyx_1 = PyInt_AsLong(__pyx_v_normalize); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; goto __pyx_L1;}
+  ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->normalize = __pyx_1;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":114 */
-  __pyx_1 = PyArray_EMPTY(1,__pyx_v_rows,NPY_DOUBLE,NPY_ALIGNED); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; goto __pyx_L1;}
-  Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_1)));
-  Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->robust));
-  ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->robust = ((PyArrayObject *)__pyx_1);
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1:;
+  __Pyx_AddTraceback("cloess.loess_model.normalize.__set__");
+  __pyx_r = -1;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  Py_DECREF(__pyx_v_normalize);
+  return __pyx_r;
+}
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":115 */
-  __pyx_1 = PyArray_EMPTY(1,__pyx_v_cols,NPY_DOUBLE,NPY_ALIGNED); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; goto __pyx_L1;}
-  Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_1)));
-  Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->divisor));
-  ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->divisor = ((PyArrayObject *)__pyx_1);
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
+static PyObject *__pyx_f_6cloess_11loess_model_6family___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_11loess_model_6family___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":117 */
-  ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_outputs.fitted_values = ((double (*))((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->fitted_values->data);
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":200 */
+  __pyx_1 = PyString_FromString(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->family); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":118 */
-  ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_outputs.fitted_residuals = ((double (*))((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->fitted_residuals->data);
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("cloess.loess_model.family.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":119 */
-  ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_outputs.pseudovalues = ((double (*))((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->pseudovalues->data);
+static PyObject *__pyx_f_6cloess_11loess_model_16parametric_flags___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_11loess_model_16parametric_flags___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":120 */
-  ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_outputs.diagonal = ((double (*))((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->diagonal->data);
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":204 */
+  __pyx_1 = PyInt_FromLong(8); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; goto __pyx_L1;}
+  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; goto __pyx_L1;}
+  __pyx_3 = __pyx_f_6cloess_boolarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->parametric); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_r = __pyx_3;
+  __pyx_3 = 0;
+  goto __pyx_L0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":121 */
-  ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_outputs.robust = ((double (*))((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->robust->data);
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  __Pyx_AddTraceback("cloess.loess_model.parametric_flags.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":122 */
-  ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_outputs.divisor = ((double (*))((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->divisor->data);
+static PyObject *__pyx_n_NPY_LONG;
+static PyObject *__pyx_n_max;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":124 */
-  ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->enp = 0;
-  ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_outputs.enp = 0;
+static int __pyx_f_6cloess_11loess_model_16parametric_flags___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_paramf); /*proto*/
+static int __pyx_f_6cloess_11loess_model_16parametric_flags___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_paramf) {
+  PyArrayObject *__pyx_v_p_ndr;
+  long (*__pyx_v_p_dat);
+  int __pyx_v_i;
+  int __pyx_r;
+  PyObject *__pyx_1 = 0;
+  enum NPY_TYPES __pyx_2;
+  PyObject *__pyx_3 = 0;
+  PyObject *__pyx_4 = 0;
+  PyObject *__pyx_5 = 0;
+  PyObject *__pyx_6 = 0;
+  PyObject *__pyx_7 = 0;
+  int __pyx_8;
+  Py_INCREF(__pyx_v_self);
+  Py_INCREF(__pyx_v_paramf);
+  __pyx_v_p_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":125 */
-  ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->s = 0;
-  ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_outputs.s = 0;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":209 */
+  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_NPY_LONG); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; goto __pyx_L1;}
+  __pyx_2 = ((enum NPY_TYPES )PyInt_AsLong(__pyx_1)); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = PyArray_FROMANY(__pyx_v_paramf,__pyx_2,1,1,NPY_OWNDATA); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; goto __pyx_L1;}
+  Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_1)));
+  Py_DECREF(((PyObject *)__pyx_v_p_ndr));
+  __pyx_v_p_ndr = ((PyArrayObject *)__pyx_1);
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":126 */
-  ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->one_delta = 0;
-  ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_outputs.one_delta = 0;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":210 */
+  __pyx_v_p_dat = ((long (*))__pyx_v_p_ndr->data);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":127 */
-  ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->two_delta = 0;
-  ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_outputs.two_delta = 0;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":211 */
+  __pyx_1 = PyInt_FromLong(0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
+  __pyx_3 = PyInt_FromLong(__pyx_v_i); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_1, __pyx_3, &__pyx_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
+  __pyx_8 = __pyx_8 <= 0;
+  if (__pyx_8) {
+    __pyx_4 = __Pyx_GetName(__pyx_b, __pyx_n_max); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
+    __pyx_5 = PyInt_FromLong(8); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
+    __pyx_6 = PyObject_GetAttr(((PyObject *)__pyx_v_p_ndr), __pyx_n_size); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
+    __pyx_7 = PyTuple_New(2); if (!__pyx_7) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
+    PyTuple_SET_ITEM(__pyx_7, 0, __pyx_5);
+    PyTuple_SET_ITEM(__pyx_7, 1, __pyx_6);
+    __pyx_5 = 0;
+    __pyx_6 = 0;
+    __pyx_5 = PyObject_CallObject(__pyx_4, __pyx_7); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    Py_DECREF(__pyx_7); __pyx_7 = 0;
+    if (PyObject_Cmp(__pyx_3, __pyx_5, &__pyx_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
+    __pyx_8 = __pyx_8 < 0;
+    Py_DECREF(__pyx_5); __pyx_5 = 0;
+  }
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  __pyx_6 = PyInt_FromLong(__pyx_8); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
+  __pyx_4 = PyObject_GetIter(__pyx_6); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
+  Py_DECREF(__pyx_6); __pyx_6 = 0;
+  for (;;) {
+    __pyx_7 = PyIter_Next(__pyx_4);
+    if (!__pyx_7) {
+      if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
+      break;
+    }
+    __pyx_8 = PyInt_AsLong(__pyx_7); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
+    Py_DECREF(__pyx_7); __pyx_7 = 0;
+    __pyx_v_i = __pyx_8;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":128 */
-  ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->trace_hat = 0;
-  ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_outputs.trace_hat = 0;
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":212 */
+    (((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->parametric[__pyx_v_i]) = (__pyx_v_p_dat[__pyx_v_i]);
+  }
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":129 */
-  if (__Pyx_PrintItem(__pyx_k28p) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; goto __pyx_L1;}
-  if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; goto __pyx_L1;}
-
   __pyx_r = 0;
   goto __pyx_L0;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);
-  __Pyx_AddTraceback("cloess.loess_outputs.__init__");
+  Py_XDECREF(__pyx_3);
+  Py_XDECREF(__pyx_4);
+  Py_XDECREF(__pyx_5);
+  Py_XDECREF(__pyx_6);
+  Py_XDECREF(__pyx_7);
+  __Pyx_AddTraceback("cloess.loess_model.parametric_flags.__set__");
   __pyx_r = -1;
   __pyx_L0:;
+  Py_DECREF(__pyx_v_p_ndr);
   Py_DECREF(__pyx_v_self);
-  Py_DECREF(__pyx_v_n);
-  Py_DECREF(__pyx_v_p);
+  Py_DECREF(__pyx_v_paramf);
   return __pyx_r;
 }
 
-static PyObject *__pyx_n_max;
-static PyObject *__pyx_n_NPY_LONG;
+static PyObject *__pyx_f_6cloess_11loess_model_17drop_square_flags___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_11loess_model_17drop_square_flags___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  Py_INCREF(__pyx_v_self);
 
-static PyObject *__pyx_k29p;
-static PyObject *__pyx_k30p;
-static PyObject *__pyx_k31p;
-static PyObject *__pyx_k32p;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":216 */
+  __pyx_1 = PyInt_FromLong(8); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 216; goto __pyx_L1;}
+  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 216; goto __pyx_L1;}
+  __pyx_3 = __pyx_f_6cloess_boolarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->drop_square); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 216; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_r = __pyx_3;
+  __pyx_3 = 0;
+  goto __pyx_L0;
 
-static char (__pyx_k29[]) = "DEBUG: Initializing loess_kdtree...";
-static char (__pyx_k30[]) = "(python side)";
-static char (__pyx_k31[]) = "(C side)";
-static char (__pyx_k32[]) = "OK.";
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  __Pyx_AddTraceback("cloess.loess_model.drop_square_flags.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
 
-static int __pyx_f_6cloess_13loess_kd_tree___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static int __pyx_f_6cloess_13loess_kd_tree___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  long __pyx_v_n;
-  long __pyx_v_p;
-  long __pyx_v_maxkd;
-  long __pyx_v_nval;
-  long __pyx_v_nvert;
-  npy_intp (*__pyx_v_nmaxkd);
-  npy_intp (*__pyx_v_nnval);
-  npy_intp (*__pyx_v_nnvert);
-  npy_intp (*__pyx_v_npars);
+static int __pyx_f_6cloess_11loess_model_17drop_square_flags___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_drop_sq); /*proto*/
+static int __pyx_f_6cloess_11loess_model_17drop_square_flags___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_drop_sq) {
+  PyArrayObject *__pyx_v_d_ndr;
+  long (*__pyx_v_d_dat);
+  int __pyx_v_i;
   int __pyx_r;
   PyObject *__pyx_1 = 0;
-  PyObject *__pyx_2 = 0;
+  enum NPY_TYPES __pyx_2;
   PyObject *__pyx_3 = 0;
   PyObject *__pyx_4 = 0;
-  long __pyx_5;
-  enum NPY_TYPES __pyx_6;
-  static char *__pyx_argnames[] = {"n","p",0};
-  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "ll", __pyx_argnames, &__pyx_v_n, &__pyx_v_p)) return -1;
+  PyObject *__pyx_5 = 0;
+  PyObject *__pyx_6 = 0;
+  PyObject *__pyx_7 = 0;
+  int __pyx_8;
   Py_INCREF(__pyx_v_self);
+  Py_INCREF(__pyx_v_drop_sq);
+  __pyx_v_d_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":150 */
-  if (__Pyx_PrintItem(__pyx_k29p) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; goto __pyx_L1;}
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":151 */
-  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_max); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 151; goto __pyx_L1;}
-  __pyx_2 = PyInt_FromLong(__pyx_v_n); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 151; goto __pyx_L1;}
-  __pyx_3 = PyInt_FromLong(200); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 151; goto __pyx_L1;}
-  __pyx_4 = PyTuple_New(2); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 151; goto __pyx_L1;}
-  PyTuple_SET_ITEM(__pyx_4, 0, __pyx_2);
-  PyTuple_SET_ITEM(__pyx_4, 1, __pyx_3);
-  __pyx_2 = 0;
-  __pyx_3 = 0;
-  __pyx_2 = PyObject_CallObject(__pyx_1, __pyx_4); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 151; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":221 */
+  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_NPY_LONG); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 221; goto __pyx_L1;}
+  __pyx_2 = ((enum NPY_TYPES )PyInt_AsLong(__pyx_1)); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 221; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  Py_DECREF(__pyx_4); __pyx_4 = 0;
-  __pyx_5 = PyInt_AsLong(__pyx_2); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 151; goto __pyx_L1;}
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
-  __pyx_v_maxkd = __pyx_5;
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":152 */
-  __pyx_v_nvert = (__pyx_v_p * 2);
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":153 */
-  __pyx_v_nval = ((__pyx_v_p + 1) * __pyx_v_maxkd);
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":155 */
-  if (__Pyx_PrintItem(__pyx_k30p) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; goto __pyx_L1;}
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":156 */
-  (__pyx_v_nmaxkd[0]) = ((int )__pyx_v_maxkd);
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":157 */
-  (__pyx_v_nnvert[0]) = ((int )__pyx_v_nvert);
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":158 */
-  (__pyx_v_nnval[0]) = ((int )__pyx_v_nval);
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":159 */
-  (__pyx_v_npars[0]) = ((int )8);
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":160 */
-  __pyx_3 = __Pyx_GetName(__pyx_b, __pyx_n_NPY_LONG); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; goto __pyx_L1;}
-  __pyx_6 = ((enum NPY_TYPES )PyInt_AsLong(__pyx_3)); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; goto __pyx_L1;}
-  Py_DECREF(__pyx_3); __pyx_3 = 0;
-  __pyx_1 = PyArray_EMPTY(1,__pyx_v_npars,__pyx_6,NPY_ALIGNED); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; goto __pyx_L1;}
+  __pyx_1 = PyArray_FROMANY(__pyx_v_drop_sq,__pyx_2,1,1,NPY_OWNDATA); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 221; goto __pyx_L1;}
   Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_1)));
-  Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess_kd_tree *)__pyx_v_self)->parameter));
-  ((struct __pyx_obj_6cloess_loess_kd_tree *)__pyx_v_self)->parameter = ((PyArrayObject *)__pyx_1);
+  Py_DECREF(((PyObject *)__pyx_v_d_ndr));
+  __pyx_v_d_ndr = ((PyArrayObject *)__pyx_1);
   Py_DECREF(__pyx_1); __pyx_1 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":161 */
-  __pyx_4 = __Pyx_GetName(__pyx_b, __pyx_n_NPY_LONG); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; goto __pyx_L1;}
-  __pyx_6 = ((enum NPY_TYPES )PyInt_AsLong(__pyx_4)); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; goto __pyx_L1;}
-  Py_DECREF(__pyx_4); __pyx_4 = 0;
-  __pyx_2 = PyArray_EMPTY(1,__pyx_v_nmaxkd,__pyx_6,NPY_ALIGNED); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; goto __pyx_L1;}
-  Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_2)));
-  Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess_kd_tree *)__pyx_v_self)->a));
-  ((struct __pyx_obj_6cloess_loess_kd_tree *)__pyx_v_self)->a = ((PyArrayObject *)__pyx_2);
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":222 */
+  __pyx_v_d_dat = ((long (*))__pyx_v_d_ndr->data);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":162 */
-  __pyx_3 = PyArray_EMPTY(1,__pyx_v_nmaxkd,NPY_DOUBLE,NPY_ALIGNED); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; goto __pyx_L1;}
-  Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_3)));
-  Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess_kd_tree *)__pyx_v_self)->xi));
-  ((struct __pyx_obj_6cloess_loess_kd_tree *)__pyx_v_self)->xi = ((PyArrayObject *)__pyx_3);
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":223 */
+  __pyx_1 = PyInt_FromLong(0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
+  __pyx_3 = PyInt_FromLong(__pyx_v_i); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_1, __pyx_3, &__pyx_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
+  __pyx_8 = __pyx_8 <= 0;
+  if (__pyx_8) {
+    __pyx_4 = __Pyx_GetName(__pyx_b, __pyx_n_max); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
+    __pyx_5 = PyInt_FromLong(8); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
+    __pyx_6 = PyObject_GetAttr(((PyObject *)__pyx_v_d_ndr), __pyx_n_size); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
+    __pyx_7 = PyTuple_New(2); if (!__pyx_7) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
+    PyTuple_SET_ITEM(__pyx_7, 0, __pyx_5);
+    PyTuple_SET_ITEM(__pyx_7, 1, __pyx_6);
+    __pyx_5 = 0;
+    __pyx_6 = 0;
+    __pyx_5 = PyObject_CallObject(__pyx_4, __pyx_7); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    Py_DECREF(__pyx_7); __pyx_7 = 0;
+    if (PyObject_Cmp(__pyx_3, __pyx_5, &__pyx_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
+    __pyx_8 = __pyx_8 < 0;
+    Py_DECREF(__pyx_5); __pyx_5 = 0;
+  }
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
   Py_DECREF(__pyx_3); __pyx_3 = 0;
+  __pyx_6 = PyInt_FromLong(__pyx_8); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
+  __pyx_4 = PyObject_GetIter(__pyx_6); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
+  Py_DECREF(__pyx_6); __pyx_6 = 0;
+  for (;;) {
+    __pyx_7 = PyIter_Next(__pyx_4);
+    if (!__pyx_7) {
+      if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
+      break;
+    }
+    __pyx_8 = PyInt_AsLong(__pyx_7); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
+    Py_DECREF(__pyx_7); __pyx_7 = 0;
+    __pyx_v_i = __pyx_8;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":163 */
-  __pyx_1 = PyArray_EMPTY(1,__pyx_v_nnvert,NPY_DOUBLE,NPY_ALIGNED); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; goto __pyx_L1;}
-  Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_1)));
-  Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess_kd_tree *)__pyx_v_self)->vert));
-  ((struct __pyx_obj_6cloess_loess_kd_tree *)__pyx_v_self)->vert = ((PyArrayObject *)__pyx_1);
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":164 */
-  __pyx_4 = PyArray_EMPTY(1,__pyx_v_nnval,NPY_DOUBLE,NPY_ALIGNED); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; goto __pyx_L1;}
-  Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_4)));
-  Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess_kd_tree *)__pyx_v_self)->vval));
-  ((struct __pyx_obj_6cloess_loess_kd_tree *)__pyx_v_self)->vval = ((PyArrayObject *)__pyx_4);
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":224 */
+    (((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->drop_square[__pyx_v_i]) = (__pyx_v_d_dat[__pyx_v_i]);
+  }
   Py_DECREF(__pyx_4); __pyx_4 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":171 */
-  if (__Pyx_PrintItem(__pyx_k31p) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; goto __pyx_L1;}
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":172 */
-  ((struct __pyx_obj_6cloess_loess_kd_tree *)__pyx_v_self)->_kdtree.parameter = ((long (*))((struct __pyx_obj_6cloess_loess_kd_tree *)__pyx_v_self)->parameter->data);
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":173 */
-  ((struct __pyx_obj_6cloess_loess_kd_tree *)__pyx_v_self)->_kdtree.a = ((long (*))((struct __pyx_obj_6cloess_loess_kd_tree *)__pyx_v_self)->a->data);
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":174 */
-  ((struct __pyx_obj_6cloess_loess_kd_tree *)__pyx_v_self)->_kdtree.xi = ((double (*))((struct __pyx_obj_6cloess_loess_kd_tree *)__pyx_v_self)->xi->data);
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":175 */
-  ((struct __pyx_obj_6cloess_loess_kd_tree *)__pyx_v_self)->_kdtree.vert = ((double (*))((struct __pyx_obj_6cloess_loess_kd_tree *)__pyx_v_self)->vert->data);
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":176 */
-  ((struct __pyx_obj_6cloess_loess_kd_tree *)__pyx_v_self)->_kdtree.vval = ((double (*))((struct __pyx_obj_6cloess_loess_kd_tree *)__pyx_v_self)->vval->data);
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":187 */
-  if (__Pyx_PrintItem(__pyx_k32p) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; goto __pyx_L1;}
-  if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; goto __pyx_L1;}
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":188 */
   __pyx_r = 0;
   goto __pyx_L0;
-
-  __pyx_r = 0;
-  goto __pyx_L0;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);
-  Py_XDECREF(__pyx_2);
   Py_XDECREF(__pyx_3);
   Py_XDECREF(__pyx_4);
-  __Pyx_AddTraceback("cloess.loess_kd_tree.__init__");
+  Py_XDECREF(__pyx_5);
+  Py_XDECREF(__pyx_6);
+  Py_XDECREF(__pyx_7);
+  __Pyx_AddTraceback("cloess.loess_model.drop_square_flags.__set__");
   __pyx_r = -1;
   __pyx_L0:;
+  Py_DECREF(__pyx_v_d_ndr);
   Py_DECREF(__pyx_v_self);
+  Py_DECREF(__pyx_v_drop_sq);
   return __pyx_r;
 }
 
-static PyObject *__pyx_n_hasattr;
-static PyObject *__pyx_n___len__;
+static PyObject *__pyx_n_family;
+static PyObject *__pyx_n_span;
+static PyObject *__pyx_n_degree;
+static PyObject *__pyx_n_normalize;
+static PyObject *__pyx_n_parametric;
+static PyObject *__pyx_n_drop_square;
+static PyObject *__pyx_n_drop_square_flags;
 
-static PyObject *__pyx_k33p;
-static PyObject *__pyx_k36p;
 
-static char (__pyx_k33[]) = "DEBUG: Initializing loess_model...";
-static char (__pyx_k36[]) = "OK.";
-
-static int __pyx_f_6cloess_11loess_model___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static int __pyx_f_6cloess_11loess_model___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  double __pyx_v_span;
-  int __pyx_v_degree;
-  int __pyx_v_normalize;
-  PyObject *__pyx_v_parametric_in = 0;
-  PyObject *__pyx_v_drop_square_in = 0;
-  PyObject *__pyx_v_family = 0;
-  int __pyx_v_i;
-  int __pyx_r;
-  char (*__pyx_1);
+static PyObject *__pyx_f_6cloess_11loess_model_update(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_6cloess_11loess_model_update(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_modelargs = 0;
+  PyObject *__pyx_v_family;
+  PyObject *__pyx_v_span;
+  PyObject *__pyx_v_degree;
+  PyObject *__pyx_v_normalize;
+  PyObject *__pyx_v_parametric;
+  PyObject *__pyx_v_drop_square;
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
   PyObject *__pyx_2 = 0;
   PyObject *__pyx_3 = 0;
-  PyObject *__pyx_4 = 0;
-  int __pyx_5;
-  long __pyx_6;
-  long __pyx_7;
-  static char *__pyx_argnames[] = {"span","degree","normalize","parametric_in","drop_square_in","family",0};
-  __pyx_v_span = __pyx_k3;
-  __pyx_v_degree = __pyx_k4;
-  __pyx_v_normalize = __pyx_k5;
-  __pyx_v_parametric_in = __pyx_k6;
-  __pyx_v_drop_square_in = __pyx_k7;
-  __pyx_v_family = __pyx_k9;
-  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "|diiOOO", __pyx_argnames, &__pyx_v_span, &__pyx_v_degree, &__pyx_v_normalize, &__pyx_v_parametric_in, &__pyx_v_drop_square_in, &__pyx_v_family)) return -1;
+  int __pyx_4;
+  static char *__pyx_argnames[] = {0};
+  if (__Pyx_GetStarArgs(&__pyx_args, &__pyx_kwds, __pyx_argnames, 0, 0, &__pyx_v_modelargs) < 0) return 0;
+  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "", __pyx_argnames)) {
+    Py_XDECREF(__pyx_args);
+    Py_XDECREF(__pyx_kwds);
+    Py_XDECREF(__pyx_v_modelargs);
+    return 0;
+  }
   Py_INCREF(__pyx_v_self);
-  Py_INCREF(__pyx_v_parametric_in);
-  Py_INCREF(__pyx_v_drop_square_in);
-  Py_INCREF(__pyx_v_family);
+  __pyx_v_family = Py_None; Py_INCREF(Py_None);
+  __pyx_v_span = Py_None; Py_INCREF(Py_None);
+  __pyx_v_degree = Py_None; Py_INCREF(Py_None);
+  __pyx_v_normalize = Py_None; Py_INCREF(Py_None);
+  __pyx_v_parametric = Py_None; Py_INCREF(Py_None);
+  __pyx_v_drop_square = Py_None; Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":208 */
-  if (__Pyx_PrintItem(__pyx_k33p) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":227 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_modelargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; goto __pyx_L1;}
+  Py_INCREF(__pyx_n_family);
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_family);
+  Py_INCREF(Py_None);
+  PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_v_family);
+  __pyx_v_family = __pyx_3;
+  __pyx_3 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":209 */
-  ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->span = __pyx_v_span;
-  ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_model.span = __pyx_v_span;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":228 */
+  __pyx_4 = __pyx_v_family != Py_None;
+  if (__pyx_4) {
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":210 */
-  ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->degree = __pyx_v_degree;
-  ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_model.degree = __pyx_v_degree;
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":229 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_family, __pyx_v_family) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 229; goto __pyx_L1;}
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":211 */
-  ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->normalize = __pyx_v_normalize;
-  ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_model.normalize = __pyx_v_normalize;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":231 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_modelargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; goto __pyx_L1;}
+  Py_INCREF(__pyx_n_span);
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_span);
+  Py_INCREF(Py_None);
+  PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_v_span);
+  __pyx_v_span = __pyx_3;
+  __pyx_3 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":212 */
-  __pyx_1 = PyString_AsString(__pyx_v_family); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; goto __pyx_L1;}
-  ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->family = __pyx_1;
-  __pyx_1 = PyString_AsString(__pyx_v_family); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; goto __pyx_L1;}
-  ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_model.family = __pyx_1;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":232 */
+  __pyx_4 = __pyx_v_span != Py_None;
+  if (__pyx_4) {
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":214 */
-  __pyx_2 = PyList_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":233 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_span, __pyx_v_span) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; goto __pyx_L1;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":235 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_modelargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; goto __pyx_L1;}
+  Py_INCREF(__pyx_n_degree);
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_degree);
   Py_INCREF(Py_None);
-  PyList_SET_ITEM(__pyx_2, 0, Py_None);
-  __pyx_3 = PyInt_FromLong(8); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; goto __pyx_L1;}
-  __pyx_4 = PyNumber_Multiply(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
-  Py_DECREF(__pyx_3); __pyx_3 = 0;
-  Py_DECREF(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->parametric_flags);
-  ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->parametric_flags = __pyx_4;
-  __pyx_4 = 0;
+  Py_DECREF(__pyx_v_degree);
+  __pyx_v_degree = __pyx_3;
+  __pyx_3 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":215 */
-  __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_hasattr); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 215; goto __pyx_L1;}
-  __pyx_3 = PyTuple_New(2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 215; goto __pyx_L1;}
-  Py_INCREF(__pyx_v_parametric_in);
-  PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_parametric_in);
-  Py_INCREF(__pyx_n___len__);
-  PyTuple_SET_ITEM(__pyx_3, 1, __pyx_n___len__);
-  __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 215; goto __pyx_L1;}
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
-  Py_DECREF(__pyx_3); __pyx_3 = 0;
-  __pyx_5 = PyObject_IsTrue(__pyx_4); if (__pyx_5 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 215; goto __pyx_L1;}
-  Py_DECREF(__pyx_4); __pyx_4 = 0;
-  if (__pyx_5) {
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":236 */
+  __pyx_4 = __pyx_v_degree != Py_None;
+  if (__pyx_4) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":216 */
-    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_len); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 216; goto __pyx_L1;}
-    __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 216; goto __pyx_L1;}
-    Py_INCREF(__pyx_v_parametric_in);
-    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_parametric_in);
-    __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 216; goto __pyx_L1;}
-    Py_DECREF(__pyx_2); __pyx_2 = 0;
-    Py_DECREF(__pyx_3); __pyx_3 = 0;
-    __pyx_6 = PyInt_AsLong(__pyx_4); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 216; goto __pyx_L1;}
-    Py_DECREF(__pyx_4); __pyx_4 = 0;
-    for (__pyx_v_i = 0; __pyx_v_i < __pyx_6; ++__pyx_v_i) {
-
-      /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":217 */
-      __pyx_2 = PyInt_FromLong(__pyx_v_i); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; goto __pyx_L1;}
-      __pyx_3 = PyObject_GetItem(__pyx_v_parametric_in, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; goto __pyx_L1;}
-      Py_DECREF(__pyx_2); __pyx_2 = 0;
-      __pyx_4 = PyInt_FromLong(__pyx_v_i); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; goto __pyx_L1;}
-      if (PyObject_SetItem(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->parametric_flags, __pyx_4, __pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; goto __pyx_L1;}
-      Py_DECREF(__pyx_4); __pyx_4 = 0;
-      Py_DECREF(__pyx_3); __pyx_3 = 0;
-
-      /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":218 */
-      __pyx_2 = PyInt_FromLong(__pyx_v_i); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; goto __pyx_L1;}
-      __pyx_3 = PyObject_GetItem(__pyx_v_parametric_in, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; goto __pyx_L1;}
-      Py_DECREF(__pyx_2); __pyx_2 = 0;
-      __pyx_7 = PyInt_AsLong(__pyx_3); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; goto __pyx_L1;}
-      Py_DECREF(__pyx_3); __pyx_3 = 0;
-      (((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_model.parametric[__pyx_v_i]) = __pyx_7;
-    }
-    goto __pyx_L2;
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":237 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_degree, __pyx_v_degree) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; goto __pyx_L1;}
+    goto __pyx_L4;
   }
-  /*else*/ {
+  __pyx_L4:;
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":220 */
-    for (__pyx_v_i = 0; __pyx_v_i <= 7; ++__pyx_v_i) {
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":239 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_modelargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; goto __pyx_L1;}
+  Py_INCREF(__pyx_n_normalize);
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_normalize);
+  Py_INCREF(Py_None);
+  PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_v_normalize);
+  __pyx_v_normalize = __pyx_3;
+  __pyx_3 = 0;
 
-      /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":221 */
-      __pyx_4 = PyInt_FromLong(__pyx_v_i); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 221; goto __pyx_L1;}
-      if (PyObject_SetItem(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->parametric_flags, __pyx_4, __pyx_v_parametric_in) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 221; goto __pyx_L1;}
-      Py_DECREF(__pyx_4); __pyx_4 = 0;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":240 */
+  __pyx_4 = __pyx_v_normalize != Py_None;
+  if (__pyx_4) {
 
-      /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":222 */
-      __pyx_7 = PyInt_AsLong(__pyx_v_parametric_in); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; goto __pyx_L1;}
-      (((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_model.parametric[__pyx_v_i]) = __pyx_7;
-    }
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":241 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_normalize, __pyx_v_normalize) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 241; goto __pyx_L1;}
+    goto __pyx_L5;
   }
-  __pyx_L2:;
+  __pyx_L5:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":224 */
-  __pyx_2 = PyList_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 224; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":243 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_modelargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; goto __pyx_L1;}
+  Py_INCREF(__pyx_n_parametric);
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_parametric);
   Py_INCREF(Py_None);
-  PyList_SET_ITEM(__pyx_2, 0, Py_None);
-  __pyx_3 = PyInt_FromLong(8); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 224; goto __pyx_L1;}
-  __pyx_4 = PyNumber_Multiply(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 224; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
-  Py_DECREF(__pyx_3); __pyx_3 = 0;
-  Py_DECREF(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->drop_square_flags);
-  ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->drop_square_flags = __pyx_4;
-  __pyx_4 = 0;
+  Py_DECREF(__pyx_v_parametric);
+  __pyx_v_parametric = __pyx_3;
+  __pyx_3 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":225 */
-  __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_hasattr); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; goto __pyx_L1;}
-  __pyx_3 = PyTuple_New(2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; goto __pyx_L1;}
-  Py_INCREF(__pyx_v_drop_square_in);
-  PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_drop_square_in);
-  Py_INCREF(__pyx_n___len__);
-  PyTuple_SET_ITEM(__pyx_3, 1, __pyx_n___len__);
-  __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; goto __pyx_L1;}
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
-  Py_DECREF(__pyx_3); __pyx_3 = 0;
-  __pyx_5 = PyObject_IsTrue(__pyx_4); if (__pyx_5 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; goto __pyx_L1;}
-  Py_DECREF(__pyx_4); __pyx_4 = 0;
-  if (__pyx_5) {
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":244 */
+  __pyx_4 = __pyx_v_parametric != Py_None;
+  if (__pyx_4) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":226 */
-    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_len); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; goto __pyx_L1;}
-    __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; goto __pyx_L1;}
-    Py_INCREF(__pyx_v_drop_square_in);
-    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_drop_square_in);
-    __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; goto __pyx_L1;}
-    Py_DECREF(__pyx_2); __pyx_2 = 0;
-    Py_DECREF(__pyx_3); __pyx_3 = 0;
-    __pyx_6 = PyInt_AsLong(__pyx_4); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; goto __pyx_L1;}
-    Py_DECREF(__pyx_4); __pyx_4 = 0;
-    for (__pyx_v_i = 0; __pyx_v_i < __pyx_6; ++__pyx_v_i) {
-
-      /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":227 */
-      __pyx_2 = PyInt_FromLong(__pyx_v_i); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; goto __pyx_L1;}
-      __pyx_3 = PyObject_GetItem(__pyx_v_drop_square_in, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; goto __pyx_L1;}
-      Py_DECREF(__pyx_2); __pyx_2 = 0;
-      __pyx_4 = PyInt_FromLong(__pyx_v_i); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; goto __pyx_L1;}
-      if (PyObject_SetItem(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->drop_square_flags, __pyx_4, __pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; goto __pyx_L1;}
-      Py_DECREF(__pyx_4); __pyx_4 = 0;
-      Py_DECREF(__pyx_3); __pyx_3 = 0;
-
-      /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":228 */
-      __pyx_2 = PyInt_FromLong(__pyx_v_i); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 228; goto __pyx_L1;}
-      __pyx_3 = PyObject_GetItem(__pyx_v_drop_square_in, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 228; goto __pyx_L1;}
-      Py_DECREF(__pyx_2); __pyx_2 = 0;
-      __pyx_7 = PyInt_AsLong(__pyx_3); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 228; goto __pyx_L1;}
-      Py_DECREF(__pyx_3); __pyx_3 = 0;
-      (((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_model.drop_square[__pyx_v_i]) = __pyx_7;
-    }
-    goto __pyx_L7;
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":245 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_parametric_flags, __pyx_v_parametric) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 245; goto __pyx_L1;}
+    goto __pyx_L6;
   }
-  /*else*/ {
+  __pyx_L6:;
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":230 */
-    for (__pyx_v_i = 0; __pyx_v_i < 8; ++__pyx_v_i) {
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":247 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_modelargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 247; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 247; goto __pyx_L1;}
+  Py_INCREF(__pyx_n_drop_square);
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_drop_square);
+  Py_INCREF(Py_None);
+  PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 247; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_v_drop_square);
+  __pyx_v_drop_square = __pyx_3;
+  __pyx_3 = 0;
 
-      /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":231 */
-      __pyx_4 = PyInt_FromLong(__pyx_v_i); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; goto __pyx_L1;}
-      if (PyObject_SetItem(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->drop_square_flags, __pyx_4, __pyx_v_drop_square_in) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; goto __pyx_L1;}
-      Py_DECREF(__pyx_4); __pyx_4 = 0;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":248 */
+  __pyx_4 = __pyx_v_drop_square != Py_None;
+  if (__pyx_4) {
 
-      /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":232 */
-      __pyx_7 = PyInt_AsLong(__pyx_v_drop_square_in); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 232; goto __pyx_L1;}
-      (((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_model.drop_square[__pyx_v_i]) = __pyx_7;
-    }
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":249 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_drop_square_flags, __pyx_v_drop_square) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 249; goto __pyx_L1;}
+    goto __pyx_L7;
   }
   __pyx_L7:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":233 */
-  if (__Pyx_PrintItem(__pyx_k36p) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; goto __pyx_L1;}
-  if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; goto __pyx_L1;}
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":246 */
-  __pyx_r = 0;
+  __pyx_r = Py_None; Py_INCREF(Py_None);
   goto __pyx_L0;
-
-  __pyx_r = 0;
-  goto __pyx_L0;
   __pyx_L1:;
+  Py_XDECREF(__pyx_1);
   Py_XDECREF(__pyx_2);
   Py_XDECREF(__pyx_3);
-  Py_XDECREF(__pyx_4);
-  __Pyx_AddTraceback("cloess.loess_model.__init__");
-  __pyx_r = -1;
+  __Pyx_AddTraceback("cloess.loess_model.update");
+  __pyx_r = 0;
   __pyx_L0:;
+  Py_XDECREF(__pyx_v_modelargs);
+  Py_DECREF(__pyx_v_family);
+  Py_DECREF(__pyx_v_span);
+  Py_DECREF(__pyx_v_degree);
+  Py_DECREF(__pyx_v_normalize);
+  Py_DECREF(__pyx_v_parametric);
+  Py_DECREF(__pyx_v_drop_square);
   Py_DECREF(__pyx_v_self);
-  Py_DECREF(__pyx_v_parametric_in);
-  Py_DECREF(__pyx_v_drop_square_in);
-  Py_DECREF(__pyx_v_family);
+  Py_XDECREF(__pyx_args);
+  Py_XDECREF(__pyx_kwds);
   return __pyx_r;
 }
 
 static PyObject *__pyx_n_id;
 
-static PyObject *__pyx_k37p;
+static PyObject *__pyx_k31p;
 
-static char (__pyx_k37[]) = "loess model parameters @%s";
+static char (__pyx_k31[]) = "loess model parameters @%s";
 
 static PyObject *__pyx_f_6cloess_11loess_model___repr__(PyObject *__pyx_v_self); /*proto*/
 static PyObject *__pyx_f_6cloess_11loess_model___repr__(PyObject *__pyx_v_self) {
@@ -1052,15 +1706,15 @@
   PyObject *__pyx_3 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":249 */
-  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_id); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 249; goto __pyx_L1;}
-  __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 249; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":252 */
+  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_id); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; goto __pyx_L1;}
   Py_INCREF(__pyx_v_self);
   PyTuple_SET_ITEM(__pyx_2, 0, __pyx_v_self);
-  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 249; goto __pyx_L1;}
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
-  __pyx_1 = PyNumber_Remainder(__pyx_k37p, __pyx_3); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 249; goto __pyx_L1;}
+  __pyx_1 = PyNumber_Remainder(__pyx_k31p, __pyx_3); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; goto __pyx_L1;}
   Py_DECREF(__pyx_3); __pyx_3 = 0;
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
@@ -1079,27 +1733,23 @@
   return __pyx_r;
 }
 
-static PyObject *__pyx_n___name__;
-static PyObject *__pyx_n_parametric;
-static PyObject *__pyx_n_drop_square;
-
+static PyObject *__pyx_k32p;
+static PyObject *__pyx_k33p;
+static PyObject *__pyx_k34p;
+static PyObject *__pyx_k35p;
+static PyObject *__pyx_k36p;
+static PyObject *__pyx_k37p;
 static PyObject *__pyx_k38p;
 static PyObject *__pyx_k39p;
-static PyObject *__pyx_k40p;
-static PyObject *__pyx_k41p;
-static PyObject *__pyx_k42p;
-static PyObject *__pyx_k43p;
-static PyObject *__pyx_k44p;
-static PyObject *__pyx_k45p;
 
-static char (__pyx_k38[]) = "Object      : %s";
-static char (__pyx_k39[]) = "family      : %s";
-static char (__pyx_k40[]) = "span        : %s";
-static char (__pyx_k41[]) = "degree      : %s";
-static char (__pyx_k42[]) = "normalized  : %s";
-static char (__pyx_k43[]) = "parametric  : %s";
-static char (__pyx_k44[]) = "drop_square : %s";
-static char (__pyx_k45[]) = "\n";
+static char (__pyx_k32[]) = "Model parameters.....";
+static char (__pyx_k33[]) = "family      : %s";
+static char (__pyx_k34[]) = "span        : %s";
+static char (__pyx_k35[]) = "degree      : %s";
+static char (__pyx_k36[]) = "normalized  : %s";
+static char (__pyx_k37[]) = "parametric  : %s";
+static char (__pyx_k38[]) = "drop_square : %s";
+static char (__pyx_k39[]) = "\n";
 
 static PyObject *__pyx_f_6cloess_11loess_model___str__(PyObject *__pyx_v_self); /*proto*/
 static PyObject *__pyx_f_6cloess_11loess_model___str__(PyObject *__pyx_v_self) {
@@ -1112,57 +1762,57 @@
   PyObject *__pyx_5 = 0;
   PyObject *__pyx_6 = 0;
   PyObject *__pyx_7 = 0;
-  PyObject *__pyx_8 = 0;
   Py_INCREF(__pyx_v_self);
   __pyx_v_strg = Py_None; Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":251 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n___name__); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; goto __pyx_L1;}
-  __pyx_2 = PyNumber_Remainder(__pyx_k38p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":255 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_family); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; goto __pyx_L1;}
+  __pyx_2 = PyNumber_Remainder(__pyx_k33p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyString_FromString(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_model.family); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; goto __pyx_L1;}
-  __pyx_3 = PyNumber_Remainder(__pyx_k39p, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; goto __pyx_L1;}
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_span); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; goto __pyx_L1;}
+  __pyx_3 = PyNumber_Remainder(__pyx_k34p, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_model.span); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; goto __pyx_L1;}
-  __pyx_4 = PyNumber_Remainder(__pyx_k40p, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; goto __pyx_L1;}
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_degree); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; goto __pyx_L1;}
+  __pyx_4 = PyNumber_Remainder(__pyx_k35p, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_model.degree); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 254; goto __pyx_L1;}
-  __pyx_5 = PyNumber_Remainder(__pyx_k41p, __pyx_1); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 254; goto __pyx_L1;}
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_normalize); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; goto __pyx_L1;}
+  __pyx_5 = PyNumber_Remainder(__pyx_k36p, __pyx_1); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_model.normalize); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; goto __pyx_L1;}
-  __pyx_6 = PyNumber_Remainder(__pyx_k42p, __pyx_1); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; goto __pyx_L1;}
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_parametric_flags); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; goto __pyx_L1;}
+  __pyx_6 = PySequence_GetSlice(__pyx_1, 0, ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->npar); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_parametric); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; goto __pyx_L1;}
-  __pyx_7 = PyNumber_Remainder(__pyx_k43p, __pyx_1); if (!__pyx_7) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; goto __pyx_L1;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_drop_square); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; goto __pyx_L1;}
-  __pyx_8 = PyNumber_Remainder(__pyx_k44p, __pyx_1); if (!__pyx_8) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; goto __pyx_L1;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyList_New(7); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; goto __pyx_L1;}
-  PyList_SET_ITEM(__pyx_1, 0, __pyx_2);
-  PyList_SET_ITEM(__pyx_1, 1, __pyx_3);
-  PyList_SET_ITEM(__pyx_1, 2, __pyx_4);
-  PyList_SET_ITEM(__pyx_1, 3, __pyx_5);
-  PyList_SET_ITEM(__pyx_1, 4, __pyx_6);
-  PyList_SET_ITEM(__pyx_1, 5, __pyx_7);
-  PyList_SET_ITEM(__pyx_1, 6, __pyx_8);
+  __pyx_1 = PyNumber_Remainder(__pyx_k37p, __pyx_6); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; goto __pyx_L1;}
+  Py_DECREF(__pyx_6); __pyx_6 = 0;
+  __pyx_6 = PyObject_GetAttr(__pyx_v_self, __pyx_n_drop_square_flags); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; goto __pyx_L1;}
+  __pyx_7 = PySequence_GetSlice(__pyx_6, 0, ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->npar); if (!__pyx_7) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; goto __pyx_L1;}
+  Py_DECREF(__pyx_6); __pyx_6 = 0;
+  __pyx_6 = PyNumber_Remainder(__pyx_k38p, __pyx_7); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; goto __pyx_L1;}
+  Py_DECREF(__pyx_7); __pyx_7 = 0;
+  __pyx_7 = PyList_New(7); if (!__pyx_7) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; goto __pyx_L1;}
+  Py_INCREF(__pyx_k32p);
+  PyList_SET_ITEM(__pyx_7, 0, __pyx_k32p);
+  PyList_SET_ITEM(__pyx_7, 1, __pyx_2);
+  PyList_SET_ITEM(__pyx_7, 2, __pyx_3);
+  PyList_SET_ITEM(__pyx_7, 3, __pyx_4);
+  PyList_SET_ITEM(__pyx_7, 4, __pyx_5);
+  PyList_SET_ITEM(__pyx_7, 5, __pyx_1);
+  PyList_SET_ITEM(__pyx_7, 6, __pyx_6);
   __pyx_2 = 0;
   __pyx_3 = 0;
   __pyx_4 = 0;
   __pyx_5 = 0;
+  __pyx_1 = 0;
   __pyx_6 = 0;
+  Py_DECREF(__pyx_v_strg);
+  __pyx_v_strg = __pyx_7;
   __pyx_7 = 0;
-  __pyx_8 = 0;
-  Py_DECREF(__pyx_v_strg);
-  __pyx_v_strg = __pyx_1;
-  __pyx_1 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":258 */
-  __pyx_2 = PyObject_GetAttr(__pyx_k45p, __pyx_n_join); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; goto __pyx_L1;}
-  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":263 */
+  __pyx_2 = PyObject_GetAttr(__pyx_k39p, __pyx_n_join); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; goto __pyx_L1;}
   Py_INCREF(__pyx_v_strg);
   PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_strg);
-  __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; goto __pyx_L1;}
+  __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; goto __pyx_L1;}
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_3); __pyx_3 = 0;
   __pyx_r = __pyx_4;
@@ -1179,7 +1829,6 @@
   Py_XDECREF(__pyx_5);
   Py_XDECREF(__pyx_6);
   Py_XDECREF(__pyx_7);
-  Py_XDECREF(__pyx_8);
   __Pyx_AddTraceback("cloess.loess_model.__str__");
   __pyx_r = 0;
   __pyx_L0:;
@@ -1188,113 +1837,808 @@
   return __pyx_r;
 }
 
-static PyObject *__pyx_k46p;
+static PyObject *__pyx_f_6cloess_13loess_outputs_13fitted_values___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_13loess_outputs_13fitted_values___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  Py_INCREF(__pyx_v_self);
 
-static char (__pyx_k46[]) = "DEBUG:Initializing loess_cside";
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":274 */
+  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->nobs); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; goto __pyx_L1;}
+  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; goto __pyx_L1;}
+  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->fitted_values); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_r = __pyx_3;
+  __pyx_3 = 0;
+  goto __pyx_L0;
 
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  __Pyx_AddTraceback("cloess.loess_outputs.fitted_values.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6cloess_13loess_outputs_16fitted_residuals___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_13loess_outputs_16fitted_residuals___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":278 */
+  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->nobs); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 278; goto __pyx_L1;}
+  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 278; goto __pyx_L1;}
+  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->fitted_residuals); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 278; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_r = __pyx_3;
+  __pyx_3 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  __Pyx_AddTraceback("cloess.loess_outputs.fitted_residuals.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6cloess_13loess_outputs_12pseudovalues___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_13loess_outputs_12pseudovalues___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":282 */
+  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->nobs); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 282; goto __pyx_L1;}
+  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 282; goto __pyx_L1;}
+  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->pseudovalues); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 282; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_r = __pyx_3;
+  __pyx_3 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  __Pyx_AddTraceback("cloess.loess_outputs.pseudovalues.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6cloess_13loess_outputs_8diagonal___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_13loess_outputs_8diagonal___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":286 */
+  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->nobs); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; goto __pyx_L1;}
+  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; goto __pyx_L1;}
+  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->diagonal); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_r = __pyx_3;
+  __pyx_3 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  __Pyx_AddTraceback("cloess.loess_outputs.diagonal.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6cloess_13loess_outputs_6robust___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_13loess_outputs_6robust___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":290 */
+  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->nobs); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; goto __pyx_L1;}
+  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; goto __pyx_L1;}
+  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->robust); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_r = __pyx_3;
+  __pyx_3 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  __Pyx_AddTraceback("cloess.loess_outputs.robust.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6cloess_13loess_outputs_7divisor___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_13loess_outputs_7divisor___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":294 */
+  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->nobs); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; goto __pyx_L1;}
+  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; goto __pyx_L1;}
+  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->divisor); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_r = __pyx_3;
+  __pyx_3 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  __Pyx_AddTraceback("cloess.loess_outputs.divisor.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6cloess_13loess_outputs_3enp___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_13loess_outputs_3enp___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":299 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->enp); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("cloess.loess_outputs.enp.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6cloess_13loess_outputs_1s___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_13loess_outputs_1s___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":304 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->s); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("cloess.loess_outputs.s.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6cloess_13loess_outputs_9one_delta___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_13loess_outputs_9one_delta___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":309 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->one_delta); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("cloess.loess_outputs.one_delta.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6cloess_13loess_outputs_9two_delta___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_13loess_outputs_9two_delta___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":314 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->two_delta); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 314; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("cloess.loess_outputs.two_delta.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6cloess_13loess_outputs_9trace_hat___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_13loess_outputs_9trace_hat___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":319 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->trace_hat); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 319; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("cloess.loess_outputs.trace_hat.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6cloess_11loess_anova_3dfn___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_11loess_anova_3dfn___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":339 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_anova *)__pyx_v_self)->_base->dfn); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 339; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("cloess.loess_anova.dfn.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6cloess_11loess_anova_3dfd___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_11loess_anova_3dfd___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":343 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_anova *)__pyx_v_self)->_base->dfd); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 343; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("cloess.loess_anova.dfd.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6cloess_11loess_anova_7F_value___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_11loess_anova_7F_value___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":347 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_anova *)__pyx_v_self)->_base->F_value); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 347; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("cloess.loess_anova.F_value.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6cloess_11loess_anova_4Pr_F___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_11loess_anova_4Pr_F___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":351 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_anova *)__pyx_v_self)->_base->Pr_F); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("cloess.loess_anova.Pr_F.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_n_pw_free_mem;
+
+static void __pyx_f_6cloess_19confidence_interval___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_f_6cloess_19confidence_interval___dealloc__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":361 */
+  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_c_loess); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 361; goto __pyx_L1;}
+  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_n_pw_free_mem); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 361; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 361; goto __pyx_L1;}
+  Py_INCREF(__pyx_v_self);
+  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_v_self);
+  __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 361; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  __Pyx_AddTraceback("cloess.confidence_interval.__dealloc__");
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+}
+
+static PyObject *__pyx_n_nest;
+
+static PyObject *__pyx_f_6cloess_19confidence_interval_3fit___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_19confidence_interval_3fit___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":365 */
+  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_nest); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 365; goto __pyx_L1;}
+  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 365; goto __pyx_L1;}
+  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_confidence_interval *)__pyx_v_self)->_base->fit); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 365; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_r = __pyx_3;
+  __pyx_3 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  __Pyx_AddTraceback("cloess.confidence_interval.fit.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6cloess_19confidence_interval_5upper___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_19confidence_interval_5upper___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":369 */
+  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_nest); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 369; goto __pyx_L1;}
+  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 369; goto __pyx_L1;}
+  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_confidence_interval *)__pyx_v_self)->_base->upper); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 369; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_r = __pyx_3;
+  __pyx_3 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  __Pyx_AddTraceback("cloess.confidence_interval.upper.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6cloess_19confidence_interval_5lower___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_19confidence_interval_5lower___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":373 */
+  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_nest); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; goto __pyx_L1;}
+  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; goto __pyx_L1;}
+  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_confidence_interval *)__pyx_v_self)->_base->lower); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_r = __pyx_3;
+  __pyx_3 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  __Pyx_AddTraceback("cloess.confidence_interval.lower.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static void __pyx_f_6cloess_15loess_predicted___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_f_6cloess_15loess_predicted___dealloc__(PyObject *__pyx_v_self) {
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":384 */
+  pred_free_mem(((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->_base);
+
+  Py_DECREF(__pyx_v_self);
+}
+
+static PyObject *__pyx_f_6cloess_15loess_predicted_9predicted___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_15loess_predicted_9predicted___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":388 */
+  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_nest); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; goto __pyx_L1;}
+  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; goto __pyx_L1;}
+  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->_base->fit); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_r = __pyx_3;
+  __pyx_3 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  __Pyx_AddTraceback("cloess.loess_predicted.predicted.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6cloess_15loess_predicted_16predicted_stderr___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_15loess_predicted_16predicted_stderr___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":392 */
+  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_nest); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; goto __pyx_L1;}
+  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; goto __pyx_L1;}
+  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->_base->se_fit); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_r = __pyx_3;
+  __pyx_3 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  __Pyx_AddTraceback("cloess.loess_predicted.predicted_stderr.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_n_residual_scale;
+
+static PyObject *__pyx_f_6cloess_15loess_predicted_14residual_scale___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_15loess_predicted_14residual_scale___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":396 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_residual_scale); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 396; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("cloess.loess_predicted.residual_scale.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_n_df;
+
+static PyObject *__pyx_f_6cloess_15loess_predicted_2df___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_15loess_predicted_2df___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":400 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_df); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 400; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("cloess.loess_predicted.df.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6cloess_15loess_predicted_confidence(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_6cloess_15loess_predicted_confidence[] = "\n    coverage : float\n        Confidence level of the confidence intervals limits as a fraction.\n        ";
+static PyObject *__pyx_f_6cloess_15loess_predicted_confidence(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_coverage = 0;
+  PyObject *__pyx_r;
+  double __pyx_1;
+  static char *__pyx_argnames[] = {"coverage",0};
+  __pyx_v_coverage = __pyx_k7;
+  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "|O", __pyx_argnames, &__pyx_v_coverage)) return 0;
+  Py_INCREF(__pyx_v_self);
+  Py_INCREF(__pyx_v_coverage);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":407 */
+  __pyx_1 = PyFloat_AsDouble(__pyx_v_coverage); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; goto __pyx_L1;}
+  pointwise(((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->_base,((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->nest,__pyx_1,((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->conf_interval->_base);
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  __Pyx_AddTraceback("cloess.loess_predicted.confidence");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  Py_DECREF(__pyx_v_coverage);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_n_len;
+
 static int __pyx_f_6cloess_5loess___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static int __pyx_f_6cloess_5loess___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_x = 0;
   PyObject *__pyx_v_y = 0;
   PyObject *__pyx_v_weights = 0;
-  long __pyx_v_n;
-  long __pyx_v_p;
+  PyArrayObject *__pyx_v_x_ndr;
+  PyArrayObject *__pyx_v_y_ndr;
+  double (*__pyx_v_x_dat);
+  double (*__pyx_v_y_dat);
+  PyObject *__pyx_v_n;
+  PyObject *__pyx_v_p;
   int __pyx_r;
   PyObject *__pyx_1 = 0;
   PyObject *__pyx_2 = 0;
   PyObject *__pyx_3 = 0;
+  long __pyx_4;
+  long __pyx_5;
   static char *__pyx_argnames[] = {"x","y","weights",0};
-  __pyx_v_weights = __pyx_k10;
+  __pyx_v_weights = __pyx_k8;
   if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "OO|O", __pyx_argnames, &__pyx_v_x, &__pyx_v_y, &__pyx_v_weights)) return -1;
   Py_INCREF(__pyx_v_self);
   Py_INCREF(__pyx_v_x);
   Py_INCREF(__pyx_v_y);
   Py_INCREF(__pyx_v_weights);
+  __pyx_v_x_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  __pyx_v_y_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  __pyx_v_n = Py_None; Py_INCREF(Py_None);
+  __pyx_v_p = Py_None; Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":285 */
-  __pyx_1 = PyTuple_New(3); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; goto __pyx_L1;}
-  Py_INCREF(__pyx_v_x);
-  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_v_x);
-  Py_INCREF(__pyx_v_y);
-  PyTuple_SET_ITEM(__pyx_1, 1, __pyx_v_y);
-  Py_INCREF(__pyx_v_weights);
-  PyTuple_SET_ITEM(__pyx_1, 2, __pyx_v_weights);
-  __pyx_2 = PyObject_CallObject(((PyObject*)__pyx_ptype_6cloess_loess_inputs), __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":429 */
+  __pyx_1 = PyArray_FROMANY(__pyx_v_x,NPY_DOUBLE,1,1,NPY_FORTRAN); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; goto __pyx_L1;}
+  Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_1)));
+  Py_DECREF(((PyObject *)__pyx_v_x_ndr));
+  __pyx_v_x_ndr = ((PyArrayObject *)__pyx_1);
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  if (!__Pyx_TypeTest(__pyx_2, __pyx_ptype_6cloess_loess_inputs)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; goto __pyx_L1;}
-  Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->inputs));
-  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->inputs = ((struct __pyx_obj_6cloess_loess_inputs *)__pyx_2);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":430 */
+  __pyx_1 = PyArray_FROMANY(__pyx_v_y,NPY_DOUBLE,1,1,NPY_FORTRAN); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 430; goto __pyx_L1;}
+  Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_1)));
+  Py_DECREF(((PyObject *)__pyx_v_y_ndr));
+  __pyx_v_y_ndr = ((PyArrayObject *)__pyx_1);
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":431 */
+  __pyx_v_x_dat = ((double (*))__pyx_v_x_ndr->data);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":432 */
+  __pyx_v_y_dat = ((double (*))__pyx_v_y_ndr->data);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":433 */
+  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_len); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; goto __pyx_L1;}
+  Py_INCREF(((PyObject *)__pyx_v_x_ndr));
+  PyTuple_SET_ITEM(__pyx_2, 0, ((PyObject *)__pyx_v_x_ndr));
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_v_n);
+  __pyx_v_n = __pyx_3;
+  __pyx_3 = 0;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":434 */
+  __pyx_1 = PyObject_GetAttr(((PyObject *)__pyx_v_x_ndr), __pyx_n_size); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 434; goto __pyx_L1;}
+  __pyx_2 = PyNumber_Divide(__pyx_1, __pyx_v_n); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 434; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_v_p);
+  __pyx_v_p = __pyx_2;
   __pyx_2 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":286 */
-  __pyx_v_n = ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->inputs->nobs;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":435 */
+  __pyx_4 = PyInt_AsLong(__pyx_v_n); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; goto __pyx_L1;}
+  __pyx_5 = PyInt_AsLong(__pyx_v_p); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; goto __pyx_L1;}
+  loess_setup(__pyx_v_x_dat,__pyx_v_y_dat,__pyx_4,__pyx_5,(&((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base));
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":287 */
-  __pyx_v_p = ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->inputs->nvar;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":437 */
+  __pyx_3 = PyObject_CallObject(((PyObject*)__pyx_ptype_6cloess_loess_inputs), 0); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_3, __pyx_ptype_6cloess_loess_inputs)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->inputs));
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->inputs = ((struct __pyx_obj_6cloess_loess_inputs *)__pyx_3);
+  __pyx_3 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":288 */
-  __pyx_1 = PyObject_CallObject(((PyObject*)__pyx_ptype_6cloess_loess_model), 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; goto __pyx_L1;}
-  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_6cloess_loess_model)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":438 */
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->inputs->_base = (&((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base.inputs);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":440 */
+  __pyx_1 = PyObject_CallObject(((PyObject*)__pyx_ptype_6cloess_loess_model), 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 440; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_6cloess_loess_model)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 440; goto __pyx_L1;}
   Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->model));
   ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->model = ((struct __pyx_obj_6cloess_loess_model *)__pyx_1);
   __pyx_1 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":289 */
-  __pyx_2 = PyObject_CallObject(((PyObject*)__pyx_ptype_6cloess_loess_control), 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; goto __pyx_L1;}
-  if (!__Pyx_TypeTest(__pyx_2, __pyx_ptype_6cloess_loess_control)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":441 */
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->model->_base = (&((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base.model);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":442 */
+  __pyx_4 = PyInt_AsLong(__pyx_v_p); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 442; goto __pyx_L1;}
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->model->npar = __pyx_4;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":444 */
+  __pyx_2 = PyObject_CallObject(((PyObject*)__pyx_ptype_6cloess_loess_control), 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_2, __pyx_ptype_6cloess_loess_control)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; goto __pyx_L1;}
   Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->control));
   ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->control = ((struct __pyx_obj_6cloess_loess_control *)__pyx_2);
   __pyx_2 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":290 */
-  __pyx_1 = PyInt_FromLong(__pyx_v_n); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; goto __pyx_L1;}
-  __pyx_2 = PyInt_FromLong(__pyx_v_p); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; goto __pyx_L1;}
-  __pyx_3 = PyTuple_New(2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; goto __pyx_L1;}
-  PyTuple_SET_ITEM(__pyx_3, 0, __pyx_1);
-  PyTuple_SET_ITEM(__pyx_3, 1, __pyx_2);
-  __pyx_1 = 0;
-  __pyx_2 = 0;
-  __pyx_1 = PyObject_CallObject(((PyObject*)__pyx_ptype_6cloess_loess_outputs), __pyx_3); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; goto __pyx_L1;}
-  Py_DECREF(__pyx_3); __pyx_3 = 0;
-  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_6cloess_loess_outputs)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; goto __pyx_L1;}
-  Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs));
-  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs = ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_1);
-  __pyx_1 = 0;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":445 */
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->control->_base = (&((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base.control);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":291 */
-  __pyx_2 = PyInt_FromLong(__pyx_v_n); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 291; goto __pyx_L1;}
-  __pyx_3 = PyInt_FromLong(__pyx_v_p); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 291; goto __pyx_L1;}
-  __pyx_1 = PyTuple_New(2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 291; goto __pyx_L1;}
-  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_2);
-  PyTuple_SET_ITEM(__pyx_1, 1, __pyx_3);
-  __pyx_2 = 0;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":447 */
+  __pyx_3 = PyObject_CallObject(((PyObject*)__pyx_ptype_6cloess_loess_kd_tree), 0); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_3, __pyx_ptype_6cloess_loess_kd_tree)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->kd_tree));
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->kd_tree = ((struct __pyx_obj_6cloess_loess_kd_tree *)__pyx_3);
   __pyx_3 = 0;
-  __pyx_2 = PyObject_CallObject(((PyObject*)__pyx_ptype_6cloess_loess_kd_tree), __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 291; goto __pyx_L1;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  if (!__Pyx_TypeTest(__pyx_2, __pyx_ptype_6cloess_loess_kd_tree)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 291; goto __pyx_L1;}
-  Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->kd_tree));
-  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->kd_tree = ((struct __pyx_obj_6cloess_loess_kd_tree *)__pyx_2);
-  __pyx_2 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":293 */
-  if (__Pyx_PrintItem(__pyx_k46p) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; goto __pyx_L1;}
-  if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":448 */
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->kd_tree->_base = (&((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base.kd_tree);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":294 */
-  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base.inputs = ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->inputs->_inputs;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":450 */
+  __pyx_1 = PyObject_CallObject(((PyObject*)__pyx_ptype_6cloess_loess_outputs), 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 450; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_6cloess_loess_outputs)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 450; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs));
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs = ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_1);
+  __pyx_1 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":295 */
-  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base.model = ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->model->_model;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":451 */
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs->_base = (&((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base.outputs);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":296 */
-  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base.control = ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->control->_control;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":452 */
+  __pyx_5 = PyInt_AsLong(__pyx_v_n); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; goto __pyx_L1;}
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs->nobs = __pyx_5;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":297 */
-  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base.kd_tree = ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->kd_tree->_kdtree;
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":298 */
-  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base.outputs = ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs->_outputs;
-
   __pyx_r = 0;
   goto __pyx_L0;
   __pyx_L1:;
@@ -1304,6 +2648,10 @@
   __Pyx_AddTraceback("cloess.loess.__init__");
   __pyx_r = -1;
   __pyx_L0:;
+  Py_DECREF(__pyx_v_x_ndr);
+  Py_DECREF(__pyx_v_y_ndr);
+  Py_DECREF(__pyx_v_n);
+  Py_DECREF(__pyx_v_p);
   Py_DECREF(__pyx_v_self);
   Py_DECREF(__pyx_v_x);
   Py_DECREF(__pyx_v_y);
@@ -1311,19 +2659,41 @@
   return __pyx_r;
 }
 
-static PyObject *__pyx_n_n;
+static PyObject *__pyx_f_6cloess_5loess_fit(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_6cloess_5loess_fit(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_r;
+  static char *__pyx_argnames[] = {0};
+  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "", __pyx_argnames)) return 0;
+  Py_INCREF(__pyx_v_self);
 
-static PyObject *__pyx_k47p;
-static PyObject *__pyx_k48p;
-static PyObject *__pyx_k50p;
-static PyObject *__pyx_k51p;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":455 */
+  loess_fit((&((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base));
 
-static char (__pyx_k47[]) = "Number of Observations         : %d";
-static char (__pyx_k48[]) = "Equivalent Number of Parameters: %.1f";
-static char (__pyx_k49[]) = "gaussian";
-static char (__pyx_k50[]) = "Residual Standard Error        : %.4f";
-static char (__pyx_k51[]) = "Residual Scale Estimate        : %.4f";
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":456 */
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
 
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_n_nobs;
+static PyObject *__pyx_n_enp;
+static PyObject *__pyx_n_gaussian;
+static PyObject *__pyx_n_s;
+
+static PyObject *__pyx_k40p;
+static PyObject *__pyx_k41p;
+static PyObject *__pyx_k43p;
+static PyObject *__pyx_k44p;
+
+static char (__pyx_k40[]) = "Number of Observations         : %d";
+static char (__pyx_k41[]) = "Equivalent Number of Parameters: %.1f";
+static char (__pyx_k43[]) = "Residual Standard Error        : %.4f";
+static char (__pyx_k44[]) = "Residual Scale Estimate        : %.4f";
+
 static PyObject *__pyx_f_6cloess_5loess_summary(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static PyObject *__pyx_f_6cloess_5loess_summary(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_r;
@@ -1334,44 +2704,47 @@
   if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "", __pyx_argnames)) return 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":310 */
-  __pyx_1 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->inputs), __pyx_n_n); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; goto __pyx_L1;}
-  __pyx_2 = PyNumber_Remainder(__pyx_k47p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":459 */
+  __pyx_1 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->inputs), __pyx_n_nobs); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; goto __pyx_L1;}
+  __pyx_2 = PyNumber_Remainder(__pyx_k40p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  if (__Pyx_PrintItem(__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; goto __pyx_L1;}
+  if (__Pyx_PrintItem(__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; goto __pyx_L1;}
   Py_DECREF(__pyx_2); __pyx_2 = 0;
-  if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; goto __pyx_L1;}
+  if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; goto __pyx_L1;}
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":311 */
-  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs->enp); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; goto __pyx_L1;}
-  __pyx_2 = PyNumber_Remainder(__pyx_k48p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":460 */
+  __pyx_1 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs), __pyx_n_enp); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 460; goto __pyx_L1;}
+  __pyx_2 = PyNumber_Remainder(__pyx_k41p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 460; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  if (__Pyx_PrintItem(__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; goto __pyx_L1;}
+  if (__Pyx_PrintItem(__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 460; goto __pyx_L1;}
   Py_DECREF(__pyx_2); __pyx_2 = 0;
-  if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; goto __pyx_L1;}
+  if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 460; goto __pyx_L1;}
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":312 */
-  __pyx_3 = (((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->model->family == __pyx_k49);
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":461 */
+  __pyx_1 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->model), __pyx_n_family); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 461; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_1, __pyx_n_gaussian, &__pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 461; goto __pyx_L1;}
+  __pyx_3 = __pyx_3 == 0;
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
   if (__pyx_3) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":313 */
-    __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs->s); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 313; goto __pyx_L1;}
-    __pyx_2 = PyNumber_Remainder(__pyx_k50p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 313; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":462 */
+    __pyx_2 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs), __pyx_n_s); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; goto __pyx_L1;}
+    __pyx_1 = PyNumber_Remainder(__pyx_k43p, __pyx_2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    if (__Pyx_PrintItem(__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; goto __pyx_L1;}
     Py_DECREF(__pyx_1); __pyx_1 = 0;
-    if (__Pyx_PrintItem(__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 313; goto __pyx_L1;}
-    Py_DECREF(__pyx_2); __pyx_2 = 0;
-    if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 313; goto __pyx_L1;}
+    if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; goto __pyx_L1;}
     goto __pyx_L2;
   }
   /*else*/ {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":315 */
-    __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs->s); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; goto __pyx_L1;}
-    __pyx_2 = PyNumber_Remainder(__pyx_k51p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":464 */
+    __pyx_2 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs), __pyx_n_s); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; goto __pyx_L1;}
+    __pyx_1 = PyNumber_Remainder(__pyx_k44p, __pyx_2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    if (__Pyx_PrintItem(__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; goto __pyx_L1;}
     Py_DECREF(__pyx_1); __pyx_1 = 0;
-    if (__Pyx_PrintItem(__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; goto __pyx_L1;}
-    Py_DECREF(__pyx_2); __pyx_2 = 0;
-    if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; goto __pyx_L1;}
+    if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; goto __pyx_L1;}
   }
   __pyx_L2:;
 
@@ -1387,124 +2760,206 @@
   return __pyx_r;
 }
 
+static PyObject *__pyx_n_nvar;
+
+static PyObject *__pyx_f_6cloess_5loess_predict(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_6cloess_5loess_predict[] = "\n    newdata: ndarray\n        A (m,p) ndarray specifying the values of the predictors at which the \n        evaluation is to be carried out.\n    stderr: Boolean\n        Logical flag for computing standard errors at newdata.\n        ";
+static PyObject *__pyx_f_6cloess_5loess_predict(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_newdata = 0;
+  PyObject *__pyx_v_stderr = 0;
+  PyArrayObject *__pyx_v_p_ndr;
+  double (*__pyx_v_p_dat);
+  int __pyx_v_m;
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  int __pyx_2;
+  PyObject *__pyx_3 = 0;
+  PyObject *__pyx_4 = 0;
+  static char *__pyx_argnames[] = {"newdata","stderr",0};
+  __pyx_v_stderr = __pyx_k9;
+  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "O|O", __pyx_argnames, &__pyx_v_newdata, &__pyx_v_stderr)) return 0;
+  Py_INCREF(__pyx_v_self);
+  Py_INCREF(__pyx_v_newdata);
+  Py_INCREF(__pyx_v_stderr);
+  __pyx_v_p_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":478 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_nvar); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; goto __pyx_L1;}
+  __pyx_2 = PyInt_AsLong(__pyx_1); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = PyArray_FROMANY(__pyx_v_newdata,NPY_DOUBLE,1,__pyx_2,NPY_FORTRAN); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; goto __pyx_L1;}
+  Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_1)));
+  Py_DECREF(((PyObject *)__pyx_v_p_ndr));
+  __pyx_v_p_ndr = ((PyArrayObject *)__pyx_1);
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":479 */
+  __pyx_v_p_dat = ((double (*))__pyx_v_p_ndr->data);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":480 */
+  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_len); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; goto __pyx_L1;}
+  Py_INCREF(((PyObject *)__pyx_v_p_ndr));
+  PyTuple_SET_ITEM(__pyx_3, 0, ((PyObject *)__pyx_v_p_ndr));
+  __pyx_4 = PyObject_CallObject(__pyx_1, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  __pyx_2 = PyInt_AsLong(__pyx_4); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; goto __pyx_L1;}
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+  __pyx_v_m = __pyx_2;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":481 */
+  __pyx_2 = PyInt_AsLong(__pyx_v_stderr); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 481; goto __pyx_L1;}
+  predict(__pyx_v_p_dat,__pyx_v_m,(&((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base),((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->predicted->_base,__pyx_2);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":482 */
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->predicted->nest = __pyx_v_m;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_3);
+  Py_XDECREF(__pyx_4);
+  __Pyx_AddTraceback("cloess.loess.predict");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_p_ndr);
+  Py_DECREF(__pyx_v_self);
+  Py_DECREF(__pyx_v_newdata);
+  Py_DECREF(__pyx_v_stderr);
+  return __pyx_r;
+}
+
 static __Pyx_InternTabEntry __pyx_intern_tab[] = {
   {&__pyx_n_False, "False"},
   {&__pyx_n_NPY_LONG, "NPY_LONG"},
   {&__pyx_n_ValueError, "ValueError"},
-  {&__pyx_n__N, "_N"},
-  {&__pyx_n___len__, "__len__"},
-  {&__pyx_n___name__, "__name__"},
+  {&__pyx_n_astype, "astype"},
+  {&__pyx_n_bool, "bool"},
   {&__pyx_n_c_loess, "c_loess"},
   {&__pyx_n_c_numpy, "c_numpy"},
   {&__pyx_n_c_python, "c_python"},
+  {&__pyx_n_cell, "cell"},
+  {&__pyx_n_degree, "degree"},
+  {&__pyx_n_df, "df"},
   {&__pyx_n_drop_square, "drop_square"},
+  {&__pyx_n_drop_square_flags, "drop_square_flags"},
+  {&__pyx_n_dtype, "dtype"},
+  {&__pyx_n_empty, "empty"},
+  {&__pyx_n_enp, "enp"},
+  {&__pyx_n_family, "family"},
+  {&__pyx_n_float, "float"},
   {&__pyx_n_gaussian, "gaussian"},
-  {&__pyx_n_hasattr, "hasattr"},
+  {&__pyx_n_get, "get"},
   {&__pyx_n_id, "id"},
+  {&__pyx_n_int, "int"},
+  {&__pyx_n_iterations, "iterations"},
   {&__pyx_n_join, "join"},
   {&__pyx_n_len, "len"},
   {&__pyx_n_max, "max"},
-  {&__pyx_n_n, "n"},
   {&__pyx_n_ndim, "ndim"},
+  {&__pyx_n_nest, "nest"},
+  {&__pyx_n_nobs, "nobs"},
+  {&__pyx_n_normalize, "normalize"},
   {&__pyx_n_numpy, "numpy"},
+  {&__pyx_n_nvar, "nvar"},
   {&__pyx_n_parametric, "parametric"},
-  {&__pyx_n_pesudovalues, "pesudovalues"},
+  {&__pyx_n_parametric_flags, "parametric_flags"},
+  {&__pyx_n_pw_free_mem, "pw_free_mem"},
+  {&__pyx_n_residual_scale, "residual_scale"},
+  {&__pyx_n_s, "s"},
+  {&__pyx_n_shape, "shape"},
   {&__pyx_n_size, "size"},
+  {&__pyx_n_span, "span"},
+  {&__pyx_n_statistics, "statistics"},
+  {&__pyx_n_surface, "surface"},
+  {&__pyx_n_trace_hat, "trace_hat"},
   {0, 0}
 };
 
 static __Pyx_StringTabEntry __pyx_string_tab[] = {
-  {&__pyx_k11p, __pyx_k11, sizeof(__pyx_k11)},
   {&__pyx_k12p, __pyx_k12, sizeof(__pyx_k12)},
-  {&__pyx_k13p, __pyx_k13, sizeof(__pyx_k13)},
-  {&__pyx_k14p, __pyx_k14, sizeof(__pyx_k14)},
-  {&__pyx_k15p, __pyx_k15, sizeof(__pyx_k15)},
+  {&__pyx_k18p, __pyx_k18, sizeof(__pyx_k18)},
   {&__pyx_k19p, __pyx_k19, sizeof(__pyx_k19)},
   {&__pyx_k20p, __pyx_k20, sizeof(__pyx_k20)},
   {&__pyx_k21p, __pyx_k21, sizeof(__pyx_k21)},
   {&__pyx_k22p, __pyx_k22, sizeof(__pyx_k22)},
   {&__pyx_k23p, __pyx_k23, sizeof(__pyx_k23)},
   {&__pyx_k24p, __pyx_k24, sizeof(__pyx_k24)},
-  {&__pyx_k25p, __pyx_k25, sizeof(__pyx_k25)},
-  {&__pyx_k26p, __pyx_k26, sizeof(__pyx_k26)},
-  {&__pyx_k27p, __pyx_k27, sizeof(__pyx_k27)},
-  {&__pyx_k28p, __pyx_k28, sizeof(__pyx_k28)},
-  {&__pyx_k29p, __pyx_k29, sizeof(__pyx_k29)},
-  {&__pyx_k30p, __pyx_k30, sizeof(__pyx_k30)},
   {&__pyx_k31p, __pyx_k31, sizeof(__pyx_k31)},
   {&__pyx_k32p, __pyx_k32, sizeof(__pyx_k32)},
   {&__pyx_k33p, __pyx_k33, sizeof(__pyx_k33)},
+  {&__pyx_k34p, __pyx_k34, sizeof(__pyx_k34)},
+  {&__pyx_k35p, __pyx_k35, sizeof(__pyx_k35)},
   {&__pyx_k36p, __pyx_k36, sizeof(__pyx_k36)},
   {&__pyx_k37p, __pyx_k37, sizeof(__pyx_k37)},
   {&__pyx_k38p, __pyx_k38, sizeof(__pyx_k38)},
   {&__pyx_k39p, __pyx_k39, sizeof(__pyx_k39)},
   {&__pyx_k40p, __pyx_k40, sizeof(__pyx_k40)},
   {&__pyx_k41p, __pyx_k41, sizeof(__pyx_k41)},
-  {&__pyx_k42p, __pyx_k42, sizeof(__pyx_k42)},
   {&__pyx_k43p, __pyx_k43, sizeof(__pyx_k43)},
   {&__pyx_k44p, __pyx_k44, sizeof(__pyx_k44)},
-  {&__pyx_k45p, __pyx_k45, sizeof(__pyx_k45)},
-  {&__pyx_k46p, __pyx_k46, sizeof(__pyx_k46)},
-  {&__pyx_k47p, __pyx_k47, sizeof(__pyx_k47)},
-  {&__pyx_k48p, __pyx_k48, sizeof(__pyx_k48)},
-  {&__pyx_k50p, __pyx_k50, sizeof(__pyx_k50)},
-  {&__pyx_k51p, __pyx_k51, sizeof(__pyx_k51)},
   {0, 0, 0}
 };
 
 static PyObject *__pyx_tp_new_6cloess_loess_inputs(PyTypeObject *t, PyObject *a, PyObject *k) {
   PyObject *o = (*t->tp_alloc)(t, 0);
-  struct __pyx_obj_6cloess_loess_inputs *p = (struct __pyx_obj_6cloess_loess_inputs *)o;
-  p->x = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  p->y = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  p->weights = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
   return o;
 }
 
 static void __pyx_tp_dealloc_6cloess_loess_inputs(PyObject *o) {
-  struct __pyx_obj_6cloess_loess_inputs *p = (struct __pyx_obj_6cloess_loess_inputs *)o;
-  Py_XDECREF(((PyObject *)p->x));
-  Py_XDECREF(((PyObject *)p->y));
-  Py_XDECREF(((PyObject *)p->weights));
   (*o->ob_type->tp_free)(o);
 }
 
 static int __pyx_tp_traverse_6cloess_loess_inputs(PyObject *o, visitproc v, void *a) {
-  int e;
-  struct __pyx_obj_6cloess_loess_inputs *p = (struct __pyx_obj_6cloess_loess_inputs *)o;
-  if (p->x) {
-    e = (*v)(((PyObject*)p->x), a); if (e) return e;
-  }
-  if (p->y) {
-    e = (*v)(((PyObject*)p->y), a); if (e) return e;
-  }
-  if (p->weights) {
-    e = (*v)(((PyObject*)p->weights), a); if (e) return e;
-  }
   return 0;
 }
 
 static int __pyx_tp_clear_6cloess_loess_inputs(PyObject *o) {
-  struct __pyx_obj_6cloess_loess_inputs *p = (struct __pyx_obj_6cloess_loess_inputs *)o;
-  Py_XDECREF(((PyObject *)p->x));
-  p->x = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  Py_XDECREF(((PyObject *)p->y));
-  p->y = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  Py_XDECREF(((PyObject *)p->weights));
-  p->weights = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
   return 0;
 }
 
+static PyObject *__pyx_getprop_6cloess_12loess_inputs_x(PyObject *o, void *x) {
+  return __pyx_f_6cloess_12loess_inputs_1x___get__(o);
+}
+
+static PyObject *__pyx_getprop_6cloess_12loess_inputs_y(PyObject *o, void *x) {
+  return __pyx_f_6cloess_12loess_inputs_1y___get__(o);
+}
+
+static PyObject *__pyx_getprop_6cloess_12loess_inputs_weights(PyObject *o, void *x) {
+  return __pyx_f_6cloess_12loess_inputs_7weights___get__(o);
+}
+
+static int __pyx_setprop_6cloess_12loess_inputs_weights(PyObject *o, PyObject *v, void *x) {
+  if (v) {
+    return __pyx_f_6cloess_12loess_inputs_7weights___set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_6cloess_12loess_inputs_nobs(PyObject *o, void *x) {
+  return __pyx_f_6cloess_12loess_inputs_4nobs___get__(o);
+}
+
+static PyObject *__pyx_getprop_6cloess_12loess_inputs_nvar(PyObject *o, void *x) {
+  return __pyx_f_6cloess_12loess_inputs_4nvar___get__(o);
+}
+
 static struct PyMethodDef __pyx_methods_6cloess_loess_inputs[] = {
   {0, 0, 0, 0}
 };
 
-static struct PyMemberDef __pyx_members_6cloess_loess_inputs[] = {
-  {"nobs", T_LONG, offsetof(struct __pyx_obj_6cloess_loess_inputs, nobs), 0, 0},
-  {"nvar", T_LONG, offsetof(struct __pyx_obj_6cloess_loess_inputs, nvar), 0, 0},
-  {"x", T_OBJECT, offsetof(struct __pyx_obj_6cloess_loess_inputs, x), READONLY, 0},
-  {"y", T_OBJECT, offsetof(struct __pyx_obj_6cloess_loess_inputs, y), READONLY, 0},
-  {"weights", T_OBJECT, offsetof(struct __pyx_obj_6cloess_loess_inputs, weights), READONLY, 0},
+static struct PyGetSetDef __pyx_getsets_6cloess_loess_inputs[] = {
+  {"x", __pyx_getprop_6cloess_12loess_inputs_x, 0, 0, 0},
+  {"y", __pyx_getprop_6cloess_12loess_inputs_y, 0, 0, 0},
+  {"weights", __pyx_getprop_6cloess_12loess_inputs_weights, __pyx_setprop_6cloess_12loess_inputs_weights, __pyx_k1, 0},
+  {"nobs", __pyx_getprop_6cloess_12loess_inputs_nobs, 0, __pyx_k2, 0},
+  {"nvar", __pyx_getprop_6cloess_12loess_inputs_nvar, 0, __pyx_k3, 0},
   {0, 0, 0, 0, 0}
 };
 
@@ -1605,14 +3060,14 @@
   0, /*tp_iter*/
   0, /*tp_iternext*/
   __pyx_methods_6cloess_loess_inputs, /*tp_methods*/
-  __pyx_members_6cloess_loess_inputs, /*tp_members*/
-  0, /*tp_getset*/
+  0, /*tp_members*/
+  __pyx_getsets_6cloess_loess_inputs, /*tp_getset*/
   0, /*tp_base*/
   0, /*tp_dict*/
   0, /*tp_descr_get*/
   0, /*tp_descr_set*/
   0, /*tp_dictoffset*/
-  __pyx_f_6cloess_12loess_inputs___init__, /*tp_init*/
+  0, /*tp_init*/
   0, /*tp_alloc*/
   __pyx_tp_new_6cloess_loess_inputs, /*tp_new*/
   0, /*tp_free*/
@@ -1641,16 +3096,87 @@
   return 0;
 }
 
+static PyObject *__pyx_getprop_6cloess_13loess_control_surface(PyObject *o, void *x) {
+  return __pyx_f_6cloess_13loess_control_7surface___get__(o);
+}
+
+static int __pyx_setprop_6cloess_13loess_control_surface(PyObject *o, PyObject *v, void *x) {
+  if (v) {
+    return __pyx_f_6cloess_13loess_control_7surface___set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_6cloess_13loess_control_statistics(PyObject *o, void *x) {
+  return __pyx_f_6cloess_13loess_control_10statistics___get__(o);
+}
+
+static int __pyx_setprop_6cloess_13loess_control_statistics(PyObject *o, PyObject *v, void *x) {
+  if (v) {
+    return __pyx_f_6cloess_13loess_control_10statistics___set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_6cloess_13loess_control_trace_hat(PyObject *o, void *x) {
+  return __pyx_f_6cloess_13loess_control_9trace_hat___get__(o);
+}
+
+static int __pyx_setprop_6cloess_13loess_control_trace_hat(PyObject *o, PyObject *v, void *x) {
+  if (v) {
+    return __pyx_f_6cloess_13loess_control_9trace_hat___set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_6cloess_13loess_control_iterations(PyObject *o, void *x) {
+  return __pyx_f_6cloess_13loess_control_10iterations___get__(o);
+}
+
+static int __pyx_setprop_6cloess_13loess_control_iterations(PyObject *o, PyObject *v, void *x) {
+  if (v) {
+    return __pyx_f_6cloess_13loess_control_10iterations___set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_6cloess_13loess_control_cell(PyObject *o, void *x) {
+  return __pyx_f_6cloess_13loess_control_4cell___get__(o);
+}
+
+static int __pyx_setprop_6cloess_13loess_control_cell(PyObject *o, PyObject *v, void *x) {
+  if (v) {
+    return __pyx_f_6cloess_13loess_control_4cell___set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
 static struct PyMethodDef __pyx_methods_6cloess_loess_control[] = {
+  {"update", (PyCFunction)__pyx_f_6cloess_13loess_control_update, METH_VARARGS|METH_KEYWORDS, 0},
   {0, 0, 0, 0}
 };
 
-static struct PyMemberDef __pyx_members_6cloess_loess_control[] = {
-  {"surface", T_STRING, offsetof(struct __pyx_obj_6cloess_loess_control, surface), 0, 0},
-  {"statistics", T_STRING, offsetof(struct __pyx_obj_6cloess_loess_control, statistics), 0, 0},
-  {"trace_hat", T_STRING, offsetof(struct __pyx_obj_6cloess_loess_control, trace_hat), 0, 0},
-  {"cell", T_DOUBLE, offsetof(struct __pyx_obj_6cloess_loess_control, cell), 0, 0},
-  {"iterations", T_INT, offsetof(struct __pyx_obj_6cloess_loess_control, iterations), 0, 0},
+static struct PyGetSetDef __pyx_getsets_6cloess_loess_control[] = {
+  {"surface", __pyx_getprop_6cloess_13loess_control_surface, __pyx_setprop_6cloess_13loess_control_surface, 0, 0},
+  {"statistics", __pyx_getprop_6cloess_13loess_control_statistics, __pyx_setprop_6cloess_13loess_control_statistics, 0, 0},
+  {"trace_hat", __pyx_getprop_6cloess_13loess_control_trace_hat, __pyx_setprop_6cloess_13loess_control_trace_hat, 0, 0},
+  {"iterations", __pyx_getprop_6cloess_13loess_control_iterations, __pyx_setprop_6cloess_13loess_control_iterations, 0, 0},
+  {"cell", __pyx_getprop_6cloess_13loess_control_cell, __pyx_setprop_6cloess_13loess_control_cell, 0, 0},
   {0, 0, 0, 0, 0}
 };
 
@@ -1751,14 +3277,14 @@
   0, /*tp_iter*/
   0, /*tp_iternext*/
   __pyx_methods_6cloess_loess_control, /*tp_methods*/
-  __pyx_members_6cloess_loess_control, /*tp_members*/
-  0, /*tp_getset*/
+  0, /*tp_members*/
+  __pyx_getsets_6cloess_loess_control, /*tp_getset*/
   0, /*tp_base*/
   0, /*tp_dict*/
   0, /*tp_descr_get*/
   0, /*tp_descr_set*/
   0, /*tp_dictoffset*/
-  __pyx_f_6cloess_13loess_control___init__, /*tp_init*/
+  0, /*tp_init*/
   0, /*tp_alloc*/
   __pyx_tp_new_6cloess_loess_control, /*tp_new*/
   0, /*tp_free*/
@@ -1770,74 +3296,435 @@
   0, /*tp_weaklist*/
 };
 
-static PyObject *__pyx_tp_new_6cloess_loess_outputs(PyTypeObject *t, PyObject *a, PyObject *k) {
+static PyObject *__pyx_tp_new_6cloess_loess_kd_tree(PyTypeObject *t, PyObject *a, PyObject *k) {
   PyObject *o = (*t->tp_alloc)(t, 0);
-  struct __pyx_obj_6cloess_loess_outputs *p = (struct __pyx_obj_6cloess_loess_outputs *)o;
-  p->fitted_values = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  p->fitted_residuals = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  p->pseudovalues = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  p->diagonal = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  p->robust = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  p->divisor = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
   return o;
 }
 
-static void __pyx_tp_dealloc_6cloess_loess_outputs(PyObject *o) {
-  struct __pyx_obj_6cloess_loess_outputs *p = (struct __pyx_obj_6cloess_loess_outputs *)o;
-  Py_XDECREF(((PyObject *)p->fitted_values));
-  Py_XDECREF(((PyObject *)p->fitted_residuals));
-  Py_XDECREF(((PyObject *)p->pseudovalues));
-  Py_XDECREF(((PyObject *)p->diagonal));
-  Py_XDECREF(((PyObject *)p->robust));
-  Py_XDECREF(((PyObject *)p->divisor));
+static void __pyx_tp_dealloc_6cloess_loess_kd_tree(PyObject *o) {
   (*o->ob_type->tp_free)(o);
 }
 
-static int __pyx_tp_traverse_6cloess_loess_outputs(PyObject *o, visitproc v, void *a) {
-  int e;
-  struct __pyx_obj_6cloess_loess_outputs *p = (struct __pyx_obj_6cloess_loess_outputs *)o;
-  if (p->fitted_values) {
-    e = (*v)(((PyObject*)p->fitted_values), a); if (e) return e;
+static int __pyx_tp_traverse_6cloess_loess_kd_tree(PyObject *o, visitproc v, void *a) {
+  return 0;
+}
+
+static int __pyx_tp_clear_6cloess_loess_kd_tree(PyObject *o) {
+  return 0;
+}
+
+static struct PyMethodDef __pyx_methods_6cloess_loess_kd_tree[] = {
+  {0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_loess_kd_tree = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  0, /*nb_divide*/
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  0, /*nb_coerce*/
+  0, /*nb_int*/
+  0, /*nb_long*/
+  0, /*nb_float*/
+  0, /*nb_oct*/
+  0, /*nb_hex*/
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  0, /*nb_inplace_divide*/
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_loess_kd_tree = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_loess_kd_tree = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_loess_kd_tree = {
+  0, /*bf_getreadbuffer*/
+  0, /*bf_getwritebuffer*/
+  0, /*bf_getsegcount*/
+  0, /*bf_getcharbuffer*/
+};
+
+PyTypeObject __pyx_type_6cloess_loess_kd_tree = {
+  PyObject_HEAD_INIT(0)
+  0, /*ob_size*/
+  "cloess.loess_kd_tree", /*tp_name*/
+  sizeof(struct __pyx_obj_6cloess_loess_kd_tree), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_6cloess_loess_kd_tree, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  0, /*tp_compare*/
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_loess_kd_tree, /*tp_as_number*/
+  &__pyx_tp_as_sequence_loess_kd_tree, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_loess_kd_tree, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_loess_kd_tree, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_6cloess_loess_kd_tree, /*tp_traverse*/
+  __pyx_tp_clear_6cloess_loess_kd_tree, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_6cloess_loess_kd_tree, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_6cloess_loess_kd_tree, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+};
+
+static PyObject *__pyx_tp_new_6cloess_loess_model(PyTypeObject *t, PyObject *a, PyObject *k) {
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  return o;
+}
+
+static void __pyx_tp_dealloc_6cloess_loess_model(PyObject *o) {
+  (*o->ob_type->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_6cloess_loess_model(PyObject *o, visitproc v, void *a) {
+  return 0;
+}
+
+static int __pyx_tp_clear_6cloess_loess_model(PyObject *o) {
+  return 0;
+}
+
+static PyObject *__pyx_getprop_6cloess_11loess_model_span(PyObject *o, void *x) {
+  return __pyx_f_6cloess_11loess_model_4span___get__(o);
+}
+
+static int __pyx_setprop_6cloess_11loess_model_span(PyObject *o, PyObject *v, void *x) {
+  if (v) {
+    return __pyx_f_6cloess_11loess_model_4span___set__(o, v);
   }
-  if (p->fitted_residuals) {
-    e = (*v)(((PyObject*)p->fitted_residuals), a); if (e) return e;
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
   }
-  if (p->pseudovalues) {
-    e = (*v)(((PyObject*)p->pseudovalues), a); if (e) return e;
+}
+
+static PyObject *__pyx_getprop_6cloess_11loess_model_degree(PyObject *o, void *x) {
+  return __pyx_f_6cloess_11loess_model_6degree___get__(o);
+}
+
+static PyObject *__pyx_getprop_6cloess_11loess_model_normalize(PyObject *o, void *x) {
+  return __pyx_f_6cloess_11loess_model_9normalize___get__(o);
+}
+
+static int __pyx_setprop_6cloess_11loess_model_normalize(PyObject *o, PyObject *v, void *x) {
+  if (v) {
+    return __pyx_f_6cloess_11loess_model_9normalize___set__(o, v);
   }
-  if (p->diagonal) {
-    e = (*v)(((PyObject*)p->diagonal), a); if (e) return e;
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
   }
-  if (p->robust) {
-    e = (*v)(((PyObject*)p->robust), a); if (e) return e;
+}
+
+static PyObject *__pyx_getprop_6cloess_11loess_model_family(PyObject *o, void *x) {
+  return __pyx_f_6cloess_11loess_model_6family___get__(o);
+}
+
+static PyObject *__pyx_getprop_6cloess_11loess_model_parametric_flags(PyObject *o, void *x) {
+  return __pyx_f_6cloess_11loess_model_16parametric_flags___get__(o);
+}
+
+static int __pyx_setprop_6cloess_11loess_model_parametric_flags(PyObject *o, PyObject *v, void *x) {
+  if (v) {
+    return __pyx_f_6cloess_11loess_model_16parametric_flags___set__(o, v);
   }
-  if (p->divisor) {
-    e = (*v)(((PyObject*)p->divisor), a); if (e) return e;
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
   }
+}
+
+static PyObject *__pyx_getprop_6cloess_11loess_model_drop_square_flags(PyObject *o, void *x) {
+  return __pyx_f_6cloess_11loess_model_17drop_square_flags___get__(o);
+}
+
+static int __pyx_setprop_6cloess_11loess_model_drop_square_flags(PyObject *o, PyObject *v, void *x) {
+  if (v) {
+    return __pyx_f_6cloess_11loess_model_17drop_square_flags___set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static struct PyMethodDef __pyx_methods_6cloess_loess_model[] = {
+  {"update", (PyCFunction)__pyx_f_6cloess_11loess_model_update, METH_VARARGS|METH_KEYWORDS, 0},
+  {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_6cloess_loess_model[] = {
+  {"span", __pyx_getprop_6cloess_11loess_model_span, __pyx_setprop_6cloess_11loess_model_span, 0, 0},
+  {"degree", __pyx_getprop_6cloess_11loess_model_degree, 0, 0, 0},
+  {"normalize", __pyx_getprop_6cloess_11loess_model_normalize, __pyx_setprop_6cloess_11loess_model_normalize, __pyx_k4, 0},
+  {"family", __pyx_getprop_6cloess_11loess_model_family, 0, 0, 0},
+  {"parametric_flags", __pyx_getprop_6cloess_11loess_model_parametric_flags, __pyx_setprop_6cloess_11loess_model_parametric_flags, 0, 0},
+  {"drop_square_flags", __pyx_getprop_6cloess_11loess_model_drop_square_flags, __pyx_setprop_6cloess_11loess_model_drop_square_flags, 0, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_loess_model = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  0, /*nb_divide*/
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  0, /*nb_coerce*/
+  0, /*nb_int*/
+  0, /*nb_long*/
+  0, /*nb_float*/
+  0, /*nb_oct*/
+  0, /*nb_hex*/
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  0, /*nb_inplace_divide*/
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_loess_model = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_loess_model = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_loess_model = {
+  0, /*bf_getreadbuffer*/
+  0, /*bf_getwritebuffer*/
+  0, /*bf_getsegcount*/
+  0, /*bf_getcharbuffer*/
+};
+
+PyTypeObject __pyx_type_6cloess_loess_model = {
+  PyObject_HEAD_INIT(0)
+  0, /*ob_size*/
+  "cloess.loess_model", /*tp_name*/
+  sizeof(struct __pyx_obj_6cloess_loess_model), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_6cloess_loess_model, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  0, /*tp_compare*/
+  __pyx_f_6cloess_11loess_model___repr__, /*tp_repr*/
+  &__pyx_tp_as_number_loess_model, /*tp_as_number*/
+  &__pyx_tp_as_sequence_loess_model, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_loess_model, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  __pyx_f_6cloess_11loess_model___str__, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_loess_model, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_6cloess_loess_model, /*tp_traverse*/
+  __pyx_tp_clear_6cloess_loess_model, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_6cloess_loess_model, /*tp_methods*/
+  0, /*tp_members*/
+  __pyx_getsets_6cloess_loess_model, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_6cloess_loess_model, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+};
+
+static PyObject *__pyx_tp_new_6cloess_loess_outputs(PyTypeObject *t, PyObject *a, PyObject *k) {
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  return o;
+}
+
+static void __pyx_tp_dealloc_6cloess_loess_outputs(PyObject *o) {
+  (*o->ob_type->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_6cloess_loess_outputs(PyObject *o, visitproc v, void *a) {
   return 0;
 }
 
 static int __pyx_tp_clear_6cloess_loess_outputs(PyObject *o) {
-  struct __pyx_obj_6cloess_loess_outputs *p = (struct __pyx_obj_6cloess_loess_outputs *)o;
-  Py_XDECREF(((PyObject *)p->fitted_values));
-  p->fitted_values = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  Py_XDECREF(((PyObject *)p->fitted_residuals));
-  p->fitted_residuals = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  Py_XDECREF(((PyObject *)p->pseudovalues));
-  p->pseudovalues = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  Py_XDECREF(((PyObject *)p->diagonal));
-  p->diagonal = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  Py_XDECREF(((PyObject *)p->robust));
-  p->robust = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  Py_XDECREF(((PyObject *)p->divisor));
-  p->divisor = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
   return 0;
 }
 
+static PyObject *__pyx_getprop_6cloess_13loess_outputs_fitted_values(PyObject *o, void *x) {
+  return __pyx_f_6cloess_13loess_outputs_13fitted_values___get__(o);
+}
+
+static PyObject *__pyx_getprop_6cloess_13loess_outputs_fitted_residuals(PyObject *o, void *x) {
+  return __pyx_f_6cloess_13loess_outputs_16fitted_residuals___get__(o);
+}
+
+static PyObject *__pyx_getprop_6cloess_13loess_outputs_pseudovalues(PyObject *o, void *x) {
+  return __pyx_f_6cloess_13loess_outputs_12pseudovalues___get__(o);
+}
+
+static PyObject *__pyx_getprop_6cloess_13loess_outputs_diagonal(PyObject *o, void *x) {
+  return __pyx_f_6cloess_13loess_outputs_8diagonal___get__(o);
+}
+
+static PyObject *__pyx_getprop_6cloess_13loess_outputs_robust(PyObject *o, void *x) {
+  return __pyx_f_6cloess_13loess_outputs_6robust___get__(o);
+}
+
+static PyObject *__pyx_getprop_6cloess_13loess_outputs_divisor(PyObject *o, void *x) {
+  return __pyx_f_6cloess_13loess_outputs_7divisor___get__(o);
+}
+
+static PyObject *__pyx_getprop_6cloess_13loess_outputs_enp(PyObject *o, void *x) {
+  return __pyx_f_6cloess_13loess_outputs_3enp___get__(o);
+}
+
+static PyObject *__pyx_getprop_6cloess_13loess_outputs_s(PyObject *o, void *x) {
+  return __pyx_f_6cloess_13loess_outputs_1s___get__(o);
+}
+
+static PyObject *__pyx_getprop_6cloess_13loess_outputs_one_delta(PyObject *o, void *x) {
+  return __pyx_f_6cloess_13loess_outputs_9one_delta___get__(o);
+}
+
+static PyObject *__pyx_getprop_6cloess_13loess_outputs_two_delta(PyObject *o, void *x) {
+  return __pyx_f_6cloess_13loess_outputs_9two_delta___get__(o);
+}
+
+static PyObject *__pyx_getprop_6cloess_13loess_outputs_trace_hat(PyObject *o, void *x) {
+  return __pyx_f_6cloess_13loess_outputs_9trace_hat___get__(o);
+}
+
 static struct PyMethodDef __pyx_methods_6cloess_loess_outputs[] = {
   {0, 0, 0, 0}
 };
 
+static struct PyGetSetDef __pyx_getsets_6cloess_loess_outputs[] = {
+  {"fitted_values", __pyx_getprop_6cloess_13loess_outputs_fitted_values, 0, 0, 0},
+  {"fitted_residuals", __pyx_getprop_6cloess_13loess_outputs_fitted_residuals, 0, 0, 0},
+  {"pseudovalues", __pyx_getprop_6cloess_13loess_outputs_pseudovalues, 0, 0, 0},
+  {"diagonal", __pyx_getprop_6cloess_13loess_outputs_diagonal, 0, 0, 0},
+  {"robust", __pyx_getprop_6cloess_13loess_outputs_robust, 0, 0, 0},
+  {"divisor", __pyx_getprop_6cloess_13loess_outputs_divisor, 0, 0, 0},
+  {"enp", __pyx_getprop_6cloess_13loess_outputs_enp, 0, __pyx_k5, 0},
+  {"s", __pyx_getprop_6cloess_13loess_outputs_s, 0, 0, 0},
+  {"one_delta", __pyx_getprop_6cloess_13loess_outputs_one_delta, 0, 0, 0},
+  {"two_delta", __pyx_getprop_6cloess_13loess_outputs_two_delta, 0, 0, 0},
+  {"trace_hat", __pyx_getprop_6cloess_13loess_outputs_trace_hat, 0, 0, 0},
+  {0, 0, 0, 0, 0}
+};
+
 static PyNumberMethods __pyx_tp_as_number_loess_outputs = {
   0, /*nb_add*/
   0, /*nb_subtract*/
@@ -1936,13 +3823,13 @@
   0, /*tp_iternext*/
   __pyx_methods_6cloess_loess_outputs, /*tp_methods*/
   0, /*tp_members*/
-  0, /*tp_getset*/
+  __pyx_getsets_6cloess_loess_outputs, /*tp_getset*/
   0, /*tp_base*/
   0, /*tp_dict*/
   0, /*tp_descr_get*/
   0, /*tp_descr_set*/
   0, /*tp_dictoffset*/
-  __pyx_f_6cloess_13loess_outputs___init__, /*tp_init*/
+  0, /*tp_init*/
   0, /*tp_alloc*/
   __pyx_tp_new_6cloess_loess_outputs, /*tp_new*/
   0, /*tp_free*/
@@ -1954,68 +3841,229 @@
   0, /*tp_weaklist*/
 };
 
-static PyObject *__pyx_tp_new_6cloess_loess_kd_tree(PyTypeObject *t, PyObject *a, PyObject *k) {
+static PyObject *__pyx_tp_new_6cloess_loess_anova(PyTypeObject *t, PyObject *a, PyObject *k) {
   PyObject *o = (*t->tp_alloc)(t, 0);
-  struct __pyx_obj_6cloess_loess_kd_tree *p = (struct __pyx_obj_6cloess_loess_kd_tree *)o;
-  p->parameter = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  p->a = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  p->xi = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  p->vert = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  p->vval = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
   return o;
 }
 
-static void __pyx_tp_dealloc_6cloess_loess_kd_tree(PyObject *o) {
-  struct __pyx_obj_6cloess_loess_kd_tree *p = (struct __pyx_obj_6cloess_loess_kd_tree *)o;
-  Py_XDECREF(((PyObject *)p->parameter));
-  Py_XDECREF(((PyObject *)p->a));
-  Py_XDECREF(((PyObject *)p->xi));
-  Py_XDECREF(((PyObject *)p->vert));
-  Py_XDECREF(((PyObject *)p->vval));
+static void __pyx_tp_dealloc_6cloess_loess_anova(PyObject *o) {
   (*o->ob_type->tp_free)(o);
 }
 
-static int __pyx_tp_traverse_6cloess_loess_kd_tree(PyObject *o, visitproc v, void *a) {
+static int __pyx_tp_traverse_6cloess_loess_anova(PyObject *o, visitproc v, void *a) {
+  return 0;
+}
+
+static int __pyx_tp_clear_6cloess_loess_anova(PyObject *o) {
+  return 0;
+}
+
+static PyObject *__pyx_getprop_6cloess_11loess_anova_dfn(PyObject *o, void *x) {
+  return __pyx_f_6cloess_11loess_anova_3dfn___get__(o);
+}
+
+static PyObject *__pyx_getprop_6cloess_11loess_anova_dfd(PyObject *o, void *x) {
+  return __pyx_f_6cloess_11loess_anova_3dfd___get__(o);
+}
+
+static PyObject *__pyx_getprop_6cloess_11loess_anova_F_value(PyObject *o, void *x) {
+  return __pyx_f_6cloess_11loess_anova_7F_value___get__(o);
+}
+
+static PyObject *__pyx_getprop_6cloess_11loess_anova_Pr_F(PyObject *o, void *x) {
+  return __pyx_f_6cloess_11loess_anova_4Pr_F___get__(o);
+}
+
+static struct PyMethodDef __pyx_methods_6cloess_loess_anova[] = {
+  {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_6cloess_loess_anova[] = {
+  {"dfn", __pyx_getprop_6cloess_11loess_anova_dfn, 0, 0, 0},
+  {"dfd", __pyx_getprop_6cloess_11loess_anova_dfd, 0, 0, 0},
+  {"F_value", __pyx_getprop_6cloess_11loess_anova_F_value, 0, 0, 0},
+  {"Pr_F", __pyx_getprop_6cloess_11loess_anova_Pr_F, 0, 0, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_loess_anova = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  0, /*nb_divide*/
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  0, /*nb_coerce*/
+  0, /*nb_int*/
+  0, /*nb_long*/
+  0, /*nb_float*/
+  0, /*nb_oct*/
+  0, /*nb_hex*/
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  0, /*nb_inplace_divide*/
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_loess_anova = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_loess_anova = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_loess_anova = {
+  0, /*bf_getreadbuffer*/
+  0, /*bf_getwritebuffer*/
+  0, /*bf_getsegcount*/
+  0, /*bf_getcharbuffer*/
+};
+
+PyTypeObject __pyx_type_6cloess_loess_anova = {
+  PyObject_HEAD_INIT(0)
+  0, /*ob_size*/
+  "cloess.loess_anova", /*tp_name*/
+  sizeof(struct __pyx_obj_6cloess_loess_anova), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_6cloess_loess_anova, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  0, /*tp_compare*/
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_loess_anova, /*tp_as_number*/
+  &__pyx_tp_as_sequence_loess_anova, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_loess_anova, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_loess_anova, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_6cloess_loess_anova, /*tp_traverse*/
+  __pyx_tp_clear_6cloess_loess_anova, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_6cloess_loess_anova, /*tp_methods*/
+  0, /*tp_members*/
+  __pyx_getsets_6cloess_loess_anova, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_6cloess_loess_anova, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+};
+
+static PyObject *__pyx_tp_new_6cloess_confidence_interval(PyTypeObject *t, PyObject *a, PyObject *k) {
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  struct __pyx_obj_6cloess_confidence_interval *p = (struct __pyx_obj_6cloess_confidence_interval *)o;
+  p->nest = Py_None; Py_INCREF(Py_None);
+  return o;
+}
+
+static void __pyx_tp_dealloc_6cloess_confidence_interval(PyObject *o) {
+  struct __pyx_obj_6cloess_confidence_interval *p = (struct __pyx_obj_6cloess_confidence_interval *)o;
+  {
+    PyObject *etype, *eval, *etb;
+    PyErr_Fetch(&etype, &eval, &etb);
+    ++o->ob_refcnt;
+    __pyx_f_6cloess_19confidence_interval___dealloc__(o);
+    if (PyErr_Occurred()) PyErr_WriteUnraisable(o);
+    --o->ob_refcnt;
+    PyErr_Restore(etype, eval, etb);
+  }
+  Py_XDECREF(p->nest);
+  (*o->ob_type->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_6cloess_confidence_interval(PyObject *o, visitproc v, void *a) {
   int e;
-  struct __pyx_obj_6cloess_loess_kd_tree *p = (struct __pyx_obj_6cloess_loess_kd_tree *)o;
-  if (p->parameter) {
-    e = (*v)(((PyObject*)p->parameter), a); if (e) return e;
+  struct __pyx_obj_6cloess_confidence_interval *p = (struct __pyx_obj_6cloess_confidence_interval *)o;
+  if (p->nest) {
+    e = (*v)(p->nest, a); if (e) return e;
   }
-  if (p->a) {
-    e = (*v)(((PyObject*)p->a), a); if (e) return e;
-  }
-  if (p->xi) {
-    e = (*v)(((PyObject*)p->xi), a); if (e) return e;
-  }
-  if (p->vert) {
-    e = (*v)(((PyObject*)p->vert), a); if (e) return e;
-  }
-  if (p->vval) {
-    e = (*v)(((PyObject*)p->vval), a); if (e) return e;
-  }
   return 0;
 }
 
-static int __pyx_tp_clear_6cloess_loess_kd_tree(PyObject *o) {
-  struct __pyx_obj_6cloess_loess_kd_tree *p = (struct __pyx_obj_6cloess_loess_kd_tree *)o;
-  Py_XDECREF(((PyObject *)p->parameter));
-  p->parameter = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  Py_XDECREF(((PyObject *)p->a));
-  p->a = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  Py_XDECREF(((PyObject *)p->xi));
-  p->xi = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  Py_XDECREF(((PyObject *)p->vert));
-  p->vert = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  Py_XDECREF(((PyObject *)p->vval));
-  p->vval = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+static int __pyx_tp_clear_6cloess_confidence_interval(PyObject *o) {
+  struct __pyx_obj_6cloess_confidence_interval *p = (struct __pyx_obj_6cloess_confidence_interval *)o;
+  Py_XDECREF(p->nest);
+  p->nest = Py_None; Py_INCREF(Py_None);
   return 0;
 }
 
-static struct PyMethodDef __pyx_methods_6cloess_loess_kd_tree[] = {
+static PyObject *__pyx_getprop_6cloess_19confidence_interval_fit(PyObject *o, void *x) {
+  return __pyx_f_6cloess_19confidence_interval_3fit___get__(o);
+}
+
+static PyObject *__pyx_getprop_6cloess_19confidence_interval_upper(PyObject *o, void *x) {
+  return __pyx_f_6cloess_19confidence_interval_5upper___get__(o);
+}
+
+static PyObject *__pyx_getprop_6cloess_19confidence_interval_lower(PyObject *o, void *x) {
+  return __pyx_f_6cloess_19confidence_interval_5lower___get__(o);
+}
+
+static struct PyMethodDef __pyx_methods_6cloess_confidence_interval[] = {
   {0, 0, 0, 0}
 };
 
-static PyNumberMethods __pyx_tp_as_number_loess_kd_tree = {
+static struct PyGetSetDef __pyx_getsets_6cloess_confidence_interval[] = {
+  {"fit", __pyx_getprop_6cloess_19confidence_interval_fit, 0, 0, 0},
+  {"upper", __pyx_getprop_6cloess_19confidence_interval_upper, 0, 0, 0},
+  {"lower", __pyx_getprop_6cloess_19confidence_interval_lower, 0, 0, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_confidence_interval = {
   0, /*nb_add*/
   0, /*nb_subtract*/
   0, /*nb_multiply*/
@@ -2056,7 +4104,7 @@
   0, /*nb_inplace_true_divide*/
 };
 
-static PySequenceMethods __pyx_tp_as_sequence_loess_kd_tree = {
+static PySequenceMethods __pyx_tp_as_sequence_confidence_interval = {
   0, /*sq_length*/
   0, /*sq_concat*/
   0, /*sq_repeat*/
@@ -2069,59 +4117,59 @@
   0, /*sq_inplace_repeat*/
 };
 
-static PyMappingMethods __pyx_tp_as_mapping_loess_kd_tree = {
+static PyMappingMethods __pyx_tp_as_mapping_confidence_interval = {
   0, /*mp_length*/
   0, /*mp_subscript*/
   0, /*mp_ass_subscript*/
 };
 
-static PyBufferProcs __pyx_tp_as_buffer_loess_kd_tree = {
+static PyBufferProcs __pyx_tp_as_buffer_confidence_interval = {
   0, /*bf_getreadbuffer*/
   0, /*bf_getwritebuffer*/
   0, /*bf_getsegcount*/
   0, /*bf_getcharbuffer*/
 };
 
-PyTypeObject __pyx_type_6cloess_loess_kd_tree = {
+PyTypeObject __pyx_type_6cloess_confidence_interval = {
   PyObject_HEAD_INIT(0)
   0, /*ob_size*/
-  "cloess.loess_kd_tree", /*tp_name*/
-  sizeof(struct __pyx_obj_6cloess_loess_kd_tree), /*tp_basicsize*/
+  "cloess.confidence_interval", /*tp_name*/
+  sizeof(struct __pyx_obj_6cloess_confidence_interval), /*tp_basicsize*/
   0, /*tp_itemsize*/
-  __pyx_tp_dealloc_6cloess_loess_kd_tree, /*tp_dealloc*/
+  __pyx_tp_dealloc_6cloess_confidence_interval, /*tp_dealloc*/
   0, /*tp_print*/
   0, /*tp_getattr*/
   0, /*tp_setattr*/
   0, /*tp_compare*/
   0, /*tp_repr*/
-  &__pyx_tp_as_number_loess_kd_tree, /*tp_as_number*/
-  &__pyx_tp_as_sequence_loess_kd_tree, /*tp_as_sequence*/
-  &__pyx_tp_as_mapping_loess_kd_tree, /*tp_as_mapping*/
+  &__pyx_tp_as_number_confidence_interval, /*tp_as_number*/
+  &__pyx_tp_as_sequence_confidence_interval, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_confidence_interval, /*tp_as_mapping*/
   0, /*tp_hash*/
   0, /*tp_call*/
   0, /*tp_str*/
   0, /*tp_getattro*/
   0, /*tp_setattro*/
-  &__pyx_tp_as_buffer_loess_kd_tree, /*tp_as_buffer*/
+  &__pyx_tp_as_buffer_confidence_interval, /*tp_as_buffer*/
   Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
   0, /*tp_doc*/
-  __pyx_tp_traverse_6cloess_loess_kd_tree, /*tp_traverse*/
-  __pyx_tp_clear_6cloess_loess_kd_tree, /*tp_clear*/
+  __pyx_tp_traverse_6cloess_confidence_interval, /*tp_traverse*/
+  __pyx_tp_clear_6cloess_confidence_interval, /*tp_clear*/
   0, /*tp_richcompare*/
   0, /*tp_weaklistoffset*/
   0, /*tp_iter*/
   0, /*tp_iternext*/
-  __pyx_methods_6cloess_loess_kd_tree, /*tp_methods*/
+  __pyx_methods_6cloess_confidence_interval, /*tp_methods*/
   0, /*tp_members*/
-  0, /*tp_getset*/
+  __pyx_getsets_6cloess_confidence_interval, /*tp_getset*/
   0, /*tp_base*/
   0, /*tp_dict*/
   0, /*tp_descr_get*/
   0, /*tp_descr_set*/
   0, /*tp_dictoffset*/
-  __pyx_f_6cloess_13loess_kd_tree___init__, /*tp_init*/
+  0, /*tp_init*/
   0, /*tp_alloc*/
-  __pyx_tp_new_6cloess_loess_kd_tree, /*tp_new*/
+  __pyx_tp_new_6cloess_confidence_interval, /*tp_new*/
   0, /*tp_free*/
   0, /*tp_is_gc*/
   0, /*tp_bases*/
@@ -2131,47 +4179,74 @@
   0, /*tp_weaklist*/
 };
 
-static PyObject *__pyx_tp_new_6cloess_loess_model(PyTypeObject *t, PyObject *a, PyObject *k) {
+static PyObject *__pyx_tp_new_6cloess_loess_predicted(PyTypeObject *t, PyObject *a, PyObject *k) {
   PyObject *o = (*t->tp_alloc)(t, 0);
-  struct __pyx_obj_6cloess_loess_model *p = (struct __pyx_obj_6cloess_loess_model *)o;
-  p->parametric_flags = Py_None; Py_INCREF(Py_None);
-  p->drop_square_flags = Py_None; Py_INCREF(Py_None);
+  struct __pyx_obj_6cloess_loess_predicted *p = (struct __pyx_obj_6cloess_loess_predicted *)o;
+  p->conf_interval = ((struct __pyx_obj_6cloess_confidence_interval *)Py_None); Py_INCREF(Py_None);
   return o;
 }
 
-static void __pyx_tp_dealloc_6cloess_loess_model(PyObject *o) {
-  struct __pyx_obj_6cloess_loess_model *p = (struct __pyx_obj_6cloess_loess_model *)o;
-  Py_XDECREF(p->parametric_flags);
-  Py_XDECREF(p->drop_square_flags);
+static void __pyx_tp_dealloc_6cloess_loess_predicted(PyObject *o) {
+  struct __pyx_obj_6cloess_loess_predicted *p = (struct __pyx_obj_6cloess_loess_predicted *)o;
+  {
+    PyObject *etype, *eval, *etb;
+    PyErr_Fetch(&etype, &eval, &etb);
+    ++o->ob_refcnt;
+    __pyx_f_6cloess_15loess_predicted___dealloc__(o);
+    if (PyErr_Occurred()) PyErr_WriteUnraisable(o);
+    --o->ob_refcnt;
+    PyErr_Restore(etype, eval, etb);
+  }
+  Py_XDECREF(((PyObject *)p->conf_interval));
   (*o->ob_type->tp_free)(o);
 }
 
-static int __pyx_tp_traverse_6cloess_loess_model(PyObject *o, visitproc v, void *a) {
+static int __pyx_tp_traverse_6cloess_loess_predicted(PyObject *o, visitproc v, void *a) {
   int e;
-  struct __pyx_obj_6cloess_loess_model *p = (struct __pyx_obj_6cloess_loess_model *)o;
-  if (p->parametric_flags) {
-    e = (*v)(p->parametric_flags, a); if (e) return e;
+  struct __pyx_obj_6cloess_loess_predicted *p = (struct __pyx_obj_6cloess_loess_predicted *)o;
+  if (p->conf_interval) {
+    e = (*v)(((PyObject*)p->conf_interval), a); if (e) return e;
   }
-  if (p->drop_square_flags) {
-    e = (*v)(p->drop_square_flags, a); if (e) return e;
-  }
   return 0;
 }
 
-static int __pyx_tp_clear_6cloess_loess_model(PyObject *o) {
-  struct __pyx_obj_6cloess_loess_model *p = (struct __pyx_obj_6cloess_loess_model *)o;
-  Py_XDECREF(p->parametric_flags);
-  p->parametric_flags = Py_None; Py_INCREF(Py_None);
-  Py_XDECREF(p->drop_square_flags);
-  p->drop_square_flags = Py_None; Py_INCREF(Py_None);
+static int __pyx_tp_clear_6cloess_loess_predicted(PyObject *o) {
+  struct __pyx_obj_6cloess_loess_predicted *p = (struct __pyx_obj_6cloess_loess_predicted *)o;
+  Py_XDECREF(((PyObject *)p->conf_interval));
+  p->conf_interval = ((struct __pyx_obj_6cloess_confidence_interval *)Py_None); Py_INCREF(Py_None);
   return 0;
 }
 
-static struct PyMethodDef __pyx_methods_6cloess_loess_model[] = {
+static PyObject *__pyx_getprop_6cloess_15loess_predicted_predicted(PyObject *o, void *x) {
+  return __pyx_f_6cloess_15loess_predicted_9predicted___get__(o);
+}
+
+static PyObject *__pyx_getprop_6cloess_15loess_predicted_predicted_stderr(PyObject *o, void *x) {
+  return __pyx_f_6cloess_15loess_predicted_16predicted_stderr___get__(o);
+}
+
+static PyObject *__pyx_getprop_6cloess_15loess_predicted_residual_scale(PyObject *o, void *x) {
+  return __pyx_f_6cloess_15loess_predicted_14residual_scale___get__(o);
+}
+
+static PyObject *__pyx_getprop_6cloess_15loess_predicted_df(PyObject *o, void *x) {
+  return __pyx_f_6cloess_15loess_predicted_2df___get__(o);
+}
+
+static struct PyMethodDef __pyx_methods_6cloess_loess_predicted[] = {
+  {"confidence", (PyCFunction)__pyx_f_6cloess_15loess_predicted_confidence, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6cloess_15loess_predicted_confidence},
   {0, 0, 0, 0}
 };
 
-static PyNumberMethods __pyx_tp_as_number_loess_model = {
+static struct PyGetSetDef __pyx_getsets_6cloess_loess_predicted[] = {
+  {"predicted", __pyx_getprop_6cloess_15loess_predicted_predicted, 0, 0, 0},
+  {"predicted_stderr", __pyx_getprop_6cloess_15loess_predicted_predicted_stderr, 0, 0, 0},
+  {"residual_scale", __pyx_getprop_6cloess_15loess_predicted_residual_scale, 0, 0, 0},
+  {"df", __pyx_getprop_6cloess_15loess_predicted_df, 0, 0, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_loess_predicted = {
   0, /*nb_add*/
   0, /*nb_subtract*/
   0, /*nb_multiply*/
@@ -2212,7 +4287,7 @@
   0, /*nb_inplace_true_divide*/
 };
 
-static PySequenceMethods __pyx_tp_as_sequence_loess_model = {
+static PySequenceMethods __pyx_tp_as_sequence_loess_predicted = {
   0, /*sq_length*/
   0, /*sq_concat*/
   0, /*sq_repeat*/
@@ -2225,59 +4300,59 @@
   0, /*sq_inplace_repeat*/
 };
 
-static PyMappingMethods __pyx_tp_as_mapping_loess_model = {
+static PyMappingMethods __pyx_tp_as_mapping_loess_predicted = {
   0, /*mp_length*/
   0, /*mp_subscript*/
   0, /*mp_ass_subscript*/
 };
 
-static PyBufferProcs __pyx_tp_as_buffer_loess_model = {
+static PyBufferProcs __pyx_tp_as_buffer_loess_predicted = {
   0, /*bf_getreadbuffer*/
   0, /*bf_getwritebuffer*/
   0, /*bf_getsegcount*/
   0, /*bf_getcharbuffer*/
 };
 
-PyTypeObject __pyx_type_6cloess_loess_model = {
+PyTypeObject __pyx_type_6cloess_loess_predicted = {
   PyObject_HEAD_INIT(0)
   0, /*ob_size*/
-  "cloess.loess_model", /*tp_name*/
-  sizeof(struct __pyx_obj_6cloess_loess_model), /*tp_basicsize*/
+  "cloess.loess_predicted", /*tp_name*/
+  sizeof(struct __pyx_obj_6cloess_loess_predicted), /*tp_basicsize*/
   0, /*tp_itemsize*/
-  __pyx_tp_dealloc_6cloess_loess_model, /*tp_dealloc*/
+  __pyx_tp_dealloc_6cloess_loess_predicted, /*tp_dealloc*/
   0, /*tp_print*/
   0, /*tp_getattr*/
   0, /*tp_setattr*/
   0, /*tp_compare*/
-  __pyx_f_6cloess_11loess_model___repr__, /*tp_repr*/
-  &__pyx_tp_as_number_loess_model, /*tp_as_number*/
-  &__pyx_tp_as_sequence_loess_model, /*tp_as_sequence*/
-  &__pyx_tp_as_mapping_loess_model, /*tp_as_mapping*/
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_loess_predicted, /*tp_as_number*/
+  &__pyx_tp_as_sequence_loess_predicted, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_loess_predicted, /*tp_as_mapping*/
   0, /*tp_hash*/
   0, /*tp_call*/
-  __pyx_f_6cloess_11loess_model___str__, /*tp_str*/
+  0, /*tp_str*/
   0, /*tp_getattro*/
   0, /*tp_setattro*/
-  &__pyx_tp_as_buffer_loess_model, /*tp_as_buffer*/
+  &__pyx_tp_as_buffer_loess_predicted, /*tp_as_buffer*/
   Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
   0, /*tp_doc*/
-  __pyx_tp_traverse_6cloess_loess_model, /*tp_traverse*/
-  __pyx_tp_clear_6cloess_loess_model, /*tp_clear*/
+  __pyx_tp_traverse_6cloess_loess_predicted, /*tp_traverse*/
+  __pyx_tp_clear_6cloess_loess_predicted, /*tp_clear*/
   0, /*tp_richcompare*/
   0, /*tp_weaklistoffset*/
   0, /*tp_iter*/
   0, /*tp_iternext*/
-  __pyx_methods_6cloess_loess_model, /*tp_methods*/
+  __pyx_methods_6cloess_loess_predicted, /*tp_methods*/
   0, /*tp_members*/
-  0, /*tp_getset*/
+  __pyx_getsets_6cloess_loess_predicted, /*tp_getset*/
   0, /*tp_base*/
   0, /*tp_dict*/
   0, /*tp_descr_get*/
   0, /*tp_descr_set*/
   0, /*tp_dictoffset*/
-  __pyx_f_6cloess_11loess_model___init__, /*tp_init*/
+  0, /*tp_init*/
   0, /*tp_alloc*/
-  __pyx_tp_new_6cloess_loess_model, /*tp_new*/
+  __pyx_tp_new_6cloess_loess_predicted, /*tp_new*/
   0, /*tp_free*/
   0, /*tp_is_gc*/
   0, /*tp_bases*/
@@ -2295,6 +4370,7 @@
   p->control = ((struct __pyx_obj_6cloess_loess_control *)Py_None); Py_INCREF(Py_None);
   p->kd_tree = ((struct __pyx_obj_6cloess_loess_kd_tree *)Py_None); Py_INCREF(Py_None);
   p->outputs = ((struct __pyx_obj_6cloess_loess_outputs *)Py_None); Py_INCREF(Py_None);
+  p->predicted = ((struct __pyx_obj_6cloess_loess_predicted *)Py_None); Py_INCREF(Py_None);
   return o;
 }
 
@@ -2305,6 +4381,7 @@
   Py_XDECREF(((PyObject *)p->control));
   Py_XDECREF(((PyObject *)p->kd_tree));
   Py_XDECREF(((PyObject *)p->outputs));
+  Py_XDECREF(((PyObject *)p->predicted));
   (*o->ob_type->tp_free)(o);
 }
 
@@ -2326,6 +4403,9 @@
   if (p->outputs) {
     e = (*v)(((PyObject*)p->outputs), a); if (e) return e;
   }
+  if (p->predicted) {
+    e = (*v)(((PyObject*)p->predicted), a); if (e) return e;
+  }
   return 0;
 }
 
@@ -2341,14 +4421,28 @@
   p->kd_tree = ((struct __pyx_obj_6cloess_loess_kd_tree *)Py_None); Py_INCREF(Py_None);
   Py_XDECREF(((PyObject *)p->outputs));
   p->outputs = ((struct __pyx_obj_6cloess_loess_outputs *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(((PyObject *)p->predicted));
+  p->predicted = ((struct __pyx_obj_6cloess_loess_predicted *)Py_None); Py_INCREF(Py_None);
   return 0;
 }
 
 static struct PyMethodDef __pyx_methods_6cloess_loess[] = {
+  {"fit", (PyCFunction)__pyx_f_6cloess_5loess_fit, METH_VARARGS|METH_KEYWORDS, 0},
   {"summary", (PyCFunction)__pyx_f_6cloess_5loess_summary, METH_VARARGS|METH_KEYWORDS, 0},
+  {"predict", (PyCFunction)__pyx_f_6cloess_5loess_predict, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6cloess_5loess_predict},
   {0, 0, 0, 0}
 };
 
+static struct PyMemberDef __pyx_members_6cloess_loess[] = {
+  {"inputs", T_OBJECT, offsetof(struct __pyx_obj_6cloess_loess, inputs), READONLY, 0},
+  {"model", T_OBJECT, offsetof(struct __pyx_obj_6cloess_loess, model), READONLY, 0},
+  {"control", T_OBJECT, offsetof(struct __pyx_obj_6cloess_loess, control), READONLY, 0},
+  {"kd_tree", T_OBJECT, offsetof(struct __pyx_obj_6cloess_loess, kd_tree), READONLY, 0},
+  {"outputs", T_OBJECT, offsetof(struct __pyx_obj_6cloess_loess, outputs), READONLY, 0},
+  {"predicted", T_OBJECT, offsetof(struct __pyx_obj_6cloess_loess, predicted), READONLY, 0},
+  {0, 0, 0, 0, 0}
+};
+
 static PyNumberMethods __pyx_tp_as_number_loess = {
   0, /*nb_add*/
   0, /*nb_subtract*/
@@ -2446,7 +4540,7 @@
   0, /*tp_iter*/
   0, /*tp_iternext*/
   __pyx_methods_6cloess_loess, /*tp_methods*/
-  0, /*tp_members*/
+  __pyx_members_6cloess_loess, /*tp_members*/
   0, /*tp_getset*/
   0, /*tp_base*/
   0, /*tp_dict*/
@@ -2483,28 +4577,35 @@
   if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2; goto __pyx_L1;};
   if (__Pyx_InternStrings(__pyx_intern_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2; goto __pyx_L1;};
   if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2; goto __pyx_L1;};
-  __pyx_type_6cloess_loess_inputs.tp_free = _PyObject_GC_Del;
-  if (PyType_Ready(&__pyx_type_6cloess_loess_inputs) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; goto __pyx_L1;}
-  if (PyObject_SetAttrString(__pyx_m, "loess_inputs", (PyObject *)&__pyx_type_6cloess_loess_inputs) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; goto __pyx_L1;}
+  if (PyType_Ready(&__pyx_type_6cloess_loess_inputs) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "loess_inputs", (PyObject *)&__pyx_type_6cloess_loess_inputs) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; goto __pyx_L1;}
   __pyx_ptype_6cloess_loess_inputs = &__pyx_type_6cloess_loess_inputs;
-  if (PyType_Ready(&__pyx_type_6cloess_loess_control) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; goto __pyx_L1;}
-  if (PyObject_SetAttrString(__pyx_m, "loess_control", (PyObject *)&__pyx_type_6cloess_loess_control) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; goto __pyx_L1;}
+  if (PyType_Ready(&__pyx_type_6cloess_loess_control) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "loess_control", (PyObject *)&__pyx_type_6cloess_loess_control) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; goto __pyx_L1;}
   __pyx_ptype_6cloess_loess_control = &__pyx_type_6cloess_loess_control;
-  __pyx_type_6cloess_loess_outputs.tp_free = _PyObject_GC_Del;
-  if (PyType_Ready(&__pyx_type_6cloess_loess_outputs) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; goto __pyx_L1;}
-  if (PyObject_SetAttrString(__pyx_m, "loess_outputs", (PyObject *)&__pyx_type_6cloess_loess_outputs) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; goto __pyx_L1;}
-  __pyx_ptype_6cloess_loess_outputs = &__pyx_type_6cloess_loess_outputs;
-  __pyx_type_6cloess_loess_kd_tree.tp_free = _PyObject_GC_Del;
-  if (PyType_Ready(&__pyx_type_6cloess_loess_kd_tree) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; goto __pyx_L1;}
-  if (PyObject_SetAttrString(__pyx_m, "loess_kd_tree", (PyObject *)&__pyx_type_6cloess_loess_kd_tree) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; goto __pyx_L1;}
+  if (PyType_Ready(&__pyx_type_6cloess_loess_kd_tree) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "loess_kd_tree", (PyObject *)&__pyx_type_6cloess_loess_kd_tree) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; goto __pyx_L1;}
   __pyx_ptype_6cloess_loess_kd_tree = &__pyx_type_6cloess_loess_kd_tree;
-  __pyx_type_6cloess_loess_model.tp_free = _PyObject_GC_Del;
-  if (PyType_Ready(&__pyx_type_6cloess_loess_model) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; goto __pyx_L1;}
-  if (PyObject_SetAttrString(__pyx_m, "loess_model", (PyObject *)&__pyx_type_6cloess_loess_model) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; goto __pyx_L1;}
+  if (PyType_Ready(&__pyx_type_6cloess_loess_model) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "loess_model", (PyObject *)&__pyx_type_6cloess_loess_model) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; goto __pyx_L1;}
   __pyx_ptype_6cloess_loess_model = &__pyx_type_6cloess_loess_model;
+  if (PyType_Ready(&__pyx_type_6cloess_loess_outputs) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "loess_outputs", (PyObject *)&__pyx_type_6cloess_loess_outputs) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; goto __pyx_L1;}
+  __pyx_ptype_6cloess_loess_outputs = &__pyx_type_6cloess_loess_outputs;
+  if (PyType_Ready(&__pyx_type_6cloess_loess_anova) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 333; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "loess_anova", (PyObject *)&__pyx_type_6cloess_loess_anova) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 333; goto __pyx_L1;}
+  __pyx_ptype_6cloess_loess_anova = &__pyx_type_6cloess_loess_anova;
+  __pyx_type_6cloess_confidence_interval.tp_free = _PyObject_GC_Del;
+  if (PyType_Ready(&__pyx_type_6cloess_confidence_interval) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "confidence_interval", (PyObject *)&__pyx_type_6cloess_confidence_interval) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; goto __pyx_L1;}
+  __pyx_ptype_6cloess_confidence_interval = &__pyx_type_6cloess_confidence_interval;
+  __pyx_type_6cloess_loess_predicted.tp_free = _PyObject_GC_Del;
+  if (PyType_Ready(&__pyx_type_6cloess_loess_predicted) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 378; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "loess_predicted", (PyObject *)&__pyx_type_6cloess_loess_predicted) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 378; goto __pyx_L1;}
+  __pyx_ptype_6cloess_loess_predicted = &__pyx_type_6cloess_loess_predicted;
   __pyx_type_6cloess_loess.tp_free = _PyObject_GC_Del;
-  if (PyType_Ready(&__pyx_type_6cloess_loess) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; goto __pyx_L1;}
-  if (PyObject_SetAttrString(__pyx_m, "loess", (PyObject *)&__pyx_type_6cloess_loess) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; goto __pyx_L1;}
+  if (PyType_Ready(&__pyx_type_6cloess_loess) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 414; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "loess", (PyObject *)&__pyx_type_6cloess_loess) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 414; goto __pyx_L1;}
   __pyx_ptype_6cloess_loess = &__pyx_type_6cloess_loess;
   __pyx_ptype_7c_numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr)); if (!__pyx_ptype_7c_numpy_dtype) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 76; goto __pyx_L1;}
   __pyx_ptype_7c_numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject)); if (!__pyx_ptype_7c_numpy_ndarray) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 81; goto __pyx_L1;}
@@ -2513,34 +4614,25 @@
 
   /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":7 */
   __pyx_1 = __Pyx_Import(__pyx_n_numpy, 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; goto __pyx_L1;}
-  if (PyObject_SetAttr(__pyx_m, __pyx_n__N, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; goto __pyx_L1;}
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_numpy, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":9 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":14 */
   import_array();
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":22 */
-  Py_INCREF(Py_None);
-  __pyx_k2 = Py_None;
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":202 */
-  __pyx_k3 = 0.75;
-  __pyx_k4 = 2;
-  __pyx_k5 = 1;
-  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_False); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; goto __pyx_L1;}
-  __pyx_k6 = __pyx_1;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":402 */
+  __pyx_1 = PyFloat_FromDouble(0.95); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 402; goto __pyx_L1;}
+  __pyx_k7 = __pyx_1;
   __pyx_1 = 0;
-  __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_False); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; goto __pyx_L1;}
-  __pyx_k7 = __pyx_2;
-  __pyx_2 = 0;
-  Py_INCREF(__pyx_n_gaussian);
-  __pyx_k9 = __pyx_n_gaussian;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":273 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":423 */
   Py_INCREF(Py_None);
-  __pyx_k10 = Py_None;
+  __pyx_k8 = Py_None;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":309 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":466 */
+  __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_False); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 466; goto __pyx_L1;}
+  __pyx_k9 = __pyx_2;
+  __pyx_2 = 0;
   return;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);
@@ -2559,6 +4651,79 @@
   __pyx_f = __pyx_filenames;
 }
 
+static int __Pyx_GetStarArgs(
+    PyObject **args, 
+    PyObject **kwds,
+    char *kwd_list[], 
+    int nargs,
+    PyObject **args2, 
+    PyObject **kwds2)
+{
+    PyObject *x = 0, *args1 = 0, *kwds1 = 0;
+    
+    if (args2)
+        *args2 = 0;
+    if (kwds2)
+        *kwds2 = 0;
+    
+    if (args2) {
+        args1 = PyTuple_GetSlice(*args, 0, nargs);
+        if (!args1)
+            goto bad;
+        *args2 = PyTuple_GetSlice(*args, nargs, PyTuple_Size(*args));
+        if (!*args2)
+            goto bad;
+    }
+    else {
+        args1 = *args;
+        Py_INCREF(args1);
+    }
+    
+    if (kwds2) {
+        if (*kwds) {
+            char **p;
+            kwds1 = PyDict_New();
+            if (!kwds)
+                goto bad;
+            *kwds2 = PyDict_Copy(*kwds);
+            if (!*kwds2)
+                goto bad;
+            for (p = kwd_list; *p; p++) {
+                x = PyDict_GetItemString(*kwds, *p);
+                if (x) {
+                    if (PyDict_SetItemString(kwds1, *p, x) < 0)
+                        goto bad;
+                    if (PyDict_DelItemString(*kwds2, *p) < 0)
+                        goto bad;
+                }
+            }
+        }
+        else {
+            *kwds2 = PyDict_New();
+            if (!*kwds2)
+                goto bad;
+        }
+    }
+    else {
+        kwds1 = *kwds;
+        Py_XINCREF(kwds1);
+    }
+    
+    *args = args1;
+    *kwds = kwds1;
+    return 0;
+bad:
+    Py_XDECREF(args1);
+    Py_XDECREF(kwds1);
+    if (*args2) {
+        Py_XDECREF(*args2);
+    }
+    if (*kwds2) {
+        Py_XDECREF(*kwds2);
+    }
+    return -1;
+}
+
 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
     PyObject *__import__ = 0;
     PyObject *empty_list = 0;
@@ -2600,47 +4765,18 @@
     return result;
 }
 
-static PyObject *__Pyx_GetStdout(void) {
-    PyObject *f = PySys_GetObject("stdout");
-    if (!f) {
-        PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
+static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
+    if (!type) {
+        PyErr_Format(PyExc_SystemError, "Missing type object");
+        return 0;
     }
-    return f;
-}
-
-static int __Pyx_PrintItem(PyObject *v) {
-    PyObject *f;
-    
-    if (!(f = __Pyx_GetStdout()))
-        return -1;
-    if (PyFile_SoftSpace(f, 1)) {
-        if (PyFile_WriteString(" ", f) < 0)
-            return -1;
-    }
-    if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
-        return -1;
-    if (PyString_Check(v)) {
-        char *s = PyString_AsString(v);
-        int len = PyString_Size(v);
-        if (len > 0 &&
-            isspace(Py_CHARMASK(s[len-1])) &&
-            s[len-1] != ' ')
-                PyFile_SoftSpace(f, 0);
-    }
+    if (obj == Py_None || PyObject_TypeCheck(obj, type))
+        return 1;
+    PyErr_Format(PyExc_TypeError, "Cannot convert %s to %s",
+        obj->ob_type->tp_name, type->tp_name);
     return 0;
 }
 
-static int __Pyx_PrintNewline(void) {
-    PyObject *f;
-    
-    if (!(f = __Pyx_GetStdout()))
-        return -1;
-    if (PyFile_WriteString("\n", f) < 0)
-        return -1;
-    PyFile_SoftSpace(f, 0);
-    return 0;
-}
-
 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
     Py_XINCREF(type);
     Py_XINCREF(value);
@@ -2699,18 +4835,47 @@
     return;
 }
 
-static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
-    if (!type) {
-        PyErr_Format(PyExc_SystemError, "Missing type object");
-        return 0;
+static PyObject *__Pyx_GetStdout(void) {
+    PyObject *f = PySys_GetObject("stdout");
+    if (!f) {
+        PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
     }
-    if (obj == Py_None || PyObject_TypeCheck(obj, type))
-        return 1;
-    PyErr_Format(PyExc_TypeError, "Cannot convert %s to %s",
-        obj->ob_type->tp_name, type->tp_name);
+    return f;
+}
+
+static int __Pyx_PrintItem(PyObject *v) {
+    PyObject *f;
+    
+    if (!(f = __Pyx_GetStdout()))
+        return -1;
+    if (PyFile_SoftSpace(f, 1)) {
+        if (PyFile_WriteString(" ", f) < 0)
+            return -1;
+    }
+    if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
+        return -1;
+    if (PyString_Check(v)) {
+        char *s = PyString_AsString(v);
+        int len = PyString_Size(v);
+        if (len > 0 &&
+            isspace(Py_CHARMASK(s[len-1])) &&
+            s[len-1] != ' ')
+                PyFile_SoftSpace(f, 0);
+    }
     return 0;
 }
 
+static int __Pyx_PrintNewline(void) {
+    PyObject *f;
+    
+    if (!(f = __Pyx_GetStdout()))
+        return -1;
+    if (PyFile_WriteString("\n", f) < 0)
+        return -1;
+    PyFile_SoftSpace(f, 0);
+    return 0;
+}
+
 static int __Pyx_InternStrings(__Pyx_InternTabEntry *t) {
     while (t->p) {
         *t->p = PyString_InternFromString(t->s);

Modified: trunk/Lib/sandbox/pyloess/sandbox/src/cloess.h
===================================================================
--- trunk/Lib/sandbox/pyloess/sandbox/src/cloess.h	2007-03-14 12:34:56 UTC (rev 2846)
+++ trunk/Lib/sandbox/pyloess/sandbox/src/cloess.h	2007-03-14 12:46:49 UTC (rev 2847)
@@ -1,87 +1,18 @@
 #include <stdio.h>
 #include <stdlib.h>
-#include "loess.h"
-/*
-loess.c
-*/
+
+
+// from loess.c
 void loess_setup(double *x, double *y, int n, int p, loess *lo);
 void loess_fit(loess *lo);
-void
-loess_(double *y, double *x_, int *size_info, double *weights, double *span,
-       int *degree, int *parametric, int *drop_square, int *normalize,
-       char **statistics, char **surface, double *cell, char **trace_hat_in,
-       int *iterations, double *fitted_values, double *fitted_residuals,
-       double *enp, double *s, double *one_delta, double *two_delta,
-       double *pseudovalues, double *trace_hat_out, double *diagonal,
-       double *robust, double *divisor, int *parameter, int *a, double *xi,
-       double *vert, double *vval);
 void loess_free_mem(loess *lo);
 void loess_summary(loess *lo);
-void condition(char **surface, char *new_stat, char **trace_hat_in);
-int comp(double *d1, double *d2);
-
-/*
-loessc.c
-*/
-void
-loess_raw(double *y, double *x, double *weights, double *robust, int *d,
-          int*n, double *span, int *degree, int *nonparametric,
-          int *drop_square, int *sum_drop_sqr, double *cell, char **surf_stat,
-          double *surface, int *parameter, int *a, double *xi, double *vert,
-          double *vval, double *diagonal, double *trL, double *one_delta,
-          double *two_delta, int *setLf);
-void
-loess_dfit(double *y, double *x, double *x_evaluate, double *weights,
-           double *span, int *degree, int *nonparametric,
-           int *drop_square, int *sum_drop_sqr, int *d, int *n, int *m,
-           double *fit);
-void
-loess_dfitse(double *y, double *x, double *x_evaluate, double *weights,
-             double *robust, int *family, double *span, int *degree,
-             int *nonparametric, int *drop_square, int *sum_drop_sqr,
-             int *d, int *n, int *m, double *fit, double *L);
-void
-loess_ifit(int *parameter, int *a, double *xi, double *vert, double *vval,
-           int *m, double *x_evaluate, double *fit);
-void
-loess_ise(double *y, double *x, double *x_evaluate, double *weights,
-          double *span, int *degree, int *nonparametric, int *drop_square,
-          int *sum_drop_sqr, double *cell, int *d, int *n, int *m,
-          double *fit, double *L);
-void
-loess_workspace(int *d, int *n, double *span, int *degree,
-                int *nonparametric, int *drop_square, int *sum_drop_sqr,
-                int *setLf);
-void
-loess_prune(int *parameter, int *a, double *xi, double *vert, double *vval);
-void
-loess_grow(int *parameter, int *a, double *xi, double *vert, double *vval);
-void
-F77_SUB(lowesw)(double *res, int *n, double *rw, int *pi);
-void
-F77_SUB(lowesp)(int *n, double *y, double *yhat, double *pwgts,
-                double *rwgts, int *pi, double *ytilde);
-                
-//                
-///*
-//misc.c
-//*/
-//void
-//anova(struct loess_struct *one, struct loess_struct *two,
-//      struct anova_struct *out);
-//
-///*
-//predict.c
-//*/
-//void
-//predict(double *eval, int m, struct loess_struct *lo, struct pred_struct *pre,
-//        int se);
-//void
-//pred_(double *y, double *x_, double *new_x, int *size_info, double *s,
-//      double *weights, double *robust, double *span, int *degree,
-//      int *normalize, int *parametric, int *drop_square, char **surface,
-//      double *cell, char **family, int *parameter, int *a, double *xi,
-//      double *vert, double *vval, double *divisor, int *se, double *fit,
-//      double *se_fit);
-//void
-//pred_free_mem(struct pred_struct *pre);
+               
+// from misc.c
+void anova(loess *one, loess *two, anova_struct *out);
+void pointwise(prediction *pre, int m, double coverage, conf_inv *ci);     
+void pw_free_mem(conf_inv *ci);
+////
+// from predict.c
+void predict(double *eval, int m, loess *lo, prediction *pre, int se);
+void pred_free_mem(prediction *pre);

Modified: trunk/Lib/sandbox/pyloess/sandbox/src/cloess.pyx
===================================================================
--- trunk/Lib/sandbox/pyloess/sandbox/src/cloess.pyx	2007-03-14 12:34:56 UTC (rev 2846)
+++ trunk/Lib/sandbox/pyloess/sandbox/src/cloess.pyx	2007-03-14 12:46:49 UTC (rev 2847)
@@ -3,85 +3,137 @@
 cimport c_numpy
 from c_numpy cimport ndarray, npy_intp, \
     PyArray_SIZE, PyArray_EMPTY, PyArray_FROMANY, \
-    NPY_INT, NPY_DOUBLE, NPY_OWNDATA, NPY_ALIGNED
-import numpy as _N
+    NPY_INT, NPY_DOUBLE, NPY_OWNDATA, NPY_ALIGNED, NPY_FORTRAN
+import numpy
+
+#narray = _N.array
+#ndouble = _N.float
+#nbool = _N.bool
+
 # NumPy must be initialized
 c_numpy.import_array()
 
 cimport c_loess
+
+
+cdef floatarray_from_data(rows, cols, double *data):
+    cdef ndarray a_ndr
+    cdef double *a_dat
+    a_ndr = numpy.empty((rows*cols,), dtype=numpy.float)
+    a_dat = <double *>a_ndr.data
+    for i from 0 <= i < a_ndr.size:
+        a_dat[i] = data[i]
+    if cols > 1:
+        a_ndr.shape = (rows, cols)
+    return a_ndr
+
+cdef boolarray_from_data(rows, cols, int *data):
+    cdef ndarray a_ndr
+    cdef int *a_dat
+    a_ndr = numpy.empty((rows*cols,), dtype=numpy.int)
+    a_dat = <int *>a_ndr.data
+    for i from 0 <= i < a_ndr.size:
+        a_dat[i] = data[i]
+    if cols > 1:
+        a_ndr.shape = (rows, cols)
+    return a_ndr.astype(numpy.bool)
+
     
 #####---------------------------------------------------------------------------
 #---- ---- loess model ---
 #####---------------------------------------------------------------------------
-
 cdef class loess_inputs:
-    cdef c_loess.c_loess_inputs _inputs
-    cdef public long nobs, nvar
-    cdef readonly ndarray x, y, weights
-    
-    def __init__(self, object x, object y, object weights=None):
-        cdef ndarray x_ndr, y_ndr
-        cdef double *x_dat, *y_in_dat, *w_dat
-        cdef npy_intp n, p
-        cdef npy_intp *dims
-        print "DEBUG: Initializing loess_inputs...",
-        self.x = <ndarray>PyArray_FROMANY(x, NPY_DOUBLE, 1, 1, NPY_OWNDATA)
-        self.y = <ndarray>PyArray_FROMANY(y, NPY_DOUBLE, 1, 1, NPY_OWNDATA)
-        #
-        if self.x.ndim > 2:
-            raise ValueError,"Argument 'x' should be 2D at most!"
-        n = len(self.x)
-        p = self.x.size / n
-        # Initialize the python side ............
-        self.nobs = <long>n
-        self.nvar = <long>p
-        dims[0] = n
-        # ... input weights ...
-        if weights is None:
-            self.weights = <ndarray>PyArray_EMPTY(1, dims, NPY_DOUBLE, NPY_ALIGNED)
-            w_dat = <double *>self.weights.data
-            for i from 0 <= i < dims[0]:
-                w_dat[i] = 1
-        else:
-            self.weights = <ndarray>PyArray_FROMANY(weights, NPY_DOUBLE, 1, 1, NPY_OWNDATA)
-            if self.weights.ndim > 1 or self.weights.size != n:
+    cdef c_loess.c_loess_inputs *_base
+    #.........
+    property x:
+        def __get__(self):
+            return floatarray_from_data(self._base.n, self._base.p, self._base.x)
+    #.........    
+    property y:
+        def __get__(self):
+            return floatarray_from_data(self._base.n, 1, self._base.y)
+    #.........    
+    property weights:
+        "Weights"
+        def __get__(self):
+            return floatarray_from_data(self._base.n, 1, self._base.weights)
+        
+        def __set__(self, w):
+            cdef npy_intp *dims
+            cdef ndarray w_ndr
+            w_ndr = <ndarray>PyArray_FROMANY(w, NPY_DOUBLE, 1, 1, NPY_OWNDATA)
+            if w_ndr.ndim > 1 or w_ndr.size != self._base.n:
                 raise ValueError, "Invalid size of the 'weights' vector!"
-            w_dat = <double *>self.weights.data
-        # Initialize the underlying C object ....
-        self._inputs.n = self.nobs
-        self._inputs.p = self.nvar
-        self._inputs.x = <double *>self.x.data
-        self._inputs.y = <double *>self.y.data
-        self._inputs.weights = <double *>self.weights.data
-        
-#        for i from 0 <= i < (self.nobs*self.nvar):
-#            self._inputs.x[i] = self.x.data[i]
-#        for i from 0 <= i < self.nobs:
-#            self._inputs.y[i] = self.y.data[i]
-#            self._inputs.weights[i] = w_dat[i]
-        print " OK."
-        return
-
-       
-#####---------------------------------------------------------------------------
-#---- ---- loess control ---
-#####---------------------------------------------------------------------------
+            self._base.weights = <double *>w_ndr.data
+    #.........    
+    property nobs:
+        "Number of observations."
+        def __get__(self):
+            return self._base.n
+    #.........
+    property nvar:
+        "Number of independent variables."
+        def __get__(self):
+            return self._base.p
+#       
+######---------------------------------------------------------------------------
+##---- ---- loess control ---
+######---------------------------------------------------------------------------
 cdef class loess_control:
-    cdef c_loess.c_loess_control _control
-    cdef public char *surface, *statistics, *trace_hat
-    cdef public double cell
-    cdef public int iterations
-    
-    def __init__(self):
-        print "DEBUG: Initializing loess_control...",
-        self.surface = self._control.surface = "interpolate"
-        self.statistics = self._control.statistics = "approximate"
-        self.cell = self._control.cell = 0.2
-        self.trace_hat = self._control.trace_hat = "wait.to.decide"
-        self.iterations = self._control.iterations = 4
-        print "OK."
-        return 
-        
+    cdef c_loess.c_loess_control *_base
+    #.........    
+    property surface:
+        def __get__(self):
+            return self._base.surface
+        def __set__(self, surface):
+            self._base.surface = surface
+    #.........
+    property statistics:
+        def __get__(self):
+            return self._base.statistics
+        def __set__(self, statistics):
+            self._base.statistics = statistics
+    #.........
+    property trace_hat:
+        def __get__(self):
+            return self._base.trace_hat
+        def __set__(self, trace_hat):
+            self._base.trace_hat = trace_hat
+    #.........
+    property iterations:
+        def __get__(self):
+            return self._base.iterations
+        def __set__(self, iterations):
+            self._base.iterations = iterations
+    #.........
+    property cell:
+        def __get__(self):
+            return self._base.cell
+        def __set__(self, cell):
+            self._base.cell = cell
+    #.........
+    def update(self, **cellargs):
+        surface = cellargs.get('surface', None)
+        if surface is not None:
+            self.surface = surface
+        #
+        statistics = cellargs.get('statistics', None)
+        if statistics is not None:
+            self.statistics = statistics
+        #    
+        trace_hat = cellargs.get('trace_hat', None)
+        if trace_hat is not None:
+            self.trace_hat = trace_hat
+        #
+        iterations = cellargs.get('iterations', None)
+        if iterations is not None:
+            self.iterations = iterations
+        #
+        cell = cellargs.get('cell', None)
+        if cell is not None:
+            self.parametric_flags = cell
+        #
+    #.........
     def __str__(self):
         strg = ["Control          :",
                 "Surface type     : %s" % self.surface,
@@ -91,43 +143,181 @@
                 "Nb iterations    : %s" % self.iterations,]
         return '\n'.join(strg)
         
-    
+#    
+######---------------------------------------------------------------------------
+##---- ---- loess kd_tree ---
+######---------------------------------------------------------------------------
+cdef class loess_kd_tree:
+    cdef c_loess.c_loess_kd_tree *_base
+#    #.........
+#    property parameter:
+#        def __get__(self):
+#            return self._base.parameter
+#    #.........
+#    property a:
+#        def __get__(self):
+#            return self._base.a
+#    #.........
+#    property vval:
+#        def __get__(self):
+#            return self._base.vert
+#    #.........
+#    property xi:
+#        def __get__(self):
+#            return self._base.xi
+#    #.........
+#    property vert:
+#        def __get__(self):
+#            return self._base.vert
+#        return
+#    
+######---------------------------------------------------------------------------
+##---- ---- loess model ---
+######---------------------------------------------------------------------------
+cdef class loess_model:
+    cdef c_loess.c_loess_model *_base
+    cdef long npar
+    #.........
+    property span:
+        def __get__(self):
+            return self._base.span
+        def __set__(self, span):
+            self._base.span = span
+    #.........
+    property degree:
+        def __get__(self):
+            return self._base.degree
+    #.........
+    property normalize:
+        "Normalize the variables. Only useful if more than one variable..."
+        def __get__(self):
+            return bool(self._base.normalize)
+        def __set__(self, normalize):
+            self._base.normalize = normalize
+    #.........
+    property family:
+        def __get__(self):
+            return self._base.family
+    #.........
+    property parametric_flags:
+        def __get__(self):
+            return boolarray_from_data(8, 1, self._base.parametric)
+        def __set__(self, paramf):
+            cdef ndarray p_ndr
+            cdef long *p_dat
+            cdef int i
+            p_ndr = <ndarray>PyArray_FROMANY(paramf, NPY_LONG, 1, 1, NPY_OWNDATA)
+            p_dat = <long *>p_ndr.data
+            for i in 0 <= i < max(8, p_ndr.size):
+                self._base.parametric[i] = p_dat[i]
+    #.........
+    property drop_square_flags:
+        def __get__(self):
+            return boolarray_from_data(8, 1, self._base.drop_square)
+        def __set__(self, drop_sq):
+            cdef ndarray d_ndr
+            cdef long *d_dat
+            cdef int i
+            d_ndr = <ndarray>PyArray_FROMANY(drop_sq, NPY_LONG, 1, 1, NPY_OWNDATA)
+            d_dat = <long *>d_ndr.data
+            for i in 0 <= i < max(8, d_ndr.size):
+                self._base.drop_square[i] = d_dat[i]
+    #........
+    def update(self, **modelargs):
+        family = modelargs.get('family', None)
+        if family is not None:
+            self.family = family
+        #
+        span = modelargs.get('span', None)
+        if span is not None:
+            self.span = span
+        #    
+        degree = modelargs.get('degree', None)
+        if degree is not None:
+            self.degree = degree
+        #
+        normalize = modelargs.get('normalize', None)
+        if normalize is not None:
+            self.normalize = normalize
+        #
+        parametric = modelargs.get('parametric', None)
+        if parametric is not None:
+            self.parametric_flags = parametric
+        #
+        drop_square = modelargs.get('drop_square', None)
+        if drop_square is not None:
+            self.drop_square_flags = drop_square
+    #.........
+    def __repr__(self):
+        return "loess model parameters @%s" % id(self)
+    #.........
+    def __str__(self):
+        strg = ["Model parameters.....",
+                "family      : %s" % self.family,
+                "span        : %s" % self.span,
+                "degree      : %s" % self.degree,
+                "normalized  : %s" % self.normalize,
+                "parametric  : %s" % self.parametric_flags[:self.npar],
+                "drop_square : %s" % self.drop_square_flags[:self.npar]
+                ]
+        return '\n'.join(strg)
+        
 #####---------------------------------------------------------------------------
 #---- ---- loess outputs ---
 #####---------------------------------------------------------------------------
 cdef class loess_outputs:
-    cdef c_loess.c_loess_outputs _outputs
-    cdef ndarray fitted_values, fitted_residuals, pseudovalues, diagonal, robust, divisor
-    cdef double enp, s, one_delta, two_delta, trace_hat
-    
-    def __init__(self, n, p):
-        cdef npy_intp *rows, *cols
-        #cdef double *fv_dat, *fr_dat, *pv_dat, *diag_dat, *rw_dat, *div_dat
-        rows[0] = <npy_intp>n
-        cols[0] = <npy_intp>p
-        print "DEBUG: Initializing loess_outputs...",
-        # Initialize the python side ............
-        self.fitted_values = <ndarray>PyArray_EMPTY(1, rows, NPY_DOUBLE, NPY_ALIGNED)
-        self.fitted_residuals = <ndarray>PyArray_EMPTY(1, rows, NPY_DOUBLE, NPY_ALIGNED)
-        self.pesudovalues = <ndarray>PyArray_EMPTY(1, rows, NPY_DOUBLE, NPY_ALIGNED)
-        self.diagonal = <ndarray>PyArray_EMPTY(1, rows, NPY_DOUBLE, NPY_ALIGNED)
-        self.robust = <ndarray>PyArray_EMPTY(1, rows, NPY_DOUBLE, NPY_ALIGNED)
-        self.divisor = <ndarray>PyArray_EMPTY(1, cols, NPY_DOUBLE, NPY_ALIGNED)
-        # Initialize the C side .................
-        self._outputs.fitted_values = <double *>self.fitted_values.data
-        self._outputs.fitted_residuals = <double *>self.fitted_residuals.data
-        self._outputs.pseudovalues = <double *>self.pseudovalues.data
-        self._outputs.diagonal = <double *>self.diagonal.data
-        self._outputs.robust = <double *>self.robust.data
-        self._outputs.divisor = <double *>self.divisor.data
-        # Common initialization .................
-        self.enp = self._outputs.enp = 0
-        self.s = self._outputs.s = 0
-        self.one_delta = self._outputs.one_delta = 0
-        self.two_delta = self._outputs.two_delta = 0
-        self.trace_hat = self._outputs.trace_hat = 0 
-        print "OK."   
-        
+    cdef c_loess.c_loess_outputs *_base
+    cdef long nobs
+    #........
+    property fitted_values:
+        def __get__(self):
+            return floatarray_from_data(self.nobs, 1, self._base.fitted_values)
+    #.........
+    property fitted_residuals:
+        def __get__(self):
+            return floatarray_from_data(self.nobs, 1, self._base.fitted_residuals)
+    #.........
+    property pseudovalues:
+        def __get__(self):
+            return floatarray_from_data(self.nobs, 1, self._base.pseudovalues)
+    #.........
+    property diagonal:
+        def __get__(self):
+            return floatarray_from_data(self.nobs, 1, self._base.diagonal)
+    #.........
+    property robust:
+        def __get__(self):
+            return floatarray_from_data(self.nobs, 1, self._base.robust)
+    #.........
+    property divisor:
+        def __get__(self):
+            return floatarray_from_data(self.nobs, 1, self._base.divisor)
+    #.........    
+    property enp:
+        "Equivalent number of parameters."
+        def __get__(self):
+            return self._base.enp
+    #.........
+    property s:
+#        ""
+        def __get__(self):
+            return self._base.s
+    #.........
+    property one_delta:
+#        ""
+        def __get__(self):
+            return self._base.one_delta
+    #.........
+    property two_delta:
+#        ""
+        def __get__(self):
+            return self._base.two_delta
+    #.........
+    property trace_hat:
+#        ""
+        def __get__(self):
+            return self._base.trace_hat
+#    #.........
 #    def __str__(self):
 #        strg = ["Outputs          :",
 #                "enp       : %s" % self.enp,
@@ -135,181 +325,170 @@
 #                "Deltas        : %s/%s" % (self.one_delta, self.two_delta),
 #                "Divisor    : %s" % self.divisor,]
 #        return '\n'.join(strg)
-    
+
+
 #####---------------------------------------------------------------------------
-#---- ---- loess kd_tree ---
+#---- ---- loess anova ---
 #####---------------------------------------------------------------------------
-cdef class loess_kd_tree:
-    cdef c_loess.c_loess_kd_tree _kdtree
-    cdef ndarray parameter, a, xi, vert, vval
-    
-    def __init__(self, long n, long p):
-        cdef long maxkd, nval, nvert
-        cdef npy_intp *nmaxkd, *nnval, *nnvert, *npars
-        #
-        print "DEBUG: Initializing loess_kdtree...",
-        maxkd = max(n, 200)
-        nvert = p * 2
-        nval = (p+1) * maxkd
-        # Initialize the python side ............
-        print "(python side)",
-        nmaxkd[0] = <npy_intp>maxkd
-        nnvert[0] = <npy_intp>nvert
-        nnval[0] = <npy_intp>nval
-        npars[0] = <npy_intp>8
-        self.parameter = <ndarray>PyArray_EMPTY(1, npars, NPY_LONG, NPY_ALIGNED)
-        self.a = <ndarray>PyArray_EMPTY(1, nmaxkd, NPY_LONG, NPY_ALIGNED)
-        self.xi = <ndarray>PyArray_EMPTY(1, nmaxkd, NPY_DOUBLE, NPY_ALIGNED)
-        self.vert = <ndarray>PyArray_EMPTY(1, nnvert, NPY_DOUBLE, NPY_ALIGNED)
-        self.vval = <ndarray>PyArray_EMPTY(1, nnval, NPY_DOUBLE, NPY_ALIGNED)
-#        self.parameter = <ndarray>_N.empty((8,), _N.long, order='F')
-#        self.a = <ndarray>_N.empty((maxkd,), _N.long, order='F')
-#        self.xi = <ndarray>_N.empty((maxkd,), _N.float, order='F')
-#        self.vert = <ndarray>_N.empty((p*2,), _N.float, order='F')
-#        self.vval = <ndarray>_N.empty((nnval,), _N.float, order='F')
-        # Initialize the C side .................
-        print "(C side)",
-        self._kdtree.parameter = <long *>self.parameter.data
-        self._kdtree.a = <long *>self.a.data
-        self._kdtree.xi = <double *>self.xi.data
-        self._kdtree.vert = <double *>self.vert.data
-        self._kdtree.vval = <double *>self.vval.data
-#        # FIXME : Do we need to fill the arrays ?
-#        for i from 0 <= i < 8:
-#            self._kdtree.parameter[i] = 0
-#        for i from 0 <= i < len(self.a):
-#            self._kdtree.a[i] = 0
-#            self._kdtree.xi[i] = 0
-#        for i from 0 <= i < (p*2):
-#            self._kdtree.vert[i] = 0
-#        for i from 0 <= i < nnval:
-#            self._kdtree.vval[i] = 0
-        print "OK."
-        return
-    
+cdef class loess_anova:
+    cdef c_loess.c_anova *_base
+    cdef long nest
+    #.........
+    property dfn:
+        def __get__(self):
+            return self._base.dfn
+    #.........
+    property dfd:
+        def __get__(self):
+            return self._base.dfd
+    #.........
+    property F_value:
+        def __get__(self):
+            return self._base.F_value
+    #.........
+    property Pr_F:
+        def __get__(self):
+            return self._base.Pr_F
+        
 #####---------------------------------------------------------------------------
-#---- ---- loess model ---
+#---- ---- loess confidence ---
 #####---------------------------------------------------------------------------
+cdef class confidence_interval:
+    cdef c_loess.c_conf_inv *_base
+    cdef nest
+    #.........
+    def __dealloc__(self):
+        c_loess.pw_free_mem(self)
+    #.........
+    property fit:
+        def __get__(self):
+            return floatarray_from_data(nest, 1, self._base.fit)
+    #.........
+    property upper:
+        def __get__(self):
+            return floatarray_from_data(nest, 1, self._base.upper)
+    #.........
+    property lower:
+        def __get__(self):
+            return floatarray_from_data(nest, 1, self._base.lower)
 
-cdef class loess_model:
-    cdef c_loess.c_loess_model _model
-    cdef double span
-    cdef int degree, normalize
-    cdef char *family
-#    cdef ndarray parametric_flags, drop_square_flags
-    cdef object parametric_flags, drop_square_flags
-    #
-    def __init__(self, double span=0.75, int degree=2, int normalize=1, 
-                 object parametric_in=False, object drop_square_in=False, 
-                 object family="gaussian"):
-        cdef int i
-        cdef int *parmf_dat, *dropsq_dat
-        cdef npy_intp *npars
-        print "DEBUG: Initializing loess_model...",
-        self.span = self._model.span = span
-        self.degree = self._model.degree = degree
-        self.normalize = self._model.normalize = normalize
-        self.family = self._model.family = family
-        # FIXME : trying to use a ndarray crashes around here....
-        self.parametric_flags = [None]*8
-        if hasattr(parametric_in, '__len__'):
-            for i from 0 <= i < len(parametric_in):
-                self.parametric_flags[i] = parametric_in[i]
-                self._model.parametric[i] = parametric_in[i]
-        else:
-            for i from 0 <= i <=7:
-                self.parametric_flags[i] = parametric_in
-                self._model.parametric[i] = parametric_in
-        #....
-        self.drop_square_flags = [None]*8
-        if hasattr(drop_square_in, '__len__'):
-            for i from 0 <= i < len(drop_square_in):
-                self.drop_square_flags[i] = drop_square_in[i]
-                self._model.drop_square[i] = drop_square_in[i]
-        else:
-            for i from 0 <= i < 8:
-                self.drop_square_flags[i] = drop_square_in
-                self._model.drop_square[i] = drop_square_in
-        print "OK."
-#        npars[0] = 8
-#        self.parametric = <ndarray>PyArray_EMPTY(1, npars, NPY_INT, NPY_ALIGNED)
-#        self.drop_square = <ndarray>PyArray_EMPTY(1, npars, NPY_INT, NPY_ALIGNED)
-#        parmf_dat = <int *>self.parametric_flags.data
-#        dropsq_dat = <int *>self.drop_square_flags.data
-#        for i from 0 <= i < 8:
-#            print "i:%i" % i
-#            parmf_dat[i] = 0
-#            self._model.parametric[i] = parmf_dat[i]
-#            dropsq_dat[i] = 0
-#            self._model.drop_square[i] = dropsq_dat[i]
-#        print "DEBUG: loess_model: initialized"
-        return
-    #
-    def __repr__(self):
-        return "loess model parameters @%s" % id(self)
-    def __str__(self):
-        strg = ["Object      : %s" % self.__name__,
-                "family      : %s" % self._model.family,
-                "span        : %s" % self._model.span,
-                "degree      : %s" % self._model.degree,
-                "normalized  : %s" % self._model.normalize,
-                "parametric  : %s" % self.parametric,
-                "drop_square : %s" % self.drop_square]
-        return '\n'.join(strg)
+#####---------------------------------------------------------------------------
+#---- ---- loess predictions ---
+#####---------------------------------------------------------------------------
+cdef class loess_predicted:
+    cdef c_loess.c_prediction *_base
+    cdef long nest
+    cdef confidence_interval conf_interval
+    #.........
+    def __dealloc__(self):
+        c_loess.pred_free_mem(self._base)
+    #.........
+    property predicted:
+        def __get__(self):
+            return floatarray_from_data(nest, 1, self._base.fit)
+    #.........
+    property predicted_stderr:
+        def __get__(self):
+            return floatarray_from_data(nest, 1, self._base.se_fit)
+    #.........
+    property residual_scale:
+        def __get__(self):
+            return self.residual_scale
+    #.........
+    property df:
+        def __get__(self):
+            return self.df
+    #.........
+    def confidence(self, coverage=0.95):
+        """
+    coverage : float
+        Confidence level of the confidence intervals limits as a fraction.
+        """
+        c_loess.pointwise(self._base, self.nest, coverage,
+                          self.conf_interval._base)
     
+
 #####---------------------------------------------------------------------------
 #---- ---- loess base class ---
 #####---------------------------------------------------------------------------
-
 cdef class loess:
-#    cdef c_loess.c_loess *_base # If we try the pure C way
     cdef c_loess.c_loess _base
-    cdef loess_inputs inputs
-    cdef loess_model model
-    cdef loess_control control
-    cdef loess_kd_tree kd_tree
-    cdef loess_outputs outputs
+    cdef readonly loess_inputs inputs
+    cdef readonly loess_model model
+    cdef readonly loess_control control
+    cdef readonly loess_kd_tree kd_tree
+    cdef readonly loess_outputs outputs
+    cdef readonly loess_predicted predicted
     
     def __init__(self, object x, object y, object weights=None):
         #
         cdef ndarray x_ndr, y_ndr
         cdef double *x_dat, *y_dat
-        cdef long n, p
         cdef int i
         #
-#        print "Try setup"
-#        # CHECK : The following function segfaults :(
-#        c_loess.loess_setup(x_dat, y_dat, n, d, self._base)
-#        # CHECK : So we gonna try the hard way
-        # Initialize the python side ............
-        self.inputs = loess_inputs(x, y, weights)
-        n = self.inputs.nobs
-        p = self.inputs.nvar
+        x_ndr = <ndarray>PyArray_FROMANY(x, NPY_DOUBLE, 1, 1, NPY_FORTRAN)
+        y_ndr = <ndarray>PyArray_FROMANY(y, NPY_DOUBLE, 1, 1, NPY_FORTRAN)
+        x_dat = <double *>x_ndr.data
+        y_dat = <double *>y_ndr.data
+        n = len(x_ndr)
+        p = x_ndr.size / n
+        c_loess.loess_setup(x_dat, y_dat, n, p, &self._base)
+        #
+        self.inputs = loess_inputs()
+        self.inputs._base = &self._base.inputs
+        #
         self.model = loess_model()
+        self.model._base = &self._base.model
+        self.model.npar = p
+        #
         self.control = loess_control()
-        self.outputs = loess_outputs(n,p)
-        self.kd_tree = loess_kd_tree(n,p)
-        # Initialize the C side .................
-        print "DEBUG:Initializing loess_cside"
-        self._base.inputs = self.inputs._inputs
-        self._base.model = self.model._model
-        self._base.control = self.control._control
-        self._base.kd_tree = self.kd_tree._kdtree
-        self._base.outputs = self.outputs._outputs
-
-
-
-#        self.inputs = base.in
-#        self.model = base.model
-#        self.kd_tree = base.kd_tree
-#        self.outputs = base.out
-        
-    
+        self.control._base = &self._base.control
+        #
+        self.kd_tree = loess_kd_tree()
+        self.kd_tree._base = &self._base.kd_tree
+        #
+        self.outputs = loess_outputs()
+        self.outputs._base = &self._base.outputs
+        self.outputs.nobs = n
     #......................................................
+    def fit(self):
+        c_loess.loess_fit(&self._base)
+        return
+    #......................................................
     def summary(self):
-        print "Number of Observations         : %d" % self.inputs.n
+        print "Number of Observations         : %d" % self.inputs.nobs
         print "Equivalent Number of Parameters: %.1f" % self.outputs.enp
         if self.model.family == "gaussian":
             print "Residual Standard Error        : %.4f" % self.outputs.s
         else:
-            print "Residual Scale Estimate        : %.4f" % self.outputs.s
\ No newline at end of file
+            print "Residual Scale Estimate        : %.4f" % self.outputs.s
+    #......................................................
+    def predict(self, newdata, stderr=False):
+        """
+    newdata: ndarray
+        A (m,p) ndarray specifying the values of the predictors at which the 
+        evaluation is to be carried out.
+    stderr: Boolean
+        Logical flag for computing standard errors at newdata.
+        """
+        cdef ndarray p_ndr
+        cdef double *p_dat
+        cdef int i, m
+        #
+        p_ndr = <ndarray>PyArray_FROMANY(newdata, NPY_DOUBLE, 1, self.nvar, NPY_FORTRAN)
+        p_dat = <double *>p_ndr.data
+        m = len(p_ndr)
+        c_loess.predict(p_dat, m, &self._base, self.predicted._base, stderr)
+        self.predicted.nest = m
+    #......................................................
+#    def pointwisevoid(predicted *pre, int m, double coverage,
+#                      struct ci_struct *ci)
+#        c_loess.pointwise(predicted *pre, int m, double coverage,
+#                      struct ci_struct *ci)
+#
+#def anova(loess_one, loess_two):
+#    cdef c_loess.c_anova result
+#    
+#    c_loess.anova(loess_one._base, loess_two._base, &result)
+#        
+        
\ No newline at end of file

Modified: trunk/Lib/sandbox/pyloess/sandbox/src/loess.c
===================================================================
--- trunk/Lib/sandbox/pyloess/sandbox/src/loess.c	2007-03-14 12:34:56 UTC (rev 2846)
+++ trunk/Lib/sandbox/pyloess/sandbox/src/loess.c	2007-03-14 12:46:49 UTC (rev 2847)
@@ -3,10 +3,12 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include <time.h>
+
 static char *surf_stat;
 
 void
-loess_setup(double *x, double *y, int n, int p, loess *lo)
+loess_setup(double *x, double *y, long n, long p, loess *lo)
 {
     int i, max_kd;
 
@@ -43,8 +45,8 @@
     lo->outputs.robust = (double *) malloc(n * sizeof(double));
     lo->outputs.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.parameter = (long *) malloc(7 * sizeof(long));
+    lo->kd_tree.a = (long *) malloc(max_kd * sizeof(long));
     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));
@@ -116,6 +118,12 @@
     int     cut, comp();
     char    *new_stat;
     void    condition();
+    char timestr[30];
+    size_t timestri;
+    struct tm tim;
+    time_t now;
+    now = time(NULL);
+    tim = *(localtime(&now));
 
     D = size_info[0];
     N = size_info[1];
@@ -212,8 +220,10 @@
             *one_delta = delta1;
             *two_delta = delta2;
         }
+        strftime(timestr,30,"%b %d, %Y; %H:%M:%S\n",&tim);
+        printf("%s", timestr);
         for(i = 0; i < N; i++)
-            printf("i:%i y:%.3f f:%.3f\n", i, y[i], fitted_values[i]);
+            printf("%.6f\n", fitted_values[i]);
             fitted_residuals[i] = y[i] - fitted_values[i];
         if(j < (*iterations))
             F77_SUB(lowesw)(fitted_residuals, &N, robust, temp);

Modified: trunk/Lib/sandbox/pyloess/sandbox/src/loess.h
===================================================================
--- trunk/Lib/sandbox/pyloess/sandbox/src/loess.h	2007-03-14 12:34:56 UTC (rev 2846)
+++ trunk/Lib/sandbox/pyloess/sandbox/src/loess.h	2007-03-14 12:46:49 UTC (rev 2847)
@@ -30,8 +30,8 @@
     } loess_control;
 
 typedef struct {
-    int    *parameter;
-    int    *a;
+    long   *parameter;
+    long   *a;
     double *xi;
     double *vert;
     double *vval;
@@ -64,18 +64,18 @@
     double *se_fit;
     double residual_scale;
     double df;
-} predicted;
+    } prediction;
 
-struct anova_struct {
+typedef struct {
     double dfn;
     double dfd;
     double F_value;
     double Pr_F;
-};
+    } anova_struct;
 
-struct ci_struct {
+typedef struct {
     double *fit;
     double *upper;
     double *lower;
-};
+    } conf_inv;
 

Modified: trunk/Lib/sandbox/pyloess/sandbox/src/loessc.c
===================================================================
--- trunk/Lib/sandbox/pyloess/sandbox/src/loessc.c	2007-03-14 12:34:56 UTC (rev 2846)
+++ trunk/Lib/sandbox/pyloess/sandbox/src/loessc.c	2007-03-14 12:46:49 UTC (rev 2847)
@@ -13,7 +13,7 @@
 loess_raw(double *y, double *x, double *weights, double *robust, int *d,
           int*n, double *span, int *degree, int *nonparametric,
           int *drop_square, int *sum_drop_sqr, double *cell, char **surf_stat,
-          double *surface, int *parameter, int *a, double *xi, double *vert,
+          double *surface, long *parameter, long *a, double *xi, double *vert,
           double *vval, double *diagonal, double *trL, double *one_delta,
           double *two_delta, int *setLf)
 {
@@ -116,7 +116,7 @@
     loess_free();
 }
 
-loess_ifit(int *parameter, int *a, double *xi, double *vert, double *vval,
+loess_ifit(long *parameter, long *a, double *xi, double *vert, double *vval,
            int *m, double *x_evaluate, double *fit)
 {
     loess_grow(parameter, a, xi, vert, vval);
@@ -165,7 +165,7 @@
         iv[i + 40] = drop_square[i];
 }
 
-loess_prune(int *parameter, int *a, double *xi, double *vert, double *vval)
+loess_prune(long *parameter, long *a, double *xi, double *vert, double *vval)
 {
     int    d, vc, a1, v1, xi1, vv1, nc, nv, nvmax, i, j, k;
 
@@ -198,7 +198,7 @@
         vval[i] = v[vv1 + i];
 }
 
-loess_grow(int *parameter, int *a, double *xi, double *vert, double *vval)
+loess_grow(long *parameter, long *a, double *xi, double *vert, double *vval)
 {
     int    d, vc, nc, nv, a1, v1, xi1, vv1, i, j, k;
 

Modified: trunk/Lib/sandbox/pyloess/sandbox/src/misc.c
===================================================================
--- trunk/Lib/sandbox/pyloess/sandbox/src/misc.c	2007-03-14 12:34:56 UTC (rev 2846)
+++ trunk/Lib/sandbox/pyloess/sandbox/src/misc.c	2007-03-14 12:46:49 UTC (rev 2847)
@@ -3,24 +3,18 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-static double
-fmin(double a, double b)
+static double fmin(double a, double b)
 {
     return(a < b ? a : b);
 }
 
-static double
-fmax(double a, double b)
+static double fmax(double a, double b)
 {
     return(a > b ? a : b);
 }
 
 
-
-
-void
-anova(loess *one, loess *two,
-      struct anova_struct *out)
+void anova(loess *one, loess *two, anova_struct *out)
 {
     double  one_d1, one_d2, one_s, two_d1, two_d2, two_s,
             rssdiff, d1diff, tmp, pf();
@@ -44,9 +38,7 @@
     out->Pr_F = 1 - pf(out->F_value, out->dfn, out->dfd);
 }
 
-void
-pointwise(predicted *pre, int m, double coverage,
-          struct ci_struct *ci)
+void pointwise(prediction *pre, int m, double coverage, conf_inv *ci)
 {
     double    t_dist, limit, fit, qt();
     int    i;
@@ -64,23 +56,20 @@
     }
 }
 
-void
-pw_free_mem(struct ci_struct *ci)
+void pw_free_mem(conf_inv *ci)
 {
     free(ci->fit);
     free(ci->upper);
     free(ci->lower);
 }
 
-double
-pf(double q, double df1, double df2)
+double pf(double q, double df1, double df2)
 {
     double    ibeta();
     return(ibeta(q*df1/(df2+q*df1), df1/2, df2/2));
 }
 
-double
-qt(double p, double df)
+double qt(double p, double df)
 {
     double    t, invibeta();
     t = invibeta(fabs(2*p-1), 0.5, df/2);
@@ -97,8 +86,7 @@
 #define IBETA_LARGE     1.0e30
 #define IBETA_SMALL     1.0e-30
 
-double
-ibeta(double x, double a, double b)
+double ibeta(double x, double a, double b)
 {
     int flipped = 0, i, k, count;
     double I, temp, pn[6], ak, bk, next, prev, factor, val;
@@ -169,8 +157,7 @@
         0.001308
 };
 
-double
-invigauss_quick(double p)
+double invigauss_quick(double p)
 {
     int lower;
     double t, n, d, q;
@@ -191,8 +178,7 @@
  * Assumption: 0 <= p <= 1, a,b > 0.
  */
 
-double
-invibeta(double p, double a, double b)
+double invibeta(double p, double a, double b)
 {
     int i;
     double ql, qr, qm, qdiff;
@@ -280,8 +266,7 @@
  * Assumption: 0 < p < 1, a,b > 0.
  */
 
-double
-invibeta_quick(double p, double a, double b)
+double invibeta_quick(double p, double a, double b)
 {
     double x, m, s, fmax(), fmin(), invigauss_quick();
 
@@ -291,8 +276,7 @@
     return(fmax(0.0, fmin(1.0, invigauss_quick(p)*s + m)));
 }
 
-int
-max(int a, int b)
+int max(int a, int b)
 {
     return(a > b ? a : b);
 }
@@ -300,15 +284,13 @@
 typedef double doublereal;
 typedef int integer;
 
-void
-Recover(char *a, int *b)
+void Recover(char *a, int *b)
 {
     printf(a);
     exit(1);
 }
 
-void
-Warning(char *a, int *b)
+void Warning(char *a, int *b)
 {
     printf(a);
 }



More information about the Scipy-svn mailing list