PythonMan1029
PythonMan1029

Reputation: 85

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?

Upvotes: 0

Views: 92

Answers (2)

Mario Ishac
Mario Ishac

Reputation: 5887

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.

Upvotes: 0

joshmeranda
joshmeranda

Reputation: 3251

First, there is no data type that is both a float and a collection. Additionally, you want to pass the area function directly into the SimAnneal function rather than the return of a call to it as you currently have it:

SimAnneal(x, area, T)

From a design standpoint, it would make more sense to leave the area function as is taking a single float as a parameter. That being said, it is relatively simple to run a single function through a list and store those outputs with the theta that created it using a technique called Dictionary Comprehensions. In the example below thetas is the list of thetas you want to choose from:

areas = {i: area(i) for i in thetas}

From there you can then search through the new dictionary to find the theta that produced the greatest area:

max_theta = list(areas.keys())[0] # retrieve the first theta

for theta, area in areas.items():
    if area > areas[theta]:
        max_theta = theta

return theta

Upvotes: -1

Related Questions