Program Listing for File tinymatrix.hpp¶
↰ Return to documentation for file (/home/docs/checkouts/readthedocs.org/user_builds/intel-qs/checkouts/docs/include/tinymatrix.hpp
)
// Copyright (C) 2015 Theoretical Physics, ETH Zurich
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef IQS_TINYMATRIX_HPP
#define IQS_TINYMATRIX_HPP
#include <cassert>
#include <initializer_list>
#include <iostream>
namespace qhipster {
template <class ValueType, unsigned M, unsigned N = M, unsigned align = alignof(ValueType)>
class TinyMatrix
{
public:
using value_type = ValueType;
using pointer = ValueType*;
using const_pointer = ValueType const*;
using reference = ValueType&;
using size_type = unsigned;
using RowType = ValueType[N];
TinyMatrix() { static_assert(N * M != 0, "a zero-dimensional matrix is not allowed"); }
template <class U>
// TinyMatrix(U const (init)[M][N])
TinyMatrix(U init[M][N])
{
for (size_type i = 0; i < this->numRows(); ++i)
for (size_type j = 0; j < this->numCols(); ++j) data_[i][j] = init[i][j];
}
template <class U>
TinyMatrix(std::initializer_list<std::initializer_list<U>> const& init)
{
unsigned i = 0;
for (auto const& line : init) {
unsigned j = 0;
for (auto const& elem : line) data_[i][j++] = elem;
++i;
}
}
template <class U, unsigned alignrhs>
TinyMatrix(TinyMatrix<U, M, N, alignrhs> const& rhs)
{
for (size_type i = 0; i < this->numRows(); ++i)
for (size_type j = 0; j < this->numCols(); ++j) data_[i][j] = rhs(i, j);
}
TinyMatrix(TinyMatrix const&) = default;
TinyMatrix& operator=(TinyMatrix const&) = default;
template <class U, unsigned alignrhs>
TinyMatrix& operator=(TinyMatrix<U, M, N, alignrhs> const& rhs)
{
for (size_type i = 0; i < this->numRows(); ++i)
for (size_type j = 0; j < this->numCols(); ++j) data_[i][j] = rhs(i, j);
return *this;
}
template <class U>
TinyMatrix& operator=(U const (&rhs)[M][N])
{
for (size_type i = 0; i < this->numRows(); ++i)
for (size_type j = 0; j < this->numCols(); ++j) data_[i][j] = rhs[i][j];
return *this;
}
constexpr size_type numRows() const { return M; }
constexpr size_type numCols() const { return N; }
constexpr size_type size() const { return N * M; }
value_type operator()(unsigned i, unsigned j) const
{
assert(i < this->numRows() && j < this->numCols());
return data_[i][j];
}
reference operator()(unsigned i, unsigned j)
{
assert(i < this->numRows() && j < this->numCols());
return data_[i][j];
}
template <class U, unsigned alignrhs>
bool operator==(TinyMatrix<U, M, N, alignrhs> const& rhs) const
{
for (size_type i = 0; i < this->numRows(); ++i)
for (size_type j = 0; j < this->numCols(); ++j)
if (data_[i][j] != rhs(i, j)) return false;
return true;
}
template <class U, unsigned alignrhs>
bool operator!=(TinyMatrix<U, M, N, alignrhs> const& rhs) const
{
return !(*this == rhs);
}
template <class U>
bool operator==(U const (&rhs)[M][N])
{
for (size_type i = 0; i < this->numRows(); ++i)
for (size_type j = 0; j < this->numCols(); ++j)
if (data_[i][j] != rhs[i][j]) return false;
return true;
}
template <class U>
bool operator!=(U const (&rhs)[M][N])
{
return !(*this == rhs);
}
const_pointer getPtr() const { return &data_[0][0]; }
RowType& operator[](unsigned i)
{
assert(i < this->numRows());
return data_[i];
}
RowType const& operator[](unsigned i) const
{
assert(i < this->numRows());
return data_[i];
}
template <unsigned MSub, unsigned NSub = MSub>
TinyMatrix<ValueType, MSub, NSub, align> getSubMatrix(unsigned i_start = 0,
unsigned j_start = 0,
unsigned i_stride = 1,
unsigned j_stride = 1) const
{
assert(i_stride > 0 && j_stride > 0);
assert((MSub - 1) * i_stride + i_start < M && (NSub - 1) * j_stride + j_start < N);
TinyMatrix<ValueType, MSub, NSub, align> tmp;
for (unsigned i = i_start, i_sub = 0; i_sub < MSub; i += i_stride, ++i_sub)
for (unsigned j = j_start, j_sub = 0; j_sub < NSub; j += j_stride, ++j_sub)
tmp(i_sub, j_sub) = (*this)(i, j);
return tmp;
}
void print(std::string name)
{
printf("name: %s\n", (const char *)name.c_str());
for (size_type i = 0; i < this->numRows(); ++i) {
for (size_type j = 0; j < this->numCols(); ++j)
{
std::cout << data_[i][j].real() << " + i*" << data_[i][j].imag() << " ";
}
printf("\n");
}
}
std::string tostr() const
{
std::string str;
str = "{";
for (size_type i = 0; i < this->numRows(); ++i) {
str += "{";
for (size_type j = 0; j < this->numCols(); ++j)
{
char s[2048];
sprintf(s, "%.3lf+%.3lf ", data_[i][j].real(), data_[i][j].imag());
str += s;
}
str += "}";
}
str += "{";
return str;
}
std::string name;
private:
alignas(align == 0 ? 8 : align) ValueType data_[M][N];
};
} // end namespace qhipster
#endif // header guard IQS_TINYMATRIX_HPP