source: src/Fragmentation/MatrixContainer.cpp@ 33a694

Action_Thermostats Add_AtomRandomPerturbation Add_RotateAroundBondAction Add_SelectAtomByNameAction Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests AutomationFragmentation_failures Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator Docu_Python_wait EmpiricalPotential_contain_HomologyGraph_documentation Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph Fix_ChronosMutex Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion GeometryObjects Gui_displays_atomic_force_velocity IndependentFragmentGrids_IntegrationTest JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks RotateToPrincipalAxisSystem_UndoRedo StoppableMakroAction TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps Ubuntu_1604_changes
Last change on this file since 33a694 was 9eb71b3, checked in by Frederik Heber <frederik.heber@…>, 8 years ago

Commented out MemDebug include and Memory::ignore.

  • MemDebug clashes with various allocation operators that use a specific placement in memory. It is so far not possible to wrap new/delete fully. Hence, we stop this effort which so far has forced us to put ever more includes (with clashes) into MemDebug and thereby bloat compilation time.
  • MemDebug does not add that much usefulness which is not also provided by valgrind.
  • Property mode set to 100644
File size: 20.2 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
5 *
6 *
7 * This file is part of MoleCuilder.
8 *
9 * MoleCuilder is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * MoleCuilder is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/*
24 * MatrixContainer.cpp
25 *
26 * Created on: Sep 15, 2011
27 * Author: heber
28 */
29
30// include config.h
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34
35//#include "CodePatterns/MemDebug.hpp"
36
37#include <cstring>
38#include <fstream>
39#include <iomanip>
40
41#include "CodePatterns/Log.hpp"
42#include "KeySetsContainer.hpp"
43
44#include "Fragmentation/helpers.hpp"
45#include "Helpers/defs.hpp"
46#include "Helpers/helpers.hpp"
47
48#include "MatrixContainer.hpp"
49
50/** Constructor of MatrixContainer class.
51 */
52MatrixContainer::MatrixContainer()
53{
54 Header.resize(1);
55 RowCounter.resize(1);
56 ColumnCounter.resize(1);
57 ColumnCounter[0] = -1;
58 MatrixCounter = 0;
59};
60
61/** Destructor of MatrixContainer class.
62 */
63MatrixContainer::~MatrixContainer()
64{}
65
66/** Either copies index matrix from another MatrixContainer or initialises with trivial mapping if NULL.
67 * This either copies the index matrix or just maps 1 to 1, 2 to 2 and so on for all fragments.
68 * \param *Matrix pointer to other MatrixContainer
69 * \return true - copy/initialisation sucessful, false - dimension false for copying
70 */
71bool MatrixContainer::InitialiseIndices(class MatrixContainer *_container)
72{
73 if (_container == NULL) {
74 LOG(3, "INFO: Initialising indices with trivial mapping.");
75 Indices.resize(MatrixCounter + 1);
76 for(int i=MatrixCounter+1;i--;) {
77 Indices[i].resize(RowCounter[i]);
78 for(int j=RowCounter[i];j--;)
79 Indices[i][j] = j;
80 }
81 } else {
82 std::stringstream output;
83 if (MatrixCounter != _container->MatrixCounter)
84 return false;
85 Indices.resize(MatrixCounter + 1);
86 for(int i=MatrixCounter+1;i--;) {
87 if (RowCounter[i] != _container->RowCounter[i])
88 return false;
89 Indices[i].resize(_container->RowCounter[i]);
90 for(int j=_container->RowCounter[i];j--;) {
91 Indices[i][j] = _container->Indices[i][j];
92 output << Indices[i][j] << "\t";
93 }
94 }
95 LOG(3, "INFO: Initialising indices from other MatrixContainer: " << output.str());
96 }
97 return true;
98};
99
100/** Parsing a number of matrices.
101 * -# open the matrix file
102 * -# skip some lines (\a skiplines)
103 * -# scan header lines for number of columns
104 * -# scan lines for number of rows
105 * -# allocate a temporary matrix
106 * -# loop over found column and row counts and parse in each entry
107 * -# use MatrixContainer::AddMatrix() to add the parsed matrix to the internal
108 * \param &input input stream
109 * \param skiplines number of inital lines to skip
110 * \param skiplines number of inital columns to skip
111 * \param MatrixNr index number in Matrix array to parse into
112 * \return parsing successful
113 */
114bool MatrixContainer::ParseMatrix(std::istream &input, int skiplines, int skipcolumns, size_t MatrixNr)
115{
116 stringstream line;
117 string token;
118 char filename[1023];
119
120 if (input.fail()) {
121 ELOG(1, endl << "MatrixContainer::ParseMatrix: Unable to parse istream.");
122 //performCriticalExit();
123 return false;
124 }
125
126 // parse header
127 std::string header;
128 char dummy[1024];
129 for (int m=skiplines+1;m--;)
130 input.getline(dummy, 1023);
131 line.str(dummy);
132 for(int k=skipcolumns;k--;)
133 line >> header;
134 LOG(3, "INFO: Header of Matrix " << MatrixNr << " :" << line.str());
135
136 // scan header for number of columns
137 size_t ColumnCounter = 0;
138 while ( getline(line,token, '\t') ) {
139 if (token.length() > 0)
140 ColumnCounter++;
141 }
142 LOG(3, "INFO: "+line.str());
143
144 // scan rest for number of rows/lines
145 size_t RowCounter = -1;
146 while (!input.eof()) {
147 input.getline(filename, 1023);
148 LOG(3, "INFO: Comparing: " << strncmp(filename,"MeanForce",9));
149 RowCounter++; // then line was not last MeanForce
150 if (strncmp(filename,"MeanForce", 9) == 0) {
151 break;
152 }
153 }
154
155 // allocate temporary matrix
156 MatrixArray temp_matrix;
157 temp_matrix.resize(RowCounter);
158 for(MatrixArray::iterator iter = temp_matrix.begin(); iter != temp_matrix.end(); ++iter)
159 (*iter).resize(ColumnCounter);
160
161 // parse in each entry for this matrix
162 input.clear();
163 input.seekg(ios::beg);
164 for (int m=skiplines+1;m--;)
165 input.getline(dummy, 1023); // skip header
166 line.str(dummy);
167 LOG(3, "INFO: Header: " << line.str());
168 for(int k=skipcolumns;k--;) // skip columns in header too
169 line >> filename;
170 header = line.str();
171 for(size_t j=0;j<RowCounter;j++) {
172 input.getline(filename, 1023);
173 std::stringstream lines(filename);
174 std::stringstream output;
175 output << "INFO: Matrix at level " << j << ":";// << filename << endl;
176 for(int k=skipcolumns;k--;)
177 lines >> filename;
178 for(size_t k=0;(k<ColumnCounter) && (!lines.eof());k++) {
179 lines >> temp_matrix[j][k];
180 output << " " << std::setprecision(2) << temp_matrix[j][k] << endl;
181 }
182 LOG(3, output.str());
183 }
184
185 // finally add the matrix
186 return AddMatrix(header, temp_matrix, MatrixNr);
187}
188
189/** Adds a matrix at position \a MatrixNr to MatrixContainer::Matrix.
190 *
191 * @param header header to add for this matrix
192 * @param matrix to add
193 * @param MatrixNr position in MatrixContainer::Matrix.
194 * @return true - insertion ok, false - invalid matrix
195 */
196bool MatrixContainer::AddMatrix(const std::string &header, const MatrixArray &matrix, size_t MatrixNr)
197{
198 // make some pre-checks
199 if (header.size() == 0)
200 ELOG(2, "The given header of the matrix to add is empty.");
201 if (matrix.size() == 0) {
202 ELOG(1, "RowCounter[" << MatrixNr << "]: " << RowCounter[MatrixNr] << " from input stream.");
203 return false;
204 }
205 if (matrix[0].size() == 0) {
206 ELOG(1, "ColumnCounter[" << MatrixNr << "]: " << ColumnCounter[MatrixNr] << " from ostream.");
207 return false;
208 }
209
210 // add header
211 if (Header.size() <= MatrixNr)
212 Header.resize(MatrixNr+1);
213 Header[MatrixNr] = header;
214
215 // row count
216 if (RowCounter.size() <= MatrixNr)
217 RowCounter.resize(MatrixNr+1);
218 RowCounter[MatrixNr] = matrix.size();
219 LOG(4, "INFO: RowCounter[" << MatrixNr << "]: " << RowCounter[MatrixNr] << " from input stream.");
220
221 // column count
222 if (ColumnCounter.size() <= MatrixNr)
223 ColumnCounter.resize(MatrixNr+1);
224 ColumnCounter[MatrixNr] = matrix[0].size();
225 LOG(4, "INFO: ColumnCounter[" << MatrixNr << "]: " << ColumnCounter[MatrixNr] << ".");
226
227 // allocate matrix ...
228 if (Matrix.size() <= MatrixNr)
229 Matrix.resize(MatrixNr+1);
230 MatrixCounter = Matrix.size()-1;
231 Matrix[MatrixNr].resize(RowCounter[MatrixNr] + 1);
232 for(int j=0;j<=RowCounter[MatrixNr];++j)
233 Matrix[MatrixNr][j].resize(ColumnCounter[MatrixNr]+1);
234
235 // .. and copy values
236 for(int j=0;j<RowCounter[MatrixNr];++j)
237 for(int k=0;k<ColumnCounter[MatrixNr];++k)
238 Matrix[MatrixNr][j][k] = matrix[j][k];
239 // reset last column
240 for(int j=0;j<RowCounter[MatrixNr];++j)
241 Matrix[MatrixNr][j][ ColumnCounter[MatrixNr] ] = 0.;
242 // reset last row
243 for(int k=0;k<=ColumnCounter[MatrixNr];++k)
244 Matrix[MatrixNr][ RowCounter[MatrixNr] ][ k ] = 0.;
245
246 return true;
247}
248
249/** Parsing a number of matrices.
250 * -# First, count the number of matrices by counting lines in KEYSETFILE
251 * -# Then,
252 * -# construct the fragment number
253 * -# open the matrix file
254 * -# skip some lines (\a skiplines)
255 * -# scan header lines for number of columns
256 * -# scan lines for number of rows
257 * -# allocate matrix
258 * -# loop over found column and row counts and parse in each entry
259 * -# Finally, allocate one additional matrix (\a MatrixCounter) containing combined or temporary values
260 * \param *name directory with files
261 * \param *prefix prefix of each matrix file
262 * \param *suffix suffix of each matrix file
263 * \param skiplines number of inital lines to skip
264 * \param skiplines number of inital columns to skip
265 * \return parsing successful
266 */
267bool MatrixContainer::ParseFragmentMatrix(const std::string name, const std::string prefix, std::string suffix, int skiplines, int skipcolumns)
268{
269 char filename[1023];
270 ifstream input;
271 char *FragmentNumber = NULL;
272 stringstream file;
273 string token;
274
275 // count the number of matrices
276 MatrixCounter = -1; // we count one too much
277 file << name << FRAGMENTPREFIX << KEYSETFILE;
278 input.open(file.str().c_str(), ios::in);
279 if (input.bad()) {
280 ELOG(1, "MatrixContainer::ParseFragmentMatrix: Unable to open " << file.str() << ", is the directory correct?");
281 return false;
282 }
283 while (!input.eof()) {
284 input.getline(filename, 1023);
285 stringstream zeile(filename);
286 MatrixCounter++;
287 }
288 input.close();
289 LOG(2, "INFO: Determined " << MatrixCounter << " fragments.");
290
291 LOG(1, "STATUS: Parsing through each fragment and retrieving " << prefix << suffix << ".");
292 Header.clear();
293 Matrix.clear();
294 RowCounter.clear();
295 ColumnCounter.clear();
296 Header.resize(MatrixCounter + 1); // one more each for the total molecule
297 Matrix.resize(MatrixCounter + 1); // one more each for the total molecule
298 RowCounter.resize(MatrixCounter + 1);
299 ColumnCounter.resize(MatrixCounter + 1);
300 for(int i=0; i < MatrixCounter;i++) {
301 // open matrix file
302 FragmentNumber = FixedDigitNumber(MatrixCounter, i);
303 file.str(" ");
304 file << name << FRAGMENTPREFIX << FragmentNumber << prefix << suffix;
305 std::ifstream input(file.str().c_str());
306 LOG(2, "INFO: Opening " << file.str() << " ... ");
307 if (!ParseMatrix(input, skiplines, skipcolumns, i)) {
308 input.close();
309 return false;
310 }
311 input.close();
312 delete[](FragmentNumber);
313 }
314 return true;
315};
316
317/** Allocates and resets the memory for a number \a MCounter of matrices.
318 * \param **GivenHeader Header line for each matrix
319 * \param MCounter number of matrices
320 * \param *RCounter number of rows for each matrix
321 * \param *CCounter number of columns for each matrix
322 * \return Allocation successful
323 */
324bool MatrixContainer::AllocateMatrix(StringVector GivenHeader, int MCounter, IntVector RCounter, IntVector CCounter)
325{
326 MatrixCounter = MCounter;
327 Header.resize(MatrixCounter + 1);
328 Matrix.resize(MatrixCounter + 1); // one more each for the total molecule
329 RowCounter.resize(MatrixCounter + 1);
330 ColumnCounter.resize(MatrixCounter + 1);
331 for(int i=MatrixCounter+1;i--;) {
332 Header[i] = GivenHeader[i];
333 RowCounter[i] = RCounter[i];
334 ColumnCounter[i] = CCounter[i];
335 if ((int)Matrix[i].size() <= RowCounter[i] + 2)
336 Matrix[i].resize(RowCounter[i] + 1);
337 for(int j=0;j<=RowCounter[i];j++)
338 if ((int)Matrix[i][j].size() <= ColumnCounter[i]+1)
339 Matrix[i][j].resize(ColumnCounter[i]);
340 // allocation with 0 is guaranted by STL
341 }
342 return true;
343};
344
345/** Resets all values in MatrixContainer::Matrix.
346 * \return true if successful
347 */
348bool MatrixContainer::ResetMatrix()
349{
350 for(int i=MatrixCounter+1;i--;)
351 for(int j=RowCounter[i]+1;j--;)
352 for(int k=ColumnCounter[i];k--;)
353 Matrix[i][j][k] = 0.;
354 return true;
355};
356
357/** Scans all elements of MatrixContainer::Matrix for greatest absolute value.
358 * \return greatest value of MatrixContainer::Matrix
359 */
360double MatrixContainer::FindMaxValue()
361{
362 double max = Matrix[0][0][0];
363 for(int i=MatrixCounter+1;i--;)
364 for(int j=RowCounter[i]+1;j--;)
365 for(int k=ColumnCounter[i];k--;)
366 if (fabs(Matrix[i][j][k]) > max)
367 max = fabs(Matrix[i][j][k]);
368 if (fabs(max) < MYEPSILON)
369 max += MYEPSILON;
370 return max;
371};
372
373/** Scans all elements of MatrixContainer::Matrix for smallest absolute value.
374 * \return smallest value of MatrixContainer::Matrix
375 */
376double MatrixContainer::FindMinValue()
377{
378 double min = Matrix[0][0][0];
379 for(int i=MatrixCounter+1;i--;)
380 for(int j=RowCounter[i]+1;j--;)
381 for(int k=ColumnCounter[i];k--;)
382 if (fabs(Matrix[i][j][k]) < min)
383 min = fabs(Matrix[i][j][k]);
384 if (fabs(min) < MYEPSILON)
385 min += MYEPSILON;
386 return min;
387};
388
389/** Sets all values in the last of MatrixContainer::Matrix to \a value.
390 * \param value reset value
391 * \param skipcolumns skip initial columns
392 * \return true if successful
393 */
394bool MatrixContainer::SetLastMatrix(double value, int skipcolumns)
395{
396 for(int j=RowCounter[MatrixCounter]+1;j--;)
397 for(int k=skipcolumns;k<ColumnCounter[MatrixCounter];k++)
398 Matrix[MatrixCounter][j][k] = value;
399 return true;
400};
401
402/** Sets all values in the last of MatrixContainer::Matrix to \a value.
403 * \param **values matrix with each value (must have at least same dimensions!)
404 * \param skipcolumns skip initial columns
405 * \return true if successful
406 */
407bool MatrixContainer::SetLastMatrix(const MatrixArray &values, int skipcolumns)
408{
409 for(int j=RowCounter[MatrixCounter]+1;j--;)
410 for(int k=skipcolumns;k<ColumnCounter[MatrixCounter];k++)
411 Matrix[MatrixCounter][j][k] = values[j][k];
412 return true;
413};
414
415/** Sums the entries with each factor and put into last element of \a ***Matrix.
416 * Sums over "E"-terms to create the "F"-terms
417 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
418 * \param KeySets KeySetContainer with bond Order and association mapping of each fragment to an order
419 * \param Order bond order
420 * \return true if summing was successful
421 */
422bool MatrixContainer::SumSubManyBodyTerms(class MatrixContainer &MatrixValues, class KeySetsContainer &KeySets, int Order)
423{
424 // go through each order
425 for (int CurrentFragment=0;CurrentFragment<KeySets.FragmentsPerOrder[Order];CurrentFragment++) {
426 //LOG(0, "Current Fragment is " << CurrentFragment << "/" << KeySets.OrderSet[Order][CurrentFragment] << ".");
427 // then go per order through each suborder and pick together all the terms that contain this fragment
428 for(int SubOrder=0;SubOrder<=Order;SubOrder++) { // go through all suborders up to the desired order
429 for (int j=0;j<KeySets.FragmentsPerOrder[SubOrder];j++) { // go through all possible fragments of size suborder
430 if (KeySets.Contains(KeySets.OrderSet[Order][CurrentFragment], KeySets.OrderSet[SubOrder][j])) {
431 //LOG(0, "Current other fragment is " << j << "/" << KeySets.OrderSet[SubOrder][j] << ".");
432 // if the fragment's indices are all in the current fragment
433 for(int k=0;k<RowCounter[ KeySets.OrderSet[SubOrder][j] ];k++) { // go through all atoms in this fragment
434 int m = MatrixValues.Indices[ KeySets.OrderSet[SubOrder][j] ][k];
435 //LOG(0, "Current index is " << k << "/" << m << ".");
436 if (m != -1) { // if it's not an added hydrogen
437 for (int l=0;l<RowCounter[ KeySets.OrderSet[Order][CurrentFragment] ];l++) { // look for the corresponding index in the current fragment
438 //LOG(0, "Comparing " << m << " with " << MatrixValues.Indices[ KeySets.OrderSet[Order][CurrentFragment] ][l] << ".");
439 if (m == MatrixValues.Indices[ KeySets.OrderSet[Order][CurrentFragment] ][l]) {
440 m = l;
441 break;
442 }
443 }
444 //LOG(0, "Corresponding index in CurrentFragment is " << m << ".");
445 if (m > RowCounter[ KeySets.OrderSet[Order][CurrentFragment] ]) {
446 ELOG(0, "In fragment No. " << KeySets.OrderSet[Order][CurrentFragment] << " current force index " << m << " is greater than " << RowCounter[ KeySets.OrderSet[Order][CurrentFragment] ] << "!");
447 performCriticalExit();
448 return false;
449 }
450 if (Order == SubOrder) { // equal order is always copy from Energies
451 for(int l=ColumnCounter[ KeySets.OrderSet[SubOrder][j] ];l--;) // then adds/subtract each column
452 Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][m][l] += MatrixValues.Matrix[ KeySets.OrderSet[SubOrder][j] ][k][l];
453 } else {
454 for(int l=ColumnCounter[ KeySets.OrderSet[SubOrder][j] ];l--;)
455 Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][m][l] -= Matrix[ KeySets.OrderSet[SubOrder][j] ][k][l];
456 }
457 }
458 //if ((ColumnCounter[ KeySets.OrderSet[SubOrder][j] ]>1) && (RowCounter[0]-1 >= 1))
459 //LOG(0, "Fragments[ KeySets.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySets.OrderSet[Order][CurrentFragment] << " ][" << RowCounter[0]-1 << "][" << 1 << "] = " << Matrix[ KeySets.OrderSet[Order][CurrentFragment] ][RowCounter[0]-1][1]);
460 }
461 } else {
462 //LOG(0, "Fragment " << KeySets.OrderSet[SubOrder][j] << " is not contained in fragment " << KeySets.OrderSet[Order][CurrentFragment] << ".");
463 }
464 }
465 }
466 //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]);
467 }
468
469 return true;
470};
471
472/** Writes the summed total fragment terms \f$F_{ij}\f$ to file.
473 * \param *name inputdir
474 * \param *prefix prefix before \a EnergySuffix
475 * \return file was written
476 */
477bool MatrixContainer::WriteTotalFragments(const std::string name, const std::string prefix)
478{
479 ofstream output;
480 char *FragmentNumber = NULL;
481
482 LOG(1, "STATUS: Writing fragment files.");
483 for(int i=0;i<MatrixCounter;i++) {
484 stringstream line;
485 FragmentNumber = FixedDigitNumber(MatrixCounter, i);
486 line << name << FRAGMENTPREFIX << FragmentNumber << "/" << prefix;
487 delete[](FragmentNumber);
488 output.open(line.str().c_str(), ios::out);
489 if (output == NULL) {
490 ELOG(0, "MatrixContainer::WriteTotalFragments: Unable to open output energy file " << line.str() << "!");
491 performCriticalExit();
492 return false;
493 }
494 output << Header[i] << endl;
495 for(int j=0;j<RowCounter[i];j++) {
496 for(int k=0;k<ColumnCounter[i];k++)
497 output << scientific << Matrix[i][j][k] << "\t";
498 output << endl;
499 }
500 output.close();
501 }
502 return true;
503};
504
505/** Writes the summed total values in the last matrix to file.
506 * \param *name inputdir
507 * \param *prefix prefix
508 * \param *suffix suffix
509 * \return file was written
510 */
511bool MatrixContainer::WriteLastMatrix(const std::string name, const std::string prefix, const std::string suffix)
512{
513 ofstream output;
514 stringstream line;
515
516 LOG(1, "STATUS: Writing matrix values of " << suffix << ".");
517 line << name << prefix << suffix;
518 output.open(line.str().c_str(), ios::out);
519 if (output == NULL) {
520 ELOG(0, "MatrixContainer::WriteLastMatrix: Unable to open output matrix file " << line.str() << "!");
521 performCriticalExit();
522 return false;
523 }
524 output << Header[MatrixCounter] << endl;
525 for(int j=0;j<RowCounter[MatrixCounter];j++) {
526 for(int k=0;k<ColumnCounter[MatrixCounter];k++)
527 output << scientific << Matrix[MatrixCounter][j][k] << "\t";
528 output << endl;
529 }
530 output.close();
531 return true;
532};
533
534/** Comparison operator for class MatrixContainer.
535 *
536 * @param other instance to compare to
537 * @return true - both instances are the same in each member variable.
538 */
539bool MatrixContainer::operator==(const MatrixContainer &other) const
540{
541 // compare matrices
542 if (Matrix != other.Matrix)
543 return false;
544 // compare Indices
545 if (Indices != other.Indices)
546 return false;
547 // compare Headers
548 if (Header != other.Header)
549 return false;
550 // compare MatrixCounter
551 if (MatrixCounter != other.MatrixCounter)
552 return false;
553 // compare RowCounter
554 if (RowCounter != other.RowCounter)
555 return false;
556 // compare ColumnCounter
557 if (ColumnCounter != other.ColumnCounter)
558 return false;
559 return true;
560}
561
562std::ostream & operator << (std::ostream &ost, const MatrixContainer &m)
563{
564 for (int i=0;i<=m.MatrixCounter;++i) {
565 ost << "Matrix " << i << " in MatrixContainer:" << std::endl;
566 for (int j=0;j<=m.RowCounter[i];++j) {
567 for (int k=0;k<m.ColumnCounter[i];++k) {
568 ost << m.Matrix[i][j][k] << " ";
569 }
570 ost << std::endl;
571 }
572 }
573 ost << std::endl;
574 return ost;
575}
576
Note: See TracBrowser for help on using the repository browser.