1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
/*=========================================================================
Program: Visualization Toolkit
Module: vtkRandomPool.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/**
* @class vtkRandomPool
* @brief convenience class to quickly generate a pool of random numbers
*
* vtkRandomPool generates random numbers, and can do so using
* multithreading. It supports parallel applications where generating random
* numbers on the fly is difficult (i.e., non-deterministic). Also, it can be
* used to populate vtkDataArrays in an efficient manner. By default it uses
* an instance of vtkMersenneTwister to generate random sequences, but any
* subclass of vtkRandomSequence may be used. It also supports simple methods
* to generate, access, and pass random memory pools between objects.
*
* In threaded applications, these class may be conveniently used to
* pre-generate a sequence of random numbers, followed by the use of
* deterministic accessor methods to produce random sequences without
* problems etc. due to unpredictable work load and order of thread
* execution.
*
* @warning
* The class uses vtkMultiThreader if the size of the pool is larger than
* the specified chunk size. Also, vtkSMPTools may be used to scale the
* components in the method PopulateDataArray().
*/
#ifndef vtkRandomPool_h
#define vtkRandomPool_h
#include "vtkCommonCoreModule.h" // For export macro
#include "vtkObject.h"
VTK_ABI_NAMESPACE_BEGIN
class vtkRandomSequence;
class vtkDataArray;
class VTKCOMMONCORE_EXPORT vtkRandomPool : public vtkObject
{
public:
///@{
/**
* Standard methods for instantiation, type information, and printing.
*/
static vtkRandomPool* New();
vtkTypeMacro(vtkRandomPool, vtkObject);
void PrintSelf(ostream& os, vtkIndent indent) override;
///@}
///@{
/**
* Specify the random sequence generator used to produce the random pool.
* By default vtkMersenneTwister is used.
*/
virtual void SetSequence(vtkRandomSequence* seq);
vtkGetObjectMacro(Sequence, vtkRandomSequence);
///@}
///@{
/**
* Methods to set and get the size of the pool. The size must be specified
* before invoking GeneratePool(). Note the number of components will
* affect the total size (allocated memory is Size*NumberOfComponents).
*/
vtkSetClampMacro(Size, vtkIdType, 1, VTK_ID_MAX);
vtkGetMacro(Size, vtkIdType);
///@}
///@{
/**
* Methods to set and get the number of components in the pool. This is a
* convenience capability and can be used to interface with
* vtkDataArrays. By default the number of components is =1.
*/
vtkSetClampMacro(NumberOfComponents, vtkIdType, 1, VTK_INT_MAX);
vtkGetMacro(NumberOfComponents, vtkIdType);
///@}
/**
* This convenience method returns the total size of the memory pool, i.e.,
* Size*NumberOfComponents.
*/
vtkIdType GetTotalSize() { return (this->Size * this->NumberOfComponents); }
///@{
/**
* These methods provide access to the raw random pool as a double
* array. The size of the array is Size*NumberOfComponents. Each x value
* ranges between (0<=x<=1). The class will generate the pool as necessary
* (a modified time for generation is maintained). Also a method is
* available for getting the value at the ith pool position and compNum
* component. Finally, note that the GetValue() method uses modulo
* reduction to ensure that the request remains inside of the pool. Two
* forms are provided, the first assumes NumberOfComponents=1; the second
* allows access to a particular component. The GetPool() and GetValue()
* methods should only be called after GeneratePool() has been invoked;
*/
const double* GeneratePool();
const double* GetPool() { return this->Pool; }
double GetValue(vtkIdType i) { return this->Pool[(i % this->TotalSize)]; }
double GetValue(vtkIdType i, int compNum)
{
return this->Pool[(compNum + this->NumberOfComponents * i) % this->TotalSize];
}
///@}
///@{
/**
* Methods to populate data arrays of various types with values within a
* specified (min,max) range. Note that compNumber is used to specify the
* range for a particular component; otherwise all generated components are
* within the (min,max) range specified. (Thus it is possible to make
* multiple calls to generate random numbers for each component with
* different ranges.) Internally the type of the data array passed in is
* used to cast to the appropriate type. Also the size and number of
* components of the vtkDataArray controls the total number of random
* numbers generated; so the input data array should be pre-allocated with
* (SetNumberOfComponents, SetNumberOfTuples).
*/
void PopulateDataArray(vtkDataArray* da, double minRange, double maxRange);
void PopulateDataArray(vtkDataArray* da, int compNumber, double minRange, double maxRange);
///@}
///@{
/**
* Specify the work chunk size at which point multithreading kicks in. For small
* memory pools < ChunkSize, no threading is used. Larger pools are computed using
* vtkMultiThreader.
*/
vtkSetClampMacro(ChunkSize, vtkIdType, 1000, VTK_INT_MAX);
vtkGetMacro(ChunkSize, vtkIdType);
///@}
protected:
vtkRandomPool();
~vtkRandomPool() override;
// Keep track of last generation time
vtkTimeStamp GenerateTime;
// Data members to support public API
vtkRandomSequence* Sequence;
vtkIdType Size;
int NumberOfComponents;
vtkIdType ChunkSize;
// Internal data members
vtkIdType TotalSize;
double* Pool;
private:
vtkRandomPool(const vtkRandomPool&) = delete;
void operator=(const vtkRandomPool&) = delete;
};
VTK_ABI_NAMESPACE_END
#endif
|