NonlinearlySpaced.h
1 //-*-C++-*-
2 /***************************************************************************
3  *
4  * Copyright (C) 2007 by Willem van Straten
5  * Licensed under the Academic Free License version 2.1
6  *
7  ***************************************************************************/
8 
9 // psrchive/More/General/Pulsar/NonlinearlySpaced.h
10 
11 #ifndef __Pulsar_NonlinearlySpaced_h
12 #define __Pulsar_NonlinearlySpaced_h
13 
14 #include "Pulsar/Divided.h"
15 #include "debug.h"
16 
17 #include <cmath>
18 
19 namespace Pulsar {
20 
21  template<class C>
22  class Integrate<C>::NonlinearlySpaced : public Integrate<C>::Divided
23  {
24 
26  void initialize (Integrate*, C*);
27 
29  unsigned get_nrange () { return stop_indeces.size(); }
30 
31  void get_range (unsigned irange, unsigned& start, unsigned& stop);
32 
34  virtual double get_value (const C*, unsigned ielement) = 0;
35 
36  protected:
37 
39  std::vector<unsigned> stop_indeces;
40 
41  };
42 
43 }
44 
45 template<class C>
47  C* container)
48 {
49  unsigned container_size = this->get_size( container );
50 
51  // divide them up
52  unsigned output_elements = 0;
53  unsigned spacing = 0;
54  this->divide (container_size, output_elements, spacing);
55 
56  DEBUG("NonlinearlySpaced::initialize container_size=" << container_size << " output_elements=" << output_elements);
57 
58  if (output_elements == 0)
59  return;
60 
61  stop_indeces.resize (output_elements);
62  stop_indeces[output_elements-1] = container_size;
63 
64  if (output_elements == 1)
65  return;
66 
67  double value_0 = get_value (container, 0);
68  double value_range = get_value (container, container_size - 1) - value_0;
69  double value_step = value_range / output_elements;
70 
71  DEBUG("NonlinearlySpaced::initialize value_0=" << value_0 << " value_range=" << value_range);
72 
73  unsigned ielement = 0;
74 
75  for (unsigned irange=0; irange+1 < output_elements; irange++)
76  {
77  double stop_value = value_0 + (irange+1) * value_step;
78 
79  DEBUG("NonlinearlySpaced::initialize stop_value[" << irange << "]=" << stop_value);
80 
81  bool first = true;
82  double min_diff = 0;
83 
84  while (ielement < container_size)
85  {
86  double value = get_value (container, ielement);
87  double diff = std::fabs( value - stop_value );
88 
89  DEBUG("NonlinearlySpaced::initialize value[" << ielement << "]=" << value << " diff=" << diff);
90 
91  if (first)
92  min_diff = diff;
93  else if (diff > min_diff)
94  break;
95  else
96  min_diff = diff;
97 
98  ielement ++;
99  first = false;
100  }
101 
102  DEBUG("NonlinearlySpaced::initialize stop_index[" << irange << "]=" << ielement);
103 
104  stop_indeces[irange] = ielement;
105  }
106 }
107 
108 template<class C>
110  unsigned& start,
111  unsigned& stop)
112 {
113  if (irange >= stop_indeces.size())
114  throw Error (InvalidParam,
115  "Pulsar::Integrate::Divide::NonlinearlySpaced::get_range",
116  "irange=%u >= output_elements=%u", irange, stop_indeces.size());
117 
118  if (irange > 0)
119  start = stop_indeces[irange-1];
120  else
121  start = 0;
122 
123  stop = stop_indeces[irange];
124 }
125 
126 
127 
128 #endif
Profile integration algorithms.
Definition: Integrate.h:41
Defines the PSRCHIVE library.
Definition: CalSource.h:17

Generated using doxygen 1.8.17