Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
06/22/21 18:28:36 (3 years ago)
Author:
dpiringe
Message:

#3119

  • added additional parameters to enable different evaluation options
  • added additive restrictions
  • added additional implementations for dynamic restrictions:
    • dynamic intervalls
    • exponatial smoothing
    • rising multiplier
  • adapted IntervalUtil to get model bounds and refactored some sections
  • adapted ShapeConstraintsParser for added features
  • added a ResultCollection in SymbolicRegressionSolution for shape constraint violations
Location:
branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval/ShapeConstraint.cs

    r17946 r17995  
    107107
    108108    [Storable]
    109     private Interval threshold;
     109    private Interval threshold = new Interval(0, 0);
    110110    public Interval Threshold {
    111111      get => threshold;
     
    114114          return;
    115115        threshold = value;
     116        OnToStringChanged();
     117        OnChanged();
     118      }
     119    }
     120
     121
     122    [Storable]
     123    private Interval targetInterval;
     124    public Interval TargetInterval {
     125      get => targetInterval;
     126      set {
     127        if (targetInterval == value)
     128          return;
     129        targetInterval = value;
     130        OnToStringChanged();
     131        OnChanged();
     132      }
     133    }
     134
     135    [Storable]
     136    private Interval dynInterval = new Interval(double.NegativeInfinity, double.PositiveInfinity);
     137    public Interval DynInterval {
     138      get => dynInterval;
     139      set {
     140        if (dynInterval == value)
     141          return;
     142        dynInterval = value;
    116143        OnToStringChanged();
    117144        OnChanged();
     
    125152    private void AfterDeserialization() {
    126153      if (regions != null) regions.Changed += regions_Changed;
     154      if (TargetInterval == null)
     155        TargetInterval = new Interval(interval.LowerBound, interval.UpperBound);
    127156    }
    128157
    129158    // without derivation
    130     public ShapeConstraint(Interval interval, double weight, Interval threshold)
     159    public ShapeConstraint(Interval interval, double weight, Interval threshold, Interval dynInterval)
    131160      : this(string.Empty, 0,
    132          interval, new IntervalCollection(), weight, threshold) { }
    133 
    134     public ShapeConstraint(Interval interval, IntervalCollection regions, double weight, Interval threshold)
     161         interval, new IntervalCollection(), weight, threshold, dynInterval) { }
     162
     163    public ShapeConstraint(Interval interval, IntervalCollection regions, double weight, Interval threshold, Interval dynInterval)
    135164      : this(string.Empty, 0,
    136          interval, regions, weight, threshold) { }
     165         interval, regions, weight, threshold, dynInterval) { }
    137166
    138167    public ShapeConstraint(string variable, int numberOfDerivations,
    139                               Interval interval, double weight, Interval threshold)
     168                              Interval interval, double weight, Interval threshold, Interval dynInterval)
    140169      : this(variable, numberOfDerivations,
    141              interval, new IntervalCollection(), weight, threshold) { }
     170             interval, new IntervalCollection(), weight, threshold, dynInterval) { }
    142171
    143172    public ShapeConstraint(string variable, int numberOfDerivations,
    144                               Interval interval, IntervalCollection regions, double weight, Interval threshold) {
     173                              Interval interval, IntervalCollection regions, double weight, Interval threshold, Interval dynInterval) {
    145174      Variable = variable;
    146175      NumberOfDerivations = numberOfDerivations;
     
    149178      Weight = weight;
    150179      Threshold = threshold;
     180      DynInterval = dynInterval;
     181      TargetInterval = new Interval(interval.LowerBound, interval.UpperBound);
    151182    }
    152183
     
    162193      Regions = cloner.Clone(original.Regions);
    163194      Weight = original.weight;
    164     }
    165 
     195      Threshold = original.Threshold;
     196      DynInterval = original.DynInterval;
     197      TargetInterval = original.TargetInterval;
     198    }
    166199
    167200    public event EventHandler Changed;
     
    188221      string write(double val) => double.IsPositiveInfinity(val) ? "inf." : double.IsNegativeInfinity(val) ? "-inf." : $"{val}";
    189222      if (!IsDerivative) {
    190         expression = string.Format($"f in [{write(Interval.LowerBound)} .. {write(Interval.UpperBound)}]");
     223        expression = string.Format($"f in [{write(TargetInterval.LowerBound)} .. {write(TargetInterval.UpperBound)}]");
    191224      } else {
    192225        var derivationString = string.Empty;
     
    199232            derivationString = "³"; break;
    200233        }
    201         expression = string.Format($"∂{derivationString}f/∂{Variable}{derivationString} in [{write(Interval.LowerBound)} .. {write(Interval.UpperBound)}]");
     234        expression = string.Format($"∂{derivationString}f/∂{Variable}{derivationString} in [{write(TargetInterval.LowerBound)} .. {write(TargetInterval.UpperBound)}]");
    202235      }
    203236
     
    209242        expression += $" weight: {weight}";
    210243      }
     244
    211245      if (!double.IsNegativeInfinity(Threshold.LowerBound) || !double.IsPositiveInfinity(Threshold.UpperBound))
    212         expression += $" threshold: [{write(Threshold.LowerBound)} .. {write(Threshold.UpperBound)}]";
     246        expression += $" threshold in [{write(Threshold.LowerBound)} .. {write(Threshold.UpperBound)}]";
     247
     248      if (!double.IsNegativeInfinity(DynInterval.LowerBound) && !double.IsPositiveInfinity(DynInterval.UpperBound))
     249        expression += $" start in [{write(DynInterval.LowerBound)} .. {write(DynInterval.UpperBound)}]";
    213250
    214251      return expression;
  • branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval/ShapeConstraintsParser.cs

    r17946 r17995  
    7676    private const string weightRegex = @"\s*(weight:\s*(?<weight>\S*))?";
    7777    private const string thresholdRegex = @"\s*(threshold\s*in\s*(?<threshold> "+ intervalRegex + @"))?";
     78    private const string dynIntervalStartRegex = @"\s*(start\s*in\s*(?<dynInterval> " + intervalRegex + @"))?";
    7879    public static ShapeConstraint ParseFunctionRangeConstraint(string expr) {
    7980      if (!expr.StartsWith("f")) throw new ArgumentException($"Invalid function range constraint {expr} (e.g. f in [1..2])");
     
    9091      // df/d'x' in [0 .. 10] weight: 2.0
    9192      // df / d'x' in [0..10], 'x' in [1 .. 3]
    92       // df / d'x' in [0..10], 'x' in [1 .. 3], y in [10..30] weight: 1.2
    93       // df / d'x' in [0..10], 'x' in [1 .. 3], y in [10..30] weight: 1.2 threshold in [-10 .. 10]
     93      // df / d'x' in [0..10], 'x' in [1 .. 3], 'y' in [10..30] weight: 1.2
     94      // df / d'x' in [0..10], 'x' in [1 .. 3], 'y' in [10..30] weight: 1.2 threshold in [-10 .. 10]
    9495      var match = Regex.Match(targetConstraint,
    9596                    @"\s*\bin\b" +
     
    101102                    @")*" +
    102103                    weightRegex +
    103                     thresholdRegex
     104                    thresholdRegex +
     105                    dynIntervalStartRegex
    104106                    );
    105107
     
    112114        var interval = new Interval(lowerBound, upperBound);
    113115        var weight = 1.0;
    114         var threshold = new Interval(double.NegativeInfinity, double.PositiveInfinity);
     116        var threshold = new Interval(0, 0);
     117        Interval dynInterval = new Interval(double.NegativeInfinity, double.PositiveInfinity);
     118        int intervalIdx = 1;
     119        var lowerboundCount = match.Groups["lowerBound"].Captures.Count;
     120        var upperboundCount = match.Groups["upperBound"].Captures.Count;
    115121
    116122        if (match.Groups["weight"].Success && !string.IsNullOrWhiteSpace(match.Groups["weight"].Value))
    117123          weight = ParseAndValidateDouble(match.Groups["weight"].Value);
    118124
    119         if(match.Groups["threshold"].Success) {
    120           var lowerboundCount = match.Groups["lowerBound"].Captures.Count;
    121           var upperboundCount = match.Groups["upperBound"].Captures.Count;
    122           var thresholdLb = ParseIntervalBounds(match.Groups["lowerBound"].Captures[lowerboundCount - 1].Value);
    123           var thresholdUb = ParseIntervalBounds(match.Groups["upperBound"].Captures[upperboundCount - 1].Value);
     125        if (match.Groups["dynInterval"].Success) {
     126          var dynIntervalLb = ParseIntervalBounds(match.Groups["lowerBound"].Captures[lowerboundCount - intervalIdx].Value);
     127          var dynIntervalUb = ParseIntervalBounds(match.Groups["upperBound"].Captures[upperboundCount - intervalIdx].Value);
     128          intervalIdx++;
     129          dynInterval = new Interval(dynIntervalLb, dynIntervalUb);
     130        }
     131
     132        if (match.Groups["threshold"].Success) {
     133          var thresholdLb = ParseIntervalBounds(match.Groups["lowerBound"].Captures[lowerboundCount - intervalIdx].Value);
     134          var thresholdUb = ParseIntervalBounds(match.Groups["upperBound"].Captures[upperboundCount - intervalIdx].Value);
     135          intervalIdx++;
    124136          threshold = new Interval(thresholdLb, thresholdUb);
    125137        }
     138
    126139
    127140        if (match.Groups["varName"].Success) {
     
    138151              throw new ArgumentException($"The constraint {expr} has multiple regions of the same variable.");
    139152          }
    140           return new ShapeConstraint(interval, regions, weight, threshold);
     153          return new ShapeConstraint(interval, regions, weight, threshold, dynInterval);
    141154        } else
    142           return new ShapeConstraint(interval, weight, threshold);
     155          return new ShapeConstraint(interval, weight, threshold, dynInterval);
    143156      } else
    144157        throw new ArgumentException($"The target constraint {expr} is not valid.");
     
    160173                                  @")*" +
    161174                                weightRegex +
    162                                 thresholdRegex
     175                                thresholdRegex +
     176                                dynIntervalStartRegex
    163177                                );
    164178
     
    184198        var interval = new Interval(lowerBound, upperBound);
    185199        var weight = 1.0;
    186         var threshold = new Interval(double.NegativeInfinity, double.PositiveInfinity);
     200        var threshold = new Interval(0, 0);
     201        Interval dynInterval = new Interval(double.NegativeInfinity, double.PositiveInfinity);
     202        int intervalIdx = 1;
     203        var lowerboundCount = match.Groups["lowerBound"].Captures.Count;
     204        var upperboundCount = match.Groups["upperBound"].Captures.Count;
    187205
    188206        if (match.Groups["weight"].Success && !string.IsNullOrWhiteSpace(match.Groups["weight"].Value))
    189207          weight = ParseAndValidateDouble(match.Groups["weight"].Value);
    190208
     209        if (match.Groups["dynInterval"].Success) {
     210          var dynIntervalLb = ParseIntervalBounds(match.Groups["lowerBound"].Captures[lowerboundCount - intervalIdx].Value);
     211          var dynIntervalUb = ParseIntervalBounds(match.Groups["upperBound"].Captures[upperboundCount - intervalIdx].Value);
     212          intervalIdx++;
     213          dynInterval = new Interval(dynIntervalLb, dynIntervalUb);
     214        }
     215
    191216        if (match.Groups["threshold"].Success) {
    192           var lowerboundCount = match.Groups["lowerBound"].Captures.Count;
    193           var upperboundCount = match.Groups["upperBound"].Captures.Count;
    194           var thresholdLb = ParseIntervalBounds(match.Groups["lowerBound"].Captures[lowerboundCount - 1].Value);
    195           var thresholdUb = ParseIntervalBounds(match.Groups["upperBound"].Captures[upperboundCount - 1].Value);
     217          var thresholdLb = ParseIntervalBounds(match.Groups["lowerBound"].Captures[lowerboundCount - intervalIdx].Value);
     218          var thresholdUb = ParseIntervalBounds(match.Groups["upperBound"].Captures[upperboundCount - intervalIdx].Value);
     219          intervalIdx++;
    196220          threshold = new Interval(thresholdLb, thresholdUb);
    197221        }
     
    210234              throw new ArgumentException($"The constraint {expr} has multiple regions of the same variable.");
    211235          }
    212           return new ShapeConstraint(variable, numberOfDerivation, interval, regions, weight, threshold);
     236          return new ShapeConstraint(variable, numberOfDerivation, interval, regions, weight, threshold, dynInterval);
    213237        } else
    214           return new ShapeConstraint(variable, numberOfDerivation, interval, weight, threshold);
     238          return new ShapeConstraint(variable, numberOfDerivation, interval, weight, threshold, dynInterval);
    215239      } else
    216240        throw new ArgumentException($"The derivation constraint {expr} is not valid.");
Note: See TracChangeset for help on using the changeset viewer.