52std::vector<Pointer_>
compress_sparse_triplets(
const Extent_ num_primary, Values_& values,
const PrimaryIndices_& primary_indices, SecondaryIndices_& secondary_indices) {
53 const auto num_triplets = values.size();
54 if (!sanisizer::is_equal(num_triplets, primary_indices.size()) || !sanisizer::is_equal(num_triplets, secondary_indices.size())) {
55 throw std::runtime_error(
"'primary_indices', 'secondary_indices' and 'values' should have the same length");
57 sanisizer::cast<Pointer_>(num_triplets);
59 typedef std::vector<Pointer_> Output;
60 typedef typename Output::size_type OutputSize;
61 Output ptrs(sanisizer::sum<OutputSize>(num_primary, 1));
62 for (
const auto p : primary_indices) {
63 ++ptrs[sanisizer::sum_unsafe<OutputSize>(p, 1)];
65 std::partial_sum(ptrs.begin(), ptrs.end(), ptrs.begin());
67 if (!std::is_sorted(primary_indices.begin(), primary_indices.end())) {
68 std::vector<Pointer_> copy(ptrs.begin(), ptrs.begin() + num_primary);
69 auto triplet_indices = sanisizer::create<std::vector<I<
decltype(num_triplets)> > >(num_triplets);
70 for (I<
decltype(num_triplets)> t = 0; t < num_triplets; ++t) {
71 auto& offset = copy[primary_indices[t]];
72 triplet_indices[offset] = t;
78 for (I<
decltype(num_triplets)> i = 0; i < num_triplets; ++i) {
79 if (triplet_indices[i] == num_triplets) {
83 const auto cur_second = secondary_indices[i];
84 const auto cur_value = values[i];
85 auto current = i, replacement = triplet_indices[current];
87 while (replacement != i) {
88 secondary_indices[current] = secondary_indices[replacement];
89 values[current] = values[replacement];
90 triplet_indices[current] = num_triplets;
91 current = replacement;
92 replacement = triplet_indices[replacement];
95 secondary_indices[current] = cur_second;
96 values[current] = cur_value;
97 triplet_indices[current] = num_triplets;
101 std::vector<std::pair<I<
decltype(secondary_indices[0])>, I<
decltype(values[0])> > > sortspace;
102 for (Extent_ p = 0; p < num_primary; ++p) {
103 const auto start = ptrs[p];
104 const auto end = ptrs[p + 1];
105 if (std::is_sorted(secondary_indices.begin() + start, secondary_indices.begin() + end)) {
110 sortspace.reserve(end - start);
111 for (Pointer_ x = start; x < end; ++x) {
112 sortspace.emplace_back(secondary_indices[x], values[x]);
114 std::sort(sortspace.begin(), sortspace.end());
116 auto ssIt = sortspace.begin();
117 for (Pointer_ x = start; x < end; ++x, ++ssIt) {
118 secondary_indices[x] = ssIt->first;
119 values[x] = ssIt->second;
131std::vector<decltype(std::declval<Values_>().size())>
compress_sparse_triplets(std::size_t nrow, std::size_t ncol, Values_& values, RowIndices_& row_indices, ColumnIndices_& column_indices,
bool csr) {