Open kevinxxq opened 2 years ago
Hi @kevinxxq, thanks for your question! I'm not sure I understand your problem tough. The symfit model dict can have any number of elements in it, e.g.
x_1, x_2, y_1, y_2 = variables('x_1, x_2, y_1, y_2')
y0, a_1, a_2, b_1, b_2 = parameters('y0, a_1, a_2, b_1, b_2')
model_dict = {
y_1: y0 + a_1 * exp(- b_1 * x_1),
y_2: y0 + a_2 * exp(- b_2 * x_2),
}
such as the example taken from here: https://symfit.readthedocs.io/en/stable/fitting_types.html#fitting-multiple-datasets. Maybe that helps? If not, maybe you can reformulate the question? I've had a look at the stackoverflow question but that deals with automatically generating the model, is that your problem?
Thank you for so quick reply.
Not true. I don't know the left part of below declarification:
x_1, x_2, y_1, y_2 = variables('x_1, x_2, y_1, y_2')
The variables come from the caller when the function is called,the signature of my function is something as below.
def my_fit_function(expr,list_var,list_para,dict_data(key_var,list_data))->list_para:
expr: a*x+b
list_var:[x,y]
list_para:[a,b]
dict_data:{x:[1,2,...10],y:[2,4,6...20]}
Thank you.
It's a bit unclear to me what you're exactly asking, and your code snippet also does not add clarity.
The variables
function does no magic. It simply returns a list of Variable
objects. Beyond that x_1, x_2, y_1, y_2 = variables('x_1, x_2, y_1, y_2')
is just tuple unpacking. So you could do:
list_of_variables = variables('x, y, z')
x, y, z = list_of_variables # This is optional! You can also use list_of_variables[0] to get x, etc.
@pckroon Thank you for involving. Sorry for the inconvenience.
Yes, I understand that the variables are tuple unpacking.
The problem is that I don't know the symbols for a sympy expression. I can't define x,y=variables("x,y) since it may be x_1,x_2=variables("x_1,x_2)
The way it would be possible or I expect is:
list_of_variables = variables('x, y, z')
list_of_parameters = parameters('a, b, c')
fit=Fit(expr,list_of_variables,list_of_parameters,dict_data(key_var,list_data),...)
fit_result = fit.execute()
Thank you.
It's still not clear to me what you need/want. If you need the symbol names to pass the relevant data to Fit you can use dictionary unpacking. Otherwise I really need you to phrase your question more carefully: What do you want to achieve, what have you tried, what functionality are you missing.
Do you know the number of variables and/or parameters?
from symfit import variables, parameters
from functools import reduce
from operator import add
num_terms = 5
var_names = [f'x_{i}' for i in range(num_terms)]
par_names = [f'a_{i}' for i in range(num_terms)]
var_tup = variables(', '.join(var_names))
par_tup = parameters(', '.join(par_names))
expression = reduce(add, [a*v**i for i, (v, a) in enumerate(zip(var_tup, par_tup))])
expression
>>> a_0 + a_1*x_1 + a_2*x_2**2 + a_3*x_3**3 + a_4*x_4**4
You can then do fitting by passing a dict with var_names
as keys
Thank you ALL, sorry that is me to consider it too simplistic or idealized:
def my_fit_function(expr,list_var,list_para,dict_data(key_var,list_data))->list_para:
It will work as a powerful funtion to any expresion, any number of variables/parameters.
I just want to wrap the code in python to serve other clients who don't know anything about python. They need pass the expression, list of variables in str, list of paramers in str, dict(str_variable, data), then they can get the fitted parameters(list of parameters).
So I expect:
fit=Fit(expr,list_of_variables,list_of_parameters,dict_data(key_var,list_data),...) # here inside Fit class, zip(list_of_variables) would be helpful to evaluate expr. Sorry I didn't get into the internal implentation
fit_result = fit.execute()
It may be impossible now, I will try to split it to serveral different functions.
Thank you again.
Ok. You'll need a way to turn your string expression into a sympy expression with the appropriate Variable
/Parameter
objects. That is out of scope for this issue/discussion though. It doesn't help for this discussion that your signature has a list_var
, but it's actually a string, same for expr
.
If you have a string of variables as you feed them to variables
you know they're comma-separated, so you can do my_string_of_variables.split(',')
to get all your variable names. Otherwise all Variable
objects have a name
attribute and str(my_var)
will also do what you expect.
It's still not clear to me where you get stuck, we won't write your adapter function for you.
Hi, @tBuLi , thank you for the package. Just as https://stackoverflow.com/questions/55580926/how-to-extend-the-number-of-symfit-parameters-arbitrarily-in-python, I would like to wrap this package for api: model: (dict of) sympy expression(s). e.g; a * x+ b variables: x,y parameters: a,b
Here is your example:
Now it turns to a different arbitrary way: a,b may be c,d, x,y may be x1,y1
I will pass a list of varibles and parameters such as "a, b, c, d" and "x, y, z" and a related sympy expression.
How can I handle it?
Thank you very much!