Changeset 17902 for trunk/HeuristicLab.Problems.DataAnalysis.Symbolic
- Timestamp:
- 03/16/21 14:23:41 (4 years ago)
- Location:
- trunk/HeuristicLab.Problems.DataAnalysis.Symbolic
- Files:
-
- 5 edited
- 5 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/HeuristicLab.Problems.DataAnalysis.Symbolic
- Property svn:mergeinfo changed
-
trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/DerivativeCalculator.cs
r17180 r17902 149 149 return Product(Product(CreateConstant(3.0), Square(f)), Derive(f, variableName)); 150 150 } 151 if (branch.Symbol is Power) { 152 // HL evaluators handle power strangely (exponent is rounded to an integer) 153 // here we only support the case when the exponent is a constant integer 154 var exponent = branch.GetSubtree(1) as ConstantTreeNode; 155 if (exponent != null && Math.Truncate(exponent.Value) == exponent.Value) { 156 var newPower = (ISymbolicExpressionTreeNode)branch.Clone(); 157 var f = (ISymbolicExpressionTreeNode)newPower.GetSubtree(0).Clone(); 158 var newExponent = (ConstantTreeNode)newPower.GetSubtree(1); 159 newExponent.Value -= 1; 160 return Product(Product(CreateConstant(exponent.Value), newPower), Derive(f, variableName)); 161 } else throw new NotSupportedException("Cannot derive non-integer powers"); 162 } 151 163 if (branch.Symbol is Absolute) { 152 164 var f = (ISymbolicExpressionTreeNode)branch.GetSubtree(0).Clone(); … … 263 275 !(n.Symbol is Cube) && 264 276 !(n.Symbol is CubeRoot) && 277 !(n.Symbol is Power) && 265 278 !(n.Symbol is Absolute) && 266 279 !(n.Symbol is AnalyticQuotient) && 280 !(n.Symbol is HyperbolicTangent) && 267 281 !(n.Symbol is Sine) && 268 282 !(n.Symbol is Cosine) && -
trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/IntervalArithmeticGrammar.cs
r17884 r17902 1 using System.Collections.Generic; 1 #region License Information 2 3 /* HeuristicLab 4 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL) 5 * 6 * This file is part of HeuristicLab. 7 * 8 * HeuristicLab is free software: you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation, either version 3 of the License, or 11 * (at your option) any later version. 12 * 13 * HeuristicLab is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>. 20 */ 21 22 #endregion 23 using System.Collections.Generic; 2 24 using System.Linq; 3 25 using HEAL.Attic; … … 8 30 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 9 31 [StorableType("5A2300A0-D0FC-4F2D-B910-F86384FE9052")] 10 [Item("IntervalArithmeticGrammar", "Represents a grammar for interval arithmetic ")]32 [Item("IntervalArithmeticGrammar", "Represents a grammar for interval arithmetic which includes linear scaling parts implicitly.")] 11 33 public class IntervalArithmeticGrammar : DataAnalysisGrammar, ISymbolicDataAnalysisGrammar { 12 34 public IntervalArithmeticGrammar() : base(ItemAttribute.GetName(typeof(IntervalArithmeticGrammar)), … … 35 57 var cos = new Cosine(); 36 58 var tan = new Tangent(); 59 var tanh = new HyperbolicTangent(); 37 60 var log = new Logarithm(); 38 var pow = new Power();61 var exp = new Exponential(); 39 62 var square = new Square(); 40 var root = new Root();41 63 var sqrt = new SquareRoot(); 42 var exp = new Exponential(); 43 var tanh = new HyperbolicTangent(); 64 var cube = new Cube(); 65 var cbrt = new CubeRoot(); 66 var abs = new Absolute(); 67 var aq = new AnalyticQuotient(); 44 68 var constant = new Constant(); 45 var aq = new AnalyticQuotient();46 69 constant.MinValue = -20; 47 70 constant.MaxValue = 20; … … 51 74 52 75 //Special symbols 53 var offset = new Addition { Name = "Offset"};54 var scaling = new Multiplication { Name = "Scaling"};76 var offset = new Addition { Name = "Offset" }; 77 var scaling = new Multiplication { Name = "Scaling" }; 55 78 //all other symbols 56 79 var allSymbols = new List<Symbol> { 57 add, sub, mul, div, constant, variableSymbol, sin, cos, tan, log, pow, square, root, sqrt, exp,58 tanh, aq 80 add, sub, mul, div, constant, variableSymbol, sin, cos, tan, log, square, sqrt, cube, cbrt, exp, 81 tanh, aq, abs 59 82 }; 60 83 61 var arithmeticSymbols = new List<Symbol> {add, sub, mul, div}; 62 var trigonometricSymbols = new List<Symbol> {sin, cos, tan, tanh}; 63 var exponentialAndLogarithmicSymbols = new List<Symbol> {exp, log}; 64 var powerSymbols = new List<Symbol> {square, pow, sqrt, root}; 65 var specialSymbols = new List<Symbol> {aq}; 66 var realValueSymbols = new List<Symbol> 67 {add, sub, mul, div, sin, cos, tan, tanh, exp, log, variableSymbol, constant, aq}; 84 var bivariateFuncs = new List<Symbol> { add, sub, mul, div, aq }; 85 var univariateFuncs = new List<Symbol> { sin, cos, tan, tanh, exp, log, abs, square, cube, sqrt, cbrt }; 86 var realValueSymbols = new List<Symbol> { 87 add, sub, mul, div, sin, cos, tan, tanh, exp, log, aq, abs, square, cube, sqrt, cbrt, 88 variableSymbol, constant, 89 }; 68 90 69 91 … … 76 98 #region define subtree count for special symbols 77 99 78 foreach (var symb in arithmeticSymbols) SetSubtreeCount(symb, 2, 2);100 foreach (var symb in bivariateFuncs) SetSubtreeCount(symb, 2, 2); 79 101 80 foreach (var symb in trigonometricSymbols) SetSubtreeCount(symb, 1, 1); 81 82 foreach (var symb in exponentialAndLogarithmicSymbols) SetSubtreeCount(symb, 1, 1); 102 foreach (var symb in univariateFuncs) SetSubtreeCount(symb, 1, 1); 83 103 84 104 SetSubtreeCount(offset, 2, 2); 85 105 SetSubtreeCount(scaling, 2, 2); 86 SetSubtreeCount(pow, 2, 2);87 SetSubtreeCount(root, 2, 2);88 SetSubtreeCount(square, 1, 1);89 SetSubtreeCount(sqrt, 1, 1);90 SetSubtreeCount(aq, 2, 2);91 106 92 107 #endregion … … 109 124 } 110 125 111 //define childs for power symbols112 foreach (var symb in powerSymbols) {113 AddAllowedChildSymbol(symb, variableSymbol, 0);114 AddAllowedChildSymbol(symb, constant, 1);115 }116 117 //define child for sqrt and square118 foreach (var c in realValueSymbols) {119 AddAllowedChildSymbol(square, c, 0);120 AddAllowedChildSymbol(sqrt, c, 0);121 }122 123 //define child for aq124 foreach (var c in realValueSymbols) {125 AddAllowedChildSymbol(aq, c, 0);126 AddAllowedChildSymbol(aq, c, 1);127 }128 129 126 #endregion 130 127 131 Symbols.First(s => s is Power).Enabled = false;132 Symbols.First(s => s is Root).Enabled = false;133 Symbols.First(s => s is A nalyticQuotient).Enabled = false;128 Symbols.First(s => s is Cube).Enabled = false; 129 Symbols.First(s => s is CubeRoot).Enabled = false; 130 Symbols.First(s => s is Absolute).Enabled = false; 134 131 } 135 132 } -
trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
r17413 r17902 107 107 <Private>False</Private> 108 108 </Reference> 109 <Reference Include="HEAL.Attic, Version=1. 0.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">109 <Reference Include="HEAL.Attic, Version=1.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL"> 110 110 <SpecificVersion>False</SpecificVersion> 111 111 <HintPath>..\..\bin\HEAL.Attic.dll</HintPath> … … 157 157 <Compile Include="Formatters\SymbolicDataAnalysisExpressionCSharpFormatter.cs" /> 158 158 <Compile Include="Grammars\DataAnalysisGrammar.cs" /> 159 <Compile Include="Grammars\IntervalArithmeticGrammar.cs" /> 159 160 <Compile Include="Hashing\HashExtensions.cs" /> 160 161 <Compile Include="Hashing\HashUtil.cs" /> … … 163 164 <Compile Include="Importer\SymbolicExpressionImporter.cs" /> 164 165 <Compile Include="Importer\Token.cs" /> 166 <Compile Include="Interfaces\IBoundsEstimator.cs" /> 165 167 <Compile Include="Interfaces\IModelBacktransformator.cs" /> 166 168 <Compile Include="Interfaces\IVariableTreeNode.cs" /> … … 168 170 <Compile Include="Interpreter\BatchInstruction.cs" /> 169 171 <Compile Include="Interpreter\BatchOperations.cs" /> 172 <Compile Include="Interpreter\IntervalArithBoundsEstimator.cs" /> 173 <Compile Include="Interpreter\IntervalArithCompiledExpressionBoundsEstimator.cs" /> 170 174 <Compile Include="Interpreter\IntervalInterpreter.cs" /> 171 175 <Compile Include="Interpreter\SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs" /> 172 176 <Compile Include="Interpreter\SymbolicDataAnalysisExpressionTreeBatchInterpreter.cs" /> 173 177 <Compile Include="Interpreter\SymbolicDataAnalysisExpressionTreeNativeInterpreter.cs" /> 178 <Compile Include="IntervalUtil.cs" /> 174 179 <Compile Include="Selectors\DiversitySelector.cs" /> 175 180 <Compile Include="SymbolicDataAnalysisExpressionTreeAverageSimilarityCalculator.cs" /> -
trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs
r17180 r17902 64 64 } 65 65 66 private class Symbol NameComparer : IEqualityComparer<ISymbol>, IComparer<ISymbol> {66 private class SymbolComparer : IEqualityComparer<ISymbol>, IComparer<ISymbol> { 67 67 public int Compare(ISymbol x, ISymbol y) { 68 68 return x.Name.CompareTo(y.Name); … … 70 70 71 71 public bool Equals(ISymbol x, ISymbol y) { 72 return Compare(x, y) == 0;72 return x.GetType() == y.GetType(); 73 73 } 74 74 75 75 public int GetHashCode(ISymbol obj) { 76 return obj. Name.GetHashCode();76 return obj.GetType().GetHashCode(); 77 77 } 78 78 } … … 80 80 // the lookup table is also used in the corresponding formatter 81 81 internal static readonly BidirectionalLookup<string, ISymbol> 82 knownSymbols = new BidirectionalLookup<string, ISymbol>(StringComparer.InvariantCulture, new Symbol NameComparer());82 knownSymbols = new BidirectionalLookup<string, ISymbol>(StringComparer.InvariantCulture, new SymbolComparer()); 83 83 84 84 private Constant constant = new Constant(); -
trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/IBoundsEstimator.cs
r17884 r17902 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 1 using System.Collections.Generic; 6 2 using HEAL.Attic; 7 3 using HeuristicLab.Core; 8 4 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 9 5 10 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {6 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 11 7 [StorableType("C94A360D-5A9F-48A3-A6D3-CF920C77E50D")] 12 8 public interface IBoundsEstimator : INamedItem, IStatefulItem { 13 9 Interval GetModelBound(ISymbolicExpressionTree tree, IntervalCollection variableRanges); 14 10 15 IDictionary<ISymbolicExpressionTreeNode, Interval> GetModelNode sBounds(11 IDictionary<ISymbolicExpressionTreeNode, Interval> GetModelNodeBounds( 16 12 ISymbolicExpressionTree tree, IntervalCollection variableRanges); 17 13 18 double CheckConstraint( 19 ISymbolicExpressionTree tree, IntervalCollection variableRanges, IntervalConstraint constraint); 14 // returns the size of the violation which is the distance to one of the bounds 15 double GetConstraintViolation( 16 ISymbolicExpressionTree tree, IntervalCollection variableRanges, ShapeConstraint constraint); 20 17 21 18 bool IsCompatible(ISymbolicExpressionTree tree); 22 19 23 20 int EvaluatedSolutions { get; set; } 24 21 } 25 22 } -
trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalInterpreter.cs
r17579 r17902 1 1 #region License Information 2 2 3 /* HeuristicLab 3 4 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL) … … 18 19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>. 19 20 */ 21 20 22 #endregion 21 23 … … 32 34 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 33 35 [StorableType("DE6C1E1E-D7C1-4070-847E-63B68562B10C")] 34 [Item("IntervalInterpreter", "Int perter for calculation of intervals of symbolic models.")]36 [Item("IntervalInterpreter", "Interpreter for calculation of intervals of symbolic models.")] 35 37 public sealed class IntervalInterpreter : ParameterizedNamedItem, IStatefulItem { 36 37 38 private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions"; 38 39 public IFixedValueParameter<IntValue> EvaluatedSolutionsParameter { 40 get { return (IFixedValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; } 41 } 39 public IFixedValueParameter<IntValue> EvaluatedSolutionsParameter => 40 (IFixedValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; 42 41 43 42 public int EvaluatedSolutions { 44 get { return EvaluatedSolutionsParameter.Value.Value; }45 set { EvaluatedSolutionsParameter.Value.Value = value; }43 get => EvaluatedSolutionsParameter.Value.Value; 44 set => EvaluatedSolutionsParameter.Value.Value = value; 46 45 } 47 46 48 47 [StorableConstructor] 49 48 private IntervalInterpreter(StorableConstructorFlag _) : base(_) { } 49 50 50 private IntervalInterpreter(IntervalInterpreter original, Cloner cloner) 51 51 : base(original, cloner) { } 52 52 53 53 public IntervalInterpreter() 54 : base("IntervalInterpreter", "Intperter for calculation of intervals of symbolic models.") { 55 Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0))); 54 : base("IntervalInterpreter", "Interpreter for calculation of intervals of symbolic models.") { 55 Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, 56 "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0))); 56 57 } 57 58 … … 63 64 64 65 #region IStatefulItem Members 66 65 67 public void InitializeState() { 66 68 EvaluatedSolutions = 0; 67 69 } 70 68 71 public void ClearState() { } 72 69 73 #endregion 70 74 71 public Interval GetSymbolicExpressionTreeInterval(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows = null) { 75 public Interval GetSymbolicExpressionTreeInterval( 76 ISymbolicExpressionTree tree, IDataset dataset, 77 IEnumerable<int> rows = null) { 72 78 var variableRanges = DatasetUtil.GetVariableRanges(dataset, rows); 73 79 return GetSymbolicExpressionTreeInterval(tree, variableRanges); 74 80 } 75 81 76 public Interval GetSymbolicExpressionTreeIntervals(ISymbolicExpressionTree tree, IDataset dataset, 77 out IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals, IEnumerable<int> rows = null) { 82 public Interval GetSymbolicExpressionTreeIntervals( 83 ISymbolicExpressionTree tree, IDataset dataset, 84 out IDictionary<ISymbolicExpressionTreeNode, Interval> 85 nodeIntervals, IEnumerable<int> rows = null) { 78 86 var variableRanges = DatasetUtil.GetVariableRanges(dataset, rows); 79 87 return GetSymbolicExpressionTreeIntervals(tree, variableRanges, out nodeIntervals); 80 88 } 81 89 82 public Interval GetSymbolicExpressionTreeInterval(ISymbolicExpressionTree tree, IReadOnlyDictionary<string, Interval> variableRanges) { 90 public Interval GetSymbolicExpressionTreeInterval( 91 ISymbolicExpressionTree tree, 92 IReadOnlyDictionary<string, Interval> variableRanges) { 83 93 lock (syncRoot) { 84 94 EvaluatedSolutions++; 85 95 } 86 int instructionCount = 0; 96 97 Interval outputInterval; 98 99 var instructionCount = 0; 87 100 var instructions = PrepareInterpreterState(tree, variableRanges); 88 var outputInterval = Evaluate(instructions, ref instructionCount); 89 90 // because of numerical errors the bounds might be incorrect 91 if (outputInterval.LowerBound <= outputInterval.UpperBound) 92 return outputInterval; 93 else 94 return new Interval(outputInterval.UpperBound, outputInterval.LowerBound); 95 } 96 97 98 public Interval GetSymbolicExpressionTreeIntervals(ISymbolicExpressionTree tree, 99 IReadOnlyDictionary<string, Interval> variableRanges, out IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals) { 101 outputInterval = Evaluate(instructions, ref instructionCount); 102 103 return outputInterval.LowerBound <= outputInterval.UpperBound 104 ? outputInterval 105 : new Interval(outputInterval.UpperBound, outputInterval.LowerBound); 106 } 107 108 109 public Interval GetSymbolicExpressionTreeIntervals( 110 ISymbolicExpressionTree tree, 111 IReadOnlyDictionary<string, Interval> variableRanges, 112 out IDictionary<ISymbolicExpressionTreeNode, Interval> 113 nodeIntervals) { 100 114 lock (syncRoot) { 101 115 EvaluatedSolutions++; 102 116 } 103 int instructionCount = 0; 117 104 118 var intervals = new Dictionary<ISymbolicExpressionTreeNode, Interval>(); 105 119 var instructions = PrepareInterpreterState(tree, variableRanges); 106 var outputInterval = Evaluate(instructions, ref instructionCount, intervals); 107 108 // fix incorrect intervals if necessary (could occur because of numerical errors) 120 121 Interval outputInterval; 122 var instructionCount = 0; 123 outputInterval = Evaluate(instructions, ref instructionCount, intervals); 124 109 125 nodeIntervals = new Dictionary<ISymbolicExpressionTreeNode, Interval>(); 110 126 foreach (var kvp in intervals) { … … 119 135 if (outputInterval.IsInfiniteOrUndefined || outputInterval.LowerBound <= outputInterval.UpperBound) 120 136 return outputInterval; 121 else 122 return new Interval(outputInterval.UpperBound, outputInterval.LowerBound); 123 } 124 125 126 private static Instruction[] PrepareInterpreterState(ISymbolicExpressionTree tree, IReadOnlyDictionary<string, Interval> variableRanges) { 137 138 return new Interval(outputInterval.UpperBound, outputInterval.LowerBound); 139 } 140 141 142 private static Instruction[] PrepareInterpreterState( 143 ISymbolicExpressionTree tree, 144 IReadOnlyDictionary<string, Interval> variableRanges) { 127 145 if (variableRanges == null) 128 146 throw new ArgumentNullException("No variablew ranges are present!", nameof(variableRanges)); 129 147 130 148 //Check if all variables used in the tree are present in the dataset 131 foreach (var variable in tree.IterateNodesPrefix().OfType<VariableTreeNode>().Select(n => n.VariableName).Distinct()) { 132 if (!variableRanges.ContainsKey(variable)) throw new InvalidOperationException($"No ranges for variable {variable} is present"); 133 } 134 135 Instruction[] code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode); 136 foreach (Instruction instr in code.Where(i => i.opCode == OpCodes.Variable)) { 149 foreach (var variable in tree.IterateNodesPrefix().OfType<VariableTreeNode>().Select(n => n.VariableName) 150 .Distinct()) 151 if (!variableRanges.ContainsKey(variable)) 152 throw new InvalidOperationException($"No ranges for variable {variable} is present"); 153 154 var code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode); 155 foreach (var instr in code.Where(i => i.opCode == OpCodes.Variable)) { 137 156 var variableTreeNode = (VariableTreeNode)instr.dynamicNode; 138 157 instr.data = variableRanges[variableTreeNode.VariableName]; 139 158 } 159 140 160 return code; 141 161 } 142 162 143 private Interval Evaluate(Instruction[] instructions, ref int instructionCounter, IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals = null) { 144 Instruction currentInstr = instructions[instructionCounter]; 145 //Use ref parameter, because the tree will be iterated through recursively from the left-side branch to the right side 146 //Update instructionCounter, whenever Evaluate is called 163 // Use ref parameter, because the tree will be iterated through recursively from the left-side branch to the right side 164 // Update instructionCounter, whenever Evaluate is called 165 public static Interval Evaluate( 166 Instruction[] instructions, ref int instructionCounter, 167 IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals = null, 168 IReadOnlyDictionary<string, Interval> variableIntervals = null) { 169 var currentInstr = instructions[instructionCounter]; 170 147 171 instructionCounter++; 148 Interval result = null;172 Interval result; 149 173 150 174 switch (currentInstr.opCode) { 151 //Variables, Constants, ...152 175 case OpCodes.Variable: { 153 176 var variableTreeNode = (VariableTreeNode)currentInstr.dynamicNode; 154 177 var weightInterval = new Interval(variableTreeNode.Weight, variableTreeNode.Weight); 155 var variableInterval = (Interval)currentInstr.data; 178 179 Interval variableInterval; 180 if (variableIntervals != null && variableIntervals.ContainsKey(variableTreeNode.VariableName)) 181 variableInterval = variableIntervals[variableTreeNode.VariableName]; 182 else 183 variableInterval = (Interval)currentInstr.data; 156 184 157 185 result = Interval.Multiply(variableInterval, weightInterval); … … 165 193 //Elementary arithmetic rules 166 194 case OpCodes.Add: { 167 result = Evaluate(instructions, ref instructionCounter, nodeIntervals );168 for ( inti = 1; i < currentInstr.nArguments; i++) {169 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );195 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 196 for (var i = 1; i < currentInstr.nArguments; i++) { 197 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 170 198 result = Interval.Add(result, argumentInterval); 171 199 } 200 172 201 break; 173 202 } 174 203 case OpCodes.Sub: { 175 result = Evaluate(instructions, ref instructionCounter, nodeIntervals );204 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 176 205 if (currentInstr.nArguments == 1) 177 206 result = Interval.Multiply(new Interval(-1, -1), result); 178 207 179 for ( inti = 1; i < currentInstr.nArguments; i++) {180 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );208 for (var i = 1; i < currentInstr.nArguments; i++) { 209 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 181 210 result = Interval.Subtract(result, argumentInterval); 182 211 } 212 183 213 break; 184 214 } 185 215 case OpCodes.Mul: { 186 result = Evaluate(instructions, ref instructionCounter, nodeIntervals );187 for ( inti = 1; i < currentInstr.nArguments; i++) {188 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );216 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 217 for (var i = 1; i < currentInstr.nArguments; i++) { 218 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 189 219 result = Interval.Multiply(result, argumentInterval); 190 220 } 221 191 222 break; 192 223 } 193 224 case OpCodes.Div: { 194 result = Evaluate(instructions, ref instructionCounter, nodeIntervals );225 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 195 226 if (currentInstr.nArguments == 1) 196 227 result = Interval.Divide(new Interval(1, 1), result); 197 228 198 for ( inti = 1; i < currentInstr.nArguments; i++) {199 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );229 for (var i = 1; i < currentInstr.nArguments; i++) { 230 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 200 231 result = Interval.Divide(result, argumentInterval); 201 232 } 202 break; 203 }204 //Trigonometric functions233 234 break; 235 } 205 236 case OpCodes.Sin: { 206 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );237 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 207 238 result = Interval.Sine(argumentInterval); 208 239 break; 209 240 } 210 241 case OpCodes.Cos: { 211 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );242 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 212 243 result = Interval.Cosine(argumentInterval); 213 244 break; 214 245 } 215 246 case OpCodes.Tan: { 216 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );247 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 217 248 result = Interval.Tangens(argumentInterval); 218 249 break; 219 250 } 220 251 case OpCodes.Tanh: { 221 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );252 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 222 253 result = Interval.HyperbolicTangent(argumentInterval); 223 254 break; 224 255 } 225 //Exponential functions226 256 case OpCodes.Log: { 227 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );257 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 228 258 result = Interval.Logarithm(argumentInterval); 229 259 break; 230 260 } 231 261 case OpCodes.Exp: { 232 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );262 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 233 263 result = Interval.Exponential(argumentInterval); 234 264 break; 235 265 } 236 266 case OpCodes.Square: { 237 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );267 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 238 268 result = Interval.Square(argumentInterval); 239 269 break; 240 270 } 241 271 case OpCodes.SquareRoot: { 242 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );272 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 243 273 result = Interval.SquareRoot(argumentInterval); 244 274 break; 245 275 } 246 276 case OpCodes.Cube: { 247 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );277 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 248 278 result = Interval.Cube(argumentInterval); 249 279 break; 250 280 } 251 281 case OpCodes.CubeRoot: { 252 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );282 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 253 283 result = Interval.CubicRoot(argumentInterval); 254 284 break; 255 285 } 256 286 case OpCodes.Absolute: { 257 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );287 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 258 288 result = Interval.Absolute(argumentInterval); 259 289 break; 260 290 } 261 291 case OpCodes.AnalyticQuotient: { 262 result = Evaluate(instructions, ref instructionCounter, nodeIntervals );263 for (var i = 1; i < currentInstr.nArguments; i++) { 264 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );292 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 293 for (var i = 1; i < currentInstr.nArguments; i++) { 294 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 265 295 result = Interval.AnalyticalQuotient(result, argumentInterval); 266 296 } … … 272 302 } 273 303 274 if ( nodeIntervals != null)304 if (!(nodeIntervals == null || nodeIntervals.ContainsKey(currentInstr.dynamicNode))) 275 305 nodeIntervals.Add(currentInstr.dynamicNode, result); 276 306 … … 278 308 } 279 309 310 280 311 public static bool IsCompatible(ISymbolicExpressionTree tree) { 281 var containsUnknownSy umbol= (312 var containsUnknownSymbols = ( 282 313 from n in tree.Root.GetSubtree(0).IterateNodesPrefix() 283 314 where 284 !(n.Symbol is Problems.DataAnalysis.Symbolic.Variable) &&315 !(n.Symbol is Variable) && 285 316 !(n.Symbol is Constant) && 286 317 !(n.Symbol is StartSymbol) && … … 292 323 !(n.Symbol is Cosine) && 293 324 !(n.Symbol is Tangent) && 325 !(n.Symbol is HyperbolicTangent) && 294 326 !(n.Symbol is Logarithm) && 295 327 !(n.Symbol is Exponential) && … … 301 333 !(n.Symbol is AnalyticQuotient) 302 334 select n).Any(); 303 return !containsUnknownSy umbol;335 return !containsUnknownSymbols; 304 336 } 305 337 } -
trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/IntervalUtil.cs
r17884 r17902 1 using System; 1 #region License Information 2 3 /* HeuristicLab 4 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL) 5 * 6 * This file is part of HeuristicLab. 7 * 8 * HeuristicLab is free software: you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation, either version 3 of the License, or 11 * (at your option) any later version. 12 * 13 * HeuristicLab is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>. 20 */ 21 22 #endregion 23 using System; 2 24 using System.Collections.Generic; 3 25 using System.Linq; … … 6 28 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 7 29 public static class IntervalUtil { 8 public static double IntervalConstraintViolation(9 I ntervalConstraint constraint, IBoundsEstimator estimator, IntervalCollection intervalCollection,30 public static IEnumerable<double> GetConstraintViolations( 31 IEnumerable<ShapeConstraint> constraints, IBoundsEstimator estimator, IntervalCollection intervalCollection, 10 32 ISymbolicExpressionTree solution) { 11 var variableRanges = intervalCollection.GetReadonlyDictionary(); 33 return constraints.Select(constraint => GetConstraintViolation(constraint, estimator, intervalCollection, solution)).ToList(); 34 } 12 35 13 if (constraint.Variable != null && !variableRanges.ContainsKey(constraint.Variable)) { 36 public static double GetConstraintViolation( 37 ShapeConstraint constraint, IBoundsEstimator estimator, IntervalCollection variableRanges, 38 ISymbolicExpressionTree tree) { 39 var varRanges = variableRanges.GetReadonlyDictionary(); 40 41 if (constraint.Variable != null && !varRanges.ContainsKey(constraint.Variable)) { 14 42 throw new ArgumentException( 15 43 $"The given variable {constraint.Variable} in the constraint does not exist in the model.", 16 nameof( IntervalConstraintsParser));44 nameof(constraint)); 17 45 } 18 46 19 // Create new variable ranges for defined regions47 // Create new variable ranges for defined regions 20 48 var regionRanges = new IntervalCollection(); 21 foreach (var kvp in var iableRanges) {22 if ( kvp.Key != constraint.Target &&constraint.Regions.GetReadonlyDictionary().TryGetValue(kvp.Key, out var val)) {49 foreach (var kvp in varRanges) { 50 if (constraint.Regions.GetReadonlyDictionary().TryGetValue(kvp.Key, out var val)) { 23 51 regionRanges.AddInterval(kvp.Key, val); 24 52 } else { … … 27 55 } 28 56 29 var error = 0.0;30 57 if (!constraint.IsDerivative) { 31 error = estimator.CheckConstraint(solution, regionRanges, constraint);58 return estimator.GetConstraintViolation(tree, regionRanges, constraint); 32 59 } else { 33 var tree = solution;34 60 for (var i = 0; i < constraint.NumberOfDerivations; ++i) { 35 61 if (!estimator.IsCompatible(tree) || !DerivativeCalculator.IsCompatible(tree)) { 36 throw new ArgumentException(" Cube, Root, Power symbols are not supported.");62 throw new ArgumentException("The tree contains an unsupported symbol."); 37 63 } 38 64 … … 40 66 } 41 67 42 error = estimator.CheckConstraint(tree, regionRanges, constraint);68 return estimator.GetConstraintViolation(tree, regionRanges, constraint); 43 69 } 44 45 return error;46 }47 48 public static IEnumerable<double> IntervalConstraintsViolation(49 IEnumerable<IntervalConstraint> constraints, IBoundsEstimator estimator, IntervalCollection intervalCollection,50 ISymbolicExpressionTree solution) {51 return constraints.Select(constraint => IntervalConstraintViolation(constraint, estimator, intervalCollection, solution)).ToList();52 70 } 53 71 }
Note: See TracChangeset
for help on using the changeset viewer.