Author: tlinnet
Date: Mon Aug 25 15:22:55 2014
New Revision: 25245
URL: http://svn.gna.org/viewcvs/relax?rev=25245&view=rev
Log:
Split function to minimise with scipy.optimize.leastsq out in estimate_r2eff
module.
This is to prepare for implementing with minfx.
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=25245&r1=25244&r2=25245&view=diff
==============================================================================
--- trunk/specific_analyses/relax_disp/estimate_r2eff.py (original)
+++ trunk/specific_analyses/relax_disp/estimate_r2eff.py Mon Aug 25
15:22:55 2014
@@ -205,7 +205,7 @@
return weights * (self.calc_exp(times, *params) - intensities)
-def estimate_r2eff(spin_id=None, ftol=1e-15, xtol=1e-15, maxfev=10000000,
factor=100.0, verbosity=1):
+def estimate_r2eff(spin_id=None, ftol=1e-15, xtol=1e-15, maxfev=10000000,
factor=100.0, method='scipy.optimize.leastsq', verbosity=1):
"""Estimate r2eff and errors by exponential curve fitting with
scipy.optimize.leastsq.
scipy.optimize.leastsq is a wrapper around MINPACK's lmdif and lmder
algorithms.
@@ -231,19 +231,21 @@
@type maxfev: int
@keyword factor: The initial step bound, parsed to leastsq. It
determines the initial step bound (''factor * || diag * x||''). Should be in
the interval (0.1, 100).
@type factor: float
+ @keyword method: The method to minimise and estimate errors.
Options are: 'scipy.optimize.leastsq'.
+ @type method: string
@keyword verbosity: The amount of information to print. The
higher the value, the greater the verbosity.
@type verbosity: int
"""
- # Check that scipy.optimize.leastsq is available.
- if not scipy_module:
- raise RelaxError("scipy module is not available.")
-
# Perform checks.
check_model_type(model=MODEL_R2EFF)
+ # Set list with scipy setting.
+ scipy_settings = [ftol, xtol, maxfev, factor]
+
# Initialise target function class, to access functions.
- exp_class = Exponential()
+ if method == 'scipy.optimize.leastsq':
+ exp_class = Exponential()
# Check if intensity errors have already been calculated by the user.
precalc = True
@@ -313,82 +315,23 @@
errors = asarray(errors)
times = asarray(times)
- # Initial guess for minimisation. Solved by linear least squares.
- x0 = exp_class.estimate_x0_exp(intensities=values, times=times)
-
- # Define function to minimise. Use errors as weights in the
minimisation.
- use_weights = True
-
- # If 'sigma'/erros describes one standard deviation errors of the
input data points. The estimated covariance in 'pcov' is based on these values.
- absolute_sigma = True
-
- if use_weights:
- func = exp_class.func_exp_weighted_general
- weights = 1.0 / asarray(errors)
- args=(times, values, weights )
+ # Get the result based on method.
+ if method == 'scipy.optimize.leastsq':
+ results = minimise_leastsq(exp_class=exp_class,
scipy_settings=scipy_settings, values=values, errors=errors, times=times)
else:
- func = exp_class.func_exp_general
- args=(times, values)
-
- # Call scipy.optimize.leastsq.
- popt, pcov, infodict, errmsg, ier = leastsq(func=func, x0=x0,
args=args, full_output=True, ftol=ftol, xtol=xtol, maxfev=maxfev, factor=factor)
-
- # Catch errors:
- if ier in [1, 2, 3, 4]:
- warning = None
- elif ier in [9]:
- warn(RelaxWarning("%s." % errmsg))
- warning = errmsg
- elif ier in [0, 5, 6, 7, 8]:
- raise RelaxError("scipy.optimize.leastsq raises following
error: '%s'." % errmsg)
-
- # 'nfev' number of function calls.
- f_count = infodict['nfev']
-
- # 'fvec': function evaluated at the output.
- fvec = infodict['fvec']
- #fvec_test = func(popt, times, values)
-
- # 'fjac': A permutation of the R matrix of a QR factorization of
the final approximate Jacobian matrix, stored column wise. Together with ipvt,
the covariance of the estimate can be approximated.
- # fjac = infodict['fjac']
-
- # 'qtf': The vector (transpose(q) * fvec).
- # qtf = infodict['qtf']
-
- # 'ipvt' An integer array of length N which defines a permutation
matrix, p, such that fjac*p = q*r, where r is upper triangular
- # with diagonal elements of nonincreasing magnitude. Column j of p
is column ipvt(j) of the identity matrix.
-
- # Back calc fitted curve.
- back_calc = exp_class.calc_exp(times=times, r2eff=popt[0],
i0=popt[1])
-
- # Calculate chi2.
- chi2 = chi2_rankN(data=values, back_calc_vals=back_calc,
errors=errors)
-
- # 'pcov': The estimated covariance of popt.
- # The diagonals provide the variance of the parameter estimate.
-
- if pcov is None:
- # indeterminate covariance
- pcov = zeros((len(popt), len(popt)), dtype=float)
- pcov.fill(inf)
- elif not absolute_sigma:
- if len(values) > len(x0):
- s_sq = sum( fvec**2 ) / (len(values) - len(x0))
- pcov = pcov * s_sq
- else:
- pcov.fill(inf)
-
- # To compute one standard deviation errors on the parameters, take
the square root of the diagonal covariance.
- perr = sqrt(diag(pcov))
+ raise RelaxError("Method for minimisation not known. Try
setting: method='scipy.optimize.leastsq'.")
+
+ # Unpack results
+ param_vector, param_vector_error, chi2, iter_count, f_count,
g_count, h_count, warning = results
# Extract values.
- r2eff = popt[0]
- i0 = popt[1]
- r2eff_err = perr[0]
- i0_err = perr[1]
+ r2eff = param_vector[0]
+ i0 = param_vector[1]
+ r2eff_err = param_vector_error[0]
+ i0_err = param_vector_error[1]
# Disassemble the parameter vector.
- disassemble_param_vector(param_vector=popt, spins=[cur_spin],
key=param_key)
+ disassemble_param_vector(param_vector=param_vector,
spins=[cur_spin], key=param_key)
# Errors.
if not hasattr(cur_spin, 'r2eff_err'):
@@ -427,3 +370,111 @@
if len(print_strings) > 0:
for print_string in print_strings:
print(print_string),
+
+
+def minimise_leastsq(exp_class=None, scipy_settings=None, values=None,
errors=None, times=None):
+ """Estimate r2eff and errors by exponential curve fitting with
scipy.optimize.leastsq.
+
+ @keyword exp_class: The class instance object, which contains
functions to calculate with.
+ @type exp_class: class
+ @keyword scipy_settings: The parsed setting to leastsq. scipy_settings
= [ftol, xtol, maxfev, factor]
+ @type scipy_settings: list of float, float, int, float
+ @keyword values: The measured intensity values per time point.
+ @type values: numpy array
+ @keyword errors: The standard deviation of the measured
intensity values per time point.
+ @type errors: numpy array
+ @keyword times: The time points.
+ @type times: numpy array
+ @return: Packed list with optimised parameter,
estimated parameter error, chi2, iter_count, f_count, g_count, h_count, warning
+ @rtype: list
+ """
+
+ # Check that scipy.optimize.leastsq is available.
+ if not scipy_module:
+ raise RelaxError("scipy module is not available.")
+
+ # Unpack settings:
+ ftol, xtol, maxfev, factor = scipy_settings
+
+ # Initial guess for minimisation. Solved by linear least squares.
+ x0 = exp_class.estimate_x0_exp(intensities=values, times=times)
+
+ # Define function to minimise. Use errors as weights in the minimisation.
+ use_weights = True
+
+ # If 'sigma'/erros describes one standard deviation errors of the input
data points. The estimated covariance in 'pcov' is based on these values.
+ absolute_sigma = True
+
+ if use_weights:
+ func = exp_class.func_exp_weighted_general
+ weights = 1.0 / asarray(errors)
+ args=(times, values, weights)
+ else:
+ func = exp_class.func_exp_general
+ args=(times, values)
+
+ # Call scipy.optimize.leastsq.
+ popt, pcov, infodict, errmsg, ier = leastsq(func=func, x0=x0, args=args,
full_output=True, ftol=ftol, xtol=xtol, maxfev=maxfev, factor=factor)
+
+ # Catch errors:
+ if ier in [1, 2, 3, 4]:
+ warning = None
+ elif ier in [9]:
+ warn(RelaxWarning("%s." % errmsg))
+ warning = errmsg
+ elif ier in [0, 5, 6, 7, 8]:
+ raise RelaxError("scipy.optimize.leastsq raises following error:
'%s'." % errmsg)
+
+ # 'nfev' number of function calls.
+ f_count = infodict['nfev']
+
+ # 'fvec': function evaluated at the output.
+ fvec = infodict['fvec']
+ #fvec_test = func(popt, times, values)
+
+ # 'fjac': A permutation of the R matrix of a QR factorization of the final
approximate Jacobian matrix, stored column wise. Together with ipvt, the
covariance of the estimate can be approximated.
+ # fjac = infodict['fjac']
+
+ # 'qtf': The vector (transpose(q) * fvec).
+ # qtf = infodict['qtf']
+
+ # 'ipvt' An integer array of length N which defines a permutation matrix,
p, such that fjac*p = q*r, where r is upper triangular
+ # with diagonal elements of nonincreasing magnitude. Column j of p is
column ipvt(j) of the identity matrix.
+
+ # Back calc fitted curve.
+ back_calc = exp_class.calc_exp(times=times, r2eff=popt[0], i0=popt[1])
+
+ # Calculate chi2.
+ chi2 = chi2_rankN(data=values, back_calc_vals=back_calc, errors=errors)
+
+ # 'pcov': The estimated covariance of popt.
+ # The diagonals provide the variance of the parameter estimate.
+
+ if pcov is None:
+ # indeterminate covariance
+ pcov = zeros((len(popt), len(popt)), dtype=float)
+ pcov.fill(inf)
+ elif not absolute_sigma:
+ if len(values) > len(x0):
+ s_sq = sum( fvec**2 ) / (len(values) - len(x0))
+ pcov = pcov * s_sq
+ else:
+ pcov.fill(inf)
+
+ # To compute one standard deviation errors on the parameters, take the
square root of the diagonal covariance.
+ perr = sqrt(diag(pcov))
+
+ # Return as standard from minfx.
+ param_vector = popt
+ param_vector_error = perr
+
+ iter_count = 0
+ g_count = 0
+ h_count = 0
+
+ # Pack to list.
+ results = [param_vector, param_vector_error, chi2, iter_count, f_count,
g_count, h_count, warning]
+
+ # Return, including errors.
+ return results
+
_______________________________________________
relax (http://www.nmr-relax.com)
This is the relax-commits mailing list
[email protected]
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