Skip to content

Commit 7918408

Browse files
committed
Random Sparse2d / Dense to sparse
1 parent 35b7529 commit 7918408

6 files changed

Lines changed: 113 additions & 4 deletions

File tree

lib/cpp-test/array/array_gtest.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class ArrayTest : public ::testing::Test {
3737
typedef ::testing::Types<ArrayFloat, ArrayDouble, ArrayShort, ArrayUShort,
3838
ArrayInt, ArrayUInt, ArrayLong, ArrayULong>
3939
MyArrayTypes;
40-
TYPED_TEST_CASE(ArrayTest, MyArrayTypes);
40+
TYPED_TEST_SUITE(ArrayTest, MyArrayTypes);
4141

4242
template <typename ArrType>
4343
class Array2dTest : public ::testing::Test {
@@ -49,7 +49,7 @@ typedef ::testing::Types<ArrayFloat2d, ArrayDouble2d, ArrayShort2d,
4949
ArrayUShort2d, ArrayInt2d, ArrayUInt2d, ArrayLong2d,
5050
ArrayULong2d>
5151
MyArray2dTypes;
52-
TYPED_TEST_CASE(Array2dTest, MyArray2dTypes);
52+
TYPED_TEST_SUITE(Array2dTest, MyArray2dTypes);
5353

5454
TYPED_TEST(ArrayTest, InitToZero) {
5555
TypeParam arr{TICK_TEST_DATA_SIZE};
@@ -626,6 +626,15 @@ TYPED_TEST(Array2dTest, SerializationBinary) {
626626
TypeParam>();
627627
}
628628

629+
TEST(SparseTesting, RandomSparse2d) {
630+
auto random_sparse = SparseArray2d<double>::RANDOM(100, 100, .33);
631+
auto dense = random_sparse->as_array2d();
632+
auto sparse = dense.as_sparsearray2d();
633+
ASSERT_EQ(random_sparse->size(), sparse->size());
634+
ASSERT_EQ(random_sparse->n_rows(), sparse->n_rows());
635+
ASSERT_EQ(random_sparse->n_cols(), sparse->n_cols());
636+
}
637+
629638
#ifdef ADD_MAIN
630639
int main(int argc, char **argv) {
631640
::testing::InitGoogleTest(&argc, argv);

lib/cpp-test/array/atomic_array_gtest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ class AtomicArrayTest : public ::testing::Test {
163163
};
164164

165165
typedef ::testing::Types<Array<float>, Array<double>> MyArrayTypes;
166-
TYPED_TEST_CASE(AtomicArrayTest, MyArrayTypes);
166+
TYPED_TEST_SUITE(AtomicArrayTest, MyArrayTypes);
167167

168168
TYPED_TEST(AtomicArrayTest, InitToZero) {
169169
TypeParam arr{TICK_TEST_DATA_SIZE};

lib/cpp-test/array/linear_system_gtest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class LinearSystemTest : public ::testing::Test {
2525
};
2626

2727
typedef ::testing::Types<ArrayFloat, ArrayDouble> MyArrayTypes;
28-
TYPED_TEST_CASE(LinearSystemTest, MyArrayTypes);
28+
TYPED_TEST_SUITE(LinearSystemTest, MyArrayTypes);
2929

3030

3131

lib/include/tick/array/array2d.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,8 @@ class Array2d : public BaseArray2d<T, MAJ> {
270270
// The definition is in the file sarray.h
271271
std::shared_ptr<SArray2d<T, MAJ>> as_sarray2d_ptr();
272272

273+
std::shared_ptr<SparseArray2d<T, MAJ>> as_sparsearray2d() const;
274+
273275
public:
274276
bool compare(const Array2d<T, MAJ>& that) const {
275277
bool are_equal = BaseArray2d<T, MAJ>::compare(that);
@@ -562,4 +564,36 @@ inline std::ostream &operator<<(std::ostream &s, const std::vector<T> &p) {
562564
return s << typeid(p).name() << "<" << typeid(T).name() << ">";
563565
}
564566

567+
template <typename T, typename MAJ>
568+
std::shared_ptr<SparseArray2d<T, MAJ>> Array2d<T, MAJ>::as_sparsearray2d() const {
569+
T zero {0};
570+
auto this_data = this->data();
571+
size_t _n_rows = this->n_rows(), _n_cols = this->n_cols(), nnz = 0, size = 0;
572+
for (size_t r = 0; r < _n_rows; r++) {
573+
for (size_t c = 0; c < _n_cols; c++) {
574+
T val {0};
575+
if ((val = this_data[(r * _n_cols) + c]) != zero) size++;
576+
}
577+
}
578+
auto sparse = SSparseArray2d<T, MAJ>::new_ptr(_n_rows, _n_cols, size);
579+
auto *data = sparse->data();
580+
auto *indices = sparse->indices();
581+
auto *row_indices = sparse->row_indices();
582+
row_indices[0] = 0;
583+
for (size_t r = 0; r < _n_rows; r++) {
584+
size_t nnz_row = 0;
585+
for (size_t c = 0; c < _n_cols; c++) {
586+
T val {0};
587+
if ((val = this_data[(r * _n_cols) + c]) != zero) {
588+
data[nnz] = val;
589+
indices[nnz] = c;
590+
nnz++;
591+
nnz_row++;
592+
}
593+
}
594+
row_indices[r + 1] = row_indices[r] + nnz_row;
595+
}
596+
return sparse;
597+
}
598+
565599
#endif // LIB_INCLUDE_TICK_ARRAY_ARRAY2D_H_
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
2+
#ifndef LIB_INCLUDE_TICK_ARRAY_SPARSE2D_RANDOM2D_H_
3+
#define LIB_INCLUDE_TICK_ARRAY_SPARSE2D_RANDOM2D_H_
4+
5+
#include <random>
6+
7+
template <typename T, typename MAJ>
8+
std::shared_ptr<SparseArray2d<T, MAJ>> SparseArray2d<T, MAJ>::RANDOM(size_t rows, size_t cols, T density, T seed) {
9+
if (density < 0 || density > 1)
10+
throw std::runtime_error("Invalid sparse density, must be between 0 and 1");
11+
12+
size_t size = std::floor(rows * cols * density);
13+
auto arr = SSparseArray2d<T, MAJ>::new_ptr(rows, cols, size);
14+
15+
std::mt19937_64 generator;
16+
if (seed > 0) {
17+
generator = std::mt19937_64(seed);
18+
} else {
19+
std::random_device r;
20+
std::seed_seq seed_seq{r(), r(), r(), r(), r(), r(), r(), r()};
21+
generator = std::mt19937_64(seed_seq);
22+
}
23+
std::uniform_real_distribution<T> dist;
24+
auto data = arr->data();
25+
for (size_t i = 0; i < size; i++) data[i] = dist(generator);
26+
27+
size_t nnz = size;
28+
std::vector<size_t> nnz_row(rows, 0);
29+
30+
size_t index = 0;
31+
while (nnz > 0) {
32+
std::uniform_int_distribution<size_t> dist_int(1, 100); // to do 50 50
33+
if (dist_int(generator) > 50) {
34+
nnz_row[index]++;
35+
nnz--;
36+
}
37+
index++;
38+
if (index >= rows) index = 0;
39+
}
40+
41+
index = 0;
42+
auto indices = arr->indices();
43+
for (size_t i : nnz_row) {
44+
std::vector<size_t> indice_comb;
45+
for (size_t j = 0; j < cols; j++) indice_comb.emplace_back(j);
46+
std::shuffle(indice_comb.begin(), indice_comb.end(), generator);
47+
for (size_t j = 0; j < i; j++) {
48+
indices[index++] = indice_comb[j];
49+
}
50+
}
51+
52+
// if (index != arr->indices().size() - 1)
53+
// std::runtime_error("Uh something is wrong");
54+
55+
auto row_indices = arr->row_indices();
56+
row_indices[0] = 0;
57+
for (size_t i = 1; i < rows + 1; i++) row_indices[i] = row_indices[i - 1] + nnz_row[i - 1];
58+
59+
return arr;
60+
}
61+
62+
#endif // LIB_INCLUDE_TICK_ARRAY_SPARSE2D_RANDOM2D_H_

lib/include/tick/array/sparsearray2d.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ class SparseArray2d : public BaseArray2d<T, MAJ> {
103103
//! called on a view
104104
std::shared_ptr<SSparseArray2d<T, MAJ>> as_ssparsearray2d_ptr();
105105

106+
static std::shared_ptr<SparseArray2d<T, MAJ>> RANDOM(size_t rows, size_t cols, T density, T seed = -1);
107+
106108
template <class Archive>
107109
void save(Archive &ar) const {
108110
ar(this->_size_sparse);
@@ -277,4 +279,6 @@ SPARSE_ARRAY2D_DEFINE_TYPE(ulong, ULong);
277279
* @}
278280
*/
279281

282+
#include "tick/array/sparse2d/random2d.h"
283+
280284
#endif // LIB_INCLUDE_TICK_ARRAY_SPARSEARRAY2D_H_

0 commit comments

Comments
 (0)