VTK-m  2.2
NDimsHistMarginalization.h
Go to the documentation of this file.
1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10 
11 #ifndef vtk_m_worklet_NDimsHistMarginalization_h
12 #define vtk_m_worklet_NDimsHistMarginalization_h
13 
14 #include <vtkm/Math.h>
15 #include <vtkm/cont/Algorithm.h>
16 #include <vtkm/cont/ArrayCopy.h>
17 #include <vtkm/cont/ArrayHandle.h>
19 #include <vtkm/cont/DataSet.h>
20 #include <vtkm/filter/density_estimate/worklet/histogram/ComputeNDHistogram.h>
21 #include <vtkm/filter/density_estimate/worklet/histogram/MarginalizeNDHistogram.h>
24 
25 #include <vtkm/cont/Field.h>
26 
27 namespace vtkm
28 {
29 namespace worklet
30 {
31 
32 
34 {
35 public:
36  // Execute the histogram (conditional) marginalization,
37  // given the multi-variable histogram(binId, freqIn)
38  // , marginalVariable and marginal condition
39  // Input arguments:
40  // binId, freqsIn: input ND-histogram in the fashion of sparse representation
41  // (definition of binId and frqIn please refer to NDimsHistogram.h),
42  // (binId.size() is the number of variables)
43  // numberOfBins: number of bins of each variable (length of numberOfBins must be the same as binId.size() )
44  // marginalVariables: length is the same as number of variables.
45  // 1 indicates marginal variable, otherwise 0.
46  // conditionFunc: The Condition function for non-marginal variable.
47  // This func takes two arguments (vtkm::Id var, vtkm::Id binId) and return bool
48  // var is index of variable and binId is bin index in the variable var
49  // return true indicates considering this bin into final marginal histogram
50  // more details can refer to example in UnitTestNDimsHistMarginalization.cxx
51  // marginalBinId, marginalFreqs: return marginalized histogram in the fashion of sparse representation
52  // the definition is the same as (binId and freqsIn)
53  template <typename BinaryCompare>
54  void Run(const std::vector<vtkm::cont::ArrayHandle<vtkm::Id>>& binId,
57  vtkm::cont::ArrayHandle<bool>& marginalVariables,
58  BinaryCompare conditionFunc,
59  std::vector<vtkm::cont::ArrayHandle<vtkm::Id>>& marginalBinId,
60  vtkm::cont::ArrayHandle<vtkm::Id>& marginalFreqs)
61  {
62  //total variables
63  vtkm::Id numOfVariable = static_cast<vtkm::Id>(binId.size());
64 
65  const vtkm::Id numberOfValues = freqsIn.GetNumberOfValues();
66  vtkm::cont::ArrayHandleConstant<vtkm::Id> constant0Array(0, numberOfValues);
68  vtkm::cont::ArrayCopy(constant0Array, bin1DIndex);
69 
71  vtkm::cont::ArrayCopy(freqsIn, freqs);
72  vtkm::Id numMarginalVariables = 0; //count num of marginal variables
73  const auto marginalPortal = marginalVariables.ReadPortal();
74  const auto numBinsPortal = numberOfBins.ReadPortal();
75  for (vtkm::Id i = 0; i < numOfVariable; i++)
76  {
77  if (marginalPortal.Get(i) == true)
78  {
79  // Worklet to calculate 1D index for marginal variables
80  numMarginalVariables++;
81  const vtkm::Id nFieldBins = numBinsPortal.Get(i);
82  vtkm::worklet::histogram::To1DIndex binWorklet(nFieldBins);
84  binWorklet);
85  size_t vecIndex = static_cast<size_t>(i);
86  to1DIndexDispatcher.Invoke(binId[vecIndex], bin1DIndex, bin1DIndex);
87  }
88  else
89  { //non-marginal variable
90  // Worklet to set the frequency of entities which does not meet the condition
91  // to 0 on non-marginal variables
92  vtkm::worklet::histogram::ConditionalFreq<BinaryCompare> conditionalFreqWorklet{
93  conditionFunc
94  };
95  conditionalFreqWorklet.setVar(i);
97  cfDispatcher(conditionalFreqWorklet);
98  size_t vecIndex = static_cast<size_t>(i);
99  cfDispatcher.Invoke(binId[vecIndex], freqs, freqs);
100  }
101  }
102 
103 
104  // Sort the freq array for counting by key(1DIndex)
105  vtkm::cont::Algorithm::SortByKey(bin1DIndex, freqs);
106 
107  // Add frequency within same 1d index bin (this get a nonSparse representation)
108  vtkm::cont::ArrayHandle<vtkm::Id> nonSparseMarginalFreqs;
110  bin1DIndex, freqs, bin1DIndex, nonSparseMarginalFreqs, vtkm::Add());
111 
112  // Convert to sparse representation(remove all zero freqncy entities)
113  vtkm::cont::ArrayHandle<vtkm::Id> sparseMarginal1DBinId;
114  vtkm::cont::Algorithm::CopyIf(bin1DIndex, nonSparseMarginalFreqs, sparseMarginal1DBinId);
115  vtkm::cont::Algorithm::CopyIf(nonSparseMarginalFreqs, nonSparseMarginalFreqs, marginalFreqs);
116 
117  //convert back to multi variate binId
118  marginalBinId.resize(static_cast<size_t>(numMarginalVariables));
119  vtkm::Id marginalVarIdx = numMarginalVariables - 1;
120  for (vtkm::Id i = numOfVariable - 1; i >= 0; i--)
121  {
122  if (marginalPortal.Get(i) == true)
123  {
124  const vtkm::Id nFieldBins = numBinsPortal.Get(i);
125  vtkm::worklet::histogram::ConvertHistBinToND binWorklet(nFieldBins);
127  convertHistBinToNDDispatcher(binWorklet);
128  size_t vecIndex = static_cast<size_t>(marginalVarIdx);
129  convertHistBinToNDDispatcher.Invoke(
130  sparseMarginal1DBinId, sparseMarginal1DBinId, marginalBinId[vecIndex]);
131  marginalVarIdx--;
132  }
133  }
134  } //Run()
135 
136  // Execute the histogram marginalization WITHOUT CONDITION,
137  // Please refer to the other Run() functions for the definition of input arguments.
138  void Run(const std::vector<vtkm::cont::ArrayHandle<vtkm::Id>>& binId,
140  vtkm::cont::ArrayHandle<vtkm::Id>& numberOfBins,
141  vtkm::cont::ArrayHandle<bool>& marginalVariables,
142  std::vector<vtkm::cont::ArrayHandle<vtkm::Id>>& marginalBinId,
143  vtkm::cont::ArrayHandle<vtkm::Id>& marginalFreqs)
144  {
145  //total variables
146  vtkm::Id numOfVariable = static_cast<vtkm::Id>(binId.size());
147 
148  const vtkm::Id numberOfValues = freqsIn.GetNumberOfValues();
149  vtkm::cont::ArrayHandleConstant<vtkm::Id> constant0Array(0, numberOfValues);
151  vtkm::cont::ArrayCopy(constant0Array, bin1DIndex);
152 
154  vtkm::cont::ArrayCopy(freqsIn, freqs);
155  vtkm::Id numMarginalVariables = 0; //count num of marginal variables
156  const auto marginalPortal = marginalVariables.ReadPortal();
157  const auto numBinsPortal = numberOfBins.ReadPortal();
158  for (vtkm::Id i = 0; i < numOfVariable; i++)
159  {
160  if (marginalPortal.Get(i) == true)
161  {
162  // Worklet to calculate 1D index for marginal variables
163  numMarginalVariables++;
164  const vtkm::Id nFieldBins = numBinsPortal.Get(i);
165  vtkm::worklet::histogram::To1DIndex binWorklet(nFieldBins);
167  binWorklet);
168  size_t vecIndex = static_cast<size_t>(i);
169  to1DIndexDispatcher.Invoke(binId[vecIndex], bin1DIndex, bin1DIndex);
170  }
171  }
172 
173  // Sort the freq array for counting by key (1DIndex)
174  vtkm::cont::Algorithm::SortByKey(bin1DIndex, freqs);
175 
176  // Add frequency within same 1d index bin
177  vtkm::cont::Algorithm::ReduceByKey(bin1DIndex, freqs, bin1DIndex, marginalFreqs, vtkm::Add());
178 
179  //convert back to multi variate binId
180  marginalBinId.resize(static_cast<size_t>(numMarginalVariables));
181  vtkm::Id marginalVarIdx = numMarginalVariables - 1;
182  for (vtkm::Id i = numOfVariable - 1; i >= 0; i--)
183  {
184  if (marginalPortal.Get(i) == true)
185  {
186  const vtkm::Id nFieldBins = numBinsPortal.Get(i);
187  vtkm::worklet::histogram::ConvertHistBinToND binWorklet(nFieldBins);
189  convertHistBinToNDDispatcher(binWorklet);
190  size_t vecIndex = static_cast<size_t>(marginalVarIdx);
191  convertHistBinToNDDispatcher.Invoke(bin1DIndex, bin1DIndex, marginalBinId[vecIndex]);
192  marginalVarIdx--;
193  }
194  }
195  } //Run()
196 };
197 }
198 } // namespace vtkm::worklet
199 
200 #endif // vtk_m_worklet_NDimsHistMarginalization_h
vtkm::worklet::NDimsHistMarginalization::Run
void Run(const std::vector< vtkm::cont::ArrayHandle< vtkm::Id >> &binId, vtkm::cont::ArrayHandle< vtkm::Id > &freqsIn, vtkm::cont::ArrayHandle< vtkm::Id > &numberOfBins, vtkm::cont::ArrayHandle< bool > &marginalVariables, std::vector< vtkm::cont::ArrayHandle< vtkm::Id >> &marginalBinId, vtkm::cont::ArrayHandle< vtkm::Id > &marginalFreqs)
Definition: NDimsHistMarginalization.h:138
vtkm::cont::ArrayHandle< vtkm::Id >
ArrayHandle.h
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::cont::Algorithm::ReduceByKey
static void ReduceByKey(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle< T, CKeyIn > &keys, const vtkm::cont::ArrayHandle< U, CValIn > &values, vtkm::cont::ArrayHandle< T, CKeyOut > &keys_output, vtkm::cont::ArrayHandle< U, CValOut > &values_output, BinaryFunctor binary_functor)
Definition: Algorithm.h:698
WorkletMapField.h
vtkm::cont::Algorithm::SortByKey
static void SortByKey(vtkm::cont::DeviceAdapterId devId, vtkm::cont::ArrayHandle< T, StorageT > &keys, vtkm::cont::ArrayHandle< U, StorageU > &values)
Definition: Algorithm.h:1008
vtkm::worklet::NDimsHistMarginalization
Definition: NDimsHistMarginalization.h:33
vtkm::cont::ArrayHandle::GetNumberOfValues
vtkm::Id GetNumberOfValues() const
Returns the number of entries in the array.
Definition: ArrayHandle.h:468
ArrayCopy.h
DispatcherMapField.h
vtkm::Add
Definition: Types.h:260
vtkm::worklet::DispatcherMapField
Dispatcher for worklets that inherit from WorkletMapField.
Definition: DispatcherMapField.h:25
Math.h
Algorithm.h
vtkm::cont::ArrayCopy
void ArrayCopy(const SourceArrayType &source, DestArrayType &destination)
Does a deep copy from one array to another array.
Definition: ArrayCopy.h:120
vtkm::worklet::NDimsHistMarginalization::Run
void Run(const std::vector< vtkm::cont::ArrayHandle< vtkm::Id >> &binId, vtkm::cont::ArrayHandle< vtkm::Id > &freqsIn, vtkm::cont::ArrayHandle< vtkm::Id > &numberOfBins, vtkm::cont::ArrayHandle< bool > &marginalVariables, BinaryCompare conditionFunc, std::vector< vtkm::cont::ArrayHandle< vtkm::Id >> &marginalBinId, vtkm::cont::ArrayHandle< vtkm::Id > &marginalFreqs)
Definition: NDimsHistMarginalization.h:54
Field.h
vtkm::Id
vtkm::Int64 Id
Base type to use to index arrays.
Definition: Types.h:227
vtkm::cont::ArrayHandleConstant
An array handle with a constant value.
Definition: ArrayHandleConstant.h:70
vtkm::cont::ArrayHandle::ReadPortal
ReadPortalType ReadPortal() const
Get an array portal that can be used in the control environment.
Definition: ArrayHandle.h:433
ArrayHandleCounting.h
vtkm::cont::Algorithm::CopyIf
static void CopyIf(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle< T, CIn > &input, const vtkm::cont::ArrayHandle< U, CStencil > &stencil, vtkm::cont::ArrayHandle< T, COut > &output)
Definition: Algorithm.h:436
DataSet.h