OpenMS
DistanceMatrix.h
Go to the documentation of this file.
1 // Copyright (c) 2002-present, The OpenMS Team -- EKU Tuebingen, ETH Zurich, and FU Berlin
2 // SPDX-License-Identifier: BSD-3-Clause
3 //
4 // --------------------------------------------------------------------------
5 // $Maintainer: Mathias Walzer $
6 // $Authors: $
7 // --------------------------------------------------------------------------
8 
9 #pragma once
10 
13 #include <OpenMS/CONCEPT/Macros.h>
14 #include <OpenMS/CONCEPT/Types.h>
15 #include <OpenMS/config.h>
16 #include <algorithm>
17 #include <cmath>
18 #include <iomanip>
19 #include <iostream>
20 
21 namespace OpenMS
22 {
23 
40 template<typename Value>
42 {
43 public:
45 
46  typedef Value value_type;
48 
50 
51  typedef Size SizeType;
54 
59  {
60  }
61 
69  DistanceMatrix(SizeType dimensionsize, Value value = Value()):
73  min_element_(0, 0)
74  {
75  matrix_[0] = NULL;
76  SizeType i = 1;
77  for (i = 1; i < dimensionsize; ++i)
78  {
79  matrix_[i] = new ValueType[i];
80  if (matrix_[i] == NULL)
81  {
82  SizeType j = i;
83  for (i = 1; i < j; i++)
84  {
85  delete[] matrix_[i];
86  }
87  delete[] matrix_;
88  matrix_ = NULL;
89  dimensionsize_ = 0;
90  init_size_ = 0;
91  throw Exception::OutOfMemory(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
92  (UInt)((((dimensionsize - 2) * (dimensionsize - 1)) / 2) * sizeof(ValueType)));
93  }
94  }
95  if (matrix_ != NULL)
96  {
97  for (i = 1; i < dimensionsize; ++i)
98  {
99  for (SizeType j = 0; j < i; ++j)
100  {
101  matrix_[i][j] = value;
102  }
103  }
104  min_element_ = std::make_pair(1, 0);
105  }
106  }
107 
115  matrix_(new ValueType*[source.dimensionsize_]),
116  init_size_(source.dimensionsize_),
118  min_element_(source.min_element_)
119  {
120  matrix_[0] = NULL;
121  SizeType i = 1;
122  for (i = 1; i < dimensionsize_; ++i)
123  {
124  matrix_[i] = new ValueType[i];
125  if (matrix_[i] == NULL)
126  {
127  SizeType j = i;
128  for (i = 1; i < j; i++)
129  {
130  delete[] matrix_[i];
131  }
132  delete[] matrix_;
133  matrix_ = NULL;
134  dimensionsize_ = 0;
135  init_size_ = 0;
136  min_element_ = std::make_pair(0, 0);
137  throw Exception::OutOfMemory(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
138  (UInt)((((dimensionsize_ - 2) * (dimensionsize_ - 1)) / 2) * sizeof(ValueType)));
139  }
140  }
141  if (matrix_ != NULL)
142  {
143  for (i = 1; i < dimensionsize_; ++i)
144  {
145  std::copy(source.matrix_[i], source.matrix_[i] + i, matrix_[i]);
146  }
147  }
148  }
149 
152  {
153  for (SizeType i = 1; i < init_size_; i++)
154  {
155  delete[] matrix_[i];
156  }
157  delete[] matrix_;
158  }
159 
167  {
168  return getValue(i, j);
169  }
170 
178  {
179  return getValue(i, j);
180  }
181 
190  {
191  if (i >= dimensionsize_ || j >= dimensionsize_) { throw Exception::OutOfRange(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION); }
192  // elements on main diagonal are not stored and assumed to be 0
193  if (i == j) { return 0; }
194  if (i < j) { std::swap(i, j); }
195  return (const ValueType)(matrix_[i][j]);
196  }
197 
206  {
207  if (i >= dimensionsize_ || j >= dimensionsize_) { throw Exception::OutOfRange(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION); }
208  // elements on main diagonal are not stored and assumed to be 0
209  if (i == j) { return 0; }
210  if (i < j) { std::swap(i, j); }
211  return matrix_[i][j];
212  }
213 
223  {
224  if (i >= dimensionsize_ || j >= dimensionsize_) { throw Exception::OutOfRange(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION); }
225  // elements on main diagonal are not stored and assumed to be 0
226  if (i != j)
227  {
228  if (i < j) { std::swap(i, j); }
229  if (i != min_element_.first && j != min_element_.second)
230  {
231  matrix_[i][j] = value;
232  if (value < matrix_[min_element_.first][min_element_.second]) // keep min_element_ up-to-date
233  {
234  min_element_ = std::make_pair(i, j);
235  }
236  }
237  else
238  {
239  if (value <= matrix_[min_element_.first][min_element_.second]) { matrix_[i][j] = value; }
240  else
241  {
242  matrix_[i][j] = value;
244  }
245  }
246  }
247  }
248 
260  {
261  if (i >= dimensionsize_ || j >= dimensionsize_) { throw Exception::OutOfRange(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION); }
262  // elements on main diagonal are not stored and assumed to be 0
263  if (i != j)
264  {
265  if (i < j) { std::swap(i, j); }
266  matrix_[i][j] = value;
267  }
268  }
269 
271  void clear()
272  {
273  for (SizeType i = 1; i < init_size_; i++)
274  {
275  delete[] matrix_[i];
276  }
277  delete[] matrix_;
278  matrix_ = nullptr;
279  min_element_ = std::make_pair(0, 0);
280  dimensionsize_ = 0;
281  init_size_ = 0;
282  }
283 
293  void resize(SizeType dimensionsize, Value value = Value())
294  {
295  for (SizeType j = 1; j < init_size_; j++)
296  {
297  delete[] matrix_[j];
298  }
299  delete[] matrix_;
302  min_element_ = std::make_pair(0, 0);
304  for (SizeType j = 1; j < dimensionsize_; ++j)
305  {
306  matrix_[j] = new ValueType[j];
307  if (matrix_[j] == nullptr)
308  {
309  for (SizeType k = 1; k < j; ++k)
310  {
311  delete[] matrix_[k];
312  }
313  delete[] matrix_;
314  matrix_ = nullptr;
315  dimensionsize_ = 0;
316  init_size_ = 0;
317  throw Exception::OutOfMemory(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
318  (UInt)((((dimensionsize_ - 2) * (dimensionsize_ - 1)) / 2) * sizeof(Value)));
319  }
320  }
321  if (matrix_ != nullptr)
322  {
323  for (SizeType j = 0; j < dimensionsize; ++j)
324  {
325  for (SizeType k = 0; k < j; ++k)
326  {
327  matrix_[j][k] = value;
328  }
329  }
330  min_element_ = std::make_pair(1, 0);
331  }
332  }
333 
342  void reduce(SizeType j)
343  {
344  if (j >= dimensionsize_) { throw Exception::OutOfRange(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION); }
345  // delete row j and therefor overwrite with row j+1 and iterate like this to last row
346  SizeType i = j + 1;
347  while (i < dimensionsize_ && matrix_[i] != nullptr)
348  {
349  // left out in the copy is each rows jth element, pointer working here as iterators just fine
350  std::copy(matrix_[i] + j + 1, matrix_[i] + i, std::copy(matrix_[i], matrix_[i] + j, matrix_[i - 1]));
351  ++i;
352  }
353  // last row is freed and the pointer set to NULL (outer array's size is not changed)
354  delete[] matrix_[i - 1];
355  matrix_[i - 1] = nullptr;
356  --dimensionsize_;
357  }
358 
361  {
362  return dimensionsize_;
363  }
364 
371  {
372  min_element_ = std::make_pair(1, 0);
373  // error if dimensionsize_<1, return if dimensionsize_ == 1, else
374  if (dimensionsize_ < 1) { throw Exception::OutOfRange(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION); }
375  if (dimensionsize_ != 1) // else matrix has one element: (1,0)
376  {
377  ValueType* row_min_;
378  for (SizeType r = 2; r < dimensionsize_ && matrix_[r] != nullptr; ++r)
379  {
380  row_min_ = std::min_element(matrix_[r], matrix_[r] + r);
381  if (*row_min_ < matrix_[min_element_.first][min_element_.second]) { min_element_ = std::make_pair(r, row_min_ - matrix_[r]); }
382  }
383  }
384  }
385 
391  bool operator==(DistanceMatrix<ValueType> const& rhs) const
392  {
393  OPENMS_PRECONDITION(dimensionsize_ == rhs.dimensionsize_, "DistanceMatrices have different sizes.");
394  for (Size i = 1; i < rhs.dimensionsize(); ++i)
395  {
396  for (Size j = 0; j < i; ++j)
397  {
398  if (matrix_[i][j] != rhs.matrix_[i][j]) { return false; }
399  }
400  }
401  return true;
402  }
403 
409  std::pair<SizeType, SizeType> getMinElementCoordinates() const
410  {
411  if (dimensionsize_ == 0) { throw Exception::OutOfRange(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION); }
412  return min_element_;
413  }
414 
415 protected:
419  SizeType init_size_; // actual size of outer array
421  SizeType dimensionsize_; // number of virtual elements: ((dimensionsize-1)*(dimensionsize))/2
423  std::pair<SizeType, SizeType> min_element_;
424 
425 private:
428  {
429  matrix_ = rhs.matrix_;
430  init_size_ = rhs.init_size_;
433 
434  return *this;
435  }
436 
437 }; // class DistanceMatrix
438 
444 template<typename Value>
445 std::ostream& operator<<(std::ostream& os, const DistanceMatrix<Value>& matrix)
446 {
447  using SizeType = typename DistanceMatrix<Value>::SizeType;
448 
449  // we need to print a square matrix. So we set the width
450  //std::ios_base::fmtflags flag_backup = os.setf(std::ios::scientific); // 'scientific' messes with the width; don't do it
451  std::streamsize precision_backup = os.precision(6); // we could go with `writtenDigits<Value>(Value())`, but it becomes unreadable...
452  auto width_backup = os.width(8);
453 
454  for (SizeType i = 0; i < matrix.dimensionsize(); ++i)
455  {
456  for (SizeType j = 0; j < matrix.dimensionsize(); ++j)
457  {
458  if (i == j)
459  { // color the diagonal in red (conditional, see Colorizer)
460  os << red(matrix(i, j)) << '\t';
461  }
462  else
463  {
464  os << matrix(i, j) << '\t';
465  }
466  }
467  os << '\n';
468  }
469  //os.flags(flag_backup);
470  os.precision(precision_backup);
471  os.width(width_backup);
472  return os;
473 }
474 
475 } // namespace OpenMS
A two-dimensional distance matrix, similar to OpenMS::Matrix.
Definition: DistanceMatrix.h:42
SizeType dimensionsize() const
gives the number of rows (i.e. number of columns)
Definition: DistanceMatrix.h:360
Value value_type
Definition: DistanceMatrix.h:46
std::ostream & operator<<(std::ostream &os, const DistanceMatrix< Value > &matrix)
Print the contents to a stream (and colors the diagonal, if the stream is cout/cerr)
Definition: DistanceMatrix.h:445
DistanceMatrix()
default constructor
Definition: DistanceMatrix.h:58
bool operator==(DistanceMatrix< ValueType > const &rhs) const
Equality comparator.
Definition: DistanceMatrix.h:391
void setValue(SizeType i, SizeType j, ValueType value)
sets a value at a given position:
Definition: DistanceMatrix.h:222
void updateMinElement()
keep track of the actual minimum element after altering the matrix
Definition: DistanceMatrix.h:370
std::pair< SizeType, SizeType > getMinElementCoordinates() const
Indexpair of minimal element.
Definition: DistanceMatrix.h:409
const ValueType getValue(SizeType i, SizeType j) const
gets a value at a given position:
Definition: DistanceMatrix.h:189
ValueType getValue(SizeType i, SizeType j)
gets a value at a given position:
Definition: DistanceMatrix.h:205
const ValueType operator()(SizeType i, SizeType j) const
gets a value at a given position (read only):
Definition: DistanceMatrix.h:166
DistanceMatrix(const DistanceMatrix &source)
copy constructor
Definition: DistanceMatrix.h:114
Size SizeType
Definition: DistanceMatrix.h:51
std::pair< SizeType, SizeType > min_element_
index of minimal element(i.e. number in underlying SparseVector)
Definition: DistanceMatrix.h:423
ValueType operator()(SizeType i, SizeType j)
gets a value at a given position (read only):
Definition: DistanceMatrix.h:177
ValueType ** matrix_
sparse element not to be included in base container
Definition: DistanceMatrix.h:417
void setValueQuick(SizeType i, SizeType j, ValueType value)
sets a value at a given position:
Definition: DistanceMatrix.h:259
value_type ValueType
Definition: DistanceMatrix.h:52
~DistanceMatrix()
destructor
Definition: DistanceMatrix.h:151
SizeType init_size_
number of actually stored rows
Definition: DistanceMatrix.h:419
DistanceMatrix(SizeType dimensionsize, Value value=Value())
detailed constructor
Definition: DistanceMatrix.h:69
DistanceMatrix & operator=(const DistanceMatrix &rhs)
assignment operator (unsafe)
Definition: DistanceMatrix.h:427
void clear()
reset all
Definition: DistanceMatrix.h:271
SizeType dimensionsize_
number of accessibly stored rows (i.e. number of columns)
Definition: DistanceMatrix.h:421
void resize(SizeType dimensionsize, Value value=Value())
resizing the container
Definition: DistanceMatrix.h:293
void reduce(SizeType j)
reduces DistanceMatrix by one dimension. first the jth row, then jth column
Definition: DistanceMatrix.h:342
Out of memory exception.
Definition: Exception.h:428
Out of range exception.
Definition: Exception.h:290
unsigned int UInt
Unsigned integer type.
Definition: Types.h:64
size_t Size
Size type e.g. used as variable which can hold result of size()
Definition: Types.h:97
#define OPENMS_PRECONDITION(condition, message)
Precondition macro.
Definition: openms/include/OpenMS/CONCEPT/Macros.h:94
const double k
Definition: Constants.h:132
Main OpenMS namespace.
Definition: openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/ISpectrumAccess.h:19
Colorizer red