lmoffatt / macro_dr

GNU General Public License v3.0
1 stars 1 forks source link

remove redundant saving/loading functions for simulation #92

Open lmoffatt opened 9 months ago

lmoffatt commented 9 months ago

List and analyze the use of saving/loading functions for simulation data.

Then depreciate/remove the redundant.

lmoffatt commented 9 months ago

template <includes_N_state_evolution keep_N_state>
void save_simulation(std::string name,
                     Simulated_Recording<keep_N_state> const &r) {
  std::ofstream f(name + "_sim.txt");

  f << std::setprecision(std::numeric_limits<double>::digits10 + 1) << r
    << "\n";
}

this function below is clearly not implemented


template <includes_N_state_evolution keep_N_state>
void load_simulation(std::string name, Simulated_Recording<keep_N_state> &r) {
    std::ofstream f(name + "_sim.txt");

    f << std::setprecision(std::numeric_limits<double>::digits10 + 1) << r
      << "\n";
}

template <includes_N_state_evolution keep_N_state>
void save_simulation(std::string name,
                     std::vector<Simulated_Recording<keep_N_state>> const &r) {
  std::ofstream f(name + "_sim.txt");
  f << "nrep"
    << ","
    << "i_x"
    << ","
    << "Y"
    << "\n

  for (std::size_t i = 0; i < r.size(); ++i)
    for (std::size_t n = 0; n < r[i]()().size(); ++n) {
      f << i << "," << n << "," << r[i]()()[n]() << "\n";
    }
}

template <includes_N_state_evolution keep_N_state>
void report(std::string filename, const Patch_State_Evolution &predictions,
            const Simulated_Recording<keep_N_state> &y, const Experiment &xs) {
  auto &ys = get<Recording>(y());
  std::ofstream f(filename);
  f << std::setprecision(std::numeric_limits<double>::digits10 + 1) << "i_x"
    << ","
    << "time"
    << ","
    << "num_samples"
    << ","
    << "ATP_step"
    << ","
    << "v_ev"
    << ","
    << "y"
    << ","
    << "y_mean"
    << ","
    << "y_var"
    << ","
    << "plogL"
    << ","
    << "eplogL"
    << ","
    << "logL"
    << ","
    << "i"
    << ","
    << "P_mean"
    << ","
    << "j"
    << ","
    << "P_Cov";
  if constexpr (keep_N_state.value)
    f << ","
      << "N"
      << "\n";
  else
    f << "\n";
  for (std::size_t i_x = 0; i_x < size(ys); ++i_x) {
    auto v_ev = get<ATP_evolution>(get<Recording_conditions>(xs)()[i_x]);
    for (std::size_t i = 0; i < get<P_Cov>(predictions()[i_x])().nrows(); ++i) {
      for (std::size_t j = 0; j < get<P_Cov>(predictions()[i_x])().ncols();
           ++j) {
        f << i_x << "," << get<Time>(get<Recording_conditions>(xs)()[i_x])
          << "," << get_num_samples(v_ev) << ","
          << ToString(average_ATP_step(v_ev)) << "," << ToString(v_ev) << ","
          << ys()[i_x]() << "," << get<y_mean>(predictions()[i_x]) << ","
          << get<y_var>(predictions()[i_x]) << ","
          << get<plogL>(predictions()[i_x]) << ","
          << get<eplogL>(predictions()[i_x]) << ","
          << get<logL>(predictions()[i_x]) << "," << i << ","
          << get<P_mean>(predictions()[i_x])()[i] << "," << j << ","
          << get<P_Cov>(predictions()[i_x])()(i, j);
        if constexpr (keep_N_state.value)
          f << "," << get<N_Ch_State_Evolution>(y())()[i_x]()[i] << "\n";
        else
          f << "\n";
      }
    }
  }
}

inline Maybe_error<bool> load_Recording_Data(std::string const &fname,
                                 std::string const &separator, Recording &e) {
    std::ifstream f(fname);
    if (!f)
        return error_message("cannot open file " + fname);
    else {
        std::string line;
        std::getline(f, line);
        std::stringstream ss(line);

        if (!(ss >> septr("i_step") >> septr(separator) >> septr("patch_current")))
            return error_message("titles are wrong : expected  i_step:" + separator +
                                 "patch_current; found:" + line);
        else {
            std::getline(f, line);
            ss = std::stringstream(line);
            std::size_t i_step;
            double val;
            while (extract_double(ss >> i_step >> septr(separator), val)) {
                if (i_step != e().size())
                    return error_message("i_step missmatch expected" +
                                         std::to_string(e().size()) +
                                         " found:" + std::to_string(i_step));
                else {
                    e().push_back(Patch_current(val));
                }
                std::getline(f, line);
                ss = std::stringstream(line);
            }
        }
        return true;
    }
}+

inline void save_Recording(std::string const &fname, std::string const &separator,
                    Recording const &e) {
    std::ofstream f(fname);
    f << std::setprecision(std::numeric_limits<double>::digits10 + 1);

    f << "i_step" << separator << "patch_current"
      << "\n";

    for (auto i_step = 0ul; i_step < e().size(); ++i_step) {
        f << i_step << separator << e()[i_step]() << "\n";
    }
}

template <class Parameter>
void report_model(save_Parameter<Parameter> &s, Recording const &e) {
    std::ofstream f(s.fname + "_recording.csv");
    f << std::setprecision(std::numeric_limits<double>::digits10 + 1);

    f << "i_step" << s.sep << "patch_current"
      << "\n";

    for (auto i_step = 0ul; i_step < e().size(); ++i_step) {
        f << i_step << s.sep << e()[i_step]() << "\n";
    }
}
lmoffatt commented 9 months ago

so we have a coherent duality of save_Recording and load_Recording_Data

I should have a save_Simulation (were we also save the states) and load_Simulated_Data (that would also load the states)

now for commands, what would we prefer? we want to be able to simulate a number of replicates with or without the states.

then we want to calculate the likelihood with or without the predictions and the derivatives.

we also want to fraction the data in different ways.

lmoffatt commented 9 months ago

so report and save are similar but different report checks for some condition to append info regularly save just saves.

lmoffatt commented 9 months ago

here I saw THE problem.

How to compose different objects to be saved (like simulations and likelihood predictions).

The problem of course is that we need these objects to be indexed. So we need an Idexed Object composition logic. This problem I solved long time ago, but it is somewhat heavy to transport it here. However I will have to (and that is a future Milestone).

In any case, implementing the index by hand, we will still need to differentiate the save_data from save_title.

Or just refrain to do such a thing and have duplication of code.... for now.