In this case, how do I handle nil well? - crystal-lang

Situation
I wrote the following code.
class Gear
getter :chainring, :cog, :wheel
def initialize(#chainring : Int32, #cog : Int32, #wheel : Wheel?)
end
def ratio
chainring / cog.to_f
end
def gear_inches
ratio * wheel.diameter
end
end
Then the following compilation error occurs
$ crystal run gear.cr
Showing last frame. Use --error-trace for full trace.
In bicycle.cr:12:19
12 | ratio * wheel.diameter
Things I want to do
I want to fix this compilation error without using try method.
What I tried, what I researched
Crystal language does not allow the use of safe navigation operator.
Execute the diameter method only if the wheel variable is truthy, as in TypeScript.An example is given below.
def gear_inches
if wheel
ratio * wheel.diameter
else
0
end
end
That's it for questions.
I would appreciate any advice you can give me.

In a concurrent program the value of an instance variable could change between any two accesses to it. getter wheel makes wheel just return the instance variable #wheel. So between checking if wheel and the second call in wheel.diameter Crystal cannot tell that the value couldn't have changed.
The usual solution to this is to assign the value to a local variable, which allows Crystal to reason about when the value cannot change:
record Wheel, diameter : Int32
class Gear
getter :chainring, :cog, :wheel
def initialize(#chainring : Int32, #cog : Int32, #wheel : Wheel?)
end
def ratio
chainring / cog.to_f
end
def gear_inches
(wheel = self.wheel) ? ratio * wheel.diameter : 0
end
end
gear = Gear.new(1, 2, Wheel.new(3))
puts gear.gear_inches
In many situations a nice alternative is to see if you can find a default value to internally return for your optional field:
record Wheel, diameter : Int32
class Gear
getter :chainring, :cog
def initialize(#chainring : Int32, #cog : Int32, #wheel : Wheel?)
end
def ratio
chainring / cog.to_f
end
def gear_inches
ratio * wheel.diameter
end
private def wheel
#wheel || Wheel.new(0)
end
end
gear = Gear.new(1, 2, nil)
puts gear.gear_inches

Related

efficient update of objective function in pyomo (for re-solving)

I have a model that I need to solve many times, with different objective function coefficients.
Naturally, I want to spend as little time as possible on updating the model.
My current setup is as follows (simplified):
Abstract model:
def obj_rule(m):
return sum(Dist[m, n] * m.flow[m,n] for (m,n) in m.From * m.To)
m.obj = Objective(rule=obj_rule, sense=minimize)
After solve, I update the concrete model instance mi this way, we new values in Dist:
mi.obj = sum(Dist[m, n] * mi.flow[m,n] for (m,n) in mi.From * mi.To)
However, I see that the update line takes a lot of time - ca. 1/4 of the overall solution time, several seconds for bigger cases.
Is there some faster way of updating the objective function?
(After all, in the usual way of saving an LP model, the objective function coefficients are in a separate vector, so changing them should not affect anything else.)
Do you have a reason to define an Abstract model before creating your Concrete model? If you define your concrete model with the rule you show above, you should be able to just update your data and re-solve the model without a lot of overhead since you do don't redefine the objective object. Here's a simple example where I change the values of the cost parameter and re-solve.
import pyomo.environ as pyo
a = list(range(2)) # set the variables define over
#%% Begin basic model
model = pyo.ConcreteModel()
model.c = pyo.Param(a,initialize={0:5,1:3},mutable=True)
model.x = pyo.Var(a,domain = pyo.Binary)
model.con = pyo.Constraint(expr=model.x[0] + model.x[1] <= 1)
def obj_rule(model):
return(sum(model.x[ind] * model.c[ind] for ind in a))
model.obj = pyo.Objective(rule=obj_rule,sense=pyo.maximize)
#%% Solve the first time
solver = pyo.SolverFactory('glpk')
res=solver.solve(model)
print('x[0]: {} \nx[1]: {}'.format(pyo.value(model.x[0]),
pyo.value(model.x[1])))
# x[0]: 1
# x[1]: 0
#%% Update data and re-solve
model.c.reconstruct({0:0,1:5})
res=solver.solve(model)
print('x[0]: {} \nx[1]: {}'.format(pyo.value(model.x[0]),
pyo.value(model.x[1])))
# x[0]: 0
# x[1]: 1

is there any clue this implementation represent which activation function

Here is code :
def _hard_sigmoid(x):
return tf.clip_by_value(tf.rint((x*0.2)/0.5),tf.rint(0.0),tf.rint(1.0))
def binary_tanh(x): # activation binarization to 1 and 0
a = (_hard_sigmoid(x)/0.5)*0.2
b = tf.clip_by_value(x, 0, 1)
return K.stop_gradient(a-b)+b
binary_tanh(x) # we are calling this function
This related to squeezedet CNN network activation function for each layer.
My question
Which activation function it represents.
What value I can set for my demo application. Like here they are dividing with some value and multiply by some value.

How to create a container in pymc3

I am trying to build a model for the likelihood function of a particular outcome of a Langevin equation (Brownian particle in a harmonic potential):
Here is my model in pymc2 that seems to work:
https://github.com/hstrey/BayesianAnalysis/blob/master/Langevin%20simulation.ipynb
#define the model/function to be fitted.
def model(x):
t = pm.Uniform('t', 0.1, 20, value=2.0)
A = pm.Uniform('A', 0.1, 10, value=1.0)
#pm.deterministic(plot=False)
def S(t=t):
return 1-np.exp(-4*delta_t/t)
#pm.deterministic(plot=False)
def s(t=t):
return np.exp(-2*delta_t/t)
path = np.empty(N, dtype=object)
path[0]=pm.Normal('path_0',mu=0, tau=1/A, value=x[0], observed=True)
for i in range(1,N):
path[i] = pm.Normal('path_%i' % i,
mu=path[i-1]*s,
tau=1/A/S,
value=x[i],
observed=True)
return locals()
mcmc = pm.MCMC( model(x) )
mcmc.sample( 20000, 2000, 10 )
The basic idea is that each point depends on the previous point in the chain (Markov chain). Btw, x is an array of data, N is its length, delta_t is the time step =0.01. Any idea how to implement this in pymc3? I tried:
# define the model/function for diffusion in a harmonic potential
DHP_model = pm.Model()
with DHP_model:
t = pm.Uniform('t', 0.1, 20)
A = pm.Uniform('A', 0.1, 10)
S=1-pm.exp(-4*delta_t/t)
s=pm.exp(-2*delta_t/t)
path = np.empty(N, dtype=object)
path[0]=pm.Normal('path_0',mu=0, tau=1/A, observed=x[0])
for i in range(1,N):
path[i] = pm.Normal('path_%i' % i,
mu=path[i-1]*s,
tau=1/A/S,
observed=x[i])
Unfortunately the model crashes as soon as I try to run it. I tried some pymc3 examples (tutorial) on my machine and this is working.
Thanks in advance. I am really hoping that the new samplers in pymc3 will help me with this model. I am trying to apply Bayesian methods to single-molecule experiments.
Rather than creating many individual normally-distributed 1-D variables in a loop, you can make a custom distribution (by extending Continuous) that knows the formula for computing the log likelihood of your entire path. You can bootstrap this likelihood formula off of the Normal likelihood formula that pymc3 already knows. See the built-in AR1 class for an example.
Since your particle follows the Markov property, your likelihood looks like
import theano.tensor as T
def logp(path):
now = path[1:]
prev = path[:-1]
loglik_first = pm.Normal.dist(mu=0., tau=1./A).logp(path[0])
loglik_rest = T.sum(pm.Normal.dist(mu=prev*ss, tau=1./A/S).logp(now))
loglik_final = loglik_first + loglik_rest
return loglik_final
I'm guessing that you want to draw a value for ss at every time step, in which case you should make sure to specify ss = pm.exp(..., shape=len(x)-1), so that prev*ss in the block above gets interpreted as element-wise multiplication.
Then you can just specify your observations with
path = MyLangevin('path', ..., observed=x)
This should run much faster.
Since I did not see an answer to my question, let me answer it myself. I came up with the following solution:
# now lets model this data using pymc
# define the model/function for diffusion in a harmonic potential
DHP_model = pm.Model()
with DHP_model:
D = pm.Gamma('D',mu=mu_D,sd=sd_D)
A = pm.Gamma('A',mu=mu_A,sd=sd_A)
S=1.0-pm.exp(-2.0*delta_t*D/A)
ss=pm.exp(-delta_t*D/A)
path=pm.Normal('path_0',mu=0.0, tau=1/A, observed=x[0])
for i in range(1,N):
path = pm.Normal('path_%i' % i,
mu=path*ss,
tau=1.0/A/S,
observed=x[i])
start = pm.find_MAP()
print(start)
trace = pm.sample(100000, start=start)
unfortunately, this code takes at N=50 anywhere between 6hours to 2 days to compile. I am running on a pretty fast PC (24Gb RAM) running Ubuntu. I tried to using the GPU but that runs slightly slower. I suspect memory problems since it uses 99.8% of the memory when running. I tried the same calculation with Stan and it only takes 2min to run.

meaning of setUseAdjustedValues(True) om pyalgotrade

Here is an example of SMA cross strategy, what is the reason we use self.setUseAdjustedValues(True)
and how does it works?
from pyalgotrade import strategy
from pyalgotrade.technical import ma
from pyalgotrade.technical import cross
class SMACrossOver(strategy.BacktestingStrategy):
def __init__(self, feed, instrument, smaPeriod):
strategy.BacktestingStrategy.__init__(self, feed)
self.__instrument = instrument
self.__position = None
# We'll use adjusted close values instead of regular close values.
self.setUseAdjustedValues(True)
self.__prices = feed[instrument].getPriceDataSeries()
self.__sma = ma.SMA(self.__prices, smaPeriod)
def getSMA(self):
return self.__sma
def onEnterCanceled(self, position):
self.__position = None
def onExitOk(self, position):
self.__position = None
def onExitCanceled(self, position):
# If the exit was canceled, re-submit it.
self.__position.exitMarket()
def onBars(self, bars):
# If a position was not opened, check if we should enter a long position.
if self.__position is None:
if cross.cross_above(self.__prices, self.__sma) > 0:
shares = int(self.getBroker().getCash() * 0.9 / bars[self.__instrument].getPrice())
# Enter a buy market order. The order is good till canceled.
self.__position = self.enterLong(self.__instrument, shares, True)
# Check if we have to exit the position.
elif not self.__position.exitActive() and cross.cross_below(self.__prices, self.__sma) > 0:
self.__position.exitMarket()
If you use regular close values, instead of adjusted ones, your strategy may react to price changes that are actually the result of a stock split and not a price change due to regular trading activity.
As I understood and trying to simplify it, suppose a share of price is 100.
-> next day share splits in 1:2 means 2 shares of 50 each. this price change are not due to trading activities, there is not trade involve for lower this price. So setUseAdjustedValues(True) handle this situation.

Updating label values using after() method .

I am trying to create a page in which has ten labels and then update the values using the after() method .But the screen hangs .
The start definition is bind to a button creates the labels , and then using after method i am trying to call the update method in recursive fashion to update the label values .
Is their another way to call the update() method from the main function (main) .
def update(self,i):
self.lab_hold_X=25
self.data_hold_mL_screen[i].place(x=self.lab_hold_X,y=self.y_place)
self.data_hold_mL_screen[i]['text']=str(int(self.data_hold_mL_screen[i]['text']) + 1)
self.y_place +=30
self.valuess=i+1
if self.valuess <=10:
self.after(1000,self.update(self.valuess))
else :
self.valuess=0
self.after(1000,self.update(self.valuess))
def start(self):
self.lab_hold_X=25
self.lab_hold_Y=10
for i in range(0,10):
self.lab_hold_Y +=30
self.data_hold_mL_screen[i].place(x=self.lab_hold_X,y=self.lab_hold_Y)
self.lab_hold_X =25
self.after(1000,update(0))
I basically wish to create a page wherein i can get values from any external device and then display it on the screen , screen shows 10 values , on 11th iteration a value is recieved the screen shifts upward and the 1st value is discarded and the second value is displayed in 1st label position ..
This:
self.after(1000,update(0))
... needs to be this:
self.after(1000,lambda: update(0))
The same is true for the other places you call after. after requires a reference to a function, but you are calling the function and passing the result of the function to after. And since your function returns nothing, nothing is getting executed after 1000 ms.
A simple example using a list to hold the last 10 values, and a second list to hold the Label's StringVars that are updated. And please do not use "i", "l", or "O" as single character variable names as they can look like numbers.
from Tkinter import *
from functools import partial
class LabelTest():
def __init__(self, master):
self.master=master
self.string_vars=[] ## contains pointers to the label vars
self.values=[]
self.start()
Button(self.master, text="Quit", bg="orange", width=15,
command=self.master.quit).grid(row=20)
self.update(1)
def update(self, ctr):
""" Change the StringVars to the new values
"""
if len(self.values) > 9:
## full so delete the first one
del self.values[0]
self.values.append(ctr)
## update the StringVar with the corresponding
## value from self.values
for offset in range(len(self.values)):
self.string_vars[offset].set(self.values[offset])
ctr += 1
if ctr < 20: ## let's put a limit on this
self.master.after(1000, partial(self.update, ctr))
def start(self):
""" create 10 labels with StringVars that can be changed
each time a new value is created
"""
for ctr in range(10):
var=StringVar()
lab=Label(self.master, textvariable=var).grid(row=ctr)
self.string_vars.append(var) ## the variables to be updated
## initial variable value
self.values.append("***") ## the values
master=Tk()
LabelTest(master)
master.mainloop()