Changeset 3148 for trunk/MagicSoft/Mars/mtools/MCubicCoeff.cc
- Timestamp:
- 02/14/04 11:48:43 (21 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/MagicSoft/Mars/mtools/MCubicCoeff.cc
r3022 r3148 24 24 25 25 ////////////////////////////////////////////////////////////////////////////// 26 // //27 // Cubic Spline Interpolation //28 // //26 // 27 // Cubic Spline Interpolation 28 // 29 29 ////////////////////////////////////////////////////////////////////////////// 30 31 30 #include "MCubicCoeff.h" 32 31 33 #include "TMath.h"32 #include <TMath.h> 34 33 35 34 #include "MLog.h" … … 45 44 // where x is the independent variable, 2 and 3 are exponents 46 45 // 47 48 46 MCubicCoeff::MCubicCoeff(Double_t x, Double_t xNext, Double_t y, Double_t yNext, 49 47 Double_t a, Double_t b, Double_t c) : … … 51 49 { 52 50 fH = fXNext - fX; 53 if (!EvalMinMax())54 {55 gLog << warn << "Failed to eval interval Minimum and Maximum, returning zeros" << endl; 56 fMin = 0;57 fMax= 0;58 }51 if (EvalMinMax()) 52 return; 53 54 gLog << warn << "Failed to eval interval Minimum and Maximum, returning zeros" << endl; 55 fMin = 0; 56 fMax = 0; 59 57 } 60 58 … … 66 64 Double_t MCubicCoeff::Eval(Double_t x) 67 65 { 68 Double_t dx = x - fX;69 return (fY+dx*(fC+dx*(fB+dx*fA)));66 const Double_t dx = x - fX; 67 return fY + dx*(fC + dx*(fB + dx*fA)); 70 68 } 71 69 … … 79 77 Bool_t MCubicCoeff::EvalMinMax() 80 78 { 81 fMin = fMax = fY; 82 fAbMin = fAbMax = fX; 79 fMin = fY; 80 fMax = fY; 81 82 fAbMin = fX; 83 fAbMax = fX; 84 83 85 if (fYNext < fMin) 84 86 { 85 fMin = fYNext;87 fMin = fYNext; 86 88 fAbMin = fXNext; 87 89 } 88 90 if (fYNext > fMax) 89 91 { 90 fMax = fYNext;92 fMax = fYNext; 91 93 fAbMax = fXNext; 92 94 } 93 Double_t tempMinMax; 94 Double_t delta = 4.0*fB*fB - 12.0*fA*fC; 95 if (delta >= 0.0 && fA != 0.0) 96 { 97 Double_t sqrtDelta = sqrt(delta); 98 Double_t xPlus = (-2.0*fB + sqrtDelta)/(6.0*fA); 99 Double_t xMinus = (-2.0*fB - sqrtDelta)/(6.0*fA); 100 if (xPlus >= 0.0 && xPlus <= fH) 101 { 102 tempMinMax = this->Eval(fX+xPlus); 103 if (tempMinMax < fMin) 104 { 105 fMin = tempMinMax; 106 fAbMin = fX + xPlus; 107 } 108 if (tempMinMax > fMax) 109 { 110 fMax = tempMinMax; 111 fAbMax = fX + xPlus; 112 } 113 } 114 if (xMinus >= 0.0 && xMinus <= fH) 115 { 116 tempMinMax = this->Eval(fX+xMinus); 117 if (tempMinMax < fMin) 118 { 119 fMin = tempMinMax; 120 fAbMin = fX + xMinus; 121 } 122 if (tempMinMax > fMax) 123 { 124 fMax = tempMinMax; 125 fAbMax = fX + xMinus; 126 } 127 } 128 } 129 /* if fA is zero then we have only one possible solution */ 130 else if (fA == 0.0 && fB != 0.0) 131 { 132 Double_t xSolo = - (fC/(2.0*fB)); 133 if (xSolo >= 0.0 && xSolo <= fH) 134 { 135 tempMinMax = this->Eval(fX+xSolo); 136 if (tempMinMax < fMin) 137 { 138 fMin = tempMinMax; 139 fAbMin = fX + xSolo; 140 } 141 if (tempMinMax > fMax) 142 { 143 fMax = tempMinMax; 144 fAbMax = fX + xSolo; 145 } 146 } 147 } 95 96 const Double_t delta = fB*fB*4 - fA*fC*12; 97 if (delta >= 0 && fA != 0) 98 { 99 const Double_t sqrtDelta = TMath::Sqrt(delta); 100 101 const Double_t xPlus = (-fB*2 + sqrtDelta)/(fA*6); 102 const Double_t xMinus = (-fB*2 - sqrtDelta)/(fA*6); 103 104 if (xPlus >= 0 && xPlus <= fH) 105 { 106 const Double_t tempMinMax = Eval(fX+xPlus); 107 if (tempMinMax < fMin) 108 { 109 fMin = tempMinMax; 110 fAbMin = fX + xPlus; 111 } 112 if (tempMinMax > fMax) 113 { 114 fMax = tempMinMax; 115 fAbMax = fX + xPlus; 116 } 117 } 118 if (xMinus >= 0 && xMinus <= fH) 119 { 120 const Double_t tempMinMax = Eval(fX+xMinus); 121 if (tempMinMax < fMin) 122 { 123 fMin = tempMinMax; 124 fAbMin = fX + xMinus; 125 } 126 if (tempMinMax > fMax) 127 { 128 fMax = tempMinMax; 129 fAbMax = fX + xMinus; 130 } 131 } 132 return kTRUE; 133 } 134 135 /* if fA is zero then we have only one possible solution */ 136 if (fA == 0 && fB != 0) 137 { 138 const Double_t xSolo = -fC/(fB*2); 139 140 if (xSolo < 0 || xSolo > fH) 141 return kTRUE; 142 143 const Double_t tempMinMax = Eval(fX+xSolo); 144 if (tempMinMax < fMin) 145 { 146 fMin = tempMinMax; 147 fAbMin = fX + xSolo; 148 } 149 if (tempMinMax > fMax) 150 { 151 fMax = tempMinMax; 152 fAbMax = fX + xSolo; 153 } 154 return kTRUE; 155 } 156 148 157 return kTRUE; 149 158 } … … 157 166 // There could be three or one real solutions 158 167 // 159 160 168 Short_t MCubicCoeff::FindCardanRoot(Double_t y, Double_t *x) 161 169 { 162 163 Short_t whichRoot = -1; 164 165 Double_t a = fB/fA; 166 Double_t b = fC/fA; 167 Double_t c = (fY - y)/fA; 168 169 Double_t q = (a*a-3.0*b)/9.0; 170 Double_t r = (2.0*a*a*a-9.0*a*b+27.0*c)/54.0; 171 172 Double_t aOver3 = a/3.0; 173 Double_t r2 = r*r; 174 Double_t q3 = q*q*q; 170 const Double_t a = fB/fA; 171 const Double_t b = fC/fA; 172 const Double_t c = (fY - y)/fA; 173 174 const Double_t q = (a*a - b*3)/9; 175 const Double_t r = (a*a*a*2 - a*b*9 + c*27)/54; 176 177 const Double_t aOver3 = a/3; 178 const Double_t r2 = r*r; 179 const Double_t q3 = q*q*q; 175 180 176 181 if (r2 < q3) //3 real sol 177 182 { 178 Double_t sqrtQ = TMath::Sqrt(q); 179 Double_t min2SqQ = -2.0*sqrtQ; 180 Double_t theta = TMath::ACos(r/(sqrtQ*sqrtQ*sqrtQ)); 181 182 x[0] = min2SqQ * TMath::Cos(theta/3.0) - aOver3; 183 x[1] = min2SqQ * TMath::Cos((theta+TMath::TwoPi())/3.0) - aOver3; 184 x[2] = min2SqQ * TMath::Cos((theta-TMath::TwoPi())/3.0) - aOver3; 183 const Double_t sqrtQ = TMath::Sqrt(q); 184 const Double_t min2SqQ = -sqrtQ*2; 185 const Double_t theta = TMath::ACos(r/(sqrtQ*sqrtQ*sqrtQ)); 186 187 x[0] = min2SqQ * TMath::Cos(theta/3) - aOver3; 188 x[1] = min2SqQ * TMath::Cos((theta+TMath::TwoPi())/3) - aOver3; 189 x[2] = min2SqQ * TMath::Cos((theta-TMath::TwoPi())/3) - aOver3; 190 185 191 for (Int_t i = 0; i < 3; i++) 186 if (x[i] >= 0 .0&& x[i] <= fH)192 if (x[i] >= 0 && x[i] <= fH) 187 193 { 188 x[i] = x[i] + fX; 189 whichRoot = i; 190 break; 194 x[i] += fX; 195 return i; 191 196 } 192 } 193 else //only 1 real sol 194 { 195 Double_t s; 196 if (r == 0.0) 197 s = 0.0; 198 else if (r < 0.0) 199 s = TMath::Power(TMath::Abs(r) + TMath::Sqrt(r2 - q3),1.0/3.0); 200 else // r > 0.0 201 s = - TMath::Power(TMath::Abs(r) + TMath::Sqrt(r2 - q3),1.0/3.0); 202 if (s == 0.0) 203 x[0] = - aOver3; 204 else 205 x[0] = (s + q/s) - aOver3; 206 if (x[0] >= 0.0 && x[0] <= fH) 207 { 208 x[0] = x[0] + fX; 209 whichRoot = 0; 210 } 211 } 212 return whichRoot; 197 return -1; 198 } 199 200 const Double_t s = r==0 ? 0 : -TMath::Sign(TMath::Power(TMath::Abs(r) + TMath::Sqrt(r2 - q3), 1./3), r); 201 202 x[0] = s==0 ? - aOver3 : (s + q/s) - aOver3; 203 204 if (x[0] < 0 || x[0] > fH) 205 return -1; 206 207 x[0] += fX; 208 return 0; 213 209 } 214 210 … … 220 216 Bool_t MCubicCoeff :: IsIn(Double_t x) 221 217 { 222 if (x >= fX && x <= fXNext) 223 return kTRUE; 224 else 225 return kFALSE; 226 } 218 return x >= fX && x <= fXNext; 219 }
Note:
See TracChangeset
for help on using the changeset viewer.