diff --git a/src/Numerics/Optimization/BaseObjectiveFunction.cs b/src/Numerics/Optimization/BaseObjectiveFunction.cs
index b8f663f3..3e1fbd2d 100644
--- a/src/Numerics/Optimization/BaseObjectiveFunction.cs
+++ b/src/Numerics/Optimization/BaseObjectiveFunction.cs
@@ -87,7 +87,18 @@ namespace MathNet.Numerics.Optimization
}
}
- public abstract IObjectiveFunction Fork();
+ public abstract IObjectiveFunction CreateNew();
+
+ public virtual IObjectiveFunction Fork()
+ {
+ BaseObjectiveFunction fork = (BaseObjectiveFunction)CreateNew();
+ fork.PointRaw = PointRaw;
+ fork.ValueRaw = ValueRaw;
+ fork.GradientRaw = GradientRaw;
+ fork.HessianRaw = HessianRaw;
+ fork.Status = Status;
+ return fork;
+ }
protected abstract void SetValue();
protected abstract void SetGradient();
diff --git a/src/Numerics/Optimization/IObjectiveFunction.cs b/src/Numerics/Optimization/IObjectiveFunction.cs
index f257db48..7c54093c 100644
--- a/src/Numerics/Optimization/IObjectiveFunction.cs
+++ b/src/Numerics/Optimization/IObjectiveFunction.cs
@@ -2,8 +2,15 @@
namespace MathNet.Numerics.Optimization
{
+ ///
+ /// Objective function with a frozen evaluation that must not be changed from the outside.
+ ///
public interface IObjectiveFunctionEvaluation
{
+ /// Create a new unevaluated and independent copy of this objective function
+ IObjectiveFunction CreateNew();
+
+ /// Create a new independent copy of this objective function, evaluated at the same point.
IObjectiveFunction Fork();
Vector Point { get; }
@@ -16,6 +23,9 @@ namespace MathNet.Numerics.Optimization
Matrix Hessian { get; }
}
+ ///
+ /// Objective function with a mutable evaluation.
+ ///
public interface IObjectiveFunction : IObjectiveFunctionEvaluation
{
void EvaluateAt(Vector point);
diff --git a/src/Numerics/Optimization/Implementation/CheckedObjectiveFunction.cs b/src/Numerics/Optimization/Implementation/CheckedObjectiveFunction.cs
index 9b5ef05e..308d5e6d 100644
--- a/src/Numerics/Optimization/Implementation/CheckedObjectiveFunction.cs
+++ b/src/Numerics/Optimization/Implementation/CheckedObjectiveFunction.cs
@@ -103,9 +103,14 @@ namespace MathNet.Numerics.Optimization.Implementation
}
}
+ public IObjectiveFunction CreateNew()
+ {
+ return new CheckedObjectiveFunction(InnerObjectiveFunction.CreateNew(), ValueChecker, GradientChecker, HessianChecker);
+ }
+
public IObjectiveFunction Fork()
{
- return new CheckedObjectiveFunction(InnerObjectiveFunction, ValueChecker, GradientChecker, HessianChecker);
+ return new CheckedObjectiveFunction(InnerObjectiveFunction.Fork(), ValueChecker, GradientChecker, HessianChecker);
}
public bool IsGradientSupported
diff --git a/src/Numerics/Optimization/Implementation/WeakWolfeLineSearch.cs b/src/Numerics/Optimization/Implementation/WeakWolfeLineSearch.cs
index 656e764a..2901418e 100644
--- a/src/Numerics/Optimization/Implementation/WeakWolfeLineSearch.cs
+++ b/src/Numerics/Optimization/Implementation/WeakWolfeLineSearch.cs
@@ -21,8 +21,6 @@ namespace MathNet.Numerics.Optimization.Implementation
// Implemented following http://www.math.washington.edu/~burke/crs/408/lectures/L9-weak-Wolfe.pdf
public LineSearchOutput FindConformingStep(IObjectiveFunctionEvaluation startingPoint, Vector searchDirection, double initialStep)
{
- var objective = startingPoint.Fork();
-
double lowerBound = 0.0;
double upperBound = Double.PositiveInfinity;
double step = initialStep;
@@ -33,6 +31,7 @@ namespace MathNet.Numerics.Optimization.Implementation
double initialDd = searchDirection * initialGradient;
+ var objective = startingPoint.CreateNew();
int ii;
MinimizationOutput.ExitCondition reasonForExit = MinimizationOutput.ExitCondition.None;
for (ii = 0; ii < _maximumIterations; ++ii)
diff --git a/src/Numerics/Optimization/NewtonMinimizer.cs b/src/Numerics/Optimization/NewtonMinimizer.cs
index cf3d3459..79a18249 100644
--- a/src/Numerics/Optimization/NewtonMinimizer.cs
+++ b/src/Numerics/Optimization/NewtonMinimizer.cs
@@ -62,7 +62,7 @@ namespace MathNet.Numerics.Optimization
LineSearchOutput result;
try
{
- result = lineSearcher.FindConformingStep(objective.Fork(), searchDirection, 1.0);
+ result = lineSearcher.FindConformingStep(objective, searchDirection, 1.0);
}
catch (Exception e)
{
diff --git a/src/UnitTests/OptimizationTests/TestNewtonMinimizer.cs b/src/UnitTests/OptimizationTests/TestNewtonMinimizer.cs
index d6d45d4f..d7f910d7 100644
--- a/src/UnitTests/OptimizationTests/TestNewtonMinimizer.cs
+++ b/src/UnitTests/OptimizationTests/TestNewtonMinimizer.cs
@@ -25,7 +25,7 @@ namespace MathNet.Numerics.UnitTests.OptimizationTests
HessianRaw = RosenbrockFunction.Hessian(Point);
}
- public override IObjectiveFunction Fork()
+ public override IObjectiveFunction CreateNew()
{
return new RosenbrockObjectiveFunction();
}