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