I want to define a function with a lot of arguments. I do not know what is the best way not to write the argument directly and to read the function arguments from something like an array or anything else that works well. here is an example to convey my meaning in a better way:
bin=[4,4.5,5,5.5]
def interpo(x,A,B, C, D):
result=[]
for i in range(len(x)):
x2, x1=x[i,0:2]
if (x1 >= bin[0]) & (x1 <bin[1]):
if (x2>= bin[0]) & (x2<bin[1]):
f1=A + ((x1 -bin[0])/(bin[1]-bin[0]))*(B-A)
f2=A + ((x2 -bin[0])/(bin[1]-bin[0]))*(B-A)
kh=f2/f1
if x2>= bin[1] and x2<bin[2]:
f1=A + ((x1 -bin[0])/(bin[1]-bin[0]))*(B-A)
f2=B + ((x2 -bin[1])/(bin[2]-bin[1]))*(C-B)
kh=f2/f1
if x2>= bin[2] and x2<bin[3]:
f1=A + ((x1 -bin[0])/(bin[1]-bin[0]))*(B-A)
f2=C + ((x2 -bin[2])/(bin[3]-bin[2]))*(D-C)
kh=f2/f1
if x1>= bin[1] and x1<bin[2]:
if x2>= bin[1] and x2<bin[2]:
f1=B + ((x1 -bin[1])/(bin[2]-bin[1]))*(C-B)
f2=B + ((x2 -bin[1])/(bin[2]-bin[1]))*(C-B)
kh=f2/f1
if x2>= bin[2] and x2<bin[3]:
f1=B + ((x1 -bin[1])/(bin[2]-bin[1]))*(C-B)
f2=C + ((x2 -bin[2])/(bin[3]-bin[2]))*(D-C)
kh=f2/f1
if x1>= bin[2] and x1<bin[3]:
if x2>= bin[2] and x2<bin[3]:
f1=C + ((x1 -bin[2])/(bin[3]-bin[2]))*(D-C)
f2=C + ((x2 -bin[2])/(bin[3]-bin[2]))*(D-C)
kh=f2/f1
result.append(kh)
return result
I want to call A, B, C, D form something like an array if possible (like what I have done for bin, for example bin[0] instead of 4 ). I mean something like this:
array=[A,B,C,D]
so that I can simply write for example array[0] or something like that instead of writing directly A.
Is that possible at all? if yes, any suggestion would be appreciated.
*****Edited
I did what you suggested, there is no problem with the function definition, but when I want to use the function for curve fitting I get an error.
This is what I have done:
bin=[4,4.5,5,5.5]
arg=['A','B','C','D']
def interpo1(x,*arg):
result=[]
for i in range(len(x)):
x2, x1=x[i,0:2]
if (x1 >= bin[0]) & (x1 <bin[1]):
if (x2>= bin[0]) & (x2<bin[1]):
f1=arg[0] + ((x1 -bin[0])/(bin[1]-bin[0]))*(arg[1]-arg[0])
f2=arg[0] + ((x2 -bin[0])/(bin[1]-bin[0]))*(arg[1]-arg[0])
kh=f2/f1
if x2>= bin[1] and x2<bin[2]:
f1=arg[0] + ((x1 -bin[0])/(bin[1]-bin[0]))*(arg[1]-arg[0])
f2=arg[1] + ((x2 -bin[1])/(bin[2]-bin[1]))*(arg[2]-arg[1])
kh=f2/f1
if x2>= bin[2] and x2<bin[3]:
f1=arg[0] + ((x1 -bin[0])/(bin[1]-bin[0]))*(arg[1]-arg[0])
f2=arg[2] + ((x2 -bin[2])/(bin[3]-bin[2]))*(arg[3]-arg[2])
kh=f2/f1
if x1>= bin[1] and x1<bin[2]:
if x2>= bin[1] and x2<bin[2]:
f1=arg[1] + ((x1 -bin[1])/(bin[2]-bin[1]))*(arg[2]-arg[1])
f2=arg[1] + ((x2 -bin[1])/(bin[2]-bin[1]))*(arg[2]-arg[1])
kh=f2/f1
if x2>= bin[2] and x2<bin[3]:
f1=arg[1] + ((x1 -bin[1])/(bin[2]-bin[1]))*(arg[2]-arg[1])
f2=arg[2] + ((x2 -bin[2])/(bin[3]-bin[2]))*(arg[3]-arg[2])
kh=f2/f1
if x1>= bin[2] and x1<bin[3]:
if x2>= bin[2] and x2<bin[3]:
f1=arg[2] + ((x1 -bin[2])/(bin[3]-bin[2]))*(arg[3]-arg[2])
f2=arg[2] + ((x2 -bin[2])/(bin[3]-bin[2]))*(arg[3]-arg[2])
kh=f2/f1
result.append(kh)
return result
popt1, pcov1 = curve_fit(interpo1,x, y, method='lm')
A,B,C,D=popt1
and this is the error:
popt1, pcov1 = curve_fit(interpo1,x, y, method='lm')
File /opt/anaconda3/lib/python3.9/site-packages/scipy/optimize/minpack.py:710 in curve_fit
raise ValueError("Unable to determine number of fit parameters.")
ValueError: Unable to determine number of fit parameters.
Many thanks in advance for any help!