npstat is hosted by Hepforge, IPPP Durham
NPStat  5.10.0
fillArrayCentersPreservingAreas.hh
Go to the documentation of this file.
1 #ifndef NPSTAT_FILLARRAYCENTERSPRESERVINGAREAS_HH_
2 #define NPSTAT_FILLARRAYCENTERSPRESERVINGAREAS_HH_
3 
4 /*!
5 // \file fillArrayCentersPreservingAreas.hh
6 //
7 // \brief Special copy of array data appropriate for reducing cell size
8 // in smoothing scenarios
9 //
10 // Author: I. Volobouev
11 //
12 // April 2015
13 */
14 
15 #include "npstat/nm/ArrayND.hh"
16 
17 namespace npstat {
18  /**
19  // Fill the second array from the first one in a special way.
20  // It is assumed that, in each dimension, the number of elements
21  // in the second array is a multiple of the number of elements
22  // in the first one. Only the "central" element in the target
23  // array will be filled, with the value increased in the proportion
24  // of the number of elements factor. Other elements of the target
25  // array will be filled with zeros. This function is useful in
26  // certain rebinning and smoothing scenarios.
27  */
28  template <typename Num1, unsigned StackLen1, unsigned StackDim1,
29  typename Num2, unsigned StackLen2, unsigned StackDim2>
33  {
34  assert(to);
35  if (!(from.isShapeKnown() && to->isShapeKnown()))
36  throw std::invalid_argument(
37  "In npstat::fillArrayCentersPreservingAreas:"
38  " uninitialized array");
39  const unsigned dim = from.rank();
40  if (dim != to->rank()) throw std::invalid_argument(
41  "In npstat::fillArrayCentersPreservingAreas:"
42  " incompatible array ranks");
43  const unsigned* toShape = to->shapeData();
44  const unsigned* fromShape = from.shapeData();
45  unsigned factors[CHAR_BIT*sizeof(unsigned long)];
46  double areaFactor = 1.0;
47  for (unsigned idim=0; idim<dim; ++idim)
48  {
49  factors[idim] = toShape[idim]/fromShape[idim];
50  if (toShape[idim] % fromShape[idim]) throw std::invalid_argument(
51  "In npstat::fillArrayCentersPreservingAreas:"
52  " array dimensions are not exact multiples");
53  if (factors[idim] % 2U)
54  areaFactor *= factors[idim];
55  else
56  areaFactor *= (factors[idim]/2.0);
57  }
58  const Num2 zero = Num2();
59  const unsigned long toLen = to->length();
60  unsigned toIndex[CHAR_BIT*sizeof(unsigned long)];
61  unsigned fromIndex[CHAR_BIT*sizeof(unsigned long)];
62  for (unsigned long i=0; i<toLen; ++i)
63  {
64  to->convertLinearIndex(i, toIndex, dim);
65 
66  // Is this particular index in the center of the cell?
67  bool central = true;
68  for (unsigned idim=0; idim<dim && central; ++idim)
69  {
70  fromIndex[idim] = toIndex[idim]/factors[idim];
71  const unsigned rem = toIndex[idim] % factors[idim];
72  const unsigned half = factors[idim]/2U;
73  if (factors[idim] % 2U)
74  central = rem == half;
75  else
76  central = rem == half || rem == half - 1U;
77  }
78 
79  if (central)
80  to->linearValue(i) = areaFactor*from.value(fromIndex, dim);
81  else
82  to->linearValue(i) = zero;
83  }
84  }
85 
86  /**
87  // Check whether the shapes of two arrays are compatible for
88  // running the "fillArrayCentersPreservingAreas" function on them
89  */
90  template <typename Num1, unsigned StackLen1, unsigned StackDim1,
91  typename Num2, unsigned StackLen2, unsigned StackDim2>
95  {
96  if (!(from.isShapeKnown() && to.isShapeKnown()))
97  return false;
98  const unsigned dim = from.rank();
99  if (dim != to.rank())
100  return false;
101  const unsigned* toShape = to.shapeData();
102  const unsigned* fromShape = from.shapeData();
103  for (unsigned idim=0; idim<dim; ++idim)
104  if (toShape[idim] % fromShape[idim])
105  return false;
106  return true;
107  }
108 }
109 
110 #endif // NPSTAT_FILLARRAYCENTERSPRESERVINGAREAS_HH_
Arbitrary-dimensional array template.
Definition: ArrayND.hh:93
void convertLinearIndex(unsigned long l, unsigned *index, unsigned indexLen) const
unsigned rank() const
Definition: ArrayND.hh:329
unsigned long length() const
Definition: ArrayND.hh:320
Numeric & linearValue(unsigned long index)
bool isShapeKnown() const
Definition: ArrayND.hh:326
Numeric & value(const unsigned *index, unsigned indexLen)
const unsigned * shapeData() const
Definition: ArrayND.hh:335
Definition: AbsArrayProjector.hh:14
bool canFillArrayCentersPreservingAreas(const ArrayND< Num1, StackLen1, StackDim1 > &from, const ArrayND< Num2, StackLen2, StackDim2 > &to)
Definition: fillArrayCentersPreservingAreas.hh:92
void fillArrayCentersPreservingAreas(const ArrayND< Num1, StackLen1, StackDim1 > &from, ArrayND< Num2, StackLen2, StackDim2 > *to)
Definition: fillArrayCentersPreservingAreas.hh:30