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

scipy-svn@scip... scipy-svn@scip...
Wed Mar 21 17:54:13 CDT 2007


Author: pierregm
Date: 2007-03-21 17:53:54 -0500 (Wed, 21 Mar 2007)
New Revision: 2863

Added:
   trunk/Lib/sandbox/pyloess/LICENSE.txt
   trunk/Lib/sandbox/pyloess/src/S.h
   trunk/Lib/sandbox/pyloess/src/_loess.c
   trunk/Lib/sandbox/pyloess/src/_loess.pyx
   trunk/Lib/sandbox/pyloess/src/c_loess.pxd
   trunk/Lib/sandbox/pyloess/src/c_numpy.pxd
   trunk/Lib/sandbox/pyloess/src/c_python.pxd
   trunk/Lib/sandbox/pyloess/src/cloess.h
   trunk/Lib/sandbox/pyloess/src/linpack_lite.f
   trunk/Lib/sandbox/pyloess/src/loess.c
   trunk/Lib/sandbox/pyloess/src/loess.h
   trunk/Lib/sandbox/pyloess/src/loessc.c
   trunk/Lib/sandbox/pyloess/src/loessf.f
   trunk/Lib/sandbox/pyloess/src/misc.c
   trunk/Lib/sandbox/pyloess/src/predict.c
   trunk/Lib/sandbox/pyloess/tests/gas_data
   trunk/Lib/sandbox/pyloess/tests/gas_result
   trunk/Lib/sandbox/pyloess/tests/madeup_data
   trunk/Lib/sandbox/pyloess/tests/madeup_result
Modified:
   trunk/Lib/sandbox/pyloess/README
   trunk/Lib/sandbox/pyloess/__init__.py
   trunk/Lib/sandbox/pyloess/pyloess.py
   trunk/Lib/sandbox/pyloess/setup.py
   trunk/Lib/sandbox/pyloess/tests/test_pyloess.py
Log:
moved loess from the sandbox to the base package
deleted the sandbox directory
added tests for loess (2D and 1D)

Added: trunk/Lib/sandbox/pyloess/LICENSE.txt
===================================================================
--- trunk/Lib/sandbox/pyloess/LICENSE.txt	2007-03-21 21:28:18 UTC (rev 2862)
+++ trunk/Lib/sandbox/pyloess/LICENSE.txt	2007-03-21 22:53:54 UTC (rev 2863)
@@ -0,0 +1,16 @@
+From the original C package:
+
+/*
+ * The authors of this software are Cleveland, Grosse, and Shyu.
+ * Copyright (c) 1989, 1992 by AT&T.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ */
+

Modified: trunk/Lib/sandbox/pyloess/README
===================================================================
--- trunk/Lib/sandbox/pyloess/README	2007-03-21 21:28:18 UTC (rev 2862)
+++ trunk/Lib/sandbox/pyloess/README	2007-03-21 22:53:54 UTC (rev 2863)
@@ -14,3 +14,8 @@
 The initial file is available at:
 http://netlib.bell-labs.com/netlib/a/stl.gz
 Simple to double precision conversion by Pierre GERARD-MARCHANT, 2007/03.
+
+
+Note :
+The sandbox subfolder contains a pre-alpha version of the loess routines. These
+routines are not fully tested, but they run.

Modified: trunk/Lib/sandbox/pyloess/__init__.py
===================================================================
--- trunk/Lib/sandbox/pyloess/__init__.py	2007-03-21 21:28:18 UTC (rev 2862)
+++ trunk/Lib/sandbox/pyloess/__init__.py	2007-03-21 22:53:54 UTC (rev 2863)
@@ -1,10 +1,16 @@
 """
-Numpy wrappers for lowess and stl.
+Numpy wrappers for lowess, loess and stl.
+
+
+:author: Pierre GF Gerard-Marchant
+:contact: pierregm_at_uga_edu
+:date: $Date$
+:version: $Id$
 """
 __author__ = "Pierre GF Gerard-Marchant"
 __version__ = '1.0'
-__revision__ = "$Revision: 150 $"
-__date__     = '$Date: 2007-02-28 23:42:16 -0500 (Wed, 28 Feb 2007) $'
+__revision__ = "$Revision$"
+__date__     = '$Date$'
 
 import pyloess
-from pyloess import lowess, stl
\ No newline at end of file
+from pyloess import lowess, stl, loess, loess_anova
\ No newline at end of file


Property changes on: trunk/Lib/sandbox/pyloess/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Date 
Author 
Revision
Id

Modified: trunk/Lib/sandbox/pyloess/pyloess.py
===================================================================
--- trunk/Lib/sandbox/pyloess/pyloess.py	2007-03-21 21:28:18 UTC (rev 2862)
+++ trunk/Lib/sandbox/pyloess/pyloess.py	2007-03-21 22:53:54 UTC (rev 2863)
@@ -8,35 +8,43 @@
 
 initial author: W. S. Cleveland, 1979.
 Simple to double precision conversion of the Fortran code by Pierre
-GERARD-MARCHANT, 2007/03.
+Gerard-Marchant, 2007/03.
 
 STL:
 Initial Fortran code available at:
 http://netlib.bell-labs.com/netlib/a/stl.gz
 Initial Authors: R. B. Cleveland, W. S. Cleveland, J. E. McRae, and
 I. Terpenning, 1990.
-Simple-to-double precision conversion of the Fortran code by Pierre
-GERARD-MARCHANT, 2007/03.
+Simple-to-double precision conversion of the Fortran code by Pierre 
+Gerard-Marchant, 2007/03.
 
+LOESS:
+Initial C/Fortran package avialable at
+http://netlib.bell-labs.com/netlib/a/dloess.gz
+Initial authors: W. S. Cleveland, E. Grosse and Shyu
+Adaptation to Pyrex/Python by Pierre Gerard-Marchant, 2007/03
 
 :author: Pierre GF Gerard-Marchant
 :contact: pierregm_at_uga_edu
-:date: $Date: 2007-02-28 02:23:25 -0500 (Wed, 28 Feb 2007) $
-:version: $Id: generic.py 145 2007-02-28 07:23:25Z backtopop $
+:date: $Date$
+:version: $Id$
 """
-__author__ = "Pierre GF Gerard-Marchant ($Author: backtopop $)"
+__author__ = "Pierre GF Gerard-Marchant ($Author$)"
 __version__ = '1.0'
-__revision__ = "$Revision: 145 $"
-__date__     = '$Date: 2007-02-28 02:23:25 -0500 (Wed, 28 Feb 2007) $'
+__revision__ = "$Revision$"
+__date__     = '$Date$'
 
 import numpy
 from numpy import bool_, complex_, float_, int_, str_, object_
 import numpy.core.numeric as numeric
 from numpy.core.records import recarray
 
-import _lowess, _stl
+import _lowess, _stl, _loess
 
 
+#####---------------------------------------------------------------------------
+#--- --- STL ---
+#####---------------------------------------------------------------------------
 def lowess(x,y,f=0.5,nsteps=2,delta=0):
     """Performs a robust locally weighted regression (lowess).
 
@@ -141,9 +149,9 @@
     return numeric.fromiter(zip(*_lowess.lowess(x,y,f,nsteps,delta,)),
                             dtype=dtyp).view(recarray)
 
-#--------------------------------------------------------------------------
+#####---------------------------------------------------------------------------
 #--- --- STL ---
-#####----------------------------------------------------------------------
+#####---------------------------------------------------------------------------
 def stl(y, np=12, ns=7, nt=None, nl=13, isdeg=1, itdeg=1, ildeg=1,
         nsjump=None,ntjump=None,nljump=None, robust=True, ni=None,no=None):
     """Decomposes a time series into seasonal and trend  components.
@@ -264,5 +272,124 @@
     result = numeric.fromiter(zip(trn,szn,y-trn-szn,rw), dtype=dtyp)
     return result.view(recarray)
 
-################################################################################
+#####---------------------------------------------------------------------------
+#--- --- Loess ---
+#####---------------------------------------------------------------------------
+loess = _loess.loess
+"""
+loess : locally weighted estimates. Multi-variate version
 
+: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_anova = _loess.anova


Property changes on: trunk/Lib/sandbox/pyloess/pyloess.py
___________________________________________________________________
Name: svn:keywords
   + Date 
Author 
Revision
Id

Modified: trunk/Lib/sandbox/pyloess/setup.py
===================================================================
--- trunk/Lib/sandbox/pyloess/setup.py	2007-03-21 21:28:18 UTC (rev 2862)
+++ trunk/Lib/sandbox/pyloess/setup.py	2007-03-21 22:53:54 UTC (rev 2863)
@@ -1,22 +1,43 @@
 #!/usr/bin/env python
+__author__ = "Pierre GF Gerard-Marchant ($Author$)"
 __version__ = '1.0'
-__revision__ = "$Revision: 2811 $"
-__date__     = '$Date: 2007-03-02 06:30:02 -0500 (Fri, 02 Mar 2007) $'
+__revision__ = "$Revision$"
+__date__     = '$Date$'
 
 import os
 from os.path import join
 
 def configuration(parent_package='',top_path=None):
     from numpy.distutils.misc_util import Configuration
+    from numpy.distutils.system_info import get_info, dict_append
     confgr = Configuration('pyloess',parent_package,top_path)
+    # Configuration of LOWESS
     confgr.add_extension('_lowess',
                          sources=[join('src', 'f_lowess.pyf'),
                                   join('src', 'lowess.f'),]
                          )
+    # Configuration of STL
     confgr.add_extension('_stl',
                          sources=[join('src', 'f_stl.pyf'),
                                   join('src', 'stl.f')],
                          )
+    # Configuration of LOESS
+    f_sources = ('loessf.f', 'linpack_lite.f')
+    confgr.add_library('floess', 
+                       sources = [join('src',x) for x in f_sources])
+    blas_info = get_info('blas_opt')
+    build_info = {}
+    dict_append(build_info, **blas_info)
+    dict_append(build_info, libraries=['floess'])    
+    c_sources = ['_loess.c', 'loess.c', 'loessc.c', 'misc.c', 'predict.c',]
+    confgr.add_extension('_loess',
+                         sources=[join('src', x) for x in c_sources],
+                         depends = [join('src','*.h'),
+                                    join('src','*.pyx'),
+                                    join('src','*.pxd')
+                                    ],
+                         **build_info
+                        )
     confgr.add_data_dir('tests')
     return confgr
 


Property changes on: trunk/Lib/sandbox/pyloess/setup.py
___________________________________________________________________
Name: svn:keywords
   + Date 
Author 
Revision
Id

Added: trunk/Lib/sandbox/pyloess/src/S.h
===================================================================
--- trunk/Lib/sandbox/pyloess/src/S.h	2007-03-21 21:28:18 UTC (rev 2862)
+++ trunk/Lib/sandbox/pyloess/src/S.h	2007-03-21 22:53:54 UTC (rev 2863)
@@ -0,0 +1,32 @@
+#include <stdio.h>
+#include <math.h>
+
+#define Calloc(n,t)	(t *)calloc((unsigned)(n),sizeof(t))
+#define Free(p)		free((char *)(p))
+
+/* the mapping from f77 to C intermediate code -- may be machine dependent
+ * the first definition satisfies lint's narrowminded preprocessing & should
+ * stay the same for all implementations.  The __STDC__ definition is for
+ * ANSI standard conforming C compilers. The #else definition should
+ * generate the version of the fortran subroutine & common block names x
+ * handed to the local loader; e.g., "x_" in system V, Berkeley & 9th edition
+ */
+
+#ifdef lint
+#define F77_SUB(x) x
+#define F77_COM(x) x
+#else
+#ifdef __STDC__
+#define F77_SUB(x) x##_
+#define F77_COM(x) x##_
+#else
+#define F77_SUB(x) x/**/_
+#define F77_COM(x) x/**/_
+#endif
+#endif
+
+#define NULL_ENTRY          ((int *)NULL)
+
+
+
+

Added: trunk/Lib/sandbox/pyloess/src/_loess.c
===================================================================
--- trunk/Lib/sandbox/pyloess/src/_loess.c	2007-03-21 21:28:18 UTC (rev 2862)
+++ trunk/Lib/sandbox/pyloess/src/_loess.c	2007-03-21 22:53:54 UTC (rev 2863)
@@ -0,0 +1,6287 @@
+/* Generated by Pyrex 0.9.5.1a on Wed Mar 21 17:37:22 2007 */
+
+#include "Python.h"
+#include "structmember.h"
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifdef __cplusplus
+#define __PYX_EXTERN_C extern "C"
+#else
+#define __PYX_EXTERN_C extern
+#endif
+__PYX_EXTERN_C double pow(double, double);
+#include "stdlib.h"
+#include "numpy/arrayobject.h"
+#include "loess.h"
+#include "cloess.h"
+
+
+typedef struct {PyObject **p; char *s;} __Pyx_InternTabEntry; /*proto*/
+typedef struct {PyObject **p; char *s; long n;} __Pyx_StringTabEntry; /*proto*/
+
+static PyObject *__pyx_m;
+static PyObject *__pyx_b;
+static int __pyx_lineno;
+static char *__pyx_filename;
+static char **__pyx_f;
+
+static int __Pyx_GetStarArgs(PyObject **args, PyObject **kwds, char *kwd_list[], int nargs, PyObject **args2, PyObject **kwds2); /*proto*/
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
+
+static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
+
+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*/
+
+static int __Pyx_InternStrings(__Pyx_InternTabEntry *t); /*proto*/
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
+
+static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, long size);  /*proto*/
+
+static void __Pyx_AddTraceback(char *funcname); /*proto*/
+
+/* Declarations from c_python */
+
+
+/* Declarations from c_numpy */
+
+static PyTypeObject *__pyx_ptype_7c_numpy_dtype = 0;
+static PyTypeObject *__pyx_ptype_7c_numpy_ndarray = 0;
+static PyTypeObject *__pyx_ptype_7c_numpy_flatiter = 0;
+static PyTypeObject *__pyx_ptype_7c_numpy_broadcast = 0;
+
+/* Declarations from c_loess */
+
+
+/* Declarations from _loess */
+
+
+struct __pyx_obj_6_loess_loess_inputs {
+  PyObject_HEAD
+  loess_inputs (*_base);
+};
+
+
+struct __pyx_obj_6_loess_loess_control {
+  PyObject_HEAD
+  loess_control (*_base);
+};
+
+
+struct __pyx_obj_6_loess_loess_kd_tree {
+  PyObject_HEAD
+  loess_kd_tree (*_base);
+};
+
+
+struct __pyx_obj_6_loess_loess_model {
+  PyObject_HEAD
+  struct __pyx_vtabstruct_6_loess_loess_model *__pyx_vtab;
+  loess_model (*_base);
+  long npar;
+};
+
+struct __pyx_vtabstruct_6_loess_loess_model {
+  PyObject *((*setup)(struct __pyx_obj_6_loess_loess_model *,loess_model (*),long ));
+};
+static struct __pyx_vtabstruct_6_loess_loess_model *__pyx_vtabptr_6_loess_loess_model;
+
+
+struct __pyx_obj_6_loess_loess_outputs {
+  PyObject_HEAD
+  loess_outputs (*_base);
+  long nobs;
+  long npar;
+  int activated;
+};
+
+
+struct __pyx_obj_6_loess_conf_intervals {
+  PyObject_HEAD
+  struct __pyx_vtabstruct_6_loess_conf_intervals *__pyx_vtab;
+  conf_inv _base;
+  PyArrayObject *lower;
+  PyArrayObject *fit;
+  PyArrayObject *upper;
+};
+
+struct __pyx_vtabstruct_6_loess_conf_intervals {
+  PyObject *((*setup)(struct __pyx_obj_6_loess_conf_intervals *,conf_inv ,long ));
+};
+static struct __pyx_vtabstruct_6_loess_conf_intervals *__pyx_vtabptr_6_loess_conf_intervals;
+
+
+struct __pyx_obj_6_loess_loess_predicted {
+  PyObject_HEAD
+  struct __pyx_vtabstruct_6_loess_loess_predicted *__pyx_vtab;
+  prediction _base;
+  long nest;
+  struct __pyx_obj_6_loess_conf_intervals *confidence_intervals;
+};
+
+struct __pyx_vtabstruct_6_loess_loess_predicted {
+  PyObject *((*setup)(struct __pyx_obj_6_loess_loess_predicted *,prediction ,long ));
+};
+static struct __pyx_vtabstruct_6_loess_loess_predicted *__pyx_vtabptr_6_loess_loess_predicted;
+
+
+struct __pyx_obj_6_loess_loess {
+  PyObject_HEAD
+  loess _base;
+  struct __pyx_obj_6_loess_loess_inputs *inputs;
+  struct __pyx_obj_6_loess_loess_model *model;
+  struct __pyx_obj_6_loess_loess_control *control;
+  struct __pyx_obj_6_loess_loess_kd_tree *kd_tree;
+  struct __pyx_obj_6_loess_loess_outputs *outputs;
+  struct __pyx_obj_6_loess_loess_predicted *predicted;
+  long nobs;
+  long npar;
+};
+
+
+struct __pyx_obj_6_loess_anova {
+  PyObject_HEAD
+  double dfn;
+  double dfd;
+  double F_value;
+  double Pr_F;
+};
+
+static PyTypeObject *__pyx_ptype_6_loess_loess_inputs = 0;
+static PyTypeObject *__pyx_ptype_6_loess_loess_control = 0;
+static PyTypeObject *__pyx_ptype_6_loess_loess_kd_tree = 0;
+static PyTypeObject *__pyx_ptype_6_loess_loess_model = 0;
+static PyTypeObject *__pyx_ptype_6_loess_loess_outputs = 0;
+static PyTypeObject *__pyx_ptype_6_loess_conf_intervals = 0;
+static PyTypeObject *__pyx_ptype_6_loess_loess_predicted = 0;
+static PyTypeObject *__pyx_ptype_6_loess_loess = 0;
+static PyTypeObject *__pyx_ptype_6_loess_anova = 0;
+static PyObject *__pyx_k32;
+static PyObject *__pyx_k33;
+static PyObject *__pyx_k34;
+static PyObject *(__pyx_f_6_loess_floatarray_from_data(int ,int ,double (*))); /*proto*/
+static PyObject *(__pyx_f_6_loess_boolarray_from_data(int ,int ,int (*))); /*proto*/
+
+
+/* Implementation of _loess */
+
+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[]) = "\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[]) = "\n    normalize : boolean [True]\n        Determines whether the independent variables should be normalized.  \n        If True, the normalization is performed by setting the 10% trimmed \n        standard deviation to one. If False, no normalization is carried out. \n        This option is only useful for more than one variable. For spatial\n        coordinates predictors or variables with a common scale, it should be \n        set to False.\n        ";
+static char (__pyx_k10[]) = "Smoothing factor, as a fraction of the number of points to take into\n    account. By default, span=0.75.";
+static char (__pyx_k11[]) = "\n    degree : integer [2]\n        Overall degree of locally-fitted polynomial. 1 is locally-linear \n        fitting and 2 is locally-quadratic fitting.  Degree should be 2 at most.\n        ";
+static char (__pyx_k12[]) = "\n    family : string [\"gaussian\"]\n        Determines the assumed distribution of the errors. The values are \n        \"gaussian\" or \"symmetric\". If \"gaussian\" is selected, the fit is \n        performed with least-squares. If \"symmetric\" is selected, the fit\n        is performed robustly by redescending M-estimators.\n        ";
+static char (__pyx_k13[]) = "\n    parametric_flags : sequence [ [False]*p ]\n        Indicates which independent variables should be conditionally-parametric\n       (if there are two or more independent variables). The argument should \n       be a sequence of booleans, with the same size as the number of independent \n       variables, specified in the order of the predictor group ordered in x. \n        ";
+static char (__pyx_k14[]) = "\n    drop_square : sequence [ [False]* p]\n        When there are two or more independent variables and when a 2nd order\n        polynomial is used, \"drop_square_flags\" specifies those numeric predictors \n        whose squares should be dropped from the set of fitting variables. \n        The method of specification is the same as for parametric.  \n        ";
+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    values : ndarray\n        The (m,) ndarray of loess values evaluated at newdata\n        ";
+static char (__pyx_k27[]) = "\n    stderr : ndarray\n        The (m,) ndarray of the estimates of the standard error on the estimated\n        values.\n        ";
+static char (__pyx_k28[]) = "\n    residual_scale : float\n        Estimate of the scale of the residuals\n        ";
+static char (__pyx_k29[]) = "\n    df : integer\n        Degrees of freedom of the t-distribution used to compute pointwise \n        confidence intervals for the evaluated surface.\n        ";
+static char (__pyx_k31[]) = "\n:Keywords:\n    x : ndarray\n        A (n,p) ndarray of independent variables, with n the number of observations\n        and p the number of variables.\n    y : ndarray\n        A (n,) ndarray of observations\n    weights : ndarray\n        A (n,) ndarray of weights to be given to individual observations in the \n        sum of squared residuals that forms the local fitting criterion. If not\n        None, the weights should be non negative. If the different observations\n        have non-equal variances, the weights should be inversely proportional \n        to the variances.\n        By default, an unweighted fit is carried out (all the weights are one).\n    surface : string [\"interpolate\"]\n        Determines whether the fitted surface is computed directly at all points\n        (\"direct\") or whether an interpolation method is used (\"interpolate\").\n        The default (\"interpolate\") is what most users should use unless special \n        circumstances warrant.\n    statistics : string [\"approximate\"]\n        Determines whether the statistical quantities are computed exactly \n        (\"exact\") or approximately (\"approximate\"). \"exact\" should only be used \n        for testing the approximation in statistical development and is not meant \n        for routine usage because computation time can be horrendous.\n    trace_hat : string [\"wait.to.decide\"]\n        Determines how the trace of the hat matrix should be computed. The hat\n        matrix is used in the computation of the statistical quantities. \n        If \"exact\", an exact computation is done; this could be slow when the\n        number of observations n becomes large. If \"wait.to.decide\" is selected, \n        then a default is \"exact\" for n < 500 and \"approximate\" otherwise. \n        This option is only useful when the fitted surface is interpolated. If  \n        surface is \"exact\", an exact computation is always done for the trace. \n        Setting trace_hat to \"approximate\" for large dataset will substantially \n        reduce the computation time.\n    iterations : integer\n        Number of iterations of the robust fitting method. If the family is \n        \"gaussian\", the number of iterations is set to 0.\n    cell : integer\n        Maximum cell size of the kd-tree. Suppose k = floor(n*cell*span),\n        where n is the number of observations, and span the smoothing parameter.\n        Then, a cell is further divided if the number of observations within it \n        is greater than or equal to k. This option is only used if the surface \n        is interpolated.\n    span : float [0.75]\n        Smoothing factor, as a fraction of the number of points to take into\n        account. \n    degree : integer [2]\n        Overall degree of locally-fitted polynomial. 1 is locally-linear \n        fitting and 2 is locally-quadratic fitting.  Degree should be 2 at most.\n    normalize : boolean [True]\n        Determines whether the independent variables should be normalized.  \n        If True, the normalization is performed by setting the 10% trimmed \n        standard deviation to one. If False, no normalization is carried out. \n        This option is only useful for more than one variable. For spatial\n        coordinates predictors or variables with a common scale, it should be \n        set to False.\n    family : string [\"gaussian\"]\n        Determines the assumed distribution of the errors. The values are \n        \"gaussian\" or \"symmetric\". If \"gaussian\" is selected, the fit is \n        performed with least-squares. If \"symmetric\" is selected, the fit\n        is performed robustly by redescending M-estimators.\n    parametric_flags : sequence [ [False]*p ]\n        Indicates which independent variables should be conditionally-parametric\n       (if there are two or more independent variables). The argument should \n       be a sequence of booleans, with the same size as the number of independent \n       variables, specified in the order of the predictor group ordered in x. \n    drop_square : sequence [ [False]* p]\n        When there are two or more independent variables and when a 2nd order\n        polynomial is used, \"drop_square_flags\" specifies those numeric predictors \n        whose squares should be dropped from the set of fitting variables. \n        The method of specification is the same as for parametric.  \n        \n:Outputs:\n    fitted_values : ndarray\n        The (n,) ndarray of fitted values.\n    fitted_residuals : ndarray\n        The (n,) ndarray of fitted residuals (observations - fitted values).\n    enp : float\n        Equivalent number of parameters.\n    s : float\n        Estimate of the scale of residuals.\n    one_delta: float\n        Statistical parameter used in the computation of standard errors.\n    two_delta : float\n        Statistical parameter used in the computation of standard errors.\n    pseudovalues : ndarray\n        The (n,) ndarray of adjusted values of the response when robust estimation \n        is used.\n    trace_hat : float    \n        Trace of the operator hat matrix.\n    diagonal :\n        Diagonal of the operator hat matrix.\n    robust : ndarray\n        The (n,) ndarray of robustness weights for robust fitting.\n    divisor : ndarray\n        The (p,) array of normalization divisors for numeric predictors.\n        \n\n    newdata : ndarray\n        The (m,p) array of independent variables where the surface must be estimated.\n    values : ndarray\n        The (m,) ndarray of loess values evaluated at newdata\n    stderr : ndarray\n        The (m,) ndarray of the estimates of the standard error on the estimated\n        values.\n    residual_scale : float\n        Estimate of the scale of the residuals\n    df : integer\n        Degrees of freedom of the t-distribution used to compute pointwise \n        confidence intervals for the evaluated surface.\n    nest : integer\n        Number of new observations.\n       \n        \n";
+
+static PyObject *__pyx_n_c_python;
+static PyObject *__pyx_n_c_numpy;
+static PyObject *__pyx_n_numpy;
+static PyObject *__pyx_n_narray;
+static PyObject *__pyx_n_c_loess;
+static PyObject *__pyx_n_array;
+static PyObject *__pyx_n_False;
+
+static PyObject *__pyx_n_shape;
+
+static PyObject *__pyx_f_6_loess_floatarray_from_data(int __pyx_v_rows,int __pyx_v_cols,double (*__pyx_v_data)) {
+  PyArrayObject *__pyx_v_a_ndr;
+  npy_intp __pyx_v_size;
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  int __pyx_2;
+  PyObject *__pyx_3 = 0;
+  PyObject *__pyx_4 = 0;
+  __pyx_v_a_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":19 */
+  __pyx_v_size = (__pyx_v_rows * __pyx_v_cols);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":20 */
+  __pyx_1 = PyArray_SimpleNewFromData(1,(&__pyx_v_size),NPY_DOUBLE,__pyx_v_data); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_7c_numpy_ndarray)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; goto __pyx_L1;}
+  Py_INCREF(((PyObject *)__pyx_1));
+  Py_DECREF(((PyObject *)__pyx_v_a_ndr));
+  __pyx_v_a_ndr = ((PyArrayObject *)((PyObject *)__pyx_1));
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":21 */
+  __pyx_2 = (__pyx_v_cols > 1);
+  if (__pyx_2) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":22 */
+    __pyx_1 = PyInt_FromLong(__pyx_v_rows); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
+    __pyx_3 = PyInt_FromLong(__pyx_v_cols); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(2); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
+    PyTuple_SET_ITEM(__pyx_4, 0, __pyx_1);
+    PyTuple_SET_ITEM(__pyx_4, 1, __pyx_3);
+    __pyx_1 = 0;
+    __pyx_3 = 0;
+    if (PyObject_SetAttr(((PyObject *)__pyx_v_a_ndr), __pyx_n_shape, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":23 */
+  Py_INCREF(((PyObject *)__pyx_v_a_ndr));
+  __pyx_r = ((PyObject *)__pyx_v_a_ndr);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_3);
+  Py_XDECREF(__pyx_4);
+  __Pyx_AddTraceback("_loess.floatarray_from_data");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_a_ndr);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_n_astype;
+static PyObject *__pyx_n_bool;
+
+static PyObject *__pyx_f_6_loess_boolarray_from_data(int __pyx_v_rows,int __pyx_v_cols,int (*__pyx_v_data)) {
+  PyArrayObject *__pyx_v_a_ndr;
+  npy_intp __pyx_v_size;
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  int __pyx_2;
+  PyObject *__pyx_3 = 0;
+  PyObject *__pyx_4 = 0;
+  __pyx_v_a_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":28 */
+  __pyx_v_size = (__pyx_v_rows * __pyx_v_cols);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":29 */
+  __pyx_1 = PyArray_SimpleNewFromData(1,(&__pyx_v_size),NPY_DOUBLE,__pyx_v_data); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_7c_numpy_ndarray)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; goto __pyx_L1;}
+  Py_INCREF(((PyObject *)__pyx_1));
+  Py_DECREF(((PyObject *)__pyx_v_a_ndr));
+  __pyx_v_a_ndr = ((PyArrayObject *)((PyObject *)__pyx_1));
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":30 */
+  __pyx_2 = (__pyx_v_cols > 1);
+  if (__pyx_2) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":31 */
+    __pyx_1 = PyInt_FromLong(__pyx_v_rows); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; goto __pyx_L1;}
+    __pyx_3 = PyInt_FromLong(__pyx_v_cols); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(2); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; goto __pyx_L1;}
+    PyTuple_SET_ITEM(__pyx_4, 0, __pyx_1);
+    PyTuple_SET_ITEM(__pyx_4, 1, __pyx_3);
+    __pyx_1 = 0;
+    __pyx_3 = 0;
+    if (PyObject_SetAttr(((PyObject *)__pyx_v_a_ndr), __pyx_n_shape, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; goto __pyx_L1;}
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":32 */
+  __pyx_1 = PyObject_GetAttr(((PyObject *)__pyx_v_a_ndr), __pyx_n_astype); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; goto __pyx_L1;}
+  __pyx_3 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; goto __pyx_L1;}
+  __pyx_4 = PyObject_GetAttr(__pyx_3, __pyx_n_bool); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; goto __pyx_L1;}
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_3, 0, __pyx_4);
+  __pyx_4 = 0;
+  __pyx_4 = PyObject_CallObject(__pyx_1, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 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_3);
+  Py_XDECREF(__pyx_4);
+  __Pyx_AddTraceback("_loess.boolarray_from_data");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_a_ndr);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_12loess_inputs_1x___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_12loess_inputs_1x___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":198 */
+  __pyx_1 = __pyx_f_6_loess_floatarray_from_data(((struct __pyx_obj_6_loess_loess_inputs *)__pyx_v_self)->_base->n,((struct __pyx_obj_6_loess_loess_inputs *)__pyx_v_self)->_base->p,((struct __pyx_obj_6_loess_loess_inputs *)__pyx_v_self)->_base->x); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 198; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_inputs.x.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_12loess_inputs_1y___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_12loess_inputs_1y___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":202 */
+  __pyx_1 = __pyx_f_6_loess_floatarray_from_data(((struct __pyx_obj_6_loess_loess_inputs *)__pyx_v_self)->_base->n,1,((struct __pyx_obj_6_loess_loess_inputs *)__pyx_v_self)->_base->y); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 202; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_inputs.y.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_12loess_inputs_7weights___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_12loess_inputs_7weights___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":213 */
+  __pyx_1 = __pyx_f_6_loess_floatarray_from_data(((struct __pyx_obj_6_loess_loess_inputs *)__pyx_v_self)->_base->n,1,((struct __pyx_obj_6_loess_loess_inputs *)__pyx_v_self)->_base->weights); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 213; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_inputs.weights.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_n_ndim;
+static PyObject *__pyx_n_size;
+static PyObject *__pyx_n_ValueError;
+
+static PyObject *__pyx_k35p;
+
+static char (__pyx_k35[]) = "Invalid size of the 'weights' vector!";
+
+static int __pyx_f_6_loess_12loess_inputs_7weights___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_w); /*proto*/
+static int __pyx_f_6_loess_12loess_inputs_7weights___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_w) {
+  PyArrayObject *__pyx_v_w_ndr;
+  int __pyx_r;
+  PyObject *__pyx_1 = 0;
+  int __pyx_2;
+  PyObject *__pyx_3 = 0;
+  Py_INCREF(__pyx_v_self);
+  Py_INCREF(__pyx_v_w);
+  __pyx_v_w_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":218 */
+  __pyx_1 = PyArray_FROMANY(__pyx_v_w,NPY_DOUBLE,1,1,NPY_OWNDATA); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; goto __pyx_L1;}
+  Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_1)));
+  Py_DECREF(((PyObject *)__pyx_v_w_ndr));
+  __pyx_v_w_ndr = ((PyArrayObject *)__pyx_1);
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":219 */
+  __pyx_1 = PyObject_GetAttr(((PyObject *)__pyx_v_w_ndr), __pyx_n_ndim); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; goto __pyx_L1;}
+  __pyx_3 = PyInt_FromLong(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_1, __pyx_3, &__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; goto __pyx_L1;}
+  __pyx_2 = __pyx_2 > 0;
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  if (!__pyx_2) {
+    __pyx_1 = PyObject_GetAttr(((PyObject *)__pyx_v_w_ndr), __pyx_n_size); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; goto __pyx_L1;}
+    __pyx_3 = PyInt_FromLong(((struct __pyx_obj_6_loess_loess_inputs *)__pyx_v_self)->_base->n); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; goto __pyx_L1;}
+    if (PyObject_Cmp(__pyx_1, __pyx_3, &__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; goto __pyx_L1;}
+    __pyx_2 = __pyx_2 != 0;
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+  }
+  if (__pyx_2) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":220 */
+    __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 220; goto __pyx_L1;}
+    __Pyx_Raise(__pyx_1, __pyx_k35p, 0);
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 220; goto __pyx_L1;}
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":221 */
+  ((struct __pyx_obj_6_loess_loess_inputs *)__pyx_v_self)->_base->weights = ((double (*))__pyx_v_w_ndr->data);
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_3);
+  __Pyx_AddTraceback("_loess.loess_inputs.weights.__set__");
+  __pyx_r = -1;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_w_ndr);
+  Py_DECREF(__pyx_v_self);
+  Py_DECREF(__pyx_v_w);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_12loess_inputs_4nobs___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_12loess_inputs_4nobs___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":226 */
+  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6_loess_loess_inputs *)__pyx_v_self)->_base->n); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_inputs.nobs.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_12loess_inputs_4npar___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_12loess_inputs_4npar___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":231 */
+  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6_loess_loess_inputs *)__pyx_v_self)->_base->p); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_inputs.npar.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_13loess_control_7surface___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_13loess_control_7surface___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":248 */
+  __pyx_1 = PyString_FromString(((struct __pyx_obj_6_loess_loess_control *)__pyx_v_self)->_base->surface); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_control.surface.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_n_lower;
+static PyObject *__pyx_n_interpolate;
+static PyObject *__pyx_n_direct;
+
+static PyObject *__pyx_k38p;
+static PyObject *__pyx_k39p;
+
+static char (__pyx_k38[]) = "Invalid value for the 'surface' argument: ";
+static char (__pyx_k39[]) = "should be in ('interpolate', 'direct').";
+
+static int __pyx_f_6_loess_13loess_control_7surface___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_surface); /*proto*/
+static int __pyx_f_6_loess_13loess_control_7surface___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_surface) {
+  PyObject *__pyx_v_tmpx;
+  int __pyx_r;
+  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/src/_loess.pyx":250 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_surface, __pyx_n_lower); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; goto __pyx_L1;}
+  __pyx_2 = PyObject_CallObject(__pyx_1, 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = PyTuple_New(2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; goto __pyx_L1;}
+  Py_INCREF(__pyx_n_interpolate);
+  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_n_interpolate);
+  Py_INCREF(__pyx_n_direct);
+  PyTuple_SET_ITEM(__pyx_1, 1, __pyx_n_direct);
+  __pyx_3 = PySequence_Contains(__pyx_1, __pyx_2); if (__pyx_3 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; goto __pyx_L1;}
+  __pyx_3 = !__pyx_3;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  if (__pyx_3) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":251 */
+    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; goto __pyx_L1;}
+    __pyx_1 = PyNumber_Add(__pyx_k38p, __pyx_k39p); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; goto __pyx_L1;}
+    PyTuple_SET_ITEM(__pyx_4, 0, __pyx_1);
+    __pyx_1 = 0;
+    __pyx_1 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    __Pyx_Raise(__pyx_1, 0, 0);
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; goto __pyx_L1;}
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":253 */
+  __pyx_2 = PyObject_GetAttr(__pyx_v_surface, __pyx_n_lower); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; goto __pyx_L1;}
+  __pyx_4 = PyObject_CallObject(__pyx_2, 0); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_v_tmpx);
+  __pyx_v_tmpx = __pyx_4;
+  __pyx_4 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":254 */
+  __pyx_5 = PyString_AsString(__pyx_v_tmpx); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 254; goto __pyx_L1;}
+  ((struct __pyx_obj_6_loess_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("_loess.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;
+}
+
+static PyObject *__pyx_f_6_loess_13loess_control_10statistics___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_13loess_control_10statistics___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":265 */
+  __pyx_1 = PyString_FromString(((struct __pyx_obj_6_loess_loess_control *)__pyx_v_self)->_base->statistics); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 265; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_control.statistics.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_n_approximate;
+static PyObject *__pyx_n_exact;
+
+static PyObject *__pyx_k42p;
+
+static char (__pyx_k42[]) = "Invalid value for the 'statistics' argument: should be in ('approximate', 'exact').";
+
+static int __pyx_f_6_loess_13loess_control_10statistics___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_statistics); /*proto*/
+static int __pyx_f_6_loess_13loess_control_10statistics___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_statistics) {
+  PyObject *__pyx_v_tmpx;
+  int __pyx_r;
+  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/src/_loess.pyx":267 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_statistics, __pyx_n_lower); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; goto __pyx_L1;}
+  __pyx_2 = PyObject_CallObject(__pyx_1, 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = PyTuple_New(2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; goto __pyx_L1;}
+  Py_INCREF(__pyx_n_approximate);
+  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_n_approximate);
+  Py_INCREF(__pyx_n_exact);
+  PyTuple_SET_ITEM(__pyx_1, 1, __pyx_n_exact);
+  __pyx_3 = PySequence_Contains(__pyx_1, __pyx_2); if (__pyx_3 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; goto __pyx_L1;}
+  __pyx_3 = !__pyx_3;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  if (__pyx_3) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":268 */
+    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; goto __pyx_L1;}
+    __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; goto __pyx_L1;}
+    Py_INCREF(__pyx_k42p);
+    PyTuple_SET_ITEM(__pyx_1, 0, __pyx_k42p);
+    __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    __Pyx_Raise(__pyx_4, 0, 0);
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; goto __pyx_L1;}
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":270 */
+  __pyx_2 = PyObject_GetAttr(__pyx_v_statistics, __pyx_n_lower); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; goto __pyx_L1;}
+  __pyx_1 = PyObject_CallObject(__pyx_2, 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_v_tmpx);
+  __pyx_v_tmpx = __pyx_1;
+  __pyx_1 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":271 */
+  __pyx_5 = PyString_AsString(__pyx_v_tmpx); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; goto __pyx_L1;}
+  ((struct __pyx_obj_6_loess_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("_loess.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;
+}
+
+static PyObject *__pyx_f_6_loess_13loess_control_9trace_hat___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_13loess_control_9trace_hat___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":287 */
+  __pyx_1 = PyString_FromString(((struct __pyx_obj_6_loess_loess_control *)__pyx_v_self)->_base->trace_hat); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_control.trace_hat.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_k45p;
+
+static char (__pyx_k45[]) = "Invalid value for the 'trace_hat' argument: should be in ('approximate', 'exact').";
+
+static int __pyx_f_6_loess_13loess_control_9trace_hat___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_trace_hat); /*proto*/
+static int __pyx_f_6_loess_13loess_control_9trace_hat___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_trace_hat) {
+  PyObject *__pyx_v_tmpx;
+  int __pyx_r;
+  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/src/_loess.pyx":289 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_trace_hat, __pyx_n_lower); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; goto __pyx_L1;}
+  __pyx_2 = PyObject_CallObject(__pyx_1, 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = PyTuple_New(2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; goto __pyx_L1;}
+  Py_INCREF(__pyx_n_approximate);
+  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_n_approximate);
+  Py_INCREF(__pyx_n_exact);
+  PyTuple_SET_ITEM(__pyx_1, 1, __pyx_n_exact);
+  __pyx_3 = PySequence_Contains(__pyx_1, __pyx_2); if (__pyx_3 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; goto __pyx_L1;}
+  __pyx_3 = !__pyx_3;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  if (__pyx_3) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":290 */
+    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; goto __pyx_L1;}
+    __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; goto __pyx_L1;}
+    Py_INCREF(__pyx_k45p);
+    PyTuple_SET_ITEM(__pyx_1, 0, __pyx_k45p);
+    __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    __Pyx_Raise(__pyx_4, 0, 0);
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; goto __pyx_L1;}
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":292 */
+  __pyx_2 = PyObject_GetAttr(__pyx_v_trace_hat, __pyx_n_lower); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 292; goto __pyx_L1;}
+  __pyx_1 = PyObject_CallObject(__pyx_2, 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 292; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_v_tmpx);
+  __pyx_v_tmpx = __pyx_1;
+  __pyx_1 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":293 */
+  __pyx_5 = PyString_AsString(__pyx_v_tmpx); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; goto __pyx_L1;}
+  ((struct __pyx_obj_6_loess_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("_loess.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;
+}
+
+static PyObject *__pyx_f_6_loess_13loess_control_10iterations___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_13loess_control_10iterations___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":302 */
+  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6_loess_loess_control *)__pyx_v_self)->_base->iterations); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_control.iterations.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_k46p;
+
+static char (__pyx_k46[]) = "Invalid number of iterations: should be positive";
+
+static int __pyx_f_6_loess_13loess_control_10iterations___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_iterations); /*proto*/
+static int __pyx_f_6_loess_13loess_control_10iterations___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_iterations) {
+  int __pyx_r;
+  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/src/_loess.pyx":304 */
+  __pyx_1 = PyInt_FromLong(0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_v_iterations, __pyx_1, &__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; goto __pyx_L1;}
+  __pyx_2 = __pyx_2 < 0;
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  if (__pyx_2) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":305 */
+    __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; goto __pyx_L1;}
+    __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; goto __pyx_L1;}
+    Py_INCREF(__pyx_k46p);
+    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_k46p);
+    __pyx_4 = PyObject_CallObject(__pyx_1, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; goto __pyx_L1;}
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    __Pyx_Raise(__pyx_4, 0, 0);
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; goto __pyx_L1;}
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":306 */
+  __pyx_2 = PyInt_AsLong(__pyx_v_iterations); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 306; goto __pyx_L1;}
+  ((struct __pyx_obj_6_loess_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("_loess.loess_control.iterations.__set__");
+  __pyx_r = -1;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  Py_DECREF(__pyx_v_iterations);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_13loess_control_4cell___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_13loess_control_4cell___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":318 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6_loess_loess_control *)__pyx_v_self)->_base->cell); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_control.cell.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_k47p;
+
+static char (__pyx_k47[]) = "Invalid value for the cell argument: should be positive";
+
+static int __pyx_f_6_loess_13loess_control_4cell___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_cell); /*proto*/
+static int __pyx_f_6_loess_13loess_control_4cell___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_cell) {
+  int __pyx_r;
+  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/src/_loess.pyx":320 */
+  __pyx_1 = PyInt_FromLong(0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 320; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_v_cell, __pyx_1, &__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 320; goto __pyx_L1;}
+  __pyx_2 = __pyx_2 <= 0;
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  if (__pyx_2) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":321 */
+    __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; goto __pyx_L1;}
+    __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; goto __pyx_L1;}
+    Py_INCREF(__pyx_k47p);
+    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_k47p);
+    __pyx_4 = PyObject_CallObject(__pyx_1, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; goto __pyx_L1;}
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    __Pyx_Raise(__pyx_4, 0, 0);
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; goto __pyx_L1;}
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":322 */
+  __pyx_5 = PyFloat_AsDouble(__pyx_v_cell); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 322; goto __pyx_L1;}
+  ((struct __pyx_obj_6_loess_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("_loess.loess_control.cell.__set__");
+  __pyx_r = -1;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  Py_DECREF(__pyx_v_cell);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_n_get;
+static PyObject *__pyx_n_surface;
+static PyObject *__pyx_n_statistics;
+static PyObject *__pyx_n_trace_hat;
+static PyObject *__pyx_n_iterations;
+static PyObject *__pyx_n_cell;
+static PyObject *__pyx_n_parametric_flags;
+
+
+static PyObject *__pyx_f_6_loess_13loess_control_update(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_6_loess_13loess_control_update[] = "Updates several parameters at once.";
+static PyObject *__pyx_f_6_loess_13loess_control_update(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_cellargs = 0;
+  PyObject *__pyx_v_surface;
+  PyObject *__pyx_v_statistics;
+  PyObject *__pyx_v_trace_hat;
+  PyObject *__pyx_v_iterations;
+  PyObject *__pyx_v_cell;
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  int __pyx_4;
+  static char *__pyx_argnames[] = {0};
+  if (__Pyx_GetStarArgs(&__pyx_args, &__pyx_kwds, __pyx_argnames, 0, 0, &__pyx_v_cellargs) < 0) return 0;
+  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "", __pyx_argnames)) {
+    Py_XDECREF(__pyx_args);
+    Py_XDECREF(__pyx_kwds);
+    Py_XDECREF(__pyx_v_cellargs);
+    return 0;
+  }
+  Py_INCREF(__pyx_v_self);
+  __pyx_v_surface = Py_None; Py_INCREF(Py_None);
+  __pyx_v_statistics = Py_None; Py_INCREF(Py_None);
+  __pyx_v_trace_hat = Py_None; Py_INCREF(Py_None);
+  __pyx_v_iterations = Py_None; Py_INCREF(Py_None);
+  __pyx_v_cell = Py_None; Py_INCREF(Py_None);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":326 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; goto __pyx_L1;}
+  Py_INCREF(__pyx_n_surface);
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_surface);
+  Py_INCREF(Py_None);
+  PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_v_surface);
+  __pyx_v_surface = __pyx_3;
+  __pyx_3 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":327 */
+  __pyx_4 = __pyx_v_surface != Py_None;
+  if (__pyx_4) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":328 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_surface, __pyx_v_surface) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; goto __pyx_L1;}
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":330 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; goto __pyx_L1;}
+  Py_INCREF(__pyx_n_statistics);
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_statistics);
+  Py_INCREF(Py_None);
+  PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_v_statistics);
+  __pyx_v_statistics = __pyx_3;
+  __pyx_3 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":331 */
+  __pyx_4 = __pyx_v_statistics != Py_None;
+  if (__pyx_4) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":332 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_statistics, __pyx_v_statistics) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 332; goto __pyx_L1;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":334 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 334; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 334; goto __pyx_L1;}
+  Py_INCREF(__pyx_n_trace_hat);
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_trace_hat);
+  Py_INCREF(Py_None);
+  PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 334; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_v_trace_hat);
+  __pyx_v_trace_hat = __pyx_3;
+  __pyx_3 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":335 */
+  __pyx_4 = __pyx_v_trace_hat != Py_None;
+  if (__pyx_4) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":336 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_trace_hat, __pyx_v_trace_hat) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 336; goto __pyx_L1;}
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":338 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; goto __pyx_L1;}
+  Py_INCREF(__pyx_n_iterations);
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_iterations);
+  Py_INCREF(Py_None);
+  PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_v_iterations);
+  __pyx_v_iterations = __pyx_3;
+  __pyx_3 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":339 */
+  __pyx_4 = __pyx_v_iterations != Py_None;
+  if (__pyx_4) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":340 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_iterations, __pyx_v_iterations) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 340; goto __pyx_L1;}
+    goto __pyx_L5;
+  }
+  __pyx_L5:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":342 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_cellargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 342; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 342; goto __pyx_L1;}
+  Py_INCREF(__pyx_n_cell);
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_n_cell);
+  Py_INCREF(Py_None);
+  PyTuple_SET_ITEM(__pyx_2, 1, Py_None);
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 342; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_v_cell);
+  __pyx_v_cell = __pyx_3;
+  __pyx_3 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":343 */
+  __pyx_4 = __pyx_v_cell != Py_None;
+  if (__pyx_4) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":344 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_parametric_flags, __pyx_v_cell) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 344; goto __pyx_L1;}
+    goto __pyx_L6;
+  }
+  __pyx_L6:;
+
+  __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("_loess.loess_control.update");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_XDECREF(__pyx_v_cellargs);
+  Py_DECREF(__pyx_v_surface);
+  Py_DECREF(__pyx_v_statistics);
+  Py_DECREF(__pyx_v_trace_hat);
+  Py_DECREF(__pyx_v_iterations);
+  Py_DECREF(__pyx_v_cell);
+  Py_DECREF(__pyx_v_self);
+  Py_XDECREF(__pyx_args);
+  Py_XDECREF(__pyx_kwds);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_n_join;
+
+static PyObject *__pyx_k53p;
+static PyObject *__pyx_k54p;
+static PyObject *__pyx_k55p;
+static PyObject *__pyx_k56p;
+static PyObject *__pyx_k57p;
+static PyObject *__pyx_k58p;
+static PyObject *__pyx_k59p;
+
+static char (__pyx_k53[]) = "Control          :";
+static char (__pyx_k54[]) = "Surface type     : %s";
+static char (__pyx_k55[]) = "Statistics       : %s";
+static char (__pyx_k56[]) = "Trace estimation : %s";
+static char (__pyx_k57[]) = "Cell size        : %s";
+static char (__pyx_k58[]) = "Nb iterations    : %s";
+static char (__pyx_k59[]) = "\n";
+
+static PyObject *__pyx_f_6_loess_13loess_control___str__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_13loess_control___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;
+  Py_INCREF(__pyx_v_self);
+  __pyx_v_strg = Py_None; Py_INCREF(Py_None);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":348 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_surface); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; goto __pyx_L1;}
+  __pyx_2 = PyNumber_Remainder(__pyx_k54p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_statistics); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 350; goto __pyx_L1;}
+  __pyx_3 = PyNumber_Remainder(__pyx_k55p, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 350; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_trace_hat); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; goto __pyx_L1;}
+  __pyx_4 = PyNumber_Remainder(__pyx_k56p, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_cell); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; goto __pyx_L1;}
+  __pyx_5 = PyNumber_Remainder(__pyx_k57p, __pyx_1); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_iterations); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; goto __pyx_L1;}
+  __pyx_6 = PyNumber_Remainder(__pyx_k58p, __pyx_1); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = PyList_New(6); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 348; goto __pyx_L1;}
+  Py_INCREF(__pyx_k53p);
+  PyList_SET_ITEM(__pyx_1, 0, __pyx_k53p);
+  PyList_SET_ITEM(__pyx_1, 1, __pyx_2);
+  PyList_SET_ITEM(__pyx_1, 2, __pyx_3);
+  PyList_SET_ITEM(__pyx_1, 3, __pyx_4);
+  PyList_SET_ITEM(__pyx_1, 4, __pyx_5);
+  PyList_SET_ITEM(__pyx_1, 5, __pyx_6);
+  __pyx_2 = 0;
+  __pyx_3 = 0;
+  __pyx_4 = 0;
+  __pyx_5 = 0;
+  __pyx_6 = 0;
+  Py_DECREF(__pyx_v_strg);
+  __pyx_v_strg = __pyx_1;
+  __pyx_1 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":354 */
+  __pyx_2 = PyObject_GetAttr(__pyx_k59p, __pyx_n_join); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; goto __pyx_L1;}
+  Py_INCREF(__pyx_v_strg);
+  PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_strg);
+  __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; 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);
+  __Pyx_AddTraceback("_loess.loess_control.__str__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_strg);
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_11loess_model_setup(struct __pyx_obj_6_loess_loess_model *__pyx_v_self,loess_model (*__pyx_v_base),long __pyx_v_npar) {
+  PyObject *__pyx_r;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":375 */
+  __pyx_v_self->_base = __pyx_v_base;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":376 */
+  __pyx_v_self->npar = __pyx_v_npar;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":386 */
+  Py_INCREF(((PyObject *)__pyx_v_self));
+  __pyx_r = ((PyObject *)__pyx_v_self);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_11loess_model_9normalize___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_11loess_model_9normalize___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.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_6_loess_loess_model *)__pyx_v_self)->_base->normalize); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_3, 0, __pyx_2);
+  __pyx_2 = 0;
+  __pyx_2 = PyObject_CallObject(__pyx_1, __pyx_3); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  __pyx_r = __pyx_2;
+  __pyx_2 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  __Pyx_AddTraceback("_loess.loess_model.normalize.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static int __pyx_f_6_loess_11loess_model_9normalize___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_normalize); /*proto*/
+static int __pyx_f_6_loess_11loess_model_9normalize___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_normalize) {
+  int __pyx_r;
+  int __pyx_1;
+  Py_INCREF(__pyx_v_self);
+  Py_INCREF(__pyx_v_normalize);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.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_6_loess_loess_model *)__pyx_v_self)->_base->normalize = __pyx_1;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1:;
+  __Pyx_AddTraceback("_loess.loess_model.normalize.__set__");
+  __pyx_r = -1;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  Py_DECREF(__pyx_v_normalize);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_11loess_model_4span___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_11loess_model_4span___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":407 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6_loess_loess_model *)__pyx_v_self)->_base->span); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_model.span.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_k60p;
+
+static char (__pyx_k60[]) = "Span should be between 0 and 1!";
+
+static int __pyx_f_6_loess_11loess_model_4span___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_span); /*proto*/
+static int __pyx_f_6_loess_11loess_model_4span___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_span) {
+  int __pyx_r;
+  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/src/_loess.pyx":409 */
+  __pyx_2 = PyFloat_FromDouble(0.); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 409; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_v_span, __pyx_2, &__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 409; goto __pyx_L1;}
+  __pyx_1 = __pyx_1 <= 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  if (!__pyx_1) {
+    __pyx_2 = PyFloat_FromDouble(1.); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 409; goto __pyx_L1;}
+    if (PyObject_Cmp(__pyx_v_span, __pyx_2, &__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 409; goto __pyx_L1;}
+    __pyx_1 = __pyx_1 > 0;
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+  }
+  if (__pyx_1) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":410 */
+    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 410; goto __pyx_L1;}
+    __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 410; goto __pyx_L1;}
+    Py_INCREF(__pyx_k60p);
+    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_k60p);
+    __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 410; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    __Pyx_Raise(__pyx_4, 0, 0);
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 410; goto __pyx_L1;}
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":411 */
+  __pyx_5 = PyFloat_AsDouble(__pyx_v_span); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; goto __pyx_L1;}
+  ((struct __pyx_obj_6_loess_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("_loess.loess_model.span.__set__");
+  __pyx_r = -1;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  Py_DECREF(__pyx_v_span);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_11loess_model_6degree___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_11loess_model_6degree___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":420 */
+  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_6_loess_loess_model *)__pyx_v_self)->_base->degree); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_model.degree.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_k61p;
+
+static char (__pyx_k61[]) = "Degree should be between 0 and 2!";
+
+static int __pyx_f_6_loess_11loess_model_6degree___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_degree); /*proto*/
+static int __pyx_f_6_loess_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/src/_loess.pyx":422 */
+  __pyx_2 = PyInt_FromLong(0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_v_degree, __pyx_2, &__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; goto __pyx_L1;}
+  __pyx_1 = __pyx_1 < 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  if (!__pyx_1) {
+    __pyx_2 = PyInt_FromLong(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; goto __pyx_L1;}
+    if (PyObject_Cmp(__pyx_v_degree, __pyx_2, &__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; goto __pyx_L1;}
+    __pyx_1 = __pyx_1 > 0;
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+  }
+  if (__pyx_1) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":423 */
+    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; goto __pyx_L1;}
+    __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; goto __pyx_L1;}
+    Py_INCREF(__pyx_k61p);
+    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_k61p);
+    __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    __Pyx_Raise(__pyx_4, 0, 0);
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; 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("_loess.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_6_loess_11loess_model_6family___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_11loess_model_6family___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":434 */
+  __pyx_1 = PyString_FromString(((struct __pyx_obj_6_loess_loess_model *)__pyx_v_self)->_base->family); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 434; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_model.family.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_n_symmetric;
+static PyObject *__pyx_n_gaussian;
+
+static PyObject *__pyx_k64p;
+
+static char (__pyx_k64[]) = "Invalid value for the 'family' argument: should be in ('symmetric', 'gaussian').";
+
+static int __pyx_f_6_loess_11loess_model_6family___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_family); /*proto*/
+static int __pyx_f_6_loess_11loess_model_6family___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_family) {
+  int __pyx_r;
+  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_family);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":436 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_family, __pyx_n_lower); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; goto __pyx_L1;}
+  __pyx_2 = PyObject_CallObject(__pyx_1, 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = PyTuple_New(2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; goto __pyx_L1;}
+  Py_INCREF(__pyx_n_symmetric);
+  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_n_symmetric);
+  Py_INCREF(__pyx_n_gaussian);
+  PyTuple_SET_ITEM(__pyx_1, 1, __pyx_n_gaussian);
+  __pyx_3 = PySequence_Contains(__pyx_1, __pyx_2); if (__pyx_3 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; goto __pyx_L1;}
+  __pyx_3 = !__pyx_3;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  if (__pyx_3) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":437 */
+    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; goto __pyx_L1;}
+    __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; goto __pyx_L1;}
+    Py_INCREF(__pyx_k64p);
+    PyTuple_SET_ITEM(__pyx_1, 0, __pyx_k64p);
+    __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    __Pyx_Raise(__pyx_4, 0, 0);
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; goto __pyx_L1;}
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":439 */
+  __pyx_5 = PyString_AsString(__pyx_v_family); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 439; goto __pyx_L1;}
+  ((struct __pyx_obj_6_loess_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("_loess.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_6_loess_11loess_model_16parametric_flags___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_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/src/_loess.pyx":450 */
+  __pyx_1 = __pyx_f_6_loess_boolarray_from_data(((struct __pyx_obj_6_loess_loess_model *)__pyx_v_self)->npar,1,((struct __pyx_obj_6_loess_loess_model *)__pyx_v_self)->_base->parametric); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 450; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_model.parametric_flags.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_n_atleast_1d;
+static PyObject *__pyx_n_copy;
+static PyObject *__pyx_n_True;
+static PyObject *__pyx_n_subok;
+static PyObject *__pyx_n_dtype;
+static PyObject *__pyx_n_min;
+
+
+static int __pyx_f_6_loess_11loess_model_16parametric_flags___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_paramf); /*proto*/
+static int __pyx_f_6_loess_11loess_model_16parametric_flags___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_paramf) {
+  PyArrayObject *__pyx_v_p_ndr;
+  int __pyx_v_i;
+  int __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;
+  long __pyx_7;
+  int __pyx_8;
+  Py_INCREF(__pyx_v_self);
+  Py_INCREF(__pyx_v_paramf);
+  __pyx_v_p_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":454 */
+  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
+  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_n_atleast_1d); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_narray); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
+  Py_INCREF(__pyx_v_paramf);
+  PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_paramf);
+  __pyx_4 = PyDict_New(); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
+  __pyx_5 = __Pyx_GetName(__pyx_b, __pyx_n_False); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
+  if (PyDict_SetItem(__pyx_4, __pyx_n_copy, __pyx_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  __pyx_5 = __Pyx_GetName(__pyx_b, __pyx_n_True); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
+  if (PyDict_SetItem(__pyx_4, __pyx_n_subok, __pyx_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  __pyx_5 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; goto __pyx_L1;}
+  __pyx_6 = PyObject_GetAttr(__pyx_5, __pyx_n_bool); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; goto __pyx_L1;}
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  if (PyDict_SetItem(__pyx_4, __pyx_n_dtype, __pyx_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
+  Py_DECREF(__pyx_6); __pyx_6 = 0;
+  __pyx_5 = PyEval_CallObjectWithKeywords(__pyx_1, __pyx_3, __pyx_4); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+  __pyx_6 = PyTuple_New(1); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_6, 0, __pyx_5);
+  __pyx_5 = 0;
+  __pyx_1 = PyObject_CallObject(__pyx_2, __pyx_6); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_6); __pyx_6 = 0;
+  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_7c_numpy_ndarray)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)__pyx_v_p_ndr));
+  __pyx_v_p_ndr = ((PyArrayObject *)__pyx_1);
+  __pyx_1 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":456 */
+  __pyx_3 = __Pyx_GetName(__pyx_b, __pyx_n_min); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; goto __pyx_L1;}
+  __pyx_4 = PyInt_FromLong(((struct __pyx_obj_6_loess_loess_model *)__pyx_v_self)->npar); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; goto __pyx_L1;}
+  __pyx_5 = PyObject_GetAttr(((PyObject *)__pyx_v_p_ndr), __pyx_n_size); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_4);
+  PyTuple_SET_ITEM(__pyx_2, 1, __pyx_5);
+  __pyx_4 = 0;
+  __pyx_5 = 0;
+  __pyx_6 = PyObject_CallObject(__pyx_3, __pyx_2); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; goto __pyx_L1;}
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_7 = PyInt_AsLong(__pyx_6); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; goto __pyx_L1;}
+  Py_DECREF(__pyx_6); __pyx_6 = 0;
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_7; ++__pyx_v_i) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":457 */
+    __pyx_1 = PyInt_FromLong(__pyx_v_i); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; goto __pyx_L1;}
+    __pyx_4 = PyObject_GetItem(((PyObject *)__pyx_v_p_ndr), __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; goto __pyx_L1;}
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    __pyx_8 = PyInt_AsLong(__pyx_4); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; goto __pyx_L1;}
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    (((struct __pyx_obj_6_loess_loess_model *)__pyx_v_self)->_base->parametric[__pyx_v_i]) = __pyx_8;
+  }
+
+  __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);
+  __Pyx_AddTraceback("_loess.loess_model.parametric_flags.__set__");
+  __pyx_r = -1;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_p_ndr);
+  Py_DECREF(__pyx_v_self);
+  Py_DECREF(__pyx_v_paramf);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_11loess_model_17drop_square_flags___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_11loess_model_17drop_square_flags___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":468 */
+  __pyx_1 = __pyx_f_6_loess_boolarray_from_data(((struct __pyx_obj_6_loess_loess_model *)__pyx_v_self)->npar,1,((struct __pyx_obj_6_loess_loess_model *)__pyx_v_self)->_base->drop_square); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_model.drop_square_flags.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+
+static int __pyx_f_6_loess_11loess_model_17drop_square_flags___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_drop_sq); /*proto*/
+static int __pyx_f_6_loess_11loess_model_17drop_square_flags___set__(PyObject *__pyx_v_self, PyObject *__pyx_v_drop_sq) {
+  PyArrayObject *__pyx_v_d_ndr;
+  int __pyx_v_i;
+  int __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;
+  long __pyx_7;
+  int __pyx_8;
+  Py_INCREF(__pyx_v_self);
+  Py_INCREF(__pyx_v_drop_sq);
+  __pyx_v_d_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":472 */
+  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
+  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_n_atleast_1d); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_narray); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
+  Py_INCREF(__pyx_v_drop_sq);
+  PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_drop_sq);
+  __pyx_4 = PyDict_New(); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
+  __pyx_5 = __Pyx_GetName(__pyx_b, __pyx_n_False); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
+  if (PyDict_SetItem(__pyx_4, __pyx_n_copy, __pyx_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  __pyx_5 = __Pyx_GetName(__pyx_b, __pyx_n_True); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
+  if (PyDict_SetItem(__pyx_4, __pyx_n_subok, __pyx_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  __pyx_5 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 473; goto __pyx_L1;}
+  __pyx_6 = PyObject_GetAttr(__pyx_5, __pyx_n_bool); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 473; goto __pyx_L1;}
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  if (PyDict_SetItem(__pyx_4, __pyx_n_dtype, __pyx_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
+  Py_DECREF(__pyx_6); __pyx_6 = 0;
+  __pyx_5 = PyEval_CallObjectWithKeywords(__pyx_1, __pyx_3, __pyx_4); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+  __pyx_6 = PyTuple_New(1); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_6, 0, __pyx_5);
+  __pyx_5 = 0;
+  __pyx_1 = PyObject_CallObject(__pyx_2, __pyx_6); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_6); __pyx_6 = 0;
+  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_7c_numpy_ndarray)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)__pyx_v_d_ndr));
+  __pyx_v_d_ndr = ((PyArrayObject *)__pyx_1);
+  __pyx_1 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":474 */
+  __pyx_3 = __Pyx_GetName(__pyx_b, __pyx_n_min); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; goto __pyx_L1;}
+  __pyx_4 = PyInt_FromLong(((struct __pyx_obj_6_loess_loess_model *)__pyx_v_self)->npar); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; goto __pyx_L1;}
+  __pyx_5 = PyObject_GetAttr(((PyObject *)__pyx_v_d_ndr), __pyx_n_size); if (!__pyx_5) {__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;}
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_4);
+  PyTuple_SET_ITEM(__pyx_2, 1, __pyx_5);
+  __pyx_4 = 0;
+  __pyx_5 = 0;
+  __pyx_6 = PyObject_CallObject(__pyx_3, __pyx_2); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; goto __pyx_L1;}
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_7 = PyInt_AsLong(__pyx_6); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; goto __pyx_L1;}
+  Py_DECREF(__pyx_6); __pyx_6 = 0;
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_7; ++__pyx_v_i) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":475 */
+    __pyx_1 = PyInt_FromLong(__pyx_v_i); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 475; goto __pyx_L1;}
+    __pyx_4 = PyObject_GetItem(((PyObject *)__pyx_v_d_ndr), __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 475; goto __pyx_L1;}
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    __pyx_8 = PyInt_AsLong(__pyx_4); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 475; goto __pyx_L1;}
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    (((struct __pyx_obj_6_loess_loess_model *)__pyx_v_self)->_base->drop_square[__pyx_v_i]) = __pyx_8;
+  }
+
+  __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);
+  __Pyx_AddTraceback("_loess.loess_model.drop_square_flags.__set__");
+  __pyx_r = -1;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_d_ndr);
+  Py_DECREF(__pyx_v_self);
+  Py_DECREF(__pyx_v_drop_sq);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_n_family;
+static PyObject *__pyx_n_span;
+static PyObject *__pyx_n_degree;
+static PyObject *__pyx_n_normalize;
+static PyObject *__pyx_n_parametric;
+static PyObject *__pyx_n_drop_square;
+static PyObject *__pyx_n_drop_square_flags;
+
+
+static PyObject *__pyx_f_6_loess_11loess_model_update(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_6_loess_11loess_model_update(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_modelargs = 0;
+  PyObject *__pyx_v_family;
+  PyObject *__pyx_v_span;
+  PyObject *__pyx_v_degree;
+  PyObject *__pyx_v_normalize;
+  PyObject *__pyx_v_parametric;
+  PyObject *__pyx_v_drop_square;
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  int __pyx_4;
+  static char *__pyx_argnames[] = {0};
+  if (__Pyx_GetStarArgs(&__pyx_args, &__pyx_kwds, __pyx_argnames, 0, 0, &__pyx_v_modelargs) < 0) return 0;
+  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "", __pyx_argnames)) {
+    Py_XDECREF(__pyx_args);
+    Py_XDECREF(__pyx_kwds);
+    Py_XDECREF(__pyx_v_modelargs);
+    return 0;
+  }
+  Py_INCREF(__pyx_v_self);
+  __pyx_v_family = Py_None; Py_INCREF(Py_None);
+  __pyx_v_span = Py_None; Py_INCREF(Py_None);
+  __pyx_v_degree = Py_None; Py_INCREF(Py_None);
+  __pyx_v_normalize = Py_None; Py_INCREF(Py_None);
+  __pyx_v_parametric = Py_None; Py_INCREF(Py_None);
+  __pyx_v_drop_square = Py_None; Py_INCREF(Py_None);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.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_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 = 478; 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/src/_loess.pyx":479 */
+  __pyx_4 = __pyx_v_family != Py_None;
+  if (__pyx_4) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":480 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_family, __pyx_v_family) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; goto __pyx_L1;}
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":482 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_modelargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 482; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 482; 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 = 482; 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/src/_loess.pyx":483 */
+  __pyx_4 = __pyx_v_span != Py_None;
+  if (__pyx_4) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":484 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_span, __pyx_v_span) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 484; goto __pyx_L1;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":486 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_modelargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 486; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 486; 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 = 486; 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/src/_loess.pyx":487 */
+  __pyx_4 = __pyx_v_degree != Py_None;
+  if (__pyx_4) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":488 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_degree, __pyx_v_degree) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 488; goto __pyx_L1;}
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":490 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_modelargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; 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 = 490; 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/src/_loess.pyx":491 */
+  __pyx_4 = __pyx_v_normalize != Py_None;
+  if (__pyx_4) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":492 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_normalize, __pyx_v_normalize) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 492; goto __pyx_L1;}
+    goto __pyx_L5;
+  }
+  __pyx_L5:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":494 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_modelargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 494; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 494; 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 = 494; 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/src/_loess.pyx":495 */
+  __pyx_4 = __pyx_v_parametric != Py_None;
+  if (__pyx_4) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":496 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_parametric_flags, __pyx_v_parametric) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; goto __pyx_L1;}
+    goto __pyx_L6;
+  }
+  __pyx_L6:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":498 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_modelargs, __pyx_n_get); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 498; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(2); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 498; 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 = 498; 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/src/_loess.pyx":499 */
+  __pyx_4 = __pyx_v_drop_square != Py_None;
+  if (__pyx_4) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":500 */
+    if (PyObject_SetAttr(__pyx_v_self, __pyx_n_drop_square_flags, __pyx_v_drop_square) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 500; goto __pyx_L1;}
+    goto __pyx_L7;
+  }
+  __pyx_L7:;
+
+  __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("_loess.loess_model.update");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_XDECREF(__pyx_v_modelargs);
+  Py_DECREF(__pyx_v_family);
+  Py_DECREF(__pyx_v_span);
+  Py_DECREF(__pyx_v_degree);
+  Py_DECREF(__pyx_v_normalize);
+  Py_DECREF(__pyx_v_parametric);
+  Py_DECREF(__pyx_v_drop_square);
+  Py_DECREF(__pyx_v_self);
+  Py_XDECREF(__pyx_args);
+  Py_XDECREF(__pyx_kwds);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_n_id;
+
+static PyObject *__pyx_k77p;
+
+static char (__pyx_k77[]) = "loess model parameters @%s";
+
+static PyObject *__pyx_f_6_loess_11loess_model___repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_11loess_model___repr__(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/src/_loess.pyx":503 */
+  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_id); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 503; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 503; 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 = 503; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_1 = PyNumber_Remainder(__pyx_k77p, __pyx_3); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 503; goto __pyx_L1;}
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  __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("_loess.loess_model.__repr__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_k78p;
+static PyObject *__pyx_k79p;
+static PyObject *__pyx_k80p;
+static PyObject *__pyx_k81p;
+static PyObject *__pyx_k82p;
+static PyObject *__pyx_k83p;
+static PyObject *__pyx_k84p;
+static PyObject *__pyx_k85p;
+
+static char (__pyx_k78[]) = "Model parameters.....";
+static char (__pyx_k79[]) = "family      : %s";
+static char (__pyx_k80[]) = "span        : %s";
+static char (__pyx_k81[]) = "degree      : %s";
+static char (__pyx_k82[]) = "normalized  : %s";
+static char (__pyx_k83[]) = "parametric  : %s";
+static char (__pyx_k84[]) = "drop_square : %s";
+static char (__pyx_k85[]) = "\n";
+
+static PyObject *__pyx_f_6_loess_11loess_model___str__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_11loess_model___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/src/_loess.pyx":506 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_family); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 507; goto __pyx_L1;}
+  __pyx_2 = PyNumber_Remainder(__pyx_k79p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 507; 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 = 508; goto __pyx_L1;}
+  __pyx_3 = PyNumber_Remainder(__pyx_k80p, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 508; 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 = 509; goto __pyx_L1;}
+  __pyx_4 = PyNumber_Remainder(__pyx_k81p, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 509; 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 = 510; goto __pyx_L1;}
+  __pyx_5 = PyNumber_Remainder(__pyx_k82p, __pyx_1); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 510; 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 = 511; goto __pyx_L1;}
+  __pyx_6 = PySequence_GetSlice(__pyx_1, 0, ((struct __pyx_obj_6_loess_loess_model *)__pyx_v_self)->npar); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = PyNumber_Remainder(__pyx_k83p, __pyx_6); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; 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 = 512; goto __pyx_L1;}
+  __pyx_7 = PySequence_GetSlice(__pyx_6, 0, ((struct __pyx_obj_6_loess_loess_model *)__pyx_v_self)->npar); if (!__pyx_7) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; goto __pyx_L1;}
+  Py_DECREF(__pyx_6); __pyx_6 = 0;
+  __pyx_6 = PyNumber_Remainder(__pyx_k84p, __pyx_7); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; 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 = 506; goto __pyx_L1;}
+  Py_INCREF(__pyx_k78p);
+  PyList_SET_ITEM(__pyx_7, 0, __pyx_k78p);
+  PyList_SET_ITEM(__pyx_7, 1, __pyx_2);
+  PyList_SET_ITEM(__pyx_7, 2, __pyx_3);
+  PyList_SET_ITEM(__pyx_7, 3, __pyx_4);
+  PyList_SET_ITEM(__pyx_7, 4, __pyx_5);
+  PyList_SET_ITEM(__pyx_7, 5, __pyx_1);
+  PyList_SET_ITEM(__pyx_7, 6, __pyx_6);
+  __pyx_2 = 0;
+  __pyx_3 = 0;
+  __pyx_4 = 0;
+  __pyx_5 = 0;
+  __pyx_1 = 0;
+  __pyx_6 = 0;
+  Py_DECREF(__pyx_v_strg);
+  __pyx_v_strg = __pyx_7;
+  __pyx_7 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":514 */
+  __pyx_2 = PyObject_GetAttr(__pyx_k85p, __pyx_n_join); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; 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 = 514; 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("_loess.loess_model.__str__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_strg);
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_13loess_outputs_13fitted_values___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_13loess_outputs_13fitted_values___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":530 */
+  __pyx_1 = __pyx_f_6_loess_floatarray_from_data(((struct __pyx_obj_6_loess_loess_outputs *)__pyx_v_self)->nobs,1,((struct __pyx_obj_6_loess_loess_outputs *)__pyx_v_self)->_base->fitted_values); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 530; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_outputs.fitted_values.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_13loess_outputs_16fitted_residuals___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_13loess_outputs_16fitted_residuals___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":538 */
+  __pyx_1 = __pyx_f_6_loess_floatarray_from_data(((struct __pyx_obj_6_loess_loess_outputs *)__pyx_v_self)->nobs,1,((struct __pyx_obj_6_loess_loess_outputs *)__pyx_v_self)->_base->fitted_residuals); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 538; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_outputs.fitted_residuals.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_13loess_outputs_12pseudovalues___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_13loess_outputs_12pseudovalues___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":547 */
+  __pyx_1 = __pyx_f_6_loess_floatarray_from_data(((struct __pyx_obj_6_loess_loess_outputs *)__pyx_v_self)->nobs,1,((struct __pyx_obj_6_loess_loess_outputs *)__pyx_v_self)->_base->pseudovalues); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 547; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_outputs.pseudovalues.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_13loess_outputs_8diagonal___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_13loess_outputs_8diagonal___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":555 */
+  __pyx_1 = __pyx_f_6_loess_floatarray_from_data(((struct __pyx_obj_6_loess_loess_outputs *)__pyx_v_self)->nobs,1,((struct __pyx_obj_6_loess_loess_outputs *)__pyx_v_self)->_base->diagonal); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 555; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_outputs.diagonal.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_13loess_outputs_6robust___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_13loess_outputs_6robust___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":563 */
+  __pyx_1 = __pyx_f_6_loess_floatarray_from_data(((struct __pyx_obj_6_loess_loess_outputs *)__pyx_v_self)->nobs,1,((struct __pyx_obj_6_loess_loess_outputs *)__pyx_v_self)->_base->robust); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 563; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_outputs.robust.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_13loess_outputs_7divisor___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_13loess_outputs_7divisor___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":568 */
+  __pyx_1 = __pyx_f_6_loess_floatarray_from_data(((struct __pyx_obj_6_loess_loess_outputs *)__pyx_v_self)->npar,1,((struct __pyx_obj_6_loess_loess_outputs *)__pyx_v_self)->_base->divisor); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 568; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_outputs.divisor.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_13loess_outputs_3enp___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_13loess_outputs_3enp___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":576 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6_loess_loess_outputs *)__pyx_v_self)->_base->enp); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 576; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_outputs.enp.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_13loess_outputs_1s___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_13loess_outputs_1s___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":584 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6_loess_loess_outputs *)__pyx_v_self)->_base->s); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 584; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_outputs.s.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_13loess_outputs_9one_delta___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_13loess_outputs_9one_delta___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":592 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6_loess_loess_outputs *)__pyx_v_self)->_base->one_delta); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 592; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_outputs.one_delta.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_13loess_outputs_9two_delta___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_13loess_outputs_9two_delta___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":600 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6_loess_loess_outputs *)__pyx_v_self)->_base->two_delta); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_outputs.two_delta.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_13loess_outputs_9trace_hat___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_13loess_outputs_9trace_hat___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":608 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6_loess_loess_outputs *)__pyx_v_self)->_base->trace_hat); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 608; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_outputs.trace_hat.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  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_k86p;
+static PyObject *__pyx_k87p;
+static PyObject *__pyx_k88p;
+static PyObject *__pyx_k89p;
+static PyObject *__pyx_k90p;
+static PyObject *__pyx_k91p;
+static PyObject *__pyx_k92p;
+static PyObject *__pyx_k93p;
+
+static char (__pyx_k86[]) = "Outputs................";
+static char (__pyx_k87[]) = "Fitted values         : %s\n";
+static char (__pyx_k88[]) = "Fitted residuals      : %s\n";
+static char (__pyx_k89[]) = "Eqv. nb of parameters : %s";
+static char (__pyx_k90[]) = "Residual error        : %s";
+static char (__pyx_k91[]) = "Deltas                : %s - %s";
+static char (__pyx_k92[]) = "Normalization factors : %s";
+static char (__pyx_k93[]) = "\n";
+
+static PyObject *__pyx_f_6_loess_13loess_outputs___str__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_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/src/_loess.pyx":611 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_fitted_values); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 612; goto __pyx_L1;}
+  __pyx_2 = PyNumber_Remainder(__pyx_k87p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 612; 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 = 613; goto __pyx_L1;}
+  __pyx_3 = PyNumber_Remainder(__pyx_k88p, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 613; 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 = 614; goto __pyx_L1;}
+  __pyx_4 = PyNumber_Remainder(__pyx_k89p, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 614; 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 = 615; goto __pyx_L1;}
+  __pyx_5 = PyNumber_Remainder(__pyx_k90p, __pyx_1); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 615; 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 = 616; goto __pyx_L1;}
+  __pyx_6 = PyObject_GetAttr(__pyx_v_self, __pyx_n_two_delta); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 616; goto __pyx_L1;}
+  __pyx_7 = PyTuple_New(2); if (!__pyx_7) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 616; 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_k91p, __pyx_7); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 616; 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 = 617; goto __pyx_L1;}
+  __pyx_7 = PyNumber_Remainder(__pyx_k92p, __pyx_6); if (!__pyx_7) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 617; 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 = 611; goto __pyx_L1;}
+  Py_INCREF(__pyx_k86p);
+  PyList_SET_ITEM(__pyx_6, 0, __pyx_k86p);
+  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/src/_loess.pyx":618 */
+  __pyx_2 = PyObject_GetAttr(__pyx_k93p, __pyx_n_join); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 618; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 618; 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 = 618; 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("_loess.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_6_loess_14conf_intervals_setup(struct __pyx_obj_6_loess_conf_intervals *__pyx_v_self,conf_inv __pyx_v_base,long __pyx_v_nest) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":633 */
+  __pyx_v_self->_base = __pyx_v_base;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":634 */
+  __pyx_1 = __pyx_f_6_loess_floatarray_from_data(__pyx_v_nest,1,__pyx_v_base.fit); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 634; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_7c_numpy_ndarray)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 634; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)__pyx_v_self->fit));
+  __pyx_v_self->fit = ((PyArrayObject *)__pyx_1);
+  __pyx_1 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":635 */
+  __pyx_1 = __pyx_f_6_loess_floatarray_from_data(__pyx_v_nest,1,__pyx_v_base.upper); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 635; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_7c_numpy_ndarray)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 635; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)__pyx_v_self->upper));
+  __pyx_v_self->upper = ((PyArrayObject *)__pyx_1);
+  __pyx_1 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":636 */
+  __pyx_1 = __pyx_f_6_loess_floatarray_from_data(__pyx_v_nest,1,__pyx_v_base.lower); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 636; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_7c_numpy_ndarray)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 636; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)__pyx_v_self->lower));
+  __pyx_v_self->lower = ((PyArrayObject *)__pyx_1);
+  __pyx_1 = 0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.conf_intervals.setup");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_n_r_;
+static PyObject *__pyx_n_T;
+
+static PyObject *__pyx_k94p;
+
+static char (__pyx_k94[]) = "Confidence intervals....\nLower b./ fit / upper b.\n%s";
+
+static PyObject *__pyx_f_6_loess_14conf_intervals___str__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_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;
+  Py_INCREF(__pyx_v_self);
+  __pyx_v_tmp_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":640 */
+  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 640; goto __pyx_L1;}
+  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_n_r_); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 640; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_1 = PyList_New(3); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 640; goto __pyx_L1;}
+  Py_INCREF(((PyObject *)((struct __pyx_obj_6_loess_conf_intervals *)__pyx_v_self)->lower));
+  PyList_SET_ITEM(__pyx_1, 0, ((PyObject *)((struct __pyx_obj_6_loess_conf_intervals *)__pyx_v_self)->lower));
+  Py_INCREF(((PyObject *)((struct __pyx_obj_6_loess_conf_intervals *)__pyx_v_self)->fit));
+  PyList_SET_ITEM(__pyx_1, 1, ((PyObject *)((struct __pyx_obj_6_loess_conf_intervals *)__pyx_v_self)->fit));
+  Py_INCREF(((PyObject *)((struct __pyx_obj_6_loess_conf_intervals *)__pyx_v_self)->upper));
+  PyList_SET_ITEM(__pyx_1, 2, ((PyObject *)((struct __pyx_obj_6_loess_conf_intervals *)__pyx_v_self)->upper));
+  __pyx_3 = PyObject_GetItem(__pyx_2, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 640; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  __pyx_2 = PyObject_GetAttr(__pyx_3, __pyx_n_T); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 640; 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 = 640; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)__pyx_v_tmp_ndr));
+  __pyx_v_tmp_ndr = ((PyArrayObject *)__pyx_2);
+  __pyx_2 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":641 */
+  __pyx_1 = PyNumber_Remainder(__pyx_k94p, ((PyObject *)__pyx_v_tmp_ndr)); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 641; 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("_loess.conf_intervals.__str__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_tmp_ndr);
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static void __pyx_f_6_loess_15loess_predicted___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_f_6_loess_15loess_predicted___dealloc__(PyObject *__pyx_v_self) {
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":655 */
+  pred_free_mem((&((struct __pyx_obj_6_loess_loess_predicted *)__pyx_v_self)->_base));
+
+  Py_DECREF(__pyx_v_self);
+}
+
+static PyObject *__pyx_f_6_loess_15loess_predicted_setup(struct __pyx_obj_6_loess_loess_predicted *__pyx_v_self,prediction __pyx_v_base,long __pyx_v_nest) {
+  PyObject *__pyx_r;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":658 */
+  __pyx_v_self->_base = __pyx_v_base;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":659 */
+  __pyx_v_self->nest = __pyx_v_nest;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_15loess_predicted_6values___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_15loess_predicted_6values___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":693 */
+  __pyx_1 = __pyx_f_6_loess_floatarray_from_data(((struct __pyx_obj_6_loess_loess_predicted *)__pyx_v_self)->nest,1,((struct __pyx_obj_6_loess_loess_predicted *)__pyx_v_self)->_base.fit); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 693; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_predicted.values.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_15loess_predicted_6stderr___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_15loess_predicted_6stderr___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":702 */
+  __pyx_1 = __pyx_f_6_loess_floatarray_from_data(((struct __pyx_obj_6_loess_loess_predicted *)__pyx_v_self)->nest,1,((struct __pyx_obj_6_loess_loess_predicted *)__pyx_v_self)->_base.se_fit); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 702; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_predicted.stderr.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_15loess_predicted_14residual_scale___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_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/src/_loess.pyx":710 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6_loess_loess_predicted *)__pyx_v_self)->_base.residual_scale); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 710; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_predicted.residual_scale.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_6_loess_15loess_predicted_2df___get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_15loess_predicted_2df___get__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":719 */
+  __pyx_1 = PyFloat_FromDouble(((struct __pyx_obj_6_loess_loess_predicted *)__pyx_v_self)->_base.df); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 719; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_loess.loess_predicted.df.__get__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_k95p;
+
+static char (__pyx_k95[]) = "The coverage precentage should be between 0 and 1!";
+
+static PyObject *__pyx_f_6_loess_15loess_predicted_confidence(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_6_loess_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_6_loess_15loess_predicted_confidence(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_coverage = 0;
+  conf_inv __pyx_v__confintv;
+  PyObject *__pyx_r;
+  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_k32;
+  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/src/_loess.pyx":730 */
+  __pyx_1 = PyFloat_FromDouble(0.5); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 730; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_v_coverage, __pyx_1, &__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 730; goto __pyx_L1;}
+  __pyx_2 = __pyx_2 < 0;
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  if (__pyx_2) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":731 */
+    __pyx_1 = PyFloat_FromDouble(1.); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 731; goto __pyx_L1;}
+    __pyx_3 = PyNumber_Subtract(__pyx_1, __pyx_v_coverage); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 731; 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/src/_loess.pyx":732 */
+  __pyx_1 = PyFloat_FromDouble(1.); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 732; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_v_coverage, __pyx_1, &__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 732; goto __pyx_L1;}
+  __pyx_2 = __pyx_2 > 0;
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  if (__pyx_2) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":733 */
+    __pyx_3 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 733; goto __pyx_L1;}
+    __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 733; goto __pyx_L1;}
+    Py_INCREF(__pyx_k95p);
+    PyTuple_SET_ITEM(__pyx_1, 0, __pyx_k95p);
+    __pyx_4 = PyObject_CallObject(__pyx_3, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 733; 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 = 733; goto __pyx_L1;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":734 */
+  __pyx_5 = PyFloat_AsDouble(__pyx_v_coverage); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; goto __pyx_L1;}
+  pointwise((&((struct __pyx_obj_6_loess_loess_predicted *)__pyx_v_self)->_base),((struct __pyx_obj_6_loess_loess_predicted *)__pyx_v_self)->nest,__pyx_5,(&__pyx_v__confintv));
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":735 */
+  __pyx_3 = PyObject_CallObject(((PyObject*)__pyx_ptype_6_loess_conf_intervals), 0); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 735; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_3, __pyx_ptype_6_loess_conf_intervals)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 735; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)((struct __pyx_obj_6_loess_loess_predicted *)__pyx_v_self)->confidence_intervals));
+  ((struct __pyx_obj_6_loess_loess_predicted *)__pyx_v_self)->confidence_intervals = ((struct __pyx_obj_6_loess_conf_intervals *)__pyx_3);
+  __pyx_3 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":736 */
+  __pyx_1 = ((struct __pyx_vtabstruct_6_loess_conf_intervals *)((struct __pyx_obj_6_loess_loess_predicted *)__pyx_v_self)->confidence_intervals->__pyx_vtab)->setup(((struct __pyx_obj_6_loess_loess_predicted *)__pyx_v_self)->confidence_intervals,__pyx_v__confintv,((struct __pyx_obj_6_loess_loess_predicted *)__pyx_v_self)->nest); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 736; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":737 */
+  Py_INCREF(((PyObject *)((struct __pyx_obj_6_loess_loess_predicted *)__pyx_v_self)->confidence_intervals));
+  __pyx_r = ((PyObject *)((struct __pyx_obj_6_loess_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("_loess.loess_predicted.confidence");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  Py_DECREF(__pyx_v_coverage);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_n_values;
+static PyObject *__pyx_n_stderr;
+static PyObject *__pyx_n_residual_scale;
+static PyObject *__pyx_n_df;
+
+static PyObject *__pyx_k96p;
+static PyObject *__pyx_k97p;
+static PyObject *__pyx_k98p;
+static PyObject *__pyx_k99p;
+static PyObject *__pyx_k100p;
+static PyObject *__pyx_k101p;
+
+static char (__pyx_k96[]) = "Outputs................";
+static char (__pyx_k97[]) = "Predicted values      : %s\n";
+static char (__pyx_k98[]) = "Predicted std error   : %s\n";
+static char (__pyx_k99[]) = "Residual scale        : %s";
+static char (__pyx_k100[]) = "Degrees of freedom    : %s";
+static char (__pyx_k101[]) = "\n";
+
+static PyObject *__pyx_f_6_loess_15loess_predicted___str__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_f_6_loess_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/src/_loess.pyx":740 */
+  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_values); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 741; goto __pyx_L1;}
+  __pyx_2 = PyNumber_Remainder(__pyx_k97p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 741; 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 = 742; goto __pyx_L1;}
+  __pyx_3 = PyNumber_Remainder(__pyx_k98p, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 742; 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 = 743; goto __pyx_L1;}
+  __pyx_4 = PyNumber_Remainder(__pyx_k99p, __pyx_1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 743; 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 = 744; goto __pyx_L1;}
+  __pyx_5 = PyNumber_Remainder(__pyx_k100p, __pyx_1); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 744; 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 = 740; goto __pyx_L1;}
+  Py_INCREF(__pyx_k96p);
+  PyList_SET_ITEM(__pyx_1, 0, __pyx_k96p);
+  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/src/_loess.pyx":747 */
+  __pyx_2 = PyObject_GetAttr(__pyx_k101p, __pyx_n_join); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 747; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 747; 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 = 747; 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("_loess.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_k110p;
+
+static char (__pyx_k110[]) = "Incompatible size between the response array (%i) and the predictor array (%i)";
+
+static int __pyx_f_6_loess_5loess___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_f_6_loess_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;
+  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_k33;
+  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);
+  Py_INCREF(__pyx_v_weights);
+  __pyx_v_x_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  __pyx_v_y_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  __pyx_v_n = Py_None; Py_INCREF(Py_None);
+  __pyx_v_p = Py_None; Py_INCREF(Py_None);
+  __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/src/_loess.pyx":769 */
+  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_narray); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; goto __pyx_L1;}
+  Py_INCREF(__pyx_v_x);
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_v_x);
+  __pyx_3 = PyDict_New(); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; goto __pyx_L1;}
+  __pyx_4 = __Pyx_GetName(__pyx_b, __pyx_n_True); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; goto __pyx_L1;}
+  if (PyDict_SetItem(__pyx_3, __pyx_n_copy, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; 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 = 769; goto __pyx_L1;}
+  if (PyDict_SetItem(__pyx_3, __pyx_n_subok, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; 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 = 769; goto __pyx_L1;}
+  __pyx_4 = PyEval_CallObjectWithKeywords(__pyx_1, __pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 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 = 769; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)__pyx_v_x_ndr));
+  __pyx_v_x_ndr = ((PyArrayObject *)__pyx_4);
+  __pyx_4 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":770 */
+  __pyx_v_x_dat = ((double (*))__pyx_v_x_ndr->data);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":771 */
+  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_len); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 771; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 771; 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 = 771; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_v_n);
+  __pyx_v_n = __pyx_3;
+  __pyx_3 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":772 */
+  __pyx_4 = PyObject_GetAttr(((PyObject *)__pyx_v_x_ndr), __pyx_n_size); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 772; goto __pyx_L1;}
+  __pyx_1 = PyNumber_Divide(__pyx_4, __pyx_v_n); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 772; goto __pyx_L1;}
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+  Py_DECREF(__pyx_v_p);
+  __pyx_v_p = __pyx_1;
+  __pyx_1 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":773 */
+  __pyx_5 = PyInt_AsLong(__pyx_v_p); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; goto __pyx_L1;}
+  ((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->npar = __pyx_5;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":774 */
+  __pyx_5 = PyInt_AsLong(__pyx_v_n); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 774; goto __pyx_L1;}
+  ((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->nobs = __pyx_5;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":776 */
+  __pyx_2 = PyInt_FromLong(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 776; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_v_p, __pyx_2, &__pyx_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 776; goto __pyx_L1;}
+  __pyx_6 = __pyx_6 > 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  if (__pyx_6) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":777 */
+    __pyx_3 = PyNumber_Multiply(__pyx_v_n, __pyx_v_p); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 777; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 777; 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 = 777; goto __pyx_L1;}
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":779 */
+  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_narray); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 779; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 779; goto __pyx_L1;}
+  Py_INCREF(__pyx_v_y);
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_v_y);
+  __pyx_3 = PyDict_New(); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 779; goto __pyx_L1;}
+  __pyx_4 = __Pyx_GetName(__pyx_b, __pyx_n_False); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 779; goto __pyx_L1;}
+  if (PyDict_SetItem(__pyx_3, __pyx_n_copy, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 779; 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 = 779; goto __pyx_L1;}
+  if (PyDict_SetItem(__pyx_3, __pyx_n_subok, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 779; 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 = 779; goto __pyx_L1;}
+  __pyx_4 = PyEval_CallObjectWithKeywords(__pyx_1, __pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 779; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 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 = 779; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)__pyx_v_y_ndr));
+  __pyx_v_y_ndr = ((PyArrayObject *)__pyx_4);
+  __pyx_4 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":780 */
+  __pyx_v_y_dat = ((double (*))__pyx_v_y_ndr->data);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":781 */
+  __pyx_1 = PyObject_GetAttr(((PyObject *)__pyx_v_y_ndr), __pyx_n_size); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_1, __pyx_v_n, &__pyx_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 781; goto __pyx_L1;}
+  __pyx_6 = __pyx_6 != 0;
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  if (__pyx_6) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":782 */
+    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 782; goto __pyx_L1;}
+    __pyx_3 = PyTuple_New(2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 783; goto __pyx_L1;}
+    Py_INCREF(((PyObject *)__pyx_v_y_ndr));
+    PyTuple_SET_ITEM(__pyx_3, 0, ((PyObject *)__pyx_v_y_ndr));
+    Py_INCREF(__pyx_v_n);
+    PyTuple_SET_ITEM(__pyx_3, 1, __pyx_v_n);
+    __pyx_4 = PyNumber_Remainder(__pyx_k110p, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 783; goto __pyx_L1;}
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 782; goto __pyx_L1;}
+    PyTuple_SET_ITEM(__pyx_1, 0, __pyx_4);
+    __pyx_4 = 0;
+    __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 782; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    __Pyx_Raise(__pyx_3, 0, 0);
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 782; goto __pyx_L1;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":785 */
+  __pyx_5 = PyInt_AsLong(__pyx_v_n); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 785; goto __pyx_L1;}
+  __pyx_7 = PyInt_AsLong(__pyx_v_p); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 785; goto __pyx_L1;}
+  loess_setup(__pyx_v_x_dat,__pyx_v_y_dat,__pyx_5,__pyx_7,(&((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->_base));
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":787 */
+  __pyx_4 = PyObject_CallObject(((PyObject*)__pyx_ptype_6_loess_loess_inputs), 0); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 787; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_4, __pyx_ptype_6_loess_loess_inputs)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 787; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->inputs));
+  ((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->inputs = ((struct __pyx_obj_6_loess_loess_inputs *)__pyx_4);
+  __pyx_4 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":788 */
+  ((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->inputs->_base = (&((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->_base.inputs);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":790 */
+  __pyx_2 = PyObject_CallObject(((PyObject*)__pyx_ptype_6_loess_loess_model), 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 790; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_2, __pyx_ptype_6_loess_loess_model)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 790; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->model));
+  ((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->model = ((struct __pyx_obj_6_loess_loess_model *)__pyx_2);
+  __pyx_2 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":791 */
+  __pyx_5 = PyInt_AsLong(__pyx_v_p); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; goto __pyx_L1;}
+  __pyx_1 = ((struct __pyx_vtabstruct_6_loess_loess_model *)((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->model->__pyx_vtab)->setup(((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->model,(&((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->_base.model),__pyx_5); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":795 */
+  __pyx_3 = PyObject_CallObject(((PyObject*)__pyx_ptype_6_loess_loess_control), 0); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 795; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_3, __pyx_ptype_6_loess_loess_control)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 795; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->control));
+  ((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->control = ((struct __pyx_obj_6_loess_loess_control *)__pyx_3);
+  __pyx_3 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":796 */
+  ((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->control->_base = (&((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->_base.control);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":798 */
+  __pyx_4 = PyObject_CallObject(((PyObject*)__pyx_ptype_6_loess_loess_kd_tree), 0); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 798; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_4, __pyx_ptype_6_loess_loess_kd_tree)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 798; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->kd_tree));
+  ((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->kd_tree = ((struct __pyx_obj_6_loess_loess_kd_tree *)__pyx_4);
+  __pyx_4 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":799 */
+  ((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->kd_tree->_base = (&((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->_base.kd_tree);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":801 */
+  __pyx_2 = PyObject_CallObject(((PyObject*)__pyx_ptype_6_loess_loess_outputs), 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 801; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_2, __pyx_ptype_6_loess_loess_outputs)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 801; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->outputs));
+  ((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->outputs = ((struct __pyx_obj_6_loess_loess_outputs *)__pyx_2);
+  __pyx_2 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":802 */
+  ((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->outputs->_base = (&((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->_base.outputs);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":803 */
+  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_False); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 803; goto __pyx_L1;}
+  __pyx_6 = PyInt_AsLong(__pyx_1); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 803; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  ((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->outputs->activated = __pyx_6;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":804 */
+  __pyx_7 = PyInt_AsLong(__pyx_v_n); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 804; goto __pyx_L1;}
+  ((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->outputs->nobs = __pyx_7;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":805 */
+  __pyx_5 = PyInt_AsLong(__pyx_v_p); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 805; goto __pyx_L1;}
+  ((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->outputs->npar = __pyx_5;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":807 */
+  __pyx_3 = PyDict_New(); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 807; goto __pyx_L1;}
+  Py_DECREF(__pyx_v_modelopt);
+  __pyx_v_modelopt = __pyx_3;
+  __pyx_3 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":808 */
+  __pyx_4 = PyDict_New(); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 808; goto __pyx_L1;}
+  Py_DECREF(__pyx_v_controlopt);
+  __pyx_v_controlopt = __pyx_4;
+  __pyx_4 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":809 */
+  __pyx_2 = PyObject_GetAttr(__pyx_v_options, __pyx_n_iteritems); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 809; goto __pyx_L1;}
+  __pyx_1 = PyObject_CallObject(__pyx_2, 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 809; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_3 = PyObject_GetIter(__pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 809; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  for (;;) {
+    __pyx_4 = PyIter_Next(__pyx_3);
+    if (!__pyx_4) {
+      if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 809; goto __pyx_L1;}
+      break;
+    }
+    __pyx_2 = PyObject_GetIter(__pyx_4); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 809; goto __pyx_L1;}
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    __pyx_1 = __Pyx_UnpackItem(__pyx_2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 809; goto __pyx_L1;}
+    Py_DECREF(__pyx_v_k);
+    __pyx_v_k = __pyx_1;
+    __pyx_1 = 0;
+    __pyx_4 = __Pyx_UnpackItem(__pyx_2); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 809; 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 = 809; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":810 */
+    __pyx_1 = PyTuple_New(6); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 810; goto __pyx_L1;}
+    Py_INCREF(__pyx_n_family);
+    PyTuple_SET_ITEM(__pyx_1, 0, __pyx_n_family);
+    Py_INCREF(__pyx_n_span);
+    PyTuple_SET_ITEM(__pyx_1, 1, __pyx_n_span);
+    Py_INCREF(__pyx_n_degree);
+    PyTuple_SET_ITEM(__pyx_1, 2, __pyx_n_degree);
+    Py_INCREF(__pyx_n_normalize);
+    PyTuple_SET_ITEM(__pyx_1, 3, __pyx_n_normalize);
+    Py_INCREF(__pyx_n_parametric);
+    PyTuple_SET_ITEM(__pyx_1, 4, __pyx_n_parametric);
+    Py_INCREF(__pyx_n_drop_square);
+    PyTuple_SET_ITEM(__pyx_1, 5, __pyx_n_drop_square);
+    __pyx_6 = PySequence_Contains(__pyx_1, __pyx_v_k); if (__pyx_6 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 810; goto __pyx_L1;}
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    if (__pyx_6) {
+
+      /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":812 */
+      if (PyObject_SetItem(__pyx_v_modelopt, __pyx_v_k, __pyx_v_v) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 812; goto __pyx_L1;}
+      goto __pyx_L6;
+    }
+    __pyx_4 = PyTuple_New(5); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 813; 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 = 813; goto __pyx_L1;}
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    if (__pyx_6) {
+
+      /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":815 */
+      if (PyObject_SetItem(__pyx_v_controlopt, __pyx_v_k, __pyx_v_v) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; goto __pyx_L1;}
+      goto __pyx_L6;
+    }
+    __pyx_L6:;
+  }
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":816 */
+  __pyx_2 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->control), __pyx_n_update); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 816; goto __pyx_L1;}
+  __pyx_1 = PyTuple_New(0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 816; goto __pyx_L1;}
+  __pyx_4 = PyEval_CallObjectWithKeywords(__pyx_2, __pyx_1, __pyx_v_controlopt); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 816; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":817 */
+  __pyx_3 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->model), __pyx_n_update); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 817; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 817; goto __pyx_L1;}
+  __pyx_1 = PyEval_CallObjectWithKeywords(__pyx_3, __pyx_2, __pyx_v_modelopt); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 817; goto __pyx_L1;}
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_1); __pyx_1 = 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("_loess.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_6_loess_5loess_fit(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_6_loess_5loess_fit(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  int __pyx_2;
+  PyObject *__pyx_3 = 0;
+  PyObject *__pyx_4 = 0;
+  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/src/_loess.pyx":820 */
+  loess_fit((&((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->_base));
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":821 */
+  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_True); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 821; goto __pyx_L1;}
+  __pyx_2 = PyInt_AsLong(__pyx_1); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 821; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  ((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->outputs->activated = __pyx_2;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":822 */
+  __pyx_2 = ((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->_base.status.err_status;
+  if (__pyx_2) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":823 */
+    __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 823; goto __pyx_L1;}
+    __pyx_3 = PyString_FromString(((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->_base.status.err_msg); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 823; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 823; goto __pyx_L1;}
+    PyTuple_SET_ITEM(__pyx_4, 0, __pyx_3);
+    __pyx_3 = 0;
+    __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 823; goto __pyx_L1;}
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    __Pyx_Raise(__pyx_3, 0, 0);
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 823; goto __pyx_L1;}
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":824 */
+  __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);
+  Py_XDECREF(__pyx_3);
+  Py_XDECREF(__pyx_4);
+  __Pyx_AddTraceback("_loess.loess.fit");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_n_nobs;
+
+static PyObject *__pyx_k122p;
+static PyObject *__pyx_k123p;
+static PyObject *__pyx_k125p;
+static PyObject *__pyx_k126p;
+
+static char (__pyx_k122[]) = "Number of Observations         : %d";
+static char (__pyx_k123[]) = "Equivalent Number of Parameters: %.1f";
+static char (__pyx_k125[]) = "Residual Standard Error        : %.4f";
+static char (__pyx_k126[]) = "Residual Scale Estimate        : %.4f";
+
+static PyObject *__pyx_f_6_loess_5loess_summary(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_6_loess_5loess_summary(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  int __pyx_3;
+  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/src/_loess.pyx":827 */
+  __pyx_1 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->inputs), __pyx_n_nobs); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 827; goto __pyx_L1;}
+  __pyx_2 = PyNumber_Remainder(__pyx_k122p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 827; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  if (__Pyx_PrintItem(__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 827; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 827; goto __pyx_L1;}
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":828 */
+  __pyx_1 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->outputs), __pyx_n_enp); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 828; goto __pyx_L1;}
+  __pyx_2 = PyNumber_Remainder(__pyx_k123p, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 828; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  if (__Pyx_PrintItem(__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 828; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 828; goto __pyx_L1;}
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":829 */
+  __pyx_1 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->model), __pyx_n_family); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 829; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_1, __pyx_n_gaussian, &__pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 829; goto __pyx_L1;}
+  __pyx_3 = __pyx_3 == 0;
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  if (__pyx_3) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":830 */
+    __pyx_2 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->outputs), __pyx_n_s); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 830; goto __pyx_L1;}
+    __pyx_1 = PyNumber_Remainder(__pyx_k125p, __pyx_2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 830; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    if (__Pyx_PrintItem(__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 830; goto __pyx_L1;}
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 830; goto __pyx_L1;}
+    goto __pyx_L2;
+  }
+  /*else*/ {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":832 */
+    __pyx_2 = PyObject_GetAttr(((PyObject *)((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->outputs), __pyx_n_s); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 832; goto __pyx_L1;}
+    __pyx_1 = PyNumber_Remainder(__pyx_k126p, __pyx_2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 832; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    if (__Pyx_PrintItem(__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 832; goto __pyx_L1;}
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    if (__Pyx_PrintNewline() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 832; goto __pyx_L1;}
+  }
+  __pyx_L2:;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  __Pyx_AddTraceback("_loess.loess.summary");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_n_ravel;
+static PyObject *__pyx_n_divmod;
+
+static PyObject *__pyx_k131p;
+static PyObject *__pyx_k132p;
+
+static char (__pyx_k131[]) = "Can't predict without input data !";
+static char (__pyx_k132[]) = "Incompatible data size: there should be as many rows as parameters";
+
+static PyObject *__pyx_f_6_loess_5loess_predict(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_6_loess_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_6_loess_5loess_predict(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_newdata = 0;
+  PyObject *__pyx_v_stderror = 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;
+  int __pyx_1;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  PyObject *__pyx_4 = 0;
+  PyObject *__pyx_5 = 0;
+  static char *__pyx_argnames[] = {"newdata","stderror",0};
+  __pyx_v_stderror = __pyx_k34;
+  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "O|O", __pyx_argnames, &__pyx_v_newdata, &__pyx_v_stderror)) return 0;
+  Py_INCREF(__pyx_v_self);
+  Py_INCREF(__pyx_v_newdata);
+  Py_INCREF(__pyx_v_stderror);
+  __pyx_v_p_ndr = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  __pyx_v_notOK = Py_None; Py_INCREF(Py_None);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":847 */
+  __pyx_1 = (((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->outputs->activated == 0);
+  if (__pyx_1) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":848 */
+    loess_fit((&((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->_base));
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":849 */
+    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_True); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 849; goto __pyx_L1;}
+    __pyx_1 = PyInt_AsLong(__pyx_2); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 849; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    ((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->outputs->activated = __pyx_1;
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":850 */
+    __pyx_1 = ((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->_base.status.err_status;
+    if (__pyx_1) {
+
+      /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":851 */
+      __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 851; goto __pyx_L1;}
+      __pyx_3 = PyString_FromString(((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->_base.status.err_msg); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 851; goto __pyx_L1;}
+      __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 851; goto __pyx_L1;}
+      PyTuple_SET_ITEM(__pyx_4, 0, __pyx_3);
+      __pyx_3 = 0;
+      __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 851; goto __pyx_L1;}
+      Py_DECREF(__pyx_2); __pyx_2 = 0;
+      Py_DECREF(__pyx_4); __pyx_4 = 0;
+      __Pyx_Raise(__pyx_3, 0, 0);
+      Py_DECREF(__pyx_3); __pyx_3 = 0;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 851; goto __pyx_L1;}
+      goto __pyx_L3;
+    }
+    __pyx_L3:;
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":853 */
+  __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_narray); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 853; goto __pyx_L1;}
+  __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 853; goto __pyx_L1;}
+  Py_INCREF(__pyx_v_newdata);
+  PyTuple_SET_ITEM(__pyx_4, 0, __pyx_v_newdata);
+  __pyx_3 = PyDict_New(); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 853; goto __pyx_L1;}
+  __pyx_5 = __Pyx_GetName(__pyx_b, __pyx_n_True); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 853; goto __pyx_L1;}
+  if (PyDict_SetItem(__pyx_3, __pyx_n_copy, __pyx_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 853; 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 = 853; goto __pyx_L1;}
+  if (PyDict_SetItem(__pyx_3, __pyx_n_subok, __pyx_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 853; goto __pyx_L1;}
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  if (PyDict_SetItem(__pyx_3, __pyx_n_order, __pyx_n_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 853; goto __pyx_L1;}
+  __pyx_5 = PyEval_CallObjectWithKeywords(__pyx_2, __pyx_4, __pyx_3); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 853; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  __pyx_2 = PyObject_GetAttr(__pyx_5, __pyx_n_ravel); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 853; goto __pyx_L1;}
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  __pyx_4 = PyObject_CallObject(__pyx_2, 0); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 853; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  if (!__Pyx_TypeTest(__pyx_4, __pyx_ptype_7c_numpy_ndarray)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 853; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)__pyx_v_p_ndr));
+  __pyx_v_p_ndr = ((PyArrayObject *)__pyx_4);
+  __pyx_4 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":854 */
+  __pyx_v_p_dat = ((double (*))__pyx_v_p_ndr->data);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":856 */
+  __pyx_3 = PyObject_GetAttr(((PyObject *)__pyx_v_p_ndr), __pyx_n_size); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 856; goto __pyx_L1;}
+  __pyx_5 = PyInt_FromLong(0); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 856; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_3, __pyx_5, &__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 856; goto __pyx_L1;}
+  __pyx_1 = __pyx_1 == 0;
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  if (__pyx_1) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":857 */
+    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 857; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 857; goto __pyx_L1;}
+    Py_INCREF(__pyx_k131p);
+    PyTuple_SET_ITEM(__pyx_4, 0, __pyx_k131p);
+    __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 857; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    __Pyx_Raise(__pyx_3, 0, 0);
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 857; goto __pyx_L1;}
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":858 */
+  __pyx_5 = __Pyx_GetName(__pyx_b, __pyx_n_divmod); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 858; goto __pyx_L1;}
+  __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_len); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 858; goto __pyx_L1;}
+  __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 858; goto __pyx_L1;}
+  Py_INCREF(((PyObject *)__pyx_v_p_ndr));
+  PyTuple_SET_ITEM(__pyx_4, 0, ((PyObject *)__pyx_v_p_ndr));
+  __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 858; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+  __pyx_2 = PyInt_FromLong(((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->npar); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 858; goto __pyx_L1;}
+  __pyx_4 = PyTuple_New(2); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 858; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_4, 0, __pyx_3);
+  PyTuple_SET_ITEM(__pyx_4, 1, __pyx_2);
+  __pyx_3 = 0;
+  __pyx_2 = 0;
+  __pyx_3 = PyObject_CallObject(__pyx_5, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 858; goto __pyx_L1;}
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+  __pyx_2 = PyObject_GetIter(__pyx_3); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 858; goto __pyx_L1;}
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  __pyx_5 = __Pyx_UnpackItem(__pyx_2); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 858; goto __pyx_L1;}
+  __pyx_1 = PyInt_AsLong(__pyx_5); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 858; goto __pyx_L1;}
+  Py_DECREF(__pyx_5); __pyx_5 = 0;
+  __pyx_v_m = __pyx_1;
+  __pyx_4 = __Pyx_UnpackItem(__pyx_2); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 858; goto __pyx_L1;}
+  Py_DECREF(__pyx_v_notOK);
+  __pyx_v_notOK = __pyx_4;
+  __pyx_4 = 0;
+  if (__Pyx_EndUnpack(__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 858; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":859 */
+  __pyx_1 = PyObject_IsTrue(__pyx_v_notOK); if (__pyx_1 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 859; goto __pyx_L1;}
+  if (__pyx_1) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":860 */
+    __pyx_3 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 860; goto __pyx_L1;}
+    __pyx_5 = PyTuple_New(1); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 860; goto __pyx_L1;}
+    Py_INCREF(__pyx_k132p);
+    PyTuple_SET_ITEM(__pyx_5, 0, __pyx_k132p);
+    __pyx_4 = PyObject_CallObject(__pyx_3, __pyx_5); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 860; goto __pyx_L1;}
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    Py_DECREF(__pyx_5); __pyx_5 = 0;
+    __Pyx_Raise(__pyx_4, 0, 0);
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 860; goto __pyx_L1;}
+    goto __pyx_L5;
+  }
+  __pyx_L5:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":863 */
+  __pyx_1 = PyInt_AsLong(__pyx_v_stderror); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 863; goto __pyx_L1;}
+  predict(__pyx_v_p_dat,__pyx_v_m,(&((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->_base),(&__pyx_v__prediction),__pyx_1);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":864 */
+  __pyx_1 = ((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->_base.status.err_status;
+  if (__pyx_1) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":865 */
+    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 865; goto __pyx_L1;}
+    __pyx_3 = PyString_FromString(((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->_base.status.err_msg); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 865; goto __pyx_L1;}
+    __pyx_5 = PyTuple_New(1); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 865; goto __pyx_L1;}
+    PyTuple_SET_ITEM(__pyx_5, 0, __pyx_3);
+    __pyx_3 = 0;
+    __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_5); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 865; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    Py_DECREF(__pyx_5); __pyx_5 = 0;
+    __Pyx_Raise(__pyx_4, 0, 0);
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 865; goto __pyx_L1;}
+    goto __pyx_L6;
+  }
+  __pyx_L6:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":866 */
+  __pyx_3 = PyObject_CallObject(((PyObject*)__pyx_ptype_6_loess_loess_predicted), 0); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 866; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_3, __pyx_ptype_6_loess_loess_predicted)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 866; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->predicted));
+  ((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->predicted = ((struct __pyx_obj_6_loess_loess_predicted *)__pyx_3);
+  __pyx_3 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":867 */
+  ((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->predicted->_base = __pyx_v__prediction;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":868 */
+  ((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->predicted->nest = __pyx_v_m;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":870 */
+  Py_INCREF(((PyObject *)((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->predicted));
+  __pyx_r = ((PyObject *)((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->predicted);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  Py_XDECREF(__pyx_4);
+  Py_XDECREF(__pyx_5);
+  __Pyx_AddTraceback("_loess.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_stderror);
+  return __pyx_r;
+}
+
+static void __pyx_f_6_loess_5loess___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_f_6_loess_5loess___dealloc__(PyObject *__pyx_v_self) {
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":873 */
+  loess_free_mem((&((struct __pyx_obj_6_loess_loess *)__pyx_v_self)->_base));
+
+  Py_DECREF(__pyx_v_self);
+}
+
+static PyObject *__pyx_n_isinstance;
+static PyObject *__pyx_n_type;
+static PyObject *__pyx_n_outputs;
+static PyObject *__pyx_n_abs;
+
+static PyObject *__pyx_k133p;
+
+static char (__pyx_k133[]) = "Arguments should be valid loess objects!got '%s' instead";
+
+static int __pyx_f_6_loess_5anova___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_f_6_loess_5anova___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_loess_one = 0;
+  PyObject *__pyx_v_loess_two = 0;
+  double __pyx_v_one_d1;
+  double __pyx_v_one_d2;
+  double __pyx_v_one_s;
+  double __pyx_v_two_d1;
+  double __pyx_v_two_d2;
+  double __pyx_v_two_s;
+  double __pyx_v_rssdiff;
+  double __pyx_v_d1diff;
+  double __pyx_v_tmp;
+  double __pyx_v_df1;
+  double __pyx_v_df2;
+  PyObject *__pyx_v_out_one;
+  PyObject *__pyx_v_out_two;
+  PyObject *__pyx_v_F_value;
+  int __pyx_r;
+  int __pyx_1;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  PyObject *__pyx_4 = 0;
+  int __pyx_5;
+  PyObject *__pyx_6 = 0;
+  double __pyx_7;
+  static char *__pyx_argnames[] = {"loess_one","loess_two",0};
+  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "OO", __pyx_argnames, &__pyx_v_loess_one, &__pyx_v_loess_two)) return -1;
+  Py_INCREF(__pyx_v_self);
+  Py_INCREF(__pyx_v_loess_one);
+  Py_INCREF(__pyx_v_loess_two);
+  __pyx_v_out_one = Py_None; Py_INCREF(Py_None);
+  __pyx_v_out_two = Py_None; Py_INCREF(Py_None);
+  __pyx_v_F_value = Py_None; Py_INCREF(Py_None);
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":887 */
+  __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_isinstance); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 887; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 887; goto __pyx_L1;}
+  Py_INCREF(__pyx_v_loess_one);
+  PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_loess_one);
+  Py_INCREF(((PyObject*)__pyx_ptype_6_loess_loess));
+  PyTuple_SET_ITEM(__pyx_3, 1, ((PyObject*)__pyx_ptype_6_loess_loess));
+  __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 887; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  __pyx_5 = PyObject_IsTrue(__pyx_4); if (__pyx_5 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 887; goto __pyx_L1;}
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+  __pyx_1 = (!__pyx_5);
+  if (!__pyx_1) {
+    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_isinstance); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 887; goto __pyx_L1;}
+    __pyx_3 = PyTuple_New(2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 887; goto __pyx_L1;}
+    Py_INCREF(__pyx_v_loess_two);
+    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_loess_two);
+    Py_INCREF(((PyObject*)__pyx_ptype_6_loess_loess));
+    PyTuple_SET_ITEM(__pyx_3, 1, ((PyObject*)__pyx_ptype_6_loess_loess));
+    __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 887; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    __pyx_5 = PyObject_IsTrue(__pyx_4); if (__pyx_5 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 887; goto __pyx_L1;}
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    __pyx_1 = (!__pyx_5);
+  }
+  if (__pyx_1) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":888 */
+    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 888; goto __pyx_L1;}
+    __pyx_3 = __Pyx_GetName(__pyx_b, __pyx_n_type); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 889; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 889; goto __pyx_L1;}
+    Py_INCREF(__pyx_v_loess_one);
+    PyTuple_SET_ITEM(__pyx_4, 0, __pyx_v_loess_one);
+    __pyx_6 = PyObject_CallObject(__pyx_3, __pyx_4); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 889; goto __pyx_L1;}
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    __pyx_3 = PyNumber_Remainder(__pyx_k133p, __pyx_6); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 889; goto __pyx_L1;}
+    Py_DECREF(__pyx_6); __pyx_6 = 0;
+    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 888; goto __pyx_L1;}
+    PyTuple_SET_ITEM(__pyx_4, 0, __pyx_3);
+    __pyx_3 = 0;
+    __pyx_6 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 888; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    __Pyx_Raise(__pyx_6, 0, 0);
+    Py_DECREF(__pyx_6); __pyx_6 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 888; goto __pyx_L1;}
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":891 */
+  __pyx_3 = PyObject_GetAttr(__pyx_v_loess_one, __pyx_n_outputs); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 891; goto __pyx_L1;}
+  Py_DECREF(__pyx_v_out_one);
+  __pyx_v_out_one = __pyx_3;
+  __pyx_3 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":892 */
+  __pyx_2 = PyObject_GetAttr(__pyx_v_loess_two, __pyx_n_outputs); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 892; goto __pyx_L1;}
+  Py_DECREF(__pyx_v_out_two);
+  __pyx_v_out_two = __pyx_2;
+  __pyx_2 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":894 */
+  __pyx_4 = PyObject_GetAttr(__pyx_v_out_one, __pyx_n_one_delta); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 894; goto __pyx_L1;}
+  __pyx_7 = PyFloat_AsDouble(__pyx_4); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 894; goto __pyx_L1;}
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+  __pyx_v_one_d1 = __pyx_7;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":895 */
+  __pyx_6 = PyObject_GetAttr(__pyx_v_out_one, __pyx_n_two_delta); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 895; goto __pyx_L1;}
+  __pyx_7 = PyFloat_AsDouble(__pyx_6); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 895; goto __pyx_L1;}
+  Py_DECREF(__pyx_6); __pyx_6 = 0;
+  __pyx_v_one_d2 = __pyx_7;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":896 */
+  __pyx_3 = PyObject_GetAttr(__pyx_v_out_one, __pyx_n_s); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 896; goto __pyx_L1;}
+  __pyx_7 = PyFloat_AsDouble(__pyx_3); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 896; goto __pyx_L1;}
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  __pyx_v_one_s = __pyx_7;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":898 */
+  __pyx_2 = PyObject_GetAttr(__pyx_v_out_two, __pyx_n_one_delta); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 898; goto __pyx_L1;}
+  __pyx_7 = PyFloat_AsDouble(__pyx_2); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 898; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_v_two_d1 = __pyx_7;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":899 */
+  __pyx_4 = PyObject_GetAttr(__pyx_v_out_two, __pyx_n_two_delta); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 899; goto __pyx_L1;}
+  __pyx_7 = PyFloat_AsDouble(__pyx_4); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 899; goto __pyx_L1;}
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+  __pyx_v_two_d2 = __pyx_7;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":900 */
+  __pyx_6 = PyObject_GetAttr(__pyx_v_out_two, __pyx_n_s); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 900; goto __pyx_L1;}
+  __pyx_7 = PyFloat_AsDouble(__pyx_6); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 900; goto __pyx_L1;}
+  Py_DECREF(__pyx_6); __pyx_6 = 0;
+  __pyx_v_two_s = __pyx_7;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":902 */
+  __pyx_3 = __Pyx_GetName(__pyx_b, __pyx_n_abs); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 902; goto __pyx_L1;}
+  __pyx_2 = PyFloat_FromDouble((((__pyx_v_one_s * __pyx_v_one_s) * __pyx_v_one_d1) - ((__pyx_v_two_s * __pyx_v_two_s) * __pyx_v_two_d1))); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 902; goto __pyx_L1;}
+  __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 902; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_4, 0, __pyx_2);
+  __pyx_2 = 0;
+  __pyx_6 = PyObject_CallObject(__pyx_3, __pyx_4); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 902; goto __pyx_L1;}
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+  __pyx_7 = PyFloat_AsDouble(__pyx_6); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 902; goto __pyx_L1;}
+  Py_DECREF(__pyx_6); __pyx_6 = 0;
+  __pyx_v_rssdiff = __pyx_7;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":903 */
+  __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_abs); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 903; goto __pyx_L1;}
+  __pyx_3 = PyFloat_FromDouble((__pyx_v_one_d1 - __pyx_v_two_d1)); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 903; goto __pyx_L1;}
+  __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 903; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_4, 0, __pyx_3);
+  __pyx_3 = 0;
+  __pyx_6 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 903; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+  __pyx_7 = PyFloat_AsDouble(__pyx_6); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 903; goto __pyx_L1;}
+  Py_DECREF(__pyx_6); __pyx_6 = 0;
+  __pyx_v_d1diff = __pyx_7;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":904 */
+  __pyx_3 = PyFloat_FromDouble((__pyx_v_d1diff * __pyx_v_d1diff)); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 904; goto __pyx_L1;}
+  __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_abs); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 904; goto __pyx_L1;}
+  __pyx_4 = PyFloat_FromDouble((__pyx_v_one_d2 - __pyx_v_two_d2)); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 904; goto __pyx_L1;}
+  __pyx_6 = PyTuple_New(1); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 904; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_6, 0, __pyx_4);
+  __pyx_4 = 0;
+  __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_6); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 904; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_6); __pyx_6 = 0;
+  __pyx_2 = PyNumber_Divide(__pyx_3, __pyx_4); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 904; goto __pyx_L1;}
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+  __pyx_7 = PyFloat_AsDouble(__pyx_2); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 904; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  ((struct __pyx_obj_6_loess_anova *)__pyx_v_self)->dfn = __pyx_7;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":905 */
+  __pyx_v_df1 = ((struct __pyx_obj_6_loess_anova *)__pyx_v_self)->dfn;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":907 */
+  __pyx_6 = PyObject_GetAttr(__pyx_v_out_one, __pyx_n_enp); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 907; goto __pyx_L1;}
+  __pyx_3 = PyObject_GetAttr(__pyx_v_out_two, __pyx_n_enp); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 907; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_6, __pyx_3, &__pyx_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 907; goto __pyx_L1;}
+  __pyx_5 = __pyx_5 > 0;
+  Py_DECREF(__pyx_6); __pyx_6 = 0;
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  if (__pyx_5) {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":908 */
+    ((struct __pyx_obj_6_loess_anova *)__pyx_v_self)->dfd = ((__pyx_v_one_d1 * __pyx_v_one_d1) / __pyx_v_one_d2);
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":909 */
+    __pyx_v_tmp = __pyx_v_one_s;
+    goto __pyx_L3;
+  }
+  /*else*/ {
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":911 */
+    ((struct __pyx_obj_6_loess_anova *)__pyx_v_self)->dfd = ((__pyx_v_two_d1 * __pyx_v_two_d1) / __pyx_v_two_d2);
+
+    /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":912 */
+    __pyx_v_tmp = __pyx_v_two_s;
+  }
+  __pyx_L3:;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":913 */
+  __pyx_v_df2 = ((struct __pyx_obj_6_loess_anova *)__pyx_v_self)->dfd;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":914 */
+  __pyx_4 = PyFloat_FromDouble(((__pyx_v_rssdiff / __pyx_v_d1diff) / (__pyx_v_tmp * __pyx_v_tmp))); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 914; goto __pyx_L1;}
+  Py_DECREF(__pyx_v_F_value);
+  __pyx_v_F_value = __pyx_4;
+  __pyx_4 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":916 */
+  __pyx_2 = PyFloat_FromDouble(__pyx_v_df1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 916; goto __pyx_L1;}
+  __pyx_6 = PyNumber_Multiply(__pyx_v_F_value, __pyx_2); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 916; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_3 = PyFloat_FromDouble(__pyx_v_df2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 916; goto __pyx_L1;}
+  __pyx_4 = PyFloat_FromDouble(__pyx_v_df1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 916; goto __pyx_L1;}
+  __pyx_2 = PyNumber_Multiply(__pyx_v_F_value, __pyx_4); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 916; goto __pyx_L1;}
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+  __pyx_4 = PyNumber_Add(__pyx_3, __pyx_2); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 916; goto __pyx_L1;}
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_3 = PyNumber_Divide(__pyx_6, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 916; goto __pyx_L1;}
+  Py_DECREF(__pyx_6); __pyx_6 = 0;
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+  __pyx_7 = PyFloat_AsDouble(__pyx_3); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 916; goto __pyx_L1;}
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  ((struct __pyx_obj_6_loess_anova *)__pyx_v_self)->Pr_F = (1. - ibeta(__pyx_7,(__pyx_v_df1 / 2),(__pyx_v_df2 / 2)));
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":917 */
+  __pyx_7 = PyFloat_AsDouble(__pyx_v_F_value); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 917; goto __pyx_L1;}
+  ((struct __pyx_obj_6_loess_anova *)__pyx_v_self)->F_value = __pyx_7;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  Py_XDECREF(__pyx_4);
+  Py_XDECREF(__pyx_6);
+  __Pyx_AddTraceback("_loess.anova.__init__");
+  __pyx_r = -1;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_out_one);
+  Py_DECREF(__pyx_v_out_two);
+  Py_DECREF(__pyx_v_F_value);
+  Py_DECREF(__pyx_v_self);
+  Py_DECREF(__pyx_v_loess_one);
+  Py_DECREF(__pyx_v_loess_two);
+  return __pyx_r;
+}
+
+static __Pyx_InternTabEntry __pyx_intern_tab[] = {
+  {&__pyx_n_C, "C"},
+  {&__pyx_n_False, "False"},
+  {&__pyx_n_T, "T"},
+  {&__pyx_n_True, "True"},
+  {&__pyx_n_ValueError, "ValueError"},
+  {&__pyx_n_abs, "abs"},
+  {&__pyx_n_approximate, "approximate"},
+  {&__pyx_n_array, "array"},
+  {&__pyx_n_astype, "astype"},
+  {&__pyx_n_atleast_1d, "atleast_1d"},
+  {&__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_enp, "enp"},
+  {&__pyx_n_exact, "exact"},
+  {&__pyx_n_family, "family"},
+  {&__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_interpolate, "interpolate"},
+  {&__pyx_n_isinstance, "isinstance"},
+  {&__pyx_n_iterations, "iterations"},
+  {&__pyx_n_iteritems, "iteritems"},
+  {&__pyx_n_join, "join"},
+  {&__pyx_n_len, "len"},
+  {&__pyx_n_lower, "lower"},
+  {&__pyx_n_min, "min"},
+  {&__pyx_n_narray, "narray"},
+  {&__pyx_n_ndim, "ndim"},
+  {&__pyx_n_nobs, "nobs"},
+  {&__pyx_n_normalize, "normalize"},
+  {&__pyx_n_numpy, "numpy"},
+  {&__pyx_n_one_delta, "one_delta"},
+  {&__pyx_n_order, "order"},
+  {&__pyx_n_outputs, "outputs"},
+  {&__pyx_n_parametric, "parametric"},
+  {&__pyx_n_parametric_flags, "parametric_flags"},
+  {&__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_type, "type"},
+  {&__pyx_n_update, "update"},
+  {&__pyx_n_values, "values"},
+  {0, 0}
+};
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_k35p, __pyx_k35, sizeof(__pyx_k35)},
+  {&__pyx_k38p, __pyx_k38, sizeof(__pyx_k38)},
+  {&__pyx_k39p, __pyx_k39, sizeof(__pyx_k39)},
+  {&__pyx_k42p, __pyx_k42, sizeof(__pyx_k42)},
+  {&__pyx_k45p, __pyx_k45, sizeof(__pyx_k45)},
+  {&__pyx_k46p, __pyx_k46, sizeof(__pyx_k46)},
+  {&__pyx_k47p, __pyx_k47, sizeof(__pyx_k47)},
+  {&__pyx_k53p, __pyx_k53, sizeof(__pyx_k53)},
+  {&__pyx_k54p, __pyx_k54, sizeof(__pyx_k54)},
+  {&__pyx_k55p, __pyx_k55, sizeof(__pyx_k55)},
+  {&__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_k64p, __pyx_k64, sizeof(__pyx_k64)},
+  {&__pyx_k77p, __pyx_k77, sizeof(__pyx_k77)},
+  {&__pyx_k78p, __pyx_k78, sizeof(__pyx_k78)},
+  {&__pyx_k79p, __pyx_k79, sizeof(__pyx_k79)},
+  {&__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_k110p, __pyx_k110, sizeof(__pyx_k110)},
+  {&__pyx_k122p, __pyx_k122, sizeof(__pyx_k122)},
+  {&__pyx_k123p, __pyx_k123, sizeof(__pyx_k123)},
+  {&__pyx_k125p, __pyx_k125, sizeof(__pyx_k125)},
+  {&__pyx_k126p, __pyx_k126, sizeof(__pyx_k126)},
+  {&__pyx_k131p, __pyx_k131, sizeof(__pyx_k131)},
+  {&__pyx_k132p, __pyx_k132, sizeof(__pyx_k132)},
+  {&__pyx_k133p, __pyx_k133, sizeof(__pyx_k133)},
+  {0, 0, 0}
+};
+
+static PyObject *__pyx_tp_new_6_loess_loess_inputs(PyTypeObject *t, PyObject *a, PyObject *k) {
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  return o;
+}
+
+static void __pyx_tp_dealloc_6_loess_loess_inputs(PyObject *o) {
+  (*o->ob_type->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_6_loess_loess_inputs(PyObject *o, visitproc v, void *a) {
+  return 0;
+}
+
+static int __pyx_tp_clear_6_loess_loess_inputs(PyObject *o) {
+  return 0;
+}
+
+static PyObject *__pyx_getprop_6_loess_12loess_inputs_x(PyObject *o, void *x) {
+  return __pyx_f_6_loess_12loess_inputs_1x___get__(o);
+}
+
+static PyObject *__pyx_getprop_6_loess_12loess_inputs_y(PyObject *o, void *x) {
+  return __pyx_f_6_loess_12loess_inputs_1y___get__(o);
+}
+
+static PyObject *__pyx_getprop_6_loess_12loess_inputs_weights(PyObject *o, void *x) {
+  return __pyx_f_6_loess_12loess_inputs_7weights___get__(o);
+}
+
+static int __pyx_setprop_6_loess_12loess_inputs_weights(PyObject *o, PyObject *v, void *x) {
+  if (v) {
+    return __pyx_f_6_loess_12loess_inputs_7weights___set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_6_loess_12loess_inputs_nobs(PyObject *o, void *x) {
+  return __pyx_f_6_loess_12loess_inputs_4nobs___get__(o);
+}
+
+static PyObject *__pyx_getprop_6_loess_12loess_inputs_npar(PyObject *o, void *x) {
+  return __pyx_f_6_loess_12loess_inputs_4npar___get__(o);
+}
+
+static struct PyMethodDef __pyx_methods_6_loess_loess_inputs[] = {
+  {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_6_loess_loess_inputs[] = {
+  {"x", __pyx_getprop_6_loess_12loess_inputs_x, 0, 0, 0},
+  {"y", __pyx_getprop_6_loess_12loess_inputs_y, 0, 0, 0},
+  {"weights", __pyx_getprop_6_loess_12loess_inputs_weights, __pyx_setprop_6_loess_12loess_inputs_weights, __pyx_k1, 0},
+  {"nobs", __pyx_getprop_6_loess_12loess_inputs_nobs, 0, __pyx_k2, 0},
+  {"npar", __pyx_getprop_6_loess_12loess_inputs_npar, 0, __pyx_k3, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_loess_inputs = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  0, /*nb_divide*/
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  0, /*nb_coerce*/
+  0, /*nb_int*/
+  0, /*nb_long*/
+  0, /*nb_float*/
+  0, /*nb_oct*/
+  0, /*nb_hex*/
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  0, /*nb_inplace_divide*/
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_loess_inputs = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_loess_inputs = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_loess_inputs = {
+  0, /*bf_getreadbuffer*/
+  0, /*bf_getwritebuffer*/
+  0, /*bf_getsegcount*/
+  0, /*bf_getcharbuffer*/
+};
+
+PyTypeObject __pyx_type_6_loess_loess_inputs = {
+  PyObject_HEAD_INIT(0)
+  0, /*ob_size*/
+  "_loess.loess_inputs", /*tp_name*/
+  sizeof(struct __pyx_obj_6_loess_loess_inputs), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_6_loess_loess_inputs, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  0, /*tp_compare*/
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_loess_inputs, /*tp_as_number*/
+  &__pyx_tp_as_sequence_loess_inputs, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_loess_inputs, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_loess_inputs, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_6_loess_loess_inputs, /*tp_traverse*/
+  __pyx_tp_clear_6_loess_loess_inputs, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_6_loess_loess_inputs, /*tp_methods*/
+  0, /*tp_members*/
+  __pyx_getsets_6_loess_loess_inputs, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_6_loess_loess_inputs, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+};
+
+static PyObject *__pyx_tp_new_6_loess_loess_control(PyTypeObject *t, PyObject *a, PyObject *k) {
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  return o;
+}
+
+static void __pyx_tp_dealloc_6_loess_loess_control(PyObject *o) {
+  (*o->ob_type->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_6_loess_loess_control(PyObject *o, visitproc v, void *a) {
+  return 0;
+}
+
+static int __pyx_tp_clear_6_loess_loess_control(PyObject *o) {
+  return 0;
+}
+
+static PyObject *__pyx_getprop_6_loess_13loess_control_surface(PyObject *o, void *x) {
+  return __pyx_f_6_loess_13loess_control_7surface___get__(o);
+}
+
+static int __pyx_setprop_6_loess_13loess_control_surface(PyObject *o, PyObject *v, void *x) {
+  if (v) {
+    return __pyx_f_6_loess_13loess_control_7surface___set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_6_loess_13loess_control_statistics(PyObject *o, void *x) {
+  return __pyx_f_6_loess_13loess_control_10statistics___get__(o);
+}
+
+static int __pyx_setprop_6_loess_13loess_control_statistics(PyObject *o, PyObject *v, void *x) {
+  if (v) {
+    return __pyx_f_6_loess_13loess_control_10statistics___set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_6_loess_13loess_control_trace_hat(PyObject *o, void *x) {
+  return __pyx_f_6_loess_13loess_control_9trace_hat___get__(o);
+}
+
+static int __pyx_setprop_6_loess_13loess_control_trace_hat(PyObject *o, PyObject *v, void *x) {
+  if (v) {
+    return __pyx_f_6_loess_13loess_control_9trace_hat___set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_6_loess_13loess_control_iterations(PyObject *o, void *x) {
+  return __pyx_f_6_loess_13loess_control_10iterations___get__(o);
+}
+
+static int __pyx_setprop_6_loess_13loess_control_iterations(PyObject *o, PyObject *v, void *x) {
+  if (v) {
+    return __pyx_f_6_loess_13loess_control_10iterations___set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_6_loess_13loess_control_cell(PyObject *o, void *x) {
+  return __pyx_f_6_loess_13loess_control_4cell___get__(o);
+}
+
+static int __pyx_setprop_6_loess_13loess_control_cell(PyObject *o, PyObject *v, void *x) {
+  if (v) {
+    return __pyx_f_6_loess_13loess_control_4cell___set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static struct PyMethodDef __pyx_methods_6_loess_loess_control[] = {
+  {"update", (PyCFunction)__pyx_f_6_loess_13loess_control_update, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6_loess_13loess_control_update},
+  {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_6_loess_loess_control[] = {
+  {"surface", __pyx_getprop_6_loess_13loess_control_surface, __pyx_setprop_6_loess_13loess_control_surface, __pyx_k4, 0},
+  {"statistics", __pyx_getprop_6_loess_13loess_control_statistics, __pyx_setprop_6_loess_13loess_control_statistics, __pyx_k5, 0},
+  {"trace_hat", __pyx_getprop_6_loess_13loess_control_trace_hat, __pyx_setprop_6_loess_13loess_control_trace_hat, __pyx_k6, 0},
+  {"iterations", __pyx_getprop_6_loess_13loess_control_iterations, __pyx_setprop_6_loess_13loess_control_iterations, __pyx_k7, 0},
+  {"cell", __pyx_getprop_6_loess_13loess_control_cell, __pyx_setprop_6_loess_13loess_control_cell, __pyx_k8, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_loess_control = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  0, /*nb_divide*/
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  0, /*nb_coerce*/
+  0, /*nb_int*/
+  0, /*nb_long*/
+  0, /*nb_float*/
+  0, /*nb_oct*/
+  0, /*nb_hex*/
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  0, /*nb_inplace_divide*/
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_loess_control = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_loess_control = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_loess_control = {
+  0, /*bf_getreadbuffer*/
+  0, /*bf_getwritebuffer*/
+  0, /*bf_getsegcount*/
+  0, /*bf_getcharbuffer*/
+};
+
+PyTypeObject __pyx_type_6_loess_loess_control = {
+  PyObject_HEAD_INIT(0)
+  0, /*ob_size*/
+  "_loess.loess_control", /*tp_name*/
+  sizeof(struct __pyx_obj_6_loess_loess_control), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_6_loess_loess_control, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  0, /*tp_compare*/
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_loess_control, /*tp_as_number*/
+  &__pyx_tp_as_sequence_loess_control, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_loess_control, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  __pyx_f_6_loess_13loess_control___str__, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_loess_control, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_6_loess_loess_control, /*tp_traverse*/
+  __pyx_tp_clear_6_loess_loess_control, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_6_loess_loess_control, /*tp_methods*/
+  0, /*tp_members*/
+  __pyx_getsets_6_loess_loess_control, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_6_loess_loess_control, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+};
+
+static PyObject *__pyx_tp_new_6_loess_loess_kd_tree(PyTypeObject *t, PyObject *a, PyObject *k) {
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  return o;
+}
+
+static void __pyx_tp_dealloc_6_loess_loess_kd_tree(PyObject *o) {
+  (*o->ob_type->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_6_loess_loess_kd_tree(PyObject *o, visitproc v, void *a) {
+  return 0;
+}
+
+static int __pyx_tp_clear_6_loess_loess_kd_tree(PyObject *o) {
+  return 0;
+}
+
+static struct PyMethodDef __pyx_methods_6_loess_loess_kd_tree[] = {
+  {0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_loess_kd_tree = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  0, /*nb_divide*/
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  0, /*nb_coerce*/
+  0, /*nb_int*/
+  0, /*nb_long*/
+  0, /*nb_float*/
+  0, /*nb_oct*/
+  0, /*nb_hex*/
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  0, /*nb_inplace_divide*/
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_loess_kd_tree = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_loess_kd_tree = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_loess_kd_tree = {
+  0, /*bf_getreadbuffer*/
+  0, /*bf_getwritebuffer*/
+  0, /*bf_getsegcount*/
+  0, /*bf_getcharbuffer*/
+};
+
+PyTypeObject __pyx_type_6_loess_loess_kd_tree = {
+  PyObject_HEAD_INIT(0)
+  0, /*ob_size*/
+  "_loess.loess_kd_tree", /*tp_name*/
+  sizeof(struct __pyx_obj_6_loess_loess_kd_tree), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_6_loess_loess_kd_tree, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  0, /*tp_compare*/
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_loess_kd_tree, /*tp_as_number*/
+  &__pyx_tp_as_sequence_loess_kd_tree, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_loess_kd_tree, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_loess_kd_tree, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_6_loess_loess_kd_tree, /*tp_traverse*/
+  __pyx_tp_clear_6_loess_loess_kd_tree, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_6_loess_loess_kd_tree, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_6_loess_loess_kd_tree, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+};
+static struct __pyx_vtabstruct_6_loess_loess_model __pyx_vtable_6_loess_loess_model;
+
+static PyObject *__pyx_tp_new_6_loess_loess_model(PyTypeObject *t, PyObject *a, PyObject *k) {
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  struct __pyx_obj_6_loess_loess_model *p = (struct __pyx_obj_6_loess_loess_model *)o;
+  *(struct __pyx_vtabstruct_6_loess_loess_model **)&p->__pyx_vtab = __pyx_vtabptr_6_loess_loess_model;
+  return o;
+}
+
+static void __pyx_tp_dealloc_6_loess_loess_model(PyObject *o) {
+  (*o->ob_type->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_6_loess_loess_model(PyObject *o, visitproc v, void *a) {
+  return 0;
+}
+
+static int __pyx_tp_clear_6_loess_loess_model(PyObject *o) {
+  return 0;
+}
+
+static PyObject *__pyx_getprop_6_loess_11loess_model_normalize(PyObject *o, void *x) {
+  return __pyx_f_6_loess_11loess_model_9normalize___get__(o);
+}
+
+static int __pyx_setprop_6_loess_11loess_model_normalize(PyObject *o, PyObject *v, void *x) {
+  if (v) {
+    return __pyx_f_6_loess_11loess_model_9normalize___set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_6_loess_11loess_model_span(PyObject *o, void *x) {
+  return __pyx_f_6_loess_11loess_model_4span___get__(o);
+}
+
+static int __pyx_setprop_6_loess_11loess_model_span(PyObject *o, PyObject *v, void *x) {
+  if (v) {
+    return __pyx_f_6_loess_11loess_model_4span___set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_6_loess_11loess_model_degree(PyObject *o, void *x) {
+  return __pyx_f_6_loess_11loess_model_6degree___get__(o);
+}
+
+static int __pyx_setprop_6_loess_11loess_model_degree(PyObject *o, PyObject *v, void *x) {
+  if (v) {
+    return __pyx_f_6_loess_11loess_model_6degree___set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_6_loess_11loess_model_family(PyObject *o, void *x) {
+  return __pyx_f_6_loess_11loess_model_6family___get__(o);
+}
+
+static int __pyx_setprop_6_loess_11loess_model_family(PyObject *o, PyObject *v, void *x) {
+  if (v) {
+    return __pyx_f_6_loess_11loess_model_6family___set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_6_loess_11loess_model_parametric_flags(PyObject *o, void *x) {
+  return __pyx_f_6_loess_11loess_model_16parametric_flags___get__(o);
+}
+
+static int __pyx_setprop_6_loess_11loess_model_parametric_flags(PyObject *o, PyObject *v, void *x) {
+  if (v) {
+    return __pyx_f_6_loess_11loess_model_16parametric_flags___set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static PyObject *__pyx_getprop_6_loess_11loess_model_drop_square_flags(PyObject *o, void *x) {
+  return __pyx_f_6_loess_11loess_model_17drop_square_flags___get__(o);
+}
+
+static int __pyx_setprop_6_loess_11loess_model_drop_square_flags(PyObject *o, PyObject *v, void *x) {
+  if (v) {
+    return __pyx_f_6_loess_11loess_model_17drop_square_flags___set__(o, v);
+  }
+  else {
+    PyErr_SetString(PyExc_NotImplementedError, "__del__");
+    return -1;
+  }
+}
+
+static struct PyMethodDef __pyx_methods_6_loess_loess_model[] = {
+  {"update", (PyCFunction)__pyx_f_6_loess_11loess_model_update, METH_VARARGS|METH_KEYWORDS, 0},
+  {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_6_loess_loess_model[] = {
+  {"normalize", __pyx_getprop_6_loess_11loess_model_normalize, __pyx_setprop_6_loess_11loess_model_normalize, __pyx_k9, 0},
+  {"span", __pyx_getprop_6_loess_11loess_model_span, __pyx_setprop_6_loess_11loess_model_span, __pyx_k10, 0},
+  {"degree", __pyx_getprop_6_loess_11loess_model_degree, __pyx_setprop_6_loess_11loess_model_degree, __pyx_k11, 0},
+  {"family", __pyx_getprop_6_loess_11loess_model_family, __pyx_setprop_6_loess_11loess_model_family, __pyx_k12, 0},
+  {"parametric_flags", __pyx_getprop_6_loess_11loess_model_parametric_flags, __pyx_setprop_6_loess_11loess_model_parametric_flags, __pyx_k13, 0},
+  {"drop_square_flags", __pyx_getprop_6_loess_11loess_model_drop_square_flags, __pyx_setprop_6_loess_11loess_model_drop_square_flags, __pyx_k14, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_loess_model = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  0, /*nb_divide*/
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  0, /*nb_coerce*/
+  0, /*nb_int*/
+  0, /*nb_long*/
+  0, /*nb_float*/
+  0, /*nb_oct*/
+  0, /*nb_hex*/
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  0, /*nb_inplace_divide*/
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_loess_model = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_loess_model = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_loess_model = {
+  0, /*bf_getreadbuffer*/
+  0, /*bf_getwritebuffer*/
+  0, /*bf_getsegcount*/
+  0, /*bf_getcharbuffer*/
+};
+
+PyTypeObject __pyx_type_6_loess_loess_model = {
+  PyObject_HEAD_INIT(0)
+  0, /*ob_size*/
+  "_loess.loess_model", /*tp_name*/
+  sizeof(struct __pyx_obj_6_loess_loess_model), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_6_loess_loess_model, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  0, /*tp_compare*/
+  __pyx_f_6_loess_11loess_model___repr__, /*tp_repr*/
+  &__pyx_tp_as_number_loess_model, /*tp_as_number*/
+  &__pyx_tp_as_sequence_loess_model, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_loess_model, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  __pyx_f_6_loess_11loess_model___str__, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_loess_model, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_6_loess_loess_model, /*tp_traverse*/
+  __pyx_tp_clear_6_loess_loess_model, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_6_loess_loess_model, /*tp_methods*/
+  0, /*tp_members*/
+  __pyx_getsets_6_loess_loess_model, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_6_loess_loess_model, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+};
+
+static PyObject *__pyx_tp_new_6_loess_loess_outputs(PyTypeObject *t, PyObject *a, PyObject *k) {
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  return o;
+}
+
+static void __pyx_tp_dealloc_6_loess_loess_outputs(PyObject *o) {
+  (*o->ob_type->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_6_loess_loess_outputs(PyObject *o, visitproc v, void *a) {
+  return 0;
+}
+
+static int __pyx_tp_clear_6_loess_loess_outputs(PyObject *o) {
+  return 0;
+}
+
+static PyObject *__pyx_getprop_6_loess_13loess_outputs_fitted_values(PyObject *o, void *x) {
+  return __pyx_f_6_loess_13loess_outputs_13fitted_values___get__(o);
+}
+
+static PyObject *__pyx_getprop_6_loess_13loess_outputs_fitted_residuals(PyObject *o, void *x) {
+  return __pyx_f_6_loess_13loess_outputs_16fitted_residuals___get__(o);
+}
+
+static PyObject *__pyx_getprop_6_loess_13loess_outputs_pseudovalues(PyObject *o, void *x) {
+  return __pyx_f_6_loess_13loess_outputs_12pseudovalues___get__(o);
+}
+
+static PyObject *__pyx_getprop_6_loess_13loess_outputs_diagonal(PyObject *o, void *x) {
+  return __pyx_f_6_loess_13loess_outputs_8diagonal___get__(o);
+}
+
+static PyObject *__pyx_getprop_6_loess_13loess_outputs_robust(PyObject *o, void *x) {
+  return __pyx_f_6_loess_13loess_outputs_6robust___get__(o);
+}
+
+static PyObject *__pyx_getprop_6_loess_13loess_outputs_divisor(PyObject *o, void *x) {
+  return __pyx_f_6_loess_13loess_outputs_7divisor___get__(o);
+}
+
+static PyObject *__pyx_getprop_6_loess_13loess_outputs_enp(PyObject *o, void *x) {
+  return __pyx_f_6_loess_13loess_outputs_3enp___get__(o);
+}
+
+static PyObject *__pyx_getprop_6_loess_13loess_outputs_s(PyObject *o, void *x) {
+  return __pyx_f_6_loess_13loess_outputs_1s___get__(o);
+}
+
+static PyObject *__pyx_getprop_6_loess_13loess_outputs_one_delta(PyObject *o, void *x) {
+  return __pyx_f_6_loess_13loess_outputs_9one_delta___get__(o);
+}
+
+static PyObject *__pyx_getprop_6_loess_13loess_outputs_two_delta(PyObject *o, void *x) {
+  return __pyx_f_6_loess_13loess_outputs_9two_delta___get__(o);
+}
+
+static PyObject *__pyx_getprop_6_loess_13loess_outputs_trace_hat(PyObject *o, void *x) {
+  return __pyx_f_6_loess_13loess_outputs_9trace_hat___get__(o);
+}
+
+static struct PyMethodDef __pyx_methods_6_loess_loess_outputs[] = {
+  {0, 0, 0, 0}
+};
+
+static struct PyMemberDef __pyx_members_6_loess_loess_outputs[] = {
+  {"activated", T_INT, offsetof(struct __pyx_obj_6_loess_loess_outputs, activated), READONLY, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_6_loess_loess_outputs[] = {
+  {"fitted_values", __pyx_getprop_6_loess_13loess_outputs_fitted_values, 0, __pyx_k15, 0},
+  {"fitted_residuals", __pyx_getprop_6_loess_13loess_outputs_fitted_residuals, 0, __pyx_k16, 0},
+  {"pseudovalues", __pyx_getprop_6_loess_13loess_outputs_pseudovalues, 0, __pyx_k17, 0},
+  {"diagonal", __pyx_getprop_6_loess_13loess_outputs_diagonal, 0, __pyx_k18, 0},
+  {"robust", __pyx_getprop_6_loess_13loess_outputs_robust, 0, __pyx_k19, 0},
+  {"divisor", __pyx_getprop_6_loess_13loess_outputs_divisor, 0, __pyx_k20, 0},
+  {"enp", __pyx_getprop_6_loess_13loess_outputs_enp, 0, __pyx_k21, 0},
+  {"s", __pyx_getprop_6_loess_13loess_outputs_s, 0, __pyx_k22, 0},
+  {"one_delta", __pyx_getprop_6_loess_13loess_outputs_one_delta, 0, __pyx_k23, 0},
+  {"two_delta", __pyx_getprop_6_loess_13loess_outputs_two_delta, 0, __pyx_k24, 0},
+  {"trace_hat", __pyx_getprop_6_loess_13loess_outputs_trace_hat, 0, __pyx_k25, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_loess_outputs = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  0, /*nb_divide*/
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  0, /*nb_coerce*/
+  0, /*nb_int*/
+  0, /*nb_long*/
+  0, /*nb_float*/
+  0, /*nb_oct*/
+  0, /*nb_hex*/
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  0, /*nb_inplace_divide*/
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_loess_outputs = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_loess_outputs = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_loess_outputs = {
+  0, /*bf_getreadbuffer*/
+  0, /*bf_getwritebuffer*/
+  0, /*bf_getsegcount*/
+  0, /*bf_getcharbuffer*/
+};
+
+PyTypeObject __pyx_type_6_loess_loess_outputs = {
+  PyObject_HEAD_INIT(0)
+  0, /*ob_size*/
+  "_loess.loess_outputs", /*tp_name*/
+  sizeof(struct __pyx_obj_6_loess_loess_outputs), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_6_loess_loess_outputs, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  0, /*tp_compare*/
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_loess_outputs, /*tp_as_number*/
+  &__pyx_tp_as_sequence_loess_outputs, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_loess_outputs, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  __pyx_f_6_loess_13loess_outputs___str__, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_loess_outputs, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_6_loess_loess_outputs, /*tp_traverse*/
+  __pyx_tp_clear_6_loess_loess_outputs, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_6_loess_loess_outputs, /*tp_methods*/
+  __pyx_members_6_loess_loess_outputs, /*tp_members*/
+  __pyx_getsets_6_loess_loess_outputs, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_6_loess_loess_outputs, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+};
+static struct __pyx_vtabstruct_6_loess_conf_intervals __pyx_vtable_6_loess_conf_intervals;
+
+static PyObject *__pyx_tp_new_6_loess_conf_intervals(PyTypeObject *t, PyObject *a, PyObject *k) {
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  struct __pyx_obj_6_loess_conf_intervals *p = (struct __pyx_obj_6_loess_conf_intervals *)o;
+  *(struct __pyx_vtabstruct_6_loess_conf_intervals **)&p->__pyx_vtab = __pyx_vtabptr_6_loess_conf_intervals;
+  p->lower = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  p->fit = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  p->upper = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  return o;
+}
+
+static void __pyx_tp_dealloc_6_loess_conf_intervals(PyObject *o) {
+  struct __pyx_obj_6_loess_conf_intervals *p = (struct __pyx_obj_6_loess_conf_intervals *)o;
+  Py_XDECREF(((PyObject *)p->lower));
+  Py_XDECREF(((PyObject *)p->fit));
+  Py_XDECREF(((PyObject *)p->upper));
+  (*o->ob_type->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_6_loess_conf_intervals(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_6_loess_conf_intervals *p = (struct __pyx_obj_6_loess_conf_intervals *)o;
+  if (p->lower) {
+    e = (*v)(((PyObject*)p->lower), a); if (e) return e;
+  }
+  if (p->fit) {
+    e = (*v)(((PyObject*)p->fit), a); if (e) return e;
+  }
+  if (p->upper) {
+    e = (*v)(((PyObject*)p->upper), a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_6_loess_conf_intervals(PyObject *o) {
+  struct __pyx_obj_6_loess_conf_intervals *p = (struct __pyx_obj_6_loess_conf_intervals *)o;
+  Py_XDECREF(((PyObject *)p->lower));
+  p->lower = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(((PyObject *)p->fit));
+  p->fit = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(((PyObject *)p->upper));
+  p->upper = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  return 0;
+}
+
+static struct PyMethodDef __pyx_methods_6_loess_conf_intervals[] = {
+  {0, 0, 0, 0}
+};
+
+static struct PyMemberDef __pyx_members_6_loess_conf_intervals[] = {
+  {"lower", T_OBJECT, offsetof(struct __pyx_obj_6_loess_conf_intervals, lower), READONLY, 0},
+  {"fit", T_OBJECT, offsetof(struct __pyx_obj_6_loess_conf_intervals, fit), READONLY, 0},
+  {"upper", T_OBJECT, offsetof(struct __pyx_obj_6_loess_conf_intervals, upper), READONLY, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_conf_intervals = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  0, /*nb_divide*/
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  0, /*nb_coerce*/
+  0, /*nb_int*/
+  0, /*nb_long*/
+  0, /*nb_float*/
+  0, /*nb_oct*/
+  0, /*nb_hex*/
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  0, /*nb_inplace_divide*/
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_conf_intervals = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_conf_intervals = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_conf_intervals = {
+  0, /*bf_getreadbuffer*/
+  0, /*bf_getwritebuffer*/
+  0, /*bf_getsegcount*/
+  0, /*bf_getcharbuffer*/
+};
+
+PyTypeObject __pyx_type_6_loess_conf_intervals = {
+  PyObject_HEAD_INIT(0)
+  0, /*ob_size*/
+  "_loess.conf_intervals", /*tp_name*/
+  sizeof(struct __pyx_obj_6_loess_conf_intervals), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_6_loess_conf_intervals, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  0, /*tp_compare*/
+  0, /*tp_repr*/
+  &__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*/
+  __pyx_f_6_loess_14conf_intervals___str__, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__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_6_loess_conf_intervals, /*tp_traverse*/
+  __pyx_tp_clear_6_loess_conf_intervals, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_6_loess_conf_intervals, /*tp_methods*/
+  __pyx_members_6_loess_conf_intervals, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_6_loess_conf_intervals, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+};
+static struct __pyx_vtabstruct_6_loess_loess_predicted __pyx_vtable_6_loess_loess_predicted;
+
+static PyObject *__pyx_tp_new_6_loess_loess_predicted(PyTypeObject *t, PyObject *a, PyObject *k) {
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  struct __pyx_obj_6_loess_loess_predicted *p = (struct __pyx_obj_6_loess_loess_predicted *)o;
+  *(struct __pyx_vtabstruct_6_loess_loess_predicted **)&p->__pyx_vtab = __pyx_vtabptr_6_loess_loess_predicted;
+  p->confidence_intervals = ((struct __pyx_obj_6_loess_conf_intervals *)Py_None); Py_INCREF(Py_None);
+  return o;
+}
+
+static void __pyx_tp_dealloc_6_loess_loess_predicted(PyObject *o) {
+  struct __pyx_obj_6_loess_loess_predicted *p = (struct __pyx_obj_6_loess_loess_predicted *)o;
+  {
+    PyObject *etype, *eval, *etb;
+    PyErr_Fetch(&etype, &eval, &etb);
+    ++o->ob_refcnt;
+    __pyx_f_6_loess_15loess_predicted___dealloc__(o);
+    if (PyErr_Occurred()) PyErr_WriteUnraisable(o);
+    --o->ob_refcnt;
+    PyErr_Restore(etype, eval, etb);
+  }
+  Py_XDECREF(((PyObject *)p->confidence_intervals));
+  (*o->ob_type->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_6_loess_loess_predicted(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_6_loess_loess_predicted *p = (struct __pyx_obj_6_loess_loess_predicted *)o;
+  if (p->confidence_intervals) {
+    e = (*v)(((PyObject*)p->confidence_intervals), a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_6_loess_loess_predicted(PyObject *o) {
+  struct __pyx_obj_6_loess_loess_predicted *p = (struct __pyx_obj_6_loess_loess_predicted *)o;
+  Py_XDECREF(((PyObject *)p->confidence_intervals));
+  p->confidence_intervals = ((struct __pyx_obj_6_loess_conf_intervals *)Py_None); Py_INCREF(Py_None);
+  return 0;
+}
+
+static PyObject *__pyx_getprop_6_loess_15loess_predicted_values(PyObject *o, void *x) {
+  return __pyx_f_6_loess_15loess_predicted_6values___get__(o);
+}
+
+static PyObject *__pyx_getprop_6_loess_15loess_predicted_stderr(PyObject *o, void *x) {
+  return __pyx_f_6_loess_15loess_predicted_6stderr___get__(o);
+}
+
+static PyObject *__pyx_getprop_6_loess_15loess_predicted_residual_scale(PyObject *o, void *x) {
+  return __pyx_f_6_loess_15loess_predicted_14residual_scale___get__(o);
+}
+
+static PyObject *__pyx_getprop_6_loess_15loess_predicted_df(PyObject *o, void *x) {
+  return __pyx_f_6_loess_15loess_predicted_2df___get__(o);
+}
+
+static struct PyMethodDef __pyx_methods_6_loess_loess_predicted[] = {
+  {"confidence", (PyCFunction)__pyx_f_6_loess_15loess_predicted_confidence, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6_loess_15loess_predicted_confidence},
+  {0, 0, 0, 0}
+};
+
+static struct PyMemberDef __pyx_members_6_loess_loess_predicted[] = {
+  {"nest", T_LONG, offsetof(struct __pyx_obj_6_loess_loess_predicted, nest), READONLY, 0},
+  {"confidence_intervals", T_OBJECT, offsetof(struct __pyx_obj_6_loess_loess_predicted, confidence_intervals), READONLY, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_6_loess_loess_predicted[] = {
+  {"values", __pyx_getprop_6_loess_15loess_predicted_values, 0, __pyx_k26, 0},
+  {"stderr", __pyx_getprop_6_loess_15loess_predicted_stderr, 0, __pyx_k27, 0},
+  {"residual_scale", __pyx_getprop_6_loess_15loess_predicted_residual_scale, 0, __pyx_k28, 0},
+  {"df", __pyx_getprop_6_loess_15loess_predicted_df, 0, __pyx_k29, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_loess_predicted = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  0, /*nb_divide*/
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  0, /*nb_coerce*/
+  0, /*nb_int*/
+  0, /*nb_long*/
+  0, /*nb_float*/
+  0, /*nb_oct*/
+  0, /*nb_hex*/
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  0, /*nb_inplace_divide*/
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_loess_predicted = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_loess_predicted = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_loess_predicted = {
+  0, /*bf_getreadbuffer*/
+  0, /*bf_getwritebuffer*/
+  0, /*bf_getsegcount*/
+  0, /*bf_getcharbuffer*/
+};
+
+PyTypeObject __pyx_type_6_loess_loess_predicted = {
+  PyObject_HEAD_INIT(0)
+  0, /*ob_size*/
+  "_loess.loess_predicted", /*tp_name*/
+  sizeof(struct __pyx_obj_6_loess_loess_predicted), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_6_loess_loess_predicted, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  0, /*tp_compare*/
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_loess_predicted, /*tp_as_number*/
+  &__pyx_tp_as_sequence_loess_predicted, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_loess_predicted, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  __pyx_f_6_loess_15loess_predicted___str__, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_loess_predicted, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_6_loess_loess_predicted, /*tp_traverse*/
+  __pyx_tp_clear_6_loess_loess_predicted, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_6_loess_loess_predicted, /*tp_methods*/
+  __pyx_members_6_loess_loess_predicted, /*tp_members*/
+  __pyx_getsets_6_loess_loess_predicted, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_6_loess_loess_predicted, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+};
+
+static PyObject *__pyx_tp_new_6_loess_loess(PyTypeObject *t, PyObject *a, PyObject *k) {
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  struct __pyx_obj_6_loess_loess *p = (struct __pyx_obj_6_loess_loess *)o;
+  p->inputs = ((struct __pyx_obj_6_loess_loess_inputs *)Py_None); Py_INCREF(Py_None);
+  p->model = ((struct __pyx_obj_6_loess_loess_model *)Py_None); Py_INCREF(Py_None);
+  p->control = ((struct __pyx_obj_6_loess_loess_control *)Py_None); Py_INCREF(Py_None);
+  p->kd_tree = ((struct __pyx_obj_6_loess_loess_kd_tree *)Py_None); Py_INCREF(Py_None);
+  p->outputs = ((struct __pyx_obj_6_loess_loess_outputs *)Py_None); Py_INCREF(Py_None);
+  p->predicted = ((struct __pyx_obj_6_loess_loess_predicted *)Py_None); Py_INCREF(Py_None);
+  return o;
+}
+
+static void __pyx_tp_dealloc_6_loess_loess(PyObject *o) {
+  struct __pyx_obj_6_loess_loess *p = (struct __pyx_obj_6_loess_loess *)o;
+  {
+    PyObject *etype, *eval, *etb;
+    PyErr_Fetch(&etype, &eval, &etb);
+    ++o->ob_refcnt;
+    __pyx_f_6_loess_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));
+  Py_XDECREF(((PyObject *)p->kd_tree));
+  Py_XDECREF(((PyObject *)p->outputs));
+  Py_XDECREF(((PyObject *)p->predicted));
+  (*o->ob_type->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_6_loess_loess(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_6_loess_loess *p = (struct __pyx_obj_6_loess_loess *)o;
+  if (p->inputs) {
+    e = (*v)(((PyObject*)p->inputs), a); if (e) return e;
+  }
+  if (p->model) {
+    e = (*v)(((PyObject*)p->model), a); if (e) return e;
+  }
+  if (p->control) {
+    e = (*v)(((PyObject*)p->control), a); if (e) return e;
+  }
+  if (p->kd_tree) {
+    e = (*v)(((PyObject*)p->kd_tree), a); if (e) return e;
+  }
+  if (p->outputs) {
+    e = (*v)(((PyObject*)p->outputs), a); if (e) return e;
+  }
+  if (p->predicted) {
+    e = (*v)(((PyObject*)p->predicted), a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_6_loess_loess(PyObject *o) {
+  struct __pyx_obj_6_loess_loess *p = (struct __pyx_obj_6_loess_loess *)o;
+  Py_XDECREF(((PyObject *)p->inputs));
+  p->inputs = ((struct __pyx_obj_6_loess_loess_inputs *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(((PyObject *)p->model));
+  p->model = ((struct __pyx_obj_6_loess_loess_model *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(((PyObject *)p->control));
+  p->control = ((struct __pyx_obj_6_loess_loess_control *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(((PyObject *)p->kd_tree));
+  p->kd_tree = ((struct __pyx_obj_6_loess_loess_kd_tree *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(((PyObject *)p->outputs));
+  p->outputs = ((struct __pyx_obj_6_loess_loess_outputs *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(((PyObject *)p->predicted));
+  p->predicted = ((struct __pyx_obj_6_loess_loess_predicted *)Py_None); Py_INCREF(Py_None);
+  return 0;
+}
+
+static struct PyMethodDef __pyx_methods_6_loess_loess[] = {
+  {"fit", (PyCFunction)__pyx_f_6_loess_5loess_fit, METH_VARARGS|METH_KEYWORDS, 0},
+  {"summary", (PyCFunction)__pyx_f_6_loess_5loess_summary, METH_VARARGS|METH_KEYWORDS, 0},
+  {"predict", (PyCFunction)__pyx_f_6_loess_5loess_predict, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6_loess_5loess_predict},
+  {0, 0, 0, 0}
+};
+
+static struct PyMemberDef __pyx_members_6_loess_loess[] = {
+  {"inputs", T_OBJECT, offsetof(struct __pyx_obj_6_loess_loess, inputs), READONLY, 0},
+  {"model", T_OBJECT, offsetof(struct __pyx_obj_6_loess_loess, model), READONLY, 0},
+  {"control", T_OBJECT, offsetof(struct __pyx_obj_6_loess_loess, control), READONLY, 0},
+  {"kd_tree", T_OBJECT, offsetof(struct __pyx_obj_6_loess_loess, kd_tree), READONLY, 0},
+  {"outputs", T_OBJECT, offsetof(struct __pyx_obj_6_loess_loess, outputs), READONLY, 0},
+  {"predicted", T_OBJECT, offsetof(struct __pyx_obj_6_loess_loess, predicted), READONLY, 0},
+  {"nobs", T_LONG, offsetof(struct __pyx_obj_6_loess_loess, nobs), 0, 0},
+  {"npar", T_LONG, offsetof(struct __pyx_obj_6_loess_loess, npar), 0, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_loess = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  0, /*nb_divide*/
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  0, /*nb_coerce*/
+  0, /*nb_int*/
+  0, /*nb_long*/
+  0, /*nb_float*/
+  0, /*nb_oct*/
+  0, /*nb_hex*/
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  0, /*nb_inplace_divide*/
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_loess = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_loess = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_loess = {
+  0, /*bf_getreadbuffer*/
+  0, /*bf_getwritebuffer*/
+  0, /*bf_getsegcount*/
+  0, /*bf_getcharbuffer*/
+};
+
+PyTypeObject __pyx_type_6_loess_loess = {
+  PyObject_HEAD_INIT(0)
+  0, /*ob_size*/
+  "_loess.loess", /*tp_name*/
+  sizeof(struct __pyx_obj_6_loess_loess), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_6_loess_loess, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  0, /*tp_compare*/
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_loess, /*tp_as_number*/
+  &__pyx_tp_as_sequence_loess, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_loess, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_loess, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_6_loess_loess, /*tp_traverse*/
+  __pyx_tp_clear_6_loess_loess, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_6_loess_loess, /*tp_methods*/
+  __pyx_members_6_loess_loess, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_f_6_loess_5loess___init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_6_loess_loess, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+};
+
+static PyObject *__pyx_tp_new_6_loess_anova(PyTypeObject *t, PyObject *a, PyObject *k) {
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  return o;
+}
+
+static void __pyx_tp_dealloc_6_loess_anova(PyObject *o) {
+  (*o->ob_type->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_6_loess_anova(PyObject *o, visitproc v, void *a) {
+  return 0;
+}
+
+static int __pyx_tp_clear_6_loess_anova(PyObject *o) {
+  return 0;
+}
+
+static struct PyMethodDef __pyx_methods_6_loess_anova[] = {
+  {0, 0, 0, 0}
+};
+
+static struct PyMemberDef __pyx_members_6_loess_anova[] = {
+  {"dfn", T_DOUBLE, offsetof(struct __pyx_obj_6_loess_anova, dfn), READONLY, 0},
+  {"dfd", T_DOUBLE, offsetof(struct __pyx_obj_6_loess_anova, dfd), READONLY, 0},
+  {"F_value", T_DOUBLE, offsetof(struct __pyx_obj_6_loess_anova, F_value), READONLY, 0},
+  {"Pr_F", T_DOUBLE, offsetof(struct __pyx_obj_6_loess_anova, Pr_F), READONLY, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_anova = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  0, /*nb_divide*/
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  0, /*nb_coerce*/
+  0, /*nb_int*/
+  0, /*nb_long*/
+  0, /*nb_float*/
+  0, /*nb_oct*/
+  0, /*nb_hex*/
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  0, /*nb_inplace_divide*/
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_anova = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_anova = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_anova = {
+  0, /*bf_getreadbuffer*/
+  0, /*bf_getwritebuffer*/
+  0, /*bf_getsegcount*/
+  0, /*bf_getcharbuffer*/
+};
+
+PyTypeObject __pyx_type_6_loess_anova = {
+  PyObject_HEAD_INIT(0)
+  0, /*ob_size*/
+  "_loess.anova", /*tp_name*/
+  sizeof(struct __pyx_obj_6_loess_anova), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_6_loess_anova, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  0, /*tp_compare*/
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_anova, /*tp_as_number*/
+  &__pyx_tp_as_sequence_anova, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_anova, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_anova, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_6_loess_anova, /*tp_traverse*/
+  __pyx_tp_clear_6_loess_anova, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_6_loess_anova, /*tp_methods*/
+  __pyx_members_6_loess_anova, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_f_6_loess_5anova___init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_6_loess_anova, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+};
+
+static struct PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+static void __pyx_init_filenames(void); /*proto*/
+
+PyMODINIT_FUNC init_loess(void); /*proto*/
+PyMODINIT_FUNC init_loess(void) {
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  __pyx_init_filenames();
+  __pyx_m = Py_InitModule4("_loess", __pyx_methods, 0, 0, PYTHON_API_VERSION);
+  if (!__pyx_m) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2; goto __pyx_L1;};
+  __pyx_b = PyImport_AddModule("__builtin__");
+  if (!__pyx_b) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2; goto __pyx_L1;};
+  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_6_loess_loess_inputs) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "loess_inputs", (PyObject *)&__pyx_type_6_loess_loess_inputs) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; goto __pyx_L1;}
+  __pyx_ptype_6_loess_loess_inputs = &__pyx_type_6_loess_loess_inputs;
+  if (PyType_Ready(&__pyx_type_6_loess_loess_control) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 236; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "loess_control", (PyObject *)&__pyx_type_6_loess_loess_control) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 236; goto __pyx_L1;}
+  __pyx_ptype_6_loess_loess_control = &__pyx_type_6_loess_loess_control;
+  if (PyType_Ready(&__pyx_type_6_loess_loess_kd_tree) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 360; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "loess_kd_tree", (PyObject *)&__pyx_type_6_loess_loess_kd_tree) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 360; goto __pyx_L1;}
+  __pyx_ptype_6_loess_loess_kd_tree = &__pyx_type_6_loess_loess_kd_tree;
+  __pyx_vtabptr_6_loess_loess_model = &__pyx_vtable_6_loess_loess_model;
+  *(void(**)())&__pyx_vtable_6_loess_loess_model.setup = (void(*)())__pyx_f_6_loess_11loess_model_setup;
+  if (PyType_Ready(&__pyx_type_6_loess_loess_model) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 366; goto __pyx_L1;}
+  if (__Pyx_SetVtable(__pyx_type_6_loess_loess_model.tp_dict, __pyx_vtabptr_6_loess_loess_model) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 366; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "loess_model", (PyObject *)&__pyx_type_6_loess_loess_model) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 366; goto __pyx_L1;}
+  __pyx_ptype_6_loess_loess_model = &__pyx_type_6_loess_loess_model;
+  if (PyType_Ready(&__pyx_type_6_loess_loess_outputs) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 519; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "loess_outputs", (PyObject *)&__pyx_type_6_loess_loess_outputs) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 519; goto __pyx_L1;}
+  __pyx_ptype_6_loess_loess_outputs = &__pyx_type_6_loess_loess_outputs;
+  __pyx_vtabptr_6_loess_conf_intervals = &__pyx_vtable_6_loess_conf_intervals;
+  *(void(**)())&__pyx_vtable_6_loess_conf_intervals.setup = (void(*)())__pyx_f_6_loess_14conf_intervals_setup;
+  __pyx_type_6_loess_conf_intervals.tp_free = _PyObject_GC_Del;
+  if (PyType_Ready(&__pyx_type_6_loess_conf_intervals) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; goto __pyx_L1;}
+  if (__Pyx_SetVtable(__pyx_type_6_loess_conf_intervals.tp_dict, __pyx_vtabptr_6_loess_conf_intervals) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "conf_intervals", (PyObject *)&__pyx_type_6_loess_conf_intervals) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; goto __pyx_L1;}
+  __pyx_ptype_6_loess_conf_intervals = &__pyx_type_6_loess_conf_intervals;
+  __pyx_vtabptr_6_loess_loess_predicted = &__pyx_vtable_6_loess_loess_predicted;
+  *(void(**)())&__pyx_vtable_6_loess_loess_predicted.setup = (void(*)())__pyx_f_6_loess_15loess_predicted_setup;
+  __pyx_type_6_loess_loess_predicted.tp_free = _PyObject_GC_Del;
+  if (PyType_Ready(&__pyx_type_6_loess_loess_predicted) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 647; goto __pyx_L1;}
+  if (__Pyx_SetVtable(__pyx_type_6_loess_loess_predicted.tp_dict, __pyx_vtabptr_6_loess_loess_predicted) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 647; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "loess_predicted", (PyObject *)&__pyx_type_6_loess_loess_predicted) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 647; goto __pyx_L1;}
+  __pyx_ptype_6_loess_loess_predicted = &__pyx_type_6_loess_loess_predicted;
+  __pyx_type_6_loess_loess.tp_free = _PyObject_GC_Del;
+  if (PyType_Ready(&__pyx_type_6_loess_loess) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 753; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "loess", (PyObject *)&__pyx_type_6_loess_loess) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 753; goto __pyx_L1;}
+  __pyx_ptype_6_loess_loess = &__pyx_type_6_loess_loess;
+  if (PyType_Ready(&__pyx_type_6_loess_anova) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 880; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "anova", (PyObject *)&__pyx_type_6_loess_anova) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 880; goto __pyx_L1;}
+  __pyx_ptype_6_loess_anova = &__pyx_type_6_loess_anova;
+  __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/src/_loess.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/src/_loess.pyx":9 */
+  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_numpy); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; goto __pyx_L1;}
+  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_n_array); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_narray, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":12 */
+  import_array();
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":73 */
+  __pyx_k31;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":721 */
+  __pyx_1 = PyFloat_FromDouble(0.95); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 721; goto __pyx_L1;}
+  __pyx_k32 = __pyx_1;
+  __pyx_1 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":763 */
+  Py_INCREF(Py_None);
+  __pyx_k33 = Py_None;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":834 */
+  __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_False); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 834; goto __pyx_L1;}
+  __pyx_k34 = __pyx_2;
+  __pyx_2 = 0;
+
+  /* "/home/backtopop/workspace/pyloess/src/_loess.pyx":883 */
+  return;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  __Pyx_AddTraceback("_loess");
+}
+
+static char *__pyx_filenames[] = {
+  "_loess.pyx",
+  "c_numpy.pxd",
+};
+
+/* Runtime support code */
+
+static void __pyx_init_filenames(void) {
+  __pyx_f = __pyx_filenames;
+}
+
+static int __Pyx_GetStarArgs(
+    PyObject **args, 
+    PyObject **kwds,
+    char *kwd_list[], 
+    int nargs,
+    PyObject **args2, 
+    PyObject **kwds2)
+{
+    PyObject *x = 0, *args1 = 0, *kwds1 = 0;
+    
+    if (args2)
+        *args2 = 0;
+    if (kwds2)
+        *kwds2 = 0;
+    
+    if (args2) {
+        args1 = PyTuple_GetSlice(*args, 0, nargs);
+        if (!args1)
+            goto bad;
+        *args2 = PyTuple_GetSlice(*args, nargs, PyTuple_Size(*args));
+        if (!*args2)
+            goto bad;
+    }
+    else {
+        args1 = *args;
+        Py_INCREF(args1);
+    }
+    
+    if (kwds2) {
+        if (*kwds) {
+            char **p;
+            kwds1 = PyDict_New();
+            if (!kwds)
+                goto bad;
+            *kwds2 = PyDict_Copy(*kwds);
+            if (!*kwds2)
+                goto bad;
+            for (p = kwd_list; *p; p++) {
+                x = PyDict_GetItemString(*kwds, *p);
+                if (x) {
+                    if (PyDict_SetItemString(kwds1, *p, x) < 0)
+                        goto bad;
+                    if (PyDict_DelItemString(*kwds2, *p) < 0)
+                        goto bad;
+                }
+            }
+        }
+        else {
+            *kwds2 = PyDict_New();
+            if (!*kwds2)
+                goto bad;
+        }
+    }
+    else {
+        kwds1 = *kwds;
+        Py_XINCREF(kwds1);
+    }
+    
+    *args = args1;
+    *kwds = kwds1;
+    return 0;
+bad:
+    Py_XDECREF(args1);
+    Py_XDECREF(kwds1);
+    if (*args2) {
+        Py_XDECREF(*args2);
+    }
+    if (*kwds2) {
+        Py_XDECREF(*kwds2);
+    }
+    return -1;
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
+    PyObject *__import__ = 0;
+    PyObject *empty_list = 0;
+    PyObject *module = 0;
+    PyObject *global_dict = 0;
+    PyObject *empty_dict = 0;
+    PyObject *list;
+    __import__ = PyObject_GetAttrString(__pyx_b, "__import__");
+    if (!__import__)
+        goto bad;
+    if (from_list)
+        list = from_list;
+    else {
+        empty_list = PyList_New(0);
+        if (!empty_list)
+            goto bad;
+        list = empty_list;
+    }
+    global_dict = PyModule_GetDict(__pyx_m);
+    if (!global_dict)
+        goto bad;
+    empty_dict = PyDict_New();
+    if (!empty_dict)
+        goto bad;
+    module = PyObject_CallFunction(__import__, "OOOO",
+        name, global_dict, empty_dict, list);
+bad:
+    Py_XDECREF(empty_list);
+    Py_XDECREF(__import__);
+    Py_XDECREF(empty_dict);
+    return module;
+}
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
+    PyObject *result;
+    result = PyObject_GetAttr(dict, name);
+    if (!result)
+        PyErr_SetObject(PyExc_NameError, name);
+    return result;
+}
+
+static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
+    if (!type) {
+        PyErr_Format(PyExc_SystemError, "Missing type object");
+        return 0;
+    }
+    if (obj == Py_None || PyObject_TypeCheck(obj, type))
+        return 1;
+    PyErr_Format(PyExc_TypeError, "Cannot convert %s to %s",
+        obj->ob_type->tp_name, type->tp_name);
+    return 0;
+}
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
+    Py_XINCREF(type);
+    Py_XINCREF(value);
+    Py_XINCREF(tb);
+    /* First, check the traceback argument, replacing None with NULL. */
+    if (tb == Py_None) {
+        Py_DECREF(tb);
+        tb = 0;
+    }
+    else if (tb != NULL && !PyTraceBack_Check(tb)) {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: arg 3 must be a traceback or None");
+        goto raise_error;
+    }
+    /* Next, replace a missing value with None */
+    if (value == NULL) {
+        value = Py_None;
+        Py_INCREF(value);
+    }
+    /* Next, repeatedly, replace a tuple exception with its first item */
+    while (PyTuple_Check(type) && PyTuple_Size(type) > 0) {
+        PyObject *tmp = type;
+        type = PyTuple_GET_ITEM(type, 0);
+        Py_INCREF(type);
+        Py_DECREF(tmp);
+    }
+    if (PyString_Check(type)) {
+        if (PyErr_Warn(PyExc_DeprecationWarning,
+                "raising a string exception is deprecated"))
+            goto raise_error;
+    }
+    else if (PyType_Check(type) || PyClass_Check(type))
+        ; /*PyErr_NormalizeException(&type, &value, &tb);*/
+    else {
+        /* Raising an instance.  The value should be a dummy. */
+        if (value != Py_None) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto raise_error;
+        }
+        /* Normalize to raise <class>, <instance> */
+        Py_DECREF(value);
+        value = type;
+        if (PyInstance_Check(type))
+            type = (PyObject*) ((PyInstanceObject*)type)->in_class;
+        else
+            type = (PyObject*) type->ob_type;
+        Py_INCREF(type);
+    }
+    PyErr_Restore(type, value, tb);
+    return;
+raise_error:
+    Py_XDECREF(value);
+    Py_XDECREF(type);
+    Py_XDECREF(tb);
+    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) {
+        PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
+    }
+    return f;
+}
+
+static int __Pyx_PrintItem(PyObject *v) {
+    PyObject *f;
+    
+    if (!(f = __Pyx_GetStdout()))
+        return -1;
+    if (PyFile_SoftSpace(f, 1)) {
+        if (PyFile_WriteString(" ", f) < 0)
+            return -1;
+    }
+    if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
+        return -1;
+    if (PyString_Check(v)) {
+        char *s = PyString_AsString(v);
+        int len = PyString_Size(v);
+        if (len > 0 &&
+            isspace(Py_CHARMASK(s[len-1])) &&
+            s[len-1] != ' ')
+                PyFile_SoftSpace(f, 0);
+    }
+    return 0;
+}
+
+static int __Pyx_PrintNewline(void) {
+    PyObject *f;
+    
+    if (!(f = __Pyx_GetStdout()))
+        return -1;
+    if (PyFile_WriteString("\n", f) < 0)
+        return -1;
+    PyFile_SoftSpace(f, 0);
+    return 0;
+}
+
+static int __Pyx_InternStrings(__Pyx_InternTabEntry *t) {
+    while (t->p) {
+        *t->p = PyString_InternFromString(t->s);
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
+    PyObject *pycobj = 0;
+    int result;
+    
+    pycobj = PyCObject_FromVoidPtr(vtable, 0);
+    if (!pycobj)
+        goto bad;
+    if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
+        goto bad;
+    result = 0;
+    goto done;
+
+bad:
+    result = -1;
+done:
+    Py_XDECREF(pycobj);
+    return result;
+}
+
+static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, 
+    long size) 
+{
+    PyObject *py_module_name = 0;
+    PyObject *py_class_name = 0;
+    PyObject *py_name_list = 0;
+    PyObject *py_module = 0;
+    PyObject *result = 0;
+    
+    py_module_name = PyString_FromString(module_name);
+    if (!py_module_name)
+        goto bad;
+    py_class_name = PyString_FromString(class_name);
+    if (!py_class_name)
+        goto bad;
+    py_name_list = PyList_New(1);
+    if (!py_name_list)
+        goto bad;
+    Py_INCREF(py_class_name);
+    if (PyList_SetItem(py_name_list, 0, py_class_name) < 0)
+        goto bad;
+    py_module = __Pyx_Import(py_module_name, py_name_list);
+    if (!py_module)
+        goto bad;
+    result = PyObject_GetAttr(py_module, py_class_name);
+    if (!result)
+        goto bad;
+    if (!PyType_Check(result)) {
+        PyErr_Format(PyExc_TypeError, 
+            "%s.%s is not a type object",
+            module_name, class_name);
+        goto bad;
+    }
+    if (((PyTypeObject *)result)->tp_basicsize != size) {
+        PyErr_Format(PyExc_ValueError, 
+            "%s.%s does not appear to be the correct type object",
+            module_name, class_name);
+        goto bad;
+    }
+    goto done;
+bad:
+    Py_XDECREF(result);
+    result = 0;
+done:
+    Py_XDECREF(py_module_name);
+    Py_XDECREF(py_class_name);
+    Py_XDECREF(py_name_list);
+    return (PyTypeObject *)result;
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+
+static void __Pyx_AddTraceback(char *funcname) {
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    PyObject *py_globals = 0;
+    PyObject *empty_tuple = 0;
+    PyObject *empty_string = 0;
+    PyCodeObject *py_code = 0;
+    PyFrameObject *py_frame = 0;
+    
+    py_srcfile = PyString_FromString(__pyx_filename);
+    if (!py_srcfile) goto bad;
+    py_funcname = PyString_FromString(funcname);
+    if (!py_funcname) goto bad;
+    py_globals = PyModule_GetDict(__pyx_m);
+    if (!py_globals) goto bad;
+    empty_tuple = PyTuple_New(0);
+    if (!empty_tuple) goto bad;
+    empty_string = PyString_FromString("");
+    if (!empty_string) goto bad;
+    py_code = PyCode_New(
+        0,            /*int argcount,*/
+        0,            /*int nlocals,*/
+        0,            /*int stacksize,*/
+        0,            /*int flags,*/
+        empty_string, /*PyObject *code,*/
+        empty_tuple,  /*PyObject *consts,*/
+        empty_tuple,  /*PyObject *names,*/
+        empty_tuple,  /*PyObject *varnames,*/
+        empty_tuple,  /*PyObject *freevars,*/
+        empty_tuple,  /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        __pyx_lineno,   /*int firstlineno,*/
+        empty_string  /*PyObject *lnotab*/
+    );
+    if (!py_code) goto bad;
+    py_frame = PyFrame_New(
+        PyThreadState_Get(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        py_globals,          /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = __pyx_lineno;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    Py_XDECREF(empty_tuple);
+    Py_XDECREF(empty_string);
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}

Added: trunk/Lib/sandbox/pyloess/src/_loess.pyx
===================================================================
--- trunk/Lib/sandbox/pyloess/src/_loess.pyx	2007-03-21 21:28:18 UTC (rev 2862)
+++ trunk/Lib/sandbox/pyloess/src/_loess.pyx	2007-03-21 22:53:54 UTC (rev 2863)
@@ -0,0 +1,919 @@
+# -*- Mode: Python -*-  
+cimport c_python
+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, \
+    PyArray_SimpleNewFromData
+import numpy
+narray = numpy.array
+
+# NumPy must be initialized
+c_numpy.import_array()
+
+cimport c_loess
+
+cdef floatarray_from_data(int rows, int cols, double *data):
+    cdef ndarray a_ndr
+    cdef npy_intp size
+    size = rows*cols
+    a_ndr = <object>PyArray_SimpleNewFromData(1, &size, NPY_DOUBLE, data)
+    if cols > 1:
+        a_ndr.shape = (rows, cols)
+    return a_ndr
+
+cdef boolarray_from_data(int rows, int cols, int *data):
+    cdef ndarray a_ndr
+    cdef npy_intp size
+    size = rows*cols
+    a_ndr = <object>PyArray_SimpleNewFromData(1, &size, NPY_DOUBLE, data)
+    if cols > 1:
+        a_ndr.shape = (rows, cols)
+    return a_ndr.astype(numpy.bool)
+
+##cimport modelflags
+##import modelflags
+#
+#cdef list_to_clist(object p_list):
+#    cdef int i, imax
+#    p_list = list(p_list)
+#    imax = min(8, len(p_list))
+#    for i from 0 <= i < imax:
+#        c_list[i] = p_list[i]
+#    return c_list[0]
+#cdef object clist_to_list(int c_list[8]):
+#    cdef int i, imax
+#    p_list = [False] * 8
+#    imax = min(8, len(p_list))
+#    for i from 0 <= i < imax:
+#        p_list[i] = c_list[i]
+#    return p_list
+#        
+#
+#class modelflags:
+#    def __init__(self):
+#        self.str_list = [False] * 8
+#        self.c_list = list_to_clist(self.str_list)
+#    def __getitem__(self, idx):
+#        return self.str_list[idx]
+#    def __setitem__(self, idx, val):
+#        cdef int tmpval
+#        tmpval = val
+#        self.c_list[idx] = tmpval
+#        self.str_list[idx] = bool(val)
+#    def __str__(self):
+#        return str(self.str_list)
+#
+##class modelflags(c_modelflags):
+##    def __init__(self):
+##        c_modelflags.__init__(self)
+##        
+
+
+"""
+: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 ---
+#####---------------------------------------------------------------------------
+cdef class loess_inputs:
+    cdef c_loess.c_loess_inputs *_base
+    #.........
+    property x:
+        def __get__(self):
+            return floatarray_from_data(self._base.n, self._base.p, self._base.x)
+    #.........    
+    property y:
+        def __get__(self):
+            return floatarray_from_data(self._base.n, 1, self._base.y)
+    #.........    
+    property weights:
+        """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)
+        
+        def __set__(self, w):
+            cdef npy_intp *dims
+            cdef ndarray w_ndr
+            w_ndr = <ndarray>PyArray_FROMANY(w, NPY_DOUBLE, 1, 1, NPY_OWNDATA)
+            if w_ndr.ndim > 1 or w_ndr.size != self._base.n:
+                raise ValueError, "Invalid size of the 'weights' vector!"
+            self._base.weights = <double *>w_ndr.data
+    #.........    
+    property nobs:
+        "Number of observations."
+        def __get__(self):
+            return self._base.n
+    #.........
+    property npar:
+        "Number of independent variables."
+        def __get__(self):
+            return self._base.p
+#       
+######---------------------------------------------------------------------------
+##---- ---- loess control ---
+######---------------------------------------------------------------------------
+cdef class loess_control:
+    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):
+            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):
+            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):
+            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
+        #
+        statistics = cellargs.get('statistics', None)
+        if statistics is not None:
+            self.statistics = statistics
+        #    
+        trace_hat = cellargs.get('trace_hat', None)
+        if trace_hat is not None:
+            self.trace_hat = trace_hat
+        #
+        iterations = cellargs.get('iterations', None)
+        if iterations is not None:
+            self.iterations = iterations
+        #
+        cell = cellargs.get('cell', None)
+        if cell is not None:
+            self.parametric_flags = cell
+        #
+    #.........
+    def __str__(self):
+        strg = ["Control          :",
+                "Surface type     : %s" % self.surface,
+                "Statistics       : %s" % self.statistics,
+                "Trace estimation : %s" % self.trace_hat,
+                "Cell size        : %s" % self.cell,
+                "Nb iterations    : %s" % self.iterations,]
+        return '\n'.join(strg)
+        
+#    
+######---------------------------------------------------------------------------
+##---- ---- loess kd_tree ---
+######---------------------------------------------------------------------------
+cdef class loess_kd_tree:
+    cdef c_loess.c_loess_kd_tree *_base
+
+######---------------------------------------------------------------------------
+##---- ---- loess model ---
+######---------------------------------------------------------------------------
+cdef class loess_model:
+    cdef c_loess.c_loess_model *_base
+    cdef long npar
+#    cdef public double span
+#    cdef public int degree
+#    cdef public char *family
+#    cdef public parametric_mflags, drop_square_mflags
+    #.........
+    cdef setup(self, c_loess.c_loess_model *base, long npar):
+        self._base = base
+        self.npar = npar
+#        self.parametric_flags = modelflags()
+#        self.parametric_flags.c_list[0] = base.parametric[0]
+#        self.drop_square_flags = modelflags()
+#        self.drop_square_flags.c_list[0] = base.drop_square[0]
+#        self.span = self._base.span
+#        self.degree = self._base.degree
+#        self.family = self._base.family
+#        self.parametric_flags = boolarray_from_data(self.npar, 1, self._base.parametric)
+#        self.drop_square_flags = boolarray_from_data(self.npar, 1, self._base.drop_square)
+        return self    
+    #.........
+    property normalize:
+        """
+    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 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 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(self.npar, 1, self._base.parametric)
+        def __set__(self, paramf):
+            cdef ndarray p_ndr
+            cdef int i
+            p_ndr = numpy.atleast_1d(narray(paramf, copy=False, subok=True, 
+                                            dtype=numpy.bool))
+            for i from 0 <= i < min(self.npar, p_ndr.size):
+                self._base.parametric[i] = p_ndr[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(self.npar, 1, self._base.drop_square)
+        def __set__(self, drop_sq):
+            cdef ndarray d_ndr
+            cdef int i
+            d_ndr = numpy.atleast_1d(narray(drop_sq, copy=False, subok=True, 
+                                            dtype=numpy.bool))
+            for i from 0 <= i < min(self.npar, d_ndr.size):
+                self._base.drop_square[i] = d_ndr[i]
+    #........
+    def update(self, **modelargs):
+        family = modelargs.get('family', None)
+        if family is not None:
+            self.family = family
+        #
+        span = modelargs.get('span', None)
+        if span is not None:
+            self.span = span
+        #    
+        degree = modelargs.get('degree', None)
+        if degree is not None:
+            self.degree = degree
+        #
+        normalize = modelargs.get('normalize', None)
+        if normalize is not None:
+            self.normalize = normalize
+        #
+        parametric = modelargs.get('parametric', None)
+        if parametric is not None:
+            self.parametric_flags = parametric
+        #
+        drop_square = modelargs.get('drop_square', None)
+        if drop_square is not None:
+            self.drop_square_flags = drop_square
+    #.........
+    def __repr__(self):
+        return "loess model parameters @%s" % id(self)
+    #.........
+    def __str__(self):
+        strg = ["Model parameters.....",
+                "family      : %s" % self.family,
+                "span        : %s" % self.span,
+                "degree      : %s" % self.degree,
+                "normalized  : %s" % self.normalize,
+                "parametric  : %s" % self.parametric_flags[:self.npar],
+                "drop_square : %s" % self.drop_square_flags[:self.npar]
+                ]
+        return '\n'.join(strg)
+        
+#####---------------------------------------------------------------------------
+#---- ---- loess outputs ---
+#####---------------------------------------------------------------------------
+cdef class loess_outputs:
+    cdef c_loess.c_loess_outputs *_base
+    cdef long nobs, npar
+    cdef readonly int activated
+    #........
+    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.npar, 1, self._base.divisor)
+    #.........    
+    property enp:
+        """
+    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 
+    #.........
+    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................",
+                "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)
+
+
+        
+#####---------------------------------------------------------------------------
+#---- ---- loess confidence ---
+#####---------------------------------------------------------------------------
+cdef class conf_intervals:
+    cdef c_loess.c_conf_inv _base
+    cdef readonly ndarray lower, fit, upper
+    #.........
+#    def __dealloc__(self):
+#        c_loess.pw_free_mem(self._base)
+    #.........
+    cdef setup(self, c_loess.c_conf_inv base, long nest):
+        self._base = base
+        self.fit = floatarray_from_data(nest, 1, base.fit)
+        self.upper = floatarray_from_data(nest, 1, base.upper)
+        self.lower = floatarray_from_data(nest, 1, 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 readonly long nest
+    cdef readonly conf_intervals confidence_intervals
+#    cdef readonly ndarray values, stderr
+#    cdef readonly double residual_scale, df
+    #.........
+    def __dealloc__(self):
+        c_loess.pred_free_mem(&self._base)      
+    #.........
+    cdef setup(self, c_loess.c_prediction base, long nest):
+        self._base = base
+        self.nest = nest
+#    cdef setup(self, c_loess.c_loess loess_base, object newdata, stderror):
+#        cdef ndarray p_ndr
+#        cdef double *p_dat
+#        cdef c_loess.c_prediction _prediction
+#        cdef int i, m
+#        #
+#        # Note : we need a copy as we may have to normalize
+#        p_ndr = narray(newdata, copy=True, subok=True, order='C').ravel()
+#        p_dat = <double *>p_ndr.data
+#        # Test the compatibility of sizes .......
+#        if p_ndr.size == 0:
+#            raise ValueError("Can't predict without input data !")
+#        (m, notOK) = divmod(len(p_ndr), loess_base.inputs.p)
+#        if notOK:
+#            raise ValueError(
+#                  "Incompatible data size: there should be as many rows as parameters")
+#        #.....
+#        c_loess.c_predict(p_dat, m, &loess_base, &_prediction, stderror)
+#        if loess_base.status.err_status:
+#            raise ValueError(loess_base.status.err_msg)
+#        self._base = _prediction
+#        self.nest = m
+##        self.values = floatarray_from_data(m, 1, _prediction.fit)
+##        self.stderr = floatarray_from_data(m, 1, _prediction.se_fit)
+##        self.residual_scale = _prediction.residual_scale
+##        self.df = _prediction.df
+    #.........
+    property values:
+        """
+    values : ndarray
+        The (m,) ndarray of loess values evaluated at newdata
+        """
+        def __get__(self):
+            return floatarray_from_data(self.nest, 1, self._base.fit)
+    #.........
+    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(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._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._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.
+        """
+        cdef c_loess.c_conf_inv _confintv
+        if coverage < 0.5:
+            coverage = 1. - coverage 
+        if coverage > 1. :
+            raise ValueError("The coverage precentage should be between 0 and 1!")
+        c_loess.c_pointwise(&self._base, self.nest, coverage, &_confintv)
+        self.confidence_intervals = conf_intervals()
+        self.confidence_intervals.setup(_confintv, 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)
+    
+
+#####---------------------------------------------------------------------------
+#---- ---- loess base class ---
+#####---------------------------------------------------------------------------
+cdef class loess:
+    cdef c_loess.c_loess _base
+    cdef readonly loess_inputs inputs
+    cdef readonly loess_model model
+    cdef readonly loess_control control
+    cdef readonly loess_kd_tree kd_tree
+    cdef readonly loess_outputs outputs
+    cdef readonly loess_predicted predicted
+    cdef public long nobs, npar
+    
+    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
+        # Get the predictor array
+        x_ndr = narray(x, copy=True, subok=True, order='C')
+        x_dat = <double *>x_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 = narray(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()
+        self.inputs._base = &self._base.inputs
+        #
+        self.model = loess_model()
+        self.model.setup(&self._base.model, p)
+#        self.model._base = &self._base.model
+#        self.model.npar = p
+        #
+        self.control = loess_control()
+        self.control._base = &self._base.control
+        #
+        self.kd_tree = loess_kd_tree()
+        self.kd_tree._base = &self._base.kd_tree
+        #
+        self.outputs = loess_outputs()
+        self.outputs._base = &self._base.outputs
+        self.outputs.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
+        if self._base.status.err_status:
+            raise ValueError(self._base.status.err_msg)
+        return
+    #......................................................
+    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, newdata, stderror=False):
+        """
+    newdata: ndarray
+        A (m,p) ndarray specifying the values of the predictors at which the 
+        evaluation is to be carried out.
+    stderr: Boolean
+        Logical flag for computing standard errors at newdata.
+        """
+        cdef ndarray p_ndr
+        cdef double *p_dat
+        cdef c_loess.c_prediction _prediction
+        cdef int i, m
+        # Make sure there's been a fit earlier ...
+        if self.outputs.activated == 0:
+            c_loess.loess_fit(&self._base)
+            self.outputs.activated = True
+            if self._base.status.err_status:
+                raise ValueError(self._base.status.err_msg)
+        # Note : we need a copy as we may have to normalize
+        p_ndr = narray(newdata, copy=True, subok=True, order='C').ravel()
+        p_dat = <double *>p_ndr.data
+        # 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.c_predict(p_dat, m, &self._base, &_prediction, stderror)
+        if self._base.status.err_status:
+            raise ValueError(self._base.status.err_msg)
+        self.predicted = loess_predicted()
+        self.predicted._base = _prediction
+        self.predicted.nest = m
+#        self.predicted.setup(_prediction, m)
+        return self.predicted
+    #.........
+    def __dealloc__(self):
+        c_loess.loess_free_mem(&self._base)
+    #......................................................
+    
+
+#####---------------------------------------------------------------------------
+#---- ---- loess anova ---
+#####---------------------------------------------------------------------------
+cdef class anova:
+    cdef readonly double dfn, dfd, F_value, Pr_F
+    #
+    def __init__(self, loess_one, loess_two):
+        cdef double one_d1, one_d2, one_s, two_d1, two_d2, two_s, rssdiff,\
+                    d1diff, tmp, df1, df2
+        #
+        if not isinstance(loess_one, loess) or not isinstance(loess_two, loess):
+            raise ValueError("Arguments should be valid loess objects!"\
+                             "got '%s' instead" % type(loess_one))
+        #
+        out_one = loess_one.outputs
+        out_two = loess_two.outputs
+        #
+        one_d1 = out_one.one_delta
+        one_d2 = out_one.two_delta
+        one_s = out_one.s
+        #
+        two_d1 = out_two.one_delta
+        two_d2 = out_two.two_delta
+        two_s = out_two.s
+        #
+        rssdiff = abs(one_s * one_s * one_d1 - two_s * two_s * two_d1)
+        d1diff = abs(one_d1 - two_d1)
+        self.dfn = d1diff * d1diff / abs(one_d2 - two_d2)
+        df1 = self.dfn
+        #
+        if out_one.enp > out_two.enp:
+            self.dfd = one_d1 * one_d1 / one_d2
+            tmp = one_s
+        else:
+            self.dfd = two_d1 * two_d1 / two_d2
+            tmp = two_s
+        df2 = self.dfd
+        F_value = (rssdiff / d1diff) / (tmp * tmp)
+        
+        self.Pr_F = 1. - c_loess.ibeta(F_value*df1/(df2+F_value*df1), df1/2, df2/2)
+        self.F_value = F_value
+
+        
\ No newline at end of file

Added: trunk/Lib/sandbox/pyloess/src/c_loess.pxd
===================================================================
--- trunk/Lib/sandbox/pyloess/src/c_loess.pxd	2007-03-21 21:28:18 UTC (rev 2862)
+++ trunk/Lib/sandbox/pyloess/src/c_loess.pxd	2007-03-21 22:53:54 UTC (rev 2863)
@@ -0,0 +1,75 @@
+# -*- Mode: Python -*-  
+
+cdef extern from "loess.h":
+    ctypedef struct c_loess_errstatus "loess_errstatus":
+        int err_status
+        char *err_msg
+    ctypedef struct c_loess_inputs "loess_inputs":
+        long   n
+        long   p
+        double *y
+        double *x
+        double *weights
+    ctypedef struct c_loess_model "loess_model":
+        double span
+        int    degree
+        int    normalize
+        int    parametric[8]
+        int    drop_square[8]
+        char   *family
+    ctypedef struct c_loess_control "loess_control":
+        char   *surface
+        char   *statistics
+        double cell
+        char   *trace_hat
+        int    iterations
+    ctypedef struct c_loess_kd_tree "loess_kd_tree":
+        pass
+    ctypedef struct c_loess_outputs "loess_outputs":
+        double  *fitted_values
+        double  *fitted_residuals
+        double  enp
+        double  s
+        double  one_delta
+        double  two_delta
+        double  *pseudovalues
+        double  trace_hat
+        double  *diagonal
+        double  *robust
+        double  *divisor
+    ctypedef struct c_loess "loess":
+        c_loess_inputs inputs
+        c_loess_model model
+        c_loess_control control
+        c_loess_kd_tree kd_tree
+        c_loess_outputs outputs
+        c_loess_errstatus status
+    ctypedef struct c_prediction "prediction": 
+        double  *fit
+        double  *se_fit
+        double  residual_scale
+        double  df
+#    ctypedef struct c_anova "anova_struct":
+#        double  dfn
+#        double  dfd
+#        double  F_value
+#        double  Pr_F
+    ctypedef struct c_conf_inv "conf_inv":
+        double  *fit
+        double  *upper
+        double  *lower
+    
+cdef extern from "cloess.h":    
+    void loess_setup(double *x, double *y, long n, long p, c_loess *lo)
+    void loess_fit(c_loess *lo)
+    void loess_free_mem(c_loess *lo)
+    void loess_summary(c_loess *lo)
+    #
+    void c_predict "predict" (double *eval, int m, c_loess *lo, c_prediction *pre, int se) 
+    void pred_free_mem(c_prediction *pre)
+    #
+    void c_pointwise "pointwise" (c_prediction *pre, int m, double coverage, c_conf_inv *ci)
+    double pf (double q, double df1, double df2)
+    double ibeta (double x, double a, double b)
+    void pw_free_mem (c_conf_inv *ci)
+    

Added: trunk/Lib/sandbox/pyloess/src/c_numpy.pxd
===================================================================
--- trunk/Lib/sandbox/pyloess/src/c_numpy.pxd	2007-03-21 21:28:18 UTC (rev 2862)
+++ trunk/Lib/sandbox/pyloess/src/c_numpy.pxd	2007-03-21 22:53:54 UTC (rev 2863)
@@ -0,0 +1,129 @@
+# :Author:    Travis Oliphant
+
+cdef extern from "numpy/arrayobject.h":
+
+    cdef enum NPY_TYPES:
+        NPY_BOOL
+        NPY_BYTE
+        NPY_UBYTE
+        NPY_SHORT
+        NPY_USHORT 
+        NPY_INT
+        NPY_UINT 
+        NPY_LONG
+        NPY_ULONG
+        NPY_LONGLONG
+        NPY_ULONGLONG
+        NPY_FLOAT
+        NPY_DOUBLE 
+        NPY_LONGDOUBLE
+        NPY_CFLOAT
+        NPY_CDOUBLE
+        NPY_CLONGDOUBLE
+        NPY_OBJECT
+        NPY_STRING
+        NPY_UNICODE
+        NPY_VOID
+        NPY_NTYPES
+        NPY_NOTYPE
+
+    cdef enum requirements:
+        NPY_CONTIGUOUS
+        NPY_FORTRAN
+        NPY_OWNDATA
+        NPY_FORCECAST
+        NPY_ENSURECOPY
+        NPY_ENSUREARRAY
+        NPY_ELEMENTSTRIDES
+        NPY_ALIGNED
+        NPY_NOTSWAPPED
+        NPY_WRITEABLE
+        NPY_UPDATEIFCOPY
+        NPY_ARR_HAS_DESCR
+
+        NPY_BEHAVED
+        NPY_BEHAVED_NS
+        NPY_CARRAY
+        NPY_CARRAY_RO
+        NPY_FARRAY
+        NPY_FARRAY_RO
+        NPY_DEFAULT
+
+        NPY_IN_ARRAY
+        NPY_OUT_ARRAY
+        NPY_INOUT_ARRAY
+        NPY_IN_FARRAY
+        NPY_OUT_FARRAY
+        NPY_INOUT_FARRAY
+
+        NPY_UPDATE_ALL 
+
+    cdef enum defines:
+        # Note: as of Pyrex 0.9.5, enums are type-checked more strictly, so this
+        # can't be used as an integer.
+        NPY_MAXDIMS
+
+    ctypedef struct npy_cdouble:
+        double real
+        double imag
+
+    ctypedef struct npy_cfloat:
+        double real
+        double imag
+
+    ctypedef int npy_intp 
+
+    ctypedef extern class numpy.dtype [object PyArray_Descr]:
+        cdef int type_num, elsize, alignment
+        cdef char type, kind, byteorder, hasobject
+        cdef object fields, typeobj
+
+    ctypedef extern class numpy.ndarray [object PyArrayObject]:
+        cdef char *data
+        cdef int nd
+        cdef npy_intp *dimensions
+        cdef npy_intp *strides
+        cdef object base
+        cdef dtype descr
+        cdef int flags
+
+    ctypedef extern class numpy.flatiter [object PyArrayIterObject]:
+        cdef int  nd_m1
+        cdef npy_intp index, size
+        cdef ndarray ao
+        cdef char *dataptr
+        
+    ctypedef extern class numpy.broadcast [object PyArrayMultiIterObject]:
+        cdef int numiter
+        cdef npy_intp size, index
+        cdef int nd
+        # These next two should be arrays of [NPY_MAXITER], but that is
+        # difficult to cleanly specify in Pyrex. Fortunately, it doesn't matter.
+        cdef npy_intp *dimensions
+        cdef void **iters
+
+    object PyArray_ZEROS(int ndims, npy_intp* dims, NPY_TYPES type_num, int fortran)
+    object PyArray_EMPTY(int ndims, npy_intp* dims, NPY_TYPES type_num, int fortran)
+    dtype PyArray_DescrFromTypeNum(NPY_TYPES type_num)
+    object PyArray_SimpleNew(int ndims, npy_intp* dims, NPY_TYPES type_num)
+    int PyArray_Check(object obj)
+    object PyArray_ContiguousFromAny(object obj, NPY_TYPES type, 
+        int mindim, int maxdim)
+    npy_intp PyArray_SIZE(ndarray arr)
+    npy_intp PyArray_NBYTES(ndarray arr)
+    void *PyArray_DATA(ndarray arr)
+    object PyArray_FromAny(object obj, dtype newtype, int mindim, int maxdim,
+		    int requirements, object context)
+    object PyArray_FROMANY(object obj, NPY_TYPES type_num, int min,
+                           int max, int requirements)
+    object PyArray_NewFromDescr(object subtype, dtype newtype, int nd,
+                                npy_intp* dims, npy_intp* strides, void* data,
+                                int flags, object parent)
+
+    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()

Added: trunk/Lib/sandbox/pyloess/src/c_python.pxd
===================================================================
--- trunk/Lib/sandbox/pyloess/src/c_python.pxd	2007-03-21 21:28:18 UTC (rev 2862)
+++ trunk/Lib/sandbox/pyloess/src/c_python.pxd	2007-03-21 22:53:54 UTC (rev 2863)
@@ -0,0 +1,22 @@
+# -*- Mode: Python -*-  Not really, but close enough
+
+# Expose as much of the Python C API as we need here
+
+cdef extern from "stdlib.h":
+    ctypedef int size_t
+
+cdef extern from "Python.h":
+    ctypedef int Py_intptr_t
+    void*  PyMem_Malloc(size_t)
+    void*  PyMem_Realloc(void *p, size_t n)
+    void   PyMem_Free(void *p)
+    char*  PyString_AsString(object string)
+    object PyString_FromString(char *v)
+    object PyString_InternFromString(char *v)
+    int    PyErr_CheckSignals()
+    object PyFloat_FromDouble(double v)
+    void   Py_XINCREF(object o)
+    void   Py_XDECREF(object o)
+    void   Py_CLEAR(object o) # use instead of decref
+    
+    object PyList_New(int size)

Added: trunk/Lib/sandbox/pyloess/src/cloess.h
===================================================================
--- trunk/Lib/sandbox/pyloess/src/cloess.h	2007-03-21 21:28:18 UTC (rev 2862)
+++ trunk/Lib/sandbox/pyloess/src/cloess.h	2007-03-21 22:53:54 UTC (rev 2863)
@@ -0,0 +1,21 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+
+// from loess.c
+void loess_setup(double *x, double *y, int n, int p, loess *lo);
+char loess_fit(loess *lo);
+void loess_free_mem(loess *lo);
+void loess_summary(loess *lo);
+               
+// from misc.c
+void pointwise(prediction *pre, int m, double coverage, conf_inv *ci); 
+void pw_free_mem(conf_inv *ci);
+double pf(double q, double df1, double df2);
+double ibeta(double x, double a, double b);
+////
+// from predict.c
+void predict(double *eval, int m, loess *lo, prediction *pre, int se);
+void pred_free_mem(prediction *pre);
+//
+

Added: trunk/Lib/sandbox/pyloess/src/linpack_lite.f
===================================================================
--- trunk/Lib/sandbox/pyloess/src/linpack_lite.f	2007-03-21 21:28:18 UTC (rev 2862)
+++ trunk/Lib/sandbox/pyloess/src/linpack_lite.f	2007-03-21 22:53:54 UTC (rev 2863)
@@ -0,0 +1,757 @@
+      subroutine dqrsl(x,ldx,n,k,qraux,y,qy,qty,b,rsd,xb,job,info)
+      integer ldx,n,k,job,info
+      double precision x(ldx,1),qraux(1),y(1),qy(1),qty(1),b(1),rsd(1),
+     *                 xb(1)
+c
+c     dqrsl applies the output of dqrdc to compute coordinate
+c     transformations, projections, and least squares solutions.
+c     for k .le. min(n,p), let xk be the matrix
+c
+c            xk = (x(jpvt(1)),x(jpvt(2)), ... ,x(jpvt(k)))
+c
+c     formed from columnns jpvt(1), ... ,jpvt(k) of the original
+c     n x p matrix x that was input to dqrdc (if no pivoting was
+c     done, xk consists of the first k columns of x in their
+c     original order).  dqrdc produces a factored orthogonal matrix q
+c     and an upper triangular matrix r such that
+c
+c              xk = q * (r)
+c                       (0)
+c
+c     this information is contained in coded form in the arrays
+c     x and qraux.
+c
+c     on entry
+c
+c        x      double precision(ldx,p).
+c               x contains the output of dqrdc.
+c
+c        ldx    integer.
+c               ldx is the leading dimension of the array x.
+c
+c        n      integer.
+c               n is the number of rows of the matrix xk.  it must
+c               have the same value as n in dqrdc.
+c
+c        k      integer.
+c               k is the number of columns of the matrix xk.  k
+c               must nnot be greater than min(n,p), where p is the
+c               same as in the calling sequence to dqrdc.
+c
+c        qraux  double precision(p).
+c               qraux contains the auxiliary output from dqrdc.
+c
+c        y      double precision(n)
+c               y contains an n-vector that is to be manipulated
+c               by dqrsl.
+c
+c        job    integer.
+c               job specifies what is to be computed.  job has
+c               the decimal expansion abcde, with the following
+c               meaning.
+c
+c                    if a.ne.0, compute qy.
+c                    if b,c,d, or e .ne. 0, compute qty.
+c                    if c.ne.0, compute b.
+c                    if d.ne.0, compute rsd.
+c                    if e.ne.0, compute xb.
+c
+c               note that a request to compute b, rsd, or xb
+c               automatically triggers the computation of qty, for
+c               which an array must be provided in the calling
+c               sequence.
+c
+c     on return
+c
+c        qy     double precision(n).
+c               qy conntains q*y, if its computation has been
+c               requested.
+c
+c        qty    double precision(n).
+c               qty contains trans(q)*y, if its computation has
+c               been requested.  here trans(q) is the
+c               transpose of the matrix q.
+c
+c        b      double precision(k)
+c               b contains the solution of the least squares problem
+c
+c                    minimize norm2(y - xk*b),
+c
+c               if its computation has been requested.  (note that
+c               if pivoting was requested in dqrdc, the j-th
+c               component of b will be associated with column jpvt(j)
+c               of the original matrix x that was input into dqrdc.)
+c
+c        rsd    double precision(n).
+c               rsd contains the least squares residual y - xk*b,
+c               if its computation has been requested.  rsd is
+c               also the orthogonal projection of y onto the
+c               orthogonal complement of the column space of xk.
+c
+c        xb     double precision(n).
+c               xb contains the least squares approximation xk*b,
+c               if its computation has been requested.  xb is also
+c               the orthogonal projection of y onto the column space
+c               of x.
+c
+c        info   integer.
+c               info is zero unless the computation of b has
+c               been requested and r is exactly singular.  in
+c               this case, info is the index of the first zero
+c               diagonal element of r and b is left unaltered.
+c
+c     the parameters qy, qty, b, rsd, and xb are not referenced
+c     if their computation is not requested and in this case
+c     can be replaced by dummy variables in the calling program.
+c     to save storage, the user may in some cases use the same
+c     array for different parameters in the calling sequence.  a
+c     frequently occuring example is when one wishes to compute
+c     any of b, rsd, or xb and does not need y or qty.  in this
+c     case one may identify y, qty, and one of b, rsd, or xb, while
+c     providing separate arrays for anything else that is to be
+c     computed.  thus the calling sequence
+c
+c          call dqrsl(x,ldx,n,k,qraux,y,dum,y,b,y,dum,110,info)
+c
+c     will result in the computation of b and rsd, with rsd
+c     overwriting y.  more generally, each item in the following
+c     list contains groups of permissible identifications for
+c     a single callinng sequence.
+c
+c          1. (y,qty,b) (rsd) (xb) (qy)
+c
+c          2. (y,qty,rsd) (b) (xb) (qy)
+c
+c          3. (y,qty,xb) (b) (rsd) (qy)
+c
+c          4. (y,qy) (qty,b) (rsd) (xb)
+c
+c          5. (y,qy) (qty,rsd) (b) (xb)
+c
+c          6. (y,qy) (qty,xb) (b) (rsd)
+c
+c     in any group the value returned in the array allocated to
+c     the group corresponds to the last member of the group.
+c
+c     linpack. this version dated 08/14/78 .
+c     g.w. stewart, university of maryland, argonne national lab.
+c
+c     dqrsl uses the following functions and subprograms.
+c
+c     blas daxpy,dcopy,ddot
+c     fortran dabs,min0,mod
+c
+c     internal variables
+c
+      integer i,j,jj,ju,kp1
+      double precision ddot,t,temp
+      logical cb,cqy,cqty,cr,cxb
+c
+c
+c     set info flag.
+c
+      info = 0
+c
+c     determine what is to be computed.
+c
+      cqy = job/10000 .ne. 0
+      cqty = mod(job,10000) .ne. 0
+      cb = mod(job,1000)/100 .ne. 0
+      cr = mod(job,100)/10 .ne. 0
+      cxb = mod(job,10) .ne. 0
+      ju = min0(k,n-1)
+c
+c     special action when n=1.
+c
+      if (ju .ne. 0) go to 40
+         if (cqy) qy(1) = y(1)
+         if (cqty) qty(1) = y(1)
+         if (cxb) xb(1) = y(1)
+         if (.not.cb) go to 30
+            if (x(1,1) .ne. 0.0d0) go to 10
+               info = 1
+            go to 20
+   10       continue
+               b(1) = y(1)/x(1,1)
+   20       continue
+   30    continue
+         if (cr) rsd(1) = 0.0d0
+      go to 250
+   40 continue
+c
+c        set up to compute qy or qty.
+c
+         if (cqy) call dcopy(n,y,1,qy,1)
+         if (cqty) call dcopy(n,y,1,qty,1)
+         if (.not.cqy) go to 70
+c
+c           compute qy.
+c
+            do 60 jj = 1, ju
+               j = ju - jj + 1
+               if (qraux(j) .eq. 0.0d0) go to 50
+                  temp = x(j,j)
+                  x(j,j) = qraux(j)
+                  t = -ddot(n-j+1,x(j,j),1,qy(j),1)/x(j,j)
+                  call daxpy(n-j+1,t,x(j,j),1,qy(j),1)
+                  x(j,j) = temp
+   50          continue
+   60       continue
+   70    continue
+         if (.not.cqty) go to 100
+c
+c           compute trans(q)*y.
+c
+            do 90 j = 1, ju
+               if (qraux(j) .eq. 0.0d0) go to 80
+                  temp = x(j,j)
+                  x(j,j) = qraux(j)
+                  t = -ddot(n-j+1,x(j,j),1,qty(j),1)/x(j,j)
+                  call daxpy(n-j+1,t,x(j,j),1,qty(j),1)
+                  x(j,j) = temp
+   80          continue
+   90       continue
+  100    continue
+c
+c        set up to compute b, rsd, or xb.
+c
+         if (cb) call dcopy(k,qty,1,b,1)
+         kp1 = k + 1
+         if (cxb) call dcopy(k,qty,1,xb,1)
+         if (cr .and. k .lt. n) call dcopy(n-k,qty(kp1),1,rsd(kp1),1)
+         if (.not.cxb .or. kp1 .gt. n) go to 120
+            do 110 i = kp1, n
+               xb(i) = 0.0d0
+  110       continue
+  120    continue
+         if (.not.cr) go to 140
+            do 130 i = 1, k
+               rsd(i) = 0.0d0
+  130       continue
+  140    continue
+         if (.not.cb) go to 190
+c
+c           compute b.
+c
+            do 170 jj = 1, k
+               j = k - jj + 1
+               if (x(j,j) .ne. 0.0d0) go to 150
+                  info = j
+c           ......exit
+                  go to 180
+  150          continue
+               b(j) = b(j)/x(j,j)
+               if (j .eq. 1) go to 160
+                  t = -b(j)
+                  call daxpy(j-1,t,x(1,j),1,b,1)
+  160          continue
+  170       continue
+  180       continue
+  190    continue
+         if (.not.cr .and. .not.cxb) go to 240
+c
+c           compute rsd or xb as required.
+c
+            do 230 jj = 1, ju
+               j = ju - jj + 1
+               if (qraux(j) .eq. 0.0d0) go to 220
+                  temp = x(j,j)
+                  x(j,j) = qraux(j)
+                  if (.not.cr) go to 200
+                     t = -ddot(n-j+1,x(j,j),1,rsd(j),1)/x(j,j)
+                     call daxpy(n-j+1,t,x(j,j),1,rsd(j),1)
+  200             continue
+                  if (.not.cxb) go to 210
+                     t = -ddot(n-j+1,x(j,j),1,xb(j),1)/x(j,j)
+                     call daxpy(n-j+1,t,x(j,j),1,xb(j),1)
+  210             continue
+                  x(j,j) = temp
+  220          continue
+  230       continue
+  240    continue
+  250 continue
+      return
+      end
+c......................................................................
+      subroutine dsvdc(x,ldx,n,p,s,e,u,ldu,v,ldv,work,job,info)
+      integer ldx,n,p,ldu,ldv,job,info
+      double precision x(ldx,1),s(1),e(1),u(ldu,1),v(ldv,1),work(1)
+c
+c
+c     dsvdc is a subroutine to reduce a double precision nxp matrix x
+c     by orthogonal transformations u and v to diagonal form.  the
+c     diagonal elements s(i) are the singular values of x.  the
+c     columns of u are the corresponding left singular vectors,
+c     and the columns of v the right singular vectors.
+c
+c     on entry
+c
+c         x         double precision(ldx,p), where ldx.ge.n.
+c                   x contains the matrix whose singular value
+c                   decomposition is to be computed.  x is
+c                   destroyed by dsvdc.
+c
+c         ldx       integer.
+c                   ldx is the leading dimension of the array x.
+c
+c         n         integer.
+c                   n is the number of rows of the matrix x.
+c
+c         p         integer.
+c                   p is the number of columns of the matrix x.
+c
+c         ldu       integer.
+c                   ldu is the leading dimension of the array u.
+c                   (see below).
+c
+c         ldv       integer.
+c                   ldv is the leading dimension of the array v.
+c                   (see below).
+c
+c         work      double precision(n).
+c                   work is a scratch array.
+c
+c         job       integer.
+c                   job controls the computation of the singular
+c                   vectors.  it has the decimal expansion ab
+c                   with the following meaning
+c
+c                        a.eq.0    do not compute the left singular
+c                                  vectors.
+c                        a.eq.1    return the n left singular vectors
+c                                  in u.
+c                        a.ge.2    return the first min(n,p) singular
+c                                  vectors in u.
+c                        b.eq.0    do not compute the right singular
+c                                  vectors.
+c                        b.eq.1    return the right singular vectors
+c                                  in v.
+c
+c     on return
+c
+c         s         double precision(mm), where mm=min(n+1,p).
+c                   the first min(n,p) entries of s contain the
+c                   singular values of x arranged in descending
+c                   order of magnitude.
+c
+c         e         double precision(p),
+c                   e ordinarily contains zeros.  however see the
+c                   discussion of info for exceptions.
+c
+c         u         double precision(ldu,k), where ldu.ge.n.  if
+c                                   joba.eq.1 then k.eq.n, if joba.ge.2
+c                                   then k.eq.min(n,p).
+c                   u contains the matrix of left singular vectors.
+c                   u is not referenced if joba.eq.0.  if n.le.p
+c                   or if joba.eq.2, then u may be identified with x
+c                   in the subroutine call.
+c
+c         v         double precision(ldv,p), where ldv.ge.p.
+c                   v contains the matrix of right singular vectors.
+c                   v is not referenced if job.eq.0.  if p.le.n,
+c                   then v may be identified with x in the
+c                   subroutine call.
+c
+c         info      integer.
+c                   the singular values (and their corresponding
+c                   singular vectors) s(info+1),s(info+2),...,s(m)
+c                   are correct (here m=min(n,p)).  thus if
+c                   info.eq.0, all the singular values and their
+c                   vectors are correct.  in any event, the matrix
+c                   b = trans(u)*x*v is the bidiagonal matrix
+c                   with the elements of s on its diagonal and the
+c                   elements of e on its super-diagonal (trans(u)
+c                   is the transpose of u).  thus the singular
+c                   values of x and b are the same.
+c
+c     linpack. this version dated 08/14/78 .
+c              correction made to shift 2/84.
+c     g.w. stewart, university of maryland, argonne national lab.
+c
+c     dsvdc uses the following functions and subprograms.
+c
+c     external drot
+c     blas daxpy,ddot,dscal,dswap,dnrm2,drotg
+c     fortran dabs,dmax1,max0,min0,mod,dsqrt
+c
+c     internal variables
+c
+      integer i,iter,j,jobu,k,kase,kk,l,ll,lls,lm1,lp1,ls,lu,m,maxit,
+     *        mm,mm1,mp1,nct,nctp1,ncu,nrt,nrtp1
+      double precision ddot,t,r
+      double precision b,c,cs,el,emm1,f,g,dnrm2,scale,shift,sl,sm,sn,
+     *                 smm1,t1,test,ztest
+      logical wantu,wantv
+c
+c
+c     set the maximum number of iterations.
+c
+      maxit = 30
+c
+c     determine what is to be computed.
+c
+      wantu = .false.
+      wantv = .false.
+      jobu = mod(job,100)/10
+      ncu = n
+      if (jobu .gt. 1) ncu = min0(n,p)
+      if (jobu .ne. 0) wantu = .true.
+      if (mod(job,10) .ne. 0) wantv = .true.
+c
+c     reduce x to bidiagonal form, storing the diagonal elements
+c     in s and the super-diagonal elements in e.
+c
+      info = 0
+      nct = min0(n-1,p)
+      nrt = max0(0,min0(p-2,n))
+      lu = max0(nct,nrt)
+      if (lu .lt. 1) go to 170
+      do 160 l = 1, lu
+         lp1 = l + 1
+         if (l .gt. nct) go to 20
+c
+c           compute the transformation for the l-th column and
+c           place the l-th diagonal in s(l).
+c
+            s(l) = dnrm2(n-l+1,x(l,l),1)
+            if (s(l) .eq. 0.0d0) go to 10
+               if (x(l,l) .ne. 0.0d0) s(l) = dsign(s(l),x(l,l))
+               call dscal(n-l+1,1.0d0/s(l),x(l,l),1)
+               x(l,l) = 1.0d0 + x(l,l)
+   10       continue
+            s(l) = -s(l)
+   20    continue
+         if (p .lt. lp1) go to 50
+         do 40 j = lp1, p
+            if (l .gt. nct) go to 30
+            if (s(l) .eq. 0.0d0) go to 30
+c
+c              apply the transformation.
+c
+               t = -ddot(n-l+1,x(l,l),1,x(l,j),1)/x(l,l)
+               call daxpy(n-l+1,t,x(l,l),1,x(l,j),1)
+   30       continue
+c
+c           place the l-th row of x into  e for the
+c           subsequent calculation of the row transformation.
+c
+            e(j) = x(l,j)
+   40    continue
+   50    continue
+         if (.not.wantu .or. l .gt. nct) go to 70
+c
+c           place the transformation in u for subsequent back
+c           multiplication.
+c
+            do 60 i = l, n
+               u(i,l) = x(i,l)
+   60       continue
+   70    continue
+         if (l .gt. nrt) go to 150
+c
+c           compute the l-th row transformation and place the
+c           l-th super-diagonal in e(l).
+c
+            e(l) = dnrm2(p-l,e(lp1),1)
+            if (e(l) .eq. 0.0d0) go to 80
+               if (e(lp1) .ne. 0.0d0) e(l) = dsign(e(l),e(lp1))
+               call dscal(p-l,1.0d0/e(l),e(lp1),1)
+               e(lp1) = 1.0d0 + e(lp1)
+   80       continue
+            e(l) = -e(l)
+            if (lp1 .gt. n .or. e(l) .eq. 0.0d0) go to 120
+c
+c              apply the transformation.
+c
+               do 90 i = lp1, n
+                  work(i) = 0.0d0
+   90          continue
+               do 100 j = lp1, p
+                  call daxpy(n-l,e(j),x(lp1,j),1,work(lp1),1)
+  100          continue
+               do 110 j = lp1, p
+                  call daxpy(n-l,-e(j)/e(lp1),work(lp1),1,x(lp1,j),1)
+  110          continue
+  120       continue
+            if (.not.wantv) go to 140
+c
+c              place the transformation in v for subsequent
+c              back multiplication.
+c
+               do 130 i = lp1, p
+                  v(i,l) = e(i)
+  130          continue
+  140       continue
+  150    continue
+  160 continue
+  170 continue
+c
+c     set up the final bidiagonal matrix or order m.
+c
+      m = min0(p,n+1)
+      nctp1 = nct + 1
+      nrtp1 = nrt + 1
+      if (nct .lt. p) s(nctp1) = x(nctp1,nctp1)
+      if (n .lt. m) s(m) = 0.0d0
+      if (nrtp1 .lt. m) e(nrtp1) = x(nrtp1,m)
+      e(m) = 0.0d0
+c
+c     if required, generate u.
+c
+      if (.not.wantu) go to 300
+         if (ncu .lt. nctp1) go to 200
+         do 190 j = nctp1, ncu
+            do 180 i = 1, n
+               u(i,j) = 0.0d0
+  180       continue
+            u(j,j) = 1.0d0
+  190    continue
+  200    continue
+         if (nct .lt. 1) go to 290
+         do 280 ll = 1, nct
+            l = nct - ll + 1
+            if (s(l) .eq. 0.0d0) go to 250
+               lp1 = l + 1
+               if (ncu .lt. lp1) go to 220
+               do 210 j = lp1, ncu
+                  t = -ddot(n-l+1,u(l,l),1,u(l,j),1)/u(l,l)
+                  call daxpy(n-l+1,t,u(l,l),1,u(l,j),1)
+  210          continue
+  220          continue
+               call dscal(n-l+1,-1.0d0,u(l,l),1)
+               u(l,l) = 1.0d0 + u(l,l)
+               lm1 = l - 1
+               if (lm1 .lt. 1) go to 240
+               do 230 i = 1, lm1
+                  u(i,l) = 0.0d0
+  230          continue
+  240          continue
+            go to 270
+  250       continue
+               do 260 i = 1, n
+                  u(i,l) = 0.0d0
+  260          continue
+               u(l,l) = 1.0d0
+  270       continue
+  280    continue
+  290    continue
+  300 continue
+c
+c     if it is required, generate v.
+c
+      if (.not.wantv) go to 350
+         do 340 ll = 1, p
+            l = p - ll + 1
+            lp1 = l + 1
+            if (l .gt. nrt) go to 320
+            if (e(l) .eq. 0.0d0) go to 320
+               do 310 j = lp1, p
+                  t = -ddot(p-l,v(lp1,l),1,v(lp1,j),1)/v(lp1,l)
+                  call daxpy(p-l,t,v(lp1,l),1,v(lp1,j),1)
+  310          continue
+  320       continue
+            do 330 i = 1, p
+               v(i,l) = 0.0d0
+  330       continue
+            v(l,l) = 1.0d0
+  340    continue
+  350 continue
+c
+c     main iteration loop for the singular values.
+c
+      mm = m
+      iter = 0
+  360 continue
+c
+c        quit if all the singular values have been found.
+c
+c     ...exit
+         if (m .eq. 0) go to 620
+c
+c        if too many iterations have been performed, set
+c        flag and return.
+c
+         if (iter .lt. maxit) go to 370
+            info = m
+c     ......exit
+            go to 620
+  370    continue
+c
+c        this section of the program inspects for
+c        negligible elements in the s and e arrays.  on
+c        completion the variables kase and l are set as follows.
+c
+c           kase = 1     if s(m) and e(l-1) are negligible and l.lt.m
+c           kase = 2     if s(l) is negligible and l.lt.m
+c           kase = 3     if e(l-1) is negligible, l.lt.m, and
+c                        s(l), ..., s(m) are not negligible (qr step).
+c           kase = 4     if e(m-1) is negligible (convergence).
+c
+         do 390 ll = 1, m
+            l = m - ll
+c        ...exit
+            if (l .eq. 0) go to 400
+            test = dabs(s(l)) + dabs(s(l+1))
+            ztest = test + dabs(e(l))
+            if (ztest .ne. test) go to 380
+               e(l) = 0.0d0
+c        ......exit
+               go to 400
+  380       continue
+  390    continue
+  400    continue
+         if (l .ne. m - 1) go to 410
+            kase = 4
+         go to 480
+  410    continue
+            lp1 = l + 1
+            mp1 = m + 1
+            do 430 lls = lp1, mp1
+               ls = m - lls + lp1
+c           ...exit
+               if (ls .eq. l) go to 440
+               test = 0.0d0
+               if (ls .ne. m) test = test + dabs(e(ls))
+               if (ls .ne. l + 1) test = test + dabs(e(ls-1))
+               ztest = test + dabs(s(ls))
+               if (ztest .ne. test) go to 420
+                  s(ls) = 0.0d0
+c           ......exit
+                  go to 440
+  420          continue
+  430       continue
+  440       continue
+            if (ls .ne. l) go to 450
+               kase = 3
+            go to 470
+  450       continue
+            if (ls .ne. m) go to 460
+               kase = 1
+            go to 470
+  460       continue
+               kase = 2
+               l = ls
+  470       continue
+  480    continue
+         l = l + 1
+c
+c        perform the task indicated by kase.
+c
+         go to (490,520,540,570), kase
+c
+c        deflate negligible s(m).
+c
+  490    continue
+            mm1 = m - 1
+            f = e(m-1)
+            e(m-1) = 0.0d0
+            do 510 kk = l, mm1
+               k = mm1 - kk + l
+               t1 = s(k)
+               call drotg(t1,f,cs,sn)
+               s(k) = t1
+               if (k .eq. l) go to 500
+                  f = -sn*e(k-1)
+                  e(k-1) = cs*e(k-1)
+  500          continue
+               if (wantv) call drot(p,v(1,k),1,v(1,m),1,cs,sn)
+  510       continue
+         go to 610
+c
+c        split at negligible s(l).
+c
+  520    continue
+            f = e(l-1)
+            e(l-1) = 0.0d0
+            do 530 k = l, m
+               t1 = s(k)
+               call drotg(t1,f,cs,sn)
+               s(k) = t1
+               f = -sn*e(k)
+               e(k) = cs*e(k)
+               if (wantu) call drot(n,u(1,k),1,u(1,l-1),1,cs,sn)
+  530       continue
+         go to 610
+c
+c        perform one qr step.
+c
+  540    continue
+c
+c           calculate the shift.
+c
+            scale = dmax1(dabs(s(m)),dabs(s(m-1)),dabs(e(m-1)),
+     *                    dabs(s(l)),dabs(e(l)))
+            sm = s(m)/scale
+            smm1 = s(m-1)/scale
+            emm1 = e(m-1)/scale
+            sl = s(l)/scale
+            el = e(l)/scale
+            b = ((smm1 + sm)*(smm1 - sm) + emm1**2)/2.0d0
+            c = (sm*emm1)**2
+            shift = 0.0d0
+            if (b .eq. 0.0d0 .and. c .eq. 0.0d0) go to 550
+               shift = dsqrt(b**2+c)
+               if (b .lt. 0.0d0) shift = -shift
+               shift = c/(b + shift)
+  550       continue
+            f = (sl + sm)*(sl - sm) + shift
+            g = sl*el
+c
+c           chase zeros.
+c
+            mm1 = m - 1
+            do 560 k = l, mm1
+               call drotg(f,g,cs,sn)
+               if (k .ne. l) e(k-1) = f
+               f = cs*s(k) + sn*e(k)
+               e(k) = cs*e(k) - sn*s(k)
+               g = sn*s(k+1)
+               s(k+1) = cs*s(k+1)
+               if (wantv) call drot(p,v(1,k),1,v(1,k+1),1,cs,sn)
+               call drotg(f,g,cs,sn)
+               s(k) = f
+               f = cs*e(k) + sn*s(k+1)
+               s(k+1) = -sn*e(k) + cs*s(k+1)
+               g = sn*e(k+1)
+               e(k+1) = cs*e(k+1)
+               if (wantu .and. k .lt. n)
+     *            call drot(n,u(1,k),1,u(1,k+1),1,cs,sn)
+  560       continue
+            e(m-1) = f
+            iter = iter + 1
+         go to 610
+c
+c        convergence.
+c
+  570    continue
+c
+c           make the singular value  positive.
+c
+            if (s(l) .ge. 0.0d0) go to 580
+               s(l) = -s(l)
+               if (wantv) call dscal(p,-1.0d0,v(1,l),1)
+  580       continue
+c
+c           order the singular value.
+c
+  590       if (l .eq. mm) go to 600
+c           ...exit
+               if (s(l) .ge. s(l+1)) go to 600
+               t = s(l)
+               s(l) = s(l+1)
+               s(l+1) = t
+               if (wantv .and. l .lt. p)
+     *            call dswap(p,v(1,l),1,v(1,l+1),1)
+               if (wantu .and. l .lt. n)
+     *            call dswap(n,u(1,l),1,u(1,l+1),1)
+               l = l + 1
+            go to 590
+  600       continue
+            iter = 0
+            m = m - 1
+  610    continue
+      go to 360
+  620 continue
+      return
+      end
+

Added: trunk/Lib/sandbox/pyloess/src/loess.c
===================================================================
--- trunk/Lib/sandbox/pyloess/src/loess.c	2007-03-21 21:28:18 UTC (rev 2862)
+++ trunk/Lib/sandbox/pyloess/src/loess.c	2007-03-21 22:53:54 UTC (rev 2863)
@@ -0,0 +1,350 @@
+#include "S.h"
+#include "loess.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+static char *surf_stat;
+
+int error_status = 0;
+char *error_message = NULL;
+
+void
+loess_setup(double *x, double *y, long n, long p, loess *lo)
+{
+    int i, max_kd;
+
+    max_kd = n > 200 ? n : 200;
+
+    lo->inputs.y = (double *) malloc(n * sizeof(double));
+    lo->inputs.x = (double *) malloc(n * p * sizeof(double));
+    lo->inputs.weights = (double *) malloc(n * sizeof(double));
+    for(i = 0; i < (n * p); i++)
+        lo->inputs.x[i] = x[i];
+    for(i = 0; i < n; i++) {
+        lo->inputs.y[i] = y[i];
+        lo->inputs.weights[i] = 1;
+    }
+    lo->inputs.n = n;
+    lo->inputs.p = p;
+    lo->model.span = 0.75;
+    lo->model.degree = 2;
+    lo->model.normalize = TRUE;
+    for(i = 0; i < 8; i++)
+        lo->model.parametric[i] = lo->model.drop_square[i] = FALSE;
+    lo->model.family = "gaussian";
+
+    lo->control.surface = "interpolate";
+    lo->control.statistics = "approximate";
+    lo->control.cell = 0.2;
+    lo->control.trace_hat = "wait.to.decide";
+    lo->control.iterations = 4;
+
+    lo->outputs.fitted_values = (double *) malloc(n * sizeof(double));
+    lo->outputs.fitted_residuals = (double *) malloc(n * sizeof(double));
+    lo->outputs.pseudovalues = (double *) malloc(n * sizeof(double));
+    lo->outputs.diagonal = (double *) malloc(n * sizeof(double));
+    lo->outputs.robust = (double *) malloc(n * sizeof(double));
+    lo->outputs.divisor = (double *) malloc(p * sizeof(double));
+
+    lo->kd_tree.parameter = (long *) malloc(7 * sizeof(long));
+    lo->kd_tree.a = (long *) malloc(max_kd * sizeof(long));
+    lo->kd_tree.xi = (double *) malloc(max_kd * sizeof(double));
+    lo->kd_tree.vert = (double *) malloc(p * 2 * sizeof(double));
+    lo->kd_tree.vval = (double *) malloc((p + 1) * max_kd * sizeof(double));
+}
+
+void
+loess_fit(loess *lo)
+{
+    int    size_info[2], iterations;
+    void    loess_();
+
+    size_info[0] = lo->inputs.p;
+    size_info[1] = lo->inputs.n;
+    
+    //Reset the default error status...
+    error_status = 0;
+    lo->status.err_status = 0;
+    lo->status.err_msg = NULL;
+
+    iterations = (!strcmp(lo->model.family, "gaussian")) ? 0 :
+    lo->control.iterations;
+    if(!strcmp(lo->control.trace_hat, "wait.to.decide")) {
+        if(!strcmp(lo->control.surface, "interpolate"))
+            lo->control.trace_hat = (lo->inputs.n < 500) ? "exact" : "approximate";
+        else
+            lo->control.trace_hat = "exact";
+        }
+    loess_(lo->inputs.y, lo->inputs.x, size_info, lo->inputs.weights,
+           &lo->model.span,
+           &lo->model.degree,
+           lo->model.parametric,
+           lo->model.drop_square,
+           &lo->model.normalize,
+           &lo->control.statistics,
+           &lo->control.surface,
+           &lo->control.cell,
+           &lo->control.trace_hat,
+           &iterations,
+           lo->outputs.fitted_values,
+           lo->outputs.fitted_residuals,
+           &lo->outputs.enp,
+           &lo->outputs.s,
+           &lo->outputs.one_delta,
+           &lo->outputs.two_delta,
+           lo->outputs.pseudovalues,
+           &lo->outputs.trace_hat,
+           lo->outputs.diagonal,
+           lo->outputs.robust,
+           lo->outputs.divisor,
+           lo->kd_tree.parameter,
+           lo->kd_tree.a,
+           lo->kd_tree.xi,
+           lo->kd_tree.vert,
+           lo->kd_tree.vval);
+
+    if(error_status){
+        lo->status.err_status = error_status;
+        lo->status.err_msg = error_message;
+    }
+}
+
+void
+loess_(double *y, double *x_, int *size_info, double *weights, double *span,
+       int *degree, int *parametric, int *drop_square, int *normalize,
+       char **statistics, char **surface, double *cell, char **trace_hat_in,
+       int *iterations, double *fitted_values, double *fitted_residuals,
+       double *enp, double *s, double *one_delta, double *two_delta,
+       double *pseudovalues, double *trace_hat_out, double *diagonal,
+       double *robust, double *divisor, int *parameter, int *a, double *xi,
+       double *vert, double *vval)
+{
+    double  *x, *x_tmp, new_cell, trL, delta1, delta2, sum_squares = 0,
+            *pseudo_resid, *temp, *xi_tmp, *vert_tmp, *vval_tmp,
+            *diag_tmp, trL_tmp = 0, d1_tmp = 0, d2_tmp = 0, sum, mean;
+    int    i, j, k, p, N, D, sum_drop_sqr = 0, sum_parametric = 0,
+            setLf, nonparametric = 0, *order_parametric,
+            *order_drop_sqr, zero = 0, max_kd, *a_tmp, *param_tmp;
+    int     cut, comp();
+    char    *new_stat, *mess;
+    void    condition();
+
+    D = size_info[0];
+    N = size_info[1];
+    max_kd = (N > 200 ? N : 200);
+    *one_delta = *two_delta = *trace_hat_out = 0;
+
+    x = (double *) malloc(D * N * sizeof(double));
+    x_tmp = (double *) malloc(D * N * sizeof(double));
+    temp = (double *) malloc(N * sizeof(double));
+    a_tmp = (int *) malloc(max_kd * sizeof(int));
+    xi_tmp = (double *) malloc(max_kd * sizeof(double));
+    vert_tmp = (double *) malloc(D * 2 * sizeof(double));
+    vval_tmp = (double *) malloc((D + 1) * max_kd * sizeof(double));
+    diag_tmp = (double *) malloc(N * sizeof(double));
+    param_tmp = (int *) malloc(N * sizeof(int));
+    order_parametric = (int *) malloc(D * sizeof(int));
+    order_drop_sqr = (int *) malloc(D * sizeof(int));
+    if((*iterations) > 0)
+        pseudo_resid = (double *) malloc(N * sizeof(double));
+
+    new_cell = (*span) * (*cell);
+    for(i = 0; i < N; i++)
+        robust[i] = 1;
+        for(i = 0; i < (N * D); i++)
+            x_tmp[i] = x_[i];
+    if((*normalize) && (D > 1)) {
+        cut = ceil(0.100000000000000000001 * N);
+        for(i = 0; i < D; i++) {
+            k = i * N;
+            for(j = 0; j < N; j++)
+                temp[j] = x_[k + j];
+            qsort(temp, N, sizeof(double), comp);
+            sum = 0;
+            for(j = cut; j <= (N - cut - 1); j++)
+                sum = sum + temp[j];
+            mean = sum / (N - 2 * cut);
+            sum = 0;
+            for(j = cut; j <= (N - cut - 1); j++) {
+                temp[j] = temp[j] - mean;
+                sum = sum + temp[j] * temp[j];
+            }
+            divisor[i] = sqrt(sum / (N - 2 * cut - 1));
+            for(j = 0; j < N; j++) {
+                p = k + j;
+                x_tmp[p] = x_[p] / divisor[i];
+            }
+        }
+    }
+    else
+        for(i = 0; i < D; i++) divisor[i] = 1;
+    
+    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;
+    }
+    //Reorder the predictors w/ the non-parametric first
+    for(i = 0; i < D; i++) {
+        order_drop_sqr[i] = 2 - drop_square[order_parametric[i]];
+        k = i * N;
+        p = order_parametric[i] * N;
+        for(j = 0; j < N; j++)
+            x[k + j] = x_tmp[p + j];
+    }
+    
+    // Misc. checks .............................
+    if((*degree) == 1 && sum_drop_sqr) {
+    	error_status = 1;
+    	error_message = "Specified the square of a factor predictor to be "\
+               			"dropped when degree = 1";
+        return;
+    }
+    
+    if(D == 1 && sum_drop_sqr) {
+    	error_status = 1;
+        error_message = "Specified the square of a predictor to be dropped "\
+                        "with only one numeric predictor";
+        return;
+    }
+    
+    if(sum_parametric == D) {
+    	error_status = 1;
+        error_message = "Specified parametric for all predictors";
+        return;
+        }
+        
+    // Start the iterations .....................
+    for(j = 0; j <= (*iterations); j++) {
+        new_stat = j ? "none" : *statistics;
+        for(i = 0; i < N; i++)
+            robust[i] = weights[i] * robust[i];
+        condition(surface, new_stat, trace_hat_in);
+        setLf = !strcmp(surf_stat, "interpolate/exact");
+        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;
+        }
+        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);
+    }
+    if((*iterations) > 0) {
+        F77_SUB(lowesp)(&N, y, fitted_values, weights, robust, temp,
+						pseudovalues);
+        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);
+        for(i = 0; i < N; i++)
+            pseudo_resid[i] = pseudovalues[i] - temp[i];
+    }
+    if((*iterations) == 0)
+        for(i = 0; i < N; i++)
+            sum_squares = sum_squares + weights[i] *
+                    fitted_residuals[i] * fitted_residuals[i];
+    else
+        for(i = 0; i < N; i++)
+            sum_squares = sum_squares + weights[i] *
+                    pseudo_resid[i] * pseudo_resid[i];
+    *enp = (*one_delta) + 2 * (*trace_hat_out) - N;
+    *s = sqrt(sum_squares / (*one_delta));
+    
+    //Clean the mess and leave ..................
+    free(x);
+    free(x_tmp);
+    free(temp);
+    free(xi_tmp);
+    free(vert_tmp);
+    free(vval_tmp);
+    free(diag_tmp);
+    free(a_tmp);
+    free(param_tmp);
+    free(order_parametric);
+    free(order_drop_sqr);
+        if((*iterations) > 0)
+                free(pseudo_resid);
+}
+
+void
+loess_free_mem(loess *lo)
+{
+    free(lo->inputs.x);
+    free(lo->inputs.y);
+    free(lo->inputs.weights);
+    free(lo->outputs.fitted_values);
+    free(lo->outputs.fitted_residuals);
+    free(lo->outputs.pseudovalues);
+    free(lo->outputs.diagonal);
+    free(lo->outputs.robust);
+    free(lo->outputs.divisor);
+    free(lo->kd_tree.parameter);
+    free(lo->kd_tree.a);
+    free(lo->kd_tree.xi);
+    free(lo->kd_tree.vert);
+    free(lo->kd_tree.vval);
+}
+
+void
+loess_summary(loess *lo)
+{
+    printf("Number of Observations         : %d\n", lo->inputs.n);
+    printf("Equivalent Number of Parameters: %.1f\n", lo->outputs.enp);
+    if(!strcmp(lo->model.family, "gaussian"))
+        printf("Residual Standard Error        : ");
+    else
+        printf("Residual Scale Estimate: ");
+    printf("%.4f\n", lo->outputs.s);
+}
+
+void
+condition(char **surface, char *new_stat, char **trace_hat_in)
+{
+    if(!strcmp(*surface, "interpolate")) {
+        if(!strcmp(new_stat, "none"))
+            surf_stat = "interpolate/none";
+        else if(!strcmp(new_stat, "exact"))
+            surf_stat = "interpolate/exact";
+        else if(!strcmp(new_stat, "approximate"))
+        {
+            if(!strcmp(*trace_hat_in, "approximate"))
+                surf_stat = "interpolate/2.approx";
+            else if(!strcmp(*trace_hat_in, "exact"))
+                surf_stat = "interpolate/1.approx";
+        }
+    }
+    else if(!strcmp(*surface, "direct")) {
+        if(!strcmp(new_stat, "none"))
+            surf_stat = "direct/none";
+        else if(!strcmp(new_stat, "exact"))
+            surf_stat = "direct/exact";
+        else if(!strcmp(new_stat, "approximate"))
+            surf_stat = "direct/approximate";
+    }
+}
+
+int
+comp(double *d1, double *d2)
+{
+    if(*d1 < *d2)
+        return(-1);
+    else if(*d1 == *d2)
+        return(0);
+    else
+        return(1);
+}

Added: trunk/Lib/sandbox/pyloess/src/loess.h
===================================================================
--- trunk/Lib/sandbox/pyloess/src/loess.h	2007-03-21 21:28:18 UTC (rev 2862)
+++ trunk/Lib/sandbox/pyloess/src/loess.h	2007-03-21 22:53:54 UTC (rev 2863)
@@ -0,0 +1,87 @@
+/* for the meaning of these fields, see struct.m */
+/* longs are used here so that the codes can be called from S */
+
+#define TRUE  1
+#define FALSE 0
+
+typedef struct {
+    int err_status;
+    char *err_msg;
+    } loess_errstatus;
+
+typedef struct {
+    long    n;
+    long    p;
+    double  *y;
+    double  *x;
+    double  *weights;
+    } loess_inputs;
+
+typedef struct {
+    double span;
+    int    degree;
+    int    normalize;
+    int    parametric[8];
+    int    drop_square[8];
+    char   *family;
+    } loess_model;
+
+typedef struct {
+    char   *surface;
+    char   *statistics;
+    double cell;
+    char   *trace_hat;
+    int    iterations;
+    } loess_control;
+
+typedef struct {
+    long   *parameter;
+    long   *a;
+    double *xi;
+    double *vert;
+    double *vval;
+    } loess_kd_tree;
+
+typedef struct {
+    double *fitted_values;
+    double *fitted_residuals;
+    double enp;
+    double s;
+    double one_delta;
+    double two_delta;
+    double *pseudovalues;
+    double trace_hat;
+    double *diagonal;
+    double *robust;
+    double *divisor;
+    } loess_outputs;
+
+typedef struct {
+    loess_inputs inputs;
+    loess_model model;
+    loess_control control;
+    loess_kd_tree kd_tree;
+    loess_outputs outputs;
+    loess_errstatus status;
+} loess;
+
+typedef struct {
+    double *fit;
+    double *se_fit;
+    double residual_scale;
+    double df;
+    } prediction;
+
+typedef struct {
+    double dfn;
+    double dfd;
+    double F_value;
+    double Pr_F;
+    } anova_struct;
+
+typedef struct {
+    double *fit;
+    double *upper;
+    double *lower;
+    } conf_inv;
+

Added: trunk/Lib/sandbox/pyloess/src/loessc.c
===================================================================
--- trunk/Lib/sandbox/pyloess/src/loessc.c	2007-03-21 21:28:18 UTC (rev 2862)
+++ trunk/Lib/sandbox/pyloess/src/loessc.c	2007-03-21 22:53:54 UTC (rev 2863)
@@ -0,0 +1,414 @@
+#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))
+#define  GAUSSIAN  1
+#define  SYMMETRIC 0
+
+static int *iv, liv, lv, tau;
+static double *v;
+
+extern char *error_message;
+extern int error_status;
+
+loess_raw(double *y, double *x, double *weights, double *robust, int *d,
+          int*n, double *span, int *degree, int *nonparametric,
+          int *drop_square, int *sum_drop_sqr, double *cell, char **surf_stat,
+          double *surface, long *parameter, long *a, double *xi, double *vert,
+          double *vval, double *diagonal, double *trL, double *one_delta,
+          double *two_delta, int *setLf)
+{
+    int    zero = 0, one = 1, two = 2, nsing, i, k;
+    double    *hat_matrix, *LL;
+
+    *trL = 0;
+    loess_workspace(d, n, span, degree, nonparametric, drop_square,
+        sum_drop_sqr, setLf);
+    v[1] = *cell;
+    if(!strcmp(*surf_stat, "interpolate/none")) {
+        F77_SUB(lowesb)(x, y, robust, &zero, &zero, iv, &liv, &lv, v);
+        F77_SUB(lowese)(iv, &liv, &lv, v, n, x, surface);
+        loess_prune(parameter, a, xi, vert, vval);
+    }
+    else if (!strcmp(*surf_stat, "direct/none")) {
+        F77_SUB(lowesf)(x, y, robust, iv, &liv, &lv, v, n, x,
+                        &zero, &zero, surface);
+    }
+    else if (!strcmp(*surf_stat, "interpolate/1.approx")) {
+        F77_SUB(lowesb)(x, y, weights, diagonal, &one, iv, &liv, &lv, v);
+        F77_SUB(lowese)(iv, &liv, &lv, v, n, x, surface);
+        nsing = iv[29];
+        for(i = 0; i < (*n); i++) *trL = *trL + diagonal[i];
+        F77_SUB(lowesa)(trL, n, d, &tau, &nsing, one_delta, two_delta);
+        loess_prune(parameter, a, xi, vert, vval);
+    }
+        else if (!strcmp(*surf_stat, "interpolate/2.approx")) {
+        F77_SUB(lowesb)(x, y, robust, &zero, &zero, iv, &liv, &lv, v);
+        F77_SUB(lowese)(iv, &liv, &lv, v, n, x, surface);
+        nsing = iv[29];
+        F77_SUB(ehg196)(&tau, d, span, trL);
+        F77_SUB(lowesa)(trL, n, d, &tau, &nsing, one_delta, two_delta);
+        loess_prune(parameter, a, xi, vert, vval);
+    }
+    else if (!strcmp(*surf_stat, "direct/approximate")) {
+        F77_SUB(lowesf)(x, y, weights, iv, &liv, &lv, v, n, x,
+            diagonal, &one, surface);
+        nsing = iv[29];
+        for(i = 0; i < (*n); i++) *trL = *trL + diagonal[i];
+        F77_SUB(lowesa)(trL, n, d, &tau, &nsing, one_delta, two_delta);
+    }
+    else if (!strcmp(*surf_stat, "interpolate/exact")) {
+        hat_matrix = Calloc((*n)*(*n), double);
+        LL = Calloc((*n)*(*n), double);
+        F77_SUB(lowesb)(x, y, weights, diagonal, &one, iv, &liv, &lv, v);
+        F77_SUB(lowesl)(iv, &liv, &lv, v, n, x, hat_matrix);
+        F77_SUB(lowesc)(n, hat_matrix, LL, trL, one_delta, two_delta);
+        F77_SUB(lowese)(iv, &liv, &lv, v, n, x, surface);
+        loess_prune(parameter, a, xi, vert, vval);
+        Free(hat_matrix);
+        Free(LL);
+    }
+    else if (!strcmp(*surf_stat, "direct/exact")) {
+        hat_matrix = Calloc((*n)*(*n), double);
+        LL = Calloc((*n)*(*n), double);
+        F77_SUB(lowesf)(x, y, weights, iv, liv, lv, v, n, x,
+            hat_matrix, &two, surface);
+        F77_SUB(lowesc)(n, hat_matrix, LL, trL, one_delta, two_delta);
+                k = (*n) + 1;
+        for(i = 0; i < (*n); i++)
+            diagonal[i] = hat_matrix[i * k];
+        Free(hat_matrix);
+        Free(LL);
+    }
+    loess_free();
+}
+
+loess_dfit(double *y, double *x, double *x_evaluate, double *weights,
+           double *span, int *degree, int *nonparametric,
+           int *drop_square, int *sum_drop_sqr, int *d, int *n, int *m,
+           double *fit)
+{
+    int    zero = 0, one = 1;
+    loess_workspace(d, n, span, degree, nonparametric, drop_square,
+                    sum_drop_sqr, &zero);
+    F77_SUB(lowesf)(x, y, weights, iv, &liv, &lv, v, m, x_evaluate,
+                    &zero, &zero, fit);
+    loess_free();
+}
+
+loess_dfitse(double *y, double *x, double *x_evaluate, double *weights,
+             double *robust, int *family, double *span, int *degree,
+             int *nonparametric, int *drop_square, int *sum_drop_sqr,
+             int *d, int *n, int *m, double *fit, double *L)
+{
+    int    zero = 0, one = 1, two = 2;
+    loess_workspace(d, n, span, degree, nonparametric, drop_square,
+                    sum_drop_sqr, &zero);
+    if(*family == GAUSSIAN)
+        F77_SUB(lowesf)(x, y, weights, iv, &liv, &lv, v, m,
+                        x_evaluate, L, &two, fit);
+    else if(*family == SYMMETRIC)
+    {
+        F77_SUB(lowesf)(x, y, weights, iv, &liv, &lv, v, m,
+                        x_evaluate, L, &two, fit);
+        F77_SUB(lowesf)(x, y, robust, iv, &liv, &lv, v, m,
+                        x_evaluate, &zero, &zero, fit);
+    }
+    loess_free();
+}
+
+loess_ifit(long *parameter, long *a, double *xi, double *vert, double *vval,
+           int *m, double *x_evaluate, double *fit)
+{
+    loess_grow(parameter, a, xi, vert, vval);
+    F77_SUB(lowese)(iv, &liv, &lv, v, m, x_evaluate, fit);
+    loess_free();
+}
+
+loess_ise(double *y, double *x, double *x_evaluate, double *weights,
+          double *span, int *degree, int *nonparametric, int *drop_square,
+          int *sum_drop_sqr, double *cell, int *d, int *n, int *m,
+          double *fit, double *L)
+{
+    int    zero = 0, one = 1;
+    loess_workspace(d, n, span, degree, nonparametric, drop_square,
+                   sum_drop_sqr, &one);
+    v[1] = *cell;
+    F77_SUB(lowesb)(x, y, weights, &zero, &zero, iv, &liv, &lv, v);
+    F77_SUB(lowesl)(iv, &liv, &lv, v, m, x_evaluate, L);
+    loess_free();
+}
+
+loess_workspace(int *d, int *n, double *span, int *degree,
+                int *nonparametric, int *drop_square, int *sum_drop_sqr,
+                int *setLf)
+{
+    int    D, N, tau0, nvmax, nf, version = 106, i;
+    D = *d;
+    N = *n;
+    nvmax = max(200, N);
+    nf = min(N, floor(N * (*span)));
+    tau0 = ((*degree) > 1) ? ((D + 2) * (D + 1) * 0.5) : (D + 1);
+    tau = tau0 - (*sum_drop_sqr);
+    lv = 50 + (3 * D + 3) * nvmax + N + (tau0 + 2) * nf;
+    liv = 50 + ((int)pow((double)2, (double)D) + 4) * nvmax + 2 * N;
+    if(*setLf) {
+        lv = lv + (D + 1) * nf * nvmax;
+        liv = liv + nf * nvmax;
+    }
+    iv = Calloc(liv, int);
+    v = Calloc(lv, double);
+
+    F77_SUB(lowesd)(&version, iv, &liv, &lv, v, d, n, span, degree,
+                    &nvmax, setLf);
+    iv[32] = *nonparametric;
+    for(i = 0; i < D; i++)
+        iv[i + 40] = drop_square[i];
+}
+
+loess_prune(long *parameter, long *a, double *xi, double *vert, double *vval)
+{
+    int    d, vc, a1, v1, xi1, vv1, nc, nv, nvmax, i, j, k;
+
+    d = iv[1];
+    vc = iv[3] - 1;
+    nc = iv[4];
+    nv = iv[5];
+    a1 = iv[6] - 1;
+    v1 = iv[10] - 1;
+    xi1 = iv[11] - 1;
+    vv1 = iv[12] - 1;
+    nvmax = iv[13];
+
+    for(i = 0; i < 5; i++)
+        parameter[i] = iv[i + 1];
+    parameter[5] = iv[21] - 1;
+    parameter[6] = iv[14] - 1;
+
+    for(i = 0; i < d; i++){
+        k = nvmax * i;
+        vert[i] = v[v1 + k];
+        vert[i + d] = v[v1 + vc + k];
+    }
+    for(i = 0; i < nc; i++) {
+        xi[i] = v[xi1 + i];
+        a[i] = iv[a1 + i];
+    }
+    k = (d + 1) * nv;
+    for(i = 0; i < k; i++)
+        vval[i] = v[vv1 + i];
+}
+
+loess_grow(long *parameter, long *a, double *xi, double *vert, double *vval)
+{
+    int    d, vc, nc, nv, a1, v1, xi1, vv1, i, j, k;
+
+    d = parameter[0];
+    vc = parameter[2];
+    nc = parameter[3];
+    nv = parameter[4];
+    liv = parameter[5];
+    lv = parameter[6];
+    iv = Calloc(liv, int);
+    v = Calloc(lv, double);
+
+    iv[1] = d;
+    iv[2] = parameter[1];
+    iv[3] = vc;
+    iv[5] = iv[13] = nv;
+    iv[4] = iv[16] = nc;
+    iv[6] = 50;
+    iv[7] = iv[6] + nc;
+    iv[8] = iv[7] + vc * nc;
+    iv[9] = iv[8] + nc;
+    iv[10] = 50;
+    iv[12] = iv[10] + nv * d;
+    iv[11] = iv[12] + (d + 1) * nv;
+    iv[27] = 173;
+
+    v1 = iv[10] - 1;
+    xi1 = iv[11] - 1;
+    a1 = iv[6] - 1;
+    vv1 = iv[12] - 1;
+
+    for(i = 0; i < d; i++) {
+        k = nv * i;
+        v[v1 + k] = vert[i];
+        v[v1 + vc - 1 + k] = vert[i + d];
+    }
+    for(i = 0; i < nc; i++) {
+        v[xi1 + i] = xi[i];
+        iv[a1 + i] = a[i];
+    }
+    k = (d + 1) * nv;
+    for(i = 0; i < k; i++)
+        v[vv1 + i] = vval[i];
+
+    F77_SUB(ehg169)(&d, &vc, &nc, &nc, &nv, &nv, v+v1, iv+a1,
+                    v+xi1, iv+iv[7]-1, iv+iv[8]-1, iv+iv[9]-1);
+}
+
+loess_free()
+{
+        Free(v);
+        Free(iv);
+}
+
+/* begin ehg's FORTRAN-callable C-codes */
+
+void*
+F77_SUB(ehg182)(int *i)
+{
+char *mess, mess2[50];
+switch(*i){
+case 100:
+    mess="Wrong version number in lowesd.  Probably typo in caller.";
+    break;
+case 101:
+    mess="d>dMAX in ehg131.  Need to recompile with increased dimensions.";
+    break;
+case 102:
+    mess="liv too small. (Discovered by lowesd)";
+    break;
+case 103:
+    mess="lv too small. (Discovered by lowesd)";
+    break;
+case 104:
+    mess="Span too small. Fewer data values than degrees of freedom.";
+    break;
+case 105:
+    mess="k>d2MAX in ehg136.  Need to recompile with increased dimensions.";
+    break;
+case 106:
+    mess="lwork too small";
+    break;
+case 107:
+    mess="Invalid value for kernel";
+    break;
+case 108:
+    mess="Invalid value for ideg";
+    break;
+case 109:
+    mess="lowstt only applies when kernel=1.";
+    break;
+case 110:
+    mess="Not enough extra workspace for robustness calculation";
+    break;
+case 120:
+    mess="Zero-width neighborhood. Make span bigger";
+    break;
+case 121:
+    mess="All data on boundary of neighborhood. make span bigger";
+    break;
+case 122:
+    mess="Extrapolation not allowed with blending";
+    break;
+case 123:
+    mess="ihat=1 (diag L) in l2fit only makes sense if z=x (eval=data).";
+    break;
+case 171:
+    mess="lowesd must be called first.";
+    break;
+case 172:
+    mess="lowesf must not come between lowesb and lowese, lowesr, or lowesl.";
+    break;
+case 173:
+    mess="lowesb must come before lowese, lowesr, or lowesl.";
+    break;
+case 174:
+    mess="lowesb need not be called twice.";
+    break;
+case 175:
+    mess="Need setLf=.true. for lowesl.";
+    break;
+case 180:
+    mess="nv>nvmax in cpvert.";
+    break;
+case 181:
+    mess="nt>20 in eval.";
+    break;
+case 182:
+    mess="svddc failed in l2fit.";
+    break;
+case 183:
+    mess="Did not find edge in vleaf.";
+    break;
+case 184:
+    mess="Zero-width cell found in vleaf.";
+    break;
+case 185:
+    mess="Trouble descending to leaf in vleaf.";
+    break;
+case 186:
+    mess="Insufficient workspace for lowesf.";
+    break;
+case 187:
+    mess="Insufficient stack space.";
+    break;
+case 188:
+    mess="lv too small for computing explicit L.";
+    break;
+case 191:
+    mess="Computed trace L was negative; something is wrong!";
+    break;
+case 192:
+    mess="Computed delta was negative; something is wrong!";
+    break;
+case 193:
+    mess="Workspace in loread appears to be corrupted.";
+    break;
+case 194:
+    mess="Trouble in l2fit/l2tr";
+    break;
+case 195:
+    mess="Only constant, linear, or quadratic local models allowed";
+    break;
+case 196:
+    mess="degree must be at least 1 for vertex influence matrix";
+    break;
+case 999:
+    mess="not yet implemented";
+    break;
+default:
+    sprintf(mess=mess2,"Assert failed; error code %d\n",*i);
+    break;
+    }
+//    printf(mess);
+    error_status = 1;
+    error_message = mess;
+}
+
+void
+F77_SUB(ehg183)(char *s,int *i, int *n, int *inc)
+{
+    char mess[4000], num[20];
+    int j;
+    strcpy(mess,s);
+    for (j=0; j<*n; j++) {
+        sprintf(num," %d",i[j * *inc]);
+        strcat(mess,num);
+    }
+    strcat(mess,"\n");
+//    printf(mess);
+    error_status = 1;
+    error_message = mess;
+}
+
+void
+F77_SUB(ehg184)(char *s, double *x, int *n, int *inc)
+{
+    char mess[4000], num[30];
+    int j;
+    strcpy(mess,s);
+    for (j=0; j<*n; j++) {
+        sprintf(num," %.5g",x[j * *inc]);
+        strcat(mess,num);
+    }
+    strcat(mess,"\n");
+//    printf(mess);
+    error_status = 1;
+    error_message = mess;
+}

Added: trunk/Lib/sandbox/pyloess/src/loessf.f
===================================================================
--- trunk/Lib/sandbox/pyloess/src/loessf.f	2007-03-21 21:28:18 UTC (rev 2862)
+++ trunk/Lib/sandbox/pyloess/src/loessf.f	2007-03-21 22:53:54 UTC (rev 2863)
@@ -0,0 +1,2288 @@
+      subroutine ehg126(d,n,vc,x,v,nvmax)
+      integer d,execnt,i,j,k,n,nv,nvmax,vc
+      DOUBLE PRECISION machin,alpha,beta,mu,t
+      DOUBLE PRECISION v(nvmax,d),x(n,d)
+      DOUBLE PRECISION D1MACH
+      external D1MACH
+      save machin,execnt
+      data execnt /0/
+c     MachInf -> machin
+      execnt=execnt+1
+      if(execnt.eq.1)then
+         machin=D1MACH(2)
+      end if
+c     fill in vertices for bounding box of $x$
+c     lower left, upper right
+      do 3 k=1,d
+         alpha=machin
+         beta=-machin
+         do 4 i=1,n
+            t=x(i,k)
+            alpha=min(alpha,t)
+            beta=max(beta,t)
+    4    continue
+c        expand the box a little
+         mu=0.005D0*max(beta-alpha,1.d-10*max(DABS(alpha),DABS(beta))+1.
+     +d-30)
+         alpha=alpha-mu
+         beta=beta+mu
+         v(1,k)=alpha
+         v(vc,k)=beta
+    3 continue
+c     remaining vertices
+      do 5 i=2,vc-1
+         j=i-1
+         do 6 k=1,d
+            v(i,k)=v(1+mod(j,2)*(vc-1),k)
+            j=DFLOAT(j)/2.D0
+    6    continue
+    5 continue
+      return
+      end
+C----------------------------------------------------------------------C
+C     cpvert
+      subroutine ehg125(p,nv,v,vhit,nvmax,d,k,t,r,s,f,l,u)
+      logical i1,i2,match
+      integer d,execnt,h,i,i3,j,k,m,mm,nv,nvmax,p,r,s
+      integer f(r,0:1,s),l(r,0:1,s),u(r,0:1,s),vhit(nvmax)
+      DOUBLE PRECISION t
+      DOUBLE PRECISION v(nvmax,d)
+      external ehg182
+      save execnt
+      data execnt /0/
+      execnt=execnt+1
+      h=nv
+      do 3 i=1,r
+         do 4 j=1,s
+            h=h+1
+            do 5 i3=1,d
+               v(h,i3)=v(f(i,0,j),i3)
+    5       continue
+            v(h,k)=t
+c           check for redundant vertex
+            match=.false.
+            m=1
+c           top of while loop
+    6       if(.not.match)then
+               i1=(m.le.nv)
+            else
+               i1=.false.
+            end if
+            if(.not.(i1))goto 7
+               match=(v(m,1).eq.v(h,1))
+               mm=2
+c              top of while loop
+    8          if(match)then
+                  i2=(mm.le.d)
+               else
+                  i2=.false.
+               end if
+               if(.not.(i2))goto 9
+                  match=(v(m,mm).eq.v(h,mm))
+                  mm=mm+1
+                  goto 8
+c              bottom of while loop
+    9          m=m+1
+               goto 6
+c           bottom of while loop
+    7       m=m-1
+            if(match)then
+               h=h-1
+            else
+               m=h
+               if(vhit(1).ge.0)then
+                  vhit(m)=p
+               end if
+            end if
+            l(i,0,j)=f(i,0,j)
+            l(i,1,j)=m
+            u(i,0,j)=m
+            u(i,1,j)=f(i,1,j)
+    4    continue
+    3 continue
+      nv=h
+      if(.not.(nv.le.nvmax))then
+         call ehg182(180)
+      end if
+      return
+      end
+C-----------------------------------------------------------------------
+C     descend
+      integer function ehg138(i,z,a,xi,lo,hi,ncmax)
+      logical i1
+      integer d,execnt,i,j,nc,ncmax
+      integer a(ncmax),hi(ncmax),lo(ncmax)
+      DOUBLE PRECISION xi(ncmax),z(8)
+      save execnt
+      data execnt /0/
+      execnt=execnt+1
+c     descend tree until leaf or ambiguous
+      j=i
+c     top of while loop
+    3 if(a(j).ne.0)then
+         i1=(z(a(j)).ne.xi(j))
+      else
+         i1=.false.
+      end if
+      if(.not.(i1))goto 4
+         if(z(a(j)).le.xi(j))then
+            j=lo(j)
+         else
+            j=hi(j)
+         end if
+         goto 3
+c     bottom of while loop
+    4 ehg138=j
+      return
+      end
+
+C----------------------------------------------------------------------C
+C     select q-th smallest by partial sorting
+      subroutine ehg106(il,ir,k,nk,p,pi,n)
+      integer execnt,i,ii,il,ir,j,k,l,n,nk,r
+      integer pi(n)
+      DOUBLE PRECISION t
+      DOUBLE PRECISION p(nk,n)
+      save execnt
+      data execnt /0/
+      execnt=execnt+1
+c     find the $k$-th smallest of $n$ elements
+c     Floyd+Rivest, CACM Mar '75, Algorithm 489
+      l=il
+      r=ir
+c     top of while loop
+    3 if(.not.(l.lt.r))goto 4
+c        to avoid recursion, sophisticated partition deleted
+c        partition $x sub {l..r}$ about $t$
+         t=p(1,pi(k))
+         i=l
+         j=r
+         ii=pi(l)
+         pi(l)=pi(k)
+         pi(k)=ii
+         if(t.lt.p(1,pi(r)))then
+            ii=pi(l)
+            pi(l)=pi(r)
+            pi(r)=ii
+         end if
+c        top of while loop
+    5    if(.not.(i.lt.j))goto 6
+            ii=pi(i)
+            pi(i)=pi(j)
+            pi(j)=ii
+            i=i+1
+            j=j-1
+c           top of while loop
+    7       if(.not.(p(1,pi(i)).lt.t))goto 8
+               i=i+1
+               goto 7
+c           bottom of while loop
+    8       continue
+c           top of while loop
+    9       if(.not.(t.lt.p(1,pi(j))))goto 10
+               j=j-1
+               goto 9
+c           bottom of while loop
+   10       goto 5
+c        bottom of while loop
+    6    if(p(1,pi(l)).eq.t)then
+            ii=pi(l)
+            pi(l)=pi(j)
+            pi(j)=ii
+         else
+            j=j+1
+            ii=pi(r)
+            pi(r)=pi(j)
+            pi(j)=ii
+         end if
+         if(j.le.k)then
+            l=j+1
+         end if
+         if(k.le.j)then
+            r=j-1
+         end if
+         goto 3
+c     bottom of while loop
+    4 return
+      end
+
+C----------------------------------------------------------------------C
+C     l2fit,l2tr computational kernel
+      subroutine ehg127(q,n,d,nf,f,x,psi,y,rw,kernel,k,dist,eta,b,od,w,r
+     +cond,sing,sigma,u,e,dgamma,qraux,work,tol,dd,tdeg,cdeg,s)
+      integer column,d,dd,execnt,i,i3,i9,info,inorm2,j,jj,jpvt,k,kernel,
+     +n,nf,od,sing,tdeg
+      integer cdeg(8),psi(n)
+      double precision machep,f,i1,i10,i2,i4,i5,i6,i7,i8,rcond,rho,scal,
+     +tol
+      double precision g(15),sigma(15),u(15,15),e(15,15),b(nf,k),colnor(
+     +15),dist(n),eta(nf),dgamma(15),q(d),qraux(15),rw(n),s(0:od),w(nf),
+     +work(15),x(n,d),y(n)
+      external ehg106,ehg182,ehg184,dqrdc,dqrsl,dsvdc
+      integer idamax
+      external idamax
+      double precision d1mach
+      external d1mach
+      double precision ddot
+      external ddot
+      save machep,execnt
+      data execnt /0/
+c     colnorm -> colnor
+c     E -> g
+c     MachEps -> machep
+c     V -> e
+c     X -> b
+      execnt=execnt+1
+      if(execnt.eq.1)then
+         machep=d1mach(4)
+      end if
+c     sort by distance
+      do 3 i3=1,n
+         dist(i3)=0
+    3 continue
+      do 4 j=1,dd
+         i4=q(j)
+         do 5 i3=1,n
+            dist(i3)=dist(i3)+(x(i3,j)-i4)**2
+    5    continue
+    4 continue
+      call ehg106(1,n,nf,1,dist,psi,n)
+      rho=dist(psi(nf))*max(1.d0,f)
+      if(.not.(0.lt.rho))then
+         call ehg182(120)
+      end if
+c     compute neighborhood weights
+      if(kernel.eq.2)then
+         do 6 i=1,nf
+            if(dist(psi(i)).lt.rho)then
+               i1=dsqrt(rw(psi(i)))
+            else
+               i1=0
+            end if
+            w(i)=i1
+    6    continue
+      else
+         do 7 i3=1,nf
+            w(i3)=dsqrt(dist(psi(i3))/rho)
+    7    continue
+         do 8 i3=1,nf
+            w(i3)=dsqrt(rw(psi(i3))*(1-w(i3)**3)**3)
+    8    continue
+      end if
+      if(dabs(w(idamax(nf,w,1))).eq.0)then
+         call ehg184('at ',q,dd,1)
+         call ehg184('radius ',rho,1,1)
+         if(.not..false.)then
+            call ehg182(121)
+         end if
+      end if
+c     fill design matrix
+      column=1
+      do 9 i3=1,nf
+         b(i3,column)=w(i3)
+    9 continue
+      if(tdeg.ge.1)then
+         do 10 j=1,d
+            if(cdeg(j).ge.1)then
+               column=column+1
+               i5=q(j)
+               do 11 i3=1,nf
+                  b(i3,column)=w(i3)*(x(psi(i3),j)-i5)
+   11          continue
+            end if
+   10    continue
+      end if
+      if(tdeg.ge.2)then
+         do 12 j=1,d
+            if(cdeg(j).ge.1)then
+               if(cdeg(j).ge.2)then
+                  column=column+1
+                  i6=q(j)
+                  do 13 i3=1,nf
+                     b(i3,column)=w(i3)*(x(psi(i3),j)-i6)**2
+   13             continue
+               end if
+               do 14 jj=j+1,d
+                  if(cdeg(jj).ge.1)then
+                     column=column+1
+                     i7=q(j)
+                     i8=q(jj)
+                     do 15 i3=1,nf
+                        b(i3,column)=w(i3)*(x(psi(i3),j)-i7)*(x(psi(i3),
+     +jj)-i8)
+   15                continue
+                  end if
+   14          continue
+            end if
+   12    continue
+         k=column
+      end if
+      do 16 i3=1,nf
+         eta(i3)=w(i3)*y(psi(i3))
+   16 continue
+c     equilibrate columns
+      do 17 j=1,k
+         scal=0
+         do 18 inorm2=1,nf
+            scal=scal+b(inorm2,j)**2
+   18    continue
+         scal=dsqrt(scal)
+         if(0.lt.scal)then
+            do 19 i3=1,nf
+               b(i3,j)=b(i3,j)/scal
+   19       continue
+            colnor(j)=scal
+         else
+            colnor(j)=1
+         end if
+   17 continue
+c     singular value decomposition
+      call dqrdc(b,nf,nf,k,qraux,jpvt,work,0)
+      call dqrsl(b,nf,nf,k,qraux,eta,work,eta,eta,work,work,1000,info)
+      do 20 i9=1,k
+         do 21 i3=1,k
+            u(i3,i9)=0
+   21    continue
+   20 continue
+      do 22 i=1,k
+         do 23 j=i,k
+            u(i,j)=b(i,j)
+   23    continue
+   22 continue
+      call dsvdc(u,15,k,k,sigma,g,u,15,e,15,work,21,info)
+      if(.not.(info.eq.0))then
+         call ehg182(182)
+      end if
+      tol=sigma(1)*(100*machep)
+      rcond=min(rcond,sigma(k)/sigma(1))
+      if(sigma(k).le.tol)then
+         sing=sing+1
+         if(sing.eq.1)then
+            call ehg184('Warning. pseudoinverse used at',q,d,1)
+            call ehg184('neighborhood radius',dsqrt(rho),1,1)
+            call ehg184('reciprocal condition number ',rcond,1,1)
+         else
+            if(sing.eq.2)then
+               call ehg184('There are other near singularities as well.'
+     +,rho,1,1)
+            end if
+         end if
+      end if
+c     compensate for equilibration
+      do 24 j=1,k
+         i10=colnor(j)
+         do 25 i3=1,k
+            e(j,i3)=e(j,i3)/i10
+   25    continue
+   24 continue
+c     solve least squares problem
+      do 26 j=1,k
+         if(tol.lt.sigma(j))then
+            i2=ddot(k,u(1,j),1,eta,1)/sigma(j)
+         else
+            i2=0.d0
+         end if
+         dgamma(j)=i2
+   26 continue
+      do 27 j=0,od
+c        bug fix 2006-07-04 for k=1, od>1.   (thanks btyner@gmail.com)
+         if(j.lt.k)then
+            s(j)=ddot(k,e(j+1,1),15,dgamma,1)
+         else
+            s(j)=0.d0
+         end if
+   27 continue
+      return
+      end
+
+C----------------------------------------------------------------------C
+C     lowesb after workspace expansion
+      subroutine ehg131(x,y,rw,trl,diagl,kernel,k,n,d,nc,ncmax,vc,nv,nvm
+     +ax,nf,f,a,c,hi,lo,pi,psi,v,vhit,vval,xi,dist,eta,b,ntol,fd,w,vval2
+     +,rcond,sing,dd,tdeg,cdeg,lq,lf,setlf)
+      logical setlf
+      integer identi,d,dd,execnt,i1,i2,j,k,kernel,n,nc,ncmax,nf,ntol,nv,
+     +nvmax,sing,tdeg,vc
+      integer lq(nvmax,nf),a(ncmax),c(vc,ncmax),cdeg(8),hi(ncmax),lo(ncm
+     +ax),pi(n),psi(n),vhit(nvmax)
+      double precision f,fd,rcond,trl
+      double precision lf(0:d,nvmax,nf),b(*),delta(8),diagl(n),dist(n),e
+     +ta(nf),rw(n),v(nvmax,d),vval(0:d,nvmax),vval2(0:d,nvmax),w(nf),x(n
+     +,d),xi(ncmax),y(n)
+      external ehg126,ehg182,ehg139,ehg124
+      double precision dnrm2
+      external dnrm2
+      save execnt
+      data execnt /0/
+c     Identity -> identi
+c     X -> b
+      execnt=execnt+1
+      if(.not.(d.le.8))then
+         call ehg182(101)
+      end if
+c     build $k$-d tree
+      call ehg126(d,n,vc,x,v,nvmax)
+      nv=vc
+      nc=1
+      do 3 j=1,vc
+         c(j,nc)=j
+         vhit(j)=0
+    3 continue
+      do 4 i1=1,d
+         delta(i1)=v(vc,i1)-v(1,i1)
+    4 continue
+      fd=fd*dnrm2(d,delta,1)
+      do 5 identi=1,n
+         pi(identi)=identi
+    5 continue
+      call ehg124(1,n,d,n,nv,nc,ncmax,vc,x,pi,a,xi,lo,hi,c,v,vhit,nvmax,
+     +ntol,fd,dd)
+c     smooth
+      if(trl.ne.0)then
+         do 6 i2=1,nv
+            do 7 i1=0,d
+               vval2(i1,i2)=0
+    7       continue
+    6    continue
+      end if
+      call ehg139(v,nvmax,nv,n,d,nf,f,x,pi,psi,y,rw,trl,kernel,k,dist,di
+     +st,eta,b,d,w,diagl,vval2,nc,vc,a,xi,lo,hi,c,vhit,rcond,sing,dd,tde
+     +g,cdeg,lq,lf,setlf,vval)
+      return
+      end
+
+C----------------------------------------------------------------------C
+C     lowese after workspace expansion
+      subroutine ehg133(n,d,vc,nvmax,nc,ncmax,a,c,hi,lo,v,vval,xi,m,z,s)
+      integer d,execnt,i,i1,m,nc,ncmax,nv,nvmax,vc
+      integer a(ncmax),c(vc,ncmax),hi(ncmax),lo(ncmax)
+      double precision delta(8),s(m),v(nvmax,d),vval(0:d,nvmax),xi(ncmax
+     +),z(m,d)
+      double precision ehg128
+      external ehg128
+      save execnt
+      data execnt /0/
+      execnt=execnt+1
+      do 3 i=1,m
+         do 4 i1=1,d
+            delta(i1)=z(i,i1)
+    4    continue
+         s(i)=ehg128(delta,d,ncmax,vc,a,xi,lo,hi,c,v,nvmax,vval)
+    3 continue
+      return
+      end
+      subroutine ehg140(iw,i,j)
+      integer execnt,i,j
+      integer iw(i)
+      save execnt
+      data execnt /0/
+      execnt=execnt+1
+      iw(i)=j
+      return
+      end
+
+C----------------------------------------------------------------------C
+C     delta1,2 from trL
+      subroutine ehg141(trl,n,deg,k,d,nsing,dk,delta1,delta2)
+      integer d,deg,dk,k,n,nsing
+      external ehg176
+      double precision ehg176
+      double precision corx,delta1,delta2,trl,z
+      double precision c(48), c1, c2, c3, c4
+c     coef, d, deg, del
+      data c / .2971620d0,.3802660d0,.5886043d0,.4263766d0,.3346498d0,.6
+     +271053d0,.5241198d0,.3484836d0,.6687687d0,.6338795d0,.4076457d0,.7
+     +207693d0,.1611761d0,.3091323d0,.4401023d0,.2939609d0,.3580278d0,.5
+     +555741d0,.3972390d0,.4171278d0,.6293196d0,.4675173d0,.4699070d0,.6
+     +674802d0,.2848308d0,.2254512d0,.2914126d0,.5393624d0,.2517230d0,.3
+     +898970d0,.7603231d0,.2969113d0,.4740130d0,.9664956d0,.3629838d0,.5
+     +348889d0,.2075670d0,.2822574d0,.2369957d0,.3911566d0,.2981154d0,.3
+     +623232d0,.5508869d0,.3501989d0,.4371032d0,.7002667d0,.4291632d0,.4
+     +930370d0 /
+      if(deg.eq.0) dk=1
+      if(deg.eq.1) dk=d+1
+      if(deg.eq.2) dk=dfloat((d+2)*(d+1))/2.d0
+      corx=dsqrt(k/dfloat(n))
+      z=(dsqrt(k/trl)-corx)/(1-corx)
+      if(nsing .eq. 0 .and. 1 .lt. z)   call ehg184('Chernobyl! trL<k',t
+     +rl,1,1)
+      if(z .lt. 0) call ehg184('Chernobyl! trL>n',trl,1,1)
+      z=min(1.0d0,max(0.0d0,z))
+      c4=dexp(ehg176(z))
+      i=1+3*(min(d,4)-1+4*(deg-1))
+      if(d.le.4)then
+         c1=c(i)
+         c2=c(i+1)
+         c3=c(i+2)
+      else
+         c1=c(i)+(d-4)*(c(i)-c(i-3))
+         c2=c(i+1)+(d-4)*(c(i+1)-c(i-2))
+         c3=c(i+2)+(d-4)*(c(i+2)-c(i-1))
+      endif
+      delta1=n-trl*dexp(c1*z**c2*(1-z)**c3*c4)
+      i=i+24
+      if(d.le.4)then
+         c1=c(i)
+         c2=c(i+1)
+         c3=c(i+2)
+      else
+         c1=c(i)+(d-4)*(c(i)-c(i-3))
+         c2=c(i+1)+(d-4)*(c(i+1)-c(i-2))
+         c3=c(i+2)+(d-4)*(c(i+2)-c(i-1))
+      endif
+      delta2=n-trl*dexp(c1*z**c2*(1-z)**c3*c4)
+      return
+      end
+
+C----------------------------------------------------------------------C
+C     exact delta
+      subroutine lowesc(n,l,ll,trl,delta1,delta2)
+      integer execnt,i,j,n
+      double precision delta1,delta2,trl
+      double precision l(n,n),ll(n,n)
+      double precision ddot
+      external ddot
+      save execnt
+      data execnt /0/
+      execnt=execnt+1
+c     compute $LL~=~(I-L)(I-L)'$
+      do 3 i=1,n
+         l(i,i)=l(i,i)-1
+    3 continue
+      do 4 i=1,n
+         do 5 j=1,i
+            ll(i,j)=ddot(n,l(i,1),n,l(j,1),n)
+    5    continue
+    4 continue
+      do 6 i=1,n
+         do 7 j=i+1,n
+            ll(i,j)=ll(j,i)
+    7    continue
+    6 continue
+      do 8 i=1,n
+         l(i,i)=l(i,i)+1
+    8 continue
+c     accumulate first two traces
+      trl=0
+      delta1=0
+      do 9 i=1,n
+         trl=trl+l(i,i)
+         delta1=delta1+ll(i,i)
+    9 continue
+c     $delta sub 2 = "tr" LL sup 2$
+      delta2=0
+      do 10 i=1,n
+         delta2=delta2+ddot(n,ll(i,1),n,ll(1,i),1)
+   10 continue
+      return
+      end
+
+C----------------------------------------------------------------------C
+C     compute derived k-d tree information
+      subroutine ehg169(d,vc,nc,ncmax,nv,nvmax,v,a,xi,c,hi,lo)
+      integer d,execnt,i,j,k,mc,mv,nc,ncmax,nv,nvmax,p,vc
+      integer a(ncmax),c(vc,ncmax),hi(ncmax),lo(ncmax),novhit(1)
+      DOUBLE PRECISION v(nvmax,d),xi(ncmax)
+      external ehg125,ehg182
+      integer ifloor
+      external ifloor
+      save execnt
+      data execnt /0/
+      execnt=execnt+1
+c     as in bbox
+c     remaining vertices
+      do 3 i=2,vc-1
+         j=i-1
+         do 4 k=1,d
+            v(i,k)=v(1+mod(j,2)*(vc-1),k)
+            j=ifloor(DFLOAT(j)/2.D0)
+    4    continue
+    3 continue
+c     as in ehg131
+      mc=1
+      mv=vc
+      novhit(1)=-1
+      do 5 j=1,vc
+         c(j,mc)=j
+    5 continue
+c     as in rbuild
+      p=1
+c     top of while loop
+    6 if(.not.(p.le.nc))goto 7
+         if(a(p).ne.0)then
+            k=a(p)
+c           left son
+            mc=mc+1
+            lo(p)=mc
+c           right son
+            mc=mc+1
+            hi(p)=mc
+            call ehg125(p,mv,v,novhit,nvmax,d,k,xi(p),2**(k-1),2**(d-k),
+     +c(1,p),c(1,lo(p)),c(1,hi(p)))
+         end if
+         p=p+1
+         goto 6
+c     bottom of while loop
+    7 if(.not.(mc.eq.nc))then
+         call ehg182(193)
+      end if
+      if(.not.(mv.eq.nv))then
+         call ehg182(193)
+      end if
+      return
+      end
+
+C----------------------------------------------------------------------C
+C     loeval for delta
+       DOUBLE PRECISION function ehg176(z)
+       DOUBLE PRECISION z(*)
+       integer d,vc,nv,nc
+       integer a(17), c(2,17)
+       integer hi(17), lo(17)
+       DOUBLE PRECISION v(10,1)
+       DOUBLE PRECISION vval(0:1,10)
+       DOUBLE PRECISION xi(17)
+       DOUBLE PRECISION ehg128
+       data d,vc,nv,nc /1,2,10,17/
+       data a(1) /1/
+       data hi(1),lo(1),xi(1) /3,2,0.3705D0/
+       data c(1,1) /1/
+       data c(2,1) /2/
+       data a(2) /1/
+       data hi(2),lo(2),xi(2) /5,4,0.2017D0/
+       data c(1,2) /1/
+       data c(2,2) /3/
+       data a(3) /1/
+       data hi(3),lo(3),xi(3) /7,6,0.5591D0/
+       data c(1,3) /3/
+       data c(2,3) /2/
+       data a(4) /1/
+       data hi(4),lo(4),xi(4) /9,8,0.1204D0/
+       data c(1,4) /1/
+       data c(2,4) /4/
+       data a(5) /1/
+       data hi(5),lo(5),xi(5) /11,10,0.2815D0/
+       data c(1,5) /4/
+       data c(2,5) /3/
+       data a(6) /1/
+       data hi(6),lo(6),xi(6) /13,12,0.4536D0/
+       data c(1,6) /3/
+       data c(2,6) /5/
+       data a(7) /1/
+       data hi(7),lo(7),xi(7) /15,14,0.7132D0/
+       data c(1,7) /5/
+       data c(2,7) /2/
+       data a(8) /0/
+       data c(1,8) /1/
+       data c(2,8) /6/
+       data a(9) /0/
+       data c(1,9) /6/
+       data c(2,9) /4/
+       data a(10) /0/
+       data c(1,10) /4/
+       data c(2,10) /7/
+       data a(11) /0/
+       data c(1,11) /7/
+       data c(2,11) /3/
+       data a(12) /0/
+       data c(1,12) /3/
+       data c(2,12) /8/
+       data a(13) /0/
+       data c(1,13) /8/
+       data c(2,13) /5/
+       data a(14) /0/
+       data c(1,14) /5/
+       data c(2,14) /9/
+       data a(15) /1/
+       data hi(15),lo(15),xi(15) /17,16,0.8751D0/
+       data c(1,15) /9/
+       data c(2,15) /2/
+       data a(16) /0/
+       data c(1,16) /9/
+       data c(2,16) /10/
+       data a(17) /0/
+       data c(1,17) /10/
+       data c(2,17) /2/
+       data vval(0,1) /-9.0572D-2/
+       data v(1,1) /-5.D-3/
+       data vval(1,1) /4.4844D0/
+       data vval(0,2) /-1.0856D-2/
+       data v(2,1) /1.005D0/
+       data vval(1,2) /-0.7736D0/
+       data vval(0,3) /-5.3718D-2/
+       data v(3,1) /0.3705D0/
+       data vval(1,3) /-0.3495D0/
+       data vval(0,4) /2.6152D-2/
+       data v(4,1) /0.2017D0/
+       data vval(1,4) /-0.7286D0/
+       data vval(0,5) /-5.8387D-2/
+       data v(5,1) /0.5591D0/
+       data vval(1,5) /0.1611D0/
+       data vval(0,6) /9.5807D-2/
+       data v(6,1) /0.1204D0/
+       data vval(1,6) /-0.7978D0/
+       data vval(0,7) /-3.1926D-2/
+       data v(7,1) /0.2815D0/
+       data vval(1,7) /-0.4457D0/
+       data vval(0,8) /-6.4170D-2/
+       data v(8,1) /0.4536D0/
+       data vval(1,8) /3.2813D-2/
+       data vval(0,9) /-2.0636D-2/
+       data v(9,1) /0.7132D0/
+       data vval(1,9) /0.3350D0/
+       data vval(0,10) /4.0172D-2/
+       data v(10,1) /0.8751D0/
+       data vval(1,10) /-4.1032D-2/
+       ehg176=ehg128(z,d,nc,vc,a,xi,lo,hi,c,v,nv,vval)
+       end
+
+C----------------------------------------------------------------------C
+C     approximate delta
+      subroutine lowesa(trl,n,d,tau,nsing,delta1,delta2)
+      integer d,dka,dkb,execnt,n,nsing,tau
+      double precision alpha,d1a,d1b,d2a,d2b,delta1,delta2,trl
+      external ehg141
+      save execnt
+      data execnt /0/
+      execnt=execnt+1
+      call ehg141(trl,n,1,tau,d,nsing,dka,d1a,d2a)
+      call ehg141(trl,n,2,tau,d,nsing,dkb,d1b,d2b)
+      alpha=dfloat(tau-dka)/dfloat(dkb-dka)
+      delta1=(1-alpha)*d1a+alpha*d1b
+      delta2=(1-alpha)*d2a+alpha*d2b
+      return
+      end
+
+C----------------------------------------------------------------------C
+C     lowesl after workspace expansion
+      subroutine ehg191(m,z,l,d,n,nf,nv,ncmax,vc,a,xi,lo,hi,c,v,nvmax,vv
+     +al2,lf,lq)
+      integer lq1,d,execnt,i,i1,i2,j,m,n,nc,ncmax,nf,nv,nvmax,p,vc
+      integer lq(nvmax,nf),a(ncmax),c(vc,ncmax),hi(ncmax),lo(ncmax)
+      double precision l(m,n),lf(0:d,nvmax,nf),v(nvmax,d),vval2(0:d,nvma
+     +x),xi(ncmax),z(m,d),zi(8)
+      double precision ehg128
+      external ehg128
+      save execnt
+      data execnt /0/
+      execnt=execnt+1
+      do 3 j=1,n
+         do 4 i2=1,nv
+            do 5 i1=0,d
+               vval2(i1,i2)=0
+    5       continue
+    4    continue
+         do 6 i=1,nv
+c           linear search for i in Lq
+            lq1=lq(i,1)
+            lq(i,1)=j
+            p=nf
+c           top of while loop
+    7       if(.not.(lq(i,p).ne.j))goto 8
+               p=p-1
+               goto 7
+c           bottom of while loop
+    8       lq(i,1)=lq1
+            if(lq(i,p).eq.j)then
+               do 9 i1=0,d
+                  vval2(i1,i)=lf(i1,i,p)
+    9          continue
+            end if
+    6    continue
+         do 10 i=1,m
+            do 11 i1=1,d
+               zi(i1)=z(i,i1)
+   11       continue
+            l(i,j)=ehg128(zi,d,ncmax,vc,a,xi,lo,hi,c,v,nvmax,vval2)
+   10    continue
+    3 continue
+      return
+      end
+
+C----------------------------------------------------------------------C
+C     trL approximation
+      subroutine ehg196(tau,d,f,trl)
+      integer d,dka,dkb,execnt,tau
+      double precision alpha,f,trl,trla,trlb
+      external ehg197
+      save execnt
+      data execnt /0/
+      execnt=execnt+1
+      call ehg197(1,tau,d,f,dka,trla)
+      call ehg197(2,tau,d,f,dkb,trlb)
+      alpha=dfloat(tau-dka)/dfloat(dkb-dka)
+      trl=(1-alpha)*trla+alpha*trlb
+      return
+      end
+
+C----------------------------------------------------------------------C
+C     for deg 1,2
+      subroutine ehg197(deg,tau,d,f,dk,trl)
+      integer d,deg,dk,tau
+      double precision trl, f
+      dk = 0
+      if(deg.eq.1) dk=d+1
+      if(deg.eq.2) dk=dfloat((d+2)*(d+1))/2.d0
+      g1 = (-0.08125d0*d+0.13d0)*d+1.05d0
+      trl = dk*(1+max(0.d0,(g1-f)/f))
+      return
+      end
+
+C----------------------------------------------------------------------C
+C     lowesr after workspace expansion
+      subroutine ehg192(y,d,n,nf,nv,nvmax,vval,lf,lq)
+      integer d,execnt,i,i1,i2,j,n,nf,nv,nvmax
+      integer lq(nvmax,nf)
+      DOUBLE PRECISION i3
+      DOUBLE PRECISION lf(0:d,nvmax,nf),vval(0:d,nvmax),y(n)
+      save execnt
+      data execnt /0/
+      execnt=execnt+1
+      do 3 i2=1,nv
+         do 4 i1=0,d
+            vval(i1,i2)=0
+    4    continue
+    3 continue
+      do 5 i=1,nv
+         do 6 j=1,nf
+            i3=y(lq(i,j))
+            do 7 i1=0,d
+               vval(i1,i)=vval(i1,i)+i3*lf(i1,i,j)
+    7       continue
+    6    continue
+    5 continue
+      return
+      end
+
+
+C----------------------------------------------------------------------C
+C     eval
+      DOUBLE PRECISION function ehg128(z,d,ncmax,vc,a,xi,lo,hi,c,v,nvmax
+     +,vval)
+      logical i10,i2,i3,i4,i5,i6,i7,i8,i9
+      integer d,execnt,i,i1,i11,i12,ig,ii,j,lg,ll,m,nc,ncmax,nt,nv,nvmax
+     +,ur,vc
+      integer a(ncmax),c(vc,ncmax),hi(ncmax),lo(ncmax),t(20)
+      DOUBLE PRECISION ge,gn,gs,gw,gpe,gpn,gps,gpw,h,phi0,phi1,psi0,psi1
+     +,s,sew,sns,v0,v1,xibar
+      DOUBLE PRECISION g(0:8,256),g0(0:8),g1(0:8),v(nvmax,d),vval(0:d,nv
+     +max),xi(ncmax),z(d)
+      external ehg182,ehg184
+      save execnt
+      data execnt /0/
+      execnt=execnt+1
+c     locate enclosing cell
+      nt=1
+      t(nt)=1
+      j=1
+c     top of while loop
+    3 if(.not.(a(j).ne.0))goto 4
+         nt=nt+1
+c     bug fix 2006-07-18 (thanks, btyner@gmail.com)
+         if(z(a(j)).le.xi(j))then
+            i1=lo(j)
+         else
+            i1=hi(j)
+         end if
+         t(nt)=i1
+         if(.not.(nt.lt.20))then
+            call ehg182(181)
+         end if
+         j=t(nt)
+         goto 3
+c     bottom of while loop
+    4 continue
+c     tensor
+      do 5 i12=1,vc
+         do 6 i11=0,d
+            g(i11,i12)=vval(i11,c(i12,j))
+    6    continue
+    5 continue
+      lg=vc
+      ll=c(1,j)
+      ur=c(vc,j)
+      do 7 i=d,1,-1
+         h=(z(i)-v(ll,i))/(v(ur,i)-v(ll,i))
+         if(h.lt.-.001D0)then
+            call ehg184('eval ',z,d,1)
+            call ehg184('lowerlimit ',v(ll,1),d,nvmax)
+         else
+            if(1.001D0.lt.h)then
+               call ehg184('eval ',z,d,1)
+               call ehg184('upperlimit ',v(ur,1),d,nvmax)
+            end if
+         end if
+         if(-.001D0.le.h)then
+            i2=(h.le.1.001D0)
+         else
+            i2=.false.
+         end if
+         if(.not.i2)then
+            call ehg182(122)
+         end if
+         lg=DFLOAT(lg)/2.D0
+         do 8 ig=1,lg
+c           Hermite basis
+            phi0=(1-h)**2*(1+2*h)
+            phi1=h**2*(3-2*h)
+            psi0=h*(1-h)**2
+            psi1=h**2*(h-1)
+            g(0,ig)=phi0*g(0,ig)+phi1*g(0,ig+lg)+(psi0*g(i,ig)+psi1*g(i,
+     +ig+lg))*(v(ur,i)-v(ll,i))
+            do 9 ii=1,i-1
+               g(ii,ig)=phi0*g(ii,ig)+phi1*g(ii,ig+lg)
+    9       continue
+    8    continue
+    7 continue
+      s=g(0,1)
+c     blending
+      if(d.eq.2)then
+c        ----- North -----
+         v0=v(ll,1)
+         v1=v(ur,1)
+         do 10 i11=0,d
+            g0(i11)=vval(i11,c(3,j))
+   10    continue
+         do 11 i11=0,d
+            g1(i11)=vval(i11,c(4,j))
+   11    continue
+         xibar=v(ur,2)
+         m=nt-1
+c        top of while loop
+   12    if(m.eq.0)then
+            i4=.true.
+         else
+            if(a(t(m)).eq.2)then
+               i3=(xi(t(m)).eq.xibar)
+            else
+               i3=.false.
+            end if
+            i4=i3
+         end if
+         if(.not.(.not.i4))goto 13
+            m=m-1
+c           voidp junk
+            goto 12
+c        bottom of while loop
+   13    if(m.ge.1)then
+            m=hi(t(m))
+c           top of while loop
+   14       if(.not.(a(m).ne.0))goto 15
+               if(z(a(m)).le.xi(m))then
+                  m=lo(m)
+               else
+                  m=hi(m)
+               end if
+               goto 14
+c           bottom of while loop
+   15       if(v0.lt.v(c(1,m),1))then
+               v0=v(c(1,m),1)
+               do 16 i11=0,d
+                  g0(i11)=vval(i11,c(1,m))
+   16          continue
+            end if
+            if(v(c(2,m),1).lt.v1)then
+               v1=v(c(2,m),1)
+               do 17 i11=0,d
+                  g1(i11)=vval(i11,c(2,m))
+   17          continue
+            end if
+         end if
+         h=(z(1)-v0)/(v1-v0)
+c        Hermite basis
+         phi0=(1-h)**2*(1+2*h)
+         phi1=h**2*(3-2*h)
+         psi0=h*(1-h)**2
+         psi1=h**2*(h-1)
+         gn=phi0*g0(0)+phi1*g1(0)+(psi0*g0(1)+psi1*g1(1))*(v1-v0)
+         gpn=phi0*g0(2)+phi1*g1(2)
+c        ----- South -----
+         v0=v(ll,1)
+         v1=v(ur,1)
+         do 18 i11=0,d
+            g0(i11)=vval(i11,c(1,j))
+   18    continue
+         do 19 i11=0,d
+            g1(i11)=vval(i11,c(2,j))
+   19    continue
+         xibar=v(ll,2)
+         m=nt-1
+c        top of while loop
+   20    if(m.eq.0)then
+            i6=.true.
+         else
+            if(a(t(m)).eq.2)then
+               i5=(xi(t(m)).eq.xibar)
+            else
+               i5=.false.
+            end if
+            i6=i5
+         end if
+         if(.not.(.not.i6))goto 21
+            m=m-1
+c           voidp junk
+            goto 20
+c        bottom of while loop
+   21    if(m.ge.1)then
+            m=lo(t(m))
+c           top of while loop
+   22       if(.not.(a(m).ne.0))goto 23
+               if(z(a(m)).le.xi(m))then
+                  m=lo(m)
+               else
+                  m=hi(m)
+               end if
+               goto 22
+c           bottom of while loop
+   23       if(v0.lt.v(c(3,m),1))then
+               v0=v(c(3,m),1)
+               do 24 i11=0,d
+                  g0(i11)=vval(i11,c(3,m))
+   24          continue
+            end if
+            if(v(c(4,m),1).lt.v1)then
+               v1=v(c(4,m),1)
+               do 25 i11=0,d
+                  g1(i11)=vval(i11,c(4,m))
+   25          continue
+            end if
+         end if
+         h=(z(1)-v0)/(v1-v0)
+c        Hermite basis
+         phi0=(1-h)**2*(1+2*h)
+         phi1=h**2*(3-2*h)
+         psi0=h*(1-h)**2
+         psi1=h**2*(h-1)
+         gs=phi0*g0(0)+phi1*g1(0)+(psi0*g0(1)+psi1*g1(1))*(v1-v0)
+         gps=phi0*g0(2)+phi1*g1(2)
+c        ----- East -----
+         v0=v(ll,2)
+         v1=v(ur,2)
+         do 26 i11=0,d
+            g0(i11)=vval(i11,c(2,j))
+   26    continue
+         do 27 i11=0,d
+            g1(i11)=vval(i11,c(4,j))
+   27    continue
+         xibar=v(ur,1)
+         m=nt-1
+c        top of while loop
+   28    if(m.eq.0)then
+            i8=.true.
+         else
+            if(a(t(m)).eq.1)then
+               i7=(xi(t(m)).eq.xibar)
+            else
+               i7=.false.
+            end if
+            i8=i7
+         end if
+         if(.not.(.not.i8))goto 29
+            m=m-1
+c           voidp junk
+            goto 28
+c        bottom of while loop
+   29    if(m.ge.1)then
+            m=hi(t(m))
+c           top of while loop
+   30       if(.not.(a(m).ne.0))goto 31
+               if(z(a(m)).le.xi(m))then
+                  m=lo(m)
+               else
+                  m=hi(m)
+               end if
+               goto 30
+c           bottom of while loop
+   31       if(v0.lt.v(c(1,m),2))then
+               v0=v(c(1,m),2)
+               do 32 i11=0,d
+                  g0(i11)=vval(i11,c(1,m))
+   32          continue
+            end if
+            if(v(c(3,m),2).lt.v1)then
+               v1=v(c(3,m),2)
+               do 33 i11=0,d
+                  g1(i11)=vval(i11,c(3,m))
+   33          continue
+            end if
+         end if
+         h=(z(2)-v0)/(v1-v0)
+c        Hermite basis
+         phi0=(1-h)**2*(1+2*h)
+         phi1=h**2*(3-2*h)
+         psi0=h*(1-h)**2
+         psi1=h**2*(h-1)
+         ge=phi0*g0(0)+phi1*g1(0)+(psi0*g0(2)+psi1*g1(2))*(v1-v0)
+         gpe=phi0*g0(1)+phi1*g1(1)
+c        ----- West -----
+         v0=v(ll,2)
+         v1=v(ur,2)
+         do 34 i11=0,d
+            g0(i11)=vval(i11,c(1,j))
+   34    continue
+         do 35 i11=0,d
+            g1(i11)=vval(i11,c(3,j))
+   35    continue
+         xibar=v(ll,1)
+         m=nt-1
+c        top of while loop
+   36    if(m.eq.0)then
+            i10=.true.
+         else
+            if(a(t(m)).eq.1)then
+               i9=(xi(t(m)).eq.xibar)
+            else
+               i9=.false.
+            end if
+            i10=i9
+         end if
+         if(.not.(.not.i10))goto 37
+            m=m-1
+c           voidp junk
+            goto 36
+c        bottom of while loop
+   37    if(m.ge.1)then
+            m=lo(t(m))
+c           top of while loop
+   38       if(.not.(a(m).ne.0))goto 39
+               if(z(a(m)).le.xi(m))then
+                  m=lo(m)
+               else
+                  m=hi(m)
+               end if
+               goto 38
+c           bottom of while loop
+   39       if(v0.lt.v(c(2,m),2))then
+               v0=v(c(2,m),2)
+               do 40 i11=0,d
+                  g0(i11)=vval(i11,c(2,m))
+   40          continue
+            end if
+            if(v(c(4,m),2).lt.v1)then
+               v1=v(c(4,m),2)
+               do 41 i11=0,d
+                  g1(i11)=vval(i11,c(4,m))
+   41          continue
+            end if
+         end if
+         h=(z(2)-v0)/(v1-v0)
+c        Hermite basis
+         phi0=(1-h)**2*(1+2*h)
+         phi1=h**2*(3-2*h)
+         psi0=h*(1-h)**2
+         psi1=h**2*(h-1)
+         gw=phi0*g0(0)+phi1*g1(0)+(psi0*g0(2)+psi1*g1(2))*(v1-v0)
+         gpw=phi0*g0(1)+phi1*g1(1)
+c        NS
+         h=(z(2)-v(ll,2))/(v(ur,2)-v(ll,2))
+c        Hermite basis
+         phi0=(1-h)**2*(1+2*h)
+         phi1=h**2*(3-2*h)
+         psi0=h*(1-h)**2
+         psi1=h**2*(h-1)
+         sns=phi0*gs+phi1*gn+(psi0*gps+psi1*gpn)*(v(ur,2)-v(ll,2))
+c        EW
+         h=(z(1)-v(ll,1))/(v(ur,1)-v(ll,1))
+c        Hermite basis
+         phi0=(1-h)**2*(1+2*h)
+         phi1=h**2*(3-2*h)
+         psi0=h*(1-h)**2
+         psi1=h**2*(h-1)
+         sew=phi0*gw+phi1*ge+(psi0*gpw+psi1*gpe)*(v(ur,1)-v(ll,1))
+         s=(sns+sew)-s
+      end if
+      ehg128=s
+      return
+      end
+
+
+C----------------------------------------------------------------------C
+C
+      integer function ifloor(x)
+      DOUBLE PRECISION x
+      ifloor=x
+      if(ifloor.gt.x) ifloor=ifloor-1
+      end
+      DOUBLE PRECISION functionDSIGN(a1,a2)
+      DOUBLE PRECISION a1, a2
+      DSIGN=DABS(a1)
+      if(a2.ge.0)DSIGN=-DSIGN
+      end
+      subroutine ehg136(u,lm,m,n,d,nf,f,x,psi,y,rw,kernel,k,dist,eta,b,o
+     +d,o,ihat,w,rcond,sing,dd,tdeg,cdeg,s)
+      integer identi,d,dd,execnt,i,i1,ihat,info,j,k,kernel,l,lm,m,n,nf,o
+     +d,sing,tdeg
+      integer cdeg(8),psi(n)
+      double precision f,i2,rcond,scale,tol
+      double precision o(m,n),sigma(15),e(15,15),g(15,15),b(nf,k),dist(n
+     +),eta(nf),dgamma(15),q(8),qraux(15),rw(n),s(0:od,m),u(lm,d),w(nf),
+     +work(15),x(n,d),y(n)
+      external ehg127,ehg182,dqrsl
+      double precision ddot
+      external ddot
+      save execnt
+      data execnt /0/
+c     V -> g
+c     U -> e
+c     Identity -> identi
+c     L -> o
+c     X -> b
+      execnt=execnt+1
+      if(.not.(k.le.nf-1))then
+         call ehg182(104)
+      end if
+      if(.not.(k.le.15))then
+         call ehg182(105)
+      end if
+      do 3 identi=1,n
+         psi(identi)=identi
+    3 continue
+      do 4 l=1,m
+         do 5 i1=1,d
+            q(i1)=u(l,i1)
+    5    continue
+         call ehg127(q,n,d,nf,f,x,psi,y,rw,kernel,k,dist,eta,b,od,w,rcon
+     +d,sing,sigma,e,g,dgamma,qraux,work,tol,dd,tdeg,cdeg,s(0,l))
+         if(ihat.eq.1)then
+c           $L sub {l,l} =
+c           V sub {1,:} SIGMA sup {+} U sup T
+c           (Q sup T W e sub i )$
+            if(.not.(m.eq.n))then
+               call ehg182(123)
+            end if
+c           find $i$ such that $l = psi sub i$
+            i=1
+c           top of while loop
+    6       if(.not.(l.ne.psi(i)))goto 7
+               i=i+1
+               if(.not.(i.lt.nf))then
+                  call ehg182(123)
+               end if
+               goto 6
+c           bottom of while loop
+    7       do 8 i1=1,nf
+               eta(i1)=0
+    8       continue
+            eta(i)=w(i)
+c           $eta = Q sup T W e sub i$
+            call dqrsl(b,nf,nf,k,qraux,eta,eta,eta,eta,eta,eta,1000,info
+     +)
+c           $gamma = U sup T eta sub {1:k}$
+            do 9 i1=1,k
+               dgamma(i1)=0
+    9       continue
+            do 10 j=1,k
+               i2=eta(j)
+               do 11 i1=1,k
+                  dgamma(i1)=dgamma(i1)+i2*e(j,i1)
+   11          continue
+   10       continue
+c           $gamma = SIGMA sup {+} gamma$
+            do 12 j=1,k
+               if(tol.lt.sigma(j))then
+                  dgamma(j)=dgamma(j)/sigma(j)
+               else
+                  dgamma(j)=0.d0
+               end if
+   12       continue
+c           voidp junk
+c           voidp junk
+            o(l,1)=ddot(k,g(1,1),15,dgamma,1)
+         else
+            if(ihat.eq.2)then
+c              $L sub {l,:} =
+c              V sub {1,:} SIGMA sup {+}
+c              ( U sup T Q sup T ) W $
+               do 13 i1=1,n
+                  o(l,i1)=0
+   13          continue
+               do 14 j=1,k
+                  do 15 i1=1,nf
+                     eta(i1)=0
+   15             continue
+                  do 16 i1=1,k
+                     eta(i1)=e(i1,j)
+   16             continue
+                  call dqrsl(b,nf,nf,k,qraux,eta,eta,work,work,work,work
+     +,10000,info)
+                  if(tol.lt.sigma(j))then
+                     scale=1.d0/sigma(j)
+                  else
+                     scale=0.d0
+                  end if
+                  do 17 i1=1,nf
+                     eta(i1)=eta(i1)*(scale*w(i1))
+   17             continue
+                  do 18 i=1,nf
+                     o(l,psi(i))=o(l,psi(i))+g(1,j)*eta(i)
+   18             continue
+   14          continue
+            end if
+         end if
+    4 continue
+      return
+      end
+
+C----------------------------------------------------------------------C
+C     l2tr
+      subroutine ehg139(v,nvmax,nv,n,d,nf,f,x,pi,psi,y,rw,trl,kernel,k,d
+     +ist,phi,eta,b,od,w,diagl,vval2,ncmax,vc,a,xi,lo,hi,c,vhit,rcond,si
+     +ng,dd,tdeg,cdeg,lq,lf,setlf,s)
+      logical setlf
+      integer identi,d,dd,execnt,i,i2,i3,i5,i6,ii,ileaf,info,j,k,kernel,
+     +l,n,nc,ncmax,nf,nleaf,nv,nvmax,od,sing,tdeg,vc
+      integer lq(nvmax,nf),a(ncmax),c(vc,ncmax),cdeg(8),hi(ncmax),leaf(2
+     +56),lo(ncmax),phi(n),pi(n),psi(n),vhit(nvmax)
+      DOUBLE PRECISION f,i1,i4,i7,rcond,scale,term,tol,trl
+      DOUBLE PRECISION lf(0:d,nvmax,nf),sigma(15),u(15,15),e(15,15),b(nf
+     +,k),diagl(n),dist(n),eta(nf),DGAMMA(15),q(8),qraux(15),rw(n),s(0:o
+     +d,nv),v(nvmax,d),vval2(0:d,nv),w(nf),work(15),x(n,d),xi(ncmax),y(n
+     +),z(8)
+      external ehg127,ehg182,DQRSL,ehg137
+      DOUBLE PRECISION ehg128
+      external ehg128
+      DOUBLE PRECISION DDOT
+      external DDOT
+      save execnt
+      data execnt /0/
+c     V -> e
+c     Identity -> identi
+c     X -> b
+      execnt=execnt+1
+c     l2fit with trace(L)
+      if(.not.(k.le.nf-1))then
+         call ehg182(104)
+      end if
+      if(.not.(k.le.15))then
+         call ehg182(105)
+      end if
+      if(trl.ne.0)then
+         do 3 i5=1,n
+            diagl(i5)=0
+    3    continue
+         do 4 i6=1,nv
+            do 5 i5=0,d
+               vval2(i5,i6)=0
+    5       continue
+    4    continue
+      end if
+      do 6 identi=1,n
+         psi(identi)=identi
+    6 continue
+      do 7 l=1,nv
+         do 8 i5=1,d
+            q(i5)=v(l,i5)
+    8    continue
+         call ehg127(q,n,d,nf,f,x,psi,y,rw,kernel,k,dist,eta,b,od,w,rcon
+     +d,sing,sigma,u,e,DGAMMA,qraux,work,tol,dd,tdeg,cdeg,s(0,l))
+         if(trl.ne.0)then
+c           invert $psi$
+            do 9 i5=1,n
+               phi(i5)=0
+    9       continue
+            do 10 i=1,nf
+               phi(psi(i))=i
+   10       continue
+            do 11 i5=1,d
+               z(i5)=v(l,i5)
+   11       continue
+            call ehg137(z,vhit(l),leaf,nleaf,d,nv,nvmax,ncmax,vc,a,xi,lo
+     +,hi,c,v)
+            do 12 ileaf=1,nleaf
+               do 13 ii=lo(leaf(ileaf)),hi(leaf(ileaf))
+                  i=phi(pi(ii))
+                  if(i.ne.0)then
+                     if(.not.(psi(i).eq.pi(ii)))then
+                        call ehg182(194)
+                     end if
+                     do 14 i5=1,nf
+                        eta(i5)=0
+   14                continue
+                     eta(i)=w(i)
+c                    $eta = Q sup T W e sub i$
+                     call DQRSL(b,nf,nf,k,qraux,eta,work,eta,eta,work,wo
+     +rk,1000,info)
+                     do 15 j=1,k
+                        if(tol.lt.sigma(j))then
+                           i4=DDOT(k,u(1,j),1,eta,1)/sigma(j)
+                        else
+                           i4=0.D0
+                        end if
+                       DGAMMA(j)=i4
+   15                continue
+                     do 16 j=1,d+1
+c                       bug fix 2006-07-15 for k=1, od>1.   (thanks btyner@gmail.com)
+                        if(j.le.k)then
+                           vval2(j-1,l)=DDOT(k,e(j,1),15,DGAMMA,1)
+                        else
+                           vval2(j-1,l)=0
+                        end if
+   16                continue
+                     do 17 i5=1,d
+                        z(i5)=x(pi(ii),i5)
+   17                continue
+                     term=ehg128(z,d,ncmax,vc,a,xi,lo,hi,c,v,nvmax,vval2
+     +)
+                     diagl(pi(ii))=diagl(pi(ii))+term
+                     do 18 i5=0,d
+                        vval2(i5,l)=0
+   18                continue
+                  end if
+   13          continue
+   12       continue
+         end if
+         if(setlf)then
+c           $Lf sub {:,l,:} = V SIGMA sup {+} U sup T Q sup T W$
+            if(.not.(k.ge.d+1))then
+               call ehg182(196)
+            end if
+            do 19 i5=1,nf
+               lq(l,i5)=psi(i5)
+   19       continue
+            do 20 i6=1,nf
+               do 21 i5=0,d
+                  lf(i5,l,i6)=0
+   21          continue
+   20       continue
+            do 22 j=1,k
+               do 23 i5=1,nf
+                  eta(i5)=0
+   23          continue
+               do 24 i5=1,k
+                  eta(i5)=u(i5,j)
+   24          continue
+               call DQRSL(b,nf,nf,k,qraux,eta,eta,work,work,work,work,10
+     +000,info)
+               if(tol.lt.sigma(j))then
+                  scale=1.D0/sigma(j)
+               else
+                  scale=0.D0
+               end if
+               do 25 i5=1,nf
+                  eta(i5)=eta(i5)*(scale*w(i5))
+   25          continue
+               do 26 i=1,nf
+                  i7=eta(i)
+                  do 27 i5=0,d
+                     if(i5.lt.k)then
+                        lf(i5,l,i)=lf(i5,l,i)+e(1+i5,j)*i7
+                     else
+                        lf(i5,l,i)=0
+                     end if
+   27             continue
+   26          continue
+   22       continue
+         end if
+    7 continue
+      if(trl.ne.0)then
+         if(n.le.0)then
+            trl=0.D0
+         else
+            i3=n
+            i1=diagl(i3)
+            do 28 i2=i3-1,1,-1
+               i1=diagl(i2)+i1
+   28       continue
+            trl=i1
+         end if
+      end if
+      return
+      end
+
+
+C----------------------------------------------------------------------C
+      subroutine dqrdc(x,ldx,n,p,qraux,jpvt,work,job)
+      integer ldx,n,p,job
+      integer jpvt(1)
+      double precision x(ldx,1),qraux(1),work(1)
+c
+c     dqrdc uses householder transformations to compute the qr
+c     factorization of an n by p matrix x.  column pivoting
+c     based on the 2-norms of the reduced columns may be
+c     performed at the users option.
+c
+c     on entry
+c
+c        x       double precision(ldx,p), where ldx .ge. n.
+c                x contains the matrix whose decomposition is to be
+c                computed.
+c
+c        ldx     integer.
+c                ldx is the leading dimension of the array x.
+c
+c        n       integer.
+c                n is the number of rows of the matrix x.
+c
+c        p       integer.
+c                p is the number of columns of the matrix x.
+c
+c        jpvt    integer(p).
+c                jpvt contains integers that control the selection
+c                of the pivot columns.  the k-th column x(k) of x
+c                is placed in one of three classes according to the
+c                value of jpvt(k).
+c
+c                   if jpvt(k) .gt. 0, then x(k) is an initial
+c                                      column.
+c
+c                   if jpvt(k) .eq. 0, then x(k) is a free column.
+c
+c                   if jpvt(k) .lt. 0, then x(k) is a final column.
+c
+c                before the decomposition is computed, initial columns
+c                are moved to the beginning of the array x and final
+c                columns to the end.  both initial and final columns
+c                are frozen in place during the computation and only
+c                free columns are moved.  at the k-th stage of the
+c                reduction, if x(k) is occupied by a free column
+c                it is interchanged with the free column of largest
+c                reduced norm.  jpvt is not referenced if
+c                job .eq. 0.
+c
+c        work    double precision(p).
+c                work is a work array.  work is not referenced if
+c                job .eq. 0.
+c
+c        job     integer.
+c                job is an integer that initiates column pivoting.
+c                if job .eq. 0, no pivoting is done.
+c                if job .ne. 0, pivoting is done.
+c
+c     on return
+c
+c        x       x contains in its upper triangle the upper
+c                triangular matrix r of the qr factorization.
+c                below its diagonal x contains information from
+c                which the orthogonal part of the decomposition
+c                can be recovered.  note that if pivoting has
+c                been requested, the decomposition is not that
+c                of the original matrix x but that of x
+c                with its columns permuted as described by jpvt.
+c
+c        qraux   double precision(p).
+c                qraux contains further information required to recover
+c                the orthogonal part of the decomposition.
+c
+c        jpvt    jpvt(k) contains the index of the column of the
+c                original matrix that has been interchanged into
+c                the k-th column, if pivoting was requested.
+c
+c     linpack. this version dated 08/14/78 .
+c     g.w. stewart, university of maryland, argonne national lab.
+c
+c     dqrdc uses the following functions and subprograms.
+c
+c     blas daxpy,ddot,dscal,dswap,dnrm2
+c     fortran dabs,dmax1,min0,dsqrt
+c
+c     internal variables
+c
+      integer j,jp,l,lp1,lup,maxj,pl,pu
+      double precision maxnrm,dnrm2,tt
+      double precision ddot,nrmxl,t
+      logical negj,swapj
+c
+c
+      pl = 1
+      pu = 0
+      if (job .eq. 0) go to 60
+c
+c        pivoting has been requested.  rearrange the columns
+c        according to jpvt.
+c
+         do 20 j = 1, p
+            swapj = jpvt(j) .gt. 0
+            negj = jpvt(j) .lt. 0
+            jpvt(j) = j
+            if (negj) jpvt(j) = -j
+            if (.not.swapj) go to 10
+               if (j .ne. pl) call dswap(n,x(1,pl),1,x(1,j),1)
+               jpvt(j) = jpvt(pl)
+               jpvt(pl) = j
+               pl = pl + 1
+   10       continue
+   20    continue
+         pu = p
+         do 50 jj = 1, p
+            j = p - jj + 1
+            if (jpvt(j) .ge. 0) go to 40
+               jpvt(j) = -jpvt(j)
+               if (j .eq. pu) go to 30
+                  call dswap(n,x(1,pu),1,x(1,j),1)
+                  jp = jpvt(pu)
+                  jpvt(pu) = jpvt(j)
+                  jpvt(j) = jp
+   30          continue
+               pu = pu - 1
+   40       continue
+   50    continue
+   60 continue
+c
+c     compute the norms of the free columns.
+c
+      if (pu .lt. pl) go to 80
+      do 70 j = pl, pu
+         qraux(j) = dnrm2(n,x(1,j),1)
+         work(j) = qraux(j)
+   70 continue
+   80 continue
+c
+c     perform the householder reduction of x.
+c
+      lup = min0(n,p)
+      do 200 l = 1, lup
+         if (l .lt. pl .or. l .ge. pu) go to 120
+c
+c           locate the column of largest norm and bring it
+c           into the pivot position.
+c
+            maxnrm = 0.0d0
+            maxj = l
+            do 100 j = l, pu
+               if (qraux(j) .le. maxnrm) go to 90
+                  maxnrm = qraux(j)
+                  maxj = j
+   90          continue
+  100       continue
+            if (maxj .eq. l) go to 110
+               call dswap(n,x(1,l),1,x(1,maxj),1)
+               qraux(maxj) = qraux(l)
+               work(maxj) = work(l)
+               jp = jpvt(maxj)
+               jpvt(maxj) = jpvt(l)
+               jpvt(l) = jp
+  110       continue
+  120    continue
+         qraux(l) = 0.0d0
+         if (l .eq. n) go to 190
+c
+c           compute the householder transformation for column l.
+c
+            nrmxl = dnrm2(n-l+1,x(l,l),1)
+            if (nrmxl .eq. 0.0d0) go to 180
+               if (x(l,l) .ne. 0.0d0) nrmxl = dsign(nrmxl,x(l,l))
+               call dscal(n-l+1,1.0d0/nrmxl,x(l,l),1)
+               x(l,l) = 1.0d0 + x(l,l)
+c
+c              apply the transformation to the remaining columns,
+c              updating the norms.
+c
+               lp1 = l + 1
+               if (p .lt. lp1) go to 170
+               do 160 j = lp1, p
+                  t = -ddot(n-l+1,x(l,l),1,x(l,j),1)/x(l,l)
+                  call daxpy(n-l+1,t,x(l,l),1,x(l,j),1)
+                  if (j .lt. pl .or. j .gt. pu) go to 150
+                  if (qraux(j) .eq. 0.0d0) go to 150
+                     tt = 1.0d0 - (dabs(x(l,j))/qraux(j))**2
+                     tt = dmax1(tt,0.0d0)
+                     t = tt
+                     tt = 1.0d0 + 0.05d0*tt*(qraux(j)/work(j))**2
+                     if (tt .eq. 1.0d0) go to 130
+                        qraux(j) = qraux(j)*dsqrt(t)
+                     go to 140
+  130                continue
+                        qraux(j) = dnrm2(n-l,x(l+1,j),1)
+                        work(j) = qraux(j)
+  140                continue
+  150             continue
+  160          continue
+  170          continue
+c
+c              save the transformation.
+c
+               qraux(l) = x(l,l)
+               x(l,l) = -nrmxl
+  180       continue
+  190    continue
+  200 continue
+      return
+      end
+
+C---------------------------------------------------------------------C
+      integer function idamax(n,dx,incx)
+c
+c     finds the index of element having max. absolute value.
+c     jack dongarra, linpack, 3/11/78.
+c
+      double precision dx(1),dmax
+      integer i,incx,ix,n
+c
+      idamax = 0
+      if( n .lt. 1 ) return
+      idamax = 1
+      if(n.eq.1)return
+      if(incx.eq.1)go to 20
+c
+c        code for increment not equal to 1
+c
+      ix = 1
+      dmax = dabs(dx(1))
+      ix = ix + incx
+      do 10 i = 2,n
+         if(dabs(dx(ix)).le.dmax) go to 5
+         idamax = i
+         dmax = dabs(dx(ix))
+    5    ix = ix + incx
+   10 continue
+      return
+c
+c        code for increment equal to 1
+c
+   20 dmax = dabs(dx(1))
+      do 30 i = 2,n
+         if(dabs(dx(i)).le.dmax) go to 30
+         idamax = i
+         dmax = dabs(dx(i))
+   30 continue
+      return
+      end
+
+C----------------------------------------------------------------------C
+C     build kd tree
+      subroutine lowesb(xx,yy,ww,diagl,infl,iv,liv,lv,wv)
+      logical infl,setlf
+      integer execnt
+      integer iv(*)
+      DOUBLE PRECISION trl
+      DOUBLE PRECISION diagl(*),wv(*),ww(*),xx(*),yy(*)
+      external ehg131,ehg182,ehg183
+      integer ifloor
+      external ifloor
+      save execnt
+      data execnt /0/
+      execnt=execnt+1
+      if(.not.(iv(28).ne.173))then
+         call ehg182(174)
+      end if
+      if(iv(28).ne.172)then
+         if(.not.(iv(28).eq.171))then
+            call ehg182(171)
+         end if
+      end if
+      iv(28)=173
+      if(infl)then
+         trl=1.D0
+      else
+         trl=0.D0
+      end if
+      setlf=(iv(27).ne.iv(25))
+      call ehg131(xx,yy,ww,trl,diagl,iv(20),iv(29),iv(3),iv(2),iv(5),iv(
+     +17),iv(4),iv(6),iv(14),iv(19),wv(1),iv(iv(7)),iv(iv(8)),iv(iv(9)),
+     +iv(iv(10)),iv(iv(22)),iv(iv(27)),wv(iv(11)),iv(iv(23)),wv(iv(13)),
+     +wv(iv(12)),wv(iv(15)),wv(iv(16)),wv(iv(18)),ifloor(iv(3)*wv(2)),wv
+     +(3),wv(iv(26)),wv(iv(24)),wv(4),iv(30),iv(33),iv(32),iv(41),iv(iv(
+     +25)),wv(iv(34)),setlf)
+      if(iv(14).lt.iv(6)+DFLOAT(iv(4))/2.D0)then
+         call ehg183('Warning. k-d tree limited by memory; nvmax=',iv(14
+     +),1,1)
+      else
+         if(iv(17).lt.iv(5)+2)then
+            call ehg183('Warning. k-d tree limited by memory. ncmax=',iv
+     +(17),1,1)
+         end if
+      end if
+      return
+      end
+
+C----------------------------------------------------------------------C
+C     setup workspace
+      subroutine lowesd(versio,iv,liv,lv,v,d,n,f,ideg,nvmax,setlf)
+      logical setlf
+      integer bound,d,execnt,i,i1,i2,ideg,j,liv,lv,n,ncmax,nf,nvmax,vc,v
+     +ersio
+      integer iv(liv)
+      double precision f
+      double precision v(lv)
+      external ehg182
+      integer ifloor
+      external ifloor
+      save execnt
+      data execnt /0/
+c     version -> versio
+      execnt=execnt+1
+      if(.not.(versio.eq.106))then
+         call ehg182(100)
+      end if
+      iv(28)=171
+      iv(2)=d
+      iv(3)=n
+      vc=2**d
+      iv(4)=vc
+      if(.not.(0.lt.f))then
+         call ehg182(120)
+      end if
+      nf=min(n,ifloor(n*f))
+      iv(19)=nf
+      iv(20)=1
+      if(ideg.eq.0)then
+         i1=1
+      else
+         if(ideg.eq.1)then
+            i1=d+1
+         else
+            if(ideg.eq.2)then
+               i1=dfloat((d+2)*(d+1))/2.d0
+            end if
+         end if
+      end if
+      iv(29)=i1
+      iv(21)=1
+      iv(14)=nvmax
+      ncmax=nvmax
+      iv(17)=ncmax
+      iv(30)=0
+      iv(32)=ideg
+      if(.not.(ideg.ge.0))then
+         call ehg182(195)
+      end if
+      if(.not.(ideg.le.2))then
+         call ehg182(195)
+      end if
+      iv(33)=d
+      do 3 i2=41,49
+         iv(i2)=ideg
+    3 continue
+      iv(7)=50
+      iv(8)=iv(7)+ncmax
+      iv(9)=iv(8)+vc*ncmax
+      iv(10)=iv(9)+ncmax
+      iv(22)=iv(10)+ncmax
+c     initialize permutation
+      j=iv(22)-1
+      do 4 i=1,n
+         iv(j+i)=i
+    4 continue
+      iv(23)=iv(22)+n
+      iv(25)=iv(23)+nvmax
+      if(setlf)then
+         iv(27)=iv(25)+nvmax*nf
+      else
+         iv(27)=iv(25)
+      end if
+      bound=iv(27)+n
+      if(.not.(bound-1.le.liv))then
+         call ehg182(102)
+      end if
+      iv(11)=50
+      iv(13)=iv(11)+nvmax*d
+      iv(12)=iv(13)+(d+1)*nvmax
+      iv(15)=iv(12)+ncmax
+      iv(16)=iv(15)+n
+      iv(18)=iv(16)+nf
+      iv(24)=iv(18)+iv(29)*nf
+      iv(34)=iv(24)+(d+1)*nvmax
+      if(setlf)then
+         iv(26)=iv(34)+(d+1)*nvmax*nf
+      else
+         iv(26)=iv(34)
+      end if
+      bound=iv(26)+nf
+      if(.not.(bound-1.le.lv))then
+         call ehg182(103)
+      end if
+      v(1)=f
+      v(2)=0.05d0
+      v(3)=0.d0
+      v(4)=1.d0
+      return
+      end
+
+C----------------------------------------------------------------------C
+C     evaluate smooth at z
+      subroutine lowese(iv,liv,lv,wv,m,z,s)
+      integer execnt,m
+      integer iv(*)
+      double precision s(m),wv(*),z(m,1)
+      external ehg133,ehg182
+      save execnt
+      data execnt /0/
+      execnt=execnt+1
+      if(.not.(iv(28).ne.172))then
+         call ehg182(172)
+      end if
+      if(.not.(iv(28).eq.173))then
+         call ehg182(173)
+      end if
+      call ehg133(iv(3),iv(2),iv(4),iv(14),iv(5),iv(17),iv(iv(7)),iv(iv(
+     +8)),iv(iv(9)),iv(iv(10)),wv(iv(11)),wv(iv(13)),wv(iv(12)),m,z,s)
+      return
+      end
+
+C----------------------------------------------------------------------C
+C     slow smooth at z
+      subroutine lowesf(xx,yy,ww,iv,liv,lv,wv,m,z,l,ihat,s)
+      logical i1
+      integer execnt,ihat,m,n
+      integer iv(*)
+      double precision l(m,*),s(m),wv(*),ww(*),xx(*),yy(*),z(m,1)
+      external ehg182,ehg136
+      save execnt
+      data execnt /0/
+      execnt=execnt+1
+      if(171.le.iv(28))then
+         i1=(iv(28).le.174)
+      else
+         i1=.false.
+      end if
+      if(.not.i1)then
+         call ehg182(171)
+      end if
+      iv(28)=172
+      if(.not.(iv(14).ge.iv(19)))then
+         call ehg182(186)
+      end if
+      call ehg136(z,m,m,iv(3),iv(2),iv(19),wv(1),xx,iv(iv(22)),yy,ww,iv(
+     +20),iv(29),wv(iv(15)),wv(iv(16)),wv(iv(18)),0,l,ihat,wv(iv(26)),wv
+     +(4),iv(30),iv(33),iv(32),iv(41),s)
+      return
+      end
+
+C----------------------------------------------------------------------C
+C     explicit hat matrix mapping y to z
+      subroutine lowesl(iv,liv,lv,wv,m,z,l)
+      integer execnt,m,n
+      integer iv(*)
+      double precision l(m,*),wv(*),z(m,1)
+      external ehg182,ehg191
+      save execnt
+      data execnt /0/
+      execnt=execnt+1
+      if(.not.(iv(28).ne.172))then
+         call ehg182(172)
+      end if
+      if(.not.(iv(28).eq.173))then
+         call ehg182(173)
+      end if
+      if(.not.(iv(26).ne.iv(34)))then
+         call ehg182(175)
+      end if
+      call ehg191(m,z,l,iv(2),iv(3),iv(19),iv(6),iv(17),iv(4),iv(iv(7)),
+     +wv(iv(12)),iv(iv(10)),iv(iv(9)),iv(iv(8)),wv(iv(11)),iv(14),wv(iv(
+     +24)),wv(iv(34)),iv(iv(25)))
+      return
+      end
+
+C----------------------------------------------------------------------C
+C     rebuild with new data values (does not change y)
+      subroutine lowesr(yy,iv,liv,lv,wv)
+      integer execnt
+      integer iv(*)
+      DOUBLE PRECISION wv(*),yy(*)
+      external ehg182,ehg192
+      save execnt
+      data execnt /0/
+      execnt=execnt+1
+      if(.not.(iv(28).ne.172))then
+         call ehg182(172)
+      end if
+      if(.not.(iv(28).eq.173))then
+         call ehg182(173)
+      end if
+      call ehg192(yy,iv(2),iv(3),iv(19),iv(6),iv(14),wv(iv(13)),wv(iv(34
+     +)),iv(iv(25)))
+      return
+      end
+
+C----------------------------------------------------------------------C
+C     robustness weights
+      subroutine lowesw(res,n,rw,pi)
+      integer identi,execnt,i,i1,n,nh
+      integer pi(n)
+      double precision cmad,rsmall
+      double precision res(n),rw(n)
+      external ehg106
+      integer ifloor
+      external ifloor
+      double precision d1mach
+      external d1mach
+      save execnt
+      data execnt /0/
+c     Identity -> identi
+      execnt=execnt+1
+c     tranliterated from Devlin's ratfor
+c     find median of absolute residuals
+      do 3 i1=1,n
+         rw(i1)=dabs(res(i1))
+    3 continue
+      do 4 identi=1,n
+         pi(identi)=identi
+    4 continue
+      nh=ifloor(dfloat(n)/2.d0)+1
+c     partial sort to find 6*mad
+      call ehg106(1,n,nh,1,rw,pi,n)
+      if((n-nh)+1.lt.nh)then
+         call ehg106(1,nh-1,nh-1,1,rw,pi,n)
+         cmad=3*(rw(pi(nh))+rw(pi(nh-1)))
+      else
+         cmad=6*rw(pi(nh))
+      end if
+      rsmall=d1mach(1)
+      if(cmad.lt.rsmall)then
+         do 5 i1=1,n
+            rw(i1)=1
+    5    continue
+      else
+         do 6 i=1,n
+            if(cmad*0.999d0.lt.rw(i))then
+               rw(i)=0
+            else
+               if(cmad*0.001d0.lt.rw(i))then
+                  rw(i)=(1-(rw(i)/cmad)**2)**2
+               else
+                  rw(i)=1
+               end if
+            end if
+    6    continue
+      end if
+      return
+      end
+
+C----------------------------------------------------------------------C
+C     pseudovalues
+      subroutine lowesp(n,y,yhat,pwgts,rwgts,pi,ytilde)
+      integer identi,execnt,i2,i3,i5,m,n
+      integer pi(n)
+      double precision c,i1,i4,mad
+      double precision pwgts(n),rwgts(n),y(n),yhat(n),ytilde(n)
+      external ehg106
+      integer ifloor
+      external ifloor
+      save execnt
+      data execnt /0/
+c     Identity -> identi
+      execnt=execnt+1
+c     median absolute deviation
+      do 3 i5=1,n
+         ytilde(i5)=dabs(y(i5)-yhat(i5))*dsqrt(pwgts(i5))
+    3 continue
+      do 4 identi=1,n
+         pi(identi)=identi
+    4 continue
+      m=ifloor(dfloat(n)/2.d0)+1
+      call ehg106(1,n,m,1,ytilde,pi,n)
+      if((n-m)+1.lt.m)then
+         call ehg106(1,m-1,m-1,1,ytilde,pi,n)
+         mad=(ytilde(pi(m-1))+ytilde(pi(m)))/2
+      else
+         mad=ytilde(pi(m))
+      end if
+c     magic constant
+      c=(6*mad)**2/5
+      do 5 i5=1,n
+         ytilde(i5)=1-((y(i5)-yhat(i5))**2*pwgts(i5))/c
+    5 continue
+      do 6 i5=1,n
+         ytilde(i5)=ytilde(i5)*dsqrt(rwgts(i5))
+    6 continue
+      if(n.le.0)then
+         i4=0.d0
+      else
+         i3=n
+         i1=ytilde(i3)
+         do 7 i2=i3-1,1,-1
+            i1=ytilde(i2)+i1
+    7    continue
+         i4=i1
+      end if
+      c=n/i4
+c     pseudovalues
+      do 8 i5=1,n
+         ytilde(i5)=yhat(i5)+(c*rwgts(i5))*(y(i5)-yhat(i5))
+    8 continue
+      return
+      end
+
+C----------------------------------------------------------------------C
+C     rbuild
+      subroutine ehg124(ll,uu,d,n,nv,nc,ncmax,vc,x,pi,a,xi,lo,hi,c,v,vhi
+     +t,nvmax,fc,fd,dd)
+      logical i1,i2,i3,leaf
+      integer d,dd,execnt,fc,i4,inorm2,k,l,ll,m,n,nc,ncmax,nv,nvmax,p,u,
+     +uu,vc,lower,upper,check,offset
+      integer a(ncmax),c(vc,ncmax),hi(ncmax),lo(ncmax),pi(n),vhit(nvmax)
+      DOUBLE PRECISION diam,fd
+      DOUBLE PRECISION diag(8),sigma(8),v(nvmax,d),x(n,d),xi(ncmax)
+      external ehg125,ehg106,ehg129
+      integer IDAMAX
+      external IDAMAX
+      save execnt
+      data execnt /0/
+      execnt=execnt+1
+      p=1
+      l=ll
+      u=uu
+      lo(p)=l
+      hi(p)=u
+c     top of while loop
+    3 if(.not.(p.le.nc))goto 4
+         do 5 i4=1,dd
+            diag(i4)=v(c(vc,p),i4)-v(c(1,p),i4)
+    5    continue
+         diam=0
+         do 6 inorm2=1,dd
+            diam=diam+diag(inorm2)**2
+    6    continue
+         diam=DSQRT(diam)
+         if((u-l)+1.le.fc)then
+            i1=.true.
+         else
+            i1=(diam.le.fd)
+         end if
+         if(i1)then
+            leaf=.true.
+         else
+            if(ncmax.lt.nc+2)then
+               i2=.true.
+            else
+               i2=(nvmax.lt.nv+DFLOAT(vc)/2.D0)
+            end if
+            leaf=i2
+         end if
+         if(.not.leaf)then
+            call ehg129(l,u,dd,x,pi,n,sigma)
+            k=IDAMAX(dd,sigma,1)
+            m=DFLOAT(l+u)/2.D0
+            call ehg106(l,u,m,1,x(1,k),pi,n)
+
+c bug fix from btyner@gmail.com 2006-07-20
+      offset = 0
+    7 if(((m+offset).ge.u).or.((m+offset).lt.l))then
+         goto 8
+      else
+        if(offset.lt.0)then
+          lower = l
+          check = m + offset
+          upper = check
+        else
+          lower = m + offset + 1
+          check = lower
+          upper = u
+        end if
+        call ehg106(lower,upper,check,1,x(1,k),pi,n)
+        if(x(pi(m + offset),k).eq.x(pi(m+offset+1),k))then
+          offset = (-offset)
+          if(offset.ge.0)then
+            offset = offset + 1
+          end if
+      goto 7
+        else
+          m = m + offset
+          goto 8
+        end if
+      end if
+
+    8       if(v(c(1,p),k).eq.x(pi(m),k))then
+               leaf=.true.
+            else
+               leaf=(v(c(vc,p),k).eq.x(pi(m),k))
+            end if
+         end if
+         if(leaf)then
+            a(p)=0
+         else
+            a(p)=k
+            xi(p)=x(pi(m),k)
+c           left son
+            nc=nc+1
+            lo(p)=nc
+            lo(nc)=l
+            hi(nc)=m
+c           right son
+            nc=nc+1
+            hi(p)=nc
+            lo(nc)=m+1
+            hi(nc)=u
+            call ehg125(p,nv,v,vhit,nvmax,d,k,xi(p),2**(k-1),2**(d-k),c(
+     +1,p),c(1,lo(p)),c(1,hi(p)))
+         end if
+         p=p+1
+         l=lo(p)
+         u=hi(p)
+         goto 3
+c     bottom of while loop
+    4 return
+      end
+
+C----------------------------------------------------------------------C
+C     spread
+      subroutine ehg129(l,u,d,x,pi,n,sigma)
+      integer d,execnt,i,k,l,n,u
+      integer pi(n)
+      DOUBLE PRECISION machin,alpha,beta,t
+      DOUBLE PRECISION sigma(d),x(n,d)
+      DOUBLE PRECISION D1MACH
+      external D1MACH
+      save machin,execnt
+      data execnt /0/
+c     MachInf -> machin
+      execnt=execnt+1
+      if(execnt.eq.1)then
+         machin=D1MACH(2)
+      end if
+      do 3 k=1,d
+         alpha=machin
+         beta=-machin
+         do 4 i=l,u
+            t=x(pi(i),k)
+            alpha=min(alpha,x(pi(i),k))
+            beta=max(beta,t)
+    4    continue
+         sigma(k)=beta-alpha
+    3 continue
+      return
+      end
+
+C----------------------------------------------------------------------C
+C     vleaf
+      subroutine ehg137(z,kappa,leaf,nleaf,d,nv,nvmax,ncmax,vc,a,xi,lo,h
+     +i,c,v)
+      integer d,execnt,nc,ncmax,nleaf,p,stackt
+      integer a(ncmax),hi(ncmax),leaf(256),lo(ncmax),pstack(20)
+      DOUBLE PRECISION xi(ncmax),z(d)
+      external ehg182
+      save execnt
+      data execnt /0/
+c     stacktop -> stackt
+      execnt=execnt+1
+c     find leaf cells affected by $z$
+      stackt=0
+      p=1
+      nleaf=0
+c     top of while loop
+    3 if(.not.(0.lt.p))goto 4
+         if(a(p).eq.0)then
+c           leaf
+            nleaf=nleaf+1
+            leaf(nleaf)=p
+c           Pop
+            if(stackt.ge.1)then
+               p=pstack(stackt)
+            else
+               p=0
+            end if
+            stackt=max(0,stackt-1)
+         else
+            if(z(a(p)).eq.xi(p))then
+c              Push
+               stackt=stackt+1
+               if(.not.(stackt.le.20))then
+                  call ehg182(187)
+               end if
+               pstack(stackt)=hi(p)
+               p=lo(p)
+            else
+               if(z(a(p)).le.xi(p))then
+                  p=lo(p)
+               else
+                  p=hi(p)
+               end if
+            end if
+         end if
+         goto 3
+c     bottom of while loop
+    4 if(.not.(nleaf.le.256))then
+         call ehg182(185)
+      end if
+      return
+      end

Added: trunk/Lib/sandbox/pyloess/src/misc.c
===================================================================
--- trunk/Lib/sandbox/pyloess/src/misc.c	2007-03-21 21:28:18 UTC (rev 2862)
+++ trunk/Lib/sandbox/pyloess/src/misc.c	2007-03-21 22:53:54 UTC (rev 2863)
@@ -0,0 +1,316 @@
+#include "S.h"
+#include "loess.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+static double fmin(double a, double b)
+{
+    return(a < b ? a : b);
+}
+
+static double fmax(double a, double b)
+{
+    return(a > b ? a : b);
+}
+
+
+void anova(loess *one, loess *two, anova_struct *out)
+{
+    double  one_d1, one_d2, one_s, two_d1, two_d2, two_s,
+            rssdiff, d1diff, tmp, pf();
+    int     max_enp;
+
+    one_d1 = one->outputs.one_delta;
+    one_d2 = one->outputs.two_delta;
+    one_s = one->outputs.s;
+    two_d1 = two->outputs.one_delta;
+    two_d2 = two->outputs.two_delta;
+    two_s = two->outputs.s;
+
+    rssdiff = fabs(one_s * one_s * one_d1 - two_s * two_s * two_d1);
+    d1diff = fabs(one_d1 - two_d1);
+    out->dfn = d1diff * d1diff / fabs(one_d2 - two_d2);
+    max_enp = (one->outputs.enp > two->outputs.enp);
+    tmp = max_enp ? one_d1 : two_d1;
+    out->dfd = tmp * tmp / (max_enp ? one_d2 : two_d2);
+    tmp = max_enp ? one_s : two_s;
+    out->F_value = (rssdiff / d1diff) / (tmp * tmp);
+    out->Pr_F = 1 - pf(out->F_value, out->dfn, out->dfd);
+}
+
+void pointwise(prediction *pre, int m, double coverage, conf_inv *ci)
+{
+    double    t_dist, limit, fit, qt();
+    int    i;
+
+    ci->fit = (double *) malloc(m * sizeof(double));
+    ci->upper = (double *) malloc(m * sizeof(double));
+    ci->lower = (double *) malloc(m * sizeof(double));
+
+    t_dist = qt(1 - (1 - coverage)/2, pre->df);
+    for(i = 0; i < m; i++) {
+        limit = pre->se_fit[i] * t_dist;
+        ci->fit[i] = fit = pre->fit[i];
+        ci->upper[i] = fit + limit;
+        ci->lower[i] = fit - limit;
+    }
+}
+
+void pw_free_mem(conf_inv *ci)
+{
+    free(ci->fit);
+    free(ci->upper);
+    free(ci->lower);
+}
+
+double pf(double q, double df1, double df2)
+{
+    double ibeta();
+    return(ibeta(q*df1/(df2+q*df1), df1/2, df2/2));
+}
+
+double qt(double p, double df)
+{
+    double    t, invibeta();
+    t = invibeta(fabs(2*p-1), 0.5, df/2);
+    return((p>0.5?1:-1) * sqrt(t*df/(1-t)));
+}
+
+/**********************************************************************/
+ /*
+ * Incomplete beta function.
+ * Reference:  Abramowitz and Stegun, 26.5.8.
+ * Assumptions: 0 <= x <= 1; a,b > 0.
+ */
+#define DOUBLE_EPS      2.2204460492503131E-16
+#define IBETA_LARGE     1.0e30
+#define IBETA_SMALL     1.0e-30
+
+double ibeta(double x, double a, double b)
+{
+    int flipped = 0, i, k, count;
+    double I, temp, pn[6], ak, bk, next, prev, factor, val;
+
+    if (x <= 0)
+        return(0);
+    if (x >= 1)
+        return(1);
+
+    /* use ibeta(x,a,b) = 1-ibeta(1-x,b,a) */
+    if ((a+b+1)*x > (a+1)) {
+        flipped = 1;
+        temp = a;
+        a = b;
+        b = temp;
+        x = 1 - x;
+        }
+
+    pn[0] = 0.0;
+    pn[2] = pn[3] = pn[1] = 1.0;
+    count = 1;
+    val = x/(1.0-x);
+    bk = 1.0;
+    next = 1.0;
+    do {
+        count++;
+        k = count/2;
+        prev = next;
+        if (count%2 == 0)
+            ak = -((a+k-1.0)*(b-k)*val)/((a+2.0*k-2.0)*(a+2.0*k-1.0));
+        else
+            ak = ((a+b+k-1.0)*k*val)/((a+2.0*k)*(a+2.0*k-1.0));
+            pn[4] = bk*pn[2] + ak*pn[0];
+            pn[5] = bk*pn[3] + ak*pn[1];
+            next = pn[4] / pn[5];
+            for (i=0; i<=3; i++)
+                pn[i] = pn[i+2];
+            if (fabs(pn[4]) >= IBETA_LARGE)
+                for (i=0; i<=3; i++)
+                    pn[i] /= IBETA_LARGE;
+            if (fabs(pn[4]) <= IBETA_SMALL)
+                for (i=0; i<=3; i++)
+                    pn[i] /= IBETA_SMALL;
+        } while (fabs(next-prev) > DOUBLE_EPS*prev);
+        factor = a*log(x) + (b-1)*log(1-x);
+        factor -= gamma(a+1) + gamma(b) - gamma(a+b);
+        I = exp(factor) * next;
+        return(flipped ? 1-I : I);
+}
+
+/*
+ * Rational approximation to inverse Gaussian distribution.
+ * Absolute error is bounded by 4.5e-4.
+ * Reference: Abramowitz and Stegun, page 933.
+ * Assumption: 0 < p < 1.
+ */
+
+static double num[] = {
+        2.515517,
+        0.802853,
+        0.010328
+};
+
+static double den[] = {
+        1.000000,
+        1.432788,
+        0.189269,
+        0.001308
+};
+
+double invigauss_quick(double p)
+{
+    int lower;
+    double t, n, d, q;
+
+    if(p == 0.5)
+        return(0);
+    lower = p < 0.5;
+    p = lower ? p : 1 - p;
+    t = sqrt(-2 * log(p));
+    n = (num[2]*t + num[1])*t + num[0];
+    d = ((den[3]*t + den[2])*t + den[1])*t + den[0];
+    q = lower ? n/d - t : t - n/d;
+    return(q);
+}
+
+/*
+ * Inverse incomplete beta function.
+ * Assumption: 0 <= p <= 1, a,b > 0.
+ */
+
+double invibeta(double p, double a, double b)
+{
+    int i;
+    double ql, qr, qm, qdiff;
+    double pl, pr, pm, pdiff;
+    double invibeta_quick(), ibeta();
+
+/*        MEANINGFUL(qm);*/
+    qm = 0;
+    if(p == 0 || p == 1)
+        return(p);
+
+    /* initialize [ql,qr] containing the root */
+    ql = qr = invibeta_quick(p, a, b);
+    pl = pr = ibeta(ql, a, b);
+    if(pl == p)
+        return(ql);
+    if(pl < p)
+        while(1) {
+            qr += 0.05;
+            if(qr >= 1) {
+                pr = qr = 1;
+                break;
+                }
+            pr = ibeta(qr, a, b);
+            if(pr == p)
+                return(pr);
+            if(pr > p)
+                break;
+        }
+    else
+        while(1) {
+            ql -= 0.05;
+            if(ql <= 0) {
+                pl = ql = 0;
+                break;
+                }
+            pl = ibeta(ql, a, b);
+            if(pl == p)
+                return(pl);
+            if(pl < p)
+                break;
+        }
+
+    /* a few steps of bisection */
+    for(i = 0; i < 5; i++) {
+        qm = (ql + qr) / 2;
+        pm = ibeta(qm, a, b);
+        qdiff = qr - ql;
+        pdiff = pm - p;
+        if(fabs(qdiff) < DOUBLE_EPS*qm || fabs(pdiff) < DOUBLE_EPS)
+            return(qm);
+        if(pdiff < 0) {
+            ql = qm;
+            pl = pm;
+        } else {
+            qr = qm;
+            pr = pm;
+        }
+    }
+
+    /* a few steps of secant */
+    for(i = 0; i < 40; i++) {
+        qm = ql + (p-pl)*(qr-ql)/(pr-pl);
+        pm = ibeta(qm, a, b);
+        qdiff = qr - ql;
+        pdiff = pm - p;
+        if(fabs(qdiff) < 2*DOUBLE_EPS*qm || fabs(pdiff) < 2*DOUBLE_EPS)
+            return(qm);
+        if(pdiff < 0) {
+            ql = qm;
+            pl = pm;
+        } else {
+            qr = qm;
+            pr = pm;
+        }
+    }
+
+    /* no convergence */
+    return(qm);
+}
+
+/*
+ * Quick approximation to inverse incomplete beta function,
+ * by matching first two moments with the Gaussian distribution.
+ * Assumption: 0 < p < 1, a,b > 0.
+ */
+
+double invibeta_quick(double p, double a, double b)
+{
+    double x, m, s, fmax(), fmin(), invigauss_quick();
+
+    x = a + b;
+    m = a / x;
+    s = sqrt((a*b) / (x*x*(x+1)));
+    return(fmax(0.0, fmin(1.0, invigauss_quick(p)*s + m)));
+}
+
+int max(int a, int b)
+{
+    return(a > b ? a : b);
+}
+
+typedef double doublereal;
+typedef int integer;
+
+void Recover(char *a, int *b)
+{
+    printf(a);
+    exit(1);
+}
+
+void Warning(char *a, int *b)
+{
+    printf(a);
+}
+
+/*  d1mach may be replaced by Fortran code:
+    mail netlib@netlib.bell-labs.com
+    send d1mach from core.
+*/
+
+#include <float.h>
+
+doublereal F77_SUB(d1mach) (integer *i)
+{
+switch(*i){
+    case 1: return DBL_MIN;
+    case 2: return DBL_MAX;
+    case 3: return DBL_EPSILON/FLT_RADIX;
+    case 4: return DBL_EPSILON;
+    case 5: return log10(FLT_RADIX);
+    default: Recover("Invalid argument to d1mach()", 0L);
+    }
+}
+

Added: trunk/Lib/sandbox/pyloess/src/predict.c
===================================================================
--- trunk/Lib/sandbox/pyloess/src/predict.c	2007-03-21 21:28:18 UTC (rev 2862)
+++ trunk/Lib/sandbox/pyloess/src/predict.c	2007-03-21 22:53:54 UTC (rev 2863)
@@ -0,0 +1,187 @@
+#include "S.h"
+#include "loess.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+
+extern char *error_message;
+extern int error_status;
+
+void
+predict(double *eval, int m, loess *lo, prediction *pre, int se)
+{
+    int  size_info[3];
+    void pred_();
+
+    pre->fit = (double *) malloc(m * sizeof(double));
+    pre->se_fit = (double *) malloc(m * sizeof(double));
+    pre->residual_scale = lo->outputs.s;
+    pre->df = (lo->outputs.one_delta * lo->outputs.one_delta) /
+              lo->outputs.two_delta;
+
+    size_info[0] = lo->inputs.p;
+    size_info[1] = lo->inputs.n;
+    size_info[2] = m;
+    
+    error_status = 0;
+    lo->status.err_status = 0;
+    lo->status.err_msg = NULL;
+
+    pred_(lo->inputs.y,
+          lo->inputs.x, eval,
+          size_info,
+          &lo->outputs.s,
+          lo->inputs.weights,
+          lo->outputs.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->outputs.divisor,
+          &se,
+          pre->fit,
+          pre->se_fit);
+
+    if(error_status){
+        lo->status.err_status = error_status;
+        lo->status.err_msg = error_message;
+    }
+}
+
+void
+pred_(double *y, double *x_, double *new_x, int *size_info, double *s,
+      double *weights, double *robust, double *span, int *degree,
+      int *normalize, int *parametric, int *drop_square, char **surface,
+      double *cell, char **family, int *parameter, int *a, double *xi,
+      double *vert, double *vval, double *divisor, int *se, double *fit,
+      double *se_fit)
+{
+    double  *x, *x_tmp, *x_evaluate, *L, new_cell, z, tmp, *fit_tmp,
+            *temp, sum, mean;
+    int    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 = (int *) malloc(D * sizeof(int));
+    order_drop_sqr = (int *) malloc(D * sizeof(int));
+    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(prediction *pre)
+{
+    free(pre->fit);
+    free(pre->se_fit);
+}
+
+
+
+
+
+

Added: trunk/Lib/sandbox/pyloess/tests/gas_data
===================================================================
--- trunk/Lib/sandbox/pyloess/tests/gas_data	2007-03-21 21:28:18 UTC (rev 2862)
+++ trunk/Lib/sandbox/pyloess/tests/gas_data	2007-03-21 22:53:54 UTC (rev 2863)
@@ -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/tests/gas_result
===================================================================
--- trunk/Lib/sandbox/pyloess/tests/gas_result	2007-03-21 21:28:18 UTC (rev 2862)
+++ trunk/Lib/sandbox/pyloess/tests/gas_result	2007-03-21 22:53:54 UTC (rev 2863)
@@ -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/tests/madeup_data
===================================================================
--- trunk/Lib/sandbox/pyloess/tests/madeup_data	2007-03-21 21:28:18 UTC (rev 2862)
+++ trunk/Lib/sandbox/pyloess/tests/madeup_data	2007-03-21 22:53:54 UTC (rev 2863)
@@ -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/tests/madeup_result
===================================================================
--- trunk/Lib/sandbox/pyloess/tests/madeup_result	2007-03-21 21:28:18 UTC (rev 2862)
+++ trunk/Lib/sandbox/pyloess/tests/madeup_result	2007-03-21 22:53:54 UTC (rev 2863)
@@ -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/tests/test_pyloess.py
===================================================================
--- trunk/Lib/sandbox/pyloess/tests/test_pyloess.py	2007-03-21 21:28:18 UTC (rev 2862)
+++ trunk/Lib/sandbox/pyloess/tests/test_pyloess.py	2007-03-21 22:53:54 UTC (rev 2863)
@@ -17,42 +17,20 @@
 from numpy import bool_, complex_, float_, int_, str_, object_
 import numpy.core.numeric as numeric
 from numpy.core.records import recarray
+fromiter = numpy.fromiter
 
+
 from numpy.testing import NumpyTest, NumpyTestCase
 from numpy.testing.utils import build_err_msg, \
         assert_equal, assert_almost_equal
 
 import pyloess
 reload(pyloess)
-from pyloess import lowess, stl
+from pyloess import lowess, stl, loess, loess_anova
 
-
-def get_co2data():
-    "Reads CO2 data."
-    filename = os.path.join('tests','co2_data')
-    F = open(filename, 'r')
-    data = []
-    for line in F.readlines():
-        data.append([float(x) for x in line.rstrip().split()])
-    return numpy.concatenate(data)
-
-def get_co2results():
-    "Gets theoretical results of smoothed CO2."
-    filename = os.path.join('tests','co2_results_double')
-    F = open(filename, 'r')
-    result = []
-    for line in F.readlines():
-        result.append(numpy.fromiter((float(x) for x in line.rstrip().split()),
-                                     float_))
-    return result
-
-def set_parameters():
-    "Returns the parameters of the STL on CO2 data."
-    parameters = dict(np=12, ns=35, nt=19, nl=13, no=2, ni=1,
-                      nsjump=4, ntjump=2, nljump=2,
-                      isdeg=1, itdeg=1, ildeg=1)
-    return parameters
-########################################################################
+#####---------------------------------------------------------------------------
+#---- --- LOWESS ---
+#####---------------------------------------------------------------------------
 class test_lowess(NumpyTestCase):
     "Test class for lowess."
     #
@@ -61,7 +39,7 @@
         X = [ 1, 2, 3, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8,10,12,14,50]
         Y = [18, 2,15, 6,10, 4,16,11, 7, 3,14,17,20,12, 9,13, 1, 8, 5,19]
         self.data = (X, Y)
-    #
+    #............................................
     def test_lowess_1(self):
         "Tests lowess on typical data. part #1."
         (X, Y) = self.data
@@ -71,7 +49,7 @@
         Z = lowess(X, Y, f=0.25, nsteps=0, delta=0)
         assert_almost_equal(Z.smooth, YS, decimal=3)
         assert_almost_equal(Z.residuals+Z.smooth, Y, decimal=3)
-    #
+    #............................................
     def test_lowess_2(self):
         "Tests lowess on typical data. part #2."
         (X, Y) = self.data
@@ -81,7 +59,7 @@
         Z = lowess(X, Y, f=0.25, nsteps=0, delta=3)
         assert_almost_equal(Z.smooth, YS, decimal=3)
         assert_almost_equal(Z.residuals+Z.smooth, Y, decimal=3)        
-    #
+    #............................................
     def test_lowess_3(self):
         "Tests lowess on typical data. part #3."
         (X, Y) = self.data
@@ -92,17 +70,34 @@
         assert_almost_equal(Z.smooth, YS, decimal=3)
         assert_almost_equal(Z.residuals+Z.smooth, Y, decimal=3)        
 
-#-----------------------------------------------------------------------
+#####---------------------------------------------------------------------------
+#---- --- STL ---
+#####---------------------------------------------------------------------------
 class test_stl(NumpyTestCase):
     "Tests STL."
     #
     def __init__(self, *args, **kwds):
         NumpyTestCase.__init__(self, *args, **kwds)
-        co2_data = get_co2data()
-        co2_results = get_co2results()
-        parameters = set_parameters()
+        # Get CO2 data ................    
+        filename = os.path.join('tests','co2_data')
+        F = open(filename, 'r')
+        data = []
+        for line in F.readlines():
+            data.append([float(x) for x in line.rstrip().split()])
+        co2_data = numpy.concatenate(data)
+        # Get CO2 results .............
+        filename = os.path.join('tests','co2_results_double')
+        F = open(filename, 'r')
+        co2_results = []
+        for line in F.readlines():
+            co2_results.append(fromiter((float(x) for x in line.rstrip().split()),
+                                        float_))        
+        #
+        parameters = dict(np=12, ns=35, nt=19, nl=13, no=2, ni=1,
+                          nsjump=4, ntjump=2, nljump=2,
+                          isdeg=1, itdeg=1, ildeg=1)
         self.d = (co2_data, co2_results, parameters)
-    #
+    #............................................
     def test_stl_1(self):
         "Tests a classic STL."
         (co2_data, co2_results, parameters) = self.d
@@ -110,7 +105,7 @@
         assert_almost_equal(co2_fitted.seasonal, co2_results[0], 6)
         assert_almost_equal(co2_fitted.trend, co2_results[1], 6)
         assert_almost_equal(co2_fitted.weights, co2_results[2], 6)
-    #
+    #............................................
     def test_stl_2(self):
         "Tests a robust STL."
         (co2_data, co2_results, parameters) = self.d
@@ -118,14 +113,278 @@
         assert_almost_equal(co2_fitted.seasonal, co2_results[4], 6)
         assert_almost_equal(co2_fitted.trend, co2_results[5], 6)
         assert_almost_equal(co2_fitted.weights, co2_results[6], 6)
+
+
+#####---------------------------------------------------------------------------
+#---- --- LOESS ---
+#####---------------------------------------------------------------------------
+
+class test_loess2d(NumpyTestCase):
+    "Test class for lowess."
+    #
+    def __init__(self, *args, **kwds):
+        NumpyTestCase.__init__(self, *args, **kwds)
+        dfile = open(os.path.join('tests','madeup_data'), 'r')
+        dfile.readline()
+        x = fromiter((float(v) for v in dfile.readline().rstrip().split()),
+                     float_).reshape(-1,2)
+        dfile.readline()
+        y = fromiter((float(v) for v in dfile.readline().rstrip().split()),
+                     float_)
+        dfile = open(os.path.join('tests','madeup_data'), 'r')
+        dfile.readline()
+        #
+        rfile = open(os.path.join('tests','madeup_result'), 'r')
+        results = []
+        for i in range(8):
+            rfile.readline()
+            z = fromiter((float(v) for v in rfile.readline().rstrip().split()),
+                         float_)
+            results.append(z)
+        #
+        newdata1 = numpy.array([[-2.5, 0.0, 2.5], [0., 0., 0.]])
+        newdata2 = numpy.array([[-0.5, 0.5], [0., 0.]])
+        #
+        madeup = loess(x,y)
+        self.d = (x, y, results, newdata1, newdata2, madeup)
+    #
+    def test_2dbasic(self):
+        "2D standard"
+        (x, y, results, _, _, madeup) = self.d
+        madeup = 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, _, _, madeup) = self.d
+        madeup = 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"
+        (_, _, results, _, _, 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"
+        (_, _, results, _, _, 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"
+        (_, _, results, newdata1, _, madeup) = self.d
+        madeup.model.span = 0.5
+        madeup.model.normalize = True
+        madeup.predict(newdata1, stderror=False)
+        assert_almost_equal(madeup.predicted.values, results[4], 5)
+        #
+        madeup_pred = madeup.predict(newdata1, stderror=False)
+        assert_almost_equal(madeup_pred.values, results[4], 5)
+    #
+    def test_2d_pred_nodata(self):
+        "2D prediction - nodata"
+        (_, _, _, _, _, madeup) = self.d
+        try:
+            madeup.predict(None)
+        except ValueError:
+            pass
+        else:
+            raise AssertionError,"The test should have failed"   
+    #
+    def test_2d_pred_stderr(self):
+        "2D prediction - w/ stderr"
+        (_, _, results, _, newdata2, madeup) = self.d   
+        madeup.model.span = 0.5
+        madeup.model.normalize = True
+        madeup_pred = madeup.predict(newdata2, stderror=True)
+        assert_almost_equal(madeup_pred.values, results[5], 5)
+        assert_almost_equal(madeup_pred.stderr, [0.276746, 0.278009], 5)
+        assert_almost_equal(madeup_pred.residual_scale, 0.969302, 6)
+        assert_almost_equal(madeup_pred.df, 81.2319, 4)
+        # Direct access
+        madeup.predict(newdata2, stderror=True)
+        assert_almost_equal(madeup.predicted.values, results[5], 5)
+        assert_almost_equal(madeup.predicted.stderr, [0.276746, 0.278009], 5)
+        assert_almost_equal(madeup.predicted.residual_scale, 0.969302, 6)
+        assert_almost_equal(madeup.predicted.df, 81.2319, 4)
+    #
+    def test_2d_pred_confinv(self):
+        "2D prediction - confidence"
+        (_, _, results, _, newdata2, madeup) = self.d   
+        madeup.model.span = 0.5
+        madeup.model.normalize = True
+        madeup_pred = madeup.predict(newdata2, stderror=True)        
+        madeup.predicted.confidence(coverage=0.99)
+        assert_almost_equal(madeup.predicted.confidence_intervals.lower, 
+                            results[6][::3], 5)
+        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)
+    
+#####---------------------------------------------------------------------------
+#---- --- test 2D
+#####---------------------------------------------------------------------------
+class test_loess_gas(NumpyTestCase):
+    "Test class for lowess."
+    #
+    def __init__(self, *args, **kwds):
+        NumpyTestCase.__init__(self, *args, **kwds)
+        NOx = numpy.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 = numpy.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 = numpy.array([0.665, 0.949, 1.224])
+        newdata = numpy.array([0.6650000, 0.7581667, 0.8513333, 0.9445000,
+                               1.0376667, 1.1308333, 1.2240000])
+        coverage = 0.99
+
+        rfile = open(os.path.join('tests','gas_result'), 'r')
+        results = []
+        for i in range(8):
+            rfile.readline()
+            z = fromiter((float(v) for v in rfile.readline().rstrip().split()),
+                         float_)
+            results.append(z)        
+        self.d = (E, NOx, gas_fit_E, newdata, coverage, results)
+    #
+    def test_1dbasic(self):
+        "Basic test 1d"
+        (E, NOx, _, _, _, results) = self.d
+        gas = 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 test_1dbasic_alt(self):
+        "Basic test 1d - part #2"
+        (E, NOx, _, _, _, results) = self.d
+        gas_null = 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 test_1dpredict(self):
+        "Basic test 1d - prediction"
+        (E, NOx, gas_fit_E, _, _, results) = self.d
+        gas = loess(E,NOx, span=2./3.)
+        gas.fit()
+        gas.predict(gas_fit_E, stderror=False)
+        assert_almost_equal(gas.predicted.values, results[2], 6)
+    #
+    def test_1dpredict_2(self):
+        "Basic test 1d - new predictions"
+        (E, NOx, _, newdata, _, results) = self.d        
+        gas = loess(E,NOx, span=2./3.)
+        gas.predict(newdata, stderror=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)
+    #
+    def test_anova(self):
+        "Tests anova"
+        (E, NOx, _, _, _, results) = self.d        
+        gas = loess(E,NOx, span=2./3.)
+        gas.fit()
+        gas_null = loess(E, NOx, span=1.0)
+        gas_null.fit()
+        gas_anova = loess_anova(gas, gas_null)
+        gas_anova_theo = results[4]
+        assert_almost_equal(gas_anova.dfn, gas_anova_theo[0], 5)
+        assert_almost_equal(gas_anova.dfd, gas_anova_theo[1], 5)
+        assert_almost_equal(gas_anova.F_value, gas_anova_theo[2], 5)
+        assert_almost_equal(gas_anova.Pr_F, gas_anova_theo[3], 5)
+    #
+    def test_failures(self):
+        "Tests failures"
+        (E, NOx, gas_fit_E, _, _, _) = self.d       
+        gas = loess(E,NOx, span=2./3.)
+        # This one should fail (all parametric)
+        gas.model.parametric_flags = True
+        self.assertRaises(ValueError, gas.fit)
+        # This one also (all drop_square)
+        gas.model.drop_square_flags = True
+        self.assertRaises(ValueError, gas.fit)
+        gas.model.degree = 1
+        self.assertRaises(ValueError, gas.fit)
+        # This one should not (revert to std)
+        gas.model.parametric_flags = False
+        gas.model.drop_square_flags = False
+        gas.model.degree = 2
+        gas.fit()
+        # Now, for predict .................
+        gas.predict(gas_fit_E, stderror=False)
+        # This one should fail (extrapolation & blending)
+        self.assertRaises(ValueError, 
+                          gas.predict, gas.predicted.values, stderror=False)
+        # But this one should not ..........
+        gas.predict(gas_fit_E, stderror=False)
+        print "OK"
         
+        
+        
+        
+
+
+
 ########################################################################
 if __name__ == '__main__':
     NumpyTest().run()       
-    #
-    co2_data = get_co2data()
-    co2_results = get_co2results()
-    parameters = set_parameters()
-    co2_fitted = stl(co2_data, robust=False, **parameters)
+
     
 



More information about the Scipy-svn mailing list