Skip to content
Snippets Groups Projects
Commit b700265f authored by James Goppert's avatar James Goppert
Browse files

Added NM randomization.

parent 33d176a2
No related branches found
No related tags found
No related merge requests found
...@@ -69,6 +69,7 @@ int main (int argc, char const* argv[]) ...@@ -69,6 +69,7 @@ int main (int argc, char const* argv[])
double rtol = std::numeric_limits<float>::epsilon(); double rtol = std::numeric_limits<float>::epsilon();
double abstol = std::numeric_limits<double>::epsilon(); double abstol = std::numeric_limits<double>::epsilon();
double speed = 2.0; double speed = 2.0;
double random = 0.1; // 10% random factor added to all simplex calcs
int iterMax = 2000; int iterMax = 2000;
bool showConvergeStatus = false; bool showConvergeStatus = false;
bool pause = false; bool pause = false;
...@@ -194,7 +195,7 @@ int main (int argc, char const* argv[]) ...@@ -194,7 +195,7 @@ int main (int argc, char const* argv[])
{ {
solver = new FGNelderMead(trimmer,initialGuess, solver = new FGNelderMead(trimmer,initialGuess,
lowerBound, upperBound, initialStepSize,iterMax,rtol, lowerBound, upperBound, initialStepSize,iterMax,rtol,
abstol,speed,showConvergeStatus,showSimplex,pause,&callback); abstol,speed,random,showConvergeStatus,showSimplex,pause,&callback);
while(solver->status()==1) solver->update(); while(solver->status()==1) solver->update();
} }
catch (const std::runtime_error & e) catch (const std::runtime_error & e)
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <iomanip> #include <iomanip>
#include <iostream> #include <iostream>
#include <stdexcept> #include <stdexcept>
#include <ctime>
namespace JSBSim namespace JSBSim
{ {
...@@ -31,19 +32,22 @@ FGNelderMead::FGNelderMead(Function & f, const std::vector<double> & initialGues ...@@ -31,19 +32,22 @@ FGNelderMead::FGNelderMead(Function & f, const std::vector<double> & initialGues
const std::vector<double> & lowerBound, const std::vector<double> & lowerBound,
const std::vector<double> & upperBound, const std::vector<double> & upperBound,
const std::vector<double> & initialStepSize, int iterMax, const std::vector<double> & initialStepSize, int iterMax,
double rtol, double abstol, double speed, bool showConvergeStatus, double rtol, double abstol, double speed, double randomization,
bool showConvergeStatus,
bool showSimplex, bool pause, Callback * callback) : bool showSimplex, bool pause, Callback * callback) :
m_f(f), m_lowerBound(lowerBound), m_upperBound(upperBound), m_f(f), m_lowerBound(lowerBound), m_upperBound(upperBound),
m_randomization(randomization),
m_nDim(initialGuess.size()), m_nVert(m_nDim+1), m_nDim(initialGuess.size()), m_nVert(m_nDim+1),
m_iMax(1), m_iNextMax(1), m_iMin(1), m_iMax(1), m_iNextMax(1), m_iMin(1),
m_simplex(m_nVert), m_cost(m_nVert), m_elemSum(m_nDim), m_simplex(m_nVert), m_cost(m_nVert), m_elemSum(m_nDim),
m_showSimplex(showSimplex), m_callback(callback), m_status(1), m_callback(callback), m_status(1),
initialGuess(initialGuess), initialStepSize(initialStepSize), initialGuess(initialGuess), initialStepSize(initialStepSize),
iterMax(iterMax), rtol(rtol), abstol(abstol), iterMax(iterMax), rtol(rtol), abstol(abstol),
speed(speed), showConvergeStatus(showConvergeStatus), showSimplex(showSimplex), speed(speed), showConvergeStatus(showConvergeStatus), showSimplex(showSimplex),
pause(pause), rtolI(), minCostPrevResize(1), minCost(), minCostPrev(), maxCost(), pause(pause), rtolI(), minCostPrevResize(1), minCost(), minCostPrev(), maxCost(),
nextMaxCost(), iter() nextMaxCost(), iter()
{ {
srand ( time(NULL) ); // seed random number generator
} }
void FGNelderMead::update() void FGNelderMead::update()
...@@ -197,17 +201,27 @@ void FGNelderMead::update() ...@@ -197,17 +201,27 @@ void FGNelderMead::update()
{ {
// try inversion // try inversion
double costTry = tryStretch(-1.0); double costTry = tryStretch(-1.0);
//std::cout << "cost Try 0: " << costTry << std::endl;
// if lower cost than best, then try further stretch by speed factor // if lower cost than best, then try further stretch by double speed factor
if (costTry < minCost) if (costTry < minCost)
{ {
double costTry0 = costTry;
costTry = tryStretch(speed); costTry = tryStretch(speed);
//std::cout << "cost Try 1: " << costTry << std::endl;
if (showSimplex)
{
if (costTry < costTry0) std::cout << "inversion about: " << m_iMax << std::endl;
else std::cout << "inversion and stretch about: " << m_iMax << std::endl;
}
} }
// otherwise try a contraction // otherwise try a contraction
else if (costTry > nextMaxCost) else if (costTry > nextMaxCost)
{ {
// 1d contraction // 1d contraction
costTry = tryStretch(1./speed); costTry = tryStretch(1./speed);
//std::cout << "cost Try 2: " << costTry << std::endl;
// if greater than max cost, contract about min // if greater than max cost, contract about min
if (costTry > maxCost) if (costTry > maxCost)
...@@ -216,6 +230,11 @@ void FGNelderMead::update() ...@@ -216,6 +230,11 @@ void FGNelderMead::update()
std::cout << "multiD contraction about: " << m_iMin << std::endl; std::cout << "multiD contraction about: " << m_iMin << std::endl;
contract(); contract();
} }
else
{
if (showSimplex)
std::cout << "contraction about: " << m_iMin << std::endl;
}
} }
} }
...@@ -244,6 +263,13 @@ int FGNelderMead::status() ...@@ -244,6 +263,13 @@ int FGNelderMead::status()
return m_status; return m_status;
} }
double FGNelderMead::getRandomFactor()
{
double randFact = 1+(float(rand() % 1000)/500-1)*m_randomization;
//std::cout << "random factor: " << randFact << std::endl;;
return randFact;
}
std::vector<double> FGNelderMead::getSolution() std::vector<double> FGNelderMead::getSolution()
{ {
return m_simplex[m_iMin]; return m_simplex[m_iMin];
...@@ -251,6 +277,9 @@ std::vector<double> FGNelderMead::getSolution() ...@@ -251,6 +277,9 @@ std::vector<double> FGNelderMead::getSolution()
double FGNelderMead::tryStretch(double factor) double FGNelderMead::tryStretch(double factor)
{ {
// randomize factor so we can avoid locking situations
factor = factor*getRandomFactor();
// create trial vertex // create trial vertex
double a= (1.0-factor)/m_nDim; double a= (1.0-factor)/m_nDim;
double b = a - factor; double b = a - factor;
...@@ -276,8 +305,8 @@ double FGNelderMead::tryStretch(double factor) ...@@ -276,8 +305,8 @@ double FGNelderMead::tryStretch(double factor)
if (std::abs(costTry0-costTry) > std::numeric_limits<float>::epsilon()) if (std::abs(costTry0-costTry) > std::numeric_limits<float>::epsilon())
{ {
std::cout << "\twarning: dynamics not stable!" << std::endl; //std::cout << "\twarning: dynamics not stable!" << std::endl;
return 2*m_cost[m_iMax]; //return 1000000*m_cost[m_iMax];
} }
// if trial cost lower than max // if trial cost lower than max
...@@ -290,7 +319,7 @@ double FGNelderMead::tryStretch(double factor) ...@@ -290,7 +319,7 @@ double FGNelderMead::tryStretch(double factor)
for (int dim=0;dim<m_nDim;dim++) m_simplex[m_iMax][dim] = tryVertex[dim]; for (int dim=0;dim<m_nDim;dim++) m_simplex[m_iMax][dim] = tryVertex[dim];
// update the cost // update the cost
m_cost[m_iMax] = costTry; m_cost[m_iMax] = costTry;
if (m_showSimplex) std::cout << "stretched\t" << m_iMax << "\tby : " << factor << std::endl; if (showSimplex) std::cout << "stretched\t" << m_iMax << "\tby : " << factor << std::endl;
} }
return costTry; return costTry;
} }
...@@ -302,7 +331,7 @@ void FGNelderMead::contract() ...@@ -302,7 +331,7 @@ void FGNelderMead::contract()
for (int vertex=0;vertex<m_nVert;vertex++) for (int vertex=0;vertex<m_nVert;vertex++)
{ {
m_simplex[vertex][dim] = m_simplex[vertex][dim] =
0.5*(m_simplex[vertex][dim] + getRandomFactor()*0.5*(m_simplex[vertex][dim] +
m_simplex[m_iMin][dim]); m_simplex[m_iMin][dim]);
} }
} }
...@@ -314,16 +343,15 @@ void FGNelderMead::constructSimplex(const std::vector<double> & guess, ...@@ -314,16 +343,15 @@ void FGNelderMead::constructSimplex(const std::vector<double> & guess,
for (int vertex=0;vertex<m_nVert;vertex++) for (int vertex=0;vertex<m_nVert;vertex++)
{ {
m_simplex[vertex] = guess; m_simplex[vertex] = guess;
std::vector<double> upperBound(guess.size()); }
for (int dim=0;dim<m_nDim;dim++) upperBound[dim] = m_upperBound[dim]-stepSize[dim];
boundVertex(m_simplex[vertex],m_lowerBound,upperBound);
}
for (int dim=0;dim<m_nDim;dim++) for (int dim=0;dim<m_nDim;dim++)
{ {
int vertex = dim + 1; int vertex = dim + 1;
m_simplex[vertex][dim] += stepSize[dim]; m_simplex[vertex][dim] += stepSize[dim]*getRandomFactor();
boundVertex(m_simplex[vertex],m_lowerBound,m_upperBound);
} }
if (m_showSimplex) if (showSimplex)
{ {
std::cout << "simplex: " << std::endl;; std::cout << "simplex: " << std::endl;;
for (int j=0;j<m_nVert;j++) std::cout << "\t\t" << j; for (int j=0;j<m_nVert;j++) std::cout << "\t\t" << j;
......
...@@ -48,6 +48,7 @@ public: ...@@ -48,6 +48,7 @@ public:
double rtol=std::numeric_limits<float>::epsilon(), double rtol=std::numeric_limits<float>::epsilon(),
double abstol=std::numeric_limits<float>::epsilon(), double abstol=std::numeric_limits<float>::epsilon(),
double speed = 2.0, double speed = 2.0,
double randomization=0.1,
bool showConvergeStatus=true,bool showSimplex=false, bool showConvergeStatus=true,bool showSimplex=false,
bool pause=false, bool pause=false,
Callback * callback=NULL); Callback * callback=NULL);
...@@ -60,13 +61,13 @@ private: ...@@ -60,13 +61,13 @@ private:
// attributes // attributes
Function & m_f; Function & m_f;
Callback * m_callback; Callback * m_callback;
double m_randomization;
const std::vector<double> & m_lowerBound; const std::vector<double> & m_lowerBound;
const std::vector<double> & m_upperBound; const std::vector<double> & m_upperBound;
int m_nDim, m_nVert, m_iMax, m_iNextMax, m_iMin; int m_nDim, m_nVert, m_iMax, m_iNextMax, m_iMin;
std::vector< std::vector<double> > m_simplex; std::vector< std::vector<double> > m_simplex;
std::vector<double> m_cost; std::vector<double> m_cost;
std::vector<double> m_elemSum; std::vector<double> m_elemSum;
bool m_showSimplex;
int m_status; int m_status;
const std::vector<double> & initialGuess; const std::vector<double> & initialGuess;
const std::vector<double> & initialStepSize; const std::vector<double> & initialStepSize;
...@@ -77,6 +78,7 @@ private: ...@@ -77,6 +78,7 @@ private:
maxCost, nextMaxCost; maxCost, nextMaxCost;
// methods // methods
double getRandomFactor();
double tryStretch(double factor); double tryStretch(double factor);
void contract(); void contract();
void constructSimplex(const std::vector<double> & guess, const std::vector<double> & stepSize); void constructSimplex(const std::vector<double> & guess, const std::vector<double> & stepSize);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment