예제 #1
0
CValidatedUnit CEvaluationNodeCall::getUnit(const CMathContainer & math,
    const std::vector< CValidatedUnit > & units) const
{
  CEvaluationTree * pTree = NULL;

  switch (mSubType)
    {
      case S_FUNCTION:
        pTree = mpFunction;
        break;

      case S_EXPRESSION:
        pTree = mpExpression;
        break;

      default:
        return CValidatedUnit();
        break;
    }

  CUnitValidator Validator(math, *pTree);
  Validator.validateUnits(CValidatedUnit(CBaseUnit::undefined, false), units);

  return Validator.getUnit();
}
예제 #2
0
void CUnitValidator::getUnits()
{
  CValidatedUnit tmpUnit;
  CNodeContextIterator< CEvaluationNode, std::vector< CValidatedUnit > > it(const_cast< CEvaluationNode * >(mTree.getRoot()));

  while (it.next() != it.end())
    {
      if (*it != NULL)
        {
          switch (it->mainType())
            {
              case CEvaluationNode::T_VARIABLE:
                tmpUnit = it->getUnit(mMathContainer, mVariableUnits);
                break;

              case CEvaluationNode::T_OBJECT:
              {
                CObjectInterface * pObject = const_cast< CObjectInterface * >(static_cast< CEvaluationNodeObject * >(*it)->getObjectInterfacePtr());
                std::vector< CValidatedUnit > ObjectUnit;

                if (pObject != NULL)
                  {
                    std::map < CObjectInterface *, CValidatedUnit >::iterator found = mObjectUnits.find(pObject);

                    if (found == mObjectUnits.end())
                      {
                        found = mObjectUnits.insert(std::make_pair(pObject, CValidatedUnit(CBaseUnit::undefined, false))).first;
                      }

                    ObjectUnit.push_back(found->second);
                  }
                else
                  {
                    ObjectUnit.push_back(CValidatedUnit(CBaseUnit::undefined, false));
                  }

                tmpUnit = it->getUnit(mMathContainer, ObjectUnit);
              }
              break;

              default:
                tmpUnit = it->getUnit(mMathContainer, it.context());
                break;
            }

          if (it.parentContextPtr() != NULL)
            {
              it.parentContextPtr()->push_back(tmpUnit);
            }

          // tmpUnit.buildExpression(pretty);
          // std::cout << "getUnit: " << it->getData() << ", " << tmpUnit.getExpression() << std::endl;

          mNodeUnits[*it] = tmpUnit;
        }
    }
}
예제 #3
0
bool CUnitValidator::validateUnits(const CUnit & unit,
                                   const std::vector< CUnit > & variableUnits)
{
  mTargetUnit = CValidatedUnit(unit, false);
  mProvidedVariableUnits.resize(variableUnits.size());
  std::vector< CUnit >::const_iterator itSrc = variableUnits.begin();
  std::vector< CUnit >::const_iterator endSrc = variableUnits.end();
  std::vector< CValidatedUnit >::iterator itTarget = mProvidedVariableUnits.begin();

  for (; itSrc != endSrc; ++itSrc, ++itTarget)
    {
      *itTarget = CValidatedUnit(*itSrc, false);
    }

  return validate();
}
예제 #4
0
// virtual
CValidatedUnit CEvaluationNodeVariable::getUnit(const CMathContainer & /* container */,
    const std::vector< CValidatedUnit > & units) const
{
  if (mIndex < units.size())
    {
      return units[mIndex];
    }

  return CValidatedUnit();
}
예제 #5
0
// virtual
CValidatedUnit CEvaluationNodeCall::setUnit(const CMathContainer & container,
    const std::map < CEvaluationNode *, CValidatedUnit > & currentUnits,
    std::map < CEvaluationNode *, CValidatedUnit > & targetUnits) const
{
  CEvaluationTree * pTree = NULL;

  switch (mSubType)
    {
      case S_FUNCTION:
        pTree = mpFunction;
        break;

      case S_EXPRESSION:
        pTree = mpExpression;
        break;

      default:
        return CValidatedUnit();
        break;
    }

  // Retrieve the current units of the variables
  std::vector< CEvaluationNode * >::const_iterator it = mCallNodes.begin();
  std::vector< CEvaluationNode * >::const_iterator end = mCallNodes.end();

  std::vector< CValidatedUnit > CurrentVariableUnits(mCallNodes.size());
  std::vector< CValidatedUnit >::iterator itUnit = CurrentVariableUnits.begin();

  for (; it != end; ++it, ++itUnit)
    {
      *itUnit = currentUnits.find(const_cast< CEvaluationNode * >(*it))->second;
    }

  CUnitValidator Validator(container, *pTree);

  Validator.validateUnits(CValidatedUnit::merge(currentUnits.find(const_cast< CEvaluationNodeCall * >(this))->second,
                          targetUnits[const_cast< CEvaluationNodeCall * >(this)]),
                          CurrentVariableUnits);

  std::vector< CValidatedUnit >::const_iterator itValidatedVariableUnit = Validator.getVariableUnits().begin();

  for (it = mCallNodes.begin(); it != end; ++it, ++itValidatedVariableUnit)
    {
      std::map < CEvaluationNode * , CValidatedUnit >::iterator found = targetUnits.find(const_cast< CEvaluationNode * >(*it));

      if (found == targetUnits.end())
        {
          found = targetUnits.insert(std::make_pair(const_cast< CEvaluationNode * >(*it), CValidatedUnit(CBaseUnit::undefined, false))).first;
        }

      found->second = CValidatedUnit::merge(found->second, *itValidatedVariableUnit);
    }

  return Validator.getUnit();
}
예제 #6
0
// virtual
CValidatedUnit CEvaluationNodeDelay::setUnit(const CMathContainer & container,
    const std::map < CEvaluationNode * , CValidatedUnit > & currentUnits,
    std::map < CEvaluationNode * , CValidatedUnit > & targetUnits) const
{
  CValidatedUnit Delay(CEvaluationNode::setUnit(container, currentUnits, targetUnits));

  targetUnits[mpDelayValueNode] = Delay;
  targetUnits[mpDelayLagNode] = CValidatedUnit(container.getModel().getTimeUnit(), false);

  return Delay;
}
예제 #7
0
// virtual
CValidatedUnit CEvaluationNodeDelay::getUnit(const CMathContainer & container,
    const std::vector< CValidatedUnit > & units) const
{
  // The units of the delay functions are the units of the delay value which is the first child
  CValidatedUnit Delay = units[0];
  CValidatedUnit Lag = CValidatedUnit::merge(CValidatedUnit(container.getModel().getTimeUnit(), false), units[1]);

  Delay.setConflict(Delay.conflict() || Lag.conflict());

  return Delay;
}
예제 #8
0
//virtual
CValidatedUnit CEvaluationNode::getUnit(const CMathContainer & /* math */,
                                        const std::vector< CValidatedUnit > & /*units*/) const
{
  return CValidatedUnit(CBaseUnit::dimensionless, false);
}
예제 #9
0
bool CUnitValidator::setUnits()
{
  bool UnitDetermined = false;
  CValidatedUnit tmpUnit;
  std::map < CEvaluationNode * , CValidatedUnit > CurrentNodeUnits(mNodeUnits);
  std::map < CEvaluationNode * , CValidatedUnit > TargetNodeUnits;
  mNodeUnits.clear();

  std::map < CEvaluationNode * , CValidatedUnit >::iterator found;

  CNodeIterator< CEvaluationNode > it(const_cast< CEvaluationNode * >(mTree.getRoot()));
  it.setProcessingModes(CNodeIteratorMode::Before);

  TargetNodeUnits.insert(std::make_pair(*it, mTargetUnit));

  while (it.next() != it.end())
    {
      if (*it != NULL)
        {
          tmpUnit = it->setUnit(mMathContainer, CurrentNodeUnits, TargetNodeUnits);
          mNodeUnits[*it] = tmpUnit;

          // tmpUnit.buildExpression(pretty);
          // std::cout << "setUnit: " << it->getData() << ", " << tmpUnit.getExpression() << std::endl;

          switch (it->mainType())
            {
              case CEvaluationNode::T_VARIABLE:
              {
                size_t Index = static_cast< CEvaluationNodeVariable * >(*it)->getIndex();

                if (Index >= mVariableUnits.size())
                  {
                    CValidatedUnit Default;
                    mVariableUnits.resize(Index, Default);
                  }

                bool Undefined = mVariableUnits[Index] == CBaseUnit::undefined;

                mVariableUnits[Index] = CValidatedUnit::merge(mVariableUnits[Index], tmpUnit);

                UnitDetermined |= Undefined && !(mVariableUnits[Index] == CBaseUnit::undefined);
              }
              break;

              case CEvaluationNode::T_OBJECT:
              {
                CObjectInterface * pObject = const_cast< CObjectInterface * >(static_cast< CEvaluationNodeObject * >(*it)->getObjectInterfacePtr());

                if (pObject != NULL)
                  {
                    std::map < CObjectInterface *, CValidatedUnit >::iterator found = mObjectUnits.find(pObject);

                    if (found == mObjectUnits.end())
                      {
                        found = mObjectUnits.insert(std::make_pair(pObject, CValidatedUnit(CBaseUnit::undefined, false))).first;
                      }

                    bool Undefined = found->second == CBaseUnit::undefined;

                    found->second = CValidatedUnit::merge(found->second, tmpUnit);

                    UnitDetermined |= Undefined && !(found->second == CBaseUnit::undefined);
                  }
              }
              break;

              default:
                break;
            }
        }
    }

  std::cout << std::endl;

  return UnitDetermined;
}
예제 #10
0
// virtual
CValidatedUnit CEvaluationNodeFunction::setUnit(const CMathContainer & container,
        const std::map < CEvaluationNode * , CValidatedUnit > & currentUnits,
        std::map < CEvaluationNode * , CValidatedUnit > & targetUnits) const
{
    CValidatedUnit Result = CValidatedUnit::merge(currentUnits.find(const_cast< CEvaluationNodeFunction * >(this))->second,
                            targetUnits[const_cast< CEvaluationNodeFunction * >(this)]);

    switch ((SubType)this->subType())
    {
    case S_LOG:
    case S_LOG10:
    case S_EXP:
    case S_SIN:
    case S_COS:
    case S_TAN:
    case S_SEC:
    case S_CSC:
    case S_COT:
    case S_SINH:
    case S_COSH:
    case S_TANH:
    case S_SECH:
    case S_CSCH:
    case S_COTH:
    case S_ARCSIN:
    case S_ARCCOS:
    case S_ARCTAN:
    case S_ARCSEC:
    case S_ARCCSC:
    case S_ARCCOT:
    case S_ARCSINH:
    case S_ARCCOSH:
    case S_ARCTANH:
    case S_ARCSECH:
    case S_ARCCSCH:
    case S_ARCCOTH:
    case S_FACTORIAL:
    case S_NOT:
        targetUnits[mpArgNode1] = CValidatedUnit(CBaseUnit::dimensionless, false);
        break;

    case S_MAX:
    case S_MIN:
    case S_RUNIFORM:
    case S_RNORMAL:
        targetUnits[mpArgNode1] = Result;
        targetUnits[mpArgNode2] = Result;
        break;

    case S_MINUS:
    case S_PLUS:
    case S_FLOOR:
    case S_CEIL:
    case S_ABS:
    case S_RPOISSON:
        targetUnits[mpArgNode1] = Result;
        break;

    case S_RGAMMA:
        targetUnits[mpArgNode1] = CValidatedUnit(CBaseUnit::dimensionless, false);
        targetUnits[mpArgNode2] = Result.exponentiate(-1);

        break;

    case S_SQRT:
        targetUnits[mpArgNode1] = Result.exponentiate(2.0);
        break;

    default:
        Result.setConflict(true);
        break;
    }

    return Result;
}
예제 #11
0
CValidatedUnit CEvaluationNodeFunction::getUnit(const CMathContainer & /* container */,
        const std::vector< CValidatedUnit > & units) const
{
    CValidatedUnit Unit(CBaseUnit::dimensionless, false);

    switch ((SubType)this->subType())
    {
    case S_LOG:
    case S_LOG10:
    case S_EXP:
    case S_SIN:
    case S_COS:
    case S_TAN:
    case S_SEC:
    case S_CSC:
    case S_COT:
    case S_SINH:
    case S_COSH:
    case S_TANH:
    case S_SECH:
    case S_CSCH:
    case S_COTH:
    case S_ARCSIN:
    case S_ARCCOS:
    case S_ARCTAN:
    case S_ARCSEC:
    case S_ARCCSC:
    case S_ARCCOT:
    case S_ARCSINH:
    case S_ARCCOSH:
    case S_ARCTANH:
    case S_ARCSECH:
    case S_ARCCSCH:
    case S_ARCCOTH:
    case S_FACTORIAL:
    case S_NOT:
        Unit = CValidatedUnit::merge(Unit, units[0]);
        break;

    case S_MAX:
    case S_MIN:
    case S_RUNIFORM:
    case S_RNORMAL:
        Unit = CValidatedUnit::merge(units[0], units[1]);
        break;

    case S_MINUS:
    case S_PLUS:
    case S_FLOOR:
    case S_CEIL:
    case S_ABS:
    case S_RPOISSON:
        Unit = units[0];

        break;

    case S_RGAMMA:
        // The unit of the gamma distribution is the inverse of the scale parameter (units[1])
        Unit = units[1].exponentiate(-1);

        // The shape parameter must be dimensionless
        if (!Unit.conflict())
        {
            Unit.setConflict(!(units[0] == CUnit(CBaseUnit::dimensionless)));
        }

        break;

    case S_SQRT:
    {
        // Exponentiate to 1/2.
        // Test if each component's exponent
        // is an integer. (don't want fractional exponents) by . . .
        // modf(exp, NULL) =< std::numeric_limits::epsilon
        Unit = units[0].exponentiate(1.0 / 2.0);

        std::set< CUnitComponent >::const_iterator  it = Unit.getComponents().begin();
        std::set< CUnitComponent >::const_iterator end = Unit.getComponents().end();

        for (; it != end; it++)
        {
            if (!(remainder((*it).getExponent(), 1.0) <= 100.0 * std::numeric_limits< C_FLOAT64 >::epsilon()))
            {
                Unit = CValidatedUnit(CBaseUnit::undefined, true);

                break;
            }
        }

        break;
    }

    default:
        Unit.setConflict(true);
        break;
    }

    return Unit;
}