How to solve error 'Callbacks disabled in gurobi'? - callback

Currently I am investigating an MILP in Pyomo with gurobi. I would like to be able to add cuts during the B&B and found that callback functions can be used for this purpose. However, when I try to implement a callback function I get the following error: "callbacks disabled for solver gurobi" (or: callbacks disabled for gurobi_persistent). This error does not seem very common, does someone have any experience with it?
I am quite new to both Pyomo and gurobi.
My code is the following (an example that I found through the Pyomo documentation).
from gurobipy import GRB
import pyomo.environ as pe
#from pyomo.core.expr.taylor_series import taylor_series_expansion
m = pe.ConcreteModel()
m.x = pe.Var(bounds=(0, 4))
m.y = pe.Var(within=pe.Integers, bounds=(0, None))
m.obj = pe.Objective(expr=2*m.x + m.y)
m.cons = pe.ConstraintList() # for the cutting planes
def _add_cut(xval):
# a function to generate the cut
m.x.value = xval
return m.cons.add(m.y >= ((m.x - 2)**2))
_add_cut(0) # start with 2 cuts at the bounds of x
_add_cut(4) # this is an arbitrary choice
opt = pe.SolverFactory('gurobi_persistent')
opt.set_instance(m)
#opt.set_gurobi_param('PreCrush', 1)
#opt.set_gurobi_param('LazyConstraints', 1)
def my_callback(cb_m, cb_opt, cb_where):
if cb_where == GRB.Callback.MIPSOL:
cb_opt.cbGetSolution(vars=[m.x, m.y])
if m.y.value < (m.x.value - 2)**2 - 1e-6:
cb_opt.cbLazy(_add_cut(m.x.value))
opt.set_callback(my_callback)
opt.solve()
assert abs(m.x.value - 1) <= 1e-6
assert abs(m.y.value - 1) <= 1e-6
Thanks.

Related

scipy.integrate.nquad ignoring opts?

