/* A file to test imorting C modules for handling arrays to Python */

/* Python.h includes <stdio.h>, <string.h>, <errno.h>, <limits.h>, and <stdlib.h> (if available)*/
#include "Python.h"
#include "arrayobject.h"
#include "numpy_module.h"
#include "sympowerit.h"
#include <cblas.h>


/* ==== Set up the methods table ====================== */
static PyMethodDef _numpy_moduleMethods[] = {
	{"sym_powerit", sym_powerit, METH_VARARGS},
	{NULL, NULL}     /* Sentinel - marks the end of this structure */
};


/* ==== Initialize the numpy_module functions =============== */
// Module name must be _numpy_module in compile and linked 
void init_numpy_module()  {
	(void) Py_InitModule("_numpy_module", _numpy_moduleMethods);
	import_array();  // Must be present for NumPy.  Called first after above line.
}


/* =========== Power iteration on symmetric matrix ========== */ 
static PyObject *sym_powerit(PyObject *self, PyObject *args)
{
  PyArrayObject *X=NULL, *T=NULL, *E=NULL,*U=NULL;
  double  *tin, *ein, tol;
  int amax, n, info, maxiter, verbose;
  int dims[2];
  
  /* Parse tuple of input arguments*/
  if (!PyArg_ParseTuple(args, "O!O!iidii", 
			&PyArray_Type, &X,
			&PyArray_Type, &T, 
			&n,
			&amax, 
			&tol,
			&maxiter,
			&verbose)
      )  
    return NULL;
  if (NULL == X)  return NULL;
  
  /* Get the dimensions of the input */
  n = X->dimensions[0];
  
  /* Create output/ work arrays, no inplace calculations */
  dims[0] = n;
  dims[1] = amax;
  U = (PyArrayObject*) PyArray_NewCopy(T, NPY_CORDER);
  dims[1] = n;
  E = (PyArrayObject*) PyArray_NewCopy(X, NPY_CORDER);
  
  /* Get pointers to contigous data (row-major)*/
  ein = (double *)E->data;
  tin = (double *)U->data;
  
  /* Call sympower method */
  info = sympowerit (ein, n, tin, amax, tol, maxiter, verbose);
  
  Py_DECREF(E);
  
  return Py_BuildValue("Ni", U, info);

}