Пример #1
0
void WaitPhase::calculate(EvalContext context)
{
    if (context.ib()->rule_exec->phase == m_data->phase) {
        children().back()->eval(context);
        forward(children().back());
    }
}
Set<MultiSet<int> > ProductExpr::internalFindQ_V(int order, const EvalContext& context) const
{
  Tabs tab0(0);
  int verb = context.setupVerbosity();
  SUNDANCE_MSG2(verb, tab0 << "ProdExpr::internalFindQ_V(" << order << ")");

  Set<MultiSet<int> > rtn;
  if (order > 1) return rtn;

  const Set<MultipleDeriv>& vLeft 
    = leftEvaluatable()->findV(0, context);
  const Set<MultipleDeriv>& vRight
    = rightEvaluatable()->findV(0, context);

  if (order==0)
  {
    if (vLeft.size() > 0)
    {
      rtn.put(makeMultiSet<int>(0));
    }
    if (vRight.size() > 0)
    {
      rtn.put(makeMultiSet<int>(1));
    }
  }

  if (order==1)
  {
    if (vLeft.size() > 0) rtn.put(makeMultiSet<int>(1));
    if (vRight.size() > 0) rtn.put(makeMultiSet<int>(0));
  }

  SUNDANCE_MSG2(verb, tab0 << "Q_V[" << order << "]=" << rtn);  
  return rtn;
}
Пример #3
0
Set<MultipleDeriv> DiffOp::internalFindC(int order, const EvalContext& context) const
{
  Tabs tabs(0);
  int verb = context.setupVerbosity();
  SUNDANCE_MSG2(verb, tabs << "DiffOp::internalFindC() for " 
    << toString());
  Set<MultipleDeriv> rtn ;

  {
    Tabs tab1;
    SUNDANCE_MSG5(verb, tab1 << "finding R");
    const Set<MultipleDeriv>& R = findR(order, context);
    SUNDANCE_MSG5(verb, tab1 << "finding V");
    const Set<MultipleDeriv>& V = findV(order, context);
    /** Call findC() to ensure that the argument has C tabulated */
    evaluatableArg()->findC(order, context);

    SUNDANCE_MSG5(verb, tab1 << "R=" << R);
    SUNDANCE_MSG5(verb, tab1 << "V=" << V);
    rtn = R.setDifference(V);
    SUNDANCE_MSG3(verb, tabs << "C[" << order << "]=" << rtn);
  }

  SUNDANCE_MSG2(verb, tabs << "C[" << order << "]=R\\V = " << rtn);
  SUNDANCE_MSG2(verb, tabs << "done with DiffOp::internalFindC for "
    << toString());
  return rtn;
}
Set<MultipleDeriv> ExplicitFunctionalDerivativeElement
::internalFindC(int order, const EvalContext& context) const
{
  Tabs tabs(0);
  int verb = context.setupVerbosity();
  SUNDANCE_MSG2(verb, tabs << "ExplicitFunctionalDerivativeElement::internalFindC() for " 
    << toString());
  Set<MultipleDeriv> rtn ;
  if (order < 3) 
  {
    Tabs tab1;
    SUNDANCE_MSG5(verb, tab1 << "finding R");
    const Set<MultipleDeriv>& R = findR(order, context);
    SUNDANCE_MSG5(verb, tab1 << "R=" << R);

    SUNDANCE_MSG5(verb, tab1 << "finding C for arg");
    const Set<MultipleDeriv>& argC 
      = evaluatableArg()->findC(order+1, context);
    SUNDANCE_MSG5(verb, tab1 << "argC=" << argC);

    MultipleDeriv me(fd_);
    Set<MultipleDeriv> tmp = setDivision(argC, makeSet(me));
    rtn = tmp.intersection(R);
  }

  SUNDANCE_MSG2(verb, tabs << "C[" << order << "]=" << rtn);
  SUNDANCE_MSG2(verb, tabs << "done with ExplicitFunctionalDerivativeElement::internalFindC for "
    << toString());
  return rtn;
}
Set<MultipleDeriv> ExplicitFunctionalDerivativeElement
::internalFindW(int order, const EvalContext& context) const
{
  Tabs tab0(0);
  int verb = context.setupVerbosity();
  SUNDANCE_MSG2(verb, tab0 
    << "ExplicitFunctionalDerivativeElement::internalFindW(order="
    << order << ") for " << toString());


  Set<MultipleDeriv> rtn ;

  if (order < 3)
  {
    Tabs tab1;
    const Set<MultipleDeriv>& WArgPlus 
      = evaluatableArg()->findW(order+1, context);
    
    SUNDANCE_MSG5(verb, tab1 << "WArgPlus = " << WArgPlus);
    MultipleDeriv me(fd_);
    Set<MultipleDeriv> WargPlusOslashFD = setDivision(WArgPlus, makeSet(me));
    SUNDANCE_MSG5(verb, tab1 << "WArgPlus / fd = " 
      << WargPlusOslashFD);
    rtn = WargPlusOslashFD;
  }
  SUNDANCE_MSG2(verb, tab0 << "W[" << order << "]=" << rtn);
  SUNDANCE_MSG2(verb, tab0 << "done with ExplicitFunctionalDerivativeElement::internalFindW(" << order << ") for "
                     << toString());

  return rtn;
}
void EvaluatableExpr::setupEval(const EvalContext& context) const
{
  Tabs tabs0(0);
  int verb = context.evalSetupVerbosity();
  SUNDANCE_MSG1(verb, tabs0 << "setupEval() for " << this->toString());
  if (!evaluators_.containsKey(context))
  {
    Tabs tabs;
    SUNDANCE_MSG2(verb, tabs << "creating new evaluator...");
    SUNDANCE_MSG2(verb, tabs << "my sparsity superset = " << std::endl
      << *sparsitySuperset(context));
    RCP<Evaluator> eval;
    if (sparsitySuperset(context)->numDerivs()>0)
    {
      SUNDANCE_MSG2(verb, tabs << "calling createEvaluator()");
      eval = rcp(createEvaluator(this, context));
    }
    else
    {
      SUNDANCE_MSG2(verb, 
        tabs << "EE: no results needed... creating null evaluator");
      eval = rcp(new NullEvaluator());
    }
    evaluators_.put(context, eval);
  }
  else
  {
    Tabs tabs;
    SUNDANCE_MSG2(verb, tabs << "reusing existing evaluator...");
  }
}
Пример #7
0
Set<MultipleDeriv> DiffOp::internalFindW(int order, const EvalContext& context) const
{
  Tabs tabs(0);
  int verb = context.setupVerbosity();

  SUNDANCE_MSG2(verb, tabs << "DiffOp::internalFindW(order="
    << order << ") for " << toString());

  Set<MultipleDeriv> rtn ;
  if (order <= 2)
  {
    Tabs tab1;
    const Set<MultipleDeriv>& W1 = evaluatableArg()->findW(1, context);
    const Set<MultipleDeriv>& WArg = evaluatableArg()->findW(order, context);
    const Set<MultipleDeriv>& WArgPlus = evaluatableArg()->findW(order+1, context);

    SUNDANCE_MSG5(verb, tab1 << "W1 = " << W1);
    SUNDANCE_MSG5(verb, tab1 << "WArg = " << WArg);
    SUNDANCE_MSG5(verb, tab1 << "WArgPlus = " << WArgPlus);
    Set<MultipleDeriv> Tx = applyTx(WArg, mi_);
    Set<MultipleDeriv> ZXx = applyZx(W1, mi_).setUnion(Xx(mi_));
    SUNDANCE_MSG5(verb, tab1 << "Tx(Warg) = " << Tx);
    SUNDANCE_MSG5(verb, tab1 << "ZXx(W1) = " << ZXx);
    Set<MultipleDeriv> WargPlusOslashZXx = setDivision(WArgPlus, ZXx);
    SUNDANCE_MSG5(verb, tab1 << "WArgPlus / ZXx = " 
      << WargPlusOslashZXx);
    rtn = WargPlusOslashZXx.setUnion(Tx); 
  }
  SUNDANCE_MSG3(verb, tabs << "W[" << order << "]=" << rtn);
  SUNDANCE_MSG3(verb, tabs << "done with DiffOp::internalFindW(" << order << ") for "
    << toString());

  return rtn;
}
Пример #8
0
void DiffOp::requestMultiIndexAtEvalPoint(const MultiIndex& mi,
  const MultipleDeriv& u,
  const EvalContext& context) const 
{
  int verb = context.setupVerbosity();
  Tabs tab0(0);
  SUNDANCE_MSG3(verb, tab0 << "DiffOp::requestMultiIndexAtEvalPoint() for=" << toString());
  TEUCHOS_TEST_FOR_EXCEPT(u.size() != 1);
  const Deriv& d = *(u.begin());

  if (d.isFunctionalDeriv())
  {
    const SpatialDerivSpecifier& sds = d.opOnFunc();

    TEUCHOS_TEST_FOR_EXCEPTION(sds.isDivergence(), std::logic_error,
      "divergence operators not possible within DiffOp");
    TEUCHOS_TEST_FOR_EXCEPTION(sds.isNormal(), std::logic_error,
      "normal deriv operators not possible within DiffOp");

    const MultiIndex& newMi = sds.mi();

    const SymbolicFuncElement* sfe = d.symbFuncElem();
    TEUCHOS_TEST_FOR_EXCEPT(sfe == 0);
    const EvaluatableExpr* evalPt = sfe->evalPt();
    const ZeroExpr* z = dynamic_cast<const ZeroExpr*>(evalPt);
    if (z != 0) return;
    const DiscreteFuncElement* df 
      = dynamic_cast<const DiscreteFuncElement*>(evalPt);
    df->addMultiIndex(newMi);
    df->findW(1, context);
    df->findV(1, context);
    df->findC(1, context);
  }
}
Пример #9
0
Value OrExpr::Evaluate(SymbolTable *scope, EvalContext& context, bool asbool)
{
	// Scope override; must do this for every expression that might contain an identifier
	if(this->scope != NULL)
		scope = this->scope;

	// Lowering of A or B:
	//  [A]
	//  [iftrue goto end]
	//  [B]
	//  label end:
	String* value = new String();

	string labelbase = context.GetUniqueLabelName();
	Anchor* endanchor = new Anchor(labelbase + ".end");

	// a
	value->Append( a->Evaluate(scope, context, true).ToCodeString() );
	// iftrue goto end:
	value->Code("1B 03 FF FF FF FF");
	value->AddReference(value->GetPos()-4, endanchor);
	// b
	value->Append( b->Evaluate(scope, context, true).ToCodeString() );
	// end:
	value->AddAnchor(endanchor);

	return Value(value);
}
Пример #10
0
void FinishPhase::calculate(EvalContext context)
{
    map_calculate(children().back(), context);

    if (context.ib()->rule_exec->phase == m_data->phase) {
        finish();
    }
}
Set<MultipleDeriv> 
ConstantExpr::internalFindC(int order, const EvalContext& context) const
{
  Tabs tab;
  SUNDANCE_MSG2(context.setupVerbosity(), 
    tab << "ConstantExpr::internalFindC is forwarding to findR()");
  return findR(order, context);
}
Set<MultipleDeriv> 
ConstantExpr::internalFindV(int order, const EvalContext& context) const
{
  Set<MultipleDeriv> rtn;
  Tabs tab;
  SUNDANCE_MSG2(context.setupVerbosity(), 
    tab << "ConstantExpr::internalFindV is a no-op");
  return rtn;
}
Пример #13
0
Value Operator::value_calculate(Value v, EvalContext context)
{
    static const char* c_capture_name = "predicate_operator_capture";

    if (! m_data) {
        BOOST_THROW_EXCEPTION(
            einval() << errinfo_what(
                "Evaluation without pre evaluation!"
            )
        );
    }

    IronBee::Field capture = IronBee::Field::create_no_copy_list<void *>(
        context.memory_pool(),
        c_capture_name,
        sizeof(c_capture_name) - 1,
        List<void *>::create(context.memory_pool())
    );

    int success = 0;
    try {
        success = m_data->op.execute_instance(
            m_data->instance_data,
            context,
            v,
            capture
        );
    }
    catch (const error& e) {
        string old_what = *boost::get_error_info<errinfo_what>(e);
        e << errinfo_what(
            "Predicate operator failure for " +
            to_s() + " : " + old_what
        );
        throw e;
    }

    if (success) {
        return capture;
    }
    else {
        return Value();
    }
}
Set<MultipleDeriv> 
UnknownParameterElement::internalFindV(int order, const EvalContext& context) const
{
  Tabs tab;
  SUNDANCE_MSG2(context.setupVerbosity(), 
    tab << "UPE::internalFindV is a no-op");
  Set<MultipleDeriv> rtn;

  return rtn;
}
Пример #15
0
Set<MultipleDeriv>
ZeroExpr::internalFindC(int order, const EvalContext& context) const
{
    Set<MultipleDeriv> rtn;

    Tabs tab;
    SUNDANCE_MSG2(context.setupVerbosity(),
                  tab << "ZeroExpr::internalFindC found" << rtn << " for order="
                  << order);
    return rtn;
}
Пример #16
0
Value Transformation::value_calculate(Value v, EvalContext context)
{
    if (! m_data) {
        BOOST_THROW_EXCEPTION(
            einval() << errinfo_what(
                "Reset without pre evaluation!"
            )
        );
    }

    return m_data->transformation.execute(context.memory_pool(), v);
}
RCP<Array<Set<MultipleDeriv> > > 
ExplicitFunctionalDerivativeElement
::internalDetermineR(const EvalContext& context,
                           const Array<Set<MultipleDeriv> >& RInput) const
{
  Tabs tab0(0);
  int verb = context.setupVerbosity();
  SUNDANCE_MSG2(verb, tab0 << "ExplicitFunctionalDerivativeElement::internalDetermineR for=" << toString());
  SUNDANCE_MSG2(verb, tab0 << "RInput = " << RInput );

  RCP<Array<Set<MultipleDeriv> > > rtn 
    = rcp(new Array<Set<MultipleDeriv> >(RInput.size()));
  
  {
    Tabs tab1;
    for (int i=0; i<RInput.size(); i++)
      {
        Tabs tab2;
        const Set<MultipleDeriv>& Wi = findW(i, context);
        SUNDANCE_MSG5(verb,  tab2 << "W[" << i << "] = " << Wi );
        (*rtn)[i] = RInput[i].intersection(Wi);
      }

    Array<Set<MultipleDeriv> > RArg(RInput.size()+1);
    MultipleDeriv me(fd_);
    
    for (int order=1; order<=RInput.size(); order++)
      {
        Tabs tab2;
        SUNDANCE_MSG3(verb, tab2 << "order = " << order);
        if (RInput[order-1].size() == 0) continue;
        const Set<MultipleDeriv>& WArg = evaluatableArg()->findW(order, context);
        const Set<MultipleDeriv>& RMinus = (*rtn)[order-1];

        SUNDANCE_MSG3(verb, tab2 << "RInput = " << RInput[order-1]);
        SUNDANCE_MSG3(verb, tab2 << "FD times RInput = " 
          << setProduct(RMinus, makeSet(me)));
        
        RArg[order].merge(setProduct(RMinus, makeSet(me)).intersection(WArg));
      }
    SUNDANCE_MSG3(verb, tab1 << "RArg = " << RArg);
    
    SUNDANCE_MSG3(verb, tab1 << "calling determineR() for arg "
                       << evaluatableArg()->toString());
    evaluatableArg()->determineR(context, RArg);
  }
  printR(verb, rtn);
  SUNDANCE_MSG2(verb, tab0 << "done with ExplicitFunctionalDerivativeElement::internalDetermineR for "
                     << toString());
  /* all done */  
  return rtn;
}
Set<MultipleDeriv> 
ConstantExpr::internalFindW(int order, const EvalContext& context) const
{
  Set<MultipleDeriv> rtn;

  if (order==0) rtn.put(MultipleDeriv());
  Tabs tab;
  SUNDANCE_MSG2(context.setupVerbosity(), 
    tab << "ConstantExpr::internalFindW found" << rtn << " for order="
    << order);

  return rtn;
}
RCP<SparsitySuperset> 
EvaluatableExpr::sparsitySuperset(const EvalContext& context) const 
{
  Tabs tab;
  
  SUNDANCE_MSG2(context.setupVerbosity(), 
    tab << "getting sparsity superset for " << toString());

  RCP<SparsitySuperset> rtn;

  if (sparsity_.containsKey(context))
  {
    Tabs tab1;
    SUNDANCE_MSG2(context.setupVerbosity(), 
      tab1 << "reusing previously computed data...");
    rtn = sparsity_.get(context);
  }
  else
  {
    Tabs tab1;
    SUNDANCE_MSG2(context.setupVerbosity(), 
      tab1 << "computing from scratch...");
    const Set<MultipleDeriv>& R = findR(context);
    const Set<MultipleDeriv>& C = findC(context);
    const Set<MultipleDeriv>& V = findV(context);
    if (context.setupVerbosity() > 4)
    {
      Out::os() << tab1 << "R=" << R << endl;
      Out::os() << tab1 << "C=" << C << endl;
      Out::os() << tab1 << "V=" << V << endl;
    }
    rtn = rcp(new SparsitySuperset(C.intersection(R), V.intersection(R)));
    sparsity_.put(context, rtn);
  }
  return rtn;
}
Пример #20
0
Value AndExpr::Evaluate(SymbolTable *scope, EvalContext& context, bool asbool)
{
	// Scope override; must do this for every expression that might contain an identifier
	if(this->scope != NULL)
		scope = this->scope;

	// Lowering A and B:
	//  [A]
	//  [iffalse goto end]
	//  [B]
	//  label end:

	String* value = new String();

	// Create internal label
	string labelbase = context.GetUniqueLabelName();
	Anchor* endanchor = new Anchor(labelbase + ".end");

	// Evaluate the first operand
	value->Append( a->Evaluate(scope, context, true).ToCodeString() );

	// Add a jump to the end if the first operand is false
	value->Code("1B 02 FF FF FF FF");
	value->AddReference(value->GetPos()-4, endanchor);

	// TODO:
	//  Hm. I just realized that some boolean expressions (and and or) rely on reference
	//  resolution to operate correctly. Thus, it doesn't make sense to use them in ROM
	//  write statements at the moment, because ROM write statements occur after normal
	//  resolution, but without doing any resolution themselves. Perhaps ROM write statements
	//  should have a special resolution step to take care of stuff like this. (Perhaps
	//  the ROM data itself should be represented as a ByteChunk, with refs?)
	//  Anyway, don't worry about this for now, since using boolean expressions in a ROM
	//  write statement is not a very likely usage scenario.
	// UPDATE: 11/11/2008
	//  This issue has been fixed by moving the evaluation of ROM write subexpressions
	//  back to the evaluation pass of the compiler, and simply caching the results and
	//  resolving references in a later pass. However, it still might be worthwhile to
	//  consider alternative solutions; whole-ROM resolution seems interesting for example.

	// Evaluate the second operand
	value->Append( b->Evaluate(scope, context, true).ToCodeString() );

	// Set the position of the end label
	value->AddAnchor(endanchor);

	return Value(value);
}
Пример #21
0
Set<MultipleDeriv> DiffOp::internalFindV(int order, const EvalContext& context) const
{
  Tabs tabs(0);
  int verb = context.setupVerbosity();
  SUNDANCE_MSG2(verb, tabs << "DiffOp::internalFindV(" << order << ") for " 
    << toString());

  Set<MultipleDeriv> rtn;
  
  if (order <= 2)
  {
    Tabs tab1;
    const Set<MultipleDeriv>& W1 = evaluatableArg()->findW(1, context);
    const Set<MultipleDeriv>& VArg = evaluatableArg()->findV(order, context);
    const Set<MultipleDeriv>& VArgPlus 
      = evaluatableArg()->findV(order+1, context);
    const Set<MultipleDeriv>& WArg = evaluatableArg()->findW(order, context);
    const Set<MultipleDeriv>& WArgPlus 
      = evaluatableArg()->findW(order+1, context);

    SUNDANCE_MSG5(verb, tab1 << "W1=" << W1);
    SUNDANCE_MSG5(verb, tab1 << "VArg=" << VArg);
    SUNDANCE_MSG5(verb, tab1 << "VArgPlus=" << VArgPlus);
    SUNDANCE_MSG5(verb, tab1 << "WArg=" << WArg);
    SUNDANCE_MSG5(verb, tab1 << "WArgPlus=" << WArgPlus);

    Set<MultipleDeriv> Tx = applyTx(VArg, mi_);
    Set<MultipleDeriv> Zx = applyZx(W1, mi_);
    SUNDANCE_MSG5(verb, tab1 << "Tx(Varg) = " << Tx);
    SUNDANCE_MSG5(verb, tab1 << "Zx(W1) = " << Zx);
    Set<MultipleDeriv> WargPlusOslashZx = setDivision(WArgPlus, Zx);
    Set<MultipleDeriv> VargPlusOslashXx = setDivision(VArgPlus, Xx(mi_));
    SUNDANCE_MSG5(verb, tab1 << "WArgPlus / Z_alpha = " 
      << WargPlusOslashZx);
    SUNDANCE_MSG5(verb, tab1 << "VArgPlus / X_alpha = " 
      << VargPlusOslashXx);
    rtn = WargPlusOslashZx.setUnion(VargPlusOslashXx).setUnion(Tx); 
   
    SUNDANCE_MSG5(verb, tab1 << "WArgPlus/Z union VArgPlus/X union T =" << rtn);
    rtn = rtn.intersection(findR(order, context));
  }

  SUNDANCE_MSG2(verb, tabs << "V[" << order << "]=" << rtn);
  SUNDANCE_MSG2(verb, tabs << "done with DiffOp::internalFindV(" << order << ") for "
    << toString());

  return rtn;
}
Set<MultiSet<int> > ProductExpr::internalFindQ_W(int order, const EvalContext& context) const
{
  Tabs tab0(0);
  int verb = context.setupVerbosity();
  SUNDANCE_MSG2(verb, tab0 << "ProdExpr::internalFindQ_W(" << order << ")");

  Set<MultiSet<int> > rtn;
  if (order > 2) return rtn;

  if (order==2)
  {
    rtn.put(makeMultiSet<int>(0,1));
    return rtn;
  }

  Tabs tab1;
  SUNDANCE_MSG3(verb, tab1 << "calling findW(0) for left");
  const Set<MultipleDeriv>& wLeft 
    = leftEvaluatable()->findW(0, context);
  SUNDANCE_MSG3(verb, tab1 << "found wLeft(0)=" << wLeft);

  SUNDANCE_MSG3(verb, tab1 << "calling findW(0) for right");
  const Set<MultipleDeriv>& wRight
    = rightEvaluatable()->findW(0, context);
  SUNDANCE_MSG3(verb, tab1 << "found wRight(0)=" << wRight);
  
  if (order==0)
  {
    if (wLeft.size() > 0)
    {
      rtn.put(makeMultiSet<int>(0));
    }
    if (wRight.size() > 0)
    {
      rtn.put(makeMultiSet<int>(1));
    }
  }
  
  if (order==1)
  {
    if (wLeft.size() > 0) rtn.put(makeMultiSet<int>(1));
    if (wRight.size() > 0) rtn.put(makeMultiSet<int>(0));
  }
  
  SUNDANCE_MSG2(verb, tab0 << "Q_W[" << order << "]=" << rtn);
  return rtn;
}
Set<MultipleDeriv> 
UnknownParameterElement::internalFindW(int order, const EvalContext& context) const
{
  Tabs tab;
  SUNDANCE_MSG2(context.setupVerbosity(), 
    tab << "in UPE::internalFindW, order=" << order);
  Set<MultipleDeriv> rtn;

  if (order==0) 
  {
    if (!evalPtIsZero()) rtn.put(MultipleDeriv());
  }
  else if (order==1)
  {
    MultipleDeriv md = makeMultiDeriv(funcDeriv(this));
    rtn.put(md);
  }

  return rtn;
}
Array<Set<MultipleDeriv> > EvaluatableExpr
::computeInputR(const EvalContext& context,
  const Array<Set<MultiSet<int> > >& funcIDCombinations,
  const Array<Set<MultiIndex> >& spatialDerivs) const 
{
  int verb = context.setupVerbosity();
  Tabs tabs(0);
  SUNDANCE_MSG2(verb, tabs << "in EE::computeInputR()");
  Array<Set<MultipleDeriv> > rtn(funcIDCombinations.size());
  for (int order=0; order<funcIDCombinations.size(); order++)
  {
    Tabs tabs1;
    SUNDANCE_MSG2(verb, tabs << "order=" << order);
    SUNDANCE_MSG2(verb, tabs1 << "funcID combs=" 
      << funcIDCombinations[order]);
    const Set<MultipleDeriv>& W = findW(order, context);
    SUNDANCE_MSG2(verb, tabs1 << "W[order=" << order << "]=" << W);

    for (Set<MultipleDeriv>::const_iterator i=W.begin(); i!=W.end(); i++)
    {
      Tabs tab2;
      const MultipleDeriv& nonzeroDeriv = *i;
      if (nonzeroDeriv.isInRequiredSet(funcIDCombinations[order],
          spatialDerivs[order]))
      {
        SUNDANCE_MSG2(verb, tab2 << "md=" << nonzeroDeriv 
          << " added to inputR");
        rtn[order].put(nonzeroDeriv);
      }
      else
      {
        SUNDANCE_MSG2(verb, tab2 << "md=" << nonzeroDeriv << " not needed");
      }
    }
  }
  SUNDANCE_MSG2(verb, tabs << "inputR=" << rtn);
  return rtn;
}
RCP<Array<Set<MultipleDeriv> > > EvaluatableExpr
::internalDetermineR(const EvalContext& context,
  const Array<Set<MultipleDeriv> >& RInput) const
{
  Tabs tab0(0);
  int verb = context.setupVerbosity();
  RCP<Array<Set<MultipleDeriv> > > rtn 
    = rcp(new Array<Set<MultipleDeriv> >(RInput.size()));

  SUNDANCE_MSG2(verb, tab0 << "EE::internalDetermineR() for " << toString() );
  SUNDANCE_MSG2(verb, tab0 << "RInput = " << RInput );

  for (int i=0; i<RInput.size(); i++)
  {
    Tabs tab1;
    if (RInput[i].size()==0) continue;
    const Set<MultipleDeriv>& Wi = findW(i, context);
    SUNDANCE_MSG3(verb, tab1 << "W[" << i << "] = " << Wi );
    (*rtn)[i] = RInput[i].intersection(Wi);
  }

  printR(verb, rtn);
  return rtn;
}
Set<MultipleDeriv> ExplicitFunctionalDerivativeElement
::internalFindV(int order, const EvalContext& context) const
{
  Tabs tabs(0);
  int verb = context.setupVerbosity();
  SUNDANCE_MSG2(verb, tabs << "ExplicitFunctionalDerivativeElement::internalFindV(" << order << ") for " 
                     << toString());

  Set<MultipleDeriv> rtn;
  
  {
    Tabs tab1;
    SUNDANCE_MSG5(verb, tab1 << "finding R");
    const Set<MultipleDeriv>& R = findR(order, context);
    SUNDANCE_MSG5(verb, tab1 << "finding C");
    const Set<MultipleDeriv>& C = findC(order, context);
    rtn = R.setDifference(C);
  }
  SUNDANCE_MSG2(verb, tabs << "V[" << order << "]=" << rtn);
  SUNDANCE_MSG2(verb, tabs << "done with ExplicitFunctionalDerivativeElement::internalFindV(" << order << ") for "
    << toString());
  
  return rtn;
}
CellDiameterExprEvaluator::CellDiameterExprEvaluator(
    const CellDiameterExpr* expr,
    const EvalContext& context)
    : SubtypeEvaluator<CellDiameterExpr>(expr, context),
      stringRep_(expr->toString())
{

    Tabs tabs;
    int verb = context.setupVerbosity();
    SUNDANCE_MSG1(verb, tabs << "initializing cell diameter expr evaluator for "
                  << expr->toString());
    SUNDANCE_MSG2(verb, tabs << "return sparsity " << std::endl << *(this->sparsity)());

    TEUCHOS_TEST_FOR_EXCEPTION(this->sparsity()->numDerivs() > 1, std::logic_error,
                               "CellDiameterExprEvaluator ctor found a sparsity table "
                               "with more than one entry. The bad sparsity table is "
                               << *(this->sparsity)());

    /*
     * There is only one possible entry in the nozeros table for a
     * cell diameter expression: a zeroth derivative.
     */

    for (int i=0; i<this->sparsity()->numDerivs(); i++)
    {
        const MultipleDeriv& d = this->sparsity()->deriv(i);

        TEUCHOS_TEST_FOR_EXCEPTION(d.order()!=0, std::logic_error,
                                   "CellDiameterExprEvaluator ctor found an entry in the "
                                   "sparsity superset that is not a zeroth-order derivative. "
                                   "The bad entry is " << this->sparsity()->deriv(i)
                                   << ". The superset is "
                                   << *(this->sparsity)());
        addVectorIndex(i, 0);
    }
}
Пример #28
0
Value MenuExpr::Evaluate(SymbolTable* scope, EvalContext& context, bool asbool)
{
	if(this->scope != NULL)
		scope = this->scope;

	// Lowering a menu statement:
	// [19 02][option][02] - for each option
	// [1C 0C $cols][11][12]
	// [09 $num (statementjmps)]
	// [goto end]
	// [statement][goto end] - for each statement
	// label end:

	String* value = new String();

	// Create internal labels
	vector<Anchor*> anchors;
	string labelbase = context.GetUniqueLabelName();

	for(unsigned int i = 0; i < options.size(); ++i) {
		std::stringstream ss;
		ss << ".opt" << i;
		Anchor* a = new Anchor(labelbase + ss.str());
		anchors.push_back(a);
	}
	Anchor* endanchor = new Anchor(labelbase + ".end");

	// First, append the options between [19 02] and [02] codes
	for(unsigned int i = 0; i < options.size(); ++i) {
		value->Code("19 02");
		value->Append( options[i]->Evaluate(scope, context).ToCodeString() );
		value->Code("02");
	}

	// Next, append the option display commands
	// If we're only using two options, and no number of columns was specified,
	// use "1C 07", otherwise, use "1C 0C".
	if(options.size() == 2 && defcolumns)
		value->Code("1C 07");
	else
		value->Code("1C 0C");

	value->Byte(columns);// write exactly one byte for the column count
	value->Code("11 12");

	// Next, the multi-jump code
	value->Code("09");
	value->Byte(results.size());// write exactly one byte for the option count
	for(unsigned int i = 0; i < results.size(); ++i) {
		value->Code("FF FF FF FF");
		value->AddReference(value->GetPos() - 4, anchors[i]);
	}

	// Add a jump to the "default" option after the multi-jump, or end if no default
	value->Code("0A FF FF FF FF");
	if(defaultopt != -1)
		value->AddReference(value->GetPos() - 4, anchors[defaultopt]);
	else
		value->AddReference(value->GetPos() - 4, endanchor);


	// Finally, write out all the options, with a "goto end" after each
	// At each point we set the position of the relevant label.
	for(unsigned int i = 0; i < results.size(); ++i)
	{
		value->AddAnchor(anchors[i]);
		value->Append( results[i]->Evaluate(scope, context).ToCodeString() );

		// Add a "goto end" after every statement, in case it falls through
		value->Code("0A FF FF FF FF");
		value->AddReference(value->GetPos() - 4, endanchor);
	}

	// Last step: set position of the "end" label
	value->AddAnchor(endanchor);

	return Value(value);
}
Пример #29
0
Value IfExpr::Evaluate(SymbolTable *env, EvalContext& context, bool asbool)
{
	if(this->scope != NULL)
		env = this->scope;

	/*
	 * Lowering an if statement:
	 *
	 *  [condition]
	 *  [iffalse goto falselbl]
	 *  [thenstmt]
	 *  [goto endlbl]
	 * falselbl:
	 *  [elsestmt]
	 * endlbl:
	 */

	String* value = new String();
	
	// Create internal labels
	string labelbase = context.GetUniqueLabelName();
	Anchor* endanchor = new Anchor(labelbase + ".end");
	Anchor* falseanchor = new Anchor(labelbase + ".false");

	// First, we evaluate the condition
	Value cond_val = condition->Evaluate(env, context, true);

	// TODO: this might be an opportunity to do some typechecking on the returned value,
	// instead of just converting it to a string. Maybe some warnings would be appropriate?
	// (i.e., conditioning on a number value, which is almost always meaningless)

	// append cond_val to the output:
	value->Append(cond_val.ToCodeString());

	// Then, we output an "iffalse goto false" instruction, and register a jump reference
	value->Code("1B 02 FF FF FF FF");
	value->AddReference(value->GetSize() - 4, falseanchor);

	// Evaluate the "then" statement
	Value then_val = thenexpr->Evaluate(env, context);
	value->Append(then_val.ToCodeString());


	// Add a "goto end"
	// TODO: strictly speaking, we can dispense with this last goto when
	// there is no 'else' clause. We'll leave it here for now until we
	// get the first round of regression tests in place, and then we'll
	// update it along with the other evaluation refactoring.
	value->Code("0A FF FF FF FF");
	value->AddReference(value->GetPos() - 4, endanchor);

	// Set the position of the false anchor within the string
	value->AddAnchor(falseanchor);

	// Evaluate the "else" statement
	if(elseexpr) {
		Value else_val = elseexpr->Evaluate(env, context);
		value->Append(else_val.ToCodeString());
	}

	// Set the position of the "end" label
	value->AddAnchor(endanchor);

	return Value(value);
}
ProductEvaluator::ProductEvaluator(const ProductExpr* expr,
  const EvalContext& context)
  : BinaryEvaluator<ProductExpr>(expr, context),
    maxOrder_(this->sparsity()->maxOrder()),
    resultIndex_(maxOrder_+1),
    resultIsConstant_(maxOrder_+1),
    hasWorkspace_(maxOrder_+1),
    workspaceIsLeft_(maxOrder_+1),
    workspaceIndex_(maxOrder_+1),
    workspaceCoeffIndex_(maxOrder_+1),
    workspaceCoeffIsConstant_(maxOrder_+1),
    ccTerms_(maxOrder_+1),
    cvTerms_(maxOrder_+1),
    vcTerms_(maxOrder_+1),
    vvTerms_(maxOrder_+1),
    startingVectors_(maxOrder_+1),
    startingParities_(maxOrder_+1)
{
  int verb = context.evalSetupVerbosity();

  try
  {
    Tabs tabs(0);
    {
      Tabs tab;
      Tabs tabz;
      SUNDANCE_MSG1(verb,
        tabs << "initializing product evaluator for " 
        << expr->toString());

      SUNDANCE_MSG2(verb,
        tab << "return sparsity " << std::endl
        << tabz << *(this->sparsity)());

      SUNDANCE_MSG2(verb,
        tab << "left sparsity " << std::endl 
        << tabz << *(leftSparsity()) << std::endl
        << tabz << "right sparsity " << std::endl 
        << tabz << *(rightSparsity()));
  
      SUNDANCE_MSG3(verb,
        tab << "left vector index map " 
        << leftEval()->vectorIndexMap() << std::endl
        << tabz << "right vector index map " 
        << rightEval()->vectorIndexMap() << std::endl
        << tabz << "left constant index map " 
        << leftEval()->constantIndexMap() << std::endl
        << tabz << "right constant index map " 
        << rightEval()->constantIndexMap());
    }                
    int vecResultIndex = 0;
    int constResultIndex = 0;

    for (int i=0; i<this->sparsity()->numDerivs(); i++)
    {
      Tabs tab0;
      const MultipleDeriv& d = this->sparsity()->deriv(i);

      SUNDANCE_MSG2(verb,
        tabs << std::endl 
        << tabs << "finding rules for deriv " << d);

      int order = d.order();

      /* Determine the index into which the result will be written */
      bool resultIsConstant = this->sparsity()->state(i)==ConstantDeriv; 
      resultIsConstant_[order].append(resultIsConstant);
      if (resultIsConstant)
      {
        SUNDANCE_MSG3(verb,
          tab0 << std::endl 
          << tab0 << "result will be in constant index " << constResultIndex);
        resultIndex_[order].append(constResultIndex);
        addConstantIndex(i, constResultIndex);
        constResultIndex++;
      }
      else
      {
        SUNDANCE_MSG3(verb,
          tab0 << std::endl 
          << tab0 << "result will be in constant index " << vecResultIndex);
        resultIndex_[order].append(vecResultIndex);
        addVectorIndex(i, vecResultIndex);
        vecResultIndex++;
      }

      /* If possible, we want to do the calculations in-place, writing into
       * one of the two operand's results vectors for the same derivative.
       * Provided that we process derivatives in descending order, it is
       * safe to destroy the operands' result vectors.
       */
       
      int dnLeftIndex = leftSparsity()->getIndex(d);
      int dnRightIndex = rightSparsity()->getIndex(d);

      
      bool hasVectorWorkspace = false;
      bool workspaceIsLeft = false;
      int workspaceIndex = -1;
      int workspaceCoeffIndex = -1;
      bool workspaceCoeffIsConstant = false;


      bool dnLeftIsConst = false;
      if (dnLeftIndex != -1) 
      {
        dnLeftIsConst = leftSparsity()->state(dnLeftIndex)==ConstantDeriv;
      }
      bool dnRightIsConst = false;
      if (dnRightIndex != -1)
      {
        dnRightIsConst = rightSparsity()->state(dnRightIndex)==ConstantDeriv;
      }

      /* First try to use the left result as a workspace */
      if (dnLeftIndex != -1 && !dnLeftIsConst 
        && rightSparsity()->containsDeriv(MultipleDeriv()))
      {
        /* We can write onto left vector */
        hasVectorWorkspace = true;
        workspaceIndex = leftEval()->vectorIndexMap().get(dnLeftIndex);       
        SUNDANCE_MSG3(verb,
          tab0 << "using left as workspace");
        workspaceIsLeft = true;
        int d0RightIndex = rightSparsity()->getIndex(MultipleDeriv());
        bool d0RightIsConst = rightSparsity()->state(d0RightIndex)==ConstantDeriv;
        workspaceCoeffIsConstant = d0RightIsConst;
        if (d0RightIsConst)
        {
          workspaceCoeffIndex 
            = rightEval()->constantIndexMap().get(d0RightIndex);
        }
        else
        {
          workspaceCoeffIndex 
            = rightEval()->vectorIndexMap().get(d0RightIndex);
        }
      }

      /* If the left didn't provide a workspace, try the right */
      if (!hasVectorWorkspace && dnRightIndex != -1 && !dnRightIsConst
        && leftSparsity()->containsDeriv(MultipleDeriv()))
      {
        /* We can write onto right vector */
        hasVectorWorkspace = true;
        workspaceIndex = rightEval()->vectorIndexMap().get(dnRightIndex); 
        workspaceIsLeft = false;
        SUNDANCE_MSG3(verb,
          tab0 << "using right as workspace");
        int d0LeftIndex = leftSparsity()->getIndex(MultipleDeriv());
        bool d0LeftIsConst = leftSparsity()->state(d0LeftIndex)==ConstantDeriv;
        workspaceCoeffIsConstant = d0LeftIsConst;
        if (d0LeftIsConst)
        {
          workspaceCoeffIndex 
            = leftEval()->constantIndexMap().get(d0LeftIndex);
        }
        else
        {
          workspaceCoeffIndex 
            = leftEval()->vectorIndexMap().get(d0LeftIndex);
        }
      }
      
      if (hasVectorWorkspace && verb > 2)
      {
        std::string wSide = "right";
        MultipleDeriv wsDeriv;
        if (workspaceIsLeft) 
        {
          wSide = "left";
          wsDeriv = leftSparsity()->deriv(dnLeftIndex);
        }
        else
        {
          wsDeriv = rightSparsity()->deriv(dnRightIndex);
        }
        SUNDANCE_MSG2(verb, tab0 << "has workspace vector: "
          << wSide << " deriv= " 
          << wsDeriv
          << ", coeff index= " << workspaceCoeffIndex);
      }
      else
      {
        SUNDANCE_MSG2(verb, tab0 << "has no workspace vector");
      }

      hasWorkspace_[order].append(hasVectorWorkspace);
      workspaceIsLeft_[order].append(workspaceIsLeft);
      workspaceIndex_[order].append(workspaceIndex);
      workspaceCoeffIndex_[order].append(workspaceCoeffIndex);
      workspaceCoeffIsConstant_[order].append(workspaceCoeffIsConstant);
      
      ProductRulePerms perms;
      d.productRulePermutations(perms);
      SUNDANCE_MSG4(verb,
        tabs << "product rule permutations " << perms);

      Array<Array<int> > ccTerms;
      Array<Array<int> > cvTerms;
      Array<Array<int> > vcTerms;
      Array<Array<int> > vvTerms;
      Array<int> startingVector;
      ProductParity startingParity;

      bool hasStartingVector = false;

      for (ProductRulePerms::const_iterator 
             iter = perms.begin(); iter != perms.end(); iter++)
      {
        Tabs tab1;
        MultipleDeriv dLeft = iter->first.first();
        MultipleDeriv dRight = iter->first.second();
        int multiplicity = iter->second;
          
        /* skip this combination if we've already pulled it out 
         * for workspace */
        if (hasVectorWorkspace && workspaceIsLeft 
          && dLeft.order()==order) continue;
        if (hasVectorWorkspace && !workspaceIsLeft 
          && dRight.order()==order) continue;

        if (!leftSparsity()->containsDeriv(dLeft)
          || !rightSparsity()->containsDeriv(dRight)) continue;
        int iLeft = leftSparsity()->getIndex(dLeft);
        int iRight = rightSparsity()->getIndex(dRight);

        if (iLeft==-1 || iRight==-1) continue;
        SUNDANCE_MSG4(verb,
          tab1 << "left deriv=" << dLeft);
        SUNDANCE_MSG4(verb,
          tab1 << "right deriv=" << dRight);

        bool leftIsConst = leftSparsity()->state(iLeft)==ConstantDeriv;
        bool rightIsConst = rightSparsity()->state(iRight)==ConstantDeriv;

        if (leftIsConst)
        {
          Tabs tab2;
          SUNDANCE_MSG4(verb,
            tab2 << "left is const");
          int leftIndex = leftEval()->constantIndexMap().get(iLeft);
          if (rightIsConst)
          {
            SUNDANCE_MSG4(verb,
              tab2 << "right is const");
            int rightIndex = rightEval()->constantIndexMap().get(iRight);
            ccTerms.append(tuple(leftIndex, rightIndex, multiplicity));
          }
          else
          {
            SUNDANCE_MSG4(verb,
              tab2 << "right is vec");
            int rightIndex = rightEval()->vectorIndexMap().get(iRight);
            if (!hasVectorWorkspace && !hasStartingVector)
            {
              SUNDANCE_MSG4(verb,
                tab1 << "found c-v starting vec");
              startingVector = tuple(leftIndex, rightIndex, 
                multiplicity);
              hasStartingVector = true;
              startingParity = ConstVec;
            }
            else
            {
              SUNDANCE_MSG4(verb,
                tab1 << "found c-v term");
              cvTerms.append(tuple(leftIndex, rightIndex, 
                  multiplicity));
            }
          }
        }
        else
        {
          Tabs tab2;
          SUNDANCE_MSG4(verb,
            tab2 << "left is vec");
          int leftIndex = leftEval()->vectorIndexMap().get(iLeft);
          if (rightIsConst)
          {
            SUNDANCE_MSG4(verb,
              tab2 << "right is const");
            int rightIndex = rightEval()->constantIndexMap().get(iRight);
            if (!hasVectorWorkspace && !hasStartingVector)
            {
              SUNDANCE_MSG4(verb,
                tab1 << "found v-c starting vec");
              startingVector = tuple(leftIndex, rightIndex, 
                multiplicity);
              hasStartingVector = true;
              startingParity = VecConst;
            }
            else
            {
              SUNDANCE_MSG4(verb,
                tab1 << "found v-c term");
              vcTerms.append(tuple(leftIndex, rightIndex, 
                  multiplicity));
            }
          }
          else
          {
            SUNDANCE_MSG4(verb,
              tab2 << "right is vec");
            int rightIndex = rightEval()->vectorIndexMap().get(iRight);
            if (!hasVectorWorkspace && !hasStartingVector)
            {
              SUNDANCE_MSG4(verb,
                tab1 << "found v-v starting vec");
              startingVector = tuple(leftIndex, rightIndex, 
                multiplicity);
              hasStartingVector = true;
              startingParity = VecVec;
            }
            else
            {
              SUNDANCE_MSG4(verb,
                tab1 << "found v-v term");
              vvTerms.append(tuple(leftIndex, rightIndex, 
                  multiplicity));
            }
          }
        }
      }
      ccTerms_[order].append(ccTerms);
      cvTerms_[order].append(cvTerms);
      vcTerms_[order].append(vcTerms);
      vvTerms_[order].append(vvTerms);
      startingVectors_[order].append(startingVector);
      startingParities_[order].append(startingParity);

      if (verb > 2)
      {
        Tabs tab0;
        Out::os() << tab0 << "deriv " << i << " order=" << order ;
        if (resultIsConstant)
        {
          Out::os() << " constant result, index= ";
        }
        else
        {
          Out::os() << " vector result, index= ";
        }
        Out::os() << resultIndex_[order] << std::endl;
        {
          Tabs tab1;
          if (hasStartingVector) 
          {
            Out::os() << tab1 << "starting vector " << startingVector << std::endl;
          }
          Out::os() << tab1 << "c-c terms " << ccTerms << std::endl;
          Out::os() << tab1 << "c-v terms " << cvTerms << std::endl;
          Out::os() << tab1 << "v-c terms " << vcTerms << std::endl;
          Out::os() << tab1 << "v-v terms " << vvTerms << std::endl;
        }
      }
    }

    if (verb > 2)
    {
      Out::os() << tabs << "maps: " << std::endl;
      Out::os() << tabs << "vector index map " << vectorIndexMap() << std::endl;
      Out::os() << tabs << "constant index map " << constantIndexMap() << std::endl;
    }
  }
  catch(std::exception& e)
  {
    TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, 
      "exception detected in ProductEvaluator: expr="
      << expr->toString() << std::endl
      << "exception=" << e.what());
  }
}