test-econ-model/include/econ.hpp

88 lines
2.5 KiB
C++
Raw Permalink Normal View History

2022-11-30 13:59:32 -08:00
#include <iostream>
2022-11-30 02:07:09 -08:00
#include <vector>
2022-11-30 13:59:32 -08:00
#include <random>
2022-12-03 01:40:48 -08:00
#include <cmath>
2022-11-30 02:07:09 -08:00
2022-11-30 13:59:32 -08:00
std::random_device econ_dev;
std::mt19937 econ_rng(econ_dev());
2022-12-03 01:40:48 -08:00
// ----------------------------------------------------------
// -- Recipient Finders
// ----------------------------------------------------------
/**
* @brief Find & return random participant
*
* @param balances Balance vec
* @return int
*/
int find_participant_random(std::vector<int> &balances) {
// random spend ratio is too costly
std::uniform_int_distribution<std::mt19937::result_type> dist_len(0,balances.size()-1);
return dist_len(econ_rng);
}
/**
* @brief Find & return random participant
*
* @param balances Balance vec
* @param percent_cutoff Upper N% to decide among
* @return int
*/
int find_participant_random_wealthy(std::vector<int> &balances, float percent_cutoff = 10) {
// random spend ratio is too costly
int cutoff = percent_cutoff / 100 * balances.size();
std::uniform_int_distribution<std::mt19937::result_type> dist_len(0,balances.size()-1);
return dist_len(econ_rng);
}
// ----------------------------------------------------------
// -- Spend Decisions
// ----------------------------------------------------------
2022-11-30 13:59:32 -08:00
/**
* @brief Simple random economic spend decision
*
* @param balances Balances vec
* @param id ID of participant making the decision
* @param spend_ratio Proportion of savings they are willing
* to spend
*/
2022-11-30 02:07:09 -08:00
void economic_decision_simple(std::vector<int> &balances, int id, float spend_ratio) {
// assert(spend_ratio > 0 && spend_ratio <= 1);
int total_bal = balances.at(id);
2022-11-30 13:59:32 -08:00
int spendable = spend_ratio * total_bal;
2022-12-03 01:40:48 -08:00
int recipient_id = find_participant_random(balances);
2022-11-30 02:07:09 -08:00
balances.at(id) -= spendable;
balances.at(recipient_id) += spendable;
}
2022-11-30 13:59:32 -08:00
2022-12-02 02:00:45 -08:00
/**
2022-12-03 01:40:48 -08:00
* @brief Sin-based varying spend output based on age. Peaks in midlife
2022-12-02 02:00:45 -08:00
*
2022-12-03 01:40:48 -08:00
* @param ages Ages vec
2022-12-02 02:00:45 -08:00
* @param balances Balances vec
* @param id ID of participant making decision
2022-12-03 01:40:48 -08:00
* @param max_spend_ratio max/peak spend ratio
* @param bump how much to bump min spend amount from 0
2022-12-02 02:00:45 -08:00
*/
2022-12-03 01:40:48 -08:00
void economic_random_age_sin(
std::vector<int> &ages,
std::vector<int> &balances,
int max_age,
int id,
float max_spend_ratio,
int bump = 0.1
) {
int recipient_id = find_participant_random(balances);
int spendable = round(
max_spend_ratio *
sin(ages[id] / max_age) +
bump)
;
balances.at(id) -= spendable;
balances.at(recipient_id) += spendable;
2022-11-30 13:59:32 -08:00
}