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

scipy-svn at scipy.org scipy-svn at scipy.org
Fri Mar 16 16:43:08 EDT 2007


Author: pierregm
Date: 2007-03-16 15:42:51 -0500 (Fri, 16 Mar 2007)
New Revision: 2849

Added:
   trunk/Lib/sandbox/pyloess/sandbox/examples/gas_data
   trunk/Lib/sandbox/pyloess/sandbox/examples/gas_result
   trunk/Lib/sandbox/pyloess/sandbox/examples/madeup_data
   trunk/Lib/sandbox/pyloess/sandbox/examples/madeup_result
Modified:
   trunk/Lib/sandbox/pyloess/sandbox/pyloess.py
   trunk/Lib/sandbox/pyloess/sandbox/src/c_numpy.pxd
   trunk/Lib/sandbox/pyloess/sandbox/src/cloess.c
   trunk/Lib/sandbox/pyloess/sandbox/src/cloess.pyx
   trunk/Lib/sandbox/pyloess/sandbox/src/loess.c
   trunk/Lib/sandbox/pyloess/sandbox/src/loessc.c
Log:
updated loess. 
Still in sandbox till some of issues are not dealt with. Globally, it works when it should.

Problems:
- when F functions exit abnormally, we should catch the output and process it as an exception instead of brute exit.
- ndarray arguments should be modifiable elementwise
- find where the "Exception exceptions.NameError: 'c_loess' in <cloess.conf_intervals object at ....> ignored" comes from
- add anova


Added: trunk/Lib/sandbox/pyloess/sandbox/examples/gas_data
===================================================================
--- trunk/Lib/sandbox/pyloess/sandbox/examples/gas_data	2007-03-14 16:52:59 UTC (rev 2848)
+++ trunk/Lib/sandbox/pyloess/sandbox/examples/gas_data	2007-03-16 20:42:51 UTC (rev 2849)
@@ -0,0 +1,3 @@
+E (observations)
+0.831000 1.045000 1.021000 0.970000 0.825000 0.891000 0.710000 0.801000 1.074000 1.148000 1.000000 0.928000 0.767000 0.701000 0.807000 0.902000 0.997000 1.224000 1.089000 0.973000 0.980000 0.665000 NOx (response)
+4.818000 2.849000 3.275000 4.691000 4.255000 5.064000 2.118000 4.602000 2.286000 0.970000 3.965000 5.344000 3.834000 1.990000 5.199000 5.283000 3.752000 0.537000 1.640000 5.055000 4.937000 1.561000 
\ No newline at end of file

Added: trunk/Lib/sandbox/pyloess/sandbox/examples/gas_result
===================================================================
--- trunk/Lib/sandbox/pyloess/sandbox/examples/gas_result	2007-03-14 16:52:59 UTC (rev 2848)
+++ trunk/Lib/sandbox/pyloess/sandbox/examples/gas_result	2007-03-16 20:42:51 UTC (rev 2849)
@@ -0,0 +1,10 @@
+loess(&gas):
+4.883437 2.927639 3.572746 4.710510 4.815363 5.196193 2.512832 4.474939 2.149797 0.990044 4.089353 5.303627 3.864174 2.267121 4.575636 5.240293 4.154036 0.523682 1.853026 4.659184 4.521148 1.196414 
+loess(&gas_null):
+4.892690 3.362733 3.728575 4.489023 4.831715 5.177112 2.535887 4.530370 2.873000 1.453502 4.059136 5.052650 3.943568 2.265232 4.614320 5.163913 4.107184 -0.276342 2.604373 4.445040 4.351615 1.051719 
+predict(gas_fit_E, m, &gas, &gas_pred, 0):
+1.196414 5.068747 0.523682 
+pointwise(&gas_pred, m, coverage, &gas_ci):
+0.407208 1.196414 1.985621 3.249187 3.679498 4.109808 4.631187 5.055708 5.480229 4.704010 5.135260 5.566510 2.759703 3.143656 3.527609 0.683247 1.196932 1.710617 -0.424684 0.523682 1.472049 
+anova(&gas_null, &gas, &gas_anova):
+2.5531 15.663 10.1397 0.000860102

Added: trunk/Lib/sandbox/pyloess/sandbox/examples/madeup_data
===================================================================
--- trunk/Lib/sandbox/pyloess/sandbox/examples/madeup_data	2007-03-14 16:52:59 UTC (rev 2848)
+++ trunk/Lib/sandbox/pyloess/sandbox/examples/madeup_data	2007-03-16 20:42:51 UTC (rev 2849)
@@ -0,0 +1,4 @@
+one_two (observations)
+-0.957581 -2.809549 -0.696511 3.451000 0.509260 0.557854 0.052582 -2.050644 -1.115675 -1.183665 0.511959 0.334364 -2.057062 -0.121897 0.544238 0.600502 0.531074 0.495400 -1.608602 0.277371 0.290464 0.579894 -0.290441 1.306226 -0.482898 -0.716423 0.742413 -0.911613 1.279436 -0.189153 0.592293 0.952416 0.491436 -0.305681 -0.363871 -0.285424 -0.037209 -0.923529 1.138054 -1.331223 0.551234 -0.852726 1.196875 0.498782 0.320180 0.212447 1.009358 -0.900989 1.132164 0.018867 0.424170 -0.198621 0.955170 0.948321 0.473848 -0.699121 -0.612853 0.580431 1.277996 0.806797 -1.038559 1.008663 -0.578257 -0.323245 -0.756302 1.386352 0.722419 -1.216078 -0.498280 0.726247 -0.260119 -0.741135 -0.184111 0.307762 0.464568 -0.252531 -0.486504 0.426634 -1.303969 0.067149 1.771176 0.907249 0.432350 1.419897 -0.413389 2.442025 0.041138 0.509505 -0.282744 0.179882 -1.188083 0.982653 -1.042886 1.181365 -0.398340 -1.335565 -0.502790 0.484762 -0.806446 1.412077 -0.878874 -0.935197 -0.339255 0.164497 1.370018 -1.494684 1.380505 0.885084 0.835609 0.896235 -1.289541 0.233203 1.183198 -0.857934 -1.334234 -0.923351 0.769146 -0.377948 0.059114 -1.870615 -0.677868 0.038185 0.375301 0.964717 0.695051 -0.342140 -1.145463 -0.993246 -0.130573 1.213711 0.291241 1.106891 0.949571 0.463675 0.455723 0.398786 -0.015849 -1.397373 0.770062 0.083291 0.531798 0.049727 -0.734140 -0.963487 0.573561 -0.281942 -0.594503 0.770262 1.073983 -0.615706 -0.084794 -0.491630 -1.526969 -0.196881 0.165653 0.198357 0.974930 -0.954848 0.588474 -0.426883 0.177119 -0.916442 -1.885139 0.086894 0.456306 0.174285 -0.001308 -0.000585 0.284023 -0.365679 -0.548867 0.857848 0.699094 -0.140026 1.332454 1.601795 0.012415 0.243429 1.077369 1.859246 0.185910 0.033342 0.613008 1.068595 -0.683305 -0.128826 -1.655525 0.013086 0.062454 0.773042 0.127046 0.408652 1.195438 -0.185558 -1.299714 0.899675 -0.033648 -1.544602 0.655203 -0.713935 
+response
+14.453553 6.622825 13.671414 14.197518 12.860530 12.522856 14.214638 7.924264 12.506938 13.734205 14.710855 13.596223 5.890019 13.558654 14.043167 13.931391 13.218920 17.090560 15.199322 13.261667 15.760636 12.083855 14.344907 12.609494 11.932959 13.408674 13.700765 13.013366 15.794999 14.600198 16.275751 11.564349 14.809023 12.982361 15.003502 14.737337 15.747677 11.674508 14.047278 14.666917 13.806240 13.611149 13.347149 14.225152 14.718846 14.217216 14.418058 14.719634 12.799716 13.933038 15.264603 14.660387 9.738691 14.443424 14.417284 15.184538 13.344938 15.372943 13.811554 15.103777 15.383834 14.368612 12.525202 14.325033 15.259658 13.004547 14.515988 15.176982 14.924187 13.872430 15.395366 13.428076 15.203430 14.186631 13.305833 14.074624 14.103092 13.499669 11.584675 14.264891 14.885616 13.967297 16.604680 10.367606 14.743473 16.308827 14.108673 13.590988 14.674546 15.294047 14.686723 13.611422 11.970270 13.884157 15.071776 12.589816 13.818745 14.245317 14.406530 14.347941 
\ No newline at end of file

Added: trunk/Lib/sandbox/pyloess/sandbox/examples/madeup_result
===================================================================
--- trunk/Lib/sandbox/pyloess/sandbox/examples/madeup_result	2007-03-14 16:52:59 UTC (rev 2848)
+++ trunk/Lib/sandbox/pyloess/sandbox/examples/madeup_result	2007-03-16 20:42:51 UTC (rev 2849)
@@ -0,0 +1,16 @@
+loess(&madeup):
+13.898675 5.225583 14.265096 14.237045 13.366442 13.157273 14.189032 7.971348 13.215581 12.835208 13.967757 14.457845 6.039091 14.722007 13.758002 14.654508 14.243303 14.733353 13.696778 12.510036 15.026972 14.346972 14.547927 11.702517 14.222303 14.288345 13.755227 13.742749 14.250887 14.188543 14.388616 12.552611 14.100045 14.552719 14.514971 14.556744 14.496872 12.868609 12.871890 14.427522 14.410413 14.598345 13.415146 14.731999 14.657565 14.778805 13.988940 13.723749 11.932352 14.908485 14.457978 14.616147 11.100703 14.254687 14.411890 14.519007 13.734456 14.634786 13.080897 14.415189 14.623631 13.340049 12.584224 14.510466 14.293842 13.954341 14.281046 14.643596 14.492646 14.497077 14.497688 13.732467 14.573564 14.548255 13.560984 13.917026 14.496924 14.452028 11.687567 13.865395 13.908958 14.184016 14.514209 10.835782 14.203921 15.273614 13.702645 14.383224 14.506619 14.707063 14.595778 13.877506 12.326903 14.236236 13.962165 12.281695 14.477443 13.192765 13.985441 13.206705 
+loess(&madeup_new):
+12.874079 10.889912 14.072472 14.688408 13.581655 13.741506 12.966195 11.778153 12.623840 12.391277 13.915575 14.549806 10.648311 13.714716 13.908051 14.338239 13.839956 14.661187 14.500423 12.892713 14.344422 14.557473 14.294094 14.258892 13.410545 14.058327 14.340850 12.675257 14.839750 12.706903 14.551439 14.002773 13.589104 14.094192 14.098484 14.246415 14.548803 11.925623 14.212327 14.501013 14.199258 14.517379 15.151176 14.202325 14.044125 14.549456 15.030205 12.957176 14.170346 14.166684 14.617600 14.160491 14.230993 14.821136 14.547624 14.489024 12.630700 14.292239 14.381246 14.834949 14.480650 14.747398 11.611371 14.519760 13.997474 14.591257 14.591759 14.478131 14.427821 14.785485 14.034793 12.821834 13.556879 14.606041 13.505266 12.561710 14.525273 14.555914 11.728344 13.296039 14.621341 14.570526 14.015254 14.451527 13.670446 15.113971 12.849321 14.570355 14.526773 13.616773 14.493652 14.496696 11.739043 14.886699 12.740301 12.265455 14.504240 13.584999 13.370259 15.378514 
+loess(&madeup_new) (family = symmetric):
+13.853372 13.076392 14.410502 14.317606 13.530344 13.909561 13.483542 13.661465 13.738437 13.662424 14.078653 14.471725 13.362504 14.161261 14.056621 14.370400 13.827138 14.543779 14.563051 13.263340 14.405462 14.511807 14.391442 13.655949 13.919863 14.406599 14.307597 13.717301 14.561751 13.479815 14.423533 13.588048 13.644027 14.268385 14.283955 14.361030 14.528760 13.151054 13.826620 14.570806 14.120641 14.538117 14.640103 14.309962 14.069715 14.527437 14.606612 13.824681 13.607361 14.370144 14.535820 14.399329 14.122194 14.580712 14.478250 14.541334 13.593458 14.346338 14.016117 14.580121 14.566098 14.522580 12.578184 14.528995 14.305679 14.422916 14.523434 14.533691 14.490958 14.574831 14.352653 13.714577 13.911857 14.540189 13.522831 13.495538 14.528432 14.462617 13.481391 13.705501 14.399779 14.509204 14.010568 13.623165 14.211318 14.586042 13.392231 14.520972 14.525897 13.822231 14.577431 14.267078 13.423198 14.589490 13.573646 13.655627 14.531561 13.811793 13.979165 14.705119 
+loess(&madeup_new) (normalize = FALSE):
+13.853372 13.076392 14.410502 14.317606 13.530344 13.909561 13.483542 13.661465 13.738437 13.662424 14.078653 14.471725 13.362504 14.161261 14.056621 14.370400 13.827138 14.543779 14.563051 13.263340 14.405462 14.511807 14.391442 13.655949 13.919863 14.406599 14.307597 13.717301 14.561751 13.479815 14.423533 13.588048 13.644027 14.268385 14.283955 14.361030 14.528760 13.151054 13.826620 14.570806 14.120641 14.538117 14.640103 14.309962 14.069715 14.527437 14.606612 13.824681 13.607361 14.370144 14.535820 14.399329 14.122194 14.580712 14.478250 14.541334 13.593458 14.346338 14.016117 14.580121 14.566098 14.522580 12.578184 14.528995 14.305679 14.422916 14.523434 14.533691 14.490958 14.574831 14.352653 13.714577 13.911857 14.540189 13.522831 13.495538 14.528432 14.462617 13.481391 13.705501 14.399779 14.509204 14.010568 13.623165 14.211318 14.586042 13.392231 14.520972 14.525897 13.822231 14.577431 14.267078 13.423198 14.589490 13.573646 13.655627 14.531561 13.811793 13.979165 14.705119 
+predict(newdata1, m, &madeup, &madeup_pred, 0):
+8.156780 14.493587 14.854142 
+predict(newdata2, m, &madeup, &madeup_pred, 1):
+14.491811 14.389726 
+pointwise(&madeup_pred, m, coverage, &madeup_ci):
+13.761833 14.491811 15.221789 13.656419 14.389726 15.123034 
+anova(&madeup2, &madeup, &madeup_anova):
+6.45034 81.2319 2.85933 0.0121449

Modified: trunk/Lib/sandbox/pyloess/sandbox/pyloess.py
===================================================================
--- trunk/Lib/sandbox/pyloess/sandbox/pyloess.py	2007-03-14 16:52:59 UTC (rev 2848)
+++ trunk/Lib/sandbox/pyloess/sandbox/pyloess.py	2007-03-16 20:42:51 UTC (rev 2849)
@@ -1,517 +1,250 @@
 import os
 from math import ceil
 
-import numpy
-from numpy import bool_, int_, float_
+import numpy as N
+from numpy.testing import NumpyTest, NumpyTestCase
+from numpy.testing.utils import build_err_msg, \
+        assert_equal, assert_almost_equal
 
-narray = numpy.array
-nempty = numpy.empty
-nzeros = numpy.zeros
-
-import logging
-logging.basicConfig(level=logging.DEBUG)
-loesslogging = logging.getLogger('loesss')
-
 import cloess
 reload(cloess)
+from cloess import loess
 
-class paramdict(dict):
-    def __init__(self, **kwargs):
-        dict.__init__(self, **kwargs)
-    
-    def __getattr__(self, attr):
-        _got = getattr(super(paramdict,self), attr, None)
-        if _got is None:
-            _got = self.get(attr, None)
-        return _got
+#####---------------------------------------------------------------------------
+#---- --- test 2D
+#####---------------------------------------------------------------------------
 
-    def __setattr__(self, attr, value):
-        if attr in self.keys():
-            self[attr] = value
+class test_loess2d(NumpyTestCase):
+    "Test class for lowess."
+    #
+    def __init__(self, *args, **kwds):
+        NumpyTestCase.__init__(self, *args, **kwds)
+        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)
+        self.d = (x, y, results, newdata1, newdata2, madeup)
+    #
+    def test_2dbasic(self):
+        "2D standard"
+        (x, y, results, newdata1, newdata2, madeup) = self.d
+        madeup = cloess.loess(x,y)
+        madeup.model.span = 0.5
+        madeup.model.normalize = True
+        madeup.fit()
+        assert_almost_equal(madeup.outputs.fitted_values, results[0], 5)
+        assert_almost_equal(madeup.outputs.enp, 14.9, 1)
+        assert_almost_equal(madeup.outputs.s, 0.9693, 4)
+    #
+#    def test_2d_modflags_ez(self):
+#        "2D - modification of model flags"
+#        (x, y, results, newdata1, newdata2, madeup) = self.d
+#        madeup = cloess.loess(x,y)
+#        madeup.model.span = 0.8
+#        madeup.model.drop_square_flags[0] = True
+#        madeup.model.parametric_flags[0] = True
+#        assert_equal(madeup.model.parametric_flags[:2],[1,0])
+#        madeup.fit()        
+#        assert_almost_equal(madeup.outputs.fitted_values, results[1], 5)
+#        assert_almost_equal(madeup.outputs.enp, 6.9, 1)
+#        assert_almost_equal(madeup.outputs.s, 1.4804, 4)
+    #
+    def test_2d_modflags_tot(self):
+        "2D - modification of model flags"
+        (x, y, results, newdata1, newdata2, madeup) = self.d
+        madeup = cloess.loess(x,y)
+        madeup.model.span = 0.8
+        madeup.model.drop_square_flags = [True, False]
+        madeup.model.parametric_flags = [True, False]
+        assert_equal(madeup.model.parametric_flags[:2],[1,0])
+        madeup.fit()        
+        assert_almost_equal(madeup.outputs.fitted_values, results[1], 5)
+        assert_almost_equal(madeup.outputs.enp, 6.9, 1)
+        assert_almost_equal(madeup.outputs.s, 1.4804, 4)
+    #
+    def test_2d_modfamily(self):
+        "2D - family modification"
+        (x, y, results, newdata1, newdata2, madeup) = self.d
+        madeup.model.span = 0.8
+        madeup.model.drop_square_flags = [True, False]
+        madeup.model.parametric_flags = [True, False]
+        madeup.model.family = "symmetric"
+        madeup.fit()
+        assert_almost_equal(madeup.outputs.fitted_values, results[2], 5)
+        assert_almost_equal(madeup.outputs.enp, 6.9, 1)
+        assert_almost_equal(madeup.outputs.s, 1.0868, 4)
+    #
+    def test_2d_modnormalize(self):
+        "2D - normalization modification"
+        (x, y, results, newdata1, newdata2, madeup) = self.d
+        madeup.model.span = 0.8
+        madeup.model.drop_square_flags = [True, False]
+        madeup.model.parametric_flags = [True, False]
+        madeup.model.family = "symmetric"
+        madeup.model.normalize = False
+        madeup.fit()
+        assert_almost_equal(madeup.outputs.fitted_values, results[3], 5)
+        assert_almost_equal(madeup.outputs.enp, 6.9, 1)
+        assert_almost_equal(madeup.outputs.s, 1.0868, 4)
+    #
+    def test_2d_pred_nostderr(self):
+        "2D prediction - no stderr"
+        (x, y, results, newdata1, newdata2, madeup) = self.d
+        madeup.model.span = 0.5
+        madeup.model.normalize = True
+        madeup.predict(newdata1, stderr=False)
+        assert_almost_equal(madeup.predicted.values, results[4], 5)
+        #
+        madeup_pred = madeup.predict(newdata1, stderr=False)
+        assert_almost_equal(madeup_pred.values, results[4], 5)
+    #
+    def test_2d_pred_nodata(self):
+        "2D prediction - nodata"
+        (x, y, results, newdata1, newdata2, madeup) = self.d
+        try:
+            madeup.predict(None)
+        except ValueError:
+            pass
         else:
-            dict.__setattr__(self, attr, value)
-
-#-------------------------------------------------------------------------------    
-class _loess_control(dict):
-
-    _optiondict = dict(surface=('interpolate', 'direct'),
-                       statistics=('approximate', 'exact'),
-                       trace_hat=('wait.to.decide', 'exact', 'approximate'),)
+            raise AssertionError,"The test should have failed"   
+    #
+    def test_2d_pred_stderr(self):
+        "2D prediction - w/ stderr"
+        (x, y, results, newdata1, newdata2, madeup) = self.d   
+        madeup.model.span = 0.5
+        madeup.model.normalize = True
+        madeup_pred = madeup.predict(newdata2, stderr=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)
+        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)
+        assert_almost_equal(madeup.predicted.df, 81.2319, 4)
+    #
+    def test_2d_pred_confinv(self):
+        "2D prediction - confidence"
+        (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.predicted.confidence(coverage=0.99)
+        assert_almost_equal(madeup.predicted.confidence_intervals.lower, 
+                            results[6][::3], 5)
+        assert_almost_equal(madeup.predicted.confidence_intervals.fit, 
+                            results[6][1::3], 5)
+        assert_almost_equal(madeup.predicted.confidence_intervals.upper, 
+                            results[6][2::3], 5)
+        # Direct access
+        confinv = madeup.predicted.confidence(coverage=0.99)
+        assert_almost_equal(confinv.lower, results[6][::3], 5)
+        assert_almost_equal(confinv.fit, results[6][1::3], 5)
+        assert_almost_equal(confinv.upper, results[6][2::3], 5)
     
-    def __init__(self, surface="interpolate", statistics="approximate",
-                 trace_hat="wait.to.decide", iterations=4, cell=0.2):
-        dict.__init__(self, surface=None, statistics=None, 
-                      trace_hat=None, iterations=iterations, 
-                      cell=cell)
-        self.surface = surface.lower()
-        self.statistics = statistics.lower()
-        self.trace_hat = trace_hat.lower()
+#####---------------------------------------------------------------------------
+#---- --- test 2D
+#####---------------------------------------------------------------------------
+class test_loess_gas(NumpyTestCase):
+    "Test class for lowess."
     #
-    def __getattr__(self, attr):
-        _got = getattr(super(dict,self), attr, None)
-        if _got is None:
-            _got = self.get(attr, None)
-        return _got
+    def __init__(self, *args, **kwds):
+        NumpyTestCase.__init__(self, *args, **kwds)
+        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,
+                       3.752, 0.537, 1.640, 5.055, 4.937, 1.561])
+        E = N.array([0.831, 1.045, 1.021, 0.970, 0.825, 0.891, 0.71, 0.801,
+                     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])
+        newdata = N.array([0.6650000, 0.7581667, 0.8513333, 0.9445000,
+                           1.0376667, 1.1308333, 1.2240000])
+        coverage = 0.99;
+
+        rfile = open(os.path.join('examples','gas_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)        
+        self.d = (E, NOx, gas_fit_E, newdata, coverage, results)
     #
-    def __setattr__(self, attr, value):
-        if attr in self.keys():
-            self.__setitem__(attr, value)
-        else:
-            dict.__setattr__(self, attr, value)
+    def test_1dbasic(self):
+        "Basic test 1d"
+        (E, NOx, gas_fit_E, newdata, coverage, results) = self.d
+        gas = cloess.loess(E,NOx)
+        gas.model.span = 2./3.
+        gas.fit()
+        assert_almost_equal(gas.outputs.fitted_values, results[0], 6)
+        assert_almost_equal(gas.outputs.enp, 5.5, 1)
+        assert_almost_equal(gas.outputs.s, 0.3404, 4)
     #
-    def __setitem__(self, attr, value):
-        if attr in _loess_control._optiondict.keys():
-            self.__setoption__(attr, value)
-        else:
-            dict.__setitem__(self, attr, value)
+    def test_1dbasic_alt(self):
+        "Basic test 1d - part #2"
+        (E, NOx, gas_fit_E, newdata, coverage, results) = self.d
+        gas_null = cloess.loess(E, NOx)
+        gas_null.model.span=1.0
+        gas_null.fit()
+        assert_almost_equal(gas_null.outputs.fitted_values, results[1], 6)
+        assert_almost_equal(gas_null.outputs.enp, 3.5, 1)
+        assert_almost_equal(gas_null.outputs.s, 0.5197, 4)
     #
-    def __setoption__(self, attr, value):
-        msg = "Invalid argument: %s must be in %s (got %s)"
-        attrlist = _loess_control._optiondict[attr]
-        if (not isinstance(value, str)) or \
-            (value.lower() not in attrlist):
-            raise ValueError, msg % (attr, attrlist, value)
-        dict.__setitem__(self, attr, value.lower())
+    def test_1dpredict(self):
+        "Basic test 1d - prediction"
+        (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)
+        assert_almost_equal(gas.predicted.values, results[2], 6)
     #
-#    def set_surface_status(self, new_stat):
-#        if new_stat.lower() not in ('none','exact','approximate'):
-#            raise ValueError,"Invalid value for the new_stat parameter: "\
-#                  "should be in ('none','exact','approximate'), got %s" % new_stat
-#        if self.surface == "interpolate" and new_stat == "approximate":
-#            if self.trace_hat == "approximate":
-#                new_stat = "2.approx"
-#            else:
-#                trace_hat='exact' in that case
-#                new_stat = "1.approx"
-#        return "/".join([self.surface, new_stat])
-    def set_surface_status(self, new_stat):
-        if new_stat.lower() not in ('none','exact','approximate'):
-            raise ValueError,"Invalid value for the new_stat parameter: "\
-                  "should be in ('none','exact','approximate'), got %s" % new_stat
-        statusdict = {"interpolate":{"none": 10,
-                                     "exact":11,
-                                     "1.approx":12,
-                                     "2.approx":13 },
-                      "direct":{"none" : 20,
-                                "exact": 21,
-                                "approximate": 22}}
-        if self.surface == "interpolate" and new_stat == "approximate":
-            if self.trace_hat == "approximate":
-                status = 13
-            else:
-                # trace_hat='exact' in that case
-                status = 12
-        else:
-            status = statusdict[self.surface][new_stat]
-        return status
+    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.predicted.confidence(0.99)
+        assert_almost_equal(gas.predicted.confidence_intervals.lower,
+                            results[3][0::3], 6)
+        assert_almost_equal(gas.predicted.confidence_intervals.fit,
+                            results[3][1::3], 6)
+        assert_almost_equal(gas.predicted.confidence_intervals.upper,
+                            results[3][2::3], 6)
         
-#      
-#            
-#
-#class loess(object):
-#    """
-#    
-#:Ivariables:
-#    x : ndarray
-#        Independent variables
-#    y : ndarray
-#        Dependent variables
-#    weights : ndarray
-#    """
-#    def __init__(self, x, y, weights=None,
-#                 span=0.75, degree=2, normalize=True, family="gaussian",
-#                 surface="interpolate", statistics="approximate", 
-#                 cell=0.2, trace_hat="wait.to.decide",iterations=4):
-#        x = narray(x, copy=False, subok=True, order='F')
-#        if x.ndim == 2:
-#            (n,d) = x.shape
-#        elif x.ndim == 1:
-#            (n,d) = (len(x),1)
-#        else:
-#            raise ValueError,"Argument 'x' should be 2D at most!"
-#        max_kd = max(n, 200)
-#        #    
-#        y = narray(y, copy=False, subok=True, order='F')
-#        if weights is None:
-#            weights = numpy.ones_like(y)
-#        self.inputs = paramdict(x=x, y=y, weights=weights, nobs=n, nvars=d)
-#        self.model = paramdict(span=span, degree=degree, 
-#                               normalize=normalize, family=family.lower(),
-#                               parametric=nzeros((d,), bool_, 'F'),
-#                               drop_square=nzeros((d,), bool_, 'F')
-#                               )        
-#        self.control = _loess_control(surface=surface.lower(), 
-#                                      statistics=statistics.lower(),
-#                                      trace_hat=trace_hat.lower(),
-#                                      iterations=iterations, cell=cell, 
-#                                      )
-#        self.outputs = paramdict(fitted_values=nempty((n,), float_, 'F'),
-#                                 fitted_residuals=nempty((n,), float_, 'F'),
-#                                 pseudovalues=nempty((n,), float_, 'F'),
-#                                 diagonal=nempty((n,), float_, 'F'),
-#                                 robust=numpy.ones((n,), float_, 'F'),
-#                                 divisor=nempty((d,), float_, 'F'),
-#                                 enp=0, s=0, one_delta=0, two_delta=0,
-#                                 trace_hat=0
-#                                 )
-#        self.kd_tree = paramdict(parameter=nempty((7,), int_, 'F'),
-#                                 a=nempty((max_kd,), int_, 'F'),
-#                                 xi=nempty((max_kd,), float_, 'F'),
-#                                 vert=nempty((d*2,), float_, 'F'),
-#                                 vval=nempty(((d+1)*max_kd,), float_, 'F')
-#                                 )
-#        #
-#        if self.model.family == "gaussian":
-#            self.control['iterations'] = 0
-#        if self.control.trace_hat == "wait.to.decide":
-#            if (self.control.surface == "interpolate") and n >= 500:
-#                self.control.trace_hat = "approximate"
-#            else:
-#                self.control.trace_hat = "exact"
-#    #......................................................            
-#    def fit(self, span = 0.75, degree = 2, parametric = False,
-#            drop_square = False, normalize = True,
-#            statistics = "approximate", surface = "interpolate",
-#            cell = 0.2, iterations = 1, trace_hat = "exact"):
-#        
-#        # Get input....................
-#        inputs = self.inputs
-#        (x, y, n, d, weights) = [inputs[k] 
-#                                 for k in ('x','y','nobs','nvars', 'weights')]
-#
-#        max_kd = max(n, 200) 
-##        a = max_kd
-#        one_delta = two_delta = trace_hat_out = 0
-#        
-#        # Set temporary ...............
-#        kd_tree = self.kd_tree
-#        (a, xi, vert, vval, parameter) = [kd_tree[k] 
-#                                          for k in ('a', 'xi', 'vert', 'vval', 
-#                                                    'parameter')]
-#        a_tmp = nempty((max_kd,), int_)
-#        xi_tmp = nempty((max_kd,), float_)
-#        vert_tmp = nempty((2*d,), float_)
-#        vval_tmp = nempty(((d+1)*max_kd,), float_)
-#        
-#        # Check control ................
-#        control = self.control
-#        surface = control.surface
-#        statistics = control.statistics
-#        iterations = control.iterations
-#        trace_hat = control.trace_hat
-#        # Get model ....................
-#        model = self.model
-#        family = model.family
-#        parametric = model.parametric
-#        drop_square = model.drop_square
-#        (span, degree, normalize) = [model[k] 
-#                                     for k in ('span', 'degree', 'normalize')]                         
-#        #
-#        outputs = self.outputs 
-#        fitted_values = outputs.fitted_values
-#        fitted_residuals = outputs.fitted_residuals
-#        pseudovalues = outputs.pseudovalues 
-#        diagonal = outputs.diagonal
-#        robust = outputs.robust
-#        (enp, s, one_delta, two_delta) = [outputs[k]
-#                                          for k in ('enp','s','one_delta','two_delta')]
-#        trace_hat = outputs.trace_hat
-##        parameter = 7
-#        (d1_tmp, d2_tmp, trL_tmp, zero,) = (0., 0., 0., 0.)
-#        (delta1, delta2, trL, trace_hat_in) = (0, 0, 0, 0)
-#        temp = nempty((n,), float_)
-#        diag_tmp = nempty((n,), float_)
-#        param_tmp = nempty((n,), int_)
-#        if iterations > 0:
-#            pseudo_resid = nempty((n,), float_)
-#        #
-#        new_cell = span * cell
-#        #
-#        loesslogging.debug("initial divisor: %s" % self.outputs.divisor)
-#        if normalize and d > 1:
-#            cut = int(ceil(0.1*n))
-#            x_trimmed = numpy.sort(x, axis=0)[cut:-cut]
-#            outputs.divisor = x_trimmed.std(axis=0)
-#            outputs.divisor *= numpy.sqrt(n/float(n-1))
-#            x = x / outputs.divisor
-#        else:
-#            outputs.divisor = numpy.ones(d, float_)
-#        loesslogging.debug("final divisor: %s" % self.outputs.divisor)
-#        #
-#        sum_drop_sqr = sum(drop_square)
-#        #
-#        parametric = narray(parametric, copy=True)
-#        parametric.resize((d,))
-#        sum_parametric = parametric.sum()
-#        nonparametric = numpy.logical_not(parametric).sum()
-#        order_parametric = numpy.argsort(parametric)
-#        #
-#        order_drop_sqr = 2 - drop_square[order_parametric]
-#        x = x[:,order_parametric].ravel()
-#        #
-#        if degree == 1 and sum_drop_sqr:
-#            msg = "Specified the square of a factor predictor to be dropped"\
-#                  " when degree = 1"
-#            raise ValueError, msg
-#        if d == 1 and sum_drop_sqr:
-#            msg = "Specified the square of a predictor to be dropped "\
-#                  "with only one numeric predictor"
-#            raise ValueError, msg  
-#        if sum_parametric == d:
-#            raise ValueError, "Specified parametric for all predictors"
-#        #
-#        new_stat = statistics.lower()
-#        loesslogging.debug("start iteration: %s" % new_stat)
-#        for j in range(iterations+1):
-#            if j > 0:
-#                new_stat = "none"
-#            robust = weights * robust
-#            surf_stat = control.set_surface_status(new_stat)
-#            #setLf = (surf_stat.lower() == "interpolate/exact")
-#            setLf = int(surf_stat == 11)
-#            loesslogging.debug("iteration: %i: %s - %s" % (j, surf_stat, setLf))
-#            #
-#            (surf_stat, fitted_values, parameter, a, 
-#             xi, vert, vval, diagonal, trL, delta1, delta2, 
-#             ) = loess_raw(y, x, weights, robust, d, n, span, degree, 
-#                      nonparametric, order_drop_sqr, sum_drop_sqr, 
-#                      new_cell, surf_stat, fitted_values, parameter, a, 
-#                      xi, vert, vval, diagonal, trL, delta1, delta2, 
-#                      setLf)
-#            #
-#            if j == 0:
-#                trace_hat_out = trL
-#                one_delta = delta1
-#                two_delta = delta2
-#            fitted_residuals = y - fitted_values
-#            if j < iterations:
-#                (fitted_residuals, n, robust, temp) = lowesw(fitted_residuals, n, robust, temp)
-#        #
-#        if (iterations > 0):
-#            lowesp(n, y, fitted_values, weights, robust, temp, pseudovalues)
-#            (temp, param_tmp, a_tmp, xi_tmp,
-#             vert_tmp, vval_tmp, diag_tmp, trL_tmp, d1_tmp, d2_tmp, 
-#             ) = loess_raw(pseudovalues, x, weights, weights, d, n, span, 
-#                               degree, nonparametric, order_drop_sqr, sum_drop_sqr,
-#                               new_cell, surf_stat, temp, param_tmp, a_tmp, xi_tmp,
-#                               vert_tmp, vval_tmp, diag_tmp, trL_tmp, d1_tmp, d2_tmp, 
-#                               zero)
-#            pseudo_resid = pseudovalues - temp
-#        #
-#        if (iterations == 0):
-#            sum_squares = numpy.sum(weights * fitted_residuals**2)
-#        else:
-#            sum_squares = numpy.sum(weights * pseudo_resid**2)
-#        #
-#        loesslogging.debug("setLf:%s" % setLf)
-#        loesslogging.debug("SSR:%s" % sum_squares)
-#        outputs.enp = (one_delta) + 2 * (trace_hat_out) - n;
-#        loesslogging.debug("one_delta:%s-trace_out:%s" % (one_delta, trace_hat_out))
-#        outputs.s = numpy.sqrt(sum_squares / (one_delta))
-#        for attr in ('one_delta','two_delta','diagonal','trace_hat',
-#                     'fitted_values','fitted_residuals','pseudovalues'):
-#            setattr(outputs,attr,eval(attr))
-##        (outputs.one_delta, outputs.two_delta) = (one_delta, two_delta)
-##        outputs.diagonal = diagonal
-##        outputs.
-#        #
-#    #......................................................
-#    def summary(self):
-#        print "Number of Observations         : %d" % self.inputs.nobs
-#        print "Equivalent Number of Parameters: %.1f" % self.outputs.enp
-#        if self.model.family == "gaussian":
-#            print "Residual Standard Error        : %.4f" % self.outputs.s
-#        else:
-#            print "Residual Scale Estimate        : %.4f" % self.outputs.s
-#    #.......................................................
-#    def predict(self):
-#        outputs = self.outputs
-#        self.prediction = paramdict(fit=None,
-#                                    se_fit=None,
-#                                    residual_scale=outputs.s,
-#                                    df=outputs.one_delta**2 / outputs.two_delta,
-#                                    )
-#        raise NotImplementedError
-#    
-#    
-#
-#
-#    
-#
-##    size_info[0] = lo->in.p;
-##    size_info[1] = lo->in.n;
-##    size_info[2] = m;
-##    
-##    pred_(lo->in.y, lo->in.x, eval, size_info, &lo->out.s,
-##        lo->in.weights,
-##        lo->out.robust,
-##        &lo->model.span,
-##        &lo->model.degree,
-##        &lo->model.normalize,
-##        lo->model.parametric,
-##        lo->model.drop_square,
-##        &lo->control.surface,
-##        &lo->control.cell,
-##        &lo->model.family,
-##        lo->kd_tree.parameter,
-##        lo->kd_tree.a,
-##        lo->kd_tree.xi,
-##        lo->kd_tree.vert,
-##        lo->kd_tree.vval,
-##        lo->out.divisor,
-##        &se,
-##        pre->fit,
-##        pre->se_fit);
-##}
-#
-##void
-##pred_(y, x_, new_x, size_info, s, weights, robust, span, degree, 
-##    normalize, parametric, drop_square, surface, cell, family,
-##    parameter, a, xi, vert, vval, divisor, se, fit, se_fit)
-##double  *y, *x_, *new_x, *weights, *robust, *span, *cell, *fit, *s,
-##        *xi, *vert, *vval, *divisor, *se_fit;
-##long    *size_info, *degree, *normalize, *parametric, *drop_square, 
-##        *parameter, *a, *se;
-##char    **surface, **family;
-##{     
-##    double  *x, *x_tmp, *x_evaluate, *L, new_cell, z, tmp, *fit_tmp,
-##            *temp, sum, mean;
-##    long    N, D, M, sum_drop_sqr = 0, sum_parametric = 0,
-##            nonparametric = 0, *order_parametric, *order_drop_sqr;
-##    int     i, j, k, p, cut, comp();
-##
-##    D = size_info[0];
-##    N = size_info[1];
-##    M = size_info[2];
-##
-##    x = (double *) malloc(N * D * sizeof(double));
-##    x_tmp = (double *) malloc(N * D * sizeof(double));
-##    x_evaluate = (double *) malloc(M * D * sizeof(double));
-##    L = (double *) malloc(N * M * sizeof(double));
-##    order_parametric = (long *) malloc(D * sizeof(long));
-##    order_drop_sqr = (long *) malloc(D * sizeof(long));
-##    temp = (double *) malloc(N * D * sizeof(double));
-##
-##    for(i = 0; i < (N * D); i++)
-##        x_tmp[i] = x_[i];
-##    for(i = 0; i < D; i++) {
-##        k = i * M;
-##        for(j = 0; j < M; j++) {
-##            p = k + j;
-##            new_x[p] = new_x[p] / divisor[i];
-##        }
-##    }
-##    if(!strcmp(*surface, "direct") || se) {
-##        for(i = 0; i < D; i++) {
-##            k = i * N;
-##            for(j = 0; j < N; j++) {
-##                p = k + j;
-##                x_tmp[p] = x_[p] / divisor[i];
-##                }
-##        }
-##    }
-##    j = D - 1;
-##    for(i = 0; i < D; i++) {
-##            sum_drop_sqr = sum_drop_sqr + drop_square[i];
-##            sum_parametric = sum_parametric + parametric[i];
-##            if(parametric[i])
-##                order_parametric[j--] = i;
-##        else
-##                order_parametric[nonparametric++] = i;
-##    }
-##    for(i = 0; i < D; i++) {
-##        order_drop_sqr[i] = 2 - drop_square[order_parametric[i]];
-##        k = i * M;
-##        p = order_parametric[i] * M;
-##        for(j = 0; j < M; j++)
-##            x_evaluate[k + j] = new_x[p + j];
-##        k = i * N;
-##        p = order_parametric[i] * N;
-##        for(j = 0; j < N; j++)
-##            x[k + j] = x_tmp[p + j];
-##        }
-##    for(i = 0; i < N; i++)
-##        robust[i] = weights[i] * robust[i];
-##
-##    if(!strcmp(*surface, "direct")) {
-##        if(*se) {
-##            loess_dfitse(y, x, x_evaluate, weights, robust,
-##            !strcmp(*family, "gaussian"), span, degree,
-##                    &nonparametric, order_drop_sqr, &sum_drop_sqr,
-##                    &D, &N, &M, fit, L);
-##            }
-##        else {
-##            loess_dfit(y, x, x_evaluate, robust, span, degree,
-##                       &nonparametric, order_drop_sqr, &sum_drop_sqr,
-##                       &D, &N, &M, fit);
-##            }
-##        }
-##    else {
-##        loess_ifit(parameter, a, xi, vert, vval, &M, x_evaluate, fit);
-##        if(*se) {
-##                new_cell = (*span) * (*cell);
-##                fit_tmp = (double *) malloc(M * sizeof(double));
-##                loess_ise(y, x, x_evaluate, weights, span, degree,
-##                &nonparametric, order_drop_sqr, &sum_drop_sqr,
-##                &new_cell, &D, &N, &M, fit_tmp, L);
-##                free(fit_tmp);
-##                }
-##        }
-##    if(*se) {
-##        for(i = 0; i < N; i++) {
-##            k = i * M;
-##            for(j = 0; j < M; j++) {
-##                p = k + j;
-##                L[p] = L[p] / weights[i];
-##                L[p] = L[p] * L[p];
-##            }
-##        }
-##        for(i = 0; i < M; i++) {
-##            tmp = 0;
-##            for(j = 0; j < N; j++)
-##                tmp = tmp + L[i + j * M];
-##            se_fit[i] = (*s) * sqrt(tmp);
-##        }
-##    }
-##    free(x);
-##    free(x_tmp);
-##    free(x_evaluate);
-##    free(L);
-##    free(order_parametric);
-##    free(order_drop_sqr);
-##    free(temp);
-##}
-##
-##void
-##pred_free_mem(pre)
-##struct    pred_struct    *pre;
-##{
-##    free(pre->fit);
-##    free(pre->se_fit);
-##}
-
-
-
-################################################################################
+########################################################################
 if __name__ == '__main__':
-    import numpy as N
-    _data = open(os.path.join('examples','sin_data'), 'r')
-    _result = open(os.path.join('examples','sin_result'), 'r')
-    x = N.arange(1.,121.)
-    y = N.concatenate([N.fromiter((float(v) for v in L.rstrip().split()), float_) 
-                       for L in _data.readlines()])
-    z = N.concatenate([N.fromiter((float(v) for v in L.rstrip().split()), float_) 
-                       for L in _result.readlines()])
-#    x = N.concatenate([N.fromiter((float(v) for v in L.rstrip().split()), float_) 
-#                       for L in open('_data','r').readlines()])
-#    x.shape = (-1,2)
-#    y = N.concatenate([N.fromiter((float(v) for v in L.rstrip().split()), float_) 
-#                       for L in open('_response','r').readlines()])
-    tester = cloess.loess(x,y)
-    enp_theo = 4.34
-    rse_theo = 0.579
-    trc_smoother = 4.73
-    print "OK"
-    tester.fit()
-    tester.summary()
-    print "Fit OK"
+    NumpyTest().run()       
+
+    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,
+                       3.752, 0.537, 1.640, 5.055, 4.937, 1.561])
+        E = N.array([0.831, 1.045, 1.021, 0.970, 0.825, 0.891, 0.71, 0.801,
+                     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)
+    
\ No newline at end of file

Modified: trunk/Lib/sandbox/pyloess/sandbox/src/c_numpy.pxd
===================================================================
--- trunk/Lib/sandbox/pyloess/sandbox/src/c_numpy.pxd	2007-03-14 16:52:59 UTC (rev 2848)
+++ trunk/Lib/sandbox/pyloess/sandbox/src/c_numpy.pxd	2007-03-16 20:42:51 UTC (rev 2849)
@@ -123,4 +123,7 @@
     object PyArray_IterNew(object arr)
     void PyArray_ITER_NEXT(flatiter it)
 
+
+    object PyArray_SimpleNewFromData(int ndims, npy_intp* dims, NPY_TYPES type_num, void* data)
+
     void import_array()

Modified: trunk/Lib/sandbox/pyloess/sandbox/src/cloess.c
===================================================================
--- trunk/Lib/sandbox/pyloess/sandbox/src/cloess.c	2007-03-14 16:52:59 UTC (rev 2848)
+++ trunk/Lib/sandbox/pyloess/sandbox/src/cloess.c	2007-03-16 20:42:51 UTC (rev 2849)
@@ -1,4 +1,4 @@
-/* Generated by Pyrex 0.9.5.1a on Wed Mar 14 08:14:04 2007 */
+/* Generated by Pyrex 0.9.5.1a on Fri Mar 16 16:29:33 2007 */
 
 #include "Python.h"
 #include "structmember.h"
@@ -36,6 +36,9 @@
 
 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
 
+static PyObject *__Pyx_UnpackItem(PyObject *); /*proto*/
+static int __Pyx_EndUnpack(PyObject *); /*proto*/
+
 static int __Pyx_PrintItem(PyObject *); /*proto*/
 static int __Pyx_PrintNewline(void); /*proto*/
 
@@ -92,6 +95,8 @@
   PyObject_HEAD
   loess_outputs (*_base);
   long nobs;
+  long npar;
+  int activated;
 };
 
 
@@ -102,18 +107,18 @@
 };
 
 
-struct __pyx_obj_6cloess_confidence_interval {
+struct __pyx_obj_6cloess_conf_intervals {
   PyObject_HEAD
-  conf_inv (*_base);
+  conf_inv _base;
   PyObject *nest;
 };
 
 
 struct __pyx_obj_6cloess_loess_predicted {
   PyObject_HEAD
-  prediction (*_base);
+  prediction _base;
   long nest;
-  struct __pyx_obj_6cloess_confidence_interval *conf_interval;
+  struct __pyx_obj_6cloess_conf_intervals *confidence_intervals;
 };
 
 
@@ -126,6 +131,8 @@
   struct __pyx_obj_6cloess_loess_kd_tree *kd_tree;
   struct __pyx_obj_6cloess_loess_outputs *outputs;
   struct __pyx_obj_6cloess_loess_predicted *predicted;
+  long nobs;
+  long npar;
 };
 
 static PyTypeObject *__pyx_ptype_6cloess_loess_inputs = 0;
@@ -134,23 +141,51 @@
 static PyTypeObject *__pyx_ptype_6cloess_loess_model = 0;
 static PyTypeObject *__pyx_ptype_6cloess_loess_outputs = 0;
 static PyTypeObject *__pyx_ptype_6cloess_loess_anova = 0;
-static PyTypeObject *__pyx_ptype_6cloess_confidence_interval = 0;
+static PyTypeObject *__pyx_ptype_6cloess_conf_intervals = 0;
 static PyTypeObject *__pyx_ptype_6cloess_loess_predicted = 0;
 static PyTypeObject *__pyx_ptype_6cloess_loess = 0;
-static PyObject *__pyx_k7;
-static PyObject *__pyx_k8;
-static PyObject *__pyx_k9;
-static PyObject *(__pyx_f_6cloess_floatarray_from_data(PyObject *,PyObject *,double (*))); /*proto*/
-static PyObject *(__pyx_f_6cloess_boolarray_from_data(PyObject *,PyObject *,int (*))); /*proto*/
+static PyObject *__pyx_k35;
+static PyObject *__pyx_k36;
+static PyObject *__pyx_k37;
+static PyObject *(__pyx_f_6cloess_floatarray_from_data(int ,int ,double (*))); /*proto*/
+static PyObject *(__pyx_f_6cloess_boolarray_from_data(int ,int ,int (*))); /*proto*/
 
 
 /* Implementation of cloess */
 
-static char (__pyx_k1[]) = "Weights";
+static char (__pyx_k1[]) = "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        ";
 static char (__pyx_k2[]) = "Number of observations.";
 static char (__pyx_k3[]) = "Number of independent variables.";
-static char (__pyx_k4[]) = "Normalize the variables. Only useful if more than one variable...";
-static char (__pyx_k5[]) = "Equivalent number of parameters.";
+static char (__pyx_k4[]) = "\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        ";
+static char (__pyx_k5[]) = "\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        ";
+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_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        ";
+static char (__pyx_k15[]) = "\n    fitted_values : ndarray\n        The (n,) ndarray of fitted values.\n        ";
+static char (__pyx_k16[]) = "\n    fitted_residuals : ndarray\n        The (n,) ndarray of fitted residuals (observations - fitted values).\n        ";
+static char (__pyx_k17[]) = "\n    pseudovalues : ndarray\n        The (n,) ndarray of adjusted values of the response when robust estimation \n        is used.\n        ";
+static char (__pyx_k18[]) = "\n    diagonal :\n        Diagonal of the operator hat matrix.\n        ";
+static char (__pyx_k19[]) = "\n    robust : ndarray\n        The (n,) ndarray of robustness weights for robust fitting.\n        ";
+static char (__pyx_k20[]) = "Equivalent number of parameters.";
+static char (__pyx_k21[]) = "\n    enp : float\n        Equivalent number of parameters.\n        ";
+static char (__pyx_k22[]) = "\n    s : float\n        Estimate of the scale of residuals.\n        ";
+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 PyObject *__pyx_n_c_python;
 static PyObject *__pyx_n_c_numpy;
@@ -158,97 +193,48 @@
 static PyObject *__pyx_n_c_loess;
 static PyObject *__pyx_n_False;
 
-static PyObject *__pyx_n_empty;
-static PyObject *__pyx_n_float;
-static PyObject *__pyx_n_dtype;
-static PyObject *__pyx_n_size;
 static PyObject *__pyx_n_shape;
 
-
-static PyObject *__pyx_f_6cloess_floatarray_from_data(PyObject *__pyx_v_rows,PyObject *__pyx_v_cols,double (*__pyx_v_data)) {
+static PyObject *__pyx_f_6cloess_floatarray_from_data(int __pyx_v_rows,int __pyx_v_cols,double (*__pyx_v_data)) {
   PyArrayObject *__pyx_v_a_ndr;
-  double (*__pyx_v_a_dat);
-  PyObject *__pyx_v_i;
+  npy_intp __pyx_v_size;
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
-  PyObject *__pyx_2 = 0;
+  int __pyx_2;
   PyObject *__pyx_3 = 0;
   PyObject *__pyx_4 = 0;
-  PyObject *__pyx_5 = 0;
-  long __pyx_6;
-  long __pyx_7;
-  int __pyx_8;
-  int __pyx_9;
-  Py_INCREF(__pyx_v_rows);
-  Py_INCREF(__pyx_v_cols);
   __pyx_v_a_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  __pyx_v_i = Py_None; Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":22 */
-  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
-  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_n_empty); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyNumber_Multiply(__pyx_v_rows, __pyx_v_cols); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
-  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
-  PyTuple_SET_ITEM(__pyx_3, 0, __pyx_1);
-  __pyx_1 = 0;
-  __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
-  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_3);
-  __pyx_3 = 0;
-  __pyx_3 = PyDict_New(); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
-  __pyx_4 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
-  __pyx_5 = PyObject_GetAttr(__pyx_4, __pyx_n_float); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
-  Py_DECREF(__pyx_4); __pyx_4 = 0;
-  if (PyDict_SetItem(__pyx_3, __pyx_n_dtype, __pyx_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
-  Py_DECREF(__pyx_5); __pyx_5 = 0;
-  __pyx_4 = PyEval_CallObjectWithKeywords(__pyx_2, __pyx_1, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  Py_DECREF(__pyx_3); __pyx_3 = 0;
-  if (!__Pyx_TypeTest(__pyx_4, __pyx_ptype_7c_numpy_ndarray)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
-  Py_DECREF(((PyObject *)__pyx_v_a_ndr));
-  __pyx_v_a_ndr = ((PyArrayObject *)__pyx_4);
-  __pyx_4 = 0;
-
   /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":23 */
-  __pyx_v_a_dat = ((double (*))__pyx_v_a_ndr->data);
+  __pyx_v_size = (__pyx_v_rows * __pyx_v_cols);
 
   /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":24 */
-  __pyx_5 = PyObject_GetAttr(((PyObject *)__pyx_v_a_ndr), __pyx_n_size); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; goto __pyx_L1;}
-  __pyx_7 = PyInt_AsLong(__pyx_5); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; goto __pyx_L1;}
-  Py_DECREF(__pyx_5); __pyx_5 = 0;
-  for (__pyx_6 = 0; __pyx_6 < __pyx_7; ++__pyx_6) {
-    __pyx_2 = PyInt_FromLong(__pyx_6); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; goto __pyx_L1;}
-    Py_DECREF(__pyx_v_i);
-    __pyx_v_i = __pyx_2;
-    __pyx_2 = 0;
+  __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;}
+  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":25 */
-    __pyx_8 = PyInt_AsLong(__pyx_v_i); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; goto __pyx_L1;}
-    __pyx_9 = PyInt_AsLong(__pyx_v_i); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; goto __pyx_L1;}
-    (__pyx_v_a_dat[__pyx_9]) = (__pyx_v_data[__pyx_8]);
-  }
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":29 */
+  __pyx_2 = (__pyx_v_cols > 1);
+  if (__pyx_2) {
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":26 */
-  __pyx_1 = PyInt_FromLong(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; goto __pyx_L1;}
-  if (PyObject_Cmp(__pyx_v_cols, __pyx_1, &__pyx_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; goto __pyx_L1;}
-  __pyx_8 = __pyx_8 > 0;
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  if (__pyx_8) {
-
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":27 */
-    __pyx_3 = PyTuple_New(2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; goto __pyx_L1;}
-    Py_INCREF(__pyx_v_rows);
-    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_rows);
-    Py_INCREF(__pyx_v_cols);
-    PyTuple_SET_ITEM(__pyx_3, 1, __pyx_v_cols);
-    if (PyObject_SetAttr(((PyObject *)__pyx_v_a_ndr), __pyx_n_shape, __pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; goto __pyx_L1;}
-    Py_DECREF(__pyx_3); __pyx_3 = 0;
-    goto __pyx_L4;
+    /* "/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;}
+    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;}
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    goto __pyx_L2;
   }
-  __pyx_L4:;
+  __pyx_L2:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":28 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":31 */
   Py_INCREF(((PyObject *)__pyx_v_a_ndr));
   __pyx_r = ((PyObject *)__pyx_v_a_ndr);
   goto __pyx_L0;
@@ -257,138 +243,82 @@
   goto __pyx_L0;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);
-  Py_XDECREF(__pyx_2);
   Py_XDECREF(__pyx_3);
   Py_XDECREF(__pyx_4);
-  Py_XDECREF(__pyx_5);
   __Pyx_AddTraceback("cloess.floatarray_from_data");
   __pyx_r = 0;
   __pyx_L0:;
   Py_DECREF(__pyx_v_a_ndr);
-  Py_DECREF(__pyx_v_i);
-  Py_DECREF(__pyx_v_rows);
-  Py_DECREF(__pyx_v_cols);
   return __pyx_r;
 }
 
-static PyObject *__pyx_n_int;
 static PyObject *__pyx_n_astype;
 static PyObject *__pyx_n_bool;
 
-
-static PyObject *__pyx_f_6cloess_boolarray_from_data(PyObject *__pyx_v_rows,PyObject *__pyx_v_cols,int (*__pyx_v_data)) {
+static PyObject *__pyx_f_6cloess_boolarray_from_data(int __pyx_v_rows,int __pyx_v_cols,int (*__pyx_v_data)) {
   PyArrayObject *__pyx_v_a_ndr;
-  int (*__pyx_v_a_dat);
-  PyObject *__pyx_v_i;
+  npy_intp __pyx_v_size;
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
-  PyObject *__pyx_2 = 0;
+  int __pyx_2;
   PyObject *__pyx_3 = 0;
   PyObject *__pyx_4 = 0;
-  PyObject *__pyx_5 = 0;
-  long __pyx_6;
-  long __pyx_7;
-  int __pyx_8;
-  int __pyx_9;
-  Py_INCREF(__pyx_v_rows);
-  Py_INCREF(__pyx_v_cols);
   __pyx_v_a_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  __pyx_v_i = Py_None; Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":33 */
-  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
-  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_n_empty); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":36 */
+  __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;}
+  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;
-  __pyx_1 = PyNumber_Multiply(__pyx_v_rows, __pyx_v_cols); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
-  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
-  PyTuple_SET_ITEM(__pyx_3, 0, __pyx_1);
-  __pyx_1 = 0;
-  __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
-  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_3);
-  __pyx_3 = 0;
-  __pyx_3 = PyDict_New(); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
-  __pyx_4 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
-  __pyx_5 = PyObject_GetAttr(__pyx_4, __pyx_n_int); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
-  Py_DECREF(__pyx_4); __pyx_4 = 0;
-  if (PyDict_SetItem(__pyx_3, __pyx_n_dtype, __pyx_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
-  Py_DECREF(__pyx_5); __pyx_5 = 0;
-  __pyx_4 = PyEval_CallObjectWithKeywords(__pyx_2, __pyx_1, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  Py_DECREF(__pyx_3); __pyx_3 = 0;
-  if (!__Pyx_TypeTest(__pyx_4, __pyx_ptype_7c_numpy_ndarray)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; goto __pyx_L1;}
-  Py_DECREF(((PyObject *)__pyx_v_a_ndr));
-  __pyx_v_a_ndr = ((PyArrayObject *)__pyx_4);
-  __pyx_4 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":34 */
-  __pyx_v_a_dat = ((int (*))__pyx_v_a_ndr->data);
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":43 */
+  __pyx_2 = (__pyx_v_cols > 1);
+  if (__pyx_2) {
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":35 */
-  __pyx_5 = PyObject_GetAttr(((PyObject *)__pyx_v_a_ndr), __pyx_n_size); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; goto __pyx_L1;}
-  __pyx_7 = PyInt_AsLong(__pyx_5); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; goto __pyx_L1;}
-  Py_DECREF(__pyx_5); __pyx_5 = 0;
-  for (__pyx_6 = 0; __pyx_6 < __pyx_7; ++__pyx_6) {
-    __pyx_2 = PyInt_FromLong(__pyx_6); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; goto __pyx_L1;}
-    Py_DECREF(__pyx_v_i);
-    __pyx_v_i = __pyx_2;
-    __pyx_2 = 0;
-
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":36 */
-    __pyx_8 = PyInt_AsLong(__pyx_v_i); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; goto __pyx_L1;}
-    __pyx_9 = PyInt_AsLong(__pyx_v_i); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; goto __pyx_L1;}
-    (__pyx_v_a_dat[__pyx_9]) = (__pyx_v_data[__pyx_8]);
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":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;}
+    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;}
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    goto __pyx_L2;
   }
+  __pyx_L2:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":37 */
-  __pyx_1 = PyInt_FromLong(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; goto __pyx_L1;}
-  if (PyObject_Cmp(__pyx_v_cols, __pyx_1, &__pyx_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; goto __pyx_L1;}
-  __pyx_8 = __pyx_8 > 0;
+  /* "/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;}
+  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;}
+  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;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  if (__pyx_8) {
-
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":38 */
-    __pyx_3 = PyTuple_New(2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; goto __pyx_L1;}
-    Py_INCREF(__pyx_v_rows);
-    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_rows);
-    Py_INCREF(__pyx_v_cols);
-    PyTuple_SET_ITEM(__pyx_3, 1, __pyx_v_cols);
-    if (PyObject_SetAttr(((PyObject *)__pyx_v_a_ndr), __pyx_n_shape, __pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; goto __pyx_L1;}
-    Py_DECREF(__pyx_3); __pyx_3 = 0;
-    goto __pyx_L4;
-  }
-  __pyx_L4:;
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":39 */
-  __pyx_4 = PyObject_GetAttr(((PyObject *)__pyx_v_a_ndr), __pyx_n_astype); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; goto __pyx_L1;}
-  __pyx_5 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; goto __pyx_L1;}
-  __pyx_2 = PyObject_GetAttr(__pyx_5, __pyx_n_bool); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; goto __pyx_L1;}
-  Py_DECREF(__pyx_5); __pyx_5 = 0;
-  __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; goto __pyx_L1;}
-  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_2);
-  __pyx_2 = 0;
-  __pyx_3 = PyObject_CallObject(__pyx_4, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; goto __pyx_L1;}
-  Py_DECREF(__pyx_4); __pyx_4 = 0;
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_r = __pyx_3;
-  __pyx_3 = 0;
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  __pyx_r = __pyx_4;
+  __pyx_4 = 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);
   Py_XDECREF(__pyx_4);
-  Py_XDECREF(__pyx_5);
   __Pyx_AddTraceback("cloess.boolarray_from_data");
   __pyx_r = 0;
   __pyx_L0:;
   Py_DECREF(__pyx_v_a_ndr);
-  Py_DECREF(__pyx_v_i);
-  Py_DECREF(__pyx_v_rows);
-  Py_DECREF(__pyx_v_cols);
   return __pyx_r;
 }
 
@@ -396,26 +326,18 @@
 static PyObject *__pyx_f_6cloess_12loess_inputs_1x___get__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
-  PyObject *__pyx_2 = 0;
-  PyObject *__pyx_3 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":50 */
-  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->n); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; goto __pyx_L1;}
-  __pyx_2 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->p); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; goto __pyx_L1;}
-  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->x); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; goto __pyx_L1;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
-  __pyx_r = __pyx_3;
-  __pyx_3 = 0;
+  /* "/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;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
   goto __pyx_L0;
 
   __pyx_r = Py_None; Py_INCREF(Py_None);
   goto __pyx_L0;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);
-  Py_XDECREF(__pyx_2);
-  Py_XDECREF(__pyx_3);
   __Pyx_AddTraceback("cloess.loess_inputs.x.__get__");
   __pyx_r = 0;
   __pyx_L0:;
@@ -427,26 +349,18 @@
 static PyObject *__pyx_f_6cloess_12loess_inputs_1y___get__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
-  PyObject *__pyx_2 = 0;
-  PyObject *__pyx_3 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":54 */
-  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->n); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; goto __pyx_L1;}
-  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; goto __pyx_L1;}
-  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->y); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; goto __pyx_L1;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
-  __pyx_r = __pyx_3;
-  __pyx_3 = 0;
+  /* "/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;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
   goto __pyx_L0;
 
   __pyx_r = Py_None; Py_INCREF(Py_None);
   goto __pyx_L0;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);
-  Py_XDECREF(__pyx_2);
-  Py_XDECREF(__pyx_3);
   __Pyx_AddTraceback("cloess.loess_inputs.y.__get__");
   __pyx_r = 0;
   __pyx_L0:;
@@ -458,26 +372,18 @@
 static PyObject *__pyx_f_6cloess_12loess_inputs_7weights___get__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
-  PyObject *__pyx_2 = 0;
-  PyObject *__pyx_3 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":59 */
-  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->n); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; goto __pyx_L1;}
-  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; goto __pyx_L1;}
-  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->weights); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; goto __pyx_L1;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
-  __pyx_r = __pyx_3;
-  __pyx_3 = 0;
+  /* "/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;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
   goto __pyx_L0;
 
   __pyx_r = Py_None; Py_INCREF(Py_None);
   goto __pyx_L0;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);
-  Py_XDECREF(__pyx_2);
-  Py_XDECREF(__pyx_3);
   __Pyx_AddTraceback("cloess.loess_inputs.weights.__get__");
   __pyx_r = 0;
   __pyx_L0:;
@@ -486,11 +392,12 @@
 }
 
 static PyObject *__pyx_n_ndim;
+static PyObject *__pyx_n_size;
 static PyObject *__pyx_n_ValueError;
 
-static PyObject *__pyx_k12p;
+static PyObject *__pyx_k38p;
 
-static char (__pyx_k12[]) = "Invalid size of the 'weights' vector!";
+static char (__pyx_k38[]) = "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) {
@@ -503,40 +410,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":64 */
-  __pyx_1 = PyArray_FROMANY(__pyx_v_w,NPY_DOUBLE,1,1,NPY_OWNDATA); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; goto __pyx_L1;}
+  /* "/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;}
   Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_1)));
   Py_DECREF(((PyObject *)__pyx_v_w_ndr));
   __pyx_v_w_ndr = ((PyArrayObject *)__pyx_1);
   Py_DECREF(__pyx_1); __pyx_1 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":65 */
-  __pyx_1 = PyObject_GetAttr(((PyObject *)__pyx_v_w_ndr), __pyx_n_ndim); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;}
-  __pyx_3 = PyInt_FromLong(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;}
-  if (PyObject_Cmp(__pyx_1, __pyx_3, &__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;}
+  /* "/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;}
   __pyx_2 = __pyx_2 > 0;
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   Py_DECREF(__pyx_3); __pyx_3 = 0;
   if (!__pyx_2) {
-    __pyx_1 = PyObject_GetAttr(((PyObject *)__pyx_v_w_ndr), __pyx_n_size); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;}
-    __pyx_3 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->n); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;}
-    if (PyObject_Cmp(__pyx_1, __pyx_3, &__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;}
+    __pyx_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_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":66 */
-    __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; goto __pyx_L1;}
-    __Pyx_Raise(__pyx_1, __pyx_k12p, 0);
+    /* "/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);
     Py_DECREF(__pyx_1); __pyx_1 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; goto __pyx_L1;}
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 195; goto __pyx_L1;}
     goto __pyx_L2;
   }
   __pyx_L2:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":67 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":196 */
   ((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->weights = ((double (*))__pyx_v_w_ndr->data);
 
   __pyx_r = 0;
@@ -559,8 +466,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":72 */
-  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->n); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; goto __pyx_L1;}
+  /* "/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;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -576,14 +483,14 @@
   return __pyx_r;
 }
 
-static PyObject *__pyx_f_6cloess_12loess_inputs_4nvar___get__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_f_6cloess_12loess_inputs_4nvar___get__(PyObject *__pyx_v_self) {
+static PyObject *__pyx_f_6cloess_12loess_inputs_4npar___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_12loess_inputs_4npar___get__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":77 */
-  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_inputs *)__pyx_v_self)->_base->p); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; goto __pyx_L1;}
+  /* "/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;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -592,7 +499,7 @@
   goto __pyx_L0;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);
-  __Pyx_AddTraceback("cloess.loess_inputs.nvar.__get__");
+  __Pyx_AddTraceback("cloess.loess_inputs.npar.__get__");
   __pyx_r = 0;
   __pyx_L0:;
   Py_DECREF(__pyx_v_self);
@@ -605,8 +512,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":87 */
-  __pyx_1 = PyString_FromString(((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->surface); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; goto __pyx_L1;}
+  /* "/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;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -622,23 +529,82 @@
   return __pyx_r;
 }
 
+static PyObject *__pyx_n_lower;
+static PyObject *__pyx_n_interpolate;
+static PyObject *__pyx_n_direct;
+
+static PyObject *__pyx_k41p;
+static PyObject *__pyx_k42p;
+
+static char (__pyx_k41[]) = "Invalid value for the 'surface' argument: ";
+static char (__pyx_k42[]) = "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) {
+  PyObject *__pyx_v_tmpx;
   int __pyx_r;
-  char (*__pyx_1);
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  int __pyx_3;
+  PyObject *__pyx_4 = 0;
+  char (*__pyx_5);
   Py_INCREF(__pyx_v_self);
   Py_INCREF(__pyx_v_surface);
+  __pyx_v_tmpx = Py_None; Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":89 */
-  __pyx_1 = PyString_AsString(__pyx_v_surface); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; goto __pyx_L1;}
-  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->surface = __pyx_1;
+  /* "/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;}
+  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;}
+  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 = !__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;}
+    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;}
+    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;}
+    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;}
+  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;}
+  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->surface = __pyx_5;
+
   __pyx_r = 0;
   goto __pyx_L0;
   __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_4);
   __Pyx_AddTraceback("cloess.loess_control.surface.__set__");
   __pyx_r = -1;
   __pyx_L0:;
+  Py_DECREF(__pyx_v_tmpx);
   Py_DECREF(__pyx_v_self);
   Py_DECREF(__pyx_v_surface);
   return __pyx_r;
@@ -650,8 +616,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":93 */
-  __pyx_1 = PyString_FromString(((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->statistics); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; goto __pyx_L1;}
+  /* "/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;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -667,23 +633,78 @@
   return __pyx_r;
 }
 
+static PyObject *__pyx_n_approximate;
+static PyObject *__pyx_n_exact;
+
+static PyObject *__pyx_k45p;
+
+static char (__pyx_k45[]) = "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) {
+  PyObject *__pyx_v_tmpx;
   int __pyx_r;
-  char (*__pyx_1);
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  int __pyx_3;
+  PyObject *__pyx_4 = 0;
+  char (*__pyx_5);
   Py_INCREF(__pyx_v_self);
   Py_INCREF(__pyx_v_statistics);
+  __pyx_v_tmpx = Py_None; Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":95 */
-  __pyx_1 = PyString_AsString(__pyx_v_statistics); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; goto __pyx_L1;}
-  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->statistics = __pyx_1;
+  /* "/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;}
+  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;}
+  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 = !__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;}
+    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;}
+    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;}
+  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;}
+  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->statistics = __pyx_5;
+
   __pyx_r = 0;
   goto __pyx_L0;
   __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_4);
   __Pyx_AddTraceback("cloess.loess_control.statistics.__set__");
   __pyx_r = -1;
   __pyx_L0:;
+  Py_DECREF(__pyx_v_tmpx);
   Py_DECREF(__pyx_v_self);
   Py_DECREF(__pyx_v_statistics);
   return __pyx_r;
@@ -695,8 +716,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":99 */
-  __pyx_1 = PyString_FromString(((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->trace_hat); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; goto __pyx_L1;}
+  /* "/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;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -712,23 +733,75 @@
   return __pyx_r;
 }
 
+static PyObject *__pyx_k48p;
+
+static char (__pyx_k48[]) = "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) {
+  PyObject *__pyx_v_tmpx;
   int __pyx_r;
-  char (*__pyx_1);
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  int __pyx_3;
+  PyObject *__pyx_4 = 0;
+  char (*__pyx_5);
   Py_INCREF(__pyx_v_self);
   Py_INCREF(__pyx_v_trace_hat);
+  __pyx_v_tmpx = Py_None; Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":101 */
-  __pyx_1 = PyString_AsString(__pyx_v_trace_hat); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; goto __pyx_L1;}
-  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->trace_hat = __pyx_1;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":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;}
+  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;}
+  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 = !__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;}
+    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;}
+    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;}
+  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;}
+  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->trace_hat = __pyx_5;
+
   __pyx_r = 0;
   goto __pyx_L0;
   __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_4);
   __Pyx_AddTraceback("cloess.loess_control.trace_hat.__set__");
   __pyx_r = -1;
   __pyx_L0:;
+  Py_DECREF(__pyx_v_tmpx);
   Py_DECREF(__pyx_v_self);
   Py_DECREF(__pyx_v_trace_hat);
   return __pyx_r;
@@ -740,8 +813,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":105 */
-  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->iterations); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; goto __pyx_L1;}
+  /* "/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;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -757,20 +830,52 @@
   return __pyx_r;
 }
 
+static PyObject *__pyx_k49p;
+
+static char (__pyx_k49[]) = "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) {
   int __pyx_r;
-  int __pyx_1;
+  PyObject *__pyx_1 = 0;
+  int __pyx_2;
+  PyObject *__pyx_3 = 0;
+  PyObject *__pyx_4 = 0;
   Py_INCREF(__pyx_v_self);
   Py_INCREF(__pyx_v_iterations);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":107 */
-  __pyx_1 = PyInt_AsLong(__pyx_v_iterations); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; goto __pyx_L1;}
-  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->iterations = __pyx_1;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":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;}
+  __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;}
+    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;}
+    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;}
+  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->iterations = __pyx_2;
+
   __pyx_r = 0;
   goto __pyx_L0;
   __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_3);
+  Py_XDECREF(__pyx_4);
   __Pyx_AddTraceback("cloess.loess_control.iterations.__set__");
   __pyx_r = -1;
   __pyx_L0:;
@@ -785,8 +890,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":111 */
-  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->cell); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; goto __pyx_L1;}
+  /* "/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;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -802,20 +907,53 @@
   return __pyx_r;
 }
 
+static PyObject *__pyx_k50p;
+
+static char (__pyx_k50[]) = "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) {
   int __pyx_r;
-  double __pyx_1;
+  PyObject *__pyx_1 = 0;
+  int __pyx_2;
+  PyObject *__pyx_3 = 0;
+  PyObject *__pyx_4 = 0;
+  double __pyx_5;
   Py_INCREF(__pyx_v_self);
   Py_INCREF(__pyx_v_cell);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":113 */
-  __pyx_1 = PyFloat_AsDouble(__pyx_v_cell); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; goto __pyx_L1;}
-  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->cell = __pyx_1;
+  /* "/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;}
+  __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;}
+    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;}
+    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;}
+  ((struct __pyx_obj_6cloess_loess_control *)__pyx_v_self)->_base->cell = __pyx_5;
+
   __pyx_r = 0;
   goto __pyx_L0;
   __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_3);
+  Py_XDECREF(__pyx_4);
   __Pyx_AddTraceback("cloess.loess_control.cell.__set__");
   __pyx_r = -1;
   __pyx_L0:;
@@ -834,6 +972,7 @@
 
 
 static PyObject *__pyx_f_6cloess_13loess_control_update(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_6cloess_13loess_control_update[] = "Updates several parameters at once.";
 static PyObject *__pyx_f_6cloess_13loess_control_update(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_cellargs = 0;
   PyObject *__pyx_v_surface;
@@ -861,122 +1000,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":116 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; goto __pyx_L1;}
-  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; goto __pyx_L1;}
+  /* "/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;}
   Py_INCREF(__pyx_n_surface);
   PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_surface);
   Py_INCREF(Py_None);
   PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
-  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; goto __pyx_L1;}
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 301; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_v_surface);
   __pyx_v_surface = __pyx_3;
   __pyx_3 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":117 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":302 */
   __pyx_4 = __pyx_v_surface != Py_None;
   if (__pyx_4) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":118 */
-    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_surface, __pyx_v_surface) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; goto __pyx_L1;}
+    /* "/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;}
     goto __pyx_L2;
   }
   __pyx_L2:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":120 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; goto __pyx_L1;}
-  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; goto __pyx_L1;}
+  /* "/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;}
   Py_INCREF(__pyx_n_statistics);
   PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_statistics);
   Py_INCREF(Py_None);
   PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
-  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; goto __pyx_L1;}
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_v_statistics);
   __pyx_v_statistics = __pyx_3;
   __pyx_3 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":121 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":306 */
   __pyx_4 = __pyx_v_statistics != Py_None;
   if (__pyx_4) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":122 */
-    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_statistics, __pyx_v_statistics) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 122; goto __pyx_L1;}
+    /* "/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;}
     goto __pyx_L3;
   }
   __pyx_L3:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":124 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; goto __pyx_L1;}
-  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; goto __pyx_L1;}
+  /* "/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;}
   Py_INCREF(__pyx_n_trace_hat);
   PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_trace_hat);
   Py_INCREF(Py_None);
   PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
-  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; goto __pyx_L1;}
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_v_trace_hat);
   __pyx_v_trace_hat = __pyx_3;
   __pyx_3 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":125 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":310 */
   __pyx_4 = __pyx_v_trace_hat != Py_None;
   if (__pyx_4) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":126 */
-    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_trace_hat, __pyx_v_trace_hat) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 126; goto __pyx_L1;}
+    /* "/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;}
     goto __pyx_L4;
   }
   __pyx_L4:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":128 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; goto __pyx_L1;}
-  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; goto __pyx_L1;}
+  /* "/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;}
   Py_INCREF(__pyx_n_iterations);
   PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_iterations);
   Py_INCREF(Py_None);
   PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
-  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; goto __pyx_L1;}
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 313; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_v_iterations);
   __pyx_v_iterations = __pyx_3;
   __pyx_3 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":129 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":314 */
   __pyx_4 = __pyx_v_iterations != Py_None;
   if (__pyx_4) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":130 */
-    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_iterations, __pyx_v_iterations) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 130; goto __pyx_L1;}
+    /* "/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;}
     goto __pyx_L5;
   }
   __pyx_L5:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":132 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; goto __pyx_L1;}
-  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; goto __pyx_L1;}
+  /* "/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;}
   Py_INCREF(__pyx_n_cell);
   PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_cell);
   Py_INCREF(Py_None);
   PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
-  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; goto __pyx_L1;}
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 317; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_v_cell);
   __pyx_v_cell = __pyx_3;
   __pyx_3 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":133 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":318 */
   __pyx_4 = __pyx_v_cell != Py_None;
   if (__pyx_4) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":134 */
-    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_parametric_flags, __pyx_v_cell) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; goto __pyx_L1;}
+    /* "/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;}
     goto __pyx_L6;
   }
   __pyx_L6:;
@@ -1004,21 +1143,21 @@
 
 static PyObject *__pyx_n_join;
 
-static PyObject *__pyx_k18p;
-static PyObject *__pyx_k19p;
-static PyObject *__pyx_k20p;
-static PyObject *__pyx_k21p;
-static PyObject *__pyx_k22p;
-static PyObject *__pyx_k23p;
-static PyObject *__pyx_k24p;
+static PyObject *__pyx_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_k18[]) = "Control          :";
-static char (__pyx_k19[]) = "Surface type     : %s";
-static char (__pyx_k20[]) = "Statistics       : %s";
-static char (__pyx_k21[]) = "Trace estimation : %s";
-static char (__pyx_k22[]) = "Cell size        : %s";
-static char (__pyx_k23[]) = "Nb iterations    : %s";
-static char (__pyx_k24[]) = "\n";
+static 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 PyObject *__pyx_f_6cloess_13loess_control___str__(PyObject *__pyx_v_self); /*proto*/
 static PyObject *__pyx_f_6cloess_13loess_control___str__(PyObject *__pyx_v_self) {
@@ -1033,25 +1172,25 @@
   Py_INCREF(__pyx_v_self);
   __pyx_v_strg = Py_None; Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":138 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_surface); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; goto __pyx_L1;}
-  __pyx_2 = PyNumber_Remainder(__pyx_k19p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; goto __pyx_L1;}
+  /* "/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;}
   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 = 140; goto __pyx_L1;}
-  __pyx_3 = PyNumber_Remainder(__pyx_k20p, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; goto __pyx_L1;}
+  __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;}
   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 = 141; goto __pyx_L1;}
-  __pyx_4 = PyNumber_Remainder(__pyx_k21p, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; goto __pyx_L1;}
+  __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;}
   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 = 142; goto __pyx_L1;}
-  __pyx_5 = PyNumber_Remainder(__pyx_k22p, __pyx_1); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; goto __pyx_L1;}
+  __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;}
   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 = 143; goto __pyx_L1;}
-  __pyx_6 = PyNumber_Remainder(__pyx_k23p, __pyx_1); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; goto __pyx_L1;}
+  __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;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyList_New(6); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; goto __pyx_L1;}
-  Py_INCREF(__pyx_k18p);
-  PyList_SET_ITEM(__pyx_1, 0, __pyx_k18p);
+  __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);
   PyList_SET_ITEM(__pyx_1, 1, __pyx_2);
   PyList_SET_ITEM(__pyx_1, 2, __pyx_3);
   PyList_SET_ITEM(__pyx_1, 3, __pyx_4);
@@ -1066,12 +1205,12 @@
   __pyx_v_strg = __pyx_1;
   __pyx_1 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":144 */
-  __pyx_2 = PyObject_GetAttr(__pyx_k24p, __pyx_n_join); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; goto __pyx_L1;}
-  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; goto __pyx_L1;}
+  /* "/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;}
   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 = 144; goto __pyx_L1;}
+  __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; goto __pyx_L1;}
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_3); __pyx_3 = 0;
   __pyx_r = __pyx_4;
@@ -1101,8 +1240,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":183 */
-  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->span); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 183; goto __pyx_L1;}
+  /* "/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;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -1118,20 +1257,59 @@
   return __pyx_r;
 }
 
+static PyObject *__pyx_k63p;
+
+static char (__pyx_k63[]) = "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) {
   int __pyx_r;
-  double __pyx_1;
+  int __pyx_1;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  PyObject *__pyx_4 = 0;
+  double __pyx_5;
   Py_INCREF(__pyx_v_self);
   Py_INCREF(__pyx_v_span);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":185 */
-  __pyx_1 = PyFloat_AsDouble(__pyx_v_span); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; goto __pyx_L1;}
-  ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->span = __pyx_1;
+  /* "/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;}
+  __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_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;}
+    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;}
+    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;}
+  ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->span = __pyx_5;
+
   __pyx_r = 0;
   goto __pyx_L0;
   __pyx_L1:;
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  Py_XDECREF(__pyx_4);
   __Pyx_AddTraceback("cloess.loess_model.span.__set__");
   __pyx_r = -1;
   __pyx_L0:;
@@ -1146,8 +1324,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":189 */
-  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->degree); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; goto __pyx_L1;}
+  /* "/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;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -1163,6 +1341,62 @@
   return __pyx_r;
 }
 
+static PyObject *__pyx_k64p;
+
+static char (__pyx_k64[]) = "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) {
+  int __pyx_r;
+  int __pyx_1;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  PyObject *__pyx_4 = 0;
+  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;}
+  __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_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;}
+    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;}
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  Py_XDECREF(__pyx_4);
+  __Pyx_AddTraceback("cloess.loess_model.degree.__set__");
+  __pyx_r = -1;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  Py_DECREF(__pyx_v_degree);
+  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;
@@ -1171,13 +1405,13 @@
   PyObject *__pyx_3 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":194 */
-  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_bool); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; goto __pyx_L1;}
-  __pyx_2 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->normalize); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; goto __pyx_L1;}
-  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; goto __pyx_L1;}
+  /* "/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 = 194; goto __pyx_L1;}
+  __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;
@@ -1204,8 +1438,8 @@
   Py_INCREF(__pyx_v_self);
   Py_INCREF(__pyx_v_normalize);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":196 */
-  __pyx_1 = PyInt_AsLong(__pyx_v_normalize); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; goto __pyx_L1;}
+  /* "/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;
@@ -1225,8 +1459,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":200 */
-  __pyx_1 = PyString_FromString(((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->family); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; goto __pyx_L1;}
+  /* "/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;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -1242,30 +1476,88 @@
   return __pyx_r;
 }
 
-static PyObject *__pyx_f_6cloess_11loess_model_16parametric_flags___get__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_f_6cloess_11loess_model_16parametric_flags___get__(PyObject *__pyx_v_self) {
-  PyObject *__pyx_r;
+static PyObject *__pyx_n_symmetric;
+static PyObject *__pyx_n_gaussian;
+
+static PyObject *__pyx_k67p;
+
+static char (__pyx_k67[]) = "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) {
+  int __pyx_r;
   PyObject *__pyx_1 = 0;
   PyObject *__pyx_2 = 0;
-  PyObject *__pyx_3 = 0;
+  int __pyx_3;
+  PyObject *__pyx_4 = 0;
+  char (*__pyx_5);
   Py_INCREF(__pyx_v_self);
+  Py_INCREF(__pyx_v_family);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":204 */
-  __pyx_1 = PyInt_FromLong(8); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; goto __pyx_L1;}
-  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; goto __pyx_L1;}
-  __pyx_3 = __pyx_f_6cloess_boolarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->parametric); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; goto __pyx_L1;}
+  /* "/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;}
   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;}
+  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 = !__pyx_3;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
-  __pyx_r = __pyx_3;
-  __pyx_3 = 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;}
+    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;}
+    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;}
+  ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->family = __pyx_5;
+
+  __pyx_r = 0;
   goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_4);
+  __Pyx_AddTraceback("cloess.loess_model.family.__set__");
+  __pyx_r = -1;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  Py_DECREF(__pyx_v_family);
+  return __pyx_r;
+}
 
+static PyObject *__pyx_f_6cloess_11loess_model_16parametric_flags___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_11loess_model_16parametric_flags___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  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;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
   __pyx_r = Py_None; Py_INCREF(Py_None);
   goto __pyx_L0;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);
-  Py_XDECREF(__pyx_2);
-  Py_XDECREF(__pyx_3);
   __Pyx_AddTraceback("cloess.loess_model.parametric_flags.__get__");
   __pyx_r = 0;
   __pyx_L0:;
@@ -1273,9 +1565,15 @@
   return __pyx_r;
 }
 
-static PyObject *__pyx_n_NPY_LONG;
-static PyObject *__pyx_n_max;
+static PyObject *__pyx_n_array;
+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;
 
+
 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;
@@ -1283,80 +1581,78 @@
   int __pyx_v_i;
   int __pyx_r;
   PyObject *__pyx_1 = 0;
-  enum NPY_TYPES __pyx_2;
+  PyObject *__pyx_2 = 0;
   PyObject *__pyx_3 = 0;
   PyObject *__pyx_4 = 0;
   PyObject *__pyx_5 = 0;
-  PyObject *__pyx_6 = 0;
-  PyObject *__pyx_7 = 0;
-  int __pyx_8;
+  long __pyx_6;
   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":209 */
-  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_NPY_LONG); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; goto __pyx_L1;}
-  __pyx_2 = ((enum NPY_TYPES )PyInt_AsLong(__pyx_1)); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; goto __pyx_L1;}
+  /* "/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;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyArray_FROMANY(__pyx_v_paramf,__pyx_2,1,1,NPY_OWNDATA); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; goto __pyx_L1;}
-  Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_1)));
+  __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; 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;}
+  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;
+  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(((PyObject *)__pyx_v_p_ndr));
-  __pyx_v_p_ndr = ((PyArrayObject *)__pyx_1);
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_v_p_ndr = ((PyArrayObject *)__pyx_4);
+  __pyx_4 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":210 */
+  /* "/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":211 */
-  __pyx_1 = PyInt_FromLong(0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
-  __pyx_3 = PyInt_FromLong(__pyx_v_i); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
-  if (PyObject_Cmp(__pyx_1, __pyx_3, &__pyx_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
-  __pyx_8 = __pyx_8 <= 0;
-  if (__pyx_8) {
-    __pyx_4 = __Pyx_GetName(__pyx_b, __pyx_n_max); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
-    __pyx_5 = PyInt_FromLong(8); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
-    __pyx_6 = PyObject_GetAttr(((PyObject *)__pyx_v_p_ndr), __pyx_n_size); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
-    __pyx_7 = PyTuple_New(2); if (!__pyx_7) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
-    PyTuple_SET_ITEM(__pyx_7, 0, __pyx_5);
-    PyTuple_SET_ITEM(__pyx_7, 1, __pyx_6);
-    __pyx_5 = 0;
-    __pyx_6 = 0;
-    __pyx_5 = PyObject_CallObject(__pyx_4, __pyx_7); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
-    Py_DECREF(__pyx_4); __pyx_4 = 0;
-    Py_DECREF(__pyx_7); __pyx_7 = 0;
-    if (PyObject_Cmp(__pyx_3, __pyx_5, &__pyx_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
-    __pyx_8 = __pyx_8 < 0;
-    Py_DECREF(__pyx_5); __pyx_5 = 0;
-  }
+  /* "/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_6 = PyInt_FromLong(__pyx_8); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
-  __pyx_4 = PyObject_GetIter(__pyx_6); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
-  Py_DECREF(__pyx_6); __pyx_6 = 0;
-  for (;;) {
-    __pyx_7 = PyIter_Next(__pyx_4);
-    if (!__pyx_7) {
-      if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
-      break;
-    }
-    __pyx_8 = PyInt_AsLong(__pyx_7); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
-    Py_DECREF(__pyx_7); __pyx_7 = 0;
-    __pyx_v_i = __pyx_8;
+  __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;
+  __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;}
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_6; ++__pyx_v_i) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":212 */
+    /* "/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]);
   }
-  Py_DECREF(__pyx_4); __pyx_4 = 0;
 
   __pyx_r = 0;
   goto __pyx_L0;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
   Py_XDECREF(__pyx_3);
   Py_XDECREF(__pyx_4);
   Py_XDECREF(__pyx_5);
-  Py_XDECREF(__pyx_6);
-  Py_XDECREF(__pyx_7);
   __Pyx_AddTraceback("cloess.loess_model.parametric_flags.__set__");
   __pyx_r = -1;
   __pyx_L0:;
@@ -1370,26 +1666,18 @@
 static PyObject *__pyx_f_6cloess_11loess_model_17drop_square_flags___get__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
-  PyObject *__pyx_2 = 0;
-  PyObject *__pyx_3 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":216 */
-  __pyx_1 = PyInt_FromLong(8); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 216; goto __pyx_L1;}
-  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 216; goto __pyx_L1;}
-  __pyx_3 = __pyx_f_6cloess_boolarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->drop_square); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 216; goto __pyx_L1;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
-  __pyx_r = __pyx_3;
-  __pyx_3 = 0;
+  /* "/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;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
   goto __pyx_L0;
 
   __pyx_r = Py_None; Py_INCREF(Py_None);
   goto __pyx_L0;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);
-  Py_XDECREF(__pyx_2);
-  Py_XDECREF(__pyx_3);
   __Pyx_AddTraceback("cloess.loess_model.drop_square_flags.__get__");
   __pyx_r = 0;
   __pyx_L0:;
@@ -1397,6 +1685,7 @@
   return __pyx_r;
 }
 
+
 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;
@@ -1404,80 +1693,78 @@
   int __pyx_v_i;
   int __pyx_r;
   PyObject *__pyx_1 = 0;
-  enum NPY_TYPES __pyx_2;
+  PyObject *__pyx_2 = 0;
   PyObject *__pyx_3 = 0;
   PyObject *__pyx_4 = 0;
   PyObject *__pyx_5 = 0;
-  PyObject *__pyx_6 = 0;
-  PyObject *__pyx_7 = 0;
-  int __pyx_8;
+  long __pyx_6;
   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":221 */
-  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_NPY_LONG); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 221; goto __pyx_L1;}
-  __pyx_2 = ((enum NPY_TYPES )PyInt_AsLong(__pyx_1)); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 221; goto __pyx_L1;}
+  /* "/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;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyArray_FROMANY(__pyx_v_drop_sq,__pyx_2,1,1,NPY_OWNDATA); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 221; goto __pyx_L1;}
-  Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_1)));
+  __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; 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;}
+  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;
+  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(((PyObject *)__pyx_v_d_ndr));
-  __pyx_v_d_ndr = ((PyArrayObject *)__pyx_1);
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_v_d_ndr = ((PyArrayObject *)__pyx_4);
+  __pyx_4 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":222 */
+  /* "/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":223 */
-  __pyx_1 = PyInt_FromLong(0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
-  __pyx_3 = PyInt_FromLong(__pyx_v_i); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
-  if (PyObject_Cmp(__pyx_1, __pyx_3, &__pyx_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
-  __pyx_8 = __pyx_8 <= 0;
-  if (__pyx_8) {
-    __pyx_4 = __Pyx_GetName(__pyx_b, __pyx_n_max); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
-    __pyx_5 = PyInt_FromLong(8); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
-    __pyx_6 = PyObject_GetAttr(((PyObject *)__pyx_v_d_ndr), __pyx_n_size); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
-    __pyx_7 = PyTuple_New(2); if (!__pyx_7) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
-    PyTuple_SET_ITEM(__pyx_7, 0, __pyx_5);
-    PyTuple_SET_ITEM(__pyx_7, 1, __pyx_6);
-    __pyx_5 = 0;
-    __pyx_6 = 0;
-    __pyx_5 = PyObject_CallObject(__pyx_4, __pyx_7); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
-    Py_DECREF(__pyx_4); __pyx_4 = 0;
-    Py_DECREF(__pyx_7); __pyx_7 = 0;
-    if (PyObject_Cmp(__pyx_3, __pyx_5, &__pyx_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
-    __pyx_8 = __pyx_8 < 0;
-    Py_DECREF(__pyx_5); __pyx_5 = 0;
-  }
+  /* "/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_6 = PyInt_FromLong(__pyx_8); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
-  __pyx_4 = PyObject_GetIter(__pyx_6); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
-  Py_DECREF(__pyx_6); __pyx_6 = 0;
-  for (;;) {
-    __pyx_7 = PyIter_Next(__pyx_4);
-    if (!__pyx_7) {
-      if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
-      break;
-    }
-    __pyx_8 = PyInt_AsLong(__pyx_7); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; goto __pyx_L1;}
-    Py_DECREF(__pyx_7); __pyx_7 = 0;
-    __pyx_v_i = __pyx_8;
+  __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;
+  __pyx_4 = 0;
+  __pyx_3 = PyObject_CallObject(__pyx_5, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; 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 = 454; goto __pyx_L1;}
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_6; ++__pyx_v_i) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":224 */
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":455 */
     (((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->_base->drop_square[__pyx_v_i]) = (__pyx_v_d_dat[__pyx_v_i]);
   }
-  Py_DECREF(__pyx_4); __pyx_4 = 0;
 
   __pyx_r = 0;
   goto __pyx_L0;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
   Py_XDECREF(__pyx_3);
   Py_XDECREF(__pyx_4);
   Py_XDECREF(__pyx_5);
-  Py_XDECREF(__pyx_6);
-  Py_XDECREF(__pyx_7);
   __Pyx_AddTraceback("cloess.loess_model.drop_square_flags.__set__");
   __pyx_r = -1;
   __pyx_L0:;
@@ -1526,146 +1813,146 @@
   __pyx_v_parametric = Py_None; Py_INCREF(Py_None);
   __pyx_v_drop_square = Py_None; Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":227 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_modelargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; goto __pyx_L1;}
-  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":458 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_modelargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 458; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 458; goto __pyx_L1;}
   Py_INCREF(__pyx_n_family);
   PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_family);
   Py_INCREF(Py_None);
   PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
-  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; goto __pyx_L1;}
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 458; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_v_family);
   __pyx_v_family = __pyx_3;
   __pyx_3 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":228 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":459 */
   __pyx_4 = __pyx_v_family != Py_None;
   if (__pyx_4) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":229 */
-    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_family, __pyx_v_family) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 229; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":460 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_family, __pyx_v_family) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 460; goto __pyx_L1;}
     goto __pyx_L2;
   }
   __pyx_L2:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":231 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_modelargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; goto __pyx_L1;}
-  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":462 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_modelargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; goto __pyx_L1;}
   Py_INCREF(__pyx_n_span);
   PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_span);
   Py_INCREF(Py_None);
   PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
