text: // Copyright (C) 2022 Frank E. Curtis
  //
  // This code is published under the MIT License.
  //
  // Author(s) : Frank E. Curtis
  
  // Description : Implementation for NonOpt of the objective
  //                 f(x) = max_{i=1..n} x_i^2
  //               with initial point
  //                 x_i =  i for all i = 1..n/2
  //                 x_i = -i for all i = n/2+1..n
  // Notes       : THIS PROBLEM IS CONVEX
  //               Optimal value: 0.0
  
  #ifndef __MAXQ_HPP__
  #define __MAXQ_HPP__
  
  #include "NonOptProblem.hpp"
  
  using namespace NonOpt;
  
  /**
   * MaxQ class
   */
  class MaxQ : public Problem
  {
  
  public:
    /** @name Constructors */
    //@{
    /**
     * Constructor
     */
    MaxQ(int n);
    //@}
  
    /** @name Destructor */
    //@{
    /**
     * Destructor
     */
    ~MaxQ();
    //@}
  
    /** @name Get methods */
    //@{
    /**
     * Number of variables
     * \param[out] n is the number of variables, an integer (return value)
     * \return indicator of success (true) or failure (false)
     */
    bool numberOfVariables(int& n);
    /**
     * Initial point
     * \param[in] n is the number of variables, the size of "x", a constant integer
     * \param[out] x is the initial point/iterate, a double array (return value)
     * \return indicator of success (true) or failure (false)
     */
    bool initialPoint(int n,
                      double* x);
    //@}
  
    /** @name Evaluate methods */
    //@{
    /**
     * Evaluates objective
     * \param[in] n is the number of variables, the size of "x", a constant integer
     * \param[in] x is a given point/iterate, a constant double array
     * \param[out] f is the objective value at "x", a double (return value)
     * \return indicator of success (true) or failure (false)
     */
    bool evaluateObjective(int n,
                           const double* x,
                           double& f);
    /**
     * Evaluates objective and gradient
     * \param[in] n is the number of variables, the size of "x", a constant integer
     * \param[in] x is a given point/iterate, a constant double array
     * \param[out] f is the objective value at "x", a double (return value)
     * \param[out] g is the gradient value at "x", a double array (return value)
     * \return indicator of success (true) or failure (false)
     */
    bool evaluateObjectiveAndGradient(int n,
                                      const double* x,
                                      double& f,
                                      double* g);
    /**
     * Evaluates gradient
     * \param[in] n is the number of variables, the size of "x", a constant integer
     * \param[in] x is a given point/iterate, a constant double array
     * \param[out] g is the gradient value at "x", a double array (return value)
     * \return indicator of success (true) or failure (false)
     */
    bool evaluateGradient(int n,
                          const double* x,
                          double* g);
    //@}
  
    /** @name Finalize methods */
    //@{
    /**
     * Finalizes solution
     * \param[in] n is the number of variables, the size of "x", a constant integer
     * \param[in] x is the final point/iterate, a constant double array
     * \param[in] f is the objective value at "x", a constant double
     * \param[in] g is the gradient value at "x", a constant double array
     * \return indicator of success (true) or failure (false)
     */
    bool finalizeSolution(int n,
                          const double* x,
                          double f,
                          const double* g);
    //@}
  
  private:
    /** @name Default compiler generated methods
     * (Hidden to avoid implicit creation/calling.)
     */
    //@{
    /**
     * Copy constructor
     */
    MaxQ(const MaxQ&);
    /**
     * Overloaded equals operator
     */
    void operator=(const MaxQ&);
    //@}
  
    /** @name Private members */
    //@{
    int number_of_variables_; /**< Number of variables */
    //@}
  
  }; // end MaxQ
  
  #endif /* __MAXQ_HPP__ */
  