source: branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost/3.3/Utils/StepFunction.cs @ 13069

Last change on this file since 13069 was 13069, checked in by gkronber, 7 years ago

#2499: imported source code for HeuristicLab.BioBoost from private repository with some changes

File size: 3.2 KB
Line 
1using HeuristicLab.Common;
2using HeuristicLab.Core;
3using HeuristicLab.Data;
4using HeuristicLab.Parameters;
5using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
6using System;
7using System.Collections.Generic;
8using System.Globalization;
9using System.Linq;
10using System.Text.RegularExpressions;
11
12namespace HeuristicLab.BioBoost.Utils {
13
14  [StorableClass]
15  [Item("StepFunction", "A simple step function specifying upper bounds and corresponding values.")]
16  public class StepFunction : ParameterizedNamedItem {
17
18    #region parameters
19    public IValueLookupParameter<DoubleMatrix> ValuesParameter {
20      get { return (IValueLookupParameter<DoubleMatrix>) Parameters["Values"]; }
21    }
22    public DoubleMatrix Values {
23      get { return ValuesParameter.Value; }
24      set { ValuesParameter.Value = value; }
25    }
26    #endregion
27
28    #region Construction & Cloning
29    public StepFunction() {
30      Parameters.Add(new ValueLookupParameter<DoubleMatrix>("Values", "The upper bounds and corresponding values.", new DoubleMatrix(0, 2, new[] {"Upper Bound", "Value"})));
31    }
32    [StorableConstructor]
33    protected StepFunction(bool isDeserializing) : base(isDeserializing) {}
34    protected StepFunction(StepFunction orig, Cloner cloner) : base(orig, cloner) {}
35    public override IDeepCloneable Clone(Cloner cloner) {
36      return new StepFunction(this, cloner);
37    }
38    #endregion
39
40    public void Sort() {
41      if (Values.Columns != 2)
42        throw new InvalidOperationException("StepFunction values need two columns (upper bound and value)");
43      var steps = Enumerable.Range(0, Values.Rows).Select(i => new {s = Values[i, 0], v = Values[i, 1]}).OrderBy(p => p.s).ToList();
44      for (int i = 0; i<Values.Rows; i++) {
45        Values[i, 0] = steps[i].s;
46        Values[i, 1] = steps[i].v;
47      }
48    }
49
50    public double GetValue(double x) {
51      int i = 0;
52      while (i < Values.Rows-1 && x > Values[i, 0]) i++;
53      return Values[i, 1];
54    }
55
56    public static StepFunction Parse(String s, String rowSepRegex="/", String colSepRegex="->") {
57      var values = new List<Tuple<double, double>>();
58      foreach (var row in Regex.Split(s, rowSepRegex)) {
59        var cols = Regex.Split(row, colSepRegex);
60        if (cols.Length != 2) {
61          throw new ArgumentException("step function must contain two rows (separated by /" + colSepRegex + "/");
62        }
63        try {
64          values.Add(new Tuple<double, double>(ParseDouble(cols[0]), ParseDouble(cols[1])));
65        }
66        catch (Exception x) {
67          if (x is FormatException || x is ArgumentNullException || x is OverflowException) {
68            throw new ArgumentException(String.Format("could not parse row \"{0}\"", row), x);
69          }
70        }
71      }
72      var sf = new StepFunction();
73      var matrix = new DoubleMatrix(values.Count, 2, new[] {"Upper Bound", "Value"});
74      for (int i = 0; i < values.Count; i++) {
75        matrix[i, 0] = values[i].Item1;
76        matrix[i, 1] = values[i].Item2;
77      }
78      sf.Values = matrix;
79      sf.Sort();
80      return sf;
81    }
82
83
84    public static double ParseDouble(String s) {
85      return Double.Parse(s, NumberStyles.Float, NumberFormatInfo.InvariantInfo);
86    }
87  }
88}
Note: See TracBrowser for help on using the repository browser.