eXpress “1.5”

src/bundles.cpp

00001 //
00002 //  bundles.cpp
00003 //  express
00004 //
00005 //  Created by Adam Roberts on 9/6/11.
00006 //  Copyright 2011 Adam Roberts. All rights reserved.
00007 //
00008 
00009 #include "bundles.h"
00010 
00011 #include "main.h"
00012 #include "targets.h"
00013 
00014 using namespace std;
00015 
00016 void CovarTable::increment(TargID targ1, TargID targ2, double incr_amt) {
00017   size_t pair_id = size()*min(targ1, targ2)+max(targ1, targ2);
00018   if (_covar_map.count(pair_id)) {
00019     _covar_map[pair_id] = log_add(_covar_map[pair_id], incr_amt);
00020   } else {
00021     _covar_map[pair_id] = incr_amt;
00022   }
00023 }
00024 
00025 double CovarTable::get(TargID targ1, TargID targ2) {
00026   size_t pair_id = size()*min(targ1, targ2)+max(targ1, targ2);
00027   if (_covar_map.count(pair_id)) {
00028     return _covar_map[pair_id];
00029   } else {
00030     return LOG_0;
00031   }
00032 }
00033 
00034 Bundle::Bundle(Target* targ)
00035     : _counts(targ->tot_counts()),
00036       _mass(targ->mass(true)),
00037       _merged_into(NULL) {
00038   _targets.push_back(targ);
00039 }
00040 
00041 size_t Bundle::size() const {
00042   boost::unique_lock<boost::mutex>(_mut);
00043   if (_merged_into) {
00044     return _targets.size() + _merged_into->size();
00045   }
00046   return _targets.size();
00047 }
00048 
00049 void Bundle::incr_counts(size_t incr_amt) {
00050   boost::unique_lock<boost::mutex>(_mut);
00051   if (_merged_into) {
00052     _merged_into->incr_counts(incr_amt);
00053   } else {
00054     _counts += incr_amt;
00055   }
00056 }
00057 
00058 void Bundle::incr_mass(double incr_amt) {
00059   boost::unique_lock<boost::mutex>(_mut);
00060   if (_merged_into) {
00061     _merged_into->incr_mass(incr_amt);
00062   } else {
00063     _mass = log_add(_mass, incr_amt);
00064   }
00065 }
00066 
00067 void Bundle::reset_mass() {
00068   boost::unique_lock<boost::mutex>(_mut);
00069   _mass = LOG_0;
00070 }
00071 
00072 size_t Bundle::counts() const {
00073   boost::unique_lock<boost::mutex>(_mut);
00074   if (_merged_into) {
00075     return _merged_into->counts();
00076   }
00077   return _counts;
00078 }
00079 
00080 double Bundle::mass() const {
00081   boost::unique_lock<boost::mutex>(_mut);
00082   if (_merged_into) {
00083     return _merged_into->mass();
00084   }
00085   return _mass;
00086 }
00087 
00088 
00089 BundleTable::BundleTable() : _threadsafe_mode(false) {}
00090 
00091 BundleTable::~BundleTable() {
00092   foreach(Bundle* bundle, _bundles) {
00093     delete bundle;
00094   }
00095 }
00096 
00097 Bundle* BundleTable::get_rep(Bundle* b) {
00098   if (b->_merged_into) {
00099     return get_rep(b->_merged_into);
00100   }
00101   return b;
00102 }
00103 
00104 Bundle* BundleTable::create_bundle(Target* targ) {
00105   Bundle* b = new Bundle(targ);
00106   _bundles.insert(b);
00107   return b;
00108 }
00109 
00110 Bundle* BundleTable::merge(Bundle* b1, Bundle* b2) {
00111   // Lock so that only one merge can happen at a time...
00112   boost::unique_lock<boost::mutex>(_mut);
00113   
00114   b1 = get_rep(b1);
00115   b2 = get_rep(b2);
00116   if (b1==b2) {
00117     return b1;
00118   }
00119   
00120   if (b1->size() < b2->size()) {
00121     swap(b1, b2);
00122   }
00123   
00124   if (_threadsafe_mode) {
00125     // Lock b1 and b2
00126     boost::unique_lock<boost::mutex>(b1->_mut);
00127     boost::unique_lock<boost::mutex>(b2->_mut);
00128     b1->_counts += b2->_counts;
00129     b1->_mass = log_add(b1->_mass, b2->_mass);
00130     b2->_counts = 0;
00131     b2->_mass = LOG_0;
00132     b2->_merged_into = b1;
00133   } else {
00134     foreach(Target* targ, b2->_targets) {
00135       targ->bundle(b1);
00136       b1->_targets.push_back(targ);
00137     }
00138 
00139     b1->incr_counts(b2->counts());
00140     b1->incr_mass(b2->mass());
00141     _bundles.erase(b2);
00142     delete b2;
00143   }
00144   
00145   return b1;
00146 }
00147 
00148 void BundleTable::collapse() {
00149   // Lock
00150   boost::unique_lock<boost::mutex>(_mut);
00151   
00152   BundleSet to_delete;
00153   foreach(Bundle* b, _bundles) {
00154     Bundle* rep = get_rep(b);
00155     if (rep != b) {
00156       foreach(Target* targ, b->_targets) {
00157         targ->bundle(rep);
00158         rep->_targets.push_back(targ);
00159       }
00160       to_delete.insert(b);
00161     }
00162   }
00163   
00164   foreach(Bundle* b, to_delete) {
00165     _bundles.erase(b);
00166     delete b;
00167   }
00168   
00169 }
 All Classes Functions Variables