Skip to content

Instantly share code, notes, and snippets.

@lambday
Last active August 29, 2015 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lambday/9647120 to your computer and use it in GitHub Desktop.
Save lambday/9647120 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <typeinfo>
#include <memory>
#include <algorithm>
#include <functional>
#include <random>
#include <Eigen/Eigen>
using namespace std;
using namespace Eigen;
typedef unsigned int index_t;
typedef double float64_t;
template <class T> class SGVector;
// dot product functors - base
template <class T>
class VectorDotProduct
{
public:
VectorDotProduct<T>() {}
virtual T operator() (SGVector<T> vector1, SGVector<T> vector2) const = 0;
virtual ~VectorDotProduct<T>() {}
};
// eigen3 implementation
template <class T>
class Eigen3DotProduct : public VectorDotProduct<T>
{
public:
Eigen3DotProduct<T>() {}
virtual T operator() (SGVector<T> vector1, SGVector<T> vector2) const
{
if (vector1.vlen != vector2.vlen)
cerr << "dimension mismatch" << endl;
Map<Matrix<T, Dynamic, 1> > vec1(vector1.vector.get(), vector1.vlen);
Map<Matrix<T, Dynamic, 1> > vec2(vector2.vector.get(), vector2.vlen);
return vec1.dot(vec2);
}
virtual ~Eigen3DotProduct<T>() {}
};
// other implementation
// modified linear operator implementation
template <class T, class Operand, class RetType>
class LinearOperator
{
public:
virtual RetType apply(Operand operand) = 0;
};
// now vector dot operator - everything fits within apply then
template <class T, class DotProductFunctor = Eigen3DotProduct<T> >
class VectorDotOperator : public LinearOperator<T, SGVector<T>, float64_t>
{
public:
VectorDotOperator(SGVector<T> vec, DotProductFunctor dot = DotProductFunctor()) :
vector(vec), dotproduct(dot)
{
}
virtual float64_t apply(SGVector<T> other)
{
return dotproduct(this->vector, other);
}
private:
SGVector<T> vector;
DotProductFunctor& dotproduct;
};
// could have used shogun's SGVector here instead - does nothing special now
template <class T>
class SGVector
{
public:
SGVector<T>(index_t len) : vlen(len)
{
vector = shared_ptr<T>(new T[vlen](), [](T* ptr) { delete[] ptr; });
}
inline const T operator[](index_t idx) const { return vector.get()[idx]; }
inline T operator[](index_t idx) { return vector.get()[idx]; }
void set_const(T val)
{
for_each(&vector.get()[0], &vector.get()[vlen], [&val](T& elem) { elem = val; });
}
/*
template <class DotProductFunctor = Eigen3DotProduct<T> >
T dot(SGVector<T> other, DotProductFunctor dotproduct = DotProductFunctor())
{
return dotproduct(*this, other);
}
*/
void display_vector(const char* name = "")
{
cout << name << ":";
for_each(&vector.get()[0], &vector.get()[vlen], [](T& elem) { cout << elem << " "; });
cout << endl;
}
virtual ~SGVector<T>() {}
index_t vlen;
shared_ptr<T> vector;
};
// have another implementation GPUVector or so...
int main()
{
const index_t size = 10, iter = 10;
SGVector<float64_t> v1(size), v2(size);
default_random_engine generator;
normal_distribution<float64_t> distrib(0.0, 1.0);
Eigen3DotProduct<float64_t> functor;
VectorDotOperator<float64_t> dotoperator(v1, functor);
for (index_t i = 0; i < iter; ++i)
{
for_each(&v1.vector.get()[0], &v1.vector.get()[size],
[&distrib, &generator](float64_t& elem) { elem = distrib(generator); });
for_each(&v2.vector.get()[0], &v2.vector.get()[size],
[&distrib, &generator](float64_t& elem) { elem = distrib(generator); });
v1.display_vector("v1");
v2.display_vector("v2");
cout << "v1.v2 : " << dotoperator.apply(v2) << endl;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment