@@ -232,20 +232,29 @@ void Calculate::CalculatePowerLawAutoFitSimple(Parameters *para)
232232 double error, sumError;
233233 double minError = 1e100 ;
234234 double curB = 0.0 ;
235- double x, y;
235+
236+ const unsigned int nWavel = para->nWavel ;
237+ const double refWavel = para->refWavel ;
238+ const double muspRef = para->muspAtRefWavel [para->refWavelIdx ];
239+
240+ // xRatio and y depend only on k, not on bMie
241+ std::vector<double > xRatio (nWavel);
242+ std::vector<double > y (nWavel);
243+ for (unsigned int k = 0 ; k < nWavel; k++)
244+ {
245+ xRatio[k] = para->wavelArray [k] / refWavel;
246+ y[k] = para->mus [k] * (1.0 - para->g [k]);
247+ }
236248
237249 for (int j=0 ; j<=400 ; j++)
238250 {
239251 bMie = j*0.01 ; // Range: [0, 4]
240252 sumError = 0.0 ;
241- for (unsigned int k=0 ; k<para-> nWavel ; k++)
253+ for (unsigned int k=0 ; k<nWavel; k++)
242254 {
243255 // Steve L Jacques,"Optical properties of biological tissues: a review" Phys. Med & Bio. 58(2013) R37-R61.
244- x = para->wavelArray [k];
245- yFit = ( para->muspAtRefWavel [para->refWavelIdx ]*pow (x/para->refWavel , -bMie));
246-
247- y = para->mus [k] * (1.0 - para->g [k]);
248- error = yFit - y;
256+ yFit = muspRef * pow (xRatio[k], -bMie);
257+ error = yFit - y[k];
249258 sumError += error*error;
250259 }
251260 if (sumError < minError)
@@ -264,7 +273,30 @@ void Calculate::CalculatePowerLawAutoFitComplex(Parameters *para)
264273 double error, sumError;
265274 double minError = 1e100 ;
266275 double curB = 0.0 , curF = 0.0 ;
267- double x, y;
276+
277+ const unsigned int nWavel = para->nWavel ;
278+ const double refWavel = para->refWavel ;
279+ const double muspRef = para->muspAtRefWavel [para->refWavelIdx ];
280+
281+ // xRatio, rayTerm and y depend only on k
282+ std::vector<double > xRatio (nWavel);
283+ std::vector<double > rayTerm (nWavel); // (x/refWavel)^-4, invariant across fRay and bMie
284+ std::vector<double > y (nWavel);
285+ for (unsigned int k = 0 ; k < nWavel; k++)
286+ {
287+ xRatio[k] = para->wavelArray [k] / refWavel;
288+ rayTerm[k] = pow (xRatio[k], -4.0 );
289+ y[k] = para->mus [k] * (1.0 - para->g [k]);
290+ }
291+
292+ // (x/refWavel)^-bMie depends only on (j, k), not on fRay
293+ std::vector<std::vector<double >> powTerm (401 , std::vector<double >(nWavel));
294+ for (int j = 0 ; j <= 400 ; j++)
295+ {
296+ double bMieCandidate = j * 0.01 ;
297+ for (unsigned int k = 0 ; k < nWavel; k++)
298+ powTerm[j][k] = pow (xRatio[k], -bMieCandidate);
299+ }
268300
269301 for (int i=0 ; i<=100 ; i++)
270302 {
@@ -273,14 +305,12 @@ void Calculate::CalculatePowerLawAutoFitComplex(Parameters *para)
273305 {
274306 bMie = j*0.01 ; // Range: [0, 4]
275307 sumError = 0.0 ;
276- for (unsigned int k=0 ; k<para->nWavel ; k++)
308+ const std::vector<double > &powTermJ = powTerm[j];
309+ for (unsigned int k=0 ; k<nWavel; k++)
277310 {
278311 // Steve L Jacques,"Optical properties of biological tissues: a review" Phys. Med & Bio. 58(2013) R37-R61.
279- x = para->wavelArray [k];
280- yFit = ( para->muspAtRefWavel [para->refWavelIdx ] *(fRay *pow (x/para->refWavel , -4.0 ) + (1.0 -fRay )*pow (x/para->refWavel , -bMie)));
281-
282- y = para->mus [k] * (1.0 - para->g [k]);
283- error = yFit - y;
312+ yFit = muspRef * (fRay *rayTerm[k] + (1.0 -fRay )*powTermJ[k]);
313+ error = yFit - y[k];
284314 sumError += error*error;
285315 }
286316 if (sumError < minError)
@@ -350,7 +380,7 @@ double Calculate::CalculateForwardBackward(std::complex<double> *S1,
350380 return sum;
351381}
352382
353- // Builds a ThetaGrid internally on every call
383+ // Back-compat wrapper: builds a ThetaGrid internally on every call
354384double Calculate::CalculateForwardBackward (std::complex <double > *S1 ,
355385 std::complex <double > *S2 ,
356386 Parameters *para,
@@ -379,10 +409,8 @@ double Calculate::CalculateG(std::complex<double> *S1, std::complex<double> *S2,
379409 return num/den;
380410}
381411
382- // Builds a ThetaGrid internally on every call
383- double Calculate::CalculateG (std::complex <double > *S1 ,
384- std::complex <double > *S2 ,
385- Parameters *para)
412+ // Calculate G
413+ double Calculate::CalculateG (std::complex <double > *S1 , std::complex <double > *S2 , Parameters *para)
386414{
387415 ThetaGrid grid;
388416 BuildThetaGrid (para, grid);
0 commit comments