1  using System;


2  using System.Collections.Generic;


3  using System.Linq;


4  using System.Text;


5  using System.Threading.Tasks;


6 


7  namespace HeuristicLab.Common {


8  public static class Extensions {


9  public static bool IsAlmost(this double x, double y) {


10  return Math.Abs(x  y) < 1.0e12;


11  }


12 


13  public static T SelectRandom<T>(this IEnumerable<T> xs, Random rand) {


14  var xsArr = xs.ToArray();


15  return xsArr[rand.Next(xsArr.Length)];


16  }


17 


18  public static IEnumerable<T> SampleProportional<T>(this IEnumerable<T> source, Random random, IEnumerable<double> weights) {


19  var sourceArray = source.ToArray();


20  var valueArray = weights.ToArray();


21  double total = valueArray.Sum();


22 


23  while (true) {


24  int index = 0;


25  double ball = valueArray[index], sum = random.NextDouble() * total;


26  while (ball < sum)


27  ball += valueArray[++index];


28  yield return sourceArray[index];


29  }


30  }


31 


32  public static double RSq(IEnumerable<double> xs, IEnumerable<double> ys) {


33  // two pass implementation, but we don't care


34  var meanX = xs.Average();


35  var meanY = ys.Average();


36 


37  var s = 0.0;


38  var ssX = 0.0;


39  var ssY = 0.0;


40  var xEnum = xs.GetEnumerator();


41  var yEnum = ys.GetEnumerator();


42  while (xEnum.MoveNext() & yEnum.MoveNext()) {


43  var x = xEnum.Current;


44  var y = yEnum.Current;


45  s += (x  meanX) * (y  meanY);


46  ssX += Math.Pow(x  meanX, 2);


47  ssY += Math.Pow(y  meanY, 2);


48  }


49  if (xEnum.MoveNext()  yEnum.MoveNext()) throw new ArgumentException("lengths are not equal");


50 


51  if (s.IsAlmost(0)) return 0;


52  if (ssX.IsAlmost(0)  ssY.IsAlmost(0)) return 0;


53  return s * s / (ssX * ssY);


54  }


55 


56 


57  }


58  }

