[Scipy-svn] r2850 - in trunk/Lib/sandbox/pyloess/sandbox: . src

scipy-svn@scip... scipy-svn@scip...
Mon Mar 19 18:50:35 CDT 2007


Author: pierregm
Date: 2007-03-19 18:50:21 -0500 (Mon, 19 Mar 2007)
New Revision: 2850

Modified:
   trunk/Lib/sandbox/pyloess/sandbox/pyloess.py
   trunk/Lib/sandbox/pyloess/sandbox/src/S.h
   trunk/Lib/sandbox/pyloess/sandbox/src/c_loess.pxd
   trunk/Lib/sandbox/pyloess/sandbox/src/c_python.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/loessf.f
   trunk/Lib/sandbox/pyloess/sandbox/src/misc.c
   trunk/Lib/sandbox/pyloess/sandbox/src/predict.c
Log:
* Add anova
* Prevent the code to exit on Fortran error, raise an exception instead
* Fixed the exception.NameError in confidence_intervals

TODO:
Modify parametric_flags and drop_square on an element-by-element basis

Modified: trunk/Lib/sandbox/pyloess/sandbox/pyloess.py
===================================================================
--- trunk/Lib/sandbox/pyloess/sandbox/pyloess.py	2007-03-16 20:42:51 UTC (rev 2849)
+++ trunk/Lib/sandbox/pyloess/sandbox/pyloess.py	2007-03-19 23:50:21 UTC (rev 2850)
@@ -110,10 +110,10 @@
         (x, y, results, newdata1, newdata2, madeup) = self.d
         madeup.model.span = 0.5
         madeup.model.normalize = True
-        madeup.predict(newdata1, stderr=False)
+        madeup.predict(newdata1, stderror=False)
         assert_almost_equal(madeup.predicted.values, results[4], 5)
         #
-        madeup_pred = madeup.predict(newdata1, stderr=False)
+        madeup_pred = madeup.predict(newdata1, stderror=False)
         assert_almost_equal(madeup_pred.values, results[4], 5)
     #
     def test_2d_pred_nodata(self):
@@ -131,13 +131,13 @@
         (x, y, results, newdata1, newdata2, madeup) = self.d   
         madeup.model.span = 0.5
         madeup.model.normalize = True
-        madeup_pred = madeup.predict(newdata2, stderr=True)
+        madeup_pred = madeup.predict(newdata2, stderror=True)
         assert_almost_equal(madeup_pred.values, results[5], 5)
         assert_almost_equal(madeup_pred.stderr, [0.276746, 0.278009], 5)
         assert_almost_equal(madeup_pred.residual_scale, 0.969302, 6)
         assert_almost_equal(madeup_pred.df, 81.2319, 4)
         # Direct access
-        madeup.predict(newdata2, stderr=True)
+        madeup.predict(newdata2, stderror=True)
         assert_almost_equal(madeup.predicted.values, results[5], 5)
         assert_almost_equal(madeup.predicted.stderr, [0.276746, 0.278009], 5)
         assert_almost_equal(madeup.predicted.residual_scale, 0.969302, 6)
@@ -148,7 +148,7 @@
         (x, y, results, newdata1, newdata2, madeup) = self.d   
         madeup.model.span = 0.5
         madeup.model.normalize = True
-        madeup_pred = madeup.predict(newdata2, stderr=True)        
+        madeup_pred = madeup.predict(newdata2, stderror=True)        
         madeup.predicted.confidence(coverage=0.99)
         assert_almost_equal(madeup.predicted.confidence_intervals.lower, 
                             results[6][::3], 5)
@@ -215,14 +215,14 @@
         (E, NOx, gas_fit_E, newdata, coverage, results) = self.d
         gas = cloess.loess(E,NOx, span=2./3.)
         gas.fit()
-        gas.predict(gas_fit_E, stderr=False)
+        gas.predict(gas_fit_E, stderror=False)
         assert_almost_equal(gas.predicted.values, results[2], 6)
     #
     def test_1dpredict_2(self):
         "Basic test 1d - new predictions"
         (E, NOx, gas_fit_E, newdata, coverage, results) = self.d        
         gas = cloess.loess(E,NOx, span=2./3.)
-        gas.predict(newdata, stderr=True)
+        gas.predict(newdata, stderror=True)
         gas.predicted.confidence(0.99)
         assert_almost_equal(gas.predicted.confidence_intervals.lower,
                             results[3][0::3], 6)
@@ -230,11 +230,59 @@
                             results[3][1::3], 6)
         assert_almost_equal(gas.predicted.confidence_intervals.upper,
                             results[3][2::3], 6)
+    #
+    def test_anova(self):
+        "Tests anova"
+        (E, NOx, gas_fit_E, newdata, coverage, results) = self.d        
+        gas = cloess.loess(E,NOx, span=2./3.)
+        gas.fit()
+        gas_null = cloess.loess(E, NOx, span=1.0)
+        gas_null.fit()
+        gas_anova = cloess.anova(gas, gas_null)
+        gas_anova_theo = results[4]
+        assert_almost_equal(gas_anova.dfn, gas_anova_theo[0], 5)
+        assert_almost_equal(gas_anova.dfd, gas_anova_theo[1], 5)
+        assert_almost_equal(gas_anova.F_value, gas_anova_theo[2], 5)
+        assert_almost_equal(gas_anova.Pr_F, gas_anova_theo[3], 5)
+    #
+    def test_failures(self):
+        "Tests failures"
+        (E, NOx, gas_fit_E, newdata, coverage, results) = self.d       
+        gas = cloess.loess(E,NOx, span=2./3.)
+        # This one should fail (all parametric)
+        gas.model.parametric_flags = True
+        self.assertRaises(ValueError, gas.fit)
+        # This one also (all drop_square)
+        gas.model.drop_square_flags = True
+        self.assertRaises(ValueError, gas.fit)
+        gas.model.degree = 1
+        self.assertRaises(ValueError, gas.fit)
+        # This one should not (revert to std)
+        gas.model.parametric_flags = False
+        gas.model.drop_square_flags = False
+        gas.model.degree = 2
+        gas.fit()
+        # Now, for predict .................
+        gas.predict(gas_fit_E, stderror=False)
+        # This one should fail (extrapolation & blending)
+        self.assertRaises(ValueError, 
+                          gas.predict, gas.predicted.values, stderror=False)
+        # But this one should not ..........
+        gas.predict(gas_fit_E, stderror=False)
+        print "OK"
         
+        
+        
+        
+        
+        
 ########################################################################
 if __name__ == '__main__':
     NumpyTest().run()       
 
+    print "cloess:", dir(cloess)
+#    print "cloess.modelflags", dir(cloess.modelflags)
+
     if 0:
         NOx = N.array([4.818, 2.849, 3.275, 4.691, 4.255, 5.064, 2.118, 4.602,
                        2.286, 0.970, 3.965, 5.344, 3.834, 1.990, 5.199, 5.283,
@@ -243,8 +291,48 @@
                      1.074, 1.148, 1.000, 0.928, 0.767, 0.701, 0.807, 0.902,
                      0.997, 1.224, 1.089, 0.973, 0.980, 0.665])
         gas_fit_E = N.array([0.665, 0.949, 1.224])
-        gas_test = loess(E, NOx, span=2./3.)
-#        gas_test.fit()
-        gas_test.predict(gas_fit_E, stderr=False)
-        gas_test.predict(gas_test.predicted.values, stderr=False)
+        gas = loess(E, NOx, span=2./3.)
+        #
+        gas.model.parametric_flags = True
+        try:
+            gas.fit()
+        except ValueError:
+            pass
+        else:
+            raise AssertionError("ValueError not raised !")
+        
+        
+    #
+    if 0:
+        dfile = open(os.path.join('examples','madeup_data'), 'r')
+        dfile.readline()
+        x = N.fromiter((float(v) for v in dfile.readline().rstrip().split()),
+                        N.float_).reshape(-1,2)
+        dfile.readline()
+        y = N.fromiter((float(v) for v in dfile.readline().rstrip().split()),
+                        N.float_)
+        dfile = open(os.path.join('examples','madeup_data'), 'r')
+        dfile.readline()
+        #
+        rfile = open(os.path.join('examples','madeup_result'), 'r')
+        results = []
+        for i in range(8):
+            rfile.readline()
+            z = N.fromiter((float(v) for v in rfile.readline().rstrip().split()),
+                           N.float_)
+            results.append(z)
+        #
+        newdata1 = N.array([[-2.5, 0.0, 2.5], [0., 0., 0.]])
+        newdata2 = N.array([[-0.5, 0.5], [0., 0.]])
+        #
+        madeup = cloess.loess(x,y)
+        
+        print madeup.model
+        madeup.model.parametric_flags = [True, False]        
+        print madeup.model
+        madeup.model.parametric_flags[0] = False
+        print madeup.model
+        madeup.model.update(family="symmetric",normalize=False)
+        print madeup.model
+        
     
\ No newline at end of file

Modified: trunk/Lib/sandbox/pyloess/sandbox/src/S.h
===================================================================
--- trunk/Lib/sandbox/pyloess/sandbox/src/S.h	2007-03-16 20:42:51 UTC (rev 2849)
+++ trunk/Lib/sandbox/pyloess/sandbox/src/S.h	2007-03-19 23:50:21 UTC (rev 2850)
@@ -27,3 +27,6 @@
 
 #define NULL_ENTRY          ((int *)NULL)
 
+
+
+

Modified: trunk/Lib/sandbox/pyloess/sandbox/src/c_loess.pxd
===================================================================
--- trunk/Lib/sandbox/pyloess/sandbox/src/c_loess.pxd	2007-03-16 20:42:51 UTC (rev 2849)
+++ trunk/Lib/sandbox/pyloess/sandbox/src/c_loess.pxd	2007-03-19 23:50:21 UTC (rev 2850)
@@ -1,6 +1,9 @@
 # -*- Mode: Python -*-  
 
 cdef extern from "loess.h":
+    ctypedef struct c_loess_errstatus "loess_errstatus":
+        int err_status
+        char *err_msg
     ctypedef struct c_loess_inputs "loess_inputs":
         long   n
         long   p
@@ -40,16 +43,17 @@
         c_loess_control control
         c_loess_kd_tree kd_tree
         c_loess_outputs outputs
+        c_loess_errstatus status
     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_anova "anova_struct":
+#        double  dfn
+#        double  dfd
+#        double  F_value
+#        double  Pr_F
     ctypedef struct c_conf_inv "conf_inv":
         double  *fit
         double  *upper
