/// <summary>Creates a new <see cref="NLoptConstraint"/> object. /// </summary> /// <param name="dimension">The dimension of the constrain region.</param> /// <param name="inequalityConstraintFunction">The inequality constraint function c(x), i.e. a argument x will be accepted iff c(x) < <paramref name="tolerance"/>, /// where the first argument is the point where to evalute and the second argument contains the gradient (perhaps <c>null</c>), i.e. the partial derivatives of the function at the first argument; /// the return value is the value of the function at the first argument.</param> /// <param name="tolerance">The tolerance to take into account.</param> /// <returns>A specific <see cref="NLoptConstraint"/> object with respect to the specified optimization algorithm.</returns> /// <exception cref="InvalidOperationException">Thrown, if the optimization algorithm does not support this kind of constraints.</exception> public NLoptConstraint Create(int dimension, Func <double[], double[], double> inequalityConstraintFunction, double tolerance = MachineConsts.Epsilon) { if (inequalityConstraintFunction == null) { throw new ArgumentNullException(nameof(inequalityConstraintFunction)); } if (nloptMultiDimOptimizer.Configuration.NonlinearConstraintRequirement.HasFlag(NLoptNonlinearConstraintRequirement.SupportsInequalityConstraints) == false) { throw new InvalidOperationException("The NLopt algorithm does not support inequality constraints."); } NLoptInequalityConstraintFunction c = (n, x, grad, data) => inequalityConstraintFunction(x, grad); return(new NLoptConstraint(this, dimension, "Inequality constraint", nloptPtr => { var code = nloptPtr.AddInequalityConstraint(c, tolerance); if (code != NLoptResultCode.Success) { throw new InvalidOperationException(String.Format("Constraint can not be set to NLopt algorithm {0}; error code: {1}.", nloptPtr.ToString(), code)); } } )); }
/// <summary>Adds a specific inequality constraint. /// </summary> /// <param name="inequalityConstraintFunction">The inequality constraint function, i.e. a argument x will be accepted iff c(x) < <paramref name="tolerance"/>.</param> /// <param name="tolerance">The tolerance.</param> /// <returns>A value indicating whether the inequality constraint has been added.</returns> public NLoptResultCode AddInequalityConstraint(NLoptInequalityConstraintFunction inequalityConstraintFunction, double tolerance) { if (m_NLopPtr == IntPtr.Zero) { throw new ObjectDisposedException("NLoptPtr"); } return(nlopt_add_inequality(m_NLopPtr, inequalityConstraintFunction, IntPtr.Zero, tolerance)); }
/// <summary>Creates a specific (one-side) NLopt constraint which is specified in its <see cref="MultiDimRegion.Polynomial"/> representation. /// </summary> /// <param name="polynomialConstraint">The polynomial constraint.</param> /// <param name="lowerBound">The lower bound.</param> /// <param name="sign">The sign.</param> /// <returns>The specific <see cref="NLoptConstraint"/> object.</returns> private NLoptConstraint CreateSingle(MultiDimRegion.Polynomial polynomialConstraint, double lowerBound, int sign = 1) { NLoptInequalityConstraintFunction c = (n, x, grad, data) => { double polynomialValue = 0.0; foreach (var term in polynomialConstraint.Terms) { double temp = 0.0; foreach (var monomial in term.Item2) { temp += DoMath.Pow(x[monomial.ArgumentIndex], monomial.Power); } polynomialValue += term.Item1 * temp; } if (grad != null) { for (int j = 0; j < n; j++) { grad[j] = 0.0; } foreach (var term in polynomialConstraint.Terms) { foreach (var monomial in term.Item2) { grad[monomial.ArgumentIndex] -= term.Item1 * monomial.Power * DoMath.Pow(x[monomial.ArgumentIndex], monomial.Power - 1); } } } return(sign * (lowerBound - polynomialValue)); }; return(new NLoptConstraint(this, polynomialConstraint.Dimension, "Polynomial constraint", nloptPtr => { var code = nloptPtr.AddInequalityConstraint(c, MachineConsts.Epsilon); if (code != NLoptResultCode.Success) { throw new InvalidOperationException(String.Format("Constraint can not be set to NLopt algorithm {0}; error code: {1}.", nloptPtr.ToString(), code)); } } )); }
private static extern NLoptResultCode nlopt_add_inequality(IntPtr opt, [MarshalAs(UnmanagedType.FunctionPtr)] NLoptInequalityConstraintFunction constraintFunction, IntPtr data, double tolerance);