Skip to content

Commit

Permalink
added row and column vectors
Browse files Browse the repository at this point in the history
  • Loading branch information
t-weber committed Feb 12, 2022
1 parent 9a89397 commit feec418
Show file tree
Hide file tree
Showing 3 changed files with 397 additions and 4 deletions.
141 changes: 141 additions & 0 deletions libs/tensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@
//#define __TENSOR_USE_DYN_LOOPS__


// --------------------------------------------------------------------------------
// helpers
// --------------------------------------------------------------------------------
template<class t_val, t_val val, class t_dummy = void>
constexpr const t_val static_value = val;
// --------------------------------------------------------------------------------



/**
* tensor with static size
*/
Expand Down Expand Up @@ -177,6 +186,19 @@ class Tensor
{
return const_cast<Tensor<t_scalar, SIZES...>*>(this)->operator()<DIMS...>();
}


/**
* if the tensor contains just one element, allow conversion to scalar
*/
constexpr operator t_scalar() const noexcept
{
if constexpr (size() == 1)
return operator[](0);
else
static_assert(static_value<bool, false, t_scalar>, "Invalid tensor -> scalar conversion.");
return 0;
}
// ------------------------------------------------------------------------


Expand Down Expand Up @@ -689,6 +711,35 @@ class Matrix : public Tensor<t_scalar, SIZE1, SIZE2>
{
return t_tensor::template size<1>();
}


/**
* get the transposed matrix
*/
constexpr Matrix<t_scalar, SIZE2, SIZE1> transpose() const noexcept
{
using t_mat_transp = Matrix<t_scalar, SIZE2, SIZE1>;

t_mat_transp mat;

for(t_size i=0; i<SIZE1; ++i)
{
#ifdef __TENSOR_USE_DYN_LOOPS__
for(t_size j=0; j<SIZE2; ++j)
mat(j, i) = (*this)(i, j);
#else
[&mat, i, this]<t_size ...j>(const std::integer_sequence<t_size, j...>&) -> void
{
( [&mat, i, this]() -> void
{
mat(j, i) = (*this)(i, j);
}(), ...);
}(std::make_integer_sequence<t_size, SIZE2>());
#endif
}

return mat;
}
};


Expand Down Expand Up @@ -839,4 +890,94 @@ operator*(const Vector<t_scalar_1, SIZE>& v, const Vector<t_scalar_2, SIZE>& w)
// --------------------------------------------------------------------------------



// --------------------------------------------------------------------------------
/**
* row vector with static size
*/
template<class t_scalar, std::size_t SIZE>
class RowVector : public Matrix<t_scalar, SIZE, 1>
{
public:
using t_matrix = Matrix<t_scalar, SIZE, 1>;
using t_tensor = typename Matrix<t_scalar, SIZE, 1>::t_tensor;
using t_size = typename t_matrix::t_size;
using t_cont = typename t_matrix::t_cont;
using value_type = typename t_matrix::value_type;


public:
constexpr RowVector(bool zero = true) noexcept
: t_matrix(zero)
{
}


~RowVector() noexcept = default;


/**
* copy constructor from tensor super class
*/
constexpr RowVector(const t_tensor& other) noexcept
{
t_tensor::operator=(other);
}


/**
* number of rows
*/
constexpr t_size size() const noexcept
{
return t_matrix::size1();
}
};



/**
* column vector with static size
*/
template<class t_scalar, std::size_t SIZE>
class ColVector : public Matrix<t_scalar, 1, SIZE>
{
public:
using t_matrix = Matrix<t_scalar, 1, SIZE>;
using t_tensor = typename Matrix<t_scalar, 1, SIZE>::t_tensor;
using t_size = typename t_matrix::t_size;
using t_cont = typename t_matrix::t_cont;
using value_type = typename t_matrix::value_type;


public:
constexpr ColVector(bool zero = true) noexcept
: t_matrix(zero)
{
}


~ColVector() noexcept = default;


/**
* copy constructor from tensor super class
*/
constexpr ColVector(const t_tensor& other) noexcept
{
t_tensor::operator=(other);
}


/**
* number of rows
*/
constexpr t_size size() const noexcept
{
return t_matrix::size2();
}
};

// --------------------------------------------------------------------------------

#endif
183 changes: 183 additions & 0 deletions libs/tensor_dyn.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,19 @@ class TensorDyn
{
return const_cast<TensorDyn<t_scalar, t_size, t_cont_templ>*>(this)->operator()<t_init>(dims);
}


/**
* if the tensor contains just one element, allow conversion to scalar
*/
constexpr operator t_scalar() const
{
if(size() == 1)
return operator[](0);
else
throw std::logic_error("Invalid tensor -> scalar conversion.");
return 0;
}
// ------------------------------------------------------------------------


Expand Down Expand Up @@ -554,6 +567,9 @@ class MatrixDyn : public TensorDyn<t_scalar, t_size, t_cont_templ>
}


MatrixDyn() noexcept = default;


~MatrixDyn() noexcept = default;


Expand Down Expand Up @@ -600,6 +616,23 @@ class MatrixDyn : public TensorDyn<t_scalar, t_size, t_cont_templ>
{
return t_tensor::operator()({row, col});
}


/**
* get the transposed matrix
*/
MatrixDyn transpose() const noexcept
{
MatrixDyn<t_scalar, t_size, t_cont_templ> mat{size2(), size1()};

for(t_size i=0; i<size1(); ++i)
{
for(t_size j=0; j<size2(); ++j)
mat(j, i) = (*this)(i, j);
}

return mat;
}
};


Expand Down Expand Up @@ -752,4 +785,154 @@ operator*(const VectorDyn<t_scalar_1, t_size, t_cont_templ>& v,
// --------------------------------------------------------------------------------



// --------------------------------------------------------------------------------
/**
* row vector with dynamic size
*/
template<class t_scalar, class t_size = std::size_t,
template<class...> class t_cont_templ = std::vector>
class RowVectorDyn : public MatrixDyn<t_scalar, t_size, t_cont_templ>
{
public:
using t_matrix = MatrixDyn<t_scalar, t_size, t_cont_templ>;
using t_tensor = typename t_matrix::t_tensor;
using t_cont = typename t_tensor::t_cont;
using value_type = typename t_tensor::value_type;


public:
constexpr RowVectorDyn(t_size rows) noexcept : t_matrix(rows, 1)
{
}


~RowVectorDyn() noexcept = default;


/**
* copy constructor from tensor super class
*/
RowVectorDyn(const t_tensor& other)
{
this->operator=(other);
}


/**
* assignment from tensor super class
*/
const RowVectorDyn& operator=(const t_tensor& other)
{
if(other.size(1) != 1)
throw std::logic_error("Invalid conversion to row vector.");

t_tensor::operator=(other);
return *this;
}


/**
* number of elements
*/
constexpr t_size size() const noexcept
{
return t_matrix::size1();
}


/**
* element access
*/
t_scalar& operator()(t_size row) noexcept
{
return t_matrix::operator()(row, 1);
}


/**
* element access
*/
const t_scalar& operator()(t_size row) const noexcept
{
return t_matrix::operator()(row, 1);
}
};



/**
* column vector with dynamic size
*/
template<class t_scalar, class t_size = std::size_t,
template<class...> class t_cont_templ = std::vector>
class ColVectorDyn : public MatrixDyn<t_scalar, t_size, t_cont_templ>
{
public:
using t_matrix = MatrixDyn<t_scalar, t_size, t_cont_templ>;
using t_tensor = typename t_matrix::t_tensor;
using t_cont = typename t_tensor::t_cont;
using value_type = typename t_tensor::value_type;


public:
constexpr ColVectorDyn(t_size cols) noexcept : t_matrix(1, cols)
{
}


~ColVectorDyn() noexcept = default;


/**
* copy constructor from tensor super class
*/
ColVectorDyn(const t_tensor& other)
{
this->operator=(other);
}


/**
* assignment from tensor super class
*/
const ColVectorDyn& operator=(const t_tensor& other)
{
if(other.size(0) != 1)
throw std::logic_error("Invalid conversion to column vector.");

t_tensor::operator=(other);
return *this;
}


/**
* number of elements
*/
constexpr t_size size() const noexcept
{
return t_matrix::size2();
}


/**
* element access
*/
t_scalar& operator()(t_size col) noexcept
{
return t_matrix::operator()(1, col);
}


/**
* element access
*/
const t_scalar& operator()(t_size col) const noexcept
{
return t_matrix::operator()(1, col);
}
};

// --------------------------------------------------------------------------------

#endif
Loading

0 comments on commit feec418

Please sign in to comment.