/// <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) &lt; <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));
                }
            }
                                       ));
        }
Example #2
0
 /// <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) &lt; <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));
                }
            }
                                       ));
        }
Example #4
0
 private static extern NLoptResultCode nlopt_add_inequality(IntPtr opt, [MarshalAs(UnmanagedType.FunctionPtr)]  NLoptInequalityConstraintFunction constraintFunction, IntPtr data, double tolerance);