OpenMDAO/ScipyOptimizer "UnboundLocalError: local variable 'f_new' referenced before assignment" - python

Trying to run the paraboloid example from OpenMDAO documentation but using the ScipyOptimizer, and I get the error in the title. Not sure what I'm doing wrong. I've attached a MWE below.
OpenMDAO 1.7.3, Python 3.6.0.
# -*- coding: utf-8 -*-
"""
Paraboloid tutorial from OpenMDAO documentation:
https://openmdao.readthedocs.io/en/latest/usr-guide/tutorials/paraboloid-tutorial.html
"""
# import print function from Python 3 if we are using Python 2
from __future__ import print_function
# import all the components we need from openmdao module
from openmdao.api import IndepVarComp, Component, Problem, Group, ScipyOptimizer
class Paraboloid(Component):
""" Evaluates the equation f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3 """
def __init__(self):
super(Paraboloid, self).__init__()
self.add_param('x', val=0.0)
self.add_param('y', val=0.0)
self.add_output('f_xy', shape=1)
def solve_nonlinear(self, params, unknowns, resids):
"""f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3
"""
x = params['x']
y = params['y']
unknowns['f_xy'] = (x-3.0)**2 + x*y + (y+4.0)**2 - 3.0
def linearize(self, params, unknowns, resids):
""" Jacobian for our paraboloid."""
x = params['x']
y = params['y']
J = {}
J['f_xy', 'x'] = 2.0*x - 6.0 + y
J['f_xy', 'y'] = 2.0*y + 8.0 + x
return J
# This if statement executes only if the script is run as a script, not if the
# script is imported as a module. It's not necessary for this demo, but it
# is good coding practice.
if __name__ == "__main__":
# initiallize the overall problem
top = Problem()
# each problem has a root "group" that contains the component evaluating
# the objective function
root = top.root = Group()
# define components with the independent variables and their initial guesses
root.add('p1', IndepVarComp('x', 3.0))
root.add('p2', IndepVarComp('y', -4.0))
# add the component that defines our objective function
root.add('p', Paraboloid())
# connect the components together
root.connect('p1.x', 'p.x')
root.connect('p2.y', 'p.y')
# specify our driver for the problem (optional)
top.driver = ScipyOptimizer()
top.driver.options['optimizer'] = 'SLSQP'
top.driver.options['disp'] = True # don't display optimizer output
# set up the problem
top.setup()
# run the optimization
top.run()
print(top['p.f_xy'])

I figured it out. In a classic moment of brain-fartiness, I forgot to add my design variables and objective functions to the driver. Something like this is what I was missing:
top.driver = ScipyOptimizer()
top.driver.options['optimizer'] = 'SLSQP'
top.driver.add_desvar('p1.x', lower=-50, upper=50)
top.driver.add_desvar('p2.y', lower=-50, upper=50)
top.driver.add_objective('p.f_xy')

Related

How to solve non-numeric type in numeric context error in pyomo python

This is the code. I think the solver could be glpk instead of gurobi. I got the error before it tries to solve the problem.
from pyomo.environ import *
from pyomo.opt import SolverFactory, SolverStatus
PrintSolverOutput = False ###
model = ConcreteModel()
model.dual = Suffix(direction =Suffix.IMPORT)
model.X = Var(I,T, within = NonNegativeReals)
model.In = Var(I,T, within = NonNegativeReals)
model.S = Var(T, within = NonNegativeReals)
def Objetivo(model):
return (sum(C[i]*model.X[i,t]*((1+tau[i])**(t-1))+Ch[i]*model.In[i,t]
for i in I for t in T)
+sum(Cs*model.S[t]
for t in T)
)
model.Total_Cost = Objective(rule = Objetivo, sense= minimize)
def Balance(model,i,t):
if t==1:
return model.X[i,t]+I0[i]-model.In[i,t]==D[i,t]
elif t>=2:
return model.X[i,t]+model.IN[i,t-1]-model.In[i,t]==D[i,t]
def Horas(model, t):
return sum(r[i]*model.X[i,t] for i in I) <= H+model.S[t]
def Limite(model,t):
return model.S[T]<=LS
model.RBalance = Constraint(I,T,rule=Balance)
model.RHoras = Constraint(T,rule=Horas)
model.RLimiteoras = Constraint(T,rule=Limite)
opt = SolverFactory("gurobi")
This is the data
I forgot to put the data before.
T = [1,2,3,4,5,6]
I = ['A','B']
D = {('A',1):300,
('A',2):400,
('A',3):500,
('A',4):600,
('A',5):800,
('A',6):700,
('B',1):700,
('B',2):600,
('B',3):500,
('B',4):400,
('B',5):300,
('B',6):400}
tau = {'A':0.02,'B':0.01}
r = {'A':5,'B':3}
H = 3520
LS = 800
C = {'A':150,'B':120}
Ch = {'A':8,'B':4}
Cs = 6
I0 = {'A':100,'B':250}
error
The code is from a youtube tutorial and it worked for him but not for me. Why?
Aside from fixing two typos in your code, this model computes and solves for me without that error. Make these fixes, run it again, re-post the exact error with line number and the exact code that produces the error if stuck...

How can i add the auxil.py module?

I am trying to perform image classification using Sentinel 1.
I am new to coding so I am using this: http://mortcanty.github.io/src/s1class.html
I got an error saying: auxil is not a module so I thought of installing auxil.py from git hub:
https://github.com/mortcanty/CRCPython/blob/master/src/auxil/auxil.py
but some modules/libraries are outdated so I keep getting errors
any help is much appreciated
It appears the repository you linked is using python 2.7. Are you using python 2 or python 3? Python 2 is no longer being supported (as of 1/1/2020). But, you can still use it--it's just not advised.
You could just define the classes and methods from that repository inside your own code and they will work. For instance, I needed the class Cpm:
class Cpm(object):
'''Provisional means algorithm'''
def __init__(self,N):
self.mn = np.zeros(N)
self.cov = np.zeros((N,N))
self.sw = 0.0000001
def update(self,Xs,Ws=None):
n,N = np.shape(Xs)
if Ws is None:
Ws = np.ones(n)
sw = ctypes.c_double(self.sw)
mn = self.mn
cov = self.cov
provmeans(Xs,Ws,N,n,ctypes.byref(sw),mn,cov)
self.sw = sw.value
self.mn = mn
self.cov = cov
def covariance(self):
c = np.mat(self.cov/(self.sw-1.0))
d = np.diag(np.diag(c))
return c + c.T - d
def means(self):
return self.mn

Why isn't the output recognized with the promotion?

I am trying to change from ''connect'' to ''promotes'' for paraboloid example (without constraint) and I receive the output error.
Output not found for response 'parab.f_xy' in system ''.
Feel free to have a look at the code below, I tried to make it similar to the topic explained in the ""Linking Variables with Promotion vs. Connection"". The code is independent from the released paraboloid component.
from openmdao.api import Problem, ScipyOptimizeDriver, IndepVarComp
from openmdao.core.explicitcomponent import ExplicitComponent
class Paraboloid(ExplicitComponent):
def setup(self):
self.add_input('x', val=0.0)
self.add_input('y', val=0.0)
self.add_output('f_xy', val=0.0)
self.declare_partials('*', '*')
def compute(self, inputs, outputs):
x = inputs['x']
y = inputs['y']
outputs['f_xy'] = (x-3.0)**2 + x*y + (y+4.0)**2 - 3.0
def compute_partials(self, inputs, partials):
x = inputs['x']
y = inputs['y']
partials['f_xy', 'x'] = 2.0*x - 6.0 + y
partials['f_xy', 'y'] = 2.0*y + 8.0 + x
# build the model
prob = Problem()
indeps = prob.model.add_subsystem('indeps', IndepVarComp(), promotes=['*'])
indeps.add_output('x', 3.0)
indeps.add_output('y', -4.0)
prob.model.add_subsystem('parab', Paraboloid(), promotes_inputs=['x','y'] , promotes_outputs=['f_xy'])
# setup the optimization
prob.driver = ScipyOptimizeDriver()
prob.driver.options['optimizer'] = 'SLSQP'
prob.model.add_design_var('indeps.x', lower=-50, upper=50)
prob.model.add_design_var('indeps.y', lower=-50, upper=50)
prob.model.add_objective('parab.f_xy')
prob.setup()
prob.run_driver()
Because you promoted 'f_xy' up from the 'parab' component, your objective should now be named 'f_xy' instead of 'parab.f_xy', and because you promoted 'x' and 'y' up from the 'indeps' component, your design variables should be named 'x' and 'y' instead of 'indeps.x' and 'indeps.y'.

trying to understand SIMPLEST CASE of Python class and self

I'm pretty new to Python, but learning. I'm trying to sort out class and self after talking to professor today. Here's a SIMPLE experiment I am trying with one "calling", Main program, and a separate class with called functions, called from Main and called from inside the class. I've written enough to try to test some of the flexibilities but I'm now debugging and I fear I'll put A BUNCH of stupid garbage in this to try to get it to run. Can someone see what needs to be done please, to get it to run without any excess complication? Thanks!
#######################################################################################################
#
# BoxDemoMain.py calling program
# demonstration of using and calling BoxClass.py pgm
#
#
import numpy as np
import BoxClassPgm
#
#
def ReportBoxDimensions(anySizeBox):
Ht = anySizeBox.boxHeight
Wd = anySizeBox.boxWidth
Dp = anySizeBox.boxDepth
print "The Height, Width, and Depth of this box is " + str(Ht) + "," + str(Wd) + "," + str(Dp)
print "The Surface Area of this box is " + str(BoxClassPgm.BoxClass(anySizeBox).CalcSurfArea())
print "The Volume of this box is " + str(BoxClassPgm.BoxClass(anySizeBox).CalcVolume())
#
#
largeBox = BoxClass(6,8,4)
mediumBox = BoxClass(4,5,3)
smallBox = BoxClass(3,3,3)
#
#
ReportBoxDimensions(largeBox)
ReportBoxDimensions(mediumBox)
ReportBoxDimensions(smallBox)
#######################################################################################################
#
# BoxClassPgm.py class program
# class demonstration
#
#
import numpy as np
#
#
class BoxClass:
def __init__(self,boxHeight=0,boxWidth=0,boxDepth=0):
self.boxHeight = boxHeight
self.boxWidth = boxWidth
self.boxDepth = boxDepth
def CalcVolume(self):
print "height is " + str(self.boxHeight)
boxVol = self.boxHeight * self.boxWidth * self.boxDepth
return boxVol
def CalcSurfArea(self):
areaOf3Faces = BoxClass().CalcFaceAreas()
boxSurfArea = 2 * areaOf3Faces
return boxSurfArea
def CalcFaceAreas(self):
frontBack = self.boxHeight * self.boxWidth
leftRight = self.boxHeight * self.boxDepth
topBottom = self.boxWidth * self.boxDepth
box3Faces = frontBack + leftRight + topBottom

AlwaysError when running a testbench on a synchronizer

I encountered this error when running a testbench, together with a synchronizer built on two existing D-FFs.
File "/home/runner/design.py", line 28, in Sync
#always_seq(clk.posedge, reset=reset)
File "/usr/share/myhdl-0.8/lib/python/myhdl/_always_seq.py", line 76, in _always_seq_decorator
raise AlwaysSeqError(_error.ArgType)
myhdl.AlwaysError: decorated object should be a classic (non-generator) function
My testbench is outlined as follows
from myhdl import *
from random import randrange
HALF_PERIOD = delay(10) ### This makes a 20-ns clock signal
ACTIVE_HIGH = 1
G_DELAY = delay(15)
def Main():
### Signal declaration
clk, d, dout = [Signal(intbv(0)) for i in range(3)]
reset = ResetSignal(1,active=ACTIVE_HIGH,async=True)
### Module Instantiation
S1 = Sync(dout, d, clk,reset)
### Clk generator
#always(HALF_PERIOD)
def ClkGen():
clk.next = not clk
### TB def
#instance
def Driver():
yield(HALF_PERIOD)
reset.next = 0
for i in range(4):
yield(G_DELAY)
d.next = not d
raise StopSimulation
return ClkGen, Driver, S1
m1 = traceSignals(Main)
sim = Simulation(m1)
sim.run()
And my synchronizer is coded as follows.
from myhdl import *
from DFF import *
def Sync(dout,din,clk,reset):
""" The module consists of two FFs with one internal signal
External signals
dout : output
din : input
clk : input
Internal signal:
F2F : output-to-input signal that connects two FFs together
"""
### Connectivity
F2F = Signal(intbv(0))
F1 = DFF(F2F,din,clk,reset)
F2 = DFF(dout,F2F,clk,reset)
### Function
#always_seq(clk.posedge,reset=reset)
def SyncLogic():
if reset:
F2F.next = 0
dout.next = 0
else:
F2F.next = din
yield(WIRE_DELAY)
dout.next = F2F
return SyncLogic
and the FF prototype is coded as follows.
from myhdl import *
def DFF(dout,din,clk,reset):
#always_seq(clk.posedge, reset=reset)
def Flogic():
if reset:
dout.next = 0
else:
dout.next = din
return Flogic
The testbench did work with the similar testbench I coded earlier(with slight modification), but it didn't work when combining two modules together. Please clarify. Thank you.
To model a wire delay, use the "delay" argument in the Signal.
change
#always_seq(clk.posedge,reset=reset)
def SyncLogic():
if reset:
F2F.next = 0
dout.next = 0
else:
F2F.next = din
yield(WIRE_DELAY)
dout.next = F2F
return SyncLogic
to:
dout = Signal(<type>, delay=WIRE_DELAY)
# ...
#always_seq(clk.posedge, reset=reset)
def synclogic():
dout.next = din
With the "always_seq" don't define the reset (it is automatically added). If you want to explicitly define the reset use "#always(clock.posedge, reset.negedge)".

Categories

Resources