/******************************************************************************
* NOMAD -  Nonlinear Optimization for Mixed vAriables and Derivatives.        *
* Copyright (C) 2001-2004  Gilles Couture - Ecole Polytechnique,              *
*                          Charles Audet - Ecole Polytechnique,               *
*		           John Dennis - Rice University.                     *
*                                                                             *
* Author: Gilles Couture                                                      *
* École Polytechnique de Montréal - GERAD                                     *
* C.P. 6079, Succ. Centre-ville, Montréal (Québec) H3C 3A7 Canada             *
* Tel:  (514) 340-6053 x6928                                                  *
* Email: Gilles.Couture@gerad.ca                                              *
* Fax: (514) 340-5665                                                         *
*                                                                             *
* This program is free software; you can redistribute it and/or               *
* modify it under the terms of the GNU General Public License                 *
* as published by the Free Software Foundation. You can find the              *
* GNU General Public License at:                                              *
*             http://www.gnu.org/copyleft/gpl.html                            *
*                                                                             *
* This program 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 General Public License for more details.                                *
*                                                                             *
* You should have received a copy of the GNU General Public License           *
* along with this program; if not, write to the Free Software                 *
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. *
*                                                                             *
* You can find information on the NOMAD software at:                          *
*             http://www.gerad.ca/NOMAD/                                      *
******************************************************************************/

// directionset.h -- class definition for DirectionSet. This class controls
// the set of poll directions.

#ifndef _DIRECTIONSET_H_
#define _DIRECTIONSET_H_
#include <deque>
#include <vector>
using namespace std;
#include "direction.h"

class Description;
class Parameters;

class DirectionSet
{
  // The DirectionSet object has the following variables:
  // - "polldirs" is a STL container of Direction objects.
 private:
  double r_max;
  int display_factor;
  std::deque<Direction> primary_dirs;
  std::deque<Direction> secondary_dirs;
  std::deque<Direction>::iterator direction;
  std::vector<std::vector<double> > permanent_dirs;
  const Description * const description;
  const Parameters * const parameters;

// The class methods are described in "directionset.cpp".
  double randomProportion();
  double randomSign();
  double roundNumber(double temp) const;
  int findIndex(const double index);
  int makePermanentDir(const double index, const double index_factor);
  void buildDirection(const int pos, const int val);
  void buildGPSPollSet();
  void buildHybridPollDirs(int * prox, const int count);
  void buildOrthogonalPollDirs(int * prox, const int count);
  void makeGPS2NDirs();
  void makeGPSNPlus1Dirs(const int dimension, std::deque<Direction> & p);
  void makeGPSUniformDirs(const int dimension, std::deque<Direction> & p);
  void makeMADSDirs();
  void makePollDir(const std::vector<double> v, std::deque<Direction> & p);
  void showDirections();
  void showPermanentDirs();

 public:
  DirectionSet(const Description * const des, const Parameters * const par);
  ~DirectionSet();
  std::vector<double> & getSuccessfulDirection(const int polldir_index);
  void buildMADSPollSet(const double delta);
  void rebuildPollDirSet(int * prox);
  void success(const int index);

  // Inline methods.
  // ---------------

  // This method returns the address of 'primary_dirs'.
  std::deque<Direction> & getPrimaryDirs() {return primary_dirs;}
  // This method returns the address of 'secondary_dirs'.
  std::deque<Direction> & getSecondaryDirs() {return secondary_dirs;}
  // The display factor is reset.
  void setDisplay(const int display) {display_factor = display;}
};
#endif
