Exemplo n.º 1
0
int factorial(const MultipleDeriv& ms)
{
  Sundance::Map<Deriv, int> counts;
    
  for (MultipleDeriv::const_iterator i=ms.begin(); i!=ms.end(); i++)
  {
    if (counts.containsKey(*i)) counts[*i]++;
    else counts.put(*i, 1);
  }

  int rtn = 1;
  for (Sundance::Map<Deriv, int>::const_iterator
         i=counts.begin(); i!=counts.end(); i++)
  {
    int f = 1;
    for (int j=1; j<=i->second; j++) f *= j;
    rtn *= f;
  }
  return rtn;
}
bool ReorderSum::doTransform(const RCP<ScalarExpr>& left, 
                             const RCP<ScalarExpr>& right,
                             int sign, RCP<ScalarExpr>& rtn) const
{
  TimeMonitor timer(reorderSumTimer());
  /* first we check to see whether the terms are already in order.
   * The left and right trees are already ordered, so that if the
   * first term on the right is after the last term on the left, the
   * combination of both is already ordered. In that case, nothing more needs
   * to be done. 
   */
  Expr L = Expr::handle(left);
  Expr R = Expr::handle(right);
  Sundance::Map<Expr, int> tree = L.getSumTree();
  Sundance::Map<Expr, int>::const_reverse_iterator iL = tree.rbegin();
  Expr endOfLeft = iL->first;
  Sundance::Map<Expr, int> rightTree = R.getSumTree();
  Sundance::Map<Expr, int>::const_iterator iR = rightTree.begin();
  Expr startOfRight = iR->first;

  if (endOfLeft.lessThan(startOfRight))
    {
      Tabs tab1;
      SUNDANCE_VERB_MEDIUM(tab1 << "Terms are already ordered, doing nothing");
      return false;
    }
  else
    {
      Tabs tab1;

      for (Map<Expr, int>::const_iterator i=rightTree.begin(); i!=rightTree.end(); i++)
        {
          int leftCount = 0;
          if (tree.containsKey(i->first))
            {
              leftCount = tree[i->first];
            }
          int count = leftCount + sign * i->second;
          tree.put(i->first, count);
        }
      SUNDANCE_VERB_MEDIUM(tab1 << "Ordered terms are: " << tree);      


      Expr sum = new ZeroExpr();

      /* add up all terms. If no terms are left after cancellations, the result will 
       * be zero. */
      for (Map<Expr, int>::const_iterator i=tree.begin(); i!=tree.end(); i++)
        {
          const Expr& term = i->first;
          int count = i->second;
          if (count==0) continue;
          if (count==1) sum = sum + term;
          else if (count==-1) sum = sum - term;
          else sum = sum + count*term;
        }
      
      rtn = getScalar(sum);
      return true;
    }
}