Skip to content

Commit

Permalink
setup if statement, count operations
Browse files Browse the repository at this point in the history
Signed-off-by: Laurynas Jagutis <[email protected]>
  • Loading branch information
Laurynas-Jagutis committed Nov 30, 2023
1 parent c924777 commit 0984153
Showing 1 changed file with 88 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -111,76 +111,99 @@ struct DenseMapping {

inline DenseMapping build_dense_mapping(IdxVector const& idx_B_in_A, Idx const n_B) {
auto const n_A = static_cast<Idx>(idx_B_in_A.size());
auto const r = std::max_element(idx_B_in_A.begin(), idx_B_in_A.end());
auto const r = std::max_element(idx_B_in_A.begin(), idx_B_in_A.end())[0];
// for counting sort nr_of_operations = 1 + 3*n_A + 2*n_B + 2*n_A + 2*n_B - 1 + 1 + n_A + 1 + 14 * n_A
// nr_of_operations = 20*n_A + 4*n_B + 2
// auto const c = 20*n_A + 4*n_B + 2
// if (n_A * log(n_A) < c * r){
// } else {

auto const c = 20 * n_A + 4 * n_B + 2;
// for n log n sort nr of operations = 1 + 7*n_A + n_A*log(n_A)?
using DenseEntry = std::pair<Idx, Idx>;
// std::vector<DenseEntry> mapping_to_from;

// auto index_range = std::ranges::views::iota(0, static_cast<Idx>(idx_B_in_A.size()));
// std::ranges::transform(idx_B_in_A, index_range,
// std::back_inserter(mapping_to_from),
// [](Idx value, Idx orig_idx){ return std::pair{value, orig_idx}; });
// std::ranges::sort(mapping_to_from); // runs in O(n log n)

// DenseMapping result;
// std::ranges::transform(mapping_to_from, std::back_inserter(result.indvector),
// [](DenseEntry const& to_from) { return to_from.first; } );
// std::ranges::transform(mapping_to_from, std::back_inserter(result.reorder),
// [](DenseEntry const& to_from) { return to_from.second; });

// 1
std::vector<DenseEntry> entries(n_A);

// n_A * 1, since the transform operation will be performed n_A times and it only does one operation - returning the
// dense entry
std::transform(idx_B_in_A.cbegin(), idx_B_in_A.cend(), IdxCount{0}, entries.begin(), [](Idx j_B, Idx i_A) {
return DenseEntry{i_A, j_B};
});

DenseMapping dense_mapping;

// n_A
dense_mapping.indvector.resize(n_A);
// n_A
dense_mapping.reorder.resize(n_A);

IdxVector xndvector;
// n_B
xndvector.resize(n_B);
// n_B
IdxVector counter(n_B, 0);

// entries have the same size as idx_B_in_A, thus n_A * 2. One for access, one for incrementing
for (auto const& entry : entries) {
++counter[entry.second];
}

// Loop over counter is n_B, but the addition does not happen on the first element so n_B - 1?
// Placing the values in xndvector is n_B, thus 2n_B - 1?
std::inclusive_scan(counter.cbegin(), counter.cend(), xndvector.begin());

// {0,3},{1,5},{2,2},{3,1},{4,1},{5,2}

// auto it_entry = entries.crbegin() should be 1
// it_entry != entries.crend() should be n_A + 1, since it does all the operations including
// the final one to check whether the condition does not hold anymore
// ++it_entry will be n_A
// Inside the loop:
// dense_mapping.indvector[xndvector[idx_B_in_A[it_entry->first]] - 1] will be 5 * n_A
// idx_B_in_A[it_entry->first] should then be 2 * n_A
// the first line becomes 5 * n_A + n_A(for assigning) + 2 * n_A = 8 * n_A
// dense_mapping.reorder[--xndvector[it_entry->second]] will be 4 * n_A
// it_entry->first will be n_A
// total second line will be 6 * n_A
// total both lines = 8 * n_A + 6 * n_A = 14 * n_A
for (auto it_entry = entries.crbegin(); it_entry != entries.crend(); ++it_entry) {
dense_mapping.indvector[xndvector[idx_B_in_A[it_entry->first]] - 1] = idx_B_in_A[it_entry->first];
dense_mapping.reorder[--xndvector[it_entry->second]] = it_entry->first;
if (n_A * log(n_A) < c * r) {
// 1 operation?
std::vector<DenseEntry> mapping_to_from;

// n_A operations
auto index_range = std::ranges::views::iota(0, static_cast<Idx>(idx_B_in_A.size()));

// n_A * 2 operations?
std::ranges::transform(idx_B_in_A, index_range, std::back_inserter(mapping_to_from),
[](Idx value, Idx orig_idx) {
return std::pair{value, orig_idx};
});
// n_A log n_A?
std::ranges::sort(mapping_to_from); // runs in O(n log n)

// n_A * 2 operations?
std::ranges::transform(mapping_to_from, std::back_inserter(dense_mapping.indvector),
[](DenseEntry const& to_from) { return to_from.first; });
// n_A * 2 operations?
std::ranges::transform(mapping_to_from, std::back_inserter(dense_mapping.reorder),
[](DenseEntry const& to_from) { return to_from.second; });
} else {
// 1
std::vector<DenseEntry> entries(n_A);

// n_A, since the transform operation will be performed n_A times and it only does one operation - returning the
// dense entry
std::transform(idx_B_in_A.cbegin(), idx_B_in_A.cend(), IdxCount{0}, entries.begin(), [](Idx j_B, Idx i_A) {
return DenseEntry{i_A, j_B};
});

// n_A or can we say that resize is constant 1?
dense_mapping.indvector.resize(n_A);
// n_A or can we say that resize is constant 1?
dense_mapping.reorder.resize(n_A);

IdxVector xndvector;
// n_B or can we say that resize is constant 1?
xndvector.resize(n_B);
// n_B
IdxVector counter(n_B, 0);

// entries have the same size as idx_B_in_A, thus n_A * 2. One for access, one for incrementing
for (auto const& entry : entries) {
++counter[entry.second];
}

// Loop over counter is n_B, but the addition does not happen on the first element so n_B - 1?
// Placing the values in xndvector is n_B, thus 2n_B - 1?
std::inclusive_scan(counter.cbegin(), counter.cend(), xndvector.begin());

// {0,3},{1,5},{2,2},{3,1},{4,1},{5,2}

// auto it_entry = entries.crbegin() should be 1
// it_entry != entries.crend() should be n_A + 1, since it does all the operations including
// the final one to check whether the condition does not hold anymore
// ++it_entry will be n_A

// Inside the loop:
// dense_mapping.indvector[xndvector[idx_B_in_A[it_entry->first]] - 1] will be 5 * n_A:
// first one for it_entry->first
// second one for idx_B_in_A[it_entry->first]
// third one for xndvector[idx_B_in_A[it_entry->first]]
// fourth one for xndvector[idx_B_in_A[it_entry->first]] - 1
// fifth one for dense_mapping.indvector[xndvector[idx_B_in_A[it_entry->first]] - 1]

// idx_B_in_A[it_entry->first] should then be 2 * n_A

// the first line becomes 5 * n_A + n_A(for assigning) + 2 * n_A = 8 * n_A

// Second line first part: dense_mapping.reorder[--xndvector[it_entry->second]] will be 4 * n_A
// first one for it_entry->second
// second one for xndvector[it_entry->second]
// third one for --xndvector[it_entry->second]
// fourth one fpr dense_mapping.reorder[--xndvector[it_entry->second]]

// Second line second part:it_entry->first will be n_A

// total second line will be 6 * n_A

// total both lines = 8 * n_A + 6 * n_A = 14 * n_A
for (auto it_entry = entries.crbegin(); it_entry != entries.crend(); ++it_entry) {
dense_mapping.indvector[xndvector[idx_B_in_A[it_entry->first]] - 1] = idx_B_in_A[it_entry->first];
dense_mapping.reorder[--xndvector[it_entry->second]] = it_entry->first;
}
}

return dense_mapping;
Expand Down

0 comments on commit 0984153

Please sign in to comment.