1  #region License Information


2  /* HeuristicLab


3  * Copyright (C) 20022012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)


4  *


5  * This file is part of HeuristicLab.


6  *


7  * HeuristicLab is free software: you can redistribute it and/or modify


8  * it under the terms of the GNU General Public License as published by


9  * the Free Software Foundation, either version 3 of the License, or


10  * (at your option) any later version.


11  *


12  * HeuristicLab is distributed in the hope that it will be useful,


13  * but WITHOUT ANY WARRANTY; without even the implied warranty of


14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the


15  * GNU General Public License for more details.


16  *


17  * You should have received a copy of the GNU General Public License


18  * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.


19  */


20  #endregion


21 


22  using System;


23  using System.Collections.Generic;


24  using System.Linq;


25  using HeuristicLab.Common;


26  using HeuristicLab.Random;


27 


28  namespace HeuristicLab.Problems.Instances.DataAnalysis {


29  public static class ValueGenerator {


30  private static FastRandom rand = new FastRandom();


31 


32  /// <summary>


33  /// Generates a sequence of evenly spaced points between start and end (inclusive!).


34  /// </summary>


35  /// <param name="start">The smallest and first value of the sequence.</param>


36  /// <param name="end">The largest and last value of the sequence.</param>


37  /// <param name="stepWidth">The step size between subsequent values.</param>


38  /// <returns>An sequence of values from start to end (inclusive)</returns>


39  public static IEnumerable<double> GenerateSteps(double start, double end, double stepWidth) {


40  if (start > end) throw new ArgumentException("start must be less than or equal end.");


41  if (stepWidth <= 0) throw new ArgumentException("stepwith must be larger than zero.", "stepWidth");


42  double x = start;


43  // x<=end could skip the last value because of numerical problems


44  while (x < end  x.IsAlmost(end)) {


45  yield return x;


46  x += stepWidth;


47  }


48  }


49 


50  /// <summary>


51  /// Generates uniformly distributed values between start and end (inclusive!)


52  /// </summary>


53  /// <param name="n">Number of values to generate.</param>


54  /// <param name="start">The lower value (inclusive)</param>


55  /// <param name="end">The upper value (inclusive)</param>


56  /// <returns>An enumerable including n values in [start, end]</returns>


57  public static IEnumerable<double> GenerateUniformDistributedValues(int n, double start, double end) {


58  for (int i = 0; i < n; i++) {


59  // we need to return a random value including end.


60  // so we cannot use rand.NextDouble() as it returns a value strictly smaller than 1.


61  double r = rand.NextUInt() / (double)uint.MaxValue; // r \in [0,1]


62  yield return r * (end  start) + start;


63  }


64  }


65 


66  /// <summary>


67  /// Generates normally distributed values sampling from N(mu, sigma)


68  /// </summary>


69  /// <param name="n">Number of values to generate.</param>


70  /// <param name="mu">The mu parameter of the normal distribution</param>


71  /// <param name="sigma">The sigma parameter of the normal distribution</param>


72  /// <returns>An enumerable including n values ~ N(mu, sigma)</returns>


73  public static IEnumerable<double> GenerateNormalDistributedValues(int n, double mu, double sigma) {


74  for (int i = 0; i < n; i++)


75  yield return NormalDistributedRandom.NextDouble(rand, mu, sigma);


76  }


77 


78  // iterative approach


79  public static IEnumerable<IEnumerable<double>> GenerateAllCombinationsOfValuesInLists(List<List<double>> lists) {


80  List<List<double>> allCombinations = new List<List<double>>();


81  if (lists.Count < 1) {


82  return allCombinations;


83  }


84 


85  List<IEnumerator<double>> enumerators = new List<IEnumerator<double>>();


86  foreach (var list in lists) {


87  allCombinations.Add(new List<double>());


88  enumerators.Add(list.GetEnumerator());


89  }


90 


91  bool finished = !enumerators.All(x => x.MoveNext());


92 


93  while (!finished) {


94  GetCurrentCombination(enumerators, allCombinations);


95  finished = MoveNext(enumerators, lists);


96  }


97  return allCombinations;


98  }


99 


100  private static bool MoveNext(List<IEnumerator<double>> enumerators, List<List<double>> lists) {


101  int cur = enumerators.Count  1;


102  while (cur >= 0 && !enumerators[cur].MoveNext()) {


103  enumerators[cur] = lists[cur].GetEnumerator();


104  enumerators[cur].MoveNext();


105  cur;


106  }


107  return cur < 0;


108  }


109 


110  private static void GetCurrentCombination(List<IEnumerator<double>> enumerators, List<List<double>> allCombinations) {


111  for (int i = 0; i < enumerators.Count(); i++) {


112  allCombinations[i].Add(enumerators[i].Current);


113  }


114  }


115  }


116  }

