tesseract 4.1.1
Loading...
Searching...
No Matches
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
41class BLOB_CHOICE_LIST;
42class 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.
49template <class T>
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),
74 }
76 : array_(nullptr), empty_(static_cast<T>(0)), dim1_(0), dim2_(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 }
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
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.
523template <class 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
578class 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.
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
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_
#define NOT_CLASSIFIED
Definition: matrix.h:44
#define ASSERT_HOST(x)
Definition: errcode.h:88
void ReverseN(void *ptr, int num_bytes)
Definition: helpers.h:185
T ClipToRange(const T &x, const T &lower_bound, const T &upper_bound)
Definition: helpers.h:108
bool DeSerialize(FILE *fp, char *data, size_t n)
Definition: serialis.cpp:28
bool Serialize(FILE *fp, const char *data, size_t n)
Definition: serialis.cpp:60
void operator+=(const GENERIC_2D_ARRAY< T > &addend)
Definition: matrix.h:254
GENERIC_2D_ARRAY(int dim1, int dim2, const T &empty)
Definition: matrix.h:62
void operator-=(const GENERIC_2D_ARRAY< T > &minuend)
Definition: matrix.h:270
void operator+=(const T &addend)
Definition: matrix.h:286
void SumSquares(const GENERIC_2D_ARRAY< T > &src, const T &decay_factor)
Definition: matrix.h:371
bool DeSerializeSize(tesseract::TFile *fp)
Definition: matrix.h:497
bool Serialize(FILE *fp) const
Definition: matrix.h:147
int dim2() const
Definition: matrix.h:210
void delete_matrix_pointers()
Definition: matrix.h:458
virtual int index(int column, int row) const
Definition: matrix.h:218
void operator*=(const T &factor)
Definition: matrix.h:293
bool DeSerializeSize(bool swap, FILE *fp)
Definition: matrix.h:483
bool DeSerializeClasses(bool swap, FILE *fp)
Definition: matrix.h:198
GENERIC_2D_ARRAY(const GENERIC_2D_ARRAY< T > &src)
Definition: matrix.h:75
const T & operator()(int column, int row) const
Definition: matrix.h:238
bool WithinBounds(const T &rangemin, const T &rangemax) const
Definition: matrix.h:308
void Clear()
Definition: matrix.h:139
bool DeSerialize(bool swap, FILE *fp)
Definition: matrix.h:164
void AdamUpdate(const GENERIC_2D_ARRAY< T > &sum, const GENERIC_2D_ARRAY< T > &sqsum, const T &epsilon)
Definition: matrix.h:382
void put(int column, int row, const T &thing)
Definition: matrix.h:226
T MaxAbs() const
Definition: matrix.h:358
void operator=(const GENERIC_2D_ARRAY< T > &src)
Definition: matrix.h:82
virtual int num_elements() const
Definition: matrix.h:213
GENERIC_2D_ARRAY(int dim1, int dim2, const T &empty, T *array)
Definition: matrix.h:56
T Max() const
Definition: matrix.h:345
void ResizeWithCopy(int size1, int size2)
Definition: matrix.h:115
void RotatingTranspose(const int *dims, int num_dims, int src_dim, int dest_dim, GENERIC_2D_ARRAY< T > *result) const
Definition: matrix.h:421
bool DeSerialize(tesseract::TFile *fp)
Definition: matrix.h:177
bool Serialize(tesseract::TFile *fp) const
Definition: matrix.h:154
T & operator()(int column, int row)
Definition: matrix.h:241
T get(ICOORD pos) const
Definition: matrix.h:231
const T * operator[](int column) const
Definition: matrix.h:249
T * operator[](int column)
Definition: matrix.h:246
void AssertFinite() const
Definition: matrix.h:390
bool SerializeSize(FILE *fp) const
Definition: matrix.h:469
void put(ICOORD pos, const T &thing)
Definition: matrix.h:223
bool SerializeSize(tesseract::TFile *fp) const
Definition: matrix.h:475
void Resize(int size1, int size2, const T &empty)
Definition: matrix.h:108
double Normalize()
Definition: matrix.h:318
GENERIC_2D_ARRAY()
Definition: matrix.h:71
int dim1() const
Definition: matrix.h:209
T get(int column, int row) const
Definition: matrix.h:234
int size_allocated_
Definition: matrix.h:515
virtual ~GENERIC_2D_ARRAY()
Definition: matrix.h:80
void ResizeNoInit(int size1, int size2, int pad=0)
Definition: matrix.h:94
bool SerializeClasses(FILE *fp) const
Definition: matrix.h:185
void Clip(const T &rangemin, const T &rangemax)
Definition: matrix.h:300
void AttachOnCorner(BandTriMatrix< T > *array2)
Definition: matrix.h:553
int index(int column, int row) const override
Definition: matrix.h:543
int bandwidth() const
Definition: matrix.h:538
BandTriMatrix(int dim1, int dim2, const T &empty)
Definition: matrix.h:529
int dimension() const
Definition: matrix.h:536
Definition: matrix.h:578
void print(const UNICHARSET &unicharset) const
Definition: matrix.cpp:112
bool Classified(int col, int row, int wildcard_id) const
Definition: matrix.cpp:36
MATRIX(int dimension, int bandwidth)
Definition: matrix.h:580
void IncreaseBandSize(int bandwidth)
Definition: matrix.cpp:49
MATRIX * DeepCopy() const
Definition: matrix.cpp:94
MATRIX * ConsumeAndMakeBigger(int ind)
Definition: matrix.cpp:58
~MATRIX() override
void MapForSplit(int ind)
Definition: matrix.h:629
MATRIX_COORD()
Definition: matrix.h:614
static void Delete(void *arg)
Definition: matrix.h:609
~MATRIX_COORD()
Definition: matrix.h:616
MATRIX_COORD(int c, int r)
Definition: matrix.h:615
bool Valid(const MATRIX &m) const
Definition: matrix.h:618
integer coordinate
Definition: points.h:32
int16_t y() const
access_function
Definition: points.h:56
int16_t x() const
access function
Definition: points.h:52
bool Serialize(const char *data, size_t count=1)
Definition: serialis.cpp:148
bool DeSerialize(char *data, size_t count=1)
Definition: serialis.cpp:104