Program Listing for File factory.hpp
↰ Return to documentation for file (src/navtk/factory.hpp)
#pragma once
#include <xtensor/core/xmath.hpp>
#include <navtk/inspect.hpp>
#include <navtk/tensors.hpp>
namespace navtk {
template <class T, IfTensorOfDim<T, 0>* = nullptr>
Vector to_vec(const T& m) {
if (has_zero_size(m)) return Vector{};
return Vector{m()};
}
#ifndef NEED_DOXYGEN_EXHALE_WORKAROUND
template <class T, IfTensorOfDim<T, 1>* = nullptr>
Vector to_vec(const T& m) {
return m;
}
template <class T, IfTensorOfDim<T, 2>* = nullptr>
Vector to_vec(const T& m) {
if (has_zero_size(m)) {
return Vector{};
} else if (m.shape()[0] == 1 && m.shape()[1] == 1) {
return Tensor<1>{m(0, 0)};
} else if (m.shape()[0] == 1 || m.shape()[1] == 1) {
return xt::squeeze(m);
}
// Combine data from all rows into one row
return xt::flatten(m);
}
template <class T, IfTensorOfDim<T, 3>* = nullptr>
Vector to_vec(const T& m) {
if (has_zero_size(m)) {
return Vector{};
} else if (m.shape()[0] == 1 && m.shape()[1] == 1 && m.shape()[2] == 1) {
return Tensor<1>{m(0, 0, 0)};
}
// if there is at least one dimmension that is not being used
if (m.shape()[0] == 1 || m.shape()[1] == 1 || m.shape()[2] == 1) {
auto squeezed = xt::squeeze(m);
if (squeezed.dimension() == 1) {
return squeezed;
} else if (squeezed.dimension() == 2) {
return xt::flatten(squeezed);
}
}
return xt::flatten(m);
}
template <typename T, IfEigenInterface<T>* = nullptr>
Vector to_vec(const T& m) {
// TODO: PNTOS-56 Instead, could attempt to block memory copy if we can determine memory layout
// of m
auto rows = m.rows();
auto cols = m.cols();
Vector out = xt::zeros<Scalar>({rows * cols});
for (decltype(rows) i = 0; i < rows; i++) {
for (decltype(cols) j = 0; j < cols; j++) {
out(i * cols + j) = m(i, j);
}
}
return out;
}
#endif
template <class T, IfTensorOfDim<T, 0>* = nullptr>
Matrix to_matrix(const T& m, std::size_t = 1) {
if (has_zero_size(m)) return Matrix{};
return Matrix{{m()}};
}
#ifndef NEED_DOXYGEN_EXHALE_WORKAROUND
template <class T, IfTensorOfDim<T, 1>* = nullptr>
Matrix to_matrix(const T& m, std::size_t axis = 1) {
return xt::expand_dims(m, axis);
}
template <class T, IfTensorOfDim<T, 2>* = nullptr>
Matrix to_matrix(const T& m, std::size_t = 1) {
return m;
}
template <class T, IfTensorOfDim<T, 3>* = nullptr>
Matrix to_matrix(const T& m, std::size_t axis = 1) {
if (has_zero_size(m)) {
return Matrix{};
}
if (m.shape()[0] == 1 && m.shape()[1] == 1 && m.shape()[2] == 1) {
return Tensor<2>{{m(0, 0, 0)}};
}
if (m.shape()[0] == 1 || m.shape()[1] == 1 || m.shape()[2] == 1) {
auto squeezed = xt::squeeze(m);
if (squeezed.dimension() == 1) {
return xt::expand_dims(squeezed, axis);
} else if (squeezed.dimension() == 2) {
return squeezed;
}
}
auto flattened = xt::flatten(m);
return xt::expand_dims(flattened, axis);
}
template <typename T, IfEigenInterface<T>* = nullptr>
Matrix to_matrix(const T& m, std::size_t = 1) {
// TODO: PNTOS-56 Instead, could attempt to block memory copy if we can determine memory layout
// of m
auto rows = m.rows();
auto cols = m.cols();
Matrix out = xt::zeros<Scalar>({rows, cols});
for (decltype(rows) i = 0; i < rows; i++) {
for (decltype(cols) j = 0; j < cols; j++) {
out(i, j) = m(i, j);
}
}
return out;
}
template <typename T, std::size_t rows, std::size_t cols>
Matrix to_matrix(T (&data)[rows][cols]) {
Matrix out = xt::zeros<Scalar>({rows, cols});
for (Size ii = 0; ii < rows; ++ii)
for (Size jj = 0; jj < cols; ++jj) out(ii, jj) = data[ii][jj];
return out;
}
#endif
Matrix eye(Size rows, Size cols, int diagonal_index = 0);
Matrix eye(Size size);
#ifndef NEED_DOXYGEN_EXHALE_WORKAROUND
template <typename... T>
Tensor<sizeof...(T)> zeros(T... dim) {
return xt::zeros<Scalar>({Size(dim)...});
}
template <typename... T>
Tensor<sizeof...(T)> fill(Scalar value, T... dim) {
return zeros(dim...) + value;
}
template <typename... T>
Tensor<sizeof...(T)> ones(T... dim) {
return xt::ones<Scalar>({Size(dim)...});
}
#endif
Matrix block_diag(std::initializer_list<Matrix> matrices);
template <typename... T>
Matrix block_diag(T&&... matrices) {
return block_diag({to_matrix(matrices, 0)...});
}
} // namespace navtk