32.3.1 Implementation and Design

Class Diagram (an x means that class is currently supported):
x Matrix 
x   Matrix_sparse
x     Matrix_generic_sparse
x     Matrix_integer_sparse
x     Matrix_rational_sparse    
      Matrix_cyclo_sparse
x     Matrix_modn_sparse
      Matrix_RR_sparse    
      Matrix_CC_sparse    
      Matrix_RDF_sparse    
      Matrix_CDF_sparse

x  Matrix_dense
x     Matrix_generic_dense
x     Matrix_integer_dense
      Matrix_integer_2x2_dense
x     Matrix_rational_dense
      Matrix_cyclo_dense    -- idea: restrict scalars to QQ, compute charpoly there, then factor
x     Matrix_modn_dense
      Matrix_RR_dense
      Matrix_CC_dense
x     Matrix_real_double_dense
x     Matrix_complex_double_dense

The corresponding files in the sage/matrix library code directory are named

          [matrix] [base ring] [dense or sparse].

See the files matrix_template.pxd and matrix_template.pyx.

New matrices types can only be implemented in Cython.   

*********** LEVEL 1  **********
NON-OPTIONAL
For each base field it is *absolutely* essential to completely
implement the following functionality for that base ring:
    
   * __new__       -- should use sage_malloc from ext/stdsage.pxi (only
                      needed if allocate memory)
   * __init__      -- this signature: 'def __init__(self, parent, entries, copy, coerce)'
   * __dealloc__   -- use sage_free (only needed if allocate memory)
   * set_unsafe(self, size_t i, size_t j, x) -- doesn't do bounds or any other checks; assumes x is in self._base_ring
   * get_unsafe(self, size_t i, size_t j) -- doesn't do checks
   * __richcmp__    -- always the same (I don't know why its needed -- bug in PYREX).
*********** LEVEL 2  **********

IMPORTANT (and *highly* recommended):
    
After getting the special class with all level 1 functionality to
work, implement all of the following (they should not change
functionality, except speed (always faster!) in any way):
    
   * def _pickle(self):
          return data, version
   * def _unpickle(self, data, int version)
          reconstruct matrix from given data and version; may assume _parent, _nrows, and _ncols are set.
          Use version numbers >= 0 so if you change the pickle strategy then
          old objects still unpickle.
   * cdef _list -- list of underlying elements (need not be a copy)
   * cdef _dict -- sparse dictionary of underlying elements 
   * cdef _add_c_impl -- add two matrices with identical parents
   * _matrix_times_matrix_c_impl -- multiply two matrices with compatible dimensions and
                                    identical base rings (both sparse or both dense)
   * cdef _cmp_c_impl -- compare two matrices with identical parents
   * cdef _lmul_c_impl -- multiply this matrix on the right by a scalar, i.e., self * scalar
   * cdef _rmul_c_impl -- multiply this matrix on the left by a scalar, i.e., scalar * self
   * __copy__
   * __neg__

The list and dict returned by _list and _dict will *not* be changed
by any internal algorithms and are not accessible to the user. 

*********** LEVEL 3  **********
OPTIONAL:

   * cdef _sub_c_impl
   * __invert__
   * _multiply_classical
   * __deepcopy__

Further special support:
   * Matrix windows -- to support Strassen multiplication for a given base ring.
   * Other functions, e.g., transpose, for which knowing the
     specific representation can be helpful.

NOTES:
   * For caching, use self.fetch and self.cache.
   * Any method that can change the matrix should call check_mutability() first.
     There are also many fast cdef'd bounds checking methods.

See About this document... for information on suggesting changes.