是否有一个numpy / scipy函数来计算出站罚款?

问题描述 投票:0回答:1

在我的最小化问题中,所有有界最小化方法,例如'L-BFGS-B','TNC'都不收敛,但是'Nelder-Mead'很好地收敛。因此,我更喜欢使用经过修改的最小化功能的“ Nelder-Mead”,如下所示:

def outbound_penalty(x, bounds):
    o1 = (bounds[:, 0]-x).max()
    o2 = (x-bounds[:, 1]).max()
    outbound = max(o1, o2, 0)
    rez = 100500*outbound

def bounded_fun(x, bounds):
    return fun(x) + outbound_penalty(x, bounds)

x是numpy数组形状(4),界限具有形状(2,4),界限[0]是底部边框,界限[1]-顶部边框。令人惊讶的是,它没有我预期的那么快。在4 * 10 ^ 6调用时,CPU占用自己的40秒时间。我当然记得了。但是我不得不问。 numpy / scipy中是否有一些非常优化的函数,可以用来构造出站罚分?

    def outbound_penalty(x, bs):
        o1 = (bs[:, 0] - x).max()
        o2 = (x - bs[:, 1]).max()
        outbound = max(o1, o2, 0)
        return 1000000 * outbound

%timeit outbound_penalty(smpls [0],np_bounds)每个循环22.5 µs±123 ns(平均±标准偏差,共运行7次,每个循环10000个)%timeit outbound_penalty_fast(smpls [0],np_bounds)每个循环68.4 µs±390 ns(平均±标准偏差,共运行7次,每个10000个循环)

python numpy scipy minimize scipy-optimize
1个回答
1
投票

您可以使用广播一次性执行出站逐元素函数调用,并且当然可以使用np.max()而不是在for循环中将ymx进行比较:

import numpy as np


def outbound_penalty(x, bs):
    o1 = (bs[:, 0] - x).max()
    o2 = (x - bs[:, 1]).max()
    outbound = max(o1, o2, 0)
    return 1000000 * outbound


def outbound_penalty_fast(x, bs):
    o1 = (bs[:, 0, None] - x).max(axis=0)
    o2 = (x - bs[:, 1, None]).max(axis=0)
    outbound = np.clip(np.maximum(o1, o2), a_max=None, a_min=0)
    return 1000000 * outbound


bnd = np.random.randint(100, 200, size=(2, 2))
bnd[:, 0] = 0
sss = np.random.uniform(-100, 300, size=(2, 1000))

%timeit np.max(np.array([outbound_penalty(x, bnd) for x in sss.T]))
# 9.44 ms ± 166 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit np.max(outbound_penalty_fast(sss, bnd))
# 38.1 µs ± 1.33 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

mx = np.max(np.array([outbound_penalty(x, bnd) for x in sss.T]))
mx_fast = np.max(outbound_penalty_fast(sss, bnd))

mx == mx_fast  # True
© www.soinside.com 2019 - 2024. All rights reserved.