mailRe: r25329 - /trunk/specific_analyses/relax_disp/estimate_r2eff.py


Others Months | Index by Date | Thread Index
>>   [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Header


Content

Posted by Edward d'Auvergne on August 27, 2014 - 11:32:
Hi Troels,

Maybe you could try and see if your Jacobian setup matches the numeric
values returned by the target_functions.relax_fit.jacobian() Python C
module function.  The C module function has been tested against the
synthetic data in
test_suite/shared_data/curve_fitting/numeric_gradient/ and is 100% bug
free.  Also, you should also turn off parameter scaling when comparing
number initially in case that is causing a scaling of the error
estimates.

Regards,

Edward


On 27 August 2014 11:12,  <tlinnet@xxxxxxxxxxxxx> wrote:
Author: tlinnet
Date: Wed Aug 27 11:12:50 2014
New Revision: 25329

URL: http://svn.gna.org/viewcvs/relax?rev=25329&view=rev
Log:
Implemented the first try to compute the Variance of R2eff and i0, by the 
co-variance.

This uses the Jacobian matrix.
The errors calculated, are though way to small compared 2000 Monte-Carlo 
simulations.

task #7822(https://gna.org/task/index.php?7822): Implement user function to 
estimate R2eff and associated errors for exponential curve fitting.

Modified:
    trunk/specific_analyses/relax_disp/estimate_r2eff.py

Modified: trunk/specific_analyses/relax_disp/estimate_r2eff.py
URL: 
http://svn.gna.org/viewcvs/relax/trunk/specific_analyses/relax_disp/estimate_r2eff.py?rev=25329&r1=25328&r2=25329&view=diff
==============================================================================
--- trunk/specific_analyses/relax_disp/estimate_r2eff.py        (original)
+++ trunk/specific_analyses/relax_disp/estimate_r2eff.py        Wed Aug 27 
11:12:50 2014
@@ -24,7 +24,7 @@

 # Python module imports.
 from copy import deepcopy
-from numpy import asarray, array, diag, dot, exp, inf, log, sqrt, sum, 
transpose, zeros
+from numpy import asarray, array, diag, dot, exp, eye, inf, log, multiply, 
sqrt, sum, transpose, zeros
 from numpy.linalg import inv
 from minfx.generic import generic_minimise
 from re import match, search
@@ -40,8 +40,9 @@
 from specific_analyses.relax_disp.data import average_intensity, 
loop_exp_frq_offset_point, loop_frq, loop_time, return_param_key_from_data
 from specific_analyses.relax_disp.parameters import 
disassemble_param_vector
 from specific_analyses.relax_disp.variables import MODEL_R2EFF
+from specific_analyses.relax_fit.optimisation import func_wrapper, 
dfunc_wrapper, d2func_wrapper
 from target_functions.chi2 import chi2_rankN
-from target_functions.relax_fit import setup, func, dfunc, d2func, 
back_calc_I
+from target_functions.relax_fit import setup


 # Scipy installed.
@@ -257,16 +258,23 @@
         # See: 
http://wiki.nmr-relax.com/Calculate_jacobian_hessian_matrix_in_sympy_exponential_decay

         # Make partial derivative, with respect to r2eff.
-        d_chi2_d_r2eff = sum( 2.0 * i0 * self.times * ( -i0 * exp( -r2eff 
* self.times) + self.values) * exp( -r2eff * self.times ) / self.errors**2 )
+        d_chi2_d_r2eff = 2.0 * i0 * self.times * ( -i0 * exp( -r2eff * 
self.times) + self.values) * exp( -r2eff * self.times ) / self.errors**2

         # Make partial derivative, with respect to i0.
-        d_chi2_d_i0 = sum ( - 2.0 * ( -i0 * exp( -r2eff * self.times) + 
self.values) * exp( -r2eff * self.times) / self.errors**2 )
+        d_chi2_d_i0 = - 2.0 * ( -i0 * exp( -r2eff * self.times) + 
self.values) * exp( -r2eff * self.times) / self.errors**2

         # Define Jacobian as m rows with function derivatives and n 
columns of parameters.
-        jacobian_matrix = transpose(array( [d_chi2_d_r2eff , d_chi2_d_i0] 
) )
+        self.jacobian_matrix = transpose(array( [d_chi2_d_r2eff , 
d_chi2_d_i0] ) )
+
+        # Take the sum, to send to minfx.
+        sum_d_chi2_d_r2eff = sum( d_chi2_d_r2eff )
+        sum_d_chi2_d_i0 = sum( d_chi2_d_i0 )
+
+        # Define Jacobian as m rows with function derivatives and n 
columns of parameters.
+        sum_jacobian_matrix = transpose(array( [sum_d_chi2_d_r2eff , 
sum_d_chi2_d_i0] ) )

         # Return Jacobian matrix.
-        return jacobian_matrix
+        return sum_jacobian_matrix


     def func_exp_hess(self, params):
@@ -324,62 +332,82 @@
         return 1. / self.errors * (self.calc_exp(self.times, *params) - 
self.values)


-    def multifit_cova(self, J=None, matrix_X_J=None, epsrel=None, 
matrix_X_covar=None):
-        """This is the implementation of 'gsl_multifit_covar' from GNU 
Scientific Library (GSL).
+    def multifit_covar(self, J=None, epsrel=None):
+        """This is the implementation of the multifit covariance.
+
+        This is inspired from GNU Scientific Library (GSL).

         This function uses the Jacobian matrix J to compute the covariance 
matrix of the best-fit parameters, covar.
+
         The parameter 'epsrel' is used to remove linear-dependent columns 
when J is rank deficient.

         The covariance matrix is given by,

-        covar = (J^T J)^{-1}
+            covar = (J^T J)^{-1}

         and is computed by QR decomposition of J with column-pivoting. Any 
columns of R which satisfy

-        |R_{kk}| <= epsrel |R_{11}|
-
-        are considered linearly-dependent and are excluded from the 
covariance matrix (the corresponding rows and columns of the covariance 
matrix are set to zero).
+            |R_{kk}| <= epsrel |R_{11}|
+
+        are considered linearly-dependent and are excluded from the 
covariance matrix
+        (the corresponding rows and columns of the covariance matrix are 
set to zero).

         If the minimisation uses the weighted least-squares function:
+
             f_i = (Y(x, t_i) - y_i) / \sigma_i
+
         then the covariance matrix above gives the statistical error on 
the best-fit parameters resulting from the Gaussian errors \sigma_i on the 
underlying data y_i.
-        This can be verified from the relation \delta f = J \delta c and 
the fact that the fluctuations in f from the data y_i are normalised by 
\sigma_i and so satisfy <\delta f \delta f^T> = I.
-
-        For an unweighted least-squares function f_i = (Y(x, t_i) - y_i) 
the covariance matrix above should be multiplied by the variance of the 
residuals about the best-fit
+
+        This can be verified from the relation \delta f = J \delta c and 
the fact that the fluctuations in f from the data y_i are normalised by 
\sigma_i
+        and so satisfy <\delta f \delta f^T> = I.
+
+        For an unweighted least-squares function f_i = (Y(x, t_i) - y_i) 
the covariance matrix above should be multiplied by
+        the variance of the residuals about the best-fit
+
             \sigma^2 = \sum (y_i - Y(x,t_i))^2 / (n-p)
+
         to give the variance-covariance matrix \sigma^2 C.
         This estimates the statistical error on the best-fit parameters 
from the scatter of the underlying data.

         See:
         U{GSL - GNU Scientific Library<http://www.gnu.org/software/gsl/>}
+        U{Manual: 
Overview<http://www.gnu.org/software/gsl/manual/gsl-ref_37.html#SEC510>}
         U{Manual: Computing the covariance matrix of best fit 
parameters<http://www.gnu.org/software/gsl/manual/gsl-ref_38.html#SEC528>}
-        U{Manual: Computing the covariance matrix of best fit 
parameters<http://www.gnu.org/software/gsl/manual/gsl-ref_38.html#SEC528>}
-        U{Manual: 
Overview<http://www.gnu.org/software/gsl/manual/gsl-ref_37.html#SEC510>}
-
-        @param matrix_X_J:      The vector of parameter values.
-        @type matrix_X_J:       numpy rank-1 float array
-        @param epsrel:          The vector of parameter values.
-        @type epsrel:           numpy rank-1 float array
-        @param matrix_X_covar:  The vector of parameter values.
-        @type matrix_X_covar:   numpy rank-1 float array
-        @return:                ?
-        @rtype:                 ?
-        """
-
-        # http://www.orbitals.com/self/least/least.htm
-        # Weighting matrix. This is a square symmetric matrix. For 
independent measurements, this is a diagonal matrix. Larger values indicate 
greater significance
-        W = sum( self.errors**2 )
-
-        # The covariance matrix (sometimes referred to as the 
variance-covariance matrix), Qxx, is defined as
-        # Qxx = (J^t W J)^(-1)
-
+        U{Other reference<http://www.orbitals.com/self/least/least.htm>}
+
+        @param J:               The Jacobian matrix.
+        @type J:                numpy array
+        @param epsrel:          This is not implemented.  Any columns of R 
which satisfy |R_{kk}| <= epsrel |R_{11}| are considered linearly-dependent 
and are excluded from the covariance matrix, where the corresponding rows 
and columns of the covariance matrix are set to zero.
+        @type epsrel:           float
+        @return:                The co-variance matrix
+        @rtype:                 square numpy array
+        """
+
+        # Weighting matrix. This is a square symmetric matrix.
+        # For independent measurements, this is a diagonal matrix. Larger 
values indicate greater significance.
+
+        # Make a square diagonal matrix.
+        eye_mat = eye(self.errors.shape[0])
+
+        # Now form the error matrix, with errors down the diagonal.
+        #weights = self.errors**2
+        weights = self.errors
+
+        W = multiply(weights, eye_mat)
+
+        # The covariance matrix (sometimes referred to as the 
variance-covariance matrix), Qxx, is defined as:
+        # Qxx = (J^t W J)^(-1)
+
+        # Calculate step by step, by matrix multiplication.
         Jt = transpose(J)
-
-        # Calc
         Jt_W = dot(Jt, W)
         Jt_W_J = dot(Jt_W, J)
-        print Jt_W_J
+
+        # Invert matrix.
         Qxx = inv(Jt_W_J)
+
+        return Qxx
+

 # 'minfx'
 # 'scipy.optimize.leastsq'
@@ -706,16 +734,17 @@
     E.set_settings_minfx(min_algor=min_algor)

     # Do C code
-    do_C = True
+    do_C = False

     if do_C:
         # Initialise the function to minimise.
         scaling_list = [1.0, 1.0]
         setup(num_params=len(x0), num_times=len(E.times), values=E.values, 
sd=E.errors, relax_times=E.times, scaling_matrix=scaling_list)

-        t_func = func
-        t_dfunc = dfunc
-        t_d2func = d2func
+
+        t_func = func_wrapper
+        t_dfunc = dfunc_wrapper
+        t_d2func = d2func_wrapper

     else:
         # Minimise with minfx.
@@ -737,13 +766,18 @@
     param_vector, chi2, iter_count, f_count, g_count, h_count, warning = 
results_minfx

     # Get the Jacobian.
-    jacobian_matrix = E.func_exp_grad(param_vector)
-
-    # Get the covariance.
-    #a = E.multifit_cova(J=jacobian_matrix)
+    # First make a call to the Jacobian function, which store it in the 
class.
+    E.func_exp_grad(params=param_vector)
+    jacobian_matrix = deepcopy(E.jacobian_matrix)

     # Set error to inf.
-    param_vector_error = [inf, inf]
+    #param_vector_error = [inf, inf]
+
+    # Get the co-variance
+    pcov = E.multifit_covar(J=jacobian_matrix)
+
+    # To compute one standard deviation errors on the parameters, take the 
square root of the diagonal covariance.
+    param_vector_error = sqrt(diag(pcov))

     # Pack to list.
     results = [param_vector, param_vector_error, chi2, iter_count, 
f_count, g_count, h_count, warning]


_______________________________________________
relax (http://www.nmr-relax.com)

This is the relax-commits mailing list
relax-commits@xxxxxxx

To unsubscribe from this list, get a password
reminder, or change your subscription options,
visit the list information page at
https://mail.gna.org/listinfo/relax-commits



Related Messages


Powered by MHonArc, Updated Thu Aug 28 14:20:26 2014