tesseract  5.0.0
stridemap.cpp
Go to the documentation of this file.
1 // File: stridemap.cpp
3 // Description: Indexing into a 4-d tensor held in a 2-d Array.
4 // Author: Ray Smith
5 //
6 // (C) Copyright 2016, Google Inc.
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
17 
18 #include "stridemap.h"
19 #include <cassert> // for assert
20 
21 namespace tesseract {
22 
23 // Returns true if *this is a valid index.
25  // Cheap check first.
26  for (int index : indices_) {
27  if (index < 0) {
28  return false;
29  }
30  }
31  for (int d = 0; d < FD_DIMSIZE; ++d) {
32  if (indices_[d] > MaxIndexOfDim(static_cast<FlexDimensions>(d))) {
33  return false;
34  }
35  }
36  return true;
37 }
38 
39 // Returns true if the index of the given dimension is the last.
41  return MaxIndexOfDim(dimension) == indices_[dimension];
42 }
43 
44 // Given that the dimensions up to and including dim-1 are valid, returns the
45 // maximum index for dimension dim.
47  int max_index = stride_map_->shape_[dim] - 1;
48  if (dim == FD_BATCH) {
49  return max_index;
50  }
51  assert(0 <= indices_[FD_BATCH]);
52  const size_t batch = indices_[FD_BATCH];
53  if (dim == FD_HEIGHT) {
54  if (batch >= stride_map_->heights_.size() || stride_map_->heights_[batch] > max_index) {
55  return max_index;
56  }
57  return stride_map_->heights_[batch] - 1;
58  }
59  if (batch >= stride_map_->widths_.size() || stride_map_->widths_[batch] > max_index) {
60  return max_index;
61  }
62  return stride_map_->widths_[batch] - 1;
63 }
64 
65 // Adds the given offset to the given dimension. Returns true if the result
66 // makes a valid index.
67 bool StrideMap::Index::AddOffset(int offset, FlexDimensions dimension) {
68  indices_[dimension] += offset;
69  SetTFromIndices();
70  return IsValid();
71 }
72 
73 // Increments the index in some encapsulated way that guarantees to remain
74 // valid until it returns false, meaning that the iteration is complete.
76  for (int d = FD_DIMSIZE - 1; d >= 0; --d) {
77  if (!IsLast(static_cast<FlexDimensions>(d))) {
78  t_ += stride_map_->t_increments_[d];
79  ++indices_[d];
80  return true;
81  }
82  t_ -= stride_map_->t_increments_[d] * indices_[d];
83  indices_[d] = 0;
84  // Now carry to the next dimension.
85  }
86  return false;
87 }
88 
89 // Decrements the index in some encapsulated way that guarantees to remain
90 // valid until it returns false, meaning that the iteration (that started
91 // with InitToLast()) is complete.
93  for (int d = FD_DIMSIZE - 1; d >= 0; --d) {
94  if (indices_[d] > 0) {
95  --indices_[d];
96  if (d == FD_BATCH) {
97  // The upper limits of the other dimensions may have changed as a result
98  // of a different batch index, so they have to be reset.
99  InitToLastOfBatch(indices_[FD_BATCH]);
100  } else {
101  t_ -= stride_map_->t_increments_[d];
102  }
103  return true;
104  }
105  indices_[d] = MaxIndexOfDim(static_cast<FlexDimensions>(d));
106  t_ += stride_map_->t_increments_[d] * indices_[d];
107  // Now borrow from the next dimension.
108  }
109  return false;
110 }
111 
112 // Initializes the indices to the last valid location in the given batch
113 // index.
114 void StrideMap::Index::InitToLastOfBatch(int batch) {
115  indices_[FD_BATCH] = batch;
116  for (int d = FD_BATCH + 1; d < FD_DIMSIZE; ++d) {
117  indices_[d] = MaxIndexOfDim(static_cast<FlexDimensions>(d));
118  }
119  SetTFromIndices();
120 }
121 
122 // Computes and sets t_ from the current indices_.
123 void StrideMap::Index::SetTFromIndices() {
124  t_ = 0;
125  for (int d = 0; d < FD_DIMSIZE; ++d) {
126  t_ += stride_map_->t_increments_[d] * indices_[d];
127  }
128 }
129 
130 // Sets up the stride for the given array of height, width pairs.
131 void StrideMap::SetStride(const std::vector<std::pair<int, int>> &h_w_pairs) {
132  int max_height = 0;
133  int max_width = 0;
134  for (const std::pair<int, int> &hw : h_w_pairs) {
135  int height = hw.first;
136  int width = hw.second;
137  heights_.push_back(height);
138  widths_.push_back(width);
139  if (height > max_height) {
140  max_height = height;
141  }
142  if (width > max_width) {
143  max_width = width;
144  }
145  }
146  shape_[FD_BATCH] = heights_.size();
147  shape_[FD_HEIGHT] = max_height;
148  shape_[FD_WIDTH] = max_width;
149  ComputeTIncrements();
150 }
151 
152 // Scales width and height dimensions by the given factors.
153 void StrideMap::ScaleXY(int x_factor, int y_factor) {
154  for (int &height : heights_) {
155  height /= y_factor;
156  }
157  for (int &width : widths_) {
158  width /= x_factor;
159  }
160  shape_[FD_HEIGHT] /= y_factor;
161  shape_[FD_WIDTH] /= x_factor;
162  ComputeTIncrements();
163 }
164 
165 // Reduces width to 1, across the batch, whatever the input size.
167  widths_.assign(widths_.size(), 1);
168  shape_[FD_WIDTH] = 1;
169  ComputeTIncrements();
170 }
171 
172 // Transposes the width and height dimensions.
174  std::swap(shape_[FD_HEIGHT], shape_[FD_WIDTH]);
175  std::swap(heights_, widths_);
176  ComputeTIncrements();
177 }
178 
179 // Computes t_increments_ from shape_.
180 void StrideMap::ComputeTIncrements() {
181  t_increments_[FD_DIMSIZE - 1] = 1;
182  for (int d = FD_DIMSIZE - 2; d >= 0; --d) {
183  t_increments_[d] = t_increments_[d + 1] * shape_[d + 1];
184  }
185 }
186 
187 } // namespace tesseract
FlexDimensions
Definition: stridemap.h:32
@ FD_WIDTH
Definition: stridemap.h:35
@ FD_DIMSIZE
Definition: stridemap.h:36
@ FD_BATCH
Definition: stridemap.h:33
@ FD_HEIGHT
Definition: stridemap.h:34
void SetStride(const std::vector< std::pair< int, int >> &h_w_pairs)
Definition: stridemap.cpp:131
void ScaleXY(int x_factor, int y_factor)
Definition: stridemap.cpp:153
int index(FlexDimensions dimension) const
Definition: stridemap.h:59
bool AddOffset(int offset, FlexDimensions dimension)
Definition: stridemap.cpp:67
bool IsLast(FlexDimensions dimension) const
Definition: stridemap.cpp:40
int MaxIndexOfDim(FlexDimensions dim) const
Definition: stridemap.cpp:46