tesseract  4.1.1
matrix.h
Go to the documentation of this file.
1 /* -*-C-*-
2  ******************************************************************************
3  * File: matrix.h
4  * Description: Generic 2-d array/matrix and banded triangular matrix class.
5  * Author: Ray Smith
6  * TODO(rays) Separate from ratings matrix, which it also contains:
7  *
8  * Description: Ratings matrix class (specialization of banded matrix).
9  * Segmentation search matrix of lists of BLOB_CHOICE.
10  * Author: Mark Seaman, OCR Technology
11  * Created: Wed May 16 13:22:06 1990
12  * Modified: Tue Mar 19 16:00:20 1991 (Mark Seaman) marks@hpgrlt
13  *
14  * (c) Copyright 1990, Hewlett-Packard Company.
15  ** Licensed under the Apache License, Version 2.0 (the "License");
16  ** you may not use this file except in compliance with the License.
17  ** You may obtain a copy of the License at
18  ** http://www.apache.org/licenses/LICENSE-2.0
19  ** Unless required by applicable law or agreed to in writing, software
20  ** distributed under the License is distributed on an "AS IS" BASIS,
21  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22  ** See the License for the specific language governing permissions and
23  ** limitations under the License.
24  *
25  *********************************************************************************/
26 
27 #ifndef TESSERACT_CCSTRUCT_MATRIX_H_
28 #define TESSERACT_CCSTRUCT_MATRIX_H_
29 
30 #include <algorithm> // for max, min
31 #include <cmath> // for sqrt, fabs, isfinite
32 #include <cstdint> // for int32_t
33 #include <cstdio> // for FILE
34 #include <cstring> // for memcpy
35 #include "errcode.h" // for ASSERT_HOST
36 #include "helpers.h" // for ReverseN, ClipToRange
37 #include "kdpair.h" // for KDPairInc
38 #include "points.h" // for ICOORD
39 #include "serialis.h" // for TFile
40 
41 class BLOB_CHOICE_LIST;
42 class UNICHARSET;
43 
44 #define NOT_CLASSIFIED static_cast<BLOB_CHOICE_LIST*>(nullptr)
45 
46 // A generic class to hold a 2-D matrix with entries of type T, but can also
47 // act as a base class for other implementations, such as a triangular or
48 // banded matrix.
49 template <class T>
50 class GENERIC_2D_ARRAY {
51  public:
52  // Initializes the array size, and empty element, but cannot allocate memory
53  // for the subclasses or initialize because calls to the num_elements
54  // member will be routed to the base class implementation. Subclasses can
55  // either pass the memory in, or allocate after by calling Resize().
56  GENERIC_2D_ARRAY(int dim1, int dim2, const T& empty, T* array)
57  : empty_(empty), dim1_(dim1), dim2_(dim2), array_(array) {
59  }
60  // Original constructor for a full rectangular matrix DOES allocate memory
61  // and initialize it to empty.
62  GENERIC_2D_ARRAY(int dim1, int dim2, const T& empty)
63  : empty_(empty), dim1_(dim1), dim2_(dim2) {
64  int new_size = dim1 * dim2;
65  array_ = new T[new_size];
66  size_allocated_ = new_size;
67  for (int i = 0; i < size_allocated_; ++i)
68  array_[i] = empty_;
69  }
70  // Default constructor for array allocation. Use Resize to set the size.
72  : array_(nullptr), empty_(static_cast<T>(0)), dim1_(0), dim2_(0),
73  size_allocated_(0) {
74  }
76  : array_(nullptr), empty_(static_cast<T>(0)), dim1_(0), dim2_(0),
77  size_allocated_(0) {
78  *this = src;
79  }
80  virtual ~GENERIC_2D_ARRAY() { delete[] array_; }
81 
82  void operator=(const GENERIC_2D_ARRAY<T>& src) {
83  ResizeNoInit(src.dim1(), src.dim2());
84  int size = num_elements();
85  if (size > 0) {
86  memcpy(array_, src.array_, size * sizeof(array_[0]));
87  }
88  }
89 
90  // Reallocates the array to the given size. Does not keep old data, but does
91  // not initialize the array either.
92  // The allocated memory is expanded on the end by pad, allowing deliberate
93  // access beyond the bounds of the array.
94  void ResizeNoInit(int size1, int size2, int pad = 0) {
95  int new_size = size1 * size2 + pad;
96  if (new_size > size_allocated_) {
97  delete [] array_;
98  array_ = new T[new_size];
99  size_allocated_ = new_size;
100  }
101  dim1_ = size1;
102  dim2_ = size2;
103  // Fill the padding data so it isn't uninitialized.
104  for (int i = size1 * size2; i < new_size; ++i) array_[i] = empty_;
105  }
106 
107  // Reallocate the array to the given size. Does not keep old data.
108  void Resize(int size1, int size2, const T& empty) {
109  empty_ = empty;
110  ResizeNoInit(size1, size2);
111  Clear();
112  }
113 
114  // Reallocate the array to the given size, keeping old data.
115  void ResizeWithCopy(int size1, int size2) {
116  if (size1 != dim1_ || size2 != dim2_) {
117  int new_size = size1 * size2;
118  T* new_array = new T[new_size];
119  for (int col = 0; col < size1; ++col) {
120  for (int row = 0; row < size2; ++row) {
121  int old_index = col * dim2() + row;
122  int new_index = col * size2 + row;
123  if (col < dim1_ && row < dim2_) {
124  new_array[new_index] = array_[old_index];
125  } else {
126  new_array[new_index] = empty_;
127  }
128  }
129  }
130  delete[] array_;
131  array_ = new_array;
132  dim1_ = size1;
133  dim2_ = size2;
134  size_allocated_ = new_size;
135  }
136  }
137 
138  // Sets all the elements of the array to the empty value.
139  void Clear() {
140  int total_size = num_elements();
141  for (int i = 0; i < total_size; ++i)
142  array_[i] = empty_;
143  }
144 
145  // Writes to the given file. Returns false in case of error.
146  // Only works with bitwise-serializeable types!
147  bool Serialize(FILE* fp) const {
148  if (!SerializeSize(fp)) return false;
149  if (!tesseract::Serialize(fp, &empty_)) return false;
150  int size = num_elements();
151  return tesseract::Serialize(fp, &array_[0], size);
152  }
153 
154  bool Serialize(tesseract::TFile* fp) const {
155  if (!SerializeSize(fp)) return false;
156  if (!fp->Serialize(&empty_)) return false;
157  int size = num_elements();
158  return fp->Serialize(&array_[0], size);
159  }
160 
161  // Reads from the given file. Returns false in case of error.
162  // Only works with bitwise-serializeable types!
163  // If swap is true, assumes a big/little-endian swap is needed.
164  bool DeSerialize(bool swap, FILE* fp) {
165  if (!DeSerializeSize(swap, fp)) return false;
166  if (!tesseract::DeSerialize(fp, &empty_)) return false;
167  if (swap) ReverseN(&empty_, sizeof(empty_));
168  int size = num_elements();
169  if (!tesseract::DeSerialize(fp, &array_[0], size)) return false;
170  if (swap) {
171  for (int i = 0; i < size; ++i)
172  ReverseN(&array_[i], sizeof(array_[i]));
173  }
174  return true;
175  }
176 
178  return DeSerializeSize(fp) &&
179  fp->DeSerialize(&empty_) &&
180  fp->DeSerialize(&array_[0], num_elements());
181  }
182 
183  // Writes to the given file. Returns false in case of error.
184  // Assumes a T::Serialize(FILE*) const function.
185  bool SerializeClasses(FILE* fp) const {
186  if (!SerializeSize(fp)) return false;
187  if (!empty_.Serialize(fp)) return false;
188  int size = num_elements();
189  for (int i = 0; i < size; ++i) {
190  if (!array_[i].Serialize(fp)) return false;
191  }
192  return true;
193  }
194 
195  // Reads from the given file. Returns false in case of error.
196  // Assumes a T::DeSerialize(bool swap, FILE*) function.
197  // If swap is true, assumes a big/little-endian swap is needed.
198  bool DeSerializeClasses(bool swap, FILE* fp) {
199  if (!DeSerializeSize(swap, fp)) return false;
200  if (!empty_.DeSerialize(swap, fp)) return false;
201  int size = num_elements();
202  for (int i = 0; i < size; ++i) {
203  if (!array_[i].DeSerialize(swap, fp)) return false;
204  }
205  return true;
206  }
207 
208  // Provide the dimensions of this rectangular matrix.
209  int dim1() const { return dim1_; }
210  int dim2() const { return dim2_; }
211  // Returns the number of elements in the array.
212  // Banded/triangular matrices may override.
213  virtual int num_elements() const { return dim1_ * dim2_; }
214 
215  // Expression to select a specific location in the matrix. The matrix is
216  // stored COLUMN-major, so the left-most index is the most significant.
217  // This allows [][] access to use indices in the same order as (,).
218  virtual int index(int column, int row) const {
219  return (column * dim2_ + row);
220  }
221 
222  // Put a list element into the matrix at a specific location.
223  void put(ICOORD pos, const T& thing) {
224  array_[this->index(pos.x(), pos.y())] = thing;
225  }
226  void put(int column, int row, const T& thing) {
227  array_[this->index(column, row)] = thing;
228  }
229 
230  // Get the item at a specified location from the matrix.
231  T get(ICOORD pos) const {
232  return array_[this->index(pos.x(), pos.y())];
233  }
234  T get(int column, int row) const {
235  return array_[this->index(column, row)];
236  }
237  // Return a reference to the element at the specified location.
238  const T& operator()(int column, int row) const {
239  return array_[this->index(column, row)];
240  }
241  T& operator()(int column, int row) {
242  return array_[this->index(column, row)];
243  }
244  // Allow access using array[column][row]. NOTE that the indices are
245  // in the same left-to-right order as the () indexing.
246  T* operator[](int column) {
247  return &array_[this->index(column, 0)];
248  }
249  const T* operator[](int column) const {
250  return &array_[this->index(column, 0)];
251  }
252 
253  // Adds addend to *this, element-by-element.
254  void operator+=(const GENERIC_2D_ARRAY<T>& addend) {
255  if (dim2_ == addend.dim2_) {
256  // Faster if equal size in the major dimension.
257  int size = std::min(num_elements(), addend.num_elements());
258  for (int i = 0; i < size; ++i) {
259  array_[i] += addend.array_[i];
260  }
261  } else {
262  for (int x = 0; x < dim1_; x++) {
263  for (int y = 0; y < dim2_; y++) {
264  (*this)(x, y) += addend(x, y);
265  }
266  }
267  }
268  }
269  // Subtracts minuend from *this, element-by-element.
270  void operator-=(const GENERIC_2D_ARRAY<T>& minuend) {
271  if (dim2_ == minuend.dim2_) {
272  // Faster if equal size in the major dimension.
273  int size = std::min(num_elements(), minuend.num_elements());
274  for (int i = 0; i < size; ++i) {
275  array_[i] -= minuend.array_[i];
276  }
277  } else {
278  for (int x = 0; x < dim1_; x++) {
279  for (int y = 0; y < dim2_; y++) {
280  (*this)(x, y) -= minuend(x, y);
281  }
282  }
283  }
284  }
285  // Adds addend to all elements.
286  void operator+=(const T& addend) {
287  int size = num_elements();
288  for (int i = 0; i < size; ++i) {
289  array_[i] += addend;
290  }
291  }
292  // Multiplies *this by factor, element-by-element.
293  void operator*=(const T& factor) {
294  int size = num_elements();
295  for (int i = 0; i < size; ++i) {
296  array_[i] *= factor;
297  }
298  }
299  // Clips *this to the given range.
300  void Clip(const T& rangemin, const T& rangemax) {
301  int size = num_elements();
302  for (int i = 0; i < size; ++i) {
303  array_[i] = ClipToRange(array_[i], rangemin, rangemax);
304  }
305  }
306  // Returns true if all elements of *this are within the given range.
307  // Only uses operator<
308  bool WithinBounds(const T& rangemin, const T& rangemax) const {
309  int size = num_elements();
310  for (int i = 0; i < size; ++i) {
311  const T& value = array_[i];
312  if (value < rangemin || rangemax < value)
313  return false;
314  }
315  return true;
316  }
317  // Normalize the whole array.
318  double Normalize() {
319  int size = num_elements();
320  if (size <= 0) return 0.0;
321  // Compute the mean.
322  double mean = 0.0;
323  for (int i = 0; i < size; ++i) {
324  mean += array_[i];
325  }
326  mean /= size;
327  // Subtract the mean and compute the standard deviation.
328  double sd = 0.0;
329  for (int i = 0; i < size; ++i) {
330  double normed = array_[i] - mean;
331  array_[i] = normed;
332  sd += normed * normed;
333  }
334  sd = sqrt(sd / size);
335  if (sd > 0.0) {
336  // Divide by the sd.
337  for (int i = 0; i < size; ++i) {
338  array_[i] /= sd;
339  }
340  }
341  return sd;
342  }
343 
344  // Returns the maximum value of the array.
345  T Max() const {
346  int size = num_elements();
347  if (size <= 0) return empty_;
348  // Compute the max.
349  T max_value = array_[0];
350  for (int i = 1; i < size; ++i) {
351  const T& value = array_[i];
352  if (value > max_value) max_value = value;
353  }
354  return max_value;
355  }
356 
357  // Returns the maximum absolute value of the array.
358  T MaxAbs() const {
359  int size = num_elements();
360  if (size <= 0) return empty_;
361  // Compute the max.
362  T max_abs = static_cast<T>(0);
363  for (int i = 0; i < size; ++i) {
364  T value = static_cast<T>(fabs(array_[i]));
365  if (value > max_abs) max_abs = value;
366  }
367  return max_abs;
368  }
369 
370  // Accumulates the element-wise sums of squares of src into *this.
371  void SumSquares(const GENERIC_2D_ARRAY<T>& src, const T& decay_factor) {
372  T update_factor = 1.0 - decay_factor;
373  int size = num_elements();
374  for (int i = 0; i < size; ++i) {
375  array_[i] = array_[i] * decay_factor +
376  update_factor * src.array_[i] * src.array_[i];
377  }
378  }
379 
380  // Scales each element using the adam algorithm, ie array_[i] by
381  // sqrt(sqsum[i] + epsilon)).
383  const GENERIC_2D_ARRAY<T>& sqsum, const T& epsilon) {
384  int size = num_elements();
385  for (int i = 0; i < size; ++i) {
386  array_[i] += sum.array_[i] / (sqrt(sqsum.array_[i]) + epsilon);
387  }
388  }
389 
390  void AssertFinite() const {
391  int size = num_elements();
392  for (int i = 0; i < size; ++i) {
393  ASSERT_HOST(isfinite(array_[i]));
394  }
395  }
396 
397  // REGARDLESS OF THE CURRENT DIMENSIONS, treats the data as a
398  // num_dims-dimensional array/tensor with dimensions given by dims, (ordered
399  // from most significant to least significant, the same as standard C arrays)
400  // and moves src_dim to dest_dim, with the initial dest_dim and any dimensions
401  // in between shifted towards the hole left by src_dim. Example:
402  // Current data content: array_=[0, 1, 2, ....119]
403  // perhaps *this may be of dim[40, 3], with values [[0, 1, 2][3, 4, 5]...
404  // but the current dimensions are irrelevant.
405  // num_dims = 4, dims=[5, 4, 3, 2]
406  // src_dim=3, dest_dim=1
407  // tensor=[[[[0, 1][2, 3][4, 5]]
408  // [[6, 7][8, 9][10, 11]]
409  // [[12, 13][14, 15][16, 17]]
410  // [[18, 19][20, 21][22, 23]]]
411  // [[[24, 25]...
412  // output dims =[5, 2, 4, 3]
413  // output tensor=[[[[0, 2, 4][6, 8, 10][12, 14, 16][18, 20, 22]]
414  // [[1, 3, 5][7, 9, 11][13, 15, 17][19, 21, 23]]]
415  // [[[24, 26, 28]...
416  // which is stored in the array_ as:
417  // [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 1, 3, 5, 7, 9, 11, 13...]
418  // NOTE: the 2 stored matrix dimensions are simply copied from *this. To
419  // change the dimensions after the transpose, use ResizeNoInit.
420  // Higher dimensions above 2 are strictly the responsibility of the caller.
421  void RotatingTranspose(const int* dims, int num_dims, int src_dim,
422  int dest_dim, GENERIC_2D_ARRAY<T>* result) const {
423  int max_d = std::max(src_dim, dest_dim);
424  int min_d = std::min(src_dim, dest_dim);
425  // In a tensor of shape [d0, d1... min_d, ... max_d, ... dn-2, dn-1], the
426  // ends outside of min_d and max_d are unaffected, with [max_d +1, dn-1]
427  // being contiguous blocks of data that will move together, and
428  // [d0, min_d -1] being replicas of the transpose operation.
429  // num_replicas represents the large dimensions unchanged by the operation.
430  // move_size represents the small dimensions unchanged by the operation.
431  // src_step represents the stride in the src between each adjacent group
432  // in the destination.
433  int num_replicas = 1, move_size = 1, src_step = 1;
434  for (int d = 0; d < min_d; ++d) num_replicas *= dims[d];
435  for (int d = max_d + 1; d < num_dims; ++d) move_size *= dims[d];
436  for (int d = src_dim + 1; d < num_dims; ++d) src_step *= dims[d];
437  if (src_dim > dest_dim) src_step *= dims[src_dim];
438  // wrap_size is the size of a single replica, being the amount that is
439  // handled num_replicas times.
440  int wrap_size = move_size;
441  for (int d = min_d; d <= max_d; ++d) wrap_size *= dims[d];
442  result->ResizeNoInit(dim1_, dim2_);
443  result->empty_ = empty_;
444  const T* src = array_;
445  T* dest = result->array_;
446  for (int replica = 0; replica < num_replicas; ++replica) {
447  for (int start = 0; start < src_step; start += move_size) {
448  for (int pos = start; pos < wrap_size; pos += src_step) {
449  memcpy(dest, src + pos, sizeof(*dest) * move_size);
450  dest += move_size;
451  }
452  }
453  src += wrap_size;
454  }
455  }
456 
457  // Delete objects pointed to by array_[i].
459  int size = num_elements();
460  for (int i = 0; i < size; ++i) {
461  T matrix_cell = array_[i];
462  if (matrix_cell != empty_)
463  delete matrix_cell;
464  }
465  }
466 
467  protected:
468  // Factored helper to serialize the size.
469  bool SerializeSize(FILE* fp) const {
470  uint32_t size = dim1_;
471  if (!tesseract::Serialize(fp, &size)) return false;
472  size = dim2_;
473  return tesseract::Serialize(fp, &size);
474  }
475  bool SerializeSize(tesseract::TFile* fp) const {
476  uint32_t size = dim1_;
477  if (!fp->Serialize(&size)) return false;
478  size = dim2_;
479  return fp->Serialize(&size);
480  }
481  // Factored helper to deserialize the size.
482  // If swap is true, assumes a big/little-endian swap is needed.
483  bool DeSerializeSize(bool swap, FILE* fp) {
484  uint32_t size1, size2;
485  if (!tesseract::DeSerialize(fp, &size1)) return false;
486  if (!tesseract::DeSerialize(fp, &size2)) return false;
487  if (swap) {
488  ReverseN(&size1, sizeof(size1));
489  ReverseN(&size2, sizeof(size2));
490  }
491  // Arbitrarily limit the number of elements to protect against bad data.
492  if (size1 > UINT16_MAX) return false;
493  if (size2 > UINT16_MAX) return false;
494  Resize(size1, size2, empty_);
495  return true;
496  }
498  int32_t size1, size2;
499  if (!fp->DeSerialize(&size1)) return false;
500  if (!fp->DeSerialize(&size2)) return false;
501  // Arbitrarily limit the number of elements to protect against bad data.
502  if (size1 > UINT16_MAX) return false;
503  if (size2 > UINT16_MAX) return false;
504  Resize(size1, size2, empty_);
505  return true;
506  }
507 
508  T* array_;
509  T empty_; // The unused cell.
510  int dim1_; // Size of the 1st dimension in indexing functions.
511  int dim2_; // Size of the 2nd dimension in indexing functions.
512  // The total size to which the array can be expanded before a realloc is
513  // needed. If Resize is used, memory is retained so it can be re-expanded
514  // without a further alloc, and this stores the allocated size.
516 };
517 
518 // A generic class to store a banded triangular matrix with entries of type T.
519 // In this array, the nominally square matrix is dim1_ x dim1_, and dim2_ is
520 // the number of bands, INCLUDING the diagonal. The storage is thus of size
521 // dim1_ * dim2_ and index(col, row) = col * dim2_ + row - col, and an
522 // assert will fail if row < col or row - col >= dim2.
523 template <class T>
524 class BandTriMatrix : public GENERIC_2D_ARRAY<T> {
525  public:
526  // Allocate a piece of memory to hold a 2d-array of the given dimension.
527  // Initialize all the elements of the array to empty instead of assuming
528  // that a default constructor can be used.
529  BandTriMatrix(int dim1, int dim2, const T& empty)
530  : GENERIC_2D_ARRAY<T>(dim1, dim2, empty) {
531  }
532  // The default destructor will do.
533 
534  // Provide the dimensions of this matrix.
535  // dimension is the size of the nominally square matrix.
536  int dimension() const { return this->dim1_; }
537  // bandwidth is the number of bands in the matrix, INCLUDING the diagonal.
538  int bandwidth() const { return this->dim2_; }
539 
540  // Expression to select a specific location in the matrix. The matrix is
541  // stored COLUMN-major, so the left-most index is the most significant.
542  // This allows [][] access to use indices in the same order as (,).
543  int index(int column, int row) const override {
544  ASSERT_HOST(row >= column);
545  ASSERT_HOST(row - column < this->dim2_);
546  return column * this->dim2_ + row - column;
547  }
548 
549  // Appends array2 corner-to-corner to *this, making an array of dimension
550  // equal to the sum of the individual dimensions.
551  // array2 is not destroyed, but is left empty, as all elements are moved
552  // to *this.
554  int new_dim1 = this->dim1_ + array2->dim1_;
555  int new_dim2 = std::max(this->dim2_, array2->dim2_);
556  T* new_array = new T[new_dim1 * new_dim2];
557  for (int col = 0; col < new_dim1; ++col) {
558  for (int j = 0; j < new_dim2; ++j) {
559  int new_index = col * new_dim2 + j;
560  if (col < this->dim1_ && j < this->dim2_) {
561  new_array[new_index] = this->get(col, col + j);
562  } else if (col >= this->dim1_ && j < array2->dim2_) {
563  new_array[new_index] = array2->get(col - this->dim1_,
564  col - this->dim1_ + j);
565  array2->put(col - this->dim1_, col - this->dim1_ + j, nullptr);
566  } else {
567  new_array[new_index] = this->empty_;
568  }
569  }
570  }
571  delete[] this->array_;
572  this->array_ = new_array;
573  this->dim1_ = new_dim1;
574  this->dim2_ = new_dim2;
575  }
576 };
577 
578 class MATRIX : public BandTriMatrix<BLOB_CHOICE_LIST *> {
579  public:
581  : BandTriMatrix<BLOB_CHOICE_LIST *>(dimension, bandwidth, NOT_CLASSIFIED) {}
582 
583  ~MATRIX() override;
584 
585  // Returns true if there are any real classification results.
586  bool Classified(int col, int row, int wildcard_id) const;
587 
588  // Expands the existing matrix in-place to make the band wider, without
589  // losing any existing data.
590  void IncreaseBandSize(int bandwidth);
591 
592  // Returns a bigger MATRIX with a new column and row in the matrix in order
593  // to split the blob at the given (ind,ind) diagonal location.
594  // Entries are relocated to the new MATRIX using the transformation defined
595  // by MATRIX_COORD::MapForSplit.
596  // Transfers the pointer data to the new MATRIX and deletes *this.
597  MATRIX* ConsumeAndMakeBigger(int ind);
598 
599  // Makes and returns a deep copy of *this, including all the BLOB_CHOICEs
600  // on the lists, but not any LanguageModelState that may be attached to the
601  // BLOB_CHOICEs.
602  MATRIX* DeepCopy() const;
603 
604  // Print a shortened version of the contents of the matrix.
605  void print(const UNICHARSET &unicharset) const;
606 };
607 
608 struct MATRIX_COORD {
609  static void Delete(void *arg) {
610  auto *c = static_cast<MATRIX_COORD *>(arg);
611  delete c;
612  }
613  // Default constructor required by GenericHeap.
614  MATRIX_COORD() : col(0), row(0) {}
615  MATRIX_COORD(int c, int r): col(c), row(r) {}
617 
618  bool Valid(const MATRIX &m) const {
619  return 0 <= col && col < m.dimension() &&
620  col <= row && row < col + m.bandwidth() && row < m.dimension();
621  }
622 
623  // Remaps the col,row pair to split the blob at the given (ind,ind) diagonal
624  // location.
625  // Entries at (i,j) for i in [0,ind] and j in [ind,dim) move to (i,j+1),
626  // making a new row at ind.
627  // Entries at (i,j) for i in [ind+1,dim) and j in [i,dim) move to (i+i,j+1),
628  // making a new column at ind+1.
629  void MapForSplit(int ind) {
630  ASSERT_HOST(row >= col);
631  if (col > ind) ++col;
632  if (row >= ind) ++row;
633  ASSERT_HOST(row >= col);
634  }
635 
636  int col;
637  int row;
638 };
639 
640 // The MatrixCoordPair contains a MATRIX_COORD and its priority.
642 
643 #endif // TESSERACT_CCSTRUCT_MATRIX_H_
GENERIC_2D_ARRAY::operator[]
const T * operator[](int column) const
Definition: matrix.h:249
GENERIC_2D_ARRAY::DeSerializeSize
bool DeSerializeSize(bool swap, FILE *fp)
Definition: matrix.h:483
GENERIC_2D_ARRAY::num_elements
virtual int num_elements() const
Definition: matrix.h:213
GENERIC_2D_ARRAY::SerializeSize
bool SerializeSize(FILE *fp) const
Definition: matrix.h:469
MATRIX_COORD::col
int col
Definition: matrix.h:636
BandTriMatrix::BandTriMatrix
BandTriMatrix(int dim1, int dim2, const T &empty)
Definition: matrix.h:529
BandTriMatrix::bandwidth
int bandwidth() const
Definition: matrix.h:538
MATRIX::MATRIX
MATRIX(int dimension, int bandwidth)
Definition: matrix.h:580
tesstrain_utils.dest
dest
Definition: tesstrain_utils.py:139
MATRIX_COORD
Definition: matrix.h:608
kdpair.h
GENERIC_2D_ARRAY::empty_
T empty_
Definition: matrix.h:509
MATRIX_COORD::MATRIX_COORD
MATRIX_COORD()
Definition: matrix.h:614
tesseract::KDPairInc
Definition: kdpair.h:51
GENERIC_2D_ARRAY::operator*=
void operator*=(const T &factor)
Definition: matrix.h:293
MATRIX_COORD::MapForSplit
void MapForSplit(int ind)
Definition: matrix.h:629
MATRIX::print
void print(const UNICHARSET &unicharset) const
Definition: matrix.cpp:112
MATRIX_COORD::Valid
bool Valid(const MATRIX &m) const
Definition: matrix.h:618
serialis.h
GENERIC_2D_ARRAY::delete_matrix_pointers
void delete_matrix_pointers()
Definition: matrix.h:458
tesseract::TFile::DeSerialize
bool DeSerialize(char *data, size_t count=1)
Definition: serialis.cpp:121
MATRIX::DeepCopy
MATRIX * DeepCopy() const
Definition: matrix.cpp:94
MATRIX_COORD::row
int row
Definition: matrix.h:637
BandTriMatrix::AttachOnCorner
void AttachOnCorner(BandTriMatrix< T > *array2)
Definition: matrix.h:553
GENERIC_2D_ARRAY::dim2
int dim2() const
Definition: matrix.h:210
ICOORD::y
int16_t y() const
access_function
Definition: points.h:56
GENERIC_2D_ARRAY::operator()
T & operator()(int column, int row)
Definition: matrix.h:241
GENERIC_2D_ARRAY::Max
T Max() const
Definition: matrix.h:345
ClipToRange
T ClipToRange(const T &x, const T &lower_bound, const T &upper_bound)
Definition: helpers.h:108
GENERIC_2D_ARRAY::ResizeWithCopy
void ResizeWithCopy(int size1, int size2)
Definition: matrix.h:115
MATRIX::IncreaseBandSize
void IncreaseBandSize(int bandwidth)
Definition: matrix.cpp:49
GENERIC_2D_ARRAY::Serialize
bool Serialize(FILE *fp) const
Definition: matrix.h:147
GENERIC_2D_ARRAY::SerializeClasses
bool SerializeClasses(FILE *fp) const
Definition: matrix.h:185
ASSERT_HOST
#define ASSERT_HOST(x)
Definition: errcode.h:88
MATRIX_COORD::Delete
static void Delete(void *arg)
Definition: matrix.h:609
MATRIX::Classified
bool Classified(int col, int row, int wildcard_id) const
Definition: matrix.cpp:36
GENERIC_2D_ARRAY::SumSquares
void SumSquares(const GENERIC_2D_ARRAY< T > &src, const T &decay_factor)
Definition: matrix.h:371
GENERIC_2D_ARRAY::~GENERIC_2D_ARRAY
virtual ~GENERIC_2D_ARRAY()
Definition: matrix.h:80
ICOORD
integer coordinate
Definition: points.h:32
GENERIC_2D_ARRAY::dim1
int dim1() const
Definition: matrix.h:209
MATRIX::~MATRIX
~MATRIX() override
helpers.h
tesseract::Serialize
bool Serialize(FILE *fp, const char *data, size_t n)
Definition: serialis.cpp:77
MATRIX_COORD::~MATRIX_COORD
~MATRIX_COORD()
Definition: matrix.h:616
GENERIC_2D_ARRAY::WithinBounds
bool WithinBounds(const T &rangemin, const T &rangemax) const
Definition: matrix.h:308
MATRIX_COORD::MATRIX_COORD
MATRIX_COORD(int c, int r)
Definition: matrix.h:615
GENERIC_2D_ARRAY::DeSerializeClasses
bool DeSerializeClasses(bool swap, FILE *fp)
Definition: matrix.h:198
GENERIC_2D_ARRAY::operator=
void operator=(const GENERIC_2D_ARRAY< T > &src)
Definition: matrix.h:82
GENERIC_2D_ARRAY::Resize
void Resize(int size1, int size2, const T &empty)
Definition: matrix.h:108
GENERIC_2D_ARRAY::put
void put(ICOORD pos, const T &thing)
Definition: matrix.h:223
GENERIC_2D_ARRAY::index
virtual int index(int column, int row) const
Definition: matrix.h:218
GENERIC_2D_ARRAY::operator+=
void operator+=(const T &addend)
Definition: matrix.h:286
GENERIC_2D_ARRAY::Clear
void Clear()
Definition: matrix.h:139
GENERIC_2D_ARRAY::SerializeSize
bool SerializeSize(tesseract::TFile *fp) const
Definition: matrix.h:475
GENERIC_2D_ARRAY::DeSerialize
bool DeSerialize(bool swap, FILE *fp)
Definition: matrix.h:164
BandTriMatrix::dimension
int dimension() const
Definition: matrix.h:536
BandTriMatrix::index
int index(int column, int row) const override
Definition: matrix.h:543
MATRIX::ConsumeAndMakeBigger
MATRIX * ConsumeAndMakeBigger(int ind)
Definition: matrix.cpp:58
GENERIC_2D_ARRAY::Normalize
double Normalize()
Definition: matrix.h:318
GENERIC_2D_ARRAY::operator-=
void operator-=(const GENERIC_2D_ARRAY< T > &minuend)
Definition: matrix.h:270
GENERIC_2D_ARRAY::operator()
const T & operator()(int column, int row) const
Definition: matrix.h:238
tesseract::TFile::Serialize
bool Serialize(const char *data, size_t count=1)
Definition: serialis.cpp:165
GENERIC_2D_ARRAY::get
T get(int column, int row) const
Definition: matrix.h:234
MATRIX
Definition: matrix.h:578
GENERIC_2D_ARRAY::GENERIC_2D_ARRAY
GENERIC_2D_ARRAY()
Definition: matrix.h:71
GENERIC_2D_ARRAY::ResizeNoInit
void ResizeNoInit(int size1, int size2, int pad=0)
Definition: matrix.h:94
tesseract::DeSerialize
bool DeSerialize(FILE *fp, char *data, size_t n)
Definition: serialis.cpp:45
NOT_CLASSIFIED
#define NOT_CLASSIFIED
Definition: matrix.h:44
GENERIC_2D_ARRAY::Clip
void Clip(const T &rangemin, const T &rangemax)
Definition: matrix.h:300
GENERIC_2D_ARRAY::size_allocated_
int size_allocated_
Definition: matrix.h:515
GENERIC_2D_ARRAY::dim2_
int dim2_
Definition: matrix.h:511
GENERIC_2D_ARRAY::DeSerialize
bool DeSerialize(tesseract::TFile *fp)
Definition: matrix.h:177
GENERIC_2D_ARRAY::GENERIC_2D_ARRAY
GENERIC_2D_ARRAY(const GENERIC_2D_ARRAY< T > &src)
Definition: matrix.h:75
GENERIC_2D_ARRAY::GENERIC_2D_ARRAY
GENERIC_2D_ARRAY(int dim1, int dim2, const T &empty, T *array)
Definition: matrix.h:56
errcode.h
ReverseN
void ReverseN(void *ptr, int num_bytes)
Definition: helpers.h:185
GENERIC_2D_ARRAY::array_
T * array_
Definition: matrix.h:508
GENERIC_2D_ARRAY
Definition: intsimdmatrix.h:26
GENERIC_2D_ARRAY::get
T get(ICOORD pos) const
Definition: matrix.h:231
GENERIC_2D_ARRAY::operator[]
T * operator[](int column)
Definition: matrix.h:246
points.h
GENERIC_2D_ARRAY::MaxAbs
T MaxAbs() const
Definition: matrix.h:358
GENERIC_2D_ARRAY::DeSerializeSize
bool DeSerializeSize(tesseract::TFile *fp)
Definition: matrix.h:497
GENERIC_2D_ARRAY::AssertFinite
void AssertFinite() const
Definition: matrix.h:390
GENERIC_2D_ARRAY::put
void put(int column, int row, const T &thing)
Definition: matrix.h:226
GENERIC_2D_ARRAY::Serialize
bool Serialize(tesseract::TFile *fp) const
Definition: matrix.h:154
tesseract::TFile
Definition: serialis.h:76
GENERIC_2D_ARRAY::operator+=
void operator+=(const GENERIC_2D_ARRAY< T > &addend)
Definition: matrix.h:254
GENERIC_2D_ARRAY::dim1_
int dim1_
Definition: matrix.h:510
ICOORD::x
int16_t x() const
access function
Definition: points.h:52
UNICHARSET
Definition: unicharset.h:145
GENERIC_2D_ARRAY::AdamUpdate
void AdamUpdate(const GENERIC_2D_ARRAY< T > &sum, const GENERIC_2D_ARRAY< T > &sqsum, const T &epsilon)
Definition: matrix.h:382
GENERIC_2D_ARRAY::GENERIC_2D_ARRAY
GENERIC_2D_ARRAY(int dim1, int dim2, const T &empty)
Definition: matrix.h:62
BandTriMatrix
Definition: matrix.h:524
GENERIC_2D_ARRAY::RotatingTranspose
void RotatingTranspose(const int *dims, int num_dims, int src_dim, int dest_dim, GENERIC_2D_ARRAY< T > *result) const
Definition: matrix.h:421