coriolis/hurricane/src/analog/PyMatrix.cpp

231 lines
7.1 KiB
C++

// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2019-2019, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | H u r r i c a n e A n a l o g |
// | |
// | Author : Jean-Paul Chaput |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./PyMatrix.cpp" |
// +-----------------------------------------------------------------+
#include "hurricane/analog/PyMatrix.h"
namespace Isobar {
using namespace Hurricane;
using namespace Analog;
extern "C" {
#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Matrix,matrix,function)
#if defined(__PYTHON_MODULE__)
// +=================================================================+
// | "PyMatrix" Python Module Code Part |
// +=================================================================+
DirectGetUIntAttribute(PyMatrix_rows , rows , PyMatrix, Matrix)
DirectGetUIntAttribute(PyMatrix_columns, columns, PyMatrix, Matrix)
static PyObject* PyMatrix_NEW ( PyObject* , PyObject* args )
{
unsigned int rows = 0;
unsigned int columns = 0;
PyMatrix* pyMatrix = NULL;
HTRY
if (not PyArg_ParseTuple( args, "II:Matrix_NEW", &rows, &columns ) ) {
PyErr_SetString ( ConstructorError, "Matrix.create(): Invalid/bad number of parameters ." );
return NULL;
}
pyMatrix = PyObject_NEW( PyMatrix, &PyTypeMatrix );
if (pyMatrix == NULL) { return NULL; }
pyMatrix->_object = new Matrix( rows, columns );
HCATCH
return (PyObject*)pyMatrix;
}
static int PyMatrix_Init ( PyMatrix* self, PyObject* args, PyObject* kwargs )
{
cdebug_log(20,0) << "PyMatrix_Init(): " << (void*)self << endl;
return 0;
}
static PyObject* PyMatrix_resize ( PyMatrix *self, PyObject* args )
{
cdebug_log(20,0) << "PyMatrix.resize()" << endl;
HTRY
METHOD_HEAD ( "Matrix.resize()" )
unsigned int rows = 0;
unsigned int columns = 0;
if (PyArg_ParseTuple(args,"II:Matrix.resize",&rows,&columns)) {
matrix->resize( (size_t)rows, (size_t)columns );
} else {
PyErr_SetString( ConstructorError, "Matrix.resize(): Invalid number/bad type of parameters." );
return NULL;
}
HCATCH
Py_RETURN_NONE;
}
static PyObject* PyMatrix_getValue ( PyMatrix *self, PyObject* args )
{
cdebug_log(20,0) << "PyMatrix.getValue()" << endl;
size_t value = 0;
HTRY
METHOD_HEAD ( "Matrix.getValue()" )
unsigned int row = 0;
unsigned int column = 0;
if (PyArg_ParseTuple(args,"II:Matrix.getValue",&row,&column)) {
value = matrix->at( (size_t)row, (size_t)column );
} else {
PyErr_SetString( ConstructorError, "Matrix.getValue(): Invalid number/bad type of parameters." );
return NULL;
}
HCATCH
return Py_BuildValue("I",(unsigned int)value);
}
static PyObject* PyMatrix_setValue ( PyMatrix *self, PyObject* args )
{
cdebug_log(20,0) << "PyMatrix.setValue()" << endl;
HTRY
METHOD_HEAD ( "Matrix.setValue()" )
unsigned int row = 0;
unsigned int column = 0;
unsigned int value = 0;
if (PyArg_ParseTuple(args,"III:Matrix.setValue",&row,&column,&value)) {
matrix->at( (size_t)row, (size_t)column ) = value;
} else {
PyErr_SetString( ConstructorError, "Matrix.setValue(): Invalid number/bad type of parameters." );
return NULL;
}
HCATCH
Py_RETURN_NONE;
}
// ---------------------------------------------------------------
// PyMatrix Attribute Method table.
PyMethodDef PyMatrix_Methods[] =
{ { "rows" , (PyCFunction)PyMatrix_rows , METH_NOARGS
, "Self explanatory." }
, { "columns" , (PyCFunction)PyMatrix_columns, METH_NOARGS
, "Self explanatory." }
, { "resize" , (PyCFunction)PyMatrix_resize , METH_VARARGS
, "Self explanatory." }
, { "getValue" , (PyCFunction)PyMatrix_getValue , METH_VARARGS
, "Self explanatory." }
, { "setValue" , (PyCFunction)PyMatrix_setValue , METH_VARARGS
, "Self explanatory." }
, { NULL, NULL, 0, NULL } /* sentinel */
};
// +-------------------------------------------------------------+
// | "PyMatrix" Object Methods |
// +-------------------------------------------------------------+
DirectDeleteMethod(PyMatrix_DeAlloc,PyMatrix)
PyTypeObjectLinkPyTypeNewInit(Matrix)
#else // End of Python Module Code Part.
// +=================================================================+
// | "PyMatrix" Shared Library Code Part |
// +=================================================================+
PyTypeObjectDefinitions(Matrix)
#endif // End of Shared Library Code Part.
} // extern "C".
#if !defined(__PYTHON_MODULE__)
extern Matrix Matrix_FromListOfList ( PyObject* pyLoList )
{
Matrix matrix;
if (not PyList_Check(pyLoList)) {
PyErr_SetString( ConstructorError, "Matrix_FromListOfList(): First level type is *not* a list." );
return matrix;
}
Py_ssize_t rows = PyList_Size( pyLoList );
Py_ssize_t cols = 0;
for ( Py_ssize_t rowIndex = 0; rowIndex<rows ; ++rowIndex ) {
PyObject* row = PyList_GetItem( pyLoList, rowIndex );
if (not PyList_Check(row)) {
ostringstream message;
message << "Matrix_FromListOfList(): Row [" << rowIndex << "] type is *not* list.";
PyErr_SetString( ConstructorError, message.str().c_str() );
return matrix.makeEmpty();
}
if (not cols) {
cols = PyList_Size( row );
matrix.resize( rows, cols );
} else {
if (cols != PyList_Size(row)) {
ostringstream message;
message << "Matrix_FromListOfList(): Row [0] and [" << rowIndex << "] have different sizes ("
<< cols << " vs. " << PyList_Size(row) << ").";
PyErr_SetString( ConstructorError, message.str().c_str() );
return matrix.makeEmpty();
}
}
for ( Py_ssize_t colIndex = 0; colIndex<cols ; ++colIndex ) {
PyObject* element = PyList_GetItem( row, colIndex );
if (not PyLong_Check(element)) {
ostringstream message;
message << "Matrix_FromListOfList(): Element [" << colIndex << "," << rowIndex << "] is not an integer.";
PyErr_SetString( ConstructorError, message.str().c_str() );
return matrix.makeEmpty();
}
matrix.at( rowIndex, colIndex ) = (size_t)PyInt_AsLong( element );
}
}
return matrix;
}
#endif
} // Isobar namespace.