#ifndef __PCSVM_VECTOR__ #define __PCSVM_VECTOR__ #include #include #include #include #include "FullPolicy.hpp" #include "SparsePolicy.hpp" struct ZipItem { int index; float value1; float value2; }; namespace local { // klassen welchen nur intern benutzt werden // template class ZipIter // wird nicht spezilaisert fuer FullPolicy. // tauch nämlich nur in dot() und tpao() auf, und // die werden fuer FullPolicy eh spezialisiert. { public: ZipIter(const typename VS::item_iterator &b1, const typename VS::item_iterator &e1, const typename VS::item_iterator &b2, const typename VS::item_iterator &e2): it1_(b1), e1_(e1), it2_(b2), e2_(e2) { updateActual(); } ZipIter(const VS &p1, const VS &p2): it1_(p1.begin()), e1_(p1.end()), it2_(p2.begin()), e2_(p2.end()) { if (VS::do_comp_test) assert(p1.len() == p2.len()); updateActual(); } void updateActual(); bool isValid() { return it1_ != e1_ || it2_ != e2_; } const ZipItem* operator->() const { return &actual_; } const ZipItem operator*() const { return actual_; } ZipIter operator++() { if (it1_ != e1_ && (it2_ == e2_ || it1_->index < it2_->index)) ++it1_; else if (it2_ != e2_ && (it1_ == e1_ || it1_->index > it2_->index)) ++it2_; else if (it1_ != e1_ && it2_ != e2_) { ++it1_; ++it2_; } updateActual(); return *this; } private: typename VS::const_item_iterator it1_, e1_, it2_, e2_; ZipItem actual_; }; template void ZipIter::updateActual() { if (it1_ == e1_ && it2_ == e2_) return; if (it2_ == e2_) { actual_.index = it1_->index; actual_.value1 = it1_->value; actual_.value2 = 0; return; } if (it1_ == e1_) { actual_.index = it2_->index; actual_.value2 = it2_->value; actual_.value1 = 0; return; } // now: it1_ and it2_ are valid if (it1_->index < it2_->index) { actual_.index = it1_->index; actual_.value1 = it1_->value; actual_.value2 = 0; return; } // now: it1_ is valid if (it2_->index < it1_->index) { actual_.index = it2_->index; actual_.value2 = it2_->value; actual_.value1 = 0; return; } if (it1_->index == it2_->index) { actual_.index = it2_->index; actual_.value2 = it2_->value; actual_.value1 = it1_->value; return; } } } // namespace local ////////////////////////////////////////////////////////////////////////////////// // // HIER GEHTS LOS !! // ////////////////////////////////////////////////////////////////////////////////// template class VectorBase: public StoragePolicy { public: VectorBase(): StoragePolicy() {}; VectorBase(int n): StoragePolicy(n) {}; VectorBase(const StoragePolicy &p): StoragePolicy(p) {}; typedef ::local::ZipIter zip_iter; // this + alpha * other VectorBase tpao(float a, const VectorBase &other) const { if (StoragePolicy::do_comp_test) assert(this->len() == other.len()); VectorBase x(other.len()); zip_iter it(*this,other); for (; it.isValid(); ++it) x[it->index]= (it->value1)+a*(it->value2); return x; } VectorBase operator+(const VectorBase &other) const { return tpao(1.0, other); } VectorBase operator-(const VectorBase &other) const { return tpao(-1.0, other); } template friend VectorBase operator*(float alpha, const VectorBase &other); template friend float dot(const VectorBase &v1, const VectorBase &v2); float operator*(const VectorBase &other) const { return dot(*this, other); } VectorBase operator-() const { return operator*(-1.0f, *this); } float pNorm(float p) const { float sum = 0.0f; for (typename StoragePolicy::const_value_iterator it = this->begin(); it != this->end(); ++it) sum += std::pow(*it, p); return std::pow(sum, 1.0f/p); } template friend float euk_distance(const VectorBase &v1, const VectorBase &v2); }; template VectorBase operator*(float alpha, const VectorBase &other) { VectorBase res(other.len()); for (typename VectorBase::const_item_iterator it=other.begin(); it != other.end(); ++it) res[it->index] = alpha*(it->value); return res; } template float dot(const VectorBase &v1, const VectorBase &v2) { float sum =0.0f; typename VectorBase::zip_iter it(v1, v2); for (; it.isValid(); ++it) sum += it->value1*it->value2; return sum; } template float euk_distance(const VectorBase &v1, const VectorBase &v2) { VectorBase diff = v1.tpao(-1.0, v2); // = v1-v2; float distsq = diff*diff; return std::sqrt(distsq); } template std::ostream & operator<<(std::ostream &os, const VectorBase &v) { int l = v.len(); typename VectorBase::const_value_iterator it=v.begin(); int n = 0; if (it != v.end()) { os << *it ; ++it; n = 1; } while (n<10 && it != v.end()) { os << ", " ; os << *it ; ++it; ++n; } if (n==10 && it != v.end()) os << ", ... "; return os; } //////////////////////////////////////////////////////////////////////////////// // // spezialisierung zur optimierung der ausführungszeit // //////////////////////////////////////////////////////////////////////////////// // float dot(const VectorBase &v1, const VectorBase &v2) { float sum=0.0f; // optimiert fuer Policy ! int i; int n=v1.len(); assert( n == v2.len()); for (i=0; i+3 VectorBase::tpao(float a, const VectorBase &other) const { assert(n_ == other.n_); VectorBase x(n_); int i; for (i=0; ioperator[](i)+a*other[i]; ++i; x[i]= this->operator[](i)+a*other[i]; ++i; x[i]= this->operator[](i)+a*other[i]; ++i; x[i]= this->operator[](i)+a*other[i]; } for (; ioperator[](i)+a*other[i]; return x; } class Vector: public VectorBase { public: Vector(int n): VectorBase(n) { }; Vector(const VectorBase &other): VectorBase(other) {}; }; class SparseVector: public VectorBase { public: SparseVector(): VectorBase() {}; SparseVector(const VectorBase &other): VectorBase(other) {}; }; #endif