#region License Information
/* HeuristicLab
* Copyright (C) 2002-2018 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 HeuristicLab.Common;
using HeuristicLab.Core;
using HeuristicLab.Data;
using HeuristicLab.Operators;
using HeuristicLab.Parameters;
using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
namespace HeuristicLab.Optimization.Operators {
///
/// Base class for modifying a double value according to a certain function in discrete intervalls.
///
[Item("DiscreteDoubleValueModifier", "Base class for modifying a double value according to a certain function in discrete intervalls.")]
[StorableClass]
public abstract class DiscreteDoubleValueModifier : SingleSuccessorOperator, IDiscreteDoubleValueModifier {
#region parameter properties
///
/// The parameter that should be modified.
///
public ILookupParameter ValueParameter {
get { return (ILookupParameter)Parameters["Value"]; }
}
///
/// The start value of the parameter, will be assigned to as soon as equals .
///
public IValueLookupParameter StartValueParameter {
get { return (IValueLookupParameter)Parameters["StartValue"]; }
}
///
/// The end value of the parameter, will be assigned to as soon as equals .
///
public IValueLookupParameter EndValueParameter {
get { return (IValueLookupParameter)Parameters["EndValue"]; }
}
///
/// The index that denotes from which point in the function (relative to and the value should be assigned.
///
public ILookupParameter IndexParameter {
get { return (ILookupParameter)Parameters["Index"]; }
}
///
/// As soon as is >= this parameter the value will start to be modified.
///
public IValueLookupParameter StartIndexParameter {
get { return (IValueLookupParameter)Parameters["StartIndex"]; }
}
///
/// As long as is <= this parameter the value will start to be modified.
///
public IValueLookupParameter EndIndexParameter {
get { return (IValueLookupParameter)Parameters["EndIndex"]; }
}
#endregion
[StorableConstructor]
protected DiscreteDoubleValueModifier(bool deserializing) : base(deserializing) { }
protected DiscreteDoubleValueModifier(DiscreteDoubleValueModifier original, Cloner cloner) : base(original, cloner) { }
///
/// Initializes a new instance of with 6 parameters
/// (Value, StartValue, EndValue, Index, StartIndex, EndIndex).
///
protected DiscreteDoubleValueModifier()
: base() {
Parameters.Add(new LookupParameter("Value", "The double value to modify."));
Parameters.Add(new ValueLookupParameter("StartValue", "The start value of 'Value'."));
Parameters.Add(new ValueLookupParameter("EndValue", "The end value of 'Value'."));
Parameters.Add(new LookupParameter("Index", "The current index."));
Parameters.Add(new ValueLookupParameter("StartIndex", "The start index at which to start modifying 'Value'."));
Parameters.Add(new ValueLookupParameter("EndIndex", "The end index by which 'Value' should have reached 'EndValue'."));
}
///
/// Checks whether index is between start and end and forwards the call to if startIndex < index < endIndex.
///
///
/// If index = startIndex the call will not be forwarded and startValue will be used. The same with endIndex and endValue.
///
/// What the base class returns.
public override IOperation Apply() {
int index = IndexParameter.ActualValue.Value, startIndex = StartIndexParameter.ActualValue.Value;
if (index >= startIndex) {
int endIndex = EndIndexParameter.ActualValue.Value;
DoubleValue value = ValueParameter.ActualValue;
if (value == null) {
value = new DoubleValue();
ValueParameter.ActualValue = value;
}
double newValue = value.Value;
if (index == startIndex) {
newValue = StartValueParameter.ActualValue.Value;
} else if (index == endIndex) {
newValue = EndValueParameter.ActualValue.Value;
} else if (index < endIndex) {
double start = StartValueParameter.ActualValue.Value, end = EndValueParameter.ActualValue.Value;
newValue = Modify(value.Value, start, end, index, startIndex, endIndex);
}
value.Value = newValue;
}
return base.Apply();
}
///
/// Modifies a given value according to two support points denoted by (startIndex; startValue) and (endIndex; endValue).
/// The current 'index' and the last value of 'value' is also given.
///
/// The last value.
/// The start value.
/// The end value.
/// The current index.
/// The start index.
/// The end index.
/// The new value.
protected abstract double Modify(double value, double startValue, double endValue, int index, int startIndex, int endIndex);
}
}