Boost logo

Ublas :

From: Paul C. Leopardi (leopardi_at_[hidden])
Date: 2005-07-12 08:13:15


Andrew, Thanks. Reply below. Best, Paul Leopardi
On Tue, 12 Jul 2005 11:14 am, Andrew Rieck wrote:
> The following:
>
> #include <boost/enable_if.hpp>
>
> would provide a very clean solution for selecting specializations based on
> group/ring/field/etc properties.
> In this case the above library relies on the SFINAE principle.
>
> Kind regards,
> Andrew

Thanks for the references to enable_if and SFINAE. I will consider using
enable_if for GluCat ( http://glucat.sf.net ) whenever I come to its next
major revision. GluCat currently uses a variation of the Barton-Nackman
trick. See the end of this message for details.

I wrote GluCat at about the time of MTL2 and just as uBLAS was making its
first appearance. The design of GluCat was heavily influenced by
Alexandrescu's "Modern C++ Design" and by Meyers' "Effective C++". It looks
like time and templates have passed GluCat by and I will need to do some
reading so that GluCat and I can catch up with current usage.

Just now, I'm busy finishing up my PhD, so I don't really have much time for
GluCat. Over the next few months, though, I may read the following book and
articles in more depth:

David Vandevoorde and Nicolai M. Josuttis,
C++ Templates: The Complete Guide
http://www.vandevoorde.com/C++Templates/templates_scope.shtml

http://www.boost.org/libs/utility/enable_if.html

Jaakko Jarvi, Jeremiah Willcock, and Andrew Lumsdaine.
"Concept-controlled polymorphism". In Frank Pfennig and Yannis Smaragdakis,
editors, Generative Programming and Component Engineering,
volume 2830 of LNCS, pages 228–244. Springer Verlag, September 2003.
http://faculty.cs.tamu.edu/jarvi/papers/concept-controlled.pdf

Jaakko Jarvi, Jeremiah Willcock, and Andrew Lumsdaine,
"Algorithm specialization and concept-constrained genericity"
http://www.osl.iu.edu/publications/prints/2004/jarvi04:algorithm_specialization.pdf

Sunil Kothari, Martin Sulzmann,
"C++ templates/traits versus Haskell type classes", October 31, 2004
http://www.comp.nus.edu.sg/~sulzmann/c++vshaskell.pdf

Modified Barton-Nackman trick as used in GluCat.

// Definitions

template< typename Scalar_T, typename Index_Set_T, typename Multivector_T>
class clifford_algebra
{
  public:
    typedef Scalar_T scalar_t;
    typedef Index_Set_T index_set_t;
    typedef Multivector_T multivector_t;
//...
    virtual ~clifford_algebra() {};
//...
    /// Geometric sum
    virtual multivector_t& operator+= (const multivector_t& rhs) =0;
//...
}
//...
  /// Geometric sum
  template
  <
    template<typename, const index_t, const index_t> class Multivector,
    template<typename, const index_t, const index_t> class RHS,
    typename Scalar_T, const index_t LO, const index_t HI
>
  const Multivector<Scalar_T,LO,HI>
  operator+ (const Multivector<Scalar_T,LO,HI>& lhs,
             const RHS<Scalar_T,LO,HI>& rhs);
//...
template< typename Scalar_T,
  const index_t LO = DEFAULT_LO, const index_t HI = DEFAULT_HI >
  class matrix_multi :
  public clifford_algebra< Scalar_T, index_set<LO,HI>,
                           matrix_multi<Scalar_T,LO,HI> >
  {
  public:
    typedef matrix_multi multivector_t;
    typedef multivector_t matrix_multi_t;
    typedef Scalar_T scalar_t;
    typedef index_set<LO,HI> index_set_t;
//...
  _GLUCAT_PRIVATE:
    typedef ublas::row_major orientation_t;
    typedef ublas::compressed_matrix< Scalar_T, orientation_t >
                                                       matrix_t;
    typedef typename matrix_t::size_type matrix_index_t;
  public:
//...
    /// Destructor
    ~matrix_multi() {};
//...
    multivector_t& operator+= (const multivector_t& rhs);
//...
}

// Implementations

/// Geometric sum
template
  <
    template<typename, const index_t, const index_t> class Multivector,
    template<typename, const index_t, const index_t> class RHS,
    typename Scalar_T, const index_t LO, const index_t HI
>
inline
const Multivector<Scalar_T,LO,HI>
operator+ (const Multivector<Scalar_T,LO,HI>& lhs,
           const RHS<Scalar_T,LO,HI>& rhs)
  {
    Multivector<Scalar_T,LO,HI> result = lhs;
    return result += rhs;
  }
//...
  /// Geometric sum
template< typename Scalar_T, const index_t LO, const index_t HI >
  matrix_multi<Scalar_T,LO,HI>&
  matrix_multi<Scalar_T,LO,HI>::
  operator+= (const multivector_t& rhs)
  {
    //...
    return *this;
  }