Skip to content

Instantly share code, notes, and snippets.

@dno89
Created July 20, 2021 01:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dno89/7cfbd8ec138ef95b0833109672a35217 to your computer and use it in GitHub Desktop.
Save dno89/7cfbd8ec138ef95b0833109672a35217 to your computer and use it in GitHub Desktop.
Transpose inplace
#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