SciPy: TypeError when using scipy.optimize.minimize - python

I'm encountering a vague error when attempting to minimise a function using scipy.optimize.minimize. The error I get is,
Traceback (most recent call last):
File "general_fd.py", line 103, in <module>:
a_tmp[index] = minimize(iF.hamiltonian,0,(x,u_last,m_tmp,dt,dx,k*dt,index),tol=1e-3)
TypeError: float() argument must be a string or number
where
def hamiltonian(alphas,x_array,u_array,m_array,dt,dx,time,index):
sigma2 = Sigma_local(time,x_array[index],alphas,m_array[index])**2
movement = f_global(time,x_array[index],alphas)
L_var = L_global(time,x_array[index],alphas,m_array[index])
dx2 = dx**2
if index==0:
sigma2R = Sigma_local(time,x_array[index+1],alphas,m_array[index])**2
tmp = u_array[0]*(abs(movement)/dx - sigma2/dx2) + u_array[1]*(sigma2R/dx2 - abs(movement)/dx) + L_var
elif index==x_array.size-1:
sigma2L = Sigma_local(time,x_array[index-1],alphas,m_array[index])**2
tmp = u_array[-1]*(abs(movement)/dx - sigma2/dx2) + u_array[-2]*(sigma2L/dx2 - abs(movement)/dx) + L_var
else:
sigma2L = Sigma_local(time,x_array[index-1],alphas,m_array[index])**2
sigma2R = Sigma_local(time,x_array[index+1],alphas,m_array[index])**2
tmp = u_array[index]*(abs(movement)/dx - sigma2/dx2) + u_array[index+1]*(sigma2R/(2*dx2) + min(movement,0)/dx) + u_array[index-1]*(sigma2L/(2*dx2) - max(movement,0)/dx) + L_var
return tmp[0]
def Sigma_local(time,x,a,m):
return 0*x
def f_global(time,x_array,a_array):
return 0.1*a_array*x_array
def L_global(time,x_array,a_array,m_array): #general cost
return a_array + np.sqrt(x_array) + a_array**2
The above code is pretty ugly as I've modified it somewhat in order to try and find the error; my apologies. I've found that minimize-function runs a few trial values of hamiltonian before throwing the error message upon the return statement in hamiltonian. I've used the minimize function on other, similar functions without this error occurring, and I'm honestly quite stumped. Any help would be appreciated.

Related

Problems encountered in derivation with tensorflow

I have some problem when derivate with tensorflow. My code is:
def pde(x,y):
x = dde.config.real.set_float64()
u,k = y[:,0:1],y[:,1:2]
du_x = tf.gradients(u,x)[0]
du_x,du_y= du_x[:,0:1],du_x[:,1:2]
du_xx = tf.gradients(du_x,x)[0][:,0:1]
du_yy = tf.gradients(du_y,x)[0][:,1:2]
return k*du_xx + k*du_yy
and the error is:
f = self.pde(inputs, outputs_pde)
File "d:/VS_CODE/AI_code/experiment/seepage_rectangle_bc.py", line 22, in pde *
du_x = tf.gradients(u,x)[0]
AttributeError: 'NoneType' object has no attribute 'op'
How can I solve this problem?
In the first line of your function, you are overwriting x
x = dde.config.real.set_float64()
Change it to
def pde(x,y):
dde.config.real.set_float64()
u,k = y[:,0:1],y[:,1:2]

Memory error - double recursion at fault?

I want to generate well formed formulas in python, but I am running into a memory error. I think I am accidentally doing some double recursion, but I am not certain. I am using python 3.8.3 and am not really formally trained. Any tips are welcome. Here's my code:
from string import Template
vars = ['w','x','y','z', '$x', '$y', 's($x, $y)']
mxy = Template('m($x, $y)')
stage1 = []
for var1 in vars:
for var2 in vars:
stage1.append(mxy.substitute(x=var1, y=var2))
def extractFunctions(x):
ans = []
for formula in x:
if '$' in formula:
ans.append(formula)
return ans
def stageSub(stageSet, iterations):
currentStageSet = stageSet
wffs = []
newTemplates = extractFunctions(currentStageSet)
for phormula in newTemplates:
if ('$x' in phormula) and ('$y' not in phormula):
for varx in currentStageSet:
wffs.append(Template(phormula).substitute(x = varx))
elif '$y' in phormula and '$x' not in phormula:
for vary in currentStageSet:
wffs.append(Template(phormula).substitute(y = vary))
elif '$x' in phormula and '$y' in phormula:
for varx in currentStageSet:
for vary in currentStageSet:
wffs.append(Template(phormula).substitute(x = varx, y = vary))
iterations = iterations - 1
print(iterations)
if iterations == 0:
return wffs
if iterations > 0:
print('this happened', iterations)
return stageSub(wffs, iterations)
stage2 = stageSub(stage1, 2)
print(len(stage2))
If you run stageSub(stage1, 1) (so just 1 iteration) it does actually halt.
Here is the error and traceback:
1
this happened 1
Traceback (most recent call last):
File "d:\Python\ringSingleAxiom\generatingWffs.py", line 48, in <module>
stage2 = stageSub(stage1, 2)
File "d:\Python\ringSingleAxiom\generatingWffs.py", line 46, in stageSub
return stageSub(wffs, iterations)
File "d:\Python\ringSingleAxiom\generatingWffs.py", line 38, in stageSub
wffs.append(Template(phormula).substitute(x = varx, y = vary))
MemoryError

NoneType error while finding minima with Scipy Optimize

I am trying to find the global minima of a function using scipy.optimizer methods and keep running into NoneType issues. I have tried multiple algorithms including differential_evolution, shgo, and brute but keep running into errors.
Here is the setup:
def sizing_trade_study(ranges, payload):
with open("config.yml", "r") as yml:
cfg = yaml.load(yml)
first_int = True
km = []
for range in ranges:
km.append( range * 1000)
print(km)
params = (km, payload)
if first_int:
x0 = [float(cfg['design_variables']['initial_guess']['prop_radius']),
float(cfg['design_variables']['initial_guess']['speed']),
float(cfg['design_variables']['initial_guess']['battery_mass']),
float(cfg['design_variables']['initial_guess']['motor_mass']),
float(cfg['design_variables']['initial_guess']['mtow'])]
lb = [float(cfg['design_variables']['lower_bound']['prop_radius']),
float(cfg['design_variables']['lower_bound']['speed']),
float(cfg['design_variables']['lower_bound']['battery_mass']),
float(cfg['design_variables']['lower_bound']['motor_mass']),
float(cfg['design_variables']['lower_bound']['mtow'])] # Min cruise at 1.3 * VStall
ub = [float(cfg['design_variables']['upper_bound']['prop_radius']),
float(cfg['design_variables']['upper_bound']['speed']),
float(cfg['design_variables']['upper_bound']['battery_mass']),
float(cfg['design_variables']['upper_bound']['motor_mass']),
float(cfg['design_variables']['upper_bound']['mtow'])]
# bounds = (slice(lb[0], ub[0]), slice(lb[1], ub[1]), slice(lb[2], ub[2]), slice(lb[3], ub[3]), slice(lb[4], ub[4]))
# bounds = [(lb[0], ub[0]), (lb[1], ub[1]), (lb[2], ub[2]), (lb[3], ub[3]), (lb[4], ub[4])]
bounds = optimize.Bounds(lb,ub)
result = optimize.differential_evolution(objective_function, bounds, args=(params,))
print(result)
def objective_function(x, *params):
global trials
trials = trials+1
print(trials)
performance.compute_performance(x, params[0][0], params[0][1])
Here is the function I am trying to optimize:
import yaml
import simple_mission
import reserve_mission
import config_weight
def compute_performance(x, range, payload):
rprop = x[0]
speed = x[1]
battery = x[2]
motors = x[3]
mtow = x[4]
w = mtow * 9.8
with open("config.yml", "r") as yml:
cfg = yaml.load(yml)
bat_energy_density = int(cfg['performance']['bat_energy_density'])
motor_power_density = int(cfg['performance']['motor_power_density'])
discharge_depth = float(cfg['performance']['discharge_depth'])
e_nominal, flight_time, hover_output, cruise_output = simple_mission.run_simple_mission(rprop, speed, w, range)
reserve_e = reserve_mission.reserve_mission(rprop,speed, w, range)
mass = config_weight.config_weight(battery,motors, rprop, w, mtow, hover_output, cruise_output, payload)
batt = reserve_e - battery * bat_energy_density * discharge_depth / 1000
motor = hover_output.pow_hover / 1000 - motors * motor_power_density
weight = mass - w
return batt+ motor+ weight
The failure doesn't happen immediately but after a couple of runs of the optimizer function. For example, with differential_evolution, it always happens after the 75th trial.
Here is the stacktrace:
69
70
71
72
73
74
75
76
Traceback (most recent call last):
File "sizing_trade_study.py", line 62, in <module>
sizing_trade_study(args.ranges, args.payload)
File "sizing_trade_study.py", line 42, in sizing_trade_study
result = optimize.differential_evolution(objective_function, bounds, args=(params,))
File "/usr/local/anaconda3/envs/simple_mission/lib/python3.7/site-packages/scipy/optimize/_differentialevolution.py", line 308, in differential_evolution
ret = solver.solve()
File "/usr/local/anaconda3/envs/simple_mission/lib/python3.7/site-packages/scipy/optimize/_differentialevolution.py", line 759, in solve
next(self)
File "/usr/local/anaconda3/envs/simple_mission/lib/python3.7/site-packages/scipy/optimize/_differentialevolution.py", line 1082, in __next__
self.constraint_violation[candidate]):
File "/usr/local/anaconda3/envs/simple_mission/lib/python3.7/site-packages/scipy/optimize/_differentialevolution.py", line 1008, in _accept_trial
return energy_trial <= energy_orig
TypeError: '>=' not supported between instances of 'float' and 'NoneType'
Any help is greatly appreciated!
The issue is with one of the retrieved values from your bounds or objective_function, which in turn is being passed in as a NoneType to energy_orig within differential_evolution()
Source: https://github.com/scipy/scipy/blob/master/scipy/optimize/_differentialevolution.py
if feasible_orig and feasible_trial:
return energy_trial <= energy_orig
You should make sure that each key value is not empty from your config.yml or other function parameters. It's hard to tell which could be the problem. However, you could wrap it around a try/catch to get this to not stop on the 75th try for the meantime.
try:
result = optimize.differential_evolution(
objective_function,
bounds,
args=(params,),
)
except TypeError:
import pdb; pdb.set_trace()
I've set pdb, which will allow to to debug the values of each parameter, feel free to swap it out with a pass if you need to continue swiftly

print statement in test function changes outcome of test

Function being tested:
def first_ball_contacts(self, timestep):
"""Returns the time and all touching ballpairs (ball_1, ball_2) at the time of the first ball-ball collision within the timestep"""
first_ball_contacts = {'time': timestep, 'collidors': []} # collidors will be Ball
for ball_1, ball_2 in itertools.combinations(self.balls, 2):
t = self.collision_time(ball_1, ball_2, timestep)
if t!=None:
if t < first_ball_contacts['time']:
first_ball_contacts['time'] = t
first_ball_contacts['collidors'] = [(ball_1, ball_2)]
elif t == first_ball_contacts['time']:
first_ball_contacts['collidors'].append((ball_1, ball_2))
return first_ball_contacts
Test function:
def test_first_ball_contacts_2_balls(self):
board = Board(width = 100, height = 100, sps = 1) # Same thing with one line changed
ball_1 = board.add_ball(x = 45, y = 50, r = 5, vx = 2, vy = 0, m = 1)
ball_2 = board.add_ball(x = 55, y = 50, r = 5, vx = -2, vy = 0, m = 1)
contacts = board.first_ball_contacts(1)
print("FROM "+str(contacts))
self.assertEqual(contacts['time'], 0)
self.assertEqual(contacts['collidors'], [(ball_1, ball_2)])
When I run this test, it is successful:
(balls) Sahands-MBP:src sahandzarrinkoub$ python test_boardmodel.py
.......FROM {'time': 0.0, 'collidors': [(<model.boardmodel.Ball object at 0x105786e10>, <model.boardmodel.Ball object at 0x105786e48>)]}
..........
----------------------------------------------------------------------
Ran 17 tests in 0.004s
OK
But when I remove the print statement (or if I change it to something else, for example if I change it to print(str(contacts))), the test fails:
.......F.........
======================================================================
FAIL: test_first_ball_contacts_2_balls (__main__.BoardModelMethods)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_boardmodel.py", line 282, in test_first_ball_contacts_2_balls
self.assertEqual(contacts['collidors'], [(ball_1, ball_2)])
AssertionError: Lists differ: [(<mo[28 chars]t 0x10c56ae10>, <model.boardmodel.Ball object at 0x10c56add8>)] != [(<mo[28 chars]t 0x10c56add8>, <model.boardmodel.Ball object at 0x10c56ae10>)]
First differing element 0:
(<mod[26 chars]at 0x10c56ae10>, <model.boardmodel.Ball object at 0x10c56add8>)
(<mod[26 chars]at 0x10c56add8>, <model.boardmodel.Ball object at 0x10c56ae10>)
- [(<model.boardmodel.Ball object at 0x10c56ae10>,
? ^^^
+ [(<model.boardmodel.Ball object at 0x10c56add8>,
? ^^^
- <model.boardmodel.Ball object at 0x10c56add8>)]
? ^^^
+ <model.boardmodel.Ball object at 0x10c56ae10>)]
? ^^^
Also, if I comment out the print statement, the test is successful. This is very strange behaviour that I would like to understand. How can a print-statement have any effect on the contests of the dictionary it's printing? Especially if the print statement is commented out!
EDIT: It seems like it didn't still succeed after I commented the print statement out. However, it stills fails if I remove it entirely. So the same questions remains: Why does this print statement change the outcome of the test?
Also, don't get hung up on why I've written "FROM " inside the print. I discovered this strange behaviour by accident and would like to have it explained.

Receiving a KeyError: '0_0' for my python program

I'm was working on this question (it's from Leetcode):
"Given an integer matrix, find the length of the longest increasing
path.
From each cell, you can either move to four directions: left, right, up or down.
You may NOT move diagonally or move outside of the
boundary (i.e. wrap-around is not allowed).
Example 1:
nums = [
[9,9,4],
[6,6,8],
[2,1,1]
]
Return 4.
I keep running into a KeyError specifically:
Traceback (most recent call last):
File "/Users/Desktop/longest_increasing_path_in_a_matrix.py", line 41, in <module>
print(test.longestIncreasingPath(matrix))
File "/Users/Desktop/longest_increasing_path_in_a_matrix.py", line 31, in longestIncreasingPath
traverse(x, y, [])
File "/Users/Desktop/longest_increasing_path_in_a_matrix.py", line 5, in traverse
if traverse.traveled[str(x_coor) + "_" + str(y_coor)]:
KeyError: '0_0'
and I'm not sure exactly what I'm doing wrong. I understand it has to do with my dictionary. Please let me know if there is anything else I need to post:
class Solution(object):
def longestIncreasingPath(self, matrix):
def traverse(x_coor, y_coor, build):
key = str(x_coor) + "_" + str(y_coor)
if key in traverse.traveled and traverse.traveled[key]:
if traveled[str(x_coor) + "_" + str(y_coor)]:
return
elif x_coor < 0 or y_coor < 0 or x_coor >= len(matrix[0]) or y_coor >= len(matrix)-1:
return
elif len(build) > 0 and matrix[x_coor][y_coor] <= build[-1]:
if len(build) > traverse.count:
traverse.count = len(build)
return
traveled[str(x_coor) + "_" + str(y_coor)] = true
build.append(matrix[y_coor][x_coor])
traverse(x_coor, y_coor-1, build)
traverse(x_coor, y_coor+1, build)
traverse(x_coor+1, y_coor, build)
traverse(x_coor-1, y_coor, build)
build.pop()
del traveled[str(x_coor) + "_" + str(y_coor)]
traverse.count = 0
traverse.traveled = {}
for y in range(0, len(matrix)-1, 1):
for x in range(0, len(matrix[0]), 1):
traverse(x, y, [])
return(traverse.count)
matrix = [
[9,9,4],
[6,6,8],
[2,1,1]
]
test = Solution()
print(test.longestIncreasingPath(matrix))
You are trying to access a key (0_0) that doesn't exist yet in the dictionary.
You have to check beforehand if it exists, I'd suggest the in keyword:
key = str(x_coor) + "_" + str(y_coor)
if key in traverse.traveled and traverse.traveled[key]:
# ...

Categories