Changeset 8344c50 in sasview for sansmodels


Ignore:
Timestamp:
Aug 5, 2009 5:37:00 PM (15 years ago)
Author:
Gervaise Alina <gervyh@…>
Branches:
master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, release_4.0.1, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
eba9885
Parents:
9188cc1
Message:

add eval function

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sansmodels/src/sans/models/c_models/classTemplate.txt

    r4176435 r8344c50  
    2222 * 
    2323 */ 
     24#define NO_IMPORT_ARRAY 
     25#define PY_ARRAY_UNIQUE_SYMBOL PyArray_API_sans 
    2426  
    2527extern "C" { 
    2628#include <Python.h> 
     29#include <arrayobject.h> 
    2730#include "structmember.h" 
    2831#include <stdio.h> 
     
    116119    } 
    117120} 
    118  
     121/** 
     122 * Function to call to evaluate model 
     123 * @param args: input numpy array q[]  
     124 * @return: numpy array object  
     125 */ 
     126  
     127static PyObject *evaluateOneDim([CMODEL]* model, PyArrayObject *q){ 
     128    PyArrayObject *result; 
     129    
     130    // Check validity of array q , q must be of dimension 1, an array of double 
     131    if (q->nd != 1 || q->descr->type_num != PyArray_DOUBLE) 
     132    { 
     133        //const char * message= "Invalid array: q->nd=%d,type_num=%d\n",q->nd,q->descr->type_num; 
     134        //PyErr_SetString(PyExc_ValueError , message); 
     135        return NULL; 
     136    } 
     137    result = (PyArrayObject *)PyArray_FromDims(q->nd, (int *)(q->dimensions),  
     138                                                                                  PyArray_DOUBLE); 
     139        if (result == NULL) { 
     140        const char * message= "Could not create result "; 
     141        PyErr_SetString(PyExc_RuntimeError , message); 
     142                return NULL; 
     143        } 
     144         for (int i = 0; i < q->dimensions[0]; i++){ 
     145      double q_value  = *(double *)(q->data + i*q->strides[0]); 
     146      double *result_value = (double *)(result->data + i*result->strides[0]); 
     147      *result_value =(*model)(q_value); 
     148        } 
     149    return PyArray_Return(result);  
     150 } 
     151/** 
     152 * Function to call to evaluate model 
     153 * @param args: input numpy array  [q[],phi[]] 
     154 * @return: numpy array object  
     155 */ 
     156static PyObject * evaluateTwoDim( [CMODEL]* model,  
     157                              PyArrayObject *q, PyArrayObject *phi) 
     158 { 
     159    PyArrayObject *result; 
     160    //check validity of input vectors 
     161    if (q->nd != 1 || q->descr->type_num != PyArray_DOUBLE 
     162        || phi->nd != 1 || phi->descr->type_num != PyArray_DOUBLE 
     163        || phi->dimensions[0] != q->dimensions[0]){ 
     164      
     165        //const char * message= "Invalid array: q->nd=%d,type_num=%d\n",q->nd,q->descr->type_num; 
     166        PyErr_SetString(PyExc_ValueError ,"wrong input");  
     167        return NULL; 
     168    } 
     169        result= (PyArrayObject *)PyArray_FromDims(q->nd,(int*)(q->dimensions), PyArray_DOUBLE); 
     170 
     171        if (result == NULL){ 
     172            const char * message= "Could not create result "; 
     173        PyErr_SetString(PyExc_RuntimeError , message); 
     174            return NULL; 
     175        } 
     176         
     177    for (int i = 0; i < q->dimensions[0]; i++) { 
     178      double q_value = *(double *)(q->data + i*q->strides[0]); 
     179      double phi_value = *(double *)(phi->data + i*phi->strides[0]); 
     180      double *result_value = (double *)(result->data + i*result->strides[0]); 
     181      if (q_value == 0) 
     182          *result_value = 0.0; 
     183      else 
     184          *result_value = model->evaluate_rphi(q_value, phi_value); 
     185    } 
     186    return PyArray_Return(result);  
     187 } 
     188 /** 
     189 * Function to call to evaluate model 
     190 * @param args: input numpy array  [x[],y[]] 
     191 * @return: numpy array object  
     192 */ 
     193 static PyObject * evaluateTwoDimXY( [CMODEL]* model,  
     194                              PyArrayObject *x, PyArrayObject *y) 
     195 { 
     196    PyArrayObject *result; 
     197    int i,j, x_len, y_len, dims[2]; 
     198    //check validity of input vectors 
     199    if (x->nd != 2 || x->descr->type_num != PyArray_DOUBLE 
     200        || y->nd != 2 || y->descr->type_num != PyArray_DOUBLE 
     201        || y->dimensions[1] != x->dimensions[0]){ 
     202        const char * message= "evaluateTwoDimXY  expect 2 numpy arrays"; 
     203        PyErr_SetString(PyExc_ValueError , message);  
     204        return NULL; 
     205    } 
     206    
     207        if (PyArray_Check(x) && PyArray_Check(y)) { 
     208            x_len = dims[0]= x->dimensions[0]; 
     209        y_len = dims[1]= y->dimensions[1]; 
     210             
     211            // Make a new double matrix of same dims 
     212        result=(PyArrayObject *) PyArray_FromDims(2,dims,NPY_DOUBLE); 
     213        if (result == NULL){ 
     214            const char * message= "Could not create result "; 
     215        PyErr_SetString(PyExc_RuntimeError , message); 
     216            return NULL; 
     217            } 
     218        
     219        /* Do the calculation. */ 
     220        for ( i=0; i< x_len; i++) { 
     221            for ( j=0; j< y_len; j++) { 
     222                double x_value = *(double *)(x->data + i*x->strides[0]); 
     223                    double y_value = *(double *)(y->data + j*y->strides[1]); 
     224                        double *result_value = (double *)(result->data + 
     225                              i*result->strides[0] + j*result->strides[1]); 
     226                        *result_value = (*model)(x_value, y_value); 
     227            }            
     228        } 
     229        return PyArray_Return(result);  
     230         
     231        }else{ 
     232                    PyErr_SetString([PYTHONCLASS]Error,  
     233                   "[PYTHONCLASS].evaluateTwoDimXY couldn't run."); 
     234                return NULL; 
     235                }        
     236} 
     237/** 
     238 *  evalDistribution function evaluate a model function with input vector 
     239 *  @param args: input q as vector or [qx, qy] where qx, qy are vectors 
     240 * 
     241 */  
     242static PyObject * evalDistribution([PYTHONCLASS] *self, PyObject *args){ 
     243        PyObject *qx, *qy; 
     244        PyArrayObject * pars; 
     245        int npars ,mpars; 
     246         
     247        // Get parameters 
     248         
     249        [READDICTIONARY] 
     250         
     251        // Get input and determine whether we have to supply a 1D or 2D return value. 
     252        if ( !PyArg_ParseTuple(args,"O",&pars) ) { 
     253            PyErr_SetString([PYTHONCLASS]Error,  
     254                "[PYTHONCLASS].evalDistribution expects a q value."); 
     255                return NULL; 
     256        } 
     257    // Check params 
     258         
     259    if(PyArray_Check(pars)==1) { 
     260                 
     261            // Length of list should 1 or 2 
     262            npars = pars->nd;  
     263            if(npars==1) { 
     264                // input is a numpy array 
     265                if (PyArray_Check(pars)) { 
     266                        return evaluateOneDim(self->model, (PyArrayObject*)pars);  
     267                    } 
     268                }else{ 
     269                    PyErr_SetString([PYTHONCLASS]Error,  
     270                   "[PYTHONCLASS].evalDistribution expect numpy array of one dimension."); 
     271                return NULL; 
     272                } 
     273    }else if( PyList_Check(pars)==1) { 
     274        // Length of list should be 2 for I(qx,qy) 
     275            mpars = PyList_GET_SIZE(pars);  
     276            if(mpars!=2) { 
     277                PyErr_SetString([PYTHONCLASS]Error,  
     278                        "[PYTHONCLASS].evalDistribution expects a list of dimension 2."); 
     279                return NULL; 
     280            } 
     281             qx = PyList_GET_ITEM(pars,0); 
     282             qy = PyList_GET_ITEM(pars,1); 
     283             if (PyArray_Check(qx) && PyArray_Check(qy)) { 
     284                 return evaluateTwoDimXY(self->model, (PyArrayObject*)qx, 
     285                           (PyArrayObject*)qy); 
     286                 }else{ 
     287                    PyErr_SetString([PYTHONCLASS]Error,  
     288                   "[PYTHONCLASS].evalDistribution expect 2 numpy arrays in list."); 
     289                return NULL; 
     290             } 
     291        }else{ 
     292            PyErr_SetString([PYTHONCLASS]Error,  
     293                   "[PYTHONCLASS].evalDistribution couln't be run."); 
     294            return NULL; 
     295        } 
     296} 
    119297 
    120298/** 
     
    252430    {"runXY",      (PyCFunction)runXY     , METH_VARARGS, 
    253431      "Evaluate the model at a given Q or Qx, Qy"}, 
     432       
     433    {"evalDistribution",  (PyCFunction)evalDistribution , METH_VARARGS, 
     434      "Evaluate the model at a given Q or Qx, Qy vector "}, 
    254435    {"reset",    (PyCFunction)reset   , METH_VARARGS, 
    255436      "Reset pair correlation"}, 
     
    302483 
    303484 
    304 static PyMethodDef module_methods[] = { 
    305     {NULL}  
    306 }; 
     485//static PyMethodDef module_methods[] = { 
     486//    {NULL}  
     487//}; 
    307488 
    308489/** 
Note: See TracChangeset for help on using the changeset viewer.