Ignore:
Timestamp:
Aug 7, 2009 9:10:34 AM (15 years ago)
Author:
Jae Cho <jhjcho@…>
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:
58c6ba6
Parents:
83a25da
Message:

recompiled all due to Alina's new eval(run) function

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sansmodels/src/sans/models/c_models/CLamellarPSModel.cpp

    rb341b16 r9bd69098  
    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> 
     
    134137    } 
    135138} 
    136  
     139/** 
     140 * Function to call to evaluate model 
     141 * @param args: input numpy array q[]  
     142 * @return: numpy array object  
     143 */ 
     144  
     145static PyObject *evaluateOneDim(LamellarPSModel* model, PyArrayObject *q){ 
     146    PyArrayObject *result; 
     147    
     148    // Check validity of array q , q must be of dimension 1, an array of double 
     149    if (q->nd != 1 || q->descr->type_num != PyArray_DOUBLE) 
     150    { 
     151        //const char * message= "Invalid array: q->nd=%d,type_num=%d\n",q->nd,q->descr->type_num; 
     152        //PyErr_SetString(PyExc_ValueError , message); 
     153        return NULL; 
     154    } 
     155    result = (PyArrayObject *)PyArray_FromDims(q->nd, (int *)(q->dimensions),  
     156                                                                                  PyArray_DOUBLE); 
     157        if (result == NULL) { 
     158        const char * message= "Could not create result "; 
     159        PyErr_SetString(PyExc_RuntimeError , message); 
     160                return NULL; 
     161        } 
     162         for (int i = 0; i < q->dimensions[0]; i++){ 
     163      double q_value  = *(double *)(q->data + i*q->strides[0]); 
     164      double *result_value = (double *)(result->data + i*result->strides[0]); 
     165      *result_value =(*model)(q_value); 
     166        } 
     167    return PyArray_Return(result);  
     168 } 
     169/** 
     170 * Function to call to evaluate model 
     171 * @param args: input numpy array  [q[],phi[]] 
     172 * @return: numpy array object  
     173 */ 
     174static PyObject * evaluateTwoDim( LamellarPSModel* model,  
     175                              PyArrayObject *q, PyArrayObject *phi) 
     176 { 
     177    PyArrayObject *result; 
     178    //check validity of input vectors 
     179    if (q->nd != 1 || q->descr->type_num != PyArray_DOUBLE 
     180        || phi->nd != 1 || phi->descr->type_num != PyArray_DOUBLE 
     181        || phi->dimensions[0] != q->dimensions[0]){ 
     182      
     183        //const char * message= "Invalid array: q->nd=%d,type_num=%d\n",q->nd,q->descr->type_num; 
     184        PyErr_SetString(PyExc_ValueError ,"wrong input");  
     185        return NULL; 
     186    } 
     187        result= (PyArrayObject *)PyArray_FromDims(q->nd,(int*)(q->dimensions), PyArray_DOUBLE); 
     188 
     189        if (result == NULL){ 
     190            const char * message= "Could not create result "; 
     191        PyErr_SetString(PyExc_RuntimeError , message); 
     192            return NULL; 
     193        } 
     194         
     195    for (int i = 0; i < q->dimensions[0]; i++) { 
     196      double q_value = *(double *)(q->data + i*q->strides[0]); 
     197      double phi_value = *(double *)(phi->data + i*phi->strides[0]); 
     198      double *result_value = (double *)(result->data + i*result->strides[0]); 
     199      if (q_value == 0) 
     200          *result_value = 0.0; 
     201      else 
     202          *result_value = model->evaluate_rphi(q_value, phi_value); 
     203    } 
     204    return PyArray_Return(result);  
     205 } 
     206 /** 
     207 * Function to call to evaluate model 
     208 * @param args: input numpy array  [x[],y[]] 
     209 * @return: numpy array object  
     210 */ 
     211 static PyObject * evaluateTwoDimXY( LamellarPSModel* model,  
     212                              PyArrayObject *x, PyArrayObject *y) 
     213 { 
     214    PyArrayObject *result; 
     215    int i,j, x_len, y_len, dims[2]; 
     216    //check validity of input vectors 
     217    if (x->nd != 2 || x->descr->type_num != PyArray_DOUBLE 
     218        || y->nd != 2 || y->descr->type_num != PyArray_DOUBLE 
     219        || y->dimensions[1] != x->dimensions[0]){ 
     220        const char * message= "evaluateTwoDimXY  expect 2 numpy arrays"; 
     221        PyErr_SetString(PyExc_ValueError , message);  
     222        return NULL; 
     223    } 
     224    
     225        if (PyArray_Check(x) && PyArray_Check(y)) { 
     226            x_len = dims[0]= x->dimensions[0]; 
     227        y_len = dims[1]= y->dimensions[1]; 
     228             
     229            // Make a new double matrix of same dims 
     230        result=(PyArrayObject *) PyArray_FromDims(2,dims,NPY_DOUBLE); 
     231        if (result == NULL){ 
     232            const char * message= "Could not create result "; 
     233        PyErr_SetString(PyExc_RuntimeError , message); 
     234            return NULL; 
     235            } 
     236        
     237        /* Do the calculation. */ 
     238        for ( i=0; i< x_len; i++) { 
     239            for ( j=0; j< y_len; j++) { 
     240                double x_value = *(double *)(x->data + i*x->strides[0]); 
     241                    double y_value = *(double *)(y->data + j*y->strides[1]); 
     242                        double *result_value = (double *)(result->data + 
     243                              i*result->strides[0] + j*result->strides[1]); 
     244                        *result_value = (*model)(x_value, y_value); 
     245            }            
     246        } 
     247        return PyArray_Return(result);  
     248         
     249        }else{ 
     250                    PyErr_SetString(CLamellarPSModelError,  
     251                   "CLamellarPSModel.evaluateTwoDimXY couldn't run."); 
     252                return NULL; 
     253                }        
     254} 
     255/** 
     256 *  evalDistribution function evaluate a model function with input vector 
     257 *  @param args: input q as vector or [qx, qy] where qx, qy are vectors 
     258 * 
     259 */  
     260static PyObject * evalDistribution(CLamellarPSModel *self, PyObject *args){ 
     261        PyObject *qx, *qy; 
     262        PyArrayObject * pars; 
     263        int npars ,mpars; 
     264         
     265        // Get parameters 
     266         
     267            // Reader parameter dictionary 
     268    self->model->n_plates = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_plates") ); 
     269    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") ); 
     270    self->model->spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "spacing") ); 
     271    self->model->caille = PyFloat_AsDouble( PyDict_GetItemString(self->params, "caille") ); 
     272    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") ); 
     273    self->model->delta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "delta") ); 
     274    self->model->sigma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma") ); 
     275    self->model->contrast = PyFloat_AsDouble( PyDict_GetItemString(self->params, "contrast") ); 
     276    // Read in dispersion parameters 
     277    PyObject* disp_dict; 
     278    DispersionVisitor* visitor = new DispersionVisitor(); 
     279    disp_dict = PyDict_GetItemString(self->dispersion, "spacing"); 
     280    self->model->spacing.dispersion->accept_as_destination(visitor, self->model->spacing.dispersion, disp_dict); 
     281 
     282         
     283        // Get input and determine whether we have to supply a 1D or 2D return value. 
     284        if ( !PyArg_ParseTuple(args,"O",&pars) ) { 
     285            PyErr_SetString(CLamellarPSModelError,  
     286                "CLamellarPSModel.evalDistribution expects a q value."); 
     287                return NULL; 
     288        } 
     289    // Check params 
     290         
     291    if(PyArray_Check(pars)==1) { 
     292                 
     293            // Length of list should 1 or 2 
     294            npars = pars->nd;  
     295            if(npars==1) { 
     296                // input is a numpy array 
     297                if (PyArray_Check(pars)) { 
     298                        return evaluateOneDim(self->model, (PyArrayObject*)pars);  
     299                    } 
     300                }else{ 
     301                    PyErr_SetString(CLamellarPSModelError,  
     302                   "CLamellarPSModel.evalDistribution expect numpy array of one dimension."); 
     303                return NULL; 
     304                } 
     305    }else if( PyList_Check(pars)==1) { 
     306        // Length of list should be 2 for I(qx,qy) 
     307            mpars = PyList_GET_SIZE(pars);  
     308            if(mpars!=2) { 
     309                PyErr_SetString(CLamellarPSModelError,  
     310                        "CLamellarPSModel.evalDistribution expects a list of dimension 2."); 
     311                return NULL; 
     312            } 
     313             qx = PyList_GET_ITEM(pars,0); 
     314             qy = PyList_GET_ITEM(pars,1); 
     315             if (PyArray_Check(qx) && PyArray_Check(qy)) { 
     316                 return evaluateTwoDimXY(self->model, (PyArrayObject*)qx, 
     317                           (PyArrayObject*)qy); 
     318                 }else{ 
     319                    PyErr_SetString(CLamellarPSModelError,  
     320                   "CLamellarPSModel.evalDistribution expect 2 numpy arrays in list."); 
     321                return NULL; 
     322             } 
     323        }else{ 
     324            PyErr_SetString(CLamellarPSModelError,  
     325                   "CLamellarPSModel.evalDistribution couln't be run."); 
     326            return NULL; 
     327        } 
     328} 
    137329 
    138330/** 
     
    302494    {"runXY",      (PyCFunction)runXY     , METH_VARARGS, 
    303495      "Evaluate the model at a given Q or Qx, Qy"}, 
     496       
     497    {"evalDistribution",  (PyCFunction)evalDistribution , METH_VARARGS, 
     498      "Evaluate the model at a given Q or Qx, Qy vector "}, 
    304499    {"reset",    (PyCFunction)reset   , METH_VARARGS, 
    305500      "Reset pair correlation"}, 
     
    352547 
    353548 
    354 static PyMethodDef module_methods[] = { 
    355     {NULL}  
    356 }; 
     549//static PyMethodDef module_methods[] = { 
     550//    {NULL}  
     551//}; 
    357552 
    358553/** 
Note: See TracChangeset for help on using the changeset viewer.