Changeset eca05c8 in sasview for pr_inversion/c_extensions


Ignore:
Timestamp:
Apr 30, 2008 2:29:36 PM (16 years ago)
Author:
Mathieu Doucet <doucetm@…>
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:
34ae302
Parents:
47f695c9
Message:

Added P(r) fit test

Location:
pr_inversion/c_extensions
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • pr_inversion/c_extensions/Cinvertor.c

    r9e8dc22 reca05c8  
    222222} 
    223223 
     224static PyObject * set_alpha(Cinvertor *self, PyObject *args) { 
     225        double alpha; 
     226   
     227        if (!PyArg_ParseTuple(args, "d", &alpha)) return NULL; 
     228        self->params.alpha = alpha; 
     229        return Py_BuildValue("d", self->params.alpha);   
     230} 
     231 
     232/** 
     233 * Gets the maximum distance 
     234 */ 
     235static PyObject * get_alpha(Cinvertor *self, PyObject *args) { 
     236        return Py_BuildValue("d", self->params.alpha);   
     237} 
     238 
    224239/** 
    225240 * Gets the number of x points 
     
    246261/** 
    247262 * Function to call to evaluate the residuals 
    248  * @param args: input q or [q,phi] 
    249  * @return: function value 
     263 * @param args: input parameters 
     264 * @return: list of residuals 
    250265 */ 
    251266static PyObject * residuals(Cinvertor *self, PyObject *args) { 
     
    257272        double residual, diff; 
    258273        // Regularization factor 
    259         double lmult = 0.0; 
     274        double regterm = 0.0; 
     275        double tmp = 0.0; 
    260276         
    261277        PyObject *data_obj; 
     
    266282        OUTVECTOR(data_obj,pars,npars); 
    267283                 
    268         //printf("npars: %i", npars); 
    269284    // PyList of residuals 
    270285        // Should create this list only once and refill it 
    271286    residuals = PyList_New(self->params.npoints); 
     287 
     288    regterm = reg_term(pars, self->params.d_max, npars); 
    272289     
    273290    for(i=0; i<self->params.npoints; i++) { 
    274         //printf("\n%i: ", i); 
    275291        diff = self->params.y[i] - iq(pars, self->params.d_max, npars, self->params.x[i]); 
    276292        residual = diff*diff / (self->params.err[i]*self->params.err[i]); 
    277         //printf("%i %g\n", i, residual); 
     293        tmp = residual; 
     294         
     295        // regularization term 
     296        residual += self->params.alpha * regterm; 
     297         
    278298        if (PyList_SetItem(residuals, i, Py_BuildValue("d",residual) ) < 0){ 
    279299            PyErr_SetString(CinvertorError,  
     
    286306        return residuals; 
    287307} 
     308/** 
     309 * Function to call to evaluate the residuals 
     310 * for P(r) minimization (for testing purposes) 
     311 * @param args: input parameters 
     312 * @return: list of residuals 
     313 */ 
     314static PyObject * pr_residuals(Cinvertor *self, PyObject *args) { 
     315        double *pars; 
     316        PyObject* residuals; 
     317        PyObject* temp; 
     318        double *res; 
     319        int i; 
     320        double residual, diff; 
     321        // Regularization factor 
     322        double regterm = 0.0; 
     323        double tmp = 0.0; 
     324         
     325        PyObject *data_obj; 
     326        Py_ssize_t npars; 
     327           
     328        if (!PyArg_ParseTuple(args, "O", &data_obj)) return NULL; 
     329         
     330        OUTVECTOR(data_obj,pars,npars); 
     331                 
     332        // Should create this list only once and refill it 
     333    residuals = PyList_New(self->params.npoints); 
     334 
     335    regterm = reg_term(pars, self->params.d_max, npars); 
     336 
     337     
     338    for(i=0; i<self->params.npoints; i++) { 
     339        diff = self->params.y[i] - pr(pars, self->params.d_max, npars, self->params.x[i]); 
     340        residual = diff*diff / (self->params.err[i]*self->params.err[i]); 
     341        tmp = residual; 
     342         
     343        // regularization term 
     344        residual += self->params.alpha * regterm; 
     345         
     346        if (PyList_SetItem(residuals, i, Py_BuildValue("d",residual) ) < 0){ 
     347            PyErr_SetString(CinvertorError,  
     348                "Cinvertor.residuals: error setting residual."); 
     349                return NULL; 
     350        }; 
     351                 
     352    } 
     353     
     354        return residuals; 
     355} 
    288356 
    289357/** 
     
    323391} 
    324392 
     393/** 
     394 * Function to call to evaluate P(r) with errors 
     395 * @param args: c-parameters and r 
     396 * @return: P(r) 
     397 */ 
     398static PyObject * get_pr_err(Cinvertor *self, PyObject *args) { 
     399        double *pars; 
     400        double *pars_err; 
     401        double pr_err_value; 
     402        double r, pr_value; 
     403        PyObject *data_obj; 
     404        Py_ssize_t npars; 
     405        PyObject *err_obj; 
     406        Py_ssize_t npars2; 
     407           
     408        if (!PyArg_ParseTuple(args, "OOd", &data_obj, &err_obj, &r)) return NULL; 
     409        OUTVECTOR(data_obj,pars,npars); 
     410        OUTVECTOR(err_obj,pars_err,npars2); 
     411                 
     412        pr_err(pars, pars_err, self->params.d_max, npars, r, &pr_value, &pr_err_value); 
     413        return Py_BuildValue("ff", pr_value, pr_err_value);      
     414} 
     415 
    325416 
    326417static PyMethodDef Cinvertor_methods[] = { 
    327418                   {"residuals", (PyCFunction)residuals, METH_VARARGS, "Get the list of residuals"}, 
     419                   {"pr_residuals", (PyCFunction)pr_residuals, METH_VARARGS, "Get the list of residuals"}, 
    328420                   {"set_x", (PyCFunction)set_x, METH_VARARGS, ""}, 
    329421                   {"get_x", (PyCFunction)get_x, METH_VARARGS, ""}, 
     
    334426                   {"set_dmax", (PyCFunction)set_dmax, METH_VARARGS, ""}, 
    335427                   {"get_dmax", (PyCFunction)get_dmax, METH_VARARGS, ""}, 
     428                   {"set_alpha", (PyCFunction)set_alpha, METH_VARARGS, ""}, 
     429                   {"get_alpha", (PyCFunction)get_alpha, METH_VARARGS, ""}, 
    336430                   {"get_nx", (PyCFunction)get_nx, METH_VARARGS, ""}, 
    337431                   {"get_ny", (PyCFunction)get_ny, METH_VARARGS, ""}, 
     
    339433                   {"iq", (PyCFunction)get_iq, METH_VARARGS, ""}, 
    340434                   {"pr", (PyCFunction)get_pr, METH_VARARGS, ""}, 
     435                   {"get_pr_err", (PyCFunction)get_pr_err, METH_VARARGS, ""}, 
    341436                   {"is_valid", (PyCFunction)is_valid, METH_VARARGS, ""}, 
    342437    
  • pr_inversion/c_extensions/invertor.c

    r9e8dc22 reca05c8  
    4040double ortho(double d_max, int n, double r) { 
    4141        return 2.0*r*sin(pi*n*r/d_max); 
    42          
    4342} 
    4443 
     
    7675 */ 
    7776double pr(double *pars, double d_max, int n_c, double r) { 
    78     double sum = 0.0;  
     77    double sum = 0.0;   
    7978        int i; 
    8079    for (i=0; i<n_c; i++) { 
     
    8483} 
    8584 
     85/** 
     86 * P(r) calculated from the expansion, with errors 
     87 */ 
     88void pr_err(double *pars, double *err, double d_max, int n_c,  
     89                double r, double *pr_value, double *pr_value_err) { 
     90    double sum = 0.0;  
     91    double sum_err = 0.0; 
     92    double func_value; 
     93        int i; 
     94    for (i=0; i<n_c; i++) { 
     95        func_value = ortho(d_max, i+1, r); 
     96        sum += pars[i] * func_value; 
     97        sum_err += err[i]*err[i]*func_value*func_value; 
     98    } 
     99    *pr_value = sum; 
     100    if (sum_err>0) { 
     101        *pr_value_err = sqrt(sum_err); 
     102    } else { 
     103        *pr_value_err = sum; 
     104    } 
     105}  
    86106 
     107/** 
     108 * dP(r)/dr calculated from the expansion. 
     109 */ 
     110double dprdr(double *pars, double d_max, int n_c, double r) { 
     111    double sum = 0.0;  
     112        int i; 
     113    for (i=0; i<n_c; i++) { 
     114        sum += pars[i] * 2.0*(sin(pi*(i+1)*r/d_max) + pi*(i+1)*r/d_max * cos(pi*(i+1)*r/d_max)); 
     115    } 
     116    return sum; 
     117} 
     118 
     119/** 
     120 * regularization term calculated from the expansion. 
     121 */ 
     122double reg_term(double *pars, double d_max, int n_c) { 
     123    double sum = 0.0;  
     124    double r; 
     125    double deriv; 
     126        int i; 
     127    for (i=0; i<25; i++) { 
     128        r = d_max/25.0*i; 
     129        deriv = dprdr(pars, d_max, n_c, r); 
     130        sum += deriv*deriv; 
     131    } 
     132    return sum/25.0*d_max; 
     133} 
     134 
     135 
  • pr_inversion/c_extensions/invertor.h

    r9e8dc22 reca05c8  
    1010    int npoints;     
    1111    int ny;     
    12     int nerr;     
    13 } Invertor_params; 
     12    int nerr;   
     13    double alpha; 
     14} Invertor_params;  
    1415 
    1516void invertor_dealloc(Invertor_params *pars); 
     
    2425double iq(double *c, double d_max, int n_c, double q); 
    2526double pr(double *c, double d_max, int n_c, double r); 
     27double dprdr(double *pars, double d_max, int n_c, double r); 
     28double reg_term(double *pars, double d_max, int n_c); 
     29void pr_err(double *pars, double *err, double d_max, int n_c,  
     30                double r, double *pr_value, double *pr_value_err); 
    2631 
    2732#endif 
Note: See TracChangeset for help on using the changeset viewer.