/*
 * Copyright Nick Thompson, 2024
 * Use, modification and distribution are subject to the
 * Boost Software License, Version 1.0. (See accompanying file
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 */
#ifndef BOOST_MATH_OPTIMIZATION_DIFFERENTIAL_EVOLUTION_HPP
#define BOOST_MATH_OPTIMIZATION_DIFFERENTIAL_EVOLUTION_HPP
#include <atomic>
#include <boost/math/optimization/detail/common.hpp>
#include <cmath>
#include <limits>
#include <mutex>
#include <random>
#include <sstream>
#include <stdexcept>
#include <thread>
#include <utility>
#include <vector>

namespace boost::math::optimization {

// Storn, R., Price, K. (1997). Differential evolution-a simple and efficient heuristic for global optimization over
// continuous spaces.
// Journal of global optimization, 11, 341-359.
// See:
// https://www.cp.eng.chula.ac.th/~prabhas//teaching/ec/ec2012/storn_price_de.pdf

// We provide the parameters in a struct-there are too many of them and they are too unwieldy to pass individually:
template <typename ArgumentContainer> struct differential_evolution_parameters {
  using Real = typename ArgumentContainer::value_type;
  using DimensionlessReal = decltype(Real()/Real());
  ArgumentContainer lower_bounds;
  ArgumentContainer upper_bounds;
  // mutation factor is also called scale factor or just F in the literature:
  DimensionlessReal mutation_factor = static_cast<DimensionlessReal>(0.65);
  DimensionlessReal crossover_probability = static_cast<DimensionlessReal>(0.5);
  // Population in each generation:
  size_t NP = 500;
  size_t max_generations = 1000;
  ArgumentContainer const *initial_guess = nullptr;
  unsigned threads = std::thread::hardware_concurrency();
};

template <typename ArgumentContainer>
void validate_differential_evolution_parameters(differential_evolution_parameters<ArgumentContainer> const &de_params) {
  using std::isfinite;
  using std::isnan;
  std::ostringstream oss;
  detail::validate_bounds(de_params.lower_bounds, de_params.upper_bounds);
  if (de_params.NP < 4) {
    oss << __FILE__ << ":" << __LINE__ << ":" << __func__;
    oss << ": The population size must be at least 4, but requested population size of " << de_params.NP << ".";
    throw std::invalid_argument(oss.str());
  }
  // From: "Differential Evolution: A Practical Approach to Global Optimization (Natural Computing Series)"
  // > The scale factor, F in (0,1+), is a positive real number that controls the rate at which the population evolves.
  // > While there is no upper limit on F, effective values are seldom greater than 1.0.
  // ...
  // Also see "Limits on F", Section 2.5.1:
  // > This discontinuity at F = 1 reduces the number of mutants by half and can result in erratic convergence...
  auto F = de_params.mutation_factor;
  if (isnan(F) || F >= 1 || F <= 0) {
    oss << __FILE__ << ":" << __LINE__ << ":" << __func__;
    oss << ": F in (0, 1) is required, but got F=" << F << ".";
    throw std::domain_error(oss.str());
  }
  if (de_params.max_generations < 1) {
    oss << __FILE__ << ":" << __LINE__ << ":" << __func__;
    oss << ": There must be at least one generation.";
    throw std::invalid_argument(oss.str());
  }
  if (de_params.initial_guess) {
    detail::validate_initial_guess(*de_params.initial_guess, de_params.lower_bounds, de_params.upper_bounds);
  }
  if (de_params.threads == 0) {
    oss << __FILE__ << ":" << __LINE__ << ":" << __func__;
    oss << ": There must be at least one thread.";
    throw std::invalid_argument(oss.str());
  }
}

template <typename ArgumentContainer, class Func, class URBG>
ArgumentContainer differential_evolution(
    const Func cost_function, differential_evolution_parameters<ArgumentContainer> const &de_params, URBG &gen,
    std::invoke_result_t<Func, ArgumentContainer> target_value =
        std::numeric_limits<std::invoke_result_t<Func, ArgumentContainer>>::quiet_NaN(),
    std::atomic<bool> *cancellation = nullptr,
    std::atomic<std::invoke_result_t<Func, ArgumentContainer>> *current_minimum_cost = nullptr,
    std::vector<std::pair<ArgumentContainer, std::invoke_result_t<Func, ArgumentContainer>>> *queries = nullptr) {
  using Real = typename ArgumentContainer::value_type;
  using DimensionlessReal = decltype(Real()/Real());
  using ResultType = std::invoke_result_t<Func, ArgumentContainer>;
  using std::clamp;
  using std::isnan;
  using std::round;
  using std::uniform_real_distribution;
  validate_differential_evolution_parameters(de_params);
  const size_t dimension = de_params.lower_bounds.size();
  auto NP = de_params.NP;
  auto population = detail::random_initial_population(de_params.lower_bounds, de_params.upper_bounds, NP, gen);
  if (de_params.initial_guess) {
    population[0] = *de_params.initial_guess;
  }
  std::vector<ResultType> cost(NP, std::numeric_limits<ResultType>::quiet_NaN());
  std::atomic<bool> target_attained = false;
  // This mutex is only used if the queries are stored:
  std::mutex mt;

  std::vector<std::thread> thread_pool;
  auto const threads = de_params.threads;
  for (size_t j = 0; j < threads; ++j) {
    // Note that if some members of the population take way longer to compute,
    // then this parallelization strategy is very suboptimal.
    // However, we tried using std::async (which should be robust to this particular problem),
    // but the overhead was just totally unacceptable on ARM Macs (the only platform tested).
    // As the economists say "there are no solutions, only tradeoffs".
    thread_pool.emplace_back([&, j]() {
      for (size_t i = j; i < cost.size(); i += threads) {
        cost[i] = cost_function(population[i]);
        if (current_minimum_cost && cost[i] < *current_minimum_cost) {
          *current_minimum_cost = cost[i];
        }
        if (queries) {
          std::scoped_lock lock(mt);
          queries->push_back(std::make_pair(population[i], cost[i]));
        }
        if (!isnan(target_value) && cost[i] <= target_value) {
          target_attained = true;
        }
      }
    });
  }
  for (auto &thread : thread_pool) {
    thread.join();
  }

  std::vector<ArgumentContainer> trial_vectors(NP);
  for (size_t i = 0; i < NP; ++i) {
    if constexpr (detail::has_resize_v<ArgumentContainer>) {
      trial_vectors[i].resize(dimension);
    }
  }
  std::vector<URBG> thread_generators(threads);
  for (size_t j = 0; j < threads; ++j) {
    thread_generators[j].seed(gen());
  }
  // std::vector<bool> isn't threadsafe!
  std::vector<int> updated_indices(NP, 0);

  for (size_t generation = 0; generation < de_params.max_generations; ++generation) {
    if (cancellation && *cancellation) {
      break;
    }
    if (target_attained) {
      break;
    }
    thread_pool.resize(0);
    for (size_t j = 0; j < threads; ++j) {
      thread_pool.emplace_back([&, j]() {
        auto& tlg = thread_generators[j];
        uniform_real_distribution<DimensionlessReal> unif01(DimensionlessReal(0), DimensionlessReal(1));
        for (size_t i = j; i < cost.size(); i += threads) {
          if (target_attained) {
            return;
          }
          if (cancellation && *cancellation) {
            return;
          }
          size_t r1, r2, r3;
          do {
            r1 = tlg() % NP;
          } while (r1 == i);
          do {
            r2 = tlg() % NP;
          } while (r2 == i || r2 == r1);
          do {
            r3 = tlg() % NP;
          } while (r3 == i || r3 == r2 || r3 == r1);

          for (size_t k = 0; k < dimension; ++k) {
            // See equation (4) of the reference:
            auto guaranteed_changed_idx = tlg() % dimension;
            if (unif01(tlg) < de_params.crossover_probability || k == guaranteed_changed_idx) {
              auto tmp = population[r1][k] + de_params.mutation_factor * (population[r2][k] - population[r3][k]);
              auto const &lb = de_params.lower_bounds[k];
              auto const &ub = de_params.upper_bounds[k];
              // Some others recommend regenerating the indices rather than clamping;
              // I dunno seems like it could get stuck regenerating . . .
              trial_vectors[i][k] = clamp(tmp, lb, ub);
            } else {
              trial_vectors[i][k] = population[i][k];
            }
          }

          auto const trial_cost = cost_function(trial_vectors[i]);
          if (isnan(trial_cost)) {
            continue;
          }
          if (queries) {
            std::scoped_lock lock(mt);
            queries->push_back(std::make_pair(trial_vectors[i], trial_cost));
          }
          if (trial_cost < cost[i] || isnan(cost[i])) {
            cost[i] = trial_cost;
            if (!isnan(target_value) && cost[i] <= target_value) {
              target_attained = true;
            }
            if (current_minimum_cost && cost[i] < *current_minimum_cost) {
              *current_minimum_cost = cost[i];
            }
            // Can't do this! It's a race condition!
            //population[i] = trial_vectors[i];
            // Instead mark all the indices that need to be updated:
            updated_indices[i] = 1;
          }
        }
      });
    }
    for (auto &thread : thread_pool) {
      thread.join();
    }
    for (size_t i = 0; i < NP; ++i) {
      if (updated_indices[i]) {
        population[i] = trial_vectors[i];
        updated_indices[i] = 0;
      }
    }
  }

  auto it = std::min_element(cost.begin(), cost.end());
  return population[std::distance(cost.begin(), it)];
}

} // namespace boost::math::optimization
#endif
