Commits

Janez Demšar  committed 68b51ae

- it seems that swig does not accept things like
%typemap(in,numinputs=0) struct CFInfo *OutValue {
--> i needed to change all these to
%typemap(in,numinputs=0) TCFInfo *OutValue {
This broke k-means clustering (and probably everything else in orngCRS). Now it seems to work.

  • Participants
  • Parent commits cdff6d2

Comments (0)

Files changed (2)

File src/Clustind_wrap.cxx

 
 /* -------- TYPES TABLE (BEGIN) -------- */
 
-#define SWIGTYPE_p_CFInfo swig_types[0]
-#define SWIGTYPE_p_CHInfo swig_types[1]
-#define SWIGTYPE_p_CInput swig_types[2]
-#define SWIGTYPE_p_CMInfo swig_types[3]
-#define SWIGTYPE_p_DInput swig_types[4]
-#define SWIGTYPE_p_KArray swig_types[5]
-#define SWIGTYPE_p_KInfo swig_types[6]
-#define SWIGTYPE_p_KInput swig_types[7]
-#define SWIGTYPE_p_KList swig_types[8]
-#define SWIGTYPE_p_KMatrix swig_types[9]
-#define SWIGTYPE_p_KModel swig_types[10]
-#define SWIGTYPE_p_KModels swig_types[11]
-#define SWIGTYPE_p_LRInfo swig_types[12]
-#define SWIGTYPE_p_LRInput swig_types[13]
-#define SWIGTYPE_p_NBInfo swig_types[14]
-#define SWIGTYPE_p_NBInput swig_types[15]
-#define SWIGTYPE_p_NBList swig_types[16]
-#define SWIGTYPE_p_NBModel swig_types[17]
-#define SWIGTYPE_p_NBResult swig_types[18]
-#define SWIGTYPE_p_SVMExample swig_types[19]
-#define SWIGTYPE_p_SVMInput swig_types[20]
-#define SWIGTYPE_p_SVMOut swig_types[21]
-#define SWIGTYPE_p_SVMSparseExample swig_types[22]
-#define SWIGTYPE_p_SVMSparseInput swig_types[23]
-#define SWIGTYPE_p_XX swig_types[24]
-#define SWIGTYPE_p_char swig_types[25]
-#define SWIGTYPE_p_double swig_types[26]
-#define SWIGTYPE_p_int swig_types[27]
-#define SWIGTYPE_p_psvm_model swig_types[28]
-#define SWIGTYPE_p_svm_model swig_types[29]
-#define SWIGTYPE_p_wsvm_model swig_types[30]
-static swig_type_info *swig_types[32];
-static swig_module_info swig_module = {swig_types, 31, 0, 0, 0, 0};
+#define SWIGTYPE_p_TCFInfo swig_types[0]
+#define SWIGTYPE_p_TCHInfo swig_types[1]
+#define SWIGTYPE_p_TCInput swig_types[2]
+#define SWIGTYPE_p_TCMInfo swig_types[3]
+#define SWIGTYPE_p_TDInput swig_types[4]
+#define SWIGTYPE_p_TKArray swig_types[5]
+#define SWIGTYPE_p_TKInfo swig_types[6]
+#define SWIGTYPE_p_TKInput swig_types[7]
+#define SWIGTYPE_p_TKList swig_types[8]
+#define SWIGTYPE_p_TKMatrix swig_types[9]
+#define SWIGTYPE_p_TKModel swig_types[10]
+#define SWIGTYPE_p_TKModels swig_types[11]
+#define SWIGTYPE_p_TLRInfo swig_types[12]
+#define SWIGTYPE_p_TLRInput swig_types[13]
+#define SWIGTYPE_p_TNBInfo swig_types[14]
+#define SWIGTYPE_p_TNBInput swig_types[15]
+#define SWIGTYPE_p_TNBList swig_types[16]
+#define SWIGTYPE_p_TNBModel swig_types[17]
+#define SWIGTYPE_p_TNBResult swig_types[18]
+#define SWIGTYPE_p_TSVMExample swig_types[19]
+#define SWIGTYPE_p_TSVMInput swig_types[20]
+#define SWIGTYPE_p_TSVMOut swig_types[21]
+#define SWIGTYPE_p_TSVMSparseExample swig_types[22]
+#define SWIGTYPE_p_TSVMSparseInput swig_types[23]
+#define SWIGTYPE_p_TXX swig_types[24]
+#define SWIGTYPE_p_Tsvm_model swig_types[25]
+#define SWIGTYPE_p_char swig_types[26]
+#define SWIGTYPE_p_double swig_types[27]
+#define SWIGTYPE_p_int swig_types[28]
+#define SWIGTYPE_p_psvm_model swig_types[29]
+static swig_type_info *swig_types[31];
+static swig_module_info swig_module = {swig_types, 30, 0, 0, 0, 0};
 #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
 #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
 
 #include "nb.h"
 #include "kikuchi.h"
 
+typedef struct CMInfo TCMInfo;
+typedef struct LRInfo TLRInfo;
+typedef struct CHInfo TCHInfo;
+typedef struct CFInfo TCFInfo;
+typedef struct SVMInput TSVMInput;
+typedef struct SVMExample TSVMExample;
+typedef struct SVMSparseInput TSVMSparseInput;
+typedef struct SVMSparseExample TSVMSparseExample ;
+typedef struct svm_model Tsvm_model;
+typedef struct wsvm_model Twsvm_model;
+typedef struct LRInput TLRInput;
+typedef struct CInput TCInput;
+typedef struct DInput TDInput;
+typedef struct SVMOut TSVMOut;
+typedef struct NBResult TNBResult;
+typedef struct NBInput TNBInput;
+typedef struct NBModel TNBModel;
+typedef struct NBList TNBList;
+typedef struct XX TXX;
+typedef struct NBInfo TNBInfo;
+typedef struct KInput TKInput;
+typedef struct KList TKList;
+typedef struct KMatrix TKMatrix;
+typedef struct KModel TKModel;
+typedef struct KGroup TKGroup;
+typedef struct KModels TKModels;
+typedef struct KArray TKArray;
+typedef struct KInfo TKInfo;
+
 
 #include <limits.h>
 #ifndef LLONG_MIN
 
 SWIGINTERN PyObject *_wrap_SVMClassifier(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  svm_model *arg1 = (svm_model *) 0 ;
+  Tsvm_model *arg1 = (Tsvm_model *) 0 ;
   psvm_model result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
   PyObject * obj0 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:SVMClassifier",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_svm_model, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SVMClassifier" "', argument " "1"" of type '" "svm_model *""'"); 
-  }
-  arg1 = reinterpret_cast< svm_model * >(argp1);
+  {
+    PyObject *o, *t, *p, *zz, *uu;
+    int m,l,i,j, elements, pairs;
+    struct svm_node *x_space;
+    Tsvm_model *model;
+    struct svm_parameter *param;
+    
+    
+    o = obj0;
+    model = (Tsvm_model *)malloc(sizeof(Tsvm_model));
+    param = &(model->param);
+    model->label = NULL;
+    model->nSV = NULL;
+    model->probA = NULL;
+    model->probB = NULL;
+    
+    if (!PyDict_Check(o)) {
+      PyErr_SetString(PyExc_TypeError,"must be a dictionary");
+      free(model);
+      return NULL;
+    }
+    t = PyDict_GetItemString(o, "svm_type");
+    if (!PyInt_Check(t)) {
+      PyErr_SetString(PyExc_TypeError,"svm_type missing");
+      free(model);
+      return NULL;
+    }
+    param->svm_type = PyInt_AsLong(t);
+    t = PyDict_GetItemString(o, "kernel_type");
+    if (!PyInt_Check(t)) {
+      PyErr_SetString(PyExc_TypeError,"kernel_type missing");
+      free(model);
+      return NULL;
+    }
+    param->kernel_type = PyInt_AsLong(t);
+    
+    if(param->kernel_type == POLY) {
+      t = PyDict_GetItemString(o, "degree");
+      if (!PyFloat_Check(t)) {
+        PyErr_SetString(PyExc_TypeError,"degree missing");
+        free(model);
+        return NULL;
+      }
+      param->degree = PyFloat_AsDouble(t);
+    }
+    
+    if(param->kernel_type == POLY || param->kernel_type == RBF || param->kernel_type == SIGMOID) {
+      t = PyDict_GetItemString(o, "gamma");
+      if (!PyFloat_Check(t)) {
+        PyErr_SetString(PyExc_TypeError,"gamma missing");
+        free(model);
+        return NULL;
+      }
+      param->gamma = PyFloat_AsDouble(t);
+    }
+    
+    if(param->kernel_type == POLY || param->kernel_type == SIGMOID) {
+      t = PyDict_GetItemString(o, "coef0");
+      if (!PyFloat_Check(t)) {
+        PyErr_SetString(PyExc_TypeError,"coef0 missing");
+        free(model);
+        return NULL;
+      }
+      param->coef0 = PyFloat_AsDouble(t);
+    }
+    
+    t = PyDict_GetItemString(o, "nr_class");
+    if (!PyInt_Check(t)) {
+      PyErr_SetString(PyExc_TypeError,"nr_class missing");
+      free(model);
+      return NULL;
+    }
+    m = model->nr_class = PyInt_AsLong(t);
+    t = PyDict_GetItemString(o, "total_sv");
+    if (!PyInt_Check(t)) {
+      PyErr_SetString(PyExc_TypeError,"total_sv missing");
+      free(model);
+      return NULL;
+    }
+    l = model->l = PyInt_AsLong(t);
+    
+    
+    t = PyDict_GetItemString(o, "rho");
+    if (!PyList_Check(t)) {
+      PyErr_SetString(PyExc_TypeError,"rho missing");
+      free(model);
+      return NULL;
+    }
+    pairs = m*(m-1)/2;
+    model->rho = (double *)malloc(sizeof(double)*pairs);
+    for(i=0;i<pairs;i++) {
+      p = PyList_GetItem(t, i);
+      model->rho[i] = PyFloat_AsDouble(p);
+    }
+    
+    t = PyDict_GetItemString(o, "ProbA");
+    if (t != NULL) {
+      model->probA = (double *)malloc(sizeof(double)*pairs);
+      for(i=0;i<pairs;i++) {
+        p = PyList_GetItem(t, i);
+        model->probA[i] = PyFloat_AsDouble(p);
+      }
+    }
+    
+    t = PyDict_GetItemString(o, "ProbB");
+    if (t != NULL) {
+      model->probB = (double *)malloc(sizeof(double)*pairs);
+      for(i=0;i<pairs;i++) {
+        p = PyList_GetItem(t, i);
+        model->probB[i] = PyFloat_AsDouble(p);
+      }
+    }
+    
+    t = PyDict_GetItemString(o, "label");
+    if (t != NULL) {
+      model->label = (int *)malloc(sizeof(int)*m);
+      for(i=0;i<m;i++) {
+        p = PyList_GetItem(t, i);
+        model->label[i] = PyInt_AsLong(p);
+      }
+    }
+    
+    t = PyDict_GetItemString(o, "nr_sv");
+    if (t != NULL) {
+      model->nSV = (int *)malloc(sizeof(int)*m);
+      for(i=0;i<m;i++) {
+        p = PyList_GetItem(t, i);
+        model->nSV[i] = PyInt_AsLong(p);
+      }
+    }
+    
+    t = PyDict_GetItemString(o, "elements");
+    elements = PyInt_AsLong(t);
+    
+    model->sv_coef = (double **)malloc(sizeof(double *)*m);
+    model->SVidx = (int *)malloc(sizeof(int)*l); // allocate even if not use
+    model->SV = (struct svm_node **)malloc(sizeof(struct svm_node **)*l);
+    for(i=0;i<m;i++)
+    model->sv_coef[i] = (double *)malloc(sizeof(double)*l);
+    
+    x_space = (struct svm_node *)malloc(sizeof(struct svm_node)*elements);
+    
+    p = PyDict_GetItemString(o, "SV");
+    if (!PyList_Check(p) || PyList_Size(p)!=l) {
+      PyErr_SetString(PyExc_TypeError,"SV list missing");
+      free(model);
+      return NULL;
+    }
+    j = 0;
+    for(i=0;i<l;i++)
+    {
+      int jj, kk;
+      
+      zz = PyList_GetItem(p,i);
+      if (!PyList_Check(zz)) {
+        PyErr_SetString(PyExc_TypeError,"wrong SV vector (leak)"); return NULL;
+      }
+      
+      t = PyList_GetItem(zz, 0); // sv_coef is first
+      if (!PyList_Check(t) || PyList_Size(t)!= m-1 ) {
+        PyErr_SetString(PyExc_TypeError,"SV coef wrong (leak)"); return NULL;
+      }
+      
+      for(jj=0;jj<m-1;jj++) {
+        uu = PyList_GetItem(t, jj);
+        if (!PyFloat_Check(uu)) {
+          PyErr_SetString(PyExc_TypeError,"SV coef entry wrong (leak)"); return NULL;
+        }
+        model->sv_coef[jj][i] = PyFloat_AsDouble(uu);
+      }
+      
+      model->SV[i] = &(x_space[j]);
+      
+      kk = PyList_Size(zz);
+      
+      for (jj = 1; jj < kk; ++jj) {
+        t =PyList_GetItem(zz, jj);
+        if (!PyTuple_Check(t)) {
+          PyErr_SetString(PyExc_TypeError,"SV entry wrong (leak)"); return NULL;
+        }
+        
+        uu = PyTuple_GetItem(t,0);
+        x_space[j].index = PyInt_AsLong(uu);
+        uu = PyTuple_GetItem(t,1);
+        x_space[j].value = PyFloat_AsDouble(uu);
+        
+        ++j;
+      }
+      x_space[j++].index = -1;
+    }
+    assert(j == elements);
+    model->free_sv = 1;	// XXX
+    arg1 = model;
+  }
   result = SVMClassifier(arg1);
   resultobj = SWIG_NewPointerObj((new psvm_model(static_cast< const psvm_model& >(result))), SWIGTYPE_p_psvm_model, SWIG_POINTER_OWN |  0 );
   return resultobj;
 
 SWIGINTERN PyObject *_wrap_SVMLearnS(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  SVMSparseInput *arg1 = (SVMSparseInput *) 0 ;
+  TSVMSparseInput *arg1 = (TSVMSparseInput *) 0 ;
   int arg2 ;
   int arg3 ;
   double arg4 ;
   int arg14 ;
   double *arg15 = (double *) 0 ;
   int *arg16 = (int *) 0 ;
-  wsvm_model *result = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
+  Twsvm_model *result = 0 ;
   int val2 ;
   int ecode2 = 0 ;
   int val3 ;
   PyObject * obj15 = 0 ;
   
   {
+    arg1 = NULL;
+  }
+  {
     arg15 = NULL;
   }
   {
     arg16 = NULL;
   }
   if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOOOOOOOO:SVMLearnS",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9,&obj10,&obj11,&obj12,&obj13,&obj14,&obj15)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SVMSparseInput, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SVMLearnS" "', argument " "1"" of type '" "SVMSparseInput *""'"); 
-  }
-  arg1 = reinterpret_cast< SVMSparseInput * >(argp1);
+  {
+    /* Check if is a list */
+    if (PyList_Check(obj0)) {
+      int i, j, k, nex, nvals;
+      
+      nex = PyList_Size(obj0);
+      nvals = 0;
+      
+      arg1 = (TSVMSparseInput *) malloc(sizeof(TSVMSparseInput));
+      arg1->elements = 0;
+      arg1->index = NULL;
+      arg1->value = NULL;
+      arg1->label = NULL;
+      for (i = 0; i < nex; i++) {
+        PyObject *ex = PyList_GetItem(obj0,i);
+        // example
+        if (PyList_Check(ex)) {
+          nvals = PyList_Size(ex)-1;
+          if (arg1->index == NULL) {
+            arg1->nn = nex;
+            arg1->lengths = (int *)malloc(arg1->nn*sizeof(int));
+            arg1->value = (double **)malloc(arg1->nn*sizeof(double *));
+            arg1->index = (int **)malloc(arg1->nn*sizeof(int *));
+            arg1->label = (double *)malloc(arg1->nn*sizeof(double));
+            for(j = 0; j < nex; ++j)
+            arg1->lengths[j] = -1;
+          }
+          // fetch the class (must be binary)
+          PyObject *p = PyList_GetItem(ex,0);
+          if (p == NULL) {
+            PyErr_SetString(PyExc_TypeError,"cannot fetch label");
+            SVMscleanup(arg1);
+            return NULL;
+          }
+          if (PyInt_Check(p) || PyLong_Check(p)) {
+            arg1->label[i] = (double)PyInt_AsLong(p);
+          } else if(PyFloat_Check(p)) {
+            arg1->label[i] = PyFloat_AsDouble(p);
+          } else {
+            PyErr_SetString(PyExc_TypeError,"class not float or int");
+            SVMscleanup(arg1);
+            return NULL;
+          }
+          arg1->lengths[i] = nvals-1;
+          arg1->elements += nvals-1;
+          if(nvals > 0) {
+            arg1->value[i] = (double *)malloc((nvals-1)*sizeof(double));
+            arg1->index[i] = (int *)malloc((nvals-1)*sizeof(int));
+          }
+          // fetch the attribute values
+          for (j = 1; j < nvals; ++j) {
+            PyObject *p = PyList_GetItem(ex,j);
+            if(PyTuple_Check(p)) {
+              PyObject *idx = PyTuple_GetItem(p,0); 
+              PyObject *val = PyTuple_GetItem(p,1); 
+              if ((PyInt_Check(idx) || PyLong_Check(idx)) && (PyInt_AsLong(idx) >= 1) ) {
+                arg1->index[i][j-1] = PyInt_AsLong(idx);
+              } else {
+                PyErr_SetString(PyExc_TypeError,"index not a positive integer");
+                SVMscleanup(arg1);
+                return NULL;
+              }
+              if (PyInt_Check(val) || PyLong_Check(val)) {
+                arg1->value[i][j-1] = (double)PyInt_AsLong(val);
+              } else if(PyFloat_Check(val)) {
+                arg1->value[i][j-1] = PyFloat_AsDouble(val);
+              }  else {
+                PyErr_SetString(PyExc_TypeError,"value not an integer or a float");
+                SVMscleanup(arg1);
+                return NULL;
+              }
+            } else {
+              PyErr_SetString(PyExc_TypeError,"attribute values within an example must be tuples (index,value)");
+              SVMscleanup(arg1);
+              return NULL;
+            }
+          } 
+        } else {
+          PyErr_SetString(PyExc_TypeError,"example table must contain examples as lists of tuples");
+          SVMscleanup(arg1);
+          return NULL;
+        }
+      }
+    } else {
+      PyErr_SetString(PyExc_TypeError,"not a list");
+      return NULL;
+    }
+  }
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
     SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SVMLearnS" "', argument " "2"" of type '" "int""'");
       return NULL;
     }
   }
-  result = (wsvm_model *)SVMLearnS(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13,arg14,arg15,arg16);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_wsvm_model, 0 |  0 );
+  result = (Twsvm_model *)SVMLearnS(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13,arg14,arg15,arg16);
+  {
+    struct svm_parameter *param = &(result->m->param);
+    double **sv_coef;
+    struct svm_node **SV;
+    Tsvm_model *model = result->m;
+    int i, j, nr_class, l, elements;
+    PyObject *o, *t, *p, *ip;
+    
+    o = PyDict_New();
+    t = PyInt_FromLong(param->svm_type);
+    PyDict_SetItemString(o, "svm_type", t); Py_XDECREF(t);
+    t = PyInt_FromLong(param->kernel_type);
+    PyDict_SetItemString(o, "kernel_type", t); Py_XDECREF(t);
+    
+    if(param->kernel_type == POLY) {
+      t =	PyFloat_FromDouble(param->degree);
+      PyDict_SetItemString(o, "degree", t); Py_XDECREF(t);
+    }
+    
+    if(param->kernel_type == POLY || param->kernel_type == RBF || param->kernel_type == SIGMOID) {
+      t = PyFloat_FromDouble(param->gamma);
+      PyDict_SetItemString(o, "gamma", t); Py_XDECREF(t);
+    }
+    
+    if(param->kernel_type == POLY || param->kernel_type == SIGMOID) {
+      t = PyFloat_FromDouble(param->coef0);
+      PyDict_SetItemString(o, "coef0", t); Py_XDECREF(t);
+    }
+    
+    nr_class = model->nr_class;
+    l = model->l;
+    
+    t = PyInt_FromLong(nr_class);
+    PyDict_SetItemString(o, "nr_class", t); Py_XDECREF(t);
+    t = PyInt_FromLong(l);
+    PyDict_SetItemString(o, "total_sv", t); Py_XDECREF(t);
+    
+    {
+      t = PyList_New(nr_class*(nr_class-1)/2);
+      for(i=0;i<nr_class*(nr_class-1)/2;i++) {
+        PyList_SetItem(t, i, PyFloat_FromDouble(model->rho[i]));
+      }
+      PyDict_SetItemString(o, "rho", t); Py_XDECREF(t);
+    }
+    
+    if(model->probA) {
+      t = PyList_New(nr_class*(nr_class-1)/2);
+      for(i=0;i<nr_class*(nr_class-1)/2;i++) {
+        PyList_SetItem(t, i, PyFloat_FromDouble(model->probA[i]));
+      }
+      PyDict_SetItemString(o, "ProbA", t); Py_XDECREF(t);
+    }
+    
+    if(model->probB) {
+      t = PyList_New(nr_class*(nr_class-1)/2);
+      for(i=0;i<nr_class*(nr_class-1)/2;i++) {
+        PyList_SetItem(t, i, PyFloat_FromDouble(model->probB[i]));
+      }
+      PyDict_SetItemString(o, "ProbB", t); Py_XDECREF(t);
+    }
+    
+    if(model->label) {
+      t = PyList_New(nr_class);
+      for(i=0;i<nr_class;i++) {
+        PyList_SetItem(t, i, PyInt_FromLong(model->label[i]));
+      }
+      PyDict_SetItemString(o, "label", t); Py_XDECREF(t);
+    }
+    
+    
+    if(model->nSV) {
+      t = PyList_New(nr_class);
+      for(i=0;i<nr_class;i++) {
+        PyList_SetItem(t, i, PyInt_FromLong(model->nSV[i]));
+      }
+      PyDict_SetItemString(o, "nr_sv", t); Py_XDECREF(t);
+    }
+    
+    
+    sv_coef = model->sv_coef;
+    SV = model->SV;
+    
+    p = PyList_New(l);
+    ip = PyList_New(l);
+    elements = l; // terminals
+    for(i=0;i<l;i++)
+    {
+      const struct svm_node *pp;
+      PyObject *zz;
+      
+      t = PyList_New(nr_class-1);
+      for(j=0;j<nr_class-1;j++) {
+        PyList_SetItem(t, j, PyFloat_FromDouble(model->sv_coef[j][i]));
+      }
+      
+      // count attributes
+      pp = SV[i];
+      PyList_SetItem(ip, i, PyInt_FromLong(model->SVidx[i])); // save the SV index
+      j = 1;
+      while(pp->index != -1)
+      {
+        pp++; ++j;
+      }
+      
+      // allocate
+      zz = PyList_New(j);
+      PyList_SetItem(zz, 0, t); // sv_coef is first
+      
+      pp = SV[i];
+      j = 0;
+      while(pp->index != -1)
+      {
+        t = PyTuple_New(2);
+        PyTuple_SetItem(t,0,PyInt_FromLong(pp->index));
+        PyTuple_SetItem(t,1,PyFloat_FromDouble(pp->value));
+        pp++; ++j; ++elements;
+        PyList_SetItem(zz,j,t);
+      }
+      
+      PyList_SetItem(p,i,zz);
+    }
+    PyDict_SetItemString(o, "SV", p); Py_XDECREF(p);
+    PyDict_SetItemString(o, "SVi", ip); Py_XDECREF(ip);
+    
+    //  printf("svmo:2\n");
+    t = PyInt_FromLong(elements);
+    PyDict_SetItemString(o, "elements", t); Py_XDECREF(t);
+    svm_destroy_model(result->m);
+    free(result->prob->x);	
+    free(result->prob->y);	
+    free(result->prob);	
+    free(result->x_space);	
+    free(result);
+    resultobj = o;
+  }
+  {
+    if(arg1 != NULL) {
+      int i;
+      for (i = 0; i < arg1->nn; ++i) {
+        if(arg1->lengths[i] > 0) {
+          free((double*)arg1->value[i]);
+          free((int*)arg1->index[i]);
+        }
+      }
+      free((double**) arg1->value);
+      free((int**) arg1->index);
+      free((double*) arg1->label);
+      free((int*) arg1->lengths);
+      free((TSVMSparseInput*) arg1);
+    }
+  }
   {
     if (arg15 != NULL)
     free((double *) arg15);
   return resultobj;
 fail:
   {
+    if(arg1 != NULL) {
+      int i;
+      for (i = 0; i < arg1->nn; ++i) {
+        if(arg1->lengths[i] > 0) {
+          free((double*)arg1->value[i]);
+          free((int*)arg1->index[i]);
+        }
+      }
+      free((double**) arg1->value);
+      free((int**) arg1->index);
+      free((double*) arg1->label);
+      free((int*) arg1->lengths);
+      free((TSVMSparseInput*) arg1);
+    }
+  }
+  {
     if (arg15 != NULL)
     free((double *) arg15);
   }
 
 SWIGINTERN PyObject *_wrap_SVMLearn(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  SVMInput *arg1 = (SVMInput *) 0 ;
+  TSVMInput *arg1 = (TSVMInput *) 0 ;
   int arg2 ;
   int arg3 ;
   double arg4 ;
   int arg14 ;
   double *arg15 = (double *) 0 ;
   int *arg16 = (int *) 0 ;
-  wsvm_model *result = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
+  Twsvm_model *result = 0 ;
   int val2 ;
   int ecode2 = 0 ;
   int val3 ;
   PyObject * obj15 = 0 ;
   
   {
+    arg1 = NULL;
+  }
+  {
     arg15 = NULL;
   }
   {
     arg16 = NULL;
   }
   if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOOOOOOOO:SVMLearn",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9,&obj10,&obj11,&obj12,&obj13,&obj14,&obj15)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SVMInput, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SVMLearn" "', argument " "1"" of type '" "SVMInput *""'"); 
-  }
-  arg1 = reinterpret_cast< SVMInput * >(argp1);
+  {
+    /* Check if is a list */
+    if (PyList_Check(obj0)) {
+      int i, j, k, size, msize;
+      
+      size = PyList_Size(obj0);
+      msize = 0;
+      
+      arg1 = (TSVMInput *) malloc(sizeof(TSVMInput));
+      arg1->data = NULL;
+      arg1->masking = NULL;
+      arg1->label = NULL;
+      for (i = 0; i < size; i++) {
+        PyObject *o = PyList_GetItem(obj0,i);
+        if (PyList_Check(o)) {
+          int zsize = PyList_Size(o);
+          if (arg1->data == NULL) {
+            msize = zsize;
+            arg1->nn = size;
+            arg1->k = msize-1;
+            arg1->total = (arg1->nn)*(msize-1+1); // size correction, last is class
+            arg1->masking = (char **)malloc(sizeof(char *)*(size+1));
+            for (j = 0; j <= size; ++j) {
+              arg1->masking[j] = (char *)malloc(sizeof(char)*(arg1->k+1));
+              for (k = 0; k <= arg1->k; ++k) {
+                arg1->masking[j][k] = 0;
+              }
+            }
+            arg1->data = (double **)malloc(sizeof(double *)*(size+1));
+            for (j = 0; j <= size; ++j) {
+              arg1->data[j] = (double *)malloc(sizeof(double)*(arg1->k+1));
+            }
+            arg1->label = (double *)malloc(sizeof(double)*(arg1->nn+1));
+          }
+          if (zsize == msize) {
+            // fetch the class (must be binary)
+            PyObject *p = PyList_GetItem(o,zsize-1);
+            if (p == NULL) {
+              PyErr_SetString(PyExc_TypeError,"cannot fetch example");
+              SVMcleanup(arg1);
+              return NULL;
+            }
+            
+            if (PyInt_Check(p) || PyLong_Check(p)) {
+              arg1->label[i] = (double)PyInt_AsLong(p);
+            } else if(PyFloat_Check(p)) {
+              arg1->label[i] = PyFloat_AsDouble(p);
+            } else {
+              PyErr_SetString(PyExc_TypeError,"class not float or int");
+              SVMcleanup(arg1);
+              return NULL;
+            }
+            
+            // fetch the attribute values
+            for (j = 0; j < zsize-1; ++j) {
+              PyObject *p = PyList_GetItem(o,j);
+              
+              if(PyTuple_Check(p)) {
+                PyObject *ps = PyTuple_GetItem(p,1); // masking
+                if (PyInt_Check(ps) || PyLong_Check(ps)) {
+                  arg1->masking[i][j] = (char)PyInt_AsLong(ps);
+                } else if(PyFloat_Check(ps)) {
+                  arg1->masking[i][j] = (char)PyFloat_AsDouble(ps);
+                } else {
+                  PyErr_SetString(PyExc_TypeError,"masking not 1 or 0");
+                  SVMcleanup(arg1);
+                  return NULL;
+                }
+                p = PyTuple_GetItem(p,0); // foist value
+              }
+              if (PyFloat_Check(p)) {
+                // correct +1 because that array starts at 1
+                arg1->data[i][j] = PyFloat_AsDouble(p);
+              } else if (PyInt_Check(p)) {
+                arg1->data[i][j] = (double)PyInt_AsLong(p);
+              } else {
+                PyErr_SetString(PyExc_TypeError,"examples must contain doubles or ints. if masking, use tuples");
+                SVMcleanup(arg1);
+                return NULL;
+              }
+            }
+          } else {
+            PyErr_SetString(PyExc_TypeError,"examples must be of equal size");
+            SVMcleanup(arg1);
+            return NULL;
+          }
+        } else {
+          PyErr_SetString(PyExc_TypeError,"example table must contain examples as lists");
+          SVMcleanup(arg1);
+          return NULL;
+        }
+      }
+    } else {
+      PyErr_SetString(PyExc_TypeError,"not a list");
+      return NULL;
+    }
+    //("svmi:done\n");
+  }
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
     SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SVMLearn" "', argument " "2"" of type '" "int""'");
       return NULL;
     }
   }
-  result = (wsvm_model *)SVMLearn(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13,arg14,arg15,arg16);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_wsvm_model, 0 |  0 );
+  result = (Twsvm_model *)SVMLearn(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13,arg14,arg15,arg16);
+  {
+    struct svm_parameter *param = &(result->m->param);
+    double **sv_coef;
+    struct svm_node **SV;
+    Tsvm_model *model = result->m;
+    int i, j, nr_class, l, elements;
+    PyObject *o, *t, *p, *ip;
+    
+    o = PyDict_New();
+    t = PyInt_FromLong(param->svm_type);
+    PyDict_SetItemString(o, "svm_type", t); Py_XDECREF(t);
+    t = PyInt_FromLong(param->kernel_type);
+    PyDict_SetItemString(o, "kernel_type", t); Py_XDECREF(t);
+    
+    if(param->kernel_type == POLY) {
+      t =	PyFloat_FromDouble(param->degree);
+      PyDict_SetItemString(o, "degree", t); Py_XDECREF(t);
+    }
+    
+    if(param->kernel_type == POLY || param->kernel_type == RBF || param->kernel_type == SIGMOID) {
+      t = PyFloat_FromDouble(param->gamma);
+      PyDict_SetItemString(o, "gamma", t); Py_XDECREF(t);
+    }
+    
+    if(param->kernel_type == POLY || param->kernel_type == SIGMOID) {
+      t = PyFloat_FromDouble(param->coef0);
+      PyDict_SetItemString(o, "coef0", t); Py_XDECREF(t);
+    }
+    
+    nr_class = model->nr_class;
+    l = model->l;
+    
+    t = PyInt_FromLong(nr_class);
+    PyDict_SetItemString(o, "nr_class", t); Py_XDECREF(t);
+    t = PyInt_FromLong(l);
+    PyDict_SetItemString(o, "total_sv", t); Py_XDECREF(t);
+    
+    {
+      t = PyList_New(nr_class*(nr_class-1)/2);
+      for(i=0;i<nr_class*(nr_class-1)/2;i++) {
+        PyList_SetItem(t, i, PyFloat_FromDouble(model->rho[i]));
+      }
+      PyDict_SetItemString(o, "rho", t); Py_XDECREF(t);
+    }
+    
+    if(model->probA) {
+      t = PyList_New(nr_class*(nr_class-1)/2);
+      for(i=0;i<nr_class*(nr_class-1)/2;i++) {
+        PyList_SetItem(t, i, PyFloat_FromDouble(model->probA[i]));
+      }
+      PyDict_SetItemString(o, "ProbA", t); Py_XDECREF(t);
+    }
+    
+    if(model->probB) {
+      t = PyList_New(nr_class*(nr_class-1)/2);
+      for(i=0;i<nr_class*(nr_class-1)/2;i++) {
+        PyList_SetItem(t, i, PyFloat_FromDouble(model->probB[i]));
+      }
+      PyDict_SetItemString(o, "ProbB", t); Py_XDECREF(t);
+    }
+    
+    if(model->label) {
+      t = PyList_New(nr_class);
+      for(i=0;i<nr_class;i++) {
+        PyList_SetItem(t, i, PyInt_FromLong(model->label[i]));
+      }
+      PyDict_SetItemString(o, "label", t); Py_XDECREF(t);
+    }
+    
+    
+    if(model->nSV) {
+      t = PyList_New(nr_class);
+      for(i=0;i<nr_class;i++) {
+        PyList_SetItem(t, i, PyInt_FromLong(model->nSV[i]));
+      }
+      PyDict_SetItemString(o, "nr_sv", t); Py_XDECREF(t);
+    }
+    
+    
+    sv_coef = model->sv_coef;
+    SV = model->SV;
+    
+    p = PyList_New(l);
+    ip = PyList_New(l);
+    elements = l; // terminals
+    for(i=0;i<l;i++)
+    {
+      const struct svm_node *pp;
+      PyObject *zz;
+      
+      t = PyList_New(nr_class-1);
+      for(j=0;j<nr_class-1;j++) {
+        PyList_SetItem(t, j, PyFloat_FromDouble(model->sv_coef[j][i]));
+      }
+      
+      // count attributes
+      pp = SV[i];
+      PyList_SetItem(ip, i, PyInt_FromLong(model->SVidx[i])); // save the SV index
+      j = 1;
+      while(pp->index != -1)
+      {
+        pp++; ++j;
+      }
+      
+      // allocate
+      zz = PyList_New(j);
+      PyList_SetItem(zz, 0, t); // sv_coef is first
+      
+      pp = SV[i];
+      j = 0;
+      while(pp->index != -1)
+      {
+        t = PyTuple_New(2);
+        PyTuple_SetItem(t,0,PyInt_FromLong(pp->index));
+        PyTuple_SetItem(t,1,PyFloat_FromDouble(pp->value));
+        pp++; ++j; ++elements;
+        PyList_SetItem(zz,j,t);
+      }
+      
+      PyList_SetItem(p,i,zz);
+    }
+    PyDict_SetItemString(o, "SV", p); Py_XDECREF(p);
+    PyDict_SetItemString(o, "SVi", ip); Py_XDECREF(ip);
+    
+    //  printf("svmo:2\n");
+    t = PyInt_FromLong(elements);
+    PyDict_SetItemString(o, "elements", t); Py_XDECREF(t);
+    svm_destroy_model(result->m);
+    free(result->prob->x);	
+    free(result->prob->y);	
+    free(result->prob);	
+    free(result->x_space);	
+    free(result);
+    resultobj = o;
+  }
+  {
+    if(arg1 != NULL) {
+      int i;
+      //printf("svmc:1\n");
+      for (i = 0; i <= arg1->nn; ++i) {
+        free((double*)arg1->data[i]);
+        free((char*)arg1->masking[i]);
+      }
+      free((double**) arg1->data);
+      free((char**) arg1->masking);
+      free((double*) arg1->label);
+      free((TSVMInput*) arg1);
+      //("svmc:2\n");
+    }
+  }
   {
     if (arg15 != NULL)
     free((double *) arg15);
   return resultobj;
 fail:
   {
+    if(arg1 != NULL) {
+      int i;
+      //printf("svmc:1\n");
+      for (i = 0; i <= arg1->nn; ++i) {
+        free((double*)arg1->data[i]);
+        free((char*)arg1->masking[i]);
+      }
+      free((double**) arg1->data);
+      free((char**) arg1->masking);
+      free((double*) arg1->label);
+      free((TSVMInput*) arg1);
+      //("svmc:2\n");
+    }
+  }
+  {
     if (arg15 != NULL)
     free((double *) arg15);
   }
 SWIGINTERN PyObject *_wrap_SVMClassify(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   psvm_model arg1 ;
-  SVMExample *arg2 = (SVMExample *) 0 ;
+  TSVMExample *arg2 = (TSVMExample *) 0 ;
   double result;
   void *argp1 ;
   int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
+  {
+    arg2 = NULL;
+  }
   if (!PyArg_ParseTuple(args,(char *)"OO:SVMClassify",&obj0,&obj1)) SWIG_fail;
   {
     res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_psvm_model,  0  | 0);
       if (SWIG_IsNewObj(res1)) delete temp;
     }
   }
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_SVMExample, 0 |  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SVMClassify" "', argument " "2"" of type '" "SVMExample *""'"); 
-  }
-  arg2 = reinterpret_cast< SVMExample * >(argp2);
+  {
+    /* Check if is a list */
+    if (PyList_Check(obj1)) {
+      int j, msize;
+      
+      msize = PyList_Size(obj1);
+      
+      arg2 = (TSVMExample *)malloc(sizeof(TSVMExample));
+      arg2->k = msize;
+      arg2->data    = (double *)malloc(sizeof(double)*msize);
+      arg2->masking = (char *)malloc(sizeof(char)*msize);
+      
+      // fetch the attribute values
+      for (j = 0; j < msize; ++j) {
+        PyObject *p = PyList_GetItem(obj1,j);
+        
+        arg2->masking[j] = 0;
+        if(PyTuple_Check(p)) {
+          arg2->masking[j] = 1;
+          p = PyTuple_GetItem(p,0); // foist value
+        }
+        if (PyFloat_Check(p)) {
+          arg2->data[j] = PyFloat_AsDouble(p);
+        } else if (PyInt_Check(p)) {
+          arg2->data[j] = (double)PyInt_AsLong(p);
+        } else {
+          PyErr_SetString(PyExc_TypeError,"examples must contain doubles or ints. if masking, use tuples");
+          SVMexcleanup(arg2);
+          return NULL;
+        }
+      }
+    } else {
+      PyErr_SetString(PyExc_TypeError,"not a list");
+      return NULL;
+    }
+  }
   result = (double)SVMClassify(arg1,arg2);
   resultobj = SWIG_From_double(static_cast< double >(result));
+  {
+    if (arg2 != NULL) {
+      free((double*) arg2->data);
+      free((char*) arg2->masking);
+      free((TSVMExample*) arg2);
+    }
+  }
   return resultobj;
 fail:
+  {
+    if (arg2 != NULL) {
+      free((double*) arg2->data);
+      free((char*) arg2->masking);
+      free((TSVMExample*) arg2);
+    }
+  }
   return NULL;
 }
 
 SWIGINTERN PyObject *_wrap_SVMClassifyP(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   psvm_model arg1 ;
-  SVMExample *arg2 = (SVMExample *) 0 ;
-  SVMOut *arg3 = (SVMOut *) 0 ;
+  TSVMExample *arg2 = (TSVMExample *) 0 ;
+  TSVMOut *arg3 = (TSVMOut *) 0 ;
   void *argp1 ;
   int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:SVMClassifyP",&obj0,&obj1,&obj2)) SWIG_fail;
+  {
+    arg2 = NULL;
+  }
+  {
+    arg3 = (TSVMOut *)malloc(sizeof(TSVMOut));
+  }
+  if (!PyArg_ParseTuple(args,(char *)"OO:SVMClassifyP",&obj0,&obj1)) SWIG_fail;
   {
     res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_psvm_model,  0  | 0);
     if (!SWIG_IsOK(res1)) {
       if (SWIG_IsNewObj(res1)) delete temp;
     }
   }
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_SVMExample, 0 |  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SVMClassifyP" "', argument " "2"" of type '" "SVMExample *""'"); 
-  }
-  arg2 = reinterpret_cast< SVMExample * >(argp2);
-  res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_SVMOut, 0 |  0 );
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "SVMClassifyP" "', argument " "3"" of type '" "SVMOut *""'"); 
-  }
-  arg3 = reinterpret_cast< SVMOut * >(argp3);
+  {
+    /* Check if is a list */
+    if (PyList_Check(obj1)) {
+      int j, msize;
+      
+      msize = PyList_Size(obj1);
+      
+      arg2 = (TSVMExample *)malloc(sizeof(TSVMExample));
+      arg2->k = msize;
+      arg2->data    = (double *)malloc(sizeof(double)*msize);
+      arg2->masking = (char *)malloc(sizeof(char)*msize);
+      
+      // fetch the attribute values
+      for (j = 0; j < msize; ++j) {
+        PyObject *p = PyList_GetItem(obj1,j);
+        
+        arg2->masking[j] = 0;
+        if(PyTuple_Check(p)) {
+          arg2->masking[j] = 1;
+          p = PyTuple_GetItem(p,0); // foist value
+        }
+        if (PyFloat_Check(p)) {
+          arg2->data[j] = PyFloat_AsDouble(p);
+        } else if (PyInt_Check(p)) {
+          arg2->data[j] = (double)PyInt_AsLong(p);
+        } else {
+          PyErr_SetString(PyExc_TypeError,"examples must contain doubles or ints. if masking, use tuples");
+          SVMexcleanup(arg2);
+          return NULL;
+        }
+      }
+    } else {
+      PyErr_SetString(PyExc_TypeError,"not a list");
+      return NULL;
+    }
+  }
   SVMClassifyP(arg1,arg2,arg3);
   resultobj = SWIG_Py_Void();
+  {
+    int i;
+    PyObject *o, *q;
+    
+    o = PyList_New(arg3->nn);
+    
+    for(i = 0; i < arg3->nn; ++i) {
+      q = PyFloat_FromDouble(arg3->v[i]);
+      PyList_SetItem(o, i, q);
+    }
+    free(arg3->v);
+    free(arg3);
+    if ((!resultobj) || (resultobj == Py_None)) {
+      resultobj = o;
+    } else {
+      if (!PyList_Check(resultobj)) {
+        PyObject *o2 = resultobj;
+        resultobj = PyList_New(0);
+        PyList_Append(resultobj,o2);
+        Py_XDECREF(o2);
+      }
+      PyList_Append(resultobj,o);
+      Py_XDECREF(o);
+    }
+  }
+  {
+    if (arg2 != NULL) {
+      free((double*) arg2->data);
+      free((char*) arg2->masking);
+      free((TSVMExample*) arg2);
+    }
+  }
   return resultobj;
 fail:
+  {
+    if (arg2 != NULL) {
+      free((double*) arg2->data);
+      free((char*) arg2->masking);
+      free((TSVMExample*) arg2);
+    }
+  }
   return NULL;
 }
 
 SWIGINTERN PyObject *_wrap_SVMClassifyM(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   psvm_model arg1 ;
-  SVMExample *arg2 = (SVMExample *) 0 ;
-  SVMOut *arg3 = (SVMOut *) 0 ;
+  TSVMExample *arg2 = (TSVMExample *) 0 ;
+  TSVMOut *arg3 = (TSVMOut *) 0 ;
   void *argp1 ;
   int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:SVMClassifyM",&obj0,&obj1,&obj2)) SWIG_fail;
+  {
+    arg2 = NULL;
+  }
+  {
+    arg3 = (TSVMOut *)malloc(sizeof(TSVMOut));
+  }
+  if (!PyArg_ParseTuple(args,(char *)"OO:SVMClassifyM",&obj0,&obj1)) SWIG_fail;
   {
     res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_psvm_model,  0  | 0);
     if (!SWIG_IsOK(res1)) {
       if (SWIG_IsNewObj(res1)) delete temp;
     }
   }
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_SVMExample, 0 |  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SVMClassifyM" "', argument " "2"" of type '" "SVMExample *""'"); 
-  }
-  arg2 = reinterpret_cast< SVMExample * >(argp2);
-  res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_SVMOut, 0 |  0 );
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "SVMClassifyM" "', argument " "3"" of type '" "SVMOut *""'"); 
-  }
-  arg3 = reinterpret_cast< SVMOut * >(argp3);
+  {
+    /* Check if is a list */
+    if (PyList_Check(obj1)) {
+      int j, msize;
+      
+      msize = PyList_Size(obj1);
+      
+      arg2 = (TSVMExample *)malloc(sizeof(TSVMExample));
+      arg2->k = msize;
+      arg2->data    = (double *)malloc(sizeof(double)*msize);
+      arg2->masking = (char *)malloc(sizeof(char)*msize);
+      
+      // fetch the attribute values
+      for (j = 0; j < msize; ++j) {
+        PyObject *p = PyList_GetItem(obj1,j);
+        
+        arg2->masking[j] = 0;
+        if(PyTuple_Check(p)) {
+          arg2->masking[j] = 1;
+          p = PyTuple_GetItem(p,0); // foist value
+        }
+        if (PyFloat_Check(p)) {
+          arg2->data[j] = PyFloat_AsDouble(p);
+        } else if (PyInt_Check(p)) {
+          arg2->data[j] = (double)PyInt_AsLong(p);
+        } else {
+          PyErr_SetString(PyExc_TypeError,"examples must contain doubles or ints. if masking, use tuples");
+          SVMexcleanup(arg2);
+          return NULL;
+        }
+      }
+    } else {
+      PyErr_SetString(PyExc_TypeError,"not a list");
+      return NULL;
+    }
+  }
   SVMClassifyM(arg1,arg2,arg3);
   resultobj = SWIG_Py_Void();
+  {
+    int i;
+    PyObject *o, *q;
+    
+    o = PyList_New(arg3->nn);
+    
+    for(i = 0; i < arg3->nn; ++i) {
+      q = PyFloat_FromDouble(arg3->v[i]);
+      PyList_SetItem(o, i, q);
+    }
+    free(arg3->v);
+    free(arg3);
+    if ((!resultobj) || (resultobj == Py_None)) {
+      resultobj = o;
+    } else {
+      if (!PyList_Check(resultobj)) {
+        PyObject *o2 = resultobj;
+        resultobj = PyList_New(0);
+        PyList_Append(resultobj,o2);
+        Py_XDECREF(o2);
+      }
+      PyList_Append(resultobj,o);
+      Py_XDECREF(o);
+    }
+  }
+  {
+    if (arg2 != NULL) {
+      free((double*) arg2->data);
+      free((char*) arg2->masking);
+      free((TSVMExample*) arg2);
+    }
+  }
   return resultobj;
 fail:
+  {
+    if (arg2 != NULL) {
+      free((double*) arg2->data);
+      free((char*) arg2->masking);
+      free((TSVMExample*) arg2);
+    }
+  }
   return NULL;
 }
 
 SWIGINTERN PyObject *_wrap_SVMClassifyS(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   psvm_model arg1 ;
-  SVMSparseExample *arg2 = (SVMSparseExample *) 0 ;
+  TSVMSparseExample *arg2 = (TSVMSparseExample *) 0 ;
   double result;
   void *argp1 ;
   int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
+  {
+    arg2 = NULL;
+  }
   if (!PyArg_ParseTuple(args,(char *)"OO:SVMClassifyS",&obj0,&obj1)) SWIG_fail;
   {
     res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_psvm_model,  0  | 0);
       if (SWIG_IsNewObj(res1)) delete temp;
     }
   }
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_SVMSparseExample, 0 |  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SVMClassifyS" "', argument " "2"" of type '" "SVMSparseExample *""'"); 
-  }
-  arg2 = reinterpret_cast< SVMSparseExample * >(argp2);
+  {
+    int nvals, i,j; 
+    /* Check if is a list */
+    if (PyList_Check(obj1)) {
+      nvals = PyList_Size(obj1);
+      arg2 = (SVMSparseExample *)malloc(sizeof(SVMSparseExample));
+      arg2->nn = nvals;
+      arg2->value = (double *)malloc((nvals)*sizeof(double));
+      arg2->index = (int *)malloc((nvals)*sizeof(int));
+      // fetch the attribute values
+      for (j = 0; j < nvals; ++j) {
+        PyObject *p = PyList_GetItem(obj1,j);
+        if(PyTuple_Check(p)) {
+          PyObject *idx = PyTuple_GetItem(p,0); 
+          PyObject *val = PyTuple_GetItem(p,1); 
+          if (PyInt_Check(idx) || PyLong_Check(idx)) {
+            arg2->index[j] = PyInt_AsLong(idx);
+          } else {
+            PyErr_SetString(PyExc_TypeError,"index not 1 or 0");
+            SVMsecleanup(arg2);
+            return NULL;
+          }
+          if (PyInt_Check(val) || PyLong_Check(val)) {
+            arg2->value[j] = (double)PyInt_AsLong(val);
+          } else if(PyFloat_Check(val)) {
+            arg2->value[j] = PyFloat_AsDouble(val);
+          }  else {
+            PyErr_SetString(PyExc_TypeError,"value not an integer or a float");
+            SVMsecleanup(arg2);
+            return NULL;
+          }
+        } else {
+          PyErr_SetString(PyExc_TypeError,"attribute values within an example must be tuples (index,value)");
+          SVMsecleanup(arg2);
+          return NULL;
+        }
+      } 
+    } else {
+      PyErr_SetString(PyExc_TypeError,"example must be a list of tuples");
+      SVMsecleanup(arg2);
+      return NULL;
+    }
+  }
   result = (double)SVMClassifyS(arg1,arg2);
   resultobj = SWIG_From_double(static_cast< double >(result));
+  {
+    if (arg2 != NULL) {
+      free((double*) arg2->value);
+      free((int *) arg2->index);
+      free((TSVMSparseExample*) arg2);
+    }
+  }
   return resultobj;
 fail:
+  {
+    if (arg2 != NULL) {
+      free((double*) arg2->value);
+      free((int *) arg2->index);
+      free((TSVMSparseExample*) arg2);
+    }
+  }
   return NULL;
 }
 
 SWIGINTERN PyObject *_wrap_SVMClassifyPS(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   psvm_model arg1 ;
-  SVMSparseExample *arg2 = (SVMSparseExample *) 0 ;
-  SVMOut *arg3 = (SVMOut *) 0 ;
+  TSVMSparseExample *arg2 = (TSVMSparseExample *) 0 ;
+  TSVMOut *arg3 = (TSVMOut *) 0 ;
   void *argp1 ;
   int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:SVMClassifyPS",&obj0,&obj1,&obj2)) SWIG_fail;
+  {
+    arg2 = NULL;
+  }
+  {
+    arg3 = (TSVMOut *)malloc(sizeof(TSVMOut));
+  }
+  if (!PyArg_ParseTuple(args,(char *)"OO:SVMClassifyPS",&obj0,&obj1)) SWIG_fail;
   {
     res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_psvm_model,  0  | 0);
     if (!SWIG_IsOK(res1)) {
       if (SWIG_IsNewObj(res1)) delete temp;
     }
   }
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_SVMSparseExample, 0 |  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SVMClassifyPS" "', argument " "2"" of type '" "SVMSparseExample *""'"); 
-  }
-  arg2 = reinterpret_cast< SVMSparseExample * >(argp2);
-  res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_SVMOut, 0 |  0 );
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "SVMClassifyPS" "', argument " "3"" of type '" "SVMOut *""'"); 
-  }
-  arg3 = reinterpret_cast< SVMOut * >(argp3);
+  {
+    int nvals, i,j; 
+    /* Check if is a list */
+    if (PyList_Check(obj1)) {
+      nvals = PyList_Size(obj1);
+      arg2 = (SVMSparseExample *)malloc(sizeof(SVMSparseExample));
+      arg2->nn = nvals;
+      arg2->value = (double *)malloc((nvals)*sizeof(double));
+      arg2->index = (int *)malloc((nvals)*sizeof(int));
+      // fetch the attribute values
+      for (j = 0; j < nvals; ++j) {
+        PyObject *p = PyList_GetItem(obj1,j);
+        if(PyTuple_Check(p)) {
+          PyObject *idx = PyTuple_GetItem(p,0); 
+          PyObject *val = PyTuple_GetItem(p,1); 
+          if (PyInt_Check(idx) || PyLong_Check(idx)) {
+            arg2->index[j] = PyInt_AsLong(idx);
+          } else {
+            PyErr_SetString(PyExc_TypeError,"index not 1 or 0");
+            SVMsecleanup(arg2);
+            return NULL;
+          }
+          if (PyInt_Check(val) || PyLong_Check(val)) {
+            arg2->value[j] = (double)PyInt_AsLong(val);
+          } else if(PyFloat_Check(val)) {
+            arg2->value[j] = PyFloat_AsDouble(val);
+          }  else {
+            PyErr_SetString(PyExc_TypeError,"value not an integer or a float");
+            SVMsecleanup(arg2);
+            return NULL;
+          }
+        } else {
+          PyErr_SetString(PyExc_TypeError,"attribute values within an example must be tuples (index,value)");
+          SVMsecleanup(arg2);
+          return NULL;
+        }
+      } 
+    } else {
+      PyErr_SetString(PyExc_TypeError,"example must be a list of tuples");
+      SVMsecleanup(arg2);
+      return NULL;
+    }
+  }
   SVMClassifyPS(arg1,arg2,arg3);
   resultobj = SWIG_Py_Void();
+  {
+    int i;
+    PyObject *o, *q;
+    
+    o = PyList_New(arg3->nn);
+    
+    for(i = 0; i < arg3->nn; ++i) {
+      q = PyFloat_FromDouble(arg3->v[i]);
+      PyList_SetItem(o, i, q);
+    }
+    free(arg3->v);
+    free(arg3);
+    if ((!resultobj) || (resultobj == Py_None)) {
+      resultobj = o;
+    } else {
+      if (!PyList_Check(resultobj)) {
+        PyObject *o2 = resultobj;
+        resultobj = PyList_New(0);
+        PyList_Append(resultobj,o2);
+        Py_XDECREF(o2);
+      }
+      PyList_Append(resultobj,o);
+      Py_XDECREF(o);
+    }
+  }
+  {
+    if (arg2 != NULL) {
+      free((double*) arg2->value);
+      free((int *) arg2->index);
+      free((TSVMSparseExample*) arg2);
+    }
+  }
   return resultobj;
 fail:
+  {
+    if (arg2 != NULL) {
+      free((double*) arg2->value);
+      free((int *) arg2->index);
+      free((TSVMSparseExample*) arg2);
+    }
+  }
   return NULL;
 }
 
 SWIGINTERN PyObject *_wrap_SVMClassifyMS(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   psvm_model arg1 ;
-  SVMSparseExample *arg2 = (SVMSparseExample *) 0 ;
-  SVMOut *arg3 = (SVMOut *) 0 ;
+  TSVMSparseExample *arg2 = (TSVMSparseExample *) 0 ;
+  TSVMOut *arg3 = (TSVMOut *) 0 ;
   void *argp1 ;
   int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:SVMClassifyMS",&obj0,&obj1,&obj2)) SWIG_fail;
+  {
+    arg2 = NULL;
+  }
+  {
+    arg3 = (TSVMOut *)malloc(sizeof(TSVMOut));
+  }
+  if (!PyArg_ParseTuple(args,(char *)"OO:SVMClassifyMS",&obj0,&obj1)) SWIG_fail;
   {
     res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_psvm_model,  0  | 0);
     if (!SWIG_IsOK(res1)) {
       if (SWIG_IsNewObj(res1)) delete temp;
     }
   }
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_SVMSparseExample, 0 |  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SVMClassifyMS" "', argument " "2"" of type '" "SVMSparseExample *""'"); 
-  }
-  arg2 = reinterpret_cast< SVMSparseExample * >(argp2);
-  res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_SVMOut, 0 |  0 );
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "SVMClassifyMS" "', argument " "3"" of type '" "SVMOut *""'"); 
-  }
-  arg3 = reinterpret_cast< SVMOut * >(argp3);
+  {
+    int nvals, i,j; 
+    /* Check if is a list */
+    if (PyList_Check(obj1)) {
+      nvals = PyList_Size(obj1);
+      arg2 = (SVMSparseExample *)malloc(sizeof(SVMSparseExample));
+      arg2->nn = nvals;
+      arg2->value = (double *)malloc((nvals)*sizeof(double));
+      arg2->index = (int *)malloc((nvals)*sizeof(int));
+      // fetch the attribute values
+      for (j = 0; j < nvals; ++j) {
+        PyObject *p = PyList_GetItem(obj1,j);
+        if(PyTuple_Check(p)) {
+          PyObject *idx = PyTuple_GetItem(p,0); 
+          PyObject *val = PyTuple_GetItem(p,1); 
+          if (PyInt_Check(idx) || PyLong_Check(idx)) {
+            arg2->index[j] = PyInt_AsLong(idx);
+          } else {
+            PyErr_SetString(PyExc_TypeError,"index not 1 or 0");
+            SVMsecleanup(arg2);
+            return NULL;
+          }
+          if (PyInt_Check(val) || PyLong_Check(val)) {
+            arg2->value[j] = (double)PyInt_AsLong(val);
+          } else if(PyFloat_Check(val)) {
+            arg2->value[j] = PyFloat_AsDouble(val);
+          }  else {
+            PyErr_SetString(PyExc_TypeError,"value not an integer or a float");
+            SVMsecleanup(arg2);
+            return NULL;
+          }
+        } else {
+          PyErr_SetString(PyExc_TypeError,"attribute values within an example must be tuples (index,value)");
+          SVMsecleanup(arg2);
+          return NULL;
+        }
+      } 
+    } else {
+      PyErr_SetString(PyExc_TypeError,"example must be a list of tuples");
+      SVMsecleanup(arg2);
+      return NULL;
+    }
+  }
   SVMClassifyMS(arg1,arg2,arg3);
   resultobj = SWIG_Py_Void();
