Commit 83adf28a authored by Vladislav Perepelkin's avatar Vladislav Perepelkin
Browse files

added rules.txt and fill()

parent 02344b7f
all: hpprp run density/video.avi
all: run avi
hpprp: hpprp.c config.c
g++ -O3 hpprp.c -o hpprp
hpprp: hpprp.c config.c collide.c
g++ -O3 hpprp.c -o hpprp -lrt
run: hpprp
collide.c: rules.txt scripts/rules_gen.py
python scripts/rules_gen.py rules.txt collide.c
run: hpprp FORCE
./hpprp
avi: density/video.avi
density/video.avi: run
./image_gen.sh density
scripts/image_gen.sh density
clean:
rm -f density/*.txt density/*.png density/video.avi hpprp
rm -f density/*.txt density/*.png density/video.avi hpprp collide.c
FORCE:
// USER CONFIGURATION FILE
// TODO: rules table
// Main properties
#define WIDTH 400
#define HEIGHT 300
......@@ -10,47 +12,23 @@
// Field initialization
void init()
{
int i, j;
for (i=0; i<HEIGHT; i++) {
for (j=0; j<WIDTH; j++) {
double r=drand48();
if (r>=0 && r<1.0/3) {
FIELD(i, j)=5;
} else if (r>=1.0/3 && r<2.0/3) {
FIELD(i, j)=10;
} else {
FIELD(i, j)=16;
}
}
}
}
// Collision rules
char collide(char cell)
{
double r=drand48();
switch(cell) {
case 5:
case 10:
case 16:
if (r>=0 && r<1.0/3) { return 5; }
else if (r>=1.0/3 && r<2.0/3) { return 10; }
else { return 16; }
default:
return cell;
}
fill(0, 0, HEIGHT, WIDTH, // area
0.5, 0.5, 0.5, 0.5, // move
0.5, 0.0, 0.0, 0.0); // rest
}
// Sources rules
void sources(int iter)
{
if (iter==0) {
int i, j;
for (i=0; i<HEIGHT; i++) {
for (j=WIDTH*4/10; j<WIDTH*6/10; j++) {
FIELD(i, j)=15;
}
}
fill(0, WIDTH*4/10, HEIGHT, WIDTH*6/10, // area
1.0, 1.0, 1.0, 1.0, // move
1.0, 0.0, 0.0, 0.0); // rest
}
if (iter==ITERS/3) {
fill(0, WIDTH*2/10, HEIGHT, WIDTH*3/10, // area
1.0, 1.0, 1.0, 1.0, // move
1.0, 0.0, 0.0, 0.0); // rest
}
}
......@@ -6,7 +6,33 @@
#define NEW_FIELD(i, j) new_field[(i)*(WIDTH) + j]
char *field, *new_field;
void fill(int i0, int j0, int i1, int j1,
double r, double d, double l, double u,
double r1, double r2, double r3, double r4);
#include "config.c"
#include "collide.c"
void fill(int i0, int j0, int i1, int j1,
double r, double d, double l, double u,
double r1, double r2, double r3, double r4)
{
int i, j;
for (i=i0; i<i1; i++) {
for (j=j0; j<j1; j++) {
char cell=0;
if (drand48() < r) { cell += 1; }
if (drand48() < d) { cell += 2; }
if (drand48() < l) { cell += 4; }
if (drand48() < u) { cell += 8; }
if (drand48() < r1) { cell += 16; }
if (drand48() < r2) { cell += 32; }
if (drand48() < r3) { cell += 64; }
if (drand48() < r4) { cell += 128; }
FIELD(i, j)=cell;
}
}
}
inline int get_mass(char cell)
{
int mass=0;
......
5 10 16
5 0.6 0.2 0.2
10 0.2 0.6 0.2
16 0.2 0.2 0.6
#!/usr/bin/python
import sys
# ALGORITHM:
# obtain file name from sys.argv[1]
# check that file exists
# try read contents from file
# parse contents:
# skip empty lines and comments
# if non-empty line, read states from it
# check states are valid
# read next N lines
# check line syntax:
# has N+1 words
# fist word is in states[]
# other words are floats
# add rules to table
# check table
# give error if normalization fails
# give warning if semi-detailed balance fails
# generate collision function to argv[2]
def error(message):
print
print "ERROR", message
print
sys.exit()
def extract_words(line):
return filter(lambda x: x.strip(),
line.replace('\t', ' ').split(' '))
def validate_prob(word, line):
try:
num=float(word)
if num>=0 and num<1:
return
except ValueError:
pass
error("Not a probability (" + str(word) + ') in line: ' + line)
def validate_state(word, line):
try:
num=int(word)
if num>=0 and num<=255:
return
except ValueError:
pass
error("Not a state (" + str(word) + ') in line: ' + line)
rules={}
def init_rules():
global rules
for i in range(256):
rules[i]={i: 1.0}
def add_rule(s0, s1, p):
global rules
rules[s0][s1]=p
init_rules()
if len(sys.argv) != 3:
print
print "Usage:", sys.argv[0], "<rules_file.txt>", "<output_file.c>"
print
sys.exit()
try:
lines=filter(lambda x: x.strip(), open(sys.argv[1]).readlines())
except IOError:
error("ERROR: Failed to read from file " + sys.argv[1])
i=0
while i<len(lines):
line=lines[i].strip()
states=extract_words(line)
for word in states:
validate_state(word, line)
if i+len(states) >= len(lines):
error("Unexpected end of file, need more lines for states (" +\
', '.join(states) + '), given in line ' + line);
i+=1
for j in range(len(states)):
words=extract_words(lines[i+j])
if len(words) != len(states)+1:
error("Too few words in line " + lines[i+j])
validate_state(words[0], lines[i+j])
if words[0] != states[j]:
error("Invalid state (" + words[0] + "), need (" +\
states[j] + ") in line " + lines[i+j])
for k in range(len(words)-1):
validate_prob(words[k+1], lines[i+j])
add_rule(int(words[0]), int(states[k]), float(words[k+1]))
i+=len(states)
# check normalization
for s0 in range(256):
sum_prob=reduce(lambda x, y: x+y, [rules[s0][s1] for s1 in rules[s0]])
if sum_prob!=1:
error("Normalization fails for state (" + s0 + "), sum prob is "
+ str(sum_prob))
# generate code
try:
f=open(sys.argv[2], 'w')
f.write("char collide(char cell)\n")
f.write("{\n")
f.write("\tdouble r=drand48();\n")
f.write("\tswitch(cell) {\n")
for s0 in range(256):
if len(rules[s0])==1 and s0 in rules[s0]:
continue # trivial rule
f.write("\t\tcase " + str(s0) + ":\n")
cur_prob=0
for s1, prob in rules[s0].iteritems():
cur_prob+=prob
if prob<1.0:
f.write("\t\t\tif (r<" + str(cur_prob) + ") return " +\
str(s1) + ";\n")
f.write("\t\t\tbreak;\n")
f.write("\t\tdefault:\n")
f.write("\t\t\treturn cell;\n")
f.write("\t}\n")
f.write("}\n")
except IOError:
error("Failed to write output to file " + sys.argv[2])
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment