G4INCLInverseInterpolationTable.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 // INCL++ intra-nuclear cascade model
00027 // Pekka Kaitaniemi, CEA and Helsinki Institute of Physics
00028 // Davide Mancusi, CEA
00029 // Alain Boudard, CEA
00030 // Sylvie Leray, CEA
00031 // Joseph Cugnon, University of Liege
00032 //
00033 #define INCLXX_IN_GEANT4_MODE 1
00034 
00035 #include "globals.hh"
00036 
00044 // #include <cassert>
00045 #include <algorithm>
00046 #include <functional>
00047 #include "G4INCLInverseInterpolationTable.hh"
00048 
00049 namespace G4INCL {
00050 
00051   InverseInterpolationTable::InverseInterpolationTable(IFunction1D const &f, const unsigned int nNodes) {
00052 // assert(nNodes>2);
00053 
00054     const G4double x0 = f.getXMinimum();
00055     const G4double x1 = f.getXMaximum();
00056 
00057     // Build the nodes
00058     G4double last = f(x0);
00059     InterpolationNode firstNode(last, x0, 0.);
00060     nodes.push_back(firstNode);
00061     G4int skippedNodes = 0;
00062     for(unsigned i = 1; i < nNodes; i++) {
00063       const G4double xi = x0 + i*(x1-x0)/((G4double)(nNodes-1));
00064       // Make sure that the x vector is sorted (corresponding to a monotonous
00065       // function)
00066       const G4double value = f(xi);
00067       if(value <= last) {
00068         ++skippedNodes;
00069         continue;
00070       }
00071       InterpolationNode node(value, xi, 0.);
00072       nodes.push_back(node);
00073       last = value;
00074     }
00075 
00076 // assert(nNodes==nodes.size()+skippedNodes);
00077 
00078     // Initialise the "derivative" values
00079     initDerivatives();
00080     setFunctionDomain();
00081   }
00082 
00083   InverseInterpolationTable::InverseInterpolationTable(std::vector<G4double> const &x, std::vector<G4double> const &y) {
00084 // assert(x.size()==y.size());
00085     // Assert that the x vector is sorted (corresponding to a monotonous
00086     // function
00087 // assert(std::adjacent_find(nodes.begin(), nodes.end(), std::greater<InterpolationNode>()) == nodes.end());
00088 
00089     for(unsigned i = 0; i < x.size(); ++i)
00090       nodes.push_back(InterpolationNode(x.at(i), y.at(i), 0.));
00091 
00092     initDerivatives();
00093     setFunctionDomain();
00094   }
00095 
00096   void InverseInterpolationTable::initDerivatives() {
00097     for(unsigned i = 0; i < nodes.size()-1; i++) {
00098       if((nodes.at(i+1).getX() - nodes.at(i).getX()) == 0.0) // Safeguard against division by zero
00099         nodes[i].setYPrime(0.0);
00100       else
00101         nodes[i].setYPrime((nodes.at(i+1).getY() - nodes.at(i).getY())/(nodes.at(i+1).getX() - nodes.at(i).getX()));
00102     }
00103     nodes.back().setYPrime(nodes.at(nodes.size()-2).getYPrime()); // Duplicate the last value
00104   }
00105 
00106   void InverseInterpolationTable::setFunctionDomain() {
00107     // Set the function domain
00108     if(nodes.front()>nodes.back()) {
00109       xMin = nodes.back().getX();
00110       xMax = nodes.front().getX();
00111     } else {
00112       xMin = nodes.front().getX();
00113       xMax = nodes.back().getX();
00114     }
00115   }
00116 
00117   G4double InverseInterpolationTable::operator()(const G4double x) const {
00118     // Find the relevant interpolation bin
00119     std::vector<InterpolationNode>::const_iterator iter =
00120       std::lower_bound(nodes.begin(), nodes.end(), x);
00121 
00122     if(iter==nodes.begin())
00123       return nodes.front().getY();
00124 
00125     if(iter==nodes.end())
00126       return nodes.back().getY();
00127 
00128     std::vector<InterpolationNode>::const_iterator previousIter = iter - 1;
00129     const G4double dx = x - previousIter->getX();
00130     return previousIter->getY() + previousIter->getYPrime()*dx;
00131   }
00132 
00133   std::string InverseInterpolationTable::print() const {
00134     std::string message;
00135     for(std::vector<InterpolationNode>::const_iterator n=nodes.begin(); n!=nodes.end(); ++n)
00136       message += n->print();
00137     return message;
00138   }
00139 
00140 }

Generated on Mon May 27 17:48:35 2013 for Geant4 by  doxygen 1.4.7