Last active
February 26, 2023 02:06
-
-
Save samkhn/73aa63426f7b62187f35560f95f427d8 to your computer and use it in GitHub Desktop.
Fast matrix transpose with `follow-the-cycle`.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <algorithm> | |
#include <iostream> | |
#include <iterator> | |
#include <vector> | |
// num_columns refers to the number of columns in the original matrix, not the | |
// desired column count post transpose. | |
void Transpose(int* begin, int* end, const std::size_t num_columns) { | |
const int64_t size = (end-begin-1); // num_elements-1 | |
const int64_t num_rows = (end-begin)/num_columns; | |
// TODO: if (num_row=num_col), just swap indices | |
std::vector<bool> visited(end-begin); | |
int* cycle = begin; | |
while (++cycle != end) { | |
if (visited[cycle-begin]) { | |
continue; | |
} | |
int64_t i = cycle-begin; | |
do { | |
i = (i == size) ? size : (i*num_rows) % size; | |
std::swap(*(begin+i), *cycle); | |
visited[i] = true; | |
} while ((begin+i) != cycle); | |
} | |
} | |
int main() { | |
int v[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; | |
std::cout << "Pre transpose "; | |
std::copy(v, v+8, std::ostream_iterator<int>(std::cout, " ")); | |
std::cout << "\n"; | |
Transpose(v, v+8, 4); | |
std::cout << "Post transpose "; | |
std::copy(v, v+8, std::ostream_iterator<int>(std::cout, " ")); | |
std::cout << "\n"; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment