using System; using System.Collections.Generic; using System.Linq; using HeuristicLab.Core; using HeuristicLab.Problems.Instances.DataAnalysis; using HeuristicLab.Random; using Irony.Interpreter; namespace HeuristicLab.BenchmarkGenerator { public static class Functions { private static readonly IRandom Random = new MersenneTwister(); public static void SetSeed(int seed) { Random.Reset(seed); } public static object NormalDouble(ScriptThread thread, object[] args) { if (args.Length != 2) throw new ArgumentException("The NormalDouble function accepts exactly two arguments."); var mu = (double)args[0]; var sigma = (double)args[1]; return NormalDouble(mu, sigma); } public static object UniformDouble(ScriptThread thread, object[] args) { if (args.Length != 2) throw new ArgumentException("The UniformDouble function accepts exactly two arguments."); var a = (double)args[0]; var b = (double)args[1]; return UniformDouble(a, b); } public static object NormalDistribution(ScriptThread thread, object[] args) { if (args.Length != 3) throw new ArgumentException("The dnormal function accepts exactly three arguments."); var n = (int)(double)args[0]; var start = (double)args[1]; var end = (double)args[2]; return NormalDistribution(n, start, end).Cast().ToArray(); } public static object UniformDistribution(ScriptThread thread, object[] args) { if (args.Length != 3) throw new ArgumentException("The duniform function accepts exactly three arguments."); var n = (int)(double)args[0]; var start = (double)args[1]; var end = (double)args[2]; return UniformDistribution(n, start, end).Cast().ToArray(); } public static object[] Steps(ScriptThread thread, object[] args) { if (args.Length != 3) throw new ArgumentException("The Steps function accepts exactly three arguments."); var start = (double)args[0]; var end = (double)args[1]; var step = (double)args[2]; return Steps(start, end, step).Cast().ToArray(); } public static object[] Sin(ScriptThread thread, object[] args) { if (args.Length != 1) throw new ArgumentException("The Sin function accepts exactly one argument."); var values = (object[])args[0]; return values.Cast().Select(Math.Sin).Cast().ToArray(); } public static object[] Cos(ScriptThread thread, object[] args) { if (args.Length != 1) throw new ArgumentException("The Cos function accepts exactly one argument."); var values = (object[])args[0]; return values.Cast().Select(Math.Cos).Cast().ToArray(); } public static object Length(ScriptThread thread, object[] args) { if (args.Length != 1) throw new ArgumentException("The Length function accepts exactly one argument which must be an object array."); var values = (object[])args[0]; return (double)values.Length; } public static object DotProduct(ScriptThread thread, object[] args) { if (args.Length != 2) throw new ArgumentException("The DotProduct function accepts exactly two arguments which must be object arrays of the same length."); var a = (object[])args[0]; var b = (object[])args[1]; return DotProduct(a.Cast(), b.Cast()); } public static object[] Abs(ScriptThread thread, object[] args) { if (args.Length != 1) throw new ArgumentException("The Length function accepts exactly one argument which must be an object array."); var values = (object[])args[0]; return values.Cast().Select(Math.Abs).Cast().ToArray(); } public static object[] Repeat(ScriptThread thread, object[] args) { if (args.Length != 2) throw new ArgumentException("The Repeat function accepts exactly two arguments."); var n = (int)(double)args[0]; var v = (double)args[1]; return Enumerable.Repeat(v, n).Cast().ToArray(); } #region convenience methods for less typing private static double UniformDouble(double min, double max) { return UniformDistributedRandom.NextDouble(Random, min, max); } private static double NormalDouble(double mu, double sigma) { return NormalDistributedRandom.NextDouble(Random, mu, sigma); } private static IEnumerable Steps(double start, double end, double step) { return ValueGenerator.GenerateSteps(start, end, step); } private static IEnumerable UniformDistribution(int n, double start, double end) { return ValueGenerator.GenerateUniformDistributedValues(n, start, end); } private static IEnumerable NormalDistribution(int n, double start, double end) { return ValueGenerator.GenerateNormalDistributedValues(n, start, end); } private static double DotProduct(IEnumerable a, IEnumerable b) { return a.Zip(b, (x, y) => x * y).Sum(); } #endregion } }