protected static void lnsrch( int n, double[] xold, double fold, double[] g, double[] p, double[] x, out double f, double stpmax, out int check, BFGSFunctionEval _FunctionEval, object _Params )
{
int i;
double a,alam,alam2 = 0.0,alamin,b,disc,f2 = 0.0,fold2 = 0.0,rhs1,rhs2,slope,sum,temp,test,tmplam;
check=0;
for ( sum=0.0,i=1; i <= n; i++ )
sum += p[i]*p[i];
sum = Math.Sqrt( sum );
if ( sum > stpmax )
for ( i=1; i <= n; i++ )
p[i] *= stpmax / sum;
for ( slope=0.0,i=1; i <= n; i++ )
slope += g[i] * p[i];
test = 0.0;
for ( i=1; i <= n; i++ )
{
temp = Math.Abs( p[i] ) / Math.Max( Math.Abs( xold[i] ), 1.0 );
if ( temp > test )
test = temp;
}
alamin = TOLY / test;
alam = 1.0;
int IterationsCount = 0;
while ( true )
{
IterationsCount++;
for ( i=1; i <= n; i++ )
x[i] = xold[i] + alam * p[i];
f = _FunctionEval( x, _Params );
if ( double.IsInfinity( f ) )
throw new Exception( "Infinity!" );
ENSUREVALID( x );
if ( alam < alamin )
{
for ( i=1; i <= n; i++ )
x[i] = xold[i];
check = 1;
return;
}
else if ( f <= fold + ALF * alam * slope )
return;
else
{
if ( alam == 1.0 )
tmplam = -slope / (2.0 * (f - fold-slope));
else
{
rhs1 = f-fold-alam*slope;
rhs2 = f2-fold2-alam2*slope;
a=(rhs1/(alam*alam)-rhs2/(alam2*alam2))/(alam-alam2);
b=(-alam2*rhs1/(alam*alam)+alam*rhs2/(alam2*alam2))/(alam-alam2);
if (a == 0.0) tmplam = -slope/(2.0*b);
else
{
disc = b*b - 3.0 * a * slope;
if ( disc < 0.0 )
throw new Exception( "Roundoff problem in lnsrch." );
else
tmplam = (-b + Math.Sqrt( disc ) ) / (3.0 * a);
}
if ( tmplam > 0.5 * alam )
tmplam = 0.5 * alam;
}
}
alam2=alam;
f2 = f;
fold2=fold;
alam = Math.Max( tmplam, 0.1*alam );
}
}