Last active
January 29, 2017 00:56
-
-
Save rikkimax/42c3dfa6500155c5e441cbb1437142ea to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct Experiments { | |
Experiment[] sets; | |
} | |
struct Experiment { | |
string fileName; | |
string endCondition; | |
Variation[] variations; | |
bool doesTurtlesMove; | |
} | |
struct Variation { | |
string name; | |
string probForFrom, probForTo; | |
string probFrom, probTo; | |
string resultFileName; | |
this(string name, string suffix) { | |
import std.string : split, startsWith; | |
this.name = name; | |
this.resultFileName = name ~ suffix; | |
if (name.startsWith("experiment_")) { | |
auto temp = name.split("_"); | |
auto temp2 = temp[1].split("-"); | |
probForFrom = temp2[0]; | |
probForTo = temp2[1]; | |
probFrom = temp[2]; | |
probTo = temp[3]; | |
} | |
} | |
} | |
void main() { | |
import std.json; | |
import std.file : readText, exists, rmdirRecurse, mkdirRecurse; | |
if ("data".exists) | |
rmdirRecurse("data"); | |
mkdirRecurse("data"); | |
if ("reports/graphs".exists) | |
rmdirRecurse("reports/graphs"); | |
mkdirRecurse("reports/graphs"); | |
JSONValue descriptorsJsonValue = readText("descriptors.json").parseJSON(); | |
Experiments experiments; | |
size_t offset; | |
foreach(k, v; descriptorsJsonValue.object) { | |
if (v.type == JSON_TYPE.OBJECT) { | |
experiments.sets.length++; | |
experiments.sets[offset].doesTurtlesMove = v.object["doesTurtlesMove"].type == JSON_TYPE.TRUE; | |
experiments.sets[offset].endCondition = v.object["endCondition"].str; | |
experiments.sets[offset].fileName = v.object["fileName"].str; | |
import std.algorithm : map; | |
import std.array : array; | |
experiments.sets[offset].variations = v.object["variations"].array.map!(a => Variation(a.str, experiments.sets[offset].fileName)).array; | |
offset++; | |
} | |
} | |
ResultContainer[] results; | |
processForResults(results, experiments); | |
generateGraphs(results, experiments); | |
} | |
struct ResultContainer { | |
uint run; | |
ResultMetrics[] results; | |
Experiment* experiment; | |
Variation* experimentVariation; | |
} | |
struct ResultMetrics { | |
uint susceptible, exposed, infected, recovered, skeptic; | |
this(T)(T from) { | |
susceptible = from.front; | |
from.popFront; | |
exposed = from.front; | |
from.popFront; | |
infected = from.front; | |
from.popFront; | |
recovered = from.front; | |
from.popFront; | |
skeptic = from.front; | |
from.popFront; | |
} | |
} | |
void processForResults(ref ResultContainer[] container, ref Experiments experiments) { | |
import std.file : readText, write; | |
import std.algorithm : map, filter, joiner, splitter, sum, each; | |
import std.math : ceil; | |
import std.array : array; | |
import std.range : chunks, iota, dropExactly, lockstep, repeat; | |
import std.conv; | |
size_t offset = container.length; | |
container.length += experiments.sets.map!(a => a.variations.length).sum * 10; | |
string head; | |
foreach(i; 0 .. 10) { | |
foreach(v; ["Susceptible", "Exposed", "Infected", "Recovered", "Skeptic"]) { | |
head ~= `"` ~ v ~ `(` ~ i.text ~ `)",`; | |
} | |
} | |
head.length--; | |
head ~= "\r\n"; | |
foreach(i, ref experiment; experiments.sets) { | |
foreach(ref variation; experiment.variations) { | |
string raw_text = readText("results/" ~ variation.resultFileName ~ ".csv"); | |
ResultMetrics[][10] results = new ResultMetrics[1000]; | |
auto temp = raw_text | |
.splitter("\r\n") | |
.dropExactly(50) | |
.map!(a => a | |
.splitter(",") | |
.filter!(b => b.length > 2) | |
.map!(b => b[1 .. $-1]) | |
.map!(b => b.to!uint) | |
.chunks(5) | |
.map!(b => ResultMetrics(b)) | |
) | |
.filter!(a => !a.empty) | |
.joiner | |
.chunks(10) | |
.lockstep(iota(0, 1000)); | |
foreach(a, j; temp) { | |
foreach(i, b; iota(0, 10).lockstep(a)) { | |
results[i][j] = b; | |
} | |
} | |
foreach(run, v; results) { | |
container[offset + run] = ResultContainer(run, null/+v+/, &experiment, &variation); | |
} | |
write("data/" ~ variation.resultFileName ~ ".csv", cast(ubyte[])head ~ (raw_text | |
.splitter("\r\n") | |
.dropExactly(50) | |
.filter!(a => a.length > 1) | |
.map!(a => a[1 .. $]) | |
.joiner("\n") | |
.map!(a => cast(ubyte)a) | |
.filter!(a => a != 0) | |
.array)); | |
offset += 10; | |
} | |
} | |
} | |
void generateGraphs(ResultContainer[] container, ref Experiments experiments) { | |
import std.algorithm : map; | |
import std.array : array; | |
import std.range : chunks, evenChunks, lockstep; | |
import std.parallelism : parallel; | |
struct Iteration { | |
ResultContainer[] container; | |
string inputFileName, outputFileName; | |
string description; | |
} | |
enum NumThreads = 10; | |
Iteration[][] iterations = container | |
.chunks(10) | |
.map!(a => Iteration(a, | |
"data/" ~ a[0].experimentVariation.resultFileName ~ ".csv", | |
"reports/graphs/" ~ a[0].experimentVariation.resultFileName, | |
a[0].experimentVariation.probForFrom ~ " to " ~ a[0].experimentVariation.probForTo ~ | |
" μ(mean) " ~ a[0].experimentVariation.probForTo ~ " σ(stddev) " ~ a[0].experimentVariation.probTo)) | |
.evenChunks(NumThreads) | |
.map!array | |
.array; | |
foreach(iteration2; iterations.parallel(NumThreads)) { | |
import std.process : pipeProcess, wait; | |
auto pipes = pipeProcess(["gnuplot/bin/gnuplot"]); | |
pipes.stdin.write(` | |
reset | |
set encoding utf8 | |
set terminal png with size 800, 600 | |
set style data linespoints | |
set datafile separator "," | |
set xrange [0 : 1001] | |
set yrange [0:100] | |
set xlabel "Ticks" | |
set ylabel "Number of agents" | |
set grid | |
set key default | |
set key autotitle columnhead | |
`); | |
foreach(iteration; iteration2) { | |
pipes.stdin.writeln(` | |
set title "Number of agents where ` ~ (iteration.description.length > 15 ? iteration.description : `equal probabilities is used`) ~ `"` | |
); | |
foreach(i; 0 .. 10) { | |
import std.conv : text; | |
pipes.stdin.writeln(`set output "` ~ iteration.outputFileName ~ "_" ~ i.text ~ `.png"`); | |
pipes.stdin.writeln(`plot for [col=` ~ ((i * 5) + 1).text ~ `:` ~ ((i * 5) + 5).text ~ `] "` ~ iteration.inputFileName ~ `" using 0:col`); | |
} | |
} | |
pipes.stdin.flush; | |
pipes.stdin.close; | |
wait(pipes.pid); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment