#region License Information /* HeuristicLab * Copyright (C) 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.Collections.Generic; using System.Linq; using HEAL.Attic; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; using DoubleVector = MathNet.Numerics.LinearAlgebra.Vector; namespace HeuristicLab.Problems.DataAnalysis.Symbolic { [StorableType("C913F5C6-AF16-4F2C-BA93-2D5AE1F8E68A")] [Item("FullFunctionalVectorExpressionGrammar", "Represents a grammar for functional expressions using all available functions.")] public class FullFunctionalVectorExpressionGrammar : DataAnalysisGrammar, ISymbolicDataAnalysisGrammar { [StorableConstructor] protected FullFunctionalVectorExpressionGrammar(StorableConstructorFlag _) : base(_) { } protected FullFunctionalVectorExpressionGrammar(FullFunctionalVectorExpressionGrammar original, Cloner cloner) : base(original, cloner) { } public FullFunctionalVectorExpressionGrammar() : base(ItemAttribute.GetName(typeof(FullFunctionalVectorExpressionGrammar)), ItemAttribute.GetDescription(typeof(FullFunctionalVectorExpressionGrammar))) { Initialize(); } public override IDeepCloneable Clone(Cloner cloner) { return new FullFunctionalVectorExpressionGrammar(this, cloner); } private void Initialize() { var add = new Addition(); var sub = new Subtraction(); var mul = new Multiplication(); var div = new Division(); var sin = new Sine(); var cos = new Cosine(); var tan = new Tangent(); var log = new Logarithm(); var exp = new Exponential(); var pow = new Power { InitialFrequency = 0.0 }; var root = new Root { InitialFrequency = 0.0 }; var square = new Square { InitialFrequency = 0.0 }; var sqrt = new SquareRoot { InitialFrequency = 0.0 }; var cube = new Cube { InitialFrequency = 0.0 }; var cubeRoot = new CubeRoot { InitialFrequency = 0.0 }; var constant = new Constant { MinValue = -20, MaxValue = 20 }; var variable = new Variable(); var binFactorVariable = new BinaryFactorVariable(); var factorVariable = new FactorVariable(); var vectorVariable = new Variable() { Name = "Vector Variable" }; var sum = new Sum(); var mean = new Average() { Name = "Mean" }; var allSymbols = new List() { add, sub, mul, div, sin, cos, tan, log, exp, square, sqrt, cube, cubeRoot, pow, root, constant, variable, binFactorVariable, factorVariable, vectorVariable, sum, mean }; var unaryFunctionSymbols = new List() { sin, cos, tan, log, exp }; var binaryFunctionSymbols = new List() { pow, root }; var ternarySymbols = new List() { add, sub, mul, div }; var terminalSymbols = new List() { variable, binFactorVariable, factorVariable, vectorVariable, constant }; var aggregationSymbols = new List() { sum, mean }; foreach (var symb in allSymbols) AddSymbol(symb); foreach (var funSymb in ternarySymbols) { SetSubtreeCount(funSymb, 1, 3); } foreach (var funSymb in unaryFunctionSymbols) { SetSubtreeCount(funSymb, 1, 1); } foreach (var funSymb in binaryFunctionSymbols) { SetSubtreeCount(funSymb, 2, 2); } foreach (var terminalSymbol in terminalSymbols) { SetSubtreeCount(terminalSymbol, 0, 0); } foreach (var aggrSymb in aggregationSymbols) { SetSubtreeCount(aggrSymb, 1, 1); } // allow each symbol as child of the start symbol foreach (var symb in allSymbols) { AddAllowedChildSymbol(StartSymbol, symb); AddAllowedChildSymbol(DefunSymbol, symb); } // allow each symbol as child of every other symbol (except for terminals that have maxSubtreeCount == 0) foreach (var parent in allSymbols.Except(terminalSymbols)) { foreach (var child in allSymbols) AddAllowedChildSymbol(parent, child); } } public override void ConfigureVariableSymbols(IDataAnalysisProblemData problemData) { base.ConfigureVariableSymbols(problemData); var dataset = problemData.Dataset; foreach (var varSymbol in Symbols.OfType().Where(sym => sym.Name == "Variable")) { if (!varSymbol.Fixed) { varSymbol.AllVariableNames = problemData.InputVariables.Select(x => x.Value).Where(x => dataset.VariableHasType(x)); varSymbol.VariableNames = problemData.AllowedInputVariables.Where(x => dataset.VariableHasType(x)); } } foreach (var varSymbol in Symbols.OfType().Where(sym => sym.Name == "Vector Variable")) { if (!varSymbol.Fixed) { varSymbol.AllVariableNames = problemData.InputVariables.Select(x => x.Value).Where(x => dataset.VariableHasType(x)); varSymbol.VariableNames = problemData.AllowedInputVariables.Where(x => dataset.VariableHasType(x)); } } } } }