- Timestamp:
- 05/07/08 00:02:43 (17 years ago)
- Location:
- branches/ExperimentalFunctionsBaking
- Files:
-
- 26 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified branches/ExperimentalFunctionsBaking/Addition.cs ¶
r203 r220 30 30 31 31 namespace HeuristicLab.Functions { 32 public class Addition : FunctionBase {32 public sealed class Addition : FunctionBase { 33 33 public override string Description { 34 34 get { … … 46 46 } 47 47 48 public static double Add(double[] args) {49 // (+ 3) => 350 // (+ 2 3) => 551 // (+ 3 4 5) => 1252 double sum = 0.0;53 for (int i = 0; i < args.Length; i++) {54 sum += args[i];55 }56 return sum;57 }58 59 public override double Apply(Dataset dataset, int sampleIndex, double[] args) {60 return Addition.Add(args);61 }62 63 48 public override void Accept(IFunctionVisitor visitor) { 64 49 visitor.Visit(this); -
TabularUnified branches/ExperimentalFunctionsBaking/And.cs ¶
r192 r220 28 28 29 29 namespace HeuristicLab.Functions { 30 public class And : FunctionBase {30 public sealed class And : FunctionBase { 31 31 public override string Description { 32 32 get { … … 42 42 } 43 43 44 public override IFunctionTree GetTreeNode() {45 return new AndFunctionTree(this);46 }47 48 // special form49 public override double Apply(Dataset dataset, int sampleIndex, double[] args) {50 throw new NotImplementedException();51 }52 53 44 public override void Accept(IFunctionVisitor visitor) { 54 45 visitor.Visit(this); 55 46 } 56 47 } 57 58 class AndFunctionTree : FunctionTree {59 public AndFunctionTree() : base() { }60 public AndFunctionTree(And and) : base(and) { }61 62 public override double Evaluate(Dataset dataset, int sampleIndex) {63 foreach(IFunctionTree subTree in SubTrees) {64 double result = Math.Round(subTree.Evaluate(dataset, sampleIndex));65 if(result == 0.0) return 0.0; // one sub-tree is 0.0 (false) => return false66 else if(result != 1.0) return double.NaN;67 }68 // all sub-trees evaluated to 1.0 (true) => return 1.0 (true)69 return 1.0;70 }71 72 public override object Clone(IDictionary<Guid, object> clonedObjects) {73 AndFunctionTree clone = new AndFunctionTree();74 clonedObjects.Add(clone.Guid, clone);75 FillClone(clone, clonedObjects);76 return clone;77 }78 }79 48 } -
TabularUnified branches/ExperimentalFunctionsBaking/Average.cs ¶
r155 r220 28 28 29 29 namespace HeuristicLab.Functions { 30 public class Average : FunctionBase {30 public sealed class Average : FunctionBase { 31 31 public override string Description { 32 32 get { … … 40 40 } 41 41 42 public override double Apply(Dataset dataset, int sampleIndex, double[] args) {43 double sum = 0.0;44 for(int i = 0; i < args.Length; i++) {45 sum += args[i];46 }47 return sum / args.Length;48 }49 50 42 public override void Accept(IFunctionVisitor visitor) { 51 43 visitor.Visit(this); -
TabularUnified branches/ExperimentalFunctionsBaking/BakedFunctionTree.cs ¶
r208 r220 30 30 namespace HeuristicLab.Functions { 31 31 class BakedFunctionTree : ItemBase, IFunctionTree { 32 private List<double> code; 33 private static double nextFunctionSymbol = 10000; 34 private static Dictionary<double, IFunction> symbolTable = new Dictionary<double, IFunction>(); 35 private static Dictionary<IFunction, double> reverseSymbolTable = new Dictionary<IFunction, double>(); 36 private static double additionSymbol = -1; 37 private static double substractionSymbol = -1; 38 private static double multiplicationSymbol = -1; 39 private static double divisionSymbol = -1; 40 private static double variableSymbol = -1; 41 private static double constantSymbol = -1; 32 private List<int> code; 33 private List<double> data; 34 private const int ADDITION = 10010; 35 private const int AND = 10020; 36 private const int AVERAGE = 10030; 37 private const int CONSTANT = 10040; 38 private const int COSINUS = 10050; 39 private const int DIVISION = 10060; 40 private const int EQU = 10070; 41 private const int EXP = 10080; 42 private const int GT = 10090; 43 private const int IFTE = 10100; 44 private const int LT = 10110; 45 private const int LOG = 10120; 46 private const int MULTIPLICATION = 10130; 47 private const int NOT = 10140; 48 private const int OR = 10150; 49 private const int POWER = 10160; 50 private const int SIGNUM = 10170; 51 private const int SINUS = 10180; 52 private const int SQRT = 10190; 53 private const int SUBSTRACTION = 10200; 54 private const int TANGENS = 10210; 55 private const int VARIABLE = 10220; 56 private const int XOR = 10230; 57 58 private static int nextFunctionSymbol = 10240; 59 private static Dictionary<int, IFunction> symbolTable; 60 private static Dictionary<IFunction, int> reverseSymbolTable; 61 private static Dictionary<Type, int> staticTypes; 62 63 static BakedFunctionTree() { 64 symbolTable = new Dictionary<int, IFunction>(); 65 reverseSymbolTable = new Dictionary<IFunction, int>(); 66 staticTypes = new Dictionary<Type, int>(); 67 staticTypes[typeof(Addition)] = ADDITION; 68 staticTypes[typeof(And)] = AND; 69 staticTypes[typeof(Average)] = AVERAGE; 70 staticTypes[typeof(Constant)] = CONSTANT; 71 staticTypes[typeof(Cosinus)] = COSINUS; 72 staticTypes[typeof(Division)] = DIVISION; 73 staticTypes[typeof(Equal)] = EQU; 74 staticTypes[typeof(Exponential)] = EXP; 75 staticTypes[typeof(GreaterThan)] = GT; 76 staticTypes[typeof(IfThenElse)] = IFTE; 77 staticTypes[typeof(LessThan)] = LT; 78 staticTypes[typeof(Logarithm)] = LOG; 79 staticTypes[typeof(Multiplication)] = MULTIPLICATION; 80 staticTypes[typeof(Not)] = NOT; 81 staticTypes[typeof(Or)] = OR; 82 staticTypes[typeof(Power)] = POWER; 83 staticTypes[typeof(Signum)] = SIGNUM; 84 staticTypes[typeof(Sinus)] = SINUS; 85 staticTypes[typeof(Sqrt)] = SQRT; 86 staticTypes[typeof(Substraction)] = SUBSTRACTION; 87 staticTypes[typeof(Tangens)] = TANGENS; 88 staticTypes[typeof(Variable)] = VARIABLE; 89 staticTypes[typeof(Xor)] = XOR; 90 } 42 91 43 92 internal BakedFunctionTree() { 44 code = new List<double>(); 93 code = new List<int>(); 94 data = new List<double>(); 45 95 } 46 96 … … 65 115 code.Add(0); 66 116 code.Add(MapFunction(tree.Function)); 67 code.Add( (byte)tree.LocalVariables.Count);117 code.Add(tree.LocalVariables.Count); 68 118 foreach(IVariable variable in tree.LocalVariables) { 69 119 IItem value = variable.Value; 70 code.Add(GetDoubleValue(value));120 data.Add(GetDoubleValue(value)); 71 121 } 72 122 foreach(IFunctionTree subTree in tree.SubTrees) { … … 87 137 } 88 138 89 private doubleMapFunction(IFunction function) {139 private int MapFunction(IFunction function) { 90 140 if(!reverseSymbolTable.ContainsKey(function)) { 91 reverseSymbolTable[function] = nextFunctionSymbol; 92 symbolTable[nextFunctionSymbol] = function; 93 if(function is Variable) { 94 variableSymbol = nextFunctionSymbol; 95 } else if(function is Constant) { 96 constantSymbol = nextFunctionSymbol; 97 } else if(function is Addition) { 98 additionSymbol = nextFunctionSymbol; 99 } else if(function is Substraction) { 100 substractionSymbol = nextFunctionSymbol; 101 } else if(function is Multiplication) { 102 multiplicationSymbol = nextFunctionSymbol; 103 } else if(function is Division) { 104 divisionSymbol = nextFunctionSymbol; 105 } else throw new NotSupportedException("Unsupported function " + function); 106 107 nextFunctionSymbol++; 141 int curFunctionSymbol; 142 if(staticTypes.ContainsKey(function.GetType())) curFunctionSymbol = staticTypes[function.GetType()]; 143 else { 144 curFunctionSymbol = nextFunctionSymbol; 145 nextFunctionSymbol++; 146 } 147 reverseSymbolTable[function] = curFunctionSymbol; 148 symbolTable[curFunctionSymbol] = function; 108 149 } 109 150 return reverseSymbolTable[function]; 110 151 } 111 152 112 private int BranchLength(int branchRoot) { 113 double arity = code[branchRoot]; 114 int nLocalVariables = (int)code[branchRoot + 2]; 115 int len = 3 + nLocalVariables; 116 int subBranchStart = branchRoot + len; 153 private void BranchLength(int branchRoot, out int codeLength, out int dataLength) { 154 int arity = code[branchRoot]; 155 int nLocalVariables = code[branchRoot + 2]; 156 codeLength = 3; 157 dataLength = nLocalVariables; 158 int subBranchStart = branchRoot + codeLength; 117 159 for(int i = 0; i < arity; i++) { 118 int branchLen = BranchLength(subBranchStart); 119 len += branchLen; 120 subBranchStart += branchLen; 121 } 122 return len; 160 int branchCodeLength; 161 int branchDataLength; 162 BranchLength(subBranchStart, out branchCodeLength, out branchDataLength); 163 subBranchStart += branchCodeLength; 164 codeLength += branchCodeLength; 165 dataLength += branchDataLength; 166 } 123 167 } 124 168 … … 130 174 subTree.FlattenTrees(); 131 175 code.AddRange(subTree.code); 176 data.AddRange(subTree.data); 132 177 } 133 178 treesExpanded = false; … … 139 184 if(variablesExpanded) { 140 185 code[2] = variables.Count; 141 int localVariableIndex = 3;142 186 foreach(IVariable variable in variables) { 143 code.Insert(localVariableIndex, GetDoubleValue(variable.Value)); 144 localVariableIndex++; 187 data.Add(GetDoubleValue(variable.Value)); 145 188 } 146 189 variablesExpanded = false; … … 155 198 if(!treesExpanded) { 156 199 subTrees = new List<IFunctionTree>(); 157 double arity = code[0]; 158 int nLocalVariables = (int)code[2]; 159 int branchIndex = 3 + nLocalVariables; 200 int arity = code[0]; 201 int nLocalVariables = code[2]; 202 int branchIndex = 3; 203 int dataIndex = nLocalVariables; // skip my local variables to reach the local variables of the first branch 160 204 for(int i = 0; i < arity; i++) { 161 205 BakedFunctionTree subTree = new BakedFunctionTree(); 162 int branchLen = BranchLength(branchIndex); 163 subTree.code = code.GetRange(branchIndex, branchLen); 164 branchIndex += branchLen; 206 int codeLength; 207 int dataLength; 208 BranchLength(branchIndex, out codeLength, out dataLength); 209 subTree.code = code.GetRange(branchIndex, codeLength); 210 subTree.data = data.GetRange(dataIndex, dataLength); 211 branchIndex += codeLength; 212 dataIndex += dataLength; 165 213 subTrees.Add(subTree); 166 214 } 167 215 treesExpanded = true; 168 code.RemoveRange(3 + nLocalVariables, code.Count - (3 + nLocalVariables));216 code.RemoveRange(3, code.Count - 3); 169 217 code[0] = 0; 218 data.RemoveRange(nLocalVariables, data.Count - nLocalVariables); 170 219 } 171 220 return subTrees; … … 180 229 variables = new List<IVariable>(); 181 230 IFunction function = symbolTable[code[1]]; 182 int localVariableIndex = 3;231 int localVariableIndex = 0; 183 232 foreach(IVariableInfo variableInfo in function.VariableInfos) { 184 233 if(variableInfo.Local) { … … 186 235 IItem value = clone.Value; 187 236 if(value is ConstrainedDoubleData) { 188 ((ConstrainedDoubleData)value).Data = code[localVariableIndex];237 ((ConstrainedDoubleData)value).Data = data[localVariableIndex]; 189 238 } else if(value is ConstrainedIntData) { 190 ((ConstrainedIntData)value).Data = (int) code[localVariableIndex];239 ((ConstrainedIntData)value).Data = (int)data[localVariableIndex]; 191 240 } else if(value is DoubleData) { 192 ((DoubleData)value).Data = code[localVariableIndex];241 ((DoubleData)value).Data = data[localVariableIndex]; 193 242 } else if(value is IntData) { 194 ((IntData)value).Data = (int) code[localVariableIndex];243 ((IntData)value).Data = (int)data[localVariableIndex]; 195 244 } else throw new NotSupportedException("Invalid local variable type for GP."); 196 245 variables.Add(clone); … … 200 249 variablesExpanded = true; 201 250 code[2] = 0; 202 code.RemoveRange(3, variables.Count);251 data.RemoveRange(0, variables.Count); 203 252 } 204 253 return variables; … … 211 260 212 261 public IVariable GetLocalVariable(string name) { 213 throw new NotImplementedException(); 262 foreach(IVariable var in LocalVariables) { 263 if(var.Name == name) return var; 264 } 265 return null; 214 266 } 215 267 216 268 public void AddVariable(IVariable variable) { 217 throw new Not ImplementedException();269 throw new NotSupportedException(); 218 270 } 219 271 220 272 public void RemoveVariable(string name) { 221 throw new Not ImplementedException();273 throw new NotSupportedException(); 222 274 } 223 275 224 276 public void AddSubTree(IFunctionTree tree) { 225 if(treesExpanded) { 226 subTrees.Add(tree); 227 } else { 228 //code.AddRange(((BakedFunctionTree)tree).code); 229 //code[0] = code[0] + 1; 230 throw new NotImplementedException(); 231 } 277 if(!treesExpanded) throw new InvalidOperationException(); 278 subTrees.Add(tree); 232 279 } 233 280 234 281 public void InsertSubTree(int index, IFunctionTree tree) { 235 if(treesExpanded) { 236 subTrees.Insert(index, tree); 237 } else { 238 //byte nLocalVariables = code[2]; 239 //// skip branches 240 //int currentBranchIndex = 3 + nLocalVariables; 241 //for(int i = 0; i < index; i++) { 242 // int branchLength = BranchLength(currentBranchIndex); 243 // currentBranchIndex += branchLength; 244 //} 245 246 //code.InsertRange(currentBranchIndex, ((BakedFunctionTree)tree).code); 247 //code[0] = code[0] + 1; 248 249 throw new NotImplementedException(); 250 } 282 if(!treesExpanded) throw new InvalidOperationException(); 283 subTrees.Insert(index, tree); 251 284 } 252 285 253 286 public void RemoveSubTree(int index) { 254 if(treesExpanded) { 255 subTrees.RemoveAt(index); 256 } else { 257 //int nLocalVariables = (int)code[2]; 258 //// skip branches 259 //int currentBranchIndex = 3 + nLocalVariables; 260 //for(int i = 0; i < index; i++) { 261 // int branchLength = BranchLength(currentBranchIndex); 262 // currentBranchIndex += branchLength; 263 //} 264 //int deletedBranchLength = BranchLength(currentBranchIndex); 265 //code.RemoveRange(currentBranchIndex, deletedBranchLength); 266 //code[0] = code[0] - 1; 267 throw new NotImplementedException(); 268 } 287 // sanity check 288 if(!treesExpanded) throw new InvalidOperationException(); 289 subTrees.RemoveAt(index); 269 290 } 270 291 271 292 private int PC; 272 private double[] codeArr; 293 private int DP; 294 private int[] codeArr; 295 private double[] dataArr; 296 private Dataset dataset; 297 private int sampleIndex; 273 298 public double Evaluate(Dataset dataset, int sampleIndex) { 274 299 PC = 0; 300 DP = 0; 275 301 FlattenVariables(); 276 302 FlattenTrees(); 277 303 if(codeArr == null) { 278 codeArr = new double[code.Count]; 304 codeArr = new int[code.Count]; 305 dataArr = new double[data.Count]; 279 306 code.CopyTo(codeArr); 280 } 281 return EvaluateBakedCode(dataset, sampleIndex); 282 } 283 284 private double EvaluateBakedCode(Dataset dataset, int sampleIndex) { 285 double arity = codeArr[PC++]; 286 double functionSymbol = codeArr[PC++]; 287 double nLocalVariables = codeArr[PC++]; 288 if(functionSymbol == variableSymbol) { 289 int var = (int)codeArr[PC++]; 290 double weight = codeArr[PC++]; 291 int offset = (int)codeArr[PC++]; 292 return weight * dataset.GetValue(sampleIndex+offset, var); 293 } else if(functionSymbol == constantSymbol) { 294 double value = codeArr[PC++]; 295 return value; 296 } else if(functionSymbol == additionSymbol) { 297 double sum = 0.0; 298 for(int i = 0; i < arity; i++) { 299 sum += EvaluateBakedCode(dataset, sampleIndex); 300 } 301 return sum; 302 } else if(functionSymbol == substractionSymbol) { 303 if(arity == 1) { 304 return -EvaluateBakedCode(dataset, sampleIndex); 305 } else { 306 double result = EvaluateBakedCode(dataset, sampleIndex); 307 for(int i = 1; i < arity; i++) { 308 result -= EvaluateBakedCode(dataset, sampleIndex); 309 } 310 return result; 311 } 312 } else if(functionSymbol == multiplicationSymbol) { 313 double result = 1.0; 314 for(int i = 0; i < arity; i++) { 315 result *= EvaluateBakedCode(dataset, sampleIndex); 316 } 317 return result; 318 } else if(functionSymbol == divisionSymbol) { 319 if(arity == 1) { 320 double divisor = EvaluateBakedCode(dataset, sampleIndex); 321 if(divisor == 0) return 0; 322 else return 1.0 / divisor; 323 } else { 324 double result = EvaluateBakedCode(dataset, sampleIndex); 325 for(int i = 1; i < arity; i++) { 326 double divisor = EvaluateBakedCode(dataset, sampleIndex); 327 if(divisor == 0) result = 0; 328 else result /= divisor; 329 } 330 return result; 331 } 332 } else { throw new NotSupportedException(); } 307 data.CopyTo(dataArr); 308 } 309 this.sampleIndex = sampleIndex; 310 this.dataset = dataset; 311 return EvaluateBakedCode(); 312 } 313 314 private double EvaluateBakedCode() { 315 int arity = codeArr[PC++]; 316 int functionSymbol = codeArr[PC++]; 317 int nLocalVariables = codeArr[PC++]; 318 switch(functionSymbol) { 319 case VARIABLE: { 320 int var = (int)dataArr[DP++]; 321 double weight = dataArr[DP++]; 322 int offset = (int)dataArr[DP++]; 323 return weight * dataset.GetValue(sampleIndex + offset, var); 324 } 325 case CONSTANT: { 326 double value = dataArr[DP++]; 327 return value; 328 } 329 case MULTIPLICATION: { 330 double result = 1.0; 331 for(int i = 0; i < arity; i++) { 332 result *= EvaluateBakedCode(); 333 } 334 return result; 335 } 336 case ADDITION: { 337 double sum = 0.0; 338 for(int i = 0; i < arity; i++) { 339 sum += EvaluateBakedCode(); 340 } 341 return sum; 342 } 343 case SUBSTRACTION: { 344 if(arity == 1) { 345 return -EvaluateBakedCode(); 346 } else { 347 double result = EvaluateBakedCode(); 348 for(int i = 1; i < arity; i++) { 349 result -= EvaluateBakedCode(); 350 } 351 return result; 352 } 353 } 354 case DIVISION: { 355 if(arity == 1) { 356 double divisor = EvaluateBakedCode(); 357 if(divisor == 0) return 0; 358 else return 1.0 / divisor; 359 } else { 360 double result = EvaluateBakedCode(); 361 for(int i = 1; i < arity; i++) { 362 double divisor = EvaluateBakedCode(); 363 if(divisor == 0) result = 0; 364 else result /= divisor; 365 } 366 return result; 367 } 368 } 369 case AVERAGE: { 370 double sum = 0.0; 371 for(int i = 0; i < arity; i++) { 372 sum += EvaluateBakedCode(); 373 } 374 return sum / arity; 375 } 376 case COSINUS: { 377 return Math.Cos(EvaluateBakedCode()); 378 } 379 case SINUS: { 380 return Math.Sin(EvaluateBakedCode()); 381 } 382 case EXP: { 383 return Math.Exp(EvaluateBakedCode()); 384 } 385 case LOG: { 386 return Math.Log(EvaluateBakedCode()); 387 } 388 case POWER: { 389 double x = EvaluateBakedCode(); 390 double p = EvaluateBakedCode(); 391 return Math.Pow(x, p); 392 } 393 case SIGNUM: { 394 // protected signum 395 double value = EvaluateBakedCode(); 396 if(value < 0) return -1; 397 if(value > 0) return 1; 398 return 0; 399 } 400 case SQRT: { 401 return Math.Sqrt(EvaluateBakedCode()); 402 } 403 case TANGENS: { 404 return Math.Tan(EvaluateBakedCode()); 405 } 406 case AND: { 407 double result = 1.0; 408 // have to evaluate all sub-trees, skipping would probably not lead to a big gain because 409 // we have to iterate over the linear structure anyway 410 for(int i = 0; i < arity; i++) { 411 double x = Math.Round(EvaluateBakedCode()); 412 if(x == 0) result *= 0; 413 else if(x == 1.0) result *= 1.0; 414 else result *= double.NaN; 415 } 416 return result; 417 } 418 case EQU: { 419 double x = EvaluateBakedCode(); 420 double y = EvaluateBakedCode(); 421 if(x == y) return 1.0; else return 0.0; 422 } 423 case GT: { 424 double x = EvaluateBakedCode(); 425 double y = EvaluateBakedCode(); 426 if(x > y) return 1.0; 427 else return 0.0; 428 } 429 case IFTE: { 430 double condition = Math.Round(EvaluateBakedCode()); 431 double x = EvaluateBakedCode(); 432 double y = EvaluateBakedCode(); 433 if(condition < .5) return x; 434 else if(condition >= .5) return y; 435 else return double.NaN; 436 } 437 case LT: { 438 double x = EvaluateBakedCode(); 439 double y = EvaluateBakedCode(); 440 if(x < y) return 1.0; 441 else return 0.0; 442 } 443 case NOT: { 444 double result = Math.Round(EvaluateBakedCode()); 445 if(result == 0.0) return 1.0; 446 else if(result == 1.0) return 0.0; 447 else return double.NaN; 448 } 449 case OR: { 450 double result = 0.0; // default is false 451 for(int i = 0; i < arity; i++) { 452 double x = Math.Round(EvaluateBakedCode()); 453 if(x == 1.0 && result == 0.0) result = 1.0; // found first true (1.0) => set to true 454 else if(x != 0.0) result = double.NaN; // if it was not true it can only be false (0.0) all other cases are undefined => (NaN) 455 } 456 return result; 457 } 458 case XOR: { 459 double x = Math.Round(EvaluateBakedCode()); 460 double y = Math.Round(EvaluateBakedCode()); 461 if(x == 0.0 && y == 0.0) return 0.0; 462 if(x == 1.0 && y == 0.0) return 1.0; 463 if(x == 0.0 && y == 1.0) return 1.0; 464 if(x == 1.0 && y == 1.0) return 0.0; 465 return double.NaN; 466 } 467 default: { 468 IFunction function = symbolTable[functionSymbol]; 469 double[] args = new double[nLocalVariables + arity]; 470 for(int i = 0; i < nLocalVariables; i++) { 471 args[i] = dataArr[DP++]; 472 } 473 for(int j = 0; j < arity; j++) { 474 args[nLocalVariables + j] = EvaluateBakedCode(); 475 } 476 return function.Apply(dataset, sampleIndex, args); 477 } 478 } 333 479 } 334 480 … … 343 489 public override object Clone(IDictionary<Guid, object> clonedObjects) { 344 490 BakedFunctionTree clone = new BakedFunctionTree(); 345 if(treesExpanded || variablesExpanded) throw new InvalidOperationException(); 346 //if(treesExpanded) FlattenTrees(); 347 //if(variablesExpanded) FlattenVariables(); 348 clone.code = new List<double>(code); 491 if(treesExpanded || variablesExpanded) throw new InvalidOperationException(); // sanity check 492 clone.code.AddRange(code); 493 clone.data.AddRange(data); 349 494 return clone; 495 } 496 497 public override IView CreateView() { 498 return new FunctionTreeView(this); 350 499 } 351 500 } -
TabularUnified branches/ExperimentalFunctionsBaking/Constant.cs ¶
r201 r220 30 30 31 31 namespace HeuristicLab.Functions { 32 public class Constant : FunctionBase {32 public sealed class Constant : FunctionBase { 33 33 public const string VALUE = "Value"; 34 34 … … 51 51 AddConstraint(new NumberOfSubOperatorsConstraint(0, 0)); 52 52 } 53 54 //public override IFunctionTree GetTreeNode() {55 // return new ConstantFunctionTree(this);56 //}57 58 // can't apply a constant59 public override double Apply(Dataset dataset, int sampleIndex, double[] args) {60 throw new NotSupportedException();61 }62 63 53 public override void Accept(IFunctionVisitor visitor) { 64 54 visitor.Visit(this); 65 55 } 66 56 } 67 68 class ConstantFunctionTree : FunctionTree {69 private ConstrainedDoubleData value;70 public ConstantFunctionTree() : base() { }71 public ConstantFunctionTree(Constant constant) : base(constant) {72 UpdateCachedValues();73 }74 75 private void UpdateCachedValues() {76 value = (ConstrainedDoubleData)GetLocalVariable(Constant.VALUE).Value;77 }78 79 public override double Evaluate(Dataset dataset, int sampleIndex) {80 return value.Data;81 }82 83 public override object Clone(IDictionary<Guid, object> clonedObjects) {84 ConstantFunctionTree clone = new ConstantFunctionTree();85 clonedObjects.Add(clone.Guid, clone);86 FillClone(clone, clonedObjects);87 clone.UpdateCachedValues();88 return clone;89 }90 91 public override void Populate(System.Xml.XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {92 base.Populate(node, restoredObjects);93 UpdateCachedValues();94 }95 }96 57 } -
TabularUnified branches/ExperimentalFunctionsBaking/Cosinus.cs ¶
r155 r220 29 29 30 30 namespace HeuristicLab.Functions { 31 public class Cosinus : FunctionBase {31 public sealed class Cosinus : FunctionBase { 32 32 public override string Description { 33 33 get { return "Returns the cosinus of the first sub-tree."; } … … 40 40 } 41 41 42 public override double Apply(Dataset dataset, int sampleIndex, double[] args) {43 return Math.Cos(args[0]);44 }45 46 42 public override void Accept(IFunctionVisitor visitor) { 47 43 visitor.Visit(this); -
TabularUnified branches/ExperimentalFunctionsBaking/Division.cs ¶
r203 r220 30 30 31 31 namespace HeuristicLab.Functions { 32 public class Division : FunctionBase {32 public sealed class Division : FunctionBase { 33 33 private const double EPSILON = 10.0E-20; // if any divisor is < EPSILON return 0 34 34 … … 52 52 } 53 53 54 public static double Divide(double[] args) {55 // (/ 3) => 1/356 // (/ 2 3) => 2/357 // (/ 3 4 5) => 3/2058 if(args.Length == 1) {59 double divisor = args[0];60 if(Math.Abs(divisor) < EPSILON) return 0;61 else return 1.0 / divisor;62 } else {63 double result = args[0];64 for(int i = 1; i < args.Length; i++) {65 double divisor = args[i];66 if(Math.Abs(divisor) < EPSILON) return 0.0;67 result /= divisor;68 }69 return result;70 }71 }72 73 public override double Apply(Dataset dataset, int sampleIndex, double[] args) {74 return Division.Divide(args);75 }76 77 54 public override void Accept(IFunctionVisitor visitor) { 78 55 visitor.Visit(this); -
TabularUnified branches/ExperimentalFunctionsBaking/Equal.cs ¶
r155 r220 28 28 29 29 namespace HeuristicLab.Functions { 30 public class Equal : FunctionBase {30 public sealed class Equal : FunctionBase { 31 31 public override string Description { 32 32 get { … … 40 40 } 41 41 42 public override double Apply(Dataset dataset, int sampleIndex, double[] args) {43 if(args[0] == args[1]) return 1.0;44 else return 0.0;45 }46 47 42 public override void Accept(IFunctionVisitor visitor) { 48 43 visitor.Visit(this); -
TabularUnified branches/ExperimentalFunctionsBaking/Exponential.cs ¶
r155 r220 29 29 30 30 namespace HeuristicLab.Functions { 31 public class Exponential : FunctionBase {31 public sealed class Exponential : FunctionBase { 32 32 public override string Description { 33 33 get { return "Returns returns exponential of the first sub-tree (power(e, x))."; } … … 40 40 } 41 41 42 public override double Apply(Dataset dataset, int sampleIndex, double[] args) {43 return Math.Exp(args[0]);44 }45 46 42 public override void Accept(IFunctionVisitor visitor) { 47 43 visitor.Visit(this); -
TabularUnified branches/ExperimentalFunctionsBaking/FunctionBase.cs ¶
r203 r220 34 34 /// </summary> 35 35 public abstract class FunctionBase : OperatorBase, IFunction { 36 37 public abstract double Apply(Dataset dataset, int sampleIndex, double[] args); 36 37 public virtual double Apply(Dataset dataset, int sampleIndex, double[] args) { 38 throw new NotImplementedException(); 39 } 38 40 39 41 public virtual void Accept(IFunctionVisitor visitor) { -
TabularUnified branches/ExperimentalFunctionsBaking/GreaterThan.cs ¶
r159 r220 28 28 29 29 namespace HeuristicLab.Functions { 30 public class GreaterThan : FunctionBase {30 public sealed class GreaterThan : FunctionBase { 31 31 public override string Description { 32 32 get { … … 39 39 AddConstraint(new NumberOfSubOperatorsConstraint(2, 2)); 40 40 } 41 42 public override double Apply(Dataset dataset, int sampleIndex, double[] args) {43 if(args[0] > args[1]) return 1.0;44 else return 0.0;45 }46 47 41 public override void Accept(IFunctionVisitor visitor) { 48 42 visitor.Visit(this); -
TabularUnified branches/ExperimentalFunctionsBaking/IfThenElse.cs ¶
r192 r220 28 28 29 29 namespace HeuristicLab.Functions { 30 public class IfThenElse : FunctionBase {30 public sealed class IfThenElse : FunctionBase { 31 31 public override string Description { 32 32 get { … … 41 41 } 42 42 43 public override IFunctionTree GetTreeNode() {44 return new IfThenElseFunctionTree(this);45 }46 47 // special form48 public override double Apply(Dataset dataset, int sampleIndex, double[] args) {49 throw new NotImplementedException();50 }51 52 43 public override void Accept(IFunctionVisitor visitor) { 53 44 visitor.Visit(this); 54 45 } 55 46 } 56 57 class IfThenElseFunctionTree : FunctionTree {58 public IfThenElseFunctionTree() : base() { }59 public IfThenElseFunctionTree(IfThenElse ifte) : base(ifte) { }60 61 public override double Evaluate(Dataset dataset, int sampleIndex) {62 double condition = Math.Round(SubTrees[0].Evaluate(dataset, sampleIndex));63 if(condition < .5) return SubTrees[1].Evaluate(dataset, sampleIndex);64 else if(condition >= .5) return SubTrees[2].Evaluate(dataset, sampleIndex);65 else return double.NaN;66 }67 68 public override object Clone(IDictionary<Guid, object> clonedObjects) {69 IfThenElseFunctionTree clone = new IfThenElseFunctionTree();70 clonedObjects.Add(clone.Guid, clone);71 FillClone(clone, clonedObjects);72 return clone;73 }74 }75 47 } -
TabularUnified branches/ExperimentalFunctionsBaking/LessThan.cs ¶
r155 r220 28 28 29 29 namespace HeuristicLab.Functions { 30 public class LessThan : FunctionBase {30 public sealed class LessThan : FunctionBase { 31 31 public override string Description { 32 32 get { … … 40 40 } 41 41 42 public override double Apply(Dataset dataset, int sampleIndex, double[] args) {43 if(args[0] < args[1]) return 1.0;44 else return 0.0;45 }46 47 42 public override void Accept(IFunctionVisitor visitor) { 48 43 visitor.Visit(this); -
TabularUnified branches/ExperimentalFunctionsBaking/Logarithm.cs ¶
r155 r220 29 29 30 30 namespace HeuristicLab.Functions { 31 public class Logarithm : FunctionBase {31 public sealed class Logarithm : FunctionBase { 32 32 public override string Description { 33 33 get { return "Returns the natural (base e) logarithm of the first sub-tree."; } … … 40 40 } 41 41 42 public override double Apply(Dataset dataset, int sampleIndex, double[] args) {43 return Math.Log(args[0]);44 }45 46 42 public override void Accept(IFunctionVisitor visitor) { 47 43 visitor.Visit(this); -
TabularUnified branches/ExperimentalFunctionsBaking/Multiplication.cs ¶
r203 r220 30 30 31 31 namespace HeuristicLab.Functions { 32 public class Multiplication : FunctionBase {32 public sealed class Multiplication : FunctionBase { 33 33 public override string Description { 34 34 get { … … 45 45 AddConstraint(new NumberOfSubOperatorsConstraint(2, 3)); 46 46 } 47 public static double Multipy(double[] args) {48 // (* 3) => 349 // (* 2 3) => 650 // (* 3 4 5) => 6051 double result = 1.0;52 for(int i = 0; i < args.Length; i++) {53 result *= args[i];54 }55 return result;56 }57 public override double Apply(Dataset dataset, int sampleIndex, double[] args) {58 return Multiplication.Multipy(args);59 }60 47 61 48 public override void Accept(IFunctionVisitor visitor) { -
TabularUnified branches/ExperimentalFunctionsBaking/Not.cs ¶
r155 r220 28 28 29 29 namespace HeuristicLab.Functions { 30 public class Not : FunctionBase {30 public sealed class Not : FunctionBase { 31 31 public override string Description { 32 32 get { … … 40 40 } 41 41 42 public override double Apply(Dataset dataset, int sampleIndex, double[] args) {43 double result = Math.Round(args[0]);44 if(result == 0.0) return 1.0;45 else if(result == 1.0) return 0.0;46 else return double.NaN;47 }48 49 42 public override void Accept(IFunctionVisitor visitor) { 50 43 visitor.Visit(this); -
TabularUnified branches/ExperimentalFunctionsBaking/Or.cs ¶
r192 r220 28 28 29 29 namespace HeuristicLab.Functions { 30 public class Or : FunctionBase {30 public sealed class Or : FunctionBase { 31 31 public override string Description { 32 32 get { … … 41 41 } 42 42 43 public override IFunctionTree GetTreeNode() {44 return new OrFunctionTree(this);45 }46 // or is a special form and can't be applied47 public override double Apply(Dataset dataset, int sampleIndex, double[] args) {48 throw new NotImplementedException();49 }50 43 public override void Accept(IFunctionVisitor visitor) { 51 44 visitor.Visit(this); 52 45 } 53 46 } 54 55 class OrFunctionTree : FunctionTree {56 public OrFunctionTree() : base() { }57 public OrFunctionTree(Or or) : base(or) { }58 59 public override double Evaluate(Dataset dataset, int sampleIndex) {60 foreach(IFunctionTree subTree in SubTrees) {61 double result = Math.Round(subTree.Evaluate(dataset, sampleIndex));62 if(result == 1.0) return 1.0; // sub-tree evaluates to 1.0 (true) return 1.063 else if(result != 0.0) return double.NaN;64 }65 // all sub-trees evaluated to 0.0 (false) return false66 return 0.0;67 }68 69 public override object Clone(IDictionary<Guid, object> clonedObjects) {70 OrFunctionTree clone = new OrFunctionTree();71 clonedObjects.Add(clone.Guid, clone);72 FillClone(clone, clonedObjects);73 return clone;74 }75 }76 47 } -
TabularUnified branches/ExperimentalFunctionsBaking/Power.cs ¶
r155 r220 29 29 30 30 namespace HeuristicLab.Functions { 31 public class Power : FunctionBase {31 public sealed class Power : FunctionBase { 32 32 public override string Description { 33 33 get { return "Returns the result of the first sub-tree to the power of the second sub-tree (power(x, y))."; } … … 40 40 } 41 41 42 public override double Apply(Dataset dataset, int sampleIndex, double[] args) {43 return Math.Pow(args[0], args[1]);44 }45 46 42 public override void Accept(IFunctionVisitor visitor) { 47 43 visitor.Visit(this); -
TabularUnified branches/ExperimentalFunctionsBaking/ProgrammableFunction.cs ¶
r189 r220 36 36 37 37 namespace HeuristicLab.Functions { 38 public class ProgrammableFunction : ProgrammableOperator, IFunction {38 public sealed class ProgrammableFunction : ProgrammableOperator, IFunction { 39 39 private MethodInfo applyMethod; 40 40 public ProgrammableFunction() -
TabularUnified branches/ExperimentalFunctionsBaking/Signum.cs ¶
r155 r220 29 29 30 30 namespace HeuristicLab.Functions { 31 public class Signum : FunctionBase {31 public sealed class Signum : FunctionBase { 32 32 public override string Description { 33 33 get { return "Returns the signum of the first sub-tree."; } … … 40 40 } 41 41 42 public override double Apply(Dataset dataset, int sampleIndex, double[] args) {43 double value = args[0];44 if(value < 0) return -1;45 if(value > 0) return 1;46 return 0;47 }48 49 42 public override void Accept(IFunctionVisitor visitor) { 50 43 visitor.Visit(this); -
TabularUnified branches/ExperimentalFunctionsBaking/Sinus.cs ¶
r155 r220 29 29 30 30 namespace HeuristicLab.Functions { 31 public class Sinus : FunctionBase {31 public sealed class Sinus : FunctionBase { 32 32 public override string Description { 33 33 get { return "Returns the sinus of the first sub-tree."; } … … 40 40 } 41 41 42 public override double Apply(Dataset dataset, int sampleIndex, double[] args) {43 return Math.Sin(args[0]);44 }45 46 42 public override void Accept(IFunctionVisitor visitor) { 47 43 visitor.Visit(this); -
TabularUnified branches/ExperimentalFunctionsBaking/Sqrt.cs ¶
r155 r220 29 29 30 30 namespace HeuristicLab.Functions { 31 public class Sqrt : FunctionBase {31 public sealed class Sqrt : FunctionBase { 32 32 public override string Description { 33 33 get { return "Returns the square root of the first sub-tree."; } … … 40 40 } 41 41 42 43 public override double Apply(Dataset dataset, int sampleIndex, double[] args) {44 return Math.Sqrt(args[0]);45 }46 47 42 public override void Accept(IFunctionVisitor visitor) { 48 43 visitor.Visit(this); -
TabularUnified branches/ExperimentalFunctionsBaking/Substraction.cs ¶
r203 r220 30 30 31 31 namespace HeuristicLab.Functions { 32 public class Substraction : FunctionBase {32 public sealed class Substraction : FunctionBase { 33 33 public override string Description { 34 34 get { … … 46 46 } 47 47 48 public static double Substract(double[] args) {49 if(args.Length == 1) {50 return -args[0];51 } else {52 double result = args[0];53 for(int i = 1; i < args.Length; i++) {54 result -= args[i];55 }56 return result;57 }58 }59 60 public override double Apply(Dataset dataset, int sampleIndex, double[] args) {61 return Substraction.Substract(args);62 }63 64 48 public override void Accept(IFunctionVisitor visitor) { 65 49 visitor.Visit(this); -
TabularUnified branches/ExperimentalFunctionsBaking/Tangens.cs ¶
r155 r220 29 29 30 30 namespace HeuristicLab.Functions { 31 public class Tangens : FunctionBase {31 public sealed class Tangens : FunctionBase { 32 32 public override string Description { 33 33 get { return "Returns the tangens of the first sub-tree."; } … … 40 40 } 41 41 42 public override double Apply(Dataset dataset, int sampleIndex, double[] args) {43 return Math.Tan(args[0]);44 }45 46 42 public override void Accept(IFunctionVisitor visitor) { 47 43 visitor.Visit(this); -
TabularUnified branches/ExperimentalFunctionsBaking/Variable.cs ¶
r201 r220 30 30 31 31 namespace HeuristicLab.Functions { 32 public class Variable : FunctionBase {32 public sealed class Variable : FunctionBase { 33 33 34 34 public const string WEIGHT = "Weight"; … … 37 37 38 38 public override string Description { 39 get { return @"Variable reads a value from a dataset, multiplies that value with a given factor and returns the result. 39 get { 40 return @"Variable reads a value from a dataset, multiplies that value with a given factor and returns the result. 40 41 The variable 'SampleOffset' can be used to read a value from previous or following rows. 41 The index of the row that is actually read is SampleIndex+SampleOffset)."; } 42 The index of the row that is actually read is SampleIndex+SampleOffset)."; 43 } 42 44 } 43 45 … … 68 70 } 69 71 70 //public override IFunctionTree GetTreeNode() {71 // return new VariableFunctionTree(this);72 //}73 74 // can't apply a variable75 public override double Apply(Dataset dataset, int sampleIndex, double[] args) {76 throw new NotSupportedException();77 }78 79 72 public override void Accept(IFunctionVisitor visitor) { 80 73 visitor.Visit(this); 81 74 } 82 75 } 83 class VariableFunctionTree : FunctionTree {84 private ConstrainedDoubleData weight;85 private ConstrainedIntData index;86 private ConstrainedIntData offset;87 88 public VariableFunctionTree() : base() { }89 public VariableFunctionTree(Variable variable) : base(variable) {90 UpdateCachedValues();91 }92 93 protected void UpdateCachedValues() {94 weight = (ConstrainedDoubleData)GetLocalVariable(Variable.WEIGHT).Value;95 index = (ConstrainedIntData)GetLocalVariable(Variable.INDEX).Value;96 offset = (ConstrainedIntData)GetLocalVariable(Variable.OFFSET).Value;97 }98 99 public override double Evaluate(Dataset dataset, int sampleIndex) {100 if(sampleIndex + offset.Data < 0 || sampleIndex + offset.Data >= dataset.Rows) return double.NaN;101 return weight.Data * dataset.GetValue(sampleIndex + offset.Data, index.Data);102 }103 104 public override object Clone(IDictionary<Guid, object> clonedObjects) {105 VariableFunctionTree clone = new VariableFunctionTree();106 clonedObjects.Add(clone.Guid, clone);107 FillClone(clone, clonedObjects);108 clone.UpdateCachedValues();109 return clone;110 }111 112 public override void Populate(System.Xml.XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {113 base.Populate(node, restoredObjects);114 UpdateCachedValues();115 }116 }117 76 } -
TabularUnified branches/ExperimentalFunctionsBaking/Xor.cs ¶
r155 r220 28 28 29 29 namespace HeuristicLab.Functions { 30 public class Xor : FunctionBase {30 public sealed class Xor : FunctionBase { 31 31 public override string Description { 32 32 get { … … 40 40 } 41 41 42 public override double Apply(Dataset dataset, int sampleIndex, double[] args) {43 if(args[0] == 0.0 && args[1] == 0.0) return 0.0;44 if(args[0] * args[1] == 0.0) return 1.0;45 return 0.0;46 }47 48 42 public override void Accept(IFunctionVisitor visitor) { 49 43 visitor.Visit(this);
Note: See TracChangeset
for help on using the changeset viewer.