Skip to content
This repository has been archived by the owner on Nov 19, 2020. It is now read-only.

Commit

Permalink
GH-177: AugmentedLagrangian with NonlinearConstraints - Gradient Null…
Browse files Browse the repository at this point in the history
…ReferenceException issue
  • Loading branch information
cesarsouza committed Sep 24, 2016
1 parent cf1b850 commit 38ba635
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 241 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,71 +62,18 @@ namespace Accord.Math.Optimization
/// <para>
/// In this framework, it is possible to state a non-linear programming problem
/// using either symbolic processing or vector-valued functions. The following
/// example demonstrates the former.</para>
/// example demonstrates the symbolic processing case:</para>
///
/// <code>
/// // Suppose we would like to minimize the following function:
/// //
/// // f(x,y) = min 100(y-x²)²+(1-x)²
/// //
/// // Subject to the constraints
/// //
/// // x >= 0 (x must be positive)
/// // y >= 0 (y must be positive)
/// //
///
/// // In this example we will be using some symbolic processing.
/// // The following variables could be initialized to any value.
///
/// double x = 0, y = 0;
///
///
/// // First, we create our objective function
/// var f = new NonlinearObjectiveFunction(
///
/// // This is the objective function: f(x,y) = min 100(y-x²)²+(1-x)²
/// function: () => 100 * Math.Pow(y - x * x, 2) + Math.Pow(1 - x, 2),
///
/// // The gradient vector:
/// gradient: () => new[]
/// {
/// 2 * (200 * Math.Pow(x, 3) - 200 * x * y + x - 1), // df/dx = 2(200x³-200xy+x-1)
/// 200 * (y - x*x) // df/dy = 200(y-x²)
/// }
///
/// );
///
///
/// // Now we can start stating the constraints
/// var constraints = new List&lt;NonlinearConstraint>();
///
/// // Add the non-negativity constraint for x
/// constraints.Add(new NonlinearConstraint(f,
///
/// // 1st constraint: x should be greater than or equal to 0
/// function: () => x, shouldBe: ConstraintType.GreaterThanOrEqualTo, value: 0,
///
/// gradient: () => new[] { 1.0, 0.0 }
/// ));
///
/// // Add the non-negativity constraint for y
/// constraints.Add(new NonlinearConstraint(f,
///
/// // 2nd constraint: y should be greater than or equal to 0
/// function: () => y, shouldBe: ConstraintType.GreaterThanOrEqualTo, value: 0,
///
/// gradient: () => new[] { 0.0, 1.0 }
/// ));
///
///
/// // Finally, we create the non-linear programming solver
/// var solver = new AugmentedLagrangianSolver(2, constraints);
///
/// // And attempt to solve the problem
/// double minValue = solver.Minimize(f);
/// </code>
/// <code source="Unit Tests\Accord.Tests.Math\Optimization\AugmentedLagrangianTest.cs" region="doc_lambda"/>
///
/// <para>
/// And this is the same example as before, but using standard vectors instead.</para>
///
/// <code source="Unit Tests\Accord.Tests.Math\Optimization\AugmentedLagrangianTest.cs" region="doc_vector"/>
/// </example>
///
/// <seealso cref="GoldfarbIdnani"/>
///
public class AugmentedLagrangian : BaseGradientOptimizationMethod, IGradientOptimizationMethod
{

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,83 +172,27 @@ public NonlinearConstraint(IObjectiveFunction objective,
}
#endif

/// <summary>
/// Constructs a new nonlinear constraint.
/// </summary>
///
/// <param name="objective">The objective function to which this constraint refers.</param>
/// <param name="function">A lambda expression defining the left hand side of the
/// constraint equation.</param>
/// <param name="shouldBe">How the left hand side of the constraint should be
/// compared to the given <paramref name="value"/>.</param>
/// <param name="value">The right hand side of the constraint equation. Default is 0.</param>
///
public NonlinearConstraint(IObjectiveFunction objective,
Func<double[], double> function, ConstraintType shouldBe, double value)
{
int n = objective.NumberOfVariables;

this.Create(objective.NumberOfVariables, function, shouldBe, value, null, DEFAULT_TOL);
}

/// <summary>
/// Constructs a new nonlinear constraint.
/// </summary>
///
/// <param name="objective">The objective function to which this constraint refers.</param>
/// <param name="function">A lambda expression defining the left hand side of the
/// constraint equation.</param>
/// <param name="gradient">A lambda expression defining the gradient of the <paramref name="function">
/// left hand side of the constraint equation</paramref>.</param>
/// <param name="shouldBe">How the left hand side of the constraint should be
/// compared to the given <paramref name="value"/>.</param>
/// <param name="value">The right hand side of the constraint equation. Default is 0.</param>
///
public NonlinearConstraint(IObjectiveFunction objective,
Func<double[], double> function, ConstraintType shouldBe, double value,
Func<double[], double[]> gradient)
{
int n = objective.NumberOfVariables;

this.Create(objective.NumberOfVariables, function, shouldBe, value, gradient, DEFAULT_TOL);
}

/// <summary>
/// Constructs a new nonlinear constraint.
/// </summary>
///
/// <param name="numberOfVariables">The number of variables in the constraint.</param>
/// <param name="function">A lambda expression defining the left hand side of the constraint equation.</param>
/// <param name="shouldBe">How the left hand side of the constraint should be compared to
/// the given <paramref name="value"/>. Default is <see cref="ConstraintType.GreaterThanOrEqualTo"/>.</param>
/// <param name="value">The right hand side of the constraint equation. Default is 0.</param>
///
public NonlinearConstraint(int numberOfVariables,
Func<double[], double> function, ConstraintType shouldBe, double value)
{
this.Create(numberOfVariables, function, shouldBe, value, null, DEFAULT_TOL);
}

/// <summary>
/// Constructs a new nonlinear constraint.
/// </summary>
///
/// <param name="objective">The objective function to which this constraint refers.</param>
/// <param name="constraint">A boolean lambda expression expressing the constraint. Please
/// see examples for details.</param>
/// <param name="gradient">A lambda expression defining the gradient of the <paramref name="constraint">
/// left hand side of the constraint equation</paramref>.</param>
///
public NonlinearConstraint(IObjectiveFunction objective,
Expression<Func<double[], bool>> constraint)
public NonlinearConstraint(IObjectiveFunction objective,
Expression<Func<double[], bool>> constraint,
Func<double[], double[]> gradient = null)
{
int n = objective.NumberOfVariables;

Func<double[], double> function;
ConstraintType shouldBe;
double value;

parse(constraint, out function, out shouldBe, out value);

this.Create(objective.NumberOfVariables, function, shouldBe, value, null, DEFAULT_TOL);
this.Create(objective.NumberOfVariables, function, shouldBe, value, gradient, DEFAULT_TOL);
}

/// <summary>
Expand All @@ -258,88 +202,20 @@ public NonlinearConstraint(IObjectiveFunction objective,
/// <param name="numberOfVariables">The number of variables in the constraint.</param>
/// <param name="constraint">A boolean lambda expression expressing the constraint. Please
/// see examples for details.</param>
/// <param name="gradient">A lambda expression defining the gradient of the <paramref name="constraint">
/// left hand side of the constraint equation</paramref>.</param>
///
public NonlinearConstraint(int numberOfVariables, Expression<Func<double[], bool>> constraint)
public NonlinearConstraint(int numberOfVariables,
Expression<Func<double[], bool>> constraint,
Func<double[], double[]> gradient = null)
{
Func<double[], double> function;
ConstraintType shouldBe;
double value;

parse(constraint, out function, out shouldBe, out value);

this.Create(numberOfVariables, function, shouldBe, value, null, DEFAULT_TOL);
}

/// <summary>
/// Constructs a new nonlinear constraint.
/// </summary>
///
/// <param name="objective">The objective function to which this constraint refers.</param>
/// <param name="function">A lambda expression defining the left hand side of the constraint.</param>
///
public NonlinearConstraint(IObjectiveFunction objective, Func<double[], double> function)
{
int n = objective.NumberOfVariables;

this.Create(objective.NumberOfVariables, function, ConstraintType.GreaterThanOrEqualTo, 0.0, null, DEFAULT_TOL);
}

/// <summary>
/// Constructs a new nonlinear constraint.
/// </summary>
///
/// <param name="objective">The objective function to which this constraint refers.</param>
/// <param name="function">A lambda expression defining the left hand side of the
/// constraint equation.</param>
/// <param name="gradient">A lambda expression defining the gradient of the <paramref name="function">
/// left hand side of the constraint equation.</paramref>.</param>
///
public NonlinearConstraint(IObjectiveFunction objective,
Func<double[], double> function,
Func<double[], double[]> gradient)
{
int n = objective.NumberOfVariables;

this.Create(objective.NumberOfVariables, function,
ConstraintType.GreaterThanOrEqualTo, 0.0, gradient, DEFAULT_TOL);
}

/// <summary>
/// Constructs a new nonlinear constraint.
/// </summary>
///
/// <param name="numberOfVariables">The number of variables in the constraint.</param>
/// <param name="function">A lambda expression defining the left hand side of the
/// constraint equation.</param>
/// <param name="gradient">A lambda expression defining the gradient of the <paramref name="function">
/// left hand side of the constraint equation</paramref>.</param>
/// <param name="shouldBe">How the left hand side of the constraint should be
/// compared to the given <paramref name="value"/>.</param>
/// <param name="value">The right hand side of the constraint equation. Default is 0.</param>
/// <param name="withinTolerance">The tolerance for violations of the constraint. Equality
/// constraints should set this to a small positive value. Default is 1e-8.</param>
///
public NonlinearConstraint(int numberOfVariables,
Func<double[], double> function,
Func<double[], double[]> gradient,
ConstraintType shouldBe = ConstraintType.GreaterThanOrEqualTo,
double value = 0, double withinTolerance = DEFAULT_TOL)
{
this.Create(numberOfVariables, function,
shouldBe, value, gradient, withinTolerance);
}

/// <summary>
/// Constructs a new nonlinear constraint.
/// </summary>
///
/// <param name="numberOfVariables">The number of variables in the constraint.</param>
/// <param name="function">A lambda expression defining the left hand side of the
/// constraint equation.</param>
///
public NonlinearConstraint(int numberOfVariables, Func<double[], double> function)
{
this.Create(numberOfVariables, function, ConstraintType.GreaterThanOrEqualTo, 0.0, null, DEFAULT_TOL);
this.Create(numberOfVariables, function, shouldBe, value, gradient, DEFAULT_TOL);
}

/// <summary>
Expand All @@ -356,8 +232,11 @@ public NonlinearConstraint(int numberOfVariables, Func<double[], double> functio
/// constraints should set this to a small positive value. Default is 1e-8.</param>
///
public NonlinearConstraint(IObjectiveFunction objective,
Func<double[], double> function, ConstraintType shouldBe, double value,
Func<double[], double[]> gradient, double withinTolerance = DEFAULT_TOL)
Func<double[], double> function,
ConstraintType shouldBe = ConstraintType.GreaterThanOrEqualTo,
double value = 0,
Func<double[], double[]> gradient = null,
double withinTolerance = DEFAULT_TOL)
{
this.Create(objective.NumberOfVariables, function, shouldBe, value, gradient, withinTolerance);
}
Expand All @@ -377,8 +256,11 @@ public NonlinearConstraint(IObjectiveFunction objective,
/// constraints should set this to a small positive value. Default is 1e-8.</param>
///
public NonlinearConstraint(int numberOfVariables,
Func<double[], double> function, ConstraintType shouldBe, double value,
Func<double[], double[]> gradient, double withinTolerance = DEFAULT_TOL)
Func<double[], double> function,
ConstraintType shouldBe = ConstraintType.GreaterThanOrEqualTo,
double value = 0,
Func<double[], double[]> gradient = null,
double withinTolerance = DEFAULT_TOL)
{
this.Create(numberOfVariables, function, shouldBe, value, gradient, withinTolerance);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ public enum GoldfarbIdnaniStatus
/// <code source="Unit Tests\Accord.Tests.Math\Optimization\GoldfarbIdnaniTest.cs" region="doc_matrix" />
/// </example>
///
/// <seealso cref="AugmentedLagrangian"/>
///
public class GoldfarbIdnani : BaseGradientOptimizationMethod,
IOptimizationMethod, IOptimizationMethod<GoldfarbIdnaniStatus>
{
Expand Down
Loading

0 comments on commit 38ba635

Please sign in to comment.