【问题标题】:Evolving functions in pythonpython中不断发展的函数
【发布时间】:2020-04-12 23:52:50
【问题描述】:

更新问题


在我原来的帖子之后,使用@Attack68 的代码,我创建了一个程序,该程序成功地进化了该函数,并选择了基于随机变量的乘法函数。但是,现在我收到一个错误,说列表索引必须是整数(即使我很确定它们是),我不确定发生了什么,代码如下:
import numpy as np
import scipy.integrate as integrate
x=np.linspace(0.0,1.0,100)
n=10 #iterations
d=700.0
def f(x):
    return np.sin(x)

def g(x,list_):
    return np.cos(x)*apply(x,list_)

base = [f, g]

list_ = list()
for i in range(n):
    testvar=np.random.randint(1, 100, 1)
    if testvar> 50 and i!=0:
        func_idx = 0 # choose a random operation: 0=ten, 1=inv
    else:
        func_idx= 1
    list_.append(func_idx)

    # now you have a list of indexes referencing your base functions so you can apply them:

    def apply(x,list_):
        y = 1
        for i in range(len(list_)):
            y *= base[list_[i]](x)
        return y

    print(list_)
    #testint=integrate.quad(apply(x,list_),-d,d)[0]
    #print(testint)
    print(apply(list_, x)) 

我现在收到错误:

TypeError: list indices must be integers or slices, not numpy.float64

我也试图让它在每次迭代后集成新函数,但似乎这个函数的形式不能被 scipys quad 积分器调用,关于如何在每次迭代中集成进化函数的任何建议也将是赞赏。


原文:

我正在 python 中创建一个模拟,我在其中考虑一个在循环中演变的函数。这个函数开始定义为:

def f(x):
    return 1.0

所以只是一个平坦的分布。在循环的每次迭代之后,我希望根据某些(随机)条件重新定义函数。它可以乘以 cos(b*x),也可以乘以某个函数 A(x),由于随机性,每次演化不会相同,所以我不能简单地每次乘以相同的值。

在一个实例中的进展可能是:

f(x)----> f(x)*A(x)----> f(x)*A(x)*A(x)...

但在另一种情况下,它可能是:

f(x)----> f(x)*A(x)----> f(x)*A(x)*cos(x)...

f(x)----> f(x)*cos(x)----> f(x)*cos(x)*cos(x)...

等等。 在每次迭代的 n 次迭代之后,我必须计算与函数相关的积分,因此我需要在每次迭代后更新函数,以由 scipys quad 积分器调用。

我尝试使用数组来操纵分布,它在函数演化过程中起作用,但是在集成时,它给出了 numpy.trapz 不正确的结果,我不知道为什么。无论如何,Sci-pys quad 积分器更准确,我之前设法让它在第一次迭代中工作,但它需要基于函数的输入,所以如果没有这个函数演化,我就无法使用它。

如果有人能告诉我这种功能进化是否/如何可能,那就太好了。如果不可能,也许有人可以尝试帮助我了解 numpy.trapz 的实际作用,以便我可以锻炼如何解决它?

【问题讨论】:

  • 看起来你在使用复合设计模式。
  • 请显示一些代码。没有任何实际细节的“我的代码似乎没有正确运行”形式的问题几乎是不可能回答的。
  • 让我们假设 t1=f(x), t2=f(x)*A(x), t3=f(x)*A(x)*A(x)。从问题中,我们可以了解您的进程中的 t1、t2、t3,t4、t5 等看起来如何尚不清楚。能否提供更多信息?
  • @quamrana。或带有包装器的函数列表以按顺序调用它们。 OP 是在相乘,而不是在这里实际组合函数。
  • @Haranadth。您将什么标记为 t4 和 t5?

标签: python function numpy lambda integration


【解决方案1】:

您的描述表明您的迭代值是通过产品组合的,实际上不是函数的组合。记录这些的一种简单方法是拥有一组基本函数:

import numpy as np
import scipy.integrate as int

def two(x):
    return x*2

def inv(x):
    return 1/x

base = [two, inv]

funcs = np.random.choice(base, size=10)

def apply(x, funcs):
    y = 1
    for func in funcs:
        y *= func(x)
    return y

print('function value at 1.5 ', apply(1.5, funcs))

answer = int.quad(apply, 1, 2, args=(funcs,))
print('integration over [1,2]: ', answer)

【讨论】:

  • apply 中不需要索引。可以直接遍历函数列表,例如for func in base: y *= func(x)
  • 感谢您的贡献,有没有办法在每次迭代后调用每个函数并存储函数......因为第二个函数实际上取决于累积乘积......即如果在两次迭代后函数是十inv,那么第三次迭代的inv是(teninv)**2
  • 是的,只需使用列表或字典并附加新条目。很难根据通用问题为您的用例准确规划,但我确信它是可以实现的
  • 谢谢,至于集成是用 scipys quad 积分器调用的函数“apply”还是需要其他方法?
  • 它是一个可调用函数,因此是有效的。根据 scipy quad 文档,您可能需要重新排序参数,因此 x 是第一个
【解决方案2】:

这个怎么样:

class MyFunction:
    def __init__(self):
        def f1(x):
            return 1.0
        self.functions = [f1]

    def append_function(self, fn):
        self.functions.append(fn)

    def __call__(self, x):
        product = 1.0
        for f in self.functions:
            product *= f(x)
        return product

这个对象一开始只是简单地返回 1.0。稍后您添加更多函数,它会返回所有函数的乘积。

【讨论】:

  • 更改了我的答案以跟踪函数列表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-28
  • 1970-01-01
  • 1970-01-01
  • 2022-06-30
  • 1970-01-01
  • 2020-07-29
  • 2011-12-08
相关资源
最近更新 更多