当前位置: 首页 > 面试题库 >

多个scipy.integrate.ode实例

阮选
2023-03-14
问题内容

我想在 多个线程* (每个CPU内核一个)中使用 scipy.integrate.ode
(或scipy.integrate.odeint)实例,以便一次解决多个IVP。但是文档中说:“此集成器不可重入。您不能同时使用“vode”集成器拥有两个ode实例。
* __

(尽管文档未说明,但如果多次实例化,odeint也会导致内部错误。)

知道该怎么办吗?


问题答案:

一种选择是使用multiprocessing(即使用进程而不是线程)。这是一个使用类map函数的示例multiprocessing.Pool

该函数solve采用一组初始条件,并返回由生成的解odeint。主要部分中代码的“串行”版本solve反复调用,对于中的每组初始条件一次ics。“多重处理”版本使用实例的map功能multiprocessing.Pool来同时运行多个进程,每个进程都调用solve。该map函数负责为分配参数solve

我的计算机有四个核心,并且随着我的增加num_processes,加速最大达到约3.6。

from __future__ import division, print_function

import sys
import time
import multiprocessing as mp
import numpy as np
from scipy.integrate import odeint



def lorenz(q, t, sigma, rho, beta):
    x, y, z = q
    return [sigma*(y - x), x*(rho - z) - y, x*y - beta*z]


def solve(ic):
    t = np.linspace(0, 200, 801)
    sigma = 10.0
    rho = 28.0
    beta = 8/3
    sol = odeint(lorenz, ic, t, args=(sigma, rho, beta), rtol=1e-10, atol=1e-12)
    return sol


if __name__ == "__main__":
    ics = np.random.randn(100, 3)

    print("multiprocessing:", end='')
    tstart = time.time()
    num_processes = 5
    p = mp.Pool(num_processes)
    mp_solutions = p.map(solve, ics)
    tend = time.time()
    tmp = tend - tstart
    print(" %8.3f seconds" % tmp)

    print("serial:         ", end='')
    sys.stdout.flush()
    tstart = time.time()
    serial_solutions = [solve(ic) for ic in ics]
    tend = time.time()
    tserial = tend - tstart
    print(" %8.3f seconds" % tserial)

    print("num_processes = %i, speedup = %.2f" % (num_processes, tserial/tmp))

    check = [(sol1 == sol2).all()
             for sol1, sol2 in zip(serial_solutions, mp_solutions)]
    if not all(check):
        print("There was at least one discrepancy in the solutions.")

在我的计算机上,输出为:

multiprocessing:    6.904 seconds
serial:            24.756 seconds
num_processes = 5, speedup = 3.59


 类似资料:
  • 问题内容: 大多数人似乎建议在不同的端口(6379和6380)上运行单独的Redis实例。为什么在创建第二个数据库时更通常建议这样做?我还没有完全阅读文档,但是大多数示例在连接时并未真正提及“选择Redis数据库”。Ruby客户端的一个示例,nrk / predis的自述文件: 目前,我们正在使用Campfire在办公室中运行Hubot,而我正在为GTalk工作第二个,因为每个Hubot实例只能使

  • 当我试图创建多个实例时,我遇到了一个问题。 例如: 控制台日志:,仅此而已。不再有了。

  • 我们目前在办公室用营火运行Hubot,我正在为GTalk开发第二个适配器,因为每个Hubot实例只能使用一个适配器。因此,我正在考虑创建第二个Redis数据库或实例,以便隔离两个hubots之间的数据。但是在我深入讨论之前,我想了解为什么要使用单独的实例而不是创建第二个数据库。

  • 我正在将Vue集成到一个表单网站上,这意味着如果页面上有多个表单,我必须创建Vue应用程序的几个实例。所有实例共享相同的Vuex存储。 我创建了一个Vuex模块,这样每个Vue实例都可以有自己的本地状态。我的主要目标是防止一个Vue实例更新另一个Vue实例的状态。 这是我的Vuex模块 创建我的Vuex实例: 我正在阅读Vuex文档,它说你需要使用一个返回模块状态的函数,这就是我正在做的。但是,当

  • 我们有一个Spring Boot Restful API,它需要从两个不同的Elasticsearch实例(在不同的服务器上)获取数据,一个用于“共享”数据(上面有大约5个不同的索引),一个用于“私有”数据(有大约3个不同的索引)。目前只针对“私有”数据实例运行,一切都很好。但我们现在需要获取“共享”数据。 在我们的Spring Boot应用程序中,我们启用了如下Elasticsearch存储库

  • 首先,我已经阅读了Hibernate——一个包含多个实体的表?。 然而,我希望将两个实体映射到同一个表,但我希望它们都是实体,我可以从中选择。我的意思是: 一个表:人(id、姓名、出生日期、城市、街道、邮政编码)。 两个实体:人(id、name、dateOfBirth)、地址(id、城市、街道、邮政编码)。 实体之间是1:1的关系,但数据库中仍然是1个表。 如果我在上面的链接中使用建议的解决方案(