OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::Measure::RootsPolynomial Class Reference

#include </home/runner/work/OrcaSlicer/OrcaSlicer/src/libslic3r/MeasureUtils.hpp>

Static Public Member Functions

static int32_t Find (int32_t degree, const double *c, uint32_t maxIterations, double *roots)
static bool Find (int32_t degree, const double *c, double tmin, double tmax, uint32_t maxIterations, double &root)
static int32_t FindRecursive (int32_t degree, double const *c, double tmin, double tmax, uint32_t maxIterations, double *roots)
static double Evaluate (int32_t degree, const double *c, double t)

Detailed Description

Member Function Documentation

◆ Evaluate()

double Slic3r::Measure::RootsPolynomial::Evaluate ( int32_t degree,
const double * c,
double t )
inlinestatic
345 {
346 int32_t i = degree;
347 double result = c[i];
348 while (--i >= 0) {
349 result = t * result + c[i];
350 }
351 return result;
352 }

Referenced by Find().

Here is the caller graph for this function:

◆ Find() [1/2]

bool Slic3r::Measure::RootsPolynomial::Find ( int32_t degree,
const double * c,
double tmin,
double tmax,
uint32_t maxIterations,
double & root )
inlinestatic
234 {
235 const double zero = 0.0;
236 double pmin = Evaluate(degree, c, tmin);
237 if (pmin == zero) {
238 root = tmin;
239 return true;
240 }
241 double pmax = Evaluate(degree, c, tmax);
242 if (pmax == zero) {
243 root = tmax;
244 return true;
245 }
246
247 if (pmin * pmax > zero)
248 // It is not known whether the interval bounds a root.
249 return false;
250
251 if (tmin >= tmax)
252 // Invalid ordering of interval endpoitns.
253 return false;
254
255 for (uint32_t i = 1; i <= maxIterations; ++i) {
256 root = 0.5 * (tmin + tmax);
257
258 // This test is designed for 'float' or 'double' when tmin
259 // and tmax are consecutive floating-point numbers.
260 if (root == tmin || root == tmax)
261 break;
262
263 const double p = Evaluate(degree, c, root);
264 const double product = p * pmin;
265 if (product < zero) {
266 tmax = root;
267 pmax = p;
268 }
269 else if (product > zero) {
270 tmin = root;
271 pmin = p;
272 }
273 else
274 break;
275 }
276
277 return true;
278 }
static double Evaluate(int32_t degree, const double *c, double t)
Definition MeasureUtils.hpp:344

References Evaluate().

Here is the call graph for this function:

◆ Find() [2/2]

int32_t Slic3r::Measure::RootsPolynomial::Find ( int32_t degree,
const double * c,
uint32_t maxIterations,
double * roots )
inlinestatic
196 {
197 if (degree >= 0 && c != nullptr) {
198 const double zero = 0.0;
199 while (degree >= 0 && c[degree] == zero) {
200 --degree;
201 }
202
203 if (degree > 0) {
204 // Compute the Cauchy bound.
205 const double one = 1.0;
206 const double invLeading = one / c[degree];
207 double maxValue = zero;
208 for (int32_t i = 0; i < degree; ++i) {
209 const double value = std::fabs(c[i] * invLeading);
210 if (value > maxValue)
211 maxValue = value;
212 }
213 const double bound = one + maxValue;
214
215 return FindRecursive(degree, c, -bound, bound, maxIterations, roots);
216 }
217 else if (degree == 0)
218 // The polynomial is a nonzero constant.
219 return 0;
220 else {
221 // The polynomial is identically zero.
222 roots[0] = zero;
223 return 1;
224 }
225 }
226 else
227 // Invalid degree or c.
228 return 0;
229 }
static int32_t FindRecursive(int32_t degree, double const *c, double tmin, double tmax, uint32_t maxIterations, double *roots)
Definition MeasureUtils.hpp:281

References FindRecursive().

Referenced by FindRecursive(), and Slic3r::Measure::get_measurement().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ FindRecursive()

int32_t Slic3r::Measure::RootsPolynomial::FindRecursive ( int32_t degree,
double const * c,
double tmin,
double tmax,
uint32_t maxIterations,
double * roots )
inlinestatic
282 {
283 // The base of the recursion.
284 const double zero = 0.0;
285 double root = zero;
286 if (degree == 1) {
287 int32_t numRoots;
288 if (c[1] != zero) {
289 root = -c[0] / c[1];
290 numRoots = 1;
291 }
292 else if (c[0] == zero) {
293 root = zero;
294 numRoots = 1;
295 }
296 else
297 numRoots = 0;
298
299 if (numRoots > 0 && tmin <= root && root <= tmax) {
300 roots[0] = root;
301 return 1;
302 }
303 return 0;
304 }
305
306 // Find the roots of the derivative polynomial scaled by 1/degree.
307 // The scaling avoids the factorial growth in the coefficients;
308 // for example, without the scaling, the high-order term x^d
309 // becomes (d!)*x through multiple differentiations. With the
310 // scaling we instead get x. This leads to better numerical
311 // behavior of the root finder.
312 const int32_t derivDegree = degree - 1;
313 std::vector<double> derivCoeff(static_cast<size_t>(derivDegree) + 1);
314 std::vector<double> derivRoots(derivDegree);
315 for (int32_t i = 0, ip1 = 1; i <= derivDegree; ++i, ++ip1) {
316 derivCoeff[i] = c[ip1] * (double)(ip1) / (double)degree;
317 }
318 const int32_t numDerivRoots = FindRecursive(degree - 1, &derivCoeff[0], tmin, tmax, maxIterations, &derivRoots[0]);
319
320 int32_t numRoots = 0;
321 if (numDerivRoots > 0) {
322 // Find root on [tmin,derivRoots[0]].
323 if (Find(degree, c, tmin, derivRoots[0], maxIterations, root))
324 roots[numRoots++] = root;
325
326 // Find root on [derivRoots[i],derivRoots[i+1]].
327 for (int32_t i = 0, ip1 = 1; i <= numDerivRoots - 2; ++i, ++ip1) {
328 if (Find(degree, c, derivRoots[i], derivRoots[ip1], maxIterations, root))
329 roots[numRoots++] = root;
330 }
331
332 // Find root on [derivRoots[numDerivRoots-1],tmax].
333 if (Find(degree, c, derivRoots[static_cast<size_t>(numDerivRoots) - 1], tmax, maxIterations, root))
334 roots[numRoots++] = root;
335 }
336 else {
337 // The polynomial is monotone on [tmin,tmax], so has at most one root.
338 if (Find(degree, c, tmin, tmax, maxIterations, root))
339 roots[numRoots++] = root;
340 }
341 return numRoots;
342 }
static int32_t Find(int32_t degree, const double *c, uint32_t maxIterations, double *roots)
Definition MeasureUtils.hpp:195

References Find(), and FindRecursive().

Referenced by Find(), and FindRecursive().

Here is the call graph for this function:
Here is the caller graph for this function:

The documentation for this class was generated from the following file: