diff options
author | Chris Dyer <cdyer@cs.cmu.edu> | 2011-04-22 13:38:32 -0400 |
---|---|---|
committer | Chris Dyer <cdyer@cs.cmu.edu> | 2011-04-22 13:38:32 -0400 |
commit | 9986bc8fe11435b2134350bba24aa0139d2665ac (patch) | |
tree | d27b526d929b788dcdc2b1ab949c608a4751edfe | |
parent | 5061409a26050b9a4724b50b30d66d3c3a583951 (diff) |
make compatible with FastSparseVector
-rw-r--r-- | decoder/aligner.cc | 2 | ||||
-rw-r--r-- | decoder/cdec_ff.cc | 2 | ||||
-rw-r--r-- | decoder/dwarf.cc | 2 | ||||
-rw-r--r-- | decoder/dwarf.h | 2 | ||||
-rwxr-xr-x | decoder/feature_accum.h | 10 | ||||
-rwxr-xr-x | decoder/ff_from_fsa.h | 2 | ||||
-rw-r--r-- | decoder/hg.cc | 4 | ||||
-rw-r--r-- | decoder/scfg_translator.cc | 2 | ||||
-rw-r--r-- | decoder/trule.h | 2 | ||||
-rw-r--r-- | extools/extract.cc | 4 | ||||
-rw-r--r-- | extools/sg_lexer.l | 2 | ||||
-rw-r--r-- | training/lbfgs_test.cc | 2 | ||||
-rw-r--r-- | training/mr_em_adapted_reduce.cc | 8 | ||||
-rw-r--r-- | training/mr_em_map_adapter.cc | 4 | ||||
-rw-r--r-- | utils/fast_sparse_vector.h | 187 | ||||
-rw-r--r-- | utils/sparse_vector.h | 48 | ||||
-rw-r--r-- | utils/ts.cc | 18 | ||||
-rw-r--r-- | vest/line_optimizer.h | 2 | ||||
-rw-r--r-- | vest/mr_vest_generate_mapper_input.cc | 4 |
19 files changed, 225 insertions, 82 deletions
diff --git a/decoder/aligner.cc b/decoder/aligner.cc index 7830b955..292ee123 100644 --- a/decoder/aligner.cc +++ b/decoder/aligner.cc @@ -250,7 +250,7 @@ void AlignerTools::WriteAlignment(const Lattice& src_lattice, SparseVector<prob_t> posts; const prob_t z = InsideOutside<prob_t, EdgeProb, SparseVector<prob_t>, TransitionEventWeightFunction>(*g, &posts); for (int i = 0; i < edge_posteriors.size(); ++i) - edge_posteriors[i] = posts[i] / z; + edge_posteriors[i] = posts.value(i) / z; } vector<set<int> > src_cov(g->edges_.size()); vector<set<int> > trg_cov(g->edges_.size()); diff --git a/decoder/cdec_ff.cc b/decoder/cdec_ff.cc index 7ec54a5a..cbcb0fcd 100644 --- a/decoder/cdec_ff.cc +++ b/decoder/cdec_ff.cc @@ -1,6 +1,7 @@ #include <boost/shared_ptr.hpp> #include "ff.h" +#include "ff_identity.h" #include "ff_spans.h" #include "ff_lm.h" #include "ff_klm.h" @@ -70,6 +71,7 @@ void register_feature_functions() { ff_registry.Register("LexicalPairIndicator", new FFFactory<LexicalPairIndicator>); ff_registry.Register("OutputIndicator", new FFFactory<OutputIndicator>); ff_registry.Register("IdentityCycleDetector", new FFFactory<IdentityCycleDetector>); + ff_registry.Register("FEIdentity", new FFFactory<FEIdentity>); ff_registry.Register("InputIndicator", new FFFactory<InputIndicator>); ff_registry.Register("LexicalTranslationTrigger", new FFFactory<LexicalTranslationTrigger>); ff_registry.Register("WordPairFeatures", new FFFactory<WordPairFeatures>); diff --git a/decoder/dwarf.cc b/decoder/dwarf.cc index 7968fee2..fb0404a6 100644 --- a/decoder/dwarf.cc +++ b/decoder/dwarf.cc @@ -3064,7 +3064,7 @@ void Alignment::SetCurrAlVector() { } } -const void CountTable::print() { +void CountTable::print() const { cerr << "+++ Model +++" << endl; for (map<WordID,int*>::const_iterator iter=model.begin(); iter!=model.end(); iter++) { cerr << TD::Convert(iter->first) << " "; diff --git a/decoder/dwarf.h b/decoder/dwarf.h index 83a0cae9..49d2a3b7 100644 --- a/decoder/dwarf.h +++ b/decoder/dwarf.h @@ -27,7 +27,7 @@ public: map<WordID,int*> model; int mode; int numColumn; - const void print(); + void print() const; void setup(int _numcolumn, int _mode) { mode = _mode; numColumn = _numcolumn; } diff --git a/decoder/feature_accum.h b/decoder/feature_accum.h index 851b29db..4b8338eb 100755 --- a/decoder/feature_accum.h +++ b/decoder/feature_accum.h @@ -7,15 +7,15 @@ struct SparseFeatureAccumulator : public FeatureVector { typedef FeatureVector State; - SparseFeatureAccumulator() { } + SparseFeatureAccumulator() { assert(!"this code is disabled"); } template <class FF> FeatureVector const& describe(FF const& ) { return *this; } void Store(FeatureVector *fv) const { - fv->set_from(*this); +//NO fv->set_from(*this); } template <class FF> void Store(FF const& /* ff */,FeatureVector *fv) const { - fv->set_from(*this); +//NO fv->set_from(*this); } template <class FF> void Add(FF const& /* ff */,FeatureVector const& fv) { @@ -33,10 +33,10 @@ struct SparseFeatureAccumulator : public FeatureVector { } */ void Add(int i,Featval v) { - (*this)[i]+=v; +//NO (*this)[i]+=v; } void Add(Features const& fids,int i,Featval v) { - (*this)[i]+=v; +//NO (*this)[i]+=v; } }; diff --git a/decoder/ff_from_fsa.h b/decoder/ff_from_fsa.h index f2db8a4b..f8d79e03 100755 --- a/decoder/ff_from_fsa.h +++ b/decoder/ff_from_fsa.h @@ -295,7 +295,7 @@ private: # include "ff_sample_fsa.h" int main() { std::cerr<<"Testing left_end...\n"; - std::cerr<<"sizeof(FeatureVector)="<<sizeof(FeatureVector)<<"\nsizeof(FeatureVectorList)="<<sizeof(FeatureVectorList)<<"\n"; + std::cerr<<"sizeof(FeatureVector)="<<sizeof(FeatureVector)<<"\n"; WordPenaltyFromFsa::test(); return 0; } diff --git a/decoder/hg.cc b/decoder/hg.cc index a4028b0e..3ad17f1a 100644 --- a/decoder/hg.cc +++ b/decoder/hg.cc @@ -163,7 +163,7 @@ prob_t Hypergraph::ComputeEdgePosteriors(double scale, vector<prob_t>* posts) co ScaledTransitionEventWeightFunction>(*this, &pv, weight, w2); posts->resize(edges_.size()); for (int i = 0; i < edges_.size(); ++i) - (*posts)[i] = prob_t(pv.get(i)); + (*posts)[i] = prob_t(pv.value(i)); return prob_t(inside); } @@ -176,7 +176,7 @@ prob_t Hypergraph::ComputeBestPathThroughEdges(vector<prob_t>* post) const { ViterbiTransitionEventWeightFunction>(*this, &pv); post->resize(edges_.size()); for (int i = 0; i < edges_.size(); ++i) - (*post)[i] = pv.get(i).v_; + (*post)[i] = pv.value(i).v_; return viterbi_weight.v_; } diff --git a/decoder/scfg_translator.cc b/decoder/scfg_translator.cc index 0f7e40bd..d4bec40d 100644 --- a/decoder/scfg_translator.cc +++ b/decoder/scfg_translator.cc @@ -226,7 +226,7 @@ struct SCFGTranslatorImpl { new_edge->j_ = edge.j_; new_edge->feature_values_ = fine_rule_ptr->GetFeatureValues(); new_edge->feature_values_.set_value(FD::Convert("LatticeCost"), - edge.feature_values_[FD::Convert("LatticeCost")]); + edge.feature_values_.value(FD::Convert("LatticeCost"))); Hypergraph::Node* head_node; Split2Node::iterator it = s2n.find(StateSplit(node.id_, cat)); if (it == s2n.end()){ diff --git a/decoder/trule.h b/decoder/trule.h index 7cd24bc9..4df4ec90 100644 --- a/decoder/trule.h +++ b/decoder/trule.h @@ -132,7 +132,7 @@ class TRule { int Arity() const { return arity_; } bool IsUnary() const { return (Arity() == 1) && (f_.size() == 1); } const SparseVector<double>& GetFeatureValues() const { return scores_; } - double Score(int i) const { return scores_.get(i); } + double Score(int i) const { return scores_.value(i); } WordID GetLHS() const { return lhs_; } void ComputeArity(); diff --git a/extools/extract.cc b/extools/extract.cc index a9de142e..f6c121b4 100644 --- a/extools/extract.cc +++ b/extools/extract.cc @@ -105,8 +105,8 @@ void Extract::LoosenPhraseBounds(const AnnotatedParallelSentence& sentence, const int ilim = min(i2_max, i1 + max_base_phrase_size); for (int i2 = max(i1+1,i2_min); i2 <= ilim; ++i2) { for (int j1 = j1_min; j1 <= j1_max; ++j1) { - const int jlim = min(j2_max, j1 + max_base_phrase_size); - for (int j2 = max(j1+1, j2_min); j2 <= jlim; ++j2) { + const int jlim = std::min(j2_max, j1 + max_base_phrase_size); + for (int j2 = std::max(j1+1, j2_min); j2 <= jlim; ++j2) { bool& seen = marker[i1][i2][j1][j2]; if (!seen) phrases->push_back(ParallelSpan(i1,i2,j1,j2)); diff --git a/extools/sg_lexer.l b/extools/sg_lexer.l index d60bd0fc..c85cdea7 100644 --- a/extools/sg_lexer.l +++ b/extools/sg_lexer.l @@ -240,7 +240,7 @@ ALIGN [0-9]+-[0-9]+ } <FEATVAL>{REAL} { // std::cerr << "Feature val input: " << yytext << std::endl; - cur_stats->counts[sglex_cur_fid] += strtod(yytext, NULL); + cur_stats->counts.add_value(sglex_cur_fid, strtod(yytext, NULL)); BEGIN(FEATS); } <FEATVAL>. { diff --git a/training/lbfgs_test.cc b/training/lbfgs_test.cc index 4171c118..fc21e98d 100644 --- a/training/lbfgs_test.cc +++ b/training/lbfgs_test.cc @@ -95,7 +95,7 @@ void TestSparseVector() { assert(B64::Decode(&obj, &v, &data[0], data.size())); cerr << obj << "\t" << v << endl; assert(obj == iobj); - assert(g.num_active() == v.num_active()); + assert(g.size() == v.size()); } int main() { diff --git a/training/mr_em_adapted_reduce.cc b/training/mr_em_adapted_reduce.cc index 29416348..d4c16a2f 100644 --- a/training/mr_em_adapted_reduce.cc +++ b/training/mr_em_adapted_reduce.cc @@ -53,7 +53,7 @@ void Maximize(const bool use_vb, const SparseVector<double>& counts = *pc; if (use_vb) - assert(total_event_types >= counts.num_active()); + assert(total_event_types >= counts.size()); double tot = 0; for (SparseVector<double>::const_iterator it = counts.begin(); @@ -73,7 +73,7 @@ void Maximize(const bool use_vb, } } #if 0 - if (counts.num_active() < 50) { + if (counts.size() < 50) { for (SparseVector<double>::const_iterator it = counts.begin(); it != counts.end(); ++it) { cerr << " p(" << FD::Convert(it->first) << ")=" << exp(it->second); @@ -112,7 +112,7 @@ int main(int argc, char** argv) { if (cur_key.size() > 0) { // TODO shouldn't be num_active, should be total number // of events - Maximize(use_vb, alpha, acc.num_active(), &acc); + Maximize(use_vb, alpha, acc.size(), &acc); cout << cur_key << '\t'; if (use_b64) B64::Encode(0.0, acc, &cout); @@ -159,7 +159,7 @@ int main(int argc, char** argv) { } // TODO shouldn't be num_active, should be total number // of events - Maximize(use_vb, alpha, acc.num_active(), &acc); + Maximize(use_vb, alpha, acc.size(), &acc); cout << cur_key << '\t'; if (use_b64) B64::Encode(0.0, acc, &cout); diff --git a/training/mr_em_map_adapter.cc b/training/mr_em_map_adapter.cc index a98e1b77..ead4598d 100644 --- a/training/mr_em_map_adapter.cc +++ b/training/mr_em_map_adapter.cc @@ -132,9 +132,9 @@ int main(int argc, char** argv) { for (SparseVector<double>::const_iterator it = cg.begin(); it != cg.end(); ++it) { const int cond_var = event_mapper->Map(it->first); SparseVector<double>& cond_counts = counts[cond_var]; - int delta = cond_counts.num_active(); + int delta = cond_counts.size(); cond_counts.add_value(it->first, it->second); - delta = cond_counts.num_active() - delta; + delta = cond_counts.size() - delta; total += delta; } if (total > buffer_size) { diff --git a/utils/fast_sparse_vector.h b/utils/fast_sparse_vector.h index c4a44b99..b8b3df1f 100644 --- a/utils/fast_sparse_vector.h +++ b/utils/fast_sparse_vector.h @@ -7,6 +7,7 @@ // important: indexes are integers // important: iterators may return elements in any order +#include <cmath> #include <cstring> #include <climits> #include <map> @@ -21,18 +22,35 @@ #define L2_CACHE_LINE 128 // this should just be a typedef to pair<int,T> on the new c++ +// I have to avoid this since I want to use unions and c++-98 +// does not let unions have types with constructors in them +// this type bypasses default constructors. use with caution! +// this should work as long as T is in a acceptable state to +// have its destructor called when initialized with all zeros template <typename T> struct PairIntT { - int first; - T second; const PairIntT& operator=(const std::pair<const int, T>& v) { - first = v.first; - second = v.second; + std::memcpy(this, &v, sizeof(PairIntT)); return *this; } operator const std::pair<const int, T>&() const { return *reinterpret_cast<const std::pair<const int, T>*>(this); } + int& first() { + return reinterpret_cast<std::pair<int, T>*>(this)->first; + } + T& second() { + return reinterpret_cast<std::pair<int, T>*>(this)->second; + } + const int& first() const { + return reinterpret_cast<const std::pair<int, T>*>(this)->first; + } + const T& second() const { + return reinterpret_cast<const std::pair<int, T>*>(this)->second; + } + private: + // very bad way of bypassing the default constructor on T + char data_[sizeof(std::pair<int, T>)]; }; BOOST_STATIC_ASSERT(sizeof(PairIntT<float>) == sizeof(std::pair<int,float>)); @@ -40,7 +58,7 @@ template <typename T, int LOCAL_MAX = (sizeof(T) == sizeof(float) ? 15 : 7)> class FastSparseVector { public: struct const_iterator { - const_iterator(const FastSparseVector<T>& v, const bool is_end) : local_(v.is_local_) { + const_iterator(const FastSparseVector<T>& v, const bool is_end) : local_(!v.is_remote_) { if (local_) { local_it_ = &v.data_.local[is_end ? v.local_size_ : 0]; } else { @@ -85,43 +103,89 @@ class FastSparseVector { } }; public: - FastSparseVector() : local_size_(0), is_local_(true) {} + FastSparseVector() : local_size_(0), is_remote_(false) { std::memset(&data_, 0, sizeof(data_)); } + explicit FastSparseVector(const std::vector<T>& init) : local_size_(0), is_remote_(false) { + for (int i = 0; i < init.size(); ++i) set_value(i, init[i]); + } ~FastSparseVector() { - if (!is_local_) delete data_.rbmap; + clear(); } FastSparseVector(const FastSparseVector& other) { std::memcpy(this, &other, sizeof(FastSparseVector)); - if (is_local_) return; - data_.rbmap = new std::map<int, T>(*data_.rbmap); + if (is_remote_) data_.rbmap = new std::map<int, T>(*data_.rbmap); + } + void erase(int k) { + if (is_remote_) { + data_.rbmap->erase(k); + } else { + for (int i = 0; i < local_size_; ++i) { + if (data_.local[i].first() == k) { + for (int j = i+1; j < local_size_; ++j) { + data_.local[j-1].first() = data_.local[j].first(); + data_.local[j-1].second() = data_.local[j].second(); + } + } + } + } } const FastSparseVector& operator=(const FastSparseVector& other) { - if (!is_local_) delete data_.rbmap; + if (is_remote_) delete data_.rbmap; std::memcpy(this, &other, sizeof(FastSparseVector)); - if (is_local_) return *this; - data_.rbmap = new std::map<int, T>(*data_.rbmap); + if (is_remote_) + data_.rbmap = new std::map<int, T>(*data_.rbmap); return *this; } + T const& get_singleton() const { + assert(size()==1); + return begin()->second; + } + bool nonzero(int k) const { + return static_cast<bool>(value(k)); + } inline void set_value(int k, const T& v) { get_or_create_bin(k) = v; } + inline T& add_value(int k, const T& v) { + return get_or_create_bin(k) += v; + } + inline T get(int k) const { + return value(k); + } inline T value(int k) const { - if (is_local_) { + if (is_remote_) { + typename std::map<int, T>::const_iterator it = data_.rbmap->find(k); + if (it != data_.rbmap->end()) return it->second; + } else { for (int i = 0; i < local_size_; ++i) { const PairIntT<T>& p = data_.local[i]; - if (p.first == k) return p.second; + if (p.first() == k) return p.second(); } - } else { - typename std::map<int, T>::const_iterator it = data_.rbmap->find(k); - if (it != data_.rbmap->end()) return it->second; } return T(); } + T l2norm_sq() const { + T sum = T(); + for (const_iterator it = begin(), e = end(); it != e; ++it) + sum += it->second * it->second; + return sum; + } + T l2norm() const { + return sqrt(l2norm_sq()); + } + // if values are binary, gives |A intersect B|/|A union B| + template<typename S> + S tanimoto_coef(const FastSparseVector<S> &vec) const { + const S dp=dot(vec); + return dp/(l2norm_sq()+vec.l2norm_sq()-dp); + } inline size_t size() const { - if (is_local_) return local_size_; - return data_.rbmap->size(); + if (is_remote_) + return data_.rbmap->size(); + else + return local_size_; } inline void clear() { - if (!is_local_) delete data_.rbmap; + if (is_remote_) delete data_.rbmap; local_size_ = 0; } inline bool empty() const { @@ -135,6 +199,14 @@ class FastSparseVector { } return *this; } + template <typename O> + inline FastSparseVector& operator+=(const FastSparseVector<O>& other) { + const typename FastSparseVector<O>::const_iterator end = other.end(); + for (typename FastSparseVector<O>::const_iterator it = other.begin(); it != end; ++it) { + get_or_create_bin(it->first) += it->second; + } + return *this; + } inline FastSparseVector& operator-=(const FastSparseVector& other) { const typename FastSparseVector::const_iterator end = other.end(); for (typename FastSparseVector::const_iterator it = other.begin(); it != end; ++it) { @@ -143,24 +215,24 @@ class FastSparseVector { return *this; } inline FastSparseVector& operator*=(const T& scalar) { - if (is_local_) { - for (int i = 0; i < local_size_; ++i) - data_.local[i].second *= scalar; - } else { + if (is_remote_) { const typename std::map<int, T>::iterator end = data_.rbmap->end(); for (typename std::map<int, T>::iterator it = data_.rbmap->begin(); it != end; ++it) it->second *= scalar; + } else { + for (int i = 0; i < local_size_; ++i) + data_.local[i].second() *= scalar; } return *this; } inline FastSparseVector& operator/=(const T& scalar) { - if (is_local_) { - for (int i = 0; i < local_size_; ++i) - data_.local[i].second /= scalar; - } else { + if (is_remote_) { const typename std::map<int, T>::iterator end = data_.rbmap->end(); for (typename std::map<int, T>::iterator it = data_.rbmap->begin(); it != end; ++it) it->second /= scalar; + } else { + for (int i = 0; i < local_size_; ++i) + data_.local[i].second() /= scalar; } return *this; } @@ -182,38 +254,57 @@ class FastSparseVector { T res = T(); for (const_iterator it = begin(), e = end(); it != e; ++it) if (it->first < v.size()) res += it->second * v[it->first]; + return res; + } + T dot(const FastSparseVector<T>& other) const { + T res = T(); + for (const_iterator it = begin(), e = end(); it != e; ++it) + res += other.value(it->first) * it->second; + return res; + } + bool operator==(const FastSparseVector<T>& other) const { + if (other.size() != size()) return false; + for (const_iterator it = begin(), e = end(); it != e; ++it) { + if (other.value(it->first) != it->second) return false; + } + return true; + } + void swap(FastSparseVector<T>& other) { + char t[sizeof(data_)]; + std::swap(other.is_remote_, is_remote_); + std::swap(other.local_size_, local_size_); + std::memcpy(t, &other.data_, sizeof(data_)); + std::memcpy(&other.data_, &data_, sizeof(data_)); + std::memcpy(&data_, t, sizeof(data_)); } private: - inline T& extend_vector(std::vector<T> &v,int i) { + static inline T& extend_vector(std::vector<T> &v,int i) { if (i>=v.size()) v.resize(i+1); return v[i]; } inline T& get_or_create_bin(int k) { - if (is_local_) { - for (int i = 0; i < local_size_; ++i) - if (data_.local[i].first == k) return data_.local[i].second; - } else { + if (is_remote_) { return (*data_.rbmap)[k]; + } else { + for (int i = 0; i < local_size_; ++i) + if (data_.local[i].first() == k) return data_.local[i].second(); } - assert(is_local_); + assert(!is_remote_); // currently local! if (local_size_ < LOCAL_MAX) { PairIntT<T>& p = data_.local[local_size_]; ++local_size_; - p.first = k; - return p.second; + p.first() = k; + p.second() = T(); + return p.second(); } else { swap_local_rbmap(); return (*data_.rbmap)[k]; } } void swap_local_rbmap() { - if (is_local_) { // data is local, move to rbmap - std::map<int, T>* m = new std::map<int, T>(&data_.local[0], &data_.local[local_size_]); - data_.rbmap = m; - is_local_ = false; - } else { // data is in rbmap, move to local + if (is_remote_) { // data is in rbmap, move to local assert(data_.rbmap->size() < LOCAL_MAX); const std::map<int, T>* m = data_.rbmap; local_size_ = m->size(); @@ -223,7 +314,11 @@ class FastSparseVector { data_.local[i] = *it; ++i; } - is_local_ = true; + is_remote_ = false; + } else { // data is local, move to rbmap + std::map<int, T>* m = new std::map<int, T>(&data_.local[0], &data_.local[local_size_]); + data_.rbmap = m; + is_remote_ = true; } } @@ -232,7 +327,7 @@ class FastSparseVector { std::map<int, T>* rbmap; } data_; unsigned char local_size_; - bool is_local_; + bool is_remote_; }; template <typename T> @@ -261,6 +356,12 @@ const FastSparseVector<T> operator-(const FastSparseVector<T>& x, const FastSpar } } +template <class T> +std::size_t hash_value(FastSparseVector<T> const& x) { + assert(!"not implemented"); + return 0; +} + namespace performance_checks { // if you get a failure on the next line, you should adjust LOCAL_MAX for // your architecture diff --git a/utils/sparse_vector.h b/utils/sparse_vector.h index de8c0291..dbeacbe8 100644 --- a/utils/sparse_vector.h +++ b/utils/sparse_vector.h @@ -646,6 +646,19 @@ SparseVector<T> operator+(const SparseVector<T>& a, const SparseVector<T>& b) { } template <class T> +SparseVector<T> operator*(const double& a, const SparseVector<T>& b) { + SparseVector<T> result = b; + return result *= a; +} + +#else + +#include "fast_sparse_vector.h" +#define SparseVector FastSparseVector + +#endif + +template <class T> SparseVector<T> operator*(const SparseVector<T>& a, const double& b) { SparseVector<T> result = a; return result *= b; @@ -658,23 +671,36 @@ SparseVector<T> operator*(const SparseVector<T>& a, const T& b) { } template <class T> -SparseVector<T> operator*(const double& a, const SparseVector<T>& b) { - SparseVector<T> result = b; - return result *= a; +SparseVector<T> operator/(const SparseVector<T>& a, const double& b) { + SparseVector<T> result = a; + return result *= b; } template <class T> -std::ostream &operator<<(std::ostream &out, const SparseVector<T> &vec) -{ - return vec.operator<<(out); +SparseVector<T> operator/(const SparseVector<T>& a, const T& b) { + SparseVector<T> result = a; + return result *= b; } -#else - -#include "fast_sparse_vector.h" -#define SparseVector FastSparseVector +template <class O, typename T> +inline void print(O &o,const SparseVector<T>& v, const char* kvsep="=",const char* pairsep=" ",const char* pre="",const char* post="") { + o << pre; + bool first=true; + for (typename SparseVector<T>::const_iterator i=v.begin(),e=v.end();i!=e;++i) { + if (first) + first=false; + else + o<<pairsep; + o<<FD::Convert(i->first)<<kvsep<<i->second; + } + o << post; +} -#endif +template <typename T> +inline std::ostream& operator<<(std::ostream& out, const SparseVector<T>& v) { + print(out, v); + return out; +} namespace B64 { void Encode(double objective, const SparseVector<double>& v, std::ostream* out); diff --git a/utils/ts.cc b/utils/ts.cc index 28b5f9b1..563794c5 100644 --- a/utils/ts.cc +++ b/utils/ts.cc @@ -11,7 +11,7 @@ using namespace std; template <typename T> -void Print(const T& x) { +void MPrint(const T& x) { typename T::const_iterator it = x.begin(); for (; it != x.end(); ++it) { cerr << it->first << ":" << it->second << " "; @@ -24,16 +24,30 @@ void test_unique() { T x; x.set_value(100, 1.0); x.set_value(100, 2.0); - Print(x); + MPrint(x); assert(x.size() == 1); assert(x.value(100) == 2.0); } +void test_logv() { + FastSparseVector<prob_t> x; + cerr << "FSV<prob_t> = " << sizeof(FastSparseVector<prob_t>) << endl; + x.set_value(999, prob_t(0.5)); + x.set_value(0, prob_t()); + x.set_value(1, prob_t(1)); + MPrint(x); + x += x; + MPrint(x); + x -= x; + MPrint(x); +} + int main() { cerr << sizeof(prob_t) << " " << sizeof(LogVal<float>) << endl; cerr << " sizeof(FSV<float>) = " << sizeof(FastSparseVector<float>) << endl; cerr << "sizeof(FSV<double>) = " << sizeof(FastSparseVector<double>) << endl; test_unique<FastSparseVector<float> >(); + test_logv(); // sranddev(); int c = 0; FastSparseVector<float> p; diff --git a/vest/line_optimizer.h b/vest/line_optimizer.h index 1b5382cd..99a591f4 100644 --- a/vest/line_optimizer.h +++ b/vest/line_optimizer.h @@ -3,10 +3,10 @@ #include <vector> +#include "sparse_vector.h" #include "error_surface.h" #include "sampler.h" -template <typename T> class SparseVector; class Weights; struct LineOptimizer { diff --git a/vest/mr_vest_generate_mapper_input.cc b/vest/mr_vest_generate_mapper_input.cc index 68191a6a..b84c44bc 100644 --- a/vest/mr_vest_generate_mapper_input.cc +++ b/vest/mr_vest_generate_mapper_input.cc @@ -87,9 +87,9 @@ struct oracle_directions { for (int i = 0; i < dev_set_size; ++i) for (int j = 0; j < directions.size(); ++j) { cout << forest_file(i) <<" " << i<<" "; - origin.print(cout,"=",";"); + print(cout,origin,"=",";"); cout<<" "; - directions[j].print(cout,"=",";"); + print(cout,directions[j],"=",";"); cout<<"\n"; } } |