/* Example programs from the book Scientific and Engineering Programming in C++: An Introduction with Advanced Techniques and Examples, Addison-Wesley, 1994. (c) COPYRIGHT INTERNATIONAL BUSINESS MACHINES CORPORATION 1994. ALL RIGHTS RESERVED. See README file for further details. */ #include "Algebra/DivisionAlgebraCategory.h" #include "Function/Functional.h" #include "SciEng/Ptrs.h" template class ZeroIsoFunctional : public IsoFunctional { public: ZeroIsoFunctional(){ } virtual D operator()(D v) const { return 0.0; } }; template class OneIsoFunctional : public IsoFunctional { public: OneIsoFunctional(){ } virtual D operator()(D v) const { return 1.0; } }; template class XIsoFunctional : public IsoFunctional { public: XIsoFunctional(){} virtual D operator()(D v) const {return v;} }; template class ConstantIsoFunctional : public IsoFunctional { public: ConstantIsoFunctional(const D& r) : r_(r){ } virtual D operator()(D v) const { return r_; } private: D r_; }; template class BinaryIsoFunctional { public: BinaryIsoFunctional(const CopiedBasePtr >& lhs, const CopiedBasePtr >& rhs): the_lhs(lhs), the_rhs(rhs){ } const IsoFunctional& lhs() const { return *the_lhs;} const IsoFunctional& rhs() const { return *the_rhs;} private: CopiedBasePtr > the_lhs; CopiedBasePtr > the_rhs; }; template class AddIsoFunctional : public IsoFunctional, protected BinaryIsoFunctional { public: AddIsoFunctional(const CopiedBasePtr >& lhs, const CopiedBasePtr >& rhs): BinaryIsoFunctional(lhs,rhs){ } virtual D operator()(D v) const { D s = lhs()(v); s += rhs()(v); return s; } }; template class SubtractIsoFunctional : public IsoFunctional, protected BinaryIsoFunctional { public: SubtractIsoFunctional(const CopiedBasePtr >& lhs, const CopiedBasePtr >& rhs): BinaryIsoFunctional(lhs,rhs){ } virtual D operator()(D v) const { D s = lhs()(v); s -= rhs()(v); return s; } }; template class MultiplyIsoFunctional : public IsoFunctional, protected BinaryIsoFunctional { public: MultiplyIsoFunctional(const CopiedBasePtr >& lhs, const CopiedBasePtr >& rhs): BinaryIsoFunctional(lhs,rhs){ } MultiplyIsoFunctional(const CopiedBasePtr >& lhs, const D& rhs): BinaryIsoFunctional( lhs, InterfacedObjPtr< IsoFunctional, ConstantIsoFunctional >(new ConstantIsoFunctional(rhs)) ) { } virtual D operator()(D v) const { D s = lhs()(v); s *= rhs()(v); return s; } }; template class DivideIsoFunctional : public IsoFunctional, protected BinaryIsoFunctional { public: DivideIsoFunctional(const CopiedBasePtr >& lhs, const CopiedBasePtr >& rhs): BinaryIsoFunctional(lhs,rhs){ } DivideIsoFunctional(const CopiedBasePtr >& lhs, const D& rhs): BinaryIsoFunctional( lhs, InterfacedObjPtr< IsoFunctional, ConstantIsoFunctional >(new ConstantIsoFunctional(rhs)) ) { } virtual D operator()(D v) const { D s = lhs()(v); s /= rhs()(v); return s; } }; template class UnaryIsoFunctional { public: UnaryIsoFunctional(const CopiedBasePtr >& lhs): the_lhs(lhs){ } const IsoFunctional& lhs() const { return *the_lhs;} private: CopiedBasePtr > the_lhs; }; template class AdditiveInverseIsoFunctional : public IsoFunctional, protected UnaryIsoFunctional{ public: AdditiveInverseIsoFunctional(const CopiedBasePtr >& lhs): UnaryIsoFunctional(lhs){ } virtual D operator()(D v) const { return -lhs()(v); } }; template class MultiplicativeInverseIsoFunctional : public IsoFunctional, protected UnaryIsoFunctional { public: MultiplicativeInverseIsoFunctional(const CopiedBasePtr >& lhs): UnaryIsoFunctional(lhs){ } virtual D operator()(D v) const { return 1./lhs()(v); } }; template class IsoFunctionalAlgebra : public IsoFunctional, public DivisionAlgebraCategory,D> { public: virtual D operator()(D v) const { return (*f)(v);} IsoFunctionalAlgebra(const D& d) : f(InterfacedObjPtr,ConstantIsoFunctional >( new ConstantIsoFunctional(d) )) {} IsoFunctionalAlgebra(const CloneablePtr< IsoFunctional >& fp) : f(fp) {} IsoFunctionalAlgebra operator+=(IsoFunctionalAlgebra rhs); IsoFunctionalAlgebra operator-=(IsoFunctionalAlgebra rhs); IsoFunctionalAlgebra operator*=(IsoFunctionalAlgebra rhs); IsoFunctionalAlgebra operator/=(IsoFunctionalAlgebra rhs); IsoFunctionalAlgebra operator*=(const D&); IsoFunctionalAlgebra operator/=(const D&); IsoFunctionalAlgebra setToZero(); IsoFunctionalAlgebra setToOne(); IsoFunctionalAlgebra negate(); IsoFunctionalAlgebra invert(); static IsoFunctionalAlgebra x; private: const CopiedBasePtr >& operator()(){return f;} CopiedBasePtr > f; IsoFunctionalAlgebra() : f(InterfacedObjPtr,XIsoFunctional >( new XIsoFunctional() )) {} }; template IsoFunctionalAlgebra IsoFunctionalAlgebra::x = IsoFunctionalAlgebra(); template IsoFunctionalAlgebra IsoFunctionalAlgebra::operator+=(IsoFunctionalAlgebra rhs){ f = InterfacedObjPtr,AddIsoFunctional >(new AddIsoFunctional( (*this)(), rhs() )); return *this; } template IsoFunctionalAlgebra IsoFunctionalAlgebra::operator-=(IsoFunctionalAlgebra rhs){ f = InterfacedObjPtr,SubtractIsoFunctional >(new SubtractIsoFunctional( (*this)(), rhs() )); return *this; } template IsoFunctionalAlgebra IsoFunctionalAlgebra::operator*=(IsoFunctionalAlgebra rhs){ f = InterfacedObjPtr,MultiplyIsoFunctional >(new MultiplyIsoFunctional( (*this)(), rhs() )); return *this; } template IsoFunctionalAlgebra IsoFunctionalAlgebra::operator/=(IsoFunctionalAlgebra rhs){ f = InterfacedObjPtr,DivideIsoFunctional >(new DivideIsoFunctional( (*this)(), rhs() )); return *this; } template IsoFunctionalAlgebra IsoFunctionalAlgebra::setToZero(){ f = InterfacedObjPtr,ZeroIsoFunctional >(new ZeroIsoFunctional()); return *this; } template IsoFunctionalAlgebra IsoFunctionalAlgebra::setToOne(){ f = InterfacedObjPtr,OneIsoFunctional >(new OneIsoFunctional()); return *this; } template IsoFunctionalAlgebra IsoFunctionalAlgebra::negate(){ f = InterfacedObjPtr,AdditiveInverseIsoFunctional >(new AdditiveInverseIsoFunctional( (*this)() )); return *this; } template IsoFunctionalAlgebra IsoFunctionalAlgebra::invert(){ f = InterfacedObjPtr,MultiplicativeInverseIsoFunctional >(new MultiplicativeInverseIsoFunctional( (*this)() )); return *this; } template IsoFunctionalAlgebra IsoFunctionalAlgebra::operator*=(const D& rhs){ f = InterfacedObjPtr,MultiplyIsoFunctional >(new MultiplyIsoFunctional( (*this)(), rhs )); return *this; } template IsoFunctionalAlgebra IsoFunctionalAlgebra::operator/=(const D& rhs){ f = InterfacedObjPtr,DivideIsoFunctional >(new DivideIsoFunctional( (*this)(), rhs )); return *this; }