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/CParallelepipedModel.cpp

    r8a48713 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> 
     
    146149    } 
    147150} 
    148  
    149  
    150151/** 
    151152 * Function to call to evaluate model 
    152  * @param args: input q or [q,phi] 
    153  * @return: function value 
     153 * @param args: input numpy array q[]  
     154 * @return: numpy array object  
    154155 */ 
    155 static PyObject * run(CParallelepipedModel *self, PyObject *args) { 
    156         double q_value, phi_value; 
    157         PyObject* pars; 
    158         int npars; 
     156  
     157static PyObject *evaluateOneDim(ParallelepipedModel* model, PyArrayObject *q){ 
     158    PyArrayObject *result; 
     159    
     160    // Check validity of array q , q must be of dimension 1, an array of double 
     161    if (q->nd != 1 || q->descr->type_num != PyArray_DOUBLE) 
     162    { 
     163        //const char * message= "Invalid array: q->nd=%d,type_num=%d\n",q->nd,q->descr->type_num; 
     164        //PyErr_SetString(PyExc_ValueError , message); 
     165        return NULL; 
     166    } 
     167    result = (PyArrayObject *)PyArray_FromDims(q->nd, (int *)(q->dimensions),  
     168                                                                                  PyArray_DOUBLE); 
     169        if (result == NULL) { 
     170        const char * message= "Could not create result "; 
     171        PyErr_SetString(PyExc_RuntimeError , message); 
     172                return NULL; 
     173        } 
     174         for (int i = 0; i < q->dimensions[0]; i++){ 
     175      double q_value  = *(double *)(q->data + i*q->strides[0]); 
     176      double *result_value = (double *)(result->data + i*result->strides[0]); 
     177      *result_value =(*model)(q_value); 
     178        } 
     179    return PyArray_Return(result);  
     180 } 
     181/** 
     182 * Function to call to evaluate model 
     183 * @param args: input numpy array  [q[],phi[]] 
     184 * @return: numpy array object  
     185 */ 
     186static PyObject * evaluateTwoDim( ParallelepipedModel* model,  
     187                              PyArrayObject *q, PyArrayObject *phi) 
     188 { 
     189    PyArrayObject *result; 
     190    //check validity of input vectors 
     191    if (q->nd != 1 || q->descr->type_num != PyArray_DOUBLE 
     192        || phi->nd != 1 || phi->descr->type_num != PyArray_DOUBLE 
     193        || phi->dimensions[0] != q->dimensions[0]){ 
     194      
     195        //const char * message= "Invalid array: q->nd=%d,type_num=%d\n",q->nd,q->descr->type_num; 
     196        PyErr_SetString(PyExc_ValueError ,"wrong input");  
     197        return NULL; 
     198    } 
     199        result= (PyArrayObject *)PyArray_FromDims(q->nd,(int*)(q->dimensions), PyArray_DOUBLE); 
     200 
     201        if (result == NULL){ 
     202            const char * message= "Could not create result "; 
     203        PyErr_SetString(PyExc_RuntimeError , message); 
     204            return NULL; 
     205        } 
     206         
     207    for (int i = 0; i < q->dimensions[0]; i++) { 
     208      double q_value = *(double *)(q->data + i*q->strides[0]); 
     209      double phi_value = *(double *)(phi->data + i*phi->strides[0]); 
     210      double *result_value = (double *)(result->data + i*result->strides[0]); 
     211      if (q_value == 0) 
     212          *result_value = 0.0; 
     213      else 
     214          *result_value = model->evaluate_rphi(q_value, phi_value); 
     215    } 
     216    return PyArray_Return(result);  
     217 } 
     218 /** 
     219 * Function to call to evaluate model 
     220 * @param args: input numpy array  [x[],y[]] 
     221 * @return: numpy array object  
     222 */ 
     223 static PyObject * evaluateTwoDimXY( ParallelepipedModel* model,  
     224                              PyArrayObject *x, PyArrayObject *y) 
     225 { 
     226    PyArrayObject *result; 
     227    int i,j, x_len, y_len, dims[2]; 
     228    //check validity of input vectors 
     229    if (x->nd != 2 || x->descr->type_num != PyArray_DOUBLE 
     230        || y->nd != 2 || y->descr->type_num != PyArray_DOUBLE 
     231        || y->dimensions[1] != x->dimensions[0]){ 
     232        const char * message= "evaluateTwoDimXY  expect 2 numpy arrays"; 
     233        PyErr_SetString(PyExc_ValueError , message);  
     234        return NULL; 
     235    } 
     236    
     237        if (PyArray_Check(x) && PyArray_Check(y)) { 
     238            x_len = dims[0]= x->dimensions[0]; 
     239        y_len = dims[1]= y->dimensions[1]; 
     240             
     241            // Make a new double matrix of same dims 
     242        result=(PyArrayObject *) PyArray_FromDims(2,dims,NPY_DOUBLE); 
     243        if (result == NULL){ 
     244            const char * message= "Could not create result "; 
     245        PyErr_SetString(PyExc_RuntimeError , message); 
     246            return NULL; 
     247            } 
     248        
     249        /* Do the calculation. */ 
     250        for ( i=0; i< x_len; i++) { 
     251            for ( j=0; j< y_len; j++) { 
     252                double x_value = *(double *)(x->data + i*x->strides[0]); 
     253                    double y_value = *(double *)(y->data + j*y->strides[1]); 
     254                        double *result_value = (double *)(result->data + 
     255                              i*result->strides[0] + j*result->strides[1]); 
     256                        *result_value = (*model)(x_value, y_value); 
     257            }            
     258        } 
     259        return PyArray_Return(result);  
     260         
     261        }else{ 
     262                    PyErr_SetString(CParallelepipedModelError,  
     263                   "CParallelepipedModel.evaluateTwoDimXY couldn't run."); 
     264                return NULL; 
     265                }        
     266} 
     267/** 
     268 *  evalDistribution function evaluate a model function with input vector 
     269 *  @param args: input q as vector or [qx, qy] where qx, qy are vectors 
     270 * 
     271 */  
     272static PyObject * evalDistribution(CParallelepipedModel *self, PyObject *args){ 
     273        PyObject *qx, *qy; 
     274        PyArrayObject * pars; 
     275        int npars ,mpars; 
    159276         
    160277        // Get parameters 
     
    187304        if ( !PyArg_ParseTuple(args,"O",&pars) ) { 
    188305            PyErr_SetString(CParallelepipedModelError,  
    189                 "CParallelepipedModel.run expects a q value."); 
     306                "CParallelepipedModel.evalDistribution expects a q value."); 
    190307                return NULL; 
    191308        } 
    192            
    193         // Check params 
    194         if( PyList_Check(pars)==1) { 
     309    // Check params 
     310         
     311    if(PyArray_Check(pars)==1) { 
    195312                 
    196                 // Length of list should be 2 for I(q,phi) 
    197             npars = PyList_GET_SIZE(pars);  
    198             if(npars!=2) { 
     313            // Length of list should 1 or 2 
     314            npars = pars->nd;  
     315            if(npars==1) { 
     316                // input is a numpy array 
     317                if (PyArray_Check(pars)) { 
     318                        return evaluateOneDim(self->model, (PyArrayObject*)pars);  
     319                    } 
     320                }else{ 
     321                    PyErr_SetString(CParallelepipedModelError,  
     322                   "CParallelepipedModel.evalDistribution expect numpy array of one dimension."); 
     323                return NULL; 
     324                } 
     325    }else if( PyList_Check(pars)==1) { 
     326        // Length of list should be 2 for I(qx,qy) 
     327            mpars = PyList_GET_SIZE(pars);  
     328            if(mpars!=2) { 
    199329                PyErr_SetString(CParallelepipedModelError,  
    200                         "CParallelepipedModel.run expects a double or a list of dimension 2."); 
     330                        "CParallelepipedModel.evalDistribution expects a list of dimension 2."); 
    201331                return NULL; 
    202332            } 
    203             // We have a vector q, get the q and phi values at which 
    204             // to evaluate I(q,phi) 
    205             q_value = CParallelepipedModel_readDouble(PyList_GET_ITEM(pars,0)); 
    206             phi_value = CParallelepipedModel_readDouble(PyList_GET_ITEM(pars,1)); 
    207             // Skip zero 
    208             if (q_value==0) { 
    209                 return Py_BuildValue("d",0.0); 
    210             } 
    211                 return Py_BuildValue("d",(*(self->model)).evaluate_rphi(q_value,phi_value)); 
    212  
    213         } else { 
    214  
    215                 // We have a scalar q, we will evaluate I(q) 
    216                 q_value = CParallelepipedModel_readDouble(pars);                 
    217                  
    218                 return Py_BuildValue("d",(*(self->model))(q_value)); 
    219         }        
     333             qx = PyList_GET_ITEM(pars,0); 
     334             qy = PyList_GET_ITEM(pars,1); 
     335             if (PyArray_Check(qx) && PyArray_Check(qy)) { 
     336                 return evaluateTwoDimXY(self->model, (PyArrayObject*)qx, 
     337                           (PyArrayObject*)qy); 
     338                 }else{ 
     339                    PyErr_SetString(CParallelepipedModelError,  
     340                   "CParallelepipedModel.evalDistribution expect 2 numpy arrays in list."); 
     341                return NULL; 
     342             } 
     343        }else{ 
     344            PyErr_SetString(CParallelepipedModelError,  
     345                   "CParallelepipedModel.evalDistribution couln't be run."); 
     346            return NULL; 
     347        } 
    220348} 
    221349 
    222350/** 
    223  * Function to call to evaluate model in cartesian coordinates 
    224  * @param args: input q or [qx, qy]] 
     351 * Function to call to evaluate model 
     352 * @param args: input q or [q,phi] 
    225353 * @return: function value 
    226354 */ 
    227 static PyObject * runXY(CParallelepipedModel *self, PyObject *args) { 
    228         double qx_value, qy_value; 
     355static PyObject * run(CParallelepipedModel *self, PyObject *args) { 
     356        double q_value, phi_value; 
    229357        PyObject* pars; 
    230358        int npars; 
     
    266394        if( PyList_Check(pars)==1) { 
    267395                 
     396                // Length of list should be 2 for I(q,phi) 
     397            npars = PyList_GET_SIZE(pars);  
     398            if(npars!=2) { 
     399                PyErr_SetString(CParallelepipedModelError,  
     400                        "CParallelepipedModel.run expects a double or a list of dimension 2."); 
     401                return NULL; 
     402            } 
     403            // We have a vector q, get the q and phi values at which 
     404            // to evaluate I(q,phi) 
     405            q_value = CParallelepipedModel_readDouble(PyList_GET_ITEM(pars,0)); 
     406            phi_value = CParallelepipedModel_readDouble(PyList_GET_ITEM(pars,1)); 
     407            // Skip zero 
     408            if (q_value==0) { 
     409                return Py_BuildValue("d",0.0); 
     410            } 
     411                return Py_BuildValue("d",(*(self->model)).evaluate_rphi(q_value,phi_value)); 
     412 
     413        } else { 
     414 
     415                // We have a scalar q, we will evaluate I(q) 
     416                q_value = CParallelepipedModel_readDouble(pars);                 
     417                 
     418                return Py_BuildValue("d",(*(self->model))(q_value)); 
     419        }        
     420} 
     421 
     422/** 
     423 * Function to call to evaluate model in cartesian coordinates 
     424 * @param args: input q or [qx, qy]] 
     425 * @return: function value 
     426 */ 
     427static PyObject * runXY(CParallelepipedModel *self, PyObject *args) { 
     428        double qx_value, qy_value; 
     429        PyObject* pars; 
     430        int npars; 
     431         
     432        // Get parameters 
     433         
     434            // Reader parameter dictionary 
     435    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") ); 
     436    self->model->longer_edgeB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "longer_edgeB") ); 
     437    self->model->longuest_edgeC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "longuest_edgeC") ); 
     438    self->model->parallel_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_phi") ); 
     439    self->model->parallel_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_theta") ); 
     440    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") ); 
     441    self->model->short_edgeA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "short_edgeA") ); 
     442    self->model->contrast = PyFloat_AsDouble( PyDict_GetItemString(self->params, "contrast") ); 
     443    // Read in dispersion parameters 
     444    PyObject* disp_dict; 
     445    DispersionVisitor* visitor = new DispersionVisitor(); 
     446    disp_dict = PyDict_GetItemString(self->dispersion, "short_edgeA"); 
     447    self->model->short_edgeA.dispersion->accept_as_destination(visitor, self->model->short_edgeA.dispersion, disp_dict); 
     448    disp_dict = PyDict_GetItemString(self->dispersion, "longer_edgeB"); 
     449    self->model->longer_edgeB.dispersion->accept_as_destination(visitor, self->model->longer_edgeB.dispersion, disp_dict); 
     450    disp_dict = PyDict_GetItemString(self->dispersion, "longuest_edgeC"); 
     451    self->model->longuest_edgeC.dispersion->accept_as_destination(visitor, self->model->longuest_edgeC.dispersion, disp_dict); 
     452    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_phi"); 
     453    self->model->parallel_phi.dispersion->accept_as_destination(visitor, self->model->parallel_phi.dispersion, disp_dict); 
     454    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_theta"); 
     455    self->model->parallel_theta.dispersion->accept_as_destination(visitor, self->model->parallel_theta.dispersion, disp_dict); 
     456 
     457         
     458        // Get input and determine whether we have to supply a 1D or 2D return value. 
     459        if ( !PyArg_ParseTuple(args,"O",&pars) ) { 
     460            PyErr_SetString(CParallelepipedModelError,  
     461                "CParallelepipedModel.run expects a q value."); 
     462                return NULL; 
     463        } 
     464           
     465        // Check params 
     466        if( PyList_Check(pars)==1) { 
     467                 
    268468                // Length of list should be 2 for I(qx, qy)) 
    269469            npars = PyList_GET_SIZE(pars);  
     
    338538    {"runXY",      (PyCFunction)runXY     , METH_VARARGS, 
    339539      "Evaluate the model at a given Q or Qx, Qy"}, 
     540       
     541    {"evalDistribution",  (PyCFunction)evalDistribution , METH_VARARGS, 
     542      "Evaluate the model at a given Q or Qx, Qy vector "}, 
    340543    {"reset",    (PyCFunction)reset   , METH_VARARGS, 
    341544      "Reset pair correlation"}, 
     
    388591 
    389592 
    390 static PyMethodDef module_methods[] = { 
    391     {NULL}  
    392 }; 
     593//static PyMethodDef module_methods[] = { 
     594//    {NULL}  
     595//}; 
    393596 
    394597/** 
Note: See TracChangeset for help on using the changeset viewer.