Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

Lattice.h

Go to the documentation of this file.
00001 /* WARANTY NOTICE AND COPYRIGHT
00002 This program is free software; you can redistribute it and/or
00003 modify it under the terms of the GNU General Public License
00004 as published by the Free Software Foundation; either version 2
00005 of the License, or (at your option) any later version.
00006 
00007 This program is distributed in the hope that it will be useful,
00008 but WITHOUT ANY WARRANTY; without even the implied warranty of
00009 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010 GNU General Public License for more details.
00011 
00012 You should have received a copy of the GNU General Public License
00013 along with this program; if not, write to the Free Software
00014 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00015 
00016 Copyright (C) Michael J. Meyer
00017 
00018 matmjm@mindspring.com
00019 spyqqqdia@yahoo.com
00020 
00021 */
00022 
00023 #ifndef martingale_lattice_h    
00024 #define martingale_lattice_h
00025 
00026 // definitions are in the header
00027 #include "TypedefsMacros.h"
00028 #include "Node.h"
00029 #include "Array.h"
00030 #include <vector>
00031 #include <cstdlib> // exit()
00032 #include <cmath>
00033 
00034 MTGL_BEGIN_NAMESPACE(Martingale)
00035 
00036 using std::vector;
00037 
00038 
00047 /**********************************************************************************
00048  *
00049  *            GENERAL LATTICE
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         // nodeList[t] is the list of pointers to nodes at time t
00100         Array1D< vector<Node*>* > nodeList; 
00101 
00102         
00103 public:
00104         
00105 
00106 // ACCESSORS
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 // CONSTRUCTOR
00131         
00134         Lattice(int s) : 
00135         T(s), nodeList(T+1)
00136         {  
00137                 // the lists of nodes at each time t
00138                 for(int t=0;t<=T;t++)
00139                 nodeList[t]=new vector<Node*>(); // empty list
00140         }
00141 
00142 
00143         // since we have lists of pointers to node not lists of nodes
00144         // at each time t we have to manuallay iterate through the list
00145         // and deallocate each pointee node. Only then can we use
00146         // list deallocation to free the list of pointers.
00147         virtual ~Lattice(){ 
00148                 
00149                 for(int t=0;t<=T;t++){ 
00150                         
00151                         // iterate through the list of pointers to Node at time t
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                         // now deallocate the list of pointers
00156                         delete nodes_t; 
00157                 }
00158         } // end destructor
00159 
00160                                         
00165         // code is more general than necessary.
00166         void selfTest()
00167     {   
00168                 cout << endl << endl << "Checking nodes until time T-1 = " << T-1 << endl;
00169                 // loop over times t
00170                 for(int t=0;t<T;t++){
00171                         
00172                         std::cout << "\nNodes at time t = " << t << ";";
00173                         
00174                         // probabilities at each node and their sum
00175                         Real p,psum=0.0;   
00176                         bool prob_failure=false;
00177                                                 
00178                         vector<Node*>* nodes=nodeList[t];
00179 
00180                         // iterate over list elements, 
00181                         // *theNode is pointer to node
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                                         // Node* edge=edges[i];
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                                  } // endif
00204                                  
00205                                  ++theNode;
00206                                 
00207                         } // end while(theNode)
00208                                                         
00209             cout << " OK";
00210                         
00211                 } // end for t
00212                 
00213         } // end selfTest()
00214 
00215                                 
00216 
00217 }; // end Lattice
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;                                          // counter
00246         // list of nodes at time t
00247         vector<Node*>* nodes_0 = theLattice->getNodeList(0);  
00248 
00249         // array of integer tick multiples Z_j=k[j]*a, j=0,1, at each node
00250         IntArray1D k(2);
00251 
00252         // the initial node n(s,k0,k1), k0=k1=0.
00253         // 4 edges per node
00254         Node* nextNode=new Node(4,k);
00255         
00256         // how big is this?
00257         if(verbose)
00258         cout << "\nNode size: " << sizeof(*nextNode) << " bytes" << endl;
00259                         
00260         // enter into node list at time s=0
00261         nodes_0->push_back(nextNode); 
00262         nodes++;
00263 
00264         // for s=0,...,T-1 build nodes at time s+1 from nodes at time s
00265         for(int s=0;s<T;s++) {
00266 
00267                 vector<Node*>* listCurrentNodes = theLattice->getNodeList(s);   // list of nodes at time t
00268                 vector<Node*>* listNewNodes = theLattice->getNodeList(s+1);     // list of nodes at time t+1
00269         listNewNodes->reserve((2*s+3)*(2*s+3));
00270                 
00271                 // registry for possible nodes at time s+1, n(s+1,i,j), 
00272                 // -(s+1) <= i=k[0],j=k[1] <= s+1
00273                 Array2D<Node*> newNodes(2*s+3,2*s+3,-s-1,-s-1);
00274                         
00275                 // run through the list of nodes at time t and connect to the new nodes
00276                 // iterator is pointer to pointer to node
00277                 vector<Node*>::const_iterator theNode=listCurrentNodes->begin();
00278                 while(theNode!=listCurrentNodes->end())                 
00279                 {
00280                         Node* currentNode=*theNode;
00281                         Array1D<Node*>& edges=currentNode->getEdges();  // edge list 
00282                         int i=0;                                        // edge counter
00283                         
00284                         // state of this node
00285                         int* l=currentNode->getIntegerTicks();
00286 
00287                         // allocate the four successor nodes
00288                         // loop over transitions p,q=-1,+1 (up/down tick)
00289                         for(int p=-1;p<2;p+=2)
00290                         for(int q=-1;q<2;q+=2) 
00291                         {       
00292                                 // integer state we transition to
00293                                 k[0]=l[0]+p; k[1]=l[1]+q;
00294                                 // connect to this node in the registry
00295                                 nextNode=newNodes(k[0],k[1]);
00296                                 // if it does not exist yet
00297                                 if(!nextNode){ 
00298                                                 
00299                                           nextNode=new Node(4,k);                // 4 edges per node
00300                                           newNodes(k[0],k[1])=nextNode;          // register the node
00301                                           listNewNodes->push_back(nextNode);     // append to list
00302                                           nodes++; 
00303                                 }
00304         
00305                                 edges[i]=nextNode;      // connect the current node
00306                                 ++i;
00307                                 
00308                    } // end for p,q
00309                            
00310                    ++theNode;
00311                            
00312             } // end while(theNode)
00313 
00314                 if(verbose)             
00315                 cout << "\nTime step = " << s+1 << ";  total nodes = " << nodes;
00316                 
00317         } // end for s
00318 } // end buildTwoFactorLattice
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;                                          // counter
00332         vector<Node*>* nodes_0 = theLattice->getNodeList(0);  // list of nodes at time t
00333 
00334         // array of integer tick multiples Z_j=k[j]*a, j=0,1, at each node
00335         IntArray1D k(3);
00336         // the initial node n(s,k0,k1), k0=k1=0.
00337         // 8 edges per node
00338         Node* nextNode=new Node(8,k);
00339         
00340         // how big is this?
00341         if(verbose)
00342         cout << "\nNode size: " << sizeof(*nextNode) << " bytes" << endl;
00343                         
00344         // enter into node list at time s=0
00345         nodes_0->push_back(nextNode); 
00346         nodes++;
00347         
00348         // for s=0,...,T-1 build nodes at time s+1 from nodes at time s
00349         for(int s=0;s<T;s++) {
00350         
00351                 vector<Node*>* listCurrentNodes = theLattice->getNodeList(s);    // list of nodes at time t
00352                 vector<Node*>* listNewNodes = theLattice->getNodeList(s+1);      // list of nodes at time t+1
00353         listNewNodes->reserve((2*s+3)*(2*s+3)*(2*s+3));
00354                 
00355                 // registry for possible nodes at time s+1, n(s+1,i,j), 
00356                 // -(s+1) <= i=k[0],j=k[1] <= s+1
00357                 Array3D<Node*> newNodes(2*s+3,2*s+3,2*s+3,-s-1,-s-1,-s-1);
00358                         
00359                 // run through the list of nodes at time t and connect to the new nodes
00360                 // *theNode is pointer to node
00361                 vector<Node*>::const_iterator theNode=listCurrentNodes->begin();
00362                 while(theNode!=listCurrentNodes->end())                 
00363                 {
00364                         Node* currentNode=*theNode;
00365                         Array1D<Node*>& edges=currentNode->getEdges();  // edge list 
00366                         int i=0;                                        // edge counter
00367                         
00368                         // state of this node
00369                         int* l=currentNode->getIntegerTicks();
00370                         
00371                         // allocate the 8 successor nodes
00372                         // loop over transitions p,q=-1,+1 (up/down tick)
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                                 // integer state we transition to
00378                                 k[0]=l[0]+p; k[1]=l[1]+q; k[2]=l[2]+r;
00379                                 // connect to this node in the registry
00380                                 nextNode=newNodes(k[0],k[1],k[2]);
00381                                 // if it does not exist yet
00382                                 if(!nextNode){ 
00383                                                 
00384                                           nextNode=new Node(8,k);               // 8 edges per node
00385                                           newNodes(k[0],k[1],k[2])=nextNode;    // register the node
00386                                           listNewNodes->push_back(nextNode);    // append to list
00387                                           nodes++; 
00388                                 }
00389         
00390                                 edges[i]=nextNode;      // connect the current node
00391                                 ++i;
00392                                         
00393                    } // end for p,q,r
00394                            
00395                    ++theNode;
00396                            
00397             } // end while(theNode)
00398                 
00399                 if(verbose)
00400                 cout << "\nTime step = " << s+1 << ";  total nodes = " << nodes;
00401                 
00402         } // end for s
00403 } // end buildThreeFactorLattice
00404 
00405 
00406 }; // end LatticeBuilder
00407 
00408 
00409 
00410         
00411 
00412 MTGL_END_NAMESPACE(Martingale)
00413 
00414 #endif
00415  

Generated on Mon Sep 22 02:16:32 2003 for Libor-Library by doxygen1.3-rc3