--- /dev/null
+#include "smat.hh"
+
+template<class T>
+void
+Full_storage<T>::operator=(Full_storage const &fs)
+{
+ resize(fs.h, fs.w);
+ for (int i=0; i<h; i++)
+ for (int j=0; i<w; j++)
+ els[i][j]= fs.els[i][j];
+}
+
+template<class T>
+void
+Full_storage<T>::OK() const
+{
+ assert(maxh >= h && maxw >= w);
+ assert(h >= 0 && w >= 0);
+}
+template<class T>
+void
+Full_storage<T>::resize_cols(int newh)
+{
+ if (newh <= maxh) {
+ h=newh;
+ return;
+ }
+
+ T** newa=new T*[newh];
+ int j=0;
+ for (; j < h; j++)
+ newa[j] = els[j];
+ for (; j < newh; j++)
+ newa[j] = new T[w];
+ delete[] els;
+ els=newa;
+ maxh = newh;
+}
+
+template<class T>
+void
+Full_storage<T>::resize_rows(int neww)
+{
+ if (neww <= maxw) {
+ w=neww;
+ return;
+ }
+ for (int i=0; i < h ; i++) {
+ T* newa=new T[neww];
+ for (int k=0; k < w; k++)
+ newa[k] = els[i][k];
+
+ delete[] els[i];
+ els[i] = newa;
+ maxw = neww;
+ }
+}
+
+template<class T>
+Full_storage<T>::~Full_storage() {
+ for (int i=0; i < maxh; i++)
+ delete [] els[i];
+ delete[] els;
+}
+
+template<class T>
+void
+Full_storage<T>::resize(int i, int j)
+{
+ resize_cols(i);
+ resize_rows(j);
+}
+
+template<class T>
+void
+Full_storage<T>::set_size(int i, int j)
+{
+ resize(i,j)
+}
+
+template<class T>
+bool
+Full_storage<T>::mult_ok(int i, int j) const
+{
+ return valid(i,j);
+}
+
+template<class T>
+bool
+Full_storage<T>::trans_ok(int i, int j) const
+{
+ return valid(i,j);
+}
+
+
+template<class T>
+void
+Full_storage<T>::trans_next(int &i, int &j) const
+{
+ assert(trans_ok(i,j));
+ i++;
+ if (i >= h) {
+ i=0;
+ j ++;
+ }
+}
+
+template<class T>
+void
+Full_storage<T>::mult_next(int &i, int &j) const
+{
+ assert(mult_ok(i,j));
+ j++;
+ if (j >= w) {
+ j=0;
+ i++;
+ }
+}
+
+template<class T>
+void
+Full_storage<T>::delete_row(int k)
+{
+ assert(0 <= k <h);
+ for (int i=h-1; i > k ; i++)
+ for (int j=0; j < w; j++)
+ els[i-1][j]=els[i][j];
+}
+
+template<class T>
+void
+Full_storage<T>::insert_row(int k)
+{
+ assert(0 <= k <=h);
+ resize_cols(h+1);
+ for (int i=h-1; i > k ; i++)
+ for (int j=0; j <w; j++)
+ els[i][j]=els[i-1][j];
+}
+
+/****************************************************************/
+
+template<class T>
+virtual_smat<T> *
+virtual_smat<T>::get_full(int n, int m)
+{
+ return new Full_storage<T>(n,m);
+}
+#include "real.hh"
+
+template Full_storage<Real>;
--- /dev/null
+#ifndef SMAT_HH
+#define SMAT_HH
+#include "vray.hh"
+#include "vsmat.hh"
+
+/// simplest matrix storage. refer to its baseclass for the doco.
+template<class T>
+class Full_storage : public virtual_smat<T>
+{
+ /// height, width
+ int h,w;
+ /// maxima.
+ int maxh, maxw;
+
+ /// the storage
+ T** els;
+ void
+ init() {
+ els=0;
+ h=w=maxh=maxw=0;
+
+ }
+
+ bool valid(int i, int j) const {
+ return (i>=0 && i < h)
+ && (j < w && j >=0);
+ }
+
+
+ void resize_rows(int);
+ void resize_cols(int);
+
+public:
+ virtual int rows() const {
+ return h;
+ }
+ virtual int cols() const {
+ return w;
+ }
+
+
+ virtual void set_size(int i, int j)
+ {
+ resize(i,j); //this could be more efficient.
+ }
+
+ virtual void set_size(int i) {
+ set_size(i,i);
+ }
+ virtual void resize(int i, int j);
+ virtual void resize(int i) {
+ resize(i,i);
+ }
+
+ virtual T& elem(int i,int j) {
+ assert(valid(i,j));
+ return els[i][j];
+ }
+ virtual const T& elem(int i, int j) const {
+ assert(valid(i,j));
+ return els[i][j];
+ }
+ virtual svec<T> row(int i) const;
+ virtual svec<T> column(int j) const;
+
+ Full_storage() {
+ init();
+ }
+ Full_storage(int i, int j) {
+ init();
+ set_size(i,j);
+ }
+ Full_storage(int i) {
+ init();
+ set_size(i);
+ }
+ void OK() const;
+ void operator=(Full_storage const &);
+
+ virtual void insert_row(int k);
+ virtual void delete_row(int k);
+
+
+ ~Full_storage();
+ virtual bool mult_ok(int i, int j)const;
+ virtual void mult_next(int &i, int &j) const ;
+ virtual bool trans_ok(int i, int j) const;
+ virtual void trans_next(int &i, int &j) const;
+
+};
+
+#endif
--- /dev/null
+#ifndef VSMAT_HH
+#define VSMAT_HH
+#include "vray.hh"
+
+/// a matrix storage baseclass.
+class virtual_smat {
+
+
+public:
+ /// check invariants
+ virtual void OK() const=0;
+
+ /// height of matrix
+ virtual int rows() const = 0;
+
+ /// width of matrix
+ virtual int cols() const = 0;
+
+ /// set the size. contents lost
+ virtual void set_size(int i, int j) = 0;
+ /**
+ PRE
+ i >=0, j>=0
+ */
+
+ /// set the size to square dimen. contents lost
+ virtual void set_size(int i) = 0;
+ /**
+ PRE
+ i>=0
+ */
+ /// set the size to i
+ virtual void resize(int i, int j) = 0;
+ /**
+
+ keep contents. If enlarged contents unspecified
+
+ PRE
+ i>=0, j>=0
+
+ */
+
+ /// set the size to square dimen. contents kept
+ virtual void resize(int i) = 0;
+ /**
+ Keep contents. If enlarged contents are unspecified
+
+ PRE
+ i>=0
+ */
+
+ /// access an element
+ virtual Real& elem(int i,int j) = 0;
+ /**
+ access an element.
+
+ Generate an errormessage, if this happens
+ in the 0-part of a sparse matrix.
+ */
+
+ /// access a element, no modify
+ virtual const Real& elem(int i, int j) const = 0;
+
+#if 1
+ virtual svec<Real> row(int i) const = 0;
+ virtual svec<Real> column(int j) const = 0;
+#endif
+
+ /// add a row
+ virtual void insert_row(int k)=0;
+ /**
+ add a row to the matrix before row k. Contents
+ of added row are unspecified
+
+ 0 <= k <= rows()
+ */
+
+ /// delete a row
+ virtual void delete_row(int k)=0;
+ /**
+ delete a row from this matrix.
+
+ PRE
+ 0 <= k < rows();
+ */
+ virtual ~virtual_smat() { }
+ virtual virtual_smat *clone()=0;
+
+
+ /// is there a next?
+ virtual bool mult_ok(int i, int j) const=0;
+ /**
+ at end of matrix? when doing loop
+
+ for(i=0; i<h; i++)
+ for(j=0; j<w; j++)
+ ...
+
+ */
+ /// iterate
+ virtual void mult_next(int &i, int &j) const = 0;
+ /**
+ walk through matrix (regular multiply)
+ get next j for row i, or get next row i and reset j.
+ this will make sparse matrix implementation easy.
+
+ PRE
+ mult_ok(i,j)
+ */
+ virtual bool trans_ok(int i, int j) const=0;
+ /**
+ valid matrix entry. return false if at end of row
+ */
+ virtual void trans_next(int &i, int &j) const = 0;
+ /**
+ walk through matrix (transposed multiply).
+ Get next i (for column j)
+
+ PRE
+ ver_ok(i,j)
+ */
+
+ /// generate a "Full_storage" matrix
+ virtual_smat<Real> *get_full(int n, int m);
+
+};
+
+/** base class for interface with matrix storageclasses. There are no
+ iterators for matrixclasses, since matrices are (like arrays)
+ explicitly int-indexed.
+
+ Iteration is provided by *_next, *_ok, which update and check both
+ index variables simultaneously.
+
+ TODO
+ determine type of product matrix.
+
+*/
+
+#endif