121Real agiant,floatn,s1,s2,s3,xabs,x1max,x3max;
123static double rdwarf = 3.834e-20;
124static double rgiant = 1.304e19;
125static double zero = 0.0;
126static double one = 1.0;
134agiant = rgiant/floatn;
138xabs = std::fabs(x[i]);
139if( (xabs > rdwarf) && (xabs < agiant) )
156 s1 = one + s1*temp*temp;
172 s3 = one + s3*temp*temp;
189 temp = s1 + (s2/x1max)/x1max;
190 ans = x1max*std::sqrt(temp);
196 temp = s2*(one+(x3max/s2)*(x3max*s3));
198 temp = x3max*((s2/x3max)+(x3max*s3));
199 ans = std::sqrt(temp);
203 ans = x3max*std::sqrt(s3);
344 static double zero = 0.0;
348 eps = std::sqrt(temp);
350 for (j = 0; j <
n; j++) {
352 h = eps * std::fabs(temp);
356 fcn(m,
n, x, wa, iflag);
360 for (i = 0; i < m; i++) {
361 fjac[ij] = (wa[i] - fvec[i]) / h;
453int i,ij,jj,j,jp1,k,kmax,minmn;
455static double zero = 0.0;
456static double one = 1.0;
457static double p05 = 0.05;
465 acnorm[j] =
enorm(m,&a[ij]);
466 rdiag[j] = acnorm[j];
476for( j=0; j<minmn; j++ )
486 if(rdiag[k] > rdiag[kmax])
502rdiag[kmax] = rdiag[j];
514ajnorm =
enorm(m-j,&a[jj]);
533for( k=jp1; k<
n; k++ )
553 if( (pivot != 0) && (rdiag[k] != zero) )
555 temp = a[j+m*k]/rdiag[k];
556 temp =
dmax1( zero, one-temp*temp );
557 rdiag[k] *= std::sqrt(temp);
558 temp = rdiag[k]/wa[k];
559 if( (p05*temp*temp) <=
MACHEP)
561 rdiag[k] =
enorm(m-j-1,&a[jp1+m*k]);
667 int i, ij, ik, kk, j, jp1, k, kp1, l, nsing;
668 Real cos, cotan, qtbpj, sin, sum, tan, temp;
669 static double zero = 0.0;
670 static double p25 = 0.25;
671 static double p5 = 0.5;
678 for (j = 0; j <
n; j++) {
681 for (i = j; i <
n; i++) {
720 if(std::fabs(
r[kk]) < std::fabs(sdiag[k]))
722 cotan =
r[kk]/sdiag[k];
723 sin = p5/std::sqrt(p25+p25*cotan*cotan);
728 tan = sdiag[k]/
r[kk];
729 cos = p5/std::sqrt(p25+p25*tan*tan);
736 r[kk] = cos*
r[kk] + sin*sdiag[k];
737 temp = cos*wa[k] + sin*qtbpj;
738 qtbpj = -sin*wa[k] + cos*qtbpj;
747 for( i=kp1; i<
n; i++ )
749 temp = cos*
r[ik] + sin*sdiag[i];
750 sdiag[i] = -sin*
r[ik] + cos*sdiag[i];
772 if( (sdiag[j] == zero) && (nsing ==
n) )
780for( k=0; k<nsing; k++ )
788 for( i=jp1; i<nsing; i++ )
794 wa[j] = (wa[j] - sum)/sdiag[j];
920 int i, iter, ij, jj, j, jm1, jp1, k, l, nsing;
921 Real dxnorm, fp, gnorm, parc, parl, paru;
923 static double zero = 0.0;
924 static double p1 = 0.1;
925 static double p001 = 0.001;
934 for (j = 0; j <
n; j++) {
936 if ((
r[jj] == zero) && (nsing ==
n))
944 for( k=0; k<nsing; k++ )
947 wa1[j] = wa1[j]/
r[j+ldr*j];
953 for( i=0; i<=jm1; i++ )
955 wa1[i] -=
r[ij]*temp;
974 wa2[j] = diag[j]*x[j];
992 wa1[j] = diag[l]*(wa2[l]/dxnorm);
1002 for( i=0; i<=jm1; i++ )
1004 sum +=
r[ij]*wa1[i];
1008 wa1[j] = (wa1[j] - sum)/
r[j+ldr*j];
1012 parl = ((fp/delta)/temp)/temp;
1022 for( i=0; i<=j; i++ )
1024 sum +=
r[ij]*qtb[i];
1028 wa1[j] = sum/diag[l];
1039*par =
dmax1( *par,parl);
1040*par =
dmin1( *par,paru);
1042 *par = gnorm/dxnorm;
1053temp = std::sqrt( *par );
1055 wa1[j] = temp*diag[j];
1056qrsolv(
n,
r,ldr,ipvt,wa1,qtb,x,sdiag,wa2);
1058 wa2[j] = diag[j]*x[j];
1067if( (std::fabs(fp) <= p1*delta)
1068 || ((parl == zero) && (fp <= temp) && (temp < zero))
1077 wa1[j] = diag[l]*(wa2[l]/dxnorm);
1082 wa1[j] = wa1[j]/sdiag[j];
1088 for( i=jp1; i<
n; i++ )
1090 wa1[i] -=
r[ij]*temp;
1097parc = ((fp/delta)/temp)/temp;
1102 parl =
dmax1(parl, *par);
1104 paru =
dmin1(paru, *par);
1108*par =
dmax1(parl, *par + parc);
1133 int nprint,
int* info,
int* nfev,
Real* fjac,
1134 int ldfjac,
int* ipvt,
Real* qtf,
1321int i,iflag,ij,jj,iter,j,l;
1322Real actred,delta=0,dirder,fnorm,fnorm1,gnorm;
1323Real par,pnorm,prered,ratio;
1324Real sum,temp,temp1,temp2,temp3,xnorm=0;
1325static double one = 1.0;
1326static double p1 = 0.1;
1327static double p5 = 0.5;
1328static double p25 = 0.25;
1329static double p75 = 0.75;
1330static double p0001 = 1.0e-4;
1331static double zero = 0.0;
1339if( (
n <= 0) || (m <
n) || (ldfjac < m) || (ftol < zero)
1340 || (xtol < zero) || (gtol < zero) || (maxfev <= 0)
1341 || (factor <= zero) )
1346 for( j=0; j<
n; j++ )
1348 if( diag[j] <= 0.0 )
1357fcn(m,
n,x,fvec,&iflag);
1361fnorm =
enorm(m,fvec);
1378 fdjac2(m,
n,x,fvec,fjac,ldfjac,&iflag,epsfcn,wa4, fcn);
1380 jacFcn(m,
n,x,fjac,&iflag);
1390 if(
mod(iter-1,nprint) == 0)
1392 fcn(m,
n,x,fvec,&iflag);
1400qrfac(m,
n,fjac,ldfjac,1,ipvt,
n,wa1,wa2,wa3);
1409 for( j=0; j<
n; j++ )
1412 if( wa2[j] == zero )
1421 for( j=0; j<
n; j++ )
1422 wa3[j] = diag[j] * x[j];
1425 delta = factor*xnorm;
1444 for( i=j; i<m; i++ )
1446 sum += fjac[ij] * wa4[i];
1449 temp = -sum / temp3;
1451 for( i=j; i<m; i++ )
1453 wa4[i] += fjac[ij] * temp;
1469 for( j=0; j<
n; j++ )
1476 for( i=0; i<=j; i++ )
1478 sum += fjac[ij]*(qtf[i]/fnorm);
1481 gnorm =
dmax1(gnorm,std::fabs(sum/wa2[l]));
1499 for( j=0; j<
n; j++ )
1500 diag[j] =
dmax1(diag[j],wa2[j]);
1510lmpar(
n,fjac,ldfjac,ipvt,diag,qtf,delta,&par,wa1,wa2,wa3,wa4);
1517 wa2[j] = x[j] + wa1[j];
1518 wa3[j] = diag[j]*wa1[j];
1525 delta =
dmin1(delta,pnorm);
1530fcn(m,
n,wa2,wa4,&iflag);
1534fnorm1 =
enorm(m,wa4);
1539if( (p1*fnorm1) < fnorm)
1541 temp = fnorm1/fnorm;
1542 actred = one - temp * temp;
1555 for( i=0; i<=j; i++ )
1557 wa3[i] += fjac[ij]*temp;
1562temp1 =
enorm(
n,wa3)/fnorm;
1563temp2 = (std::sqrt(par)*pnorm)/fnorm;
1564prered = temp1*temp1 + (temp2*temp2)/p5;
1565dirder = -(temp1*temp1 + temp2*temp2);
1572 ratio = actred/prered;
1581 temp = p5*dirder/(dirder + p5*actred);
1582 if( ((p1*fnorm1) >= fnorm)
1585 delta = temp*
dmin1(delta,pnorm/p1);
1590 if( (par == zero) || (ratio >= p75) )
1604 for( j=0; j<
n; j++ )
1607 wa2[j] = diag[j]*x[j];
1609 for( i=0; i<m; i++ )
1618if( (std::fabs(actred) <= ftol)
1620 && (p5*ratio <= one) )
1622if(delta <= xtol*xnorm)
1624if( (std::fabs(actred) <= ftol)
1626 && (p5*ratio <= one)
1636if( (std::fabs(actred) <=
MACHEP)
1638 && (p5*ratio <= one) )
1664 fcn(m,
n,x,fvec,&iflag);
std::function< Real(Real)> b
wrapper for MINPACK minimization routine
void lmdif(int m, int n, Real *x, Real *fvec, Real ftol, Real xtol, Real gtol, int maxfev, Real epsfcn, Real *diag, int mode, Real factor, int nprint, int *info, int *nfev, Real *fjac, int ldfjac, int *ipvt, Real *qtf, Real *wa1, Real *wa2, Real *wa3, Real *wa4, const QuantLib::MINPACK::LmdifCostFunction &fcn, const QuantLib::MINPACK::LmdifCostFunction &jacFcn)
void qrfac(int m, int n, Real *a, int, int pivot, int *ipvt, int, Real *rdiag, Real *acnorm, Real *wa)
void fdjac2(int m, int n, Real *x, const Real *fvec, Real *fjac, int, int *iflag, Real epsfcn, Real *wa, const QuantLib::MINPACK::LmdifCostFunction &fcn)
Real dmin1(Real a, Real b)
Real enorm(int n, Real *x)
void qrsolv(int n, Real *r, int ldr, const int *ipvt, const Real *diag, const Real *qtb, Real *x, Real *sdiag, Real *wa)
std::function< void(int, int, Real *, Real *, int *)> LmdifCostFunction
void lmpar(int n, Real *r, int ldr, int *ipvt, const Real *diag, Real *qtb, Real delta, Real *par, Real *x, Real *sdiag, Real *wa1, Real *wa2)
Real dmax1(Real a, Real b)
ext::shared_ptr< YieldTermStructure > r