在 Python 中缩短冗长且重复的方程式
Shortening long and repetitive equations in Python
我有这么长的等式
def equation(x, s, z, m, p1, f1, g1, e1, p2, f2, g2, e2, p3, f3, g3, e3, p4, f4, g4, e4, p5, f5, g5, e5,
p6, f6, g6, e6, p7, f7, g7, e7):
return float(s) + (float(z) / pow(x, float(m))) + (float(p1) * (1 + float(e1) * (x - float(f1))) / (
pow((x - float(f1)), 2) + pow((float(g1) / 2), 2)) + float(p2) * (1 + float(e2) * (x - float(f2))) / (
pow((x - float(f2)), 2) + pow((float(g2) / 2), 2)) + float(p3) * (1 + float(e3) * (x - float(f3))) / (
pow((x - float(f3)), 2) + pow((float(g3) / 2), 2)) + float(p4) * (1 + float(e4) * (x - float(f4))) / (
pow((x - float(f4)), 2) + pow((float(g4) / 2), 2)) + float(p5) * (1 + float(e5) * (x - float(f5))) / (
pow((x - float(f5)), 2) + pow((float(g5) / 2), 2)) + float(p6) * (1 + float(e6) * (x - float(f6))) / (
pow((x - float(f6)), 2) + pow((float(g6) / 2), 2)) + float(p7) * (1 + float(e7) * (x - float(f7))) / (
pow((x - float(f7)), 2) + pow((float(g7) / 2), 2)))
如您所见,但开头和数字是相同的,有没有办法用循环或其他方法缩短它?我想过列表理解,但我不知道如何在这个例子中写它。
干杯!
这是我的尝试:
def equation(x, s, z, m, es, fs, gs, ps):
something = sum(
p * (1 + e * (x - f)) / (pow(x - f, 2) + pow(g / 2, 2))
for e, f, g, p in zip(es, fs, gs, ps)
)
return s + z / pow(x, m) + something
其中:
es = [e1, e2, ...]
fs = [f1, f2, ...]
gs = ...
ps = ...
您实际上不需要明确指定 float
类型转换,因为 python 会 "automatically"。
这里是不改变参数顺序的变体。
def equation2(x, s, z, m, *params):
def subeq(x, p, f, g, e):
return (float(p) * (1 + float(e) * (x - float(f))) /
(pow((x - float(f)), 2) + pow((float(g) / 2), 2)))
return (float(s) + (float(z) / pow(x, float(m))) +
sum(subeq(x, *pfge) for pfge in zip(*([iter(params)]*4))))
可读性不是很好,只是把x,s,z,m之后的所有参数分成四组,计算重复表达式之和
这是我针对这种情况的解决方案:
def equation(x, s, z, m, p1, f1, g1, e1, p2, f2, g2, e2, p3, f3, g3, e3, p4, f4, g4, e4, p5, f5, g5, e5,
p6, f6, g6, e6, p7, f7, g7, e7):
plist = [[p1, p2, p3, p4, p5, p6, p7],
[f1, f2, f3, f4, f5, f6, f7],
[g1, g2, g3, g4, g5, g6, g7],
[e1, e2, e3, e4, e5, e6, e7]]
result = s + (z / pow(x, m))
for i in range(0, 7):
result += plist[0][i] * (1 + plist[3][i] * (x - plist[1][i])) / \
(pow((x - plist[1][i]), 2) + pow((plist[2][i] / 2), 2))
return result
保留所有参数的原因是我稍后需要它们与 lmfit
模块一起使用,这需要所有参数。
我有这么长的等式
def equation(x, s, z, m, p1, f1, g1, e1, p2, f2, g2, e2, p3, f3, g3, e3, p4, f4, g4, e4, p5, f5, g5, e5,
p6, f6, g6, e6, p7, f7, g7, e7):
return float(s) + (float(z) / pow(x, float(m))) + (float(p1) * (1 + float(e1) * (x - float(f1))) / (
pow((x - float(f1)), 2) + pow((float(g1) / 2), 2)) + float(p2) * (1 + float(e2) * (x - float(f2))) / (
pow((x - float(f2)), 2) + pow((float(g2) / 2), 2)) + float(p3) * (1 + float(e3) * (x - float(f3))) / (
pow((x - float(f3)), 2) + pow((float(g3) / 2), 2)) + float(p4) * (1 + float(e4) * (x - float(f4))) / (
pow((x - float(f4)), 2) + pow((float(g4) / 2), 2)) + float(p5) * (1 + float(e5) * (x - float(f5))) / (
pow((x - float(f5)), 2) + pow((float(g5) / 2), 2)) + float(p6) * (1 + float(e6) * (x - float(f6))) / (
pow((x - float(f6)), 2) + pow((float(g6) / 2), 2)) + float(p7) * (1 + float(e7) * (x - float(f7))) / (
pow((x - float(f7)), 2) + pow((float(g7) / 2), 2)))
如您所见,但开头和数字是相同的,有没有办法用循环或其他方法缩短它?我想过列表理解,但我不知道如何在这个例子中写它。
干杯!
这是我的尝试:
def equation(x, s, z, m, es, fs, gs, ps):
something = sum(
p * (1 + e * (x - f)) / (pow(x - f, 2) + pow(g / 2, 2))
for e, f, g, p in zip(es, fs, gs, ps)
)
return s + z / pow(x, m) + something
其中:
es = [e1, e2, ...]
fs = [f1, f2, ...]
gs = ...
ps = ...
您实际上不需要明确指定 float
类型转换,因为 python 会 "automatically"。
这里是不改变参数顺序的变体。
def equation2(x, s, z, m, *params):
def subeq(x, p, f, g, e):
return (float(p) * (1 + float(e) * (x - float(f))) /
(pow((x - float(f)), 2) + pow((float(g) / 2), 2)))
return (float(s) + (float(z) / pow(x, float(m))) +
sum(subeq(x, *pfge) for pfge in zip(*([iter(params)]*4))))
可读性不是很好,只是把x,s,z,m之后的所有参数分成四组,计算重复表达式之和
这是我针对这种情况的解决方案:
def equation(x, s, z, m, p1, f1, g1, e1, p2, f2, g2, e2, p3, f3, g3, e3, p4, f4, g4, e4, p5, f5, g5, e5,
p6, f6, g6, e6, p7, f7, g7, e7):
plist = [[p1, p2, p3, p4, p5, p6, p7],
[f1, f2, f3, f4, f5, f6, f7],
[g1, g2, g3, g4, g5, g6, g7],
[e1, e2, e3, e4, e5, e6, e7]]
result = s + (z / pow(x, m))
for i in range(0, 7):
result += plist[0][i] * (1 + plist[3][i] * (x - plist[1][i])) / \
(pow((x - plist[1][i]), 2) + pow((plist[2][i] / 2), 2))
return result
保留所有参数的原因是我稍后需要它们与 lmfit
模块一起使用,这需要所有参数。