00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef martingale_lattice_h
00024 #define martingale_lattice_h
00025
00026
00027 #include "TypedefsMacros.h"
00028 #include "Node.h"
00029 #include "Array.h"
00030 #include <vector>
00031 #include <cstdlib>
00032 #include <cmath>
00033
00034 MTGL_BEGIN_NAMESPACE(Martingale)
00035
00036 using std::vector;
00037
00038
00047
00048
00049
00050
00051
00052
00053
00088 template<typename Node>
00089 class Lattice {
00090
00091 protected:
00092
00094 typedef Node NodeType;
00095
00097 int T;
00098
00099
00100 Array1D< vector<Node*>* > nodeList;
00101
00102
00103 public:
00104
00105
00106
00107
00108 int getTimeSteps() const { return T; }
00109
00111 virtual Real getTimeStep() = 0;
00112
00115 vector<Node*>* getNodeList(int t) { return nodeList[t]; }
00116
00119 Node* getRoot(){ return nodeList[0]->front(); }
00120
00127 virtual Real transitionProbability(int i) = 0;
00128
00129
00130
00131
00134 Lattice(int s) :
00135 T(s), nodeList(T+1)
00136 {
00137
00138 for(int t=0;t<=T;t++)
00139 nodeList[t]=new vector<Node*>();
00140 }
00141
00142
00143
00144
00145
00146
00147 virtual ~Lattice(){
00148
00149 for(int t=0;t<=T;t++){
00150
00151
00152 vector<Node*>* nodes_t=nodeList[t];
00153 vector<Node*>::iterator theNode=nodes_t->begin();
00154 while(theNode!=nodes_t->end()) { delete *theNode; ++theNode; }
00155
00156 delete nodes_t;
00157 }
00158 }
00159
00160
00165
00166 void selfTest()
00167 {
00168 cout << endl << endl << "Checking nodes until time T-1 = " << T-1 << endl;
00169
00170 for(int t=0;t<T;t++){
00171
00172 std::cout << "\nNodes at time t = " << t << ";";
00173
00174
00175 Real p,psum=0.0;
00176 bool prob_failure=false;
00177
00178 vector<Node*>* nodes=nodeList[t];
00179
00180
00181
00182 vector<Node*>::const_iterator theNode=nodes->begin();
00183 while(theNode!=nodes->end()){
00184
00185 Node* node=*theNode;
00186 const Array1D<Node*>& edges=node->getEdges();
00187 int nEdge = edges.getDimension();
00188 psum=0.0;
00189 for(int i=0;i<nEdge;i++) {
00190
00191
00192 p=transitionProbability(i);
00193 if((p<0)||(p>1)) prob_failure=true;
00194 psum+=p;
00195 }
00196
00197 if(abs(psum-1.0)>0.0000001) prob_failure=true;
00198 if(prob_failure){
00199
00200 cout << " *** t = " << t
00201 << "; transition probabilities defective, sum = " << psum;
00202 exit(0);
00203 }
00204
00205 ++theNode;
00206
00207 }
00208
00209 cout << " OK";
00210
00211 }
00212
00213 }
00214
00215
00216
00217 };
00218
00219
00220
00234 namespace LatticeBuilder {
00235
00241 template<typename LatticeType>
00242 void buildTwoFactorLattice(LatticeType* theLattice, int T, bool verbose=false)
00243 {
00244 typedef typename LatticeType::NodeType Node;
00245 int nodes=0;
00246
00247 vector<Node*>* nodes_0 = theLattice->getNodeList(0);
00248
00249
00250 IntArray1D k(2);
00251
00252
00253
00254 Node* nextNode=new Node(4,k);
00255
00256
00257 if(verbose)
00258 cout << "\nNode size: " << sizeof(*nextNode) << " bytes" << endl;
00259
00260
00261 nodes_0->push_back(nextNode);
00262 nodes++;
00263
00264
00265 for(int s=0;s<T;s++) {
00266
00267 vector<Node*>* listCurrentNodes = theLattice->getNodeList(s);
00268 vector<Node*>* listNewNodes = theLattice->getNodeList(s+1);
00269 listNewNodes->reserve((2*s+3)*(2*s+3));
00270
00271
00272
00273 Array2D<Node*> newNodes(2*s+3,2*s+3,-s-1,-s-1);
00274
00275
00276
00277 vector<Node*>::const_iterator theNode=listCurrentNodes->begin();
00278 while(theNode!=listCurrentNodes->end())
00279 {
00280 Node* currentNode=*theNode;
00281 Array1D<Node*>& edges=currentNode->getEdges();
00282 int i=0;
00283
00284
00285 int* l=currentNode->getIntegerTicks();
00286
00287
00288
00289 for(int p=-1;p<2;p+=2)
00290 for(int q=-1;q<2;q+=2)
00291 {
00292
00293 k[0]=l[0]+p; k[1]=l[1]+q;
00294
00295 nextNode=newNodes(k[0],k[1]);
00296
00297 if(!nextNode){
00298
00299 nextNode=new Node(4,k);
00300 newNodes(k[0],k[1])=nextNode;
00301 listNewNodes->push_back(nextNode);
00302 nodes++;
00303 }
00304
00305 edges[i]=nextNode;
00306 ++i;
00307
00308 }
00309
00310 ++theNode;
00311
00312 }
00313
00314 if(verbose)
00315 cout << "\nTime step = " << s+1 << "; total nodes = " << nodes;
00316
00317 }
00318 }
00319
00320
00321
00327 template<typename LatticeType>
00328 void buildThreeFactorLattice(LatticeType* theLattice, int T, bool verbose=false)
00329 {
00330 typedef typename LatticeType::NodeType Node;
00331 int nodes=0;
00332 vector<Node*>* nodes_0 = theLattice->getNodeList(0);
00333
00334
00335 IntArray1D k(3);
00336
00337
00338 Node* nextNode=new Node(8,k);
00339
00340
00341 if(verbose)
00342 cout << "\nNode size: " << sizeof(*nextNode) << " bytes" << endl;
00343
00344
00345 nodes_0->push_back(nextNode);
00346 nodes++;
00347
00348
00349 for(int s=0;s<T;s++) {
00350
00351 vector<Node*>* listCurrentNodes = theLattice->getNodeList(s);
00352 vector<Node*>* listNewNodes = theLattice->getNodeList(s+1);
00353 listNewNodes->reserve((2*s+3)*(2*s+3)*(2*s+3));
00354
00355
00356
00357 Array3D<Node*> newNodes(2*s+3,2*s+3,2*s+3,-s-1,-s-1,-s-1);
00358
00359
00360
00361 vector<Node*>::const_iterator theNode=listCurrentNodes->begin();
00362 while(theNode!=listCurrentNodes->end())
00363 {
00364 Node* currentNode=*theNode;
00365 Array1D<Node*>& edges=currentNode->getEdges();
00366 int i=0;
00367
00368
00369 int* l=currentNode->getIntegerTicks();
00370
00371
00372
00373 for(int p=-1;p<2;p+=2)
00374 for(int q=-1;q<2;q+=2)
00375 for(int r=-1;r<2;r+=2)
00376 {
00377
00378 k[0]=l[0]+p; k[1]=l[1]+q; k[2]=l[2]+r;
00379
00380 nextNode=newNodes(k[0],k[1],k[2]);
00381
00382 if(!nextNode){
00383
00384 nextNode=new Node(8,k);
00385 newNodes(k[0],k[1],k[2])=nextNode;
00386 listNewNodes->push_back(nextNode);
00387 nodes++;
00388 }
00389
00390 edges[i]=nextNode;
00391 ++i;
00392
00393 }
00394
00395 ++theNode;
00396
00397 }
00398
00399 if(verbose)
00400 cout << "\nTime step = " << s+1 << "; total nodes = " << nodes;
00401
00402 }
00403 }
00404
00405
00406 };
00407
00408
00409
00410
00411
00412 MTGL_END_NAMESPACE(Martingale)
00413
00414 #endif
00415