OpenMS
Loading...
Searching...
No Matches
DistanceMatrix.h
Go to the documentation of this file.
1// Copyright (c) 2002-present, OpenMS Inc. -- 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
15#include <OpenMS/config.h>
16#include <algorithm>
17#include <cmath>
18#include <iomanip>
19#include <iostream>
20
21namespace OpenMS
22{
23
40template<typename Value>
42{
43public:
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;
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_]),
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
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;
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
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
415protected:
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
425private:
428 {
429 matrix_ = rhs.matrix_;
433
434 return *this;
435 }
436
437}; // class DistanceMatrix
438
444template<typename Value>
445std::ostream& operator<<(std::ostream& os, const DistanceMatrix<Value>& matrix)
446{
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
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
std::pair< SizeType, SizeType > getMinElementCoordinates() const
Indexpair of minimal element.
Definition DistanceMatrix.h:409
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:429
Out of range exception.
Definition Exception.h:291
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
Main OpenMS namespace.
Definition openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/ISpectrumAccess.h:19
Colorizer red