Free cookie consent management tool by TermsFeed Policy Generator

Changeset 165


Ignore:
Timestamp:
04/22/08 21:57:56 (16 years ago)
Author:
gkronber
Message:

implemented ProgrammableFunction inherited from ProgrammableOperator (fixes #106)

Location:
trunk/sources/HeuristicLab.Functions
Files:
3 edited

Legend:

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

    r155 r165  
    4949    public abstract double Apply(Dataset dataset, int sampleIndex, double[] args);
    5050
     51    public virtual void Accept(IFunctionVisitor visitor) {
     52      visitor.Visit(this);
     53    }
     54
    5155    // operator-tree style evaluation is not supported for functions.
    5256    public override IOperation Apply(IScope scope) {
    5357      throw new NotSupportedException();
    54     }
    55     public virtual void Accept(IFunctionVisitor visitor) {
    56       visitor.Visit(this);
    5758    }
    5859
  • trunk/sources/HeuristicLab.Functions/HeuristicLabFunctionsPlugin.cs

    r2 r165  
    3232  [Dependency(Dependency = "HeuristicLab.Data")]
    3333  [Dependency(Dependency = "HeuristicLab.DataAnalysis")]
     34  [Dependency(Dependency = "HeuristicLab.Operators.Programmable")]
    3435  public class HeuristicLabFunctionsPlugin : PluginBase {
    3536  }
  • trunk/sources/HeuristicLab.Functions/ProgrammableFunction.cs

    r155 r165  
    3333using Microsoft.CSharp;
    3434using System.IO;
     35using HeuristicLab.Operators.Programmable;
    3536
    3637namespace HeuristicLab.Functions {
    37   public class ProgrammableFunction : FunctionBase {
    38     private MethodInfo evaluateMethod;
    39 
    40     private string myDescription;
    41     public override string Description {
    42       get { return myDescription; }
    43     }
    44     private string myCode;
    45     public string Code {
    46       get { return myCode; }
    47       set {
    48         if(value != myCode) {
    49           myCode = value;
    50           evaluateMethod = null;
    51           OnCodeChanged();
    52         }
    53       }
    54     }
    55 
    56     public ProgrammableFunction() : base() {
    57       myCode = "return 0.0;";
    58       myDescription = "A function that can be programmed for arbitrary needs.";
    59       evaluateMethod = null;
    60     }
    61 
    62     public void SetDescription(string description) {
    63       if(description == null)
    64         throw new NullReferenceException("description must not be null");
    65 
    66       if(description != myDescription) {
    67         myDescription = description;
    68         OnDescriptionChanged();
    69       }
    70     }
    71 
    72     public void Compile() {
     38  public class ProgrammableFunction : ProgrammableOperator, IFunction {
     39    private MethodInfo applyMethod;
     40    public ProgrammableFunction()
     41      : base() {
     42      Code = "return 0.0;";
     43      SetDescription("A function that can be programmed for arbitrary needs.");
     44      applyMethod = null;
     45    }
     46
     47    public override void Compile() {
    7348      CodeNamespace ns = new CodeNamespace("HeuristicLab.Functions.CustomFunctions");
    7449      CodeTypeDeclaration typeDecl = new CodeTypeDeclaration("Function");
     
    7752
    7853      CodeMemberMethod method = new CodeMemberMethod();
    79       method.Name = "Evaluate";
     54      method.Name = "Apply";
    8055      method.ReturnType = new CodeTypeReference(typeof(double));
    8156      method.Attributes = MemberAttributes.Public | MemberAttributes.Static;
    82       method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(IFunction), "function"));
    8357      method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Dataset), "dataset"));
    8458      method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "index"));
    8559      foreach(IVariableInfo info in VariableInfos)
    8660        method.Parameters.Add(new CodeParameterDeclarationExpression(info.DataType, info.FormalName));
    87       string code = myCode;
     61      method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(double[]), "args"));
     62      string code = Code;
    8863      method.Statements.Add(new CodeSnippetStatement(code));
    8964      typeDecl.Members.Add(method);
     
    11085      CompilerResults results = provider.CompileAssemblyFromDom(parameters, unit);
    11186
    112       evaluateMethod = null;
     87      applyMethod = null;
    11388      if(results.Errors.HasErrors) {
    11489        StringWriter writer = new StringWriter();
     
    135110        Assembly assembly = results.CompiledAssembly;
    136111        Type[] types = assembly.GetTypes();
    137         evaluateMethod = types[0].GetMethod("Evaluate");
    138       }
    139     }
    140 
    141     public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
    142       //if(evaluateMethod == null) {
    143       //  Compile();
    144       //}
    145 
    146       //// collect parameters
    147       //object[] parameters = new object[VariableInfos.Count + 3];
    148       //parameters[0] = this;
    149       //parameters[1] = dataset;
    150       //parameters[2] = sampleIndex;
    151       //int i = 3;
    152       //// all local variables are available in the custom function
    153       //foreach(IVariableInfo info in VariableInfos) {
    154       //  if(info.Local) {
    155       //    parameters[i] = this.GetVariable(info.ActualName);
    156       //    i++;
    157       //  }
    158       //}
    159       //return (double)evaluateMethod.Invoke(null, parameters);
    160       return 0.0;
    161     }
    162 
    163     public override object Clone(IDictionary<Guid, object> clonedObjects) {
    164       ProgrammableFunction clone = (ProgrammableFunction)base.Clone(clonedObjects);
    165       clone.myDescription = Description;
    166       clone.myCode = Code;
    167       clone.evaluateMethod = evaluateMethod;
    168       return clone;
    169     }
    170 
    171     public override void Accept(IFunctionVisitor visitor) {
     112        applyMethod = types[0].GetMethod("Apply");
     113      }
     114    }
     115
     116    #region IFunction Members
     117    public void Accept(IFunctionVisitor visitor) {
    172118      visitor.Visit(this);
    173119    }
    174120
    175     public event EventHandler DescriptionChanged;
    176     protected virtual void OnDescriptionChanged() {
    177       if(DescriptionChanged != null)
    178         DescriptionChanged(this, new EventArgs());
    179     }
    180     public event EventHandler CodeChanged;
    181     protected virtual void OnCodeChanged() {
    182       if(CodeChanged != null)
    183         CodeChanged(this, new EventArgs());
    184     }
    185 
    186     #region Persistence Methods
    187     public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) {
    188       XmlNode node = base.GetXmlNode(name, document, persistedObjects);
    189       XmlNode descriptionNode = document.CreateNode(XmlNodeType.Element, "Description", null);
    190       descriptionNode.InnerText = myDescription;
    191       node.AppendChild(descriptionNode);
    192       XmlNode codeNode = document.CreateNode(XmlNodeType.Element, "Code", null);
    193       codeNode.InnerText = myCode;
    194       node.AppendChild(codeNode);
    195       return node;
    196     }
    197     public override void Populate(XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {
    198       base.Populate(node, restoredObjects);
    199       XmlNode descriptionNode = node.SelectSingleNode("Description");
    200       myDescription = descriptionNode.InnerText;
    201       XmlNode codeNode = node.SelectSingleNode("Code");
    202       myCode = codeNode.InnerText;
     121    public double Evaluate(Dataset dataset, int sampleIndex, IFunctionTree tree) {
     122      // evaluate sub-trees
     123      double[] evaluationResults = new double[tree.SubTrees.Count];
     124      for(int subTree=0; subTree < tree.SubTrees.Count; subTree++) {
     125        evaluationResults[subTree] = tree.SubTrees[subTree].Evaluate(dataset, sampleIndex);
     126      }
     127      // lazy activation of the user-programmed code
     128      if(applyMethod == null) {
     129        Compile();
     130      }
     131
     132      // collect parameters
     133      object[] parameters = new object[VariableInfos.Count + 3];
     134      parameters[0] = dataset;
     135      parameters[1] = sampleIndex;
     136      int i = 2;
     137      // all local variables are available in the custom function
     138      foreach(IVariable variable in tree.LocalVariables) {
     139        parameters[i] = variable;
     140        i++;
     141      }
     142      parameters[i] = evaluationResults;
     143      return (double)applyMethod.Invoke(null, parameters);
     144    }
     145
     146    // application of programmable-function is not possible
     147    public double Apply(Dataset dataset, int sampleIndex, double[] args) {
     148      throw new NotSupportedException();
     149    }
     150
     151    #endregion
     152
     153    #region disabled operator functionality
     154    // operator-tree style evaluation is not supported for functions.
     155    public override IOperation Apply(IScope scope) {
     156      throw new NotSupportedException();
     157    }
     158
     159    private static readonly List<IOperator> emptySubOperatorList = new List<IOperator>();
     160    public override IList<IOperator> SubOperators {
     161      get { return emptySubOperatorList; }
     162    }
     163
     164    public override void AddSubOperator(IOperator subOperator) {
     165      throw new NotSupportedException();
     166    }
     167
     168    public override bool TryAddSubOperator(IOperator subOperator) {
     169      throw new NotSupportedException();
     170    }
     171
     172    public override bool TryAddSubOperator(IOperator subOperator, int index) {
     173      throw new NotSupportedException();
     174    }
     175
     176    public override bool TryAddSubOperator(IOperator subOperator, int index, out ICollection<IConstraint> violatedConstraints) {
     177      throw new NotSupportedException();
     178    }
     179
     180    public override bool TryAddSubOperator(IOperator subOperator, out ICollection<IConstraint> violatedConstraints) {
     181      throw new NotSupportedException();
     182    }
     183
     184    public override void AddSubOperator(IOperator subOperator, int index) {
     185      throw new NotSupportedException();
     186    }
     187
     188    public override void RemoveSubOperator(int index) {
     189      throw new NotSupportedException();
     190    }
     191
     192    public override bool TryRemoveSubOperator(int index) {
     193      throw new NotSupportedException();
     194    }
     195
     196    public override bool TryRemoveSubOperator(int index, out ICollection<IConstraint> violatedConstraints) {
     197      throw new NotSupportedException();
    203198    }
    204199    #endregion
Note: See TracChangeset for help on using the changeset viewer.