Index: src/LinearAlgebra/Subspace.cpp
===================================================================
--- src/LinearAlgebra/Subspace.cpp	(revision a06042e843c266378c28a07d857634215eb6f8b9)
+++ src/LinearAlgebra/Subspace.cpp	(revision 286af5fb9ad803eaed15af491597fbf6b924d817)
@@ -25,8 +25,10 @@
 #include "Helpers/Assert.hpp"
 #include "Helpers/Log.hpp"
+#include "Helpers/toString.hpp"
 #include "Helpers/Verbose.hpp"
 
 #include "Eigenspace.hpp"
 #include "Subspace.hpp"
+
 
 /** Constructor for class Subspace.
@@ -39,6 +41,8 @@
   ProjectToSubspace(_FullSpace.getIndices().size(), _s.size()),
   ProjectFromSubspace(_s.size(), _FullSpace.getIndices().size()),
-  FullSpace(_FullSpace)
-{
+  FullSpace(_FullSpace),
+  ZeroVector(_FullSpace.getIndices().size())
+{
+  // TODO: away with both of this when calculateEigenSubspace() works
   // create projection matrices
   createProjectionMatrices();
@@ -62,5 +66,21 @@
 void Subspace::calculateEigenSubspace()
 {
-  getSubspacematrixFromBigmatrix(FullSpace.getEigenspaceMatrix());
+  // project down
+  createProjectionMatrices();
+  // remove subsubspace directions
+  correctEigenvectorsFromSubIndices();
+  // solve
+  projectFullSpaceMatrixToSubspace();
+  EigenvectorMatrix = EigenspaceMatrix;
+  VectorContent *EigenvalueVector = new VectorContent(EigenvectorMatrix.transformToEigenbasis());
+  Eigenvalues.clear();
+  for(size_t i = 0; i< EigenvalueVector->getDimension(); ++i) {
+    Eigenvalues.push_back( EigenvalueVector->at(i) );
+  }
+  delete EigenvalueVector;
+  Log() << Verbose(2) << "Eigenvector matrix is " << EigenvectorMatrix << std::endl;
+  Log() << Verbose(2) << "Eigenvalues are " << Eigenvalues << std::endl;
+  // create mapping
+  createLocalMapping();
 }
 
@@ -126,5 +146,5 @@
  * @return set of projected eigenvectors.
  */
-Eigenspace::eigenvectorset Subspace::getEigenvectorsInFullSpace()
+const Eigenspace::eigenvectorset & Subspace::getEigenvectorsInFullSpace()
 {
   // check whether bigmatrix is at least as big as EigenspaceMatrix
@@ -213,7 +233,51 @@
  * @return set of eigenvectors in subspace
  */
-Eigenspace::eigenvectorset Subspace::getEigenvectorsInSubspace()
-{
-  return Eigenvectors;
+const MatrixContent & Subspace::getEigenvectorMatrixInFullSpace()
+{
+  // check whether bigmatrix is at least as big as EigenspaceMatrix
+  ASSERT(EigenspaceMatrix.getRows() <= Eigenvectors[0]->getDimension(),
+      "embedEigenspaceMatrix() - EigenspaceMatrix has more rows "
+      +toString(EigenspaceMatrix.getRows())+" than eigenvectors "
+      +toString(Eigenvectors[0]->getDimension())+"!");
+  ASSERT(EigenspaceMatrix.getColumns() <= Eigenvectors.size(),
+      "embedEigenspaceMatrix() - EigenspaceMatrix has more columns "
+      +toString(EigenspaceMatrix.getColumns())+" than eigenvectors "
+      +toString(Eigenvectors.size())+"!");
+  // check whether EigenspaceMatrix is big enough for both index sets
+  ASSERT(EigenspaceMatrix.getColumns() == EigenspaceMatrix.getRows(),
+      "embedEigenspaceMatrix() - EigenspaceMatrix is not square "
+      +toString(EigenspaceMatrix.getRows())+" than needed by index set "
+      +toString(EigenspaceMatrix.getColumns())+"!");
+  ASSERT(Indices.size() == EigenspaceMatrix.getColumns(),
+      "embedEigenspaceMatrix() - EigenspaceMatrix has not the same number of columns "
+      +toString(EigenspaceMatrix.getColumns())+" compared to the index set "
+      +toString(Indices.size())+"!");
+
+  // 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++;
+  }
+
+  return *bigmatrix;
 }
 
@@ -258,2 +322,87 @@
   Log() << Verbose(2) << "EigenspaceMatrix matrix is " << EigenspaceMatrix << std::endl;
 }
+
+
+/** We associate local Eigenvectors with ones from FullSpace by a paralellity
+ * criterion.
+ */
+void Subspace::createLocalMapping()
+{
+  // first LocalToGlobal
+  LocalToGlobal.clear();
+  IndexSet CorrespondenceList(Indices); // is to ensure one-to-one mapping
+
+  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;
+
+    // (for now settle with the one we are most parallel to)
+    size_t mostparallel_index = FullSpace.getIndices().size();
+    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;
+      if (fabs(scalarproduct) > fabs(mostparallel_scalarproduct)) {
+        mostparallel_scalarproduct = scalarproduct;
+        mostparallel_index = indexiter;
+      }
+    }
+    // and make the assignment if we found one
+    if (mostparallel_index != FullSpace.getIndices().size()) {
+      // put into std::list for later use
+      // invert if pointing in negative direction
+      if (mostparallel_scalarproduct < 0) {
+        *CurrentEigenvector *= -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;
+      }
+      ASSERT( LocalToGlobal.count(localindex) == 0,
+          "Subspace::createLocalMapping() - localindex "+toString(localindex)+" already assigned to "
+          +toString(LocalToGlobal[localindex])+" !=? "+toString(mostparallel_index)+".");
+      LocalToGlobal.insert( make_pair(localindex, mostparallel_index) );
+      CorrespondenceList.erase(mostparallel_index);
+    }
+  }
+
+  // then invert mapping
+  GlobalToLocal.clear();
+  BOOST_FOREACH(mapping::value_type iter, LocalToGlobal) {
+    ASSERT(GlobalToLocal.count(iter.second) == 0,
+        "Subspace::createLocalMapping() - LocalToGlobal is not bijective, key "
+        +toString(iter.second)+" present more than once!");
+    GlobalToLocal.insert( make_pair(iter.second, iter.first) );
+  }
+}
+
+
+/** Get the local eigenvector that is most parallel to the \a i'th full one.
+ * We just the internal mapping Subspace::GlobalToLocal.
+ * @param i index of global eigenvector
+ * @return local eigenvector, most parallel
+ */
+const VectorContent Subspace::getEigenvectorParallelToFullOne(size_t i)
+{
+  if (GlobalToLocal.count(i) == 0) {
+    return ZeroVector;
+  } else {
+    return ProjectToSubspace*(*Eigenvectors[GlobalToLocal[i]]);
+  }
+}
+
+
+/** Get the local eigenvalue of the eigenvector that is most parallel to the
+ * \a i'th full one.
+ * We just the internal mapping Subspace::GlobalToLocal.
+ * @param i index of global eigenvector
+ * @return eigenvalue of local eigenvector, most parallel
+ */
+const double Subspace::getEigenvalueOfEigenvectorParallelToFullOne(size_t i)
+{
+  if (GlobalToLocal.count(i) == 0) {
+    return 0.;
+  } else {
+    return Eigenvalues[GlobalToLocal[i]];
+  }
+}
