All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines
Public Types | Public Member Functions | Protected Member Functions
DinverCore::AbstractForward Class Reference

Brief description of class still missing. More...

#include <AbstractForward.h>

Inheritance diagram for DinverCore::AbstractForward:
Forward Forward Forward ModelGenerator Spac3CForward StackWeights

List of all members.

Public Types

enum  State {
  Sleeping, Repairing, Accepting, Running,
  Aborting, Sending
}

Public Member Functions

void abort ()
 AbstractForward ()
bool beginRepair ()
virtual AbstractForwardclone () const =0
void copyValues (const AbstractForward &o)
void endRepair ()
bool firstModel ()
bool firstModel (Random &randomNumbers, AtomicBoolean &terminated)
virtual bool generate (int parentActiveIndex=-1)
void initGenerate (const ScaledModels *scaledModels, int nWalks)
bool isAborting () const
bool isAccepting () const
virtual bool isFussyOk (const Parameter *)
bool isRunning () const
bool isSending () const
bool isSleeping () const
bool isValidMisfit () const
bool isValidParent () const
bool lock ()
virtual int maximumThreadCount () const
virtual void misfit ()
virtual double misfit (bool &ok)
virtual double misfit (double *, bool &)
double misfitValue () const
int modelIndex () const
const QVector< int > & navigatorHits () const
const RealSpaceparameterSpace () const
RealSpaceparameterSpace ()
int parentActiveIndex () const
double parentVolume () const
void setAllModels (ModelSet *allModels)
void setFinishSignal (ForwardSignal *s)
void setGenerator (UniqueRandom *generator)
virtual void sleep ()
void timeReport (const QString &prefix)
void unlock ()
virtual void valueChanged (const Parameter *p=0)
virtual bool wake ()
virtual void writeReport (ReportWriter *)
virtual XMLMember xml_member (XML_MEMBER_ARGS)
virtual void xml_polish (XML_POLISH_ARGS)
virtual bool xml_setProperty (XML_SETPROPERTY_ARGS)
virtual void xml_writeChildren (XML_WRITECHILDREN_ARGS) const
virtual void xml_writeProperties (XML_WRITEPROPERTIES_ARGS) const
virtual ~AbstractForward ()

Protected Member Functions

void addTimeMisfit (int ms)
void addTimeWait (int ms)
bool generateInternal ()
void send (double misfit, bool isValid, bool isValidParent=true)
void setParentActiveIndex (int parentActiveIndex)
QString streamPrefix () const

Detailed Description

Brief description of class still missing.

Full description of class still missing


Member Enumeration Documentation

Enumerator:
Sleeping 
Repairing 
Accepting 
Running 
Aborting 
Sending 

Constructor & Destructor Documentation

References Sleeping, and TRACE.

{
  TRACE;
  _state=Sleeping;
  _parentActiveIndex=-1;
  _modelIndex=-1;
  _nav=0;
  _generator=0;
  _allModels=0;
  _finishSignal=0;
}
{
  delete _nav;
}

Member Function Documentation

If the current state is 'Running' or 'Sending', the state is set to 'Aborting'. In re-implemented misfit function, you can regularly call isAborting() to abort the current computation.

References Aborting, Accepting, DinverCore::ForwardSignal::finished(), Repairing, Running, Sending, and Sleeping.

Referenced by DinverCore::Neighborhood::terminate().

{
  _stateMutex.lock();
  switch (_state) {
  case Sleeping:
  case Accepting:
  case Repairing:
  case Aborting:
    _stateMutex.unlock();
    break;
  case Running:
    _state=Aborting;
    _stateMutex.unlock();
    break;
  case Sending:
    _state=Accepting;
    _stateMutex.unlock();
    _finishSignal->finished(this);
    break;
  }
}
void DinverCore::AbstractForward::addTimeMisfit ( int  ms) [inline, protected]

Referenced by misfit().

{_timeMisfit+=ms;}
void DinverCore::AbstractForward::addTimeWait ( int  ms) [inline, protected]
{_timeWait+=ms;}

References Repairing, and Sleeping.

{
  QMutexLocker ml (&_stateMutex);
  if(_state==Sleeping) {
    _state=Repairing;
    return true;
  } else {
    return false;
  }
}
virtual AbstractForward* DinverCore::AbstractForward::clone ( ) const [pure virtual]

Copy current values from o. Used during the initialization of several parallel forward thread (intialized with the same values).

References parameterSpace(), DinverCore::Parameter::realValue(), DinverCore::Parameter::setRealValue(), TRACE, valueChanged(), DinverCore::RealSpace::variableParameter(), and DinverCore::RealSpace::variableParameterCount().

Referenced by DinverCore::Neighborhood::setThreadCount(), and DinverCore::ModelRepository::start().

{
  TRACE;
  int ndVar=_parameterSpace.variableParameterCount();
  for(int i=0; i < ndVar; i++ ) {
    Parameter * p=_parameterSpace.variableParameter(i);
    p->setRealValue(o.parameterSpace().variableParameter(i)->realValue());
  }
  valueChanged();
}

References Aborting, Accepting, Repairing, Running, Sending, and Sleeping.

{
  QMutexLocker ml (&_stateMutex);
  switch (_state) {
  case Sleeping:
  case Repairing:
    _state=Sleeping;
    break;
  case Accepting:
  case Aborting:
  case Running:
  case Sending:
    break;
  }
}

Init all random walks by generating the very first model. The forward thread must be in 'Running' state.

References DinverCore::RealSpace::conditionDiagnostic(), QGpCoreTools::endl(), DinverCore::Parameter::getGridLimits(), DinverCore::Parameter::gridCount(), isAborting(), DinverCore::RealSpace::isOk(), lock(), SAFE_UNINITIALIZED, DinverCore::Parameter::setGridValue(), QGpCoreTools::tr(), TRACE, TRACE_BUG, TRACE_BUG_N, DinverCore::UniqueRandom::uniform(), unlock(), valueChanged(), DinverCore::RealSpace::variableParameter(), and DinverCore::RealSpace::variableParameterCount().

Referenced by DinverCore::ModelRepository::start().

{
  TRACE;
  // Generate very first model
  // Set random values for parameters without checking conditions
  int ndVar=_parameterSpace.variableParameterCount();
  for(int i=0; i < ndVar; i++ ) {
    Parameter * p=_parameterSpace.variableParameter(i);
    p->setGridValue(_generator->uniform(0, p->gridCount()) );
  }
  App::stream() << tr("   The current model is probably not yet inside the parameter space.\n"
                      "   Some warnings here can be ignored.") << endl;
  // Some parametrizations may need some updates before proceeding
  valueChanged();

  // Iterate untill finding a valid model (fussy parameters conditions are not
  // handled because the current model may not be totally valid
  int nWalks=1;
  int nWalksDiagnostic=64;
  int minp, maxp;
  SAFE_UNINITIALIZED(minp, 0);
  SAFE_UNINITIALIZED(maxp, 0);
  lock();
  TRACE_BUG;
  while( !_parameterSpace.isOk()) {
    if(nWalks==nWalksDiagnostic) {
      App::stream() << tr("   Random model generated from scratch: not possible to find a good model after %1 walks.").arg(nWalks) << endl;
      _parameterSpace.conditionDiagnostic();
      nWalksDiagnostic*=2;
    }
    nWalks++;
    for(int i=0;i<ndVar; i++) {
      TRACE_BUG_N(1);
      Parameter * p=_parameterSpace.variableParameter(i);
      TRACE_BUG_N(2);
      p->getGridLimits(minp, maxp);
      TRACE_BUG_N(3);
      if(maxp<=minp) { // Forced to a fixed parameter, break it, back to initial range
        //printf("Back to original range for parameter %s\n",p->name().toAscii().data());
        minp=0;
        maxp=p->gridCount();
      }
      p->setGridValue(_generator->uniform(minp, maxp) );
      // Some parametrizations may need some updates before proceeding
      valueChanged(p);
    }
    if(isAborting()) {
      unlock();
      return false;
    }
  }
  unlock();
  App::stream() << tr("   Random model generated from scratch: perfomed %1 random walk(s)").arg(nWalks) << endl;
  //printModel();
  return true;
}
bool DinverCore::AbstractForward::firstModel ( Random randomNumbers,
AtomicBoolean terminated 
)

Init all random walks by generating the very first model. The forward thread must be in 'Running' state.

References DinverCore::RealSpace::conditionDiagnostic(), QGpCoreTools::endl(), DinverCore::Parameter::getGridLimits(), DinverCore::Parameter::gridCount(), DinverCore::RealSpace::isOk(), SAFE_UNINITIALIZED, DinverCore::Parameter::setGridValue(), QGpCoreTools::tr(), TRACE, TRACE_BUG, TRACE_BUG_N, QGpCoreTools::Random::uniform(), unlock(), QGpCoreTools::AtomicBoolean::value(), valueChanged(), DinverCore::RealSpace::variableParameter(), and DinverCore::RealSpace::variableParameterCount().

{
  TRACE;
  // Generate very first model
  // Set random values for parameters without checking conditions
  int ndVar=_parameterSpace.variableParameterCount();
  for(int i=0; i < ndVar; i++ ) {
    Parameter * p=_parameterSpace.variableParameter(i);
    p->setGridValue(randomNumbers.uniform(0, p->gridCount()) );
  }
  App::stream() << tr("   The current model is probably not yet inside the parameter space.\n"
                      "   Some warnings here can be ignored.") << endl;
  // Some parametrizations may need some updates before proceeding
  valueChanged();

  // Iterate untill finding a valid model (fussy parameters conditions are not
  // handled because the current model may not be totally valid
  int nWalks=1;
  int nWalksDiagnostic=64;
  int minp, maxp;
  SAFE_UNINITIALIZED(minp, 0);
  SAFE_UNINITIALIZED(maxp, 0);
  TRACE_BUG;
  while( !_parameterSpace.isOk()) {
    if(nWalks==nWalksDiagnostic) {
      App::stream() << tr("   Random model generated from scratch: not possible to find a good model after %1 walks.").arg(nWalks) << endl;
      _parameterSpace.conditionDiagnostic();
      nWalksDiagnostic*=2;
    }
    nWalks++;
    for(int i=0;i<ndVar; i++) {
      TRACE_BUG_N(1);
      Parameter * p=_parameterSpace.variableParameter(i);
      TRACE_BUG_N(2);
      p->getGridLimits(minp, maxp);
      TRACE_BUG_N(3);
      if(maxp<=minp) { // Forced to a fixed parameter, break it, back to initial range
        //printf("Back to original range for parameter %s\n",p->name().toAscii().data());
        minp=0;
        maxp=p->gridCount();
      }
      p->setGridValue(randomNumbers.uniform(minp, maxp) );
      // Some parametrizations may need some updates before proceeding
      valueChanged(p);
    }
    if(terminated.value()) {
      return false;
    }
  }
  unlock();
  App::stream() << tr("   Random model generated from scratch: perfomed %1 random walk(s)").arg(nWalks) << endl;
  //printModel();
  return true;
}
bool DinverCore::AbstractForward::generate ( int  parentActiveIndex = -1) [virtual]

Performs Monte-Carlo or Neighborhood according to arguments of initGenerate(). This function can be re-implemented to provide parallel model generation.

For Neighborhood only, parentModelIndex must be greater than -1 and the model corresponding to parentModelIndex must be already loaded into parameter space.

Returns false if inversion cannot be continued (parameter space maximum coverage).

References generateInternal(), setParentActiveIndex(), and streamPrefix().

Referenced by DinverCore::Neighborhood::optimization(), and DinverCore::Neighborhood::random().

{
  setParentActiveIndex(parentActiveIndex);
  CoreApplication::instance()->setStreamPrefix(streamPrefix());
  return generateInternal();
}

Referenced by generate().

{
  if(_nav) {
    ASSERT(_parentActiveIndex>-1);
    return neighborhood();
  } else {
    return monteCarlo();
  }
}
void DinverCore::AbstractForward::initGenerate ( const ScaledModels scaledModels,
int  nWalks 
)

If scaledModels is null, a random Monte-Carlo is performed by generate(), else a Neighborhood.

Referenced by DinverCore::Neighborhood::optimization(), and DinverCore::Neighborhood::random().

{
  delete _nav;
  if(scaledModels) {
    _nav=new VoronoiNavigator(scaledModels);
  } else {
    _nav=0;
  }
  _nWalks=nWalks;
}
bool DinverCore::AbstractForward::isAborting ( ) const [inline]

References Aborting.

