Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
05/11/08 10:39:49 (16 years ago)
Author:
gkronber
Message:

fixed #145

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Functions/ProgrammableFunction.cs

    r229 r231  
    3434using System.IO;
    3535using HeuristicLab.Operators.Programmable;
     36using HeuristicLab.Data;
     37using System.Collections;
    3638
    3739namespace HeuristicLab.Functions {
    3840  public sealed class ProgrammableFunction : ProgrammableOperator, IFunction {
    3941    private MethodInfo applyMethod;
    40     public ProgrammableFunction()
    41       : base() {
     42    public ProgrammableFunction() {
     43      // clear the variableinfo that was added by the default constructor of ProgrammableOperator
     44      RemoveVariableInfo("Result");
    4245      Code = "return 0.0;";
    4346      SetDescription("A function that can be programmed for arbitrary needs.");
     
    123126    }
    124127
    125     // application of programmable-function is not possible
    126128    public double Apply(Dataset dataset, int sampleIndex, double[] args) {
    127       throw new NotSupportedException();
    128     }
    129 
    130     internal double Call(object[] parameters) {
     129      // collect parameters
     130      ArrayList parameters = new ArrayList(args.Length);
     131      parameters.Add(dataset);
     132      parameters.Add(sampleIndex);
     133      int j = 0;
     134      List<double> backupValues = new List<double>();
     135      // all local variables are available in the custom function
     136      // values of local variables need to be adjusted based on the arguments we recieve from the evaluator
     137      // because each instance of programmable-function can have different values for the local variables
     138      foreach(IVariableInfo info in VariableInfos) {
     139        if(info.Local) {
     140          IVariable localVariable = GetVariable(info.FormalName);
     141          double curValue = GetDoubleValue(localVariable);
     142          backupValues.Add(curValue);
     143          SetFromDoubleValue(localVariable, args[j++]);
     144          parameters.Add(localVariable.Value);
     145        }
     146      }
     147      // copy the evaluation results of the sub-branches into a separate array (last argument of user-defined function)
     148      double[] evaluationResults = new double[args.Length - j];
     149      Array.Copy(args, j, evaluationResults, 0, evaluationResults.Length);
     150      parameters.Add(evaluationResults);
    131151      // lazy activation of the user-programmed code
    132152      if(applyMethod == null) {
    133153        Compile();
    134154      }
    135       return (double)applyMethod.Invoke(null, parameters);
     155      double result = (double)applyMethod.Invoke(null, parameters.ToArray());
     156
     157      // restore backed up values of variables (just a savety measure. changes of the function-library are unwanted)
     158      j = 0;
     159      foreach(IVariableInfo info in VariableInfos) {
     160        if(info.Local) {
     161          SetFromDoubleValue(GetVariable(info.FormalName), backupValues[j]);
     162        }
     163      }
     164      return result;
     165    }
     166
     167    private double GetDoubleValue(IVariable localVariable) {
     168      IItem value = localVariable.Value;
     169      if(value is ConstrainedDoubleData) {
     170        return ((ConstrainedDoubleData)value).Data;
     171      } else if(value is ConstrainedIntData) {
     172        return (double)((ConstrainedIntData)value).Data;
     173      } else if(value is DoubleData) {
     174        return ((DoubleData)value).Data;
     175      } else if(value is IntData) {
     176        return (double)((IntData)value).Data;
     177      } else throw new NotSupportedException("Datatype of variable " + localVariable.Name + " is not supported as local variable for programmable-functions.");
     178    }
     179
     180    private void SetFromDoubleValue(IVariable variable, double x) {
     181      IItem value = variable.Value;
     182      if(value is ConstrainedDoubleData) {
     183        ((ConstrainedDoubleData)value).Data = x;
     184      } else if(value is ConstrainedIntData) {
     185        ((ConstrainedIntData)value).Data = (int)x;
     186      } else if(value is DoubleData) {
     187        ((DoubleData)value).Data = x;
     188      } else if(value is IntData) {
     189        ((IntData)value).Data = (int)x;
     190      } else throw new NotSupportedException("Datatype of variable " + variable.Name + " is not supported as local variable for programmable-functions.");
    136191    }
    137192
     
    186241    #endregion
    187242  }
    188 
    189   //class ProgrammableFunctionTree : FunctionTree {
    190   //  private ProgrammableFunction progFun;
    191   //  public ProgrammableFunctionTree() : base() { }
    192   //  public ProgrammableFunctionTree(ProgrammableFunction progFun) : base(progFun) {
    193   //    this.progFun = progFun;
    194   //  }
    195   //  public override double Evaluate(Dataset dataset, int sampleIndex) {
    196   //    // evaluate sub-trees
    197   //    double[] evaluationResults = new double[SubTrees.Count];
    198   //    for(int subTree = 0; subTree < SubTrees.Count; subTree++) {
    199   //      evaluationResults[subTree] = SubTrees[subTree].Evaluate(dataset, sampleIndex);
    200   //    }
    201 
    202   //    // collect parameters
    203   //    object[] parameters = new object[LocalVariables.Count + 3];
    204   //    parameters[0] = dataset;
    205   //    parameters[1] = sampleIndex;
    206   //    int i = 2;
    207   //    // all local variables are available in the custom function
    208   //    foreach(IVariable variable in LocalVariables) {
    209   //      parameters[i] = variable;
    210   //      i++;
    211   //    }
    212   //    parameters[i] = evaluationResults;
    213   //    return progFun.Call(parameters);
    214   //  }
    215   //}
    216243}
Note: See TracChangeset for help on using the changeset viewer.