Skip to content

Commit 1f7e13e

Browse files
committed
Added map constructor to SparseVector
1 parent 5a0cfad commit 1f7e13e

File tree

4 files changed

+45
-0
lines changed

4 files changed

+45
-0
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.2.2 (unreleased)
2+
3+
- Added map constructor to `SparseVector`
4+
15
## 0.2.1 (2025-01-15)
26

37
- Added `std::span` constructor to `Vector`

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,13 @@ Create a sparse vector from a `std::vector<float>`
118118
auto vec = pgvector::SparseVector({1, 0, 2, 0, 3, 0});
119119
```
120120
121+
Or a map of non-zero elements [unreleased]
122+
123+
```cpp
124+
std::unordered_map<int, float> map = {{0, 1}, {2, 2}, {4, 3}};
125+
auto vec = pgvector::SparseVector(map, 6);
126+
```
127+
121128
Get the number of dimensions
122129

123130
```cpp

include/pgvector/sparsevec.hpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#pragma once
88

99
#include <ostream>
10+
#include <unordered_map>
1011
#include <vector>
1112

1213
namespace pgvector {
@@ -37,6 +38,30 @@ class SparseVector {
3738
}
3839
}
3940

41+
/// Creates a sparse vector from a map of non-zero elements.
42+
SparseVector(const std::unordered_map<int, float>& map, int dimensions) {
43+
if (dimensions < 1) {
44+
throw std::invalid_argument("sparsevec must have at least 1 dimension");
45+
}
46+
dimensions_ = dimensions;
47+
48+
for (auto [i, v] : map) {
49+
if (i < 0 || i >= dimensions) {
50+
throw std::invalid_argument("sparsevec index out of bounds");
51+
}
52+
53+
if (v != 0) {
54+
indices_.push_back(i);
55+
}
56+
}
57+
std::sort(indices_.begin(), indices_.end());
58+
59+
values_.reserve(indices_.size());
60+
for (auto i : indices_) {
61+
values_.push_back(map.at(i));
62+
}
63+
}
64+
4065
/// Returns the number of dimensions.
4166
int dimensions() const {
4267
return dimensions_;

test/main.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <cassert>
2+
#include <unordered_map>
23

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

31+
void test_sparsevec_map() {
32+
std::unordered_map<int, float> map = {{2, 2}, {4, 3}, {3, 0}, {0, 1}};
33+
auto vec = SparseVector(map, 6);
34+
assert(vec.dimensions() == 6);
35+
assert(vec.indices() == (std::vector<int>{0, 2, 4}));
36+
assert(vec.values() == (std::vector<float>{1, 2, 3}));
37+
}
38+
3039
int main() {
3140
test_pqxx();
3241
test_vector();

0 commit comments

Comments
 (0)