Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/tesseract/src/ccstruct/quadlsq.cpp @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /********************************************************************** | |
| 2 * File: quadlsq.cpp (Formerly qlsq.c) | |
| 3 * Description: Code for least squares approximation of quadratics. | |
| 4 * Author: Ray Smith | |
| 5 * | |
| 6 * (C) Copyright 1993, Hewlett-Packard Ltd. | |
| 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. | |
| 16 * | |
| 17 **********************************************************************/ | |
| 18 | |
| 19 #include "quadlsq.h" | |
| 20 | |
| 21 #include "tprintf.h" | |
| 22 | |
| 23 #include <cmath> | |
| 24 #include <cstdio> | |
| 25 | |
| 26 namespace tesseract { | |
| 27 | |
| 28 // Minimum variance in least squares before backing off to a lower degree. | |
| 29 const long double kMinVariance = 1.0L / 1024; | |
| 30 | |
| 31 /********************************************************************** | |
| 32 * QLSQ::clear | |
| 33 * | |
| 34 * Function to initialize a QLSQ. | |
| 35 **********************************************************************/ | |
| 36 | |
| 37 void QLSQ::clear() { // initialize | |
| 38 a = 0.0; | |
| 39 b = 0.0; | |
| 40 c = 0.0; | |
| 41 n = 0; // No elements. | |
| 42 sigx = 0.0; // Zero accumulators. | |
| 43 sigy = 0.0; | |
| 44 sigxx = 0.0; | |
| 45 sigxy = 0.0; | |
| 46 sigyy = 0.0; | |
| 47 sigxxx = 0.0; | |
| 48 sigxxy = 0.0; | |
| 49 sigxxxx = 0.0; | |
| 50 } | |
| 51 | |
| 52 /********************************************************************** | |
| 53 * QLSQ::add | |
| 54 * | |
| 55 * Add an element to the accumulator. | |
| 56 **********************************************************************/ | |
| 57 | |
| 58 void QLSQ::add(double x, double y) { | |
| 59 n++; // Count elements. | |
| 60 sigx += x; // Update accumulators. | |
| 61 sigy += y; | |
| 62 sigxx += x * x; | |
| 63 sigxy += x * y; | |
| 64 sigyy += y * y; | |
| 65 sigxxx += static_cast<long double>(x) * x * x; | |
| 66 sigxxy += static_cast<long double>(x) * x * y; | |
| 67 sigxxxx += static_cast<long double>(x) * x * x * x; | |
| 68 } | |
| 69 | |
| 70 /********************************************************************** | |
| 71 * QLSQ::remove | |
| 72 * | |
| 73 * Delete an element from the accumulator. | |
| 74 **********************************************************************/ | |
| 75 | |
| 76 void QLSQ::remove(double x, double y) { | |
| 77 if (n <= 0) { | |
| 78 tprintf("Can't remove an element from an empty QLSQ accumulator!\n"); | |
| 79 return; | |
| 80 } | |
| 81 n--; // Count elements. | |
| 82 sigx -= x; // Update accumulators. | |
| 83 sigy -= y; | |
| 84 sigxx -= x * x; | |
| 85 sigxy -= x * y; | |
| 86 sigyy -= y * y; | |
| 87 sigxxx -= static_cast<long double>(x) * x * x; | |
| 88 sigxxy -= static_cast<long double>(x) * x * y; | |
| 89 sigxxxx -= static_cast<long double>(x) * x * x * x; | |
| 90 } | |
| 91 | |
| 92 /********************************************************************** | |
| 93 * QLSQ::fit | |
| 94 * | |
| 95 * Fit the given degree of polynomial and store the result. | |
| 96 * This creates a quadratic of the form axx + bx + c, but limited to | |
| 97 * the given degree. | |
| 98 **********************************************************************/ | |
| 99 | |
| 100 void QLSQ::fit(int degree) { | |
| 101 long double x_variance = | |
| 102 static_cast<long double>(sigxx) * n - static_cast<long double>(sigx) * sigx; | |
| 103 | |
| 104 // Note: for computational efficiency, we do not normalize the variance, | |
| 105 // covariance and cube variance here as they are in the same order in both | |
| 106 // nominators and denominators. However, we need be careful in value range | |
| 107 // check. | |
| 108 if (x_variance < kMinVariance * n * n || degree < 1 || n < 2) { | |
| 109 // We cannot calculate b reliably so forget a and b, and just work on c. | |
| 110 a = b = 0.0; | |
| 111 if (n >= 1 && degree >= 0) { | |
| 112 c = sigy / n; | |
| 113 } else { | |
| 114 c = 0.0; | |
| 115 } | |
| 116 return; | |
| 117 } | |
| 118 long double top96 = 0.0; // Accurate top. | |
| 119 long double bottom96 = 0.0; // Accurate bottom. | |
| 120 long double cubevar = sigxxx * n - static_cast<long double>(sigxx) * sigx; | |
| 121 long double covariance = | |
| 122 static_cast<long double>(sigxy) * n - static_cast<long double>(sigx) * sigy; | |
| 123 | |
| 124 if (n >= 4 && degree >= 2) { | |
| 125 top96 = cubevar * covariance; | |
| 126 top96 += x_variance * (static_cast<long double>(sigxx) * sigy - sigxxy * n); | |
| 127 | |
| 128 bottom96 = cubevar * cubevar; | |
| 129 bottom96 -= x_variance * (sigxxxx * n - static_cast<long double>(sigxx) * sigxx); | |
| 130 } | |
| 131 if (bottom96 >= kMinVariance * n * n * n * n) { | |
| 132 // Denominators looking good | |
| 133 a = top96 / bottom96; | |
| 134 top96 = covariance - cubevar * a; | |
| 135 b = top96 / x_variance; | |
| 136 } else { | |
| 137 // Forget a, and concentrate on b. | |
| 138 a = 0.0; | |
| 139 b = covariance / x_variance; | |
| 140 } | |
| 141 c = (sigy - a * sigxx - b * sigx) / n; | |
| 142 } | |
| 143 | |
| 144 } // namespace tesseract |
