// for each factor variable value we need a parameter which represents a binary indicator for that variable & value combination
        // each binary indicator is only necessary once. So we only create a parameter if this combination is not yet available
        private static Term FindOrCreateParameter(Dictionary <DataForVariable, AutoDiff.Variable> parameters,
                                                  string varName, string varValue = "", int lag = 0)
        {
            var data = new DataForVariable(varName, varValue, lag);

            AutoDiff.Variable par = null;
            if (!parameters.TryGetValue(data, out par))
            {
                // not found -> create new parameter and entries in names and values lists
                par = new AutoDiff.Variable();
                parameters.Add(data, par);
            }
            return(par);
        }
Пример #2
0
 public void Visit(AutoDiff.Variable variable)
 {
     AddToQueue(variable);
     //return true;
 }
        private static bool TryTransformToAutoDiff(ISymbolicExpressionTreeNode node, List <AutoDiff.Variable> variables, List <AutoDiff.Variable> parameters, List <string> variableNames, bool updateVariableWeights, out AutoDiff.Term term)
        {
            if (node.Symbol is Constant)
            {
                var var = new AutoDiff.Variable();
                variables.Add(var);
                term = var;
                return(true);
            }
            if (node.Symbol is Variable)
            {
                var varNode = node as VariableTreeNode;
                var par     = new AutoDiff.Variable();
                parameters.Add(par);
                variableNames.Add(varNode.VariableName);

                if (updateVariableWeights)
                {
                    var w = new AutoDiff.Variable();
                    variables.Add(w);
                    term = AutoDiff.TermBuilder.Product(w, par);
                }
                else
                {
                    term = par;
                }
                return(true);
            }
            if (node.Symbol is Addition)
            {
                List <AutoDiff.Term> terms = new List <Term>();
                foreach (var subTree in node.Subtrees)
                {
                    AutoDiff.Term t;
                    if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, updateVariableWeights, out t))
                    {
                        term = null;
                        return(false);
                    }
                    terms.Add(t);
                }
                term = AutoDiff.TermBuilder.Sum(terms);
                return(true);
            }
            if (node.Symbol is Subtraction)
            {
                List <AutoDiff.Term> terms = new List <Term>();
                for (int i = 0; i < node.SubtreeCount; i++)
                {
                    AutoDiff.Term t;
                    if (!TryTransformToAutoDiff(node.GetSubtree(i), variables, parameters, variableNames, updateVariableWeights, out t))
                    {
                        term = null;
                        return(false);
                    }
                    if (i > 0)
                    {
                        t = -t;
                    }
                    terms.Add(t);
                }
                if (terms.Count == 1)
                {
                    term = -terms[0];
                }
                else
                {
                    term = AutoDiff.TermBuilder.Sum(terms);
                }
                return(true);
            }
            if (node.Symbol is Multiplication)
            {
                List <AutoDiff.Term> terms = new List <Term>();
                foreach (var subTree in node.Subtrees)
                {
                    AutoDiff.Term t;
                    if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, updateVariableWeights, out t))
                    {
                        term = null;
                        return(false);
                    }
                    terms.Add(t);
                }
                if (terms.Count == 1)
                {
                    term = terms[0];
                }
                else
                {
                    term = terms.Aggregate((a, b) => new AutoDiff.Product(a, b));
                }
                return(true);
            }
            if (node.Symbol is Division)
            {
                List <AutoDiff.Term> terms = new List <Term>();
                foreach (var subTree in node.Subtrees)
                {
                    AutoDiff.Term t;
                    if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, updateVariableWeights, out t))
                    {
                        term = null;
                        return(false);
                    }
                    terms.Add(t);
                }
                if (terms.Count == 1)
                {
                    term = 1.0 / terms[0];
                }
                else
                {
                    term = terms.Aggregate((a, b) => new AutoDiff.Product(a, 1.0 / b));
                }
                return(true);
            }
            if (node.Symbol is Logarithm)
            {
                AutoDiff.Term t;
                if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t))
                {
                    term = null;
                    return(false);
                }
                else
                {
                    term = AutoDiff.TermBuilder.Log(t);
                    return(true);
                }
            }
            if (node.Symbol is Exponential)
            {
                AutoDiff.Term t;
                if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t))
                {
                    term = null;
                    return(false);
                }
                else
                {
                    term = AutoDiff.TermBuilder.Exp(t);
                    return(true);
                }
            }
            if (node.Symbol is Square)
            {
                AutoDiff.Term t;
                if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t))
                {
                    term = null;
                    return(false);
                }
                else
                {
                    term = AutoDiff.TermBuilder.Power(t, 2.0);
                    return(true);
                }
            }
            if (node.Symbol is SquareRoot)
            {
                AutoDiff.Term t;
                if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t))
                {
                    term = null;
                    return(false);
                }
                else
                {
                    term = AutoDiff.TermBuilder.Power(t, 0.5);
                    return(true);
                }
            }
            if (node.Symbol is Sine)
            {
                AutoDiff.Term t;
                if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t))
                {
                    term = null;
                    return(false);
                }
                else
                {
                    term = sin(t);
                    return(true);
                }
            }
            if (node.Symbol is Cosine)
            {
                AutoDiff.Term t;
                if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t))
                {
                    term = null;
                    return(false);
                }
                else
                {
                    term = cos(t);
                    return(true);
                }
            }
            if (node.Symbol is Tangent)
            {
                AutoDiff.Term t;
                if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t))
                {
                    term = null;
                    return(false);
                }
                else
                {
                    term = tan(t);
                    return(true);
                }
            }
            if (node.Symbol is Erf)
            {
                AutoDiff.Term t;
                if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t))
                {
                    term = null;
                    return(false);
                }
                else
                {
                    term = erf(t);
                    return(true);
                }
            }
            if (node.Symbol is Norm)
            {
                AutoDiff.Term t;
                if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t))
                {
                    term = null;
                    return(false);
                }
                else
                {
                    term = norm(t);
                    return(true);
                }
            }
            if (node.Symbol is StartSymbol)
            {
                var alpha = new AutoDiff.Variable();
                var beta  = new AutoDiff.Variable();
                variables.Add(beta);
                variables.Add(alpha);
                AutoDiff.Term branchTerm;
                if (TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out branchTerm))
                {
                    term = branchTerm * alpha + beta;
                    return(true);
                }
                else
                {
                    term = null;
                    return(false);
                }
            }
            term = null;
            return(false);
        }
