summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Dyer <cdyer@cs.cmu.edu>2011-04-22 13:38:32 -0400
committerChris Dyer <cdyer@cs.cmu.edu>2011-04-22 13:38:32 -0400
commit9d393298ce21159907884ea9b7318c52585409ee (patch)
treecab034a01642abb2a067818f9c8f29999c4c6797
parentb6634dff2cd515d9e6f95416512db893a08bde29 (diff)
make compatible with FastSparseVector
-rw-r--r--decoder/aligner.cc2
-rw-r--r--decoder/cdec_ff.cc2
-rw-r--r--decoder/dwarf.cc2
-rw-r--r--decoder/dwarf.h2
-rwxr-xr-xdecoder/feature_accum.h10
-rwxr-xr-xdecoder/ff_from_fsa.h2
-rw-r--r--decoder/hg.cc4
-rw-r--r--decoder/scfg_translator.cc2
-rw-r--r--decoder/trule.h2
-rw-r--r--extools/extract.cc4
-rw-r--r--extools/sg_lexer.l2
-rw-r--r--training/lbfgs_test.cc2
-rw-r--r--training/mr_em_adapted_reduce.cc8
-rw-r--r--training/mr_em_map_adapter.cc4
-rw-r--r--utils/fast_sparse_vector.h187
-rw-r--r--utils/sparse_vector.h48
-rw-r--r--utils/ts.cc18
-rw-r--r--vest/line_optimizer.h2
-rw-r--r--vest/mr_vest_generate_mapper_input.cc4
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";
}
}