# TOMNET  
# REGISTER (TOMNET)
# LOGIN  
# myTOMNET
TOMLAB LOGO

« Previous « Start » Next »

6  QPCON Problem

When solving a problem with a quadratic objective and nonlinear constraints TOMNET automatically supplies objective derivatives (gradient and Hessian) if inheriting from the quadratic problem class, as shown for the LPCON 5 problem.

The quadratic constrained nonlinear programming problem is defined as:

 
min
x
f(x) =
1
2
xT F x + dT x
   
s/t
xL x xU
bL A x bU
cL c(x) cU
    (8)
where x, xL, xU, d ∈ Rn, F ∈ Rn × n, f(x) ∈ R, A ∈ Rm1 × n, bL,bU ∈ Rm1 and cL,c(x),cU ∈ Rm2.

The following file (maintained from quickguide/qpconQG/qpconQG.sln) defines and solves an example problem in TOMNET:
using System;
using TOMNET;

namespace TOMNET
{
  /// <summary>
  /// Quick guide class for quadratic problem with both
  /// linear and nonlinear constraints.
  /// </summary>
  public class qpconQG : QuadraticProblem
  {
    /// <summary>
    /// Constructor for Quadratic problem with both
    /// linear and nonlinear constraints.
    /// </summary>
    /// <param name="n">Number of variables</param>
    /// <param name="mLin">Number of linear constraints</param>
    /// <param name="mNonLin">Number of nonlinear constraints</param>
    /// <param name="c">Linear part of goal function</param>
    /// <param name="F">Quadratic part of goal function</param>
    /// <param name="A">Linear constraints (row-based)</param>
    /// <param name="b_L">Lower limits of linear constraints</param>
    /// <param name="b_U">Upper limits of linear constraints</param>
    /// <param name="x_0">Initial point</param>
    /// <param name="x_L">Lower limits of variables</param>
    /// <param name="x_U">Upper limits of variables</param>
    /// <param name="c_L">Lower limits of nonlinear constraints</param>
    /// <param name="c_U">Upper limits of nonlinear constraints</param>
    /// <param name="Name">Name of problem</param>
    public qpconQG(int n, int mLin, int mNonLin, double[] c,
      double[] F, double[] A, double[] b_L, double[] b_U,
      double[] x_0, double[] x_L, double[] x_U, double[] c_L,
      double[] c_U, String Name) : base(n, mLin, F, c, A, b_L, b_U,
      x_0, x_L, x_U)
    {

      //
      // Nonlinear constraints
      //
      this.mNonLin = mNonLin;
      this.c_L = new double[mNonLin];
      this.c_U = new double[mNonLin];

      //
      // Setting the nonlinear constraint bounds
      //
      c_L.CopyTo(this.c_L, 0);
      c_U.CopyTo(this.c_U, 0);

      //
      // Other parameters
      //
      this.Name = Name;
    }

    /// <summary>
    /// Nonlinear constraints
    /// </summary>
    /// <param name="c">Values of nonlinear constraints in x.</param>
    /// <param name="x">The decision variables.</param>
    public override void c(double[] c, double[] x)
    {
      c[0] = 0.0;
      for (int i = 0; i < this.N; i++)
      {
        c[0] += Math.Pow(x[i], 2.0) / (1.0 + ((double)i) / 3.0);
      }
    }

    /// <summary>
    /// Jacobian for the nonlinear constraints
    /// </summary>
    /// <param name="Jac">Jacobian of nonlinear constraints.</param>
    /// <param name="x">The decision variables.</param>
    public override void dc(Jacobian Jac, double[] x)
    {
      for (int i = 0; i < this.N; i++)
      {
        Jac[0, i] = 2.0 * x[i] / (1.0 + ((double)i) / 3.0);
      }
    }

