DinverCore/AbstractForward.h
Go to the documentation of this file.
00001 /***************************************************************************
00002 **
00003 **  This file is part of DinverCore.
00004 **
00005 **  This file may be distributed and/or modified under the terms of the
00006 **  GNU General Public License version 2 or 3 as published by the Free
00007 **  Software Foundation and appearing in the file LICENSE.GPL included
00008 **  in the packaging of this file.
00009 **
00010 **  This file is distributed in the hope that it will be useful, but WITHOUT
00011 **  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 **  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
00013 **  more details.
00014 **
00015 **  You should have received a copy of the GNU General Public License
00016 **  along with this program. If not, see <http://www.gnu.org/licenses/>.
00017 **
00018 **  See http://www.geopsy.org for more information.
00019 **
00020 **  Created : 2009-05-06
00021 **  Authors:
00022 **    Marc Wathelet
00023 **    Marc Wathelet (LGIT, Grenoble, France)
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 * /*model*/ , bool& /*ok*/ ) {return 1.0;}
00059   virtual void writeReport(ReportWriter * /*report*/ ) {}
00060   virtual void valueChanged(const Parameter * p=0) {Q_UNUSED(p);}
00061   virtual bool isFussyOk(const Parameter * /*p*/ ) {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   // Public XML interface... this object is not an XMLClass
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 } // namespace DinverCore
00273 
00274 #endif // ABSTRACTFORWARD_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines