I am trying to solve an ILP that optimises a problem on graphs using Gurobi. Unfortunately, I get the following error when creating the problem:
gurobipy.GurobiError: Element 302194 of a double array is Nan or Inf.
The error is thrown when setting the objective.
m.setObjective(quicksum([G.G.nodes[node]['prize'] * node_var for
node, node_var in nodes.items()])
- quicksum([mod_var * mod[1][1] for mod, mod_var in modules.items()]),
GRB.MAXIMIZE)
All my variables are initialised and have a finite value. I don't understand which double array is being referenced. I have not found a solution online.
Can anyone help me?
It's difficult to debug inside a Python generator expression. Try debugging by rewriting as loops, like the following:
obj = 0
for node, node_var in nodes.items():
# print(f"node={node}, prize={G.G.nodes[node]['prize']}, node_var={node_var}")
obj += G.G.nodes[node]['prize'] * node_var
for mod, mod_var in modules.items():
# print(f"mod_var={mod_var}, mod={mod[1][1]}")
obj -= mod_var * mod[1][1]
m.setObjective(obj, GRB.MAXIMIZE)
Since I can't test this code, it's possible there may be errors, but this should give you some ideas how to debug your issue.
First off let me just say I know what I'm doing is not ideal, but I'm trying to write the member? function from The Little Schemer using Hy.
(setv else True)
(defn null? [lst]
" If list is empty return True else False "
(if lst
False
True))
(defn member? [a lat]
" Checks if value is a member of a list "
(cond
[(null? lat) False]
[else (or (= (first lat) a)
(member? a (rest lat)))]))
(print (member? 1 '(2 3 4 1)))
This works exactly how I expect. The problem is, if the list is greater than 4 elements long I get the error
RecursionError: maximum recursion depth exceeded while calling a Python object
I know Python isn't meant to do recursion and in the Python docs it even says that there is a default recursion limit to keep the C stack from overflowing. On my machine getrecursionlimit() yields the value of 1000, and I was able to successfully set it to over 20,000 before getting a segfault. Even with it set to 20,000 I am still getting the error on a list of 5 elements. What I don't understand is... How am I hitting over 20,000 levels of recursion on a 5 element list?
And for those curious I'm using Python 3.6.5, MacOS Mojave version 10.14.6 on a 15" Macbook pro, Hylang version 0.18.0, and the output of my program using hy2py is
from hy.core.language import first, rest
from hy import HyExpression, HyInteger
hyx_else = True
def is_null(lst):
""" If list is empty return True else False """
return False if lst else True
def is_member(a, lat):
""" Checks if value is a member of a list """
return False if is_null(lat) else first(lat) == a or is_member(a, rest(lat)
) if hyx_else else None
print(is_member(1, HyExpression([] + [HyInteger(2)] + [HyInteger(3)] + [
HyInteger(4)] + [HyInteger(5)] + [HyInteger(1)])))
I can't reproduce this on Hy master. It's probably a bug that was fixed since 0.18.0.
I have a binary file that was created using a Python code. This code mainly scripts a bunch of tasks to pre-process a set of data files. I would now like to read this binary file in Fortran. The content of the binary file is coordinates of points in a simple format e.g.: number of points, x0, y0, z0, x1, y1, z1, ....
These binary files were created using the 'tofile' function in numpy. I have the following code in Fortran so far:
integer:: intValue
double precision:: dblValue
integer:: counter
integer:: check
open(unit=10, file='file.bin', form='unformatted', status='old', access='stream')
counter = 1
do
if ( counter == 1 ) then
read(unit=10, iostat=check) intValue
if ( check < 0 ) then
print*,"End Of File"
stop
else if ( check > 0 ) then
print*, "Error Detected"
stop
else if ( check == 0 ) then
counter = counter + 1
print*, intValue
end if
else if ( counter > 1 ) then
read(unit=10, iostat=check) dblValue
if ( check < 0 ) then
print*,"End Of File"
stop
else if ( check > 0 ) then
print*, "Error Detected"
stop
else if ( check == 0 ) then
counter = counter + 1
print*,dblValue
end if
end if
end do
close(unit=10)
This unfortunately does not work, and I get garbage numbers (e.g 6.4731191026611484E+212, 2.2844499004808491E-279 etc.). Could someone give some pointers on how to do this correctly?
Also what would be a good way of writing and reading binary files interchangeably between Python and Fortran - as it seems like that is going to be one of the requirements of my application.
Thanks
Here's a trivial example of how to take data generated with numpy to Fortran the binary way.
I calculated 360 values of sin on [0,2π),
#!/usr/bin/env python3
import numpy as np
with open('sin.dat', 'wb') as outfile:
np.sin(np.arange(0., 2*np.pi, np.pi/180.,
dtype=np.float32)).tofile(outfile)
exported that with tofile to binary file 'sin.dat', which has a size of 1440 bytes (360 * sizeof(float32)), read that file with this Fortran95 (gfortran -O3 -Wall -pedantic) program which outputs 1. - (val**2 + cos(x)**2) for x in [0,2π),
program numpy_import
integer, parameter :: REAL_KIND = 4
integer, parameter :: UNIT = 10
integer, parameter :: SAMPLE_LENGTH = 360
real(REAL_KIND), parameter :: PI = acos(-1.)
real(REAL_KIND), parameter :: DPHI = PI/180.
real(REAL_KIND), dimension(0:SAMPLE_LENGTH-1) :: arr
real(REAL_KIND) :: r
integer :: i
open(UNIT, file="sin.dat", form='unformatted',&
access='direct', recl=4)
do i = 0,ubound(arr, 1)
read(UNIT, rec=i+1, err=100) arr(i)
end do
do i = 0,ubound(arr, 1)
r = 1. - (arr(i)**2. + cos(real(i*DPHI, REAL_KIND))**2)
write(*, '(F6.4, " ")', advance='no')&
real(int(r*1E6+1)/1E6, REAL_KIND)
end do
100 close(UNIT)
write(*,*)
end program numpy_import
thus if val == sin(x), the numeric result must in good approximation vanish for float32 types.
And indeed:
output:
360 x 0.0000
So thanks to this great community, from all the advise I got, and a little bit of tinkering around, I think I figured out a stable solution to this problem, and I wanted to share with you all this answer. I will provide a minimal example here, where I want to write a variable size array from Python into a binary file, and read it using Fortran. I am assuming that the number of rows numRows and number of columns numCols are also written along with the full array datatArray. The following Python script writeBin.py writes the file:
import numpy as np
# Read in the numRows and numCols value
# Read in the array values
numRowArr = np.array([numRows], dtype=np.float32)
numColArr = np.array([numCols], dtype=np.float32)
fileObj = open('pybin.bin', 'wb')
numRowArr.tofile(fileObj)
numColArr.tofile(fileObj)
for i in range(numRows):
lineArr = dataArray[i,:]
lineArr.tofile(fileObj)
fileObj.close()
Following this, the fortran code to read the array from the file can be programmed as follows:
program readBin
use iso_fortran_env
implicit none
integer:: nR, nC, i
real(kind=real32):: numRowVal, numColVal
real(kind=real32), dimension(:), allocatable:: rowData
real(kind=real32), dimension(:,:), allocatable:: fullData
open(unit=10,file='pybin.bin',form='unformatted',status='old',access='stream')
read(unit=10) numRowVal
nR = int(numRowVal)
read(unit=10) numColVal
nC = int(numColVal)
allocate(rowData(nC))
allocate(fullData(nR,nC))
do i = 1, nR
read(unit=10) rowData
fullData(i,:) = rowData(:)
end do
close(unit=10)
end program readBin
The main point that I gathered from the discussion on this thread is to match the read and the write as much as possible, with precise specifications of the data types to be read, the way they are written etc. As you may note, this is a made up example, so there may be some things here and there that are not perfect. However, I have used this now to program a finite element program, and the mesh data was where I used this binary read/write - and it worked very well.
P.S: In case you find some typo, please let me know, and I will edit it out rightaway.
Thanks a lot.
I am going through a Python/Pygame tutorial. I came across this <- operator. What does it mean?
Here's the line of code:
if bullet[1]<-64 or bullet[1]>640 or bullet[2]<-64 or bullet[2]>480:
arrows.pop(index)
Python doesn't have a <- operator. Perhaps you have it backwards and meant ->?
The only time you see that is in function annotations:
def func(a:int, b:str) -> str:
It lets the user know what the function should return.
Or, you could have seen something like this:
x<-1
which is basically testing if x is less than -1.
Edit:
Now that you have included the code, I can say for certain that it is the second answer. This part:
if bullet[1]<-64
is basically testing if bullet[1] is less than -64.
You are misreading the operator; it's < (lower than) -64 (negative sixtyfour).
The line you show is a perfect example why the Python Style Guide requires spaces around operators; the following is much clearer:
if bullet[1] < -64 or bullet[1] > 640 or bullet[2] < -64 or bullet[2] > 480:
Or, using chaining:
if not (-64 > bullet[1] > 640) or not (-64 > bullet[2] > 480):
I am reading a file containing single precision data with 512**3 data points. Based on a threshold, I assign each point a flag of 1 or 0. I wrote two programs doing the same thing, one in fortran, the other in python. But the one in fortran takes like 0.1 sec while the one in python takes minutes. Is it normal? Or can you please point out the problem with my python program:
fortran.f
program vorticity_tracking
implicit none
integer, parameter :: length = 512**3
integer, parameter :: threshold = 1320.0
character(255) :: filen
real, dimension(length) :: stored_data
integer, dimension(length) :: flag
integer index
filen = "vor.dat"
print *, "Reading the file ", trim(filen)
open(10, file=trim(filen),form="unformatted",
& access="direct", recl = length*4)
read (10, rec=1) stored_data
close(10)
do index = 1, length
if (stored_data(index).ge.threshold) then
flag(index) = 1
else
flag(index) = 0
end if
end do
stop
end program
Python file:
#!/usr/bin/env python
import struct
import numpy as np
f_type = 'float32'
length = 512**3
threshold = 1320.0
file = 'vor_00000_455.float'
f = open(file,'rb')
data = np.fromfile(f, dtype=f_type, count=-1)
f.close()
flag = []
for index in range(length):
if (data[index] >= threshold):
flag.append(1)
else:
flag.append(0)
********* Edit ******
Thanks for your comments. I am not sure then how to do this in fortran. I tried the following but this is still as slow.
flag = np.ndarray(length, dtype=np.bool)
for index in range(length):
if (data[index] >= threshold):
flag[index] = 1
else:
flag[index] = 0
Can anyone please show me?
Your two programs are totally different. Your Python code repeatedly changes the size of a structure. Your Fortran code does not. You're not comparing two languages, you're comparing two algorithms and one of them is obviously inferior.
In general Python is an interpreted language while Fortran is a compiled one. Therefore you have some overhead in Python. But it shouldn't take that long.
One thing that can be improved in the python version is to replace the for loop by an index operation.
#create flag filled with zeros with same shape as data
flag=numpy.zeros(data.shape)
#get bool array stating where data>=threshold
barray=data>=threshold
#everywhere where barray==True put a 1 in flag
flag[barray]=1
shorter version:
#create flag filled with zeros with same shape as data
flag=numpy.zeros(data.shape)
#combine the two operations without temporary barray
flag[data>=threshold]=1
Try this for python:
flag = data > threshhold
It will give you an array of flags as you want.