/************************************************************************

  Copyright
  Alessandro MIRONE
  mirone@esrf.fr

  Copyright 2002  by European Synchrotron Radiation Facility, Grenoble, 
                  France

                               ----------
 
                           All Rights Reserved
 
                               ----------

Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the names of European Synchrotron
Radiation Facility or ESRF or BLISS not be used in advertising or 
publicity pertaining to distribution of the software without specific, 
written prior permission.

EUROPEAN SYNCHROTRON RADIATION FACILITY DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL EUROPEAN SYNCHROTRON
RADIATION FACILITY OR ESRF BE LIABLE FOR ANY SPECIAL, INDIRECT OR 
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.

**************************************************************************/
%module Sparsa
%{
#include<string.h>
#include<string.h>
#include<stdio.h>
#include <stdlib.h>
#include<iostream.h>
#include<math.h>
#include<complex.h>
#include<nMatrix.h>
#include<nLapack.h>
#include<Sparsa.h>
%}

%{
#include <Numeric/arrayobject.h> 
%}



%init %{	
  import_array();
%}	



%include typemaps.i

// THE FOLLOWING TYPEMAPS HAVE BEEN STOLEN FROM
// THE SWIG *.I FILES OF THE PLPLOT PROJECT

%{
   // global variables for consistency check on argument patterns
  static int Alen = 0;
//  static int Xlen = 0, Ylen = 0;
%}


%typemap(in) (int  N, double * ArrayFLOAT) (PyArrayObject* tmp=NULL) {
  tmp = (PyArrayObject *)PyArray_ContiguousFromObject($input, PyArray_DOUBLE, 1, 1);
  if(tmp == NULL) return NULL;
  $1 = Alen = tmp->dimensions[0];
  $2 = (double  *)tmp->data;
}
%typemap(freearg) (int  N, double * ArrayFLOAT) {Py_DECREF(tmp$argnum);}


%typemap(in) (int  N, int * Array) (PyArrayObject* tmp=NULL) {
  tmp = (PyArrayObject *)PyArray_ContiguousFromObject($input, PyArray_INT, 1, 1);
  if(tmp == NULL) return NULL;
  $1 = Alen = tmp->dimensions[0];
  $2 = (int  *)tmp->data;
}
%typemap(freearg) (int  N, int  * Array) {Py_DECREF(tmp$argnum);}



%typemap(in) (double * ArrayFLOATnoN) (PyArrayObject* tmp=NULL) {
  tmp = (PyArrayObject *)PyArray_ContiguousFromObject($input, PyArray_DOUBLE, 1, 1);
  if(tmp == NULL) return NULL;
  Alen = tmp->dimensions[0];
  $1 = (double  *)tmp->data;
}
%typemap(freearg) (double * ArrayFLOATnoN) {Py_DECREF(tmp$argnum);}

%typemap(in) (double * VectFLOATnoN) (PyArrayObject* tmp=NULL) {
  PyObject* array;
  array = PyObject_GetAttrString($input,"data");
  tmp = (PyArrayObject *)PyArray_ContiguousFromObject(array, PyArray_DOUBLE, 1, 1);
  Py_DECREF(array);
  if(tmp == NULL) return NULL;
  Alen = tmp->dimensions[0];
  $1 = (double  *)tmp->data;
}
%typemap(freearg) (double * VectFLOATnoN) {Py_DECREF(tmp$argnum);}



%typemap(in) (double * ArrayFLOAT2dNOCHECK) (PyArrayObject* tmp=NULL) {
  tmp = (PyArrayObject *)PyArray_ContiguousFromObject($input, PyArray_DOUBLE, 2, 2);
  if(tmp == NULL) return NULL;
  $1 = (double  *)tmp->data;
}
%typemap(freearg) (double * ArrayFLOAT2dNOCHECK) {Py_DECREF(tmp$argnum);}