@@ -61,8 +65,11 @@
     void loess_free_mem(c_loess *lo)
     void loess_summary(c_loess *lo)
     #
-    void predict(double *eval, int m, c_loess *lo, c_prediction *pre, int se)
+    void c_predict "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
+    void c_pointwise "pointwise" (c_prediction *pre, int m, double coverage, c_conf_inv *ci)
+    double pf (double q, double df1, double df2)
+    double ibeta (double x, double a, double b)
+    void pw_free_mem (c_conf_inv *ci)
+    

Modified: trunk/Lib/sandbox/pyloess/sandbox/src/c_python.pxd
===================================================================
--- trunk/Lib/sandbox/pyloess/sandbox/src/c_python.pxd	2007-03-16 20:42:51 UTC (rev 2849)
+++ trunk/Lib/sandbox/pyloess/sandbox/src/c_python.pxd	2007-03-19 23:50:21 UTC (rev 2850)
@@ -18,3 +18,5 @@
     void   Py_XINCREF(object o)
     void   Py_XDECREF(object o)
     void   Py_CLEAR(object o) # use instead of decref
+    
+    object PyList_New(int size)

Modified: trunk/Lib/sandbox/pyloess/sandbox/src/cloess.c
===================================================================
--- trunk/Lib/sandbox/pyloess/sandbox/src/cloess.c	2007-03-16 20:42:51 UTC (rev 2849)
+++ trunk/Lib/sandbox/pyloess/sandbox/src/cloess.c	2007-03-19 23:50:21 UTC (rev 2850)
@@ -1,4 +1,4 @@
-/* Generated by Pyrex 0.9.5.1a on Fri Mar 16 16:29:33 2007 */
+/* Generated by Pyrex 0.9.5.1a on Mon Mar 19 19:46:10 2007 */
 
 #include "Python.h"
 #include "structmember.h"
@@ -46,6 +46,8 @@
 
 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
 
+static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
+
 static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, long size);  /*proto*/
 
 static void __Pyx_AddTraceback(char *funcname); /*proto*/
@@ -86,11 +88,17 @@
 
 struct __pyx_obj_6cloess_loess_model {
   PyObject_HEAD
+  struct __pyx_vtabstruct_6cloess_loess_model *__pyx_vtab;
   loess_model (*_base);
   long npar;
 };
 
+struct __pyx_vtabstruct_6cloess_loess_model {
+  PyObject *((*setup)(struct __pyx_obj_6cloess_loess_model *,loess_model (*),long ));
+};
+static struct __pyx_vtabstruct_6cloess_loess_model *__pyx_vtabptr_6cloess_loess_model;
 
+
 struct __pyx_obj_6cloess_loess_outputs {
   PyObject_HEAD
   loess_outputs (*_base);
@@ -100,28 +108,35 @@
 };
 
 
-struct __pyx_obj_6cloess_loess_anova {
-  PyObject_HEAD
-  anova_struct (*_base);
-  long nest;
-};
-
-
 struct __pyx_obj_6cloess_conf_intervals {
   PyObject_HEAD
+  struct __pyx_vtabstruct_6cloess_conf_intervals *__pyx_vtab;
   conf_inv _base;
-  PyObject *nest;
+  PyArrayObject *lower;
+  PyArrayObject *fit;
+  PyArrayObject *upper;
 };
 
+struct __pyx_vtabstruct_6cloess_conf_intervals {
+  PyObject *((*setup)(struct __pyx_obj_6cloess_conf_intervals *,conf_inv ,long ));
+};
+static struct __pyx_vtabstruct_6cloess_conf_intervals *__pyx_vtabptr_6cloess_conf_intervals;
 
+
 struct __pyx_obj_6cloess_loess_predicted {
   PyObject_HEAD
+  struct __pyx_vtabstruct_6cloess_loess_predicted *__pyx_vtab;
   prediction _base;
   long nest;
   struct __pyx_obj_6cloess_conf_intervals *confidence_intervals;
 };
 
+struct __pyx_vtabstruct_6cloess_loess_predicted {
+  PyObject *((*setup)(struct __pyx_obj_6cloess_loess_predicted *,prediction ,long ));
+};
+static struct __pyx_vtabstruct_6cloess_loess_predicted *__pyx_vtabptr_6cloess_loess_predicted;
 
+
 struct __pyx_obj_6cloess_loess {
   PyObject_HEAD
   loess _base;
@@ -135,18 +150,27 @@
   long npar;
 };
 
+
+struct __pyx_obj_6cloess_anova {
+  PyObject_HEAD
+  double dfn;
+  double dfd;
+  double F_value;
+  double Pr_F;
+};
+
 static PyTypeObject *__pyx_ptype_6cloess_loess_inputs = 0;
 static PyTypeObject *__pyx_ptype_6cloess_loess_control = 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_conf_intervals = 0;
 static PyTypeObject *__pyx_ptype_6cloess_loess_predicted = 0;
 static PyTypeObject *__pyx_ptype_6cloess_loess = 0;
-static PyObject *__pyx_k35;
-static PyObject *__pyx_k36;
-static PyObject *__pyx_k37;
+static PyTypeObject *__pyx_ptype_6cloess_anova = 0;
+static PyObject *__pyx_k32;
+static PyObject *__pyx_k33;
+static PyObject *__pyx_k34;
 static PyObject *(__pyx_f_6cloess_floatarray_from_data(int ,int ,double (*))); /*proto*/
 static PyObject *(__pyx_f_6cloess_boolarray_from_data(int ,int ,int (*))); /*proto*/
 
@@ -161,9 +185,9 @@
 static char (__pyx_k6[]) = "\n    trace_hat : string [\"wait.to.decide\"]\n        Determines how the trace of the hat matrix should be computed. The hat\n        matrix is used in the computation of the statistical quantities. \n        If \"exact\", an exact computation is done; this could be slow when the\n        number of observations n becomes large. If \"wait.to.decide\" is selected, \n        then a default is \"exact\" for n < 500 and \"approximate\" otherwise. \n        This option is only useful when the fitted surface is interpolated. If  \n        surface is \"exact\", an exact computation is always done for the trace. \n        Setting trace_hat to \"approximate\" for large dataset will substantially \n        reduce the computation time.\n        ";
 static char (__pyx_k7[]) = "\n    iterations : integer\n        Number of iterations of the robust fitting method. If the family is \n        \"gaussian\", the number of iterations is set to 0.\n        ";
 static char (__pyx_k8[]) = "\n    cell : integer\n        Maximum cell size of the kd-tree. Suppose k = floor(n*cell*span),\n        where n is the number of observations, and span the smoothing parameter.\n        Then, a cell is further divided if the number of observations within it \n        is greater than or equal to k. This option is only used if the surface \n        is interpolated.\n        ";
-static char (__pyx_k9[]) = "Smoothing factor, as a fraction of the number of points to take into\n    account. By default, span=0.75.";
-static char (__pyx_k10[]) = "\n    degree : integer [2]\n        Overall degree of locally-fitted polynomial. 1 is locally-linear \n        fitting and 2 is locally-quadratic fitting.  Degree should be 2 at most.\n        ";
-static char (__pyx_k11[]) = "\n    normalize : boolean [True]\n        Determines whether the independent variables should be normalized.  \n        If True, the normalization is performed by setting the 10% trimmed \n        standard deviation to one. If False, no normalization is carried out. \n        This option is only useful for more than one variable. For spatial\n        coordinates predictors or variables with a common scale, it should be \n        set to False.\n        ";
+static char (__pyx_k9[]) = "\n    normalize : boolean [True]\n        Determines whether the independent variables should be normalized.  \n        If True, the normalization is performed by setting the 10% trimmed \n        standard deviation to one. If False, no normalization is carried out. \n        This option is only useful for more than one variable. For spatial\n        coordinates predictors or variables with a common scale, it should be \n        set to False.\n        ";
+static char (__pyx_k10[]) = "Smoothing factor, as a fraction of the number of points to take into\n    account. By default, span=0.75.";
+static char (__pyx_k11[]) = "\n    degree : integer [2]\n        Overall degree of locally-fitted polynomial. 1 is locally-linear \n        fitting and 2 is locally-quadratic fitting.  Degree should be 2 at most.\n        ";
 static char (__pyx_k12[]) = "\n    family : string [\"gaussian\"]\n        Determines the assumed distribution of the errors. The values are \n        \"gaussian\" or \"symmetric\". If \"gaussian\" is selected, the fit is \n        performed with least-squares. If \"symmetric\" is selected, the fit\n        is performed robustly by redescending M-estimators.\n        ";
 static char (__pyx_k13[]) = "\n    parametric_flags : sequence [ [False]*p ]\n        Indicates which independent variables should be conditionally-parametric\n       (if there are two or more independent variables). The argument should \n       be a sequence of booleans, with the same size as the number of independent \n       variables, specified in the order of the predictor group ordered in x. \n        ";
 static char (__pyx_k14[]) = "\n    drop_square : sequence [ [False]* p]\n        When there are two or more independent variables and when a 2nd order\n        polynomial is used, \"drop_square_flags\" specifies those numeric predictors \n        whose squares should be dropped from the set of fitting variables. \n        The method of specification is the same as for parametric.  \n        ";
@@ -178,19 +202,18 @@
 static char (__pyx_k23[]) = "\n    one_delta: float\n        Statistical parameter used in the computation of standard errors.\n        ";
 static char (__pyx_k24[]) = "\n    two_delta : float\n        Statistical parameter used in the computation of standard errors.\n       ";
 static char (__pyx_k25[]) = "\n    trace_hat : float    \n        Trace of the operator hat matrix.\n        ";
