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