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; } }
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); }
/** \relates Expr */ inline Expr Im(const Expr& a) {return a.imag();}