TTK
Loading...
Searching...
No Matches
RangeMinimumQuery.h
Go to the documentation of this file.
1
8
9#pragma once
10
11#include <Debug.h>
12
13#include <algorithm>
14#include <cmath>
15#include <sstream>
16#include <string>
17#include <vector>
18
19namespace ttk {
20
21 template <class DataType>
22 class RangeMinimumQuery : virtual public Debug {
23 public:
25 RangeMinimumQuery(std::vector<DataType> &input);
26
27 inline void setVector(std::vector<DataType> &input) {
28 input_ = input.data();
29 input_end_ = input.data() + input.size();
30 }
31
32 int preprocess(const bool silent = false);
33 int query(int i, int j) const;
34
35 protected:
36 // Input vector
37 DataType *input_{};
38 DataType *input_end_{};
39
40 // Sparse Table
41 std::vector<std::vector<int>> table_{};
42 };
43
44} // namespace ttk
45
46/* Function definitions */
47
48// Constructors
49template <class DataType>
51 this->setDebugMsgPrefix("RangeMinimumQuery");
52}
53template <class DataType>
55 std::vector<DataType> &input) {
56 setVector(input);
57}
58
59// Preprocessing
60template <class DataType>
62
63 Timer t;
64
65 // Compute the size of the matrix
66 int const sizeOfArray = static_cast<int>(input_end_ - input_);
67 int const numberOfBlocs
68 = static_cast<unsigned int>(log2(sizeOfArray + 1)) + 1;
69
70 // Init the matrix
71 table_.resize(sizeOfArray);
72 for(int i = 0; i < sizeOfArray; i++) {
73 table_[i].resize(numberOfBlocs);
74 fill(table_[i].begin(), table_[i].end(), -1);
75 }
76
77 // Initialize for blocs of size 1 (k==0)
78 for(int i = 0; i < sizeOfArray; i++) {
79 table_[i][0] = i;
80 }
81 // Compute other values recursively
82 for(int k = 1; ((1 << k) - 1) < sizeOfArray; k++) {
83 for(int i = 0; (i + (1 << k) - 1) < sizeOfArray; i++) {
84 if(input_[table_[i][k - 1]]
85 <= input_[table_[i + (1 << (k - 1))][k - 1]]) {
86 table_[i][k] = table_[i][k - 1];
87 } else {
88 table_[i][k] = table_[i + (1 << (k - 1))][k - 1];
89 }
90 }
91 }
92 // Debug messages
93 if(!silent) {
94 this->printMsg("Preprocessed queries.", 1.0, t.getElapsedTime(), 1);
95 }
96 return 0;
97}
98
99template <class DataType>
101
102#ifndef TTK_ENABLE_KAMIKAZE
103 // i must be lower or equal to j, else swap values
104 if(i > j) {
105 std::swap(i, j);
106 }
107#endif
108
109 // Compute size of blocs (2^k) to use
110 int const k = static_cast<int>(log2(j - i + 1));
111 // Compute the range minimum
112 if(input_[table_[i][k]] <= input_[table_[j - (1 << k) + 1][k]]) {
113 return table_[i][k];
114 } else {
115 return table_[j - (1 << k) + 1][k];
116 }
117}
Minimalist debugging class.
Definition Debug.h:88
Class to answer range minimum queries in an array in constant time after a linearithmic time preproce...
int preprocess(const bool silent=false)
RangeMinimumQuery(std::vector< DataType > &input)
std::vector< std::vector< int > > table_
void setVector(std::vector< DataType > &input)
int query(int i, int j) const
double getElapsedTime()
Definition Timer.h:15
The Topology ToolKit.
T end(std::pair< T, T > &p)
Definition ripserpy.cpp:472
T begin(std::pair< T, T > &p)
Definition ripserpy.cpp:468
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)