diff egglib/egglib-2.1.5/include/egglib-cpp/Edge.hpp @ 1:420b57c3c185 draft

Uploaded
author dereeper
date Fri, 10 Jul 2015 04:39:30 -0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/egglib/egglib-2.1.5/include/egglib-cpp/Edge.hpp	Fri Jul 10 04:39:30 2015 -0400
@@ -0,0 +1,331 @@
+/*
+    Copyright 2009-2010 Stéphane De Mita, Mathieu Siol
+
+    This file is part of the EggLib library.
+
+    EggLib is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    EggLib is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with EggLib.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef EGGLIB_EDGE_HPP
+#define EGGLIB_EDGE_HPP
+
+#include <vector>
+#include <climits>
+#include "EggException.hpp"
+
+namespace egglib {
+
+    class Random;
+
+    /** \brief Edge of the ancestral recombination graph
+    *
+    * \ingroup coalesce
+    *
+    * Each Edge instance provides access to its 0, 1 or 2 descendants
+    * (the former holds for a terminal node, the middle for the parent
+    * of a recombined node and the latter for the parent of a coalesced
+    * node (most classical node in the coalescent).The Edge also
+    * provides to the edge length. Note that the Edge instance must be
+    * understood as an ARG node and the branch above it (latter in the
+    * coalescence process). Edge instances also keep track of the list
+    * of descendants descending from this node (which may differ along
+    * recombining segment). Edge instances *must* be created through one
+    * of the "default" and "coalescence" constructors or through the 
+    * recombination method. Edge instances should never be copied but
+    * manipulated by references.
+    * 
+    */
+    class Edge {
+    
+        public:
+        
+            /// Destructor
+            virtual ~Edge();
+        
+           /** \brief Constructor
+            * 
+            * \param numberOfSegments the number of recombining segments
+            * (one for a non-recombining region).
+            * 
+            * Use the Pool, instead. Objects are delivered with a
+            * complete coverage.
+            * 
+            */ 
+            Edge(unsigned int numberOfSegments);
+
+
+            /// Restore object to `factory` state
+            void reset();
+
+
+           /** \brief Builds for internal node
+            * 
+            * \param date the date of creation of the edge.
+            * \param son1 first edge descending from this edge.
+            * \param son2 second edge descending from this edge.
+            * \param edgesPerSegments counts the current number of
+            * (non-coalesced lineages for each lineages); must have the
+            * appropriate size and will be updated.
+            * \param MRCA the list where to place the address of segment
+            * MRCA, if it occurs.
+            * \param totalLength the total length of the tree.
+            * \param segmentLengths the table of tree lengths per
+            * segment.
+            *
+            * Assumes the current object has the correct number of
+            * segments.
+            * 
+            */
+            void coalescence(double date, Edge* son1, Edge* son2,
+                        unsigned int* edgesPerSegments, Edge** MRCA,
+                        double& totalLength, double* segmentLengths);
+
+
+           /** \brief Generates a recombination event
+            * 
+            * \param date the date of the event.
+            * \param dest1 destination for the first resulting edge.
+            * \param dest2 destination for the second resulting edge.
+            * \param random pointer to the Random instance used by the 
+            * simulator.
+            * \param totalLength the total length of the tree.
+            * \param segmentLengths the table of tree lengths per
+            * segment.
+            * 
+            * dest1 and dest2 must be Edge address initialized with the
+            * appropriate number of segments.
+            * 
+            */
+            void recombination(double date,
+                        Edge* dest1, Edge* dest2, Random* random,
+                        double& totalLength, double* segmentLengths);
+
+
+           /** \brief Define this edge to be terminal
+            * 
+            * The edge have only non-covered segments
+            * 
+            */
+            void set_terminal(unsigned int leaf_index);
+            
+            /// Branch's raw length (doesn't take account segment coverage)
+            double length;
+
+            /// Number of covered segments
+            unsigned int coverage;
+            
+            /// Time position of the branch's bottom
+            double bottom;
+            
+            /// Time position of the branch's top
+            double top;
+            
+            /// Address of the  first son
+            Edge* son1;
+
+            /// Address of the second son
+            Edge* son2;
+
+            /// Number of sons (0, 1 or 2)
+            unsigned int numberOfSons;
+
+            /// Checks if a given segment is covered
+            inline bool segment(unsigned int segmentIndex) const {
+                //while(segments[segmentIndex]==0) segmentIndex--;
+                if (segments[segmentIndex]==0)  return false;
+                if (segments[segmentIndex]==UINT_MAX) return true;
+                return segbools[segmentIndex];
+            }
+
+            /// leaf index (0 for internal nodes)
+            inline unsigned int label() const {
+                return _label;
+            }
+
+            /// Number of mutations per segment
+            unsigned int* numberOfMutationsPerActualSite;
+
+            /// Sets the actual number of sites
+            void set_actualNumberOfSites(unsigned int actualNumberOfSites);
+
+
+        private:
+
+            unsigned int _label;
+
+            /// Default constructor is not available
+            Edge();
+
+            /// Copy constructor is not available
+            Edge(const Edge& edge) {}
+
+            /// Assignment operator is not available
+            Edge& operator=(const Edge& edge) { return *this; }
+
+            void init(unsigned int numberOfSegments);
+
+            unsigned int numberOfSegments;
+            unsigned int* segments;
+            bool* segbools;
+
+            /// complete the covered ranges with UINT_MAX's and the non-covered by 0's
+            inline void fill() {
+                coverage=0.;
+                unsigned int i=0,j;
+                while (i<numberOfSegments) {
+                    if (segbools[i]==true) {
+                        coverage += segments[i];
+                        for (j=1; j<segments[i]; j++) {
+                            segments[i+j] = UINT_MAX;
+                        }
+                    }
+                    i+=segments[i];
+                }
+            }
+
+
+
+            /// update containing Arg's branch lengths
+            inline void update_lengths(double& totalLength, double* segmentLengths) {
+                unsigned int i=0,j;
+                while (i<numberOfSegments) {
+                    if (segbools[i]==true) {
+                        totalLength += segments[i]*length;
+                        for (j=0; j<segments[i]; j++) {
+                            segmentLengths[i+j] += length;
+                        }
+                    }
+                    i+=segments[i];
+                }
+            }
+
+
+    };
+
+
+
+
+
+
+
+
+
+
+
+
+    /** \brief Pool of Edge objects
+    *
+    * \ingroup coalesce
+    *
+    * Holds a pool of Edge objects that can be recycled to spare the
+    * building burden. A construction time, a number of Edge objects
+    * equals to the predicted number of needed instances should be
+    * requested. The Edge's will be prebuilt immediately and delivered
+    * upon request. After use, the Edge's should be released. It is only
+    * possible to release the last issued Edge instance or all of them
+    * at once.
+    * 
+    */
+    class EdgePool {
+
+        public:
+        
+            /// Default constructor (nothing allocated)
+            EdgePool();
+
+
+            /// Destructor
+            virtual ~EdgePool();
+
+
+           /** \brief Configure pool
+            * 
+            * Pre-allocates a given number of Edge objects. The objects
+            * will be immediately available.
+            * 
+            * Data previously allocated (by a previous call of this
+            * function or by the deliver() method) will be lost so it
+            * can be required to use clear() before.
+            * 
+            * \param numberOfSegments the number of segments of the
+            * simulation; all Edge instances will use this value.
+            * 
+            * \param numberOfPreAllocated the number of Edge that should
+            * be kept ready for immediate use.
+            * 
+            */
+            void set(unsigned int numberOfSegments, unsigned numberOfPreAllocated);
+            
+            
+           /** \brief Frees internally stored memory
+            * 
+            * This invalidate all points that have been delivered
+            * previously. However, any previously set number of segments
+            * (0, by default) is retained.
+            * 
+            */
+            void clear();
+
+            
+           /** \brief Deliver an Edge
+            * 
+            * The object must not be freed by the client! This object is
+            * allocated on the heap if the cache is not large enough,
+            * only reset if it was previously released, or just delivered
+            * if it is one of the initially allocated instances.
+            * 
+            */
+            Edge* deliver();
+            
+            
+           /** \brief Release an Edge
+            * 
+            * Release the last delivered Edge. The instance is only
+            * cached for a potential future use; it is not freed nor
+            * reset immediately.  If no Edge's are in use, nothing is
+            * done.
+            * 
+            */
+            void releaseLast();
+
+            
+           /** \brief Release all Edge's
+            * 
+            * Release all delivered Edges. The instances are only
+            * cached for a potential future use; they are not freed nor
+            * reset immediately. If no Edge's are in use, nothing is
+            * done.
+            * 
+            */
+            void releaseAll();
+
+        private:
+        
+            /// Not available
+            EdgePool(const EdgePool& ep) {}
+            
+            /// Not available
+            EdgePool& operator=(const EdgePool& ep) { return *this; }
+
+            unsigned int numberOfSegments;
+            unsigned int used;
+            unsigned int released;
+            unsigned int ready;
+            Edge** cache;
+            
+    };
+
+}
+
+#endif