// following functions are utilized by the correction function in algorithm.fit // "global" variables: ax,bx,cx,IterCount,fa,fb,fc print "loading numerical routines ....." // ++++ NUMERICAL ROUTINES ++++ // The following function is a litteral implementation of the MNBRAK.C function // from Numerical Recipes. For explanation of the algorithm see the book. // The only changes are the addition of the initial check for the significant change // in the value of the LSQ. Also the function SHFT, used in the original does not // work in HOC. Therefore, the shifting operation was implicitly added in the code. func bracket() { local ulim, u, r, q, fu, dum, GOLD, GLIMIT, TINY,VStepCount GOLD=1.618034 GLIMIT=3.0 TINY=1.0e-20 VStepCount=$1 dum=0 fa=LSQ_Calc(VStepCount,ax) fb=LSQ_Calc(VStepCount,bx) // if(abs(fa-fb)<Tolerance/100){ // print "1 no significant change to LSQ, G is set to zero" // cx=-999 // return cx // } if (fb>fa){ // invert fa,fb; ax,bx dum=ax ax=bx bx=dum dum=fa fa=fb fb=dum } cx=bx+GOLD*(bx-ax) fc=LSQ_Calc(VStepCount,cx) // if(abs(fb-fc)<Tolerance/100){ // print "2 no significant change to LSQ, G is set to zero" // cx=-999 // return cx // } while (fb>fc){ r=(bx-ax)*(fb-fc) q=(bx-cx)*(fb-fa) dumm=q-r if (abs(dumm)<TINY) { print abs(q-r)/(q-r) dumm=TINY*abs(q-r)/(q-r)} u=bx-((bx-cx)*q-(bx-ax)*r)/(2*dumm) ulim=bx+GLIMIT*(cx-bx) if ((bx-u)*(u-cx) > 0.0) { fu=LSQ_Calc(VStepCount,u) IterCount+=1 if (fu < fc) { ax=bx bx=u fa=fb fb=fu return cx } else if (fu > fb) { cx=u fc=fu return cx } u=cx+GOLD*(cx-bx) fu=LSQ_Calc(VStepCount,u) IterCount+=1 } else if ((cx-u)*(u-ulim) > 0.0) { fu=LSQ_Calc(VStepCount,u) IterCount+=1 if (fu < fc) { bx=cx cx=u u=cx+GOLD*(cx-bx) fb=fc fc=fu fu=LSQ_Calc(VStepCount,u) IterCount+=1 } } else if ((u-ulim)*(ulim-cx) >= 0.0) { u=ulim fu=LSQ_Calc(VStepCount,u) IterCount+=1 } else { u=cx+GOLD*(cx-bx) fu=LSQ_Calc(VStepCount,u) IterCount+=1 } ax=bx bx=cx cx=u fa=fb fb=fc fc=fu } return cx } // The following function is a literal implementation of the GOLDEN.C function // from Numerical Reciepes. The changes are the implicit implementation of // SHFT2 and SHFT3 into the code and the use of the LSQ_Calc function. I also // added the fprint "." lines to enable following the number of iterations. func golden() { local VStepCount, Ratio, C1, f1,f2,x0,x1,x2,x3,dum VStepCount=$1 Ratio=0.61803399 C1=1-Ratio x0=ax x3=cx if (abs(cx-bx) > abs(bx-ax)) { x1=bx x2=bx+C1*(cx-bx) } else { x2=bx x1=bx-C1*(bx-ax) } f1=LSQ_Calc(VStepCount,x1) f2=LSQ_Calc(VStepCount,x2) IterCount+=2 while (abs(x3-x0) > Tolerance*(abs(x1)+abs(x2))) { if (f2 < f1) { x0=x1 x1=x2 x2=Ratio*x1+C1*x3 f1=f2 f2=LSQ_Calc(VStepCount,x2) if(PrintVerbose==1) printf(".") doEvents() IterCount+=1 if (IterCount>numRun) {ax=x2 return x2} } else { x3=x2 x2=x1 x1=Ratio*x2+C1*x0 f2=f1 f1=LSQ_Calc(VStepCount,x1) if(PrintVerbose==1) printf(".") doEvents() IterCount+=1 if (IterCount>numRun) {ax=x1 return x1} } } if (f1 < f2) { ax=x1 return x1 } else { ax=x2 return x2 } }