Пример #4
0
 public bool Visit(AutoDiff.Variable variable)
 {
     return(true);
 }
    private static bool TryTransformToAutoDiff(ISymbolicExpressionTreeNode node, List<AutoDiff.Variable> variables, List<AutoDiff.Variable> parameters, List<string> variableNames, bool updateVariableWeights, out AutoDiff.Term term) {
      if (node.Symbol is Constant) {
        var var = new AutoDiff.Variable();
        variables.Add(var);
        term = var;
        return true;
      }
      if (node.Symbol is Variable) {
        var varNode = node as VariableTreeNode;
        var par = new AutoDiff.Variable();
        parameters.Add(par);
        variableNames.Add(varNode.VariableName);

        if (updateVariableWeights) {
          var w = new AutoDiff.Variable();
          variables.Add(w);
          term = AutoDiff.TermBuilder.Product(w, par);
        } else {
          term = par;
        }
        return true;
      }
      if (node.Symbol is Addition) {
        List<AutoDiff.Term> terms = new List<Term>();
        foreach (var subTree in node.Subtrees) {
          AutoDiff.Term t;
          if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, updateVariableWeights, out t)) {
            term = null;
            return false;
          }
          terms.Add(t);
        }
        term = AutoDiff.TermBuilder.Sum(terms);
        return true;
      }
      if (node.Symbol is Subtraction) {
        List<AutoDiff.Term> terms = new List<Term>();
        for (int i = 0; i < node.SubtreeCount; i++) {
          AutoDiff.Term t;
          if (!TryTransformToAutoDiff(node.GetSubtree(i), variables, parameters, variableNames, updateVariableWeights, out t)) {
            term = null;
            return false;
          }
          if (i > 0) t = -t;
          terms.Add(t);
        }
        if (terms.Count == 1) term = -terms[0];
        else term = AutoDiff.TermBuilder.Sum(terms);
        return true;
      }
      if (node.Symbol is Multiplication) {
        List<AutoDiff.Term> terms = new List<Term>();
        foreach (var subTree in node.Subtrees) {
          AutoDiff.Term t;
          if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, updateVariableWeights, out t)) {
            term = null;
            return false;
          }
          terms.Add(t);
        }
        if (terms.Count == 1) term = terms[0];
        else term = terms.Aggregate((a, b) => new AutoDiff.Product(a, b));
        return true;

      }
      if (node.Symbol is Division) {
        List<AutoDiff.Term> terms = new List<Term>();
        foreach (var subTree in node.Subtrees) {
          AutoDiff.Term t;
          if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, updateVariableWeights, out t)) {
            term = null;
            return false;
          }
          terms.Add(t);
        }
        if (terms.Count == 1) term = 1.0 / terms[0];
        else term = terms.Aggregate((a, b) => new AutoDiff.Product(a, 1.0 / b));
        return true;
      }
      if (node.Symbol is Logarithm) {
        AutoDiff.Term t;
        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
          term = null;
          return false;
        } else {
          term = AutoDiff.TermBuilder.Log(t);
          return true;
        }
      }
      if (node.Symbol is Exponential) {
        AutoDiff.Term t;
        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
          term = null;
          return false;
        } else {
          term = AutoDiff.TermBuilder.Exp(t);
          return true;
        }
      }
      if (node.Symbol is Square) {
        AutoDiff.Term t;
        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
          term = null;
          return false;
        } else {
          term = AutoDiff.TermBuilder.Power(t, 2.0);
          return true;
        }
      }
      if (node.Symbol is SquareRoot) {
        AutoDiff.Term t;
        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
          term = null;
          return false;
        } else {
          term = AutoDiff.TermBuilder.Power(t, 0.5);
          return true;
        }
      }
      if (node.Symbol is Sine) {
        AutoDiff.Term t;
        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
          term = null;
          return false;
        } else {
          term = sin(t);
          return true;
        }
      }
      if (node.Symbol is Cosine) {
        AutoDiff.Term t;
        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
          term = null;
          return false;
        } else {
          term = cos(t);
          return true;
        }
      }
      if (node.Symbol is Tangent) {
        AutoDiff.Term t;
        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
          term = null;
          return false;
        } else {
          term = tan(t);
          return true;
        }
      }
      if (node.Symbol is Erf) {
        AutoDiff.Term t;
        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
          term = null;
          return false;
        } else {
          term = erf(t);
          return true;
        }
      }
      if (node.Symbol is Norm) {
        AutoDiff.Term t;
        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
          term = null;
          return false;
        } else {
          term = norm(t);
          return true;
        }
      }
      if (node.Symbol is StartSymbol) {
        var alpha = new AutoDiff.Variable();
        var beta = new AutoDiff.Variable();
        variables.Add(beta);
        variables.Add(alpha);
        AutoDiff.Term branchTerm;
        if (TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out branchTerm)) {
          term = branchTerm * alpha + beta;
          return true;
        } else {
          term = null;
          return false;
        }
      }
      term = null;
      return false;
    }
 private static bool TryTransformToAutoDiff(ISymbolicExpressionTreeNode node, List<AutoDiff.Variable> variables, List<AutoDiff.Variable> parameters, List<string> variableNames, out AutoDiff.Term term) {
   if (node.Symbol is Constant) {
     var var = new AutoDiff.Variable();
     variables.Add(var);
     term = var;
     return true;
   }
   if (node.Symbol is Variable) {
     var varNode = node as VariableTreeNode;
     var par = new AutoDiff.Variable();
     parameters.Add(par);
     variableNames.Add(varNode.VariableName);
     var w = new AutoDiff.Variable();
     variables.Add(w);
     term = AutoDiff.TermBuilder.Product(w, par);
     return true;
   }
   if (node.Symbol is Addition) {
     List<AutoDiff.Term> terms = new List<Term>();
     foreach (var subTree in node.Subtrees) {
       AutoDiff.Term t;
       if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, out t)) {
         term = null;
         return false;
       }
       terms.Add(t);
     }
     term = AutoDiff.TermBuilder.Sum(terms);
     return true;
   }
   if (node.Symbol is Subtraction) {
     List<AutoDiff.Term> terms = new List<Term>();
     for (int i = 0; i < node.SubtreeCount; i++) {
       AutoDiff.Term t;
       if (!TryTransformToAutoDiff(node.GetSubtree(i), variables, parameters, variableNames, out t)) {
         term = null;
         return false;
       }
       if (i > 0) t = -t;
       terms.Add(t);
     }
     term = AutoDiff.TermBuilder.Sum(terms);
     return true;
   }
   if (node.Symbol is Multiplication) {
     AutoDiff.Term a, b;
     if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out a) ||
       !TryTransformToAutoDiff(node.GetSubtree(1), variables, parameters, variableNames, out b)) {
       term = null;
       return false;
     } else {
       List<AutoDiff.Term> factors = new List<Term>();
       foreach (var subTree in node.Subtrees.Skip(2)) {
         AutoDiff.Term f;
         if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, out f)) {
           term = null;
           return false;
         }
         factors.Add(f);
       }
       term = AutoDiff.TermBuilder.Product(a, b, factors.ToArray());
       return true;
     }
   }
   if (node.Symbol is Division) {
     // only works for at least two subtrees
     AutoDiff.Term a, b;
     if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out a) ||
       !TryTransformToAutoDiff(node.GetSubtree(1), variables, parameters, variableNames, out b)) {
       term = null;
       return false;
     } else {
       List<AutoDiff.Term> factors = new List<Term>();
       foreach (var subTree in node.Subtrees.Skip(2)) {
         AutoDiff.Term f;
         if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, out f)) {
           term = null;
           return false;
         }
         factors.Add(1.0 / f);
       }
       term = AutoDiff.TermBuilder.Product(a, 1.0 / b, factors.ToArray());
       return true;
     }
   }
   if (node.Symbol is Logarithm) {
     AutoDiff.Term t;
     if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
       term = null;
       return false;
     } else {
       term = AutoDiff.TermBuilder.Log(t);
       return true;
     }
   }
   if (node.Symbol is Exponential) {
     AutoDiff.Term t;
     if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
       term = null;
       return false;
     } else {
       term = AutoDiff.TermBuilder.Exp(t);
       return true;
     }
   }
   if (node.Symbol is Square) {
     AutoDiff.Term t;
     if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
       term = null;
       return false;
     } else {
       term = AutoDiff.TermBuilder.Power(t, 2.0);
       return true;
     }
   } if (node.Symbol is SquareRoot) {
     AutoDiff.Term t;
     if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
       term = null;
       return false;
     } else {
       term = AutoDiff.TermBuilder.Power(t, 0.5);
       return true;
     }
   } if (node.Symbol is Sine) {
     AutoDiff.Term t;
     if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
       term = null;
       return false;
     } else {
       term = sin(t);
       return true;
     }
   } if (node.Symbol is Cosine) {
     AutoDiff.Term t;
     if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
       term = null;
       return false;
     } else {
       term = cos(t);
       return true;
     }
   } if (node.Symbol is Tangent) {
     AutoDiff.Term t;
     if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
       term = null;
       return false;
     } else {
       term = tan(t);
       return true;
     }
   } if (node.Symbol is Erf) {
     AutoDiff.Term t;
     if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
       term = null;
       return false;
     } else {
       term = erf(t);
       return true;
     }
   } if (node.Symbol is Norm) {
     AutoDiff.Term t;
     if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
       term = null;
       return false;
     } else {
       term = norm(t);
       return true;
     }
   }
   if (node.Symbol is StartSymbol) {
     var alpha = new AutoDiff.Variable();
     var beta = new AutoDiff.Variable();
     variables.Add(beta);
     variables.Add(alpha);
     AutoDiff.Term branchTerm;
     if (TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out branchTerm)) {
       term = branchTerm * alpha + beta;
       return true;
     } else {
       term = null;
       return false;
     }
   }
   term = null;
   return false;
 }
Пример #7
0
 private static bool TryTransformToAutoDiff(ISymbolicExpressionTreeNode node, List <AutoDiff.Variable> variables, List <AutoDiff.Variable> parameters, List <string> variableNames, out AutoDiff.Term term)
 {
     if (node.Symbol is Constant)
     {
         var var = new AutoDiff.Variable();
         variables.Add(var);
         term = var;
         return(true);
     }
     if (node.Symbol is Variable)
     {
         var varNode = node as VariableTreeNode;
         var par     = new AutoDiff.Variable();
         parameters.Add(par);
         variableNames.Add(varNode.VariableName);
         var w = new AutoDiff.Variable();
         variables.Add(w);
         term = AutoDiff.TermBuilder.Product(w, par);
         return(true);
     }
     if (node.Symbol is Addition)
     {
         List <AutoDiff.Term> terms = new List <Term>();
         foreach (var subTree in node.Subtrees)
         {
             AutoDiff.Term t;
             if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, out t))
             {
                 term = null;
                 return(false);
             }
             terms.Add(t);
         }
         term = AutoDiff.TermBuilder.Sum(terms);
         return(true);
     }
     if (node.Symbol is Subtraction)
     {
         List <AutoDiff.Term> terms = new List <Term>();
         for (int i = 0; i < node.SubtreeCount; i++)
         {
             AutoDiff.Term t;
             if (!TryTransformToAutoDiff(node.GetSubtree(i), variables, parameters, variableNames, out t))
             {
                 term = null;
                 return(false);
             }
             if (i > 0)
             {
                 t = -t;
             }
             terms.Add(t);
         }
         term = AutoDiff.TermBuilder.Sum(terms);
         return(true);
     }
     if (node.Symbol is Multiplication)
     {
         AutoDiff.Term a, b;
         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out a) ||
             !TryTransformToAutoDiff(node.GetSubtree(1), variables, parameters, variableNames, out b))
         {
             term = null;
             return(false);
         }
         else
         {
             List <AutoDiff.Term> factors = new List <Term>();
             foreach (var subTree in node.Subtrees.Skip(2))
             {
                 AutoDiff.Term f;
                 if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, out f))
                 {
                     term = null;
                     return(false);
                 }
                 factors.Add(f);
             }
             term = AutoDiff.TermBuilder.Product(a, b, factors.ToArray());
             return(true);
         }
     }
     if (node.Symbol is Division)
     {
         // only works for at least two subtrees
         AutoDiff.Term a, b;
         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out a) ||
             !TryTransformToAutoDiff(node.GetSubtree(1), variables, parameters, variableNames, out b))
         {
             term = null;
             return(false);
         }
         else
         {
             List <AutoDiff.Term> factors = new List <Term>();
             foreach (var subTree in node.Subtrees.Skip(2))
             {
                 AutoDiff.Term f;
                 if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, out f))
                 {
                     term = null;
                     return(false);
                 }
                 factors.Add(1.0 / f);
             }
             term = AutoDiff.TermBuilder.Product(a, 1.0 / b, factors.ToArray());
             return(true);
         }
     }
     if (node.Symbol is Logarithm)
     {
         AutoDiff.Term t;
         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t))
         {
             term = null;
             return(false);
         }
         else
         {
             term = AutoDiff.TermBuilder.Log(t);
             return(true);
         }
     }
     if (node.Symbol is Exponential)
     {
         AutoDiff.Term t;
         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t))
         {
             term = null;
             return(false);
         }
         else
         {
             term = AutoDiff.TermBuilder.Exp(t);
             return(true);
         }
     }
     if (node.Symbol is Square)
     {
         AutoDiff.Term t;
         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t))
         {
             term = null;
             return(false);
         }
         else
         {
             term = AutoDiff.TermBuilder.Power(t, 2.0);
             return(true);
         }
     }
     if (node.Symbol is SquareRoot)
     {
         AutoDiff.Term t;
         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t))
         {
             term = null;
             return(false);
         }
         else
         {
             term = AutoDiff.TermBuilder.Power(t, 0.5);
             return(true);
         }
     }
     if (node.Symbol is Sine)
     {
         AutoDiff.Term t;
         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t))
         {
             term = null;
             return(false);
         }
         else
         {
             term = sin(t);
             return(true);
         }
     }
     if (node.Symbol is Cosine)
     {
         AutoDiff.Term t;
         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t))
         {
             term = null;
             return(false);
         }
         else
         {
             term = cos(t);
             return(true);
         }
     }
     if (node.Symbol is Tangent)
     {
         AutoDiff.Term t;
         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t))
         {
             term = null;
             return(false);
         }
         else
         {
             term = tan(t);
             return(true);
         }
     }
     if (node.Symbol is Erf)
     {
         AutoDiff.Term t;
         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t))
         {
             term = null;
             return(false);
         }
         else
         {
             term = erf(t);
             return(true);
         }
     }
     if (node.Symbol is Norm)
     {
         AutoDiff.Term t;
         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t))
         {
             term = null;
             return(false);
         }
         else
         {
             term = norm(t);
             return(true);
         }
     }
     if (node.Symbol is StartSymbol)
     {
         var alpha = new AutoDiff.Variable();
         var beta  = new AutoDiff.Variable();
         variables.Add(beta);
         variables.Add(alpha);
         AutoDiff.Term branchTerm;
         if (TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out branchTerm))
         {
             term = branchTerm * alpha + beta;
             return(true);
         }
         else
         {
             term = null;
             return(false);
         }
     }
     term = null;
     return(false);
 }
Пример #8
0
 public void Visit(AutoDiff.Variable variable)
 {
     VariableCount++;
 }
        private AutoDiff.Term ConvertToAutoDiff(ISymbolicExpressionTreeNode node)
        {
            if (node.Symbol is Constant)
            {
                initialConstants.Add(((ConstantTreeNode)node).Value);
                var var = new AutoDiff.Variable();
                variables.Add(var);
                return(var);
            }
            if (node.Symbol is Variable || node.Symbol is BinaryFactorVariable)
            {
                var varNode       = node as VariableTreeNodeBase;
                var factorVarNode = node as BinaryFactorVariableTreeNode;
                // factor variable values are only 0 or 1 and set in x accordingly
                var varValue = factorVarNode != null ? factorVarNode.VariableValue : string.Empty;
                var par      = FindOrCreateParameter(parameters, varNode.VariableName, varValue);

                if (makeVariableWeightsVariable)
                {
                    initialConstants.Add(varNode.Weight);
                    var w = new AutoDiff.Variable();
                    variables.Add(w);
                    return(AutoDiff.TermBuilder.Product(w, par));
                }
                else
                {
                    return(varNode.Weight * par);
                }
            }
            if (node.Symbol is FactorVariable)
            {
                var factorVarNode = node as FactorVariableTreeNode;
                var products      = new List <Term>();
                foreach (var variableValue in factorVarNode.Symbol.GetVariableValues(factorVarNode.VariableName))
                {
                    var par = FindOrCreateParameter(parameters, factorVarNode.VariableName, variableValue);

                    initialConstants.Add(factorVarNode.GetValue(variableValue));
                    var wVar = new AutoDiff.Variable();
                    variables.Add(wVar);

                    products.Add(AutoDiff.TermBuilder.Product(wVar, par));
                }
                return(AutoDiff.TermBuilder.Sum(products));
            }
            if (node.Symbol is LaggedVariable)
            {
                var varNode = node as LaggedVariableTreeNode;
                var par     = FindOrCreateParameter(parameters, varNode.VariableName, string.Empty, varNode.Lag);

                if (makeVariableWeightsVariable)
                {
                    initialConstants.Add(varNode.Weight);
                    var w = new AutoDiff.Variable();
                    variables.Add(w);
                    return(AutoDiff.TermBuilder.Product(w, par));
                }
                else
                {
                    return(varNode.Weight * par);
                }
            }
            if (node.Symbol is Addition)
            {
                List <AutoDiff.Term> terms = new List <Term>();
                foreach (var subTree in node.Subtrees)
                {
                    terms.Add(ConvertToAutoDiff(subTree));
                }
                return(AutoDiff.TermBuilder.Sum(terms));
            }
            if (node.Symbol is Subtraction)
            {
                List <AutoDiff.Term> terms = new List <Term>();
                for (int i = 0; i < node.SubtreeCount; i++)
                {
                    AutoDiff.Term t = ConvertToAutoDiff(node.GetSubtree(i));
                    if (i > 0)
                    {
                        t = -t;
                    }
                    terms.Add(t);
                }
                if (terms.Count == 1)
                {
                    return(-terms[0]);
                }
                else
                {
                    return(AutoDiff.TermBuilder.Sum(terms));
                }
            }
            if (node.Symbol is Multiplication)
            {
                List <AutoDiff.Term> terms = new List <Term>();
                foreach (var subTree in node.Subtrees)
                {
                    terms.Add(ConvertToAutoDiff(subTree));
                }
                if (terms.Count == 1)
                {
                    return(terms[0]);
                }
                else
                {
                    return(terms.Aggregate((a, b) => new AutoDiff.Product(a, b)));
                }
            }
            if (node.Symbol is Division)
            {
                List <AutoDiff.Term> terms = new List <Term>();
                foreach (var subTree in node.Subtrees)
                {
                    terms.Add(ConvertToAutoDiff(subTree));
                }
                if (terms.Count == 1)
                {
                    return(1.0 / terms[0]);
                }
                else
                {
                    return(terms.Aggregate((a, b) => new AutoDiff.Product(a, 1.0 / b)));
                }
            }
            if (node.Symbol is Absolute)
            {
                var x1 = ConvertToAutoDiff(node.GetSubtree(0));
                return(abs(x1));
            }
            if (node.Symbol is AnalyticQuotient)
            {
                var x1 = ConvertToAutoDiff(node.GetSubtree(0));
                var x2 = ConvertToAutoDiff(node.GetSubtree(1));
                return(x1 / (TermBuilder.Power(1 + x2 * x2, 0.5)));
            }
            if (node.Symbol is Logarithm)
            {
                return(AutoDiff.TermBuilder.Log(
                           ConvertToAutoDiff(node.GetSubtree(0))));
            }
            if (node.Symbol is Exponential)
            {
                return(AutoDiff.TermBuilder.Exp(
                           ConvertToAutoDiff(node.GetSubtree(0))));
            }
            if (node.Symbol is Square)
            {
                return(AutoDiff.TermBuilder.Power(
                           ConvertToAutoDiff(node.GetSubtree(0)), 2.0));
            }
            if (node.Symbol is SquareRoot)
            {
                return(AutoDiff.TermBuilder.Power(
                           ConvertToAutoDiff(node.GetSubtree(0)), 0.5));
            }
            if (node.Symbol is Cube)
            {
                return(AutoDiff.TermBuilder.Power(
                           ConvertToAutoDiff(node.GetSubtree(0)), 3.0));
            }
            if (node.Symbol is CubeRoot)
            {
                return(cbrt(ConvertToAutoDiff(node.GetSubtree(0))));
            }
            if (node.Symbol is Sine)
            {
                return(sin(
                           ConvertToAutoDiff(node.GetSubtree(0))));
            }
            if (node.Symbol is Cosine)
            {
                return(cos(
                           ConvertToAutoDiff(node.GetSubtree(0))));
            }
            if (node.Symbol is Tangent)
            {
                return(tan(
                           ConvertToAutoDiff(node.GetSubtree(0))));
            }
            if (node.Symbol is HyperbolicTangent)
            {
                return(tanh(
                           ConvertToAutoDiff(node.GetSubtree(0))));
            }
            if (node.Symbol is Erf)
            {
                return(erf(
                           ConvertToAutoDiff(node.GetSubtree(0))));
            }
            if (node.Symbol is Norm)
            {
                return(norm(
                           ConvertToAutoDiff(node.GetSubtree(0))));
            }
            if (node.Symbol is StartSymbol)
            {
                if (addLinearScalingTerms)
                {
                    // scaling variables α, β are given at the beginning of the parameter vector
                    var alpha = new AutoDiff.Variable();
                    var beta  = new AutoDiff.Variable();
                    variables.Add(beta);
                    variables.Add(alpha);
                    var t = ConvertToAutoDiff(node.GetSubtree(0));
                    return(t * alpha + beta);
                }
                else
                {
                    return(ConvertToAutoDiff(node.GetSubtree(0)));
                }
            }
            throw new ConversionException();
        }
Пример #10
0
 public bool Visit(AutoDiff.Variable variable)
 {
     variable.Parents.Clear();
     UpdateInterval(variable, variable.GlobalMin, variable.GlobalMax);
     return(true);
 }
Пример #11
0
 public override Term Derivative(Variable v)
 {
     return(0);
 }