/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2010-2012 University of Bonn. All rights reserved. * Please see the LICENSE file or "Copyright notice" in builder.cpp for details. */ /* * MatrixContainer.cpp * * Created on: Sep 15, 2011 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "CodePatterns/MemDebug.hpp" #include #include #include #include "CodePatterns/Log.hpp" #include "KeySetsContainer.hpp" #include "Fragmentation/helpers.hpp" #include "Helpers/defs.hpp" #include "Helpers/helpers.hpp" #include "MatrixContainer.hpp" /** Constructor of MatrixContainer class. */ MatrixContainer::MatrixContainer() { Header.resize(1); RowCounter.resize(1); ColumnCounter.resize(1); ColumnCounter[0] = -1; MatrixCounter = 0; }; /** Destructor of MatrixContainer class. */ MatrixContainer::~MatrixContainer() {} /** Either copies index matrix from another MatrixContainer or initialises with trivial mapping if NULL. * This either copies the index matrix or just maps 1 to 1, 2 to 2 and so on for all fragments. * \param *Matrix pointer to other MatrixContainer * \return true - copy/initialisation sucessful, false - dimension false for copying */ bool MatrixContainer::InitialiseIndices(class MatrixContainer *_container) { if (_container == NULL) { LOG(3, "INFO: Initialising indices with trivial mapping."); Indices.resize(MatrixCounter + 1); for(int i=MatrixCounter+1;i--;) { Indices[i].resize(RowCounter[i]); for(int j=RowCounter[i];j--;) Indices[i][j] = j; } } else { std::stringstream output; if (MatrixCounter != _container->MatrixCounter) return false; Indices.resize(MatrixCounter + 1); for(int i=MatrixCounter+1;i--;) { if (RowCounter[i] != _container->RowCounter[i]) return false; Indices[i].resize(_container->RowCounter[i]); for(int j=_container->RowCounter[i];j--;) { Indices[i][j] = _container->Indices[i][j]; output << Indices[i][j] << "\t"; } } LOG(3, "INFO: Initialising indices from other MatrixContainer: " << output.str()); } return true; }; /** Parsing a number of matrices. * -# open the matrix file * -# skip some lines (\a skiplines) * -# scan header lines for number of columns * -# scan lines for number of rows * -# allocate a temporary matrix * -# loop over found column and row counts and parse in each entry * -# use MatrixContainer::AddMatrix() to add the parsed matrix to the internal * \param &input input stream * \param skiplines number of inital lines to skip * \param skiplines number of inital columns to skip * \param MatrixNr index number in Matrix array to parse into * \return parsing successful */ bool MatrixContainer::ParseMatrix(std::istream &input, int skiplines, int skipcolumns, size_t MatrixNr) { stringstream line; string token; char filename[1023]; if (input.fail()) { ELOG(1, endl << "MatrixContainer::ParseMatrix: Unable to parse istream."); //performCriticalExit(); return false; } // parse header std::string header; char dummy[1024]; for (int m=skiplines+1;m--;) input.getline(dummy, 1023); line.str(dummy); for(int k=skipcolumns;k--;) line >> header; LOG(3, "INFO: Header of Matrix " << MatrixNr << " :" << line.str()); // scan header for number of columns size_t ColumnCounter = 0; while ( getline(line,token, '\t') ) { if (token.length() > 0) ColumnCounter++; } LOG(3, "INFO: "+line.str()); // scan rest for number of rows/lines size_t RowCounter = -1; while (!input.eof()) { input.getline(filename, 1023); LOG(3, "INFO: Comparing: " << strncmp(filename,"MeanForce",9)); RowCounter++; // then line was not last MeanForce if (strncmp(filename,"MeanForce", 9) == 0) { break; } } // allocate temporary matrix MatrixArray temp_matrix; temp_matrix.resize(RowCounter); for(MatrixArray::iterator iter = temp_matrix.begin(); iter != temp_matrix.end(); ++iter) (*iter).resize(ColumnCounter); // parse in each entry for this matrix input.clear(); input.seekg(ios::beg); for (int m=skiplines+1;m--;) input.getline(dummy, 1023); // skip header line.str(dummy); LOG(3, "INFO: Header: " << line.str()); for(int k=skipcolumns;k--;) // skip columns in header too line >> filename; header = line.str(); for(size_t j=0;j> filename; for(size_t k=0;(k> temp_matrix[j][k]; output << " " << std::setprecision(2) << temp_matrix[j][k] << endl; } LOG(3, output.str()); } // finally add the matrix return AddMatrix(header, temp_matrix, MatrixNr); } /** Adds a matrix at position \a MatrixNr to MatrixContainer::Matrix. * * @param header header to add for this matrix * @param matrix to add * @param MatrixNr position in MatrixContainer::Matrix. * @return true - insertion ok, false - invalid matrix */ bool MatrixContainer::AddMatrix(const std::string &header, const MatrixArray &matrix, size_t MatrixNr) { // make some pre-checks if (header.size() == 0) ELOG(2, "The given header of the matrix to add is empty."); if (matrix.size() == 0) { ELOG(1, "RowCounter[" << MatrixNr << "]: " << RowCounter[MatrixNr] << " from input stream."); return false; } if (matrix[0].size() == 0) { ELOG(1, "ColumnCounter[" << MatrixNr << "]: " << ColumnCounter[MatrixNr] << " from ostream."); return false; } // add header if (Header.size() <= MatrixNr) Header.resize(MatrixNr+1); Header[MatrixNr] = header; // row count if (RowCounter.size() <= MatrixNr) RowCounter.resize(MatrixNr+1); RowCounter[MatrixNr] = matrix.size(); LOG(4, "INFO: RowCounter[" << MatrixNr << "]: " << RowCounter[MatrixNr] << " from input stream."); // column count if (ColumnCounter.size() <= MatrixNr) ColumnCounter.resize(MatrixNr+1); ColumnCounter[MatrixNr] = matrix[0].size(); LOG(4, "INFO: ColumnCounter[" << MatrixNr << "]: " << ColumnCounter[MatrixNr] << "."); // allocate matrix ... if (Matrix.size() <= MatrixNr) Matrix.resize(MatrixNr+1); MatrixCounter = Matrix.size()-1; Matrix[MatrixNr].resize(RowCounter[MatrixNr] + 1); for(int j=0;j<=RowCounter[MatrixNr];++j) Matrix[MatrixNr][j].resize(ColumnCounter[MatrixNr]+1); // .. and copy values for(int j=0;j max) max = fabs(Matrix[i][j][k]); if (fabs(max) < MYEPSILON) max += MYEPSILON; return max; }; /** Scans all elements of MatrixContainer::Matrix for smallest absolute value. * \return smallest value of MatrixContainer::Matrix */ double MatrixContainer::FindMinValue() { double min = Matrix[0][0][0]; for(int i=MatrixCounter+1;i--;) for(int j=RowCounter[i]+1;j--;) for(int k=ColumnCounter[i];k--;) if (fabs(Matrix[i][j][k]) < min) min = fabs(Matrix[i][j][k]); if (fabs(min) < MYEPSILON) min += MYEPSILON; return min; }; /** Sets all values in the last of MatrixContainer::Matrix to \a value. * \param value reset value * \param skipcolumns skip initial columns * \return true if successful */ bool MatrixContainer::SetLastMatrix(double value, int skipcolumns) { for(int j=RowCounter[MatrixCounter]+1;j--;) for(int k=skipcolumns;k RowCounter[ KeySets.OrderSet[Order][CurrentFragment] ]) { ELOG(0, "In fragment No. " << KeySets.OrderSet[Order][CurrentFragment] << " current force index " << m << " is greater than " << RowCounter[ KeySets.OrderSet[Order][CurrentFragment] ] << "!"); performCriticalExit(); return false; } if (Order == SubOrder) { // equal order is always copy from Energies for(int l=ColumnCounter[ KeySets.OrderSet[SubOrder][j] ];l--;) // then adds/subtract each column Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][m][l] += MatrixValues.Matrix[ KeySets.OrderSet[SubOrder][j] ][k][l]; } else { for(int l=ColumnCounter[ KeySets.OrderSet[SubOrder][j] ];l--;) Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][m][l] -= Matrix[ KeySets.OrderSet[SubOrder][j] ][k][l]; } } //if ((ColumnCounter[ KeySets.OrderSet[SubOrder][j] ]>1) && (RowCounter[0]-1 >= 1)) //LOG(0, "Fragments[ KeySets.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySets.OrderSet[Order][CurrentFragment] << " ][" << RowCounter[0]-1 << "][" << 1 << "] = " << Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][RowCounter[0]-1][1]); } } else { //LOG(0, "Fragment " << KeySets.OrderSet[SubOrder][j] << " is not contained in fragment " << KeySets.OrderSet[Order][CurrentFragment] << "."); } } } //LOG(0, "Final Fragments[ KeySets.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySets.OrderSet[Order][CurrentFragment] << " ][" << KeySets.AtomCounter[0]-1 << "][" << 1 << "] = " << Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][KeySets.AtomCounter[0]-1][1]); } return true; }; /** Writes the summed total fragment terms \f$F_{ij}\f$ to file. * \param *name inputdir * \param *prefix prefix before \a EnergySuffix * \return file was written */ bool MatrixContainer::WriteTotalFragments(const std::string name, const std::string prefix) { ofstream output; char *FragmentNumber = NULL; LOG(1, "STATUS: Writing fragment files."); for(int i=0;i