예제 #1
0
  //---------------------------------------------------------------------------
  IValue& IValue::operator=(const IValue &ref)
  {
    if (this==&ref)
      return *this;

    switch(ref.GetType())
    {
    case 'i': 
    case 'f': 
    case 'c': return *this = cmplx_type(ref.GetFloat(), ref.GetImag());
    case 's': return *this = ref.GetString();
    case 'm': return *this = ref.GetArray();
    case 'b': return *this = ref.GetBool();
    case 'v': 
      throw ParserError(_T("Assignment from void type is not possible"));

    default:  
      throw ParserError(_T("Internal error: unexpected data type identifier in IValue& operator=(const IValue &ref)"));
    }
  }
예제 #2
0
  //-----------------------------------------------------------
  void OprtSub::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int num)
  { 
    assert(num==2);

    if (a_pArg[0]->GetType()=='m' && a_pArg[1]->GetType()=='m')
    {
      const matrix_type &a1 = a_pArg[0]->GetArray(),
                       &a2 = a_pArg[1]->GetArray();
      if (a1.GetRows()!=a2.GetRows())
        throw ParserError(ErrorContext(ecARRAY_SIZE_MISMATCH, -1, GetIdent(), 'm', 'm', 2));
      
      matrix_type rv(a1.GetRows());
      for (int i=0; i<a1.GetRows(); ++i)
      {
        if (!a1.At(i).IsNonComplexScalar())
          throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a1.At(i).GetType(), 'f', 1)); 

        if (!a2.At(i).IsNonComplexScalar())
          throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a2.At(i).GetType(), 'f', 1)); 

        rv.At(i) = cmplx_type(a1.At(i).GetFloat() - a2.At(i).GetFloat(),
                              a1.At(i).GetImag()  - a2.At(i).GetImag());
      }

      *ret = rv;
    }
    else
    {
      if (!a_pArg[0]->IsNonComplexScalar())
        throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a_pArg[0]->GetType(), 'f', 1)); 

      if (!a_pArg[1]->IsNonComplexScalar())
        throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a_pArg[1]->GetType(), 'f', 2)); 
      
      *ret = a_pArg[0]->GetFloat() - a_pArg[1]->GetFloat(); 
    }
  }
예제 #3
0
  //-----------------------------------------------------------------------------------------------
  void OprtPowCmplx::Eval(ptr_val_type& ret, const ptr_val_type *arg, int argc)
  {
    assert(argc==2);

    // Problem: -2^3   will introduce small imaginary parts due to computational errors.
    //			-1^0.5 will introduce small real parts due to computational errors.
    //
    // Fix: If roots of negative values are calculated (exponents are non integer) or complex numbers 
    //      are involved the complex version of pow is used. The float version is used otherwise.
    if (arg[0]->IsComplex() || arg[1]->IsComplex() || (arg[0]->GetFloat()<0 && !arg[1]->IsInteger()) )
    {
      cmplx_type res = std::pow(arg[0]->GetComplex(), arg[1]->GetComplex());

      // remove obviousely bogus real/imaginary parts from the result
      if (std::abs(res.imag()) < std::numeric_limits<mup::float_type>::epsilon())
        res = res.real();
      else if (std::abs(res.real()) < std::numeric_limits<mup::float_type>::epsilon())
        res = cmplx_type(0, res.imag());

      *ret = res;
    }
    else
      *ret = std::pow(arg[0]->GetFloat(), arg[1]->GetFloat());
  }
 //-----------------------------------------------------------------------
 void FunCmplxConj::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int)
 {
   *ret = cmplx_type(a_pArg[0]->GetFloat(), -a_pArg[0]->GetImag());
 }