Skip to content

Commit

Permalink
3D graphics for alleles' distribution
Browse files Browse the repository at this point in the history
  • Loading branch information
FLAK-ZOSO committed Nov 3, 2023
1 parent c83d373 commit 3f495a5
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 68 deletions.
3 changes: 2 additions & 1 deletion compile.bash
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
g++ starklag.cpp -o starklag -std=c++17
g++ starklag.cpp -o starklag -std=c++17
# g++ starklag.cpp -o starklag -std=c++17 -fsanitize=address,undefined
47 changes: 47 additions & 0 deletions graphics.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import mpl_toolkits.mplot3d as a3
import matplotlib.pyplot as plt
import numpy as np
import sys
import os

Expand All @@ -9,6 +11,51 @@
if file.endswith('.txt'):
if file in {'debug.txt', 'dna-stats.txt'}:
continue
if 'alleles' in file: # 3D histogram
data = open(f"{directory}/{file}", 'r').read().strip().split('\n')
# Data are in the form: "allele:value,allele:value,..." for each line
data = [line.split(',') for line in data]
# Remove the last element of each line, which is an empty string
data = [line[:-1] for line in data]
# Data are in the form: [["allele:value", "allele:value", ...], ...]
labels: list[str] = []
for i in range(len(data)): # iterate over each line
labels.append([pair.split(':')[0] for pair in data[i]])
data[i] = [int(pair.split(':')[1]) for pair in data[i]]
# Add padding to the data so that it is a square matrix
max_len_line = 0
for index, line in enumerate(data):
if len(line) > len(data[max_len_line]):
max_len_line = index
# Padding with zeros may be needed on the left or on the right
for index, line in enumerate(data):
if len(line) < len(data[max_len_line]):
left_padding_needed = labels[max_len_line].index(labels[index][0])
right_padding_needed = len(data[max_len_line]) - len(data[index]) - left_padding_needed
data[index] = [0] * left_padding_needed + data[index] + [0] * right_padding_needed
# Data are in the form: [["value", "value", ...], ...]
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
data_array = np.array(data)
z_data = [10*i for i in range(len(data_array))]
x_data, y_data = np.meshgrid(
np.arange(data_array.shape[1]),
np.arange(data_array.shape[0])
)
x_data = x_data.flatten()
y_data = y_data.flatten()
z_data = np.zeros(data_array.shape).flatten()
ax.bar3d(x_data, y_data, z_data, 1, 1, data_array.flatten())
ax.set_xticks(np.arange(data_array.shape[1]))
ax.set_xticklabels(labels[max_len_line], fontsize=8)
plt.title(file[:-4])
plt.xlabel('Alleles')
plt.ylabel('Time')
# plt.set_zlabel('Frequency')
plt.savefig(f'{directory}/{file[:-4]}.png')
plt.show()
continue
# 2D graphic
ys = list(map(float, open(f'{directory}/{file}', 'r').read().strip().split('\n')))
xs = [10 * i for i in range(len(ys))]

Expand Down
1 change: 0 additions & 1 deletion organism.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#include "dna.cpp"
#include <random>
#include <chrono>
#include <thread>
#define DEBUG 1


Expand Down
Binary file modified starklag
Binary file not shown.
69 changes: 3 additions & 66 deletions starklag.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include "organism.cpp"
#include <set>
#include "stats.cpp"
#include <thread>
#ifdef _WIN32
#include <windows.h>
#endif
Expand Down Expand Up @@ -46,25 +46,6 @@
}
#endif

std::ofstream speed_stats("speed-stats.txt");
std::ofstream strength_stats("strength-stats.txt");
std::ofstream fertility_stats("fertility-stats.txt");
std::ofstream nature_stats("nature-stats.txt");
std::ofstream lifespan_stats("lifespan-stats.txt");
std::ofstream attack_stats("attack-stats.txt");
std::ofstream defense_stats("defense-stats.txt");
std::ofstream vision_stats("vision-stats.txt");
std::unordered_map<Gene, std::ofstream*> gene_stats = {
{Gene::SPEED, &speed_stats},
{Gene::STRENGTH, &strength_stats},
{Gene::FERTILITY, &fertility_stats},
{Gene::NATURE, &nature_stats},
{Gene::LIFESPAN, &lifespan_stats},
{Gene::ATTACK, &attack_stats},
{Gene::DEFENSE, &defense_stats},
{Gene::VISION, &vision_stats}
};


bool isDead(Organism* organism) {
for (std::vector<Organism*>::iterator it = Organism::dead_organisms.begin(); it != Organism::dead_organisms.end(); it++) {
Expand Down Expand Up @@ -230,52 +211,8 @@ int main() {
}
});

std::ofstream dna_stats("dna-stats.txt");
std::ofstream organisms_count("organisms-count.txt");
for (int _ = 0; !quit; _++) {
organisms_count << Organism::organisms.size() << std::endl;
// I use map<Gene, ...> and not vector<...> just for the purpose of being explicit
std::unordered_map<Gene, int> sum;
std::unordered_map<Gene, std::vector<int>> values_found; // values_found[gene] = all values found for that gene
std::unordered_map<Gene, std::unordered_map<int, int>> values; // values[gene][allele] = counter of that allele
for (Gene gene : genes) {
sum.insert({gene, 0});
values_found.insert({gene, std::vector<int>()});
values.insert({gene, std::unordered_map<int, int>()});
}
for (Organism* organism : Organism::organisms) {
DNA* dna = organism->dna;
for (Allele* allele : dna->alleles) {
if (std::find(values_found[allele->name].begin(), values_found[allele->name].end(), allele->value) == values_found[allele->name].end()) {
values[allele->name][allele->value] = 1;
values_found[allele->name].push_back(allele->value);
} else {
values[allele->name][allele->value]++;
}
sum[allele->name] += allele->value;
}
}
std::unordered_map<Gene, float> averages;
for (Gene gene : genes) {
averages.insert({gene, (float)sum[gene]/(float)Organism::organisms.size()});
}
// Output the statistics to dna-stats.txt
dna_stats << "== DNA stats at " << _ << " decaframes from start ==\n\n";
dna_stats << "Allele's distribution:\n";
for (Gene gene : genes) {
dna_stats << "- " << gene_to_string[gene] << " (average: " << averages[gene] << ")\n";
*gene_stats[gene] << averages[gene] << std::endl;
std::sort(values_found[gene].begin(), values_found[gene].end());
for (int value : values_found[gene]) {
if (std::find(possible_random_allele_values[gene].begin(), possible_random_allele_values[gene].end(), value) != possible_random_allele_values[gene].end()) {
dna_stats << "\t" << allele_to_string[gene][value] << " : " << values[gene][value] << "\n";
} else {
dna_stats << "\t" << value << " : " << values[gene][value] << "\n";
}
}
}
dna_stats << std::endl;

dumpStats(_);
for (int i = 0; i < 10; i++) {
while (paused) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
Expand Down
91 changes: 91 additions & 0 deletions stats.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#include "organism.cpp"


std::ofstream dna_stats("dna-stats.txt");
std::ofstream organisms_count("organisms-count.txt");

std::ofstream speed_stats("speed-stats.txt");
std::ofstream strength_stats("strength-stats.txt");
std::ofstream fertility_stats("fertility-stats.txt");
std::ofstream nature_stats("nature-stats.txt");
std::ofstream lifespan_stats("lifespan-stats.txt");
std::ofstream attack_stats("attack-stats.txt");
std::ofstream defense_stats("defense-stats.txt");
std::ofstream vision_stats("vision-stats.txt");
std::unordered_map<Gene, std::ofstream*> gene_stats = {
{Gene::SPEED, &speed_stats},
{Gene::STRENGTH, &strength_stats},
{Gene::FERTILITY, &fertility_stats},
{Gene::NATURE, &nature_stats},
{Gene::LIFESPAN, &lifespan_stats},
{Gene::ATTACK, &attack_stats},
{Gene::DEFENSE, &defense_stats},
{Gene::VISION, &vision_stats}
};
std::ofstream speed_alleles_stats("speed-alleles-stats.txt");
std::ofstream strength_alleles_stats("strength-alleles-stats.txt");
std::ofstream fertility_alleles_stats("fertility-alleles-stats.txt");
std::ofstream nature_alleles_stats("nature-alleles-stats.txt");
std::ofstream lifespan_alleles_stats("lifespan-alleles-stats.txt");
std::ofstream attack_alleles_stats("attack-alleles-stats.txt");
std::ofstream defense_alleles_stats("defense-alleles-stats.txt");
std::ofstream vision_alleles_stats("vision-alleles-stats.txt");
std::unordered_map<Gene, std::ofstream*> alleles_stats = {
{Gene::SPEED, &speed_alleles_stats},
{Gene::STRENGTH, &strength_alleles_stats},
{Gene::FERTILITY, &fertility_alleles_stats},
{Gene::NATURE, &nature_alleles_stats},
{Gene::LIFESPAN, &lifespan_alleles_stats},
{Gene::ATTACK, &attack_alleles_stats},
{Gene::DEFENSE, &defense_alleles_stats},
{Gene::VISION, &vision_alleles_stats}
};


void dumpStats(int _) {
organisms_count << Organism::organisms.size() << std::endl;
// I use map<Gene, ...> and not vector<...> just for the purpose of being explicit
std::unordered_map<Gene, int> sum;
std::unordered_map<Gene, std::vector<int>> values_found; // values_found[gene] = all values found for that gene
std::unordered_map<Gene, std::unordered_map<int, int>> values; // values[gene][allele] = counter of that allele
for (Gene gene : genes) {
sum.insert({gene, 0});
values_found.insert({gene, std::vector<int>()});
values.insert({gene, std::unordered_map<int, int>()});
}
for (Organism* organism : Organism::organisms) {
DNA* dna = organism->dna;
for (Allele* allele : dna->alleles) {
if (std::find(values_found[allele->name].begin(), values_found[allele->name].end(), allele->value) == values_found[allele->name].end()) {
values[allele->name][allele->value] = 1;
values_found[allele->name].push_back(allele->value);
} else {
values[allele->name][allele->value]++;
}
sum[allele->name] += allele->value;
}
}
std::unordered_map<Gene, float> averages;
for (Gene gene : genes) {
averages.insert({gene, (float)sum[gene]/(float)Organism::organisms.size()});
}
// Output the statistics to dna-stats.txt
dna_stats << "== DNA stats at " << _ << " decaframes from start ==\n\n";
dna_stats << "Allele's distribution:\n";
for (Gene gene : genes) {
dna_stats << "- " << gene_to_string[gene] << " (average: " << averages[gene] << ")\n";
*gene_stats[gene] << averages[gene] << std::endl;
std::sort(values_found[gene].begin(), values_found[gene].end());
for (int value : values_found[gene]) {
if (std::find(possible_random_allele_values[gene].begin(), possible_random_allele_values[gene].end(), value) != possible_random_allele_values[gene].end()) {
dna_stats << "\t" << allele_to_string[gene][value] << " : " << values[gene][value] << "\n";
*alleles_stats[gene] << allele_to_string[gene][value] << ":" << values[gene][value] << ",";
} else {
dna_stats << "\t" << value << " : " << values[gene][value] << "\n";
*alleles_stats[gene] << value << ":" << values[gene][value] << ",";
}
}
*alleles_stats[gene] << std::endl;
}
dna_stats << std::endl;
}

0 comments on commit 3f495a5

Please sign in to comment.