+  {
+    int i;
+    PyObject *o, *q;
+    
+    o = PyList_New(arg3->nn);
+    
+    for(i = 0; i < arg3->nn; ++i) {
+      q = PyFloat_FromDouble(arg3->v[i]);
+      PyList_SetItem(o, i, q);
+    }
+    free(arg3->v);
+    free(arg3);
+    if ((!resultobj) || (resultobj == Py_None)) {
+      resultobj = o;
+    } else {
+      if (!PyList_Check(resultobj)) {
+        PyObject *o2 = resultobj;
+        resultobj = PyList_New(0);
+        PyList_Append(resultobj,o2);
+        Py_XDECREF(o2);
+      }
+      PyList_Append(resultobj,o);
+      Py_XDECREF(o);
+    }
+  }
+  {
+    if (arg2 != NULL) {
+      free((double*) arg2->value);
+      free((int *) arg2->index);
+      free((TSVMSparseExample*) arg2);
+    }
+  }
   return resultobj;
 fail:
+  {
+    if (arg2 != NULL) {
+      free((double*) arg2->value);
+      free((int *) arg2->index);
+      free((TSVMSparseExample*) arg2);
+    }
+  }
   return NULL;
 }
 
 
 SWIGINTERN PyObject *_wrap_MCluster(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  CInput *arg1 = (CInput *) 0 ;
+  TCInput *arg1 = (TCInput *) 0 ;
   long arg2 ;
   int arg3 ;
-  CMInfo *arg4 = (CMInfo *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
+  TCMInfo *arg4 = (TCMInfo *) 0 ;
   long val2 ;
   int ecode2 = 0 ;
   int val3 ;
   int ecode3 = 0 ;
-  void *argp4 = 0 ;
-  int res4 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:MCluster",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CInput, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MCluster" "', argument " "1"" of type '" "CInput *""'"); 
-  }
-  arg1 = reinterpret_cast< CInput * >(argp1);
+  {
+    arg1 = NULL;
+  }
+  {
+    arg4 = (TCMInfo *)malloc(sizeof(TCMInfo));
+  }
+  if (!PyArg_ParseTuple(args,(char *)"OOO:MCluster",&obj0,&obj1,&obj2)) SWIG_fail;
+  {
+    /* Check if is a list */
+    if (PyList_Check(obj0)) {
+      int i, j, size, msize;
+      
+      size = PyList_Size(obj0);
+      msize = 0;
+      
+      arg1 = (TCInput *) malloc(sizeof(TCInput));
+      arg1->data = NULL;
+      for (i = 0; i < size; i++) {
+        PyObject *o = PyList_GetItem(obj0,i);
+        if (PyList_Check(o)) {
+          int zsize = PyList_Size(o);
+          if (arg1->data == NULL) {
+            msize = zsize;
+            arg1->nn = size;
+            arg1->jpp = msize;
+            arg1->data = (double *)malloc(sizeof(double)*zsize*size);
+          }
+          if (zsize == msize) {
+            for (j = 0; j < zsize; ++j) {
+              PyObject *p = PyList_GetItem(o,j);
+              if (PyFloat_Check(p)) {
+                arg1->data[i+j*size] = PyFloat_AsDouble(p);
+              } else if (PyInt_Check(p)) {
+                arg1->data[i+j*size] = (double)PyInt_AsLong(p);
+              } else {
+                PyErr_SetString(PyExc_TypeError,"sublists must contain doubles");
+                if (arg1->data != NULL)
+                free(arg1->data);
+                free(arg1);
+                return NULL;
+              }
+            }
+          } else {
+            PyErr_SetString(PyExc_TypeError,"sublists must be of equal size");
+            if (arg1->data != NULL)
+            free(arg1->data);
+            free(arg1);
+            return NULL;
+          }
+        } else {
+          PyErr_SetString(PyExc_TypeError,"list must contain lists");
+          if (arg1->data != NULL)
+          free(arg1->data);
+          free(arg1);
+          return NULL;
+        }
+      }
+    } else {
+      PyErr_SetString(PyExc_TypeError,"not a list");
+      return NULL;
+    }
+  }
   ecode2 = SWIG_AsVal_long(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
     SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "MCluster" "', argument " "2"" of type '" "long""'");
     SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "MCluster" "', argument " "3"" of type '" "int""'");
   } 
   arg3 = static_cast< int >(val3);
-  res4 = SWIG_ConvertPtr(obj3, &argp4,SWIGTYPE_p_CMInfo, 0 |  0 );
-  if (!SWIG_IsOK(res4)) {
-    SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "MCluster" "', argument " "4"" of type '" "CMInfo *""'"); 
-  }
-  arg4 = reinterpret_cast< CMInfo * >(argp4);
   MCluster(arg1,arg2,arg3,arg4);
   resultobj = SWIG_Py_Void();
+  {
+    int i;
+    PyObject *o, *k, *cdisp, *disp, *n, *mapping, *medoids, *ll;
+    
+    o = PyTuple_New(6);
+    
+    n = PyInt_FromLong(arg4->n);
+    k = PyInt_FromLong(arg4->k);
+    disp = PyFloat_FromDouble(arg4->disp);
+    
+    mapping = PyList_New(arg4->n);
+    for (i = 0; i < arg4->n; ++i) {
+      ll = PyInt_FromLong(arg4->mapping[i]);
+      PyList_SetItem(mapping, i, ll);
+    }
+    medoids = PyList_New(arg4->k);
+    for (i = 0; i < arg4->k; ++i) {
+      ll = PyInt_FromLong(arg4->medoids[i]);
+      PyList_SetItem(medoids, i, ll);
+    }
+    cdisp = PyList_New(arg4->k);
+    for (i = 0; i < arg4->k; ++i) {
+      ll = PyFloat_FromDouble(arg4->cdisp[i]);
+      PyList_SetItem(cdisp, i, ll);
+    }
+    PyTuple_SetItem(o, 0, n);
+    PyTuple_SetItem(o, 1, k);
+    PyTuple_SetItem(o, 2, mapping);
+    PyTuple_SetItem(o, 3, medoids);
+    PyTuple_SetItem(o, 4, cdisp);
+    PyTuple_SetItem(o, 5, disp);
+    free(arg4->medoids);
+    free(arg4->cdisp);
+    free(arg4->mapping);
+    free(arg4);
+    
+    if ((!resultobj) || (resultobj == Py_None)) {
+      resultobj = o;
+    } else {
+      if (!PyList_Check(resultobj)) {
+        PyObject *o2 = resultobj;
+        resultobj = PyList_New(0);
+        PyList_Append(resultobj,o2);
+        Py_XDECREF(o2);
+      }
+      PyList_Append(resultobj,o);
+      Py_XDECREF(o);
+    }
+  }
+  {
+    if (arg1 != NULL) {
+      free((double*) arg1->data);
+      free((TCInput*) arg1);
+    }
+  }
   return resultobj;
 fail:
+  {
+    if (arg1 != NULL) {
+      free((double*) arg1->data);
+      free((TCInput*) arg1);
+    }
+  }
   return NULL;
 }
 
 
 SWIGINTERN PyObject *_wrap_HCluster(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  CInput *arg1 = (CInput *) 0 ;
+  TCInput *arg1 = (TCInput *) 0 ;
   int arg2 ;
   int arg3 ;
-  CHInfo *arg4 = (CHInfo *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
+  TCHInfo *arg4 = (TCHInfo *) 0 ;
   int val2 ;
   int ecode2 = 0 ;
   int val3 ;
   int ecode3 = 0 ;
-  void *argp4 = 0 ;
-  int res4 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:HCluster",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CInput, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "HCluster" "', argument " "1"" of type '" "CInput *""'"); 
-  }
-  arg1 = reinterpret_cast< CInput * >(argp1);
+  {
+    arg1 = NULL;
+  }
+  {
+    arg4 = (TCHInfo *)malloc(sizeof(TCHInfo));
+  }
+  if (!PyArg_ParseTuple(args,(char *)"OOO:HCluster",&obj0,&obj1,&obj2)) SWIG_fail;
+  {
+    /* Check if is a list */
+    if (PyList_Check(obj0)) {
+      int i, j, size, msize;
+      
+      size = PyList_Size(obj0);
+      msize = 0;
+      
+      arg1 = (TCInput *) malloc(sizeof(TCInput));
+      arg1->data = NULL;
+      for (i = 0; i < size; i++) {
+        PyObject *o = PyList_GetItem(obj0,i);
+        if (PyList_Check(o)) {
+          int zsize = PyList_Size(o);
+          if (arg1->data == NULL) {
+            msize = zsize;
+            arg1->nn = size;
+            arg1->jpp = msize;
+            arg1->data = (double *)malloc(sizeof(double)*zsize*size);
+          }
+          if (zsize == msize) {
+            for (j = 0; j < zsize; ++j) {
+              PyObject *p = PyList_GetItem(o,j);
+              if (PyFloat_Check(p)) {
+                arg1->data[i+j*size] = PyFloat_AsDouble(p);
+              } else if (PyInt_Check(p)) {
+                arg1->data[i+j*size] = (double)PyInt_AsLong(p);
+              } else {
+                PyErr_SetString(PyExc_TypeError,"sublists must contain doubles");
+                if (arg1->data != NULL)
+                free(arg1->data);
+                free(arg1);
+                return NULL;
+              }
+            }
+          } else {
+            PyErr_SetString(PyExc_TypeError,"sublists must be of equal size");
+            if (arg1->data != NULL)
+            free(arg1->data);
+            free(arg1);
+            return NULL;
+          }
+        } else {
+          PyErr_SetString(PyExc_TypeError,"list must contain lists");
+          if (arg1->data != NULL)
+          free(arg1->data);
+          free(arg1);
+          return NULL;
+        }
+      }
+    } else {
+      PyErr_SetString(PyExc_TypeError,"not a list");
+      return NULL;
+    }
+  }
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
     SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "HCluster" "', argument " "2"" of type '" "int""'");
     SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "HCluster" "', argument " "3"" of type '" "int""'");
   } 
   arg3 = static_cast< int >(val3);
-  res4 = SWIG_ConvertPtr(obj3, &argp4,SWIGTYPE_p_CHInfo, 0 |  0 );
-  if (!SWIG_IsOK(res4)) {
-    SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "HCluster" "', argument " "4"" of type '" "CHInfo *""'"); 
-  }
-  arg4 = reinterpret_cast< CHInfo * >(argp4);
   HCluster(arg1,arg2,arg3,arg4);
   resultobj = SWIG_Py_Void();
+  {
+    int i;
+    PyObject *o, *ac, *n, *height, *order, *merging, *ll;
+    
+    o = PyTuple_New(5);
+    n = PyInt_FromLong(arg4->n);
+    ac = PyFloat_FromDouble(arg4->ac);
+    merging = PyList_New((arg4->n-1)*2);
+    for (i = 0; i < (arg4->n-1)*2; ++i) {
+      ll = PyInt_FromLong(arg4->merging[i]);
+      PyList_SetItem(merging, i, ll);
+    }
+    order = PyList_New(arg4->n);
+    for (i = 0; i < arg4->n; ++i) {
+      ll = PyInt_FromLong(arg4->order[i]);
+      PyList_SetItem(order, i, ll);
+    }
+    height = PyList_New(arg4->n-1);
+    for (i = 0; i < arg4->n-1; ++i) {
+      ll = PyFloat_FromDouble(arg4->height[i+1]);
+      PyList_SetItem(height, i, ll);
+    }
+    PyTuple_SetItem(o, 0, n);
+    PyTuple_SetItem(o, 1, merging);
+    PyTuple_SetItem(o, 2, order);
+    PyTuple_SetItem(o, 3, height);
+    PyTuple_SetItem(o, 4, ac);
+    
+    free(arg4->merging);
+    free(arg4->order);
+    free(arg4->height);
+    free(arg4);
+    if ((!resultobj) || (resultobj == Py_None)) {
+      resultobj = o;
+    } else {
+      if (!PyList_Check(resultobj)) {
+        PyObject *o2 = resultobj;
+        resultobj = PyList_New(0);
+        PyList_Append(resultobj,o2);
+        Py_XDECREF(o2);
+      }
+      PyList_Append(resultobj,o);
+      Py_XDECREF(o);
+    }
+  }
+  {
+    if (arg1 != NULL) {
+      free((double*) arg1->data);
+      free((TCInput*) arg1);
+    }
+  }
   return resultobj;
 fail:
+  {
+    if (arg1 != NULL) {
+      free((double*) arg1->data);
+      free((TCInput*) arg1);
+    }
+  }
   return NULL;
 }
 
 
 SWIGINTERN PyObject *_wrap_DMCluster(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  DInput *arg1 = (DInput *) 0 ;
+  TDInput *arg1 = (TDInput *) 0 ;
   long arg2 ;
-  CMInfo *arg3 = (CMInfo *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
+  TCMInfo *arg3 = (TCMInfo *) 0 ;
   long val2 ;
   int ecode2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:DMCluster",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DInput, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DMCluster" "', argument " "1"" of type '" "DInput *""'"); 
-  }
-  arg1 = reinterpret_cast< DInput * >(argp1);
+  {
+    arg1 = NULL;
+  }
+  {
+    arg3 = (TCMInfo *)malloc(sizeof(TCMInfo));
+  }
+  if (!PyArg_ParseTuple(args,(char *)"OO:DMCluster",&obj0,&obj1)) SWIG_fail;
+  {
+    /* Check if is a list */
+    if (PyList_Check(obj0)) {
+      int i, j, size, offset;
+      
+      size = PyList_Size(obj0);     /* the number of elements - 1 */
+      
+      arg1 = (TDInput *) malloc(sizeof(TDInput));
+      arg1->nn = size+1;
+      arg1->data = (double *)malloc((1 + (size * (size + 1))/2)*sizeof(double));
+      
+      arg1->data[0] = 0.0; // offset for pam and agnes
+      //offset = (size * (size + 1))/2;
+      offset = 1;
+      for (i = 0; i < size; i++) {
+        PyObject *o = PyList_GetItem(obj0,i);
+        if (PyList_Check(o)) {
+          int zsize = PyList_Size(o); /* the line of a matrix */
+          if (zsize == i+1) {
+            for (j = 0; j < zsize; ++j) {
+              PyObject *p = PyList_GetItem(o,j);
+              if (PyFloat_Check(p)) {
+                arg1->data[offset++] = PyFloat_AsDouble(p);
+              } else if (PyInt_Check(p)) {
+                arg1->data[offset++] = (double)PyInt_AsLong(p);
+              } else {
+                PyErr_SetString(PyExc_TypeError,"sublists must contain doubles");
+                if (arg1->data != NULL)
+                free(arg1->data);
+                free(arg1);
+                return NULL;
+              }
+            }
+          } else {
+            PyErr_SetString(PyExc_TypeError,"list must contain the bottom-triangular dissimilarity matrix");
+            if (arg1->data != NULL)
+            free(arg1->data);
+            free(arg1);
+            return NULL;
+          }
+        } else {
+          PyErr_SetString(PyExc_TypeError,"list must contain lists");
+          if (arg1->data != NULL)
+          free(arg1->data);
+          free(arg1);
+          return NULL;
+        }
+      }
+      //assert(offset == 0);
+    } else {
+      PyErr_SetString(PyExc_TypeError,"not a list");
+      return NULL;
+    }
+  }
   ecode2 = SWIG_AsVal_long(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
     SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DMCluster" "', argument " "2"" of type '" "long""'");
   } 
   arg2 = static_cast< long >(val2);
-  res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_CMInfo, 0 |  0 );
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "DMCluster" "', argument " "3"" of type '" "CMInfo *""'"); 
-  }
-  arg3 = reinterpret_cast< CMInfo * >(argp3);
   DMCluster(arg1,arg2,arg3);
   resultobj = SWIG_Py_Void();
+  {
+    int i;
+    PyObject *o, *k, *cdisp, *disp, *n, *mapping, *medoids, *ll;
+    
+    o = PyTuple_New(6);
+    
+    n = PyInt_FromLong(arg3->n);
+    k = PyInt_FromLong(arg3->k);
+    disp = PyFloat_FromDouble(arg3->disp);
+    
+    mapping = PyList_New(arg3->n);
+    for (i = 0; i < arg3->n; ++i) {
+      ll = PyInt_FromLong(arg3->mapping[i]);
+      PyList_SetItem(mapping, i, ll);
+    }
+    medoids = PyList_New(arg3->k);
+    for (i = 0; i < arg3->k; ++i) {
+      ll = PyInt_FromLong(arg3->medoids[i]);
+      PyList_SetItem(medoids, i, ll);
+    }
+    cdisp = PyList_New(arg3->k);
+    for (i = 0; i < arg3->k; ++i) {
+      ll = PyFloat_FromDouble(arg3->cdisp[i]);
+      PyList_SetItem(cdisp, i, ll);
+    }
+    PyTuple_SetItem(o, 0, n);
+    PyTuple_SetItem(o, 1, k);
+    PyTuple_SetItem(o, 2, mapping);
+    PyTuple_SetItem(o, 3, medoids);
+    PyTuple_SetItem(o, 4, cdisp);
+    PyTuple_SetItem(o, 5, disp);
+    free(arg3->medoids);
+    free(arg3->cdisp);
+    free(arg3->mapping);
+    free(arg3);
+    
+    if ((!resultobj) || (resultobj == Py_None)) {
+      resultobj = o;
+    } else {
+      if (!PyList_Check(resultobj)) {
+        PyObject *o2 = resultobj;
+        resultobj = PyList_New(0);
+        PyList_Append(resultobj,o2);
+        Py_XDECREF(o2);
+      }
+      PyList_Append(resultobj,o);
+      Py_XDECREF(o);
+    }
+  }
+  {
+    if (arg1 != NULL) {
+      free((double*) arg1->data);
+      free((TDInput*) arg1);
+    }
+  }
   return resultobj;
 fail:
+  {
+    if (arg1 != NULL) {
+      free((double*) arg1->data);
+      free((TDInput*) arg1);
+    }
+  }
   return NULL;