Solve DAE with Pyomo and class - class

I'm trying to solve a car problem.
first, I have an original code of car problem:
# Ampl Car Example
#
# Shows how to convert a minimize final time optimal control problem
# to a format pyomo.dae can handle by removing the time scaling from
# the ContinuousSet.
#
# min tf
# dxdt = 0
# dvdt = a-R*v^2
# x(0)=0; x(tf)=L
# v(0)=0; v(tf)=0
# -3<=a<=1
from pyomo.environ import *
from pyomo.dae import *
m = ConcreteModel()
m.R = Param(initialize=0.001) # Friction factor
m.L = Param(initialize=100.0) # Final position
m.tau = ContinuousSet(initialize=[0.0, 0.80, 1.0]) # Unscaled time
m.time = Var(m.tau) # Scaled time
m.tf = Var()
m.x = Var(m.tau,bounds=(0,None))
m.v = Var(m.tau,bounds=(0,None))
m.a = Var(m.tau, bounds=(-3.0,1.0),initialize=0)
m.dtime = DerivativeVar(m.time)
m.dx = DerivativeVar(m.x)
m.dv = DerivativeVar(m.v)
m.obj = Objective(expr=m.tf)
def _ode1(m,i):
if i == 0 :
return Constraint.Skip
return m.dx[i] == m.tf * m.v[i]
m.ode1 = Constraint(m.tau, rule=_ode1)
def _ode2(m,i):
if i == 0 :
return Constraint.Skip
return m.dv[i] == m.tf*(m.a[i] - m.R*m.v[i]**2)
m.ode2 = Constraint(m.tau, rule=_ode2)
def _ode3(m,i):
if i == 0:
return Constraint.Skip
return m.dtime[i] == m.tf
m.ode3 = Constraint(m.tau, rule=_ode3)
def _init(m):
yield m.x[0] == 0
yield m.x[1] == m.L
yield m.v[0] == 0
yield m.v[1] == 0
yield m.time[0] == 0
m.initcon = ConstraintList(rule=_init)
discretizer = TransformationFactory('dae.collocation')
discretizer.apply_to(m,ncp=1, scheme='LAGRANGE-RADAU')
solver = SolverFactory('ipopt')
solver.solve(m, tee=True)
print("final time = %6.2f" %(value(m.tf)))
Now, I want to use class to express a car,then I could instantiate two cars.
So I write like this:
from pyomo.environ import *
from pyomo.dae import *
m = ConcreteModel()
class Car():
def __init__(self,friction):
self.friction = friction
self.R = Param(initialize = self.friction) # Friction factor
self.tau = ContinuousSet(bounds=(0, 1)) # Unscaled time
self.time = Var(self.tau) # Scaled time
self.tf = Var()
self.x = Var(self.tau, bounds=(0, None), initialize=0)
self.v = Var(self.tau, bounds=(0, None))
self.a = Var(self.tau, bounds=(-3.0, 1.0), initialize=0)
self.dtime = DerivativeVar(self.time)
self.dx = DerivativeVar(self.x)
self.dv = DerivativeVar(self.v)
def _ode1(m, i):
if i == 0:
return Constraint.Skip
return self.dx[i] == m.tf * self.v[i]
self.ode1 = Constraint(self.tau, rule=_ode1)
def _ode2(m, i):
if i == 0:
return Constraint.Skip
return self.dv[i] == m.tf * (self.a[i] - self.R * self.v[i] ** 2)
self.ode2 = Constraint(self.tau, rule=_ode2)
def _ode3(m, i):
if i == 0:
return Constraint.Skip
return self.dtime[i] == m.tf
self.ode3 = Constraint(self.tau, rule=_ode3)
m.car1 = Car(0.001)
m.obj = Objective(expr=m.car1.tf)
def _init(m):
yield m.car1.x[0] == 0
yield m.car1.x[1] == 100
yield m.car1.v[0] == 0
yield m.car1.v[1] == 0
yield m.car1.time[0] == 0
m.car1.initcon = ConstraintList(rule=_init)
discretizer = TransformationFactory('dae.finite_difference')
discretizer.apply_to(m, nfe=10, scheme='BACKWARD')
solver = SolverFactory('ipopt')
solver.solve(m, tee=True)
print("final time = %6.2f" % (value(m.car1.tf)))
However, I get this:
Traceback (most recent call last):
File "D:/pyo/pyomoceshi/ceshi3/car/classcar3.py", line 79, in <module>
solver.solve(m, tee=True)
File "D:\python\m\lib\site-packages\pyomo\opt\base\solvers.py", line 582, in solve
self._presolve(*args, **kwds)
File "D:\python\m\lib\site-packages\pyomo\opt\solver\shellcmd.py", line 196, in _presolve
OptSolver._presolve(self, *args, **kwds)
File "D:\python\m\lib\site-packages\pyomo\opt\base\solvers.py", line 661, in _presolve
**kwds)
File "D:\python\m\lib\site-packages\pyomo\opt\base\solvers.py", line 729, in _convert_problem
**kwds)
File "D:\python\m\lib\site-packages\pyomo\opt\base\convert.py", line 110, in convert_problem
problem_files, symbol_map = converter.apply(*tmp, **tmpkw)
File "D:\python\m\lib\site-packages\pyomo\solvers\plugins\converter\model.py", line 164, in apply
io_options=io_options)
File "D:\python\m\lib\site-packages\pyomo\core\base\block.py", line 1646, in write
io_options)
File "D:\python\m\lib\site-packages\pyomo\repn\plugins\ampl\ampl_.py", line 357, in __call__
include_all_variable_bounds=include_all_variable_bounds)
File "D:\python\m\lib\site-packages\pyomo\repn\plugins\ampl\ampl_.py", line 783, in _print_model_NL
list(self_varID_map[id(var)] for var in ampl_repn._linear_vars),
File "D:\python\m\lib\site-packages\pyomo\repn\plugins\ampl\ampl_.py", line 783, in <genexpr>
list(self_varID_map[id(var)] for var in ampl_repn._linear_vars),
KeyError: 68767416L
I want to know how to solve it or use other ways.

Below is a working version of your script. I changed things so that instead of a Car class there is a Car function that returns a Pyomo Block representing the car. By having a Car class you were essentially trying to create a subclass of Block and running into several subtle challenges that go along with that. You can see the blog post here for more information. The second change I made was in your declaration of the initial conditions, I changed the name of the ConstraintList from m.car1.initcon to m.car1_initcon. The difference is whether you want the ConstraintList to live on the car1 Block or the model. In your code, the 'dot' in the name meant you were trying to put it on the car1 Block but the constraints yielded in the rule were relative to the model. I changed the name to resolve this inconsistency.
from pyomo.environ import *
from pyomo.dae import *
m = ConcreteModel()
def Car(model, friction):
def construct_car_block(b):
b.R = Param(initialize = friction) # Friction factor
b.tau = ContinuousSet(bounds=(0, 1)) # Unscaled time
b.time = Var(b.tau) # Scaled time
b.tf = Var()
b.x = Var(b.tau, bounds=(0, None), initialize=0)
b.v = Var(b.tau, bounds=(0, None))
b.a = Var(b.tau, bounds=(-3.0, 1.0), initialize=0)
b.dtime = DerivativeVar(b.time)
b.dx = DerivativeVar(b.x)
b.dv = DerivativeVar(b.v)
def _ode1(b, i):
if i == 0:
return Constraint.Skip
return b.dx[i] == b.tf * b.v[i]
b.ode1 = Constraint(b.tau, rule=_ode1)
def _ode2(b, i):
if i == 0:
return Constraint.Skip
return b.dv[i] == b.tf * (b.a[i] - b.R * b.v[i] ** 2)
b.ode2 = Constraint(b.tau, rule=_ode2)
def _ode3(m, i):
if i == 0:
return Constraint.Skip
return b.dtime[i] == b.tf
b.ode3 = Constraint(b.tau, rule=_ode3)
return Block(rule=construct_car_block)
m.car1 = Car(m, friction=0.001)
m.obj = Objective(expr=m.car1.tf)
def _init(m):
yield m.car1.x[0] == 0
yield m.car1.x[1] == 100
yield m.car1.v[0] == 0
yield m.car1.v[1] == 0
yield m.car1.time[0] == 0
m.car1_initcon = ConstraintList(rule=_init)
discretizer = TransformationFactory('dae.finite_difference')
discretizer.apply_to(m, nfe=15, scheme='BACKWARD')
solver = SolverFactory('ipopt')
solver.solve(m, tee=True)
print("final time = %6.2f" % (value(m.car1.tf)))

Related

Name of Modules to compute sparsity

I'm writing a function that computes the sparsity of the weight matrices of the following fully connected network:
class FCN(nn.Module):
def __init__(self):
super(FCN, self).__init__()
self.fc1 = nn.Linear(input_dim, hidden_dim)
self.relu1 = nn.ReLU()
self.fc2 = nn.Linear(hidden_dim, hidden_dim)
self.relu2 = nn.ReLU()
self.fc3 = nn.Linear(hidden_dim, hidden_dim)
self.relu3 = nn.ReLU()
self.fc4 = nn.Linear(hidden_dim, output_dim)
def forward(self, x):
out = self.fc1(x)
out = self.relu1(out)
out = self.fc2(out)
out = self.relu2(out)
out = self.fc3(out)
out = self.relu3(out)
out = self.fc4(out)
return out
The function I have written is the following:
def print_layer_sparsity(model):
for name,module in model.named_modules():
if 'fc' in name:
zeros = 100. * float(torch.sum(model.name.weight == 0))
tot = float(model.name.weight.nelement())
print("Sparsity in {}.weight: {:.2f}%".format(name, zeros/tot))
But it gives me the following error:
torch.nn.modules.module.ModuleAttributeError: 'FCN' object has no attribute 'name'
It works fine when I manually enter the name of the layers (e.g.,
(model.fc1.weight == 0)
(model.fc2.weight == 0)
(model.fc3.weight == 0) ....
but I'd like to make it independent from the network. In other words, I'd like to adapt my function in a way that, given any sparse network, it prints the sparsity of every layer. Any suggestions?
Thanks!!
Try:
getattr(model, name).weight
In place of
model.name.weight
Your print_layer_sparsity function becomes:
def print_layer_sparsity(model):
for name,module in model.named_modules():
if 'fc' in name:
zeros = 100. * float(torch.sum(getattr(model, name).weight == 0))
tot = float(getattr(model, name).weight.nelement())
print("Sparsity in {}.weight: {:.2f}%".format(name, zeros/tot))
You can't do model.name because name is a str. The in-built getattr function allows you to get the member variables / attributes of an object using its name as a string.
For more information, checkout this answer.

Using zero_grad() after loss.backward(), but still receives RuntimeError: "Trying to backward through the graph a second time..."

Below is my implementation of a2c using PyTorch. Upon learning about backpropagation in PyTorch, I have known to zero_grad() the optimizer after each update iteration. However, there is still a RunTime error on second-time backpropagation.
def torchworker(number, model):
worker_env = gym.make("Taxi-v3").env
max_steps_per_episode = 2000
worker_opt = optim.Adam(lr=5e-4, params=model.parameters())
p_history = []
val_history = []
r_history = []
running_reward = 0
episode_count = 0
under = 0
start = time.time()
for i in range(2):
state = worker_env.reset()
episode_reward = 0
penalties = 0
drop = 0
print("Episode {} begins ({})".format(episode_count, number))
worker_env.render()
criterion = nn.SmoothL1Loss()
time_solve = 0
for _ in range(1, max_steps_per_episode):
#worker_env.render()
state = torch.tensor(state, dtype=torch.long)
action_probs = model.forward(state)[0]
critic_value = model.forward(state)[1]
val_history.append((state, critic_value[0]))
# Choose action
action = np.random.choice(6, p=action_probs.detach().numpy())
p_history.append(torch.log(action_probs[action]))
# Apply chosen action
state, reward, done, _ = worker_env.step(action)
r_history.append(reward)
episode_reward += reward
time_solve += 1
if reward == -10:
penalties += 1
elif reward == 20:
drop += 1
if done:
break
# Update running reward to check condition for solving
running_reward = (running_reward * (episode_count) + episode_reward) / (episode_count + 1)
# Calculate discounted returns
returns = deque(maxlen=3500)
discounted_sum = 0
for r in r_history[::-1]:
discounted_sum = r + gamma * discounted_sum
returns.appendleft(discounted_sum)
# Calculate actor losses and critic losses
loss_actor_value = 0
loss_critic_value = 0
history = zip(p_history, val_history, returns)
for log_prob, value, ret in history:
diff = ret - value[1]
loss_actor_value += -log_prob * diff
ret_tensor = torch.tensor(ret, dtype=torch.float32)
loss_critic_value += criterion(value[1], ret_tensor)
loss = loss_actor_value + 0.1 * loss_critic_value
print(loss)
# Update params
loss.backward()
worker_opt.step()
worker_opt.zero_grad()
# Log details
end = time.time()
episode_count += 1
if episode_count % 1 == 0:
worker_env.render()
if running_reward > -50: # Condition to consider the task solved
under += 1
if under > 5:
print("Solved at episode {} !".format(episode_count))
break
I believe there may be something to do with the architecture of my AC model, so I also include it here for reference.
class ActorCriticNetwork(nn.Module):
def __init__(self, num_inputs, num_hidden, num_actions):
super(ActorCriticNetwork, self).__init__()
self.embed = nn.Embedding(500, 10)
self.fc1 = nn.Linear(10, num_hidden * 2)
self.fc2 = nn.Linear(num_hidden * 2, num_hidden)
self.c = nn.Linear(num_hidden, 1)
self.fc3 = nn.Linear(num_hidden, num_hidden)
self.a = nn.Linear(num_hidden, num_actions)
def forward(self, x):
out = F.relu(self.embed(x))
out = F.relu(self.fc1(out))
out = F.relu(self.fc2(out))
critic = self.c(out)
out = F.relu(self.fc3(out.detach()))
actor = F.softmax(self.a(out), dim=-1)
return actor, critic
Would you please tell me what the mistake here is? Thank you in advance.
SOLVED: I forgot to clear the history of probabilities, action-values and rewards after iterations. It is clear why that would cause the issue, as the older elements would cause propagating through old dcgs.

proplem in program by python fractions

i have error in my code that write by python about fractions but I fase me proplem.
The error is that I don't know how to ask the object
Save the variable value of Objet and then call the aldea that do the mathematical operatio
plese help me to correct it
from fractions import*
# for testing vlaues
f12 = Fraction(1,2)
f44 = Fraction(4,4)
f128 = Fraction(12,8)
f32 = Fraction(3,2)
class Fraction:
def __init__ (self, numerator, denominator):
self.numerator = numerator
self.denominator = denominator
if self.denominator == 0:
raise ZeroDivisionError("sorry you are dividing by zero")
def sum(self, other):
numerator = (self.numerator * other.denominator) + (self.denominator +
other.numerator)
denominator = (self.denominator * other.denominator)
return Fraction(numerator/denominator)
def minus(self, other):
numerator = (self.numerator * other.denominator) - (self.denominator +
other.numerator)
denominator = (self.denominator * other.denominator)
return Fraction(numerator/denominator)
def times(self, other):
numerator = self.numerator * other.numerator
denominator = self.denominator * other.denominator
return Fraction(numerator/denominator)
def divid (self, other):
numerator = self.numerator * other.denominator
denominator = self.denominator * other.numerator
return Fraction(numerator/denominator)
def equals(self, other):
return self.numerator * other.denominator == self.denominator *
other.numerator
def test_suite(self,other):
if self == f12:
print(f"[{f12} + {f12} == {f12.sum(f12)} ] [4/4]")
elif self == f44 and other == f12:
print(f"[{f44} - {f12} == {f44.sum(f12)} ] [12/8]")
elif self == f12 and other == f44:
print(f"[{f12} + {f44} == {f12.minus(f44)} ] [4/8]")
elif self == f128 and other == f32:
print(f"[{f128} == {f32} == {f128.requal(f32)} ] [True]")
def main():
print("Wlecome to Fraction Caculator!")
numerator_1 = input("Fraction 1 Numerator: ")
denominator_1 = input("Fraction 1 denominator ")
f12 = Fraction(numerator_1, denominator_1)
numerator_2 = input("Fraction 2 Numerator: ")
denominator_2 = input("Fraction 2 denominator ")
f44 = Fraction(numerator_2, denominator_2)
#for texting parts
operation = print("Please enter the operation +, - , *, //, %, == ")
if operation == "+":
f12.sum(f44)
elif operation == "-":
f12.mins(f44)
elif operation == "*":
f12.times(f44)
elif operation == "//":
f12.divid(f44)
#for texting values
if __name__ == "_ _ main _ _ ":
main()

Naive Bayes classification technique algorithm

I found a code online for Naive bayes classification for a small research I am doing. The code I am using is showing some errors and cannot find the solution for them. I would greatly appreciate your help.
The code is below:
# Example of Naive Bayes implemented from Scratch in Python
import csv
import random
import math
def loadCsv(filename):
lines = csv.reader(open(filename, "rt"))
dataset = list(lines)
for i in range(len(dataset)):
dataset[i] = [float(x) for x in dataset[i]]
return dataset
def splitDataset(dataset, splitRatio):
trainSize = int(len(dataset) * splitRatio)
trainSet = []
copy = list(dataset)
while len(trainSet) < trainSize:
index = random.randrange(len(copy))
trainSet.append(copy.pop(index))
return [trainSet, copy]
def separateByClass(dataset):
separated = {}
for i in range(len(dataset)):
vector = dataset[i]
if (vector[-1] not in separated):
separated[vector[-1]] = []
separated[vector[-1]].append(vector)
return separated
def mean(numbers):
return sum(numbers) / float(len(numbers))
def stdev(numbers):
avg = mean(numbers)
variance = sum([pow(x - avg, 2) for x in numbers]) / float(len(numbers) - 1)
return math.sqrt(variance)
def summarize(dataset):
summaries = [(mean(attribute), stdev(attribute)) for attribute in zip(*dataset)]
del summaries[-1]
return summaries
def summarizeByClass(dataset):
separated = separateByClass(dataset)
summaries = {}
for classValue, instances in separated.items():
summaries[classValue] = summarize(instances)
return summaries
def calculateProbability(x, mean, stdev):
exponent = math.exp(-(math.pow(x - mean, 2) / (2 * math.pow(stdev, 2))))
return (1 / (math.sqrt(2 * math.pi) * stdev)) * exponent
def calculateClassProbabilities(summaries, inputVector):
probabilities = {}
for classValue, classSummaries in summaries.items():
probabilities[classValue] = 1
for i in range(len(classSummaries)):
mean, stdev = classSummaries[i]
x = inputVector[i]
probabilities[classValue] *= calculateProbability(x, mean, stdev)
return probabilities
def predict(summaries, inputVector):
probabilities = calculateClassProbabilities(summaries, inputVector)
bestLabel, bestProb = None, -1
for classValue, probability in probabilities.items():
if bestLabel is None or probability > bestProb:
bestProb = probability
bestLabel = classValue
return bestLabel
def getPredictions(summaries, testSet):
predictions = []
for i in range(len(testSet)):
result = predict(summaries, testSet[i])
predictions.append(result)
return predictions
def getAccuracy(testSet, predictions):
correct = 0
for i in range(len(testSet)):
if testSet[i][-1] == predictions[i]:
correct += 1
return (correct / float(len(testSet))) * 100.0
def main():
filename = 'E:\iris.data.csv'
splitRatio = 0.67
dataset = loadCsv(filename)
trainingSet, testSet = splitDataset(dataset, splitRatio)
print(('Split {0} rows into train={1} and test={2} rows').format(len(dataset), len(trainingSet), len(testSet)))
# prepare model
summaries = summarizeByClass(trainingSet)
# test model
predictions = getPredictions(summaries, testSet)
accuracy = getAccuracy(testSet, predictions)
print(('Accuracy: {0}%').format(accuracy))
main()
The traceback for the same is below:
File "<ipython-input-18-4397d9969e66>", line 1, in <module>
runfile('C:/Users/Lenovo/Desktop/EE Codes/Knn with prima.py', wdir='C:/Users/Lenovo/Desktop/EE Codes')
File "C:\Users\Lenovo\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 710, in runfile
execfile(filename, namespace)
File "C:\Users\Lenovo\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 101, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "C:/Users/Lenovo/Desktop/EE Codes/Knn with prima.py", line 76, in <module>
main()
File "C:/Users/Lenovo/Desktop/EE Codes/Knn with prima.py", line 69, in main
neighbors = getNeighbors(trainingSet, testSet[x], k)
File "C:/Users/Lenovo/Desktop/EE Codes/Knn with prima.py", line 31, in getNeighbors
dist = euclideanDistance(testInstance, trainingSet[x], length)
File "C:/Users/Lenovo/Desktop/EE Codes/Knn with prima.py", line 24, in euclideanDistance
distance += pow((instance1[x] - instance2[x]), 2)
TypeError: unsupported operand type(s) for -: 'str' and 'str'
I would request you all to please provide a solution to how to solve this error for the respective code. If you require the dataset then please do ask. I can provide you the link for that too.
Thanks in advance

instance has no attribute __getitem__

I am working on a life simulation game based on the game of life in web2py. I have two objects which contain several arrays for the various attributes of the organisms in each space on the grid. I received this error LifeSpace instance has no attribute 'getitem' on the line containing this code nxt[i][j] = processNeighborsEmpty (i, j, cur)
am I referencing the object instance improperly?
ROWS = 60
COLS = 60
GENERATIONS = 100
DELAY = 0.5
#---------------------------------------------------------------------------
class LifeSpace :
def __init__(self):
self.genus = []
self.species = []
self.tribe = []
self.hunger = []
self.wounds = []
self.age = []
self.genus = initGrid (COLS, ROWS, self.genus)
self.species = initGrid (COLS, ROWS, self.species)
self.tribe = initGrid (COLS, ROWS, self.tribe)
self.hunger = initGrid(COLS, ROWS, self.hunger)
self.wounds = initGrid(COLS, ROWS, self.wounds)
self.age = initGrid(COLS, ROWS, self.age)
#---------------------------------------------------------------------------
def initGrid(cols, rows, array):
for i in range(rows):
arrayRow = []
for j in range(cols):
arrayRow+= [0]
array += [arrayRow]
return array
#---------------------------------------------------------------------------
def printGen(cols, rows, array, genNo):
return("Game of Life -- Generation " + str(genNo + 1))
for i in range(rows):
for j in range(cols):
if array.species[i][j] == 0:
return(" ")
elif array.species[i][j] == 'weed':
return("3")
return("\n")
#---------------------------------------------------------------------------
def processNeighborsEmpty(x, y, array):
for j in range(y-1,y+1):
for i in range(x-1,x+1):
if not(i == x and j == y):
if array.genus[i][j] == "plant" :
if array.age[i][j] == "adult" :
array.species[x][y] = array.species[i][j]
array.genus[x][y] = array.genus[i][j]
array.age[x][y] = "seed"
return array[x][y]
#---------------------------------------------------------------------------
def processNeighborsPlant(x, y, array):
if array.age[x][y] != "adult" :
if array.species[x][y] == "tree" :
if array.age[x][y] == "sapling" :
array.age[x][y] = "adult"
elif array.age[x][y] == "seed" :
array.age[x][y] = "sapling"
elif array.age[x][y] == "seed" :
array.age[x][y] = "adult"
#---------------------------------------------------------------------------
def processNextGen(cols, rows, cur, nxt):
for i in range(0,rows):
for j in range(0,cols):
if cur.genus[i][j] == 0 :
nxt[i][j] = processNeighborsEmpty (i, j, cur)
elif cur.genus[i][j] == "plant" :
nxt[i][j] = processNeighborsPlant(i, j, cur)
#---------------------------------------------------------------------------
############################################################################
#---------------------------------------------------------------------------
def index():
thisGen = LifeSpace()
nextGen = LifeSpace()
thisGen.genus[25][25] = "plant"
thisGen.species[25][25] = "weed"
thisGen.age[25][25] = "adult"
for gens in range(GENERATIONS):
printGen(COLS, ROWS, thisGen, gens)
processNextGen(COLS, ROWS, thisGen, nextGen)
time.sleep(DELAY)
thisGen, nextGen = nextGen, thisGen
input("Finished. Press <return> to quit.")
nxt is a LifeSpace object so you cannot reference to it using [] notation.
You need to use nxt.attribute[x][y] with the correct attribute. Maybe nxt.genux[x][y] is what you want to use.