在Python中使用“不可Map”函数并行化循环

azpvetkf  于 2023-03-07  发布在  Python
关注(0)|答案(2)|浏览(180)

我在时间间隔0Tmax上用预先定义的步长dT数值求解积分方程,我在for循环中完成:

list_of_values = []

for i in range(dT,Tmax+dT,dT):
   func_at_t= my_fancy_solver(func_at_t)
   list_of_values.append(func_at_t)

函数my_fancy_solver有一个参数,其内部如下所示:

def my_fancy_solver(func_at_prev_t):
    while True:
        # iterate in while loop until convergence will achieved
        # compute approx_error and func_at_new_t_approx
        if approx_error < 10**(-10):
            func_at_new_t = func_at_new_t_approx
            break
    return func_at_new_t

这意味着该求解器处理前一时刻func_at_prev_t的函数值,并逼近下一时刻func_at_new_t的未知函数值。这在while-loop中进行,直到达到期望的精度,该精度由变量approx_error控制。这意味着在line中

func_at_t= my_fancy_solver(func_at_t)

(as我假设)我找到了函数在给定时刻的值然后用它来找到下一个值。
我想知道如何并行化这个计算。我的困惑是函数my_fancy_solver是不可Map的,所以我不能将其表示为map(my_fancy_solver, t),其中t是一个给定的时间值。所以,我不明白如何在multiprocessingjoblib的帮助下执行并行化。有人能给一些建议吗?

uz75evzq

uz75evzq1#

给出以下答案注解,您可能有一个可归约函数:
我在下一次迭代中使用先前找到的function_at_t
因此,考虑高阶函数(map/reduce/filter)之一的**functools.reduce,或将中间值保留在列表中的itertools.accumulate**。
因为reduceaccumulate需要一个有两个参数的方法,所以下面使用了一个分层的方法来累加结果,并且假定您的函数my_fancy_solver只接收时间作为必需参数。

from functools import reduce
from itertools import accumulate

...

def my_fancy_process(accum_value, time): 
    return accum_value + my_fancy_solver(time)

final_single_value = reduce(
    my_fancy_process, iterable=range(dT, Tmax+dT, dT), initializer=0)
)

list_of_values = accumulate(
    range(dT, Tmax+dT, dT), func=my_fancy_process, initial=0
)

在线搜索如何并行化reduceaccumulate调用的示例。

ubof19bj

ubof19bj2#

不确定你是否需要一个Map器来并行化它,当然,如果需要的话,你可以把它Map到一个对应于参数的元组列表,但是Map本身在这里似乎没有帮助,如果我理解错了请纠正我。
例如,此循环可以并行化,如下所示:

from joblib import Parallel, delayed
    
results = Parallel(n_jobs=2)(
    delayed(my_fancy_solver)(initial_condition, function_at_t)
    for i in range(dT, Tmax+dT, dT)
)

print(results)

当然,您也可以对常规循环执行相同的操作

相关问题