Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // G4GaussHermiteQ class implementation << 27 // 26 // 28 // Author: V.Grichine, 13.05.1997 V.Grichine << 27 // 29 // ------------------------------------------- << 30 28 31 #include "G4GaussHermiteQ.hh" 29 #include "G4GaussHermiteQ.hh" 32 #include "G4PhysicalConstants.hh" 30 #include "G4PhysicalConstants.hh" 33 31 34 #include <limits> << 35 << 36 // ------------------------------------------- 32 // ---------------------------------------------------------- 37 // 33 // 38 // Constructor for Gauss-Hermite 34 // Constructor for Gauss-Hermite 39 35 40 G4GaussHermiteQ::G4GaussHermiteQ(function pFun << 36 G4GaussHermiteQ::G4GaussHermiteQ ( function pFunction, 41 : G4VGaussianQuadrature(pFunction) << 37 G4int nHermite ) >> 38 : G4VGaussianQuadrature(pFunction) 42 { 39 { 43 const G4double tolerance = 1.0e-12; << 40 const G4double tolerance = 1.0e-12 ; 44 const G4int maxNumber = 12; << 41 const G4int maxNumber = 12 ; 45 << 42 46 G4int i = 1, j = 1, k = 1; << 43 G4int i=1, j=1, k=1 ; 47 G4double newton0 = 0.; << 44 G4double newton0=0.; 48 G4double newton1 = 0.0, temp1 = 0.0, temp2 = << 45 G4double newton1=0.0, temp1=0.0, temp2=0.0, temp3=0.0, temp=0.0 ; 49 G4double piInMinusQ = std::pow(pi, -0.25); << 46 G4double piInMinusQ = std::pow(pi,-0.25) ; // 1.0/std::sqrt(std::sqrt(pi)) ?? 50 << 47 51 fNumber = (nHermite + 1) / 2; << 48 fNumber = (nHermite +1)/2 ; 52 fAbscissa = new G4double[fNumber]; << 49 fAbscissa = new G4double[fNumber] ; 53 fWeight = new G4double[fNumber]; << 50 fWeight = new G4double[fNumber] ; 54 << 51 55 for(i = 1; i <= fNumber; ++i) << 52 for(i=1;i<=fNumber;i++) 56 { << 53 { 57 if(i == 1) << 54 if(i == 1) 58 { << 55 { 59 newton0 = << 56 newton0 = std::sqrt((G4double)(2*nHermite + 1)) - 60 std::sqrt((G4double)(2 * nHermite + 1) << 57 1.85575001*std::pow((G4double)(2*nHermite + 1),-0.16666999) ; 61 1.85575001 * std::pow((G4double)(2 * n << 58 } 62 } << 59 else if(i == 2) 63 else if(i == 2) << 60 { 64 { << 61 newton0 -= 1.14001*std::pow((G4double)nHermite,0.425999)/newton0 ; 65 newton0 -= 1.14001 * std::pow((G4double) << 62 } 66 } << 63 else if(i == 3) 67 else if(i == 3) << 64 { 68 { << 65 newton0 = 1.86002*newton0 - 0.86002*fAbscissa[0] ; 69 newton0 = 1.86002 * newton0 - 0.86002 * << 66 } 70 } << 67 else if(i == 4) 71 else if(i == 4) << 68 { 72 { << 69 newton0 = 1.91001*newton0 - 0.91001*fAbscissa[1] ; 73 newton0 = 1.91001 * newton0 - 0.91001 * << 70 } 74 } << 71 else 75 else << 72 { 76 { << 73 newton0 = 2.0*newton0 - fAbscissa[i - 3] ; 77 newton0 = 2.0 * newton0 - fAbscissa[i - << 74 } 78 } << 75 for(k=1;k<=maxNumber;k++) 79 for(k = 1; k <= maxNumber; ++k) << 76 { 80 { << 77 temp1 = piInMinusQ ; 81 temp1 = piInMinusQ; << 78 temp2 = 0.0 ; 82 temp2 = 0.0; << 79 for(j=1;j<=nHermite;j++) 83 for(j = 1; j <= nHermite; ++j) << 80 { 84 { << 81 temp3 = temp2 ; 85 temp3 = temp2; << 82 temp2 = temp1 ; 86 temp2 = temp1; << 83 temp1 = newton0*std::sqrt(2.0/j)*temp2 87 temp1 = newton0 * std::sqrt(2.0 / j) * << 84 - std::sqrt(((G4double)(j - 1))/j)*temp3 ; 88 std::sqrt(((G4double)(j - 1)) << 85 } 89 } << 86 temp = std::sqrt((G4double)2*nHermite)*temp2 ; 90 temp = std::sqrt((G4double) 2 * nHerm << 87 newton1 = newton0 ; 91 newton1 = newton0; << 88 newton0 = newton1 - temp1/temp ; 92 G4double ratio = std::numeric_limits<G4d << 89 if(std::fabs(newton0 - newton1) <= tolerance) 93 if(temp > 0.0) << 90 { 94 { << 91 break ; 95 ratio = temp1 / temp; << 92 } 96 } << 93 } 97 newton0 = newton1 - ratio; << 94 if(k > maxNumber) 98 if(std::fabs(newton0 - newton1) <= toler << 95 { 99 { << 96 G4Exception("G4GaussHermiteQ::G4GaussHermiteQ()", 100 break; << 97 "OutOfRange", FatalException, 101 } << 98 "Too many iterations in Gauss-Hermite constructor.") ; 102 } << 99 } 103 if(k > maxNumber) << 100 fAbscissa[i-1] = newton0 ; 104 { << 101 fWeight[i-1] = 2.0/(temp*temp) ; 105 G4Exception("G4GaussHermiteQ::G4GaussHer << 102 } 106 FatalException, << 107 "Too many iterations in Gaus << 108 } << 109 fAbscissa[i - 1] = newton0; << 110 fWeight[i - 1] = 2.0 / (temp * temp); << 111 } << 112 } 103 } 113 104 >> 105 114 // ------------------------------------------- 106 // ---------------------------------------------------------- 115 // 107 // 116 // Gauss-Hermite method for integration of std 108 // Gauss-Hermite method for integration of std::exp(-x*x)*nFunction(x) 117 // from minus infinity to plus infinity . << 109 // from minus infinity to plus infinity . 118 110 119 G4double G4GaussHermiteQ::Integral() const << 111 G4double G4GaussHermiteQ::Integral() const 120 { 112 { 121 G4double integral = 0.0; << 113 G4double integral = 0.0 ; 122 for(G4int i = 0; i < fNumber; ++i) << 114 for(G4int i=0;i<fNumber;i++) 123 { << 115 { 124 integral += << 116 integral += fWeight[i]*(fFunction(fAbscissa[i]) 125 fWeight[i] * (fFunction(fAbscissa[i]) + << 117 + fFunction(-fAbscissa[i])) ; 126 } << 118 } 127 return integral; << 119 return integral ; 128 } 120 } 129 121