    /// <summary>
    /// Testprogram for qpconQG.
    /// </summary>
    static void Main()
    {
      //
      // For use in bounds.
      //
      double Inf = double.PositiveInfinity;

      //
      // Name of the problem
      //
      string Name = "qpconQG";

      //
      // Number of decision variables, linear constraints and
      // nonlinear constraints.
      //
      const int n = 10;
      const int mLin = 8;
      const int mNonLin = 1;

      //
      // Lower and upper bounds for linear constraints.
      //
      double[] b_L = new double[mLin] { 1, 1, 1, 1, 1, 1, 1, 1 };
      double[] b_U = new double[mLin] { 1, 1, 1, 1, 1, 1, 1, 1 };

      //
      // Lower and upper bounds for nonlinear constraints.
      //
      double[] c_L = new double[mNonLin] { 4 };
      double[] c_U = new double[mNonLin] { 4 };

      //
      // Lower and upper bounds for decision variables as well
      // as the starting point for the solver.
      //
      double[] x_0 = new double[n] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
      double[] x_L = new double[n] { -Inf, -Inf, -Inf, -Inf, -Inf,
          -Inf, -Inf, -Inf, -Inf, -Inf };
      double[] x_U = new double[n] { Inf, Inf, Inf, Inf, Inf,
          Inf, Inf, Inf, Inf, Inf };

      //
      // Linear constraints
      //
      double[] A = new double[n * mLin];
      for (int i = 0; i < mLin; i++)
      {
        for (int j = 0; j < n; j++)
        {
          if (i == j)
          {
            A[i * n + j] = 0.5;
          }
          else
          {
            A[i * n + j] = 1;
          }
        }
      }

      //
      // Entries for linear part of the objective function
      //
      double[] c = new double[n] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };

      //
      // Quadratic part of the objective function
      //
      double[] F = new double[100];
      for (int i = 0; i < 10; i++)
      {
        for (int j = 0; j < 10; j++)
        {
          if (j == i)
          {
            F[i + 10 * j] = -2;
          }
          else
          {
            F[i + 10 * j] = 0.0;
          }
        }
      }

      //
      // Create a problem, solver and result instance.
      //
      qpconQG Prob = new qpconQG(n, mLin, mNonLin, c, F, A, b_L, b_U,
          x_0, x_L, x_U, c_L, c_U, Name);
      SNOPT solver = new SNOPT();
      Result result;

      //
      // Define a print file for SNOPT.
      //
      string printfilename = "SnoptqpconQP.txt";
      solver.Options.PrintFile = printfilename;

      //
      // Solve the problem.
      //
      solver.Solve(Prob, out result);

      //
      // Get the solution results
      //
      double[] solution = result.x_k;
      double objective = result.f_k;

      //
      // Display the solution on the console.
      //
      Console.WriteLine(" * * * * * * * *");
      Console.WriteLine(" * Solved " + Prob.Name);
      Console.WriteLine(" * Printfile: " + printfilename);
      Console.WriteLine(" * Objective: {0,10:g3}", objective);
      Console.WriteLine(" * Solution");
      Console.WriteLine("        x_L[i] <=     x_k[i] <=     x_U[i]");
      for (int i = 0; i < solution.Length; i++)
      {
        Console.WriteLine("    {0,10:g3} <= {1,10:g3} <= {2,10:g3} ",
         Prob.x_L[i], solution[i], Prob.x_U[i]);
      }

      double[] Ax = Prob.A.Evaluate(result.x_k);
      Console.WriteLine(" * Linear constraints");
      Console.WriteLine("        b_L[i] <=   (A*x)[i] <=     b_U[i]");
      for (int i = 0; i < Prob.mLin; i++)
      {
        Console.WriteLine("    {0,10:g3} <= {1,10:g3} <= {2,10:g3}",
          Prob.A.GetLowerBound(i), Ax[i], Prob.A.GetUpperBound(i));
      }

      Console.WriteLine(" * Nonlinear constraints ");
      Console.WriteLine("        c_L[i] <=      cx[i] <=     c_U[i]");
      double[] cx = new double[Prob.mNonLin];
      Prob.c(cx, result.x_k);
      for (int i = 0; i < Prob.mNonLin; i++)
      {
        Console.WriteLine("    {0,10:g3} <= {1,10:g3} <= {2,10:g3}",
          Prob.c_L[i], cx[i], Prob.c_U[i]);
      }
    }
  }
}
The constraints and an analytical Jacobian are defined in the example class.
  c:   Nonlinear constraint vector
  dc:  Nonlinear constraint gradient matrix
  d2c: The second part of the Hessian to the Lagrangian
       function for the nonlinear constraints.
The executable is created by compiling qpconQG.sln . When running it from a command prompt the output results should be as in the following picture:

« Previous « Start » Next »