From d09a99faaea91f6f988e0015521d54c38cf4f0f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattia=20Isgr=C3=B2?= Date: Tue, 30 Apr 2024 18:01:44 +0200 Subject: [PATCH] Add sparse vector first implementation --- examples/example.cpp | 22 ++++--- src/algebra/sparse_vec.h | 124 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+), 7 deletions(-) create mode 100644 src/algebra/sparse_vec.h diff --git a/examples/example.cpp b/examples/example.cpp index 71f147d84..8b41e4810 100644 --- a/examples/example.cpp +++ b/examples/example.cpp @@ -7,16 +7,24 @@ #include "theoretica.h" using namespace th; +#include "algebra/sparse_vec.h" + + int main() { - // Declare a 3D vector - vec3 v = {1, 2, 3}; + sparse_vec<> v1 = sparse_vec<>({ + vec2({1, PI}), vec2({9, PHI}) + }); - // Create a 3x3 identity matrix - mat3 A = mat3::identity(); + sparse_vec<> v2 = sparse_vec<>({ + vec2({1, 3.0}) + }); - // Transform v by A - vec3 w = A * v; - + std::cout << v1 << std::endl; + std::cout << v2 << std::endl; + std::cout << v1 * v2 << std::endl; + + char c; + std::cin >> c; return 0; } diff --git a/src/algebra/sparse_vec.h b/src/algebra/sparse_vec.h new file mode 100644 index 000000000..4fc56d0bc --- /dev/null +++ b/src/algebra/sparse_vec.h @@ -0,0 +1,124 @@ + +/// +/// @file sparse_vec.h Sparse vector class implemented as a hashmap +/// + +#ifndef THEORETICA_SPARSE_VEC_H +#define THEORETICA_SPARSE_VEC_H + +#include +#include "../core/constants.h" + + +namespace theoretica { + + /// @class sparse_vec Sparse vector class implemented as a hashmap + template + class sparse_vec { + public: + + /// Data is stored in a hashmap as (index, value) + std::map data; + + + /// Initialize as the zero vector + sparse_vec() {} + + + /// Initialize the sparse vector from a list + /// of pairs (index, value) + template + sparse_vec(const std::initializer_list& pairs) { + + for (auto& pair : pairs) + data[pair[0]] = pair[1]; + } + + + ~sparse_vec() = default; + + + /// Add two sparse vectors + inline sparse_vec operator+(const sparse_vec& other) { + + sparse_vec res; + res.data = this->data; + + for (auto& pair : other) + res[pair.first] += pair.second; + + return res; + } + + + /// Dot product of two sparse vectors + inline T operator*(const sparse_vec& other) { + + T res = T(0.0); + + for (auto& pair : data) + res += pair.second * other[pair.first]; + + return res; + } + + + /// Get the n-th element + inline T operator[](IndexType index) const { + + const auto iter = data.find(index); + + if(iter == data.end()) + return 0; + + return iter->second; + } + + + /// Access the n-th element + inline T& operator[](IndexType index) { + return data[index]; + } + + +#ifndef THEORETICA_NO_PRINT + + /// Convert the vector to string representation + inline std::string to_string( + const std::string& separator = ", ", + bool parenthesis = true) const { + + std::stringstream res; + + // if(parenthesis) + // res << "("; + + for (auto& pair : this->data) { + // res << pair.second; + // res << separator; + + res << "(" << pair.first << ", " + << pair.second << ") "; + + } + + // if(parenthesis) + // res << ")"; + + return res.str(); + } + + + /// Stream the vector in string representation to an output stream (std::ostream) + inline friend std::ostream& operator<<( + std::ostream& out, const sparse_vec& obj) { + return out << obj.to_string(); + } + +#endif + + }; + +} + +#endif