diff --git a/Sources/Accord.Math/Accord.Math.csproj b/Sources/Accord.Math/Accord.Math.csproj
index 610b3ef8f..dd0ba6b64 100644
--- a/Sources/Accord.Math/Accord.Math.csproj
+++ b/Sources/Accord.Math/Accord.Math.csproj
@@ -217,6 +217,7 @@
     <Compile Include="Matrix\Vector.MinMax.cs" />
     <Compile Include="Matrix\Matrix.MinMax.cs" />
     <Compile Include="Optimization\Base\IFunctionOptimizationMethod.cs" />
+    <Compile Include="Optimization\Constrained\Constraints\ConstraintExtensions.cs" />
     <Compile Include="Optimization\Losses\BinaryCrossEntropyLoss.cs" />
     <Compile Include="Optimization\Losses\CategoryCrossEntropyLoss.cs" />
     <Compile Include="Optimization\Losses\HammingLoss.cs" />
diff --git a/Sources/Accord.Math/Optimization/Constrained/AugmentedLagrangian.cs b/Sources/Accord.Math/Optimization/Constrained/AugmentedLagrangian.cs
index d38a381ac..fffe98c59 100644
--- a/Sources/Accord.Math/Optimization/Constrained/AugmentedLagrangian.cs
+++ b/Sources/Accord.Math/Optimization/Constrained/AugmentedLagrangian.cs
@@ -56,7 +56,7 @@ public enum AugmentedLagrangianStatus
 
         /// <summary>
         ///   The optimization could not make progress towards finding a feasible
-        ///   solution. Try increasing the <see cref="NonlinearConstraint.Tolerance"/>
+        ///   solution. Try increasing the <see cref="IConstraint.Tolerance"/>
         ///   of the constraints.
         /// </summary>
         /// 
@@ -115,9 +115,9 @@ public class AugmentedLagrangian : BaseGradientOptimizationMethod, IGradientOpti
 
         IGradientOptimizationMethod dualSolver;
 
-        NonlinearConstraint[] lesserThanConstraints;
-        NonlinearConstraint[] greaterThanConstraints;
-        NonlinearConstraint[] equalityConstraints;
+        IConstraint[] lesserThanConstraints;
+        IConstraint[] greaterThanConstraints;
+        IConstraint[] equalityConstraints;
 
 
         private double rho;
@@ -206,9 +206,9 @@ public int MaxEvaluations
         /// 
         /// <param name="numberOfVariables">The number of free parameters in the optimization problem.</param>
         /// <param name="constraints">
-        ///   The <see cref="NonlinearConstraint"/>s to which the solution must be subjected.</param>
+        ///   The <see cref="IConstraint"/>s to which the solution must be subjected.</param>
         /// 
-        public AugmentedLagrangian(int numberOfVariables, IEnumerable<NonlinearConstraint> constraints)
+        public AugmentedLagrangian(int numberOfVariables, IEnumerable<IConstraint> constraints)
             : base(numberOfVariables)
         {
             init(null, constraints, null);
@@ -220,9 +220,9 @@ public AugmentedLagrangian(int numberOfVariables, IEnumerable<NonlinearConstrain
         /// 
         /// <param name="function">The objective function to be optimized.</param>
         /// <param name="constraints">
-        ///   The <see cref="NonlinearConstraint"/>s to which the solution must be subjected.</param>
+        ///   The <see cref="IConstraint"/>s to which the solution must be subjected.</param>
         /// 
-        public AugmentedLagrangian(NonlinearObjectiveFunction function, IEnumerable<NonlinearConstraint> constraints)
+        public AugmentedLagrangian(NonlinearObjectiveFunction function, IEnumerable<IConstraint> constraints)
             : base(function.NumberOfVariables)
         {
             init(function, constraints, null);
@@ -237,10 +237,10 @@ public AugmentedLagrangian(NonlinearObjectiveFunction function, IEnumerable<Nonl
         ///   problem.</param>
         /// <param name="function">The objective function to be optimized.</param>
         /// <param name="constraints">
-        ///   The <see cref="NonlinearConstraint"/>s to which the solution must be subjected.</param>
+        ///   The <see cref="IConstraint"/>s to which the solution must be subjected.</param>
         /// 
         public AugmentedLagrangian(IGradientOptimizationMethod innerSolver,
-            NonlinearObjectiveFunction function, IEnumerable<NonlinearConstraint> constraints)
+            NonlinearObjectiveFunction function, IEnumerable<IConstraint> constraints)
             : base(innerSolver.NumberOfVariables)
         {
             if (innerSolver.NumberOfVariables != function.NumberOfVariables)
@@ -258,9 +258,9 @@ public AugmentedLagrangian(IGradientOptimizationMethod innerSolver,
         ///   optimization method</see> used internally to solve the dual of this optimization 
         ///   problem.</param>
         /// <param name="constraints">
-        ///   The <see cref="NonlinearConstraint"/>s to which the solution must be subjected.</param>
+        ///   The <see cref="IConstraint"/>s to which the solution must be subjected.</param>
         /// 
-        public AugmentedLagrangian(IGradientOptimizationMethod innerSolver, IEnumerable<NonlinearConstraint> constraints)
+        public AugmentedLagrangian(IGradientOptimizationMethod innerSolver, IEnumerable<IConstraint> constraints)
             : base(innerSolver.NumberOfVariables)
         {
             init(null, constraints, innerSolver);
@@ -268,7 +268,7 @@ public AugmentedLagrangian(IGradientOptimizationMethod innerSolver, IEnumerable<
 
 
         private void init(NonlinearObjectiveFunction function,
-            IEnumerable<NonlinearConstraint> constraints, IGradientOptimizationMethod innerSolver)
+            IEnumerable<IConstraint> constraints, IGradientOptimizationMethod innerSolver)
         {
             if (function != null)
             {
@@ -294,9 +294,9 @@ private void init(NonlinearObjectiveFunction function,
                 };
             }
 
-            var equality = new List<NonlinearConstraint>();
-            var lesserThan = new List<NonlinearConstraint>();
-            var greaterThan = new List<NonlinearConstraint>();
+            var equality = new List<IConstraint>();
+            var lesserThan = new List<IConstraint>();
+            var greaterThan = new List<IConstraint>();
 
             foreach (var c in constraints)
             {
diff --git a/Sources/Accord.Math/Optimization/Constrained/Constraints/ConstraintExtensions.cs b/Sources/Accord.Math/Optimization/Constrained/Constraints/ConstraintExtensions.cs
new file mode 100644
index 0000000000..31fa0cea9
--- /dev/null
+++ b/Sources/Accord.Math/Optimization/Constrained/Constraints/ConstraintExtensions.cs
@@ -0,0 +1,79 @@
+// Accord Math Library
+// The Accord.NET Framework
+// http://accord-framework.net
+//
+// Copyright © César Souza, 2009-2017
+// cesarsouza at gmail.com
+//
+//    This library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Lesser General Public
+//    License as published by the Free Software Foundation; either
+//    version 2.1 of the License, or (at your option) any later version.
+//
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Lesser General Public License for more details.
+//
+//    You should have received a copy of the GNU Lesser General Public
+//    License along with this library; if not, write to the Free Software
+//    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+namespace Accord.Math.Optimization
+{
+    using System;
+
+    /// <summary>
+    /// Extension methods on the <see cref="IConstraint"/> interface.
+    /// </summary>
+    public static class ConstraintExtensions
+    {
+
+        /// <summary>
+        ///   Gets how much the constraint is being violated.
+        /// </summary>
+        /// 
+        /// <param name="input">The function point.</param>
+        /// 
+        /// <returns>
+        ///   How much the constraint is being violated at the given point. Positive
+        ///   value means the constraint is not being violated with the returned slack, 
+        ///   while a negative value means the constraint is being violated by the returned
+        ///   amount.
+        /// </returns>
+        /// 
+        public static double GetViolation(this IConstraint constraint, double[] input)
+        {
+            double fx = constraint.Function(input);
+
+            switch (constraint.ShouldBe)
+            {
+                case ConstraintType.EqualTo:
+                    return Math.Abs(fx - constraint.Value);
+
+                case ConstraintType.GreaterThanOrEqualTo:
+                    return fx - constraint.Value;
+
+                case ConstraintType.LesserThanOrEqualTo:
+                    return constraint.Value - fx;
+            }
+
+            throw new NotSupportedException();
+        }
+
+        /// <summary>
+        /// Gets whether this constraint is being violated
+        /// (within the current tolerance threshold).
+        /// </summary>
+        /// <param name="constraint">The constraint.</param>
+        /// <param name="input">The function point.</param>
+        /// <returns>
+        /// True if the constraint is being violated, false otherwise.
+        /// </returns>
+        public static bool IsViolated(this IConstraint constraint, double[] input)
+        {
+            return constraint.GetViolation(input) + constraint.Tolerance < 0;
+        }
+    }
+}
diff --git a/Sources/Accord.Math/Optimization/Constrained/Constraints/IConstraint.cs b/Sources/Accord.Math/Optimization/Constrained/Constraints/IConstraint.cs
index d21330321..74f1167cd 100644
--- a/Sources/Accord.Math/Optimization/Constrained/Constraints/IConstraint.cs
+++ b/Sources/Accord.Math/Optimization/Constrained/Constraints/IConstraint.cs
@@ -23,11 +23,8 @@
 namespace Accord.Math.Optimization
 {
     using System;
-    using System.Collections.Generic;
-    using System.Linq;
-    using System.Text;
 
-    interface IConstraint
+    public interface IConstraint
     {
         /// <summary>
         ///   Gets the type of the constraint.
@@ -40,7 +37,13 @@ interface IConstraint
         ///   side of the constraint equation.
         /// </summary>
         /// 
-        double Value { get; }
+        double Value { get; }
+
+        /// <summary>
+        ///   Gets the violation tolerance for the constraint.
+        /// </summary>
+        /// 
+        double Tolerance { get; }
 
         /// <summary>
         ///   Gets the number of variables in the constraint.
@@ -61,20 +64,5 @@ interface IConstraint
         /// </summary>
         /// 
         Func<double[], double[]> Gradient { get; }
-
-        /// <summary>
-        ///   Gets how much the constraint is being violated.
-        /// </summary>
-        /// 
-        /// <param name="input">The function point.</param>
-        /// 
-        /// <returns>
-        ///   How much the constraint is being violated at the given point. Positive
-        ///   value means the constraint is not being violated with the returned slack, 
-        ///   while a negative value means the constraint is being violated by the returned
-        ///   amount.
-        /// </returns>
-        /// 
-        double GetViolation(double[] input);
-    }
+    }
 }
diff --git a/Sources/Accord.Math/Optimization/Constrained/Constraints/LinearConstraint.cs b/Sources/Accord.Math/Optimization/Constrained/Constraints/LinearConstraint.cs
index 56c0ca9b3..6c8316942 100644
--- a/Sources/Accord.Math/Optimization/Constrained/Constraints/LinearConstraint.cs
+++ b/Sources/Accord.Math/Optimization/Constrained/Constraints/LinearConstraint.cs
@@ -247,52 +247,6 @@ public LinearConstraint(IObjectiveFunction function, Expression<Func<bool>> cons
             this.Gradient = gradient;
         }
 
-        /// <summary>
-        ///   Gets how much the constraint is being violated.
-        /// </summary>
-        /// 
-        /// <param name="input">The function point.</param>
-        /// 
-        /// <returns>
-        ///   How much the constraint is being violated at the given point. Positive
-        ///   value means the constraint is not being violated with the returned slack, 
-        ///   while a negative value means the constraint is being violated by the returned
-        ///   amount.
-        /// </returns>
-        /// 
-        public double GetViolation(double[] input)
-        {
-            double fx = compute(input);
-
-            switch (ShouldBe)
-            {
-                case ConstraintType.EqualTo:
-                    return Math.Abs(fx - Value);
-
-                case ConstraintType.GreaterThanOrEqualTo:
-                    return fx - Value;
-
-                case ConstraintType.LesserThanOrEqualTo:
-                    return Value - fx;
-            }
-
-            throw new NotSupportedException();
-        }
-
-        /// <summary>
-        ///   Gets whether this constraint is being violated 
-        ///   (within the current tolerance threshold).
-        /// </summary>
-        /// 
-        /// <param name="input">The function point.</param>
-        /// 
-        /// <returns>True if the constraint is being violated, false otherwise.</returns>
-        /// 
-        public bool IsViolated(double[] input)
-        {
-            return GetViolation(input) < -Tolerance;
-        }
-
         /// <summary>
         ///   Attempts to create a <see cref="LinearConstraint"/>
         ///   from a <see cref="System.String"/> representation.
diff --git a/Sources/Accord.Math/Optimization/Constrained/Constraints/NonlinearConstraint.cs b/Sources/Accord.Math/Optimization/Constrained/Constraints/NonlinearConstraint.cs
index ce2f2ad26..04b546ee0 100644
--- a/Sources/Accord.Math/Optimization/Constrained/Constraints/NonlinearConstraint.cs
+++ b/Sources/Accord.Math/Optimization/Constrained/Constraints/NonlinearConstraint.cs
@@ -56,53 +56,7 @@ public class NonlinearConstraint : IConstraint, IFormattable
         /// </summary>
         /// 
         public Func<double[], double[]> Gradient { get; private set; }
-
-        /// <summary>
-        ///   Gets how much the constraint is being violated.
-        /// </summary>
-        /// 
-        /// <param name="input">The function point.</param>
-        /// 
-        /// <returns>
-        ///   How much the constraint is being violated at the given point. Positive
-        ///   value means the constraint is not being violated with the returned slack, 
-        ///   while a negative value means the constraint is being violated by the returned
-        ///   amount.
-        /// </returns>
-        /// 
-        public double GetViolation(double[] input)
-        {
-            double fx = Function(input);
-
-            switch (ShouldBe)
-            {
-                case ConstraintType.EqualTo:
-                    return Math.Abs(fx - Value);
-
-                case ConstraintType.GreaterThanOrEqualTo:
-                    return fx - Value;
-
-                case ConstraintType.LesserThanOrEqualTo:
-                    return Value - fx;
-            }
-
-            throw new NotSupportedException();
-        }
-
-        /// <summary>
-        ///   Gets whether this constraint is being violated 
-        ///   (within the current tolerance threshold).
-        /// </summary>
-        /// 
-        /// <param name="input">The function point.</param>
-        /// 
-        /// <returns>True if the constraint is being violated, false otherwise.</returns>
-        /// 
-        public bool IsViolated(double[] input)
-        {
-            return GetViolation(input) < -Tolerance;
-        }
-
+        
         /// <summary>
         ///   Gets the type of the constraint.
         /// </summary>
diff --git a/Unit Tests/Accord.Tests.Math/Optimization/AugmentedLagrangianTest.cs b/Unit Tests/Accord.Tests.Math/Optimization/AugmentedLagrangianTest.cs
index 15df16c82..7c22f65f5 100644
--- a/Unit Tests/Accord.Tests.Math/Optimization/AugmentedLagrangianTest.cs	
+++ b/Unit Tests/Accord.Tests.Math/Optimization/AugmentedLagrangianTest.cs	
@@ -379,34 +379,19 @@ public void solve_vectors()
                 gradient: (x) => new[]
                 {
                     2 * (200 * Math.Pow(x[0], 3) - 200 * x[0] * x[1] + x[0] - 1), // df/dx = 2(200x³-200xy+x-1)
-                    200 * (x[1] - x[0]*x[0])                                   // df/dy = 200(y-x²)
+                    200 * (x[1] - x[0]*x[0])                                      // df/dy = 200(y-x²)
                 }
             );
 
-            // Now we can start stating the constraints
-            var constraints = new List<NonlinearConstraint>()
-            {
-                // Add the non-negativity constraint for x
-                new NonlinearConstraint(f,
-                    // 1st constraint: x should be greater than or equal to 0
-                    function: (x) => x[0], // x
-                    shouldBe: ConstraintType.GreaterThanOrEqualTo,
-                    value: 0,
-                    gradient: (x) => new[] { 1.0, 0.0 }
-                ),
-
-                // Add the non-negativity constraint for y
-                new NonlinearConstraint(f,
-                    // 2nd constraint: y should be greater than or equal to 0
-                    function: (x) => x[1], // y 
-                    shouldBe: ConstraintType.GreaterThanOrEqualTo,
-                    value: 0,
-                    gradient: (x) => new[] { 0.0, 1.0 }
-                )
-            };
+            // As before, we state the constraints. However, to illustrate the flexibility
+            // of the AugmentedLagrangian, we shall use LinearConstraints to constrain the problem.
+            double[,] a = Matrix.Identity(2); // Set up the constraint matrix...
+            double[] b = Vector.Zeros(2);     // ...and the values they must be greater than
+            int numberOfEqualities = 0;
+            var linearConstraints = LinearConstraintCollection.Create(a, b, numberOfEqualities);
 
             // Finally, we create the non-linear programming solver
-            var solver = new AugmentedLagrangian(f, constraints);
+            var solver = new AugmentedLagrangian(f, linearConstraints);
 
             // And attempt to find a minimum
             bool success = solver.Minimize();
@@ -423,9 +408,9 @@ public void solve_vectors()
             Assert.AreEqual(1, solver.Solution[0], 1e-6);
             Assert.AreEqual(1, solver.Solution[1], 1e-6);
 
-            Assert.IsFalse(Double.IsNaN(minValue));
-            Assert.IsFalse(Double.IsNaN(solver.Solution[0]));
-            Assert.IsFalse(Double.IsNaN(solver.Solution[1]));
+            Assert.IsFalse(double.IsNaN(minValue));
+            Assert.IsFalse(double.IsNaN(solver.Solution[0]));
+            Assert.IsFalse(double.IsNaN(solver.Solution[1]));
         }
 
         [Test]