Referenced by firstModel().

{
  QMutexLocker ml (&_stateMutex);
  return _state==Aborting;
}

References Accepting.

{
  QMutexLocker ml (&_stateMutex);
  return _state==Accepting;
}
virtual bool DinverCore::AbstractForward::isFussyOk ( const Parameter ) [inline, virtual]

Reimplemented in Forward, and ModelGenerator.

Referenced by DinverCore::ImportanceSampling::generate().

{return true;}
bool DinverCore::AbstractForward::isRunning ( ) const [inline]

References Running.

{
  QMutexLocker ml (&_stateMutex);
  return _state== Running;
}
bool DinverCore::AbstractForward::isSending ( ) const [inline]

References Sending.

{
  QMutexLocker ml (&_stateMutex);
  return _state==Sending;
}
bool DinverCore::AbstractForward::isSleeping ( ) const [inline]

References Sleeping.

{
  QMutexLocker ml (&_stateMutex);
  return _state==Sleeping;
}
{return _isValidMisfit;}

Referenced by send().

{return _isValidParent;}

Returns true if this forward is accepting new tasks. In this case, the current state is set to 'Running'. It returns immediately false if it is in another state than 'Accepting'.

References Accepting, and Running.

Referenced by firstModel().

{
  QMutexLocker ml (&_stateMutex);
  if(_state==Accepting) {
    _state=Running;
    return true;
  } else {
    return false;
  }
}
virtual int DinverCore::AbstractForward::maximumThreadCount ( ) const [inline, virtual]

Reimplemented in Forward, and Forward.

Referenced by DinverCore::ModelRepository::start().

{return 1;}

Starts misfit computation and send results (misfit, isValid). This function can be re-implemented to provide parallel forward computations.

References addTimeMisfit(), and send().

Referenced by misfit(), DinverCore::GridSnoop::optimization(), and send().

{
  QTime chrono;
  chrono.start();
  bool ok=true;
  double m=misfit(ok);
  send(m, ok, true);
  addTimeMisfit(chrono.elapsed());
}
double DinverCore::AbstractForward::misfit ( bool &  ok) [virtual]

Provided for convenience, it calls misfit(double *, bool) to compute misfit from a vector of parameter values. Reimplement this function if you do not need values under this format (direct access to parameter space).

Reimplemented in Forward, Forward, Forward, StackWeights, and ModelGenerator.

References DinverCore::RealSpace::allParameterCount(), misfit(), DinverCore::RealSpace::parameter(), and DinverCore::Parameter::realValue().

{
  int ndAll=_parameterSpace.allParameterCount();
  double model[ndAll];
  for(int i=0;i<ndAll;i++) {
    model[i]=_parameterSpace.parameter(i)->realValue();
  }
  return misfit(model, ok);
}
virtual double DinverCore::AbstractForward::misfit ( double *  ,
bool &   
) [inline, virtual]

Reimplemented in Spac3CForward.

{return 1.0;}
double DinverCore::AbstractForward::misfitValue ( ) const [inline]
{return _misfitValue;}

Referenced by ModelGenerator::misfit().

{return _modelIndex;}
const QVector<int>& DinverCore::AbstractForward::navigatorHits ( ) const [inline]
{return _navigatorHits;}
{return _parameterSpace;}
{return _parentActiveIndex;}
double DinverCore::AbstractForward::parentVolume ( ) const [inline]
{return _parentVolume;}
void DinverCore::AbstractForward::send ( double  misfit,
bool  isValid,
bool  isValidParent = true 
) [inline, protected]

Send back computed misfit. isValid is true if the misfit value was properly computed. In case of any error during forward computation (physical incompatibility in model parameters, numerical problem,...), isValid has to be set to false. If isValidParent is false and parentIndex is a positive number, the parent cell is removed from best cells and put in quarantine by Neighborhood::add(). A false value is sent when a fussy parameter cannot be assigned a value, when the cell is getting atomic, and when after several tries it was impossible to generate a new model in parent cell. Parent index is set by generate().

References Aborting, Accepting, DinverCore::ForwardSignal::finished(), isValidParent(), misfit(), Repairing, Running, Sending, and Sleeping.

Referenced by misfit().

{
  _misfitValue=misfit;
  _isValidMisfit=isValid;
  _isValidParent=isValidParent;
  _stateMutex.lock();
  switch (_state) {
  case Sleeping:
  case Repairing:
  case Accepting:
  case Sending:
    ASSERT(false);
    break;
  case Aborting:
    _state=Accepting;
    _stateMutex.unlock();
    _finishSignal->finished(this);
    break;
  case Running:
    _state=Sending;
    _stateMutex.unlock();
    _finishSignal->finished(this);
    break;
  }
}
void DinverCore::AbstractForward::setAllModels ( ModelSet allModels) [inline]

Referenced by DinverCore::Neighborhood::setThreadCount().

{_allModels=allModels;}

Referenced by DinverCore::Neighborhood::setThreadCount().

{_finishSignal=s;}

Referenced by DinverCore::Neighborhood::setThreadCount().

{_generator=generator;}
void DinverCore::AbstractForward::setParentActiveIndex ( int  parentActiveIndex) [inline, protected]

Referenced by generate().

{_parentActiveIndex=parentActiveIndex;}

Reimplemented in Forward.

References Sleeping.

Referenced by DinverCore::GridSnoop::sleep(), and DinverCore::Neighborhood::sleep().

{
  QMutexLocker ml (&_stateMutex);
  _state=Sleeping;
  delete _nav;
  _nav=0;
  _generator=0;
}
QString DinverCore::AbstractForward::streamPrefix ( ) const [inline, protected]

Referenced by generate().

{return _streamPrefix.arg(_modelIndex);}
void DinverCore::AbstractForward::timeReport ( const QString &  prefix)

References QGpCoreTools::endl(), and QGpCoreTools::tr().

{
  App::stream() << prefix << tr("Waiting: %1 ms").arg(_timeWait) << endl;
  App::stream() << prefix << tr("Generating models: %1 ms").arg(_timeGenerator) << endl;
  App::stream() << prefix << tr("Misfit computation: %1 ms").arg(_timeMisfit) << endl;
}

References Aborting, Accepting, Repairing, Running, Sending, and Sleeping.

Referenced by firstModel(), and DinverCore::Neighborhood::optimization().

{
  QMutexLocker ml (&_stateMutex);
  switch (_state) {
  case Sleeping:
  case Repairing:
  case Accepting:
    break;
  case Aborting:
  case Running:
  case Sending:
    _state=Accepting;
    break;
  }
}
virtual void DinverCore::AbstractForward::valueChanged ( const Parameter p = 0) [inline, virtual]

Reimplemented in Forward.

References Aborting, Accepting, Repairing, Running, Sending, and Sleeping.

Referenced by DinverCore::Neighborhood::setThreadCount().

{
  _timeWait=0;
  _timeGenerator=0;
  _timeMisfit=0;
  QMutexLocker ml (&_stateMutex);
  switch (_state) {
  case Sleeping:
    _state=Accepting;
    return true;
  case Repairing:
    break;
  case Accepting:
  case Aborting:
  case Running:
  case Sending:
    ASSERT(false);
    break;
  }
  return false;
}
virtual void DinverCore::AbstractForward::writeReport ( ReportWriter ) [inline, virtual]

Reimplemented in Forward, Forward, and Forward.

Referenced by InversionThread::xml_member().

{Q_UNUSED(tag); Q_UNUSED(attributes); Q_UNUSED(context); return XMLMember(XMLMember::Skip);}
virtual void DinverCore::AbstractForward::xml_polish ( XML_POLISH_ARGS  ) [inline, virtual]

Reimplemented in Forward, Forward, and Forward.

Referenced by InversionThread::xml_polish().

{Q_UNUSED(context)}

Referenced by InversionThread::xml_setProperty().

{Q_UNUSED(memberID); Q_UNUSED(tag); Q_UNUSED(attributes); Q_UNUSED(content); Q_UNUSED(context); return true;}
virtual void DinverCore::AbstractForward::xml_writeChildren ( XML_WRITECHILDREN_ARGS  ) const [inline, virtual]

Reimplemented in Forward, Forward, and Forward.

Referenced by InversionThread::xml_writeChildren().

{Q_UNUSED(s); Q_UNUSED(context);}

Referenced by InversionThread::xml_writeProperties().

{Q_UNUSED(s); Q_UNUSED(context);}

The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines