Skip to content

Commit

Permalink
Added map constructor to SparseVector
Browse files Browse the repository at this point in the history
  • Loading branch information
ankane committed Feb 19, 2025
1 parent 5a0cfad commit 1f7e13e
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.2.2 (unreleased)

- Added map constructor to `SparseVector`

## 0.2.1 (2025-01-15)

- Added `std::span` constructor to `Vector`
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,13 @@ Create a sparse vector from a `std::vector<float>`
auto vec = pgvector::SparseVector({1, 0, 2, 0, 3, 0});
```
Or a map of non-zero elements [unreleased]
```cpp
std::unordered_map<int, float> map = {{0, 1}, {2, 2}, {4, 3}};
auto vec = pgvector::SparseVector(map, 6);
```

Get the number of dimensions

```cpp
Expand Down
25 changes: 25 additions & 0 deletions include/pgvector/sparsevec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#pragma once

#include <ostream>
#include <unordered_map>
#include <vector>

namespace pgvector {
Expand Down Expand Up @@ -37,6 +38,30 @@ class SparseVector {
}
}

/// Creates a sparse vector from a map of non-zero elements.
SparseVector(const std::unordered_map<int, float>& map, int dimensions) {
if (dimensions < 1) {
throw std::invalid_argument("sparsevec must have at least 1 dimension");
}
dimensions_ = dimensions;

for (auto [i, v] : map) {
if (i < 0 || i >= dimensions) {
throw std::invalid_argument("sparsevec index out of bounds");
}

if (v != 0) {
indices_.push_back(i);
}
}
std::sort(indices_.begin(), indices_.end());

values_.reserve(indices_.size());
for (auto i : indices_) {
values_.push_back(map.at(i));
}
}

/// Returns the number of dimensions.
int dimensions() const {
return dimensions_;
Expand Down
9 changes: 9 additions & 0 deletions test/main.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <cassert>
#include <unordered_map>

#include "../include/pgvector/halfvec.hpp"
#include "../include/pgvector/sparsevec.hpp"
Expand Down Expand Up @@ -27,6 +28,14 @@ void test_sparsevec() {
assert(vec.values() == (std::vector<float>{1, 2, 3}));
}

void test_sparsevec_map() {
std::unordered_map<int, float> map = {{2, 2}, {4, 3}, {3, 0}, {0, 1}};
auto vec = SparseVector(map, 6);
assert(vec.dimensions() == 6);
assert(vec.indices() == (std::vector<int>{0, 2, 4}));
assert(vec.values() == (std::vector<float>{1, 2, 3}));
}

int main() {
test_pqxx();
test_vector();
Expand Down

0 comments on commit 1f7e13e

Please sign in to comment.