]> git.donarmstrong.com Git - lilypond.git/commitdiff
lilypond-0.0.78
authorfred <fred>
Sun, 24 Mar 2002 19:49:51 +0000 (19:49 +0000)
committerfred <fred>
Sun, 24 Mar 2002 19:49:51 +0000 (19:49 +0000)
flower/include/matrix-storage.hh
flower/matrix.cc

index d7e9310acfbaedd7900caa8dc893e180bf7b45ec..a5971b268808ad12478f75ee1c3a7169503754d6 100644 (file)
@@ -39,19 +39,22 @@ public:
 
     /// width of matrix
     virtual int cols() const = 0;
+
+    /// size if square
+    virtual int dim() const =0;
       
     /**  set the size. contents lost.       
       PRE
       i >=0, j>=0
     */
-    virtual void set_size(int rows, int cols) = 0;
+    virtual void set_size(int rows, int cols) ;
+
  
     /**set the size to square dimen. contents lost
       PRE
       i>=0
     */
-    virtual void set_size(int i) = 0;
+    virtual void set_size(int i) ;
      /**set the size to i.
 
       keep contents. If enlarged contents unspecified
@@ -72,7 +75,7 @@ public:
     virtual void resize(int i) = 0;
   
     
-        /**
+    /**
     access an element.
 
     Generate an errormessage, if this happens
@@ -82,10 +85,10 @@ public:
     virtual Real& elem(int i,int j) = 0;
 
     /// access a element, no modify
-    virtual Real const & elem(int i, int j) const = 0;
+    virtual Real elem(int i, int j) const = 0;
 
-    virtual Array<Real> row(int i) const = 0;
-    virtual Array<Real> column(int j) const = 0;
+    virtual Array<Real> row(int i) const ;
+    virtual Array<Real> column(int j) const;
 
     
     /**
@@ -106,7 +109,7 @@ public:
     virtual void delete_row(int k)=0;
         virtual void delete_column(int k)=0;
     virtual ~Matrix_storage() { }
-    virtual Matrix_storage *clone()=0;
+    virtual Matrix_storage *clone()const=0;
 
 
     
@@ -130,7 +133,7 @@ public:
      */
     virtual void mult_next(int &i, int &j) const  = 0;
 
-/**
+    /**
       valid matrix entry. return false if at end of row
     */
     virtual bool trans_ok(int i, int j) const=0;
@@ -144,25 +147,28 @@ public:
      */
 
     virtual void trans_next(int &i, int &j) const  = 0;
+    
     /// generate a "Full_storage" matrix    
     static Matrix_storage *get_full(int n, int m);
-    
-
+    static void set_band(Matrix_storage*&, int band);
+    static void set_full(Matrix_storage*&);
     virtual bool try_right_multiply(Matrix_storage *dest, 
-                                   const Matrix_storage *fact) ;
+                                   const Matrix_storage *fact)const ;
     /**
       RTTI.
      */
-    NAME_MEMBERS();
-};
-
+    DECLARE_MY_RUNTIME_TYPEINFO;
 
+    
+    static Matrix_storage* get_product_result(Matrix_storage *left, 
+                                             Matrix_storage *right);
+    
+    
+    static void set_addition_result(
+       Matrix_storage *&dat, Matrix_storage *right);
+    static void set_product_result(
+       Matrix_storage*&dest, Matrix_storage*left, Matrix_storage*right);
+};
 
-inline bool
-Matrix_storage::try_right_multiply(Matrix_storage *, 
-                                   const Matrix_storage *)
-{
-    return false;
-}
 #endif // MATRIX_STORAGE_HH
 
index b096601c86dd1b14b698ded47afc97d5f3ef89ba..78e3d777b01237593e144a6c10851257c95f55b5 100644 (file)
@@ -1,4 +1,42 @@
+/*
+  matrix.cc -- implement Matrix
+
+  source file of the Flower Library
+
+  (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
 #include "matrix.hh"
+#include "full-storage.hh"
+#include "diagonal-storage.hh"
+
+bool
+Matrix::band_b()const
+{
+    return dat->is_type_b( Diagonal_storage::static_name());
+}
+
+void
+Matrix::set_full() const
+{
+    if ( dat->name() != Full_storage::static_name()) {
+       Matrix_storage::set_full( ((Matrix*)this)->dat );
+    }
+}
+
+void
+Matrix::try_set_band()const
+{
+    if (band_b())
+       return;
+    
+    int b = band_i();
+    if (  b > dim()/2)
+       return;
+    // it only looks constant
+    Matrix*self  = (Matrix*)this;
+    Matrix_storage::set_band(self->dat,b);
+}
 
 Real
 Matrix::norm() const
@@ -33,6 +71,7 @@ Matrix::set_diag(Vector d)
 void
 Matrix::operator+=(Matrix const &m)
 {
+    Matrix_storage::set_addition_result(dat, m.dat);
     assert(m.cols() == cols());
     assert(m.rows() == rows());
     for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j))
@@ -42,6 +81,7 @@ Matrix::operator+=(Matrix const &m)
 void
 Matrix::operator-=(Matrix const &m)
 {
+    Matrix_storage::set_addition_result(dat, m.dat);
     assert(m.cols() == cols());
     assert(m.rows() == rows());
     for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j))
@@ -64,6 +104,23 @@ Matrix::operator=(Matrix const &m)
     delete dat;
     dat = m.dat->clone();
 }
+
+int
+Matrix::band_i()const
+{
+    int starty = dim();
+    while (starty >= 0 ) {
+       for ( int i = starty, j = 0; i < dim(); i++, j++ )
+           if (dat->elem( i,j ))
+               goto gotcha;
+       for ( int i=0, j = starty; j < dim(); i++,j++)
+           if (dat->elem(i,j))
+               goto gotcha;
+       starty --;
+    }
+gotcha:
+    return  starty;
+}
     
 Matrix::Matrix(Matrix const &m)
 {
@@ -79,6 +136,11 @@ Matrix::Matrix(int n, int m)
     fill(0);
 }
 
+Matrix::Matrix(Matrix_storage*stor_p)
+{
+    dat = stor_p;
+}
+
 Matrix::Matrix(int n)
 {
     dat = Matrix_storage::get_full(n,n);
@@ -173,12 +235,11 @@ Matrix::transposed() const
     return m;
 }
 
-
-/* should do something smarter: bandmatrix * bandmatrix is also banded matrix.  */
 Matrix
 operator *(Matrix const &m1, Matrix const &m2)
 {
-    Matrix result(m1.rows(), m2.cols());
+    Matrix result(Matrix_storage::get_product_result(m1.dat, m2.dat));
+
     result.set_product(m1,m2);
     return result;
 }
@@ -188,7 +249,7 @@ Matrix::set_product(Matrix const &m1, Matrix const &m2)
 {
     assert(m1.cols()==m2.rows());
     assert(cols()==m2.cols() && rows()==m1.rows());
-
+    
     if (m1.dat->try_right_multiply(dat, m2.dat))
        return; 
     for (int i=0, j=0; dat->mult_ok(i,j);
@@ -243,3 +304,5 @@ Matrix::dim() const
     return rows();
 }
 
+
+