#region License Information /* HeuristicLab * Copyright (C) 2002-2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Linq; using HEAL.Attic; using HeuristicLab.Common; using HeuristicLab.Core; namespace HeuristicLab.Problems.DataAnalysis { [StorableType("8109BE58-CCFB-4462-A2F4-EEE5DFADAFF7")] [Item("Interval Constraint", "Constraint on intervals.")] public sealed class IntervalConstraint : Item { [Storable] private string expression; public string Expression { get => expression; private set { if (expression == value) return; expression = value; OnChanged(); OnToStringChanged(); } } public string Definition => GetDefinitionString(); [Storable] private string variable; public string Variable { get => variable; private set { if (variable == value) return; variable = value; UpdateExpression(); OnChanged(); } } [Storable] private string target; public string Target { get => target; private set { if (target == value) return; target = value; UpdateExpression(); OnChanged(); } } public bool IsDerivative => NumberOfDerivations > 0; [Storable] private int numberOfDerivations; public int NumberOfDerivations { get => numberOfDerivations; set { if (value < 0 || value > 3) throw new ArgumentException("Number of derivation has to be between 0 - 3."); if (numberOfDerivations == value) return; numberOfDerivations = value; UpdateExpression(); OnChanged(); } } [Storable] private Interval interval; public Interval Interval { get => interval; set { if (interval == value) return; interval = value; UpdateExpression(); OnChanged(); } } [Storable] private bool enabled; public bool Enabled { get => enabled; set { if (enabled == value) return; enabled = value; OnChanged(); } } [Storable] private IEnumerable regions; public IEnumerable Regions { get => regions; set { if (regions != value) { regions = value; UpdateExpression(); OnChanged(); } } } [Storable] private double weight = 1.0; public double Weight { get => weight; set { if (weight != value) { weight = value; UpdateExpression(); OnChanged(); } } } [StorableConstructor] private IntervalConstraint(StorableConstructorFlag _) : base(_) { } public IntervalConstraint(string expression, string variable, string target, int numberOfDerivations, Interval interval, double weight, bool enabled) : this(expression, variable, target, numberOfDerivations, interval, Enumerable.Empty(), weight, enabled) { } public IntervalConstraint(string expression, string variable, string target, int numberOfDerivations, Interval interval, IEnumerable regions, double weight, bool enabled) { this.regions = regions; this.weight = weight; this.expression = expression; this.variable = variable; this.target = target; this.numberOfDerivations = numberOfDerivations; this.interval = interval; this.enabled = enabled; } public override IDeepCloneable Clone(Cloner cloner) { return new IntervalConstraint(this, cloner); } private IntervalConstraint(IntervalConstraint original, Cloner cloner) : base(original, cloner) { Regions = new List(original.Regions?.Select(r => cloner.Clone(r)) ?? Enumerable.Empty()); Expression = original.Expression; Variable = original.Variable; Target = original.Target; NumberOfDerivations = original.NumberOfDerivations; Interval = original.Interval; Enabled = original.Enabled; } public event EventHandler Changed; private void OnChanged() { var handlers = Changed; if (handlers != null) handlers(this, EventArgs.Empty); } private static string GetDerivationString(int derivation) { switch (derivation) { case 1: return ""; case 2: return "²"; case 3: return "³"; default: return ""; } } private void UpdateExpression() { var expression = ""; if (!IsDerivative) { expression = string.Format("Target:{0} in {1}{2} .. {3}{4}", Variable, "[", Interval?.LowerBound, Interval?.UpperBound, "]"); if(Regions != null) { foreach (var region in Regions) expression += $", {region.VariableName}=({region.Interval.LowerBound} .. {region.Interval.UpperBound})"; } Expression = expression; return; } expression = string.Format("∂{6}{1}/∂{0}{6} in {2}{3} .. {4}{5}", Variable, Target, "[", Interval?.LowerBound, Interval?.UpperBound, "]", GetDerivationString(numberOfDerivations)); if (Regions != null) { foreach (var region in Regions) expression += $", {region.VariableName}=({region.Interval.LowerBound} .. {region.Interval.UpperBound})"; } Expression = expression; } private string GetDefinitionString() { if (!IsDerivative) return "Target " + Variable; var definition = $"∂{GetDerivationString(numberOfDerivations)}Target/∂{Variable}{GetDerivationString(numberOfDerivations)}"; return definition; } public override string ToString() { return Expression; } } }