Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
Slic3r::Measure::RootsPolynomial Class Reference

#include <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()

static double Slic3r::Measure::RootsPolynomial::Evaluate ( int32_t  degree,
const double *  c,
double  t 
)
inlinestatic
338 {
339 int32_t i = degree;
340 double result = c[i];
341 while (--i >= 0) {
342 result = t * result + c[i];
343 }
344 return result;
345 }
__int32 int32_t
Definition unistd.h:75

Referenced by Find().

+ Here is the caller graph for this function:

◆ Find() [1/2]

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

References Evaluate().

+ Here is the call graph for this function:

◆ Find() [2/2]

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

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()

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

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: