Skip to content

Instantly share code, notes, and snippets.

@jongwook
Last active December 26, 2015 08:39
Show Gist options
  • Save jongwook/7123717 to your computer and use it in GitHub Desktop.
Save jongwook/7123717 to your computer and use it in GitHub Desktop.
Trying to reproduce Yuji Ijiri's 1964 paper about business firm growth and size
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <algorithm>
#include <vector>
static const int SESSIONS = 10000;
static const double ALPHA = 0.25;
static const double BETA = 0.95;
void seed() {
int seed;
std::cout << "Enter seed number : ";
std::cin >> seed;
srand(seed);
}
double sample() {
return (double)rand() / RAND_MAX;
}
struct Firm {
int size;
double weight;
Firm(int size, double weight) : size(size), weight(weight) {}
};
struct Industry {
std::vector<Firm> firms;
int total_size = 0;
double total_weight = 0;
void add(Firm firm) {
firms.push_back(firm);
total_weight += firm.weight;
total_size += firm.size;
}
void step() {
// calculates values at step t based on the values at step t-1
// initial state:
// firm.size - size of each firm at t - 1: x(t-1)
// firm.weight - weights to select the firm to grow at this step: sum(tau = 1...t-1, x(tau) * beta ^ tau)
// result:
// firm.size - size of each firm at t: x(t)
// firm.weight - weights to select the firm to grow at the next step: sum(tau = 1...t, x(tau) * beta ^ tau)
// stage 1
if (sample() < ALPHA) {
firms.push_back(Firm(1, 1));
total_size++;
} else {
// stage 2
double r = sample();
double sum = 0;
auto growing = firms.begin();
for (auto firm = firms.begin(); firm != firms.end(); firm++) {
sum += firm->weight;
if (sum > r * total_weight) {
// this way growing will point to the firm with the largest index which satisfies the condition
break;
}
growing = firm;
}
// the firm size grows by 1
growing->size++;
total_size++;
// the weight gets incremented by 1, and then decays
growing->weight += 1.0;
}
// decaying
double sum = 0;
for (Firm &firm : firms) {
firm.weight *= BETA;
sum += firm.weight;
}
total_weight = sum;
}
void sort() {
// sort so that firms with larger size comes first
std::sort(firms.begin(), firms.end(), [](Firm a, Firm b) { return a.size > b.size; });
}
void print(std::string file) {
std::ofstream output(file);
if (!output) {
std::cerr << "Could not open output file!" << std::endl;
return;
}
output << "Rank" << "," << "Firm Size" << "," << "Number of Firms" << "," << "Weight" << "," << "Cumulative Weight" << "," << "Cumulative Percent of Total Assets" << std::endl;
int sum_size = 0;
double sum_weight = 0;
int rank = 0;
for (auto firm = firms.begin(); firm != firms.end();) {
int count = 1;
double weight = firm->weight;
int size = firm->size;
while (true) {
firm++;
if (firm == firms.end() || firm->size != size) break;
count++;
weight += firm->weight;
}
rank += count;
sum_size += count * size;
sum_weight += weight;
output << rank << "," << size << "," << count << "," << weight / total_weight << "," << sum_weight / total_weight << "," << (double)sum_size / total_size << std::endl;
}
std::cout << "Output Complete!" << std::endl;
}
};
int main(int argc, char **argv) {
seed();
Industry industry;
industry.add(Firm(5, 1.0));
industry.add(Firm(3, 1.0));
industry.add(Firm(1, 1.0));
for (int i = 0; i < SESSIONS; i++) {
industry.step();
}
industry.sort();
industry.print("output.csv");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment