mailr25235 - /trunk/target_functions/relax_disp_curve_fit.py


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

Header


Content

Posted by tlinnet on August 25, 2014 - 01:08:
Author: tlinnet
Date: Mon Aug 25 01:08:58 2014
New Revision: 25235

URL: http://svn.gna.org/viewcvs/relax?rev=25235&view=rev
Log:
Documentation fix for new exponential target function.

Also added new function to estimate R2eff and i0 parameters, before 
minimisation.

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

Modified:
    trunk/target_functions/relax_disp_curve_fit.py

Modified: trunk/target_functions/relax_disp_curve_fit.py
URL: 
http://svn.gna.org/viewcvs/relax/trunk/target_functions/relax_disp_curve_fit.py?rev=25235&r1=25234&r2=25235&view=diff
==============================================================================
--- trunk/target_functions/relax_disp_curve_fit.py      (original)
+++ trunk/target_functions/relax_disp_curve_fit.py      Mon Aug 25 01:08:58 
2014
@@ -21,58 +21,62 @@
 
###############################################################################
 
 # Module docstring.
-"""Target functions for relaxation fit."""
+"""Target functions for relaxation exponential curve fitting with both minfx 
and scipy.optimize.leastsq."""
 
 # Python module imports.
 from copy import deepcopy
-from numpy import exp, multiply, sum
+from numpy import dot, exp, log, multiply, sum
 
 # relax module imports.
+from target_functions.chi2 import chi2_rankN
 
 
 class Exponential:
-    def __init__(self, num_params=None, num_times=None, values=None, 
sd=None, relax_times=None, scaling_matrix=None):
+    def __init__(self, num_params=2, num_times=None, values=None, sd=None, 
relax_times=None, scaling_matrix=None):
         """Relaxation dispersion target functions for optimisation.
+
+        This class contains minimisation functions for both minfx and 
scipy.optimize.leastsq.
+
+        @keyword num_param:         The number of parameters in the model.
+        @type num_param:            int
+        @keyword num_times:         The number of time points.
+        @type num_times:            int
+        @keyword values:            The measured intensity values per time 
point.
+        @type values:               numpy array
+        @keyword sd:                The standard deviation of the measured 
intensity values per time point.
+        @type sd:                   numpy array
+        @keyword relax_times:       The time points.
+        @type relax_times:          numpy array
+        @keyword scaling_matrix:    The square and diagonal scaling matrix.
+        @type scaling_matrix:       numpy rank-2 float array
         """
 
         # Store variables.
         self.num_params = num_params
         self.num_times = num_times
+
         self.values = values
         self.errors = sd
         self.relax_times = relax_times
         self.scaling_matrix = scaling_matrix
 
+        # Scaling initialisation.
+        self.scaling_flag = False
+        if self.scaling_matrix != None:
+            self.scaling_flag = True
+
         # Create the structure for holding the back-calculated R2eff values 
(matching the dimensions of the values structure).
         self.back_calc = deepcopy(self.values)
 
-        # Define function to minimise.
+        # Define function to minimise for minfx.
         self.func = self.func_exp