-static char (__pyx_k26[]) = "\n    fit : ndarray\n        The (m,) ndarray of estimated values\n        ";
-static char (__pyx_k27[]) = "\n    upper : ndarray\n        The (m,) ndarray of the upper limits of the pointwise confidence intervals.\n        ";
-static char (__pyx_k28[]) = "\n    lower : ndarray\n        The (m,) ndarray of the lower limits of the pointwise confidence intervals.\n        ";
-static char (__pyx_k29[]) = "\n    values : ndarray\n        The (m,) ndarray of loess values evaluated at newdata\n        ";
-static char (__pyx_k30[]) = "\n    stderr : ndarray\n        The (m,) ndarray of the estimates of the standard error on the estimated\n        values.\n        ";
-static char (__pyx_k31[]) = "\n    residual_scale : float\n        Estimate of the scale of the residuals\n        ";
-static char (__pyx_k32[]) = "\n    df : integer\n        Degrees of freedom of the t-distribution used to compute pointwise \n        confidence intervals for the evaluated surface.\n        ";
-static char (__pyx_k34[]) = "\n:Keywords:\n    x : ndarray\n        A (n,p) ndarray of independent variables, with n the number of observations\n        and p the number of variables.\n    y : ndarray\n        A (n,) ndarray of observations\n    weights : ndarray\n        A (n,) ndarray of weights to be given to individual observations in the \n        sum of squared residuals that forms the local fitting criterion. If not\n        None, the weights should be non negative. If the different observations\n        have non-equal variances, the weights should be inversely proportional \n        to the variances.\n        By default, an unweighted fit is carried out (all the weights are one).\n    surface : string [\"interpolate\"]\n        Determines whether the fitted surface is computed directly at all points\n        (\"direct\") or whether an interpolation method is used (\"interpolate\").\n        The default (\"interpolate\") is what most users should use unless special \n        circumstances warrant.\n    statistics : string [\"approximate\"]\n        Determines whether the statistical quantities are computed exactly \n        (\"exact\") or approximately (\"approximate\"). \"exact\" should only be used \n        for testing the approximation in statistical development and is not meant \n        for routine usage because computation time can be horrendous.\n    trace_hat : string [\"wait.to.decide\"]\n        Determines how the trace of the hat matrix should be computed. The hat\n        matrix is used in the computation of the statistical quantities. \n        If \"exact\", an exact computation is done; this could be slow when the\n        number of observations n becomes large. If \"wait.to.decide\" is selected, \n        then a default is \"exact\" for n < 500 and \"approximate\" otherwise. \n        This option is only useful when the fitted surface is interpolated. If  \n        surface is \"exact\", an exact computation is always done for the trace. \n        Setting trace_hat to \"approximate\" for large dataset will substantially \n        reduce the computation time.\n    iterations : integer\n        Number of iterations of the robust fitting method. If the family is \n        \"gaussian\", the number of iterations is set to 0.\n    cell : integer\n        Maximum cell size of the kd-tree. Suppose k = floor(n*cell*span),\n        where n is the number of observations, and span the smoothing parameter.\n        Then, a cell is further divided if the number of observations within it \n        is greater than or equal to k. This option is only used if the surface \n        is interpolated.\n    span : float [0.75]\n        Smoothing factor, as a fraction of the number of points to take into\n        account. \n    degree : integer [2]\n        Overall degree of locally-fitted polynomial. 1 is locally-linear \n        fitting and 2 is locally-quadratic fitting.  Degree should be 2 at most.\n    normalize : boolean [True]\n        Determines whether the independent variables should be normalized.  \n        If True, the normalization is performed by setting the 10% trimmed \n        standard deviation to one. If False, no normalization is carried out. \n        This option is only useful for more than one variable. For spatial\n        coordinates predictors or variables with a common scale, it should be \n        set to False.\n    family : string [\"gaussian\"]\n        Determines the assumed distribution of the errors. The values are \n        \"gaussian\" or \"symmetric\". If \"gaussian\" is selected, the fit is \n        performed with least-squares. If \"symmetric\" is selected, the fit\n        is performed robustly by redescending M-estimators.\n    parametric_flags : sequence [ [False]*p ]\n        Indicates which independent variables should be conditionally-parametric\n       (if there are two or more independent variables). The argument should \n       be a sequence of booleans, with the same size as the number of independent \n       variables, specified in the order of the predictor group ordered in x. \n    drop_square : sequence [ [False]* p]\n        When there are two or more independent variables and when a 2nd order\n        polynomial is used, \"drop_square_flags\" specifies those numeric predictors \n        whose squares should be dropped from the set of fitting variables. \n        The method of specification is the same as for parametric.  \n        \n:Outputs:\n    fitted_values : ndarray\n        The (n,) ndarray of fitted values.\n    fitted_residuals : ndarray\n        The (n,) ndarray of fitted residuals (observations - fitted values).\n    enp : float\n        Equivalent number of parameters.\n    s : float\n        Estimate of the scale of residuals.\n    one_delta: float\n        Statistical parameter used in the computation of standard errors.\n    two_delta : float\n        Statistical parameter used in the computation of standard errors.\n    pseudovalues : ndarray\n        The (n,) ndarray of adjusted values of the response when robust estimation \n        is used.\n    trace_hat : float    \n        Trace of the operator hat matrix.\n    diagonal :\n        Diagonal of the operator hat matrix.\n    robust : ndarray\n        The (n,) ndarray of robustness weights for robust fitting.\n    divisor : ndarray\n        The (p,) array of normalization divisors for numeric predictors.\n        \n\n    newdata : ndarray\n        The (m,p) array of independent variables where the surface must be estimated.\n    values : ndarray\n        The (m,) ndarray of loess values evaluated at newdata\n    stderr : ndarray\n        The (m,) ndarray of the estimates of the standard error on the estimated\n        values.\n    residual_scale : float\n        Estimate of the scale of the residuals\n    df : integer\n        Degrees of freedom of the t-distribution used to compute pointwise \n        confidence intervals for the evaluated surface.\n    nest : integer\n        Number of new observations.\n       \n        \n";
+static char (__pyx_k26[]) = "\n    values : ndarray\n        The (m,) ndarray of loess values evaluated at newdata\n        ";
+static char (__pyx_k27[]) = "\n    stderr : ndarray\n        The (m,) ndarray of the estimates of the standard error on the estimated\n        values.\n        ";
+static char (__pyx_k28[]) = "\n    residual_scale : float\n        Estimate of the scale of the residuals\n        ";
+static char (__pyx_k29[]) = "\n    df : integer\n        Degrees of freedom of the t-distribution used to compute pointwise \n        confidence intervals for the evaluated surface.\n        ";
+static char (__pyx_k31[]) = "\n:Keywords:\n    x : ndarray\n        A (n,p) ndarray of independent variables, with n the number of observations\n        and p the number of variables.\n    y : ndarray\n        A (n,) ndarray of observations\n    weights : ndarray\n        A (n,) ndarray of weights to be given to individual observations in the \n        sum of squared residuals that forms the local fitting criterion. If not\n        None, the weights should be non negative. If the different observations\n        have non-equal variances, the weights should be inversely proportional \n        to the variances.\n        By default, an unweighted fit is carried out (all the weights are one).\n    surface : string [\"interpolate\"]\n        Determines whether the fitted surface is computed directly at all points\n        (\"direct\") or whether an interpolation method is used (\"interpolate\").\n        The default (\"interpolate\") is what most users should use unless special \n        circumstances warrant.\n    statistics : string [\"approximate\"]\n        Determines whether the statistical quantities are computed exactly \n        (\"exact\") or approximately (\"approximate\"). \"exact\" should only be used \n        for testing the approximation in statistical development and is not meant \n        for routine usage because computation time can be horrendous.\n    trace_hat : string [\"wait.to.decide\"]\n        Determines how the trace of the hat matrix should be computed. The hat\n        matrix is used in the computation of the statistical quantities. \n        If \"exact\", an exact computation is done; this could be slow when the\n        number of observations n becomes large. If \"wait.to.decide\" is selected, \n        then a default is \"exact\" for n < 500 and \"approximate\" otherwise. \n        This option is only useful when the fitted surface is interpolated. If  \n        surface is \"exact\", an exact computation is always done for the trace. \n        Setting trace_hat to \"approximate\" for large dataset will substantially \n        reduce the computation time.\n    iterations : integer\n        Number of iterations of the robust fitting method. If the family is \n        \"gaussian\", the number of iterations is set to 0.\n    cell : integer\n        Maximum cell size of the kd-tree. Suppose k = floor(n*cell*span),\n        where n is the number of observations, and span the smoothing parameter.\n        Then, a cell is further divided if the number of observations within it \n        is greater than or equal to k. This option is only used if the surface \n        is interpolated.\n    span : float [0.75]\n        Smoothing factor, as a fraction of the number of points to take into\n        account. \n    degree : integer [2]\n        Overall degree of locally-fitted polynomial. 1 is locally-linear \n        fitting and 2 is locally-quadratic fitting.  Degree should be 2 at most.\n    normalize : boolean [True]\n        Determines whether the independent variables should be normalized.  \n        If True, the normalization is performed by setting the 10% trimmed \n        standard deviation to one. If False, no normalization is carried out. \n        This option is only useful for more than one variable. For spatial\n        coordinates predictors or variables with a common scale, it should be \n        set to False.\n    family : string [\"gaussian\"]\n        Determines the assumed distribution of the errors. The values are \n        \"gaussian\" or \"symmetric\". If \"gaussian\" is selected, the fit is \n        performed with least-squares. If \"symmetric\" is selected, the fit\n        is performed robustly by redescending M-estimators.\n    parametric_flags : sequence [ [False]*p ]\n        Indicates which independent variables should be conditionally-parametric\n       (if there are two or more independent variables). The argument should \n       be a sequence of booleans, with the same size as the number of independent \n       variables, specified in the order of the predictor group ordered in x. \n    drop_square : sequence [ [False]* p]\n        When there are two or more independent variables and when a 2nd order\n        polynomial is used, \"drop_square_flags\" specifies those numeric predictors \n        whose squares should be dropped from the set of fitting variables. \n        The method of specification is the same as for parametric.  \n        \n:Outputs:\n    fitted_values : ndarray\n        The (n,) ndarray of fitted values.\n    fitted_residuals : ndarray\n        The (n,) ndarray of fitted residuals (observations - fitted values).\n    enp : float\n        Equivalent number of parameters.\n    s : float\n        Estimate of the scale of residuals.\n    one_delta: float\n        Statistical parameter used in the computation of standard errors.\n    two_delta : float\n        Statistical parameter used in the computation of standard errors.\n    pseudovalues : ndarray\n        The (n,) ndarray of adjusted values of the response when robust estimation \n        is used.\n    trace_hat : float    \n        Trace of the operator hat matrix.\n    diagonal :\n        Diagonal of the operator hat matrix.\n    robust : ndarray\n        The (n,) ndarray of robustness weights for robust fitting.\n    divisor : ndarray\n        The (p,) array of normalization divisors for numeric predictors.\n        \n\n    newdata : ndarray\n        The (m,p) array of independent variables where the surface must be estimated.\n    values : ndarray\n        The (m,) ndarray of loess values evaluated at newdata\n    stderr : ndarray\n        The (m,) ndarray of the estimates of the standard error on the estimated\n        values.\n    residual_scale : float\n        Estimate of the scale of the residuals\n    df : integer\n        Degrees of freedom of the t-distribution used to compute pointwise \n        confidence intervals for the evaluated surface.\n    nest : integer\n        Number of new observations.\n       \n        \n";
 
 static PyObject *__pyx_n_c_python;
 static PyObject *__pyx_n_c_numpy;
 static PyObject *__pyx_n_numpy;
+static PyObject *__pyx_n_narray;
 static PyObject *__pyx_n_c_loess;
+static PyObject *__pyx_n_array;
 static PyObject *__pyx_n_False;
 
 static PyObject *__pyx_n_shape;
@@ -205,36 +228,36 @@
   PyObject *__pyx_4 = 0;
   __pyx_v_a_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":23 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":19 */
   __pyx_v_size = (__pyx_v_rows * __pyx_v_cols);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":24 */
-  __pyx_1 = PyArray_SimpleNewFromData(1,(&__pyx_v_size),NPY_DOUBLE,__pyx_v_data); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; goto __pyx_L1;}
-  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_7c_numpy_ndarray)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":20 */
+  __pyx_1 = PyArray_SimpleNewFromData(1,(&__pyx_v_size),NPY_DOUBLE,__pyx_v_data); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_7c_numpy_ndarray)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; goto __pyx_L1;}
   Py_INCREF(((PyObject *)__pyx_1));
   Py_DECREF(((PyObject *)__pyx_v_a_ndr));
   __pyx_v_a_ndr = ((PyArrayObject *)((PyObject *)__pyx_1));
   Py_DECREF(__pyx_1); __pyx_1 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":29 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":21 */
   __pyx_2 = (__pyx_v_cols > 1);
   if (__pyx_2) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":30 */
-    __pyx_1 = PyInt_FromLong(__pyx_v_rows); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; goto __pyx_L1;}
-    __pyx_3 = PyInt_FromLong(__pyx_v_cols); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; goto __pyx_L1;}
-    __pyx_4 = PyTuple_New(2); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":22 */
+    __pyx_1 = PyInt_FromLong(__pyx_v_rows); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
+    __pyx_3 = PyInt_FromLong(__pyx_v_cols); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(2); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
     PyTuple_SET_ITEM(__pyx_4, 0, __pyx_1);
     PyTuple_SET_ITEM(__pyx_4, 1, __pyx_3);
     __pyx_1 = 0;
     __pyx_3 = 0;
-    if (PyObject_SetAttr(((PyObject *)__pyx_v_a_ndr), __pyx_n_shape, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; goto __pyx_L1;}
+    if (PyObject_SetAttr(((PyObject *)__pyx_v_a_ndr), __pyx_n_shape, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
     Py_DECREF(__pyx_4); __pyx_4 = 0;
     goto __pyx_L2;
   }
   __pyx_L2:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":31 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":23 */
   Py_INCREF(((PyObject *)__pyx_v_a_ndr));
   __pyx_r = ((PyObject *)__pyx_v_a_ndr);
   goto __pyx_L0;
@@ -265,44 +288,44 @@
   PyObject *__pyx_4 = 0;
   __pyx_v_a_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":36 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":28 */
   __pyx_v_size = (__pyx_v_rows * __pyx_v_cols);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":39 */
-  __pyx_1 = PyArray_SimpleNewFromData(1,(&__pyx_v_size),NPY_DOUBLE,__pyx_v_data); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; goto __pyx_L1;}
-  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_7c_numpy_ndarray)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":29 */
+  __pyx_1 = PyArray_SimpleNewFromData(1,(&__pyx_v_size),NPY_DOUBLE,__pyx_v_data); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_7c_numpy_ndarray)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; goto __pyx_L1;}
   Py_INCREF(((PyObject *)__pyx_1));
   Py_DECREF(((PyObject *)__pyx_v_a_ndr));
   __pyx_v_a_ndr = ((PyArrayObject *)((PyObject *)__pyx_1));
   Py_DECREF(__pyx_1); __pyx_1 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":43 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":30 */
   __pyx_2 = (__pyx_v_cols > 1);
   if (__pyx_2) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":44 */
-    __pyx_1 = PyInt_FromLong(__pyx_v_rows); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; goto __pyx_L1;}
-    __pyx_3 = PyInt_FromLong(__pyx_v_cols); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; goto __pyx_L1;}
-    __pyx_4 = PyTuple_New(2); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":31 */
+    __pyx_1 = PyInt_FromLong(__pyx_v_rows); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; goto __pyx_L1;}
+    __pyx_3 = PyInt_FromLong(__pyx_v_cols); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(2); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; goto __pyx_L1;}
     PyTuple_SET_ITEM(__pyx_4, 0, __pyx_1);
     PyTuple_SET_ITEM(__pyx_4, 1, __pyx_3);
     __pyx_1 = 0;
     __pyx_3 = 0;
-    if (PyObject_SetAttr(((PyObject *)__pyx_v_a_ndr), __pyx_n_shape, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; goto __pyx_L1;}
+    if (PyObject_SetAttr(((PyObject *)__pyx_v_a_ndr), __pyx_n_shape, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; goto __pyx_L1;}
     Py_DECREF(__pyx_4); __pyx_4 = 0;
     goto __pyx_L2;
   }
   __pyx_L2:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":45 */
-  __pyx_1 = PyObject_GetAttr(((PyObject *)__pyx_v_a_ndr), __pyx_n_astype); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; goto __pyx_L1;}
-  __pyx_3 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; goto __pyx_L1;}
-  __pyx_4 = PyObject_GetAttr(__pyx_3, __pyx_n_bool); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":32 */
+  __pyx_1 = PyObject_GetAttr(((PyObject *)__pyx_v_a_ndr), __pyx_n_astype); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; goto __pyx_L1;}
+  __pyx_3 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; goto __pyx_L1;}
+  __pyx_4 = PyObject_GetAttr(__pyx_3, __pyx_n_bool); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; goto __pyx_L1;}
   Py_DECREF(__pyx_3); __pyx_3 = 0;
-  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; goto __pyx_L1;}
   PyTuple_SET_ITEM(__pyx_3, 0, __pyx_4);
   __pyx_4 = 0;
-  __pyx_4 = PyObject_CallObject(__pyx_1, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; goto __pyx_L1;}
+  __pyx_4 = PyObject_CallObject(__pyx_1, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   Py_DECREF(__pyx_3); __pyx_3 = 0;
   __pyx_r = __pyx_4;
@@ -328,8 +351,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":173 */
-  __pyx_1 = __pyx_f_6cloess_floatarray_from_data(((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->n,((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->p,((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->x); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":198 */
+  __pyx_1 = __pyx_f_6cloess_floatarray_from_data(((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->n,((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->p,((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->x); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 198; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -351,8 +374,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":177 */
-  __pyx_1 = __pyx_f_6cloess_floatarray_from_data(((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->n,1,((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->y); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":202 */
+  __pyx_1 = __pyx_f_6cloess_floatarray_from_data(((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->n,1,((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->y); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 202; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -374,8 +397,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":188 */
-  __pyx_1 = __pyx_f_6cloess_floatarray_from_data(((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->n,1,((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->weights); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":213 */
+  __pyx_1 = __pyx_f_6cloess_floatarray_from_data(((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->n,1,((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->weights); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 213; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -395,9 +418,9 @@
 static PyObject *__pyx_n_size;
 static PyObject *__pyx_n_ValueError;
 
-static PyObject *__pyx_k38p;
+static PyObject *__pyx_k35p;
 
-static char (__pyx_k38[]) = "Invalid size of the 'weights' vector!";
+static char (__pyx_k35[]) = "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) {
@@ -410,40 +433,40 @@
   Py_INCREF(__pyx_v_w);
   __pyx_v_w_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":193 */
-  __pyx_1 = PyArray_FROMANY(__pyx_v_w,NPY_DOUBLE,1,1,NPY_OWNDATA); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":218 */
+  __pyx_1 = PyArray_FROMANY(__pyx_v_w,NPY_DOUBLE,1,1,NPY_OWNDATA); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; 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":194 */
-  __pyx_1 = PyObject_GetAttr(((PyObject *)__pyx_v_w_ndr), __pyx_n_ndim); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; goto __pyx_L1;}
-  __pyx_3 = PyInt_FromLong(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; goto __pyx_L1;}
-  if (PyObject_Cmp(__pyx_1, __pyx_3, &__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":219 */
+  __pyx_1 = PyObject_GetAttr(((PyObject *)__pyx_v_w_ndr), __pyx_n_ndim); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; goto __pyx_L1;}
+  __pyx_3 = PyInt_FromLong(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_1, __pyx_3, &__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; 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 = 194; 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 = 194; goto __pyx_L1;}
-    if (PyObject_Cmp(__pyx_1, __pyx_3, &__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; goto __pyx_L1;}
+    __pyx_1 = PyObject_GetAttr(((PyObject *)__pyx_v_w_ndr), __pyx_n_size); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; 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 = 219; goto __pyx_L1;}
+    if (PyObject_Cmp(__pyx_1, __pyx_3, &__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; 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) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":195 */
-    __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 195; goto __pyx_L1;}
-    __Pyx_Raise(__pyx_1, __pyx_k38p, 0);
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":220 */
+    __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 220; goto __pyx_L1;}
+    __Pyx_Raise(__pyx_1, __pyx_k35p, 0);
     Py_DECREF(__pyx_1); __pyx_1 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 195; goto __pyx_L1;}
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 220; goto __pyx_L1;}
     goto __pyx_L2;
   }
   __pyx_L2:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":196 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":221 */
   ((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->weights = ((double (*))__pyx_v_w_ndr->data);
 
   __pyx_r = 0;
@@ -466,8 +489,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":201 */
-  __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 = 201; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":226 */
+  __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 = 226; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -489,8 +512,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":206 */
-  __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 = 206; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":231 */
+  __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 = 231; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -512,8 +535,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":223 */
-  __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 = 223; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":248 */
+  __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 = 248; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -533,11 +556,11 @@
 static PyObject *__pyx_n_interpolate;
 static PyObject *__pyx_n_direct;
 
-static PyObject *__pyx_k41p;
-static PyObject *__pyx_k42p;
+static PyObject *__pyx_k38p;
+static PyObject *__pyx_k39p;
 
-static char (__pyx_k41[]) = "Invalid value for the 'surface' argument: ";
-static char (__pyx_k42[]) = "should be in ('interpolate', 'direct').";
+static char (__pyx_k38[]) = "Invalid value for the 'surface' argument: ";
+static char (__pyx_k39[]) = "should be in ('interpolate', 'direct').";
 
 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) {
@@ -552,47 +575,47 @@
   Py_INCREF(__pyx_v_surface);
   __pyx_v_tmpx = Py_None; Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":225 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_surface, __pyx_n_lower); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; goto __pyx_L1;}
-  __pyx_2 = PyObject_CallObject(__pyx_1, 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":250 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_surface, __pyx_n_lower); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; goto __pyx_L1;}
+  __pyx_2 = PyObject_CallObject(__pyx_1, 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyTuple_New(2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; goto __pyx_L1;}
+  __pyx_1 = PyTuple_New(2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; goto __pyx_L1;}
   Py_INCREF(__pyx_n_interpolate);
   PyTuple_SET_ITEM(__pyx_1, 0, __pyx_n_interpolate);
   Py_INCREF(__pyx_n_direct);
   PyTuple_SET_ITEM(__pyx_1, 1, __pyx_n_direct);
-  __pyx_3 = PySequence_Contains(__pyx_1, __pyx_2); if (__pyx_3 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; goto __pyx_L1;}
+  __pyx_3 = PySequence_Contains(__pyx_1, __pyx_2); if (__pyx_3 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; goto __pyx_L1;}
   __pyx_3 = !__pyx_3;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   if (__pyx_3) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":226 */
-    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; goto __pyx_L1;}
-    __pyx_1 = PyNumber_Add(__pyx_k41p, __pyx_k42p); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; goto __pyx_L1;}
-    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":251 */
+    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; goto __pyx_L1;}
+    __pyx_1 = PyNumber_Add(__pyx_k38p, __pyx_k39p); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; goto __pyx_L1;}
     PyTuple_SET_ITEM(__pyx_4, 0, __pyx_1);
     __pyx_1 = 0;
-    __pyx_1 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; goto __pyx_L1;}
+    __pyx_1 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; goto __pyx_L1;}
     Py_DECREF(__pyx_2); __pyx_2 = 0;
     Py_DECREF(__pyx_4); __pyx_4 = 0;
     __Pyx_Raise(__pyx_1, 0, 0);
     Py_DECREF(__pyx_1); __pyx_1 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; goto __pyx_L1;}
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; goto __pyx_L1;}
     goto __pyx_L2;
   }
   __pyx_L2:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":228 */
-  __pyx_2 = PyObject_GetAttr(__pyx_v_surface, __pyx_n_lower); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 228; goto __pyx_L1;}
-  __pyx_4 = PyObject_CallObject(__pyx_2, 0); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 228; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":253 */
+  __pyx_2 = PyObject_GetAttr(__pyx_v_surface, __pyx_n_lower); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; goto __pyx_L1;}
+  __pyx_4 = PyObject_CallObject(__pyx_2, 0); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; goto __pyx_L1;}
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_v_tmpx);
   __pyx_v_tmpx = __pyx_4;
   __pyx_4 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":229 */
-  __pyx_5 = PyString_AsString(__pyx_v_tmpx); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 229; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":254 */
+  __pyx_5 = PyString_AsString(__pyx_v_tmpx); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 254; goto __pyx_L1;}
   ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->surface = __pyx_5;
 
   __pyx_r = 0;
@@ -616,8 +639,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":240 */
-  __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 = 240; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":265 */
+  __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 = 265; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -636,9 +659,9 @@
 static PyObject *__pyx_n_approximate;
 static PyObject *__pyx_n_exact;
 
-static PyObject *__pyx_k45p;
+static PyObject *__pyx_k42p;
 
-static char (__pyx_k45[]) = "Invalid value for the 'statistics' argument: should be in ('approximate', 'exact').";
+static char (__pyx_k42[]) = "Invalid value for the 'statistics' argument: should be in ('approximate', 'exact').";
 
 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) {
@@ -653,46 +676,46 @@
   Py_INCREF(__pyx_v_statistics);
   __pyx_v_tmpx = Py_None; Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":242 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_statistics, __pyx_n_lower); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; goto __pyx_L1;}
-  __pyx_2 = PyObject_CallObject(__pyx_1, 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":267 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_statistics, __pyx_n_lower); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; goto __pyx_L1;}
+  __pyx_2 = PyObject_CallObject(__pyx_1, 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyTuple_New(2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; goto __pyx_L1;}
+  __pyx_1 = PyTuple_New(2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; goto __pyx_L1;}
   Py_INCREF(__pyx_n_approximate);
   PyTuple_SET_ITEM(__pyx_1, 0, __pyx_n_approximate);
   Py_INCREF(__pyx_n_exact);
   PyTuple_SET_ITEM(__pyx_1, 1, __pyx_n_exact);
-  __pyx_3 = PySequence_Contains(__pyx_1, __pyx_2); if (__pyx_3 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; goto __pyx_L1;}
+  __pyx_3 = PySequence_Contains(__pyx_1, __pyx_2); if (__pyx_3 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; goto __pyx_L1;}
   __pyx_3 = !__pyx_3;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   if (__pyx_3) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":243 */
-    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; goto __pyx_L1;}
-    __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; goto __pyx_L1;}
-    Py_INCREF(__pyx_k45p);
-    PyTuple_SET_ITEM(__pyx_1, 0, __pyx_k45p);
-    __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":268 */
+    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; goto __pyx_L1;}
+    __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; goto __pyx_L1;}
+    Py_INCREF(__pyx_k42p);
+    PyTuple_SET_ITEM(__pyx_1, 0, __pyx_k42p);
+    __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; goto __pyx_L1;}
     Py_DECREF(__pyx_2); __pyx_2 = 0;
     Py_DECREF(__pyx_1); __pyx_1 = 0;
     __Pyx_Raise(__pyx_4, 0, 0);
     Py_DECREF(__pyx_4); __pyx_4 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; goto __pyx_L1;}
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; goto __pyx_L1;}
     goto __pyx_L2;
   }
   __pyx_L2:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":245 */
-  __pyx_2 = PyObject_GetAttr(__pyx_v_statistics, __pyx_n_lower); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 245; goto __pyx_L1;}
-  __pyx_1 = PyObject_CallObject(__pyx_2, 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 245; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":270 */
+  __pyx_2 = PyObject_GetAttr(__pyx_v_statistics, __pyx_n_lower); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; goto __pyx_L1;}
+  __pyx_1 = PyObject_CallObject(__pyx_2, 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; goto __pyx_L1;}
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_v_tmpx);
   __pyx_v_tmpx = __pyx_1;
   __pyx_1 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":246 */
-  __pyx_5 = PyString_AsString(__pyx_v_tmpx); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 246; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":271 */
+  __pyx_5 = PyString_AsString(__pyx_v_tmpx); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; goto __pyx_L1;}
   ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->statistics = __pyx_5;
 
   __pyx_r = 0;
@@ -716,8 +739,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":262 */
-  __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 = 262; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":287 */
+  __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 = 287; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -733,9 +756,9 @@
   return __pyx_r;
 }
 
-static PyObject *__pyx_k48p;
+static PyObject *__pyx_k45p;
 
-static char (__pyx_k48[]) = "Invalid value for the 'trace_hat' argument: should be in ('approximate', 'exact').";
+static char (__pyx_k45[]) = "Invalid value for the 'trace_hat' argument: should be in ('approximate', 'exact').";
 
 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) {
@@ -750,46 +773,46 @@
   Py_INCREF(__pyx_v_trace_hat);
   __pyx_v_tmpx = Py_None; Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":264 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_trace_hat, __pyx_n_lower); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; goto __pyx_L1;}
-  __pyx_2 = PyObject_CallObject(__pyx_1, 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":289 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_trace_hat, __pyx_n_lower); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; goto __pyx_L1;}
+  __pyx_2 = PyObject_CallObject(__pyx_1, 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyTuple_New(2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; goto __pyx_L1;}
+  __pyx_1 = PyTuple_New(2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; goto __pyx_L1;}
   Py_INCREF(__pyx_n_approximate);
   PyTuple_SET_ITEM(__pyx_1, 0, __pyx_n_approximate);
   Py_INCREF(__pyx_n_exact);
   PyTuple_SET_ITEM(__pyx_1, 1, __pyx_n_exact);
-  __pyx_3 = PySequence_Contains(__pyx_1, __pyx_2); if (__pyx_3 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; goto __pyx_L1;}
+  __pyx_3 = PySequence_Contains(__pyx_1, __pyx_2); if (__pyx_3 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; goto __pyx_L1;}
   __pyx_3 = !__pyx_3;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   if (__pyx_3) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":265 */
-    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 265; goto __pyx_L1;}
-    __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 265; goto __pyx_L1;}
-    Py_INCREF(__pyx_k48p);
-    PyTuple_SET_ITEM(__pyx_1, 0, __pyx_k48p);
-    __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 265; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":290 */
+    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; goto __pyx_L1;}
+    __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; goto __pyx_L1;}
+    Py_INCREF(__pyx_k45p);
+    PyTuple_SET_ITEM(__pyx_1, 0, __pyx_k45p);
+    __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; goto __pyx_L1;}
     Py_DECREF(__pyx_2); __pyx_2 = 0;
     Py_DECREF(__pyx_1); __pyx_1 = 0;
     __Pyx_Raise(__pyx_4, 0, 0);
     Py_DECREF(__pyx_4); __pyx_4 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 265; goto __pyx_L1;}
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; goto __pyx_L1;}
     goto __pyx_L2;
   }
   __pyx_L2:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":267 */
-  __pyx_2 = PyObject_GetAttr(__pyx_v_trace_hat, __pyx_n_lower); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; goto __pyx_L1;}
-  __pyx_1 = PyObject_CallObject(__pyx_2, 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":292 */
+  __pyx_2 = PyObject_GetAttr(__pyx_v_trace_hat, __pyx_n_lower); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 292; goto __pyx_L1;}
+  __pyx_1 = PyObject_CallObject(__pyx_2, 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 292; goto __pyx_L1;}
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_v_tmpx);
   __pyx_v_tmpx = __pyx_1;
   __pyx_1 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":268 */
-  __pyx_5 = PyString_AsString(__pyx_v_tmpx); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":293 */
+  __pyx_5 = PyString_AsString(__pyx_v_tmpx); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; goto __pyx_L1;}
   ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->trace_hat = __pyx_5;
 
   __pyx_r = 0;
@@ -813,8 +836,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":277 */
-  __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 = 277; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":302 */
+  __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 = 302; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -830,9 +853,9 @@
   return __pyx_r;
 }
 
-static PyObject *__pyx_k49p;
+static PyObject *__pyx_k46p;
 
