コード例 #1
0
/**
 * Execute any reports that have the model_state
 * specified as their execution state
 *
 * @param model_state The state the model has just finished
 */
void Manager::Execute(State::Type model_state) {
  LOG_TRACE();
  RunMode::Type run_mode = model_->run_mode();
  bool tabular = model_->global_configuration().print_tabular();
  LOG_FINE() << "Checking " << state_reports_[model_state].size() << " reports";
  for(auto report : state_reports_[model_state]) {
      if ( (RunMode::Type)(report->run_mode() & run_mode) == run_mode) {
        if (tabular)
          report->ExecuteTabular();
        else
          report->Execute();
      } else
        LOG_FINE() << "Skipping report: " << report->label() << " because run mode is incorrect";
  }
}
コード例 #2
0
void SumToOne::DoBuild() {
  LOG_TRACE();
  for (auto& estimate_label : estimate_labels_) {
    Estimate* estimate = model_->managers().estimate()->GetEstimateByLabel(estimate_label);
    if (estimate == nullptr) {
      LOG_ERROR_P(PARAM_ESTIMATE_LABELS) << "Estimate " << estimate_label << " could not be found. Have you defined it?";
      return;
    } else {
      LOG_FINE() << "transform with objective = " << transform_with_jacobian_ << " estimate transform " << estimate->transform_for_objective() << " together = " << !transform_with_jacobian_ && !estimate->transform_for_objective();
      if (!transform_with_jacobian_ && !estimate->transform_for_objective()) {
        LOG_ERROR_P(PARAM_LABEL) << "You have specified a transformation that does not contribute a jacobian, and the prior parameters do not refer to the transformed estimate, in the @estimate" << estimate_label_ << ". This is not advised, and may cause bias estimation. Please address the user manual if you need help";
      }
      if (estimate->transform_with_jacobian_is_defined()) {
        if (transform_with_jacobian_ != estimate->transform_with_jacobian()) {
          LOG_ERROR_P(PARAM_LABEL) << "This parameter is not consistent with the equivalent parameter in the @estimate block " << estimate_label_ << ". please make sure these are both true or both false.";
        }
      }
      estimates_.push_back(estimate);
    }
  }


  // Validate that the parameters sum to one.
  Double total = 0.0;

  for (auto& estimate : estimates_) {
    LOG_FINEST() << "transformation value = " << estimate->value();
    total += estimate->value();
  }
  if (total != 1.0)
    LOG_ERROR_P(PARAM_ESTIMATE_LABELS) << "The estiamtes you supplied to not sum to 1.0, they sum to " << total << ", please check initial values of these parameters";

  // Check that the bounds are sensible
  if (parameters_.Get(PARAM_UPPER_BOUND)->has_been_defined() & parameters_.Get(PARAM_LOWER_BOUND)->has_been_defined()) {
    for (unsigned i = 0; i < estimates_.size(); ++i) {
      if (estimates_[i]->lower_bound() < 0.0 || estimates_[i]->lower_bound() > 1.0)
        LOG_ERROR_P(PARAM_LOWER_BOUND) << "You cannot specify a lower bound less than 0 and greater than 1.0";
      if (estimates_[i]->upper_bound() < 0.0 || estimates_[i]->upper_bound() > 1.0)
        LOG_ERROR_P(PARAM_UPPER_BOUND) << "You cannot specify a upper bound less than 0 and greater than 1.0";
    }
  }
  LOG_MEDIUM() << "total = " << total;

  // Turn off the last estimate
  LOG_FINE() << "Turning off parameter, this won't be estimated, and will be an outcome of other parameters " << estimates_[estimates_.size() - 1]->parameter() << " in the estimation";
  estimates_[estimates_.size() - 1]->set_estimated(false);
  LOG_MEDIUM() << "flagged estimated = " << estimates_[estimates_.size() - 1]->estimated();
}
コード例 #3
0
void Project::RestoreOriginalValue(unsigned year) {
  LOG_TRACE();
  if (addressable_ != nullptr) {
    LOG_FINE() << "Setting original value to: " << original_value_;
    (this->*DoUpdateFunc_)(original_value_);
  }
}
コード例 #4
0
ファイル: TimeStep.cpp プロジェクト: Cyrill1/CASAL2
/**
 * Build our time step
 */
