Skip to content

Instantly share code, notes, and snippets.

@rikkimax
Last active January 29, 2017 00:56
Show Gist options
  • Save rikkimax/42c3dfa6500155c5e441cbb1437142ea to your computer and use it in GitHub Desktop.
Save rikkimax/42c3dfa6500155c5e441cbb1437142ea to your computer and use it in GitHub Desktop.
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