def calcCandidates(str):
TOKEN_CONFIG = [
("Mor", af.automata_Mor(str))]
for (TokenKind, automata) in TOKEN_CONFIG:
candidates.append(TokenKind)
return (allTrapped, candidates)
I do get a reply and is this:
(False, [])
But I'm expecting to have something inside [], for example ["mor"]
If you need the full code of that function:
def calcCandidates(str):
TOKEN_CONFIG = [
("Mor", af.automata_Mor(str)),
("Si", af.automata_Si(str)),
("Hacer", af.automata_Hacer(str)),
("OpenC", af.automata_OpenC(str)),
("CloseC", af.automata_CloseC(str)),
]
allTrapped = True
candidates = []
for (TokenKind, automata) in TOKEN_CONFIG:
res = automata
if res == RESULT_ACCEPTED:
allTrapped = False
candidates.append(TokenKind)
if res == RESULT_NOT_ACCEPTED:
allTrapped = False
return (allTrapped, candidates)
I want to use os module specifically to handle read/write binary files. I have an issue when reading values of data type that takes more than 1 byte such as int64, float32, ... etc. To illustrate my issue, let's see the following example I wrote. I generate random values of type np.float64 which is 8 byte each:
# Write
n = 10
dim = 2
fd = os.open('test.dat', os.O_CREAT | os.O_WRONLY)
data_w = np.random.uniform(low=0.5, high=13.3, size=(n,dim)).astype(np.float64)
print("Written Data are:\n%s\n" % data_w)
os.write(fd, data_w.tobytes())
os.close(fd)
print("------------------ \n")
# Read
start_read = 0 # 0 for now. Later I can read from any row!
total_num_to_read = n*dim
fd = os.open('test.dat', os.O_RDONLY)
os.lseek(fd, start_read, 0) # start_read from the beginning 0
raw_data = os.read(fd, total_num_to_read) # How many values to be read
data_r = np.fromiter(raw_data, dtype=np.float64).reshape(-1, dim)
print("Data Read are:\n%s\n" % data_r)
os.close(fd)
The reading is not correct. Look how it is returned:
Written Data are:
[[ 2.75763292 9.87883101]
[ 1.73752327 9.9633879 ]
[ 1.01616811 1.81174597]
[ 9.93904659 10.6757686 ]
[ 7.02452029 2.68652109]
[ 5.29766028 11.15384409]
[ 4.12499766 10.37214532]
[11.75811252 3.30378401]
[ 1.72738203 2.11228277]
[ 7.7321937 11.64298051]]
------------------
Data Read are:
[[250. 87.]
[227. 216.]
[161. 15.]
[ 6. 64.]
[162. 178.]
[ 59. 35.]
[246. 193.]
[ 35. 64.]
[218. 97.]
[ 81. 50.]]
I cannot retrieve it correctly! I thought np.fromiter(raw_data, dtype=np.float64).reshape(-1, dim) is supposed to take care of it but I don't know where the issue is. How can I read binary data in this case given that I know it is of particular data type (i.e., np.float64)?
You should use np.fromstring(raw_data) instead of fromiter(). Check documentation for the purpose of each function. In addition, when reading from file, read the correct number of bytes!!!: 8* total_num_to_read.
In [103]: # Write
...: n = 10
...: dim = 2
...: fd = os.open('test.dat', os.O_CREAT | os.O_WRONLY)
...: data_w = np.random.uniform(low=0.5, high=13.3, size=(n,dim)).astype(np.float64)
...: print("Written Data are:\n%s\n" % data_w)
...: os.write(fd, data_w.tobytes())
...: os.close(fd)
...: print("------------------ \n")
...:
...: # Read
...: start_read = 0 # 0 for now. Later I can read from any row!
...: total_num_to_read = n*dim
...: fd = os.open('test.dat', os.O_RDONLY)
...: os.lseek(fd, start_read, 0) # start_read from the beginning 0
...: raw_data = os.read(fd, 8*total_num_to_read) # How many values to be read
...: data_r = np.fromstring(raw_data, dtype=np.float64).reshape(-1, dim)
...: print("Data Read are:\n%s\n" % data_r)
...: os.close(fd)
...:
...:
Written Data are:
[[ 11.2465988 5.45304778]
[ 12.06466331 9.95717255]
[ 7.35402895 1.68972606]
[ 0.7259652 1.01265826]
[ 3.11340311 2.44725153]
[ 2.82109715 5.02768335]
[ 12.69054614 9.26028537]
[ 5.13785639 2.0780649 ]
[ 4.6796513 4.24710598]
[ 2.34859141 8.87224674]]
------------------
Data Read are:
[[ 11.2465988 5.45304778]
[ 12.06466331 9.95717255]
[ 7.35402895 1.68972606]
[ 0.7259652 1.01265826]
[ 3.11340311 2.44725153]
[ 2.82109715 5.02768335]
[ 12.69054614 9.26028537]
[ 5.13785639 2.0780649 ]
[ 4.6796513 4.24710598]
[ 2.34859141 8.87224674]]
I am running the following JModelica script:
#!/usr/local/jmodelica/bin/jm_python.sh
import pyjmi
op = pyjmi.transfer_optimization_problem("BatchReactor", "model.mop")
opt_opts = op.optimize_options()
opt_opts['n_e'] = 40 # Number of elements
opt_opts['IPOPT_options']['tol'] = 1e-10
opt_opts['IPOPT_options']['print_level'] = 8
opt_opts['IPOPT_options']['output_file'] = '/z/out'
res = op.optimize(options=opt_opts)
I had hoped that the results (e.g. time, x1, x2, &c.) would be printed to the file /z/out. But the file only contains IPOPT verbose debugging/status info.
Is there a way to print the information that would be stored in res directly to a file? Either by somehow writing res itself or, preferably, having IPOPT/JModelica write the results without having to go through Python?
There is a way to print the information directly to a file. The following accomplishes this. Note that result_file_name is the key to making this happen.
#!/usr/local/jmodelica/bin/jm_python.sh
import pyjmi
op = pyjmi.transfer_optimization_problem("BatchReactor", "model.mop")
opt_opts = op.optimize_options()
opt_opts['n_e'] = 40 # Number of elements
opt_opts['result_file_name'] = '/z/out'
opt_opts['IPOPT_options']['tol'] = 1e-10
opt_opts['IPOPT_options']['print_level'] = 0
res = op.optimize(options=opt_opts)
Unfortunately, the contents of the file are somewhat mysterious.
You may find that using result_file_name per another answer here results in an output file which is difficult to understand.
The following produces a nicer format:
import StringIO
import numpy as np
def PrintResToFile(filename,result):
def StripMX(x):
return str(x).replace('MX(','').replace(')','')
varstr = '#Variable Name={name: <10}, Unit={unit: <7}, Val={val: <10}, Col={col:< 5}, Comment="{comment}"\n'
with open(filename,'w') as fout:
#Print all variables at the top of the file, along with relevant information
#about them.
for var in result.model.getAllVariables():
if not result.is_variable(var.getName()):
val = result.initial(var.getName())
col = -1
else:
val = "Varies"
col = result.get_column(var.getName())
unit = StripMX(var.getUnit())
if not unit:
unit = "X"
fout.write(varstr.format(
name = var.getName(),
unit = unit,
val = val,
col = col,
comment = StripMX(var.getAttribute('comment'))
))
#Ensure that time variable is printed
fout.write(varstr.format(
name = 'time',
unit = 's',
val = 'Varies',
col = 0,
comment = 'None'
))
#The data matrix contains only time-varying variables. So fetch all of
#these, couple them in tuples with their column number, sort by column
#number, and then extract the name of the variable again. This results in a
#list of variable names which are guaranteed to be in the same order as the
#data matrix.
vkeys_in_order = map(lambda x: x[1], sorted([(result.get_column(x),x) for x in result.keys() if result.is_variable(x)]))
for vk in vkeys_in_order:
fout.write("{0:>13},".format(vk))
fout.write("\n")
sio = StringIO.StringIO()
np.savetxt(sio, result.data_matrix, delimiter=',', fmt='%13.5f')
fout.write(sio.getvalue())
which looks like this:
#Variable Name=S0 , Unit=kg , Val=2.0 , Col=-1 , Comment="Solid Mass"
#Variable Name=F0 , Unit=kg , Val=0.0 , Col=-1 , Comment="Fluid Mass"
#Variable Name=a , Unit=Hz , Val=0.2 , Col=-1 , Comment="None"
#Variable Name=b , Unit=kg/s , Val=1.0 , Col=-1 , Comment="None"
#Variable Name=f , Unit=kg/s , Val=0.05 , Col=-1 , Comment="None"
#Variable Name=h , Unit=1/g , Val=0.05 , Col=-1 , Comment="None"
#Variable Name=der(F) , Unit=X , Val=Varies , Col= 1 , Comment="None"
#Variable Name=F , Unit=kg , Val=Varies , Col= 3 , Comment="None"
#Variable Name=der(S) , Unit=X , Val=Varies , Col= 2 , Comment="None"
#Variable Name=S , Unit=kg , Val=Varies , Col= 4 , Comment="None"
#Variable Name=u , Unit=X , Val=Varies , Col= 5 , Comment="None"
#Variable Name=startTime , Unit=X , Val=0.0 , Col=-1 , Comment="None"
#Variable Name=finalTime , Unit=X , Val=100.0 , Col=-1 , Comment="None"
#Variable Name=time , Unit=s , Val=Varies , Col= 0 , Comment="None"
time, der(F), der(S), F, S, u,
0.00000, 0.97097, -0.97097, 0.00000, 2.00000, 0.97097
0.38763, 1.07704, -1.05814, 0.38519, 1.61698, 1.00000
1.61237, 0.88350, -0.80485, 1.70714, 0.35885, 0.65862
2.50000, 0.00000, 0.09688, 2.14545, 0.00000, 0.00000
2.88763, 0.09842, -0.00000, 2.18330, 0.00000, 0.06851
4.11237, 0.10342, 0.00000, 2.30688, 0.00000, 0.07077
5.00000, 0.10716, 0.00000, 2.40033, 0.00000, 0.07240
5.38763, 0.10882, -0.00000, 2.44219, 0.00000, 0.07311
6.61237, 0.11421, 0.00000, 2.57875, 0.00000, 0.07535
I have this code:
split_at = q[:,3].searchsorted([1,random.randrange(LB,UB-I)])
D = numpy.split(q, split_at)
T=D[1]
TF=D[2]
T2=copy(TF)
T2[:,3]=T2[:,3]+I
u=random.sample(T[:],1)
v=random.sample(T2[:],1)
u=array(u)
v=array(v)
d=v[0,0]-u[0,0]+T[-1,3]
I want that ifd<=1000 :
x=numpy.where(v==T2)[0][0]
y=numpy.where(u==T)[0][0]
l=np.copy(T[y])
T[y],T2[x]=T2[x],T[y]
T2[x],l=l,T2[x]
E=np.copy(T)
E2=np.copy(T2)
E[:,3]=np.cumsum(E[:,0])
E2[:,3]=np.cumsum(E2[:,0])+I
f2=sum(E[:,1]*E[:,3])+sum(E2[:,1]*E2[:,3])
And than that if d>1000 I want ot recalculate the first part of code and verify if d<=1000 and this over and over again until the condition is met.
What about starting with:
d = 1000000
while d > 1000:
split_at = q[:,3].searchsorted([1,random.randrange(LB,UB-I)])
D = numpy.split(q, split_at)
T=D[1]
TF=D[2]
T2=copy(TF)
T2[:,3]=T2[:,3]+I
u=random.sample(T[:],1)
v=random.sample(T2[:],1)
u=array(u)
v=array(v)
d=v[0,0]-u[0,0]+T[-1,3]
x=numpy.where(v==T2)[0][0]
y=numpy.where(u==T)[0][0]
l=np.copy(T[y])
T[y],T2[x]=T2[x],T[y]
T2[x],l=l,T2[x]
E=np.copy(T)
E2=np.copy(T2)
E[:,3]=np.cumsum(E[:,0])
E2[:,3]=np.cumsum(E2[:,0])+I
f2=sum(E[:,1]*E[:,3])+sum(E2[:,1]*E2[:,3])
Why not arranging the code into functions like:
def func1(): # add your arguments to param list
split_at = q[:,3].searchsorted([1,random.randrange(LB,UB-I)])
# some code
d=v[0,0]-u[0,0]+T[-1,3]
return d,T,T2
def func2(T,T2):
x=numpy.where(v==T2)[0][0]
# more code
and just do something like:
d = 10000
while d > 1000:
d,T,T2 = func1()
else:
func2(T,T2)