HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_Cdf.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT_Cdf.h ( UT Library, C++)
7  *
8  * COMMENTS: An N-Dimensional cumulative distribution function (CDF)
9  * for sampling.
10  */
11 
12 #ifndef __UT_Cdf__
13 #define __UT_Cdf__
14 
15 #include "UT_API.h"
16 #include <SYS/SYS_Types.h>
17 #include <SYS/SYS_Math.h>
18 #include "UT_Assert.h"
19 #include "UT_Algorithm.h"
20 #include "UT_RootFinder.h"
21 #include "UT_VoxelArray.h"
22 
24 {
25  template<class InputIt, typename T>
26  static inline int eval(
27  InputIt cdf_begin,
28  const int &res,
29  const T &u)
30  {
31  int i = 0;
32  for ( ; i < res; ++i)
33  {
34  if (cdf_begin[i] > u) { break; }
35  }
36 
37  return i;
38  }
39 };
40 
42 {
43  template<class InputIt, typename T>
44  static inline int eval(
45  InputIt cdf_begin,
46  const int &res,
47  const T &u)
48  {
49  InputIt u_i = std::upper_bound(cdf_begin, cdf_begin+res, u);
50 
51  return SYSmax(int(0), int(u_i-cdf_begin));
52  }
53 };
54 
56 {
57  template<class InputIt, typename T>
58  static inline int eval(
59  InputIt cdf_begin,
60  const int &res,
61  const T &u)
62  {
63  InputIt u_i = UTfastUpperBound(cdf_begin, cdf_begin+res, u);
64 
65  return SYSmax(int(0), int(u_i-cdf_begin));
66  }
67 };
68 
70 
71 template<int N>
73 {
74  static inline int eval(const int *res,
75  const int *i)
76  {
77  return 0;
78  }
79 };
80 
81 template<>
82 struct UT_CdfIndexer<1>
83 {
84  static inline int eval(const int *res,
85  const int *i)
86  {
87  return i[0];
88  }
89 };
90 
91 template<>
92 struct UT_CdfIndexer<2>
93 {
94  static inline int eval(const int *res,
95  const int *i)
96  {
97  return i[1] * res[0] + i[0];
98  }
99 };
100 
101 template<>
102 struct UT_CdfIndexer<3>
103 {
104  static inline int eval(const int *res,
105  const int *i)
106  {
107  return (i[0] * res[1] + i[1]) * res[2] + i[2];
108  }
109 };
110 
111 template<int N>
113 {
114  template<class F, typename T>
115  static inline void eval(
116  T *cdf,
117  const int *res,
118  const F &ftor)
119  {
120  }
121 };
122 
123 template<>
125 {
126  enum { N = 1 };
127 
128  template<class F, typename T>
129  static inline void eval(
130  T *cdf,
131  const int *res,
132  const F &ftor)
133  {
134  int i[N] = {0};
135  int j = 0;
136  for ( ; i[0] < res[0]; ++i[0])
137  {
138  cdf[j++] = ftor(i);
139  }
140  }
141 };
142 
143 template<>
145 {
146  enum { N = 2 };
147 
148  template<class F, typename T>
149  static inline void eval(
150  T *cdf,
151  const int *res,
152  const F &ftor)
153  {
154  int i[N] = {0, 0};
155  int j = 0;
156  for (i[0] = 0; i[0] < res[0]; ++i[0])
157  {
158  for (i[1] = 0; i[1] < res[1]; ++i[1])
159  {
160  cdf[j++] = ftor(i);
161  }
162  }
163  }
164 };
165 
166 template<>
168 {
169  enum { N = 3 };
170 
171  template<class F, typename T>
172  static inline void eval(
173  T *cdf,
174  const int *res,
175  const F &ftor)
176  {
177  int i[N] = {0, 0, 0};
178  int j = 0;
179  for (i[0] = 0; i[0] < res[0]; ++i[0])
180  {
181  for (i[1] = 0; i[1] < res[1]; ++i[1])
182  {
183  for (i[2] = 0; i[2] < res[2]; ++i[2])
184  {
185  cdf[j++] = ftor(i);
186  }
187  }
188  }
189  }
190 };
191 
193 {
194  enum { N = 3 };
195 
197  : myVoxels(voxels) {}
198 
199  inline float operator()(const int *i) const
200  {
201  return myVoxels->operator()(i[0], i[1], i[2]);
202  }
203 
205 };
206 
207 /// Fill a linear cdf with res entries of a linear gradient.
208 template<class OutputIt>
209 inline void
210 UTfillCdfIdentity(OutputIt cdf, const int res)
211 {
212  if (res == 0) { return; }
213  typedef typename std::iterator_traits<OutputIt>::value_type output_t;
214  output_t s = 1.0F / res;
215  for (int i = 0; i < res; ++i)
216  {
217  *cdf++ = s * i;
218  }
219 }
220 
221 /// Sample from a linear cdf with res entries. The return value is the
222 /// sampled array index.
223 template<class S, class InputIt, typename T>
224 inline int
225 UTsampleCdf(InputIt cdf_begin, const int &res, const T &u)
226 {
227  return SYSclamp(S::eval(cdf_begin, res, u), 0, res-1);
228 }
229 
230 /// Sample from a linear cdf with res entries. The return value is the
231 /// sampled array index and dval is the offset.
232 template<class S, class InputIt, typename T>
233 inline int
234 UTsampleCdf(InputIt cdf_begin, const int &res, const T &u,
235  T &dval, T &pdf)
236 {
237  fpreal range;
238  int idx;
239 
240  dval = u;
241  dval *= cdf_begin[res-1];
242  idx = UTsampleCdf<S>(cdf_begin, res, dval);
243 
244  range = cdf_begin[idx];
245  pdf = 0;
246  if (idx > 0)
247  {
248  dval -= cdf_begin[idx-1];
249  range -= cdf_begin[idx-1];
250  }
251  if (range > 0)
252  {
253  dval /= range;
254  pdf = res*range / cdf_begin[res-1];
255  }
256 
257  return idx;
258 }
259 
260 /// Sample the pdf from a linear cdf at index i with res entries.
261 template<class InputIt, typename T>
262 inline void
263 UTsampleCdf(InputIt cdf_begin, const int &res, const int &i, T &pdf)
264 {
265  fpreal range = cdf_begin[i];
266  pdf = 0;
267  if (i > 0)
268  {
269  range -= cdf_begin[i-1];
270  }
271  if (range > 0)
272  {
273  pdf = res*range / cdf_begin[res-1];
274  }
275 }
276 
277 /// Find the value x from 0 to 1 where the area from 0 to x under the
278 /// trapezoid (0,0),(1,0),(1,d1),(0,d0) is portion u of the total area.
279 template<typename T>
280 inline T
281 UTsampleTrapezoidPdf(T u, T d0, T d1)
282 {
283  // Solve for x:
284  // 0 = (d1-d0)*x^2 + 2*d0*x - (d0+d1)*u
285  T x0; T x1;
286  int nroots = UT_RootFinder::quadratic(d1-d0, 2*d0, -(d0+d1)*u, x0, x1);
287  // If there are multiple roots, pick the one that is in
288  // or just outside of the [0,1] interval.
289  T x = (nroots == 1 || SYSabs(x0-0.5f) <= SYSabs(x1-0.5f)) ? x0 : x1;
290  return x;
291 }
292 
293 /// Create a PDF from a range of values.
294 template<class InputIt, class OutputIt>
295 inline void
296 UTcreatePdf(InputIt values_begin,
297  InputIt values_end,
298  OutputIt pdf_begin)
299 {
300  typedef typename std::iterator_traits<OutputIt>::value_type output_t;
301 
302  UTnormalizeArray(values_begin, values_end, pdf_begin);
303 
304  output_t sum = 0;
305  std::for_each(pdf_begin, pdf_begin + (values_end-values_begin),
306  [&sum](const output_t &v)
307  {
308  sum += v;
309  });
310 
311  output_t area = output_t(1.0) / sum;
312  std::transform(pdf_begin, pdf_begin + (values_end-values_begin), pdf_begin,
313  [&area](const output_t &v) { return v * area; });
314 }
315 
316 /// Create a CDF from a range of values.
317 template<class InputIt, class OutputIt>
318 inline void
319 UTcreateCdf(InputIt values_begin,
320  InputIt values_end,
321  OutputIt cdf_begin)
322 {
323  int i = 0;
324  while (values_begin != values_end)
325  {
326  *cdf_begin = *values_begin;
327  if (i > 0) { *cdf_begin += *(cdf_begin-1); }
328  ++values_begin;
329  ++cdf_begin;
330  ++i;
331  }
332 }
333 
334 template<
335  int N = 1,
336  typename T = float,
337  class S = UT_Cdf_default_search_t>
339 {
340  static_assert((N > 0 && N < 4), "unsupported number of dimensions");
341 
342 public:
343  enum { DIM = N };
344  using value_type = T;
345 
346  inline UT_Cdf();
347 
348  /// Construct from an array
349  /// data = row-major pdf/cdf data
350  /// res = resolution for each dimension
351  /// data values less than zero will be treated as zero.
352  inline UT_Cdf(T *data,
353  const int *res,
354  const bool &copydata);
355 
356  /// Construct from a value functor
357  /// ftor = value functor
358  /// res = resolution for each dimension
359  /// data values less than zero will be treated as zero.
360  template<class F>
361  inline UT_Cdf(const F &ftor,
362  const int *res);
363 
364  /// Create a cdf without data. You should then use getRawArray()
365  /// or setRawArray() functions and build() to construct the cdf.
366  /// This method avoids duplication of memory for the pdf and cdf
367  /// when only the cdf is needed.
368  /// res = resolution for each dimension
369  inline UT_Cdf(const int *res);
370 
371  inline ~UT_Cdf();
372 
373  /// Clear associated storage.
374  inline void clear();
375 
376  /// Resize storage according to resolution.
377  /// res = resolution for each dimension
378  inline void resize(const int *res);
379 
380  /// Set the data array from an array.
381  /// data = row-major pdf/cdf data
382  /// copydata = should the data be copied?
383  inline void setRawArray(T *data,
384  const bool &copydata);
385 
386  /// Set the data array from a value functor.
387  /// ftor = value functor
388  template<class F>
389  inline void setRawArray(const F &ftor);
390 
391  /// Retrieve the raw data array in row-major order. There will be
392  /// product(res) entries in the array to fill out.
393  inline T *getRawArray() { return myCdf[N-1]; }
394 
395  /// Build the cdf from the row-major data array. If you provided data
396  /// to the constructor, you don't need to call this method unless
397  /// you've modified the data through getRawArray().
398  inline void build();
399 
400  /// Draw an importance sample from the cdf. u and dval must have
401  /// 'N' entries. In this version, dval is the resulting sample value
402  /// for each dimension in the range [0, 1).
403  inline void sample(const T *u, T *dval) const;
404  inline void sample(const T *u, T *dval, T &pdf) const;
405 
406  /// Same as above but produces an exact index.
407  inline void sample(const T *u, int *didx) const;
408 
409  /// Same as above but produces an exact index. (dval) above relates to
410  /// (didx, doff) using the following identity:
411  /// dval[dim] = (didx[dim] + doff[dim]) / res[dim]
412  inline void sample(const T *u, int *didx, T *doff, T &pdf) const;
413 
414  /// Evaluate the pdf at the given index.
415  inline void evaluatePdf(const T *u, T &pdf) const;
416 
417  /// Get the sum over all image values
418  inline const T &getSum() const { return myCdf[0][myRes[0]-1]; }
419  inline const T &getISum() const { return myISum; }
420 
421  /// Get the average image value
422  inline const T &getScaling() const { return myScale; }
423  inline const T &getIScaling() const { return myIScale; }
424 
425  inline int getDim() const { return N; }
426  inline const int *getRes() const { return myRes; }
427  inline const int &getRes(int dim) const { return myRes[dim]; }
428 
429  inline void dump() const;
430 
431  inline size_t getMemoryUsage() const
432  {
433  size_t mem = sizeof(*this);
434  if (myOwnData)
435  {
436  int cap = 1;
437  for (int i = 0; i < N; ++i)
438  {
439  cap *= myRes[i];
440  mem += sizeof(T)*cap;
441  }
442  }
443  return mem;
444  }
445 
446 private:
447  inline void init();
448  inline void realloc(const int *res);
449 
450  T *myCdf[N];
451  int myRes[N];
452  T myIRes[N];
453  T myISum;
454  T myScale;
455  T myIScale;
456  int myCapacity;
457  int mySize;
458  bool myOwnData;
459 };
460 
461 template<int N, typename T, class S>
462 inline
464 {
465  init();
466 }
467 
468 template<int N, typename T, class S>
469 inline
471  T *data,
472  const int *res,
473  const bool &copydata)
474 {
475  init();
476  myOwnData = copydata;
477  resize(res);
478  setRawArray(data, copydata);
479  build();
480 }
481 
482 template<int N, typename T, class S>
483 template<class F>
484 inline
486  const int *res)
487 {
488  init();
489  resize(res);
490  setRawArray(ftor);
491  build();
492 }
493 
494 template<int N, typename T, class S>
495 inline
496 UT_Cdf<N, T, S>::UT_Cdf(const int *res)
497 {
498  init();
499  resize(res);
500 }
501 
502 template<int N, typename T, class S>
503 inline
505 {
506  clear();
507 }
508 
509 template<int N, typename T, class S>
510 inline void
512 {
513  for (int i = 0; i < N; ++i)
514  {
515  myCdf[i] = nullptr;
516  myRes[i] = 0;
517  myIRes[i] = 0;
518  }
519  myISum = 0;
520  myScale = 0;
521  myIScale = 0;
522  myCapacity = 0;
523  mySize = 0;
524  myOwnData = true;
525 }
526 
527 template<int N, typename T, class S>
528 inline void
530 {
531  if (!myOwnData) { return; }
532  for (int i = 0; i < N; ++i)
533  {
534  if (myCdf[i])
535  {
536  delete[] myCdf[i];
537  myCdf[i] = nullptr;
538  }
539  }
540  myCapacity = 0;
541 }
542 
543 template<int N, typename T, class S>
544 inline void
545 UT_Cdf<N, T, S>::realloc(const int *res)
546 {
547  if (!myOwnData) { return; }
548  clear();
549  myCapacity = 1;
550  for (int i = 0; i < N; ++i)
551  {
552  myCapacity *= res[i];
553  myCdf[i] = new T[myCapacity];
554  }
555 }
556 
557 template<int N, typename T, class S>
558 inline void
559 UT_Cdf<N, T, S>::resize(const int *res)
560 {
561  mySize = 1;
562  for (int i = 0; i < N; ++i)
563  {
564  myRes[i] = res[i];
565  myIRes[i] = 1.0F / myRes[i];
566  mySize *= myRes[i];
567  }
568  if (mySize > myCapacity) { realloc(res); }
569 }
570 
571 template<int N, typename T, class S>
572 inline void
574  T *data,
575  const bool &copydata)
576 {
577  if (myOwnData && !copydata)
578  {
579  clear();
580  }
581  myOwnData = copydata;
582  if (copydata)
583  {
584  memcpy(myCdf[N-1], data, mySize*sizeof(T));
585  }
586  else
587  {
588  myCdf[N-1] = data;
589  }
590 }
591 
592 template<int N, typename T, class S>
593 template<class F>
594 inline void
596 {
597  static_assert(std::is_class<F>::value, "invalid functor object");
598  static_assert(F::N == N, "unsupported number of dimensions");
599 
600  myOwnData = true;
601  UT_CdfValueFill<N>::eval(myCdf[N-1], myRes, ftor);
602 }
603 
604 template<int N, typename T, class S>
605 inline void
607 {
608  // Compute the sums for efficient sampling
609  exint size = mySize;
610  for (int i = N; i-- > 0; )
611  {
612  size /= myRes[i];
613 
614  exint idx = 0;
615  for (exint j = 0; j < size; ++j)
616  {
617  // We need non-negative, so we clamp negative to zero.
618  T value = SYSmax(myCdf[i][idx], 0.0F);
619  myCdf[i][idx] = value;
620  // Always sum using double-precision, to reduce the
621  // impact of catastrophic roundoff error.
622  double sum = value;
623  ++idx;
624  for (exint k = 1; k < myRes[i]; ++k, ++idx)
625  {
626  value = SYSmax(myCdf[i][idx], 0.0F);
627  sum += value;
628  myCdf[i][idx] = sum;
629  }
630 
631  if (i > 0)
632  myCdf[i-1][j] = myCdf[i][idx-1];
633  }
634  }
635 
636  UT_ASSERT(size == 1);
637 
638  myScale = getSum();
639  for (int i = 0; i < N; ++i)
640  myScale /= (T)myRes[i];
641 
642  myISum = 1.0F / getSum();
643  myIScale = 1.0F / getScaling();
644 }
645 
646 template<int N, typename T, class S>
647 inline void
648 UT_Cdf<N, T, S>::sample(const T *u, T *dval) const
649 {
650  T pdf = 0;
651 
652  sample(u, dval, pdf);
653 }
654 
655 template<int N, typename T, class S>
656 inline void
657 UT_Cdf<N, T, S>::sample(const T *u, T *dval, T &pdf) const
658 {
659  int didx[N];
660 
661  sample(u, didx, dval, pdf);
662  for (int i = 0; i < N; ++i)
663  {
664  dval[i] += didx[i];
665  dval[i] *= myIRes[i];
666  }
667 }
668 
669 template<int N, typename T, class S>
670 inline void
671 UT_Cdf<N, T, S>::sample(const T *u, int *didx) const
672 {
673  int off = 0;
674  int idx = 0;
675  for (int i = 0; i < N; ++i)
676  {
677  off += idx;
678  off *= myRes[i];
679  const T *cdf = myCdf[i] + off;
680 
681  idx = didx[i] = UTsampleCdf<S>(
682  cdf, myRes[i], u[i] * cdf[myRes[i]-1]);
683  }
684 }
685 
686 template<int N, typename T, class S>
687 inline void
688 UT_Cdf<N, T, S>::sample(const T *u, int *didx, T *doff, T &pdf) const
689 {
690  int off = 0;
691  int idx = 0;
692  T onepdf = 0;
693  pdf = 1;
694  for (int i = 0; i < N; ++i)
695  {
696  off += idx;
697  off *= myRes[i];
698  const T *cdf = myCdf[i] + off;
699 
700  idx = didx[i] = UTsampleCdf<S>(
701  cdf, myRes[i], u[i], doff[i], onepdf);
702  pdf *= onepdf;
703  }
704 }
705 
706 template<int N, typename T, class S>
707 inline void
708 UT_Cdf<N, T, S>::evaluatePdf(const T *u, T &pdf) const
709 {
710  int off = 0;
711  int idx = 0;
712  pdf = 1;
713  for (int i = 0; i < N; ++i)
714  {
715  off *= myRes[i];
716  idx = (int)(u[i]*myRes[i]);
717  idx = SYSclamp(idx, 0, myRes[i]-1);
718 
719  const T *cdf = myCdf[i] + off;
720 
721  T onepdf = 0;
722  T range = cdf[idx];
723  if (idx > 0)
724  range -= cdf[idx-1];
725  if (range > 0)
726  onepdf = myRes[i] * range / cdf[myRes[i]-1];
727 
728  pdf *= onepdf;
729  off += idx;
730  }
731 }
732 
733 template<int N, typename T, class S>
734 inline void
736 {
737  for (int dim = 0; dim < N; ++dim)
738  {
739  fprintf(stderr, "dim %d:\n", dim);
740  for (int i = 0; i < myRes[dim]; ++i)
741  fprintf(stderr, "%d: %f\n", i, myCdf[dim][i]);
742  }
743 }
744 
745 #endif
void dump() const
Definition: UT_Cdf.h:735
T * getRawArray()
Definition: UT_Cdf.h:393
const T & getSum() const
Get the sum over all image values.
Definition: UT_Cdf.h:418
#define SYSmax(a, b)
Definition: SYS_Math.h:1538
void clear()
Clear associated storage.
Definition: UT_Cdf.h:529
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
static void eval(T *cdf, const int *res, const F &ftor)
Definition: UT_Cdf.h:149
static int eval(const int *res, const int *i)
Definition: UT_Cdf.h:74
GLenum GLint * range
Definition: glcorearb.h:1925
void evaluatePdf(const T *u, T &pdf) const
Evaluate the pdf at the given index.
Definition: UT_Cdf.h:708
T UTsampleTrapezoidPdf(T u, T d0, T d1)
Definition: UT_Cdf.h:281
const T & getScaling() const
Get the average image value.
Definition: UT_Cdf.h:422
void setRawArray(T *data, const bool &copydata)
Definition: UT_Cdf.h:573
GLboolean * data
Definition: glcorearb.h:131
const GLdouble * v
Definition: glcorearb.h:837
GLsizei const GLfloat * value
Definition: glcorearb.h:824
static void eval(T *cdf, const int *res, const F &ftor)
Definition: UT_Cdf.h:115
int64 exint
Definition: SYS_Types.h:125
GLdouble s
Definition: glad.h:3009
#define SYSabs(a)
Definition: SYS_Math.h:1540
static int eval(const int *res, const int *i)
Definition: UT_Cdf.h:94
float operator()(const int *i) const
Definition: UT_Cdf.h:199
T value_type
Definition: UT_Cdf.h:344
void UTfillCdfIdentity(OutputIt cdf, const int res)
Fill a linear cdf with res entries of a linear gradient.
Definition: UT_Cdf.h:210
uint64 value_type
Definition: GA_PrimCompat.h:29
UT_CdfStdBinarySearch UT_Cdf_default_search_t
Definition: UT_Cdf.h:69
static int eval(const int *res, const int *i)
Definition: UT_Cdf.h:84
static int eval(InputIt cdf_begin, const int &res, const T &u)
Definition: UT_Cdf.h:58
GLfloat f
Definition: glcorearb.h:1926
const T & getIScaling() const
Definition: UT_Cdf.h:423
void sample(const T *u, T *dval) const
Definition: UT_Cdf.h:648
int getDim() const
Definition: UT_Cdf.h:425
const int & getRes(int dim) const
Definition: UT_Cdf.h:427
UT_Vector3T< T > SYSclamp(const UT_Vector3T< T > &v, const UT_Vector3T< T > &min, const UT_Vector3T< T > &max)
Definition: UT_Vector3.h:1057
static int eval(InputIt cdf_begin, const int &res, const T &u)
Definition: UT_Cdf.h:26
UT_CdfValueVoxelArrayF(const UT_VoxelArrayF *voxels)
Definition: UT_Cdf.h:196
HUSD_API bool eval(VtValue &val, T &ret_val)
static int eval(const int *res, const int *i)
Definition: UT_Cdf.h:104
size_t getMemoryUsage() const
Definition: UT_Cdf.h:431
GA_API const UT_StringHolder transform
GLint GLenum GLint x
Definition: glcorearb.h:409
static int eval(InputIt cdf_begin, const int &res, const T &u)
Definition: UT_Cdf.h:44
const T & getISum() const
Definition: UT_Cdf.h:419
void UTcreateCdf(InputIt values_begin, InputIt values_end, OutputIt cdf_begin)
Create a CDF from a range of values.
Definition: UT_Cdf.h:319
auto fprintf(std::FILE *f, const S &fmt, const T &...args) -> int
Definition: printf.h:602
void UTcreatePdf(InputIt values_begin, InputIt values_end, OutputIt pdf_begin)
Create a PDF from a range of values.
Definition: UT_Cdf.h:296
GLint j
Definition: glad.h:2733
GLsizeiptr size
Definition: glcorearb.h:664
void UTnormalizeArray(InputIt begin, InputIt end, OutputIt d_begin)
Normalize an array.
Definition: UT_Algorithm.h:250
ImageBuf OIIO_API resize(const ImageBuf &src, string_view filtername="", float filterwidth=0.0f, ROI roi={}, int nthreads=0)
~UT_Cdf()
Definition: UT_Cdf.h:504
static void eval(T *cdf, const int *res, const F &ftor)
Definition: UT_Cdf.h:129
fpreal64 fpreal
Definition: SYS_Types.h:277
#define UT_API_TMPL
Definition: UT_API.h:15
void build()
Definition: UT_Cdf.h:606
const UT_VoxelArrayF * myVoxels
Definition: UT_Cdf.h:204
GA_API const UT_StringHolder N
const int * getRes() const
Definition: UT_Cdf.h:426
int UTsampleCdf(InputIt cdf_begin, const int &res, const T &u)
Definition: UT_Cdf.h:225
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
Definition: UT_Cdf.h:338
Definition: core.h:1131
static int quadratic(T a, T b, T c, T &v0, T &v1)
ForwardIt UTfastUpperBound(ForwardIt first, ForwardIt last, const T &value)
Definition: UT_Algorithm.h:292
UT_Cdf()
Definition: UT_Cdf.h:463
void resize(const int *res)
Definition: UT_Cdf.h:559
Definition: format.h:895
GA_API const UT_StringHolder area
static void eval(T *cdf, const int *res, const F &ftor)
Definition: UT_Cdf.h:172