lundi 23 décembre 2019

Python- np.random.choice

I am using the numpy.random.choice module to generate an 'array' of choices based on an array of functions:

def f(x):
    return np.sin(x)

def g(x):
    return np.cos(x)


base=[f, g]

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

This code will produce an 'array' of 2 items referencing a function from the base array.

The reason for this post is, I have printed the outcome of funcs and recieved:

[<function f at 0x00000225AC94F0D0> <function f at 0x00000225AC94F0D0>]

Clearly this returns a reference to the functions in some form, not that I understand what that form is or how to manipulate it, this is where the problem comes in. I want to change the choice of function, so that it is no longer random and instead depends on some conditions, so it might be:

for i in range(2):
    if testvar=='true':
        choice[i] = 0 
    if testvar== 'false':
        choice[i] = 1

This would return an array of indicies to be put in later function

The problem is, the further operations of the code (I think) require this previous form of function reference: [ ] as an input, instead of a simple array of 0,1 Indicies and I don't know how I can get an array of form [ ] by using if statements.

I could be completely wrong about the rest of the code requiring this input, but I don't know how I can amend it, so am hence posting it here. The full code is as follows: (it is a slight variation of code provided by @Attack68 on Evolving functions in python) It aims to store a function that is multiplied by a random function on each iteration and integrates accordingly. (I have put a comment on the code above the function that is causing the problem)

import numpy as np
import scipy.integrate as int

def f(x):
    return np.sin(x)

def g(x):
    return np.cos(x)

base = [f, g]

funcs = np.random.choice(base, size=2)
print(funcs)
#The below function is where I believe the [<function...>] input to be required
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)

Here is my attempt of implementing a non-random event:

import numpy as np
import scipy.integrate as int
import random
def f(x):
    return np.sin(x)

def g(x):
    return np.cos(x)

base = [f, g]

funcs = list()
for i in range(2):
    testvar=random.randint(0,100) #In my actual code, this would not be random but dependent on some other situation I have not accounted for here
    if testvar>50:
        func_idx = 0 # choose a np.random operation: 0=f, 1=g
    else:
        func_idx= 1
    funcs.append(func_idx)
#funcs = np.random.choice(base, size=10)
print(funcs)
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)

This returns the following error:

TypeError: 'int' object is not callable



Aucun commentaire:

Enregistrer un commentaire