|
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;
}