我使用类似于example的GSL ODE求解器解决了一组耦合的ODE。目前,这是通过在python中编写文件来实现自动化,例如
text = """
#include <stdio.h>
#include <gsl/gsl_errno.h>
...
"""
然后用相关的单词替换text
中的字符串并写入文件script.c
。然后我使用os.system
来运行它,例如
os.system("gcc -Wall -I/usr/local/include -c script.c")
os.system("gcc -static script.o -lgsl -lgslcblas -lm")
os.system("./a.out > %s" % (file_name) )
所有这些都非常优雅,所以我一直在阅读有关替代品的内容,并且到目前为止已经发现了PyGSL,CythonGSL。这些似乎缺乏适当的文档,我不够聪明,无法弄清楚它们是如何工作的!
任何建议都将不胜感激。
答案 0 :(得分:4)
PyGSL可能是一个合理的选择。 (也是CythonGSL,但我还没试过。)
我正在运行Ubuntu 12.04(64位),对于这个安装,我使用的是Anaconda python发行版。 (它可能适用于Ubuntu中的默认Python, 但我没试过。)
我从源代码安装了GSL 1.15,我刚安装了PyGSL 0.9.5 按照自述文件中的说明来源。也就是说,我跑了
$ python setup.py build
$ python setup.py install
在提取的tar文件的顶级目录中。像许多python包一样 构建C库,在构建步骤期间打印 lot 警告,但它 完成没有错误。
这里有一些代码演示了如何在PyGSL中使用ODE求解器:
#
# pendulum_demo.py
#
# Use PyGSL to solve the differential equations for a pendulum with
# friction. Plot the solution using matplotlib.
#
import numpy as np
import matplotlib.pyplot as plt
from pygsl import odeiv
def pendsys(t, y, args):
"""
The right-hand side of the first order system of differential equations.
"""
theta, v = y
g, b, L, m = args
f = np.zeros((2,))
f[0] = v
f[1] = -b * v / (m * L ** 2) - np.sin(theta) * g / L
return f
def pendjac(t, y, args):
"""
The Jacobian of the system.
"""
theta, v = y
g, b, L, m = args
jac = np.zeros((2, 2))
jac[0, 1] = 1.0
jac[1, 0] = -g / L * np.cos(theta)
jac[1, 1] = -b / (m * L ** 2)
dfdt = np.zeros((2,))
return jac, dfdt
# Pendulum parameter values
#
# Gravitational constant
g = 9.81
# Friction coefficient
b = 0.5
# Pendulum length
L = 1.0
# Pendulum bob mass
m = 2.0
# Initial conditions
theta0 = np.pi - 0.01
v0 = 0.0
y = [theta0, v0]
t = 0
# Solver control parameters.
abserr = 1e-11
relerr = 1e-9
stoptime = 12.0
# Create the GSL ODE solver
N = 2
step = odeiv.step_rk8pd(N, pendsys, pendjac, args=(g, b, L, m))
control = odeiv.control_y_new(step, abserr, relerr)
evolve = odeiv.evolve(step, control, N)
# h is the initial step size.
h = stoptime / 500.0
# The time values and points in the solution are saved in the lists
# tsol and ysol, respectively. The lists are initialized with
# the initial conditions.
tsol = [t]
ysol = [y]
# Call evolve.apply(...) until the solution reaches stoptime
while t < stoptime:
t, h, y = evolve.apply(t, stoptime, h, y)
tsol.append(t)
ysol.append(y)
tsol = np.array(tsol)
ysol = np.array(ysol)
plt.plot(tsol, ysol[:, 0], label=r'$\theta$')
plt.plot(tsol, ysol[:, 1], label='v')
plt.xlabel('t')
plt.grid(True)
plt.legend()
plt.title('Pendulum with Friction')
plt.show()
结果图:
答案 1 :(得分:1)
如果您可以编写一个带有参数的C库,而不是使用Python代码中C代码的字符串替换,那么您可以单独编译C库,并使用CFFI从Python代码中调用函数。
这些替换有多复杂/动态?