/*  CompassSearch.cc
 *  implementation of the CompassSearch class to find a minimal objective function
 *  solution.
 *  A compass search checks the positive and negative quardinate vectors for
 *  each dimension until improvement in the function values is found.  
 *  The search then relocates to the improving point and begins again.
 *  Liz Dolan, The College of William and Mary, 1999
 *
 *                                                                 
 *  The author of this software is Elizabeth  D. Dolan.                     
 *  Permission to use, copy, modify, and distribute this software  
 *  for any purpose without fee is hereby granted, provided that   
 *  this entire notice is included in all copies of any software   
 *  which is or includes a copy or modification of this software   
 *  and in all copies of the supporting documentation for such     
 *  software.  THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT    
 *  ANY EXPRESS OR IMPLIED WARRANTY.  IN PARTICULAR, THE AUTHOR    
 *  OFFERS NO REPRESENTATION OR WARRANTY OF ANY KIND                   
 *  CONCERNING THE MERCHANTABILITY OF THIS SOFTWARE OR ITS    
 *  FITNESS FOR ANY PARTICULAR PURPOSE.                            
 */                                                                 

#include "CompassSearch.h"


CompassSearch::CompassSearch(int numberOfVariables): PatternSearch(numberOfVariables)
{
}

CompassSearch::~CompassSearch()
{
}

void CompassSearch::ExploratoryMoves()
{
  double pace = 0.0;
  pace = GetStepLength();
  CreatePattern();
  Vector<double> currentPoint(GetVarNo());
  Vector<double> nextPoint(GetVarNo());
  double value;
  double nextValue;
  int length;
  int success = 0;
  GetMinPoint(currentPoint);
  GetMinVal(value);
  GetPatternLength(length);
  do
    {
      for( int i = 0; i < length; i++)
	{
	  NextPoint(i, currentPoint, nextPoint);
	  fcnCall(GetVarNo(), nextPoint.begin(), nextValue, success);
	  if(success==1)
	    {
	      if(nextValue < value)
		{
		  ReplaceMinimum(nextPoint, nextValue);
		  value = nextValue;
		  currentPoint = (nextPoint);
		  i = -1; //start the compass search over at the new point
		}//if there is improvement
	    }//if able to get a function value
	}//for now we know that there aren't better points around this one
      UpdatePattern();
    }while(!Stop());//while we haven't stopped()
}//ExploratoryMoves

void CompassSearch::CreatePattern()
{
  int vars = GetVarNo();
  Matrix<double>* compassPattern;
  compassPattern = new Matrix<double>(vars,2*vars, 0.0);
  if(vars > 0)
    {
      for(int j = 0; j < vars; j++)
	{
	  (*compassPattern)[j][2*j] = 1.0;
	  (*compassPattern)[j][2*j+1] = -1.0;
	}//for
      InitializePattern(2*vars, compassPattern);
      delete compassPattern;
    }//if there's anything to allocate
}//CreatePattern
  
void CompassSearch::UpdatePattern()
{
  ScalePattern(0.5);
}//UpdatePattern





