Skip to content

Commit

Permalink
Random Sparse2d / Dense to sparse
Browse files Browse the repository at this point in the history
  • Loading branch information
PhilipDeegan committed Jul 5, 2020
1 parent 937c289 commit 4e3d77d
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 4 deletions.
13 changes: 11 additions & 2 deletions lib/cpp-test/array/array_gtest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class ArrayTest : public ::testing::Test {
typedef ::testing::Types<ArrayFloat, ArrayDouble, ArrayShort, ArrayUShort,
ArrayInt, ArrayUInt, ArrayLong, ArrayULong>
MyArrayTypes;
TYPED_TEST_CASE(ArrayTest, MyArrayTypes);
TYPED_TEST_SUITE(ArrayTest, MyArrayTypes);

template <typename ArrType>
class Array2dTest : public ::testing::Test {
Expand All @@ -49,7 +49,7 @@ typedef ::testing::Types<ArrayFloat2d, ArrayDouble2d, ArrayShort2d,
ArrayUShort2d, ArrayInt2d, ArrayUInt2d, ArrayLong2d,
ArrayULong2d>
MyArray2dTypes;
TYPED_TEST_CASE(Array2dTest, MyArray2dTypes);
TYPED_TEST_SUITE(Array2dTest, MyArray2dTypes);

TYPED_TEST(ArrayTest, InitToZero) {
TypeParam arr{TICK_TEST_DATA_SIZE};
Expand Down Expand Up @@ -626,6 +626,15 @@ TYPED_TEST(Array2dTest, SerializationBinary) {
TypeParam>();
}

TEST(SparseTesting, RandomSparse2d) {
auto random_sparse = SparseArray2d<double>::RANDOM(100, 100, .33);
auto dense = random_sparse->as_array2d();
auto sparse = dense.as_sparsearray2d();
ASSERT_EQ(random_sparse->size(), sparse->size());
ASSERT_EQ(random_sparse->n_rows(), sparse->n_rows());
ASSERT_EQ(random_sparse->n_cols(), sparse->n_cols());
}

#ifdef ADD_MAIN
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
Expand Down
2 changes: 1 addition & 1 deletion lib/cpp-test/array/atomic_array_gtest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ class AtomicArrayTest : public ::testing::Test {
};

typedef ::testing::Types<Array<float>, Array<double>> MyArrayTypes;
TYPED_TEST_CASE(AtomicArrayTest, MyArrayTypes);
TYPED_TEST_SUITE(AtomicArrayTest, MyArrayTypes);

TYPED_TEST(AtomicArrayTest, InitToZero) {
TypeParam arr{TICK_TEST_DATA_SIZE};
Expand Down
2 changes: 1 addition & 1 deletion lib/cpp-test/array/linear_system_gtest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class LinearSystemTest : public ::testing::Test {
};

typedef ::testing::Types<ArrayFloat, ArrayDouble> MyArrayTypes;
TYPED_TEST_CASE(LinearSystemTest, MyArrayTypes);
TYPED_TEST_SUITE(LinearSystemTest, MyArrayTypes);



Expand Down
34 changes: 34 additions & 0 deletions lib/include/tick/array/array2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@ class Array2d : public BaseArray2d<T, MAJ> {
// The definition is in the file sarray.h
std::shared_ptr<SArray2d<T, MAJ>> as_sarray2d_ptr();

std::shared_ptr<SparseArray2d<T, MAJ>> as_sparsearray2d() const;

public:
bool compare(const Array2d<T, MAJ>& that) const {
bool are_equal = BaseArray2d<T, MAJ>::compare(that);
Expand Down Expand Up @@ -562,4 +564,36 @@ inline std::ostream &operator<<(std::ostream &s, const std::vector<T> &p) {
return s << typeid(p).name() << "<" << typeid(T).name() << ">";
}

template <typename T, typename MAJ>
std::shared_ptr<SparseArray2d<T, MAJ>> Array2d<T, MAJ>::as_sparsearray2d() const {
T zero {0};
auto this_data = this->data();
size_t _n_rows = this->n_rows(), _n_cols = this->n_cols(), nnz = 0, size = 0;
for (size_t r = 0; r < _n_rows; r++) {
for (size_t c = 0; c < _n_cols; c++) {
T val {0};
if ((val = this_data[(r * _n_cols) + c]) != zero) size++;
}
}
auto sparse = SSparseArray2d<T, MAJ>::new_ptr(_n_rows, _n_cols, size);
auto *data = sparse->data();
auto *indices = sparse->indices();
auto *row_indices = sparse->row_indices();
row_indices[0] = 0;
for (size_t r = 0; r < _n_rows; r++) {
size_t nnz_row = 0;
for (size_t c = 0; c < _n_cols; c++) {
T val {0};
if ((val = this_data[(r * _n_cols) + c]) != zero) {
data[nnz] = val;
indices[nnz] = c;
nnz++;
nnz_row++;
}
}
row_indices[r + 1] = row_indices[r] + nnz_row;
}
return sparse;
}

#endif // LIB_INCLUDE_TICK_ARRAY_ARRAY2D_H_
62 changes: 62 additions & 0 deletions lib/include/tick/array/sparse2d/random2d.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@

#ifndef LIB_INCLUDE_TICK_ARRAY_SPARSE2D_RANDOM2D_H_
#define LIB_INCLUDE_TICK_ARRAY_SPARSE2D_RANDOM2D_H_

#include <random>

template <typename T, typename MAJ>
std::shared_ptr<SparseArray2d<T, MAJ>> SparseArray2d<T, MAJ>::RANDOM(size_t rows, size_t cols, T density, T seed) {
if (density < 0 || density > 1)
throw std::runtime_error("Invalid sparse density, must be between 0 and 1");

size_t size = std::floor(rows * cols * density);
auto arr = SSparseArray2d<T, MAJ>::new_ptr(rows, cols, size);

std::mt19937_64 generator;
if (seed > 0) {
generator = std::mt19937_64(seed);
} else {
std::random_device r;
std::seed_seq seed_seq{r(), r(), r(), r(), r(), r(), r(), r()};
generator = std::mt19937_64(seed_seq);
}
std::uniform_real_distribution<T> dist;
auto data = arr->data();
for (size_t i = 0; i < size; i++) data[i] = dist(generator);

size_t nnz = size;
std::vector<size_t> nnz_row(rows, 0);

size_t index = 0;
while (nnz > 0) {
std::uniform_int_distribution<size_t> dist_int(1, 100); // to do 50 50
if (dist_int(generator) > 50) {
nnz_row[index]++;
nnz--;
}
index++;
if (index >= rows) index = 0;
}

index = 0;
auto indices = arr->indices();
for (size_t i : nnz_row) {
std::vector<size_t> indice_comb;
for (size_t j = 0; j < cols; j++) indice_comb.emplace_back(j);
std::shuffle(indice_comb.begin(), indice_comb.end(), generator);
for (size_t j = 0; j < i; j++) {
indices[index++] = indice_comb[j];
}
}

// if (index != arr->indices().size() - 1)
// std::runtime_error("Uh something is wrong");

auto row_indices = arr->row_indices();
row_indices[0] = 0;
for (size_t i = 1; i < rows + 1; i++) row_indices[i] = row_indices[i - 1] + nnz_row[i - 1];

return arr;
}

#endif // LIB_INCLUDE_TICK_ARRAY_SPARSE2D_RANDOM2D_H_
4 changes: 4 additions & 0 deletions lib/include/tick/array/sparsearray2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ class SparseArray2d : public BaseArray2d<T, MAJ> {
//! called on a view
std::shared_ptr<SSparseArray2d<T, MAJ>> as_ssparsearray2d_ptr();

static std::shared_ptr<SparseArray2d<T, MAJ>> RANDOM(size_t rows, size_t cols, T density, T seed = -1);

template <class Archive>
void save(Archive &ar) const {
ar(this->_size_sparse);
Expand Down Expand Up @@ -277,4 +279,6 @@ SPARSE_ARRAY2D_DEFINE_TYPE(ulong, ULong);
* @}
*/

#include "tick/array/sparse2d/random2d.h"

#endif // LIB_INCLUDE_TICK_ARRAY_SPARSEARRAY2D_H_

0 comments on commit 4e3d77d

Please sign in to comment.