Commit e1acd30a2f8ff5cebcebc822642171c8ec730fff

Authored by knodlseder
1 parent c30f34a4

implement bisection for non-equidistant nodes

include/GNodeArray.hpp
... ... @@ -12,7 +12,7 @@
12 12 ***************************************************************************/
13 13 /**
14 14 * @file GNodeArray.hpp
15   - * @brief GNodeArray class definition.
  15 + * @brief GNodeArray class interface definition.
16 16 * @author J. Knodlseder
17 17 */
18 18  
... ...
src/GNodeArray.cpp
... ... @@ -11,6 +11,11 @@
11 11 * *
12 12 * ----------------------------------------------------------------------- *
13 13 ***************************************************************************/
  14 +/**
  15 + * @file GNodeArray.cpp
  16 + * @brief GNodeArray class implementation.
  17 + * @author J. Knodlseder
  18 + */
14 19  
15 20 /* __ Includes ___________________________________________________________ */
16 21 #include <iostream>
... ... @@ -192,10 +197,16 @@ void GNodeArray::nodes(const GVector&amp; vector)
192 197 * @brief Set indices and weighting factors for interpolation
193 198 *
194 199 * @param[in] value Value for which the interpolation should be done.
  200 + *
  201 + * Set the indices that bound the specified value and the corresponding
  202 + * weighting factors for linear interpolation. If the array has a linear
  203 + * form (i.e. the nodes are equidistant), an analytic formula is used to
  204 + * determine the boundary indices. If the nodes are not equidistant the
  205 + * boundary indices are searched by bisection.
195 206 ***************************************************************************/
196 207 void GNodeArray::set_value(const double& value)
197 208 {
198   - // If array is linear
  209 + // If array is linear then get left index from analytic formula
199 210 if (m_is_linear) {
200 211  
201 212 // Set left index
... ... @@ -205,20 +216,41 @@ void GNodeArray::set_value(const double&amp; value)
205 216 if (m_inx_left < 0) m_inx_left = 0;
206 217 else if (m_inx_left >= m_nodes-1) m_inx_left = m_nodes - 2;
207 218  
208   - // Set right index
209   - m_inx_right = m_inx_left + 1;
210   -
211   - // Set weighting factors
212   - m_wgt_right = (value - m_node[m_inx_left]) / m_step[m_inx_left];
213   - m_wgt_left = 1.0 - m_wgt_right;
214   -
215 219 } // endif: array is linear
216 220  
217   - // ... otherwise search the relevant bin
218   - {
219   - // TBD
  221 + // ... otherwise search the relevant indices by bisection
  222 + else {
  223 + // Set left index if value is before first node
  224 + if (value < m_node[0])
  225 + m_inx_left = 0;
  226 +
  227 + // Set left index if value is after last node
  228 + else if (value > m_node[m_nodes-1])
  229 + m_inx_left = m_nodes - 2;
  230 +
  231 + // Set left index by bisection
  232 + else {
  233 + int low = 0;
  234 + int high = m_nodes - 1;
  235 + int mid = 0;
  236 + while ((high - low) > 1) {
  237 + int mid = (low+high) / 2;
  238 + if (m_node[mid] > value)
  239 + high = mid;
  240 + else if (m_node[mid] <= value)
  241 + low = mid;
  242 + }
  243 + m_inx_left = low;
  244 + } // endelse: did bisection
220 245 }
221 246  
  247 + // Set right index
  248 + m_inx_right = m_inx_left + 1;
  249 +
  250 + // Set weighting factors
  251 + m_wgt_right = (value - m_node[m_inx_left]) / m_step[m_inx_left];
  252 + m_wgt_left = 1.0 - m_wgt_right;
  253 +
222 254 // Return
223 255 return;
224 256 }
... ... @@ -297,7 +329,7 @@ void GNodeArray::free_members(void)
297 329 ***************************************************************************/
298 330 void GNodeArray::setup(void)
299 331 {
300   - // Setup distance array
  332 + // Setup distance array between subsequent nodes
301 333 for (int i = 0; i < m_nodes-1; ++i)
302 334 m_step[i] = m_node[i+1] - m_node[i];
303 335  
... ... @@ -310,9 +342,8 @@ void GNodeArray::setup(void)
310 342 for (int i = 0; i < m_nodes-1; ++i) {
311 343 double eps = m_linear_slope * m_node[i] + m_linear_offset - double(i);
312 344 if (fabs(eps) > 1.0e-6) {
313   - cout << "WARNING: Node " << i
314   - << "indexing is invalid (eps=" << eps << ")" << endl;
315 345 m_is_linear = 0;
  346 + break;
316 347 }
317 348 }
318 349  
... ...