diff --git a/MathLib/LinAlg/Solvers/BiCGStab.cpp b/MathLib/LinAlg/Solvers/BiCGStab.cpp
index a63da21968505448aa71a3cecc8389e37f8d6f0e..7f6a4ef3deb685f84ecb47141ad857585016b1de 100644
--- a/MathLib/LinAlg/Solvers/BiCGStab.cpp
+++ b/MathLib/LinAlg/Solvers/BiCGStab.cpp
@@ -12,7 +12,7 @@
 
 namespace MathLib {
 
-unsigned BiCGStab(CRSMatrix<double> const& A, double* const b, double* const x,
+unsigned BiCGStab(CRSMatrix<double, unsigned> const& A, double* const b, double* const x,
 		double& eps, unsigned& nsteps)
 {
 	const unsigned N(A.getNRows());
diff --git a/MathLib/LinAlg/Solvers/BiCGStab.h b/MathLib/LinAlg/Solvers/BiCGStab.h
index 1f7821b7f29494955e229bfa7d0d9923013ce725..cdf699d336a27bffcf621a140e109ae03880cce2 100644
--- a/MathLib/LinAlg/Solvers/BiCGStab.h
+++ b/MathLib/LinAlg/Solvers/BiCGStab.h
@@ -14,7 +14,7 @@
 
 namespace MathLib {
 
-unsigned BiCGStab(CRSMatrix<double> const& A, double* const b, double* const x,
+unsigned BiCGStab(CRSMatrix<double, unsigned> const& A, double* const b, double* const x,
                   double& eps, unsigned& nsteps);
 
 } // end namespace MathLib
diff --git a/MathLib/LinAlg/Solvers/CG.cpp b/MathLib/LinAlg/Solvers/CG.cpp
index 05c2f1d977f0943cf644b04b4473a172c4e55c39..0c37460a6603aaddb6cfe46c608ebb4b3d8958d3 100644
--- a/MathLib/LinAlg/Solvers/CG.cpp
+++ b/MathLib/LinAlg/Solvers/CG.cpp
@@ -27,7 +27,7 @@
 
 namespace MathLib {
 
-unsigned CG(CRSMatrix<double> const * mat, double const * const b,
+unsigned CG(CRSMatrix<double,unsigned> const * mat, double const * const b,
 		double* const x, double& eps, unsigned& nsteps, unsigned num_threads)
 {
 	unsigned N = mat->getNRows();
diff --git a/MathLib/LinAlg/Solvers/CG.h b/MathLib/LinAlg/Solvers/CG.h
index 36cd6917402f478be69b95e0bc1f90878894dc9e..4b07debdf6a01ac5293e0e8ceb9d8810245bde76 100644
--- a/MathLib/LinAlg/Solvers/CG.h
+++ b/MathLib/LinAlg/Solvers/CG.h
@@ -11,9 +11,9 @@
 namespace MathLib {
 
 // forward declaration
-template <typename T> class CRSMatrix;
+template <typename PF_TYPE, typename IDX_TYPE> class CRSMatrix;
 
-unsigned CG(CRSMatrix<double> const * mat, double const * const b,
+unsigned CG(CRSMatrix<double,unsigned> const * mat, double const * const b,
 		double* const x, double& eps, unsigned& nsteps, unsigned num_threads = 1);
 
 } // end namespace MathLib
diff --git a/MathLib/LinAlg/Solvers/GMRes.cpp b/MathLib/LinAlg/Solvers/GMRes.cpp
index 45aeaf5a7348c4f412dab9a24e22993fc520065d..871431f40d8023210ac1eca11b6138d12ff3a3d8 100644
--- a/MathLib/LinAlg/Solvers/GMRes.cpp
+++ b/MathLib/LinAlg/Solvers/GMRes.cpp
@@ -37,7 +37,7 @@ inline void applPlRot(double& dx, double& dy, double cs, double sn)
 }
 
 // solve H y = s and update x += MVy
-static void update(const CRSMatrix<double>& A, unsigned k, double* H,
+static void update(const CRSMatrix<double,unsigned>& A, unsigned k, double* H,
 		unsigned ldH, double* s, double* V, double* x)
 {
 	const size_t n(A.getNRows());
@@ -59,7 +59,7 @@ static void update(const CRSMatrix<double>& A, unsigned k, double* H,
 	delete[] y;
 }
 
-unsigned GMRes(const CRSMatrix<double>& A, double* const b, double* const x,
+unsigned GMRes(const CRSMatrix<double,unsigned>& A, double* const b, double* const x,
 		double& eps, unsigned m, unsigned& nsteps)
 {
 	double resid;
diff --git a/MathLib/LinAlg/Solvers/GMRes.h b/MathLib/LinAlg/Solvers/GMRes.h
index f7acd6e3e010d1c9a919f359ae732c379183c38a..732c560b425b78483a16c2179fc91540d1658831 100644
--- a/MathLib/LinAlg/Solvers/GMRes.h
+++ b/MathLib/LinAlg/Solvers/GMRes.h
@@ -12,7 +12,7 @@
 
 namespace MathLib {
 
-unsigned GMRes(const CRSMatrix<double>& mat, double* const b, double* const x,
+unsigned GMRes(const CRSMatrix<double,unsigned>& mat, double* const b, double* const x,
                         double& eps, unsigned m, unsigned& steps);
 
 } // end namespace MathLib
diff --git a/MathLib/LinAlg/Sparse/CRSMatrix.h b/MathLib/LinAlg/Sparse/CRSMatrix.h
index a2c889cf3926acd1967fbdc0fadd95e299438283..f2995a353fc7907b834c0c3bc067bbed5d5595ed 100644
--- a/MathLib/LinAlg/Sparse/CRSMatrix.h
+++ b/MathLib/LinAlg/Sparse/CRSMatrix.h
@@ -11,6 +11,12 @@
 #include <string>
 #include <fstream>
 #include <iostream>
+#include <cassert>
+
+// Base
+#include "swap.h"
+
+// MathLib
 #include "SparseMatrixBase.h"
 #include "sparse.h"
 #include "amuxCRS.h"
@@ -18,29 +24,30 @@
 
 namespace MathLib {
 
-template<class T> class CRSMatrix : public SparseMatrixBase<T>
+template<typename FP_TYPE, typename IDX_TYPE>
+class CRSMatrix: public SparseMatrixBase<FP_TYPE, IDX_TYPE>
 {
 public:
 	CRSMatrix(std::string const &fname) :
-		SparseMatrixBase<T>(),
+		SparseMatrixBase<FP_TYPE, IDX_TYPE>(),
 		_row_ptr(NULL), _col_idx(NULL), _data(NULL)
 	{
 		std::ifstream in(fname.c_str(), std::ios::in | std::ios::binary);
 		if (in) {
-			CS_read(in, SparseMatrixBase<T>::_n_rows, _row_ptr, _col_idx, _data);
-			SparseMatrixBase<T>::_n_cols = SparseMatrixBase<T>::_n_rows;
+			CS_read(in, SparseMatrixBase<FP_TYPE, IDX_TYPE>::_n_rows, _row_ptr, _col_idx, _data);
+			SparseMatrixBase<FP_TYPE, IDX_TYPE>::_n_cols = SparseMatrixBase<FP_TYPE, IDX_TYPE>::_n_rows;
 			in.close();
 		} else {
 			std::cout << "cannot open " << fname << std::endl;
 		}
 	}
 
-	CRSMatrix(unsigned n, unsigned *iA, unsigned *jA, T* A) :
-		SparseMatrixBase<T>(n,n), _row_ptr(iA), _col_idx(jA), _data(A)
+	CRSMatrix(IDX_TYPE n, IDX_TYPE *iA, IDX_TYPE *jA, FP_TYPE* A) :
+		SparseMatrixBase<FP_TYPE, IDX_TYPE>(n,n), _row_ptr(iA), _col_idx(jA), _data(A)
 	{}
 
-	CRSMatrix(unsigned n1) :
-		SparseMatrixBase<T>(n1, n1), _row_ptr(NULL), _col_idx(NULL), _data(NULL)
+	CRSMatrix(IDX_TYPE n1) :
+		SparseMatrixBase<FP_TYPE, IDX_TYPE>(n1, n1), _row_ptr(NULL), _col_idx(NULL), _data(NULL)
 	{}
 
 	virtual ~CRSMatrix()
@@ -50,18 +57,292 @@ public:
 		delete [] _data;
 	}
 
-	virtual void amux(T d, T const * const x, T *y) const
+	virtual void amux(FP_TYPE d, FP_TYPE const * const x, FP_TYPE *y) const
 	{
 		amuxCRS(d, MatrixBase::_n_rows, _row_ptr, _col_idx, _data, x, y);
 	}
 
-    virtual void precondApply(T* x) const
+    virtual void precondApply(FP_TYPE* x) const
     {}
 
+    /**
+     * get the number of non-zero entries
+     * @return number of non-zero entries
+     */
+    IDX_TYPE getNNZ() const { return _row_ptr[MatrixBase::_n_rows]; }
+
+    /**
+     * This is the constant access operator to a non-zero matrix entry.
+     * Precondition: the entries have to be in the sparsity pattern!
+     * @param row the row number
+     * @param col the column number
+     * @return The corresponding matrix entry.
+     */
+    FP_TYPE operator() (IDX_TYPE row, IDX_TYPE col) const
+    {
+    	assert(0 <= row && row < MatrixBase::_n_rows);
+
+    	// linear search - for matrices with many entries per row binary search is much faster
+    	const IDX_TYPE idx_end (_row_ptr[row+1]);
+    	IDX_TYPE j(_row_ptr[row]), k;
+
+    	while (j<idx_end && (k=_col_idx[j]) <= col) {
+    		if (k == col) {
+    			return _data[j];
+    		}
+    		j++;
+    	}
+    	return 0.0;
+    }
+
+    /**
+	 * This is the non constant access operator to a non-zero matrix entry.
+	 * Precondition: the entries have to be in the sparsity pattern!
+	 * @param row the row number
+	 * @param col the column number
+	 * @return The corresponding matrix entry that can be modified by the user.
+	 */
+	FP_TYPE & operator() (IDX_TYPE row, IDX_TYPE col)
+	{
+		assert(0 <= row && row < MatrixBase::_n_rows);
+
+		// linear search - for matrices with many entries per row binary search is much faster
+		const IDX_TYPE idx_end (_row_ptr[row+1]);
+		IDX_TYPE j(_row_ptr[row]), k;
+
+		while (j<idx_end && (k=_col_idx[j]) <= col) {
+			if (k == col) {
+				return _data[j];
+			}
+			j++;
+		}
+	}
+
+	/**
+	 * get const access to the row pointer array of CRS matrix
+	 * @return the index array _row_ptr
+	 */
+	IDX_TYPE const* getRowPtrArray() const { return _row_ptr; }
+
+	/**
+	 * get const access to the column index array of CRS matrix
+	 * @return the index array _col_idx
+	 */
+	IDX_TYPE const* getColIdxArray ()const { return _col_idx; }
+
+	/**
+	 * get the matrix entries within an array of CRS matrix
+	 * @return
+	 */
+	FP_TYPE const* getEntryArray() const { return _data; }
+
+	/**
+	 * erase rows and columns from sparse matrix
+	 * @param n_rows_cols number of rows / columns to remove
+	 * @param rows sorted list of rows that should be removed
+	 * @param cols sorted list of columns that should be removed
+	 */
+	void eraseEntries (IDX_TYPE n_rows_cols,
+					IDX_TYPE const*const rows, IDX_TYPE const*const cols)
+	{
+//		std::cout << "original: " << std::endl;
+//		printMat();
+		IDX_TYPE n_cols(MatrixBase::_n_rows);
+		//*** remove the rows
+		removeRows(n_rows_cols, rows);
+//		std::cout << "removed rows: " << std::endl;
+//		printMat();
+		//*** transpose
+		transpose(n_cols);
+//		std::cout << "transposed: " << std::endl;
+//		printMat();
+		//*** remove columns in original means removing rows in the transposed
+		removeRows(n_rows_cols, cols);
+//		std::cout << "removed rows: " << std::endl;
+//		printMat();
+		//*** transpose again
+		transpose(MatrixBase::_n_rows);
+//		std::cout << "transposed: " << std::endl;
+//		printMat();
+//		//*** apply changes to the column indices
+//		correctColumnIndices(n_rows_cols, cols);
+	}
+
+	/**
+	 * get the j-th column of the sparse matrix
+	 * @param j the column number that should be returned
+	 * @param column_entries the column entries (have to be allocated
+	 */
+	void getColumn(IDX_TYPE j, FP_TYPE* column_entries) const
+	{
+		for (IDX_TYPE k(0); k<MatrixBase::_n_rows; k++) {
+			const IDX_TYPE end_row(_row_ptr[k+1]);
+			IDX_TYPE i(_row_ptr[k+1]);
+			while (i<end_row && _col_idx[i] != j) {
+				i++;
+			}
+			if (i==end_row) {
+				column_entries[k] = 0.0;
+			} else {
+				column_entries[k] = _data[i];
+			}
+		}
+	}
+
 protected:
-	unsigned *_row_ptr;
-	unsigned *_col_idx;
-	T* _data;
+	void removeRows (IDX_TYPE n_rows_cols, IDX_TYPE const*const rows)
+	{
+		//*** determine the number of new rows and the number of entries without the rows
+		const IDX_TYPE n_new_rows(MatrixBase::_n_rows - n_rows_cols);
+		IDX_TYPE *row_ptr_new(new IDX_TYPE[n_new_rows+1]);
+		row_ptr_new[0] = 0;
+		IDX_TYPE row_cnt (1), erase_row_cnt(0);
+		for (unsigned k(0); k<MatrixBase::_n_rows; k++) {
+			if (k != rows[erase_row_cnt]) {
+				row_ptr_new[row_cnt] = _row_ptr[k+1] - _row_ptr[k];
+				row_cnt++;
+			} else {
+				erase_row_cnt++;
+			}
+		}
+
+		//*** sum up the entries
+		for (IDX_TYPE k(0); k<n_new_rows; k++) {
+			row_ptr_new[k+1] = row_ptr_new[k+1] + row_ptr_new[k];
+		}
+
+		//*** create new memory for col_idx and data
+		IDX_TYPE nnz_new(row_ptr_new[n_new_rows]);
+		IDX_TYPE *col_idx_new (new IDX_TYPE[nnz_new]);
+		FP_TYPE *data_new (new FP_TYPE[nnz_new]);
+
+		//*** copy the entries
+		// initialization
+		IDX_TYPE *row_ptr_new_tmp(new IDX_TYPE[n_new_rows+1]);
+		for (unsigned k(0); k<=n_new_rows; k++) {
+			row_ptr_new_tmp[k] = row_ptr_new[k];
+		}
+		erase_row_cnt = 0;
+		row_cnt = 0;
+		// copy column index and data entries
+		for (IDX_TYPE k(0); k<MatrixBase::_n_rows; k++) {
+			if (k != rows[erase_row_cnt]) {
+				const IDX_TYPE end (_row_ptr[k+1]);
+				// walk through row
+				for (IDX_TYPE j(_row_ptr[k]); j<end; j++) {
+					col_idx_new[row_ptr_new_tmp[row_cnt]] = _col_idx[j];
+					data_new[row_ptr_new_tmp[row_cnt]] = _data[j];
+					row_ptr_new_tmp[row_cnt]++;
+				}
+				row_cnt++;
+			} else {
+				erase_row_cnt++;
+			}
+		}
+
+		MatrixBase::_n_rows -= n_rows_cols;
+		BASELIB::swap (row_ptr_new, _row_ptr);
+		BASELIB::swap (col_idx_new, _col_idx);
+		BASELIB::swap (data_new, _data);
+
+		delete [] row_ptr_new;
+		delete [] col_idx_new;
+		delete [] data_new;
+	}
+
+	void transpose (IDX_TYPE n_cols)
+	{
+		// create a helper array row_ptr_nnz
+		IDX_TYPE *row_ptr_nnz(new IDX_TYPE[n_cols+1]);
+		for (IDX_TYPE k(0); k <= n_cols; k++) {
+			row_ptr_nnz[k] = 0;
+		}
+
+		// count entries per row in the transposed matrix
+		IDX_TYPE nnz(_row_ptr[MatrixBase::_n_rows]);
+		for (IDX_TYPE k(0); k < nnz; k++) {
+			row_ptr_nnz[_col_idx[k]]++;
+		}
+
+		// create row_ptr_trans
+		IDX_TYPE *row_ptr_trans(new IDX_TYPE[n_cols + 1]);
+		row_ptr_trans[0] = 0;
+		for (IDX_TYPE k(0); k < n_cols; k++) {
+			row_ptr_trans[k+1] = row_ptr_trans[k] + row_ptr_nnz[k];
+		}
+
+		// make a copy of row_ptr_trans
+		for (IDX_TYPE k(0); k <= n_cols; k++) {
+			row_ptr_nnz[k] = row_ptr_trans[k];
+		}
+
+		// create arrays col_idx_trans and data_trans
+		assert(nnz == row_ptr_trans[n_cols]);
+		IDX_TYPE *col_idx_trans(new IDX_TYPE[nnz]);
+		FP_TYPE *data_trans(new FP_TYPE[nnz]);
+
+		// fill arrays col_idx_trans and data_trans
+		for (IDX_TYPE i(0); i < MatrixBase::_n_rows; i++) {
+			const IDX_TYPE row_end(_row_ptr[i + 1]);
+			for (IDX_TYPE j(_row_ptr[i]); j < row_end; j++) {
+				const IDX_TYPE k(_col_idx[j]);
+				col_idx_trans[row_ptr_nnz[k]] = i;
+				data_trans[row_ptr_nnz[k]] = _data[j];
+				row_ptr_nnz[k]++;
+			}
+		}
+
+		MatrixBase::_n_rows = n_cols;
+		BASELIB::swap(row_ptr_trans, _row_ptr);
+		BASELIB::swap(col_idx_trans, _col_idx);
+		BASELIB::swap(data_trans, _data);
+
+		delete[] row_ptr_nnz;
+		delete[] row_ptr_trans;
+		delete[] col_idx_trans;
+		delete[] data_trans;
+	}
+
+	void correctColumnIndices(IDX_TYPE n_rows_cols, IDX_TYPE const*const cols)
+	{
+		// create the mapping
+		const IDX_TYPE size(MatrixBase::_n_rows + n_rows_cols);
+		IDX_TYPE *mapping(new IDX_TYPE[size]);
+		IDX_TYPE k(0);
+		for (IDX_TYPE i(0); i < n_rows_cols; i++) {
+			while (k < cols[i]) {
+				mapping[k] = k - i;
+				k++;
+			}
+		}
+		for (IDX_TYPE k(cols[n_rows_cols - 1]); k < size; k++) {
+			mapping[k] = k - n_rows_cols;
+		}
+
+		// apply mapping to _col_idx
+		const IDX_TYPE nnz(_row_ptr[MatrixBase::_n_rows]);
+		for (IDX_TYPE k(0); k < nnz; k++) {
+			_col_idx[k] = mapping[_col_idx[k]];
+		}
+
+		delete[] mapping;
+	}
+
+	void printMat() const
+	{
+		for (IDX_TYPE k(0); k<MatrixBase::_n_rows; k++) {
+			std::cout << k << ": " << std::flush;
+			const IDX_TYPE row_end(_row_ptr[k+1]);
+			for (IDX_TYPE j(_row_ptr[k]); j<row_end; j++) {
+				std::cout << _col_idx[j] << " " << std::flush;
+			}
+			std::cout << std::endl;
+		}
+	}
+
+	IDX_TYPE *_row_ptr;
+	IDX_TYPE *_col_idx;
+	FP_TYPE* _data;
 };
 
 } // end namespace MathLib
diff --git a/MathLib/LinAlg/Sparse/CRSMatrixDiagPrecond.h b/MathLib/LinAlg/Sparse/CRSMatrixDiagPrecond.h
index 7bee253808a0dff9e7112d3d094d8d77a8f04f19..49fad7602837f2e4947c49b3ee8db9a4806cb734 100644
--- a/MathLib/LinAlg/Sparse/CRSMatrixDiagPrecond.h
+++ b/MathLib/LinAlg/Sparse/CRSMatrixDiagPrecond.h
@@ -9,11 +9,11 @@
 
 namespace MathLib {
 
-class CRSMatrixDiagPrecond : public CRSMatrix<double>
+class CRSMatrixDiagPrecond : public CRSMatrix<double, unsigned>
 {
 public:
 	CRSMatrixDiagPrecond (std::string const &fname)
-		: CRSMatrix<double>(fname), _inv_diag(new double[_n_rows])
+		: CRSMatrix<double, unsigned>(fname), _inv_diag(new double[_n_rows])
 	{
 		if (!generateDiagPrecond (_n_rows, _row_ptr, _col_idx, _data, _inv_diag)) {
 			std::cout << "Could not create diagonal preconditioner" << std::endl;
diff --git a/MathLib/LinAlg/Sparse/CRSMatrixOpenMP.h b/MathLib/LinAlg/Sparse/CRSMatrixOpenMP.h
index 408304ae8b69f0eb1b44b397567c0ea770854c05..b2467bb86e2c28729e66c8f2e2e48898357ead40 100644
--- a/MathLib/LinAlg/Sparse/CRSMatrixOpenMP.h
+++ b/MathLib/LinAlg/Sparse/CRSMatrixOpenMP.h
@@ -15,18 +15,18 @@
 
 namespace MathLib {
 
-template<class T> class CRSMatrixOpenMP : public CRSMatrix<T> {
+template<class T> class CRSMatrixOpenMP : public CRSMatrix<T, unsigned> {
 public:
 	CRSMatrixOpenMP(std::string const &fname, unsigned num_of_threads) :
-			CRSMatrix<T>(fname), _num_of_threads (num_of_threads)
+			CRSMatrix<T, unsigned>(fname), _num_of_threads (num_of_threads)
 	{}
 
 	CRSMatrixOpenMP(unsigned n, unsigned *iA, unsigned *jA, T* A, unsigned num_of_threads) :
-		CRSMatrix<T>(n, iA, jA, A), _num_of_threads (num_of_threads)
+		CRSMatrix<T, unsigned>(n, iA, jA, A), _num_of_threads (num_of_threads)
 	{}
 
 	CRSMatrixOpenMP(unsigned n1) :
-		CRSMatrix<T>(n1), _num_of_threads (1)
+		CRSMatrix<T, unsigned>(n1), _num_of_threads (1)
 	{}
 
 	virtual ~CRSMatrixOpenMP()
@@ -34,7 +34,7 @@ public:
 
 	virtual void amux(T d, T const * const x, T *y) const
 	{
-		amuxCRSParallelOpenMP(d, MatrixBase::_n_rows, CRSMatrix<T>::_row_ptr, CRSMatrix<T>::_col_idx, CRSMatrix<T>::_data, x, y, _num_of_threads);
+		amuxCRSParallelOpenMP(d, MatrixBase::_n_rows, CRSMatrix<T,unsigned>::_row_ptr, CRSMatrix<T,unsigned>::_col_idx, CRSMatrix<T,unsigned>::_data, x, y, _num_of_threads);
 	}
 
 private:
diff --git a/MathLib/LinAlg/Sparse/CRSMatrixPThreads.h b/MathLib/LinAlg/Sparse/CRSMatrixPThreads.h
index eeabaac76173e1d5c676c626a8cb1e7694c19816..32ca857f505bd713bb3c771623da92dedc8e196c 100644
--- a/MathLib/LinAlg/Sparse/CRSMatrixPThreads.h
+++ b/MathLib/LinAlg/Sparse/CRSMatrixPThreads.h
@@ -17,19 +17,19 @@
 
 namespace MathLib {
 
-template<class T> class CRSMatrixPThreads : public CRSMatrix<T>
+template<class T> class CRSMatrixPThreads : public CRSMatrix<T,unsigned>
 {
 public:
 	CRSMatrixPThreads(std::string const &fname, unsigned num_of_threads) :
-		CRSMatrix<T>(fname), _num_of_threads (num_of_threads)
+		CRSMatrix<T,unsigned>(fname), _num_of_threads (num_of_threads)
 	{}
 
 	CRSMatrixPThreads(unsigned n, unsigned *iA, unsigned *jA, T* A, unsigned num_of_threads) :
-		CRSMatrix<T>(n, iA, jA, A), _num_of_threads (num_of_threads)
+		CRSMatrix<T,unsigned>(n, iA, jA, A), _num_of_threads (num_of_threads)
 	{}
 
 	CRSMatrixPThreads(unsigned n1) :
-		CRSMatrix<T>(n1), _num_of_threads (1)
+		CRSMatrix<T,unsigned>(n1), _num_of_threads (1)
 	{}
 
 	virtual ~CRSMatrixPThreads()
@@ -37,7 +37,9 @@ public:
 
 	virtual void amux(T d, T const * const x, T *y) const
 	{
-		amuxCRSParallelPThreads(d, SparseMatrixBase<T>::_n_rows, CRSMatrix<T>::_row_ptr, CRSMatrix<T>::_col_idx, CRSMatrix<T>::_data, x, y, _num_of_threads);
+		amuxCRSParallelPThreads(d, SparseMatrixBase<T, unsigned>::_n_rows,
+						CRSMatrix<T, unsigned>::_row_ptr, CRSMatrix<T, unsigned>::_col_idx,
+						CRSMatrix<T, unsigned>::_data, x, y, _num_of_threads);
 	}
 
 protected:
diff --git a/MathLib/LinAlg/Sparse/CRSTranspose.h b/MathLib/LinAlg/Sparse/CRSTranspose.h
index 6b3eba986045d4327dd39bb15fc5dabd5f81e6ea..010a49e5a31126c57d14232f3185573857892aff 100644
--- a/MathLib/LinAlg/Sparse/CRSTranspose.h
+++ b/MathLib/LinAlg/Sparse/CRSTranspose.h
@@ -2,17 +2,17 @@
  * CRSTranspose.h
  *
  *  Created on: Sep 27, 2011
- *      Author: fischeth
+ *      Author: TF
  */
 
 #ifndef CRSTRANSPOSE_H_
 #define CRSTRANSPOSE_H_
 
-void CS_transp(unsigned n, double* A, unsigned* jA, unsigned *iA,
-               double* B, unsigned *jB, unsigned *iB)
+void CS_transp(unsigned n, unsigned *iA, unsigned* jA, double* A,
+				unsigned *iB, unsigned *jB, double* B)
 {
   unsigned nnz = iA[n];
-  unsigned *inz = new unsigned[n];
+  unsigned *inz(new unsigned[n]);
 
   for (unsigned i=0; i<n; ++i) inz[i] = 0;
 
diff --git a/MathLib/LinAlg/Sparse/SparseMatrixBase.h b/MathLib/LinAlg/Sparse/SparseMatrixBase.h
index d6c65de2747ab2728aaf953f9ef4a7454b94e9ac..51d612da5c5a6171040a14df0a8e8c73d8f97555 100644
--- a/MathLib/LinAlg/Sparse/SparseMatrixBase.h
+++ b/MathLib/LinAlg/Sparse/SparseMatrixBase.h
@@ -5,13 +5,13 @@
 
 namespace MathLib {
 
-template<class T> class SparseMatrixBase : public MatrixBase
+template<typename FP_TYPE, typename IDX_TYPE> class SparseMatrixBase : public MatrixBase
 {
 public:
-	SparseMatrixBase(unsigned n1, unsigned n2) : MatrixBase (n1,n2) {}
+	SparseMatrixBase(IDX_TYPE n1, IDX_TYPE n2) : MatrixBase (n1,n2) {}
 	SparseMatrixBase() : MatrixBase () {}
-	virtual void amux(T d, T const * const x, T *y) const = 0;         // y +=d*Ax
-	virtual ~SparseMatrixBase() { }
+	virtual void amux(FP_TYPE d, FP_TYPE const * const x, FP_TYPE *y) const = 0;         // y +=d*Ax
+	virtual ~SparseMatrixBase() {};
 };
 
 } // end namespace MathLib
diff --git a/MathLib/LinAlg/Sparse/amuxCRS.cpp b/MathLib/LinAlg/Sparse/amuxCRS.cpp
index 79b847d2c135c6f60086705c27f753fe6b147741..88c112409771098affce9b7d4559b3341dc09cb6 100644
--- a/MathLib/LinAlg/Sparse/amuxCRS.cpp
+++ b/MathLib/LinAlg/Sparse/amuxCRS.cpp
@@ -14,20 +14,6 @@
 
 namespace MathLib {
 
-void amuxCRS (double a,
-	unsigned n, unsigned const * const iA, unsigned const * const jA,
-        double const * const A, double const * const x, double* y)
-{
-	for (unsigned i(0); i<n; i++) {
-		y[i] = 0.0;
-		const unsigned end (iA[i+1]);
-		for (unsigned j(iA[i]); j<end; j++) {
-			y[i] += A[j] * x[jA[j]];
-		}
-		y[i] *= a;
-	}
-}
-
 struct MatMultThreadParam {
 	MatMultThreadParam (double scalar_factor, unsigned beg_row, unsigned end_row,
 		unsigned const * const iA, unsigned const * const jA,
@@ -49,14 +35,14 @@ struct MatMultThreadParam {
 extern "C" {
 void* amuxCRSpthread (void* ptr)
 {
-	MatMultThreadParam *thread_param ((MatMultThreadParam*)(ptr));
-	const double a (thread_param->_a);
-	const unsigned beg_row (thread_param->_beg_row);
-	const unsigned end_row (thread_param->_end_row);
-	unsigned const * const iA (thread_param->_row_ptr);
-	unsigned const * const jA (thread_param->_col_idx);
-        double const * const A (thread_param->_data);
-	double const * const x (thread_param->_x);
+	MatMultThreadParam *thread_param((MatMultThreadParam*) (ptr));
+	const double a(thread_param->_a);
+	const unsigned beg_row(thread_param->_beg_row);
+	const unsigned end_row(thread_param->_end_row);
+	unsigned const * const iA(thread_param->_row_ptr);
+	unsigned const * const jA(thread_param->_col_idx);
+	double const * const A(thread_param->_data);
+	double const * const x(thread_param->_x);
 	double* y(thread_param->_y);
 
 	for (unsigned i(beg_row); i<end_row; i++) {
@@ -110,24 +96,23 @@ void amuxCRSParallelPThreads (double a,
 #endif
 }
 
-void amuxCRSParallelOpenMP (double a,
-	unsigned n, unsigned const * const iA, unsigned const * const jA,
-	double const * const A, double const * const x, double* y,
-	unsigned num_of_omp_threads)
+void amuxCRSParallelOpenMP(double a, unsigned n, unsigned const * const iA,
+				unsigned const * const jA, double const * const A, double const * const x,
+				double* y, unsigned num_of_omp_threads)
 {
-        unsigned i;
-        omp_set_num_threads(num_of_omp_threads);
-        {
-                #pragma omp parallel for
-                for (i=0; i<n; i++) {
-                        y[i] = 0.0;
-                        const unsigned end (iA[i+1]);
-                        for (unsigned j(iA[i]); j<end; j++) {
-                                y[i] += A[j] * x[jA[j]];
-                        }
-                        y[i] *= a;
-                }
-        }
+	unsigned i;
+	omp_set_num_threads(num_of_omp_threads);
+	{
+#pragma omp parallel for
+		for (i = 0; i < n; i++) {
+			y[i] = 0.0;
+			const unsigned end(iA[i + 1]);
+			for (unsigned j(iA[i]); j < end; j++) {
+				y[i] += A[j] * x[jA[j]];
+			}
+			y[i] *= a;
+		}
+	}
 }
 
 void amuxCRSSym (double a,
@@ -139,17 +124,17 @@ void amuxCRSSym (double a,
 	}
 
 	for (unsigned i(0); i<n; i++) {
-			unsigned j (iA[i]);
-			// handle diagonal
-			if (jA[j] == i) {
+		unsigned j (iA[i]);
+		// handle diagonal
+		if (jA[j] == i) {
+			y[i] += A[j] * x[jA[j]];
+			j++;
+		}
+		const unsigned end (iA[i+1]);
+		for (; j<end; j++) {
 				y[i] += A[j] * x[jA[j]];
-				j++;
-			}
-			const unsigned end (iA[i+1]);
-			for (; j<end; j++) {
-					y[i] += A[j] * x[jA[j]];
-					y[jA[j]] += A[j] * x[i];
-			}
+				y[jA[j]] += A[j] * x[i];
+		}
 	}
 
 	for (unsigned i(0); i<n; i++) {
diff --git a/MathLib/LinAlg/Sparse/amuxCRS.h b/MathLib/LinAlg/Sparse/amuxCRS.h
index b1845218f8c5e8f3ad6f9a48c448b7e1eada5a67..fbe9d2ad97ec3f026b4c0f0f153a4eaa34ffa9cc 100644
--- a/MathLib/LinAlg/Sparse/amuxCRS.h
+++ b/MathLib/LinAlg/Sparse/amuxCRS.h
@@ -3,9 +3,19 @@
 
 namespace MathLib {
 
-void amuxCRS (double a,
-	unsigned n, unsigned const * const iA, unsigned const * const jA,
-        double const * const A, double const * const x, double* y);
+template<typename FP_TYPE, typename IDX_TYPE>
+void amuxCRS(FP_TYPE a, IDX_TYPE n, IDX_TYPE const * const iA, IDX_TYPE const * const jA,
+				FP_TYPE const * const A, FP_TYPE const * const x, FP_TYPE* y)
+{
+	for (IDX_TYPE i(0); i < n; i++) {
+		y[i] = 0.0;
+		const IDX_TYPE end(iA[i + 1]);
+		for (IDX_TYPE j(iA[i]); j < end; j++) {
+			y[i] += A[j] * x[jA[j]];
+		}
+		y[i] *= a;
+	}
+}
 
 void amuxCRSParallelPThreads (double a,
 	unsigned n, unsigned const * const iA, unsigned const * const jA,
diff --git a/MathLib/sparse.h b/MathLib/sparse.h
index fa3f6623659f7ec59afca7531d7b9028af31975e..3278ea93c699bee6803959e543d1dc22371ff09d 100644
--- a/MathLib/sparse.h
+++ b/MathLib/sparse.h
@@ -4,51 +4,48 @@
 #include <iostream>
 #include <cassert>
 
-extern void CS_write(char*, unsigned, unsigned*, unsigned*, double*);
+extern void CS_write(char*, unsigned, unsigned const*, unsigned const*, double const*);
 extern void CS_read(char*, unsigned&, unsigned*&, unsigned*&, double*&);
 
-template<class T> void
-CS_write(std::ostream &os, unsigned n, unsigned* iA, unsigned* jA, T* A)
+template<class T> void CS_write(std::ostream &os, unsigned n, unsigned const* iA, unsigned const* jA, T const* A)
 {
-  os.write((char*) &n, sizeof(unsigned));
-  os.write((char*) iA, (n+1)*sizeof(unsigned));
-  os.write((char*) jA, iA[n]*sizeof(unsigned));
-  os.write((char*) A, iA[n]*sizeof(T));
+	os.write((char*) &n, sizeof(unsigned));
+	os.write((char*) iA, (n + 1) * sizeof(unsigned));
+	os.write((char*) jA, iA[n] * sizeof(unsigned));
+	os.write((char*) A, iA[n] * sizeof(T));
 }
 
-template<class T> void
-CS_read(std::istream &is, unsigned &n, unsigned* &iA, unsigned* &jA, T* &A)
+template<class T> void CS_read(std::istream &is, unsigned &n, unsigned* &iA, unsigned* &jA, T* &A)
 {
-  is.read((char*) &n, sizeof(unsigned));
-  if (iA != NULL) {
-    delete [] iA;
-    delete [] jA;
-    delete [] A;
-  }
-  iA = new unsigned[n+1];
-  assert(iA!=NULL);
-  is.read((char*) iA, (n+1)*sizeof(unsigned));
-
-  jA = new unsigned[iA[n]];
-  assert(jA!=NULL);
-  is.read((char*) jA, iA[n]*sizeof(unsigned));
-
-  A = new T[iA[n]];
-  assert(A!=NULL);
-  is.read((char*) A, iA[n]*sizeof(T));
+	is.read((char*) &n, sizeof(unsigned));
+	if (iA != NULL) {
+		delete[] iA;
+		delete[] jA;
+		delete[] A;
+	}
+	iA = new unsigned[n + 1];
+	assert(iA != NULL);
+	is.read((char*) iA, (n + 1) * sizeof(unsigned));
+
+	jA = new unsigned[iA[n]];
+	assert(jA != NULL);
+	is.read((char*) jA, iA[n] * sizeof(unsigned));
+
+	A = new T[iA[n]];
+	assert(A != NULL);
+	is.read((char*) A, iA[n] * sizeof(T));
 
 #ifndef NDEBUG
-  // do simple checks
-  if (iA[0]!=0)
-    std::cerr << std::endl
-              << "CRS matrix: array iA doesn't start with 0" << std::endl;
-
-  unsigned i = 0;
-  while (i<iA[n] && jA[i]<n) ++i;
-  if (i<iA[n])
-    std::cerr << std::endl
-              << "CRS matrix: the " << i << "th entry of jA has the value "
-              << jA[i] << ", which is out of bounds." << std::endl;
+	// do simple checks
+	if (iA[0] != 0) std::cerr << std::endl << "CRS matrix: array iA doesn't start with 0"
+					<< std::endl;
+
+	unsigned i = 0;
+	while (i < iA[n] && jA[i] < n)
+		++i;
+	if (i < iA[n]) std::cerr << std::endl << "CRS matrix: the " << i
+					<< "th entry of jA has the value " << jA[i] << ", which is out of bounds."
+					<< std::endl;
 #endif
 }
 
diff --git a/SimpleTests/MatrixTests/CMakeLists.txt b/SimpleTests/MatrixTests/CMakeLists.txt
index bda3c0ca41a4d64b35dab5b17a6418d155cb8afb..50238c4a25c2bcd8a3082b9bdc6127ba148e0bca 100644
--- a/SimpleTests/MatrixTests/CMakeLists.txt
+++ b/SimpleTests/MatrixTests/CMakeLists.txt
@@ -19,6 +19,13 @@ ADD_EXECUTABLE( MatMult
         ${HEADERS}
 )
 
+# Create the executable
+ADD_EXECUTABLE( MatTestRemoveRowsCols
+        MatTestRemoveRowsCols.cpp
+        ${SOURCES}
+        ${HEADERS}
+)
+
 IF (WIN32)
         TARGET_LINK_LIBRARIES(MatMult Winmm.lib)
 ENDIF (WIN32)
@@ -28,3 +35,12 @@ TARGET_LINK_LIBRARIES ( MatMult
 	MathLib
 )
 
+IF (WIN32)
+        TARGET_LINK_LIBRARIES(MatTestRemoveRowsCols Winmm.lib)
+ENDIF (WIN32)
+
+TARGET_LINK_LIBRARIES ( MatTestRemoveRowsCols
+	Base
+	MathLib
+)
+
diff --git a/SimpleTests/MatrixTests/MatTestRemoveRowsCols.cpp b/SimpleTests/MatrixTests/MatTestRemoveRowsCols.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1d27d44c9956fdc6ec144f1459d76baaaa382f1f
--- /dev/null
+++ b/SimpleTests/MatrixTests/MatTestRemoveRowsCols.cpp
@@ -0,0 +1,71 @@
+/*
+ * MatTestRemoveRowsCols.cpp
+ *
+ *  Created on: Nov 8, 2011
+ *      Author: TF
+ */
+
+#include <fstream>
+#include <iostream>
+
+// Base
+#include "RunTimeTimer.h"
+#include "CPUTimeTimer.h"
+
+// MathLib
+#include "LinAlg/Sparse/CRSMatrix.h"
+
+int main(int argc, char *argv[])
+{
+	if (argc < 3) {
+		std::cout << "Usage: " << argv[0] << " input-matrix output-matrix" << std::endl;
+		return 1;
+	}
+
+	std::string fname_mat (argv[1]);
+	bool verbose (true);
+
+	// *** reading matrix in crs format from file
+	std::ifstream in(fname_mat.c_str(), std::ios::in | std::ios::binary);
+	double *A(NULL);
+	unsigned *iA(NULL), *jA(NULL), n;
+	if (in) {
+		if (verbose) {
+			std::cout << "reading matrix from " << fname_mat << " ... " << std::flush;
+		}
+		RunTimeTimer timer;
+		timer.start();
+		CS_read(in, n, iA, jA, A);
+		in.close();
+		timer.stop();
+		if (verbose) {
+			std::cout << "ok, " << timer.elapsed() << " s" << std::endl;
+		}
+	} else {
+		std::cout << "error reading matrix from " << fname_mat << std::endl;
+	}
+	unsigned nnz(iA[n]);
+	if (verbose) {
+		std::cout << "Parameters read: n=" << n << ", nnz=" << nnz << std::endl;
+	}
+
+	MathLib::CRSMatrix<double, unsigned> mat (n, iA, jA, A);
+
+	const unsigned n_rows_cols_to_erase(3);
+	unsigned *rows_to_erase(new unsigned[n_rows_cols_to_erase]);
+	unsigned *cols_to_erase(new unsigned[n_rows_cols_to_erase]);
+
+	for (unsigned k(0); k<n_rows_cols_to_erase; k++) {
+		rows_to_erase[k] = (k+1)*2;
+		cols_to_erase[k] = (k+1)*2;
+	}
+
+	mat.eraseEntries(n_rows_cols_to_erase, rows_to_erase, cols_to_erase);
+	delete[] rows_to_erase;
+	delete[] cols_to_erase;
+
+	fname_mat = argv[2];
+	std::ofstream out (fname_mat.c_str(), std::ios::binary);
+	CS_write (out, mat.getNRows(), mat.getRowPtrArray(), mat.getColIdxArray(), mat.getEntryArray());
+	out.close();
+}
diff --git a/SimpleTests/SolverTests/ConjugateGradientUnpreconditioned.cpp b/SimpleTests/SolverTests/ConjugateGradientUnpreconditioned.cpp
index 2413a1502def9a6f29460fd0d8bf7edd2f33532c..52f1ba239f7a459c1901ee9382cdf36ee3571b28 100644
--- a/SimpleTests/SolverTests/ConjugateGradientUnpreconditioned.cpp
+++ b/SimpleTests/SolverTests/ConjugateGradientUnpreconditioned.cpp
@@ -12,7 +12,7 @@ int main(int argc, char *argv[])
 	// *** reading matrix in crs format from file
 	std::string fname("/work/fischeth/data/testmat.bin");
 //	std::ifstream in(fname.c_str(), std::ios::binary);
-	MathLib::CRSMatrix<double> *mat (new MathLib::CRSMatrix<double>(fname));
+	MathLib::CRSMatrix<double, unsigned> *mat (new MathLib::CRSMatrix<double, unsigned>(fname));
 /*	double *A(NULL);
 	unsigned *iA(NULL), *jA(NULL), n;
 	if (in) {