Free cookie consent management tool by TermsFeed Policy Generator

Changeset 2624


Ignore:
Timestamp:
01/13/10 15:43:55 (14 years ago)
Author:
gkronber
Message:

Rewrote part of network transformation code. #833 (Genetic Programming based search for equations (modeling with multiple target variables))

Location:
trunk/sources
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.GP.StructureIdentification.Networks/3.2/FunctionLibraryInjector.cs

    r2616 r2624  
    9494      OpenExp openExp = new OpenExp();
    9595      OpenLog openLog = new OpenLog();
    96       OpenSqrt openSqrt = new OpenSqrt();
    97       OpenSqr openSqr = new OpenSqr();
     96      //OpenSqrt openSqrt = new OpenSqrt();
     97      //OpenSqr openSqr = new OpenSqr();
    9898      Flip flip = new Flip();
    9999      AdditionF1 addF1 = new AdditionF1();
     
    104104      List<IFunction> f1Functions = new List<IFunction>() {
    105105        openPar,
    106         openExp, openLog, openSqrt, openSqr, flip,
     106        openExp, openLog, flip, // openSqrt, openSqr,
    107107        addF1, subF1, mulF1, divF1
    108108      };
     
    126126      SetAllowedSubOperators(openExp, f1Functions);
    127127      SetAllowedSubOperators(openLog, f1Functions);
    128       SetAllowedSubOperators(openSqrt, f1Functions);
     128      //SetAllowedSubOperators(openSqrt, f1Functions);
     129      //SetAllowedSubOperators(openSqr, f1Functions);
    129130      SetAllowedSubOperators(flip, f1Functions);
    130131      SetAllowedSubOperators(addF1, 0, f1Functions);
     
    141142      SetAllowedSubOperators(openDivision, f1Functions);
    142143      SetAllowedSubOperators(openMul, f1Functions);
    143       SetAllowedSubOperators(openSqrt, f1Functions);
    144144
    145145      if (includeDifferential)
  • trunk/sources/HeuristicLab.GP.StructureIdentification.Networks/3.2/HeuristicLab.GP.StructureIdentification.Networks-3.2.csproj

    r2617 r2624  
    8686    <Compile Include="Properties\AssemblyInfo.cs" />
    8787    <Compile Include="Symbols\AdditionF1.cs" />
    88     <Compile Include="Symbols\BindF1.cs" />
    89     <Compile Include="Symbols\BindF2.cs" />
    90     <Compile Include="Symbols\Id.cs" />
    91     <Compile Include="Symbols\OpenSqr.cs" />
    9288    <Compile Include="Symbols\OpenParameter.cs" />
    9389    <Compile Include="Symbols\Cycle.cs" />
     
    9995    <Compile Include="Symbols\OpenAddition.cs" />
    10096    <Compile Include="Symbols\Flip.cs" />
    101     <Compile Include="Symbols\OpenSqrt.cs" />
    10297    <Compile Include="Symbols\OpenExp.cs" />
    10398    <Compile Include="Symbols\OpenLog.cs" />
  • trunk/sources/HeuristicLab.GP.StructureIdentification.Networks/3.2/NetworkToFunctionTransformer.cs

    r2622 r2624  
    7272    }
    7373
     74    /// <summary>
     75    /// applies all tree-transforming meta functions (= cycle and flip)
     76    /// precondition: root is a F2 function (possibly cycle) and the tree contains 0 or n flip functions, each branch has an openparameter symbol in the bottom left
     77    /// postconditon: root is any F2 function (but cycle) and the tree doesn't contains any flips, each branch has an openparameter symbol in the bottom left
     78    /// </summary>
     79    /// <param name="tree"></param>
     80    /// <returns></returns>
    7481    private static IFunctionTree ApplyMetaFunctions(IFunctionTree tree) {
    7582      IFunctionTree root = ApplyCycles(tree);
     
    8794        return tree;
    8895      } else if (tree.Function is Flip) {
    89         return InvertFunction(tree.SubTrees[0]);
     96        return InvertChain(tree.SubTrees[0]);
    9097      } else {
    9198        IFunctionTree tmp = ApplyFlips(tree.SubTrees[0]);
    92         tree.RemoveSubTree(0); tree.AddSubTree(tmp);
     99        tree.RemoveSubTree(0); tree.InsertSubTree(0, tmp);
    93100        return tree;
    94101      }
     102    }
     103
     104    /// <summary>
     105    ///  inverts and reverses chain of functions.
     106    ///  precondition: tree is any F1 non-terminal that ends with an openParameter
     107    ///  postcondition: tree is inverted and reversed chain of F1 non-terminals and ends with an openparameter.
     108    /// </summary>
     109    /// <param name="tree"></param>
     110    /// <returns></returns>
     111    private static IFunctionTree InvertChain(IFunctionTree tree) {
     112      List<IFunctionTree> currentChain = new List<IFunctionTree>(IterateChain(tree));
     113      // get a list of function trees from bottom to top
     114      List<IFunctionTree> reversedChain = new List<IFunctionTree>(currentChain.Reverse<IFunctionTree>().Skip(1));
     115      IFunctionTree openParam = currentChain.Last();
     116
     117      // build new tree by inverting every function in the reversed chain and keeping f0 branches untouched.
     118      IFunctionTree parent = reversedChain[0];
     119      IFunctionTree invParent = GetInvertedFunction(parent.Function).GetTreeNode();
     120      for (int j = 1; j < parent.SubTrees.Count; j++) {
     121        invParent.AddSubTree(parent.SubTrees[j]);
     122      }
     123      IFunctionTree root = invParent;
     124      for (int i = 1; i < reversedChain.Count(); i++) {
     125        IFunctionTree child = reversedChain[i];
     126        IFunctionTree invChild = GetInvertedFunction(child.Function).GetTreeNode();
     127        invParent.InsertSubTree(0, invChild);
     128
     129        parent = child;
     130        invParent = invChild;
     131        for (int j = 1; j < parent.SubTrees.Count; j++) {
     132          invParent.AddSubTree(parent.SubTrees[j]);
     133        }
     134      }
     135      // append open param at the end
     136      invParent.AddSubTree(openParam);
     137      return root;
     138    }
     139
     140    private static IEnumerable<IFunctionTree> IterateChain(IFunctionTree tree) {
     141      while (tree.SubTrees.Count > 0) {
     142        yield return tree;
     143        tree = tree.SubTrees[0];
     144      }
     145      yield return tree;
     146    }
     147
     148
     149    private static Dictionary<Type, IFunction> invertedFunction = new Dictionary<Type, IFunction>() {
     150      { typeof(AdditionF1), new SubtractionF1() },
     151      { typeof(SubtractionF1), new AdditionF1() },
     152      { typeof(MultiplicationF1), new DivisionF1() },
     153      { typeof(DivisionF1), new MultiplicationF1() },
     154      { typeof(OpenLog), new OpenExp() },
     155      { typeof(OpenExp), new OpenLog() },
     156      //{ typeof(OpenSqr), new OpenSqrt() },
     157      //{ typeof(OpenSqrt), new OpenSqr() },
     158      { typeof(Flip), new Flip()},
     159      { typeof(Addition), new Subtraction()},
     160      { typeof(Subtraction), new Addition()},
     161      { typeof(Multiplication), new Division()},
     162      { typeof(Division), new Multiplication()},
     163      { typeof(Exponential), new Logarithm()},
     164      { typeof(Logarithm), new Exponential()}
     165    };
     166    private static IFunction GetInvertedFunction(IFunction function) {
     167      return invertedFunction[function.GetType()];
    95168    }
    96169
     
    117190    }
    118191
    119     private static IFunctionTree InvertFunction(IFunctionTree tree) {
    120       IFunctionTree invertedNode = null;
    121       if (tree.Function is OpenParameter || tree.Function is Variable) {
    122         return tree;
    123       } else if (tree.Function is AdditionF1) {
    124         invertedNode = (new SubtractionF1()).GetTreeNode();
    125         invertedNode.AddSubTree(tree.SubTrees[1]);
    126       } else if (tree.Function is DivisionF1) {
    127         invertedNode = (new MultiplicationF1()).GetTreeNode();
    128         invertedNode.AddSubTree(tree.SubTrees[1]);
    129       } else if (tree.Function is MultiplicationF1) {
    130         invertedNode = (new DivisionF1()).GetTreeNode();
    131         invertedNode.AddSubTree(tree.SubTrees[1]);
    132       } else if (tree.Function is SubtractionF1) {
    133         invertedNode = (new AdditionF1()).GetTreeNode();
    134         invertedNode.AddSubTree(tree.SubTrees[1]);
    135       } else if (tree.Function is OpenExp) {
    136         invertedNode = (new OpenLog()).GetTreeNode();
    137       } else if (tree.Function is OpenLog) {
    138         invertedNode = (new OpenLog()).GetTreeNode();
    139       } else if (tree.Function is OpenSqrt) {
    140         invertedNode = (new OpenSqr()).GetTreeNode();
    141       } else {
    142         throw new ArgumentException();
    143       }
    144       IFunctionTree invertedTail = ApplyFlips(tree.SubTrees[0]);
    145       if (invertedTail.Function is OpenParameter || invertedTail.Function is Variable) {
    146         invertedNode.InsertSubTree(0, invertedTail);
    147         return invertedNode;
    148       } else {
    149         return AppendLeft(invertedTail, invertedNode);
    150       }
    151     }
     192 
    152193
    153194    private static IFunctionTree AppendLeft(IFunctionTree tree, IFunctionTree node) {
     
    158199    }
    159200
     201    /// <summary>
     202    /// recieves a function tree with an F2 root and branches containing only F0 functions and transforms it into a function-tree for the given target variable
     203    /// </summary>
     204    /// <param name="tree"></param>
     205    /// <param name="targetVariable"></param>
     206    /// <returns></returns>
    160207    private static IFunctionTree TransformExpression(IFunctionTree tree, string targetVariable) {
    161       if (tree.SubTrees.Count >= 3) {
    162         int targetIndex = -1;
    163         IFunctionTree combinator;
    164         List<IFunctionTree> subTrees = new List<IFunctionTree>(tree.SubTrees);
    165         //while (tree.SubTrees.Count > 0) tree.RemoveSubTree(0);
    166         if (HasTargetVariable(subTrees[0], targetVariable)) {
    167           targetIndex = 0;
    168           combinator = FunctionFromCombinator(tree);
    169         } else {
    170           for (int i = 1; i < subTrees.Count; i++) {
    171             if (HasTargetVariable(subTrees[i], targetVariable)) {
    172               targetIndex = i;
    173               break;
    174             }
     208      int targetIndex = -1;
     209      IFunctionTree combinator;
     210      List<IFunctionTree> subTrees = new List<IFunctionTree>(tree.SubTrees);
     211      //while (tree.SubTrees.Count > 0) tree.RemoveSubTree(0);
     212      if (HasTargetVariable(subTrees[0], targetVariable)) {
     213        targetIndex = 0;
     214        combinator = FunctionFromCombinator(tree);
     215      } else {
     216        for (int i = 1; i < subTrees.Count; i++) {
     217          if (HasTargetVariable(subTrees[i], targetVariable)) {
     218            targetIndex = i;
     219            break;
    175220          }
    176           combinator = FunctionFromCombinator(InvertCombinator(tree));
    177         }
    178         // not found
    179         if (targetIndex == -1) throw new InvalidOperationException();
    180         IFunctionTree targetChain = TransformToFunction(InvertFunction(subTrees[targetIndex]));
    181         for (int i = 0; i < subTrees.Count; i++) {
    182           if (i != targetIndex)
    183             combinator.AddSubTree(TransformToFunction(subTrees[i]));
    184         }
    185         if (targetChain.Function is Variable) return combinator;
    186         else {
    187           AppendLeft(targetChain, combinator);
    188           return targetChain;
    189         }
    190       }
    191       throw new NotImplementedException();
    192     }
    193 
    194     private static IFunctionTree TransformToFunction(IFunctionTree tree) {
    195       if (tree.SubTrees.Count == 0) return tree;
    196       else if (tree.Function is AdditionF1) {
    197         var addTree = (new Addition()).GetTreeNode();
    198         foreach (var subTree in tree.SubTrees) {
    199           addTree.AddSubTree(TransformToFunction(subTree));
    200         }
    201         return addTree;
    202       } else if (tree.Function is SubtractionF1) {
    203         var sTree = (new Subtraction()).GetTreeNode();
    204         foreach (var subTree in tree.SubTrees) {
    205           sTree.AddSubTree(TransformToFunction(subTree));
    206         }
    207         return sTree;
    208       } else if (tree.Function is MultiplicationF1) {
    209         var mulTree = (new Multiplication()).GetTreeNode();
    210         foreach (var subTree in tree.SubTrees) {
    211           mulTree.AddSubTree(TransformToFunction(subTree));
    212         }
    213         return mulTree;
    214       } else if (tree.Function is DivisionF1) {
    215         var divTree = (new Division()).GetTreeNode();
    216         foreach (var subTree in tree.SubTrees) {
    217           divTree.AddSubTree(TransformToFunction(subTree));
    218         }
    219         return divTree;
    220       } else if (tree.Function is OpenExp) {
    221         var expTree = (new Exponential()).GetTreeNode();
    222         expTree.AddSubTree(TransformToFunction(tree.SubTrees[0]));
    223         return expTree;
    224       } else if (tree.Function is OpenLog) {
    225         var logTree = (new Logarithm()).GetTreeNode();
    226         logTree.AddSubTree(TransformToFunction(tree.SubTrees[0]));
    227         return logTree;
    228       } else if (tree.Function is OpenSqr) {
    229         var powTree = (new Power()).GetTreeNode();
    230         powTree.AddSubTree(TransformToFunction(tree.SubTrees[0]));
    231         var const2 = (ConstantFunctionTree)(new Constant()).GetTreeNode();
    232         const2.Value = 2.0;
    233         powTree.AddSubTree(const2);
    234         return powTree;
    235       } else if (tree.Function is OpenSqrt) {
    236         var sqrtTree = (new Sqrt()).GetTreeNode();
    237         sqrtTree.AddSubTree(TransformToFunction(tree.SubTrees[0]));
    238         return sqrtTree;
    239       }
    240       throw new ArgumentException();
    241     }
    242 
     221        }
     222        combinator = FunctionFromCombinator(InvertCombinator(tree));
     223      }
     224      // not found
     225      if (targetIndex == -1) throw new InvalidOperationException();
     226
     227      for (int i = 0; i < subTrees.Count; i++) {
     228        if (i != targetIndex)
     229          combinator.AddSubTree(subTrees[i]);
     230      }
     231      if (subTrees[targetIndex].Function is Variable) return combinator;
     232      else {
     233        IFunctionTree targetChain = InvertF0Chain(subTrees[targetIndex]);
     234        AppendLeft(targetChain, combinator);
     235        return targetChain;
     236      }
     237    }
     238
     239    // inverts a chain of F0 functions
     240    // precondition: left bottom is a variable (the selected target variable)
     241    // postcondition: the chain is inverted. the target variable is removed
     242    private static IFunctionTree InvertF0Chain(IFunctionTree tree) {
     243      List<IFunctionTree> currentChain = IterateChain(tree).ToList();
     244
     245      List<IFunctionTree> reversedChain = currentChain.Reverse<IFunctionTree>().Skip(1).ToList();
     246
     247      // build new tree by inverting every function in the reversed chain and keeping f0 branches untouched.
     248      IFunctionTree parent = reversedChain[0];
     249      IFunctionTree invParent = GetInvertedFunction(parent.Function).GetTreeNode();
     250      for (int j = 1; j < parent.SubTrees.Count; j++) {
     251        invParent.AddSubTree(parent.SubTrees[j]);
     252      }
     253      IFunctionTree root = invParent;
     254      for (int i = 1; i < reversedChain.Count(); i++) {
     255        IFunctionTree child = reversedChain[i];
     256        IFunctionTree invChild = GetInvertedFunction(child.Function).GetTreeNode();
     257        invParent.InsertSubTree(0, invChild);
     258        parent = child;
     259        invParent = invChild;
     260        for (int j = 1; j < parent.SubTrees.Count; j++) {
     261          invParent.AddSubTree(parent.SubTrees[j]);
     262        }
     263      }
     264      return root;
     265    }
     266
     267 
    243268    private static IFunctionTree InvertCombinator(IFunctionTree tree) {
    244269      if (tree.Function is OpenAddition) {
     
    275300    }
    276301
     302    private static Dictionary<Type, IFunction> closedForm = new Dictionary<Type, IFunction>() {
     303      {typeof(OpenAddition), new OpenAddition()},
     304      {typeof(OpenSubtraction), new OpenSubtraction()},
     305      {typeof(OpenMultiplication), new OpenMultiplication()},
     306      {typeof(OpenDivision), new OpenDivision()},
     307      {typeof(AdditionF1), new Addition()},
     308      {typeof(SubtractionF1), new Subtraction()},
     309      {typeof(MultiplicationF1), new Multiplication()},
     310      {typeof(DivisionF1), new Division()},
     311      {typeof(OpenExp), new Exponential()},
     312      {typeof(OpenLog), new OpenLog()},
     313      //{typeof(OpenSqr), new Power()},
     314      //{typeof(OpenSqrt), new Sqrt()},
     315      {typeof(OpenParameter), new Variable()},
     316    };
     317
     318    /// <summary>
     319    /// transforms a tree that contains F2 and F1 functions into a tree composed of F2 and F0 functions.
     320    /// precondition: the tree doesn't contains cycle or flip symbols. the tree has openparameters in the bottom left
     321    /// postcondition: all F1 and functions are replaced by matching F0 functions
     322    /// </summary>
     323    /// <param name="tree"></param>
     324    /// <param name="targetVariables"></param>
     325    /// <returns></returns>
    277326    private static IFunctionTree BindVariables(IFunctionTree tree, IEnumerator<string> targetVariables) {
    278       if (tree.Function is OpenParameter && targetVariables.MoveNext()) {
    279         var varTreeNode = (VariableFunctionTree)(new Variable()).GetTreeNode();
     327      if (!closedForm.ContainsKey(tree.Function.GetType())) return tree;
     328      IFunction matchingFunction = closedForm[tree.Function.GetType()];
     329      IFunctionTree matchingTree = matchingFunction.GetTreeNode();
     330      if (matchingFunction is Variable) {
     331        targetVariables.MoveNext();
     332        var varTreeNode = (VariableFunctionTree)matchingTree;
    280333        varTreeNode.VariableName = targetVariables.Current;
    281334        varTreeNode.SampleOffset = ((OpenParameterFunctionTree)tree).SampleOffset;
    282335        varTreeNode.Weight = 1.0;
    283336        return varTreeNode;
     337        //} else if (matchingFunction is Power) {
     338        //  matchingTree.AddSubTree(BindVariables(tree.SubTrees[0], targetVariables));
     339        //  var const2 = (ConstantFunctionTree)(new Constant()).GetTreeNode();
     340        //  const2.Value = 2.0;
     341        //  matchingTree.AddSubTree(const2);
    284342      } else {
    285         IList<IFunctionTree> subTrees = new List<IFunctionTree>(tree.SubTrees);
    286         while (tree.SubTrees.Count > 0) tree.RemoveSubTree(0);
    287         foreach (IFunctionTree subTree in subTrees) {
    288           tree.AddSubTree(BindVariables(subTree, targetVariables));
    289         }
    290         return tree;
    291       }
     343        foreach (IFunctionTree subTree in tree.SubTrees) {
     344          matchingTree.AddSubTree(BindVariables(subTree, targetVariables));
     345        }
     346      }
     347
     348      return matchingTree;
    292349    }
    293350  }
  • trunk/sources/HeuristicLab.GP.Tests/NetworkToFunctionTransformerTest.cs

    r2622 r2624  
    8585      IFunctionTree expected = log.GetTreeNode(); expected.AddSubTree(param.GetTreeNode());
    8686      IFunctionTree actual;
    87       actual = NetworkToFunctionTransformer_Accessor.InvertFunction(tree);
     87      actual = NetworkToFunctionTransformer_Accessor.InvertChain(tree);
    8888      var e = (from x in FunctionTreeIterator.IteratePostfix(expected)
    8989               select x.Function.GetType()).GetEnumerator();
     
    121121        IEnumerable<IFunctionTree> actualTrees = NetworkToFunctionTransformer_Accessor.Transform(tree, new List<string>() { "a", "b", "c" });
    122122
    123         IFunctionTree t0 = importer.Import("(- (+ 1.0 (variable 1.0 b 0)) (* 1.0 (variable 1.0 c 0)))");
    124         IFunctionTree t1 = importer.Import("(- (+ (variable 1.0 a 0) (* 1.0 (variable 1.0 c 0) 1.0)))");
    125         IFunctionTree t2 = importer.Import("(/ (+ (variable 1.0 a 0) (+ 1.0 (variable 1.0 b 0) 1.0)))");
     123        IFunctionTree t0 = importer.Import("(- (+ (variable 1.0 b 0) 1.0) (* (variable 1.0 c 0) 1.0 ))");
     124        IFunctionTree t1 = importer.Import("(- (+ (variable 1.0 a 0) (* (variable 1.0 c 0) 1.0)) 1.0 )");
     125        IFunctionTree t2 = importer.Import("(/ (+ (variable 1.0 a 0) (+ (variable 1.0 b 0) 1.0)) 1.0 )");
    126126
    127127        CompareTrees(actualTrees, new List<IFunctionTree>() {
  • trunk/sources/HeuristicLab.GP.Tests/SymbolicExpressionImporter.cs

    r2622 r2624  
    6464        {"open-log", new HeuristicLab.GP.StructureIdentification.Networks.OpenExp()},
    6565        {"open-exp", new HeuristicLab.GP.StructureIdentification.Networks.OpenLog()},
    66         {"open-sqr", new HeuristicLab.GP.StructureIdentification.Networks.OpenSqr()},
    67         {"open-sqrt", new HeuristicLab.GP.StructureIdentification.Networks.OpenSqrt()},
     66        //{"open-sqr", new HeuristicLab.GP.StructureIdentification.Networks.OpenSqr()},
     67        //{"open-sqrt", new HeuristicLab.GP.StructureIdentification.Networks.OpenSqrt()},
    6868        {"f1-+", new HeuristicLab.GP.StructureIdentification.Networks.AdditionF1()},
    6969        {"f1--", new HeuristicLab.GP.StructureIdentification.Networks.SubtractionF1()},
Note: See TracChangeset for help on using the changeset viewer.