%typemap(in) ( double * ArrayFLOATCHECK) (PyArrayObject* tmp=NULL ) {
  tmp = (PyArrayObject *)PyArray_ContiguousFromObject($input, PyArray_DOUBLE, 1, 1);
  if(tmp == NULL) return NULL;
  if(tmp->dimensions[0] != Alen) {
    PyErr_SetString(PyExc_ValueError, "Vectors must be same length.");
    return NULL;
  }
  $1 = (double  *)tmp->data;
}
%typemap(freearg) (double * ArrayFLOATCHECK) {Py_DECREF(tmp$argnum);}





%typemap(in) ( int * ArrayCHECK) (PyArrayObject* tmp=NULL ) {
  tmp = (PyArrayObject *)PyArray_ContiguousFromObject($input, PyArray_INT, 1, 1);
  if(tmp == NULL) return NULL;
  if(tmp->dimensions[0] != Alen) {
    PyErr_SetString(PyExc_ValueError, "Vectors must be same length.");
    return NULL;
  }
  $1 = (int  *)tmp->data;
}
%typemap(freearg) (int * ArrayCHECK) {Py_DECREF(tmp$argnum);}



class Sparsa3A {
public:
  Sparsa3A(int N, double *ArrayFLOAT , int *ArrayCHECK /*from*/, 
	   int *ArrayCHECK /*to*/);	
  void inizializza( Sparsa3A &rea,Sparsa3A &ima  ) ;

  //  void Moltiplica(double * ArrayFLOATnoN , double * ArrayFLOATnoN   );
  //void Moltiplica(double * VectFLOATnoN , double * VectFLOATnoN   );
  void Moltiplica(Array * ris, Array*vect  );
  void MoltiplicaMinus(Array * ris, Array*vect  );
  void MoltiplicaDiag(Array * ris, Array*vect  );
  void MoltiplicaDiagMinus(Array * ris, Array*vect  );
  int dim;
  int dim2;

  void   gohersch   ();
  double goherschMin();
  double goherschMax();
  void trasforma(double fattore, double addendo) ;	
  void scrivi(char *file) ;


};


void dumptofile(int N,  double *ArrayFLOAT ,  char * nome ) ;


double scalare( int N , double *ArrayFLOAT  , double *ArrayFLOATCHECK);

// void diagonalizza4py(int k, int m,double *alpha,  double *beta, double *pevect, double *peval)
void diagonalizza4py(  int k , int N , double *ArrayFLOAT, double *ArrayFLOATCHECK, 
		double * ArrayFLOAT2dNOCHECK,double * ArrayFLOAT2dNOCHECK );

%exception {
        try {
        $action
        }
        catch ( std::out_of_range &e ) {
           PyErr_SetString(PyExc_IndexError, e.what() );
           return NULL;
        }

}

%rename (__getitem__) get_array(int index);

struct Array {
    Array( int size ) ;
    Array( int fd, int sd ) ;	

    ~Array() ;
    Array * get_array(int index);

	

    double get_value( int index ) const;
    void set_to_zero(  )	;
    void set_to_one(  )	;
    void set_value( int index, double value );
    void set_all_random(  double value );	

    Array* copy() const;

    Array& operator+=( const Array& a ) ;
    int len();

     static void copy_to_a_from_b(Array &a, Array&b);
     void copy_from_b( Array&b);
     static void mat_mult(Array & b, double * ArrayFLOAT2dNOCHECK ,Array & a);


     void add_from_vect( Array&vect);		
     void add_from_vect_with_fact( Array&vect, double fact);
	
     void  set_indices_inv(int N, int *Array , double *ArrayFLOATnoN) ;
     void  set_indices( int  N, int *Array, double *ArrayFLOATnoN) ;
 
 //    void  get_numarray( int  &N,  double *&ArrayFLOAT) ;
  
  void  dividebyarray( Array &b);

     

  double *dataAddress() ;
  void 	dumptofile(char * nome);
  static double scalare(Array &a, Array &b) ;
  static double sqrtscalare(Array &a, Array &b);
  void normalizza(double norm);
  void normalizzaauto();
  void mult_by_fact(double fact);


};



typedef Array ListArray;


%exception ;



