Index: src/LinearAlgebra/Eigenspace.cpp
===================================================================
--- src/LinearAlgebra/Eigenspace.cpp	(revision 1fb318e13ebc1029d5ba1a68d3b01c62237ab05b)
+++ src/LinearAlgebra/Eigenspace.cpp	(revision e828c07cc83828399b494f75295e73daf5ad0852)
@@ -85,5 +85,5 @@
     boost::shared_ptr<VectorContent> ev(EigenvectorMatrix.getColumnVector(iter));
     Eigenvectors.push_back( ev );
-    Log() << Verbose(1) << iter << " th Eigenvector is " << *ev << std::endl;
+    DoLog(1) && (Log() << Verbose(1) << iter << " th Eigenvector is " << *ev << std::endl);
   }
 }
Index: src/LinearAlgebra/MatrixContent.cpp
===================================================================
--- src/LinearAlgebra/MatrixContent.cpp	(revision 1fb318e13ebc1029d5ba1a68d3b01c62237ab05b)
+++ src/LinearAlgebra/MatrixContent.cpp	(revision e828c07cc83828399b494f75295e73daf5ad0852)
@@ -416,5 +416,6 @@
 bool MatrixContent::SwapRowColumn(size_t i, size_t j)
 {
-  assert (rows == columns && "The matrix must be square for swapping row against column to be possible.");
+  ASSERT (rows == columns,
+      "MatrixContent::SwapRowColumn() - The matrix must be square for swapping row against column to be possible.");
   return (gsl_matrix_swap_rowcol (content, i, j) == GSL_SUCCESS);
 };
@@ -533,4 +534,16 @@
 }
 
+
+/** Sorts the eigenpairs in ascending order of the eigenvalues.
+ * We assume that MatrixContent::transformToEigenbasis() has just been called.
+ * @param eigenvalues vector of eigenvalue from
+ *        MatrixContent::transformToEigenbasis()
+ */
+void MatrixContent::sortEigenbasis(gsl_vector *eigenvalues)
+{
+  gsl_eigen_symmv_sort (eigenvalues, content,
+                          GSL_EIGEN_SORT_ABS_ASC);
+}
+
 /* ============================ Properties ============================== */
 /** Checks whether matrix' elements are strictly null.
@@ -585,5 +598,6 @@
 {
   int signum = 0;
-  assert (rows == columns && "Determinant can only be calculated for square matrices.");
+  ASSERT(rows == columns,
+      "MatrixContent::Determinant() - determinant can only be calculated for square matrices.");
   gsl_permutation *p = gsl_permutation_alloc(rows);
   gsl_linalg_LU_decomp(content, p, &signum);
@@ -647,15 +661,15 @@
 std::ostream & operator<<(std::ostream &ost, const MatrixContent &mat)
 {
-  ost << "[";
+  ost << "\\begin{pmatrix}";
   for (size_t i=0;i<mat.rows;i++) {
     for (size_t j=0;j<mat.columns;j++) {
-      ost << mat.at(i,j);
+      ost << mat.at(i,j) << " ";
       if (j != mat.columns-1)
-        ost << " ";
+        ost << "& ";
     }
     if (i != mat.rows-1)
-      ost << "; ";
+      ost << "\\\\ ";
   }
-  ost << "]";
+  ost << "\\end{pmatrix}";
   return ost;
 }
Index: src/LinearAlgebra/MatrixContent.hpp
===================================================================
--- src/LinearAlgebra/MatrixContent.hpp	(revision 1fb318e13ebc1029d5ba1a68d3b01c62237ab05b)
+++ src/LinearAlgebra/MatrixContent.hpp	(revision e828c07cc83828399b494f75295e73daf5ad0852)
@@ -88,4 +88,5 @@
   MatrixContent &transpose();
   gsl_vector* transformToEigenbasis();
+  void sortEigenbasis(gsl_vector *eigenvalues);
 
   // Properties
Index: src/LinearAlgebra/Subspace.cpp
===================================================================
--- src/LinearAlgebra/Subspace.cpp	(revision 1fb318e13ebc1029d5ba1a68d3b01c62237ab05b)
+++ src/LinearAlgebra/Subspace.cpp	(revision e828c07cc83828399b494f75295e73daf5ad0852)
@@ -49,5 +49,5 @@
 
   // create eigenspace matrices
-  projectFullSpaceMatrixToSubspace();
+  EigenspaceMatrix = projectFullspaceMatrixToSubspace(FullSpace.getEigenspaceMatrix());
 }
 
@@ -62,5 +62,4 @@
 /** Diagonalizes the subspace matrix.
  *
- * @param fullmatrix full matrix to project into subspace and solve
  */
 void Subspace::calculateEigenSubspace()
@@ -69,7 +68,7 @@
   createProjectionMatrices();
   // remove subsubspace directions
-  correctEigenvectorsFromSubIndices();
+  //correctProjectionMatricesFromSubIndices();
   // solve
-  projectFullSpaceMatrixToSubspace();
+  EigenspaceMatrix = projectFullspaceMatrixToSubspace(FullSpace.getEigenspaceMatrix());
   EigenvectorMatrix = EigenspaceMatrix;
   VectorContent *EigenvalueVector = new VectorContent(EigenvectorMatrix.transformToEigenbasis());
@@ -79,8 +78,25 @@
   }
   delete EigenvalueVector;
-  Log() << Verbose(2) << "Eigenvector matrix is " << EigenvectorMatrix << std::endl;
-  Log() << Verbose(2) << "Eigenvalues are " << Eigenvalues << std::endl;
+
   // create mapping
   createLocalMapping();
+
+  // swap the eigenvectors/-values to their correct sequence
+  sortEigenvectors();
+
+  // scale eigenvectors by their eigenvalues for the subsequent correction
+  scaleEigenvectorsbyEigenvalue();
+
+  // let only remain corrections to lower orders on this order
+  correctEigenvectorsFromSubIndices();
+
+  if (!EigenvectorMatrix.IsNull()) {
+    // get correct eigenvalues
+    getNormofEigenvectorAsEigenvalue();
+
+    DoLog(2) && (Log() << Verbose(2) << "Eigenvector matrix is " << EigenvectorMatrix << std::endl);
+    DoLog(2) && (Log() << Verbose(2) << "Eigenvalues are " << Eigenvalues << std::endl);
+
+  }
 }
 
@@ -123,6 +139,96 @@
 
 
+/** Sort the eigenvectors in the order of Subspace::Indices.
+ *
+ */
+void Subspace::sortEigenvectors()
+{
+  DoLog(1) && (Log() << Verbose(1) << "Sorting Eigenvectors ..." << std::endl);
+  MatrixContent tempMatrix = EigenvectorMatrix;
+  eigenvalueset tempValues = Eigenvalues;
+  size_t localindex = 0;
+  BOOST_FOREACH( size_t iter, Indices) {
+    Log() << Verbose(1) << GlobalToLocal[iter] << "th eigenvector is associated to "
+        << iter << " and goes to column " << localindex << "." << std::endl;
+    boost::shared_ptr<VectorContent> columnvector(tempMatrix.getColumnVector(GlobalToLocal[iter]));
+    *Eigenvectors[localindex] = *columnvector;
+    Eigenvalues[localindex] = tempValues[GlobalToLocal[iter]];
+    ++localindex;
+  }
+}
+
+
+/** We remove the projections from lower subspaces from our Eigenspacematrix.
+ * This is intended to diminish parallel changing of eigenspaces.
+ */
 void Subspace::correctEigenvectorsFromSubIndices()
 {
+  DoLog(1) && (Log() << Verbose(1) << "Correcting EigenvectorMatrix ... " << std::endl);
+  BOOST_FOREACH( boost::shared_ptr<Subspace> iter, SubIndices ) {
+    const MatrixContent tempMatrix =
+        projectFullspaceMatrixToSubspace(
+            iter->projectSubspaceMatrixToFullspace(iter->getEigenvectorMatrix())
+            );
+    DoLog(1) && (Log() << Verbose(1) << "Subtracting matrix from " << *iter << ":" << tempMatrix << std::endl);
+    EigenvectorMatrix -= tempMatrix;
+  }
+  DoLog(1) && (Log() << Verbose(1) << "Corrected EigenvectorMatrix is " << EigenvectorMatrix << std::endl);
+
+  // check for null vectors
+  const size_t max = EigenvectorMatrix.getColumns();
+  for(size_t i = 0; i< max; ++i) {
+    if (Eigenvectors[i]->IsZero()) {
+      Eigenvalues[i] = 0.;
+      Eigenvectors[i]->setZero();
+    }
+  }
+}
+
+
+/** Scale the local eigenvectors each by their eigenvalue.
+ *
+ */
+void Subspace::scaleEigenvectorsbyEigenvalue()
+{
+  size_t localindex = 0;
+  BOOST_FOREACH( boost::shared_ptr<VectorContent> ev, Eigenvectors) {
+    *ev *= Eigenvalues[localindex];
+    ++localindex;
+  }
+}
+
+
+/** Get Norm of each eigenvector to serve als eigenvalue.
+ *
+ */
+void Subspace::getNormofEigenvectorAsEigenvalue()
+{
+  size_t localindex = 0;
+  BOOST_FOREACH( boost::shared_ptr<VectorContent> ev, Eigenvectors) {
+    Eigenvalues[localindex] = ev->Norm();
+    ++localindex;
+  }
+}
+
+
+/** We remove the projections from lower subspaces from our Eigenspacematrix.
+ * This is intended to diminish parallel changing of eigenspaces.
+ */
+void Subspace::correctProjectionMatricesFromSubIndices()
+{
+  MatrixContent subtractMatrix(ProjectToSubspace.getRows(), ProjectToSubspace.getColumns());
+  DoLog(1) && (Log() << Verbose(1) << "Correcting ProjectToSubspace ... " << std::endl);
+  BOOST_FOREACH( boost::shared_ptr<Subspace> iter, SubIndices ) {
+    const MatrixContent tempMatrix = iter->getEigenvectorMatrix();
+    const MatrixContent tempMatrix2 = iter->projectSubspaceMatrixToFullspace(tempMatrix);
+    const MatrixContent tempMatrix3 = (tempMatrix2 * ProjectToSubspace);
+    DoLog(1) && (Log() << Verbose(1) << "Subtracting matrix from " << *iter << ":" << tempMatrix3 << std::endl);
+    subtractMatrix += tempMatrix3;
+  }
+  ProjectToSubspace -= subtractMatrix;
+  DoLog(1) && (Log() << Verbose(1) << "Corrected ProjectToSubspace is " << ProjectToSubspace << std::endl);
+
+  ProjectFromSubspace = ((const MatrixContent)ProjectToSubspace).transpose();
+  DoLog(1) && (Log() << Verbose(1) << "Corrected ProjectFromSubspace is " << ProjectFromSubspace << std::endl);
 }
 
@@ -198,4 +304,13 @@
 
 
+/** Getter for Subspace::SubIndices.
+ *
+ * @return const reference to Subspace::SubIndices.
+ */
+const Subspace::subset & Subspace::getSubIndices() const
+{
+  return SubIndices;
+}
+
 /** Remove a subset of indices from the SubIndices.
  *
@@ -236,11 +351,11 @@
 {
   // check whether bigmatrix is at least as big as EigenspaceMatrix
-  ASSERT(EigenspaceMatrix.getRows() <= Eigenvectors[0]->getDimension(),
+  ASSERT(EigenspaceMatrix.getRows() <= FullSpace.getEigenspaceMatrix().getRows(),
       "embedEigenspaceMatrix() - EigenspaceMatrix has more rows "
-      +toString(EigenspaceMatrix.getRows())+" than eigenvectors "
+      +toString(EigenspaceMatrix.getRows())+" than FullSpace::EigenspaceMatrix "
       +toString(Eigenvectors[0]->getDimension())+"!");
-  ASSERT(EigenspaceMatrix.getColumns() <= Eigenvectors.size(),
+  ASSERT(EigenspaceMatrix.getColumns() <= FullSpace.getEigenspaceMatrix().getColumns(),
       "embedEigenspaceMatrix() - EigenspaceMatrix has more columns "
-      +toString(EigenspaceMatrix.getColumns())+" than eigenvectors "
+      +toString(EigenspaceMatrix.getColumns())+" than FullSpace::EigenspaceMatrix "
       +toString(Eigenvectors.size())+"!");
   // check whether EigenspaceMatrix is big enough for both index sets
@@ -255,27 +370,32 @@
 
   // construct intermediate matrix
-  MatrixContent *intermediatematrix = new MatrixContent(Eigenvectors[0]->getDimension(), Indices.size());
-  size_t localcolumn = 0;
-  BOOST_FOREACH(size_t columnindex, Indices) {
-    // create two vectors from each row and copy assign them
-    boost::shared_ptr<VectorContent> srceigenvector(Eigenvectors[columnindex]);
-    boost::shared_ptr<VectorContent> desteigenvector(intermediatematrix->getColumnVector(localcolumn));
-    *desteigenvector = *srceigenvector;
-    localcolumn++;
-  }
-  // matrix product with eigenbasis EigenspaceMatrix matrix
-  *intermediatematrix *= EigenspaceMatrix;
-
-  // and place at right columns into bigmatrix
-  MatrixContent *bigmatrix = new MatrixContent(Eigenvectors[0]->getDimension(), Eigenvectors.size());
-  bigmatrix->setZero();
-  localcolumn = 0;
-  BOOST_FOREACH(size_t columnindex, Indices) {
-    // create two vectors from each row and copy assign them
-    boost::shared_ptr<VectorContent> srceigenvector(intermediatematrix->getColumnVector(localcolumn));
-    boost::shared_ptr<VectorContent> desteigenvector(bigmatrix->getColumnVector(columnindex));
-    *desteigenvector = *srceigenvector;
-    localcolumn++;
-  }
+  MatrixContent *bigmatrix = new MatrixContent(
+      FullSpace.getEigenspaceMatrix().getRows(),
+      FullSpace.getEigenspaceMatrix().getColumns());
+  *bigmatrix = ProjectToSubspace * EigenspaceMatrix * ProjectFromSubspace;
+
+//  MatrixContent *intermediatematrix = new MatrixContent(FullSpace.getEigenspaceMatrix().getRows(), Indices.size());
+//  size_t localcolumn = 0;
+//  BOOST_FOREACH(size_t columnindex, Indices) {
+//    // create two vectors from each row and copy assign them
+//    boost::shared_ptr<VectorContent> srceigenvector(Eigenvectors[columnindex]);
+//    boost::shared_ptr<VectorContent> desteigenvector(intermediatematrix->getColumnVector(localcolumn));
+//    *desteigenvector = *srceigenvector;
+//    localcolumn++;
+//  }
+//  // matrix product with eigenbasis EigenspaceMatrix matrix
+//  *intermediatematrix *= EigenspaceMatrix;
+//
+//  // and place at right columns into bigmatrix
+//  MatrixContent *bigmatrix = new MatrixContent(FullSpace.getEigenspaceMatrix().getRows(), Eigenvectors.size());
+//  bigmatrix->setZero();
+//  localcolumn = 0;
+//  BOOST_FOREACH(size_t columnindex, Indices) {
+//    // create two vectors from each row and copy assign them
+//    boost::shared_ptr<VectorContent> srceigenvector(intermediatematrix->getColumnVector(localcolumn));
+//    boost::shared_ptr<VectorContent> desteigenvector(bigmatrix->getColumnVector(columnindex));
+//    *desteigenvector = *srceigenvector;
+//    localcolumn++;
+//  }
 
   return *bigmatrix;
@@ -302,27 +422,53 @@
   BOOST_FOREACH(size_t iter, Indices) {
     *ColumnVectors[localindex] = FullSpace.getEigenvector(iter);
-    localindex++;
-  }
-  Log() << Verbose(2) << "ProjectionToSubspace matrix is " << ProjectToSubspace << std::endl;
+    ++localindex;
+  }
+  DoLog(2) && (Log() << Verbose(2) << "ProjectionToSubspace matrix is " << ProjectToSubspace << std::endl);
 
   // then ProjectFromSubspace is just transposed
   ProjectFromSubspace = ((const MatrixContent)ProjectToSubspace).transpose();
-  Log() << Verbose(2) << "ProjectFromSubspace matrix is " << ProjectFromSubspace << std::endl;
-}
-
-
-/** Creates the subspace matrix by projecting down the FullSpace::EigenspaceMatrix.
+  DoLog(2) && (Log() << Verbose(2) << "ProjectFromSubspace matrix is " << ProjectFromSubspace << std::endl);
+}
+
+
+/** Creates the subspace matrix by projecting down the given \a _fullmatrix.
  *  We just perform \f$M = P^t \cdot A \cdot P\f$, when P are the projection matrix,
  *  A the full matrix and M the subspace matrix.
- */
-void Subspace::projectFullSpaceMatrixToSubspace()
-{
+ *
+ *  @param _fullmatrix full matrix A to project into subspace
+ *  @return subspace matrix M
+ */
+const MatrixContent Subspace::projectFullspaceMatrixToSubspace(const MatrixContent &_fullmatrix) const
+{
+  ASSERT((FullSpace.getIndices().size() == _fullmatrix.getRows())
+      && (FullSpace.getIndices().size() == _fullmatrix.getColumns()),
+      "Subspace::projectSubspaceMatrixToFullspace() - dimensions of this subspace "
+      +toString(Indices.size())+" and the given matrix ("
+      +toString(_fullmatrix.getRows())+" x "+toString(_fullmatrix.getColumns())+") differ!");
   // construct small matrix
-  EigenspaceMatrix = ProjectFromSubspace * FullSpace.getEigenspaceMatrix() * ProjectToSubspace;
-  Log() << Verbose(2) << "EigenspaceMatrix matrix is " << EigenspaceMatrix << std::endl;
-}
-
-
-/** We associate local Eigenvectors with ones from FullSpace by a paralellity
+  MatrixContent tempMatrix = ProjectFromSubspace * _fullmatrix * ProjectToSubspace;
+  return tempMatrix;
+  DoLog(2) && (Log() << Verbose(2) << "returned subspace matrix is " << tempMatrix << std::endl);
+}
+
+
+/** Creates a full space matrix which is the projection of given \a _subspacematrix
+ * from the subspace.
+ *
+ * @param _subspacematrix subspace matrix
+ * @return full matrix of the Subspace::EigenspaceMatrix projected into
+ *         Subspace::FullSpace.
+ */
+const MatrixContent Subspace::projectSubspaceMatrixToFullspace(const MatrixContent &_subspacematrix) const
+{
+  ASSERT((Indices.size() == _subspacematrix.getRows()) && (Indices.size() == _subspacematrix.getColumns()),
+      "Subspace::projectSubspaceMatrixToFullspace() - dimensions of this subspace "
+      +toString(Indices.size())+" and the given matrix ("
+      +toString(_subspacematrix.getRows())+" x "+toString(_subspacematrix.getColumns())+") differ!");
+  return (ProjectToSubspace * _subspacematrix * ProjectFromSubspace);
+}
+
+
+/** We associate local Eigenvectors with ones from FullSpace by a parallelity
  * criterion.
  */
@@ -335,5 +481,11 @@
   for (size_t localindex = 0; localindex< Indices.size(); ++localindex) {
     boost::shared_ptr<VectorContent> &CurrentEigenvector = Eigenvectors[localindex];
-    Log() << Verbose(1) << "Current Eigenvector is " << *CurrentEigenvector << std::endl;
+    VectorContent tempCurrentEigenvector = ProjectToSubspace * (*CurrentEigenvector);
+    Log() << Verbose(1) << "Current Eigenvector is " << *CurrentEigenvector
+        << " --(projected)-> " << tempCurrentEigenvector << std::endl;
+    if (Eigenvalues[localindex] == 0) {
+      DoLog(2) && (Log() << Verbose(2) << "Is null, skipping." << std::endl);
+      continue;
+    }
 
     // (for now settle with the one we are most parallel to)
@@ -341,7 +493,7 @@
     double mostparallel_scalarproduct = 0.;
     BOOST_FOREACH( size_t indexiter, CorrespondenceList) {
-      Log() << Verbose(2) << "Comparing to old " << indexiter << "th eigenvector " << FullSpace.getEigenvector(indexiter) << std::endl;
-      const double scalarproduct = (FullSpace.getEigenvector(indexiter)) * ( ProjectToSubspace * (*CurrentEigenvector));
-      Log() << Verbose(2) << "SKP is " << scalarproduct << std::endl;
+      DoLog(2) && (Log() << Verbose(2) << "Comparing to old " << indexiter << "th eigenvector " << FullSpace.getEigenvector(indexiter) << std::endl);
+      const double scalarproduct = (FullSpace.getEigenvector(indexiter)) * ( tempCurrentEigenvector );
+      DoLog(2) && (Log() << Verbose(2) << "SKP is " << scalarproduct << std::endl);
       if (fabs(scalarproduct) > fabs(mostparallel_scalarproduct)) {
         mostparallel_scalarproduct = scalarproduct;
@@ -355,7 +507,7 @@
       if (mostparallel_scalarproduct < 0) {
         *CurrentEigenvector *= -1.;
-        Log() << Verbose(1) << "Associating (inverted) " << *CurrentEigenvector << " with " << mostparallel_index << "th's fullspace eigenvector." << std::endl;
+        DoLog(1) && (Log() << Verbose(1) << "Associating (inverted) " << *CurrentEigenvector << " with " << mostparallel_index << "th's fullspace eigenvector." << std::endl);
       } else {
-        Log() << Verbose(1) << "Associating " << *CurrentEigenvector << " with " << mostparallel_index << "th's fullspace eigenvector." << std::endl;
+        DoLog(1) && (Log() << Verbose(1) << "Associating " << *CurrentEigenvector << " with " << mostparallel_index << "th's fullspace eigenvector." << std::endl);
       }
       ASSERT( LocalToGlobal.count(localindex) == 0,
Index: src/LinearAlgebra/Subspace.hpp
===================================================================
--- src/LinearAlgebra/Subspace.hpp	(revision 1fb318e13ebc1029d5ba1a68d3b01c62237ab05b)
+++ src/LinearAlgebra/Subspace.hpp	(revision e828c07cc83828399b494f75295e73daf5ad0852)
@@ -45,18 +45,27 @@
   bool removeSubset(boost::shared_ptr<Subspace> &_s);
 
+  // solving
   void calculateEigenSubspace();
-  void correctEigenvectorsFromSubIndices();
+
+  // accessing
   const MatrixContent & getEigenvectorMatrixInFullSpace();
   const eigenvectorset & getEigenvectorsInFullSpace();
   const VectorContent getEigenvectorParallelToFullOne(size_t i);
   const double getEigenvalueOfEigenvectorParallelToFullOne(size_t i);
-  void createLocalMapping();
+  const subset & getSubIndices() const;
 
 private:
 
+  void createLocalMapping();
   void invertLocalToGlobalMapping();
   void getSubspacematrixFromBigmatrix(const MatrixContent & bigmatrix);
+  void sortEigenvectors();
+  void correctEigenvectorsFromSubIndices();
+  void correctProjectionMatricesFromSubIndices();
+  void scaleEigenvectorsbyEigenvalue();
+  void getNormofEigenvectorAsEigenvalue();
   void createProjectionMatrices();
-  void projectFullSpaceMatrixToSubspace();
+  const MatrixContent projectFullspaceMatrixToSubspace(const MatrixContent &_fullmatrix) const;
+  const MatrixContent projectSubspaceMatrixToFullspace(const MatrixContent &_subspacematrix) const;
 
   mapping LocalToGlobal;
Index: src/LinearAlgebra/VectorContent.cpp
===================================================================
--- src/LinearAlgebra/VectorContent.cpp	(revision 1fb318e13ebc1029d5ba1a68d3b01c62237ab05b)
+++ src/LinearAlgebra/VectorContent.cpp	(revision e828c07cc83828399b494f75295e73daf5ad0852)
@@ -347,11 +347,11 @@
 ostream& operator<<(ostream& ost, const VectorContent& m)
 {
-  ost << "(";
+  ost << "[";
   for (size_t i=0;i<m.dimension;i++) {
     ost << m.at(i);
     if (i != m.dimension-1)
-      ost << ",";
+      ost << " ";
   }
-  ost << ")";
+  ost << "]";
   return ost;
 };
Index: src/Makefile.am
===================================================================
--- src/Makefile.am	(revision 1fb318e13ebc1029d5ba1a68d3b01c62237ab05b)
+++ src/Makefile.am	(revision e828c07cc83828399b494f75295e73daf5ad0852)
@@ -272,5 +272,5 @@
 
 noinst_LIBRARIES = libmenu.a
-bin_PROGRAMS = molecuilder molecuildergui joiner analyzer
+bin_PROGRAMS = molecuilder molecuildergui joiner analyzer SubspaceFactorizer
 EXTRA_PROGRAMS = unity
 
@@ -280,4 +280,13 @@
 
 molecuilder_DATA = elements.db valence.db orbitals.db Hbonddistance.db Hbondangle.db
+
+SubspaceFactorizer_CXXFLAGS = $(BOOST_CPPFLAGS)
+SubspaceFactorizer_SOURCES = SubspaceFactorizer.cpp
+SubspaceFactorizer_LDADD = \
+	LinearAlgebra/libMolecuilderLinearAlgebra-@MOLECUILDER_API_VERSION@.la \
+	Exceptions/libMolecuilderExceptions-@MOLECUILDER_API_VERSION@.la \
+	Helpers/libMolecuilderHelpers-@MOLECUILDER_API_VERSION@.la \
+	$(GSLLIB) \
+	$(BOOST_LIB)
 
 molecuilder_CXXFLAGS = $(BOOST_CPPFLAGS)
Index: src/SubspaceFactorizer.cpp
===================================================================
--- src/SubspaceFactorizer.cpp	(revision e828c07cc83828399b494f75295e73daf5ad0852)
+++ src/SubspaceFactorizer.cpp	(revision e828c07cc83828399b494f75295e73daf5ad0852)
@@ -0,0 +1,423 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2010 University of Bonn. All rights reserved.
+ * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
+ */
+
+/*
+ * SubspaceFactorizer.cpp
+ *
+ *  Created on: Nov 23, 2010
+ *      Author: heber
+ */
+
+#include <cmath>
+
+#include <gsl/gsl_eigen.h>
+#include <gsl/gsl_matrix.h>
+#include <gsl/gsl_vector.h>
+#include <boost/foreach.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/timer.hpp>
+
+#include "Helpers/Assert.hpp"
+#include "Helpers/Log.hpp"
+#include "Helpers/toString.hpp"
+#include "Helpers/Verbose.hpp"
+#include "LinearAlgebra/Eigenspace.hpp"
+#include "LinearAlgebra/MatrixContent.hpp"
+#include "LinearAlgebra/Subspace.hpp"
+#include "LinearAlgebra/VectorContent.hpp"
+
+typedef std::set<std::set<size_t> > SetofIndexSets;
+typedef std::set<size_t> IndexSet;
+typedef std::multimap< size_t, boost::shared_ptr<Subspace> > SubspaceMap;
+typedef std::multimap< size_t, boost::shared_ptr<IndexSet> > IndexMap;
+typedef std::list< boost::shared_ptr<VectorContent> > VectorList;
+typedef std::list< std::pair<boost::shared_ptr<VectorContent>, double> > VectorValueList;
+typedef std::vector< boost::shared_ptr<VectorContent> > VectorArray;
+typedef std::vector< double > ValueArray;
+
+
+/** Iterative function to generate all power sets of indices of size \a maxelements.
+ *
+ * @param SetofSets Container for all sets
+ * @param CurrentSet pointer to current set in this container
+ * @param Indices Source set of indices
+ * @param maxelements number of elements of each set in final SetofSets
+ * @return true - generation continued, false - current set already had
+ *         \a maxelements elements
+ */
+bool generatePowerSet(
+    SetofIndexSets &SetofSets,
+    SetofIndexSets::iterator &CurrentSet,
+    IndexSet &Indices,
+    const size_t maxelements)
+{
+  if (CurrentSet->size() < maxelements) {
+    // allocate the needed sets
+    const size_t size = Indices.size() - CurrentSet->size();
+    std::vector<std::set<size_t> > SetExpanded;
+    SetExpanded.reserve(size);
+
+    // copy the current set into each
+    for (size_t i=0;i<size;++i)
+      SetExpanded.push_back(*CurrentSet);
+
+    // expand each set by one index
+    size_t localindex=0;
+    BOOST_FOREACH(size_t iter, Indices) {
+      if (CurrentSet->count(iter) == 0) {
+        SetExpanded[localindex].insert(iter);
+        ++localindex;
+      }
+    }
+
+    // insert set at position of CurrentSet
+    for (size_t i=0;i<size;++i) {
+      //DoLog(1) && (Log() << Verbose(1) << "Inserting set #" << i << ": " << SetExpanded[i] << std::endl);
+      SetofSets.insert(CurrentSet, SetExpanded[i]);
+    }
+    SetExpanded.clear();
+
+    // and remove the current set
+    //SetofSets.erase(CurrentSet);
+    //CurrentSet = SetofSets.begin();
+
+    // set iterator to a valid position again
+    ++CurrentSet;
+    return true;
+  } else {
+    return false;
+  }
+}
+
+
+
+/** Prints the scalar product of each possible pair that is not orthonormal.
+ * We use class logger for printing.
+ * @param AllIndices set of all possible indices of the eigenvectors
+ * @param CurrentEigenvectors array of eigenvectors
+ * @return true - all are orthonormal to each other,
+ *        false - some are not orthogonal or not normalized.
+ */
+bool checkOrthogonality(const IndexSet &AllIndices, const VectorArray &CurrentEigenvectors)
+{
+  size_t nonnormalized = 0;
+  size_t nonorthogonal = 0;
+  // check orthogonality
+  BOOST_FOREACH( size_t firstindex, AllIndices) {
+    BOOST_FOREACH( size_t secondindex, AllIndices) {
+      const double scp = (*CurrentEigenvectors[firstindex])*(*CurrentEigenvectors[secondindex]);
+      if (firstindex == secondindex) {
+        if (fabs(scp - 1.) > MYEPSILON) {
+          nonnormalized++;
+          Log() << Verbose(2) << "Vector " << firstindex << " is not normalized, off by "
+              << fabs(1.-(*CurrentEigenvectors[firstindex])*(*CurrentEigenvectors[secondindex])) << std::endl;
+        }
+      } else {
+        if (fabs(scp) > MYEPSILON) {
+          nonorthogonal++;
+          Log() << Verbose(2) << "Scalar product between " << firstindex << " and " << secondindex
+              << " is " << (*CurrentEigenvectors[firstindex])*(*CurrentEigenvectors[secondindex]) << std::endl;
+        }
+      }
+    }
+  }
+
+  if ((nonnormalized == 0) && (nonorthogonal == 0)) {
+    DoLog(1) && (DoLog(1) && (Log() << Verbose(1) << "All vectors are orthonormal to each other." << std::endl));
+    return true;
+  }
+  if ((nonnormalized == 0) && (nonorthogonal != 0))
+    DoLog(1) && (DoLog(1) && (Log() << Verbose(1) << "All vectors are normalized." << std::endl));
+  if ((nonnormalized != 0) && (nonorthogonal == 0))
+    DoLog(1) && (DoLog(1) && (Log() << Verbose(1) << "All vectors are orthogonal to each other." << std::endl));
+  return false;
+}
+
+/** Calculate the sum of the scalar product of each possible pair.
+ * @param AllIndices set of all possible indices of the eigenvectors
+ * @param CurrentEigenvectors array of eigenvectors
+ * @return sum of scalar products between all possible pairs
+ */
+double calculateOrthogonalityThreshold(const IndexSet &AllIndices, const VectorArray &CurrentEigenvectors)
+{
+  double threshold = 0.;
+  // check orthogonality
+  BOOST_FOREACH( size_t firstindex, AllIndices) {
+    BOOST_FOREACH( size_t secondindex, AllIndices) {
+      const double scp = (*CurrentEigenvectors[firstindex])*(*CurrentEigenvectors[secondindex]);
+      if (firstindex == secondindex) {
+        threshold += fabs(scp - 1.);
+      } else {
+        threshold += fabs(scp);
+      }
+    }
+  }
+  return threshold;
+}
+
+
+/** Operator for output to std::ostream operator of an IndexSet.
+ * @param ost output stream
+ * @param indexset index set to output
+ * @return ost output stream
+ */
+std::ostream & operator<<(std::ostream &ost, const IndexSet &indexset)
+{
+  ost << "{ ";
+  for (IndexSet::const_iterator iter = indexset.begin();
+      iter != indexset.end();
+      ++iter)
+    ost << *iter << " ";
+  ost << "}";
+  return ost;
+}
+
+
+int main(int argc, char **argv)
+{
+  size_t matrixdimension = 8;
+  size_t subspacelimit = 4;
+
+  if (argc < 2) {
+    std::cerr << "Usage: " << argv[0] << " <matrixdim> <subspacelimit>" << std::endl;
+    return 255;
+  } else {
+    {
+      std::stringstream s(toString(argv[1]));;
+      s >> matrixdimension;
+    }
+    {
+      std::stringstream s(toString(argv[2]));;
+      s >> subspacelimit;
+    }
+  }
+
+  MatrixContent *matrix = new MatrixContent(matrixdimension,matrixdimension);
+  matrix->setZero();
+  for (size_t i=0; i<matrixdimension ; i++) {
+    for (size_t j=0; j<= i; ++j) {
+      //const double value = 10. * rand() / (double)RAND_MAX;
+      //const double value = i==j ? 2. : 1.;
+      if (i==j)
+        matrix->set(i,i, 2.);
+      else if (j+1 == i) {
+        matrix->set(i,j, 1.);
+        matrix->set(j,i, 1.);
+      } else {
+        matrix->set(i,j, 0.);
+        matrix->set(j,i, 0.);
+      }
+    }
+  }
+
+  Eigenspace::eigenvectorset CurrentEigenvectors;
+  Eigenspace::eigenvalueset CurrentEigenvalues;
+
+  setVerbosity(3);
+
+  boost::timer Time_generatingfullspace;
+  DoLog(0) && (Log() << Verbose(0) << std::endl << std::endl);
+  // create the total index set
+  IndexSet AllIndices;
+  for (size_t i=0;i<matrixdimension;++i)
+    AllIndices.insert(i);
+  Eigenspace FullSpace(AllIndices, *matrix);
+  DoLog(1) && (Log() << Verbose(1) << "Generated full space: " << FullSpace << std::endl);
+  DoLog(0) && (Log() << Verbose(0) << "Full space generation took " << Time_generatingfullspace.elapsed() << " seconds." << std::endl);
+
+  // generate first set of eigenvectors
+  // set to first guess, i.e. the unit vectors of R^matrixdimension
+  BOOST_FOREACH( size_t index, AllIndices) {
+    boost::shared_ptr<VectorContent> EV(new VectorContent(matrixdimension));
+    EV->setZero();
+    EV->at(index) = 1.;
+    CurrentEigenvectors.push_back(EV);
+    CurrentEigenvalues.push_back(0.);
+  }
+
+  boost::timer Time_generatingsubsets;
+  DoLog(0) && (Log() << Verbose(0) << "Generating sub sets ..." << std::endl);
+  SetofIndexSets SetofSets;
+  // note that starting off empty set is unstable
+  IndexSet singleset;
+  BOOST_FOREACH(size_t iter, AllIndices) {
+    singleset.insert(iter);
+    SetofSets.insert(singleset);
+    singleset.clear();
+  }
+  SetofIndexSets::iterator CurrentSet = SetofSets.begin();
+  while (CurrentSet != SetofSets.end()) {
+    //DoLog(2) && (Log() << Verbose(2) << "Current set is " << *CurrentSet << std::endl);
+    if (!generatePowerSet(SetofSets, CurrentSet, AllIndices, subspacelimit)) {
+      // go to next set
+      ++CurrentSet;
+    }
+  }
+  DoLog(0) && (Log() << Verbose(0) << "Sub set generation took " << Time_generatingsubsets.elapsed() << " seconds." << std::endl);
+
+  // create a subspace to each set and and to respective level
+  boost::timer Time_generatingsubspaces;
+  DoLog(0) && (Log() << Verbose(0) << "Generating sub spaces ..." << std::endl);
+  SubspaceMap Dimension_to_Indexset;
+  BOOST_FOREACH(std::set<size_t> iter, SetofSets) {
+    boost::shared_ptr<Subspace> subspace(new Subspace(iter, FullSpace));
+    DoLog(1) && (Log() << Verbose(1) << "Current subspace is " << *subspace << std::endl);
+    Dimension_to_Indexset.insert( make_pair(iter.size(), boost::shared_ptr<Subspace>(subspace)) );
+  }
+
+  for (size_t dim = 1; dim<=subspacelimit;++dim) {
+    BOOST_FOREACH( SubspaceMap::value_type subspace, Dimension_to_Indexset.equal_range(dim)) {
+      if (dim != 0) { // from level 1 and onward
+        BOOST_FOREACH( SubspaceMap::value_type entry, Dimension_to_Indexset.equal_range(dim-1)) {
+          if (subspace.second->contains(*entry.second)) {
+            // if contained then add ...
+            subspace.second->addSubset(entry.second);
+            // ... and also its containees as they are all automatically contained as well
+            BOOST_FOREACH(boost::shared_ptr<Subspace> iter, entry.second->getSubIndices()) {
+              subspace.second->addSubset(iter);
+            }
+          }
+        }
+      }
+    }
+  }
+  DoLog(0) && (Log() << Verbose(0) << "Sub space generation took " << Time_generatingsubspaces.elapsed() << " seconds." << std::endl);
+
+  // create a file handle for the eigenvalues
+  std::ofstream outputvalues("eigenvalues.dat", std::ios_base::trunc);
+  ASSERT(outputvalues.good(),
+      "SubspaceFactorizerUnittest::EigenvectorTest() - failed to open eigenvalue file!");
+  outputvalues << "# iteration ";
+  BOOST_FOREACH(size_t iter, AllIndices) {
+    outputvalues << "\teigenvalue" << iter;
+  }
+  outputvalues << std::endl;
+
+  DoLog(0) && (Log() << Verbose(0) << "Solving ..." << std::endl);
+  boost::timer Time_solving;
+  size_t run=1; // counting iterations
+  double threshold = 1.;  // containing threshold value
+  while ((threshold > MYEPSILON) && (run < 20)) {
+    // for every dimension
+    for (size_t dim = 1; dim <= subspacelimit;++dim) {
+      // for every index set of this dimension
+      DoLog(1) && (Log() << Verbose(1) << std::endl << std::endl);
+      DoLog(1) && (Log() << Verbose(1) << "Current dimension is " << dim << std::endl);
+      std::pair<SubspaceMap::const_iterator,SubspaceMap::const_iterator> Bounds = Dimension_to_Indexset.equal_range(dim);
+      for (SubspaceMap::const_iterator IndexsetIter = Bounds.first;
+          IndexsetIter != Bounds.second;
+          ++IndexsetIter) {
+        Subspace& subspace = *(IndexsetIter->second);
+        // show the index set
+        DoLog(2) && (Log() << Verbose(2) << std::endl);
+        DoLog(2) && (Log() << Verbose(2) << "Current subspace is " << subspace << std::endl);
+
+        // solve
+        subspace.calculateEigenSubspace();
+
+        // note that assignment to global eigenvectors all remains within subspace
+      }
+    }
+
+    // print list of similar eigenvectors
+    DoLog(2) && (Log() << Verbose(2) << std::endl);
+    BOOST_FOREACH( size_t index, AllIndices) {
+      DoLog(2) && (Log() << Verbose(2) << "Similar to " << index << "th current eigenvector " << *(CurrentEigenvectors[index]) << " are:" << std::endl);
+      BOOST_FOREACH( SubspaceMap::value_type iter, Dimension_to_Indexset) {
+        const VectorContent & CurrentEV = (iter.second)->getEigenvectorParallelToFullOne(index);
+        if (!CurrentEV.IsZero())
+          Log() << Verbose(2)
+          << "dim" << iter.first
+          << ", subspace{" << (iter.second)->getIndices()
+          << "}: "<< CurrentEV << std::endl;
+      }
+      DoLog(2) && (Log() << Verbose(2) << std::endl);
+    }
+
+    // create new CurrentEigenvectors from averaging parallel ones.
+    BOOST_FOREACH(size_t index, AllIndices) {
+      CurrentEigenvectors[index]->setZero();
+      CurrentEigenvalues[index] = 0.;
+      size_t count = 0;
+      BOOST_FOREACH( SubspaceMap::value_type iter, Dimension_to_Indexset) {
+        const VectorContent CurrentEV = (iter.second)->getEigenvectorParallelToFullOne(index);
+        *CurrentEigenvectors[index] += CurrentEV; // * (iter.second)->getEigenvalueOfEigenvectorParallelToFullOne(index);
+        CurrentEigenvalues[index] += (iter.second)->getEigenvalueOfEigenvectorParallelToFullOne(index);
+        if (!CurrentEV.IsZero())
+          count++;
+      }
+      *CurrentEigenvectors[index] *= 1./CurrentEigenvalues[index];
+      //CurrentEigenvalues[index] /= (double)count;
+    }
+
+    // check orthonormality
+    threshold = calculateOrthogonalityThreshold(AllIndices, CurrentEigenvectors);
+    bool dontOrthonormalization = checkOrthogonality(AllIndices, CurrentEigenvectors);
+
+    // orthonormalize
+    if (!dontOrthonormalization) {
+      DoLog(1) && (Log() << Verbose(1) << "Orthonormalizing ... " << std::endl);
+      for (IndexSet::const_iterator firstindex = AllIndices.begin();
+          firstindex != AllIndices.end();
+          ++firstindex) {
+        for (IndexSet::const_iterator secondindex = firstindex;
+            secondindex != AllIndices.end();
+            ++secondindex) {
+          if (*firstindex == *secondindex) {
+            (*CurrentEigenvectors[*secondindex]) *= 1./(*CurrentEigenvectors[*secondindex]).Norm();
+          } else {
+            (*CurrentEigenvectors[*secondindex]) -=
+                ((*CurrentEigenvectors[*firstindex])*(*CurrentEigenvectors[*secondindex]))
+                *(*CurrentEigenvectors[*firstindex]);
+          }
+        }
+      }
+    }
+
+//    // check orthonormality again
+//    checkOrthogonality(AllIndices, CurrentEigenvectors);
+
+    // put obtained eigenvectors into full space
+    FullSpace.setEigenpairs(CurrentEigenvectors, CurrentEigenvalues);
+
+    // show new ones
+    DoLog(1) && (Log() << Verbose(1) << "Resulting new eigenvectors and -values, run " << run << " are:" << std::endl);
+    outputvalues << run;
+    BOOST_FOREACH( size_t index, AllIndices) {
+      DoLog(1) && (Log() << Verbose(1) << *CurrentEigenvectors[index] << " with " << CurrentEigenvalues[index] << std::endl);
+      outputvalues << "\t" << CurrentEigenvalues[index];
+    }
+    outputvalues << std::endl;
+
+    // and next iteration
+    DoLog(0) && (Log() << Verbose(0) << "\titeration #" << run << std::endl);
+    run++;
+  }
+  DoLog(0) && (Log() << Verbose(0) << "Solving took " << Time_solving.elapsed() << " seconds." << std::endl);
+  // show final ones
+  DoLog(0) && (Log() << Verbose(0) << "Resulting new eigenvectors and -values, run " << run << " are:" << std::endl);
+  outputvalues << run;
+  BOOST_FOREACH( size_t index, AllIndices) {
+    DoLog(0) && (Log() << Verbose(0) << *CurrentEigenvectors[index] << " with " << CurrentEigenvalues[index] << std::endl);
+    outputvalues << "\t" << CurrentEigenvalues[index];
+  }
+  outputvalues << std::endl;
+  outputvalues.close();
+
+  setVerbosity(2);
+
+  DoLog(0) && (Log() << Verbose(0) << "Solving full space ..." << std::endl);
+  boost::timer Time_comparison;
+  MatrixContent tempFullspaceMatrix = FullSpace.getEigenspaceMatrix();
+  gsl_vector *eigenvalues = tempFullspaceMatrix.transformToEigenbasis();
+  tempFullspaceMatrix.sortEigenbasis(eigenvalues);
+  DoLog(0) && (Log() << Verbose(0) << "full space solution took " << Time_comparison.elapsed() << " seconds." << std::endl);
+
+  delete matrix;
+
+  return 0;
+}
Index: src/unittests/SubspaceFactorizerUnittest.cpp
===================================================================
--- src/unittests/SubspaceFactorizerUnittest.cpp	(revision 1fb318e13ebc1029d5ba1a68d3b01c62237ab05b)
+++ src/unittests/SubspaceFactorizerUnittest.cpp	(revision e828c07cc83828399b494f75295e73daf5ad0852)
@@ -27,4 +27,5 @@
 #include <boost/foreach.hpp>
 #include <boost/shared_ptr.hpp>
+#include <boost/timer.hpp>
 
 #include "Helpers/Assert.hpp"
@@ -49,9 +50,17 @@
   matrix = new MatrixContent(matrixdimension,matrixdimension);
   matrix->setZero();
-  for (int i=0; i<matrixdimension ; i++) {
-    matrix->set(i,i, 2.);
-    if (i < (matrixdimension-1)) {
-      matrix->set(i+1,i, 1.);
-      matrix->set(i,i+1, 1.);
+  for (size_t i=0; i<matrixdimension ; i++) {
+    for (size_t j=0; j<= i; ++j) {
+      //const double value = 10. * rand() / (double)RAND_MAX;
+      //const double value = i==j ? 2. : 1.;
+      if (i==j)
+        matrix->set(i,i, 2.);
+      else if (j+1 == i) {
+        matrix->set(i,j, 1.);
+        matrix->set(j,i, 1.);
+      } else {
+        matrix->set(i,j, 0.);
+        matrix->set(j,i, 0.);
+      }
     }
   }
@@ -209,5 +218,5 @@
         if (fabs(scp - 1.) > MYEPSILON) {
           nonnormalized++;
-          Log() << Verbose(1) << "Vector " << firstindex << " is not normalized, off by "
+          Log() << Verbose(2) << "Vector " << firstindex << " is not normalized, off by "
               << fabs(1.-(*CurrentEigenvectors[firstindex])*(*CurrentEigenvectors[secondindex])) << std::endl;
         }
@@ -215,5 +224,5 @@
         if (fabs(scp) > MYEPSILON) {
           nonorthogonal++;
-          Log() << Verbose(1) << "Scalar product between " << firstindex << " and " << secondindex
+          Log() << Verbose(2) << "Scalar product between " << firstindex << " and " << secondindex
               << " is " << (*CurrentEigenvectors[firstindex])*(*CurrentEigenvectors[secondindex]) << std::endl;
         }
@@ -223,11 +232,11 @@
 
   if ((nonnormalized == 0) && (nonorthogonal == 0)) {
-    Log() << Verbose(1) << "All vectors are orthonormal to each other." << std::endl;
+    DoLog(1) && (DoLog(1) && (Log() << Verbose(1) << "All vectors are orthonormal to each other." << std::endl));
     return true;
   }
   if ((nonnormalized == 0) && (nonorthogonal != 0))
-    Log() << Verbose(1) << "All vectors are normalized." << std::endl;
+    DoLog(1) && (DoLog(1) && (Log() << Verbose(1) << "All vectors are normalized." << std::endl));
   if ((nonnormalized != 0) && (nonorthogonal == 0))
-    Log() << Verbose(1) << "All vectors are orthogonal to each other." << std::endl;
+    DoLog(1) && (DoLog(1) && (Log() << Verbose(1) << "All vectors are orthogonal to each other." << std::endl));
   return false;
 }
@@ -289,5 +298,5 @@
     VectorValueList *&ParallelEigenvectorList)
 {
-  Log() << Verbose(1) << "Current Eigenvector is " << *CurrentEigenvector << std::endl;
+  DoLog(1) && (DoLog(1) && (Log() << Verbose(1) << "Current Eigenvector is " << *CurrentEigenvector << std::endl));
 
   // (for now settle with the one we are most parallel to)
@@ -295,7 +304,7 @@
   double mostparallel_scalarproduct = 0.;
   BOOST_FOREACH( size_t indexiter, CorrespondenceList) {
-    Log() << Verbose(2) << "Comparing to old " << indexiter << "th eigenvector " << *(CurrentEigenvectors[indexiter]) << std::endl;
+    DoLog(2) && (DoLog(2) && (Log() << Verbose(2) << "Comparing to old " << indexiter << "th eigenvector " << *(CurrentEigenvectors[indexiter]) << std::endl));
     const double scalarproduct = (*(CurrentEigenvectors[indexiter])) * (*CurrentEigenvector);
-    Log() << Verbose(2) << "SKP is " << scalarproduct << std::endl;
+    DoLog(2) && (DoLog(2) && (Log() << Verbose(2) << "SKP is " << scalarproduct << std::endl));
     if (fabs(scalarproduct) > mostparallel_scalarproduct) {
       mostparallel_scalarproduct = fabs(scalarproduct);
@@ -308,7 +317,7 @@
     if ((*(CurrentEigenvectors[mostparallel_index])) * (*CurrentEigenvector) < 0) {
       *CurrentEigenvector *= -1.;
-      Log() << Verbose(1) << "Pushing (inverted) " << *CurrentEigenvector << " into parallel list [" << mostparallel_index << "]" << std::endl;
+      DoLog(1) && (Log() << Verbose(1) << "Pushing (inverted) " << *CurrentEigenvector << " into parallel list [" << mostparallel_index << "]" << std::endl);
     } else {
-      Log() << Verbose(1) << "Pushing " << *CurrentEigenvector << " into parallel list [" << mostparallel_index << "]" << std::endl;
+      DoLog(1) && (Log() << Verbose(1) << "Pushing " << *CurrentEigenvector << " into parallel list [" << mostparallel_index << "]" << std::endl);
     }
     ParallelEigenvectorList[mostparallel_index].push_back(make_pair(boost::shared_ptr<VectorContent>(CurrentEigenvector), eigenvalue));
@@ -360,6 +369,6 @@
     for (size_t dim = 0; dim<subspacelimit;++dim) {
       // for every index set of this dimension
-      Log() << Verbose(0) << std::endl << std::endl;
-      Log() << Verbose(0) << "Current dimension is " << dim << std::endl;
+      DoLog(0) && (Log() << Verbose(0) << std::endl << std::endl);
+      DoLog(0) && (Log() << Verbose(0) << "Current dimension is " << dim << std::endl);
       std::pair<IndexMap::const_iterator,IndexMap::const_iterator> Bounds = Dimension_to_Indexset.equal_range(dim);
       for (IndexMap::const_iterator IndexsetIter = Bounds.first;
@@ -367,19 +376,19 @@
           ++IndexsetIter) {
         // show the index set
-        Log() << Verbose(0) << std::endl;
-        Log() << Verbose(1) << "Current index set is " << *(IndexsetIter->second) << std::endl;
+        DoLog(0) && (Log() << Verbose(0) << std::endl);
+        DoLog(1) && (Log() << Verbose(1) << "Current index set is " << *(IndexsetIter->second) << std::endl);
 
         // create transformation matrices from these
         MatrixContent *subsystem = getSubspaceMatrix(*matrix, CurrentEigenvectors, *(IndexsetIter->second));
-        Log() << Verbose(2) << "Subsystem matrix is " << *subsystem << std::endl;
+        DoLog(2) && (Log() << Verbose(2) << "Subsystem matrix is " << *subsystem << std::endl);
 
         // solve _small_ systems for eigenvalues
         VectorContent *Eigenvalues = new VectorContent(subsystem->transformToEigenbasis());
-        Log() << Verbose(2) << "Eigenvector matrix is " << *subsystem << std::endl;
-        Log() << Verbose(2) << "Eigenvalues are " << *Eigenvalues << std::endl;
+        DoLog(2) && (Log() << Verbose(2) << "Eigenvector matrix is " << *subsystem << std::endl);
+        DoLog(2) && (Log() << Verbose(2) << "Eigenvalues are " << *Eigenvalues << std::endl);
 
         // blow up eigenvectors to matrixdimensiondim column vector again
         MatrixContent *Eigenvectors = embedSubspaceMatrix(CurrentEigenvectors, *subsystem, *(IndexsetIter->second));
-        Log() << Verbose(1) << matrixdimension << "x" << matrixdimension << " Eigenvector matrix is " << *Eigenvectors << std::endl;
+        DoLog(1) && (Log() << Verbose(1) << matrixdimension << "x" << matrixdimension << " Eigenvector matrix is " << *Eigenvectors << std::endl);
 
         // we don't need the subsystem anymore
@@ -408,9 +417,9 @@
     // print list of similar eigenvectors
     BOOST_FOREACH( size_t index, AllIndices) {
-      Log() << Verbose(2) << "Similar to " << index << "th current eigenvector " << *(CurrentEigenvectors[index]) << " are:" << std::endl;
+      DoLog(2) && (Log() << Verbose(2) << "Similar to " << index << "th current eigenvector " << *(CurrentEigenvectors[index]) << " are:" << std::endl);
       BOOST_FOREACH( VectorValueList::value_type &iter, ParallelEigenvectorList[index] ) {
-        Log() << Verbose(2) << *(iter.first) << std::endl;
-      }
-      Log() << Verbose(2) << std::endl;
+        DoLog(2) && (Log() << Verbose(2) << *(iter.first) << std::endl);
+      }
+      DoLog(2) && (Log() << Verbose(2) << std::endl);
     }
 
@@ -434,5 +443,5 @@
     // orthonormalize
     if (!dontOrthonormalization) {
-      Log() << Verbose(0) << "Orthonormalizing ... " << std::endl;
+      DoLog(0) && (Log() << Verbose(0) << "Orthonormalizing ... " << std::endl);
       for (IndexSet::const_iterator firstindex = AllIndices.begin();
           firstindex != AllIndices.end();
@@ -456,15 +465,116 @@
 
     // show new ones
-    Log() << Verbose(0) << "Resulting new eigenvectors and -values, run " << run << " are:" << std::endl;
+    DoLog(0) && (Log() << Verbose(0) << "Resulting new eigenvectors and -values, run " << run << " are:" << std::endl);
     BOOST_FOREACH( size_t index, AllIndices) {
-      Log() << Verbose(0) << *CurrentEigenvectors[index] << " with " << CurrentEigenvalues[index] << std::endl;
+      DoLog(0) && (Log() << Verbose(0) << *CurrentEigenvectors[index] << " with " << CurrentEigenvalues[index] << std::endl);
     }
     run++;
   }
 
-
   delete[] ParallelEigenvectorList;
 
   CPPUNIT_ASSERT_EQUAL(0,0);
+}
+
+
+/** Iterative function to generate all power sets of indices of size \a maxelements.
+ *
+ * @param SetofSets Container for all sets
+ * @param CurrentSet pointer to current set in this container
+ * @param Indices Source set of indices
+ * @param maxelements number of elements of each set in final SetofSets
+ * @return true - generation continued, false - current set already had
+ *         \a maxelements elements
+ */
+bool generatePowerSet(
+    SetofIndexSets &SetofSets,
+    SetofIndexSets::iterator &CurrentSet,
+    IndexSet &Indices,
+    const size_t maxelements)
+{
+  if (CurrentSet->size() < maxelements) {
+    // allocate the needed sets
+    const size_t size = Indices.size() - CurrentSet->size();
+    std::vector<std::set<size_t> > SetExpanded;
+    SetExpanded.reserve(size);
+
+    // copy the current set into each
+    for (size_t i=0;i<size;++i)
+      SetExpanded.push_back(*CurrentSet);
+
+    // expand each set by one index
+    size_t localindex=0;
+    BOOST_FOREACH(size_t iter, Indices) {
+      if (CurrentSet->count(iter) == 0) {
+        SetExpanded[localindex].insert(iter);
+        ++localindex;
+      }
+    }
+
+    // insert set at position of CurrentSet
+    for (size_t i=0;i<size;++i) {
+      //DoLog(1) && (Log() << Verbose(1) << "Inserting set #" << i << ": " << SetExpanded[i] << std::endl);
+      SetofSets.insert(CurrentSet, SetExpanded[i]);
+    }
+    SetExpanded.clear();
+
+    // and remove the current set
+    //SetofSets.erase(CurrentSet);
+    //CurrentSet = SetofSets.begin();
+
+    // set iterator to a valid position again
+    ++CurrentSet;
+    return true;
+  } else {
+    return false;
+  }
+}
+
+void SubspaceFactorizerUnittest::generatePowerSetTest()
+{
+  IndexSet AllIndices;
+  for (size_t i=0;i<4;++i)
+    AllIndices.insert(i);
+
+  SetofIndexSets SetofSets;
+  // note that starting off empty set is unstable
+  IndexSet singleset;
+  BOOST_FOREACH(size_t iter, AllIndices) {
+    singleset.insert(iter);
+    SetofSets.insert(singleset);
+    singleset.clear();
+  }
+  SetofIndexSets::iterator CurrentSet = SetofSets.begin();
+  while (CurrentSet != SetofSets.end()) {
+    //DoLog(0) && (Log() << Verbose(0) << "Current set is " << *CurrentSet << std::endl);
+    if (!generatePowerSet(SetofSets, CurrentSet, AllIndices, 2)) {
+      // go to next set
+      ++CurrentSet;
+    }
+  }
+
+  SetofIndexSets ComparisonSet;
+  // now follows a very stupid construction
+  // because we can't use const arrays of some type meaningfully ...
+  { IndexSet tempSet; tempSet.insert(0); ComparisonSet.insert(tempSet); }
+  { IndexSet tempSet; tempSet.insert(1); ComparisonSet.insert(tempSet); }
+  { IndexSet tempSet; tempSet.insert(2); ComparisonSet.insert(tempSet); }
+  { IndexSet tempSet; tempSet.insert(3); ComparisonSet.insert(tempSet); }
+
+  { IndexSet tempSet; tempSet.insert(0); tempSet.insert(1); ComparisonSet.insert(tempSet); }
+  { IndexSet tempSet; tempSet.insert(0); tempSet.insert(2); ComparisonSet.insert(tempSet); }
+  { IndexSet tempSet; tempSet.insert(0); tempSet.insert(3); ComparisonSet.insert(tempSet); }
+
+  { IndexSet tempSet; tempSet.insert(1); tempSet.insert(2); ComparisonSet.insert(tempSet); }
+  { IndexSet tempSet; tempSet.insert(1); tempSet.insert(3); ComparisonSet.insert(tempSet); }
+
+  { IndexSet tempSet; tempSet.insert(2); tempSet.insert(3); ComparisonSet.insert(tempSet); }
+
+  CPPUNIT_ASSERT_EQUAL(SetofSets, ComparisonSet);
+}
+
+bool cmd(double a, double b)
+{
+  return a > b;
 }
 
@@ -474,5 +584,8 @@
   Eigenspace::eigenvalueset CurrentEigenvalues;
 
-  Log() << Verbose(0) << std::endl << std::endl;
+  setVerbosity(0);
+
+  boost::timer Time_generatingfullspace;
+  DoLog(0) && (Log() << Verbose(0) << std::endl << std::endl);
   // create the total index set
   IndexSet AllIndices;
@@ -480,5 +593,6 @@
     AllIndices.insert(i);
   Eigenspace FullSpace(AllIndices, *matrix);
-  Log() << Verbose(1) << "Generated full space: " << FullSpace << std::endl;
+  DoLog(1) && (Log() << Verbose(1) << "Generated full space: " << FullSpace << std::endl);
+  DoLog(0) && (Log() << Verbose(0) << "Full space generation took " << Time_generatingfullspace.elapsed() << " seconds." << std::endl);
 
   // generate first set of eigenvectors
@@ -492,45 +606,72 @@
   }
 
-  Log() << Verbose(1) << "Generating sub spaces ..." << std::endl;
-  // create all consecutive index subsets for dim 1 to 3
+  boost::timer Time_generatingsubsets;
+  DoLog(0) && (Log() << Verbose(0) << "Generating sub sets ..." << std::endl);
+  SetofIndexSets SetofSets;
+  // note that starting off empty set is unstable
+  IndexSet singleset;
+  BOOST_FOREACH(size_t iter, AllIndices) {
+    singleset.insert(iter);
+    SetofSets.insert(singleset);
+    singleset.clear();
+  }
+  SetofIndexSets::iterator CurrentSet = SetofSets.begin();
+  while (CurrentSet != SetofSets.end()) {
+    //DoLog(2) && (Log() << Verbose(2) << "Current set is " << *CurrentSet << std::endl);
+    if (!generatePowerSet(SetofSets, CurrentSet, AllIndices, subspacelimit)) {
+      // go to next set
+      ++CurrentSet;
+    }
+  }
+  DoLog(0) && (Log() << Verbose(0) << "Sub set generation took " << Time_generatingsubsets.elapsed() << " seconds." << std::endl);
+
+  // create a subspace to each set and and to respective level
+  boost::timer Time_generatingsubspaces;
+  DoLog(0) && (Log() << Verbose(0) << "Generating sub spaces ..." << std::endl);
   SubspaceMap Dimension_to_Indexset;
-  for (size_t dim = 0; dim<3;++dim) {
-    for (size_t i=0;i<matrixdimension;++i) {
-      IndexSet *indexset = new IndexSet;
-      for (size_t j=0;j<dim+1;++j) {
-        const int value = (i+j) % matrixdimension;
-        //std::cout << "Putting " << value << " into " << i << "th map " << dim << std::endl;
-        CPPUNIT_ASSERT_MESSAGE("index "+toString(value)+" already present in "+toString(dim)+"-dim "+toString(i)+"th indexset.", indexset->count(value) == 0);
-        indexset->insert(value);
-      }
-      boost::shared_ptr<Subspace> subspace(new Subspace(*indexset, FullSpace));
-      Log() << Verbose(1) << "Current subspace is " << *subspace << std::endl;
-      Dimension_to_Indexset.insert( make_pair(dim, boost::shared_ptr<Subspace>(subspace)) );
-      delete(indexset);
-
-      // for through next lower subspace list and add to subspaces if contained.
-      if (dim != 0) {
-        Log() << Verbose(1) << "Going through subspace list in dim " << dim-1 << "." << std::endl;
+  BOOST_FOREACH(std::set<size_t> iter, SetofSets) {
+    boost::shared_ptr<Subspace> subspace(new Subspace(iter, FullSpace));
+    DoLog(1) && (Log() << Verbose(1) << "Current subspace is " << *subspace << std::endl);
+    Dimension_to_Indexset.insert( make_pair(iter.size(), boost::shared_ptr<Subspace>(subspace)) );
+  }
+
+  for (size_t dim = 1; dim<=subspacelimit;++dim) {
+    BOOST_FOREACH( SubspaceMap::value_type subspace, Dimension_to_Indexset.equal_range(dim)) {
+      if (dim != 0) { // from level 1 and onward
         BOOST_FOREACH( SubspaceMap::value_type entry, Dimension_to_Indexset.equal_range(dim-1)) {
-          if (subspace->contains(*entry.second)) {
-            Log() << Verbose(2) << "Adding " << *(entry.second) << " to list of contained subspaces." << std::endl;
-            subspace->addSubset(entry.second);
+          if (subspace.second->contains(*entry.second)) {
+            // if contained then add ...
+            subspace.second->addSubset(entry.second);
+            // ... and also its containees as they are all automatically contained as well
+            BOOST_FOREACH(boost::shared_ptr<Subspace> iter, entry.second->SubIndices) {
+              subspace.second->addSubset(iter);
+            }
           }
         }
-      } else {
-        Log() << Verbose(2) << "Subspace with dimension of 1 cannot contain other subspaces." << std::endl;
-      }
-
-     }
-  }
-
+      }
+    }
+  }
+  DoLog(0) && (Log() << Verbose(0) << "Sub space generation took " << Time_generatingsubspaces.elapsed() << " seconds." << std::endl);
+
+  // create a file handle for the eigenvalues
+  std::ofstream outputvalues("eigenvalues.dat", std::ios_base::trunc);
+  ASSERT(outputvalues.good(),
+      "SubspaceFactorizerUnittest::EigenvectorTest() - failed to open eigenvalue file!");
+  outputvalues << "# iteration ";
+  BOOST_FOREACH(size_t iter, AllIndices) {
+    outputvalues << "\teigenvalue" << iter;
+  }
+  outputvalues << std::endl;
+
+  DoLog(0) && (Log() << Verbose(0) << "Solving ..." << std::endl);
+  boost::timer Time_solving;
   size_t run=1; // counting iterations
   double threshold = 1.;  // containing threshold value
-  while ((threshold > 1e-10) && (run < 10)) {
+  while ((threshold > MYEPSILON) && (run < 20)) {
     // for every dimension
-    for (size_t dim = 0; dim< subspacelimit;++dim) {
+    for (size_t dim = 1; dim <= subspacelimit;++dim) {
       // for every index set of this dimension
-      Log() << Verbose(0) << std::endl << std::endl;
-      Log() << Verbose(0) << "Current dimension is " << dim << std::endl;
+      DoLog(1) && (Log() << Verbose(1) << std::endl << std::endl);
+      DoLog(1) && (Log() << Verbose(1) << "Current dimension is " << dim << std::endl);
       std::pair<SubspaceMap::const_iterator,SubspaceMap::const_iterator> Bounds = Dimension_to_Indexset.equal_range(dim);
       for (SubspaceMap::const_iterator IndexsetIter = Bounds.first;
@@ -539,6 +680,6 @@
         Subspace& subspace = *(IndexsetIter->second);
         // show the index set
-        Log() << Verbose(0) << std::endl;
-        Log() << Verbose(1) << "Current subspace is " << subspace << std::endl;
+        DoLog(2) && (Log() << Verbose(2) << std::endl);
+        DoLog(2) && (Log() << Verbose(2) << "Current subspace is " << subspace << std::endl);
 
         // solve
@@ -550,12 +691,16 @@
 
     // print list of similar eigenvectors
+    DoLog(2) && (Log() << Verbose(2) << std::endl);
     BOOST_FOREACH( size_t index, AllIndices) {
-      Log() << Verbose(2) << "Similar to " << index << "th current eigenvector " << *(CurrentEigenvectors[index]) << " are:" << std::endl;
+      DoLog(2) && (Log() << Verbose(2) << "Similar to " << index << "th current eigenvector " << *(CurrentEigenvectors[index]) << " are:" << std::endl);
       BOOST_FOREACH( SubspaceMap::value_type iter, Dimension_to_Indexset) {
         const VectorContent & CurrentEV = (iter.second)->getEigenvectorParallelToFullOne(index);
         if (!CurrentEV.IsZero())
-          Log() << Verbose(2) << CurrentEV << std::endl;
-      }
-      Log() << Verbose(2) << std::endl;
+          Log() << Verbose(2)
+          << "dim" << iter.first
+          << ", subspace{" << (iter.second)->getIndices()
+          << "}: "<<CurrentEV << std::endl;
+      }
+      DoLog(2) && (Log() << Verbose(2) << std::endl);
     }
 
@@ -567,5 +712,5 @@
       BOOST_FOREACH( SubspaceMap::value_type iter, Dimension_to_Indexset) {
         const VectorContent CurrentEV = (iter.second)->getEigenvectorParallelToFullOne(index);
-        *CurrentEigenvectors[index] += CurrentEV * (iter.second)->getEigenvalueOfEigenvectorParallelToFullOne(index);
+        *CurrentEigenvectors[index] += CurrentEV; // * (iter.second)->getEigenvalueOfEigenvectorParallelToFullOne(index);
         CurrentEigenvalues[index] += (iter.second)->getEigenvalueOfEigenvectorParallelToFullOne(index);
         if (!CurrentEV.IsZero())
@@ -573,5 +718,5 @@
       }
       *CurrentEigenvectors[index] *= 1./CurrentEigenvalues[index];
-      CurrentEigenvalues[index] /= (double)count;
+      //CurrentEigenvalues[index] /= (double)count;
     }
 
@@ -582,5 +727,5 @@
     // orthonormalize
     if (!dontOrthonormalization) {
-      Log() << Verbose(0) << "Orthonormalizing ... " << std::endl;
+      DoLog(1) && (Log() << Verbose(1) << "Orthonormalizing ... " << std::endl);
       for (IndexSet::const_iterator firstindex = AllIndices.begin();
           firstindex != AllIndices.end();
@@ -607,11 +752,43 @@
 
     // show new ones
-    Log() << Verbose(0) << "Resulting new eigenvectors and -values, run " << run << " are:" << std::endl;
+    DoLog(1) && (Log() << Verbose(1) << "Resulting new eigenvectors and -values, run " << run << " are:" << std::endl);
+    outputvalues << run;
     BOOST_FOREACH( size_t index, AllIndices) {
-      Log() << Verbose(0) << *CurrentEigenvectors[index] << " with " << CurrentEigenvalues[index] << std::endl;
-    }
+      DoLog(1) && (Log() << Verbose(1) << *CurrentEigenvectors[index] << " with " << CurrentEigenvalues[index] << std::endl);
+      outputvalues << "\t" << CurrentEigenvalues[index];
+    }
+    outputvalues << std::endl;
+
+    // and next iteration
+    DoLog(0) && (Log() << Verbose(0) << "\titeration #" << run << std::endl);
     run++;
   }
-
+  DoLog(0) && (Log() << Verbose(0) << "Solving took " << Time_solving.elapsed() << " seconds." << std::endl);
+  // show final ones
+  DoLog(0) && (Log() << Verbose(0) << "Resulting new eigenvectors and -values, run " << run << " are:" << std::endl);
+  outputvalues << run;
+  BOOST_FOREACH( size_t index, AllIndices) {
+    DoLog(0) && (Log() << Verbose(0) << *CurrentEigenvectors[index] << " with " << CurrentEigenvalues[index] << std::endl);
+    outputvalues << "\t" << CurrentEigenvalues[index];
+  }
+  outputvalues << std::endl;
+  outputvalues.close();
+
+  setVerbosity(2);
+
+  DoLog(0) && (Log() << Verbose(0) << "Solving full space ..." << std::endl);
+  boost::timer Time_comparison;
+  MatrixContent tempFullspaceMatrix = FullSpace.getEigenspaceMatrix();
+  gsl_vector *eigenvalues = tempFullspaceMatrix.transformToEigenbasis();
+  tempFullspaceMatrix.sortEigenbasis(eigenvalues);
+  DoLog(0) && (Log() << Verbose(0) << "full space solution took " << Time_comparison.elapsed() << " seconds." << std::endl);
+
+  // compare all
+  sort(CurrentEigenvalues.begin(),CurrentEigenvalues.end()); //, cmd);
+  for (size_t i=0;i<eigenvalues->size; ++i) {
+    CPPUNIT_ASSERT_MESSAGE(toString(i)+"ths eigenvalue differs:"
+        +toString(CurrentEigenvalues[i])+" != "+toString(gsl_vector_get(eigenvalues,i)),
+        fabs((CurrentEigenvalues[i] - gsl_vector_get(eigenvalues,i))/CurrentEigenvalues[i]) < 1e-3);
+  }
 
   CPPUNIT_ASSERT_EQUAL(0,0);
Index: src/unittests/SubspaceFactorizerUnittest.hpp
===================================================================
--- src/unittests/SubspaceFactorizerUnittest.hpp	(revision 1fb318e13ebc1029d5ba1a68d3b01c62237ab05b)
+++ src/unittests/SubspaceFactorizerUnittest.hpp	(revision e828c07cc83828399b494f75295e73daf5ad0852)
@@ -15,4 +15,5 @@
 class Subspace;
 
+typedef std::set<std::set<size_t> > SetofIndexSets;
 typedef std::set<size_t> IndexSet;
 typedef std::multimap< size_t, boost::shared_ptr<Subspace> > SubspaceMap;
@@ -27,5 +28,6 @@
   CPPUNIT_TEST_SUITE( SubspaceFactorizerUnittest) ;
   CPPUNIT_TEST ( BlockTest );
-  CPPUNIT_TEST ( EigenvectorTest );
+  //CPPUNIT_TEST ( EigenvectorTest );
+  CPPUNIT_TEST ( generatePowerSetTest );
   CPPUNIT_TEST ( SubspaceTest );
   CPPUNIT_TEST_SUITE_END();
@@ -37,8 +39,9 @@
   void BlockTest();
   void EigenvectorTest();
+  void generatePowerSetTest();
   void SubspaceTest();
 
-  enum { matrixdimension = 3 };
-  enum { subspacelimit = 2 };
+  enum { matrixdimension = 4 };
+  enum { subspacelimit = 3 };
 private:
 
