Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 /* 27 * G4DNARevertFunction.hh 28 * 29 * Created on: Aug 25, 2015 30 * Author: mkaramit 31 */ 32 33 #ifndef SOURCE_PROCESSES_ELECTROMAGNETIC_DNA_UTILS_INCLUDE_G4DNAREVERTPROBABILITY_HH_ 34 #define SOURCE_PROCESSES_ELECTROMAGNETIC_DNA_UTILS_INCLUDE_G4DNAREVERTPROBABILITY_HH_ 35 36 #include <functional> 37 38 //------------------------------------------------------------------------------ 39 // ***************************************************** 40 // Revert a probability by binary search 41 // ***************************************************** 42 43 class G4DNARevertProbability 44 { 45 public: 46 double fXmax; 47 double fXmin; 48 double fXmaxDef; 49 double fXminDef; 50 double fToleranceProba; 51 double fIncreasingCumulativeFunction; 52 53 G4DNARevertProbability(double toleranceY) : 54 fToleranceProba(toleranceY) 55 { 56 fXmax = 0.; 57 fXmin = 0.; 58 fXminDef = 0.; 59 fXmaxDef = 0.; 60 fIncreasingCumulativeFunction = 0.; 61 } 62 63 G4DNARevertProbability(double xmin, double xmax, double toleranceY) : 64 fXmax(xmax), fXmin(xmin), fToleranceProba(toleranceY) 65 { 66 if(fXmax < fXmin) 67 { 68 double tmp = fXmin; 69 fXmin = fXmax; 70 fXmax = tmp; 71 } 72 73 fXminDef = fXmin; 74 fXmaxDef = fXmax; 75 fIncreasingCumulativeFunction = 0; 76 } 77 78 void Reset() 79 { 80 fXmin = fXminDef; 81 fXmax = fXmaxDef; 82 } 83 84 void SetBoundaries(double xmin, double xmax) 85 { 86 fXmax = xmax; 87 fXmin = xmin; 88 if(fXmax < fXmin) 89 { 90 double tmp = fXmin; 91 fXmin = fXmax; 92 fXmax = tmp; 93 } 94 95 fXminDef = fXmin; 96 fXmaxDef = fXmax; 97 } 98 99 void SetTolerance(double toleranceY) 100 { 101 fToleranceProba = toleranceY; 102 } 103 104 bool Propose(double proposedXValue, 105 double proposedProba, 106 double nextProba, 107 double& returnedValue) 108 { 109 bool returnFlag = false; 110 111 if(proposedProba < nextProba - fToleranceProba) // proba trop petite ==> augmente 112 { 113 if(fIncreasingCumulativeFunction > 0) // croissant 114 { 115 if(proposedXValue > fXmin) fXmin = proposedXValue; 116 } 117 else if(fIncreasingCumulativeFunction < 0) // decroissant 118 { 119 if(proposedXValue < fXmax) fXmax = proposedXValue; 120 } 121 122 returnedValue = (fXmax + fXmin) / 2.; 123 returnFlag = false; 124 } 125 else if(proposedProba > nextProba + fToleranceProba) // proba trop grande 126 { 127 if(fIncreasingCumulativeFunction > 0) 128 { 129 if(proposedXValue < fXmax) 130 { 131 fXmax = proposedXValue; 132 } 133 } 134 else if(fIncreasingCumulativeFunction < 0) 135 { 136 if(proposedXValue > fXmin) 137 { 138 fXmin = proposedXValue; 139 } 140 } 141 142 returnedValue = (fXmax + fXmin) / 2.; 143 returnFlag = false; 144 } 145 else 146 { 147 // Assuming search for next proba is increasing 148 if(fIncreasingCumulativeFunction < 0) 149 { 150 fXmin = fXminDef; 151 fXmax = proposedXValue; 152 } 153 else if(fIncreasingCumulativeFunction > 0) 154 { 155 fXmin = proposedXValue; 156 fXmax = fXmaxDef; 157 } 158 returnFlag = true; 159 } 160 161 return returnFlag; 162 } 163 164 //********************************** 165 // *** REVERT THE FUNCTION "FUNCT" 166 // ********************************* 167 168 double Revert(double probaForSearchedTime, 169 std::function<double(double)>& funct) 170 { 171 Reset(); 172 bool notFound = true; 173 double proposedX; 174 double x = fXmax; 175 176 fIncreasingCumulativeFunction = (funct(fXmax) - funct(fXmin)) 177 / (fXmax - fXmin); 178 179 while(notFound) 180 { 181 double newProba = funct(x); 182 183 if(Propose(x, newProba, probaForSearchedTime, proposedX)) 184 { 185 notFound = false; 186 } 187 else 188 { 189 if(x == proposedX) 190 { 191 return x; 192 // G4cout << "BREAK : x= " << x << G4endl; 193 // G4cout << "nextProba= " << probaForSearchedTime << G4endl; 194 // G4cout << "newProba= " << newProba << G4endl; 195 // abort(); 196 } 197 x = proposedX; 198 } 199 } 200 return x; 201 } 202 }; 203 #endif /* SOURCE_PROCESSES_ELECTROMAGNETIC_DNA_UTILS_INCLUDE_G4DNAREVERTPROBABILITY_HH_ */ 204