Created
July 20, 2021 01:07
-
-
Save dno89/7cfbd8ec138ef95b0833109672a35217 to your computer and use it in GitHub Desktop.
Transpose inplace
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 <vector> | |
#include <cassert> | |
#include <cmath> | |
#include <iostream> | |
#define P(X)\ | |
std::cerr << #X": " << X << std::endl; | |
class Matrix { | |
public: | |
Matrix(int rows, int col) : rows_(rows), cols_(col) | |
{ | |
data_.resize(rows_*cols_, 0.0); | |
} | |
Matrix(int rows, int col, std::vector<double> data) : rows_(rows), cols_(col), data_(std::move(data)) | |
{} | |
double& at(int i, int j) { | |
assert(i >=0 && i < rows_); | |
assert(j >=0 && j < cols_); | |
// std::cerr << "data at: " << i*cols_+j << std::endl; | |
return data_.at(i*cols_+j); | |
} | |
const double& at(int i, int j) const { | |
assert(i >=0 && i < rows_); | |
assert(j >=0 && j < cols_); | |
return data_.at(i*cols_+j); | |
} | |
int rows() const {return rows_;} | |
int cols() const {return cols_;} | |
Matrix transpose() const { | |
Matrix result(cols(), rows()); | |
for(int ii = 0; ii < result.rows(); ++ii) { | |
for(int jj = 0; jj < result.cols(); ++jj) { | |
result.at(ii, jj) = at(jj, ii); | |
} | |
} | |
return result; | |
} | |
void transpose_() { | |
auto k_next = [this](int k_prev) { | |
int _i = std::floor(k_prev/this->rows()); | |
int _j = k_prev - this->rows()*_i; | |
// P(_i) | |
// P(_j) | |
return _j*this->cols()+_i; | |
}; | |
// P(k_next(0)) | |
// P(k_next(5)) | |
double k_seed = 1; | |
double seed_tmp = data_[1]; | |
int k = k_seed; | |
auto find_next_seed = [&](int current_seed) { | |
int maybe_seed = current_seed+1; | |
int k = k_next(maybe_seed); | |
while(k != maybe_seed && k < this->data_.size()) { | |
if(k < maybe_seed) { | |
k = k_next(++maybe_seed); | |
} else { | |
k = k_next(k); | |
} | |
}; | |
return maybe_seed; | |
}; | |
while(true) { | |
int kn = k_next(k); | |
double data_next = (kn==k_seed)?seed_tmp:data_[kn]; | |
data_[k] = data_next; | |
if(kn==k_seed) { | |
k_seed = find_next_seed(k_seed); | |
if(k_seed >= data_.size()) { | |
break; | |
} | |
k = k_seed; | |
seed_tmp = data_[k_seed]; | |
} else { | |
k = kn; | |
} | |
std::cerr << k << " -> "; | |
} | |
std::swap(cols_, rows_); | |
} | |
friend std::ostream& operator<<(std::ostream& s, const Matrix& m) { | |
for(int ii = 0; ii < m.rows(); ++ii) { | |
for(int jj = 0; jj < m.cols(); ++jj) { | |
s << m.at(ii,jj) << " "; | |
} | |
s << '\n'; | |
} | |
return s; | |
} | |
private: | |
int rows_, cols_; | |
std::vector<double> data_; | |
}; | |
int main(int, char**) { | |
Matrix m(2,3); | |
m.at(0,0) = 0.0; | |
m.at(0,1) = 1.0; | |
m.at(0,2) = 2.0; | |
m.at(1,0) = 3.0; | |
m.at(1,1) = 4.0; | |
m.at(1,2) = 5.0; | |
std::cout << m << std::endl; | |
std::cout << m.transpose() << std::endl; | |
m.transpose_(); | |
std::cout << m << std::endl; | |
Matrix m2(2, 2); | |
m2.at(0,0) = 0.0; | |
m2.at(0,1) = 1.0; | |
m2.at(1,0) = 2.0; | |
m2.at(1,1) = 3.0; | |
std::cout << m2 << std::endl; | |
std::cout << m2.transpose() << std::endl; | |
Matrix m3(3, 4); | |
m3.at(0,0) = 0.0; | |
m3.at(0,1) = 1.0; | |
m3.at(0,2) = 2.0; | |
m3.at(0,3) = 3.0; | |
m3.at(1,0) = 4.0+0.0; | |
m3.at(1,1) = 4.0+1.0; | |
m3.at(1,2) = 4.0+2.0; | |
m3.at(1,3) = 4.0+3.0; | |
m3.at(2,0) = 8.0+0.0; | |
m3.at(2,1) = 8.0+1.0; | |
m3.at(2,2) = 8.0+2.0; | |
m3.at(2,3) = 8.0+3.0; | |
std::cout << m3 << std::endl; | |
std::cout << m3.transpose() << std::endl; | |
m3.transpose_(); | |
std::cout << m3 << std::endl; | |
m3.transpose_(); | |
std::cout << m3 << std::endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment