Boost logo

Boost :

Subject: Re: [boost] different matrix library?
From: DE (satan66613_at_[hidden])
Date: 2009-08-17 15:26:29


on 17.08.2009 at 21:24
 joel wrote :
ok
i think i finally could explain my point

i want to try to start from the beginning to be sure we are talking
about the same thing
consider following code

  template<typename expr_type>
  class mat_expr //general matrix expression
  {
    expr_type &ref() { return *(expr_type*)this; } //rude but efficient
  };

  mat : public mat_expr<mat> //CRTP!
  {//matrix class //we use inheritance to state that 'mat'
    //specific interface //supports the 'matrix expression'
    //... //concept (and actually mat 'is-a'
    template<typename expr> //matrix expression)
    mat(const mat_expr<expr>&); //<-construct from expression
  };
                              
  template<typename expr1, typename expr2>
  mat_add_expr<...> operator+( //handle all
  /*general case*/ const mat_expr<expr1>&, //general
                              const mat_expr<expr2>& //matrix
                              ); //expressions
                              
mat_add_expr<...> is an expression that holds operands and performs
the operation
it inherits from mat_expr<mat_add_expr<...> > (CRTP)

cool
now we want to extend our type system to handle symmetric matrices
efficiently

  template<typename expr_type>
  class symm_mat_expr : public mat_expr<expr_type> {}; //well, that's all

  class symm_mat : public symm_mat_expr<symm_mat>
  {//symmetric matrix
    //with appropriate interface
    template<typename expr> //copy from symmetric
    symm_mat(const symm_mat_expr<expr>&); //matrix expression, not
  }; //from general one

  template<typename expr1, typename expr2>
  symm_mat_add_expr<...> operator+(
  /*defining special case*/ const symm_mat_expr<expr1>&,
                                   const symm_mat_expr<expr2>&
                                   );

symm_mat_add_expr<...> is a full analogy to mat_add_expr<...>
                                   
now we can write

  mat m1, m2, m3;
  symm_mat symm1, symm2, symm3;
  //...
  m1 = m2 + m3; //general case
  m1 = m2 + symm; //fall to general case
  symm1 = symm2 + symm3; //handled by special case
  symm1 = m1 + symm2; //hah! won't compile!
  
the latter case won't compile because a sum of general matrix and
symmetric matrix is not necessary symmetric
rather it's a general matrix
compiler helps to ensure this design by its overloading resolution
rules

i tried to show that this design is easily extendable (doing it in a
natural c++ form)
i hope this will make sense for you

-- 
Pavel
ps
i have a crazy thought:
  matrix<double>
  typename matrix<double>::sparse
  typename matrix<double>::symmetric::sparse
  typename matrix<double>::sparse::symmetric  //order doesn't matter
  //etc.
  
please don't consider it serious!

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk