问题
Updated Question
Following from my original post, with the use of @Attack68 's code, I have created a program that successfully evolved the function with a choice of multiplicative functions based on a random variable. However, now I am receiving an error saying the list indices must be integers (even though I'm fairly sure they are), I'm not sure what has happened, The code is as follows:
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))
I am now getting the error:
TypeError: list indices must be integers or slices, not numpy.float64
I am also attempting to get this to integrate the new function after each iteration but it seems that the form of this function is not callable by scipys quad integrator, any suggestions on how to integrate the evolving function on each iteration would also be appreciated.
Original:
I am creating a simulation in python where I consider a function that evolves over a loop. This function starts off defined as:
def f(x):
return 1.0
So simply a flat distribution. After each iteration of the loop, I want the function to be redefined depending on certain (random) conditions. It could be multiplied by cos(b*x) or it could be multiplied by some function A(x), the evolution will not be the same each time due to the randomness, so I cannot simply multiply by the same value each time.
The progression in one instance could be:
f(x)----> f(x)*A(x)----> f(x)*A(x)*A(x)...
but in another instance it could be:
f(x)----> f(x)*A(x)----> f(x)*A(x)*cos(x)...
or
f(x)----> f(x)*cos(x)----> f(x)*cos(x)*cos(x)...
etc. after each, of n iterations of this evolution, I have to compute an integral that is related to the function, so I need to essentially update the function after each iteration to be called by scipys quad integrator.
I have tried to use arrays to manipulate the distribution instead and it works as far as the function evolution goes, but upon integration, it gives the incorrect result with numpy.trapz and I cannot work out why. Sci-pys quad integrator is more accurate anyway and I had managed to get this to work previously for the first iteration only, but it requires a function based input, so without this function evolution I cannot use it.
If someone could show me if/how this function evolution is possible that'd be great. If it is not possible, perhaps someone could try to help me understand what numpy.trapz actually does so I can workout how to fix it?
回答1:
How about this:
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
This object starts off as simply returning 1.0. Later you add more functions and it returns the product of all of them.
回答2:
Your description suggests your iterated values are combined through a product and are not in fact a composition of functions. A simple way of recording these is to have a set of base functions:
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)
来源:https://stackoverflow.com/questions/59425718/evolving-functions-in-python