Definition:
class logit
{
public:
// build objects
int nbX;
int nbY;
int nbParams;
double sigma = 1.0; // this obviates issues with general market construction (DSE)
bool outsideOption = true;
// input objects
arma::mat U;
arma::mat mu;
// equilibrium objects
arma::mat U_sol;
arma::mat mu_sol;
// member functions
~logit(){};
logit(){};
explicit logit(int nbX_inp, int nbY_inp);
explicit logit(int nbX_inp, int nbY_inp, double sigma_inp, bool outsideOption_inp);
void build(int nbX_inp, int nbY_inp);
void build(int nbX_inp, int nbY_inp, double sigma_inp, bool outsideOption_inp);
double G(const arma::vec& n);
double G(const arma::vec& n, const arma::mat& U_inp, arma::mat& mu_out);
//double Gx(const arma::mat& U_x_inp, arma::mat& mu_x_out, int x);
double Gstar(const arma::vec& n);
double Gstar(const arma::vec& n, const arma::mat& mu_inp, arma::mat& U_out);
double Gstarx(const arma::mat& mu_x_inp, arma::mat &U_x_out);
double Gstarx(const arma::mat& mu_x_inp, arma::mat &U_x_out, int x);
double Gbar(const arma::mat& Ubar, const arma::mat& mubar, const arma::vec& n, arma::mat& U_out, arma::mat& mu_out);
double Gbarx(const arma::vec& Ubar_x, const arma::vec& mubar_x, arma::mat& U_x_out, arma::mat& mu_x_out);
double Gbarx(const arma::vec& Ubar_x, const arma::vec& mubar_x, arma::mat& U_x_out, arma::mat& mu_x_out, int x);
arma::mat D2G(const arma::vec& n, bool xFirst);
void D2G(arma::mat &H, const arma::vec& n, bool xFirst);
void D2G(arma::mat &H, const arma::vec& n, const arma::mat& U_inp, bool xFirst);
arma::mat D2Gstar(const arma::vec& n, bool xFirst);
arma::mat D2Gstar(const arma::vec& n, const arma::mat& mu_inp, bool xFirst);
void D2Gstar(arma::mat &H, const arma::vec& n, bool xFirst);
void D2Gstar(arma::mat &H, const arma::vec& n, const arma::mat& mu_inp, bool xFirst);
arma::mat dtheta_NablaGstar(const arma::vec& n, arma::mat* dtheta_inp, bool xFirst);
void dtheta_NablaGstar(arma::mat &ret, const arma::vec& n, arma::mat* dtheta_inp, bool xFirst);
empirical simul();
empirical simul(int* nbDraws, int* seed);
void simul(empirical& obj_out);
void simul(empirical& obj_out, int* nbDraws, int* seed);
private:
static double differMargX(double z, void* opt_data);
};
arma::mat U(2,3);
U << 1.6 << 3.2 << 1.1 << arma::endr
<< 2.9 << 1.0 << 3.1 << arma::endr;
arma::mat mu(2,3);
mu << 1.0 << 3.0 << 1.0 << arma::endr
<< 2.0 << 1.0 << 3.0 << arma::endr;
//
// setup logit class object
int nbX = U.n_rows;
int nbY = U.n_cols;
arma::vec n = arma::sum(mu,1);
trame::logit logits(nbX,nbY);
//
// empirical object:
int sim_seed = 1777;
int n_draws = 1000;
trame::empirical logit_sim;
logits.simul(logit_sim, &n_draws, &sim_seed);
//
// first compute optimal assignment (mu)
arma::mat mu_sol, mu_sol_sim;
double G_val = logits.G(n,U,mu_sol);
double G_sim_val = logit_sim.G(n,U,mu_sol_sim);
std::cout << "G(U) and G-sim(U): \n" << G_val << " and " << G_sim_val << std::endl;
arma::cout << "\nG -> mu: \n" << mu_sol << arma::endl;
arma::cout << "G-sim -> mu: \n" << mu_sol_sim << arma::endl;
//
// solution to dual problem U*
arma::mat U_star;
arma::mat U_star_sim;
double Gstar_val = logits.Gstar(n,mu_sol,U_star);
double Gstar_sim_val = logit_sim.Gstar(n,mu_sol,U_star_sim);
std::cout << "G*(mu) and G*-sim(mu): \n" << Gstar_val << " and " << Gstar_sim_val << std::endl;
arma::cout << "\n\\nabla G*(\\nabla G(U)): \n" << U_star << arma::endl;
arma::cout << "\\nabla G-sim*(\\nabla G-sim(U)): \n" << U_star_sim << arma::endl;
//
// Gbar
arma::mat mu_bar(2,3);
mu_bar.fill(2);
arma::mat U_bar_temp, mu_bar_temp;
arma::mat U_bar_sim_temp, mu_bar_sim_temp;
double val_Gbar = logits.Gbar(U,mu_bar,n,U_bar_temp,mu_bar_temp);
double val_Gbar_sim = logit_sim.Gbar(U,mu_bar,n,U_bar_sim_temp,mu_bar_sim_temp);
std::cout << "Gbar val: \n" << val_Gbar << std::endl;
std::cout << "Gbar-sim val: \n" << val_Gbar_sim << std::endl;