I need to compute a numerical (triple) integral, but do not need very high precision on the value, and would therefore like to sacrifice some precision for speed when using nquad. I thought that I might be able to do this by increasing the epsrel and/or epsabs options, but they seem to have no effect. For example (note, this is just an example integrand - I don't actually need to compute this particular integral...):
import numpy as np
from scipy.integrate import nquad
def integrand(l, b, d, sigma=250):
x = d * np.cos(l) * np.cos(b)
y = d * np.sin(l) * np.cos(b)
z = d * np.sin(b)
return np.exp(-0.5 * z**2 / sigma**2) / np.sqrt(2*np.pi * sigma**2)
ranges = [
(0, 2*np.pi),
(0.5, np.pi/2),
(0, 1000.)
]
# No specification of `opts` - use the default epsrel and epsabs:
result1 = nquad(integrand, ranges=ranges, full_output=True)
# Set some `quad` opts:
result2 = nquad(integrand, ranges=ranges, full_output=True,
opts=dict(epsabs=1e-1, epsrel=0, limit=3))
Both outputs are identical:
>>> print(result1)
(4.252394424844468, 1.525272379143154e-12, {'neval': 9261})
>>> print(result2)
(4.252394424844468, 1.525272379143154e-12, {'neval': 9261})
A full example is included here: https://gist.github.com/adrn/b9aa92c236df011dbcdc131aa94ed9f9
Is this not the right approach, or is scipy.integrate ignoring my inputted opts?
From the scipy.integrate.nquad it is stated that opts can only be passed to quad as can be seen here:
https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.nquad.html
Example of application:
import numpy as np
from scipy.integrate import quad
def integrand(a, sigma=250):
x = 2 * np.sin(a) * np.cos(a)
return x
# No specification of `opts` - use the default epsrel and epsabs:
result1 = quad(integrand,0, 2*np.pi)
# Set some `quad` opts:
result2 = quad(integrand,0, 4*np.pi,epsabs=1e-6, epsrel=1e-6, limit=40)
returns:
result1: (-1.3690011097614755e-16, 4.4205541621600365e-14)
result2: (-1.7062635631484713e-15, 9.096805257467047e-14)
The reason nquad doesn't complain about the presence of options is because nquad includes quad, dbquad and tplquad.

TypeError("can't convert expression to float")

The code which I wrote might look foolish, because it is integration of a derivative function. since it is the basic foundation to the other code which I'm writing on acoustical analysis. this analysis contains integration of different derivative functions which are in multiplication. for this purpose I'm using SciPy for integration and sympy for differentiation. but it is giving an error showing TypeError("can't convert expression to float"). below is the code which I wrote. hoping a solution for this.
import sympy
from sympy import *
from scipy.integrate import quad
var('r')
def diff(r):
r=symbols('x')
Z = 64.25 * r ** 5 - 175.71 *r ** 4 + 170.6 *r ** 3 - 71.103 *r ** 2 + 3 * r
E=sympy.diff(Z,r)
print(E)
return E
R=quad(diff,0,1)[0]
print(R)
I have to say that I'm a bit confused by your statement "integration of a derivative function" since the fundamental theorem of calculus would suggest that this is just a waste of CPU cycles. I'll presume that you know what you're doing though and that you just want to be able to compute some definite integrals numerically...
The SymPy expression that you want to integrate is this:
In [33]: from sympy import *
In [34]: r = symbols("x") # Why are you calling this x?
In [35]: Z = 64.25 * r ** 5 - 175.71 * r ** 4 + 170.6 * r ** 3 - 71.103 * r ** 2 +
...: 3 * r
In [36]: E = diff(Z, r)
In [37]: E
Out[37]:
4 3 2
321.25⋅x - 702.84⋅x + 511.8⋅x - 142.206⋅x + 3
There are a two basic ways to do this with SymPy:
In [38]: integrate(E, (r, 0, 1)) # symbolic integration
Out[38]: -8.96299999999999
In [39]: Integral(E, (r, 0, 1)).evalf() # numeric integration
Out[39]: -8.96300000000002
Note that had you used exact rational numbers you would see a more accurate result in either case:
In [40]: nsimplify(E)
Out[40]:
4 3 2
1285⋅x 17571⋅x 2559⋅x 71103⋅x
─────── - ──────── + ─────── - ─────── + 3
4 25 5 500
In [41]: integrate(nsimplify(E), (r, 0, 1))
Out[41]:
-8963
──────
1000
In [42]: Integral(nsimplify(E), (r, 0, 1)).evalf()
Out[42]: -8.96300000000000
While the approaches above are very accurate and work nicely for this particular integral which is easy to compute both symbolically and numerically they are both slower than using something like scipy's quad function which works with machine precision floating point and efficient numpy arrays for the calculation. To use scipy's quad function you need to lambdify your expression into an ordinary Python function:
In [44]: from scipy.integrate import quad
In [45]: f = lambdify(r, E, "numpy")
In [46]: f(0)
Out[46]: 3.0
In [47]: f(1)
Out[47]: -8.99600000000001
In [48]: quad(f, 0, 1)[0]
Out[48]: -8.963000000000001
What lambdify does is just to generate an efficient Python function for you. You can see the code that it uses like this:
In [51]: import inspect
In [52]: print(inspect.getsource(f))
def _lambdifygenerated(x):
return 321.25*x**4 - 702.84*x**3 + 511.8*x**2 - 142.206*x + 3
The quad routine will pass in numpy arrays for x and so this can be very efficient. If you have high-order polynomials then sympy's horner function can be used to optimise the expression:
In [53]: horner(E)
Out[53]: x⋅(x⋅(x⋅(321.25⋅x - 702.84) + 511.8) - 142.206) + 3.0
In [54]: f2 = lambdify(r, horner(E), "numpy")
In [56]: print(inspect.getsource(f2))
def _lambdifygenerated(x):
return x*(x*(x*(321.25*x - 702.84) + 511.8) - 142.206) + 3.0
https://docs.sympy.org/latest/tutorial/calculus.html#integrals
https://docs.sympy.org/latest/modules/utilities/lambdify.html#sympy.utilities.lambdify.lambdify
https://docs.sympy.org/latest/modules/polys/reference.html#sympy.polys.polyfuncs.horner

How I read mouse data In a non blocking way

I'm implementing a fail safe handover procedure in ROS and I'm using python scripts to do so.
I'm using the optical sensor from a mouse to keep under control the acceleration of the object so I can detect when is falling. Everything seems to works fine but now I want to give give a limit to the monitoring procedure (let's say 1000 times) before declaring the handover succeded. The problem is that the function read that I use for the mouse get stucked, if no movement are detected the next iteration is not performed. How can I read from the device without encountering this issue?
Here is the code I'm using to read from the mouse:
def getMouseEvent():
buf = file.read(3)
x, y = struct.unpack( "bb", buf[1:] ) # <--- X and Y deltas.
return [x , y]
Here the loop I want to implement
release_grasp()
rospy.loginfo( "Force detected -- Release mode active")
# If the object is falling regrasp it.
detected= False
trials = 0
while (not(detected) and trials < 1000):
trials = trials + 1
rospy.loginfo ("Acc monitored for the" + str(trials) + "th time"
if fall_test():
cilindrical_grasp()
rospy.loginfo("Fall detected -- Object regrasped")
detected = True
rate.sleep()
The output I get blocks to a given iteration until the mouse does not detect some kind of movement.
UPDATE: Here is the full code
#!/usr/bin/env python2
import rospy
import numpy
import struct
from reflex_sf_msgs.msg import SFPose
from matteo.msg import force
from matteo.msg import acc
# Defining force treshold in each direction ( to be completed and tuned )
rospy.init_node('DetectionFail')
xt = 0.5
yt = xt
zt = 0.3
# For the future try to handle the initialization.
fx = None
fy = None
fz = None
ax = None
ay = None
rate = rospy.Rate(100) # <--- Rate Hz
#-----------------------------MOUSE-----------------------------------#
# Open the mouse device. To be sure if it is "mouse2" type in the terminal: cat /proc/bus/input/devices, look for the device whose name is "Logitech optical USB mouse" and get the name of the handler. If you need root permissions type: sudo chmod 777 /dev/input/(handler)
file = open ("/dev/input/mouse3" , "rb")
#Defining the function to read mouse deltas.
def getMouseEvent():
buf = file.read(3);
x,y = struct.unpack( "bb", buf[1:] ); # <--- X and Y deltas.
return [x , y]
#Defining the function to estimate the acceleraton.
def acc_comp():
vx_old = 0
vy_old = 0
vx_new = getMouseEvent()[0]
vy_new = getMouseEvent()[1]
x_acc = (vx_old - vx_new)*100
y_acc = (vy_old - vy_new)*100
vx_old = vx_new
vy_old = vy_new
return [x_acc , y_acc]
#---------------------------------------------------------------------#
#Defining function fall test
def fall_test():
if ( acc_comp()[1] >= 3000 or acc_comp()[1] <= -3000 ):
return True
else:
return False
#---------------------------------------------------------------------#
# Initialize hand publisher.
hand_pub = rospy.Publisher('/reflex_sf/command', SFPose, queue_size=1)
rospy.sleep(0.5)
#---------------------------------------------------------------------#
# Defining sferical grasp.
def cilindrical_grasp():
hand_pub.publish ( 2.5 , 2.5 , 2.5, 0)
#---------------------------------------------------------------------#
# Define release position.
def release_grasp():
hand_pub.publish ( 2, 2 , 2 , 0)
#---------------------------------------------------------------------#
# Define test for the force measure
def force_treshold ( fx, fy , fz):
if ( fx > xt and fy > yt or fz > zt):
return True
else:
return False
#---------------------------------------------------------------------#
# Callback function to save the datas obtained by the force sensor
def callback_force(msg):
global fx
global fy
global fz
fx = msg.fx
fy = msg.fy
fz = msg.fz
# Main loop.
def main():
#Apply the sferical grasp.
rospy.loginfo("Applying grasp")
cilindrical_grasp()
while not(rospy.is_shutdown()):
rospy.Subscriber("/Forces", force, callback_force )
if force_treshold ( fx , fy , fz ):
release_grasp()
rospy.loginfo( "Force detected -- Release mode active")
# If the object is falling regrasp it.
detected= False
trials = 0
while (not(detected) and trials < 1000):
trials = trials +1
if fall_test():
cilindrical_grasp()
rospy.loginfo("Fall detected -- Object regrasped")
detected = True
rate.sleep()
if rospy.is_shutdown() :
break
Yesterday I came out with this code:
#!/usr/bin/env python
import struct
import rospy
from matteo.msg import acc
import struct
import os
import time
i = 0
# Mouse read with a non blocking structure, the problem is that does not provide the same output as
# mouse_clean.py, probably there is a problem with the unpacking or the reading.
while i < 1000:
i += 1
try:
file = os.open("/dev/input/mouse0", os.O_RDONLY | os.O_NONBLOCK)
time.sleep(0.1)
buf = os.read(file , 3)
x,y = struct.unpack( "bb", buf[1:] ) # <--- X and Y deltas.
print ( "X:" +str ( x ) + "---" +"Y:" +str ( y ) )
except OSError as err:
if err.errno == 11:
print ( "No motion detected")
continue
os.close(file)
It works fine, if there is no motion the message is printed out but, in case of motion the output I get is quite different from the "vanilla" mode.

Undefined operator '>' for input arguments of type 'msspoly' (optimization software)

I know there are many similar questions like the title ask here.
However, I still believe no of these discussions can solve my problem.
I am testing the following software "SPOTless" developed by MIT:
https://github.com/spot-toolbox/spotless
This is a software which transform the polynomial optimization problem to LP or SOCP. And then call the other software "mosek" to solve it.
This example is from the tutorial in:
https://github.com/spot-toolbox/spotless/tree/master/doc (please see the last example)
n = 2 ;
d = 4 ;
x = msspoly('x',n ) ;
basis = monomials(x , 0 : d ) ;
p = randn(length(basis))'*basis ;
g = 1 - x'*x ;
prog = spotsosprog ;
prog = prog.withIndeterminate(x) ;
[prog,r] = prog.newFree(1) ;
[prog,f] = prog.newFreePoly(x,monomials(x,0:d-2)) ;
prog = prog.withSOS(r-p-f*g) ;
sol = prog.minimize(r) ;
However, when run it, Matlab shows the following error:
The line 401 and the related part is the following:
function [pr,poly,coeff] = newFreePoly(pr,basis,n)
if nargin < 3, n = 1; end
if ~isempty(basis) && n > 0 % line 401
if ~pr.isPolyInIndet(basis)
error('Basis must be polynomial in the indeterminates.');
end
[pr,coeff] = pr.newFree(length(basis)*n);
poly = reshape(coeff,n,length(basis))*basis;
else
poly = [];
end
end
$n$ is an integer, so $n > 0$ is valid obviously.
I ask the related professor (not the author of this software); he told me he has not seen this problem before. The problem comes from one .m file in the software.
I am not sure if someone can help me test this software and this example and let me know the result or how to solve this error.
Note: if you really test this software (easy to install), please also install "mosek", which is a famous optimization software.
Note: if you do not want to install "mosek", please cross out the last two lines in the code.

Extract numbers from specific image

I am involved in a project that I think you can help me. I have multiple images that you can see here Images to recognize. The goal here is to extract the numbers between the dashed lines. What is the best approach to do that? The idea that I have from the beginning is to find the coordinates of the dash lines and do the crop function, then is just run OCR software. But is not easy to find those coordinates, can you help me? Or if you have a better approach tell me.
Best regards,
Pedro Pimenta
You may start by looking at more obvious (bigger) objects in your images. The dashed lines are way too small in some images. Searching for the "euros milhoes" logo and the barcode will be easier and it will help you have an idea of the scale and rotation involved.
To find these objects without using match template you can binarize your image (watch out for the background texture) and use the Hu moments on the contours/blobs.
Don't expect a good OCR accuracy on images where the numbers are smaller than 8-10 pixels.
You can use python-tesseract https://code.google.com/p/python-tesseract/ ,it works with your image.What you need to do is to split the result string.I use your https://www.dropbox.com/sh/kcybs1i04w3ao97/u33YGH_Kv6#f:euro9.jpg to test.And source code is below.UPDATE
# -*- coding: utf-8 -*-
from PIL import Image
from PIL import ImageEnhance
import tesseract
im = Image.open('test.jpg')
enhancer = ImageEnhance.Contrast(im)
im = enhancer.enhance(4)
im = im.convert('1')
w, h = im.size
im = im.resize((w * (416 / h), 416))
pix = im.load()
LINE_CR = 0.01
WHITE_HEIGHT_CR = int(h * (20 / 416.0))
status = 0
white_line = []
for i in xrange(h):
line = []
for j in xrange(w):
line.append(pix[(j, i)])
p = line.count(0) / float(w)
if not p > LINE_CR:
white_line.append(i)
wp = None
for i in range(10, len(white_line) - WHITE_HEIGHT_CR):
k = white_line[i]
if white_line[i + WHITE_HEIGHT_CR] == k + WHITE_HEIGHT_CR:
wp = k
break
result = []
flag = 0
while 1:
if wp < 0:
result.append(wp)
break
line = []
for i in xrange(w):
line.append(pix[(i, wp)])
p = line.count(0) / float(w)
if flag == 0 and p > LINE_CR:
l = []
for xx in xrange(20):
l.append(pix[(xx, wp)])
if l.count(0) > 5:
break
l = []
for xx in xrange(416-1, 416-100-1, -1):
l.append(pix[(xx, wp)])
if l.count(0) > 17:
break
result.append(wp)
wp -= 1
flag = 1
continue
if flag == 1 and p < LINE_CR:
result.append(wp)
wp -= 1
flag = 0
continue
wp -= 1
result.reverse()
for i in range(1, len(result)):
if result[i] - result[i - 1] < 15:
result[i - 1] = -1
result = filter(lambda x: x >= 0, result)
im = im.crop((0, result[0], w, result[-1]))
im.save('test_converted.jpg')
api = tesseract.TessBaseAPI()
api.Init(".","eng",tesseract.OEM_DEFAULT)
api.SetVariable("tessedit_char_whitelist", "0123456789abcdefghijklmnopqrstuvwxyz")
api.SetPageSegMode(tesseract.PSM_AUTO)
mImgFile = "test_converted.jpg"
mBuffer=open(mImgFile,"rb").read()
result = tesseract.ProcessPagesBuffer(mBuffer,len(mBuffer),api)
print "result(ProcessPagesBuffer)=",result
Depends python 2.7 python-tesseract-win32 python-opencv numpy PIL,and be sure to follow python-tesseract's remember to .