示例#1
0
bool Expr::tryAddComplex(const Expr& L, const Expr& R, int sign,
  Expr& rtn) const
{
  TimeMonitor t(trySumComplexTimer());
  TEUCHOS_TEST_FOR_EXCEPTION(L.size() != 1 || R.size() != 1, std::logic_error, 
    "non-scalar exprs should have been reduced before "
    "call to tryAddComplex(). Left=" << L << " right="
    << R);
  if (L.isComplex() || R.isComplex())
  {
    if (sign > 0) 
    {
      rtn = new ComplexExpr(L.real() + R.real(), 
        L.imag() + R.imag());
    }
    else
    {
      rtn = new ComplexExpr(L.real() - R.real(), 
        L.imag() - R.imag());
    }
    return true;
  }
  else
  {
    return false;
  }
}
示例#2
0
Expr Expr::operator/(const Expr& other) const 
{
  TimeMonitor t(opTimer());

  /* if the right operand is a list, this operation
   * makes no sense */
  TEUCHOS_TEST_FOR_EXCEPTION(other.size() != 1,
    std::runtime_error, 
    "Expr::operator/ detected division by a non-scalar "
    "expression " << toString());

  TEUCHOS_TEST_FOR_EXCEPTION(other.isSpectral(), std::logic_error, 
    "Division by a Spectral Expr is not yet defined");

  /* If other is complex, transform to make the denominator real */
  if (other.isComplex())
  {
    Expr magSq = other.real()*other.real() + other.imag()*other.imag();
    return (*this) * other.conj() / magSq;
  }

  /* If I'm complex and the other is not, distribute division over re and im */
  if (isComplex() && !other.isComplex())
  {
    return new ComplexExpr(real()/other, imag()/other);
  }

  /* If I'm spectral and the other is not, distribute division over coefficients */
  if (isSpectral() && !other.isSpectral()  && !other.isComplex())
  {
    const SpectralExpr* se 
      = dynamic_cast<const SpectralExpr*>((*this)[0].ptr().get());

    SpectralBasis basis = se->getSpectralBasis();
    Array<Expr> coeff(basis.nterms());
	  
    for(int i=0; i<basis.nterms(); i++)
    {
      coeff[i] = se->getCoeff(i)/ other[0];
    }
    Expr rtn = new SpectralExpr( basis, coeff);
    return rtn;
  }

  /* if we are a scalar, do simple scalar division */
  if (this->size()==1)
  {
    return (*this)[0].divide(other[0]);
  }

  /* otherwise, divide each element of the left by the right operand */
  Array<Expr> rtn(this->size());
  for (int i=0; i<this->size(); i++)
  {
    rtn[i] = (*this)[i] / other;
  }
  return new ListExpr(rtn);
}
示例#3
0
/** \relates Expr */
inline Expr Im(const Expr& a) {return a.imag();}