source: trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeInterpolator.icc @ 1340

Last change on this file since 1340 was 1340, checked in by garnier, 14 years ago

update ti head

File size: 4.9 KB
Line 
1#ifndef G4CASCADE_INTERPOLATOR_ICC
2#define G4CASCADE_INTERPOLATOR_ICC
3//
4// ********************************************************************
5// * License and Disclaimer                                           *
6// *                                                                  *
7// * The  Geant4 software  is  copyright of the Copyright Holders  of *
8// * the Geant4 Collaboration.  It is provided  under  the terms  and *
9// * conditions of the Geant4 Software License,  included in the file *
10// * LICENSE and available at  http://cern.ch/geant4/license .  These *
11// * include a list of copyright holders.                             *
12// *                                                                  *
13// * Neither the authors of this software system, nor their employing *
14// * institutes,nor the agencies providing financial support for this *
15// * work  make  any representation or  warranty, express or implied, *
16// * regarding  this  software system or assume any liability for its *
17// * use.  Please see the license in the file  LICENSE  and URL above *
18// * for the full disclaimer and the limitation of liability.         *
19// *                                                                  *
20// * This  code  implementation is the result of  the  scientific and *
21// * technical work of the GEANT4 collaboration.                      *
22// * By using,  copying,  modifying or  distributing the software (or *
23// * any work based  on the software)  you  agree  to acknowledge its *
24// * use  in  resulting  scientific  publications,  and indicate your *
25// * acceptance of all terms of the Geant4 Software license.          *
26// ********************************************************************
27//
28// $Id: G4CascadeInterpolator.icc,v 1.8 2010/10/19 19:48:00 mkelsey Exp $
29// GEANT4 tag $Name: hadr-casc-V09-03-85 $
30//
31// Author:  Michael Kelsey <kelsey@slac.stanford.edu>
32//
33// Simple linear interpolation class, more lightweight than
34// G4PhysicsVector.  Templated on number of X-axis (usually energy)
35// bins, constructor takes a C-array of bin edges as input, and an
36// optional flag whether to truncate or extrapolate (the default) values
37// beyond the bin boundaries.
38//
39// The interpolation action returns a simple double: the integer part
40// is the bin index, and the fractional part is, obviously, the
41// fractional part.
42//
43// 20100517  M. Kelsey -- Bug fix in interpolate:  If bin position is _exactly_
44//              at upper edge (== last + 0.0), just return bin value.
45// 20100520  M. Kelsey -- Second bug fix:  Loop in bin search should start at
46//              i=1, not i=0 (since i-1 is the key).
47// 20100803  M. Kelsey -- Add printBins() function for debugging
48// 20101019  M. Kelsey -- CoVerity reports: recursive #include, index overrun
49
50#include "globals.hh"
51#include "G4CascadeInterpolator.hh"
52#include <iomanip>
53
54
55// Find bin position (index and fraction) using input argument and array
56
57template <int NBINS>
58G4double G4CascadeInterpolator<NBINS>::getBin(const G4double x) const {
59  if (x == lastX) return lastVal;       // Avoid unnecessary work
60
61  G4double xindex, xdiff, xbin;
62
63  lastX = x;
64  if (x < xBins[0]) {                   // Handle boundaries first
65    xindex = 0.;
66    xbin = xBins[1]-xBins[0];
67    xdiff = doExtrapolation ? x-xBins[0] : 0.;          // Less than zero
68  } else if (x >= xBins[last]) {
69    xindex = last;
70    xbin = xBins[last]-xBins[last-1];
71    xdiff = doExtrapolation ? x-xBins[last] : 0.;
72  } else {                              // Assume nBins small; linear search
73    int i;
74    for (i=1; i<last && x>xBins[i]; i++) {;}    // Stops when x within bin i-1
75    xindex = i-1;
76    xbin = xBins[i] - xBins[i-1];
77    xdiff = x - xBins[i-1];
78  }
79
80#ifdef G4CASCADE_DEBUG_SAMPLER
81  G4cout << " G4CascadeInterpolator<" << NBINS << ">: x=" << x
82         << " index=" << xindex << " fraction=" << xdiff/xbin << G4endl;
83#endif
84
85  return (lastVal = xindex + xdiff/xbin);       // Save return value for later
86}
87
88
89// Apply interpolation of input argument to user array
90
91template <int NBINS>
92G4double G4CascadeInterpolator<NBINS>::
93interpolate(const G4double x, const G4double (&yb)[nBins]) const {
94  getBin(x);
95  return interpolate(yb);
96}
97
98// Apply last found interpolation to user array
99
100template <int NBINS>
101G4double G4CascadeInterpolator<NBINS>::
102interpolate(const G4double (&yb)[nBins]) const {
103  // Treat boundary extrapolations specially, otherwise just truncate
104  G4int i = (lastVal<0) ? 0 : (lastVal>last) ? last-1 : G4int(lastVal);
105  G4double frac = lastVal - G4double(i);        // May be <0 or >1 if extrapolating
106
107  // Special case:  if exactly on upper bin edge, just return value
108  return (i==last) ? yb[last] : (yb[i] + frac*(yb[i+1]-yb[i]));
109}
110
111
112// Print bin edges for debugging
113
114template <int NBINS>
115void G4CascadeInterpolator<NBINS>::printBins() const {
116  G4cout << " G4CascadeInterpolator<" << NBINS << "> : " << G4endl;
117  for (G4int k=0; k<NBINS; k++) {
118    G4cout << " " << std::setw(5) << xBins[k];
119    if ((k+1)%12 == 0) G4cout << G4endl;
120  }
121  G4cout << G4endl;
122}
123
124#endif  /* G4CASCADE_INTERPOLATOR_ICC */
Note: See TracBrowser for help on using the repository browser.