-static char (__pyx_k49[]) = "Invalid number of iterations: should be positive";
+static char (__pyx_k46[]) = "Invalid number of iterations: should be positive";
 
 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) {
@@ -844,30 +867,30 @@
   Py_INCREF(__pyx_v_self);
   Py_INCREF(__pyx_v_iterations);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":279 */
-  __pyx_1 = PyInt_FromLong(0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; goto __pyx_L1;}
-  if (PyObject_Cmp(__pyx_v_iterations, __pyx_1, &__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":304 */
+  __pyx_1 = PyInt_FromLong(0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_v_iterations, __pyx_1, &__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; goto __pyx_L1;}
   __pyx_2 = __pyx_2 < 0;
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   if (__pyx_2) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":280 */
-    __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 280; goto __pyx_L1;}
-    __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 280; goto __pyx_L1;}
-    Py_INCREF(__pyx_k49p);
-    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_k49p);
-    __pyx_4 = PyObject_CallObject(__pyx_1, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 280; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":305 */
+    __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; goto __pyx_L1;}
+    __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; goto __pyx_L1;}
+    Py_INCREF(__pyx_k46p);
+    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_k46p);
+    __pyx_4 = PyObject_CallObject(__pyx_1, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; goto __pyx_L1;}
     Py_DECREF(__pyx_1); __pyx_1 = 0;
     Py_DECREF(__pyx_3); __pyx_3 = 0;
     __Pyx_Raise(__pyx_4, 0, 0);
     Py_DECREF(__pyx_4); __pyx_4 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 280; goto __pyx_L1;}
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; goto __pyx_L1;}
     goto __pyx_L2;
   }
   __pyx_L2:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":281 */
-  __pyx_2 = PyInt_AsLong(__pyx_v_iterations); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":306 */
+  __pyx_2 = PyInt_AsLong(__pyx_v_iterations); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 306; goto __pyx_L1;}
   ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->iterations = __pyx_2;
 
   __pyx_r = 0;
@@ -890,8 +913,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":293 */
-  __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 = 293; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":318 */
+  __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 = 318; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -907,9 +930,9 @@
   return __pyx_r;
 }
 
-static PyObject *__pyx_k50p;
+static PyObject *__pyx_k47p;
 
-static char (__pyx_k50[]) = "Invalid value for the cell argument: should be positive";
+static char (__pyx_k47[]) = "Invalid value for the cell argument: should be positive";
 
 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) {
@@ -922,30 +945,30 @@
   Py_INCREF(__pyx_v_self);
   Py_INCREF(__pyx_v_cell);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":295 */
-  __pyx_1 = PyInt_FromLong(0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; goto __pyx_L1;}
-  if (PyObject_Cmp(__pyx_v_cell, __pyx_1, &__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":320 */
+  __pyx_1 = PyInt_FromLong(0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 320; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_v_cell, __pyx_1, &__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 320; goto __pyx_L1;}
   __pyx_2 = __pyx_2 <= 0;
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   if (__pyx_2) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":296 */
-    __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; goto __pyx_L1;}
-    __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; goto __pyx_L1;}
-    Py_INCREF(__pyx_k50p);
-    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_k50p);
-    __pyx_4 = PyObject_CallObject(__pyx_1, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":321 */
+    __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; goto __pyx_L1;}
+    __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; goto __pyx_L1;}
+    Py_INCREF(__pyx_k47p);
+    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_k47p);
+    __pyx_4 = PyObject_CallObject(__pyx_1, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; goto __pyx_L1;}
     Py_DECREF(__pyx_1); __pyx_1 = 0;
     Py_DECREF(__pyx_3); __pyx_3 = 0;
     __Pyx_Raise(__pyx_4, 0, 0);
     Py_DECREF(__pyx_4); __pyx_4 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; goto __pyx_L1;}
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; goto __pyx_L1;}
     goto __pyx_L2;
   }
   __pyx_L2:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":297 */
-  __pyx_5 = PyFloat_AsDouble(__pyx_v_cell); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":322 */
+  __pyx_5 = PyFloat_AsDouble(__pyx_v_cell); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 322; goto __pyx_L1;}
   ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->cell = __pyx_5;
 
   __pyx_r = 0;
@@ -1000,122 +1023,122 @@
   __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":301 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 301; goto __pyx_L1;}
-  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 301; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":326 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; 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 = 301; goto __pyx_L1;}
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; 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":302 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":327 */
   __pyx_4 = __pyx_v_surface != Py_None;
   if (__pyx_4) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":303 */
-    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_surface, __pyx_v_surface) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":328 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_surface, __pyx_v_surface) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; goto __pyx_L1;}
     goto __pyx_L2;
   }
   __pyx_L2:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":305 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; goto __pyx_L1;}
-  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":330 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; 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 = 305; goto __pyx_L1;}
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; 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":306 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":331 */
   __pyx_4 = __pyx_v_statistics != Py_None;
   if (__pyx_4) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":307 */
-    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_statistics, __pyx_v_statistics) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 307; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":332 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_statistics, __pyx_v_statistics) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 332; goto __pyx_L1;}
     goto __pyx_L3;
   }
   __pyx_L3:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":309 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; goto __pyx_L1;}
-  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":334 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 334; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 334; 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 = 309; goto __pyx_L1;}
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 334; 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":310 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":335 */
   __pyx_4 = __pyx_v_trace_hat != Py_None;
   if (__pyx_4) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":311 */
-    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_trace_hat, __pyx_v_trace_hat) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":336 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_trace_hat, __pyx_v_trace_hat) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 336; goto __pyx_L1;}
     goto __pyx_L4;
   }
   __pyx_L4:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":313 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 313; goto __pyx_L1;}
-  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 313; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":338 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; 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 = 313; goto __pyx_L1;}
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; 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":314 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":339 */
   __pyx_4 = __pyx_v_iterations != Py_None;
   if (__pyx_4) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":315 */
-    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_iterations, __pyx_v_iterations) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":340 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_iterations, __pyx_v_iterations) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 340; goto __pyx_L1;}
     goto __pyx_L5;
   }
   __pyx_L5:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":317 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 317; goto __pyx_L1;}
-  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 317; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":342 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 342; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 342; 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 = 317; goto __pyx_L1;}
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 342; 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":318 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":343 */
   __pyx_4 = __pyx_v_cell != Py_None;
   if (__pyx_4) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":319 */
-    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_parametric_flags, __pyx_v_cell) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 319; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":344 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_parametric_flags, __pyx_v_cell) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 344; goto __pyx_L1;}
     goto __pyx_L6;
   }
   __pyx_L6:;
@@ -1143,21 +1166,21 @@
 
 static PyObject *__pyx_n_join;
 
+static PyObject *__pyx_k53p;
+static PyObject *__pyx_k54p;
+static PyObject *__pyx_k55p;
 static PyObject *__pyx_k56p;
 static PyObject *__pyx_k57p;
 static PyObject *__pyx_k58p;
 static PyObject *__pyx_k59p;
-static PyObject *__pyx_k60p;
-static PyObject *__pyx_k61p;
-static PyObject *__pyx_k62p;
 
-static char (__pyx_k56[]) = "Control          :";
-static char (__pyx_k57[]) = "Surface type     : %s";
-static char (__pyx_k58[]) = "Statistics       : %s";
-static char (__pyx_k59[]) = "Trace estimation : %s";
-static char (__pyx_k60[]) = "Cell size        : %s";
-static char (__pyx_k61[]) = "Nb iterations    : %s";
-static char (__pyx_k62[]) = "\n";
+static char (__pyx_k53[]) = "Control          :";
+static char (__pyx_k54[]) = "Surface type     : %s";
+static char (__pyx_k55[]) = "Statistics       : %s";
+static char (__pyx_k56[]) = "Trace estimation : %s";
+static char (__pyx_k57[]) = "Cell size        : %s";
+static char (__pyx_k58[]) = "Nb iterations    : %s";
+static char (__pyx_k59[]) = "\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) {
@@ -1172,25 +1195,25 @@
   Py_INCREF(__pyx_v_self);
   __pyx_v_strg = Py_None; Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":323 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_surface); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; goto __pyx_L1;}
-  __pyx_2 = PyNumber_Remainder(__pyx_k57p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":348 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_surface); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; goto __pyx_L1;}
+  __pyx_2 = PyNumber_Remainder(__pyx_k54p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_statistics); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; goto __pyx_L1;}
-  __pyx_3 = PyNumber_Remainder(__pyx_k58p, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; goto __pyx_L1;}
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_statistics); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 350; goto __pyx_L1;}
+  __pyx_3 = PyNumber_Remainder(__pyx_k55p, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 350; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_trace_hat); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; goto __pyx_L1;}
-  __pyx_4 = PyNumber_Remainder(__pyx_k59p, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; goto __pyx_L1;}
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_trace_hat); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; goto __pyx_L1;}
+  __pyx_4 = PyNumber_Remainder(__pyx_k56p, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_cell); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; goto __pyx_L1;}
-  __pyx_5 = PyNumber_Remainder(__pyx_k60p, __pyx_1); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; goto __pyx_L1;}
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_cell); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; goto __pyx_L1;}
+  __pyx_5 = PyNumber_Remainder(__pyx_k57p, __pyx_1); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_iterations); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; goto __pyx_L1;}
-  __pyx_6 = PyNumber_Remainder(__pyx_k61p, __pyx_1); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; goto __pyx_L1;}
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_iterations); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; goto __pyx_L1;}
+  __pyx_6 = PyNumber_Remainder(__pyx_k58p, __pyx_1); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; 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 = 323; goto __pyx_L1;}
-  Py_INCREF(__pyx_k56p);
-  PyList_SET_ITEM(__pyx_1, 0, __pyx_k56p);
+  __pyx_1 = PyList_New(6); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 348; goto __pyx_L1;}
+  Py_INCREF(__pyx_k53p);
+  PyList_SET_ITEM(__pyx_1, 0, __pyx_k53p);
   PyList_SET_ITEM(__pyx_1, 1, __pyx_2);
   PyList_SET_ITEM(__pyx_1, 2, __pyx_3);
   PyList_SET_ITEM(__pyx_1, 3, __pyx_4);
@@ -1205,12 +1228,12 @@
   __pyx_v_strg = __pyx_1;
   __pyx_1 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":329 */
-  __pyx_2 = PyObject_GetAttr(__pyx_k62p, __pyx_n_join); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; goto __pyx_L1;}
-  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":354 */
+  __pyx_2 = PyObject_GetAttr(__pyx_k59p, __pyx_n_join); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; 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 = 329; goto __pyx_L1;}
+  __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; goto __pyx_L1;}
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_3); __pyx_3 = 0;
   __pyx_r = __pyx_4;
@@ -1234,14 +1257,91 @@
   return __pyx_r;
 }
 
+static PyObject *__pyx_f_6cloess_11loess_model_setup(struct __pyx_obj_6cloess_loess_model *__pyx_v_self,loess_model (*__pyx_v_base),long __pyx_v_npar) {
+  PyObject *__pyx_r;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":375 */
+  __pyx_v_self->_base = __pyx_v_base;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":376 */
+  __pyx_v_self->npar = __pyx_v_npar;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":386 */
+  Py_INCREF(((PyObject *)__pyx_v_self));
+  __pyx_r = ((PyObject *)__pyx_v_self);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+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":399 */
+  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_bool); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; 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 = 399; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; 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 = 399; 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;
+
+  __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;
+}
+
+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":401 */
+  __pyx_1 = PyInt_AsLong(__pyx_v_normalize); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 401; goto __pyx_L1;}
+  ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->normalize = __pyx_1;
+
+  __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;
+}
+
 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);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":370 */
-  __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 = 370; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":407 */
+  __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 = 407; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -1257,9 +1357,9 @@
   return __pyx_r;
 }
 
-static PyObject *__pyx_k63p;
+static PyObject *__pyx_k60p;
 
-static char (__pyx_k63[]) = "Span should be between 0 and 1!";
+static char (__pyx_k60[]) = "Span should be between 0 and 1!";
 
 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) {
@@ -1272,36 +1372,36 @@
   Py_INCREF(__pyx_v_self);
   Py_INCREF(__pyx_v_span);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":372 */
-  __pyx_2 = PyFloat_FromDouble(0.); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 372; goto __pyx_L1;}
-  if (PyObject_Cmp(__pyx_v_span, __pyx_2, &__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 372; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":409 */
+  __pyx_2 = PyFloat_FromDouble(0.); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 409; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_v_span, __pyx_2, &__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 409; goto __pyx_L1;}
   __pyx_1 = __pyx_1 <= 0;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   if (!__pyx_1) {
-    __pyx_2 = PyFloat_FromDouble(1.); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 372; goto __pyx_L1;}
-    if (PyObject_Cmp(__pyx_v_span, __pyx_2, &__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 372; goto __pyx_L1;}
+    __pyx_2 = PyFloat_FromDouble(1.); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 409; goto __pyx_L1;}
+    if (PyObject_Cmp(__pyx_v_span, __pyx_2, &__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 409; goto __pyx_L1;}
     __pyx_1 = __pyx_1 > 0;
     Py_DECREF(__pyx_2); __pyx_2 = 0;
   }
   if (__pyx_1) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":373 */
-    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; goto __pyx_L1;}
-    __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; goto __pyx_L1;}
-    Py_INCREF(__pyx_k63p);
-    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_k63p);
-    __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":410 */
+    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 410; goto __pyx_L1;}
+    __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 410; goto __pyx_L1;}
+    Py_INCREF(__pyx_k60p);
+    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_k60p);
+    __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 410; goto __pyx_L1;}
     Py_DECREF(__pyx_2); __pyx_2 = 0;
     Py_DECREF(__pyx_3); __pyx_3 = 0;
     __Pyx_Raise(__pyx_4, 0, 0);
     Py_DECREF(__pyx_4); __pyx_4 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; goto __pyx_L1;}
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 410; goto __pyx_L1;}
     goto __pyx_L2;
   }
   __pyx_L2:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":374 */
-  __pyx_5 = PyFloat_AsDouble(__pyx_v_span); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":411 */
+  __pyx_5 = PyFloat_AsDouble(__pyx_v_span); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; goto __pyx_L1;}
   ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->span = __pyx_5;
 
   __pyx_r = 0;
@@ -1324,8 +1424,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":383 */
-  __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 = 383; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":420 */
+  __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 = 420; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -1341,9 +1441,9 @@
   return __pyx_r;
 }
 
-static PyObject *__pyx_k64p;
+static PyObject *__pyx_k61p;
 
-static char (__pyx_k64[]) = "Degree should be between 0 and 2!";
+static char (__pyx_k61[]) = "Degree should be between 0 and 2!";
 
 static int __pyx_f_6cloess_11loess_model_6degree___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_degree); /*proto*/
 static int __pyx_f_6cloess_11loess_model_6degree___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_degree) {
@@ -1355,30 +1455,30 @@
   Py_INCREF(__pyx_v_self);
   Py_INCREF(__pyx_v_degree);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":385 */
-  __pyx_2 = PyInt_FromLong(0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; goto __pyx_L1;}
-  if (PyObject_Cmp(__pyx_v_degree, __pyx_2, &__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":422 */
+  __pyx_2 = PyInt_FromLong(0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_v_degree, __pyx_2, &__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; goto __pyx_L1;}
   __pyx_1 = __pyx_1 < 0;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   if (!__pyx_1) {
-    __pyx_2 = PyInt_FromLong(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; goto __pyx_L1;}
-    if (PyObject_Cmp(__pyx_v_degree, __pyx_2, &__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; goto __pyx_L1;}
+    __pyx_2 = PyInt_FromLong(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; goto __pyx_L1;}
+    if (PyObject_Cmp(__pyx_v_degree, __pyx_2, &__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; goto __pyx_L1;}
     __pyx_1 = __pyx_1 > 0;
     Py_DECREF(__pyx_2); __pyx_2 = 0;
   }
   if (__pyx_1) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":386 */
-    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 386; goto __pyx_L1;}
-    __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 386; goto __pyx_L1;}
-    Py_INCREF(__pyx_k64p);
-    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_k64p);
-    __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 386; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":423 */
+    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; goto __pyx_L1;}
+    __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; goto __pyx_L1;}
+    Py_INCREF(__pyx_k61p);
+    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_k61p);
+    __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; goto __pyx_L1;}
     Py_DECREF(__pyx_2); __pyx_2 = 0;
     Py_DECREF(__pyx_3); __pyx_3 = 0;
     __Pyx_Raise(__pyx_4, 0, 0);
     Py_DECREF(__pyx_4); __pyx_4 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 386; goto __pyx_L1;}
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; goto __pyx_L1;}
     goto __pyx_L2;
   }
   __pyx_L2:;
@@ -1397,70 +1497,14 @@
   return __pyx_r;
 }
 
-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":399 */
-  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_bool); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; 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 = 399; goto __pyx_L1;}
-  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; 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 = 399; 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;
-
-  __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;
-}
-
-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":401 */
-  __pyx_1 = PyInt_AsLong(__pyx_v_normalize); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 401; goto __pyx_L1;}
-  ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->normalize = __pyx_1;
-
-  __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;
-}
-
 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":412 */
-  __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 = 412; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":434 */
+  __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 = 434; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -1479,9 +1523,9 @@
 static PyObject *__pyx_n_symmetric;
 static PyObject *__pyx_n_gaussian;
 
-static PyObject *__pyx_k67p;
+static PyObject *__pyx_k64p;
 
-static char (__pyx_k67[]) = "Invalid value for the 'family' argument: should be in ('symmetric', 'gaussian').";
+static char (__pyx_k64[]) = "Invalid value for the 'family' argument: should be in ('symmetric', 'gaussian').";
 
 static int __pyx_f_6cloess_11loess_model_6family___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_family); /*proto*/
 static int __pyx_f_6cloess_11loess_model_6family___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_family) {
@@ -1494,38 +1538,38 @@
   Py_INCREF(__pyx_v_self);
   Py_INCREF(__pyx_v_family);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":414 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_family, __pyx_n_lower); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 414; goto __pyx_L1;}
-  __pyx_2 = PyObject_CallObject(__pyx_1, 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 414; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":436 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_family, __pyx_n_lower); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; goto __pyx_L1;}
+  __pyx_2 = PyObject_CallObject(__pyx_1, 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyTuple_New(2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 414; goto __pyx_L1;}
+  __pyx_1 = PyTuple_New(2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; goto __pyx_L1;}
   Py_INCREF(__pyx_n_symmetric);
   PyTuple_SET_ITEM(__pyx_1, 0, __pyx_n_symmetric);
   Py_INCREF(__pyx_n_gaussian);
   PyTuple_SET_ITEM(__pyx_1, 1, __pyx_n_gaussian);
-  __pyx_3 = PySequence_Contains(__pyx_1, __pyx_2); if (__pyx_3 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 414; goto __pyx_L1;}
+  __pyx_3 = PySequence_Contains(__pyx_1, __pyx_2); if (__pyx_3 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; goto __pyx_L1;}
   __pyx_3 = !__pyx_3;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   if (__pyx_3) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":415 */
-    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 415; goto __pyx_L1;}
-    __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 415; goto __pyx_L1;}
-    Py_INCREF(__pyx_k67p);
-    PyTuple_SET_ITEM(__pyx_1, 0, __pyx_k67p);
-    __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 415; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":437 */
+    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; goto __pyx_L1;}
+    __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; goto __pyx_L1;}
+    Py_INCREF(__pyx_k64p);
+    PyTuple_SET_ITEM(__pyx_1, 0, __pyx_k64p);
+    __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; goto __pyx_L1;}
     Py_DECREF(__pyx_2); __pyx_2 = 0;
     Py_DECREF(__pyx_1); __pyx_1 = 0;
     __Pyx_Raise(__pyx_4, 0, 0);
     Py_DECREF(__pyx_4); __pyx_4 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 415; goto __pyx_L1;}
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; goto __pyx_L1;}
     goto __pyx_L2;
   }
   __pyx_L2:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":417 */
-  __pyx_5 = PyString_AsString(__pyx_v_family); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":439 */
+  __pyx_5 = PyString_AsString(__pyx_v_family); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 439; goto __pyx_L1;}
   ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->family = __pyx_5;
 
   __pyx_r = 0;
@@ -1548,8 +1592,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":428 */
-  __pyx_1 = __pyx_f_6cloess_boolarray_from_data(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->npar,1,((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->parametric); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 428; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":450 */
+  __pyx_1 = __pyx_f_6cloess_boolarray_from_data(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->npar,1,((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->parametric); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 450; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -1565,11 +1609,10 @@
   return __pyx_r;
 }
 
-static PyObject *__pyx_n_array;
+static PyObject *__pyx_n_atleast_1d;
 static PyObject *__pyx_n_copy;
 static PyObject *__pyx_n_True;
 static PyObject *__pyx_n_subok;
-static PyObject *__pyx_n_int;
 static PyObject *__pyx_n_dtype;
 static PyObject *__pyx_n_min;
 
@@ -1577,7 +1620,6 @@
 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;
@@ -1585,64 +1627,71 @@
   PyObject *__pyx_3 = 0;
   PyObject *__pyx_4 = 0;
   PyObject *__pyx_5 = 0;
-  long __pyx_6;
+  PyObject *__pyx_6 = 0;
+  long __pyx_7;
+  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":433 */
-  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; goto __pyx_L1;}
-  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_n_array); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":454 */
+  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
+  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_n_atleast_1d); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; 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 = 433; goto __pyx_L1;}
+  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_narray); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
   Py_INCREF(__pyx_v_paramf);
-  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_v_paramf);
-  __pyx_3 = PyDict_New(); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; goto __pyx_L1;}
-  __pyx_4 = __Pyx_GetName(__pyx_b, __pyx_n_False); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; goto __pyx_L1;}
-  if (PyDict_SetItem(__pyx_3, __pyx_n_copy, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; goto __pyx_L1;}
-  Py_DECREF(__pyx_4); __pyx_4 = 0;
-  __pyx_4 = __Pyx_GetName(__pyx_b, __pyx_n_True); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; goto __pyx_L1;}
-  if (PyDict_SetItem(__pyx_3, __pyx_n_subok, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; goto __pyx_L1;}
-  Py_DECREF(__pyx_4); __pyx_4 = 0;
-  __pyx_4 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; goto __pyx_L1;}
-  __pyx_5 = PyObject_GetAttr(__pyx_4, __pyx_n_int); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; 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 = 433; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_paramf);
+  __pyx_4 = PyDict_New(); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
+  __pyx_5 = __Pyx_GetName(__pyx_b, __pyx_n_False); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
+  if (PyDict_SetItem(__pyx_4, __pyx_n_copy, __pyx_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; 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 = 433; goto __pyx_L1;}
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_5 = __Pyx_GetName(__pyx_b, __pyx_n_True); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
+  if (PyDict_SetItem(__pyx_4, __pyx_n_subok, __pyx_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  __pyx_5 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; goto __pyx_L1;}
+  __pyx_6 = PyObject_GetAttr(__pyx_5, __pyx_n_bool); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; goto __pyx_L1;}
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  if (PyDict_SetItem(__pyx_4, __pyx_n_dtype, __pyx_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
+  Py_DECREF(__pyx_6); __pyx_6 = 0;
+  __pyx_5 = PyEval_CallObjectWithKeywords(__pyx_1, __pyx_3, __pyx_4); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
   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 = 433; goto __pyx_L1;}
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+  __pyx_6 = PyTuple_New(1); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_6, 0, __pyx_5);
+  __pyx_5 = 0;
+  __pyx_1 = PyObject_CallObject(__pyx_2, __pyx_6); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_6); __pyx_6 = 0;
+  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_7c_numpy_ndarray)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
   Py_DECREF(((PyObject *)__pyx_v_p_ndr));
-  __pyx_v_p_ndr = ((PyArrayObject *)__pyx_4);
-  __pyx_4 = 0;
+  __pyx_v_p_ndr = ((PyArrayObject *)__pyx_1);
+  __pyx_1 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":434 */
-  __pyx_v_p_dat = ((long (*))__pyx_v_p_ndr->data);
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":435 */
-  __pyx_5 = __Pyx_GetName(__pyx_b, __pyx_n_min); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; goto __pyx_L1;}
-  __pyx_2 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->npar); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; goto __pyx_L1;}
-  __pyx_1 = PyObject_GetAttr(((PyObject *)__pyx_v_p_ndr), __pyx_n_size); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; goto __pyx_L1;}
-  __pyx_3 = PyInt_FromLong(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; goto __pyx_L1;}
-  __pyx_4 = PyNumber_Subtract(__pyx_1, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; goto __pyx_L1;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  Py_DECREF(__pyx_3); __pyx_3 = 0;
-  __pyx_1 = PyTuple_New(2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; goto __pyx_L1;}
-  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_2);
-  PyTuple_SET_ITEM(__pyx_1, 1, __pyx_4);
-  __pyx_2 = 0;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":456 */
+  __pyx_3 = __Pyx_GetName(__pyx_b, __pyx_n_min); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; goto __pyx_L1;}
+  __pyx_4 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->npar); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; goto __pyx_L1;}
+  __pyx_5 = PyObject_GetAttr(((PyObject *)__pyx_v_p_ndr), __pyx_n_size); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_4);
+  PyTuple_SET_ITEM(__pyx_2, 1, __pyx_5);
   __pyx_4 = 0;
-  __pyx_3 = PyObject_CallObject(__pyx_5, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; goto __pyx_L1;}
-  Py_DECREF(__pyx_5); __pyx_5 = 0;
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_6 = PyInt_AsLong(__pyx_3); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; goto __pyx_L1;}
+  __pyx_5 = 0;
+  __pyx_6 = PyObject_CallObject(__pyx_3, __pyx_2); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; goto __pyx_L1;}
   Py_DECREF(__pyx_3); __pyx_3 = 0;
-  for (__pyx_v_i = 0; __pyx_v_i < __pyx_6; ++__pyx_v_i) {
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_7 = PyInt_AsLong(__pyx_6); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; goto __pyx_L1;}
+  Py_DECREF(__pyx_6); __pyx_6 = 0;
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_7; ++__pyx_v_i) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":436 */
-    (((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->parametric[__pyx_v_i]) = (__pyx_v_p_dat[__pyx_v_i]);
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":457 */
+    __pyx_1 = PyInt_FromLong(__pyx_v_i); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; goto __pyx_L1;}
+    __pyx_4 = PyObject_GetItem(((PyObject *)__pyx_v_p_ndr), __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; goto __pyx_L1;}
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    __pyx_8 = PyInt_AsLong(__pyx_4); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; goto __pyx_L1;}
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    (((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->parametric[__pyx_v_i]) = __pyx_8;
   }
 
   __pyx_r = 0;
@@ -1653,6 +1702,7 @@
   Py_XDECREF(__pyx_3);
   Py_XDECREF(__pyx_4);
   Py_XDECREF(__pyx_5);
+  Py_XDECREF(__pyx_6);
   __Pyx_AddTraceback("cloess.loess_model.parametric_flags.__set__");
   __pyx_r = -1;
   __pyx_L0:;
@@ -1668,8 +1718,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":447 */
-  __pyx_1 = __pyx_f_6cloess_boolarray_from_data(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->npar,1,((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->drop_square); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":468 */
+  __pyx_1 = __pyx_f_6cloess_boolarray_from_data(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->npar,1,((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->drop_square); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -1689,7 +1739,6 @@
 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;
@@ -1697,64 +1746,71 @@
   PyObject *__pyx_3 = 0;
   PyObject *__pyx_4 = 0;
   PyObject *__pyx_5 = 0;
-  long __pyx_6;
+  PyObject *__pyx_6 = 0;
+  long __pyx_7;
+  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":452 */
-  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; goto __pyx_L1;}
-  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_n_array); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":472 */
+  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
+  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_n_atleast_1d); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; 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 = 452; goto __pyx_L1;}
+  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_narray); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
   Py_INCREF(__pyx_v_drop_sq);
-  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_v_drop_sq);
-  __pyx_3 = PyDict_New(); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; goto __pyx_L1;}
-  __pyx_4 = __Pyx_GetName(__pyx_b, __pyx_n_False); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; goto __pyx_L1;}
-  if (PyDict_SetItem(__pyx_3, __pyx_n_copy, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; goto __pyx_L1;}
-  Py_DECREF(__pyx_4); __pyx_4 = 0;
-  __pyx_4 = __Pyx_GetName(__pyx_b, __pyx_n_True); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; goto __pyx_L1;}
-  if (PyDict_SetItem(__pyx_3, __pyx_n_subok, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; goto __pyx_L1;}
-  Py_DECREF(__pyx_4); __pyx_4 = 0;
-  __pyx_4 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; goto __pyx_L1;}
-  __pyx_5 = PyObject_GetAttr(__pyx_4, __pyx_n_int); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; 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 = 452; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_drop_sq);
+  __pyx_4 = PyDict_New(); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
+  __pyx_5 = __Pyx_GetName(__pyx_b, __pyx_n_False); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
+  if (PyDict_SetItem(__pyx_4, __pyx_n_copy, __pyx_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; 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 = 452; goto __pyx_L1;}
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_5 = __Pyx_GetName(__pyx_b, __pyx_n_True); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
+  if (PyDict_SetItem(__pyx_4, __pyx_n_subok, __pyx_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  __pyx_5 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 473; goto __pyx_L1;}
+  __pyx_6 = PyObject_GetAttr(__pyx_5, __pyx_n_bool); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 473; goto __pyx_L1;}
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  if (PyDict_SetItem(__pyx_4, __pyx_n_dtype, __pyx_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
+  Py_DECREF(__pyx_6); __pyx_6 = 0;
+  __pyx_5 = PyEval_CallObjectWithKeywords(__pyx_1, __pyx_3, __pyx_4); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
   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 = 452; goto __pyx_L1;}
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+  __pyx_6 = PyTuple_New(1); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_6, 0, __pyx_5);
+  __pyx_5 = 0;
+  __pyx_1 = PyObject_CallObject(__pyx_2, __pyx_6); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_6); __pyx_6 = 0;
+  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_7c_numpy_ndarray)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
   Py_DECREF(((PyObject *)__pyx_v_d_ndr));
-  __pyx_v_d_ndr = ((PyArrayObject *)__pyx_4);
-  __pyx_4 = 0;
+  __pyx_v_d_ndr = ((PyArrayObject *)__pyx_1);
+  __pyx_1 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":453 */
-  __pyx_v_d_dat = ((long (*))__pyx_v_d_ndr->data);
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":454 */
-  __pyx_5 = __Pyx_GetName(__pyx_b, __pyx_n_min); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
-  __pyx_2 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->npar); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
-  __pyx_1 = PyObject_GetAttr(((PyObject *)__pyx_v_d_ndr), __pyx_n_size); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
-  __pyx_3 = PyInt_FromLong(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
-  __pyx_4 = PyNumber_Subtract(__pyx_1, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  Py_DECREF(__pyx_3); __pyx_3 = 0;
-  __pyx_1 = PyTuple_New(2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
-  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_2);
-  PyTuple_SET_ITEM(__pyx_1, 1, __pyx_4);
-  __pyx_2 = 0;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":474 */
+  __pyx_3 = __Pyx_GetName(__pyx_b, __pyx_n_min); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; goto __pyx_L1;}
+  __pyx_4 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->npar); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; goto __pyx_L1;}
+  __pyx_5 = PyObject_GetAttr(((PyObject *)__pyx_v_d_ndr), __pyx_n_size); if (!__pyx_