void TimeStep::Build() {

  // Get the pointers to our processes
  processes::Manager& process_manager = *model_->managers().process();
  for (string process_name : process_names_) {
    Process* process = process_manager.GetProcess(process_name);
    if (!process) {
      LOG_ERROR_P(PARAM_PROCESSES) << ": process " << process_name << " does not exist. Have you defined it?";
    } else
      processes_.push_back(process);
  }
  LOG_FINE() << "Time step " << label_ << " has " << processes_.size() << " processes";

  /**
   * Find the range of our mortality block. This block encompasses the
   * first continuous collection of mortality processes within the time
   * step.
   */
  mortality_block_.first  = processes_.size();
  mortality_block_.second = processes_.size() - 1;
  bool finished_mortality_block = false;
  for (unsigned i = 0; i < processes_.size(); ++i) {
    if (processes_[i]->process_type() == ProcessType::kMortality && !finished_mortality_block) {
      mortality_block_.first = mortality_block_.first == processes_.size() ? i : mortality_block_.first;
      mortality_block_.second = i;
    } else if (processes_[i]->process_type() == ProcessType::kMortality && finished_mortality_block) {
      LOG_FATAL() << "Mortality processes within a time step need to be consecutive (i.e. a single mortality block)";
    } else if (mortality_block_.first != processes_.size())
      finished_mortality_block = true;
  }

  mortality_block_.second = mortality_block_.first == processes_.size() ? mortality_block_.first : mortality_block_.second;
}
コード例 #5
0
ファイル: CovarianceMatrix.cpp プロジェクト: Cyrill1/CASAL2
void CovarianceMatrix::DoExecute() {
  /*
   * This reports the Covariance, Correlation and Hessian matrix
   */
  LOG_TRACE();
  auto minimiser_ = model_->managers().minimiser()->active_minimiser();
  covariance_matrix_ = minimiser_->covariance_matrix();

  cache_ << "*" << label_ << " " << "(" << type_ << ")" << "\n";
  cache_ << "Covariance_Matrix " << REPORT_R_MATRIX << "\n";

  for (unsigned i = 0; i < covariance_matrix_.size1(); ++i) {
    for (unsigned j = 0; j < covariance_matrix_.size2(); ++j)
      cache_ << covariance_matrix_(i, j) << " ";
    cache_ << "\n";
  }

  if (model_->run_mode() == RunMode::kMCMC) {
    auto mcmc_ = model_->managers().mcmc()->active_mcmc();
    if (mcmc_->recalculate_covariance()) {
      cache_ << REPORT_END << "\n\n";
      LOG_FINE() << "During the mcmc run you recalculated the the covariance matrix, so we will print the modified matrix at the end of the chain";
      cache_ << "Modified_covariance_matrix  " << REPORT_R_MATRIX  << "\n";
      auto covariance = mcmc_->covariance_matrix();
      for (unsigned i = 0; i < covariance.size1(); ++i) {
        for (unsigned j = 0; j < covariance.size2() - 1; ++j)
          cache_ << covariance(i, j) << " ";
        cache_ << covariance(i, covariance.size2() - 1) << "\n";
      }
    }
  }

  ready_for_writing_ = true;
}
コード例 #6
0
ファイル: Manager.cpp プロジェクト: Cyrill1/CASAL2
/**
 *  @param current_year teh current year this method is calles
 *
 *  This function will store all parameter values that we may want to overwrite at in projection years
 */
void Manager::StoreValues(unsigned current_year, unsigned start_year, unsigned final_year) {
  LOG_TRACE();
  // iterate over all @project blocks
  for (auto project : objects_) {
    LOG_FINE() << "@Project: " << project->label();
    project->StoreValue(current_year, start_year, final_year);
  }
}
コード例 #7
0
/**
 * This method can be called from the main thread to ensure
 * we wait for all reports to finish
 */
void Manager::WaitForReportsToFinish() {
#ifndef TESTMODE
  waiting_ = true;
  LOG_FINE() << "Waiting for reports";
  while(waiting_);
#endif
  return;
}
コード例 #8
0
/**
 * Build our reports then
 * organise the reports stored in our
 * object list into different containers
 * based on their type.
 */
void Manager::Build() {
  LOG_FINEST() << "objects_.size(): " << objects_.size();
  for (auto report : objects_) {
    report->Build();

    if ((RunMode::Type)(report->run_mode() & RunMode::kInvalid) == RunMode::kInvalid)
      LOG_CODE_ERROR() << "Report: " << report->label() << " has not been properly configured to have a run mode";

    if (report->model_state() != State::kExecute) {
      LOG_FINE() << "Adding report " << report->label() << " to state reports";
      state_reports_[report->model_state()].push_back(report);
    } else {
      LOG_FINE() << "Adding report " << report->label() << " to time step reports";
      time_step_reports_[report->time_step()].push_back(report);
    }
  }
}
コード例 #9
0
/**
 * Execute our DE Solver minimiser engine
 */
void DESolver::Execute() {
  estimates::Manager& estimate_manager = *model_->managers().estimate();

  vector<double>  lower_bounds;
  vector<double>  upper_bounds;
  vector<double>  start_values;

  model_->managers().estimate_transformation()->TransformEstimates();
  vector<Estimate*> estimates = estimate_manager.GetIsEstimated();
  for (Estimate* estimate : estimates) {
    if (!estimate->estimated())
      continue;

    lower_bounds.push_back(estimate->lower_bound());
    upper_bounds.push_back(estimate->upper_bound());
    start_values.push_back(estimate->value());

    if (estimate->value() < estimate->lower_bound()) {
      LOG_FATAL() << "When starting the DESolver minimiser the starting value (" << estimate->value() << ") for estimate "
          << estimate->parameter() << " was less than the lower bound (" << estimate->lower_bound() << ")";
    } else if (estimate->value() > estimate->upper_bound()) {
      LOG_FATAL() << "When starting the DESolver minimiser the starting value (" << estimate->value() << ") for estimate "
          << estimate->parameter() << " was greater than the upper bound (" << estimate->upper_bound() << ")";
    }
  }

  // Setup Engine
  desolver::CallBack solver = desolver::CallBack(model_, start_values.size(), population_size_, tolerance_);
  solver.Setup(start_values, lower_bounds, upper_bounds, kBest1Exp, difference_scale_, crossover_probability_);

  // Solver
  if (solver.Solve(max_generations_)) {
    result_ = MinimiserResult::kSuccess;
    LOG_FINE() << "DE Solver has successfully converged";
  } else {
    result_ = MinimiserResult::kError;
    LOG_FINE() << "DE Solver has failed to converge";
  }

  model_->managers().estimate_transformation()->RestoreEstimates();

}
コード例 #10
0
ファイル: File.cpp プロジェクト: Cyrill1/CASAL2
/**
 * Attempt to open our configuration file
 *
 * @param file_name The name of the file to open
 * @return true on success, false on failure
 */
bool File::OpenFile(string file_name) {
  LOG_TRACE();

  file_name_ = file_name;
  LOG_FINE() << "Opening file: " << file_name;

  file_.open(file_name_.c_str());
  if (file_.fail() || !file_.is_open())
    return false;

  return true;
}
コード例 #11
0
/**
 *    This will restore values provided by the minimiser that need to be restored for use in the annual cycle
 */
void SumToOne::DoRestore() {
  LOG_TRACE();
  // Create zk
  Double total = 0.0;
  for (unsigned i = 0; i < (estimates_.size() - 1); ++i) {
    total += estimates_[i]-> value();
  }
  Double new_value = 1.0 - total;
  LOG_FINE() << "Setting value to " << new_value << " for parameter = " << estimates_[estimates_.size() - 1]->parameter();
  estimates_[estimates_.size() - 1]->set_value(new_value);

}
コード例 #12
0
ファイル: Manager.cpp プロジェクト: Cyrill1/CASAL2
TimeStep* Manager::GetTimeStep(const string& label) const {
  LOG_FINE() << "label: " << label;
  TimeStep* result = nullptr;
  for (auto time_step : objects_) {
    if (time_step->label() == label) {
      result = time_step;
      break;
    }
  }

  return result;
}
コード例 #13
0
/**
 * This method collapses the Numbers at length by age matrix to numbers at age for a category
 */
void Category::CollapseAgeLengthDataToLength() {
  LOG_TRACE();

  if (age_length_matrix_.size() == 0)
    LOG_CODE_ERROR() << "if (age_length_matrix_.size() == 0)";

  LOG_FINE() << "age_length_matrix_.size(): " << age_length_matrix_.size();
  LOG_FINE() << "age_length_matrix_[0].size(): " << age_length_matrix_[0].size();
  length_data_.assign(model_->length_bins().size(), 0.0);
  for (unsigned i = 0; i < age_length_matrix_.size(); ++i) {
    for (unsigned j = 0; j < age_length_matrix_[i].size(); ++j) {
      if (j >= length_data_.size())
        LOG_CODE_ERROR() << "j >= length_data_.size()";

      length_data_[j] += age_length_matrix_[i][j];
    }
  }

  for (unsigned i = 0; i < length_data_.size(); ++i)
    LOG_FINEST() << "length_data_[" << i << "]: " << length_data_[i];
}
コード例 #14
0
/**
 * Execute this report
 */
void Project::DoExecute() {
  LOG_FINE() <<" printing report " << label_ << " of type " << project_->type();
  map<unsigned,Double>& values = project_->projected_parameters();
  cache_ << "*"<< type_ << "[" << label_ << "]" << "\n";
  cache_ << "project: " << project_label_ << "\n";
  cache_ << "values " << REPORT_R_VECTOR <<"\n";
  for(auto value : values) {
    cache_ << value.first << " " << value.second << "\n";
  }

  ready_for_writing_ = true;
}
コード例 #15
0
ファイル: Manager.cpp プロジェクト: Cyrill1/CASAL2
/**
 * Execute all of the timesteps
 * for the current year.
 */
void Manager::Execute(unsigned year) {
  LOG_TRACE();

  reports::Manager& report_manager = *model_->managers().report();
  for (current_time_step_ = 0; current_time_step_ < ordered_time_steps_.size(); ++current_time_step_) {
    LOG_FINE() << "Current Time Step: " <<  current_time_step_;
    ordered_time_steps_[current_time_step_]->Execute(year);
    report_manager.Execute(year, ordered_time_steps_[current_time_step_]->label());
  }

  // reset this for age sizes
  current_time_step_ = 0;
}
コード例 #16
0
ファイル: IFStreamFile.cpp プロジェクト: susu/papyrus-war
std::string IFStreamFile::readAll()
{
  ENFORCE(m_ifs.is_open(), "File must be opened before reading it!");
  LOG_DEBUG("Read all data from file: ", getName());

  std::string line;
  std::string data;
  while(getline(m_ifs, line))
  {
    LOG_FINE("line read: '", line, "'");
    data.append(line + "\n");
  }
  return data;
}
コード例 #17
0
ファイル: BinomialApprox.cpp プロジェクト: Cyrill1/CASAL2
/**
 * Simulate observed values
 *
 * @param comparisons A collection of comparisons passed by the observation
 */
void BinomialApprox::SimulateObserved(map<unsigned, vector<observations::Comparison> >& comparisons) {
  utilities::RandomNumberGenerator& rng = utilities::RandomNumberGenerator::Instance();

  Double error_value = 0.0;
  auto iterator = comparisons.begin();
  for (; iterator != comparisons.end(); ++iterator) {
    LOG_FINE() << "Simulating values for year: " << iterator->first;
    for (observations::Comparison& comparison : iterator->second) {
      error_value = ceil(AS_DOUBLE(AdjustErrorValue(comparison.process_error_, comparison.error_value_)));

      if (comparison.expected_ <= 0.0 || error_value <= 0.0)
        comparison.observed_ = 0.0;
      else
        comparison.observed_ = rng.binomial(AS_DOUBLE(comparison.expected_), AS_DOUBLE(error_value)) / error_value;
    }
  }
}
コード例 #18
0
ファイル: GammaDiff.cpp プロジェクト: Cyrill1/CASAL2
/**
 * Execute the minimiser to solve the model
 */
void GammaDiff::Execute() {
  LOG_TRACE();
  // Variables
  LOG_FINE() << "model_: " << model_;

  gammadiff::CallBack  call_back(model_);
  estimates::Manager* estimate_manager = model_->managers().estimate();
  LOG_FINE() << "estimate_manager: " << estimate_manager;

  vector<double>  lower_bounds;
  vector<double>  upper_bounds;
  vector<double>  start_values;

  model_->managers().estimate_transformation()->TransformEstimates();
  vector<Estimate*> estimates = estimate_manager->GetIsEstimated();
  LOG_FINE() << "estimates.size(): " << estimates.size();
  for (Estimate* estimate : estimates) {
    if (!estimate->estimated())
      continue;

    LOG_FINE() << "Estimate: " << estimate;
    LOG_FINE() << "transformed value: " << estimate->value();
    LOG_FINE() << "Parameter: " << estimate->parameter();

    lower_bounds.push_back((double)estimate->lower_bound());
    upper_bounds.push_back((double)estimate->upper_bound());
    start_values.push_back((double)estimate->value());

    if (estimate->value() < estimate->lower_bound()) {
      LOG_FATAL() << "When starting the GammDiff numerical_differences minimiser the starting value (" << estimate->value() << ") for estimate "
          << estimate->parameter() << " was less than the lower bound (" << estimate->lower_bound() << ")";
    } else if (estimate->value() > estimate->upper_bound()) {
      LOG_FATAL() << "When starting the GammDiff numerical_differences minimiser the starting value (" << estimate->value() << ") for estimate "
          << estimate->parameter() << " was greater than the upper bound (" << estimate->upper_bound() << ")";
    }
  }

  LOG_FINE() << "Launching minimiser";
  int status = 0;
  gammadiff::Engine clGammaDiff;
  clGammaDiff.optimise_finite_differences(call_back,
      start_values, lower_bounds, upper_bounds,
      status, max_iterations_, max_evaluations_, gradient_tolerance_,
      hessian_,1,step_size_);

  model_->managers().estimate_transformation()->RestoreEstimates();
}
コード例 #19
0
ファイル: Manager.cpp プロジェクト: Cyrill1/CASAL2
/**
 * Build
 */
void Manager::Build(Model* model) {
  LOG_TRACE();
  if (model->run_mode() == RunMode::kProjection) {
    bool ycs_values_exist = false;
    for (auto project : objects_) {
      LOG_FINE() << "Building Project: " << project->label();
      project->Build();
      if (project->estimable_parameter() == PARAM_YCS_VALUES)
        ycs_values_exist = true;
    }

    if (!ycs_values_exist) {
      for (auto process : model->managers().process()->objects()) {
        if (process->type() == PARAM_RECRUITMENT_BEVERTON_HOLT)
          LOG_ERROR() << process->location() << " process " << process->label() << " does not contain a @project for ycs_values, but you are running in projection mode";
      }
    }
  }
}
コード例 #20
0
ファイル: TransitionCategory.cpp プロジェクト: Cyrill1/CASAL2
/**
 * Execute our maturation rate process.
 */
void TransitionCategory::DoExecute() {
  LOG_TRACE();

  auto from_iter     = from_partition_.begin();
  auto to_iter       = to_partition_.begin();
  Double amount      = 0.0;

  LOG_FINEST() << "transition_rates_.size(): " << transition_rates_.size() << "; from_partition_.size(): " << from_partition_.size()
      << "; to_partition_.size(): " << to_partition_.size();
  if (from_partition_.size() != to_partition_.size()) {
    LOG_FATAL() << "The list of categories for the Transition Category process are not of equal size in year " << model_->current_year()
    << ". We have " << from_partition_.size() << " and " << to_partition_.size() << " categories to transition between";
  }

  if (transition_rates_.size() != from_partition_.size()) {
    LOG_FINE() << "Re-building the transition rates because the partition size has changed";
    transition_rates_.resize(from_partition_.size());
    for (unsigned i = 0; i < transition_rates_.size(); ++i) {
      Double proportion = proportions_.size() > 1 ? proportions_[i] : proportions_[0];
      unsigned min_age   = (*from_iter)->min_age_;

      for (unsigned j = 0; j < (*from_iter)->data_.size(); ++j) {
        transition_rates_[i].push_back(proportion * selectivities_[i]->GetResult(min_age + j, (*from_iter)->age_length_));
        if (selectivities_[i]->GetResult(min_age + j, (*from_iter)->age_length_) > 1.0)
          LOG_ERROR() << " Selectivity result is greater than 1.0, check selectivity";
      }
    }
  }

  for (unsigned i = 0; from_iter != from_partition_.end() && to_iter != to_partition_.end(); ++from_iter, ++to_iter, ++i) {

    for (unsigned offset = 0; offset < (*from_iter)->data_.size(); ++offset) {
      amount = transition_rates_[i][offset] * (*from_iter)->data_[offset];

      (*from_iter)->data_[offset] -= amount;
      (*to_iter)->data_[offset] += amount;
      if ((*from_iter)->data_[offset] < 0.0)
        LOG_FATAL() << "Maturation rate caused a negative partition if ((*from_iter)->data_[offset] < 0.0) ";
    }
  }
}
コード例 #21
0
void Linear::DoReset() {
  bool current_year =  model_->current_year() == years_[0];
  unsigned diff = model_->current_year() - years_[0];
  LOG_FINE() << "diff unsigned = " << diff;

  Double years_since_first_year = (Double)model_->current_year() - (Double)years_[0];
  LOG_FINE() << "diff from start of year = " << years_since_first_year;
  LOG_FINE() << " did we make it past this if statement " << current_year;
  if (current_year) {
    // First year don't make a change
    LOG_FINE() << "Setting Value to: " << intercept_;
    parameter_by_year_[model_->current_year()] =  intercept_;
  } else {
    // Add a linear trend
    parameter_by_year_[model_->current_year()] = intercept_ + years_since_first_year * slope_;
    //value_ = model_->objects().GetEstimable(parameter_, error);
    LOG_FINE() << "value = " << parameter_by_year_[model_->current_year()];
    LOG_FINE() << "value after deviate of " << slope_ << " = " << parameter_by_year_[model_->current_year()] << " for year " << model_->current_year();
    LOG_FINE() << "Setting Value to: " << parameter_by_year_[model_->current_year()];
  }
}
コード例 #22
0
void ProcessRemovalsByLength::Execute() {
  LOG_TRACE();
  /**
   * Verify our cached partition and partition sizes are correct
   */
//  auto categories = model_->categories();
  unsigned year = model_->current_year();
  unsigned year_index = year - model_->start_year();
  unsigned time_step = model_->managers().time_step()->current_time_step();
  auto cached_partition_iter = cached_partition_->Begin();
  auto partition_iter = partition_->Begin(); // vector<vector<partition::Category> >
  map<unsigned, map<string, map<string, vector<Double>>>> &Removals_at_age = mortality_instantaneous_->catch_at();

  /**
   * Loop through the provided categories. Each provided category (combination) will have a list of observations
   * with it. We need to build a vector of proportions for each length using that combination and then
   * compare it to the observations.
   */
  for (unsigned category_offset = 0; category_offset < category_labels_.size(); ++category_offset, ++partition_iter, ++cached_partition_iter) {
    LOG_FINEST() << "category: " << category_labels_[category_offset];
    Double start_value = 0.0;
    Double end_value = 0.0;
    Double number_at_age = 0.0;

//    LOG_WARNING() << "This is bad code because it allocates memory in the middle of an execute";
    vector<Double> expected_values(number_bins_, 0.0);
    vector<Double> numbers_at_length;
    vector<vector<Double>> age_length_matrix;

    /**
     * Loop through the 2 combined categories building up the
     * expected proportions values.
     */
    auto category_iter = partition_iter->begin();
    auto cached_category_iter = cached_partition_iter->begin();
    for (; category_iter != partition_iter->end(); ++cached_category_iter, ++category_iter) {
//      AgeLength* age_length = categories->age_length((*category_iter)->name_);

//      LOG_WARNING() << "This is bad code because it allocates memory in the middle of an execute";
      age_length_matrix.resize((*category_iter)->data_.size());

      vector<Double> age_frequencies(length_bins_.size(), 0.0);
      const auto& age_length_proportions = model_->partition().age_length_proportions((*category_iter)->name_)[year_index][time_step];

      for (unsigned data_offset = 0; data_offset < (*category_iter)->data_.size(); ++data_offset) {
        unsigned age = ((*category_iter)->min_age_ + data_offset);

        // Calculate the age structure removed from the fishing process
        number_at_age = Removals_at_age[year][method_][(*category_iter)->name_][data_offset];
        LOG_FINEST() << "Numbers at age = " << age << " = " << number_at_age << " start value : " << start_value << " end value : " << end_value;
        // Implement an algorithm similar to DoAgeLengthConversion() to convert numbers at age to numbers at length
        // This is different to DoAgeLengthConversion as this number is now not related to the partition
//        Double mu= (*category_iter)->mean_length_by_time_step_age_[time_step][age];

//        LOG_FINEST() << "mean = " << mu << " cv = " << age_length->cv(year, time_step, age) << " distribution = " << age_length->distribution_label() << " and length plus group = " << length_plus_;
//        age_length->CummulativeNormal(mu, age_length->cv(year, time_step, age), age_frequencies, length_bins_, length_plus_);

//        LOG_WARNING() << "This is bad code because it allocates memory in the middle of an execute";
        age_length_matrix[data_offset].resize(number_bins_);

        // Loop through the length bins and multiple the partition of the current age to go from
        // length frequencies to age length numbers
        for (unsigned j = 0; j < number_bins_; ++j) {
          age_length_matrix[data_offset][j] = number_at_age * age_length_proportions[data_offset][j];
          LOG_FINEST() << "The proportion of fish in length bin : " << length_bins_[j] << " = " << age_frequencies[j];
        }
      }

      if (age_length_matrix.size() == 0)
        LOG_CODE_ERROR()<< "if (age_length_matrix_.size() == 0)";

      numbers_at_length.assign(age_length_matrix[0].size(), 0.0);
      for (unsigned i = 0; i < age_length_matrix.size(); ++i) {
        for (unsigned j = 0; j < age_length_matrix[i].size(); ++j) {
          numbers_at_length[j] += age_length_matrix[i][j];
        }
      }

      for (unsigned length_offset = 0; length_offset < number_bins_; ++length_offset) {
        LOG_FINEST() << " numbers for length bin : " << length_bins_[length_offset] << " = " << numbers_at_length[length_offset];
        expected_values[length_offset] += numbers_at_length[length_offset];

        LOG_FINE() << "----------";
        LOG_FINE() << "Category: " << (*category_iter)->name_ << " at length " << length_bins_[length_offset];
        LOG_FINE() << "start_value: " << start_value << "; end_value: " << end_value << "; final_value: " << numbers_at_length[length_offset];
        LOG_FINE() << "expected_value becomes: " << expected_values[length_offset];
      }
    }

    if (expected_values.size() != proportions_[model_->current_year()][category_labels_[category_offset]].size())
      LOG_CODE_ERROR()<< "expected_values.size(" << expected_values.size() << ") != proportions_[category_offset].size("
      << proportions_[model_->current_year()][category_labels_[category_offset]].size() << ")";

      /**
       * save our comparisons so we can use them to generate the score from the likelihoods later
       */
    for (unsigned i = 0; i < expected_values.size(); ++i) {
      SaveComparison(category_labels_[category_offset], 0, length_bins_[i], expected_values[i], proportions_[model_->current_year()][category_labels_[category_offset]][i],
          process_errors_by_year_[model_->current_year()], error_values_[model_->current_year()][category_labels_[category_offset]][i], 0.0, delta_, 0.0);
    }
  }
}
コード例 #23
0
ファイル: Constant.cpp プロジェクト: Cyrill1/CASAL2
void Constant::DoUpdate() {
  LOG_FINE() << "Setting Value to: " << parameter_by_year_[model_->current_year()];
  (this->*update_function_)(parameter_by_year_[model_->current_year()]);
}
コード例 #24
0
/**
 * Execute Cinitial this code follows from the original CASAL algorithm
 */
void Cinitial::Execute() {
  LOG_TRACE();
  map<string, vector<Double>> category_by_age_total;
  auto partition_iter = partition_->Begin();
  for (unsigned category_offset = 0; category_offset < category_labels_.size(); ++category_offset, ++partition_iter) {
    category_by_age_total[category_labels_[category_offset]].assign((max_age_ - min_age_ + 1), 0.0);
    /**
     * Loop through the  combined categories building up the total abundance for each category label
     */
    auto category_iter = partition_iter->begin();
    for (; category_iter != partition_iter->end(); ++category_iter) {
      for (unsigned data_offset = 0; data_offset < (max_age_ - min_age_ + 1); ++data_offset) {
        unsigned age_offset = (*category_iter)->min_age_ - min_age_;
        // if this category min_age occurs after model min age ignore current age
        if (data_offset < age_offset)
          continue;
        category_by_age_total[category_labels_[category_offset]][data_offset] += (*category_iter)->data_[data_offset - age_offset];
      }
    }
  }
  LOG_TRACE();
  // loop through the category_labels and calculate the cinitial factor, which is the n_ / col_sums
  map<string, vector<Double>> category_by_age_factor;

  for (unsigned category_offset = 0; category_offset < category_labels_.size(); ++category_offset) {
    category_by_age_factor[category_labels_[category_offset]].assign((max_age_ - min_age_ + 1), 0.0);
    for (unsigned data_offset = 0; data_offset < (max_age_ - min_age_ + 1); ++data_offset) {

      if (category_by_age_total[category_labels_[category_offset]][data_offset] == 0.0)
        category_by_age_factor[category_labels_[category_offset]][data_offset] = 1.0;
      else {
        category_by_age_factor[category_labels_[category_offset]][data_offset] = n_[utilities::ToLowercase(category_labels_[category_offset])][data_offset]
            / category_by_age_total[category_labels_[category_offset]][data_offset];
      }
    }
  }
  LOG_TRACE();
  // Now loop through the combined categories multiplying each category by the factory
  // from the combined group it belongs to
  partition_iter = partition_->Begin();
  for (unsigned category_offset = 0; category_offset < category_labels_.size(); ++category_offset, ++partition_iter) {
    /**
     * Loop through the  combined categories building up the total abundance for each category label
     */
    auto category_iter = partition_iter->begin();
    for (; category_iter != partition_iter->end(); ++category_iter) {
      for (unsigned data_offset = 0; data_offset < (max_age_ - min_age_ + 1); ++data_offset) {
        unsigned age_offset = (*category_iter)->min_age_ - min_age_;
        // if this category min_age occurs after model min age ignore this age
        if (data_offset < age_offset)
          continue;
        (*category_iter)->data_[data_offset - age_offset] *= category_by_age_factor[category_labels_[category_offset]][data_offset];
      }
    }
  }
  // Build cache
  LOG_FINEST() << "finished calculating Cinitial";
  cached_partition_->BuildCache();
  // Execute the annual cycle for one year to calculate Cinitial
  timesteps::Manager* time_step_manager = model_->managers().time_step();
  time_step_manager->ExecuteInitialisation(label_, 1);

  // Store that SSB value ssb_offset times in the Cintiial phase GetPhaseIndex
  LOG_FINE() << "derived_ptr_.size(): " << derived_ptr_.size();
  for (auto derived_quantities : derived_ptr_) {
    vector<vector<Double>>& initialisation_values = derived_quantities->initialisation_values();
    unsigned cinit_phase_index = model_->managers().initialisation_phase()->GetPhaseIndex(label_);
    LOG_FINE() << "initialisation_values size: " << initialisation_values.size();
    LOG_FINE() << "ssb_offset: " << ssb_offset_;
    LOG_FINE() << "cinit_phase_index: " << cinit_phase_index;
    LOG_FINE() << "init_values[cinit_phase].size(): " << initialisation_values[cinit_phase_index].size();

    for(unsigned i = 0; i < ssb_offset_; ++i)
      initialisation_values[cinit_phase_index].push_back(*initialisation_values[cinit_phase_index].rbegin());
  }


  // set the partition back to Cinitial state
  auto cached_partition_iter  = cached_partition_->Begin();
  partition_iter = partition_->Begin();
  for (unsigned category_offset = 0; category_offset < category_labels_.size(); ++category_offset, ++partition_iter, ++cached_partition_iter) {
    auto category_iter = partition_iter->begin();
    auto cached_category_iter = cached_partition_iter->begin();
    for (; category_iter != partition_iter->end(); ++cached_category_iter, ++category_iter) {
      (*category_iter)->data_ = (*cached_category_iter).data_;
    }
  }
}
コード例 #25
0
ファイル: Manager.cpp プロジェクト: Cyrill1/CASAL2
/**
 * Default Constructor
 */
Manager::Manager() {
  LOG_FINE() << "TimeStep Manager Constructor";
}
コード例 #26
0
void ProportionsMigrating::Execute() {
  LOG_TRACE();

  /**
   * Verify our cached partition and partition sizes are correct
   */
  auto cached_partition_iter  = cached_partition_->Begin();
  auto partition_iter         = partition_->Begin(); // vector<vector<partition::Category> >

  /**
   * Loop through the provided categories. Each provided category (combination) will have a list of observations
   * with it. We need to build a vector of proportions for each age using that combination and then
   * compare it to the observations.
   */
  LOG_FINEST() << "Number of categories " << category_labels_.size();
  for (unsigned category_offset = 0; category_offset < category_labels_.size(); ++category_offset, ++partition_iter, ++cached_partition_iter) {
    Double      start_value        = 0.0;
    Double      end_value          = 0.0;


    vector<Double> expected_values(age_spread_, 0.0);
    vector<Double> numbers_age_before((model_->age_spread() + 1), 0.0);
    vector<Double> numbers_age_after((model_->age_spread() + 1), 0.0);

    /**
     * Loop through the 2 combined categories building up the
     * expected proportions values.
     */
    auto category_iter = partition_iter->begin();
    auto cached_category_iter = cached_partition_iter->begin();
    for (; category_iter != partition_iter->end(); ++cached_category_iter, ++category_iter) {
      for (unsigned data_offset = 0; data_offset < (*category_iter)->data_.size(); ++data_offset) {
        // We now need to loop through all ages to apply ageing misclassification matrix to account
        // for ages older than max_age_ that could be classified as an individual within the observation range
        unsigned age = ( (*category_iter)->min_age_ + data_offset);

        start_value   = (*cached_category_iter).data_[data_offset];
        end_value     = (*category_iter)->data_[data_offset];

        numbers_age_before[data_offset] += start_value;
        numbers_age_after[data_offset] += end_value;

        LOG_FINE() << "----------";
        LOG_FINE() << "Category: " << (*category_iter)->name_ << " at age " << age;
        LOG_FINE() << "start_value: " << start_value << "; end_value: " << end_value;
      }
    }

    /*
    *  Apply Ageing error on numbers at age before and after
    */
    if (ageing_error_label_ != "") {
      vector<vector<Double>>& mis_matrix = ageing_error_->mis_matrix();
      vector<Double> temp_before(numbers_age_before.size(), 0.0);
      vector<Double> temp_after(numbers_age_after.size(), 0.0);

      for (unsigned i = 0; i < mis_matrix.size(); ++i) {
        for (unsigned j = 0; j < mis_matrix[i].size(); ++j) {
          temp_before[j] += numbers_age_before[i] * mis_matrix[i][j];
          temp_after[j] += numbers_age_after[i] * mis_matrix[i][j];
        }
      }
      numbers_age_before = temp_before;
      numbers_age_after = temp_after;
    }


    /*
     *  Now collapse the number_age into out expected values
     */
    Double plus_before = 0, plus_after = 0;
    for (unsigned k = 0; k < numbers_age_before.size(); ++k) {
      // this is the difference between the
      unsigned age_offset = min_age_ - model_->min_age();
      if (numbers_age_before[k] > 0) {
        if (k >= age_offset && (k - age_offset + min_age_) <= max_age_) {
          expected_values[k - age_offset] = (numbers_age_before[k] - numbers_age_after[k]) / numbers_age_before[k];
          LOG_FINEST() << "Numbers before migration = " << numbers_age_before[k] << " numbers after migration = " << numbers_age_after[k]
                   << " proportion migrated = " <<   expected_values[k - age_offset];
        }
        if (((k - age_offset + min_age_) > max_age_) && age_plus_) {
          plus_before += numbers_age_before[k];
          plus_after += numbers_age_after[k];
        }
      } else {
          if (k >= age_offset && (k - age_offset + min_age_) <= max_age_)
            expected_values[k] = 0;
          if (((k - age_offset + min_age_) > max_age_) && age_plus_) {
            plus_before += 0;
            plus_after += 0;
          }
      }
    }
    LOG_FINEST() << "Plus group before migration = " << plus_before << " Plus group after migration = " << plus_after;
    if (age_plus_)
      expected_values[age_spread_ - 1] = (plus_before - plus_after) / plus_before;


    if (expected_values.size() != proportions_[model_->current_year()][category_labels_[category_offset]].size())
      LOG_CODE_ERROR() << "expected_values.size(" << expected_values.size() << ") != proportions_[category_offset].size("
        << proportions_[model_->current_year()][category_labels_[category_offset]].size() << ")";

    /**
     * save our comparisons so we can use them to generate the score from the likelihoods later
     */

    for (unsigned i = 0; i < expected_values.size(); ++i) {
      LOG_FINEST() << " Numbers at age " << min_age_ + i << " = " << expected_values[i];
      SaveComparison(category_labels_[category_offset], min_age_ + i ,0.0 ,expected_values[i], proportions_[model_->current_year()][category_labels_[category_offset]][i],
          process_errors_by_year_[model_->current_year()], error_values_[model_->current_year()][category_labels_[category_offset]][i], delta_, 0.0);
    }
  }
}