/*
- matrix.hh -- declare Matrix
+ This file is part of LilyPond, the GNU music typesetter.
- source file of the Flower Library
+ Copyright (C) 2006--2015 Joe Neeman <joeneeman@gmail.com>
- (c) 1996,1997 Han-Wen Nienhuys <hanwen@stack.nl>
-*/
+ LilyPond is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ LilyPond is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ You should have received a copy of the GNU General Public License
+ along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
+*/
#ifndef MATRIX_HH
#define MATRIX_HH
-#include "matrix-storage.hh"
-#include "vector.hh"
-
-/** a Real matrix. This is a class for a nonsquare block of #Real#s. The
- implementation of sparse matrices is done in the appropriate #smat#
- class. Matrix only does the mathematical actions (adding,
- multiplying, etc.)
-
-
- TODO
- implement ref counting? */
+#include "std-vector.hh"
-
-class Matrix {
- friend Matrix operator *(Matrix const &m1, Matrix const &m2);
-
-protected:
- Matrix_storage *dat;
- void set (Matrix_storage*);
- Matrix (Matrix_storage*);
+template<class T, class A = std::allocator<T> >
+class Matrix
+{
public:
- void OK() const { dat->OK(); }
- int cols() const { return dat->cols (); }
- int rows() const { return dat->rows (); }
-
- /** return the size of a matrix.
- PRE
- the matrix needs to be square.
- */
- int dim() const;
-
- /**
- the band size of the matrix.
- @ret
-
- 0 <= band_i() <= dim
- */
- int band_i() const;
- bool band_b() const;
- void set_full() const;
- void try_set_band() const;
- ~Matrix() { delete dat; }
-
- /// set entries to r
- void fill (Real r);
-
- /// set diagonal to d
- void set_diag (Real d);
-
- void set_diag (Vector d);
- /// set unit matrix
- void unit() { set_diag (1.0); }
-
- void operator+=(Matrix const &m);
- void operator-=(Matrix const &m);
- void operator*=(Real a);
- void operator/=(Real a) { (*this) *= 1/a; }
-
- /** add a row.
- add a row to the matrix before row k
-
- PRE
- v.dim() == cols ()
- 0 <= k <= rows()
- */
- void insert_row (Vector v,int k);
- /** .
- delete a row from this matrix.
-
- PRE
- 0 <= k < rows();
- */
- void delete_row (int k) { dat->delete_row (k); }
- void delete_column (int k) { dat->delete_column (k); }
-
- /**
- square n matrix, initialised to null
- */
- Matrix (int n);
-
- /**
- n x m matrix, init to 0
- */
- Matrix (int n, int m);
- Matrix (Matrix const &m);
-
- /// dyadic product: v * w.transpose
- Matrix (Vector v, Vector w);
- void operator=(Matrix const &m);
-
- /// access an element
- Real operator()(int i,int j) const { return dat->elem (i,j); }
-
- /// access an element
- Real &operator()(int i, int j) { return dat->elem (i,j); }
-
- /// Matrix multiply with vec (from right)
- Vector operator *(Vector const &v) const;
-
- /// set this to m1*m2.
- void set_product (Matrix const &m1, Matrix const &m2);
-
-
- Vector left_multiply (Vector const &) const;
-
- Matrix operator-() const;
-
- /// transpose this.
- void transpose();
-
- /// return a transposed copy.
- Matrix transposed() const ;
-
- Real norm() const;
- /** swap.
- PRE
- 0 <= c1,c2 < cols()
- */
- void swap_columns (int c1, int c2);
-
- /** swap.
- PRE
- 0 <= c1,c2 < rows()
- */
- void swap_rows (int c1, int c2);
-
-
- Vector row (int) const;
- Vector col (int) const;
-
- operator String() const;
- void print() const;
+ Matrix<T, A> ()
+ {
+ rank_ = 0;
+ }
+
+ Matrix<T, A> (vsize rows, vsize columns, T const &t)
+ : data_ (rows *columns, t)
+ {
+ rank_ = rows;
+ }
+
+ const T &at (vsize row, vsize col) const
+ {
+ assert (row < rank_ && col * rank_ + row < data_.size ());
+
+ return data_[col * rank_ + row];
+ }
+
+ T &at (vsize row, vsize col)
+ {
+ assert (row < rank_ && col * rank_ + row < data_.size ());
+
+ return data_[col * rank_ + row];
+ }
+
+ void resize (vsize rows, vsize columns, T const &t)
+ {
+ if (rows == rank_)
+ data_.resize (rows * columns, t);
+ else
+ {
+ vector<T, A> new_data;
+ new_data.resize (rows * columns, t);
+ vsize cur_cols = rank_ ? data_.size () / rank_ : 0;
+
+ for (vsize i = 0; i < cur_cols; i++)
+ for (vsize j = 0; j < rank_; j++)
+ new_data[i * rows + j] = data_[i * rank_ + j];
+ rank_ = rows;
+ data_ = new_data;
+ }
+ }
+
+private:
+ vector<T, A> data_;
+ vsize rank_;
};
-inline Vector
-operator *(Vector &v, Matrix const & m) { return m.left_multiply (v); }
-Matrix operator *(Matrix const & m1,Matrix const &m2);
-Matrix operator /(Matrix const &m1,Real a);
-inline Matrix operator -(Matrix m1,const Matrix m2)
-{
- m1 -= m2;
- return m1;
-}
-inline Matrix operator +(Matrix m1,const Matrix m2)
-{
- m1 += m2;
- return m1;
-}
-#endif
+#endif /* MATRIX_HH */