-        self.calc = self.calc_exp
-
-
-    def chi2_rankN(self, data, back_calc_vals, errors):
-        """Function to calculate the chi-squared value for multiple numpy 
array axis.
-
-        @param data:            The multi dimensional vectors of yi values.
-        @type data:             numpy multi dimensional array
-        @param back_calc_vals:  The multi dimensional vectors of yi(theta) 
values.
-        @type back_calc_vals:   numpy multi dimensional array
-        @param errors:          The multi dimensional vectors of sigma_i 
values.
-        @type errors:           numpy multi dimensional array
-        @return:                The chi-squared value.
-        @rtype:                 float
-        """
-
-        # Calculate the chi-squared statistic.
-        return sum((1.0 / errors * (data - back_calc_vals))**2)
 
 
     def calc_exp(self, times=None, r2eff=None, i0=None):
         """Calculate the function values of exponential function.
 
         @keyword times: The time points.
-        @type times:    float
+        @type times:    numpy array
         @keyword r2eff: The effective transversal relaxation rate.
         @type r2eff:    float
         @keyword i0:    The initial intensity.
@@ -83,6 +87,35 @@
 
         # Calculate.
         return i0 * exp( -times * r2eff)
+
+
+    def estimate_x0_exp(self, intensities=None, times=None):
+        """Estimate starting parameter x0 = [r2eff_est, i0_est], by 
converting the exponential curve to a linear problem.
+         Then solving by linear least squares of: ln(Intensity[j]) = ln(i0) 
- time[j]* r2eff.
+
+        @keyword intensities:   The measured intensity values per time point.
+        @type intensities:      numpy array
+        @keyword times:         The time points.
+        @type times:            numpy array
+        @return:                The list with estimated r2eff and i0 
parameter for optimisation, [r2eff_est, i0_est]
+        @rtype:                 list
+        """
+
+        # Convert to linear problem.
+        w = log(intensities)
+        x = - 1. * times
+        n = len(times)
+
+        # Solve by linear least squares.
+        b = (sum(x*w) - 1./n * sum(x) * sum(w) ) / ( sum(x**2) - 1./n * 
(sum(x))**2 )
+        a = 1./n * sum(w) - b * 1./n * sum(x)
+
+        # Convert back from linear to exp function. Best estimate for 
parameter.
+        r2eff_est = b
+        i0_est = exp(a)
+
+        # Return.
+        return [r2eff_est, i0_est]
 
 
     def calc_exp_chi2(self, r2eff=None, i0=None):
@@ -101,17 +134,21 @@
         self.back_calc[:] = self.calc_exp(times=self.relax_times, 
r2eff=r2eff, i0=i0)
 
         # Return the total chi-squared value.
-        return self.chi2_rankN(data=self.values, 
back_calc_vals=self.back_calc, errors=self.errors)    
+        return chi2_rankN(data=self.values, back_calc_vals=self.back_calc, 
errors=self.errors)
 
 
     def func_exp(self, params):
-        """Target function for exponential fit.
+        """Target function for exponential fit in minfx.
 
         @param params:  The vector of parameter values.
         @type params:   numpy rank-1 float array
         @return:        The chi-squared value.
         @rtype:         float
         """
+
+        # Scaling.
+        if self.scaling_flag:
+            params = dot(params, self.scaling_matrix)
 
         # Unpack the parameter values.
         r2eff = params[0]
@@ -121,15 +158,37 @@
         return self.calc_exp_chi2(r2eff=r2eff, i0=i0)
 
 
-    def func_exp_general(self, params, xdata, ydata):
-        """Target function for minimisation with scipy.optimize.leastsq
+    def func_exp_general(self, params, times, intensities):
+        """Target function for minimisation with scipy.optimize.leastsq.
+
+        @param params:          The vector of parameter values.
+        @type params:           numpy rank-1 float array
+        @keyword times:         The time points.
+        @type times:            numpy array
+        @keyword intensities:   The measured intensity values per time point.
+        @type intensities:      numpy array
+        @return:                The difference between function evaluation 
with fitted parameters and measured values.
+        @rtype:                 numpy array
         """
 
-        return self.calc_exp(xdata, *params) - ydata
+        # Return
+        return self.calc_exp(times, *params) - intensities
 
 
-    def func_exp_weighted_general(self, params, xdata, ydata, weights):
-        """Target function for minimisation with scipy.optimize.leastsq
+    def func_exp_weighted_general(self, params, times, intensities, weights):
+        """Target function for weighted minimisation with 
scipy.optimize.leastsq.
+
+        @param params:          The vector of parameter values.
+        @type params:           numpy rank-1 float array
+        @keyword times:         The time points.
+        @type times:            numpy array
+        @keyword intensities:   The measured intensity values per time point.
+        @type intensities:      numpy array
+        @keyword weights:       The weights to multiply the function 
evaluation.  Should be supplied as '1/sd', where sd is the standard deviation 
of the measured intensity values.
+        @type weights:          numpy array
+        @return:                The weighted difference between function 
evaluation with fitted parameters and measured values.
+        @rtype:                 numpy array
         """
 
-        return weights * (self.calc_exp(xdata, *params) - ydata)
+        # Return
+        return weights * (self.calc_exp(times, *params) - intensities)




Related Messages


Powered by MHonArc, Updated Mon Aug 25 01:20:02 2014