Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef ABSTRACTFORWARD_H
00028 #define ABSTRACTFORWARD_H
00029
00030 #include <QGpCoreTools.h>
00031 #include "DinverCoreDLLExport.h"
00032 #include "RealSpace.h"
00033 #include "ForwardSignal.h"
00034 #include "SimpleCondition.h"
00035
00036 namespace DinverCore {
00037
00038 class UniqueRandom;
00039 class ReportWriter;
00040 class ScaledModels;
00041 class VoronoiNavigator;
00042 class ModelSet;
00043
00044 class DINVERCORE_EXPORT AbstractForward
00045 {
00046 TRANSLATIONS("AbstractForward")
00047 public:
00048 AbstractForward();
00049 virtual ~AbstractForward();
00050
00051 virtual AbstractForward * clone() const=0;
00052
00053 const RealSpace& parameterSpace() const {return _parameterSpace;}
00054 RealSpace& parameterSpace() {return _parameterSpace;}
00055
00056 virtual void misfit();
00057 virtual double misfit(bool& ok);
00058 virtual double misfit(double * , bool& ) {return 1.0;}
00059 virtual void writeReport(ReportWriter * ) {}
00060 virtual void valueChanged(const Parameter * p=0) {Q_UNUSED(p);}
00061 virtual bool isFussyOk(const Parameter * ) {return true;}
00062
00063 void setFinishSignal(ForwardSignal * s) {_finishSignal=s;}
00064 void setGenerator(UniqueRandom * generator) {_generator=generator;}
00065 void setAllModels(ModelSet * allModels) {_allModels=allModels;}
00066 bool firstModel();
00067 bool firstModel(Random& randomNumbers, AtomicBoolean& terminated);
00068 void copyValues(const AbstractForward& o);
00069 void initGenerate(const ScaledModels * scaledModels, int nWalks);
00070 virtual bool generate(int parentActiveIndex=-1);
00071
00072 enum State {Sleeping, Repairing, Accepting, Running, Aborting, Sending};
00073
00074 virtual int maximumThreadCount() const {return 1;}
00075 virtual bool wake();
00076 inline bool beginRepair();
00077 inline void endRepair();
00078 inline bool lock();
00079 inline void abort();
00080 inline void unlock();
00081 virtual void sleep();
00082
00083 inline bool isSleeping() const;
00084 inline bool isAccepting() const;
00085 inline bool isRunning() const;
00086 inline bool isAborting() const;
00087 inline bool isSending() const;
00088
00089 int parentActiveIndex() const {return _parentActiveIndex;}
00090 int modelIndex() const {return _modelIndex;}
00091 double parentVolume() const {return _parentVolume;}
00092 double misfitValue() const {return _misfitValue;}
00093 bool isValidMisfit() const {return _isValidMisfit;}
00094 bool isValidParent() const {return _isValidParent;}
00095 const QVector<int>& navigatorHits() const {return _navigatorHits;}
00096
00097 void timeReport(const QString& prefix);
00098
00099 virtual void xml_writeProperties(XML_WRITEPROPERTIES_ARGS) const {Q_UNUSED(s); Q_UNUSED(context);}
00100 virtual void xml_writeChildren(XML_WRITECHILDREN_ARGS) const {Q_UNUSED(s); Q_UNUSED(context);}
00101 virtual XMLMember xml_member(XML_MEMBER_ARGS) {Q_UNUSED(tag); Q_UNUSED(attributes); Q_UNUSED(context); return XMLMember(XMLMember::Skip);}
00102 virtual bool xml_setProperty(XML_SETPROPERTY_ARGS) {Q_UNUSED(memberID); Q_UNUSED(tag); Q_UNUSED(attributes); Q_UNUSED(content); Q_UNUSED(context); return true;}
00103 virtual void xml_polish(XML_POLISH_ARGS) {Q_UNUSED(context)}
00104 protected:
00105 bool generateInternal();
00106 void setParentActiveIndex(int parentActiveIndex) {_parentActiveIndex=parentActiveIndex;}
00107 QString streamPrefix() const {return _streamPrefix.arg(_modelIndex);}
00108 void addTimeMisfit(int ms) {_timeMisfit+=ms;}
00109 void addTimeWait(int ms) {_timeWait+=ms;}
00110 inline void send(double misfit, bool isValid, bool isValidParent=true);
00111 private:
00112 bool monteCarlo();
00113 bool neighborhood();
00114
00115 RealSpace _parameterSpace;
00116
00117 ModelSet * _allModels;
00118 UniqueRandom * _generator;
00119 VoronoiNavigator * _nav;
00120 int _nWalks;
00121 int _parentActiveIndex;
00122 int _modelIndex;
00123 QVector<int> _navigatorHits;
00124 double _parentVolume;
00125
00126 mutable QMutex _stateMutex;
00127 State _state;
00128 ForwardSignal * _finishSignal;
00129
00130 double _misfitValue;
00131 bool _isValidMisfit;
00132 bool _isValidParent;
00133
00134 int _timeWait;
00135 int _timeGenerator;
00136 int _timeMisfit;
00137 static const QString _streamPrefix;
00138 };
00139
00140 inline bool AbstractForward::lock()
00141 {
00142 QMutexLocker ml (&_stateMutex);
00143 if(_state==Accepting) {
00144 _state=Running;
00145 return true;
00146 } else {
00147 return false;
00148 }
00149 }
00150
00151 void AbstractForward::abort()
00152 {
00153 _stateMutex.lock();
00154 switch (_state) {
00155 case Sleeping:
00156 case Accepting:
00157 case Repairing:
00158 case Aborting:
00159 _stateMutex.unlock();
00160 break;
00161 case Running:
00162 _state=Aborting;
00163 _stateMutex.unlock();
00164 break;
00165 case Sending:
00166 _state=Accepting;
00167 _stateMutex.unlock();
00168 _finishSignal->finished(this);
00169 break;
00170 }
00171 }
00172
00173 void AbstractForward::unlock()
00174 {
00175 QMutexLocker ml (&_stateMutex);
00176 switch (_state) {
00177 case Sleeping:
00178 case Repairing:
00179 case Accepting:
00180 break;
00181 case Aborting:
00182 case Running:
00183 case Sending:
00184 _state=Accepting;
00185 break;
00186 }
00187 }
00188
00189 inline void AbstractForward::send(double misfit, bool isValid, bool isValidParent)
00190 {
00191 _misfitValue=misfit;
00192 _isValidMisfit=isValid;
00193 _isValidParent=isValidParent;
00194 _stateMutex.lock();
00195 switch (_state) {
00196 case Sleeping:
00197 case Repairing:
00198 case Accepting:
00199 case Sending:
00200 ASSERT(false);
00201 break;
00202 case Aborting:
00203 _state=Accepting;
00204 _stateMutex.unlock();
00205 _finishSignal->finished(this);
00206 break;
00207 case Running:
00208 _state=Sending;
00209 _stateMutex.unlock();
00210 _finishSignal->finished(this);
00211 break;
00212 }
00213 }
00214
00215 inline bool AbstractForward::beginRepair()
00216 {
00217 QMutexLocker ml (&_stateMutex);
00218 if(_state==Sleeping) {
00219 _state=Repairing;
00220 return true;
00221 } else {
00222 return false;
00223 }
00224 }
00225
00226 inline void AbstractForward::endRepair()
00227 {
00228 QMutexLocker ml (&_stateMutex);
00229 switch (_state) {
00230 case Sleeping:
00231 case Repairing:
00232 _state=Sleeping;
00233 break;
00234 case Accepting:
00235 case Aborting:
00236 case Running:
00237 case Sending:
00238 break;
00239 }
00240 }
00241
00242 inline bool AbstractForward::isSleeping() const
00243 {
00244 QMutexLocker ml (&_stateMutex);
00245 return _state==Sleeping;
00246 }
00247
00248 inline bool AbstractForward::isAccepting() const
00249 {
00250 QMutexLocker ml (&_stateMutex);
00251 return _state==Accepting;
00252 }
00253
00254 inline bool AbstractForward::isRunning() const
00255 {
00256 QMutexLocker ml (&_stateMutex);
00257 return _state== Running;
00258 }
00259
00260 inline bool AbstractForward::isAborting() const
00261 {
00262 QMutexLocker ml (&_stateMutex);
00263 return _state==Aborting;
00264 }
00265
00266 inline bool AbstractForward::isSending() const
00267 {
00268 QMutexLocker ml (&_stateMutex);
00269 return _state==Sending;
00270 }
00271
00272 }
00273
00274 #endif // ABSTRACTFORWARD_H