Search code examples
pythonfunctionparametric-polymorphismsimulated-annealing

Parametric Polymorphism Problem: Using function with single float parameter with an array of float parameters


To clarify what I mean, my issue is with a simulated annealing problem where I want to find the theta that gives me the max area of a shape:

def Area(theta):
    #returns area
def SimAnneal(space,func, T):
    #space is some linspace
    #func is some function that takes in some theta and outputs some area
    #T = separate temperature parameter that is not relevant for problem
    #returns maximum area from given thetas

Simulated annealing starts by choosing a random starting “theta”, in this scenario. My goal is to use the setup above as shown below. It should be noted that the input for area() is a single theta, but my hope was that there was some way to make ? a “potential” list of thetas that the next function, SimAnneal(), can choose from.

  x = np.linspace(0,100,1000)
  func = area(?)
  T = 4
  SimAnneal(x,func,T)

What should I put into ? in order for SimAnneal to output correctly.

In other words, is there a ? that can satisfy the condition of being a single float parameter but carry all the possible float parameters in some linspace?


Solution

  • You can use np.vectorize to apply a func taking a single value as follows:

    import numpy as np
    
    def Area(theta):
        pass
    
    def SimAnneal(space, func, T):
        applied_space = np.vectorize(func)(space)
    
    x = np.linspace(0, 100, 1000)
    T = 4
    SimAnneal(x, Area, T)
    

    Note that np.vectorize won't actually give you performance improvements that we see with actual vectorization. It is instead a convenient interface that exactly fits your need: Applying a func that takes a single value to a bunch of values (your space).

    Alternative, you can move the np.vectorize call outside of SimAnneal like this:

    def SimAnneal(space, func, T):
        applied_space = func(space)
    
    x = np.linspace(0, 100, 1000)
    func = np.vectorize(Area)
    T = 4
    SimAnneal(x, func, T)
    

    This is closer to your original example.