-  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; goto __pyx_L1;}
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_v_span);
   __pyx_v_span = __pyx_3;
   __pyx_3 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":232 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":463 */
   __pyx_4 = __pyx_v_span != Py_None;
   if (__pyx_4) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":233 */
-    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_span, __pyx_v_span) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":464 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_span, __pyx_v_span) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; goto __pyx_L1;}
     goto __pyx_L3;
   }
   __pyx_L3:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":235 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_modelargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; goto __pyx_L1;}
-  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":466 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_modelargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 466; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 466; goto __pyx_L1;}
   Py_INCREF(__pyx_n_degree);
   PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_degree);
   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 = 235; goto __pyx_L1;}
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 466; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_v_degree);
   __pyx_v_degree = __pyx_3;
   __pyx_3 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":236 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":467 */
   __pyx_4 = __pyx_v_degree != Py_None;
   if (__pyx_4) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":237 */
-    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_degree, __pyx_v_degree) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":468 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_degree, __pyx_v_degree) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; goto __pyx_L1;}
     goto __pyx_L4;
   }
   __pyx_L4:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":239 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_modelargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; goto __pyx_L1;}
-  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":470 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_modelargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 470; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 470; goto __pyx_L1;}
   Py_INCREF(__pyx_n_normalize);
   PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_normalize);
   Py_INCREF(Py_None);
   PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
-  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; goto __pyx_L1;}
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 470; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_v_normalize);
   __pyx_v_normalize = __pyx_3;
   __pyx_3 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":240 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":471 */
   __pyx_4 = __pyx_v_normalize != Py_None;
   if (__pyx_4) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":241 */
-    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_normalize, __pyx_v_normalize) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 241; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":472 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_normalize, __pyx_v_normalize) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
     goto __pyx_L5;
   }
   __pyx_L5:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":243 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_modelargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; goto __pyx_L1;}
-  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":474 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_modelargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; goto __pyx_L1;}
   Py_INCREF(__pyx_n_parametric);
   PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_parametric);
   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 = 243; goto __pyx_L1;}
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_v_parametric);
   __pyx_v_parametric = __pyx_3;
   __pyx_3 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":244 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":475 */
   __pyx_4 = __pyx_v_parametric != Py_None;
   if (__pyx_4) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":245 */
-    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_parametric_flags, __pyx_v_parametric) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 245; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":476 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_parametric_flags, __pyx_v_parametric) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 476; goto __pyx_L1;}
     goto __pyx_L6;
   }
   __pyx_L6:;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":247 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_modelargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 247; goto __pyx_L1;}
-  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 247; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":478 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_modelargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; goto __pyx_L1;}
   Py_INCREF(__pyx_n_drop_square);
   PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_drop_square);
   Py_INCREF(Py_None);
   PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
-  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 247; goto __pyx_L1;}
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_v_drop_square);
   __pyx_v_drop_square = __pyx_3;
   __pyx_3 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":248 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":479 */
   __pyx_4 = __pyx_v_drop_square != Py_None;
   if (__pyx_4) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":249 */
-    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_drop_square_flags, __pyx_v_drop_square) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 249; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":480 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_drop_square_flags, __pyx_v_drop_square) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; goto __pyx_L1;}
     goto __pyx_L7;
   }
   __pyx_L7:;
@@ -1694,9 +1981,9 @@
 
 static PyObject *__pyx_n_id;
 
-static PyObject *__pyx_k31p;
+static PyObject *__pyx_k80p;
 
-static char (__pyx_k31[]) = "loess model parameters @%s";
+static char (__pyx_k80[]) = "loess model parameters @%s";
 
 static PyObject *__pyx_f_6cloess_11loess_model___repr__(PyObject *__pyx_v_self); /*proto*/
 static PyObject *__pyx_f_6cloess_11loess_model___repr__(PyObject *__pyx_v_self) {
@@ -1706,15 +1993,15 @@
   PyObject *__pyx_3 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":252 */
-  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_id); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; goto __pyx_L1;}
-  __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":483 */
+  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_id); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 483; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 483; goto __pyx_L1;}
   Py_INCREF(__pyx_v_self);
   PyTuple_SET_ITEM(__pyx_2, 0, __pyx_v_self);
-  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; goto __pyx_L1;}
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 483; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
-  __pyx_1 = PyNumber_Remainder(__pyx_k31p, __pyx_3); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; goto __pyx_L1;}
+  __pyx_1 = PyNumber_Remainder(__pyx_k80p, __pyx_3); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 483; goto __pyx_L1;}
   Py_DECREF(__pyx_3); __pyx_3 = 0;
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
@@ -1733,23 +2020,23 @@
   return __pyx_r;
 }
 
-static PyObject *__pyx_k32p;
-static PyObject *__pyx_k33p;
-static PyObject *__pyx_k34p;
-static PyObject *__pyx_k35p;
-static PyObject *__pyx_k36p;
-static PyObject *__pyx_k37p;
-static PyObject *__pyx_k38p;
-static PyObject *__pyx_k39p;
+static PyObject *__pyx_k81p;
+static PyObject *__pyx_k82p;
+static PyObject *__pyx_k83p;
+static PyObject *__pyx_k84p;
+static PyObject *__pyx_k85p;
+static PyObject *__pyx_k86p;
+static PyObject *__pyx_k87p;
+static PyObject *__pyx_k88p;
 
-static char (__pyx_k32[]) = "Model parameters.....";
-static char (__pyx_k33[]) = "family      : %s";
-static char (__pyx_k34[]) = "span        : %s";
-static char (__pyx_k35[]) = "degree      : %s";
-static char (__pyx_k36[]) = "normalized  : %s";
-static char (__pyx_k37[]) = "parametric  : %s";
-static char (__pyx_k38[]) = "drop_square : %s";
-static char (__pyx_k39[]) = "\n";
+static char (__pyx_k81[]) = "Model parameters.....";
+static char (__pyx_k82[]) = "family      : %s";
+static char (__pyx_k83[]) = "span        : %s";
+static char (__pyx_k84[]) = "degree      : %s";
+static char (__pyx_k85[]) = "normalized  : %s";
+static char (__pyx_k86[]) = "parametric  : %s";
+static char (__pyx_k87[]) = "drop_square : %s";
+static char (__pyx_k88[]) = "\n";
 
 static PyObject *__pyx_f_6cloess_11loess_model___str__(PyObject *__pyx_v_self); /*proto*/
 static PyObject *__pyx_f_6cloess_11loess_model___str__(PyObject *__pyx_v_self) {
@@ -1765,32 +2052,32 @@
   Py_INCREF(__pyx_v_self);
   __pyx_v_strg = Py_None; Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":255 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_family); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; goto __pyx_L1;}
-  __pyx_2 = PyNumber_Remainder(__pyx_k33p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":486 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_family); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 487; goto __pyx_L1;}
+  __pyx_2 = PyNumber_Remainder(__pyx_k82p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 487; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_span); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; goto __pyx_L1;}
-  __pyx_3 = PyNumber_Remainder(__pyx_k34p, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; goto __pyx_L1;}
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_span); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 488; goto __pyx_L1;}
+  __pyx_3 = PyNumber_Remainder(__pyx_k83p, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 488; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_degree); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; goto __pyx_L1;}
-  __pyx_4 = PyNumber_Remainder(__pyx_k35p, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; goto __pyx_L1;}
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_degree); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 489; goto __pyx_L1;}
+  __pyx_4 = PyNumber_Remainder(__pyx_k84p, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 489; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_normalize); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; goto __pyx_L1;}
-  __pyx_5 = PyNumber_Remainder(__pyx_k36p, __pyx_1); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; goto __pyx_L1;}
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_normalize); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; goto __pyx_L1;}
+  __pyx_5 = PyNumber_Remainder(__pyx_k85p, __pyx_1); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_parametric_flags); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; goto __pyx_L1;}
-  __pyx_6 = PySequence_GetSlice(__pyx_1, 0, ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->npar); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; goto __pyx_L1;}
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_parametric_flags); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 491; goto __pyx_L1;}
+  __pyx_6 = PySequence_GetSlice(__pyx_1, 0, ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->npar); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 491; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyNumber_Remainder(__pyx_k37p, __pyx_6); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; goto __pyx_L1;}
+  __pyx_1 = PyNumber_Remainder(__pyx_k86p, __pyx_6); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 491; goto __pyx_L1;}
   Py_DECREF(__pyx_6); __pyx_6 = 0;
-  __pyx_6 = PyObject_GetAttr(__pyx_v_self, __pyx_n_drop_square_flags); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; goto __pyx_L1;}
-  __pyx_7 = PySequence_GetSlice(__pyx_6, 0, ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->npar); if (!__pyx_7) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; goto __pyx_L1;}
+  __pyx_6 = PyObject_GetAttr(__pyx_v_self, __pyx_n_drop_square_flags); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 492; goto __pyx_L1;}
+  __pyx_7 = PySequence_GetSlice(__pyx_6, 0, ((struct __pyx_obj_6cloess_loess_model *)__pyx_v_self)->npar); if (!__pyx_7) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 492; goto __pyx_L1;}
   Py_DECREF(__pyx_6); __pyx_6 = 0;
-  __pyx_6 = PyNumber_Remainder(__pyx_k38p, __pyx_7); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; goto __pyx_L1;}
+  __pyx_6 = PyNumber_Remainder(__pyx_k87p, __pyx_7); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 492; goto __pyx_L1;}
   Py_DECREF(__pyx_7); __pyx_7 = 0;
-  __pyx_7 = PyList_New(7); if (!__pyx_7) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; goto __pyx_L1;}
-  Py_INCREF(__pyx_k32p);
-  PyList_SET_ITEM(__pyx_7, 0, __pyx_k32p);
+  __pyx_7 = PyList_New(7); if (!__pyx_7) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 486; goto __pyx_L1;}
+  Py_INCREF(__pyx_k81p);
+  PyList_SET_ITEM(__pyx_7, 0, __pyx_k81p);
   PyList_SET_ITEM(__pyx_7, 1, __pyx_2);
   PyList_SET_ITEM(__pyx_7, 2, __pyx_3);
   PyList_SET_ITEM(__pyx_7, 3, __pyx_4);
@@ -1807,12 +2094,12 @@
   __pyx_v_strg = __pyx_7;
   __pyx_7 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":263 */
-  __pyx_2 = PyObject_GetAttr(__pyx_k39p, __pyx_n_join); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; goto __pyx_L1;}
-  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":494 */
+  __pyx_2 = PyObject_GetAttr(__pyx_k88p, __pyx_n_join); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 494; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 494; 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 = 263; goto __pyx_L1;}
+  __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 494; goto __pyx_L1;}
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_3); __pyx_3 = 0;
   __pyx_r = __pyx_4;
@@ -1841,26 +2128,18 @@
 static PyObject *__pyx_f_6cloess_13loess_outputs_13fitted_values___get__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
-  PyObject *__pyx_2 = 0;
-  PyObject *__pyx_3 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":274 */
-  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->nobs); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; goto __pyx_L1;}
-  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; goto __pyx_L1;}
-  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->fitted_values); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; goto __pyx_L1;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
-  __pyx_r = __pyx_3;
-  __pyx_3 = 0;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":510 */
+  __pyx_1 = __pyx_f_6cloess_floatarray_from_data(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->nobs,1,((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->fitted_values); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 510; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
   goto __pyx_L0;
 
   __pyx_r = Py_None; Py_INCREF(Py_None);
   goto __pyx_L0;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);
-  Py_XDECREF(__pyx_2);
-  Py_XDECREF(__pyx_3);
   __Pyx_AddTraceback("cloess.loess_outputs.fitted_values.__get__");
   __pyx_r = 0;
   __pyx_L0:;
@@ -1872,26 +2151,18 @@
 static PyObject *__pyx_f_6cloess_13loess_outputs_16fitted_residuals___get__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
-  PyObject *__pyx_2 = 0;
-  PyObject *__pyx_3 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":278 */
-  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->nobs); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 278; goto __pyx_L1;}
-  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 278; goto __pyx_L1;}
-  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->fitted_residuals); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 278; goto __pyx_L1;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
-  __pyx_r = __pyx_3;
-  __pyx_3 = 0;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":518 */
+  __pyx_1 = __pyx_f_6cloess_floatarray_from_data(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->nobs,1,((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->fitted_residuals); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 518; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
   goto __pyx_L0;
 
   __pyx_r = Py_None; Py_INCREF(Py_None);
   goto __pyx_L0;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);
-  Py_XDECREF(__pyx_2);
-  Py_XDECREF(__pyx_3);
   __Pyx_AddTraceback("cloess.loess_outputs.fitted_residuals.__get__");
   __pyx_r = 0;
   __pyx_L0:;
@@ -1903,26 +2174,18 @@
 static PyObject *__pyx_f_6cloess_13loess_outputs_12pseudovalues___get__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
-  PyObject *__pyx_2 = 0;
-  PyObject *__pyx_3 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":282 */
-  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->nobs); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 282; goto __pyx_L1;}
-  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 282; goto __pyx_L1;}
-  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->pseudovalues); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 282; goto __pyx_L1;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
-  __pyx_r = __pyx_3;
-  __pyx_3 = 0;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":527 */
+  __pyx_1 = __pyx_f_6cloess_floatarray_from_data(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->nobs,1,((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->pseudovalues); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 527; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
   goto __pyx_L0;
 
   __pyx_r = Py_None; Py_INCREF(Py_None);
   goto __pyx_L0;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);
-  Py_XDECREF(__pyx_2);
-  Py_XDECREF(__pyx_3);
   __Pyx_AddTraceback("cloess.loess_outputs.pseudovalues.__get__");
   __pyx_r = 0;
   __pyx_L0:;
@@ -1934,26 +2197,18 @@
 static PyObject *__pyx_f_6cloess_13loess_outputs_8diagonal___get__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
-  PyObject *__pyx_2 = 0;
-  PyObject *__pyx_3 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":286 */
-  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->nobs); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; goto __pyx_L1;}
-  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; goto __pyx_L1;}
-  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->diagonal); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; goto __pyx_L1;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
-  __pyx_r = __pyx_3;
-  __pyx_3 = 0;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":535 */
+  __pyx_1 = __pyx_f_6cloess_floatarray_from_data(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->nobs,1,((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->diagonal); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 535; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
   goto __pyx_L0;
 
   __pyx_r = Py_None; Py_INCREF(Py_None);
   goto __pyx_L0;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);
-  Py_XDECREF(__pyx_2);
-  Py_XDECREF(__pyx_3);
   __Pyx_AddTraceback("cloess.loess_outputs.diagonal.__get__");
   __pyx_r = 0;
   __pyx_L0:;
@@ -1965,26 +2220,18 @@
 static PyObject *__pyx_f_6cloess_13loess_outputs_6robust___get__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
-  PyObject *__pyx_2 = 0;
-  PyObject *__pyx_3 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":290 */
-  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->nobs); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; goto __pyx_L1;}
-  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; goto __pyx_L1;}
-  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->robust); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; goto __pyx_L1;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
-  __pyx_r = __pyx_3;
-  __pyx_3 = 0;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":543 */
+  __pyx_1 = __pyx_f_6cloess_floatarray_from_data(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->nobs,1,((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->robust); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 543; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
   goto __pyx_L0;
 
   __pyx_r = Py_None; Py_INCREF(Py_None);
   goto __pyx_L0;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);
-  Py_XDECREF(__pyx_2);
-  Py_XDECREF(__pyx_3);
   __Pyx_AddTraceback("cloess.loess_outputs.robust.__get__");
   __pyx_r = 0;
   __pyx_L0:;
@@ -1992,30 +2239,28 @@
   return __pyx_r;
 }
 
+static PyObject *__pyx_n_nvar;
+
 static PyObject *__pyx_f_6cloess_13loess_outputs_7divisor___get__(PyObject *__pyx_v_self); /*proto*/
 static PyObject *__pyx_f_6cloess_13loess_outputs_7divisor___get__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
-  PyObject *__pyx_2 = 0;
-  PyObject *__pyx_3 = 0;
+  int __pyx_2;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":294 */
-  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->nobs); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; goto __pyx_L1;}
-  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; goto __pyx_L1;}
-  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->divisor); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":548 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_nvar); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 548; goto __pyx_L1;}
+  __pyx_2 = PyInt_AsLong(__pyx_1); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 548; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
-  __pyx_r = __pyx_3;
-  __pyx_3 = 0;
+  __pyx_1 = __pyx_f_6cloess_floatarray_from_data(__pyx_2,1,((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->divisor); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 548; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
   goto __pyx_L0;
 
   __pyx_r = Py_None; Py_INCREF(Py_None);
   goto __pyx_L0;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);
-  Py_XDECREF(__pyx_2);
-  Py_XDECREF(__pyx_3);
   __Pyx_AddTraceback("cloess.loess_outputs.divisor.__get__");
   __pyx_r = 0;
   __pyx_L0:;
@@ -2029,8 +2274,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":299 */
-  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->enp); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":556 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->enp); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 556; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -2052,8 +2297,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":304 */
-  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->s); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":564 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->s); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 564; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -2075,8 +2320,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":309 */
-  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->one_delta); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":572 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->one_delta); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 572; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -2098,8 +2343,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":314 */
-  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->two_delta); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 314; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":580 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->two_delta); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 580; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -2121,8 +2366,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":319 */
-  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->trace_hat); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 319; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":588 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_outputs *)__pyx_v_self)->_base->trace_hat); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 588; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -2138,14 +2383,128 @@
   return __pyx_r;
 }
 
+static PyObject *__pyx_n_fitted_values;
+static PyObject *__pyx_n_fitted_residuals;
+static PyObject *__pyx_n_enp;
+static PyObject *__pyx_n_s;
+static PyObject *__pyx_n_one_delta;
+static PyObject *__pyx_n_two_delta;
+static PyObject *__pyx_n_divisor;
+
+static PyObject *__pyx_k89p;
+static PyObject *__pyx_k90p;
+static PyObject *__pyx_k91p;
+static PyObject *__pyx_k92p;
+static PyObject *__pyx_k93p;
+static PyObject *__pyx_k94p;
+static PyObject *__pyx_k95p;
+static PyObject *__pyx_k96p;
+
+static char (__pyx_k89[]) = "Outputs................";
+static char (__pyx_k90[]) = "Fitted values         : %s\n";
+static char (__pyx_k91[]) = "Fitted residuals      : %s\n";
+static char (__pyx_k92[]) = "Eqv. nb of parameters : %s";
+static char (__pyx_k93[]) = "Residual error        : %s";
+static char (__pyx_k94[]) = "Deltas                : %s - %s";
+static char (__pyx_k95[]) = "Normalization factors : %s";
+static char (__pyx_k96[]) = "\n";
+
+static PyObject *__pyx_f_6cloess_13loess_outputs___str__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_13loess_outputs___str__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_v_strg;
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  PyObject *__pyx_4 = 0;
+  PyObject *__pyx_5 = 0;
+  PyObject *__pyx_6 = 0;
+  PyObject *__pyx_7 = 0;
+  Py_INCREF(__pyx_v_self);
+  __pyx_v_strg = Py_None; Py_INCREF(Py_None);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":591 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_fitted_values); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 592; goto __pyx_L1;}
+  __pyx_2 = PyNumber_Remainder(__pyx_k90p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 592; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_fitted_residuals); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 593; goto __pyx_L1;}
+  __pyx_3 = PyNumber_Remainder(__pyx_k91p, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 593; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_enp); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 594; goto __pyx_L1;}
+  __pyx_4 = PyNumber_Remainder(__pyx_k92p, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 594; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_s); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 595; goto __pyx_L1;}
+  __pyx_5 = PyNumber_Remainder(__pyx_k93p, __pyx_1); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 595; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_one_delta); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 596; goto __pyx_L1;}
+  __pyx_6 = PyObject_GetAttr(__pyx_v_self, __pyx_n_two_delta); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 596; goto __pyx_L1;}
+  __pyx_7 = PyTuple_New(2); if (!__pyx_7) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 596; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_7, 0, __pyx_1);
+  PyTuple_SET_ITEM(__pyx_7, 1, __pyx_6);
+  __pyx_1 = 0;
+  __pyx_6 = 0;
+  __pyx_1 = PyNumber_Remainder(__pyx_k94p, __pyx_7); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 596; goto __pyx_L1;}
+  Py_DECREF(__pyx_7); __pyx_7 = 0;
+  __pyx_6 = PyObject_GetAttr(__pyx_v_self, __pyx_n_divisor); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; goto __pyx_L1;}
+  __pyx_7 = PyNumber_Remainder(__pyx_k95p, __pyx_6); if (!__pyx_7) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; goto __pyx_L1;}
+  Py_DECREF(__pyx_6); __pyx_6 = 0;
+  __pyx_6 = PyList_New(7); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 591; goto __pyx_L1;}
+  Py_INCREF(__pyx_k89p);
+  PyList_SET_ITEM(__pyx_6, 0, __pyx_k89p);
+  PyList_SET_ITEM(__pyx_6, 1, __pyx_2);
+  PyList_SET_ITEM(__pyx_6, 2, __pyx_3);
+  PyList_SET_ITEM(__pyx_6, 3, __pyx_4);
+  PyList_SET_ITEM(__pyx_6, 4, __pyx_5);
+  PyList_SET_ITEM(__pyx_6, 5, __pyx_1);
+  PyList_SET_ITEM(__pyx_6, 6, __pyx_7);
+  __pyx_2 = 0;
+  __pyx_3 = 0;
+  __pyx_4 = 0;
+  __pyx_5 = 0;
+  __pyx_1 = 0;
+  __pyx_7 = 0;
+  Py_DECREF(__pyx_v_strg);
+  __pyx_v_strg = __pyx_6;
+  __pyx_6 = 0;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":598 */
+  __pyx_2 = PyObject_GetAttr(__pyx_k96p, __pyx_n_join); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 598; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 598; 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 = 598; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  __pyx_r = __pyx_4;
+  __pyx_4 = 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);
+  Py_XDECREF(__pyx_4);
+  Py_XDECREF(__pyx_5);
+  Py_XDECREF(__pyx_6);
+  Py_XDECREF(__pyx_7);
+  __Pyx_AddTraceback("cloess.loess_outputs.__str__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_strg);
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
 static PyObject *__pyx_f_6cloess_11loess_anova_3dfn___get__(PyObject *__pyx_v_self); /*proto*/
 static PyObject *__pyx_f_6cloess_11loess_anova_3dfn___get__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":339 */
-  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_anova *)__pyx_v_self)->_base->dfn); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 339; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":610 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_anova *)__pyx_v_self)->_base->dfn); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 610; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -2167,8 +2526,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":343 */
-  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_anova *)__pyx_v_self)->_base->dfd); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 343; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":614 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_anova *)__pyx_v_self)->_base->dfd); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 614; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -2190,8 +2549,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":347 */
-  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_anova *)__pyx_v_self)->_base->F_value); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 347; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":618 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_anova *)__pyx_v_self)->_base->F_value); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 618; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -2213,8 +2572,8 @@
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":351 */
-  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_anova *)__pyx_v_self)->_base->Pr_F); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":622 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_anova *)__pyx_v_self)->_base->Pr_F); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 622; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -2232,21 +2591,21 @@
 
 static PyObject *__pyx_n_pw_free_mem;
 
-static void __pyx_f_6cloess_19confidence_interval___dealloc__(PyObject *__pyx_v_self); /*proto*/
-static void __pyx_f_6cloess_19confidence_interval___dealloc__(PyObject *__pyx_v_self) {
+static void __pyx_f_6cloess_14conf_intervals___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_f_6cloess_14conf_intervals___dealloc__(PyObject *__pyx_v_self) {
   PyObject *__pyx_1 = 0;
   PyObject *__pyx_2 = 0;
   PyObject *__pyx_3 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":361 */
-  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_c_loess); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 361; goto __pyx_L1;}
-  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_n_pw_free_mem); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 361; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":632 */
+  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_c_loess); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 632; goto __pyx_L1;}
+  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_n_pw_free_mem); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 632; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 361; goto __pyx_L1;}
+  __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 632; goto __pyx_L1;}
   Py_INCREF(__pyx_v_self);
   PyTuple_SET_ITEM(__pyx_1, 0, __pyx_v_self);
-  __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 361; goto __pyx_L1;}
+  __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 632; goto __pyx_L1;}
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   Py_DECREF(__pyx_3); __pyx_3 = 0;
@@ -2256,91 +2615,135 @@
   Py_XDECREF(__pyx_1);
   Py_XDECREF(__pyx_2);
   Py_XDECREF(__pyx_3);
-  __Pyx_AddTraceback("cloess.confidence_interval.__dealloc__");
+  __Pyx_AddTraceback("cloess.conf_intervals.__dealloc__");
   __pyx_L0:;
   Py_DECREF(__pyx_v_self);
 }
 
-static PyObject *__pyx_n_nest;
+static PyObject *__pyx_f_6cloess_14conf_intervals_3fit___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_14conf_intervals_3fit___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  int __pyx_1;
+  PyObject *__pyx_2 = 0;
+  Py_INCREF(__pyx_v_self);
 
-static PyObject *__pyx_f_6cloess_19confidence_interval_3fit___get__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_f_6cloess_19confidence_interval_3fit___get__(PyObject *__pyx_v_self) {
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":640 */
+  __pyx_1 = PyInt_AsLong(((struct __pyx_obj_6cloess_conf_intervals *)__pyx_v_self)->nest); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 640; goto __pyx_L1;}
+  __pyx_2 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,1,((struct __pyx_obj_6cloess_conf_intervals *)__pyx_v_self)->_base.fit); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 640; goto __pyx_L1;}
+  __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_2);
+  __Pyx_AddTraceback("cloess.conf_intervals.fit.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6cloess_14conf_intervals_5upper___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_14conf_intervals_5upper___get__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r;
-  PyObject *__pyx_1 = 0;
+  int __pyx_1;
   PyObject *__pyx_2 = 0;
-  PyObject *__pyx_3 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":365 */
-  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_nest); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 365; goto __pyx_L1;}
-  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 365; goto __pyx_L1;}
-  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_confidence_interval *)__pyx_v_self)->_base->fit); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 365; goto __pyx_L1;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
-  __pyx_r = __pyx_3;
-  __pyx_3 = 0;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":648 */
+  __pyx_1 = PyInt_AsLong(((struct __pyx_obj_6cloess_conf_intervals *)__pyx_v_self)->nest); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 648; goto __pyx_L1;}
+  __pyx_2 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,1,((struct __pyx_obj_6cloess_conf_intervals *)__pyx_v_self)->_base.upper); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 648; goto __pyx_L1;}
+  __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.confidence_interval.fit.__get__");
+  __Pyx_AddTraceback("cloess.conf_intervals.upper.__get__");
   __pyx_r = 0;
   __pyx_L0:;
   Py_DECREF(__pyx_v_self);
   return __pyx_r;
 }
 
-static PyObject *__pyx_f_6cloess_19confidence_interval_5upper___get__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_f_6cloess_19confidence_interval_5upper___get__(PyObject *__pyx_v_self) {
+static PyObject *__pyx_f_6cloess_14conf_intervals_5lower___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_14conf_intervals_5lower___get__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r;
-  PyObject *__pyx_1 = 0;
+  int __pyx_1;
   PyObject *__pyx_2 = 0;
-  PyObject *__pyx_3 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":369 */
-  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_nest); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 369; goto __pyx_L1;}
-  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 369; goto __pyx_L1;}
-  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_confidence_interval *)__pyx_v_self)->_base->upper); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 369; goto __pyx_L1;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
-  __pyx_r = __pyx_3;
-  __pyx_3 = 0;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":656 */
+  __pyx_1 = PyInt_AsLong(((struct __pyx_obj_6cloess_conf_intervals *)__pyx_v_self)->nest); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 656; goto __pyx_L1;}
+  __pyx_2 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,1,((struct __pyx_obj_6cloess_conf_intervals *)__pyx_v_self)->_base.lower); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 656; goto __pyx_L1;}
+  __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.confidence_interval.upper.__get__");
+  __Pyx_AddTraceback("cloess.conf_intervals.lower.__get__");
   __pyx_r = 0;
   __pyx_L0:;
   Py_DECREF(__pyx_v_self);
   return __pyx_r;
 }
 
-static PyObject *__pyx_f_6cloess_19confidence_interval_5lower___get__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_f_6cloess_19confidence_interval_5lower___get__(PyObject *__pyx_v_self) {
+static PyObject *__pyx_n_r_;
+static PyObject *__pyx_n_fit;
+static PyObject *__pyx_n_upper;
+static PyObject *__pyx_n_T;
+
+static PyObject *__pyx_k97p;
+
+static char (__pyx_k97[]) = "Confidence intervals....\nLower b./ fit / upper b.\n%s";
+
+static PyObject *__pyx_f_6cloess_14conf_intervals___str__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_14conf_intervals___str__(PyObject *__pyx_v_self) {
+  PyArrayObject *__pyx_v_tmp_ndr;
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
   PyObject *__pyx_2 = 0;
   PyObject *__pyx_3 = 0;
+  PyObject *__pyx_4 = 0;
+  PyObject *__pyx_5 = 0;
   Py_INCREF(__pyx_v_self);
+  __pyx_v_tmp_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":373 */
-  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_nest); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; goto __pyx_L1;}
-  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; goto __pyx_L1;}
-  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_confidence_interval *)__pyx_v_self)->_base->lower); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":660 */
+  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 660; goto __pyx_L1;}
+  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_n_r_); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 660; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_lower); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 660; goto __pyx_L1;}
+  __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_n_fit); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 660; goto __pyx_L1;}
+  __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_n_upper); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 660; goto __pyx_L1;}
+  __pyx_5 = PyList_New(3); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 660; goto __pyx_L1;}
+  PyList_SET_ITEM(__pyx_5, 0, __pyx_1);
+  PyList_SET_ITEM(__pyx_5, 1, __pyx_3);
+  PyList_SET_ITEM(__pyx_5, 2, __pyx_4);
+  __pyx_1 = 0;
+  __pyx_3 = 0;
+  __pyx_4 = 0;
+  __pyx_1 = PyObject_GetItem(__pyx_2, __pyx_5); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 660; goto __pyx_L1;}
   Py_DECREF(__pyx_2); __pyx_2 = 0;
-  __pyx_r = __pyx_3;
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  __pyx_3 = PyObject_GetAttr(__pyx_1, __pyx_n_T); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 660; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  if (!__Pyx_TypeTest(__pyx_3, __pyx_ptype_7c_numpy_ndarray)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 660; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)__pyx_v_tmp_ndr));
+  __pyx_v_tmp_ndr = ((PyArrayObject *)__pyx_3);
   __pyx_3 = 0;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":661 */
+  __pyx_4 = PyNumber_Remainder(__pyx_k97p, ((PyObject *)__pyx_v_tmp_ndr)); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 661; goto __pyx_L1;}
+  __pyx_r = __pyx_4;
+  __pyx_4 = 0;
   goto __pyx_L0;
 
   __pyx_r = Py_None; Py_INCREF(Py_None);
@@ -2349,9 +2752,12 @@
   Py_XDECREF(__pyx_1);
   Py_XDECREF(__pyx_2);
   Py_XDECREF(__pyx_3);
-  __Pyx_AddTraceback("cloess.confidence_interval.lower.__get__");
+  Py_XDECREF(__pyx_4);
+  Py_XDECREF(__pyx_5);
+  __Pyx_AddTraceback("cloess.conf_intervals.__str__");
   __pyx_r = 0;
   __pyx_L0:;
+  Py_DECREF(__pyx_v_tmp_ndr);
   Py_DECREF(__pyx_v_self);
   return __pyx_r;
 }
@@ -2360,84 +2766,66 @@
 static void __pyx_f_6cloess_15loess_predicted___dealloc__(PyObject *__pyx_v_self) {
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":384 */
-  pred_free_mem(((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->_base);
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":674 */
+  pred_free_mem((&((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->_base));
 
   Py_DECREF(__pyx_v_self);
 }
 
-static PyObject *__pyx_f_6cloess_15loess_predicted_9predicted___get__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_f_6cloess_15loess_predicted_9predicted___get__(PyObject *__pyx_v_self) {
+static PyObject *__pyx_f_6cloess_15loess_predicted_6values___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_15loess_predicted_6values___get__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
-  PyObject *__pyx_2 = 0;
-  PyObject *__pyx_3 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":388 */
-  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_nest); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; goto __pyx_L1;}
-  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; goto __pyx_L1;}
-  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->_base->fit); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; goto __pyx_L1;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
-  __pyx_r = __pyx_3;
-  __pyx_3 = 0;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":682 */
+  __pyx_1 = __pyx_f_6cloess_floatarray_from_data(((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->nest,1,((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->_base.fit); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 682; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
   goto __pyx_L0;
 
   __pyx_r = Py_None; Py_INCREF(Py_None);
   goto __pyx_L0;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);
-  Py_XDECREF(__pyx_2);
-  Py_XDECREF(__pyx_3);
-  __Pyx_AddTraceback("cloess.loess_predicted.predicted.__get__");
+  __Pyx_AddTraceback("cloess.loess_predicted.values.__get__");
   __pyx_r = 0;
   __pyx_L0:;
   Py_DECREF(__pyx_v_self);
   return __pyx_r;
 }
 
-static PyObject *__pyx_f_6cloess_15loess_predicted_16predicted_stderr___get__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_f_6cloess_15loess_predicted_16predicted_stderr___get__(PyObject *__pyx_v_self) {
+static PyObject *__pyx_f_6cloess_15loess_predicted_6stderr___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_15loess_predicted_6stderr___get__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
-  PyObject *__pyx_2 = 0;
-  PyObject *__pyx_3 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":392 */
-  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_nest); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; goto __pyx_L1;}
-  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; goto __pyx_L1;}
-  __pyx_3 = __pyx_f_6cloess_floatarray_from_data(__pyx_1,__pyx_2,((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->_base->se_fit); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; goto __pyx_L1;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
-  __pyx_r = __pyx_3;
-  __pyx_3 = 0;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":691 */
+  __pyx_1 = __pyx_f_6cloess_floatarray_from_data(((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->nest,1,((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->_base.se_fit); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 691; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
   goto __pyx_L0;
 
   __pyx_r = Py_None; Py_INCREF(Py_None);
   goto __pyx_L0;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);
-  Py_XDECREF(__pyx_2);
-  Py_XDECREF(__pyx_3);
-  __Pyx_AddTraceback("cloess.loess_predicted.predicted_stderr.__get__");
+  __Pyx_AddTraceback("cloess.loess_predicted.stderr.__get__");
   __pyx_r = 0;
   __pyx_L0:;
   Py_DECREF(__pyx_v_self);
   return __pyx_r;
 }
 
-static PyObject *__pyx_n_residual_scale;
-
 static PyObject *__pyx_f_6cloess_15loess_predicted_14residual_scale___get__(PyObject *__pyx_v_self); /*proto*/
 static PyObject *__pyx_f_6cloess_15loess_predicted_14residual_scale___get__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":396 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_residual_scale); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 396; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":699 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->_base.residual_scale); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 699; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -2453,16 +2841,14 @@
   return __pyx_r;
 }
 
-static PyObject *__pyx_n_df;
-
 static PyObject *__pyx_f_6cloess_15loess_predicted_2df___get__(PyObject *__pyx_v_self); /*proto*/
 static PyObject *__pyx_f_6cloess_15loess_predicted_2df___get__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":400 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_df); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 400; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":708 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->_base.df); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 708; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;
@@ -2478,25 +2864,98 @@
   return __pyx_r;
 }
 
+static PyObject *__pyx_k98p;
+
+static char (__pyx_k98[]) = "The coverage precentage should be between 0 and 1!";
+
 static PyObject *__pyx_f_6cloess_15loess_predicted_confidence(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_6cloess_15loess_predicted_confidence[] = "\n    coverage : float\n        Confidence level of the confidence intervals limits as a fraction.\n        ";
+static char __pyx_doc_6cloess_15loess_predicted_confidence[] = "Returns the pointwise confidence intervals for each predicted values,\nat the given confidence interval coverage.\n        \n:Parameters:\n    coverage : float\n        Confidence level of the confidence intervals limits, as a fraction.\n        ";
 static PyObject *__pyx_f_6cloess_15loess_predicted_confidence(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_coverage = 0;
+  conf_inv __pyx_v__conf_intv;
   PyObject *__pyx_r;
-  double __pyx_1;
+  PyObject *__pyx_1 = 0;
+  int __pyx_2;
+  PyObject *__pyx_3 = 0;
+  PyObject *__pyx_4 = 0;
+  double __pyx_5;
   static char *__pyx_argnames[] = {"coverage",0};
-  __pyx_v_coverage = __pyx_k7;
+  __pyx_v_coverage = __pyx_k35;
   if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "|O", __pyx_argnames, &__pyx_v_coverage)) return 0;
   Py_INCREF(__pyx_v_self);
   Py_INCREF(__pyx_v_coverage);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":407 */
-  __pyx_1 = PyFloat_AsDouble(__pyx_v_coverage); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; goto __pyx_L1;}
-  pointwise(((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->_base,((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->nest,__pyx_1,((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->conf_interval->_base);
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":719 */
+  __pyx_1 = PyFloat_FromDouble(0.5); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 719; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_v_coverage, __pyx_1, &__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 719; 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":720 */
+    __pyx_1 = PyFloat_FromDouble(1.); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 720; goto __pyx_L1;}
+    __pyx_3 = PyNumber_Subtract(__pyx_1, __pyx_v_coverage); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 720; goto __pyx_L1;}
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    Py_DECREF(__pyx_v_coverage);
+    __pyx_v_coverage = __pyx_3;
+    __pyx_3 = 0;
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":721 */
+  __pyx_1 = PyFloat_FromDouble(1.); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 721; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_v_coverage, __pyx_1, &__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 721; 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":722 */
+    __pyx_3 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 722; goto __pyx_L1;}
+    __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 722; goto __pyx_L1;}
+    Py_INCREF(__pyx_k98p);
+    PyTuple_SET_ITEM(__pyx_1, 0, __pyx_k98p);
+    __pyx_4 = PyObject_CallObject(__pyx_3, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 722; goto __pyx_L1;}
+    Py_DECREF(__pyx_3); __pyx_3 = 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 = 722; goto __pyx_L1;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":723 */
+  __pyx_5 = PyFloat_AsDouble(__pyx_v_coverage); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 723; goto __pyx_L1;}
+  pointwise((&((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->_base),((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->nest,__pyx_5,(&__pyx_v__conf_intv));
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":724 */
+  __pyx_3 = PyObject_CallObject(((PyObject*)__pyx_ptype_6cloess_conf_intervals), 0); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 724; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_3, __pyx_ptype_6cloess_conf_intervals)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 724; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->confidence_intervals));
+  ((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->confidence_intervals = ((struct __pyx_obj_6cloess_conf_intervals *)__pyx_3);
+  __pyx_3 = 0;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":725 */
+  ((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->confidence_intervals->_base = __pyx_v__conf_intv;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":726 */
+  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->nest); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 726; goto __pyx_L1;}
+  Py_DECREF(((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->confidence_intervals->nest);
+  ((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->confidence_intervals->nest = __pyx_1;
+  __pyx_1 = 0;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":727 */
+  Py_INCREF(((PyObject *)((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->confidence_intervals));
+  __pyx_r = ((PyObject *)((struct __pyx_obj_6cloess_loess_predicted *)__pyx_v_self)->confidence_intervals);
+  goto __pyx_L0;
+
   __pyx_r = Py_None; Py_INCREF(Py_None);
   goto __pyx_L0;
   __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_3);
+  Py_XDECREF(__pyx_4);
   __Pyx_AddTraceback("cloess.loess_predicted.confidence");
   __pyx_r = 0;
   __pyx_L0:;
@@ -2505,28 +2964,136 @@
   return __pyx_r;
 }
 
+static PyObject *__pyx_n_values;
+static PyObject *__pyx_n_stderr;
+static PyObject *__pyx_n_residual_scale;
+static PyObject *__pyx_n_df;
+
+static PyObject *__pyx_k99p;
+static PyObject *__pyx_k100p;
+static PyObject *__pyx_k101p;
+static PyObject *__pyx_k102p;
+static PyObject *__pyx_k103p;
+static PyObject *__pyx_k104p;
+
+static char (__pyx_k99[]) = "Outputs................";
+static char (__pyx_k100[]) = "Predicted values      : %s\n";
+static char (__pyx_k101[]) = "Predicted std error   : %s\n";
+static char (__pyx_k102[]) = "Residual scale        : %s";
+static char (__pyx_k103[]) = "Degrees of freedom    : %s";
+static char (__pyx_k104[]) = "\n";
+
+static PyObject *__pyx_f_6cloess_15loess_predicted___str__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6cloess_15loess_predicted___str__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_v_strg;
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  PyObject *__pyx_4 = 0;
+  PyObject *__pyx_5 = 0;
+  Py_INCREF(__pyx_v_self);
+  __pyx_v_strg = Py_None; Py_INCREF(Py_None);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":730 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_values); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 731; goto __pyx_L1;}
+  __pyx_2 = PyNumber_Remainder(__pyx_k100p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 731; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_stderr); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 732; goto __pyx_L1;}
+  __pyx_3 = PyNumber_Remainder(__pyx_k101p, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 732; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_residual_scale); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 733; goto __pyx_L1;}
+  __pyx_4 = PyNumber_Remainder(__pyx_k102p, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 733; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_df); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; goto __pyx_L1;}
+  __pyx_5 = PyNumber_Remainder(__pyx_k103p, __pyx_1); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = PyList_New(5); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 730; goto __pyx_L1;}
+  Py_INCREF(__pyx_k99p);
+  PyList_SET_ITEM(__pyx_1, 0, __pyx_k99p);
+  PyList_SET_ITEM(__pyx_1, 1, __pyx_2);
+  PyList_SET_ITEM(__pyx_1, 2, __pyx_3);
+  PyList_SET_ITEM(__pyx_1, 3, __pyx_4);
+  PyList_SET_ITEM(__pyx_1, 4, __pyx_5);
+  __pyx_2 = 0;
+  __pyx_3 = 0;
+  __pyx_4 = 0;
+  __pyx_5 = 0;
+  Py_DECREF(__pyx_v_strg);
+  __pyx_v_strg = __pyx_1;
+  __pyx_1 = 0;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":737 */
+  __pyx_2 = PyObject_GetAttr(__pyx_k104p, __pyx_n_join); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 737; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 737; 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 = 737; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  __pyx_r = __pyx_4;
+  __pyx_4 = 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);
+  Py_XDECREF(__pyx_4);
+  Py_XDECREF(__pyx_5);
+  __Pyx_AddTraceback("cloess.loess_predicted.__str__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_strg);
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_n_order;
+static PyObject *__pyx_n_C;
 static PyObject *__pyx_n_len;
+static PyObject *__pyx_n_iteritems;
+static PyObject *__pyx_n_update;
 
+static PyObject *__pyx_k113p;
+
+static char (__pyx_k113[]) = "Incompatible size between the response array (%i) and the predictor array (%i)";
+
 static int __pyx_f_6cloess_5loess___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static int __pyx_f_6cloess_5loess___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_x = 0;
   PyObject *__pyx_v_y = 0;
   PyObject *__pyx_v_weights = 0;
+  PyObject *__pyx_v_options = 0;
   PyArrayObject *__pyx_v_x_ndr;
   PyArrayObject *__pyx_v_y_ndr;
   double (*__pyx_v_x_dat);
   double (*__pyx_v_y_dat);
   PyObject *__pyx_v_n;
   PyObject *__pyx_v_p;
+  PyObject *__pyx_v_modelopt;
+  PyObject *__pyx_v_controlopt;
+  PyObject *__pyx_v_k;
+  PyObject *__pyx_v_v;
   int __pyx_r;
   PyObject *__pyx_1 = 0;
   PyObject *__pyx_2 = 0;
   PyObject *__pyx_3 = 0;
-  long __pyx_4;
+  PyObject *__pyx_4 = 0;
   long __pyx_5;
+  int __pyx_6;
+  long __pyx_7;
   static char *__pyx_argnames[] = {"x","y","weights",0};
-  __pyx_v_weights = __pyx_k8;
-  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "OO|O", __pyx_argnames, &__pyx_v_x, &__pyx_v_y, &__pyx_v_weights)) return -1;
+  __pyx_v_weights = __pyx_k36;
+  if (__Pyx_GetStarArgs(&__pyx_args, &__pyx_kwds, __pyx_argnames, 3, 0, &__pyx_v_options) < 0) return -1;
+  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "OO|O", __pyx_argnames, &__pyx_v_x, &__pyx_v_y, &__pyx_v_weights)) {
+    Py_XDECREF(__pyx_args);
+    Py_XDECREF(__pyx_kwds);
+    Py_XDECREF(__pyx_v_options);
+    return -1;
+  }
   Py_INCREF(__pyx_v_self);
   Py_INCREF(__pyx_v_x);
   Py_INCREF(__pyx_v_y);
@@ -2535,164 +3102,383 @@
   __pyx_v_y_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
   __pyx_v_n = Py_None; Py_INCREF(Py_None);
   __pyx_v_p = Py_None; Py_INCREF(Py_None);
+  __pyx_v_modelopt = Py_None; Py_INCREF(Py_None);
+  __pyx_v_controlopt = Py_None; Py_INCREF(Py_None);
+  __pyx_v_k = Py_None; Py_INCREF(Py_None);
+  __pyx_v_v = Py_None; Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":429 */
-  __pyx_1 = PyArray_FROMANY(__pyx_v_x,NPY_DOUBLE,1,1,NPY_FORTRAN); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; goto __pyx_L1;}
-  Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_1)));
-  Py_DECREF(((PyObject *)__pyx_v_x_ndr));
-  __pyx_v_x_ndr = ((PyArrayObject *)__pyx_1);
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":759 */
+  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 759; goto __pyx_L1;}
+  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_n_array); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 759; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":430 */
-  __pyx_1 = PyArray_FROMANY(__pyx_v_y,NPY_DOUBLE,1,1,NPY_FORTRAN); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 430; goto __pyx_L1;}
-  Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_1)));
-  Py_DECREF(((PyObject *)__pyx_v_y_ndr));
-  __pyx_v_y_ndr = ((PyArrayObject *)__pyx_1);
+  __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 759; goto __pyx_L1;}
+  Py_INCREF(__pyx_v_x);
+  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_v_x);
+  __pyx_3 = PyDict_New(); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 759; goto __pyx_L1;}
+  __pyx_4 = __Pyx_GetName(__pyx_b, __pyx_n_True); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 759; goto __pyx_L1;}
+  if (PyDict_SetItem(__pyx_3, __pyx_n_copy, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 759; 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 = 759; goto __pyx_L1;}
+  if (PyDict_SetItem(__pyx_3, __pyx_n_subok, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 759; goto __pyx_L1;}
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+  if (PyDict_SetItem(__pyx_3, __pyx_n_order, __pyx_n_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 759; goto __pyx_L1;}
+  __pyx_4 = PyEval_CallObjectWithKeywords(__pyx_2, __pyx_1, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 759; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  if (!__Pyx_TypeTest(__pyx_4, __pyx_ptype_7c_numpy_ndarray)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 759; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)__pyx_v_x_ndr));
+  __pyx_v_x_ndr = ((PyArrayObject *)__pyx_4);
+  __pyx_4 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":431 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":760 */
   __pyx_v_x_dat = ((double (*))__pyx_v_x_ndr->data);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":432 */
-  __pyx_v_y_dat = ((double (*))__pyx_v_y_ndr->data);
-
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":433 */
-  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_len); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; goto __pyx_L1;}
-  __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":761 */
+  __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_len); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 761; goto __pyx_L1;}
+  __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 761; goto __pyx_L1;}
   Py_INCREF(((PyObject *)__pyx_v_x_ndr));
-  PyTuple_SET_ITEM(__pyx_2, 0, ((PyObject *)__pyx_v_x_ndr));
-  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_1, 0, ((PyObject *)__pyx_v_x_ndr));
+  __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 761; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_v_n);
   __pyx_v_n = __pyx_3;
   __pyx_3 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":434 */
-  __pyx_1 = PyObject_GetAttr(((PyObject *)__pyx_v_x_ndr), __pyx_n_size); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 434; goto __pyx_L1;}
-  __pyx_2 = PyNumber_Divide(__pyx_1, __pyx_v_n); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 434; goto __pyx_L1;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":762 */
+  __pyx_4 = PyObject_GetAttr(((PyObject *)__pyx_v_x_ndr), __pyx_n_size); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 762; goto __pyx_L1;}
+  __pyx_2 = PyNumber_Divide(__pyx_4, __pyx_v_n); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 762; goto __pyx_L1;}
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
   Py_DECREF(__pyx_v_p);
   __pyx_v_p = __pyx_2;
   __pyx_2 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":435 */
-  __pyx_4 = PyInt_AsLong(__pyx_v_n); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; goto __pyx_L1;}
-  __pyx_5 = PyInt_AsLong(__pyx_v_p); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; goto __pyx_L1;}
-  loess_setup(__pyx_v_x_dat,__pyx_v_y_dat,__pyx_4,__pyx_5,(&((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base));
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":763 */
+  __pyx_5 = PyInt_AsLong(__pyx_v_p); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 763; goto __pyx_L1;}
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->npar = __pyx_5;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":437 */
-  __pyx_3 = PyObject_CallObject(((PyObject*)__pyx_ptype_6cloess_loess_inputs), 0); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; goto __pyx_L1;}
-  if (!__Pyx_TypeTest(__pyx_3, __pyx_ptype_6cloess_loess_inputs)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":764 */
+  __pyx_5 = PyInt_AsLong(__pyx_v_n); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 764; goto __pyx_L1;}
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->nobs = __pyx_5;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":766 */
+  __pyx_1 = PyInt_FromLong(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 766; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_v_p, __pyx_1, &__pyx_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 766; goto __pyx_L1;}
+  __pyx_6 = __pyx_6 > 0;
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  if (__pyx_6) {
+
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":767 */
+    __pyx_3 = PyNumber_Multiply(__pyx_v_n, __pyx_v_p); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 767; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 767; goto __pyx_L1;}
+    PyTuple_SET_ITEM(__pyx_4, 0, __pyx_3);
+    __pyx_3 = 0;
+    if (PyObject_SetAttr(((PyObject *)__pyx_v_x_ndr), __pyx_n_shape, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 767; goto __pyx_L1;}
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":769 */
+  __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; goto __pyx_L1;}
+  __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_n_array); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; goto __pyx_L1;}
+  Py_INCREF(__pyx_v_y);
+  PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_y);
+  __pyx_4 = PyDict_New(); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; goto __pyx_L1;}
+  __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_False); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; goto __pyx_L1;}
+  if (PyDict_SetItem(__pyx_4, __pyx_n_copy, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_True); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; goto __pyx_L1;}
+  if (PyDict_SetItem(__pyx_4, __pyx_n_subok, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  if (PyDict_SetItem(__pyx_4, __pyx_n_order, __pyx_n_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; goto __pyx_L1;}
+  __pyx_2 = PyEval_CallObjectWithKeywords(__pyx_1, __pyx_3, __pyx_4); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+  if (!__Pyx_TypeTest(__pyx_2, __pyx_ptype_7c_numpy_ndarray)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)__pyx_v_y_ndr));
+  __pyx_v_y_ndr = ((PyArrayObject *)__pyx_2);
+  __pyx_2 = 0;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":770 */
+  __pyx_v_y_dat = ((double (*))__pyx_v_y_ndr->data);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":771 */
+  __pyx_1 = PyObject_GetAttr(((PyObject *)__pyx_v_y_ndr), __pyx_n_size); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 771; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_1, __pyx_v_n, &__pyx_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 771; goto __pyx_L1;}
+  __pyx_6 = __pyx_6 != 0;
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  if (__pyx_6) {
+
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":772 */
+    __pyx_3 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 772; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(2); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; goto __pyx_L1;}
+    Py_INCREF(((PyObject *)__pyx_v_y_ndr));
+    PyTuple_SET_ITEM(__pyx_4, 0, ((PyObject *)__pyx_v_y_ndr));
+    Py_INCREF(__pyx_v_n);
+    PyTuple_SET_ITEM(__pyx_4, 1, __pyx_v_n);
+    __pyx_2 = PyNumber_Remainder(__pyx_k113p, __pyx_4); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; goto __pyx_L1;}
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 772; goto __pyx_L1;}
+    PyTuple_SET_ITEM(__pyx_1, 0, __pyx_2);
+    __pyx_2 = 0;
+    __pyx_4 = PyObject_CallObject(__pyx_3, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 772; goto __pyx_L1;}
+    Py_DECREF(__pyx_3); __pyx_3 = 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 = 772; goto __pyx_L1;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":775 */
+  __pyx_5 = PyInt_AsLong(__pyx_v_n); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 775; goto __pyx_L1;}
+  __pyx_7 = PyInt_AsLong(__pyx_v_p); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 775; goto __pyx_L1;}
+  loess_setup(__pyx_v_x_dat,__pyx_v_y_dat,__pyx_5,__pyx_7,(&((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base));
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":777 */
+  __pyx_2 = PyObject_CallObject(((PyObject*)__pyx_ptype_6cloess_loess_inputs), 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 777; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_2, __pyx_ptype_6cloess_loess_inputs)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 777; goto __pyx_L1;}
   Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->inputs));
-  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->inputs = ((struct __pyx_obj_6cloess_loess_inputs *)__pyx_3);
-  __pyx_3 = 0;
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->inputs = ((struct __pyx_obj_6cloess_loess_inputs *)__pyx_2);
+  __pyx_2 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":438 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":778 */
   ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->inputs->_base = (&((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base.inputs);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":440 */
-  __pyx_1 = PyObject_CallObject(((PyObject*)__pyx_ptype_6cloess_loess_model), 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 440; goto __pyx_L1;}
-  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_6cloess_loess_model)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 440; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":780 */
+  __pyx_3 = PyObject_CallObject(((PyObject*)__pyx_ptype_6cloess_loess_model), 0); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 780; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_3, __pyx_ptype_6cloess_loess_model)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 780; goto __pyx_L1;}
   Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->model));
-  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->model = ((struct __pyx_obj_6cloess_loess_model *)__pyx_1);
-  __pyx_1 = 0;
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->model = ((struct __pyx_obj_6cloess_loess_model *)__pyx_3);
+  __pyx_3 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":441 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":781 */
   ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->model->_base = (&((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base.model);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":442 */
-  __pyx_4 = PyInt_AsLong(__pyx_v_p); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 442; goto __pyx_L1;}
-  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->model->npar = __pyx_4;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":782 */
+  __pyx_5 = PyInt_AsLong(__pyx_v_p); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 782; goto __pyx_L1;}
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->model->npar = __pyx_5;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":444 */
-  __pyx_2 = PyObject_CallObject(((PyObject*)__pyx_ptype_6cloess_loess_control), 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; goto __pyx_L1;}
-  if (!__Pyx_TypeTest(__pyx_2, __pyx_ptype_6cloess_loess_control)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":784 */
+  __pyx_1 = PyObject_CallObject(((PyObject*)__pyx_ptype_6cloess_loess_control), 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 784; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_6cloess_loess_control)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 784; goto __pyx_L1;}
   Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->control));
-  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->control = ((struct __pyx_obj_6cloess_loess_control *)__pyx_2);
-  __pyx_2 = 0;
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->control = ((struct __pyx_obj_6cloess_loess_control *)__pyx_1);
+  __pyx_1 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":445 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":785 */
   ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->control->_base = (&((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base.control);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":447 */
-  __pyx_3 = PyObject_CallObject(((PyObject*)__pyx_ptype_6cloess_loess_kd_tree), 0); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; goto __pyx_L1;}
-  if (!__Pyx_TypeTest(__pyx_3, __pyx_ptype_6cloess_loess_kd_tree)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":787 */
+  __pyx_4 = PyObject_CallObject(((PyObject*)__pyx_ptype_6cloess_loess_kd_tree), 0); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 787; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_4, __pyx_ptype_6cloess_loess_kd_tree)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 787; goto __pyx_L1;}
   Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->kd_tree));
-  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->kd_tree = ((struct __pyx_obj_6cloess_loess_kd_tree *)__pyx_3);
-  __pyx_3 = 0;
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->kd_tree = ((struct __pyx_obj_6cloess_loess_kd_tree *)__pyx_4);
+  __pyx_4 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":448 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":788 */
   ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->kd_tree->_base = (&((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base.kd_tree);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":450 */
-  __pyx_1 = PyObject_CallObject(((PyObject*)__pyx_ptype_6cloess_loess_outputs), 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 450; goto __pyx_L1;}
-  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_6cloess_loess_outputs)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 450; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":790 */
+  __pyx_2 = PyObject_CallObject(((PyObject*)__pyx_ptype_6cloess_loess_outputs), 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 790; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_2, __pyx_ptype_6cloess_loess_outputs)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 790; goto __pyx_L1;}
   Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs));
-  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs = ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_1);
-  __pyx_1 = 0;
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs = ((struct __pyx_obj_6cloess_loess_outputs *)__pyx_2);
+  __pyx_2 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":451 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":791 */
   ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs->_base = (&((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base.outputs);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":452 */
-  __pyx_5 = PyInt_AsLong(__pyx_v_n); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; goto __pyx_L1;}
-  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs->nobs = __pyx_5;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":792 */
+  __pyx_3 = __Pyx_GetName(__pyx_b, __pyx_n_False); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 792; goto __pyx_L1;}
+  __pyx_6 = PyInt_AsLong(__pyx_3); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 792; goto __pyx_L1;}
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs->activated = __pyx_6;
 
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":793 */
+  __pyx_7 = PyInt_AsLong(__pyx_v_n); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 793; goto __pyx_L1;}
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs->nobs = __pyx_7;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":794 */
+  __pyx_5 = PyInt_AsLong(__pyx_v_p); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 794; goto __pyx_L1;}
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs->npar = __pyx_5;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":796 */
+  __pyx_1 = PyDict_New(); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 796; goto __pyx_L1;}
+  Py_DECREF(__pyx_v_modelopt);
+  __pyx_v_modelopt = __pyx_1;
+  __pyx_1 = 0;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":797 */
+  __pyx_4 = PyDict_New(); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 797; goto __pyx_L1;}
+  Py_DECREF(__pyx_v_controlopt);
+  __pyx_v_controlopt = __pyx_4;
+  __pyx_4 = 0;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":798 */
+  __pyx_2 = PyObject_GetAttr(__pyx_v_options, __pyx_n_iteritems); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 798; goto __pyx_L1;}
+  __pyx_3 = PyObject_CallObject(__pyx_2, 0); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 798; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_1 = PyObject_GetIter(__pyx_3); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 798; goto __pyx_L1;}
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  for (;;) {
+    __pyx_4 = PyIter_Next(__pyx_1);
+    if (!__pyx_4) {
+      if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 798; goto __pyx_L1;}
+      break;
+    }
+    __pyx_2 = PyObject_GetIter(__pyx_4); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 798; goto __pyx_L1;}
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    __pyx_3 = __Pyx_UnpackItem(__pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 798; goto __pyx_L1;}
+    Py_DECREF(__pyx_v_k);
+    __pyx_v_k = __pyx_3;
+    __pyx_3 = 0;
+    __pyx_4 = __Pyx_UnpackItem(__pyx_2); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 798; goto __pyx_L1;}
+    Py_DECREF(__pyx_v_v);
+    __pyx_v_v = __pyx_4;
+    __pyx_4 = 0;
+    if (__Pyx_EndUnpack(__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 798; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":799 */
+    __pyx_3 = PyTuple_New(6); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 799; goto __pyx_L1;}
+    Py_INCREF(__pyx_n_family);
+    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_n_family);
+    Py_INCREF(__pyx_n_span);
+    PyTuple_SET_ITEM(__pyx_3, 1, __pyx_n_span);
+    Py_INCREF(__pyx_n_degree);
+    PyTuple_SET_ITEM(__pyx_3, 2, __pyx_n_degree);
+    Py_INCREF(__pyx_n_normalize);
+    PyTuple_SET_ITEM(__pyx_3, 3, __pyx_n_normalize);
+    Py_INCREF(__pyx_n_parametric);
+    PyTuple_SET_ITEM(__pyx_3, 4, __pyx_n_parametric);
+    Py_INCREF(__pyx_n_drop_square);
+    PyTuple_SET_ITEM(__pyx_3, 5, __pyx_n_drop_square);
+    __pyx_6 = PySequence_Contains(__pyx_3, __pyx_v_k); if (__pyx_6 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 799; goto __pyx_L1;}
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    if (__pyx_6) {
+
+      /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":801 */
+      if (PyObject_SetItem(__pyx_v_modelopt, __pyx_v_k, __pyx_v_v) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 801; goto __pyx_L1;}
+      goto __pyx_L6;
+    }
+    __pyx_4 = PyTuple_New(5); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 802; goto __pyx_L1;}
+    Py_INCREF(__pyx_n_surface);
+    PyTuple_SET_ITEM(__pyx_4, 0, __pyx_n_surface);
+    Py_INCREF(__pyx_n_statistics);
+    PyTuple_SET_ITEM(__pyx_4, 1, __pyx_n_statistics);
+    Py_INCREF(__pyx_n_trace_hat);
+    PyTuple_SET_ITEM(__pyx_4, 2, __pyx_n_trace_hat);
+    Py_INCREF(__pyx_n_iterations);
+    PyTuple_SET_ITEM(__pyx_4, 3, __pyx_n_iterations);
+    Py_INCREF(__pyx_n_cell);
+    PyTuple_SET_ITEM(__pyx_4, 4, __pyx_n_cell);
+    __pyx_6 = PySequence_Contains(__pyx_4, __pyx_v_k); if (__pyx_6 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 802; goto __pyx_L1;}
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    if (__pyx_6) {
+
+      /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":804 */
+      if (PyObject_SetItem(__pyx_v_controlopt, __pyx_v_k, __pyx_v_v) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 804; goto __pyx_L1;}
+      goto __pyx_L6;
+    }
+    __pyx_L6:;
+  }
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":805 */
+  __pyx_2 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->control), __pyx_n_update); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 805; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(0); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 805; goto __pyx_L1;}
+  __pyx_4 = PyEval_CallObjectWithKeywords(__pyx_2, __pyx_3, __pyx_v_controlopt); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 805; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":806 */
+  __pyx_1 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->model), __pyx_n_update); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 806; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 806; goto __pyx_L1;}
+  __pyx_3 = PyEval_CallObjectWithKeywords(__pyx_1, __pyx_2, __pyx_v_modelopt); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 806; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+
   __pyx_r = 0;
   goto __pyx_L0;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);
   Py_XDECREF(__pyx_2);
   Py_XDECREF(__pyx_3);
+  Py_XDECREF(__pyx_4);
   __Pyx_AddTraceback("cloess.loess.__init__");
   __pyx_r = -1;
   __pyx_L0:;
