コード例 #1
0
void DiscreteFuncElementEvaluator
::internalEval(const EvalManager& mgr,
               Array<double>& constantResults,
               Array<RCP<EvalVector> >& vectorResults) const 
{
  Tabs tabs(0);
  SUNDANCE_MSG1(mgr.verb(),
    tabs << "DiscreteFuncElementEvaluator::eval: expr=" 
    << expr()->toString());

  vectorResults.resize(mi_.size());
  for (int i=0; i<mi_.size(); i++)
    {
      Tabs tab2;
      vectorResults[i] = mgr.popVector();
      TEUCHOS_TEST_FOR_EXCEPTION(!vectorResults[i]->isValid(), 
                         std::logic_error,
                         "invalid evaluation vector allocated in "
                         "DiscreteFuncElementEvaluator::internalEval()");
      SUNDANCE_MSG2(mgr.verb(),tab2<< "setting string rep " << stringReps_[i]);
      vectorResults[i]->setString(stringReps_[i]);
    }
  mgr.evalDiscreteFuncElement(expr(), mi_, vectorResults);
  mgr.stack().setVecSize(vectorResults[0]->length());
  
  if (mgr.verb() > 1)
    {
      Out::os() << tabs << "results " << std::endl;
      mgr.showResults(Out::os(), sparsity(), vectorResults,
                            constantResults);
    }
  SUNDANCE_MSG1(mgr.verb(), tabs << "DiscreteFuncEvaluator::eval() done"); 
}
コード例 #2
0
void CurveNormEvaluator::internalEval(const EvalManager& mgr,
  Array<double>& constantResults,
  Array<RCP<EvalVector> >& vectorResults) const 
{
  Tabs tabs(0);

  SUNDANCE_MSG2(mgr.verb(), tabs << "CurveNormEvaluator::eval() expr="
    << expr()->toString());

  if (mgr.verb() > 2)
    {
      Out::os() << tabs << "sparsity = " 
                << std::endl << tabs << *(this->sparsity)() << std::endl;
    }

  if (this->sparsity()->numDerivs() > 0)
    {
      vectorResults.resize(1);
      vectorResults[0] = mgr.popVector();
      SUNDANCE_MSG3(mgr.verb(), tabs << "forwarding to evaluation manager");

      mgr.evalCurveNormExpr(expr(), vectorResults[0]);

      mgr.stack().setVecSize(vectorResults[0]->length());
      if (EvalVector::shadowOps()) vectorResults[0]->setString(stringRep_);
    }

  if (mgr.verb() > 1)
    {
      Out::os() << tabs << "results " << std::endl;
      mgr.showResults(Out::os(), this->sparsity(), vectorResults,
                            constantResults);
    }
}
コード例 #3
0
void EFDEEvaluator::internalEval(const EvalManager& mgr,
  Array<double>& constantResults,
  Array<RCP<EvalVector> >& vectorResults) const 
{
  TimeMonitor timer(efdeEvalTimer());
  Tabs tabs;

  SUNDANCE_MSG1(mgr.verb(), tabs << "EFDEEvaluator::eval() expr=" 
    << expr()->toString());

  SUNDANCE_MSG2(mgr.verb(), tabs << "sparsity = " << std::endl 
    << *(this->sparsity)());

  constantResults.resize(constValIndexToArgIndexMap_.size());
  vectorResults.resize(varValIndexToArgIndexMap_.size());

  /* evaluate the argument */
  Array<RCP<EvalVector> > argVectorResults;
  Array<double> argConstantResults;

  evalOperand(mgr, argConstantResults, argVectorResults);


  if (mgr.verb() > 2)
    {
      Tabs tab1;
      Out::os() << tab1 << "EFDE operand results" << std::endl;
      argSparsitySuperset()->print(Out::os(), argVectorResults,
                                   argConstantResults);
    }


  for (int i=0; i<constantResults.size(); i++)
  {
    constantResults[i] = argConstantResults[constValIndexToArgIndexMap_[i]];
  }

  
  for (int i=0; i<vectorResults.size(); i++)
  {
    vectorResults[i] = mgr.popVector();
    const RCP<EvalVector>& v = argVectorResults[varValIndexToArgIndexMap_[i]];
    vectorResults[i]->setTo_V(v.get());
  }

  
  

  if (mgr.verb() > 2)
  {
    Tabs tab1;
    Out::os() << tab1 << "results " << std::endl;
    this->sparsity()->print(Out::os(), vectorResults,
      constantResults);
  }
}
コード例 #4
0
void NullEvaluator::internalEval(const EvalManager& mgr,
                                 Array<double>& constantResults,
                                 Array<RCP<EvalVector> >& vectorResults) const 
{
  Tabs tab;
  SUNDANCE_MSG1(mgr.verb(), tab << "doing null evaluation... nothing to do");
}
コード例 #5
0
void UnaryMinusEvaluator
::internalEval(const EvalManager& mgr,
               Array<double>& constantResults,
               Array<RCP<EvalVector> >& vectorResults) const
{
  Tabs tab;
  SUNDANCE_MSG1(mgr.verb(),
    tab << "UnaryMinusEvaluator::eval() expr=" << expr()->toString());


  /* evaluate the argument */
  evalOperand(mgr, constantResults, vectorResults);


  if (mgr.verb() > 2)
    {
      Out::os() << tab << "UnaryMinus operand results" << std::endl;
      argSparsitySuperset()->print(Out::os(), vectorResults,
                           constantResults);
    }

  for (int i=0; i<constantResults.size(); i++)
    {
      constantResults[i] *= -1;
    }

  for (int i=0; i<vectorResults.size(); i++)
    {
      vectorResults[i]->multiply_S(-1.0);
    }

  
  if (mgr.verb() > 1)
    {
      Out::os() << tab << "UnaryMinus results" << std::endl;
      sparsity()->print(Out::os(), vectorResults,
                           constantResults);
    }

  
}
コード例 #6
0
void CoordExprEvaluator::internalEval(const EvalManager& mgr,
  Array<double>& constantResults,
  Array<RCP<EvalVector> >& vectorResults) const 
{
  Tabs tabs(0);

  SUNDANCE_MSG1(mgr.verb(), tabs << "CoordExprEvaluator::eval() expr=" << expr()->toString());

  SUNDANCE_MSG2(mgr.verb(), tabs << "sparsity = " << std::endl 
    << *(this->sparsity)())

  if (doValue_)
    {
      Tabs tab2;
      SUNDANCE_MSG3(mgr.verb(), tab2 << "computing value");
      vectorResults.resize(1);
      vectorResults[0] = mgr.popVector();
      mgr.evalCoordExpr(expr(), vectorResults[0]);
      mgr.stack().setVecSize(vectorResults[0]->length());
      vectorResults[0]->setString(stringRep_);
    }
  
  if (doDeriv_)
    {
      Tabs tab2;
      SUNDANCE_MSG3(mgr.verb(), tab2 << "computing derivative");
      constantResults.resize(1);
      constantResults[0] = 1.0;
    }

  if (mgr.verb() > 1)
    {
      Tabs tab1;
      Out::os() << tab1 << "results " << std::endl;
      mgr.showResults(Out::os(), this->sparsity(), vectorResults,
                            constantResults);
    }

}
コード例 #7
0
void ProductEvaluator
::internalEval(const EvalManager& mgr,
  Array<double>& constantResults,
  Array<RCP<EvalVector> >& vectorResults) const
{
  Tabs tabs(0);

  SUNDANCE_MSG1(mgr.verb(),
    tabs << "ProductEvaluator::eval() expr=" 
    << expr()->toString());

  /* evaluate the children */
  Array<RCP<EvalVector> > leftVectorResults; 
  Array<RCP<EvalVector> > rightVectorResults; 
  Array<double> leftConstantResults;
  Array<double> rightConstantResults;
  evalChildren(mgr, leftConstantResults, leftVectorResults,
    rightConstantResults, rightVectorResults);

  if (mgr.verb() > 2)
  {
    Out::os() << tabs << "left operand results" << std::endl;
    mgr.showResults(Out::os(), leftSparsity(), leftVectorResults,
      leftConstantResults);
    Out::os() << tabs << "right operand results" << std::endl;
    mgr.showResults(Out::os(), rightSparsity(), rightVectorResults,
      rightConstantResults);
  }
  
  constantResults.resize(this->sparsity()->numConstantDerivs());
  vectorResults.resize(this->sparsity()->numVectorDerivs());

  /* Evaluate from high to low differentiation order. This is necessary
   * so that we can do in-place evaluation of derivatives, overwriting
   * one of the operands' vectors */

  for (int order=maxOrder_; order>=0; order--)
  {
    for (int i=0; i<resultIndex_[order].size(); i++)
    {
      double constantVal = 0.0;
      const Array<Array<int> >& ccTerms = ccTerms_[order][i];
      for (int j=0; j<ccTerms.size(); j++)
      {
        /* add L*R*multiplicity to result */
        constantVal += leftConstantResults[ccTerms[j][0]] 
          * rightConstantResults[ccTerms[j][1]] * ccTerms[j][2];
      }
      /* If this derivative is a constant, we're done. */
      if (resultIsConstant_[order][i]) 
      {
        constantResults[resultIndex_[order][i]] = constantVal;
        continue;
      }


      /* For the vector case, the first thing to do is get storage
       * for the result. If we can reuse one of the operands' results
       * as workspace, great. If not, we'll need to allocate a new
       * vector. */
      RCP<EvalVector> result;
      if (hasWorkspace_[order][i])
      {
        int index = workspaceIndex_[order][i];
        int coeffIndex = workspaceCoeffIndex_[order][i];
        bool coeffIsConstant = workspaceCoeffIsConstant_[order][i];
        if (workspaceIsLeft_[order][i])
        {
          result = leftVectorResults[index];
          if (coeffIsConstant)
          {
            const double& coeff = rightConstantResults[coeffIndex];
            if (!isOne(coeff)) result->multiply_S(coeff);
          }
          else
          {
            const RCP<EvalVector>& coeff 
              = rightVectorResults[coeffIndex];
            result->multiply_V(coeff.get());
          }
        }
        else
        {
          result = rightVectorResults[index];
          if (coeffIsConstant)
          {
            const double& coeff = leftConstantResults[coeffIndex];
            if (!isOne(coeff)) result->multiply_S(coeff);
          }
          else
          {
            const RCP<EvalVector>& coeff 
              = leftVectorResults[coeffIndex];
            result->multiply_V(coeff.get());
          }
        }
        SUNDANCE_MSG5(mgr.verb(), tabs << "workspace = " << result->str());
      }
      else
      {
        result = mgr.popVector();
        const Array<int>& sv = startingVectors_[order][i];
        int multiplicity = sv[2];
        switch(startingParities_[order][i])
        {
          case VecVec:
            if (!isZero(constantVal))
            {
              if (!isOne(multiplicity))
              {
                result->setTo_S_add_SVV(constantVal,
                  multiplicity,
                  leftVectorResults[sv[0]].get(),
                  rightVectorResults[sv[1]].get());
              }
              else
              {
                result->setTo_S_add_VV(constantVal,
                  leftVectorResults[sv[0]].get(),
                  rightVectorResults[sv[1]].get());
              }
            }
            else
            {
              if (!isOne(multiplicity))
              {
                result->setTo_SVV(multiplicity,
                  leftVectorResults[sv[0]].get(),
                  rightVectorResults[sv[1]].get());
              }
              else
              {
                result->setTo_VV(leftVectorResults[sv[0]].get(),
                  rightVectorResults[sv[1]].get());
              }
            }
            SUNDANCE_MSG5(mgr.verb(), tabs << "init to v-v prod, m="
              << multiplicity << ", left=" 
              << leftVectorResults[sv[0]]->str()
              << ", right=" 
              << rightVectorResults[sv[1]]->str()
              << ", result=" << result->str());
            break;
          case VecConst:
            if (!isZero(constantVal))
            {
              if (!isOne(multiplicity*rightConstantResults[sv[1]]))
              {
                result->setTo_S_add_SV(constantVal,
                  multiplicity
                  *rightConstantResults[sv[1]],  
                  leftVectorResults[sv[0]].get());
              }
              else
              {
                result->setTo_S_add_V(constantVal,
                  leftVectorResults[sv[0]].get());
              }
            }
            else
            {
              if (!isOne(multiplicity*rightConstantResults[sv[1]]))
              {
                result->setTo_SV(multiplicity
                  *rightConstantResults[sv[1]],  
                  leftVectorResults[sv[0]].get());
              }
              else
              {
                result->setTo_V(leftVectorResults[sv[0]].get());
              }
            }
            SUNDANCE_MSG5(mgr.verb(), tabs << "init to v-c prod, m="
              << multiplicity << ", left=" 
              << leftVectorResults[sv[0]]->str()
              << ", right=" 
              << rightConstantResults[sv[1]]
              << ", result=" << result->str());
            break;
          case ConstVec:
            if (!isZero(constantVal))
            {
              if (!isOne(multiplicity*leftConstantResults[sv[0]]))
              {
                result->setTo_S_add_SV(constantVal,
                  multiplicity
                  *leftConstantResults[sv[0]],  
                  rightVectorResults[sv[1]].get());
              }
              else
              {
                result->setTo_S_add_V(constantVal,  
                  rightVectorResults[sv[1]].get());
              }
            }
            else
            {
              if (!isOne(multiplicity*leftConstantResults[sv[0]]))
              {
                result->setTo_SV(multiplicity
                  *leftConstantResults[sv[0]],  
                  rightVectorResults[sv[1]].get());
              }
              else
              {
                result->setTo_V(rightVectorResults[sv[1]].get());
              }
            }
            SUNDANCE_MSG5(mgr.verb(), tabs << "init to c-v prod, m="
              << multiplicity << ", left=" 
              << leftConstantResults[sv[0]]
              << ", right=" 
              << rightVectorResults[sv[1]]->str()
              << ", result=" << result->str());
                  
        }
        SUNDANCE_MSG4(mgr.verb(), tabs << "starting value = " << result->str());
      }
      vectorResults[resultIndex_[order][i]] = result;

      const Array<Array<int> >& cvTerms = cvTerms_[order][i];
      const Array<Array<int> >& vcTerms = vcTerms_[order][i];
      const Array<Array<int> >& vvTerms = vvTerms_[order][i];

      for (int j=0; j<cvTerms.size(); j++)
      {
        SUNDANCE_MSG4(mgr.verb(), tabs << "adding c-v term " << cvTerms[j]);
              
        double multiplicity = cvTerms[j][2];
        double scalar = multiplicity*leftConstantResults[cvTerms[j][0]];
        const EvalVector* vec = rightVectorResults[cvTerms[j][1]].get();
        if (!isOne(scalar))
        {
          result->add_SV(scalar, vec);
        }
        else
        {
          result->add_V(vec);
        }
      } 

      for (int j=0; j<vcTerms.size(); j++)
      {
        SUNDANCE_MSG4(mgr.verb(), tabs << "adding v-c term " << vcTerms[j]);

        double multiplicity = vcTerms[j][2];
        double scalar = multiplicity*rightConstantResults[vcTerms[j][1]];
        const EvalVector* vec = leftVectorResults[vcTerms[j][0]].get();
        if (!isOne(scalar))
        {
          result->add_SV(scalar, vec);
        }
        else
        {
          result->add_V(vec);
        }
      }

      for (int j=0; j<vvTerms.size(); j++)
      {
        SUNDANCE_MSG4(mgr.verb(), tabs << "adding v-v term " << vvTerms[j]);

        double multiplicity = vvTerms[j][2];
        const EvalVector* vec1 = leftVectorResults[vvTerms[j][0]].get();
        const EvalVector* vec2 = rightVectorResults[vvTerms[j][1]].get();
        if (!isOne(multiplicity))
        {
          result->add_SVV(multiplicity, vec1, vec2);
        }
        else
        {
          result->add_VV(vec1, vec2);
        }
      }

          
    }
  }

  if (mgr.verb() > 1)
  {
    Out::os() << tabs << "product result " << std::endl;
    mgr.showResults(Out::os(), this->sparsity(), vectorResults,
      constantResults);
  }
}
コード例 #8
0
void DiffOpEvaluator::internalEval(const EvalManager& mgr,
  Array<double>& constantResults,
  Array<RCP<EvalVector> >& vectorResults)  const
{
  Tabs tabs;
  SUNDANCE_MSG1(mgr.verb(), tabs << "DiffOpEvaluator::eval() expr=" 
    << expr()->toString());

  /* evaluate the argument */
  Array<RCP<EvalVector> > argVectorResults;
  Array<double> argConstantResults;

  SUNDANCE_MSG2(mgr.verb(), tabs << "evaluating operand");
  evalOperand(mgr, argConstantResults, argVectorResults);


  if (mgr.verb() > 2)
  {
    Tabs tab1;
    Out::os() << tabs << "DiffOp operand results" << std::endl;
    mgr.showResults(Out::os(), argSparsitySuperset(), argVectorResults,
      argConstantResults);
  }



  /* evaluate the required discrete functions */
  SUNDANCE_MSG2(mgr.verb(), tabs << "evaluating discrete functions, num funcs= " << funcEvaluators_.size());

  Array<Array<RCP<EvalVector> > > funcVectorResults(funcEvaluators_.size());
  Array<double> funcConstantResults;
  for (int i=0; i<funcEvaluators_.size(); i++)
  {
    funcEvaluators_[i]->eval(mgr, funcConstantResults, funcVectorResults[i]);
  }
  
  constantResults.resize(this->sparsity()->numConstantDerivs());
  vectorResults.resize(this->sparsity()->numVectorDerivs());
  
  SUNDANCE_MSG3(mgr.verb(), tabs << "summing spatial/functional chain rule");

  for (int i=0; i<this->sparsity()->numDerivs(); i++)
  {
    Tabs tab1;
    SUNDANCE_MSG4(mgr.verb(), tab1 << "working on deriv " 
      << this->sparsity()->deriv(i));

    /* add constant monomials */
    SUNDANCE_MSG4(mgr.verb(), tab1 << "have " <<  constantMonomials_[i].size()
      << " constant monomials");
    double constantVal = 0.0;
    for (int j=0; j<constantMonomials_[i].size(); j++)
    {
      SUNDANCE_MSG4(mgr.verb(), tab1 << "adding in constant monomial (index "
        << constantMonomials_[i][j] 
        << " in arg results)");
      constantVal += argConstantResults[constantMonomials_[i][j]];
    }
    if (isConstant_[i])
    {
      constantResults[resultIndices_[i]] = constantVal;
      SUNDANCE_MSG4(mgr.verb(), tab1 << "result is constant: value=" 
        << constantVal);
      continue;
    }

    RCP<EvalVector> result;
    bool vecHasBeenAllocated = false;

    /* add in the vector monomials */
    const Array<int>& vm = vectorMonomials_[i];
    SUNDANCE_MSG4(mgr.verb(), tab1 << "have " << vm.size() 
      << " vector monomials");
    for (int j=0; j<vm.size(); j++)
    {
      Tabs tab2;

      const RCP<EvalVector>& v = argVectorResults[vm[j]];

      SUNDANCE_MSG4(mgr.verb(), tab2 << "found vec monomial term " << v->str());

      /* if we've not yet allocated a vector for the results, 
       * do so now, and set it to the initial value */ 
      if (!vecHasBeenAllocated)
      {
        SUNDANCE_MSG4(mgr.verb(), tab2 << "allocated result vector");
        result = mgr.popVector();
        vecHasBeenAllocated = true;
        if (isZero(constantVal))
        {
          result->setTo_V(v.get());
        }
        else
        {
          result->setTo_S_add_V(constantVal, v.get());
        }
      }
      else
      {
        result->add_V(v.get());
      }
      SUNDANCE_MSG4(mgr.verb(), tab2 << "result is " << result->str());
    }
      
    /* add in the function terms with constant coeffs */
    const Array<int>& cf = constantFuncCoeffs_[i];
    SUNDANCE_MSG4(mgr.verb(), tab1 << "adding " << cf.size()
      << " func terms with constant coeffs");
    for (int j=0; j<cf.size(); j++)
    {
      Tabs tab2;
      const double& coeff = argConstantResults[cf[j]];
      int fIndex = constantCoeffFuncIndices_[i][j];
      int miIndex = constantCoeffFuncMi_[i][j];
      const RCP<EvalVector>& fValue 
        = funcVectorResults[fIndex][miIndex];

      SUNDANCE_MSG4(mgr.verb(), tab2 << "found term: coeff= " 
        << coeff << ", func value=" << fValue->str());
          
      /* if we've not yet allocated a vector for the results, 
       * do so now, and set it to the initial value */ 
      if (!vecHasBeenAllocated)
      {
        SUNDANCE_MSG4(mgr.verb(), tab2 << "allocated result vector");
        result = mgr.popVector();
        vecHasBeenAllocated = true;
        if (isOne(coeff))
        {
          if (isZero(constantVal))
          {
            result->setTo_V(fValue.get());
          }
          else
          {
            result->setTo_S_add_V(constantVal, fValue.get());
          }
        }
        else
        {
          if (isZero(constantVal))
          {
            result->setTo_SV(coeff, fValue.get());
          }
          else
          {
            result->setTo_S_add_SV(constantVal, coeff, fValue.get());
          }
        }
      }
      else
      {
        if (isOne(coeff))
        {
          result->add_V(fValue.get());
        }
        else
        {
          result->add_SV(coeff, fValue.get());
        }
      }
      SUNDANCE_MSG4(mgr.verb(), tab2 << "result is " << result->str());
    }

      
    /* add in the function terms with vector coeffs */
    const Array<int>& vf = vectorFuncCoeffs_[i];
    SUNDANCE_MSG4(mgr.verb(), tab1 << "adding " << vf.size()
      << " func terms with vector coeffs");
    for (int j=0; j<vf.size(); j++)
    {
      Tabs tab2;

      const RCP<EvalVector>& coeff = argVectorResults[vf[j]];
      int fIndex = vectorCoeffFuncIndices_[i][j];
      int miIndex = vectorCoeffFuncMi_[i][j];
      const RCP<EvalVector>& fValue 
        = funcVectorResults[fIndex][miIndex];

      SUNDANCE_MSG4(mgr.verb(), tab2 << "found term: coeff= " 
        << coeff->str() << ", func value=" 
        << fValue->str());
          
      /* if we've not yet allocated a vector for the results, 
       * do so now, and set it to the initial value */ 
      if (!vecHasBeenAllocated)
      {
        SUNDANCE_MSG4(mgr.verb(), tab2 << "allocated result vector");
        result = mgr.popVector();
        vecHasBeenAllocated = true;
        result->setTo_VV(coeff.get(), fValue.get());
      }
      else
      {
        result->add_VV(coeff.get(), fValue.get());
      }
      SUNDANCE_MSG4(mgr.verb(), tab2 << "result is " << result->str());
    }

    TEUCHOS_TEST_FOR_EXCEPTION(!vecHasBeenAllocated, std::logic_error,
      "created empty vector in DiffOpEvaluator::internalEval");
    vectorResults[resultIndices_[i]] = result;
  }

  if (mgr.verb() > 1)
  {
    Out::os() << tabs << "diff op results" << std::endl;
    mgr.showResults(Out::os(), sparsity(), vectorResults,
      constantResults);
  }
  SUNDANCE_MSG1(mgr.verb(), tabs << "done spatial/functional chain rule");
}