<commit_before>package org.powertac.customer.evcharger;

import java.util.Arrays;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/** ---------------------------------------------------------------------------------------
   * Mutable element of the StorageState forward capacity vector for the EV Charger model.
   * Each contains a capacity histogram of length n + 1 for a timeslot n slots in the future.
   * 
   * Max demand is simply the sum of individual capacities of the chargers, constrained by to
   * remaining unfilled capacity in the batteries of attached vehicles.
   * 
   * Min demand is the minimum amount that must be consumed in a given timeslot to meet the
   * charging requirements of attached vehicles, constrained by max demand.
   * 
   * @author <NAME>
   *
   */
  class StorageElement // package visibility
  {
    static Logger log =
            LogManager.getLogger(StorageElement.class.getName());

    // Number of active chargers
    // TODO - it's possible this activeChargers value is not used anywhere
    private double activeChargers = 0.0;

    // Unsatisfied demand remaining in vehicles that will disconnect in this timeslot
    double[] energy = {0.0};

    // Population allocated to energy requirement breakdown
    private double[] population = {0.0};

    private double epsilon = 1e-8;

    // default constructor
    StorageElement (int arrayLength)
    {
      super();
      this.energy = new double[arrayLength];
      this.population = new double[arrayLength];
    }

    // populated constructor
    StorageElement (double activeChargers, double[] energy, double[] population)
    {
      super();
      this.activeChargers = activeChargers;
      this.energy = energy;
      this.population = population;
    }

    // Shrinks energy and population arrays, dropping the final element
    // which is no longer needed
    void collapseArrays ()
    {
      int len = population.length;
      if (len < 2) {
        // nothing to do here
        return;
      }
      population = Arrays.copyOf(population, len - 1);
      energy = Arrays.copyOf(energy, len - 1);
    }

    // Moves energy and population to smaller indices as needed to preserve
    // hourly constraints
    void rebalance (double chargerCapacity)
    {
      // This only works if there are multiple groups
      if (1 == population.length)
        return;
      // Each group i should have energy ratio <= (len - i - 1) + 0.5
      for (int i = energy.length - 1; i > 0; i--) {
        //note that we are not moving energy and population above index 0
        //first, find the surplus in this timeslot
        double xRatio = (energy.length - 1 - i) + 0.5; // current cell
        if (population[i] < epsilon) {
          // clear this one out
          population[i] = 0.0;
          energy[i] = 0.0;
          continue;
        }
        double chunk = population[i] * chargerCapacity;
        double currentRatio = 0.0;
        currentRatio = energy[i] / chunk;
        if (currentRatio <= xRatio) {
          continue;
        }
        else {
          double move = (currentRatio - xRatio);
          if (move > 1.0 || move < 0.0) {
            log.error("Move ratio = {} out of range", move);
          }
          double moveP = population[i] * move;
          population[i] -= moveP;
          population[i - 1] += moveP;
          double moveE = energy[i] - population[i] * chargerCapacity * xRatio;
          energy[i] -= moveE;
          energy[i - 1] += moveE;
        }
      }
    }

    double getActiveChargers ()
    {
      return activeChargers;
    }<commit_msg>#1064 - add another epsilon test to prevent bogus error reporting<commit_after>package org.powertac.customer.evcharger;

import java.util.Arrays;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/** ---------------------------------------------------------------------------------------
   * Mutable element of the StorageState forward capacity vector for the EV Charger model.
   * Each contains a capacity histogram of length n + 1 for a timeslot n slots in the future.
   * 
   * Max demand is simply the sum of individual capacities of the chargers, constrained by to
   * remaining unfilled capacity in the batteries of attached vehicles.
   * 
   * Min demand is the minimum amount that must be consumed in a given timeslot to meet the
   * charging requirements of attached vehicles, constrained by max demand.
   * 
   * @author <NAME>
   *
   */
  class StorageElement // package visibility
  {
    static Logger log =
            LogManager.getLogger(StorageElement.class.getName());

    // Number of active chargers
    // TODO - it's possible this activeChargers value is not used anywhere
    private double activeChargers = 0.0;

    // Unsatisfied demand remaining in vehicles that will disconnect in this timeslot
    double[] energy = {0.0};

    // Population allocated to energy requirement breakdown
    private double[] population = {0.0};

    private double epsilon = 1e-8;

    // default constructor
    StorageElement (int arrayLength)
    {
      super();
      this.energy = new double[arrayLength];
      this.population = new double[arrayLength];
    }

    // populated constructor
    StorageElement (double activeChargers, double[] energy, double[] population)
    {
      super();
      this.activeChargers = activeChargers;
      this.energy = energy;
      this.population = population;
    }

    // Shrinks energy and population arrays, dropping the final element
    // which is no longer needed
    void collapseArrays ()
    {
      int len = population.length;
      if (len < 2) {
        // nothing to do here
        return;
      }
      population = Arrays.copyOf(population, len - 1);
      energy = Arrays.copyOf(energy, len - 1);
    }

    // Moves energy and population to smaller indices as needed to preserve
    // hourly constraints
    void rebalance (double chargerCapacity)
    {
      // This only works if there are multiple groups
      if (1 == population.length)
        return;
      // Each group i should have energy ratio <= (len - i - 1) + 0.5
      for (int i = energy.length - 1; i > 0; i--) {
        //note that we are not moving energy and population above index 0
        //first, find the surplus in this timeslot
        double xRatio = (energy.length - 1 - i) + 0.5; // current cell
        if (population[i] < epsilon) {
          // clear this one out
          population[i] = 0.0;
          energy[i] = 0.0;
          continue;
        }
        double chunk = population[i] * chargerCapacity;
        double currentRatio = 0.0;
        currentRatio = energy[i] / chunk;
        if (currentRatio <= xRatio) {
          continue;
        }
        else {
          double move = (currentRatio - xRatio);
          if (move > 1.0 + epsilon || move < 0.0 - epsilon) {
            log.error("Move ratio = {} out of range", move);
          }
          double moveP = population[i] * move;
          population[i] -= moveP;
          population[i - 1] += moveP;
          double moveE = energy[i] - population[i] * chargerCapacity * xRatio;
          energy[i] -= moveE;
          energy[i - 1] += moveE;
        }
      }
    }

    double getActiveChargers ()
    {
      return activeChargers;
    }
{'fraction_non_alphanumeric': 0.11301276826949198, 'fraction_numerical': 0.010323281716924749, 'mean_word_length': 2.0163867267513313, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '986027', 'n_tokens_mistral': 2039, 'n_tokens_neox': 1947, 'n_words': 707}