+  Py_XDECREF(__pyx_v_options);
   Py_DECREF(__pyx_v_x_ndr);
   Py_DECREF(__pyx_v_y_ndr);
   Py_DECREF(__pyx_v_n);
   Py_DECREF(__pyx_v_p);
+  Py_DECREF(__pyx_v_modelopt);
+  Py_DECREF(__pyx_v_controlopt);
+  Py_DECREF(__pyx_v_k);
+  Py_DECREF(__pyx_v_v);
   Py_DECREF(__pyx_v_self);
   Py_DECREF(__pyx_v_x);
   Py_DECREF(__pyx_v_y);
   Py_DECREF(__pyx_v_weights);
+  Py_XDECREF(__pyx_args);
+  Py_XDECREF(__pyx_kwds);
   return __pyx_r;
 }
 
 static PyObject *__pyx_f_6cloess_5loess_fit(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static PyObject *__pyx_f_6cloess_5loess_fit(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  int __pyx_2;
   static char *__pyx_argnames[] = {0};
   if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "", __pyx_argnames)) return 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":455 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":809 */
   loess_fit((&((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base));
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":456 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":810 */
+  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_True); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 810; goto __pyx_L1;}
+  __pyx_2 = PyInt_AsLong(__pyx_1); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 810; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs->activated = __pyx_2;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":811 */
   __pyx_r = Py_None; Py_INCREF(Py_None);
   goto __pyx_L0;
 
   __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("cloess.loess.fit");
+  __pyx_r = 0;
   __pyx_L0:;
   Py_DECREF(__pyx_v_self);
   return __pyx_r;
 }
 
 static PyObject *__pyx_n_nobs;
-static PyObject *__pyx_n_enp;
-static PyObject *__pyx_n_gaussian;
-static PyObject *__pyx_n_s;
 
-static PyObject *__pyx_k40p;
-static PyObject *__pyx_k41p;
-static PyObject *__pyx_k43p;
-static PyObject *__pyx_k44p;
+static PyObject *__pyx_k125p;
+static PyObject *__pyx_k126p;
+static PyObject *__pyx_k128p;
+static PyObject *__pyx_k129p;
 
-static char (__pyx_k40[]) = "Number of Observations         : %d";
-static char (__pyx_k41[]) = "Equivalent Number of Parameters: %.1f";
-static char (__pyx_k43[]) = "Residual Standard Error        : %.4f";
-static char (__pyx_k44[]) = "Residual Scale Estimate        : %.4f";
+static char (__pyx_k125[]) = "Number of Observations         : %d";
+static char (__pyx_k126[]) = "Equivalent Number of Parameters: %.1f";
+static char (__pyx_k128[]) = "Residual Standard Error        : %.4f";
+static char (__pyx_k129[]) = "Residual Scale Estimate        : %.4f";
 
 static PyObject *__pyx_f_6cloess_5loess_summary(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static PyObject *__pyx_f_6cloess_5loess_summary(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
@@ -2704,47 +3490,47 @@
   if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "", __pyx_argnames)) return 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":459 */
-  __pyx_1 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->inputs), __pyx_n_nobs); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; goto __pyx_L1;}
-  __pyx_2 = PyNumber_Remainder(__pyx_k40p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":814 */
+  __pyx_1 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->inputs), __pyx_n_nobs); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 814; goto __pyx_L1;}
+  __pyx_2 = PyNumber_Remainder(__pyx_k125p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 814; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  if (__Pyx_PrintItem(__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; goto __pyx_L1;}
+  if (__Pyx_PrintItem(__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 814; goto __pyx_L1;}
   Py_DECREF(__pyx_2); __pyx_2 = 0;
-  if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; goto __pyx_L1;}
+  if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 814; goto __pyx_L1;}
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":460 */
-  __pyx_1 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs), __pyx_n_enp); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 460; goto __pyx_L1;}
-  __pyx_2 = PyNumber_Remainder(__pyx_k41p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 460; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":815 */
+  __pyx_1 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs), __pyx_n_enp); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; goto __pyx_L1;}
+  __pyx_2 = PyNumber_Remainder(__pyx_k126p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
-  if (__Pyx_PrintItem(__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 460; goto __pyx_L1;}
+  if (__Pyx_PrintItem(__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; goto __pyx_L1;}
   Py_DECREF(__pyx_2); __pyx_2 = 0;
-  if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 460; goto __pyx_L1;}
+  if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; goto __pyx_L1;}
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":461 */
-  __pyx_1 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->model), __pyx_n_family); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 461; goto __pyx_L1;}
-  if (PyObject_Cmp(__pyx_1, __pyx_n_gaussian, &__pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 461; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":816 */
+  __pyx_1 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->model), __pyx_n_family); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 816; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_1, __pyx_n_gaussian, &__pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 816; goto __pyx_L1;}
   __pyx_3 = __pyx_3 == 0;
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   if (__pyx_3) {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":462 */
-    __pyx_2 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs), __pyx_n_s); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; goto __pyx_L1;}
-    __pyx_1 = PyNumber_Remainder(__pyx_k43p, __pyx_2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":817 */
+    __pyx_2 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs), __pyx_n_s); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 817; goto __pyx_L1;}
+    __pyx_1 = PyNumber_Remainder(__pyx_k128p, __pyx_2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 817; goto __pyx_L1;}
     Py_DECREF(__pyx_2); __pyx_2 = 0;
-    if (__Pyx_PrintItem(__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; goto __pyx_L1;}
+    if (__Pyx_PrintItem(__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 817; goto __pyx_L1;}
     Py_DECREF(__pyx_1); __pyx_1 = 0;
-    if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; goto __pyx_L1;}
+    if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 817; goto __pyx_L1;}
     goto __pyx_L2;
   }
   /*else*/ {
 
-    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":464 */
-    __pyx_2 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs), __pyx_n_s); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; goto __pyx_L1;}
-    __pyx_1 = PyNumber_Remainder(__pyx_k44p, __pyx_2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; goto __pyx_L1;}
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":819 */
+    __pyx_2 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs), __pyx_n_s); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 819; goto __pyx_L1;}
+    __pyx_1 = PyNumber_Remainder(__pyx_k129p, __pyx_2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 819; goto __pyx_L1;}
     Py_DECREF(__pyx_2); __pyx_2 = 0;
-    if (__Pyx_PrintItem(__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; goto __pyx_L1;}
+    if (__Pyx_PrintItem(__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 819; goto __pyx_L1;}
     Py_DECREF(__pyx_1); __pyx_1 = 0;
-    if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; goto __pyx_L1;}
+    if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 819; goto __pyx_L1;}
   }
   __pyx_L2:;
 
@@ -2760,8 +3546,15 @@
   return __pyx_r;
 }
 
-static PyObject *__pyx_n_nvar;
+static PyObject *__pyx_n_ravel;
+static PyObject *__pyx_n_divmod;
 
+static PyObject *__pyx_k134p;
+static PyObject *__pyx_k135p;
+
+static char (__pyx_k134[]) = "Can't predict without input data !";
+static char (__pyx_k135[]) = "Incompatible data size: there should be as many rows as parameters";
+
 static PyObject *__pyx_f_6cloess_5loess_predict(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static char __pyx_doc_6cloess_5loess_predict[] = "\n    newdata: ndarray\n        A (m,p) ndarray specifying the values of the predictors at which the \n        evaluation is to be carried out.\n    stderr: Boolean\n        Logical flag for computing standard errors at newdata.\n        ";
 static PyObject *__pyx_f_6cloess_5loess_predict(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
@@ -2769,137 +3562,315 @@
   PyObject *__pyx_v_stderr = 0;
   PyArrayObject *__pyx_v_p_ndr;
   double (*__pyx_v_p_dat);
+  prediction __pyx_v__prediction;
   int __pyx_v_m;
+  PyObject *__pyx_v_notOK;
   PyObject *__pyx_r;
-  PyObject *__pyx_1 = 0;
-  int __pyx_2;
+  int __pyx_1;
+  PyObject *__pyx_2 = 0;
   PyObject *__pyx_3 = 0;
   PyObject *__pyx_4 = 0;
+  PyObject *__pyx_5 = 0;
   static char *__pyx_argnames[] = {"newdata","stderr",0};
-  __pyx_v_stderr = __pyx_k9;
+  __pyx_v_stderr = __pyx_k37;
   if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "O|O", __pyx_argnames, &__pyx_v_newdata, &__pyx_v_stderr)) return 0;
   Py_INCREF(__pyx_v_self);
   Py_INCREF(__pyx_v_newdata);
   Py_INCREF(__pyx_v_stderr);
   __pyx_v_p_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  __pyx_v_notOK = Py_None; Py_INCREF(Py_None);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":478 */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_nvar); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; goto __pyx_L1;}
-  __pyx_2 = PyInt_AsLong(__pyx_1); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; goto __pyx_L1;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyArray_FROMANY(__pyx_v_newdata,NPY_DOUBLE,1,__pyx_2,NPY_FORTRAN); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; goto __pyx_L1;}
-  Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_1)));
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":834 */
+  __pyx_1 = (((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs->activated == 0);
+  if (__pyx_1) {
+
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":835 */
+    loess_fit((&((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base));
+
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":836 */
+    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_True); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 836; goto __pyx_L1;}
+    __pyx_1 = PyInt_AsLong(__pyx_2); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 836; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->outputs->activated = __pyx_1;
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":838 */
+  __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 838; goto __pyx_L1;}
+  __pyx_3 = PyObject_GetAttr(__pyx_2, __pyx_n_array); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 838; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 838; goto __pyx_L1;}
+  Py_INCREF(__pyx_v_newdata);
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_v_newdata);
+  __pyx_4 = PyDict_New(); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 838; goto __pyx_L1;}
+  __pyx_5 = __Pyx_GetName(__pyx_b, __pyx_n_True); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 838; goto __pyx_L1;}
+  if (PyDict_SetItem(__pyx_4, __pyx_n_copy, __pyx_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 838; goto __pyx_L1;}
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  __pyx_5 = __Pyx_GetName(__pyx_b, __pyx_n_True); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 838; goto __pyx_L1;}
+  if (PyDict_SetItem(__pyx_4, __pyx_n_subok, __pyx_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 838; goto __pyx_L1;}
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  if (PyDict_SetItem(__pyx_4, __pyx_n_order, __pyx_n_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 838; goto __pyx_L1;}
+  __pyx_5 = PyEval_CallObjectWithKeywords(__pyx_3, __pyx_2, __pyx_4); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 838; goto __pyx_L1;}
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+  __pyx_3 = PyObject_GetAttr(__pyx_5, __pyx_n_ravel); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 838; goto __pyx_L1;}
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  __pyx_2 = PyObject_CallObject(__pyx_3, 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 838; goto __pyx_L1;}
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  if (!__Pyx_TypeTest(__pyx_2, __pyx_ptype_7c_numpy_ndarray)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 838; goto __pyx_L1;}
   Py_DECREF(((PyObject *)__pyx_v_p_ndr));
-  __pyx_v_p_ndr = ((PyArrayObject *)__pyx_1);
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_v_p_ndr = ((PyArrayObject *)__pyx_2);
+  __pyx_2 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":479 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":839 */
   __pyx_v_p_dat = ((double (*))__pyx_v_p_ndr->data);
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":480 */
-  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_len); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; goto __pyx_L1;}
-  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":841 */
+  __pyx_4 = PyObject_GetAttr(((PyObject *)__pyx_v_p_ndr), __pyx_n_size); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 841; goto __pyx_L1;}
+  __pyx_5 = PyInt_FromLong(0); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 841; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_4, __pyx_5, &__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 841; goto __pyx_L1;}
+  __pyx_1 = __pyx_1 == 0;
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  if (__pyx_1) {
+
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":842 */
+    __pyx_3 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 842; goto __pyx_L1;}
+    __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 842; goto __pyx_L1;}
+    Py_INCREF(__pyx_k134p);
+    PyTuple_SET_ITEM(__pyx_2, 0, __pyx_k134p);
+    __pyx_4 = PyObject_CallObject(__pyx_3, __pyx_2); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 842; goto __pyx_L1;}
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    __Pyx_Raise(__pyx_4, 0, 0);
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 842; goto __pyx_L1;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":843 */
+  __pyx_5 = __Pyx_GetName(__pyx_b, __pyx_n_divmod); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 843; goto __pyx_L1;}
+  __pyx_3 = __Pyx_GetName(__pyx_b, __pyx_n_len); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 843; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 843; goto __pyx_L1;}
   Py_INCREF(((PyObject *)__pyx_v_p_ndr));
-  PyTuple_SET_ITEM(__pyx_3, 0, ((PyObject *)__pyx_v_p_ndr));
-  __pyx_4 = PyObject_CallObject(__pyx_1, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; goto __pyx_L1;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  PyTuple_SET_ITEM(__pyx_2, 0, ((PyObject *)__pyx_v_p_ndr));
+  __pyx_4 = PyObject_CallObject(__pyx_3, __pyx_2); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 843; goto __pyx_L1;}
   Py_DECREF(__pyx_3); __pyx_3 = 0;
-  __pyx_2 = PyInt_AsLong(__pyx_4); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_3 = PyInt_FromLong(((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->npar); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 843; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 843; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_4);
+  PyTuple_SET_ITEM(__pyx_2, 1, __pyx_3);
+  __pyx_4 = 0;
+  __pyx_3 = 0;
+  __pyx_4 = PyObject_CallObject(__pyx_5, __pyx_2); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 843; goto __pyx_L1;}
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_3 = PyObject_GetIter(__pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 843; goto __pyx_L1;}
   Py_DECREF(__pyx_4); __pyx_4 = 0;
-  __pyx_v_m = __pyx_2;
+  __pyx_5 = __Pyx_UnpackItem(__pyx_3); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 843; goto __pyx_L1;}
+  __pyx_1 = PyInt_AsLong(__pyx_5); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 843; goto __pyx_L1;}
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  __pyx_v_m = __pyx_1;
+  __pyx_2 = __Pyx_UnpackItem(__pyx_3); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 843; goto __pyx_L1;}
+  Py_DECREF(__pyx_v_notOK);
+  __pyx_v_notOK = __pyx_2;
+  __pyx_2 = 0;
+  if (__Pyx_EndUnpack(__pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 843; goto __pyx_L1;}
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":481 */
-  __pyx_2 = PyInt_AsLong(__pyx_v_stderr); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 481; goto __pyx_L1;}
-  predict(__pyx_v_p_dat,__pyx_v_m,(&((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base),((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->predicted->_base,__pyx_2);
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":844 */
+  __pyx_1 = PyObject_IsTrue(__pyx_v_notOK); if (__pyx_1 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 844; goto __pyx_L1;}
+  if (__pyx_1) {
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":482 */
+    /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":845 */
+    __pyx_4 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 845; goto __pyx_L1;}
+    __pyx_5 = PyTuple_New(1); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 845; goto __pyx_L1;}
+    Py_INCREF(__pyx_k135p);
+    PyTuple_SET_ITEM(__pyx_5, 0, __pyx_k135p);
+    __pyx_2 = PyObject_CallObject(__pyx_4, __pyx_5); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 845; goto __pyx_L1;}
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    Py_DECREF(__pyx_5); __pyx_5 = 0;
+    __Pyx_Raise(__pyx_2, 0, 0);
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 845; goto __pyx_L1;}
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":848 */
+  __pyx_1 = PyInt_AsLong(__pyx_v_stderr); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 848; goto __pyx_L1;}
+  predict(__pyx_v_p_dat,__pyx_v_m,(&((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base),(&__pyx_v__prediction),__pyx_1);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":849 */
+  __pyx_3 = PyObject_CallObject(((PyObject*)__pyx_ptype_6cloess_loess_predicted), 0); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 849; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_3, __pyx_ptype_6cloess_loess_predicted)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 849; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->predicted));
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->predicted = ((struct __pyx_obj_6cloess_loess_predicted *)__pyx_3);
+  __pyx_3 = 0;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":850 */
+  ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->predicted->_base = __pyx_v__prediction;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":851 */
   ((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->predicted->nest = __pyx_v_m;
 
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":852 */
+  Py_INCREF(((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->predicted));
+  __pyx_r = ((PyObject *)((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->predicted);
+  goto __pyx_L0;
+
   __pyx_r = Py_None; Py_INCREF(Py_None);
   goto __pyx_L0;
   __pyx_L1:;
-  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
   Py_XDECREF(__pyx_3);
   Py_XDECREF(__pyx_4);
+  Py_XDECREF(__pyx_5);
   __Pyx_AddTraceback("cloess.loess.predict");
   __pyx_r = 0;
   __pyx_L0:;
   Py_DECREF(__pyx_v_p_ndr);
+  Py_DECREF(__pyx_v_notOK);
   Py_DECREF(__pyx_v_self);
   Py_DECREF(__pyx_v_newdata);
   Py_DECREF(__pyx_v_stderr);
   return __pyx_r;
 }
 
+static void __pyx_f_6cloess_5loess___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_f_6cloess_5loess___dealloc__(PyObject *__pyx_v_self) {
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":855 */
+  loess_free_mem((&((struct __pyx_obj_6cloess_loess *)__pyx_v_self)->_base));
+
+  Py_DECREF(__pyx_v_self);
+}
+
 static __Pyx_InternTabEntry __pyx_intern_tab[] = {
+  {&__pyx_n_C, "C"},
   {&__pyx_n_False, "False"},
-  {&__pyx_n_NPY_LONG, "NPY_LONG"},
+  {&__pyx_n_T, "T"},
+  {&__pyx_n_True, "True"},
   {&__pyx_n_ValueError, "ValueError"},
+  {&__pyx_n_approximate, "approximate"},
+  {&__pyx_n_array, "array"},
   {&__pyx_n_astype, "astype"},
   {&__pyx_n_bool, "bool"},
   {&__pyx_n_c_loess, "c_loess"},
   {&__pyx_n_c_numpy, "c_numpy"},
   {&__pyx_n_c_python, "c_python"},
   {&__pyx_n_cell, "cell"},
+  {&__pyx_n_copy, "copy"},
   {&__pyx_n_degree, "degree"},
   {&__pyx_n_df, "df"},
+  {&__pyx_n_direct, "direct"},
+  {&__pyx_n_divisor, "divisor"},
+  {&__pyx_n_divmod, "divmod"},
   {&__pyx_n_drop_square, "drop_square"},
   {&__pyx_n_drop_square_flags, "drop_square_flags"},
   {&__pyx_n_dtype, "dtype"},
-  {&__pyx_n_empty, "empty"},
   {&__pyx_n_enp, "enp"},
+  {&__pyx_n_exact, "exact"},
   {&__pyx_n_family, "family"},
-  {&__pyx_n_float, "float"},
+  {&__pyx_n_fit, "fit"},
+  {&__pyx_n_fitted_residuals, "fitted_residuals"},
+  {&__pyx_n_fitted_values, "fitted_values"},
   {&__pyx_n_gaussian, "gaussian"},
   {&__pyx_n_get, "get"},
   {&__pyx_n_id, "id"},
   {&__pyx_n_int, "int"},
+  {&__pyx_n_interpolate, "interpolate"},
   {&__pyx_n_iterations, "iterations"},
+  {&__pyx_n_iteritems, "iteritems"},
   {&__pyx_n_join, "join"},
   {&__pyx_n_len, "len"},
-  {&__pyx_n_max, "max"},
+  {&__pyx_n_lower, "lower"},
+  {&__pyx_n_min, "min"},
   {&__pyx_n_ndim, "ndim"},
-  {&__pyx_n_nest, "nest"},
   {&__pyx_n_nobs, "nobs"},
   {&__pyx_n_normalize, "normalize"},
   {&__pyx_n_numpy, "numpy"},
   {&__pyx_n_nvar, "nvar"},
+  {&__pyx_n_one_delta, "one_delta"},
+  {&__pyx_n_order, "order"},
   {&__pyx_n_parametric, "parametric"},
   {&__pyx_n_parametric_flags, "parametric_flags"},
   {&__pyx_n_pw_free_mem, "pw_free_mem"},
+  {&__pyx_n_r_, "r_"},
+  {&__pyx_n_ravel, "ravel"},
   {&__pyx_n_residual_scale, "residual_scale"},
   {&__pyx_n_s, "s"},
   {&__pyx_n_shape, "shape"},
   {&__pyx_n_size, "size"},
   {&__pyx_n_span, "span"},
   {&__pyx_n_statistics, "statistics"},
+  {&__pyx_n_stderr, "stderr"},
+  {&__pyx_n_subok, "subok"},
   {&__pyx_n_surface, "surface"},
+  {&__pyx_n_symmetric, "symmetric"},
   {&__pyx_n_trace_hat, "trace_hat"},
+  {&__pyx_n_two_delta, "two_delta"},
+  {&__pyx_n_update, "update"},
+  {&__pyx_n_upper, "upper"},
+  {&__pyx_n_values, "values"},
   {0, 0}
 };
 
 static __Pyx_StringTabEntry __pyx_string_tab[] = {
-  {&__pyx_k12p, __pyx_k12, sizeof(__pyx_k12)},
-  {&__pyx_k18p, __pyx_k18, sizeof(__pyx_k18)},
-  {&__pyx_k19p, __pyx_k19, sizeof(__pyx_k19)},
-  {&__pyx_k20p, __pyx_k20, sizeof(__pyx_k20)},
-  {&__pyx_k21p, __pyx_k21, sizeof(__pyx_k21)},
-  {&__pyx_k22p, __pyx_k22, sizeof(__pyx_k22)},
-  {&__pyx_k23p, __pyx_k23, sizeof(__pyx_k23)},
-  {&__pyx_k24p, __pyx_k24, sizeof(__pyx_k24)},
-  {&__pyx_k31p, __pyx_k31, sizeof(__pyx_k31)},
-  {&__pyx_k32p, __pyx_k32, sizeof(__pyx_k32)},
-  {&__pyx_k33p, __pyx_k33, sizeof(__pyx_k33)},
-  {&__pyx_k34p, __pyx_k34, sizeof(__pyx_k34)},
-  {&__pyx_k35p, __pyx_k35, sizeof(__pyx_k35)},
-  {&__pyx_k36p, __pyx_k36, sizeof(__pyx_k36)},
-  {&__pyx_k37p, __pyx_k37, sizeof(__pyx_k37)},
   {&__pyx_k38p, __pyx_k38, sizeof(__pyx_k38)},
-  {&__pyx_k39p, __pyx_k39, sizeof(__pyx_k39)},
-  {&__pyx_k40p, __pyx_k40, sizeof(__pyx_k40)},
   {&__pyx_k41p, __pyx_k41, sizeof(__pyx_k41)},
-  {&__pyx_k43p, __pyx_k43, sizeof(__pyx_k43)},
-  {&__pyx_k44p, __pyx_k44, sizeof(__pyx_k44)},
+  {&__pyx_k42p, __pyx_k42, sizeof(__pyx_k42)},
+  {&__pyx_k45p, __pyx_k45, sizeof(__pyx_k45)},
+  {&__pyx_k48p, __pyx_k48, sizeof(__pyx_k48)},
+  {&__pyx_k49p, __pyx_k49, sizeof(__pyx_k49)},
+  {&__pyx_k50p, __pyx_k50, sizeof(__pyx_k50)},
+  {&__pyx_k56p, __pyx_k56, sizeof(__pyx_k56)},
+  {&__pyx_k57p, __pyx_k57, sizeof(__pyx_k57)},
+  {&__pyx_k58p, __pyx_k58, sizeof(__pyx_k58)},
+  {&__pyx_k59p, __pyx_k59, sizeof(__pyx_k59)},
+  {&__pyx_k60p, __pyx_k60, sizeof(__pyx_k60)},
+  {&__pyx_k61p, __pyx_k61, sizeof(__pyx_k61)},
+  {&__pyx_k62p, __pyx_k62, sizeof(__pyx_k62)},
+  {&__pyx_k63p, __pyx_k63, sizeof(__pyx_k63)},
+  {&__pyx_k64p, __pyx_k64, sizeof(__pyx_k64)},
+  {&__pyx_k67p, __pyx_k67, sizeof(__pyx_k67)},
+  {&__pyx_k80p, __pyx_k80, sizeof(__pyx_k80)},
+  {&__pyx_k81p, __pyx_k81, sizeof(__pyx_k81)},
+  {&__pyx_k82p, __pyx_k82, sizeof(__pyx_k82)},
+  {&__pyx_k83p, __pyx_k83, sizeof(__pyx_k83)},
+  {&__pyx_k84p, __pyx_k84, sizeof(__pyx_k84)},
+  {&__pyx_k85p, __pyx_k85, sizeof(__pyx_k85)},
+  {&__pyx_k86p, __pyx_k86, sizeof(__pyx_k86)},
+  {&__pyx_k87p, __pyx_k87, sizeof(__pyx_k87)},
+  {&__pyx_k88p, __pyx_k88, sizeof(__pyx_k88)},
+  {&__pyx_k89p, __pyx_k89, sizeof(__pyx_k89)},
+  {&__pyx_k90p, __pyx_k90, sizeof(__pyx_k90)},
+  {&__pyx_k91p, __pyx_k91, sizeof(__pyx_k91)},
+  {&__pyx_k92p, __pyx_k92, sizeof(__pyx_k92)},
+  {&__pyx_k93p, __pyx_k93, sizeof(__pyx_k93)},
+  {&__pyx_k94p, __pyx_k94, sizeof(__pyx_k94)},
+  {&__pyx_k95p, __pyx_k95, sizeof(__pyx_k95)},
+  {&__pyx_k96p, __pyx_k96, sizeof(__pyx_k96)},
+  {&__pyx_k97p, __pyx_k97, sizeof(__pyx_k97)},
+  {&__pyx_k98p, __pyx_k98, sizeof(__pyx_k98)},
+  {&__pyx_k99p, __pyx_k99, sizeof(__pyx_k99)},
+  {&__pyx_k100p, __pyx_k100, sizeof(__pyx_k100)},
+  {&__pyx_k101p, __pyx_k101, sizeof(__pyx_k101)},
+  {&__pyx_k102p, __pyx_k102, sizeof(__pyx_k102)},
+  {&__pyx_k103p, __pyx_k103, sizeof(__pyx_k103)},
+  {&__pyx_k104p, __pyx_k104, sizeof(__pyx_k104)},
+  {&__pyx_k113p, __pyx_k113, sizeof(__pyx_k113)},
+  {&__pyx_k125p, __pyx_k125, sizeof(__pyx_k125)},
+  {&__pyx_k126p, __pyx_k126, sizeof(__pyx_k126)},
+  {&__pyx_k128p, __pyx_k128, sizeof(__pyx_k128)},
+  {&__pyx_k129p, __pyx_k129, sizeof(__pyx_k129)},
+  {&__pyx_k134p, __pyx_k134, sizeof(__pyx_k134)},
+  {&__pyx_k135p, __pyx_k135, sizeof(__pyx_k135)},
   {0, 0, 0}
 };
 
@@ -2946,8 +3917,8 @@
   return __pyx_f_6cloess_12loess_inputs_4nobs___get__(o);
 }
 
-static PyObject *__pyx_getprop_6cloess_12loess_inputs_nvar(PyObject *o, void *x) {
-  return __pyx_f_6cloess_12loess_inputs_4nvar___get__(o);
+static PyObject *__pyx_getprop_6cloess_12loess_inputs_npar(PyObject *o, void *x) {
+  return __pyx_f_6cloess_12loess_inputs_4npar___get__(o);
 }
 
 static struct PyMethodDef __pyx_methods_6cloess_loess_inputs[] = {
@@ -2959,7 +3930,7 @@
   {"y", __pyx_getprop_6cloess_12loess_inputs_y, 0, 0, 0},
   {"weights", __pyx_getprop_6cloess_12loess_inputs_weights, __pyx_setprop_6cloess_12loess_inputs_weights, __pyx_k1, 0},
   {"nobs", __pyx_getprop_6cloess_12loess_inputs_nobs, 0, __pyx_k2, 0},
-  {"nvar", __pyx_getprop_6cloess_12loess_inputs_nvar, 0, __pyx_k3, 0},
+  {"npar", __pyx_getprop_6cloess_12loess_inputs_npar, 0, __pyx_k3, 0},
   {0, 0, 0, 0, 0}
 };
 
@@ -3167,16 +4138,16 @@
 }
 
 static struct PyMethodDef __pyx_methods_6cloess_loess_control[] = {
-  {"update", (PyCFunction)__pyx_f_6cloess_13loess_control_update, METH_VARARGS|METH_KEYWORDS, 0},
+  {"update", (PyCFunction)__pyx_f_6cloess_13loess_control_update, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6cloess_13loess_control_update},
   {0, 0, 0, 0}
 };
 
 static struct PyGetSetDef __pyx_getsets_6cloess_loess_control[] = {
-  {"surface", __pyx_getprop_6cloess_13loess_control_surface, __pyx_setprop_6cloess_13loess_control_surface, 0, 0},
-  {"statistics", __pyx_getprop_6cloess_13loess_control_statistics, __pyx_setprop_6cloess_13loess_control_statistics, 0, 0},
-  {"trace_hat", __pyx_getprop_6cloess_13loess_control_trace_hat, __pyx_setprop_6cloess_13loess_control_trace_hat, 0, 0},
-  {"iterations", __pyx_getprop_6cloess_13loess_control_iterations, __pyx_setprop_6cloess_13loess_control_iterations, 0, 0},
-  {"cell", __pyx_getprop_6cloess_13loess_control_cell, __pyx_setprop_6cloess_13loess_control_cell, 0, 0},
+  {"surface", __pyx_getprop_6cloess_13loess_control_surface, __pyx_setprop_6cloess_13loess_control_surface, __pyx_k4, 0},
+  {"statistics", __pyx_getprop_6cloess_13loess_control_statistics, __pyx_setprop_6cloess_13loess_control_statistics, __pyx_k5, 0},
+  {"trace_hat", __pyx_getprop_6cloess_13loess_control_trace_hat, __pyx_setprop_6cloess_13loess_control_trace_hat, __pyx_k6, 0},
+  {"iterations", __pyx_getprop_6cloess_13loess_control_iterations, __pyx_setprop_6cloess_13loess_control_iterations, __pyx_k7, 0},
+  {"cell", __pyx_getprop_6cloess_13loess_control_cell, __pyx_setprop_6cloess_13loess_control_cell, __pyx_k8, 0},
   {0, 0, 0, 0, 0}
 };
 
@@ -3468,6 +4439,16 @@
   return __pyx_f_6cloess_11loess_model_6degree___get__(o);
 }
 
+static int __pyx_setprop_6cloess_11loess_model_degree(PyObject *o, PyObject *v, void *x) {
+  if (v) {
+    return __pyx_f_6cloess_11loess_model_6degree___set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
 static PyObject *__pyx_getprop_6cloess_11loess_model_normalize(PyObject *o, void *x) {
   return __pyx_f_6cloess_11loess_model_9normalize___get__(o);
 }
@@ -3486,6 +4467,16 @@
   return __pyx_f_6cloess_11loess_model_6family___get__(o);
 }
 
+static int __pyx_setprop_6cloess_11loess_model_family(PyObject *o, PyObject *v, void *x) {
+  if (v) {
+    return __pyx_f_6cloess_11loess_model_6family___set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
 static PyObject *__pyx_getprop_6cloess_11loess_model_parametric_flags(PyObject *o, void *x) {
   return __pyx_f_6cloess_11loess_model_16parametric_flags___get__(o);
 }
@@ -3520,12 +4511,12 @@
 };
 
 static struct PyGetSetDef __pyx_getsets_6cloess_loess_model[] = {
-  {"span", __pyx_getprop_6cloess_11loess_model_span, __pyx_setprop_6cloess_11loess_model_span, 0, 0},
-  {"degree", __pyx_getprop_6cloess_11loess_model_degree, 0, 0, 0},
-  {"normalize", __pyx_getprop_6cloess_11loess_model_normalize, __pyx_setprop_6cloess_11loess_model_normalize, __pyx_k4, 0},
-  {"family", __pyx_getprop_6cloess_11loess_model_family, 0, 0, 0},
-  {"parametric_flags", __pyx_getprop_6cloess_11loess_model_parametric_flags, __pyx_setprop_6cloess_11loess_model_parametric_flags, 0, 0},
-  {"drop_square_flags", __pyx_getprop_6cloess_11loess_model_drop_square_flags, __pyx_setprop_6cloess_11loess_model_drop_square_flags, 0, 0},
+  {"span", __pyx_getprop_6cloess_11loess_model_span, __pyx_setprop_6cloess_11loess_model_span, __pyx_k9, 0},
+  {"degree", __pyx_getprop_6cloess_11loess_model_degree, __pyx_setprop_6cloess_11loess_model_degree, __pyx_k10, 0},
+  {"normalize", __pyx_getprop_6cloess_11loess_model_normalize, __pyx_setprop_6cloess_11loess_model_normalize, __pyx_k11, 0},
+  {"family", __pyx_getprop_6cloess_11loess_model_family, __pyx_setprop_6cloess_11loess_model_family, __pyx_k12, 0},
+  {"parametric_flags", __pyx_getprop_6cloess_11loess_model_parametric_flags, __pyx_setprop_6cloess_11loess_model_parametric_flags, __pyx_k13, 0},
+  {"drop_square_flags", __pyx_getprop_6cloess_11loess_model_drop_square_flags, __pyx_setprop_6cloess_11loess_model_drop_square_flags, __pyx_k14, 0},
   {0, 0, 0, 0, 0}
 };
 
@@ -3710,18 +4701,23 @@
   {0, 0, 0, 0}
 };
 
+static struct PyMemberDef __pyx_members_6cloess_loess_outputs[] = {
+  {"activated", T_INT, offsetof(struct __pyx_obj_6cloess_loess_outputs, activated), READONLY, 0},
+  {0, 0, 0, 0, 0}
+};
+
 static struct PyGetSetDef __pyx_getsets_6cloess_loess_outputs[] = {
-  {"fitted_values", __pyx_getprop_6cloess_13loess_outputs_fitted_values, 0, 0, 0},
-  {"fitted_residuals", __pyx_getprop_6cloess_13loess_outputs_fitted_residuals, 0, 0, 0},
-  {"pseudovalues", __pyx_getprop_6cloess_13loess_outputs_pseudovalues, 0, 0, 0},
-  {"diagonal", __pyx_getprop_6cloess_13loess_outputs_diagonal, 0, 0, 0},
-  {"robust", __pyx_getprop_6cloess_13loess_outputs_robust, 0, 0, 0},
-  {"divisor", __pyx_getprop_6cloess_13loess_outputs_divisor, 0, 0, 0},
-  {"enp", __pyx_getprop_6cloess_13loess_outputs_enp, 0, __pyx_k5, 0},
-  {"s", __pyx_getprop_6cloess_13loess_outputs_s, 0, 0, 0},
-  {"one_delta", __pyx_getprop_6cloess_13loess_outputs_one_delta, 0, 0, 0},
-  {"two_delta", __pyx_getprop_6cloess_13loess_outputs_two_delta, 0, 0, 0},
-  {"trace_hat", __pyx_getprop_6cloess_13loess_outputs_trace_hat, 0, 0, 0},
+  {"fitted_values", __pyx_getprop_6cloess_13loess_outputs_fitted_values, 0, __pyx_k15, 0},
+  {"fitted_residuals", __pyx_getprop_6cloess_13loess_outputs_fitted_residuals, 0, __pyx_k16, 0},
+  {"pseudovalues", __pyx_getprop_6cloess_13loess_outputs_pseudovalues, 0, __pyx_k17, 0},
+  {"diagonal", __pyx_getprop_6cloess_13loess_outputs_diagonal, 0, __pyx_k18, 0},
+  {"robust", __pyx_getprop_6cloess_13loess_outputs_robust, 0, __pyx_k19, 0},
+  {"divisor", __pyx_getprop_6cloess_13loess_outputs_divisor, 0, __pyx_k20, 0},
+  {"enp", __pyx_getprop_6cloess_13loess_outputs_enp, 0, __pyx_k21, 0},
+  {"s", __pyx_getprop_6cloess_13loess_outputs_s, 0, __pyx_k22, 0},
+  {"one_delta", __pyx_getprop_6cloess_13loess_outputs_one_delta, 0, __pyx_k23, 0},
+  {"two_delta", __pyx_getprop_6cloess_13loess_outputs_two_delta, 0, __pyx_k24, 0},
+  {"trace_hat", __pyx_getprop_6cloess_13loess_outputs_trace_hat, 0, __pyx_k25, 0},
   {0, 0, 0, 0, 0}
 };
 
@@ -3809,7 +4805,7 @@
   &__pyx_tp_as_mapping_loess_outputs, /*tp_as_mapping*/
   0, /*tp_hash*/
   0, /*tp_call*/
-  0, /*tp_str*/
+  __pyx_f_6cloess_13loess_outputs___str__, /*tp_str*/
   0, /*tp_getattro*/
   0, /*tp_setattro*/
   &__pyx_tp_as_buffer_loess_outputs, /*tp_as_buffer*/
@@ -3822,7 +4818,7 @@
   0, /*tp_iter*/
   0, /*tp_iternext*/
   __pyx_methods_6cloess_loess_outputs, /*tp_methods*/
-  0, /*tp_members*/
+  __pyx_members_6cloess_loess_outputs, /*tp_members*/
   __pyx_getsets_6cloess_loess_outputs, /*tp_getset*/
   0, /*tp_base*/
   0, /*tp_dict*/
@@ -4002,20 +4998,20 @@
   0, /*tp_weaklist*/
 };
 
-static PyObject *__pyx_tp_new_6cloess_confidence_interval(PyTypeObject *t, PyObject *a, PyObject *k) {
+static PyObject *__pyx_tp_new_6cloess_conf_intervals(PyTypeObject *t, PyObject *a, PyObject *k) {
   PyObject *o = (*t->tp_alloc)(t, 0);
-  struct __pyx_obj_6cloess_confidence_interval *p = (struct __pyx_obj_6cloess_confidence_interval *)o;
+  struct __pyx_obj_6cloess_conf_intervals *p = (struct __pyx_obj_6cloess_conf_intervals *)o;
   p->nest = Py_None; Py_INCREF(Py_None);
   return o;
 }
 
-static void __pyx_tp_dealloc_6cloess_confidence_interval(PyObject *o) {
-  struct __pyx_obj_6cloess_confidence_interval *p = (struct __pyx_obj_6cloess_confidence_interval *)o;
+static void __pyx_tp_dealloc_6cloess_conf_intervals(PyObject *o) {
+  struct __pyx_obj_6cloess_conf_intervals *p = (struct __pyx_obj_6cloess_conf_intervals *)o;
   {
     PyObject *etype, *eval, *etb;
     PyErr_Fetch(&etype, &eval, &etb);
     ++o->ob_refcnt;
-    __pyx_f_6cloess_19confidence_interval___dealloc__(o);
+    __pyx_f_6cloess_14conf_intervals___dealloc__(o);
     if (PyErr_Occurred()) PyErr_WriteUnraisable(o);
     --o->ob_refcnt;
     PyErr_Restore(etype, eval, etb);
@@ -4024,46 +5020,46 @@
   (*o->ob_type->tp_free)(o);
 }
 
-static int __pyx_tp_traverse_6cloess_confidence_interval(PyObject *o, visitproc v, void *a) {
+static int __pyx_tp_traverse_6cloess_conf_intervals(PyObject *o, visitproc v, void *a) {
   int e;
-  struct __pyx_obj_6cloess_confidence_interval *p = (struct __pyx_obj_6cloess_confidence_interval *)o;
+  struct __pyx_obj_6cloess_conf_intervals *p = (struct __pyx_obj_6cloess_conf_intervals *)o;
   if (p->nest) {
     e = (*v)(p->nest, a); if (e) return e;
   }
   return 0;
 }
 
-static int __pyx_tp_clear_6cloess_confidence_interval(PyObject *o) {
-  struct __pyx_obj_6cloess_confidence_interval *p = (struct __pyx_obj_6cloess_confidence_interval *)o;
+static int __pyx_tp_clear_6cloess_conf_intervals(PyObject *o) {
+  struct __pyx_obj_6cloess_conf_intervals *p = (struct __pyx_obj_6cloess_conf_intervals *)o;
   Py_XDECREF(p->nest);
   p->nest = Py_None; Py_INCREF(Py_None);
   return 0;
 }
 
-static PyObject *__pyx_getprop_6cloess_19confidence_interval_fit(PyObject *o, void *x) {
-  return __pyx_f_6cloess_19confidence_interval_3fit___get__(o);
+static PyObject *__pyx_getprop_6cloess_14conf_intervals_fit(PyObject *o, void *x) {
+  return __pyx_f_6cloess_14conf_intervals_3fit___get__(o);
 }
 
-static PyObject *__pyx_getprop_6cloess_19confidence_interval_upper(PyObject *o, void *x) {
-  return __pyx_f_6cloess_19confidence_interval_5upper___get__(o);
+static PyObject *__pyx_getprop_6cloess_14conf_intervals_upper(PyObject *o, void *x) {
+  return __pyx_f_6cloess_14conf_intervals_5upper___get__(o);
 }
 
-static PyObject *__pyx_getprop_6cloess_19confidence_interval_lower(PyObject *o, void *x) {
-  return __pyx_f_6cloess_19confidence_interval_5lower___get__(o);
+static PyObject *__pyx_getprop_6cloess_14conf_intervals_lower(PyObject *o, void *x) {
+  return __pyx_f_6cloess_14conf_intervals_5lower___get__(o);
 }
 
-static struct PyMethodDef __pyx_methods_6cloess_confidence_interval[] = {
+static struct PyMethodDef __pyx_methods_6cloess_conf_intervals[] = {
   {0, 0, 0, 0}
 };
 
-static struct PyGetSetDef __pyx_getsets_6cloess_confidence_interval[] = {
-  {"fit", __pyx_getprop_6cloess_19confidence_interval_fit, 0, 0, 0},
-  {"upper", __pyx_getprop_6cloess_19confidence_interval_upper, 0, 0, 0},
-  {"lower", __pyx_getprop_6cloess_19confidence_interval_lower, 0, 0, 0},
+static struct PyGetSetDef __pyx_getsets_6cloess_conf_intervals[] = {
+  {"fit", __pyx_getprop_6cloess_14conf_intervals_fit, 0, __pyx_k26, 0},
+  {"upper", __pyx_getprop_6cloess_14conf_intervals_upper, 0, __pyx_k27, 0},
+  {"lower", __pyx_getprop_6cloess_14conf_intervals_lower, 0, __pyx_k28, 0},
   {0, 0, 0, 0, 0}
 };
 
-static PyNumberMethods __pyx_tp_as_number_confidence_interval = {
+static PyNumberMethods __pyx_tp_as_number_conf_intervals = {
   0, /*nb_add*/
   0, /*nb_subtract*/
   0, /*nb_multiply*/
@@ -4104,7 +5100,7 @@
   0, /*nb_inplace_true_divide*/
 };
 
-static PySequenceMethods __pyx_tp_as_sequence_confidence_interval = {
+static PySequenceMethods __pyx_tp_as_sequence_conf_intervals = {
   0, /*sq_length*/
   0, /*sq_concat*/
   0, /*sq_repeat*/
@@ -4117,51 +5113,51 @@
   0, /*sq_inplace_repeat*/
 };
 
-static PyMappingMethods __pyx_tp_as_mapping_confidence_interval = {
+static PyMappingMethods __pyx_tp_as_mapping_conf_intervals = {
   0, /*mp_length*/
   0, /*mp_subscript*/
   0, /*mp_ass_subscript*/
 };
 
-static PyBufferProcs __pyx_tp_as_buffer_confidence_interval = {
+static PyBufferProcs __pyx_tp_as_buffer_conf_intervals = {
   0, /*bf_getreadbuffer*/
   0, /*bf_getwritebuffer*/
   0, /*bf_getsegcount*/
   0, /*bf_getcharbuffer*/
 };
 
-PyTypeObject __pyx_type_6cloess_confidence_interval = {
+PyTypeObject __pyx_type_6cloess_conf_intervals = {
   PyObject_HEAD_INIT(0)
   0, /*ob_size*/
-  "cloess.confidence_interval", /*tp_name*/
-  sizeof(struct __pyx_obj_6cloess_confidence_interval), /*tp_basicsize*/
+  "cloess.conf_intervals", /*tp_name*/
+  sizeof(struct __pyx_obj_6cloess_conf_intervals), /*tp_basicsize*/
   0, /*tp_itemsize*/
-  __pyx_tp_dealloc_6cloess_confidence_interval, /*tp_dealloc*/
+  __pyx_tp_dealloc_6cloess_conf_intervals, /*tp_dealloc*/
   0, /*tp_print*/
   0, /*tp_getattr*/
   0, /*tp_setattr*/
   0, /*tp_compare*/
   0, /*tp_repr*/
-  &__pyx_tp_as_number_confidence_interval, /*tp_as_number*/
-  &__pyx_tp_as_sequence_confidence_interval, /*tp_as_sequence*/
-  &__pyx_tp_as_mapping_confidence_interval, /*tp_as_mapping*/
+  &__pyx_tp_as_number_conf_intervals, /*tp_as_number*/
+  &__pyx_tp_as_sequence_conf_intervals, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_conf_intervals, /*tp_as_mapping*/
   0, /*tp_hash*/
   0, /*tp_call*/
-  0, /*tp_str*/
+  __pyx_f_6cloess_14conf_intervals___str__, /*tp_str*/
   0, /*tp_getattro*/
   0, /*tp_setattro*/
-  &__pyx_tp_as_buffer_confidence_interval, /*tp_as_buffer*/
+  &__pyx_tp_as_buffer_conf_intervals, /*tp_as_buffer*/
   Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
   0, /*tp_doc*/
-  __pyx_tp_traverse_6cloess_confidence_interval, /*tp_traverse*/
-  __pyx_tp_clear_6cloess_confidence_interval, /*tp_clear*/
+  __pyx_tp_traverse_6cloess_conf_intervals, /*tp_traverse*/
+  __pyx_tp_clear_6cloess_conf_intervals, /*tp_clear*/
   0, /*tp_richcompare*/
   0, /*tp_weaklistoffset*/
   0, /*tp_iter*/
   0, /*tp_iternext*/
-  __pyx_methods_6cloess_confidence_interval, /*tp_methods*/
+  __pyx_methods_6cloess_conf_intervals, /*tp_methods*/
   0, /*tp_members*/
-  __pyx_getsets_6cloess_confidence_interval, /*tp_getset*/
+  __pyx_getsets_6cloess_conf_intervals, /*tp_getset*/
   0, /*tp_base*/
   0, /*tp_dict*/
   0, /*tp_descr_get*/
@@ -4169,7 +5165,7 @@
   0, /*tp_dictoffset*/
   0, /*tp_init*/
   0, /*tp_alloc*/
-  __pyx_tp_new_6cloess_confidence_interval, /*tp_new*/
+  __pyx_tp_new_6cloess_conf_intervals, /*tp_new*/
   0, /*tp_free*/
   0, /*tp_is_gc*/
   0, /*tp_bases*/
@@ -4182,7 +5178,7 @@
 static PyObject *__pyx_tp_new_6cloess_loess_predicted(PyTypeObject *t, PyObject *a, PyObject *k) {
   PyObject *o = (*t->tp_alloc)(t, 0);
   struct __pyx_obj_6cloess_loess_predicted *p = (struct __pyx_obj_6cloess_loess_predicted *)o;
-  p->conf_interval = ((struct __pyx_obj_6cloess_confidence_interval *)Py_None); Py_INCREF(Py_None);
+  p->confidence_intervals = ((struct __pyx_obj_6cloess_conf_intervals *)Py_None); Py_INCREF(Py_None);
   return o;
 }
 
@@ -4197,32 +5193,32 @@
     --o->ob_refcnt;
     PyErr_Restore(etype, eval, etb);
   }
-  Py_XDECREF(((PyObject *)p->conf_interval));
+  Py_XDECREF(((PyObject *)p->confidence_intervals));
   (*o->ob_type->tp_free)(o);
 }
 
 static int __pyx_tp_traverse_6cloess_loess_predicted(PyObject *o, visitproc v, void *a) {
   int e;
   struct __pyx_obj_6cloess_loess_predicted *p = (struct __pyx_obj_6cloess_loess_predicted *)o;
-  if (p->conf_interval) {
-    e = (*v)(((PyObject*)p->conf_interval), a); if (e) return e;
+  if (p->confidence_intervals) {
+    e = (*v)(((PyObject*)p->confidence_intervals), a); if (e) return e;
   }
   return 0;
 }
 
 static int __pyx_tp_clear_6cloess_loess_predicted(PyObject *o) {
   struct __pyx_obj_6cloess_loess_predicted *p = (struct __pyx_obj_6cloess_loess_predicted *)o;
-  Py_XDECREF(((PyObject *)p->conf_interval));
-  p->conf_interval = ((struct __pyx_obj_6cloess_confidence_interval *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(((PyObject *)p->confidence_intervals));
+  p->confidence_intervals = ((struct __pyx_obj_6cloess_conf_intervals *)Py_None); Py_INCREF(Py_None);
   return 0;
 }
 
-static PyObject *__pyx_getprop_6cloess_15loess_predicted_predicted(PyObject *o, void *x) {
-  return __pyx_f_6cloess_15loess_predicted_9predicted___get__(o);
+static PyObject *__pyx_getprop_6cloess_15loess_predicted_values(PyObject *o, void *x) {
+  return __pyx_f_6cloess_15loess_predicted_6values___get__(o);
 }
 
-static PyObject *__pyx_getprop_6cloess_15loess_predicted_predicted_stderr(PyObject *o, void *x) {
-  return __pyx_f_6cloess_15loess_predicted_16predicted_stderr___get__(o);
+static PyObject *__pyx_getprop_6cloess_15loess_predicted_stderr(PyObject *o, void *x) {
+  return __pyx_f_6cloess_15loess_predicted_6stderr___get__(o);
 }
 
 static PyObject *__pyx_getprop_6cloess_15loess_predicted_residual_scale(PyObject *o, void *x) {
@@ -4238,11 +5234,17 @@
   {0, 0, 0, 0}
 };
 
+static struct PyMemberDef __pyx_members_6cloess_loess_predicted[] = {
+  {"nest", T_LONG, offsetof(struct __pyx_obj_6cloess_loess_predicted, nest), READONLY, 0},
+  {"confidence_intervals", T_OBJECT, offsetof(struct __pyx_obj_6cloess_loess_predicted, confidence_intervals), READONLY, 0},
+  {0, 0, 0, 0, 0}
+};
+
 static struct PyGetSetDef __pyx_getsets_6cloess_loess_predicted[] = {
-  {"predicted", __pyx_getprop_6cloess_15loess_predicted_predicted, 0, 0, 0},
-  {"predicted_stderr", __pyx_getprop_6cloess_15loess_predicted_predicted_stderr, 0, 0, 0},
-  {"residual_scale", __pyx_getprop_6cloess_15loess_predicted_residual_scale, 0, 0, 0},
-  {"df", __pyx_getprop_6cloess_15loess_predicted_df, 0, 0, 0},
+  {"values", __pyx_getprop_6cloess_15loess_predicted_values, 0, __pyx_k29, 0},
+  {"stderr", __pyx_getprop_6cloess_15loess_predicted_stderr, 0, __pyx_k30, 0},
+  {"residual_scale", __pyx_getprop_6cloess_15loess_predicted_residual_scale, 0, __pyx_k31, 0},
+  {"df", __pyx_getprop_6cloess_15loess_predicted_df, 0, __pyx_k32, 0},
   {0, 0, 0, 0, 0}
 };
 
@@ -4330,7 +5332,7 @@
   &__pyx_tp_as_mapping_loess_predicted, /*tp_as_mapping*/
   0, /*tp_hash*/
   0, /*tp_call*/
-  0, /*tp_str*/
+  __pyx_f_6cloess_15loess_predicted___str__, /*tp_str*/
   0, /*tp_getattro*/
   0, /*tp_setattro*/
   &__pyx_tp_as_buffer_loess_predicted, /*tp_as_buffer*/
@@ -4343,7 +5345,7 @@
   0, /*tp_iter*/
   0, /*tp_iternext*/
   __pyx_methods_6cloess_loess_predicted, /*tp_methods*/
-  0, /*tp_members*/
+  __pyx_members_6cloess_loess_predicted, /*tp_members*/
   __pyx_getsets_6cloess_loess_predicted, /*tp_getset*/
   0, /*tp_base*/
   0, /*tp_dict*/
@@ -4376,6 +5378,15 @@
 
 static void __pyx_tp_dealloc_6cloess_loess(PyObject *o) {
   struct __pyx_obj_6cloess_loess *p = (struct __pyx_obj_6cloess_loess *)o;
+  {
+    PyObject *etype, *eval, *etb;
+    PyErr_Fetch(&etype, &eval, &etb);
+    ++o->ob_refcnt;
+    __pyx_f_6cloess_5loess___dealloc__(o);
+    if (PyErr_Occurred()) PyErr_WriteUnraisable(o);
+    --o->ob_refcnt;
+    PyErr_Restore(etype, eval, etb);
+  }
   Py_XDECREF(((PyObject *)p->inputs));
   Py_XDECREF(((PyObject *)p->model));
   Py_XDECREF(((PyObject *)p->control));
@@ -4440,6 +5451,8 @@
   {"kd_tree", T_OBJECT, offsetof(struct __pyx_obj_6cloess_loess, kd_tree), READONLY, 0},
   {"outputs", T_OBJECT, offsetof(struct __pyx_obj_6cloess_loess, outputs), READONLY, 0},
   {"predicted", T_OBJECT, offsetof(struct __pyx_obj_6cloess_loess, predicted), READONLY, 0},
+  {"nobs", T_LONG, offsetof(struct __pyx_obj_6cloess_loess, nobs), 0, 0},
+  {"npar", T_LONG, offsetof(struct __pyx_obj_6cloess_loess, npar), 0, 0},
   {0, 0, 0, 0, 0}
 };
 
@@ -4577,62 +5590,67 @@
   if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2; goto __pyx_L1;};
   if (__Pyx_InternStrings(__pyx_intern_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2; goto __pyx_L1;};
   if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2; goto __pyx_L1;};
-  if (PyType_Ready(&__pyx_type_6cloess_loess_inputs) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; goto __pyx_L1;}
-  if (PyObject_SetAttrString(__pyx_m, "loess_inputs", (PyObject *)&__pyx_type_6cloess_loess_inputs) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; goto __pyx_L1;}
+  if (PyType_Ready(&__pyx_type_6cloess_loess_inputs) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "loess_inputs", (PyObject *)&__pyx_type_6cloess_loess_inputs) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; goto __pyx_L1;}
   __pyx_ptype_6cloess_loess_inputs = &__pyx_type_6cloess_loess_inputs;
-  if (PyType_Ready(&__pyx_type_6cloess_loess_control) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; goto __pyx_L1;}
-  if (PyObject_SetAttrString(__pyx_m, "loess_control", (PyObject *)&__pyx_type_6cloess_loess_control) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; goto __pyx_L1;}
+  if (PyType_Ready(&__pyx_type_6cloess_loess_control) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "loess_control", (PyObject *)&__pyx_type_6cloess_loess_control) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; goto __pyx_L1;}
   __pyx_ptype_6cloess_loess_control = &__pyx_type_6cloess_loess_control;
-  if (PyType_Ready(&__pyx_type_6cloess_loess_kd_tree) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; goto __pyx_L1;}
-  if (PyObject_SetAttrString(__pyx_m, "loess_kd_tree", (PyObject *)&__pyx_type_6cloess_loess_kd_tree) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; goto __pyx_L1;}
+  if (PyType_Ready(&__pyx_type_6cloess_loess_kd_tree) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "loess_kd_tree", (PyObject *)&__pyx_type_6cloess_loess_kd_tree) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; goto __pyx_L1;}
   __pyx_ptype_6cloess_loess_kd_tree = &__pyx_type_6cloess_loess_kd_tree;
-  if (PyType_Ready(&__pyx_type_6cloess_loess_model) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; goto __pyx_L1;}
-  if (PyObject_SetAttrString(__pyx_m, "loess_model", (PyObject *)&__pyx_type_6cloess_loess_model) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; goto __pyx_L1;}
+  if (PyType_Ready(&__pyx_type_6cloess_loess_model) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "loess_model", (PyObject *)&__pyx_type_6cloess_loess_model) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; goto __pyx_L1;}
   __pyx_ptype_6cloess_loess_model = &__pyx_type_6cloess_loess_model;
-  if (PyType_Ready(&__pyx_type_6cloess_loess_outputs) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; goto __pyx_L1;}
-  if (PyObject_SetAttrString(__pyx_m, "loess_outputs", (PyObject *)&__pyx_type_6cloess_loess_outputs) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; goto __pyx_L1;}
+  if (PyType_Ready(&__pyx_type_6cloess_loess_outputs) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "loess_outputs", (PyObject *)&__pyx_type_6cloess_loess_outputs) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; goto __pyx_L1;}
   __pyx_ptype_6cloess_loess_outputs = &__pyx_type_6cloess_loess_outputs;
-  if (PyType_Ready(&__pyx_type_6cloess_loess_anova) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 333; goto __pyx_L1;}
-  if (PyObject_SetAttrString(__pyx_m, "loess_anova", (PyObject *)&__pyx_type_6cloess_loess_anova) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 333; goto __pyx_L1;}
+  if (PyType_Ready(&__pyx_type_6cloess_loess_anova) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 604; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "loess_anova", (PyObject *)&__pyx_type_6cloess_loess_anova) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 604; goto __pyx_L1;}
   __pyx_ptype_6cloess_loess_anova = &__pyx_type_6cloess_loess_anova;
-  __pyx_type_6cloess_confidence_interval.tp_free = _PyObject_GC_Del;
-  if (PyType_Ready(&__pyx_type_6cloess_confidence_interval) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; goto __pyx_L1;}
-  if (PyObject_SetAttrString(__pyx_m, "confidence_interval", (PyObject *)&__pyx_type_6cloess_confidence_interval) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; goto __pyx_L1;}
-  __pyx_ptype_6cloess_confidence_interval = &__pyx_type_6cloess_confidence_interval;
+  __pyx_type_6cloess_conf_intervals.tp_free = _PyObject_GC_Del;
+  if (PyType_Ready(&__pyx_type_6cloess_conf_intervals) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 627; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "conf_intervals", (PyObject *)&__pyx_type_6cloess_conf_intervals) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 627; goto __pyx_L1;}
+  __pyx_ptype_6cloess_conf_intervals = &__pyx_type_6cloess_conf_intervals;
   __pyx_type_6cloess_loess_predicted.tp_free = _PyObject_GC_Del;
-  if (PyType_Ready(&__pyx_type_6cloess_loess_predicted) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 378; goto __pyx_L1;}
-  if (PyObject_SetAttrString(__pyx_m, "loess_predicted", (PyObject *)&__pyx_type_6cloess_loess_predicted) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 378; goto __pyx_L1;}
+  if (PyType_Ready(&__pyx_type_6cloess_loess_predicted) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 667; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "loess_predicted", (PyObject *)&__pyx_type_6cloess_loess_predicted) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 667; goto __pyx_L1;}
   __pyx_ptype_6cloess_loess_predicted = &__pyx_type_6cloess_loess_predicted;
   __pyx_type_6cloess_loess.tp_free = _PyObject_GC_Del;
-  if (PyType_Ready(&__pyx_type_6cloess_loess) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 414; goto __pyx_L1;}
-  if (PyObject_SetAttrString(__pyx_m, "loess", (PyObject *)&__pyx_type_6cloess_loess) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 414; goto __pyx_L1;}
+  if (PyType_Ready(&__pyx_type_6cloess_loess) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 743; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "loess", (PyObject *)&__pyx_type_6cloess_loess) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 743; goto __pyx_L1;}
   __pyx_ptype_6cloess_loess = &__pyx_type_6cloess_loess;
   __pyx_ptype_7c_numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr)); if (!__pyx_ptype_7c_numpy_dtype) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 76; goto __pyx_L1;}
   __pyx_ptype_7c_numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject)); if (!__pyx_ptype_7c_numpy_ndarray) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 81; goto __pyx_L1;}
   __pyx_ptype_7c_numpy_flatiter = __Pyx_ImportType("numpy", "flatiter", sizeof(PyArrayIterObject)); if (!__pyx_ptype_7c_numpy_flatiter) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 90; goto __pyx_L1;}
   __pyx_ptype_7c_numpy_broadcast = __Pyx_ImportType("numpy", "broadcast", sizeof(PyArrayMultiIterObject)); if (!__pyx_ptype_7c_numpy_broadcast) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 96; goto __pyx_L1;}
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":7 */
-  __pyx_1 = __Pyx_Import(__pyx_n_numpy, 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; goto __pyx_L1;}
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_numpy, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; goto __pyx_L1;}
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":8 */
+  __pyx_1 = __Pyx_Import(__pyx_n_numpy, 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; goto __pyx_L1;}
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_numpy, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":14 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":15 */
   import_array();
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":402 */
-  __pyx_1 = PyFloat_FromDouble(0.95); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 402; goto __pyx_L1;}
-  __pyx_k7 = __pyx_1;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":48 */
+  __pyx_k34;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":710 */
+  __pyx_1 = PyFloat_FromDouble(0.95); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 710; goto __pyx_L1;}
+  __pyx_k35 = __pyx_1;
   __pyx_1 = 0;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":423 */
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":753 */
   Py_INCREF(Py_None);
-  __pyx_k8 = Py_None;
+  __pyx_k36 = Py_None;
 
-  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":466 */
-  __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_False); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 466; goto __pyx_L1;}
-  __pyx_k9 = __pyx_2;
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":821 */
+  __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_False); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 821; goto __pyx_L1;}
+  __pyx_k37 = __pyx_2;
   __pyx_2 = 0;
+
+  /* "/home/backtopop/workspace/pyloess_c/src/cloess.pyx":854 */
   return;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);
@@ -4835,6 +5853,32 @@
     return;
 }
 
+static void __Pyx_UnpackError(void) {
+    PyErr_SetString(PyExc_ValueError, "unpack sequence of wrong size");
+}
+
+static PyObject *__Pyx_UnpackItem(PyObject *iter) {
+    PyObject *item;
+    if (!(item = PyIter_Next(iter))) {
+        if (!PyErr_Occurred())
+            __Pyx_UnpackError();
+    }
+    return item;
+}
+
+static int __Pyx_EndUnpack(PyObject *iter) {
+    PyObject *item;
+    if ((item = PyIter_Next(iter))) {
+        Py_DECREF(item);
+        __Pyx_UnpackError();
+        return -1;
+    }
+    else if (!PyErr_Occurred())
+        return 0;
+    else
+        return -1;
+}
+
 static PyObject *__Pyx_GetStdout(void) {
     PyObject *f = PySys_GetObject("stdout");
     if (!f) {

Modified: trunk/Lib/sandbox/pyloess/sandbox/src/cloess.pyx
===================================================================
--- trunk/Lib/sandbox/pyloess/sandbox/src/cloess.pyx	2007-03-14 16:52:59 UTC (rev 2848)
+++ trunk/Lib/sandbox/pyloess/sandbox/src/cloess.pyx	2007-03-16 20:42:51 UTC (rev 2849)
@@ -3,7 +3,8 @@
 cimport c_numpy
 from c_numpy cimport ndarray, npy_intp, \
     PyArray_SIZE, PyArray_EMPTY, PyArray_FROMANY, \
-    NPY_INT, NPY_DOUBLE, NPY_OWNDATA, NPY_ALIGNED, NPY_FORTRAN
+    NPY_INT, NPY_DOUBLE, NPY_OWNDATA, NPY_ALIGNED, NPY_FORTRAN, \
+    PyArray_SimpleNewFromData
 import numpy
 
 #narray = _N.array
@@ -16,29 +17,151 @@
 cimport c_loess
 
 
-cdef floatarray_from_data(rows, cols, double *data):
+cdef floatarray_from_data(int rows, int cols, double *data):
     cdef ndarray a_ndr
-    cdef double *a_dat
-    a_ndr = numpy.empty((rows*cols,), dtype=numpy.float)
-    a_dat = <double *>a_ndr.data
-    for i from 0 <= i < a_ndr.size:
-        a_dat[i] = data[i]
+    cdef npy_intp size
+    size = rows*cols
+    a_ndr = <object>PyArray_SimpleNewFromData(1, &size, NPY_DOUBLE, data)
+#    a_ndr = numpy.empty((rows*cols,), dtype=numpy.float)
+#    a_dat = <double *>a_ndr.data
+#    for i from 0 <= i < a_ndr.size:
+#        a_dat[i] = data[i]
     if cols > 1:
         a_ndr.shape = (rows, cols)
     return a_ndr
 
-cdef boolarray_from_data(rows, cols, int *data):
+cdef boolarray_from_data(int rows, int cols, int *data):
     cdef ndarray a_ndr
-    cdef int *a_dat
-    a_ndr = numpy.empty((rows*cols,), dtype=numpy.int)
-    a_dat = <int *>a_ndr.data
-    for i from 0 <= i < a_ndr.size:
-        a_dat[i] = data[i]
+    cdef npy_intp size
+    size = rows*cols
+#    cdef int *a_dat
+#    a_ndr = numpy.empty((rows*cols,), dtype=numpy.int)
+    a_ndr = <object>PyArray_SimpleNewFromData(1, &size, NPY_DOUBLE, data)
+#    a_dat = <int *>a_ndr.data
+#    for i from 0 <= i < a_ndr.size:
+#        a_dat[i] = data[i]
     if cols > 1:
         a_ndr.shape = (rows, cols)
     return a_ndr.astype(numpy.bool)
 
-    
+
+"""
+:Keywords:
+    x : ndarray
+        A (n,p) ndarray of independent variables, with n the number of observations
+        and p the number of variables.
+    y : ndarray
+        A (n,) ndarray of observations
+    weights : ndarray
+        A (n,) ndarray of weights to be given to individual observations in the 
+        sum of squared residuals that forms the local fitting criterion. If not
+        None, the weights should be non negative. If the different observations
+        have non-equal variances, the weights should be inversely proportional 
+        to the variances.
+        By default, an unweighted fit is carried out (all the weights are one).
+    surface : string ["interpolate"]
+        Determines whether the fitted surface is computed directly at all points
+        ("direct") or whether an interpolation method is used ("interpolate").
+        The default ("interpolate") is what most users should use unless special 
+        circumstances warrant.
+    statistics : string ["approximate"]
+        Determines whether the statistical quantities are computed exactly 
+        ("exact") or approximately ("approximate"). "exact" should only be used 
+        for testing the approximation in statistical development and is not meant 
+        for routine usage because computation time can be horrendous.
+    trace_hat : string ["wait.to.decide"]
+        Determines how the trace of the hat matrix should be computed. The hat
+        matrix is used in the computation of the statistical quantities. 
+        If "exact", an exact computation is done; this could be slow when the
+        number of observations n becomes large. If "wait.to.decide" is selected, 
+        then a default is "exact" for n < 500 and "approximate" otherwise. 
+        This option is only useful when the fitted surface is interpolated. If  
+        surface is "exact", an exact computation is always done for the trace. 
+        Setting trace_hat to "approximate" for large dataset will substantially 
+        reduce the computation time.
+    iterations : integer
+        Number of iterations of the robust fitting method. If the family is 
+        "gaussian", the number of iterations is set to 0.
+    cell : integer
+        Maximum cell size of the kd-tree. Suppose k = floor(n*cell*span),
+        where n is the number of observations, and span the smoothing parameter.
+        Then, a cell is further divided if the number of observations within it 
+        is greater than or equal to k. This option is only used if the surface 
+        is interpolated.
+    span : float [0.75]
+        Smoothing factor, as a fraction of the number of points to take into
+        account. 
+    degree : integer [2]
+        Overall degree of locally-fitted polynomial. 1 is locally-linear 
+        fitting and 2 is locally-quadratic fitting.  Degree should be 2 at most.
+    normalize : boolean [True]
+        Determines whether the independent variables should be normalized.  
+        If True, the normalization is performed by setting the 10% trimmed 
+        standard deviation to one. If False, no normalization is carried out. 
+        This option is only useful for more than one variable. For spatial
+        coordinates predictors or variables with a common scale, it should be 
+        set to False.
+    family : string ["gaussian"]
+        Determines the assumed distribution of the errors. The values are 
+        "gaussian" or "symmetric". If "gaussian" is selected, the fit is 
+        performed with least-squares. If "symmetric" is selected, the fit
+        is performed robustly by redescending M-estimators.
+    parametric_flags : sequence [ [False]*p ]
+        Indicates which independent variables should be conditionally-parametric
+       (if there are two or more independent variables). The argument should 
+       be a sequence of booleans, with the same size as the number of independent 
+       variables, specified in the order of the predictor group ordered in x. 
+    drop_square : sequence [ [False]* p]
+        When there are two or more independent variables and when a 2nd order
+        polynomial is used, "drop_square_flags" specifies those numeric predictors 
+        whose squares should be dropped from the set of fitting variables. 
+        The method of specification is the same as for parametric.  
+        
+:Outputs:
+    fitted_values : ndarray
+        The (n,) ndarray of fitted values.
+    fitted_residuals : ndarray
+        The (n,) ndarray of fitted residuals (observations - fitted values).
+    enp : float
+        Equivalent number of parameters.
+    s : float
+        Estimate of the scale of residuals.
+    one_delta: float
+        Statistical parameter used in the computation of standard errors.
+    two_delta : float
+        Statistical parameter used in the computation of standard errors.
+    pseudovalues : ndarray
+        The (n,) ndarray of adjusted values of the response when robust estimation 
+        is used.
+    trace_hat : float    
+        Trace of the operator hat matrix.
+    diagonal :
+        Diagonal of the operator hat matrix.
+    robust : ndarray
+        The (n,) ndarray of robustness weights for robust fitting.
+    divisor : ndarray
+        The (p,) array of normalization divisors for numeric predictors.
+        
+
+    newdata : ndarray
+        The (m,p) array of independent variables where the surface must be estimated.
+    values : ndarray
+        The (m,) ndarray of loess values evaluated at newdata
+    stderr : ndarray
+        The (m,) ndarray of the estimates of the standard error on the estimated
+        values.
+    residual_scale : float
+        Estimate of the scale of the residuals
+    df : integer
+        Degrees of freedom of the t-distribution used to compute pointwise 
+        confidence intervals for the evaluated surface.
+    nest : integer
+        Number of new observations.
+       
+        
+"""
+
+
 #####---------------------------------------------------------------------------
 #---- ---- loess model ---
 #####---------------------------------------------------------------------------
@@ -54,7 +177,13 @@
             return floatarray_from_data(self._base.n, 1, self._base.y)
     #.........    
     property weights:
-        "Weights"
+        """A (n,) ndarray of weights to be given to individual observations in the 
+        sum of squared residuals that forms the local fitting criterion. If not
+        None, the weights should be non negative. If the different observations
+        have non-equal variances, the weights should be inversely proportional 
+        to the variances.
+        By default, an unweighted fit is carried out (all the weights are one).
+        """
         def __get__(self):
             return floatarray_from_data(self._base.n, 1, self._base.weights)
         
@@ -71,7 +200,7 @@
         def __get__(self):
             return self._base.n
     #.........
-    property nvar:
+    property npar:
         "Number of independent variables."
         def __get__(self):
             return self._base.p
@@ -83,36 +212,92 @@
     cdef c_loess.c_loess_control *_base
     #.........    
     property surface:
+        """
+    surface : string ["interpolate"]
+        Determines whether the fitted surface is computed directly at all points
+        ("direct") or whether an interpolation method is used ("interpolate").
+        The default ("interpolate") is what most users should use unless special 
+        circumstances warrant.
+        """
         def __get__(self):
             return self._base.surface
         def __set__(self, surface):
-            self._base.surface = surface
+            if surface.lower() not in ('interpolate', 'direct'):
+                raise ValueError("Invalid value for the 'surface' argument: "+
+                                 "should be in ('interpolate', 'direct').")
+            tmpx = surface.lower()
+            self._base.surface = tmpx
     #.........
     property statistics:
+        """
+    statistics : string ["approximate"]
+        Determines whether the statistical quantities are computed exactly 
+        ("exact") or approximately ("approximate"). "exact" should only be used 
+        for testing the approximation in statistical development and is not meant 
+        for routine usage because computation time can be horrendous.
+        """
         def __get__(self):
             return self._base.statistics
         def __set__(self, statistics):
-            self._base.statistics = statistics
+            if statistics.lower() not in ('approximate', 'exact'):
+                raise ValueError("Invalid value for the 'statistics' argument: "\
+                                 "should be in ('approximate', 'exact').")
+            tmpx = statistics.lower()
+            self._base.statistics = tmpx
     #.........
     property trace_hat:
+        """
+    trace_hat : string ["wait.to.decide"]
+        Determines how the trace of the hat matrix should be computed. The hat
+        matrix is used in the computation of the statistical quantities. 
+        If "exact", an exact computation is done; this could be slow when the
+        number of observations n becomes large. If "wait.to.decide" is selected, 
+        then a default is "exact" for n < 500 and "approximate" otherwise. 
+        This option is only useful when the fitted surface is interpolated. If  
+        surface is "exact", an exact computation is always done for the trace. 
+        Setting trace_hat to "approximate" for large dataset will substantially 
+        reduce the computation time.
+        """
         def __get__(self):
             return self._base.trace_hat
         def __set__(self, trace_hat):
-            self._base.trace_hat = trace_hat
+            if trace_hat.lower() not in ('approximate', 'exact'):
+                raise ValueError("Invalid value for the 'trace_hat' argument: "\
+                                 "should be in ('approximate', 'exact').")
+            tmpx = trace_hat.lower()
+            self._base.trace_hat = tmpx
     #.........
     property iterations:
+        """
+    iterations : integer
+        Number of iterations of the robust fitting method. If the family is 
+        "gaussian", the number of iterations is set to 0.
+        """
         def __get__(self):
             return self._base.iterations
         def __set__(self, iterations):
+            if iterations < 0:
+                raise ValueError("Invalid number of iterations: should be positive")
             self._base.iterations = iterations
     #.........
     property cell:
+        """
+    cell : integer
+        Maximum cell size of the kd-tree. Suppose k = floor(n*cell*span),
+        where n is the number of observations, and span the smoothing parameter.
+        Then, a cell is further divided if the number of observations within it 
+        is greater than or equal to k. This option is only used if the surface 
+        is interpolated.
+        """     
         def __get__(self):
             return self._base.cell
         def __set__(self, cell):
+            if cell <= 0:
+                raise ValueError("Invalid value for the cell argument: should be positive")
             self._base.cell = cell
     #.........
     def update(self, **cellargs):
+        """Updates several parameters at once."""
         surface = cellargs.get('surface', None)
         if surface is not None:
             self.surface = surface
@@ -179,48 +364,94 @@
     cdef long npar
     #.........
     property span:
+        """Smoothing factor, as a fraction of the number of points to take into
+    account. By default, span=0.75."""
         def __get__(self):
             return self._base.span
         def __set__(self, span):
+            if span <= 0. or span > 1.:
+                raise ValueError("Span should be between 0 and 1!")
             self._base.span = span
     #.........
     property degree:
+        """
+    degree : integer [2]
+        Overall degree of locally-fitted polynomial. 1 is locally-linear 
+        fitting and 2 is locally-quadratic fitting.  Degree should be 2 at most.
+        """
         def __get__(self):
             return self._base.degree
+        def __set__(self, degree):
+            if degree < 0 or degree > 2:
+                raise ValueError("Degree should be between 0 and 2!")
     #.........
     property normalize:
-        "Normalize the variables. Only useful if more than one variable..."
+        """
+    normalize : boolean [True]
+        Determines whether the independent variables should be normalized.  
+        If True, the normalization is performed by setting the 10% trimmed 
+        standard deviation to one. If False, no normalization is carried out. 
+        This option is only useful for more than one variable. For spatial
+        coordinates predictors or variables with a common scale, it should be 
+        set to False.
+        """
         def __get__(self):
             return bool(self._base.normalize)
         def __set__(self, normalize):
             self._base.normalize = normalize
     #.........
     property family:
+        """
+    family : string ["gaussian"]
+        Determines the assumed distribution of the errors. The values are 
+        "gaussian" or "symmetric". If "gaussian" is selected, the fit is 
+        performed with least-squares. If "symmetric" is selected, the fit
+        is performed robustly by redescending M-estimators.
+        """    
         def __get__(self):
             return self._base.family
+        def __set__(self, family):
+            if family.lower() not in ('symmetric', 'gaussian'):
+                raise ValueError("Invalid value for the 'family' argument: "\
+                                 "should be in ('symmetric', 'gaussian').")
+            self._base.family = family
     #.........
     property parametric_flags:
+        """
+    parametric_flags : sequence [ [False]*p ]
+        Indicates which independent variables should be conditionally-parametric
+       (if there are two or more independent variables). The argument should 
+       be a sequence of booleans, with the same size as the number of independent 
+       variables, specified in the order of the predictor group ordered in x. 
+        """
         def __get__(self):
-            return boolarray_from_data(8, 1, self._base.parametric)
+            return boolarray_from_data(self.npar, 1, self._base.parametric)
         def __set__(self, paramf):
             cdef ndarray p_ndr
             cdef long *p_dat
             cdef int i
-            p_ndr = <ndarray>PyArray_FROMANY(paramf, NPY_LONG, 1, 1, NPY_OWNDATA)
+            p_ndr = numpy.array(paramf, copy=False, subok=True, dtype=numpy.int)
             p_dat = <long *>p_ndr.data
-            for i in 0 <= i < max(8, p_ndr.size):
+            for i from 0 <= i < min(self.npar, p_ndr.size - 1):
                 self._base.parametric[i] = p_dat[i]
     #.........
     property drop_square_flags:
+        """
+    drop_square : sequence [ [False]* p]
+        When there are two or more independent variables and when a 2nd order
+        polynomial is used, "drop_square_flags" specifies those numeric predictors 
+        whose squares should be dropped from the set of fitting variables. 
+        The method of specification is the same as for parametric.  
+        """
         def __get__(self):
-            return boolarray_from_data(8, 1, self._base.drop_square)
+            return boolarray_from_data(self.npar, 1, self._base.drop_square)
         def __set__(self, drop_sq):
             cdef ndarray d_ndr
             cdef long *d_dat
             cdef int i
-            d_ndr = <ndarray>PyArray_FROMANY(drop_sq, NPY_LONG, 1, 1, NPY_OWNDATA)
+            d_ndr = numpy.array(drop_sq, copy=False, subok=True, dtype=numpy.int)
             d_dat = <long *>d_ndr.data
-            for i in 0 <= i < max(8, d_ndr.size):
+            for i from 0 <= i < min(self.npar, d_ndr.size - 1):
                 self._base.drop_square[i] = d_dat[i]
     #........
     def update(self, **modelargs):
@@ -267,64 +498,104 @@
 #####---------------------------------------------------------------------------
 cdef class loess_outputs:
     cdef c_loess.c_loess_outputs *_base
-    cdef long nobs
+    cdef long nobs, npar
+    cdef readonly int activated
     #........
-    property fitted_values:
+    property fitted_values:    
+        """
+    fitted_values : ndarray
+        The (n,) ndarray of fitted values.
+        """
         def __get__(self):
             return floatarray_from_data(self.nobs, 1, self._base.fitted_values)
     #.........
     property fitted_residuals:
+        """
+    fitted_residuals : ndarray
+        The (n,) ndarray of fitted residuals (observations - fitted values).
+        """
         def __get__(self):
             return floatarray_from_data(self.nobs, 1, self._base.fitted_residuals)
     #.........
     property pseudovalues:
+        """
+    pseudovalues : ndarray
+        The (n,) ndarray of adjusted values of the response when robust estimation 
+        is used.
+        """        
         def __get__(self):
             return floatarray_from_data(self.nobs, 1, self._base.pseudovalues)
     #.........
     property diagonal:
+        """
+    diagonal :
+        Diagonal of the operator hat matrix.
+        """    
         def __get__(self):
             return floatarray_from_data(self.nobs, 1, self._base.diagonal)
     #.........
     property robust:
+        """
+    robust : ndarray
+        The (n,) ndarray of robustness weights for robust fitting.
+        """
         def __get__(self):
             return floatarray_from_data(self.nobs, 1, self._base.robust)
     #.........
     property divisor:
+        "Equivalent number of parameters."
         def __get__(self):
-            return floatarray_from_data(self.nobs, 1, self._base.divisor)
+            return floatarray_from_data(self.nvar, 1, self._base.divisor)
     #.........    
     property enp:
-        "Equivalent number of parameters."
+        """
+    enp : float
+        Equivalent number of parameters.
+        """
         def __get__(self):
             return self._base.enp
     #.........
     property s:
-#        ""
+        """
+    s : float
+        Estimate of the scale of residuals.
+        """
         def __get__(self):
             return self._base.s
     #.........
     property one_delta:
-#        ""
+        """
+    one_delta: float
+        Statistical parameter used in the computation of standard errors.
+        """
         def __get__(self):
-            return self._base.one_delta
+            return self._base.one_delta 
     #.........
     property two_delta:
-#        ""
+        """
+    two_delta : float
+        Statistical parameter used in the computation of standard errors.
+       """
         def __get__(self):
             return self._base.two_delta
     #.........
     property trace_hat:
-#        ""
+        """
+    trace_hat : float    
+        Trace of the operator hat matrix.
+        """
         def __get__(self):
-            return self._base.trace_hat
-#    #.........
-#    def __str__(self):
-#        strg = ["Outputs          :",
-#                "enp       : %s" % self.enp,
-#                "s : %s" % self.s,
-#                "Deltas        : %s/%s" % (self.one_delta, self.two_delta),
-#                "Divisor    : %s" % self.divisor,]
-#        return '\n'.join(strg)
+            return self._base.trace_hat    #        ""
+    #.........
+    def __str__(self):
+        strg = ["Outputs................",
+                "Fitted values         : %s\n" % self.fitted_values,
+                "Fitted residuals      : %s\n" % self.fitted_residuals,
+                "Eqv. nb of parameters : %s" % self.enp,
+                "Residual error        : %s" % self.s,
+                "Deltas                : %s - %s" % (self.one_delta, self.two_delta),
+                "Normalization factors : %s" % self.divisor,]
+        return '\n'.join(strg)
 
 
 #####---------------------------------------------------------------------------
@@ -353,59 +624,117 @@
 #####---------------------------------------------------------------------------
 #---- ---- loess confidence ---
 #####---------------------------------------------------------------------------
-cdef class confidence_interval:
-    cdef c_loess.c_conf_inv *_base
+cdef class conf_intervals:
+    cdef c_loess.c_conf_inv _base
     cdef nest
     #.........
     def __dealloc__(self):
         c_loess.pw_free_mem(self)
     #.........
     property fit:
+        """
+    fit : ndarray
+        The (m,) ndarray of estimated values
+        """
         def __get__(self):
-            return floatarray_from_data(nest, 1, self._base.fit)
+            return floatarray_from_data(self.nest, 1, self._base.fit)
     #.........
     property upper:
+        """
+    upper : ndarray
+        The (m,) ndarray of the upper limits of the pointwise confidence intervals.
+        """  
         def __get__(self):
-            return floatarray_from_data(nest, 1, self._base.upper)
+            return floatarray_from_data(self.nest, 1, self._base.upper)
     #.........
-    property lower:
+    property lower:  
+        """
+    lower : ndarray
+        The (m,) ndarray of the lower limits of the pointwise confidence intervals.
+        """
         def __get__(self):
-            return floatarray_from_data(nest, 1, self._base.lower)
+            return floatarray_from_data(self.nest, 1, self._base.lower)
+    #.........
+    def __str__(self):
+        cdef ndarray tmp_ndr
+        tmp_ndr = numpy.r_[[self.lower,self.fit,self.upper]].T
+        return "Confidence intervals....\nLower b./ fit / upper b.\n%s" % \
+               tmp_ndr 
 
 #####---------------------------------------------------------------------------
 #---- ---- loess predictions ---
 #####---------------------------------------------------------------------------
 cdef class loess_predicted:
-    cdef c_loess.c_prediction *_base
-    cdef long nest
-    cdef confidence_interval conf_interval
+    cdef c_loess.c_prediction _base
+    cdef readonly long nest
+    cdef readonly conf_intervals confidence_intervals
+
     #.........
     def __dealloc__(self):
-        c_loess.pred_free_mem(self._base)
+        c_loess.pred_free_mem(&self._base)      
     #.........
-    property predicted:
+    property values:
+        """
+    values : ndarray
+        The (m,) ndarray of loess values evaluated at newdata
+        """
         def __get__(self):
-            return floatarray_from_data(nest, 1, self._base.fit)
+            return floatarray_from_data(self.nest, 1, self._base.fit)
     #.........
-    property predicted_stderr:
+    property stderr:
+        """
+    stderr : ndarray
+        The (m,) ndarray of the estimates of the standard error on the estimated
+        values.
+        """
         def __get__(self):
-            return floatarray_from_data(nest, 1, self._base.se_fit)
+            return floatarray_from_data(self.nest, 1, self._base.se_fit)
     #.........
     property residual_scale:
+        """
+    residual_scale : float
+        Estimate of the scale of the residuals
+        """
         def __get__(self):
-            return self.residual_scale
+            return self._base.residual_scale
     #.........
     property df:
+        """
+    df : integer
+        Degrees of freedom of the t-distribution used to compute pointwise 
+        confidence intervals for the evaluated surface.
+        """
         def __get__(self):
-            return self.df
+            return self._base.df
     #.........
     def confidence(self, coverage=0.95):
-        """
+        """Returns the pointwise confidence intervals for each predicted values,
+at the given confidence interval coverage.
+        
+:Parameters:
     coverage : float
-        Confidence level of the confidence intervals limits as a fraction.
+        Confidence level of the confidence intervals limits, as a fraction.
         """
-        c_loess.pointwise(self._base, self.nest, coverage,
-                          self.conf_interval._base)
+        cdef c_loess.c_conf_inv _conf_intv
+        if coverage < 0.5:
+            coverage = 1. - coverage 
+        if coverage > 1. :
+            raise ValueError("The coverage precentage should be between 0 and 1!")
+        c_loess.pointwise(&self._base, self.nest, coverage, &_conf_intv)
+        self.confidence_intervals = conf_intervals()
+        self.confidence_intervals._base = _conf_intv
+        self.confidence_intervals.nest = self.nest
+        return self.confidence_intervals
+    #.........
+    def __str__(self):
+        strg = ["Outputs................",
+                "Predicted values      : %s\n" % self.values,
+                "Predicted std error   : %s\n" % self.stderr,
+                "Residual scale        : %s" % self.residual_scale,
+                "Degrees of freedom    : %s" % self.df,
+#                "Confidence intervals  : %s" % self.confidence,
+                ]
+        return '\n'.join(strg)
     
 
 #####---------------------------------------------------------------------------
@@ -419,19 +748,30 @@
     cdef readonly loess_kd_tree kd_tree
     cdef readonly loess_outputs outputs
     cdef readonly loess_predicted predicted
+    cdef public long nobs, npar
     
-    def __init__(self, object x, object y, object weights=None):
+    def __init__(self, object x, object y, object weights=None, **options):
         #
         cdef ndarray x_ndr, y_ndr
         cdef double *x_dat, *y_dat
         cdef int i
-        #
-        x_ndr = <ndarray>PyArray_FROMANY(x, NPY_DOUBLE, 1, 1, NPY_FORTRAN)
-        y_ndr = <ndarray>PyArray_FROMANY(y, NPY_DOUBLE, 1, 1, NPY_FORTRAN)
+        # Get the predictor array
+        x_ndr = numpy.array(x, copy=True, subok=True, order='C')
         x_dat = <double *>x_ndr.data
-        y_dat = <double *>y_ndr.data
         n = len(x_ndr)
         p = x_ndr.size / n
+        self.npar = p
+        self.nobs = n
+        # Ravel the predictor array ...
+        if p > 1:
+            x_ndr.shape = (n*p,)
+        # Get the response array ......
+        y_ndr = numpy.array(y, copy=False, subok=True, order='C')
+        y_dat = <double *>y_ndr.data
+        if y_ndr.size != n:
+            raise ValueError("Incompatible size between the response array (%i)"\
+                             " and the predictor array (%i)" % (y_ndr,n))
+        # Initialization ..............
         c_loess.loess_setup(x_dat, y_dat, n, p, &self._base)
         #
         self.inputs = loess_inputs()
@@ -449,10 +789,25 @@
         #
         self.outputs = loess_outputs()
         self.outputs._base = &self._base.outputs
+        self.outputs.activated = False
         self.outputs.nobs = n
+        self.outputs.npar = p
+        # Process options .............
+        modelopt = {}
+        controlopt = {}
+        for (k,v) in options.iteritems():
+            if k in ('family', 'span', 'degree', 'normalize', 
+                     'parametric', 'drop_square',):
+                modelopt[k] = v
+            elif k in ('surface', 'statistics', 'trace_hat', 
+                       'iterations', 'cell'):
+                controlopt[k] = v
+        self.control.update(**controlopt)
+        self.model.update(**modelopt)
     #......................................................
     def fit(self):
         c_loess.loess_fit(&self._base)
+        self.outputs.activated = True
         return
     #......................................................
     def summary(self):
@@ -473,22 +828,55 @@
         """
         cdef ndarray p_ndr
         cdef double *p_dat
+        cdef c_loess.c_prediction _prediction
         cdef int i, m
-        #
-        p_ndr = <ndarray>PyArray_FROMANY(newdata, NPY_DOUBLE, 1, self.nvar, NPY_FORTRAN)
+        # Make sure there's been a fit earlier ...
+        if self.outputs.activated == 0:
+            c_loess.loess_fit(&self._base)
+            self.outputs.activated = True
+        # Note : we need a copy as we may have to normalize
+        p_ndr = numpy.array(newdata, copy=True, subok=True, order='C').ravel()
         p_dat = <double *>p_ndr.data
-        m = len(p_ndr)
-        c_loess.predict(p_dat, m, &self._base, self.predicted._base, stderr)
+        # Test the compatibility of sizes .......
+        if p_ndr.size == 0:
+            raise ValueError("Can't predict without input data !")
+        (m, notOK) = divmod(len(p_ndr), self.npar)
+        if notOK:
+            raise ValueError(
+                  "Incompatible data size: there should be as many rows as parameters")
+        #.....
+        c_loess.predict(p_dat, m, &self._base, &_prediction, stderr)
+        self.predicted = loess_predicted()
+        self.predicted._base = _prediction
         self.predicted.nest = m
+        return self.predicted
+    #.........
+    def __dealloc__(self):
+        c_loess.loess_free_mem(&self._base)
     #......................................................
-#    def pointwisevoid(predicted *pre, int m, double coverage,
-#                      struct ci_struct *ci)
-#        c_loess.pointwise(predicted *pre, int m, double coverage,
-#                      struct ci_struct *ci)
-#
+    
+
+#cdef prediction(loess loess_obj, object newdata, object stderr):
+#    cdef c_loess.c_prediction _base
+#    cdef ndarray p_ndr
+#    cdef double *p_dat
+#    cdef int i, m
+#    cdef loess_prediction result
+#    #
+#    p_ndr = numpy.array(newdata, copy=False, subok=True, order='F') #.ravel()
+##   p_ndr = <ndarray>PyArray_FROMANY(newdata, NPY_DOUBLE, 1, self.model.npar, NPY_FORTRAN)
+#    p_dat = <double *>p_ndr.data
+#    m = len(p_ndr)    
+#    c_loess.predict(p_dat, m, &loess_obj._base, &_base, stderr)
+#    result = loess_predicted()
+#    result._base = _base
+#    result.nest = m
+#    return result
+
+
 #def anova(loess_one, loess_two):
 #    cdef c_loess.c_anova result
-#    
+#   
 #    c_loess.anova(loess_one._base, loess_two._base, &result)
 #        
         
\ No newline at end of file

Modified: trunk/Lib/sandbox/pyloess/sandbox/src/loess.c
===================================================================
--- trunk/Lib/sandbox/pyloess/sandbox/src/loess.c	2007-03-14 16:52:59 UTC (rev 2848)
+++ trunk/Lib/sandbox/pyloess/sandbox/src/loess.c	2007-03-16 20:42:51 UTC (rev 2849)
@@ -3,7 +3,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include <time.h>
 
 static char *surf_stat;
 
@@ -118,12 +117,6 @@
     int     cut, comp();
     char    *new_stat;
     void    condition();
-    char timestr[30];
-    size_t timestri;
-    struct tm tim;
-    time_t now;
-    now = time(NULL);
-    tim = *(localtime(&now));
 
     D = size_info[0];
     N = size_info[1];
@@ -220,11 +213,9 @@
             *one_delta = delta1;
             *two_delta = delta2;
         }
-        strftime(timestr,30,"%b %d, %Y; %H:%M:%S\n",&tim);
-        printf("%s", timestr);
-        for(i = 0; i < N; i++)
-            printf("%.6f\n", fitted_values[i]);
+        for(i = 0; i < N; i++){
             fitted_residuals[i] = y[i] - fitted_values[i];
+        };
         if(j < (*iterations))
             F77_SUB(lowesw)(fitted_residuals, &N, robust, temp);
     }

Modified: trunk/Lib/sandbox/pyloess/sandbox/src/loessc.c
===================================================================
--- trunk/Lib/sandbox/pyloess/sandbox/src/loessc.c	2007-03-14 16:52:59 UTC (rev 2848)
+++ trunk/Lib/sandbox/pyloess/sandbox/src/loessc.c	2007-03-16 20:42:51 UTC (rev 2849)
@@ -1,6 +1,7 @@
 #include "S.h"
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 #define    min(x,y)  ((x) < (y) ? (x) : (y))
 #define    max(x,y)  ((x) > (y) ? (x) : (y))
@@ -255,7 +256,7 @@
 
 /* begin ehg's FORTRAN-callable C-codes */
 
-void
+void*
 F77_SUB(ehg182)(int *i)
 {
 char *mess, mess2[50];
@@ -298,7 +299,9 @@
 case 999: mess="not yet implemented"; break;
 default: sprintf(mess=mess2,"Assert failed; error code %d\n",*i); break;
     }
-    Recover(mess,NULL_ENTRY);  /* in /usr/s/current/src/qpe/debug.c */
+    printf(mess);
+    return(i);
+//    Recover(mess,NULL_ENTRY);  /* in /usr/s/current/src/qpe/debug.c */
 }
 
 void




More information about the Scipy-svn mailing list