Browse Source

Root Finding: Brent behavior more consistent between managed and native providers

#690
uap-experimental
Christoph Ruegg 6 years ago
parent
commit
3e91e51b6d
  1. 66
      src/Numerics/RootFinding/Broyden.cs

66
src/Numerics/RootFinding/Broyden.cs

@ -82,42 +82,50 @@ namespace MathNet.Numerics.RootFinding
Matrix<double> B = CalculateApproximateJacobian(f, initialGuess, y0, jacobianStepSize); Matrix<double> B = CalculateApproximateJacobian(f, initialGuess, y0, jacobianStepSize);
for (int i = 0; i <= maxIterations; i++) try
{ {
var dx = (DenseVector) (-B.LU().Solve(y)); for (int i = 0; i <= maxIterations; i++)
var xnew = x + dx;
var ynew = new DenseVector(f(xnew.Values));
double gnew = ynew.L2Norm();
if (gnew > g)
{ {
double g2 = g*g; var dx = (DenseVector) (-B.LU().Solve(y));
double scale = g2/(g2 + gnew*gnew); var xnew = x + dx;
if (scale == 0.0) var ynew = new DenseVector(f(xnew.Values));
double gnew = ynew.L2Norm();
if (gnew > g)
{ {
scale = 1.0e-4; double g2 = g*g;
double scale = g2/(g2 + gnew*gnew);
if (scale == 0.0)
{
scale = 1.0e-4;
}
dx = scale*dx;
xnew = x + dx;
ynew = new DenseVector(f(xnew.Values));
gnew = ynew.L2Norm();
} }
dx = scale*dx; if (gnew < accuracy)
xnew = x + dx; {
ynew = new DenseVector(f(xnew.Values)); root = xnew.Values;
gnew = ynew.L2Norm(); return true;
} }
if (gnew < accuracy)
{
root = xnew.Values;
return true;
}
// update Jacobian B // update Jacobian B
DenseVector dF = ynew - y; DenseVector dF = ynew - y;
Matrix<double> dB = (dF - B.Multiply(dx)).ToColumnMatrix() * dx.Multiply(1.0 / Math.Pow(dx.L2Norm(), 2)).ToRowMatrix(); Matrix<double> dB = (dF - B.Multiply(dx)).ToColumnMatrix() * dx.Multiply(1.0 / Math.Pow(dx.L2Norm(), 2)).ToRowMatrix();
B = B + dB; B = B + dB;
x = xnew; x = xnew;
y = ynew; y = ynew;
g = gnew; g = gnew;
}
}
catch (InvalidParameterException)
{
root = null;
return false;
} }
root = null; root = null;

Loading…
Cancel
Save