Пример #1
0
void Estimate::Build() {
  if (*target_ < lower_bound_)
    LOG_ERROR() << location() <<  "the initial value(" << AS_DOUBLE((*target_)) << ") on the estimate " << parameter_
        << " is lower than the lower_bound(" << lower_bound_ << ")";
  if (*target_ > upper_bound_)
    LOG_ERROR() << location() << "the initial value(" << AS_DOUBLE((*target_)) << ") on the estimate " << parameter_
        << " is greater than the upper_bound(" << upper_bound_ << ")";

  Reset();
}
Double DoubleNormal::GetLengthBasedResult(unsigned age, AgeLength* age_length, unsigned year, int time_step_index) {
  LOG_TRACE();
  unsigned yearx = year == 0 ? model_->current_year() : year;
  unsigned time_step = time_step_index == -1 ? model_->managers().time_step()->current_time_step() : (unsigned)time_step_index;
  Double cv = age_length->cv(yearx, time_step, age);
  Double mean = age_length->mean_length(time_step, age);
  string dist = age_length->distribution_label();

  if (dist == PARAM_NONE || n_quant_ <= 1) {

    if (mean < mu_)
      return pow(2.0, -((mean - mu_) / sigma_l_ * (mean - mu_) / sigma_l_)) * alpha_;
    else
      return  pow(2.0, -((mean - mu_)/sigma_r_ * (mean - mu_) / sigma_r_)) * alpha_;

  } else if (dist == PARAM_NORMAL) {

    Double sigma = cv * mean;
    Double size = 0.0;
    Double total = 0.0;

    for (unsigned j = 0; j < n_quant_; ++j) {
      size = mean + sigma * quantiles_at_[j];

      if (size < mu_)
        total +=  pow(2.0, -((size - mu_) / sigma_l_ * (size - mu_) / sigma_l_)) * alpha_;
      else
        total +=   pow(2.0, -((size - mu_)/sigma_r_ * (size - mu_) / sigma_r_)) * alpha_;
    }
    return total / n_quant_;

  } else if (dist == PARAM_LOGNORMAL) {
    // convert paramters to log space
    Double sigma = sqrt(log(1 + cv * cv));
    Double mu = log(mean) - sigma * sigma * 0.5;
    Double size = 0.0;
    Double total = 0.0;
    boost::math::lognormal dist{AS_DOUBLE(mu), AS_DOUBLE(sigma)};

    for (unsigned j = 0; j < n_quant_; ++j) {
      size = mu + sigma * quantile(dist, AS_DOUBLE(quantiles_[j]));

      if (size < mu_)
        total +=  pow(2.0, -((size - mu_) / sigma_l_ * (size - mu_) / sigma_l_)) * alpha_;
      else
        total +=   pow(2.0, -((size - mu_)/sigma_r_ * (size - mu_) / sigma_r_)) * alpha_;
    }
    return total / n_quant_;
  }
  LOG_CODE_ERROR() << "dist is invalid " << dist;
  return 0;
}
Пример #3
0
/**
 * Validate our Mortality Constant Rate process
 *
 * - Validate the required parameters
 * - Assign the label from the parameters
 * - Assign and validate remaining parameters
 * - Duplicate 'm' and 'selectivities' if only 1 vale specified
 * - Check m is between 0.0 and 1.0
 * - Check the categories are real
 */
void TagLoss::DoValidate() {
  LOG_FINEST() << "Number of categories = " << category_labels_.size() << " number of proportions given = " << tag_loss_input_.size();

  if (tag_loss_input_.size() == 1)
    tag_loss_input_.assign(category_labels_.size(), tag_loss_input_[0]);
  if (selectivity_names_.size() == 1)
    selectivity_names_.assign(category_labels_.size(), selectivity_names_[0]);

  if (tag_loss_input_.size() != category_labels_.size()) {
    LOG_ERROR_P(PARAM_TAG_LOSS_RATE)
        << ": Number of tag loss values provided is not the same as the number of categories provided. Expected: "
        << category_labels_.size()<< " but got " << tag_loss_input_.size();
  }

  if (selectivity_names_.size() != category_labels_.size()) {
    LOG_ERROR_P(PARAM_SELECTIVITIES)
        << ": Number of selectivities provided is not the same as the number of categories provided. Expected: "
        << category_labels_.size()<< " but got " << selectivity_names_.size();
  }

  // Validate type of tag loss
  if (tag_loss_type_ != "single")
    LOG_ERROR_P(PARAM_TAG_LOSS_TYPE) << tag_loss_type_ << " Is not an expected type. Values allowed are " << PARAM_SINGLE << " and " << PARAM_DOUBLE << " is coming soon";

  if (tag_loss_type_ == PARAM_DOUBLE)
    LOG_ERROR() << PARAM_TAG_LOSS_TYPE << " " << PARAM_DOUBLE << " is not implemented yet";
  // Validate our Ms are between 1.0 and 0.0
  for (Double tag_loss : tag_loss_input_) {
    if (tag_loss < 0.0 || tag_loss > 1.0)
      LOG_ERROR_P(PARAM_TAG_LOSS_RATE) << ": m value " << AS_DOUBLE(tag_loss) << " must be between 0.0 and 1.0 (inclusive)";
  }

  for (unsigned i = 0; i < tag_loss_input_.size(); ++i)
    tag_loss_[category_labels_[i]] = tag_loss_input_[i];
}
Пример #4
0
/**
 * Validate our Survival Constant Rate process
 *
 * - Validate the required parameters
 * - Assign the label from the parameters
 * - Assign and validate remaining parameters
 * - Duplicate 's' and 'selectivities' if only 1 vale specified
 * - Check s is between 0.0 and 1.0
 * - Check the categories are real
 */
void SurvivalConstantRate::DoValidate() {
  category_labels_ = model_->categories()->ExpandLabels(category_labels_, parameters_.Get(PARAM_CATEGORIES));

  if (s_input_.size() == 1)
    s_input_.assign(category_labels_.size(), s_input_[0]);
  if (selectivity_names_.size() == 1)
    selectivity_names_.assign(category_labels_.size(), selectivity_names_[0]);

  if (s_input_.size() != category_labels_.size()) {
    LOG_ERROR_P(PARAM_S)
        << ": Number of Ms provided is not the same as the number of categories provided. Expected: "
        << category_labels_.size()<< " but got " << s_input_.size();
  }

  if (selectivity_names_.size() != category_labels_.size()) {
    LOG_ERROR_P(PARAM_SELECTIVITIES)
        << ": Number of selectivities provided is not the same as the number of categories provided. Expected: "
        << category_labels_.size()<< " but got " << selectivity_names_.size();
  }

  // Validate our Ms are between 1.0 and 0.0
  for (Double s : s_input_) {
    if (s < 0.0 || s > 1.0)
      LOG_ERROR_P(PARAM_S) << ": m value " << AS_DOUBLE(s) << " must be between 0.0 and 1.0 (inclusive)";
  }

  for (unsigned i = 0; i < s_input_.size(); ++i)
    m_[category_labels_[i]] = s_input_[i];

  // Check categories are real
  for (const string& label : category_labels_) {
    if (!model_->categories()->IsValid(label))
      LOG_ERROR_P(PARAM_CATEGORIES) << ": category " << label << " does not exist. Have you defined it?";
  }
}
Пример #5
0
/**
 * Execute this report.
 */
void EstimateValue::DoExecute() {
  LOG_TRACE();
  vector<Estimate*> estimates = model_->managers().estimate()->objects();
  vector<Profile*> profiles = model_->managers().profile()->objects();

  if (estimates.size() > 0) {
    /**
     * if this is the first run we print the report header etc
     */
    if (first_run_) {
      LOG_FINEST() << "first run of estimate_value report";
      first_run_ = false;
      if (!skip_tags_) {
        cache_ << "*" << label_ << " " << "(" << type_ << ")" << "\n";
        cache_ << "values " << REPORT_R_DATAFRAME << "\n";
      }
      for (Estimate* estimate : estimates)
        cache_ << estimate->parameter() << " ";
      cache_ << "\n";
      LOG_FINEST() << "Number of estimates reporting on = " << estimates.size();
      for (Estimate* estimate : estimates)
        cache_ << AS_DOUBLE(estimate->value()) << " ";
      cache_ << "\n";

    } else {

      if (model_->run_mode() == RunMode::kProfiling) {
        cache_ << "*" << label_ << " " << "(" << type_ << ")" << "\n";
        cache_ << "values " << REPORT_R_DATAFRAME << "\n";
        for (Estimate* estimate : estimates)
          cache_ << estimate->parameter() << " ";
        cache_ << "\n";
        for (Estimate* estimate : estimates)
          cache_ << AS_DOUBLE(estimate->value()) << " ";
      } else {
        LOG_FINEST() << "Number of estimates reporting on = "
            << estimates.size();
        for (Estimate* estimate : estimates)
          cache_ << AS_DOUBLE(estimate->value()) << " ";
      }
      cache_ << "\n";
    }

    ready_for_writing_ = true;
  }
}
Пример #6
0
/**
 * 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;
    }
  }
}
Пример #7
0
/**
 * This method will execute our estimate summary report
 */
void EstimateSummary::DoExecute() {


  // Print the estimates
  niwa::estimates::Manager& estimate_manager = *model_->managers().estimate();
  vector<Estimate*> estimates = estimate_manager.objects();

  /*
  // Header
  cache_ << CONFIG_ARRAY_START << label_ << CONFIG_ARRAY_END << "\n";
  //  cout << PARAM_REPORT << "." << PARAM_TYPE << CONFIG_RATIO_SEPARATOR << " " << parameters_.Get(PARAM_TYPE)->GetValue<string>() << "\n";

  for (EstimatePtr estimate : estimates) {
    cache_ << "\n";
    if (estimate->label() != "") {
      cache_ << "Estimate: " << estimate->label() << " (" << estimate->parameter() << ")\n";
      cache_ << "Parameter: " << estimate->parameter() << "\n";
    } else
      cache_ << "Estimate: " << estimate->parameter() << "\n";
    cache_ << "Lower Bound: " << estimate->lower_bound() << "\n";
    cache_ << "Upper Bound: " << estimate->upper_bound() << "\n";
    cache_ << "Value: " << AS_DOUBLE(estimate->value()) << "\n";
    cache_ << "parameters:\n";
    map<string, ParameterPtr> parameters = estimate->parameters().parameters();
    for (auto iter = parameters.begin(); iter != parameters.end(); ++iter) {
      cache_ << iter->first << ": ";
      for (string parameter_value : iter->second->values())
        cache_ << parameter_value << " ";
      cache_ << "\n";
    }
  }
  cache_ << CONFIG_END_REPORT << "\n" << endl;
  */

  cache_ << "*" << label_ << " " << "("<< type_ << ")"<<"\n";
  for (Estimate* estimate : estimates) {
	cache_ << estimate->parameter() << " " << REPORT_R_LIST << "\n";
 //   cache_ << "label: " << estimate->label() << "\n";
    cache_ << "lower_bound: " << estimate->lower_bound() << "\n";
    cache_ << "upper_bound: " << estimate->upper_bound() << "\n";
    cache_ << "value: " << AS_DOUBLE(estimate->value()) << "\n";
    map<string, Parameter*> parameters = estimate->parameters().parameters();
    for (auto iter = parameters.begin(); iter != parameters.end(); ++iter) {
      cache_ << iter->first << ": ";
      for (string parameter_value : iter->second->values())
        cache_ << parameter_value << " ";
      cache_ << "\n";
    }
    cache_ << REPORT_R_LIST_END << "\n\n";
  }


  ready_for_writing_ = true;
}
Пример #8
0
/**
 * Validate this selectivity. This will load the
 * values that were passed in from the configuration
 * file and assign them to the local variables.
 *
 * We'll then do some basic checks on the local
 * variables to ensure they are within the business
 * rules for the model.
 */
void Increasing::DoValidate() {

  if (alpha_ <= 0.0)
    LOG_ERROR_P(PARAM_ALPHA) << ": alpha (" << AS_DOUBLE(alpha_) << ") cannot be less than or equal to 0.0";

  if (high_ <= low_)
    LOG_ERROR_P(PARAM_H) << ": 'h' (" << high_ << ") cannot be less than or the same as 'l' (" << low_ << ")";

  for (unsigned i = 0; i < v_.size(); ++i) {
    if (v_[i] < 0.0 || v_[i] > 1.0) {
      LOG_ERROR_P(PARAM_V) << " 'v' element " << i + 1 << " (" << AS_DOUBLE(v_[i]) << ") is not between 0.0 and 1.0";
    }
  }

  if (model_->partition_type() == PartitionType::kAge) {
    if (low_ < model_->min_age() || low_ > model_->max_age())
      LOG_ERROR_P(PARAM_L) << ": 'l' (" << low_ << ") must be between the model min_age (" << model_->min_age() << ") and max_age (" << model_->max_age() << ")";

    if (v_.size() != (high_ - low_ + 1)) {
      LOG_ERROR_P(PARAM_V) << " 'v' has incorrect amount of elements\n"
          << "Expected: " << (high_ - low_ + 1) << " but got " << v_.size();
    }
  }   else if (model_->partition_type() == PartitionType::kLength) {
    vector<unsigned> length_bins = model_->length_bins();
    if (low_ < length_bins[0] || low_ > length_bins[length_bins.size()-1])
      LOG_ERROR_P(PARAM_L) << ": 'l' (" << low_ << ") must be between the model min length (" << length_bins[0] << ") and max length (" << length_bins[length_bins.size()-1] << ")";
    unsigned bins = 0;
    for (unsigned i = 0; i < length_bins.size(); ++i) {
      if (length_bins[i] >= low_ && length_bins[i] <= high_)
        ++bins;
    }
    if (bins != v_.size()) {
      LOG_ERROR_P(PARAM_V) << ": Parameter 'v' does not have the right amount of elements n = low <= length_bins <= high, "
          << "Expected " << bins << " but got " << v_.size();
    }
  }




}
Пример #9
0
void MortalityEventBiomass::DoExecute() {
  if (catch_years_[model_->current_year()] == 0)
    return;

  LOG_TRACE();

  /**
   * Work our how much of the stock is vulnerable
   */
  Double vulnerable = 0.0;
  unsigned i = 0;
  for (auto categories : partition_) {
    categories->UpdateMeanWeightData();
    unsigned offset = 0;
    for (Double& data : categories->data_) {
      Double temp = data * selectivities_[i]->GetResult(categories->min_age_ + offset, categories->age_length_);
      vulnerable += temp * categories->mean_weight_per_[categories->min_age_ + offset];
      ++offset;
    }

    ++i;
  }

  /**
   * Work out the exploitation rate to remove (catch/vulnerable)
   */
  Double exploitation = catch_years_[model_->current_year()] / utilities::doublecompare::ZeroFun(vulnerable);
  if (exploitation > u_max_) {
    exploitation = u_max_;
    if (penalty_)
      penalty_->Trigger(label_, catch_years_[model_->current_year()], vulnerable * u_max_);

  } else if (exploitation < 0.0) {
    exploitation = 0.0;
  }

  LOG_FINEST() << "year: " << model_->current_year() << "; exploitation: " << AS_DOUBLE(exploitation);

  /**
   * Remove the stock now. The amount to remove is
   * vulnerable * exploitation
   */
  i = 0;
  for (auto categories : partition_) {
    unsigned offset = 0;
    for (Double& data : categories->data_) {
      data -= data * selectivities_[i]->GetResult(categories->min_age_ + offset, categories->age_length_) * exploitation;
      ++offset;
    }
    ++i;
  }
}
Пример #10
0
/**
 * Build our process proportions by category
 */
void ProcessProportionsByCategory::DoBuild() {
  ProportionsByCategory::DoBuild();

  if (process_proportion_ < 0.0 || process_proportion_ > 1.0)
    LOG_ERROR_P(PARAM_PROCESS_PROPORTION) << ": process_proportion (" << AS_DOUBLE(process_proportion_) << ") must be between 0.0 and 1.0";
  proportion_of_time_ = process_proportion_;

  auto time_step = model_->managers().time_step()->GetTimeStep(time_step_label_);
  if (!time_step) {
    LOG_FATAL_P(PARAM_TIME_STEP) << time_step_label_ << " could not be found. Have you defined it?";
  } else {
    for (unsigned year : years_)
      time_step->SubscribeToProcess(this, year, process_label_);
  }
}
Пример #11
0
void TimeStepAbundance::DoBuild() {
    Abundance::DoBuild();

    if (time_step_proportion_ < 0.0 || time_step_proportion_ > 1.0)
        LOG_ERROR_P(PARAM_TIME_STEP_PROPORTION) << ": time_step_proportion (" << AS_DOUBLE(time_step_proportion_) << ") must be between 0.0 and 1.0";
    proportion_of_time_ = time_step_proportion_;

    auto time_step = model_->managers().time_step()->GetTimeStep(time_step_label_);
    if (!time_step) {
        LOG_ERROR_P(PARAM_TIME_STEP) << time_step_label_ << " could not be found. Have you defined it?";
    } else {
        for (unsigned year : years_)
            time_step->SubscribeToBlock(this, year);
    }
}
Пример #12
0
void Selectivity::Validate() {
  parameters_.Populate();
  DoValidate();

  if (length_based_) {
    boost::math::normal dist{ };

    for (unsigned i = 1; i <= n_quant_; ++i) {
      quantiles_.push_back((Double(i) - 0.5) / Double(n_quant_));
      LOG_FINEST() << ": Quantile value = " << quantiles_[i - 1];
      quantiles_at_.push_back(quantile(dist, AS_DOUBLE(quantiles_[i - 1])));
      LOG_FINEST() << ": Normal quantile value = " << quantiles_at_[i - 1];
    }
  }
}
Пример #13
0
/**
 *  Execute the report in tabular format
 */
void EstimateValue::DoExecuteTabular() {
  vector<Estimate*> estimates = model_->managers().estimate()->objects();
  /**
   * if this is the first run we print the report header etc
   */
  if (first_run_) {
    first_run_ = false;
    cache_ << "*" << label_ << " " << "(" << type_ << ")" << "\n";
    cache_ << "values " << REPORT_R_DATAFRAME << "\n";
    for (Estimate* estimate : estimates)
      cache_ << estimate->parameter() << " ";
    cache_ << "\n";
  }

  for (Estimate* estimate : estimates)
    cache_ << AS_DOUBLE(estimate->value()) << " ";
  cache_ <<"\n" ;
}
Пример #14
0
void Partition::DoExecute() {
  //cerr << "execute " << label_ << "\n";
  // First, figure out the lowest and highest ages/length
  unsigned lowest         = 9999;
  unsigned highest        = 0;
  unsigned longest_length = 0;

  niwa::partition::accessors::All all_view(model_);
  for (auto iterator = all_view.Begin(); iterator != all_view.End(); ++iterator) {
    if (lowest > (*iterator)->min_age_)
      lowest = (*iterator)->min_age_;
    if (highest < (*iterator)->max_age_)
      highest = (*iterator)->max_age_;
    if (longest_length < (*iterator)->name_.length())
      longest_length = (*iterator)->name_.length();
  }

  // Print the header
  cache_ << "*"<< type_ << "[" << label_ << "]" << "\n";
  cache_ << "year: " << model_->current_year() << "\n";
  cache_ << "time_step: " << time_step_ << "\n";
  cache_ << "values "<< REPORT_R_DATAFRAME<<"\n";
  cache_ << "category";
  for (unsigned i = lowest; i <= highest; ++i)
    cache_ << " " << i;
  cache_ << "\n";

  for (auto iterator = all_view.Begin(); iterator != all_view.End(); ++iterator) {
    cache_ << (*iterator)->name_;
    unsigned age = (*iterator)->min_age_;
    for (auto values = (*iterator)->data_.begin(); values != (*iterator)->data_.end(); ++values, age++) {
      if (age >= lowest && age <= highest) {
        Double value = *values;
        cache_ << " " << std::fixed << AS_DOUBLE(value);
      } else
        cache_ << " " << "null";
    }
    cache_ << "\n";
  }
  ready_for_writing_ = true;
}
/**
 * Execute this report.
 */
void EstimateValue::DoExecute() {
  vector<Estimate*> estimates = model_->managers().estimate()->objects();
  vector<Profile*> profiles = model_->managers().profile()->objects();
  LOG_TRACE();
  // Check if estiamtes are close to bounds. flag a warning.
  for (Estimate* estimate : estimates) {
    if ((estimate->value() - estimate->lower_bound()) < 0.001 || (estimate->upper_bound() - estimate->value()) < 0.001)
      LOG_WARNING() << "estimated parameter '" <<  estimate->parameter() << "' was within 0.001 of its bound";
  }

  if (estimates.size() > 0) {
    cache_ << "*"<< type_ << "[" << label_ << "]" << "\n";
    cache_ << "values " << REPORT_R_DATAFRAME << "\n";
    for (Estimate* estimate : estimates)
      cache_ << estimate->parameter() << " ";
    cache_ << "\n";
    for (Estimate* estimate : estimates)
      cache_ << AS_DOUBLE(estimate->value()) << " ";
    cache_ << "\n";
    ready_for_writing_ = true;
  }
}
/**
 * Validate configuration file parameters
 */
void ProcessRemovalsByLength::DoValidate() {
  // How many elements are expected in our observed table;
  if (length_plus_) {
    number_bins_ = length_bins_.size();
  } else {
    number_bins_ = length_bins_.size() - 1;
  }
  for (auto year : years_) {
    if ((year < model_->start_year()) || (year > model_->final_year()))
      LOG_ERROR_P(PARAM_YEARS) << "Years can't be less than start_year (" << model_->start_year() << "), or greater than final_year (" << model_->final_year() << "). Please fix this.";
  }

  map<unsigned, vector<Double>> error_values_by_year;
  map<unsigned, vector<Double>> obs_by_year;

  /**
   * Do some simple checks
   * e.g Validate that the length_bins are strictly increasing
   */
  for (unsigned length = 0; length < length_bins_.size(); ++length) {
    if (length_bins_[length] < 0.0)
      if (length_bins_[length] > length_bins_[length + 1])
        LOG_ERROR_P(PARAM_LENGTH_BINS) << ": Length bins must be strictly increasing " << length_bins_[length] << " is greater than " << length_bins_[length + 1];
  }

  if (process_error_values_.size() != 0 && process_error_values_.size() != years_.size()) {
    LOG_ERROR_P(PARAM_PROCESS_ERRORS) << " number of values provied (" << process_error_values_.size() << ") does not match the number of years provided (" << years_.size() << ")";
  }
  for (Double process_error : process_error_values_) {
    if (process_error < 0.0)
      LOG_ERROR_P(PARAM_PROCESS_ERRORS) << ": process_error (" << AS_DOUBLE(process_error) << ") cannot be less than 0.0";
  }
  if (process_error_values_.size() != 0)
    process_errors_by_year_ = utilities::Map::create(years_, process_error_values_);
  if (delta_ < 0.0)
    LOG_ERROR_P(PARAM_DELTA) << ": delta (" << AS_DOUBLE(delta_) << ") cannot be less than 0.0";

  /**
   * Validate the number of obs provided matches age spread * category_labels * years
   * This is because we'll have 1 set of obs per category collection provided.
   * categories male+female male = 2 collections
   */
  unsigned obs_expected = number_bins_ * category_labels_.size() + 1;
  vector<vector<string>>& obs_data = obs_table_->data();
  if (obs_data.size() != years_.size()) {
    LOG_ERROR_P(PARAM_OBS) << " has " << obs_data.size() << " rows defined, but we expected " << years_.size() << " to match the number of years provided";
  }

  for (vector<string>& obs_data_line : obs_data) {
    if (obs_data_line.size() != obs_expected) {
      LOG_ERROR_P(PARAM_OBS) << " has " << obs_data_line.size() << " values defined, but we expected " << obs_expected << " to match the number bins * categories + 1 (for year)";
    }

    unsigned year = 0;
    if (!utilities::To<unsigned>(obs_data_line[0], year))
      LOG_ERROR_P(PARAM_OBS) << " value " << obs_data_line[0] << " could not be converted in to an unsigned integer. It should be the year for this line";
    if (std::find(years_.begin(), years_.end(), year) == years_.end())
      LOG_ERROR_P(PARAM_OBS) << " value " << year << " is not a valid year for this observation";

    for (unsigned i = 1; i < obs_data_line.size(); ++i) {
      Double value = 0;
      if (!utilities::To<Double>(obs_data_line[i], value))
        LOG_ERROR_P(PARAM_OBS) << " value (" << obs_data_line[i] << ") could not be converted to a double";
      obs_by_year[year].push_back(value);
    }
    if (obs_by_year[year].size() != obs_expected - 1)
      LOG_FATAL_P(PARAM_OBS)<< "you supplied " << obs_by_year[year].size() << " lengths, but we expected " << obs_expected -1 << " can you please sort this out. Chairs";
    }

    /**
     * Build our error value map
     */
  vector<vector<string>>& error_values_data = error_values_table_->data();
  if (error_values_data.size() != years_.size()) {
    LOG_FATAL_P(PARAM_ERROR_VALUES)<< " has " << error_values_data.size() << " rows defined, but we expected " << years_.size()
    << " to match the number of years provided";
  }

  for (vector<string>& error_values_data_line : error_values_data) {
    if (error_values_data_line.size() != 2 && error_values_data_line.size() != obs_expected) {
      LOG_ERROR_P(PARAM_ERROR_VALUES) << " has " << error_values_data_line.size() << " values defined, but we expected " << obs_expected << " to match the number bins * categories + 1 (for year)";
    }

    unsigned year = 0;
    if (!utilities::To<unsigned>(error_values_data_line[0], year))
      LOG_FATAL_P(PARAM_ERROR_VALUES)<< " value " << error_values_data_line[0] << " could not be converted in to an unsigned integer. It should be the year for this line";
    if (std::find(years_.begin(), years_.end(), year) == years_.end())
      LOG_FATAL_P(PARAM_ERROR_VALUES)<< " value " << year << " is not a valid year for this observation";
    for (unsigned i = 1; i < error_values_data_line.size(); ++i) {
      Double value = 0;

      if (!utilities::To<Double>(error_values_data_line[i], value))
        LOG_FATAL_P(PARAM_ERROR_VALUES)<< " value (" << error_values_data_line[i] << ") could not be converted to a double";
      if (likelihood_type_ == PARAM_LOGNORMAL && value <= 0.0) {
        LOG_ERROR_P(PARAM_ERROR_VALUES) << ": error_value (" << AS_DOUBLE(value) << ") cannot be equal to or less than 0.0";
      } else if (likelihood_type_ == PARAM_MULTINOMIAL && value < 0.0) {
        LOG_ERROR_P(PARAM_ERROR_VALUES) << ": error_value (" << AS_DOUBLE(value) << ") cannot be less than 0.0";
      }

      error_values_by_year[year].push_back(value);
    }
    if (error_values_by_year[year].size() == 1) {
      error_values_by_year[year].assign(obs_expected - 1, error_values_by_year[year][0]);
    }
    if (error_values_by_year[year].size() != obs_expected - 1)
      LOG_FATAL_P(PARAM_ERROR_VALUES)<< "We counted " << error_values_by_year[year].size() << " error values by year but expected " << obs_expected -1 << " based on the obs table";
    }

    /**
     * Build our proportions and error values for use in the observation
     * If the proportions for a given observation do not sum to 1.0
     * and is off by more than the tolerance rescale them.
     */
  Double value = 0.0;
  for (auto iter = obs_by_year.begin(); iter != obs_by_year.end(); ++iter) {
    Double total = 0.0;

    for (unsigned i = 0; i < category_labels_.size(); ++i) {
      for (unsigned j = 0; j < number_bins_; ++j) {
        unsigned obs_index = i * number_bins_ + j;
        value = iter->second[obs_index];

        Double error_value = error_values_by_year[iter->first][obs_index];
        error_values_[iter->first][category_labels_[i]].push_back(error_value);
        proportions_[iter->first][category_labels_[i]].push_back(value);
        total += value;
      }
    }

    if (fabs(1.0 - total) > tolerance_) {
      LOG_ERROR_P(PARAM_OBS) << ": obs sum total (" << total << ") for year (" << iter->first << ") exceeds tolerance (" << tolerance_ << ") from 1.0";
    }
  }
}
/**
 * Execute our mortality event object.
 *
 */
void MortalityInitialisationEventBiomass::DoExecute() {
  LOG_TRACE();
  unsigned time_step_index = model_->managers().time_step()->current_time_step();

  // only apply if initialisation phase
  if (model_->state() == State::kInitialise) {
    /**
     * Work our how much of the stock is available or vulnerable to exploit
     */
    Double vulnerable = 0.0;
    unsigned i = 0;
    for (auto categories : partition_) {
      unsigned j = 0;
      //categories->UpdateMeanWeightData();
      for (Double& data : categories->data_) {
        Double temp = data * selectivities_[i]->GetAgeResult(categories->min_age_ + j, categories->age_length_);
        vulnerable += temp * categories->mean_weight_by_time_step_age_[time_step_index][categories->min_age_ + j];
        ++j;
      }
      ++i;
    }
    /**
     * Work out the exploitation rate to remove (catch/vulnerable)
     */
    Double exploitation = 0;
    LOG_FINEST() << "vulnerable biomass = " << vulnerable << " catch = " << catch_;
    exploitation = catch_ / utilities::doublecompare::ZeroFun(vulnerable);
    if (exploitation > u_max_) {
      exploitation = u_max_;
      if (penalty_)
        penalty_->Trigger(label_, catch_, vulnerable*u_max_);

    } else if (exploitation < 0.0) {
      exploitation = 0.0;
    }
    LOG_FINEST() << "; exploitation: " << AS_DOUBLE(exploitation);

    /**
     * Remove the stock now. The amount to remove is
     * vulnerable * exploitation
     */
    // Report catches and exploitation rates for each category for each iteration
/*
    StoreForReport("initialisation_iteration: ", init_iteration_);
    StoreForReport("Exploitation: ", AS_DOUBLE(exploitation));
    StoreForReport("Catch: ", AS_DOUBLE(catch_));
*/
    Double removals =0;
    for (auto categories : partition_) {
      unsigned offset = 0;
      for (Double& data : categories->data_) {
        // report
        removals = vulnerable_[categories->name_][categories->min_age_ + offset] * exploitation;
        //StoreForReport(categories->name_ + "_Removals: ", AS_DOUBLE(removals));
        data -= removals;
        offset++;
      }
    }
    ++init_iteration_;
  }
}
/**
 * Validate our Mortality Event Process
 *
 * 1. Check for the required parameters
 * 2. Assign any remaining variables
 */
