#13273: extension of sage.numerical.optimize.find_fit
-----------------------------------------------------------+----------------
Reporter: hackstein | Owner:
hackstein
Type: enhancement | Status:
needs_review
Priority: major | Milestone:
sage-5.3
Component: numerical | Resolution:
Keywords: fitting, interpolation, two-dimensional | Work issues:
enhancement
Report Upstream: N/A | Reviewers:
evanandel, was, ncohen
Authors: Urs Hackstein | Merged in:
Dependencies: | Stopgaps:
-----------------------------------------------------------+----------------
Comment (by hackstein):
I fixed some errors (see the updated code below), but it still don't fit
together with the leastsq routine. Thus any comments and improvement would
be highly appreciated as it is my first ticket.
def find_fit2dim(data, model, initial_guess=None, parameters=None,
variables=None, solution_dict=False):
r"""
Finds numerical estimates for the parameters of the two-dimensional
function model to
give a best fit to data.
INPUT:
- ``data`` -- A two dimensional table of floating point numbers of the
form `[[x_{1,1}, x_{1,2}, f_{1,1}, f_{1,2}],
[x_{2,1}, x_{2,2}, f_{2,1}, f_{2,2}],
\ldots,
[x_{n,1}, x_{n,2}, f_{n,1}, f_{n,2}]]` given as either a
numpy array.
- ``model`` -- Either a pair of symbolic expressions, of symbolic
functions, or
of Python function. ``model`` has to be a function of the variables
`(x_1, x_2, \ldots, x_k)` and free parameters
`(a_1, a_2, \ldots, a_l)`.
- ``initial_guess`` -- (default: ``None``) Initial estimate for the
parameters `(a_1, a_2, \ldots, a_l)`, given as either a list, tuple,
vector or numpy array. If ``None``, the default estimate for each
parameter is `1`.
- ``parameters`` -- (default: ``None``) A list of the parameters
`(a_1, a_2, \ldots, a_l)`. If model is a symbolic function it is
ignored, and the free parameters of the symbolic function are used.
- ``variables`` -- (default: ``None``) A list of the variables
`(x_1, x_2, \ldots, x_k)`. If model is a symbolic function it is
ignored, and the variables of the symbolic function are used.
- ``solution_dict`` -- (default: ``False``) if ``True``, return the
solution as a dictionary rather than an equation.
EXAMPLES:
ALGORITHM:
Uses ``scipy.optimize.leastsq`` which in turn uses MINPACK's lmdif and
lmder algorithms.
"""
import numpy
if not isinstance(data, numpy.ndarray):
try:
data = numpy.array(data, dtype = float)
except (ValueError, TypeError):
raise TypeError, "data has to be a numpy array"
elif data.dtype == object:
raise ValueError, "the entries of data have to be of type float"
if data.ndim != 2:
raise ValueError, "data has to be a two dimensional table of
floating point numbers"
from sage.symbolic.expression import Expression
if isinstance(model[0], Expression) and
isinstance(model[1],Expression):
if variables is None:
variables = list(model[0].arguments())
if parameters is None:
L=list(model[0].variables())
M=list(model[1].variables())
for v in L:
if v in M:
M.remove(v)
parameters=L+M
for v in variables:
parameters.remove(v)
if data.shape[1] != len(variables) + 2:
raise ValueError, "each row of data needs %d entries, only %d
entries given" % (len(variables) + 2, data.shape[1])
if parameters is None or len(parameters) == 0 or \
variables is None or len(variables) == 0:
raise ValueError, "no variables given"
if initial_guess == None:
initial_guess = len(parameters) * [1]
if not isinstance(initial_guess, numpy.ndarray):
try:
initial_guess = numpy.array(initial_guess, dtype = float)
except (ValueError, TypeError):
raise TypeError, "initial_guess has to be a list, tuple, or
numpy array"
elif initial_guess.dtype == object:
raise ValueError, "the entries of initial_guess have to be of type
float"
if len(initial_guess) != len(parameters):
raise ValueError, "length of initial_guess does not coincide with
the number of parameters"
if isinstance(model[0], Expression) and
isinstance(model[1],Expression):
var_list = variables + parameters
var_names = map(str, var_list)
func = (model[0]._fast_float_(*var_names),
model[1]._fast_float_(*var_names))
else:
func = model
def function(x1_data, x2_data, params):
s=(len(x1_data), 2)
result = numpy.zeros(s)
for row in xrange(len(x1_data)):
fparams = numpy.hstack((x1_data[row],
x2_data[row],params)).tolist()
result[row] = (func[0](*fparams),func[1](*fparams))
return result
def error_function(params, x1_data, x2_data, y1_data, y2_data):
t=(len(x1_data),2)
result = numpy.zeros(t)
for row in xrange(len(x1_data)):
fparams = [x1_data[row], x2_data[row]]+ params.tolist()
result[row]= (func[0](*fparams), func[1](*fparams))
return numpy.array([result[:,-2] - y1_data, result[:,-1] -
y2_data])
x1_data = data[:, -4]
x2_data = data[:, -3]
y1_data = data[:, -2]
y2_data = data[:,-1]
from scipy.optimize import leastsq
estimated_params, d = leastsq(error_function, initial_guess, args =
(x1_data, x2_data, y1_data, y2_data))
if isinstance(estimated_params, float):
estimated_params = [estimated_params]
else:
estimated_params = estimated_params.tolist()
if solution_dict:
dict = {}
for item in zip(parameters, estimated_params):
dict[item[0]] = item[1]
return dict
return [item[0] == item[1] for item in zip(parameters,
estimated_params)]
--
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/13273#comment:6>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica,
and MATLAB
--
You received this message because you are subscribed to the Google Groups
"sage-trac" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sage-trac?hl=en.