ROOT logo
// $Id: ODECrawler.h 2204 2009-05-17 18:01:48Z matevz $

#ifndef Numerica_ODECrawler_H
#define Numerica_ODECrawler_H

#include <TVectorD.h>
#include <Glasses/ZGlass.h>

class ODECrawlerMaster
{
public:
  virtual ~ODECrawlerMaster() {}
  virtual UInt_t ODEOrder() = 0;
  virtual void ODEDerivatives(const Double_t x, const TVectorD& y, TVectorD& d) = 0;
  virtual void ODEStart(TVectorD& v, Double_t& x1, Double_t& x2) = 0;

  ClassDef(ODECrawlerMaster, 1);
};


//==============================================================================
// ODEStorage, ODEStorageT and typedefs
//==============================================================================

class ODEStorage
{
protected:
  Int_t      mOrder;
  Int_t      mSize;

public:
  ODEStorage() :
    mOrder(0), mSize(0) {}
  ODEStorage(Int_t order, Int_t capacity=128) :
    mOrder(order), mSize(0) {}
  virtual ~ODEStorage() {}

  Int_t Order() const { return mOrder; }
  Int_t Size()  const { return mSize; }

  void ResetOrder(Int_t order, Int_t capacity=-1)
  {
    // Reset storage for new ODE-order and given capacity.
    // If capacity is -1 (default), 1.2 of size is used.

    mOrder = order;
    if (capacity == -1)
      capacity = 12*mSize/10;
    Reset(capacity);
  }

  void Reset()
  {
    // Reset storage. Capacity of containers is set to 1.2 of size.

    Reset(12*mSize/10);
  }

  virtual void Reset(Int_t capacity) = 0;

  virtual void AddEntry(Double_t x, Double_t* y) = 0;

  virtual Double_t GetMinXStored()   const = 0;
  virtual Double_t GetMaxXStored()   const = 0;
  virtual Double_t GetDeltaXStored() const { return GetMaxXStored() -  GetMinXStored(); }

  ClassDef(ODEStorage, 1);
};

template<typename TT>
class ODEStorageT : public ODEStorage
{
protected:
  vector<TT> mX;
  vector<TT> mY;

public:
  ODEStorageT(Int_t order, Int_t capacity=128) :
    ODEStorage(order, capacity)
  {
    mX.reserve(capacity);
    mY.reserve(mOrder*capacity);
  }
  virtual ~ODEStorageT() {}

  virtual void Reset(Int_t capacity)
  {
    // Reset storage to given capacity.

    vector<TT> x; x.reserve(capacity);        mX.swap(x);
    vector<TT> y; y.reserve(mOrder*capacity); mY.swap(y);
    mSize = 0;
  }

  virtual void AddEntry(Double_t x, Double_t* y)
  {
    mX.push_back(x);
    for (Int_t i = 0; i < mOrder; ++i)
      mY.push_back(y[i]);
    ++mSize;
  }

  virtual Double_t GetMinXStored()   const { return mSize > 0 ? mX[0]       : 0; }
  virtual Double_t GetMaxXStored()   const { return mSize > 0 ? mX[mSize-1] : 0; }
  virtual Double_t GetDeltaXStored() const { return mSize > 0 ? mX[mSize-1] - mX[0] : 0; }

  TT        GetX(Int_t i) const { return  mX[i];        }
  const TT* GetY(Int_t i) const { return &mY[mOrder*i]; }
  const TT* GetXArr()     const { return &mX[0];        }
  const TT* GetYArr()     const { return &mY[0];        }

  void      AssignY(Int_t i, TVectorT<TT>& v) const { v.Use(mOrder, &mY[mOrder*i]); }

  ClassDef(ODEStorageT, 1);
};

// What's wrong with this, Axel?
#ifndef __APPLE__
template class ODEStorageT<Float_t>;
template class ODEStorageT<Double_t>;
#endif

typedef ODEStorageT<Float_t>  ODEStorageF;
typedef ODEStorageT<Double_t> ODEStorageD;


//==============================================================================
// ODECrawler
//==============================================================================

class ODECrawler : public ZGlass
{
private:
  Double_t          hTINY, hSAFETY, hPGROW, hPSHRNK, hERRCON; //!
  ODECrawlerMaster *hTrueMaster; //!
  Bool_t            hCrawling;   //!

  void _init();

protected:
  ZLink<ZGlass> mODEMaster;     // X{GS} L{a}

  Int_t 	mGuessesOK;	//! X{g}  7 ValOut(-join=>1)
  Int_t 	mGuessesBad;	//! X{g}  7 ValOut()
  Int_t 	mStored;	//! X{g}  7 ValOut(-join=>1)
  Int_t 	mMaxSteps;	//  X{gS} 7 Value()
  Int_t 	mStoreMax;	//  X{gS} 7 Value(-join=>1)
  Double_t	mStoreDx;	//  X{gS} 7 Value()
  ODEStorage   *mStorage;       //  X{g}

  TVectorD	mY;		//! X{r}
  Int_t		mN;		//  X{g}  7 ValOut(-join=>1)
  Double_t	mAcc;		//  X{gS} 7 Value(-range=>[0,1])
  Double_t	mX1;		//  X{gS} 7 Value(-join=>1)
  Double_t	mX2;		//  X{gS} 7 Value()
  Double_t	mH1;		//  X{gS} 7 Value(-join=>1)
  Double_t	mHmin;		//  X{gS} 7 Value()

  void          init_integration(Bool_t call_ode_start);

  Int_t		Rkqs(TVectorD& y, TVectorD& dydx, Double_t& x, Double_t htry,
		     TVectorD& yscal, Double_t& h_last, Double_t& h_next);
  void 		Rkck(TVectorD& y, TVectorD& dydx, Double_t x, Double_t h,
		     TVectorD& yout, TVectorD& yerr);
  void		Integrate();

public:
  ODECrawler(const Text_t* n="ODECrawler", const Text_t* t=0) :
    ZGlass(n,t) { _init(); }

  virtual ~ODECrawler();

  void        AdvanceXLimits(Double_t delta_x=0);

  void        SetStorage(ODEStorage* s);
  void        DetachStorage();
  ODEStorage* SwapStorage(ODEStorage* s);

  void        Crawl(Bool_t call_ode_start=true); // X{ED} 7 MCWButt()

  // If you really (really) know what you're doing.
  void        ChangeOrderInPlace(Int_t order);
  Double_t*   RawYArray();

#include "ODECrawler.h7"
  ClassDef(ODECrawler, 1);
}; // endclass ODECrawler


#endif
 ODECrawler.h:1
 ODECrawler.h:2
 ODECrawler.h:3
 ODECrawler.h:4
 ODECrawler.h:5
 ODECrawler.h:6
 ODECrawler.h:7
 ODECrawler.h:8
 ODECrawler.h:9
 ODECrawler.h:10
 ODECrawler.h:11
 ODECrawler.h:12
 ODECrawler.h:13
 ODECrawler.h:14
 ODECrawler.h:15
 ODECrawler.h:16
 ODECrawler.h:17
 ODECrawler.h:18
 ODECrawler.h:19
 ODECrawler.h:20
 ODECrawler.h:21
 ODECrawler.h:22
 ODECrawler.h:23
 ODECrawler.h:24
 ODECrawler.h:25
 ODECrawler.h:26
 ODECrawler.h:27
 ODECrawler.h:28
 ODECrawler.h:29
 ODECrawler.h:30
 ODECrawler.h:31
 ODECrawler.h:32
 ODECrawler.h:33
 ODECrawler.h:34
 ODECrawler.h:35
 ODECrawler.h:36
 ODECrawler.h:37
 ODECrawler.h:38
 ODECrawler.h:39
 ODECrawler.h:40
 ODECrawler.h:41
 ODECrawler.h:42
 ODECrawler.h:43
 ODECrawler.h:44
 ODECrawler.h:45
 ODECrawler.h:46
 ODECrawler.h:47
 ODECrawler.h:48
 ODECrawler.h:49
 ODECrawler.h:50
 ODECrawler.h:51
 ODECrawler.h:52
 ODECrawler.h:53
 ODECrawler.h:54
 ODECrawler.h:55
 ODECrawler.h:56
 ODECrawler.h:57
 ODECrawler.h:58
 ODECrawler.h:59
 ODECrawler.h:60
 ODECrawler.h:61
 ODECrawler.h:62
 ODECrawler.h:63
 ODECrawler.h:64
 ODECrawler.h:65
 ODECrawler.h:66
 ODECrawler.h:67
 ODECrawler.h:68
 ODECrawler.h:69
 ODECrawler.h:70
 ODECrawler.h:71
 ODECrawler.h:72
 ODECrawler.h:73
 ODECrawler.h:74
 ODECrawler.h:75
 ODECrawler.h:76
 ODECrawler.h:77
 ODECrawler.h:78
 ODECrawler.h:79
 ODECrawler.h:80
 ODECrawler.h:81
 ODECrawler.h:82
 ODECrawler.h:83
 ODECrawler.h:84
 ODECrawler.h:85
 ODECrawler.h:86
 ODECrawler.h:87
 ODECrawler.h:88
 ODECrawler.h:89
 ODECrawler.h:90
 ODECrawler.h:91
 ODECrawler.h:92
 ODECrawler.h:93
 ODECrawler.h:94
 ODECrawler.h:95
 ODECrawler.h:96
 ODECrawler.h:97
 ODECrawler.h:98
 ODECrawler.h:99
 ODECrawler.h:100
 ODECrawler.h:101
 ODECrawler.h:102
 ODECrawler.h:103
 ODECrawler.h:104
 ODECrawler.h:105
 ODECrawler.h:106
 ODECrawler.h:107
 ODECrawler.h:108
 ODECrawler.h:109
 ODECrawler.h:110
 ODECrawler.h:111
 ODECrawler.h:112
 ODECrawler.h:113
 ODECrawler.h:114
 ODECrawler.h:115
 ODECrawler.h:116
 ODECrawler.h:117
 ODECrawler.h:118
 ODECrawler.h:119
 ODECrawler.h:120
 ODECrawler.h:121
 ODECrawler.h:122
 ODECrawler.h:123
 ODECrawler.h:124
 ODECrawler.h:125
 ODECrawler.h:126
 ODECrawler.h:127
 ODECrawler.h:128
 ODECrawler.h:129
 ODECrawler.h:130
 ODECrawler.h:131
 ODECrawler.h:132
 ODECrawler.h:133
 ODECrawler.h:134
 ODECrawler.h:135
 ODECrawler.h:136
 ODECrawler.h:137
 ODECrawler.h:138
 ODECrawler.h:139
 ODECrawler.h:140
 ODECrawler.h:141
 ODECrawler.h:142
 ODECrawler.h:143
 ODECrawler.h:144
 ODECrawler.h:145
 ODECrawler.h:146
 ODECrawler.h:147
 ODECrawler.h:148
 ODECrawler.h:149
 ODECrawler.h:150
 ODECrawler.h:151
 ODECrawler.h:152
 ODECrawler.h:153
 ODECrawler.h:154
 ODECrawler.h:155
 ODECrawler.h:156
 ODECrawler.h:157
 ODECrawler.h:158
 ODECrawler.h:159
 ODECrawler.h:160
 ODECrawler.h:161
 ODECrawler.h:162
 ODECrawler.h:163
 ODECrawler.h:164
 ODECrawler.h:165
 ODECrawler.h:166
 ODECrawler.h:167
 ODECrawler.h:168
 ODECrawler.h:169
 ODECrawler.h:170
 ODECrawler.h:171
 ODECrawler.h:172
 ODECrawler.h:173
 ODECrawler.h:174
 ODECrawler.h:175
 ODECrawler.h:176
 ODECrawler.h:177
 ODECrawler.h:178
 ODECrawler.h:179
 ODECrawler.h:180
 ODECrawler.h:181
 ODECrawler.h:182
 ODECrawler.h:183
 ODECrawler.h:184
 ODECrawler.h:185
 ODECrawler.h:186
 ODECrawler.h:187
 ODECrawler.h:188
 ODECrawler.h:189
 ODECrawler.h:190