void MortalityInitialisationEventBiomass::DoValidate() {
  // Validate that the number of selectivities is the same as the number of categories
  if (category_labels_.size() != selectivity_names_.size()) {
    LOG_ERROR_P(PARAM_SELECTIVITIES)
        << " Number of selectivities provided does not match the number of categories provided."
        << " Expected " << category_labels_.size() << " but got " << selectivity_names_.size();
  }

  // Validate u_max
  if (u_max_ < 0.0 || u_max_ > 1.0)
    LOG_ERROR_P(PARAM_U_MAX) << ": u_max must be between 0.0 and 1.0 (inclusive). Value defined was " << AS_DOUBLE(u_max_);
}
Пример #19
0
/**
 * Validate this selectivity. This will load the
 * values that were passed in from the configuration
 * file and assign them to the local variables.
 *
 * We'll then do some basic checks on the local
 * variables to ensure they are within the business
 * rules for the model.
 */
void LogisticProducing::DoValidate() {
  if (alpha_ <= 0.0)
    LOG_ERROR_P(PARAM_ALPHA) << ": alpha (" << AS_DOUBLE(alpha_) << ") cannot be less than or equal to 0.0";
  if (ato95_ <= 0.0)
    LOG_ERROR_P(PARAM_ATO95) << ": ato95 (" << AS_DOUBLE(ato95_) << ") cannot be less than or equal to 0.0";
}
Пример #20
0
/**
 * Validate configuration file parameters
 */
void ProportionsMigrating::DoValidate() {
  age_spread_ = (max_age_ - min_age_) + 1;
  map<unsigned, vector<Double>> error_values_by_year;
  map<unsigned, vector<Double>> obs_by_year;

  /**
   * Do some simple checks
   */
  if (min_age_ < model_->min_age())
    LOG_ERROR_P(PARAM_MIN_AGE) << ": min_age (" << min_age_ << ") is less than the model's min_age (" << model_->min_age() << ")";
  if (max_age_ > model_->max_age())
    LOG_ERROR_P(PARAM_MAX_AGE) << ": max_age (" << max_age_ << ") is greater than the model's max_age (" << model_->max_age() << ")";
  if (process_error_values_.size() != 0 && process_error_values_.size() != years_.size()) {
    LOG_ERROR_P(PARAM_PROCESS_ERRORS) << " number of values provied (" << process_error_values_.size() << ") does not match the number of years provided ("
        << years_.size() << ")";
  }
  for (Double process_error : process_error_values_) {
    if (process_error < 0.0)
      LOG_ERROR_P(PARAM_PROCESS_ERRORS) << ": process_error (" << AS_DOUBLE(process_error) << ") cannot be less than 0.0";
  }
  if (process_error_values_.size() != 0)
    process_errors_by_year_ = utilities::Map::create(years_, process_error_values_);
  if (delta_ < 0.0)
    LOG_ERROR_P(PARAM_DELTA) << ": delta (" << AS_DOUBLE(delta_) << ") cannot be less than 0.0";

  /**
   * Validate the number of obs provided matches age spread * category_labels * years
   * This is because we'll have 1 set of obs per category collection provided.
   * categories male+female male = 2 collections
   */
  unsigned obs_expected = age_spread_ * category_labels_.size() + 1;
  vector<vector<string>>& obs_data = obs_table_->data();
  if (obs_data.size() != years_.size()) {
    LOG_ERROR_P(PARAM_OBS) << " has " << obs_data.size() << " rows defined, but we expected " << years_.size()
        << " to match the number of years provided";
  }

  for (vector<string>& obs_data_line : obs_data) {
    if (obs_data_line.size() != obs_expected) {
      LOG_ERROR_P(PARAM_OBS) << " has " << obs_data_line.size() << " values defined, but we expected " << obs_expected
          << " to match the age speard * categories + 1 (for year)";
    }

    unsigned year = 0;
    if (!utilities::To<unsigned>(obs_data_line[0], year))
      LOG_ERROR_P(PARAM_OBS) << " value " << obs_data_line[0] << " could not be converted in to an unsigned integer. It should be the year for this line";
    if (std::find(years_.begin(), years_.end(), year) == years_.end())
      LOG_ERROR_P(PARAM_OBS) << " value " << year << " is not a valid year for this observation";

    for (unsigned i = 1; i < obs_data_line.size(); ++i) {
      Double value = 0;
      if (!utilities::To<Double>(obs_data_line[i], value))
        LOG_ERROR_P(PARAM_OBS) << " value (" << obs_data_line[i] << ") could not be converted to a double";
      obs_by_year[year].push_back(value);
    }
    if (obs_by_year[year].size() != obs_expected - 1)
      LOG_CODE_ERROR() << "obs_by_year_[year].size() (" << obs_by_year[year].size() << ") != obs_expected - 1 (" << obs_expected -1 << ")";
  }

  /**
   * Build our error value map
   */
  vector<vector<string>>& error_values_data = error_values_table_->data();
  if (error_values_data.size() != years_.size()) {
    LOG_ERROR_P(PARAM_ERROR_VALUES) << " has " << error_values_data.size() << " rows defined, but we expected " << years_.size()
        << " to match the number of years provided";
  }

  for (vector<string>& error_values_data_line : error_values_data) {
    if (error_values_data_line.size() != 2 && error_values_data_line.size() != obs_expected) {
      LOG_ERROR_P(PARAM_ERROR_VALUES) << " has " << error_values_data_line.size() << " values defined, but we expected " << obs_expected
          << " to match the age speard * categories + 1 (for year)";
    }

    unsigned year = 0;
    if (!utilities::To<unsigned>(error_values_data_line[0], year))
      LOG_ERROR_P(PARAM_ERROR_VALUES) << " value " << error_values_data_line[0] << " could not be converted in to an unsigned integer. It should be the year for this line";
    if (std::find(years_.begin(), years_.end(), year) == years_.end())
      LOG_ERROR_P(PARAM_ERROR_VALUES) << " value " << year << " is not a valid year for this observation";
    for (unsigned i = 1; i < error_values_data_line.size(); ++i) {
      Double value = 0;

      if (!utilities::To<Double>(error_values_data_line[i], value))
        LOG_ERROR_P(PARAM_ERROR_VALUES) << " value (" << error_values_data_line[i] << ") could not be converted to a double";
      if (likelihood_type_ == PARAM_LOGNORMAL && value <= 0.0) {
        LOG_ERROR_P(PARAM_ERROR_VALUES) << ": error_value (" << AS_DOUBLE(value) << ") cannot be equal to or less than 0.0";
      } else if ((likelihood_type_ == PARAM_MULTINOMIAL && value < 0.0) || (likelihood_type_ == PARAM_DIRICHLET && value < 0.0)) {
        LOG_ERROR_P(PARAM_ERROR_VALUES) << ": error_value (" << AS_DOUBLE(value) << ") cannot be less than 0.0";
      }

      error_values_by_year[year].push_back(value);
    }
    if (error_values_by_year[year].size() == 1) {
      error_values_by_year[year].assign(obs_expected - 1, error_values_by_year[year][0]);
    }
    if (error_values_by_year[year].size() != obs_expected - 1)
      LOG_CODE_ERROR() << "error_values_by_year_[year].size() (" << error_values_by_year[year].size() << ") != obs_expected - 1 (" << obs_expected -1 << ")";
  }

  /**
   * Validate likelihood type
   */
  if (likelihood_type_ != PARAM_LOGNORMAL && likelihood_type_ != PARAM_MULTINOMIAL && likelihood_type_ != PARAM_DIRICHLET)
    LOG_ERROR_P(PARAM_LIKELIHOOD) << ": likelihood " << likelihood_type_ << " is not supported by the proportions at age observation. "
        << "Supported types are " << PARAM_LOGNORMAL << ", " << PARAM_MULTINOMIAL << " and " << PARAM_DIRICHLET;

  /**
   * Build our proportions and error values for use in the observation
   * If the proportions for a given observation do not sum to 1.0
   * and is off by more than the tolerance rescale them.
   */
  Double value = 0.0;
  for (auto iter = obs_by_year.begin(); iter != obs_by_year.end(); ++iter) {

    for (unsigned i = 0; i < category_labels_.size(); ++i) {
      for (unsigned j = 0; j < age_spread_; ++j) {
        unsigned obs_index = i * age_spread_ + j;
        if (!utilities::To<Double>(iter->second[obs_index], value))
          LOG_ERROR_P(PARAM_OBS) << ": obs_ value (" << iter->second[obs_index] << ") at index " << obs_index + 1
              << " in the definition could not be converted to a numeric double";

        Double error_value = error_values_by_year[iter->first][obs_index];
        error_values_[iter->first][category_labels_[i]].push_back(error_value);
        proportions_[iter->first][category_labels_[i]].push_back(value);
      }
    }
  }
}
void Partition_YearCrossAgeMatrix::DoExecute() {
  //cerr << "execute " << label_ << "\n";
  // First, figure out the lowest and highest ages/length
  unsigned lowest = 9999;
  unsigned highest = 0;
  unsigned longest_length = 0;

  niwa::partition::accessors::All all_view(model_);

  for (auto iterator = all_view.Begin(); iterator != all_view.End();
      ++iterator) {
    if (lowest > (*iterator)->min_age_)
      lowest = (*iterator)->min_age_;
    if (highest < (*iterator)->max_age_)
      highest = (*iterator)->max_age_;
    if (longest_length < (*iterator)->name_.length())
      longest_length = (*iterator)->name_.length();

  }

  const char separator = ' ';
  //const int nameWidth = 6;
  const int numWidth = 13;

  //cache_ <<  std::setprecision(5);

  for (auto iterator = all_view.Begin(); iterator != all_view.End();
      ++iterator) {
    //cache_ << (*iterator)->name_;
    cache_ << std::left << std::setw(numWidth) << std::setfill(separator) << std::setprecision(1) << std::fixed << model_->current_year();
    unsigned age = (*iterator)->min_age_;
    //unsigned year = (*iterator)->year_;
    //cout << "The year at this stage is " << year << endl;
    for (auto values = (*iterator)->data_.begin();
        values != (*iterator)->data_.end(); ++values, age++) {
      if (age >= lowest && age <= highest) {
        Double value = *values;
        //cache_ << "\t" << std::fixed << AS_DOUBLE(value);
        cache_ << std::left << std::setw(numWidth) << std::setfill(separator) << std::setprecision(0) << std::fixed << AS_DOUBLE(value);
      } else
        cache_ << " " << "null";
    }
    cache_ << "\n";
  }
  //  ready_for_writing_ = true;
  ready_for_writing_ = false;
}
Пример #22
0
/**
 * Validate our Maturation Rate process
 *
 * - Check for the required parameters
 * - Assign variables from our parameters
 * - Verify the categories are real
 * - If proportions or selectivities only has 1 element specified
 *   add more elements until they match number of categories
 * - Verify vector lengths are all the same
 * - Verify categories From->To have matching age ranges
 * - Check all proportions are between 0.0 and 1.0
 */
void TransitionCategory::DoValidate() {
  LOG_TRACE();
  from_category_names_ = model_->categories()->ExpandLabels(from_category_names_, parameters_.Get(PARAM_FROM));
  to_category_names_ = model_->categories()->ExpandLabels(to_category_names_, parameters_.Get(PARAM_TO));

  if (selectivity_names_.size() == 1)
    selectivity_names_.assign(from_category_names_.size(), selectivity_names_[0]);

  // Validate Categories
  auto categories = model_->categories();
  for (const string& label : from_category_names_) {
    if (!categories->IsValid(label))
      LOG_ERROR_P(PARAM_FROM) << ": category " << label << " does not exist. Have you defined it?";
  }
  for(const string& label : to_category_names_) {
    if (!categories->IsValid(label))
      LOG_ERROR_P(PARAM_TO) << ": category " << label << " does not exist. Have you defined it?";
  }

  // Validate the from and to vectors are the same size
  if (from_category_names_.size() != to_category_names_.size()) {
    LOG_ERROR_P(PARAM_TO)
        << ": Number of 'to' categories provided does not match the number of 'from' categories provided."
        << " Expected " << from_category_names_.size() << " but got " << to_category_names_.size();
  }

  // Allow a one to many relationship between proportions and number of categories.
  if (proportions_.size() == 1)
    proportions_.resize(to_category_names_.size(),proportions_[0]);

  // Validate the to category and proportions vectors are the same size
  if (to_category_names_.size() != proportions_.size()) {
    LOG_ERROR_P(PARAM_PROPORTIONS)
        << ": Number of proportions provided does not match the number of 'to' categories provided."
        << " Expected " << to_category_names_.size() << " but got " << proportions_.size();
  }

  // Validate the number of selectivities matches the number of proportions
  if (proportions_.size() != selectivity_names_.size() && proportions_.size() != 1) {
    LOG_ERROR_P(PARAM_SELECTIVITIES)
        << ": Number of selectivities provided does not match the number of proportions provided."
        << " Expected " << proportions_.size() << " but got " << selectivity_names_.size();
  }

  // Validate that each from and to category have the same age range.
  for (unsigned i = 0; i < from_category_names_.size(); ++i) {
    if (categories->min_age(from_category_names_[i]) != categories->min_age(to_category_names_[i])) {
      LOG_ERROR_P(PARAM_FROM) << ": Category " << from_category_names_[i] << " does not"
          << " have the same age range as the 'to' category " << to_category_names_[i];
    }

    if (categories->max_age(from_category_names_[i]) != categories->max_age(to_category_names_[i])) {
      LOG_ERROR_P(PARAM_FROM) << ": Category " << from_category_names_[i] << " does not"
          << " have the same age range as the 'to' category " << to_category_names_[i];
    }
  }

  // Validate the proportions are between 0.0 and 1.0
  for (Double proportion : proportions_) {
    if (proportion < 0.0 || proportion > 1.0)
      LOG_ERROR_P(PARAM_PROPORTIONS) << ": proportion " << AS_DOUBLE(proportion) << " must be between 0.0 and 1.0 (inclusive)";
  }

  for (unsigned i = 0; i < from_category_names_.size(); ++i)
    proportions_by_category_[from_category_names_[i]] = proportions_[i];
}
Пример #23
0
/**
 * Execute/Run/Process the object.
 */
void ObjectiveFunction::Execute() {
  niwa::ObjectiveFunction& obj = model_->objective_function();
  if (abs(AS_DOUBLE(value_) - AS_DOUBLE(obj.score())) > 1e-9)
    LOG_ERROR() << "Assert Failure: Objective Function had actual value " << obj.score() << " when we expected " << value_
        << " with difference: " << abs(AS_DOUBLE(value_) - AS_DOUBLE(obj.score()));
}
/**
 * Calculate our score for the current run
 */
void ObjectiveFunction::CalculateScore() {
	LOG_TRACE();
  Clear();

  /**
   * Get the scores from each of the observations/likelihoods
   */
  vector<Observation*> observations = model_->managers().observation()->objects();
  likelihoods_ = 0.0;
  for(auto observation : observations) {
    const map<unsigned, Double>& scores = observation->scores();
    bool append_age = scores.size() > 1 ? true : false;
    for(auto iter = scores.begin(); iter != scores.end(); ++iter) {
      objective::Score new_score;
      new_score.label_ = PARAM_OBSERVATION + string("->") + observation->label();
      if (append_age)
        new_score.label_ += string("-") + utilities::ToInline<unsigned, string>(iter->first);
      new_score.score_ = iter->second;

      score_list_.push_back(new_score);
      score_ += new_score.score_;
      likelihoods_ += AS_DOUBLE(new_score.score_);
    }
  }

  /**
   * Get the scores from each of the penalties
   */
  penalties_ = 0.0;

  for (auto penalty : model_->managers().penalty()->objects()) {
    if (penalty->has_score()) {
      objective::Score new_score;

      new_score.label_ = PARAM_PENALTY + string("->") + penalty->label();
      new_score.score_ = penalty->GetScore();

      score_list_.push_back(new_score);
      score_ += new_score.score_;
      penalties_ += AS_DOUBLE(new_score.score_);
    }
  }

  /**
   * Go through the flagged penalties
   */
  const vector<penalties::Info>& penalties = model_->managers().penalty()->flagged_penalties();
  for (penalties::Info penalty : penalties) {
    objective::Score new_score;

    new_score.label_ = PARAM_PENALTY + string("->") + penalty.label_;
    new_score.score_ = penalty.score_;

    score_list_.push_back(new_score);
    score_ += new_score.score_;
    penalties_ += AS_DOUBLE(new_score.score_);
  }

  /**
   * Get the scores from each of the estimate priors
   */
  model_->managers().estimate_transformation()->TransformEstimatesForObjectiveFunction();
  vector<Estimate*> estimates = model_->managers().estimate()->objects();
  priors_ = 0.0;
  for (Estimate* estimate : estimates) {
    if (!estimate->in_objective_function())
      continue;
    objective::Score new_score;
    if (estimate->label() != "")
      new_score.label_ = PARAM_PRIOR + string("->") + estimate->label() + "->" + estimate->parameter();
    else
      new_score.label_ = PARAM_PRIOR + string("->") + estimate->parameter();
    new_score.score_ = estimate->GetScore();

    score_list_.push_back(new_score);
    score_ += new_score.score_;
    priors_ += AS_DOUBLE(new_score.score_);
  }
  model_->managers().estimate_transformation()->RestoreEstimatesFromObjectiveFunction();

  /**
   * Get the score from each additional prior
   */
  vector<AdditionalPrior*> additional_priors = model_->managers().additional_prior()->objects();
  additional_priors_ = 0.0;
  for (auto prior : additional_priors) {
    objective::Score new_score;
    new_score.label_ = PARAM_ADDITIONAL_PRIOR + string("->") + prior->label();
    new_score.score_ = prior->GetScore();

    score_list_.push_back(new_score);
    score_ += new_score.score_;
    additional_priors_ += AS_DOUBLE(new_score.score_);
  }

  /**
   * Get the Jacobian score from estimate_transformations
   */
  auto jacobians = model_->managers().estimate_transformation()->objects();
  jacobians_ = 0.0;
  for (auto jacobian : jacobians) {
    objective::Score new_score;
    new_score.label_ = PARAM_JACOBIAN + string("->") + jacobian->label();
    new_score.score_ = jacobian->GetScore();

    score_list_.push_back(new_score);
    score_ += new_score.score_;
    jacobians_ += AS_DOUBLE(new_score.score_);
  }

  LOG_MEDIUM() << "objective.score: " << score_;
}