tesseract  4.00.00dev
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 
21 namespace tesseract {
22 
23 // Returns true if *this is a valid index.
25  // Cheap check first.
26  for (int d = 0; d < FD_DIMSIZE; ++d) {
27  if (indices_[d] < 0) return false;
28  }
29  for (int d = 0; d < FD_DIMSIZE; ++d) {
30  if (indices_[d] > MaxIndexOfDim(static_cast<FlexDimensions>(d)))
31  return false;
32  }
33  return true;
34 }
35 
36 // Returns true if the index of the given dimension is the last.
38  return MaxIndexOfDim(dimension) == indices_[dimension];
39 }
40 
41 // Given that the dimensions up to and including dim-1 are valid, returns the
42 // maximum index for dimension dim.
44  int max_index = stride_map_->shape_[dim] - 1;
45  if (dim == FD_BATCH) return max_index;
46  assert(0 <= indices_[FD_BATCH]);
47  const size_t batch = indices_[FD_BATCH];
48  if (dim == FD_HEIGHT) {
49  if (batch >= stride_map_->heights_.size() ||
50  stride_map_->heights_[batch] > max_index)
51  return max_index;
52  return stride_map_->heights_[batch] - 1;
53  }
54  if (batch >= stride_map_->widths_.size() ||
55  stride_map_->widths_[batch] > max_index)
56  return max_index;
57  return stride_map_->widths_[batch] - 1;
58 }
59 
60 // Adds the given offset to the given dimension. Returns true if the result
61 // makes a valid index.
63  indices_[dimension] += offset;
64  SetTFromIndices();
65  return IsValid();
66 }
67 
68 // Increments the index in some encapsulated way that guarantees to remain
69 // valid until it returns false, meaning that the iteration is complete.
71  for (int d = FD_DIMSIZE - 1; d >= 0; --d) {
72  if (!IsLast(static_cast<FlexDimensions>(d))) {
73  t_ += stride_map_->t_increments_[d];
74  ++indices_[d];
75  return true;
76  }
77  t_ -= stride_map_->t_increments_[d] * indices_[d];
78  indices_[d] = 0;
79  // Now carry to the next dimension.
80  }
81  return false;
82 }
83 
84 // Decrements the index in some encapsulated way that guarantees to remain
85 // valid until it returns false, meaning that the iteration (that started
86 // with InitToLast()) is complete.
88  for (int d = FD_DIMSIZE - 1; d >= 0; --d) {
89  if (indices_[d] > 0) {
90  --indices_[d];
91  if (d == FD_BATCH) {
92  // The upper limits of the other dimensions may have changed as a result
93  // of a different batch index, so they have to be reset.
94  InitToLastOfBatch(indices_[FD_BATCH]);
95  } else {
96  t_ -= stride_map_->t_increments_[d];
97  }
98  return true;
99  }
100  indices_[d] = MaxIndexOfDim(static_cast<FlexDimensions>(d));
101  t_ += stride_map_->t_increments_[d] * indices_[d];
102  // Now borrow from the next dimension.
103  }
104  return false;
105 }
106 
107 // Initializes the indices to the last valid location in the given batch
108 // index.
109 void StrideMap::Index::InitToLastOfBatch(int batch) {
110  indices_[FD_BATCH] = batch;
111  for (int d = FD_BATCH + 1; d < FD_DIMSIZE; ++d) {
112  indices_[d] = MaxIndexOfDim(static_cast<FlexDimensions>(d));
113  }
114  SetTFromIndices();
115 }
116 
117 // Computes and sets t_ from the current indices_.
118 void StrideMap::Index::SetTFromIndices() {
119  t_ = 0;
120  for (int d = 0; d < FD_DIMSIZE; ++d) {
121  t_ += stride_map_->t_increments_[d] * indices_[d];
122  }
123 }
124 
125 // Sets up the stride for the given array of height, width pairs.
126 void StrideMap::SetStride(const std::vector<std::pair<int, int>>& h_w_pairs) {
127  int max_height = 0;
128  int max_width = 0;
129  for (const std::pair<int, int>& hw : h_w_pairs) {
130  int height = hw.first;
131  int width = hw.second;
132  heights_.push_back(height);
133  widths_.push_back(width);
134  if (height > max_height) max_height = height;
135  if (width > max_width) max_width = width;
136  }
137  shape_[FD_BATCH] = heights_.size();
138  shape_[FD_HEIGHT] = max_height;
139  shape_[FD_WIDTH] = max_width;
140  ComputeTIncrements();
141 }
142 
143 // Scales width and height dimensions by the given factors.
144 void StrideMap::ScaleXY(int x_factor, int y_factor) {
145  for (int& height : heights_) height /= y_factor;
146  for (int& width : widths_) width /= x_factor;
147  shape_[FD_HEIGHT] /= y_factor;
148  shape_[FD_WIDTH] /= x_factor;
149  ComputeTIncrements();
150 }
151 
152 // Reduces width to 1, across the batch, whatever the input size.
154  widths_.assign(widths_.size(), 1);
155  shape_[FD_WIDTH] = 1;
156  ComputeTIncrements();
157 }
158 
159 // Transposes the width and height dimensions.
161  std::swap(shape_[FD_HEIGHT], shape_[FD_WIDTH]);
162  std::swap(heights_, widths_);
163  ComputeTIncrements();
164 }
165 
166 // Computes t_increments_ from shape_.
167 void StrideMap::ComputeTIncrements() {
168  t_increments_[FD_DIMSIZE - 1] = 1;
169  for (int d = FD_DIMSIZE - 2; d >= 0; --d) {
170  t_increments_[d] = t_increments_[d + 1] * shape_[d + 1];
171  }
172 }
173 
174 } // namespace tesseract
bool AddOffset(int offset, FlexDimensions dimension)
Definition: stridemap.cpp:62
int MaxIndexOfDim(FlexDimensions dim) const
Definition: stridemap.cpp:43
voidpf uLong offset
Definition: ioapi.h:42
FlexDimensions
Definition: stridemap.h:34
bool IsLast(FlexDimensions dimension) const
Definition: stridemap.cpp:37
void ScaleXY(int x_factor, int y_factor)
Definition: stridemap.cpp:144
void SetStride(const std::vector< std::pair< int, int >> &h_w_pairs)
Definition: stridemap.cpp:126