18 #include <structmember.h> 
   26 #include "Fields/Interpolation/LeastSquaresSolveFactory.h" 
   28 #include "PyOpal/Globals.h" 
   29 #include "PyOpal/PySquarePolynomialMap.h" 
   30 #include "PyOpal/PyPolynomialCoefficient.h" 
   32 namespace PySquarePolynomialMap {
 
   37 std::string(
"Return the coefficients of the matrix. Takes no arguments\n\n")+
 
   38 std::string(
"Return value is a list of lists, with polynomial coefficients\n")+
 
   39 std::string(
"for y_i = sum_j a_{ij}*prod_n(x_n^j_n) forming the i, j term\n")+
 
   40 std::string(
"in the matrix.\n");
 
   45     if (py_map == 
nullptr) {
 
   46         PyErr_SetString(PyExc_TypeError,
 
   47                 "Failed to resolve self as PolynomialMap");
 
   50     if (py_map->
map == 
nullptr) {
 
   51         PyErr_SetString(PyExc_TypeError,
 
   52                 "PolynomialMap not properly initialised");
 
   56     PyObject* py_coefficients = PyList_New(coefficients.
num_row());
 
   58     for (
size_t i = 0; i < coefficients.
num_row(); ++i) {
 
   59         PyObject* py_row = PyList_New(coefficients.
num_col());
 
   60         for (
size_t j = 0; j < coefficients.
num_col(); ++j) {
 
   61             PyObject* py_value = PyFloat_FromDouble(coefficients(i+1, j+1));
 
   63             PyList_SetItem(py_row, j, py_value);
 
   65         PyList_SetItem(py_coefficients, i, py_row);
 
   68     Py_INCREF(py_coefficients);
 
   69     return py_coefficients;
 
   73 std::string(
"Maps from the matrix index to the polynomial term.\n\n")+
 
   74 std::string(
"  - col: index of the matrix column.\n")+
 
   75 std::string(
"  - dim: dimension of the problem.\n")+
 
   76 std::string(
"Return value is a list of ints of length dim. Terms in the\n")+
 
   77 std::string(
"transfer matrix in the column given by col correspond to the\n")+
 
   78 std::string(
"coefficient of the x_j1^k1 ... x_jn^kn term where kn are the\n")+
 
   79 std::string(
"integers returned by this method.\n")+
 
   80 std::string(
"For example, PolynomialMap.index_by_power(5, 2) returns\n")+
 
   81 std::string(
"[2, 1] meaning the 7th column in a two-dimensional problem\n")+
 
   82 std::string(
"represents the coefficients of x_0^2 x_1^1\n");
 
   85 PyObject* 
index_by_power(PyObject *py_class, PyObject *args, PyObject *kwds) {
 
   86     PyTypeObject* py_map_type = 
reinterpret_cast<PyTypeObject*
>(py_class);
 
   88     if (py_map_type == 
nullptr) {
 
   89         PyErr_SetString(PyExc_TypeError,
 
   90                 "Failed to resolve self as PolynomialMapType");
 
   96     static char *kwlist[] = {
 
   97         const_cast<char*
>(
"col"),
 
   98         const_cast<char*>(
"dim"),
 
  101     if (!PyArg_ParseTupleAndKeywords(args, kwds, 
"ii", kwlist, &col, &dim)) {
 
  105         PyErr_SetString(PyExc_ValueError, 
"col should be >= 0");
 
  109         PyErr_SetString(PyExc_ValueError, 
"dim should be > 0");
 
  112     std::vector<int> powers =
 
  114     PyObject* py_powers = PyList_New(powers.size());
 
  115     Py_INCREF(py_powers);
 
  116     for (
size_t i = 0; i < powers.size(); ++i) {
 
  117         PyObject* py_one_power = PyLong_FromSize_t(powers[i]);
 
  118         Py_INCREF(py_one_power);
 
  119         PyList_SetItem(py_powers, i, py_one_power);
 
  125 std::string(
"Apply the mapping to a point.\n\n")+
 
  126 std::string(
"  - point: list of floats with length equal to the point\n")+
 
  127 std::string(
"    dimension of the mapping, corresponding to the abscissa.\n")+
 
  128 std::string(
"Return value is a list of floats, with length equal to the\n")+
 
  129 std::string(
"value dimension of the mapping; corresponding to the ordinates\n");
 
  131 PyObject* 
evaluate(PyObject *
self, PyObject *args, PyObject *kwds) {
 
  134     if (py_map == 
nullptr) {
 
  135         PyErr_SetString(PyExc_TypeError,
 
  136                 "Failed to resolve self as PolynomialMap");
 
  139     if (py_map->
map == 
nullptr) {
 
  140         PyErr_SetString(PyExc_TypeError,
 
  141                 "PolynomialMap not properly initialised");
 
  145     static char *kwlist[] = {
const_cast<char*
>(
"point"), 
nullptr};
 
  146     if (!PyArg_ParseTupleAndKeywords(args, kwds, 
"O", kwlist, &py_point)) {
 
  150     if (!PyList_Check(py_point)) {
 
  151         PyErr_SetString(PyExc_TypeError, 
"point was not a list");
 
  155         PyErr_SetString(PyExc_TypeError, 
"point had wrong size");
 
  159     for (
size_t i = 0; i < point.size(); ++i) {
 
  160         PyObject* point_i = PyList_GetItem(py_point, i);
 
  161         point[i] = PyFloat_AsDouble(point_i);
 
  163     if (PyErr_Occurred()) 
 
  166     py_map->
map->
F(&point[0], &value[0]);
 
  167     PyObject* py_value = PyList_New(value.size());
 
  168     for (
size_t i = 0; i < value.size(); ++i) {
 
  169         PyObject* value_i = PyFloat_FromDouble(value[i]);
 
  170         PyList_SetItem(py_value, i, value_i);
 
  178 std::string(
"Find a mapping by solving for the matrix.\n\n")+
 
  179 std::string(
"  - points: list, each entry containing a list of floats\n")+
 
  180 std::string(
"  corresponding to abscissa, each with length PointDimension.\n")+
 
  181 std::string(
"  The list should be as long as the number of coefficients in\n")+
 
  182 std::string(
"  the polynomial.\n")+
 
  183 std::string(
"  - values: list, each entry containing a list of floats\n")+
 
  184 std::string(
"  corresponding to ordinates, each with length ValueDimension.\n")+
 
  185 std::string(
"  The list should be as long as points.\n")+
 
  186 std::string(
"  - polynomial_order: integer, >= 0, corresponding to the\n")+
 
  187 std::string(
"  order of the fitted polynomial; 0 is constant, 1 is linear...\n")+
 
  188 std::string(
"Returns a polynomial map.\n");
 
  190 std::vector<std::vector<double> > 
get_vectors(PyObject* py_floats) {
 
  193      std::vector< std::vector<double> > data;
 
  194     if (!PyList_Check(py_floats)) {
 
  195         return std::vector<std::vector<double> >();
 
  197     size_t num_rows = PyList_Size(py_floats);
 
  199         return std::vector<std::vector<double> >();
 
  203     for (
size_t i = 0; i < num_rows; ++i) {
 
  204         PyObject* row = PyList_GetItem(py_floats, i);
 
  205         if (!PyList_Check(row)) {
 
  206             return std::vector<std::vector<double> >();
 
  210             num_cols = PyList_Size(row);
 
  212                 return std::vector<std::vector<double> >();
 
  214             data = std::vector< std::vector<double> >(num_rows, std::vector<double>(num_cols));
 
  217         if (PyList_Size(row) != static_cast<int>(num_cols)) {
 
  218             return std::vector<std::vector<double> >();
 
  220         for (
size_t j = 0; j < num_cols; ++j) {
 
  221             PyObject* py_value = PyList_GetItem(row, j);
 
  222             data.at(i).at(j) = PyFloat_AsDouble(py_value);
 
  223             if (PyErr_Occurred() != 
nullptr) 
 
  224                 return std::vector<std::vector<double> >();
 
  230 PyObject* 
exact_solve(PyObject *py_class, PyObject *args, PyObject *kwds) {
 
  231     PyTypeObject* py_map_type = 
reinterpret_cast<PyTypeObject*
>(py_class);
 
  233     if (py_map_type == 
nullptr) {
 
  234         PyErr_SetString(PyExc_TypeError,
 
  235                 "Failed to resolve self as PolynomialMapType");
 
  239     PyObject* py_points = 
nullptr;
 
  240     PyObject* py_values = 
nullptr;
 
  241     int polynomial_order = 0;
 
  242     PyObject* py_error_matrix = Py_None; 
 
  243     static char *kwlist[] = {
 
  244         const_cast<char*
>(
"points"),
 
  245         const_cast<char*>(
"values"),
 
  246         const_cast<char*
>(
"polynomial_order"),
 
  247         const_cast<char*>(
"error_matrix"),
 
  250     if (!PyArg_ParseTupleAndKeywords(args, kwds, 
"OOi|O", kwlist, &py_points,
 
  251             &py_values, &polynomial_order, &py_error_matrix)) {
 
  254     if (polynomial_order < 0) {
 
  255         PyErr_SetString(PyExc_ValueError, 
"polynomial_order should be >= 0");
 
  258     std::vector<std::vector<double> > points = 
get_vectors(py_points);
 
  259     if (points.size() == 0) {
 
  260         PyErr_SetString(PyExc_ValueError, 
"Failed to evaluate points");
 
  263     std::vector<std::vector<double> > values = 
get_vectors(py_values);
 
  264     if (values.size() == 0) {
 
  265         PyErr_SetString(PyExc_ValueError, 
"Failed to evaluate values");
 
  268     if (points.size() != values.size()) {
 
  269         PyErr_SetString(PyExc_ValueError, 
"points misaligned with values");
 
  274         std::vector<std::vector<double> > no_derivs;
 
  275         std::vector<std::vector<int> > no_indices;
 
  276         size_t dim = points[0].size();
 
  278                                           dim, dim, points, no_derivs, no_indices);
 
  281         PyErr_SetString(PyExc_ValueError, exc.
what().c_str());
 
  284     PyObject* py_map_obj = 
_alloc(py_map_type, 0);
 
  286     py_map->
map = test_map;
 
  291 std::string(
"Find a mapping by solving for the matrix.\n\n")+
 
  292 std::string(
"  - points: list, each entry containing a list of floats\n")+
 
  293 std::string(
"  corresponding to abscissa, each with length PointDimension.\n")+
 
  294 std::string(
"  The list should be at least as long as the number of \n")+
 
  295 std::string(
"  coefficients in the polynomial.\n")+
 
  296 std::string(
"  - values: list, each entry containing a list of floats\n")+
 
  297 std::string(
"  corresponding to ordinates, each with length ValueDimension.\n")+
 
  298 std::string(
"  The list should be as long as points.\n")+
 
  299 std::string(
"  - polynomial_order: integer, >= 0, corresponding to the\n")+
 
  300 std::string(
"  order of the fitted polynomial; 0 is constant, 1 is linear...\n")+
 
  301 std::string(
"  - coefficients: list of PolynomialCoefficients. Fix these\n")+
 
  302 std::string(
"    coefficients to some \n")+
 
  303 std::string(
"  - weights: list, of length = 0, corresponding to\n")+
 
  304 std::string(
"Returns a polynomial map.\n");
 
  307 PyObject* 
least_squares(PyObject *py_class, PyObject *args, PyObject *kwds) {
 
  308     PyTypeObject* py_map_type = 
reinterpret_cast<PyTypeObject*
>(py_class);
 
  310     if (py_map_type == 
nullptr) {
 
  311         PyErr_SetString(PyExc_TypeError,
 
  312                 "Failed to resolve self as PolynomialMapType");
 
  316     PyObject* py_points = 
nullptr;
 
  317     PyObject* py_values = 
nullptr;
 
  318     int polynomial_order = 0;
 
  319     PyObject* py_coefficients = 
nullptr;
 
  320     PyObject* py_weights = 
nullptr;
 
  321     static char *kwlist[] = {
 
  322         const_cast<char*
>(
"points"),
 
  323         const_cast<char*>(
"values"),
 
  324         const_cast<char*
>(
"polynomial_order"),
 
  325         const_cast<char*>(
"polynomial_coefficients"),
 
  326         const_cast<char*
>(
"weights"),
 
  329     if (!PyArg_ParseTupleAndKeywords(args, kwds, 
"OOi|OO", kwlist, &py_points,
 
  330             &py_values, &polynomial_order, &py_coefficients, &py_weights)) {
 
  333     if (polynomial_order < 0) {
 
  334         PyErr_SetString(PyExc_ValueError, 
"polynomial_order should be >= 0");
 
  337     std::vector<std::vector<double> > points = 
get_vectors(py_points);
 
  338     std::vector<std::vector<double> > values = 
get_vectors(py_values);
 
  339     std::vector<interpolation::PolynomialCoefficient> coeff;
 
  340     std::vector<double> weights;
 
  342     if (py_weights != 
nullptr) {
 
  343         if (!PyList_Check(py_weights)) {
 
  344             PyErr_SetString(PyExc_TypeError,
 
  345                             "Failed to resolve weights as a list");
 
  348         size_t list_size = PyList_Size(py_weights); 
 
  349         weights = std::vector<double>(list_size);
 
  350         for (
size_t i = 0; i < list_size; ++i) {
 
  351             PyObject* py_value = PyList_GetItem(py_weights, i);
 
  352             weights[i] = int(PyFloat_AsDouble(py_value));
 
  353             if (PyErr_Occurred() != 
nullptr) { 
 
  359     if (py_coefficients != 
nullptr) {
 
  360         if (!PyList_Check(py_coefficients)) {
 
  361             PyErr_SetString(PyExc_TypeError,
 
  362                             "Failed to resolve coefficients as a list");
 
  365         size_t list_size = PyList_Size(py_coefficients); 
 
  366         for (
size_t i = 0; i < list_size; ++i) {
 
  367             PyObject* py_value = PyList_GetItem(py_coefficients, i);
 
  369             if (py_coeff == 
nullptr) {
 
  370                 PyErr_SetString(PyExc_TypeError,
 
  371                     "Failed to resolve list item as a PolynomialCoefficient.");
 
  374             coeff.push_back(*(py_coeff->
coeff));
 
  380         interpolation::LeastSquaresSolveFactory solver(polynomial_order, points);
 
  381         solver.setWeights(weights);
 
  382         solver.setCoefficients(coeff);
 
  385         PyErr_SetString(PyExc_ValueError, exc.
what().c_str());
 
  388     PyObject* py_map_obj = 
_alloc(py_map_type, 0);
 
  390     py_map->
map = test_map;
 
  396 int _init(PyObject* 
self, PyObject *args, PyObject *kwds) {
 
  399     if (py_map == 
nullptr) {
 
  400         PyErr_SetString(PyExc_TypeError,
 
  401                         "Failed to resolve self as PolynomialMap in __init__");
 
  406     if (py_map->
map != 
nullptr) {
 
  408         py_map->
map = 
nullptr;
 
  412     PyObject* py_coefficients;
 
  413     static char *kwlist[] = {
const_cast<char*
>(
"point_dimension"),
 
  414                              const_cast<char*>(
"coefficients"), 
nullptr};
 
  415     if (!PyArg_ParseTupleAndKeywords(args, kwds, 
"iO", kwlist,
 
  416                                          &point_dim, &py_coefficients)) {
 
  422     if (!PyList_Check(py_coefficients)) {
 
  423         PyErr_SetString(PyExc_TypeError,
 
  424                         "Failed to resolve coefficients as a list");
 
  427     size_t num_rows = PyList_Size(py_coefficients);
 
  429         PyErr_SetString(PyExc_ValueError, 
"coefficients was empty");
 
  435     for (
size_t i = 0; i < num_rows; ++i) {
 
  436         PyObject* row = PyList_GetItem(py_coefficients, i);
 
  437         if (!PyList_Check(py_coefficients)) {
 
  438             PyErr_SetString(PyExc_TypeError,
 
  439                             "Failed to resolve coefficients row as a list");
 
  444             num_cols = PyList_Size(row);
 
  446                 PyErr_SetString(PyExc_ValueError, 
"coefficients row was empty");
 
  452         if (PyList_Size(row) != 
static_cast<int>(num_cols)) {
 
  453                 PyErr_SetString(PyExc_ValueError,
 
  454                                 "coefficients row had wrong number of elements");
 
  456         for (
size_t j = 0; j < num_cols; ++j) {
 
  457             PyObject* py_value = PyList_GetItem(row, j);
 
  458             coefficients(i+1, j+1) = PyFloat_AsDouble(py_value);
 
  459             if (PyErr_Occurred() != 
nullptr) 
 
  468         PyErr_SetString(PyExc_RuntimeError, (&exc)->what());
 
  480     return reinterpret_cast<PyObject*
>(map);
 
  483 PyObject *
_new(PyTypeObject *
type, Py_ssize_t nitems) {
 
  484     return _alloc(type, nitems);
 
  492     if (
self != 
nullptr) {
 
  493         if (self->map != 
nullptr)
 
  499 static PyMemberDef _members[] = {
 
  503 static PyMethodDef _methods[] = {
 
  509   METH_CLASS|METH_VARARGS|METH_KEYWORDS, exact_solve_docstring.c_str()},
 
  511   METH_CLASS|METH_VARARGS|METH_KEYWORDS, least_squares_docstring.c_str()},
 
  518 std::string(
"PolynomialMap provides routines to calculate multivariate \n")+
 
  519 std::string(
"polynomials.\n\n")+
 
  520 std::string(
"__init__()\n")+
 
  521 std::string(
"    Takes two arguments.\n")+
 
  522 std::string(
"    - point_dim: integer which defines the dimension of the\n")+
 
  523 std::string(
"      points (abscissa)\n")+
 
  524 std::string(
"    - coefficients: list of lists of floats which define the\n")+
 
  525 std::string(
"      polynomial\n")+
 
  526 std::string(
"The value dimension of the PolynomialMap is the number of rows\n")+
 
  527 std::string(
"coefficients matrix\n");
 
  529 static PyTypeObject PyPolynomialMapType = {
 
  530     PyObject_HEAD_INIT(
nullptr)
 
  531     "polynomial_map.PolynomialMap",         
 
  549     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, 
 
  550     class_docstring.c_str(),           
 
  574                        "polynomial_map module contains the PolynomialMap class";
 
  576 static struct PyModuleDef polynomial_map_def = {
 
  577     PyModuleDef_HEAD_INIT,
 
  590     PySquarePolynomialMap::PyPolynomialMapType.tp_new = PyType_GenericNew;
 
  591     if (PyType_Ready(&PySquarePolynomialMap::PyPolynomialMapType) < 0)
 
  594     PyObject* module = PyModule_Create(&polynomial_map_def);
 
  595     if (module == 
nullptr)
 
  598     PyTypeObject* polynomial_map_type = &PySquarePolynomialMap::PyPolynomialMapType;
 
  599     Py_INCREF(polynomial_map_type);
 
  600     PyModule_AddObject(module, 
"PolynomialMap",
 
  601                        reinterpret_cast<PyObject*>(polynomial_map_type));
 
PyObject * index_by_power(PyObject *py_class, PyObject *args, PyObject *kwds)
 
void solve(double *Matrix, double *Solution, double *rightHandSide, const int &M, const int &N)
 
interpolation::SquarePolynomialVector * map
 
MMatrix< double > GetCoefficientsAsMatrix() const 
 
virtual const std::string & what() const 
Return the message string for the exception. 
 
PyObject * exact_solve(PyObject *py_class, PyObject *args, PyObject *kwds)
 
void _dealloc(PyPolynomialMap *self)
 
int _init(PyObject *self, PyObject *args, PyObject *kwds)
 
PyObject * _alloc(PyTypeObject *type, Py_ssize_t nitems)
 
SolveFactory is a factory class for solving a set of linear equations to generate a polynomial based ...
 
PyObject * get_coefficients_as_matrix(PyObject *self, PyObject *args, PyObject *kwds)
 
PyObject * _new(PyTypeObject *type, Py_ssize_t nitems)
 
PyMODINIT_FUNC PyInit_polynomial_map(void)
 
const char * module_docstring
 
interpolation::PolynomialCoefficient * coeff
 
unsigned int PointDimension() const 
 
std::vector< std::vector< double > > get_vectors(PyObject *py_floats)
 
SquarePolynomialVector describes a vector of multivariate polynomials. 
 
PyObject * evaluate(PyObject *self, PyObject *args, PyObject *kwds)
 
std::string get_coefficients_as_matrix_docstring
 
size_t num_row() const 
returns number of rows in the matrix 
 
void F(const double *point, double *value) const 
 
size_t num_col() const 
returns number of columns in the matrix 
 
c Accompany it with the information you received as to the offer to distribute corresponding source complete source code means all the source code for all modules it plus any associated interface definition plus the scripts used to control compilation and installation of the executable as a special exception
 
static std::vector< int > IndexByPower(int index, int nInputVariables)
 
unsigned int ValueDimension() const 
 
void _free(PyPolynomialMap *self)
 
std::string exact_solve_docstring
 
SquarePolynomialVector * PolynomialSolve(const std::vector< std::vector< double > > &values, const std::vector< std::vector< double > > &deriv_values)
 
std::string least_squares_docstring
 
std::string index_by_power_docstring
 
std::string class_docstring
 
std::string evaluate_docstring
 
PyObject * least_squares(PyObject *py_class, PyObject *args, PyObject *kwds)