include/maths/common/CTypeTraits.h (215 lines of code) (raw):
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the following additional limitation. Functionality enabled by the
* files subject to the Elastic License 2.0 may only be used in production when
* invoked by an Elasticsearch process with a license key installed that permits
* use of machine learning features. You may not use this file except in
* compliance with the Elastic License 2.0 and the foregoing additional
* limitation.
*/
#ifndef INCLUDED_ml_maths_common_CTypeTraits_h
#define INCLUDED_ml_maths_common_CTypeTraits_h
#include <maths/common/CLinearAlgebraFwd.h>
#include <maths/common/MathsTypes.h>
#include <type_traits>
namespace ml {
namespace maths {
namespace common {
//! \brief Defines the promoted type.
template<typename T>
struct SPromoted {
using Type = T;
};
//! \brief Defines the promoted type for float.
template<>
struct SPromoted<float> {
using Type = double;
};
//! \brief Defines the promoted type for CFloatStorage.
template<>
struct SPromoted<CFloatStorage> {
using Type = double;
};
//! \brief Defines the promoted type for a CVectorNx1.
template<typename T, std::size_t N>
struct SPromoted<CVectorNx1<T, N>> {
using Type = CVectorNx1<typename SPromoted<T>::Type, N>;
};
//! \brief Defines the promoted type for a CVector.
template<typename T>
struct SPromoted<CVector<T>> {
using Type = CVector<typename SPromoted<T>::Type>;
};
//! \brief Defines the promoted type for a CSymmetricMatrixNxN.
template<typename T, std::size_t N>
struct SPromoted<CSymmetricMatrixNxN<T, N>> {
using Type = CSymmetricMatrixNxN<typename SPromoted<T>::Type, N>;
};
//! \brief Defines the promoted type for a CSymmetricMatrix.
template<typename T>
struct SPromoted<CSymmetricMatrix<T>> {
using Type = CSymmetricMatrix<typename SPromoted<T>::Type>;
};
//! \brief Defines the promoted type for an Eigen dense matrix.
template<typename SCALAR>
struct SPromoted<CDenseMatrix<SCALAR>> {
using Type = CDenseMatrix<typename SPromoted<SCALAR>::Type>;
};
//! \brief Defines the promoted type for an Eigen dense vector.
template<typename SCALAR>
struct SPromoted<CDenseVector<SCALAR>> {
using Type = CDenseVector<typename SPromoted<SCALAR>::Type>;
};
//! \brief Defines the promoted type for an Eigen memory mapped matrix.
template<typename SCALAR, Eigen::AlignmentType ALIGNMENT>
struct SPromoted<CMemoryMappedDenseMatrix<SCALAR, ALIGNMENT>> {
using Type = CDenseMatrix<typename SPromoted<SCALAR>::Type>;
};
//! \brief Defines the promoted type for an Eigen memory mapped vector.
template<typename SCALAR, Eigen::AlignmentType ALIGNMENT>
struct SPromoted<CMemoryMappedDenseVector<SCALAR, ALIGNMENT>> {
using Type = CDenseVector<typename SPromoted<SCALAR>::Type>;
};
//! \brief Defines the promoted type for an Eigen sparse matrix.
template<typename SCALAR, int FLAGS, typename STORAGE_INDEX>
struct SPromoted<Eigen::SparseMatrix<SCALAR, FLAGS, STORAGE_INDEX>> {
using Type = Eigen::SparseMatrix<typename SPromoted<SCALAR>::Type, FLAGS, STORAGE_INDEX>;
};
//! \brief Defines the promoted type for an Eigen sparse vector.
template<typename SCALAR, int FLAGS, typename STORAGE_INDEX>
struct SPromoted<Eigen::SparseVector<SCALAR, FLAGS, STORAGE_INDEX>> {
using Type = Eigen::SparseVector<typename SPromoted<SCALAR>::Type, FLAGS, STORAGE_INDEX>;
};
//! \brief Defines the promoted type for a CAnnotatedVector.
template<typename VECTOR, typename ANNOTATION>
struct SPromoted<CAnnotatedVector<VECTOR, ANNOTATION>> {
using Type = CAnnotatedVector<typename SPromoted<VECTOR>::Type, ANNOTATION>;
};
//! \brief Defines a suitable floating point type.
template<typename T, typename U>
struct SFloatingPoint {
using Type = typename std::conditional<std::is_floating_point<T>::value, T, U>::type;
};
//! \brief Defines CVectorNx1 on a suitable floating point type.
template<typename T, std::size_t N, typename U>
struct SFloatingPoint<CVectorNx1<T, N>, U> {
using Type = CVectorNx1<typename SFloatingPoint<T, U>::Type, N>;
};
//! \brief Defines CVector on a suitable floating point type.
template<typename T, typename U>
struct SFloatingPoint<CVector<T>, U> {
using Type = CVector<typename SFloatingPoint<T, U>::Type>;
};
//! \brief Defines CSymmetricMatrixNxN on a suitable floating point type.
template<typename T, std::size_t N, typename U>
struct SFloatingPoint<CSymmetricMatrixNxN<T, N>, U> {
using Type = CSymmetricMatrixNxN<typename SFloatingPoint<T, U>::Type, N>;
};
//! \brief Defines CSymmetricMatrix on a suitable floating point type.
template<typename T, typename U>
struct SFloatingPoint<CSymmetricMatrix<T>, U> {
using Type = CSymmetricMatrix<typename SFloatingPoint<T, U>::Type>;
};
//! \brief Defines an Eigen dense matrix on a suitable floating point type.
template<typename SCALAR, typename U>
struct SFloatingPoint<CDenseMatrix<SCALAR>, U> {
using Type = CDenseMatrix<typename SFloatingPoint<SCALAR, U>::Type>;
};
//! \brief Defines an Eigen dense vector on a suitable floating point type.
template<typename SCALAR, typename U>
struct SFloatingPoint<CDenseVector<SCALAR>, U> {
using Type = CDenseVector<typename SFloatingPoint<SCALAR, U>::Type>;
};
//! \brief Defines an Eigen dense matrix on a suitable floating point type.
template<typename SCALAR, Eigen::AlignmentType ALIGNMENT, typename U>
struct SFloatingPoint<CMemoryMappedDenseMatrix<SCALAR, ALIGNMENT>, U> {
using Type = CDenseMatrix<typename SFloatingPoint<SCALAR, U>::Type>;
};
//! \brief Defines an Eigen dense vector on a suitable floating point type.
template<typename SCALAR, Eigen::AlignmentType ALIGNMENT, typename U>
struct SFloatingPoint<CMemoryMappedDenseVector<SCALAR, ALIGNMENT>, U> {
using Type = CDenseVector<typename SFloatingPoint<SCALAR, U>::Type>;
};
//! \brief Defines an Eigen sparse matrix on a suitable floating point type.
template<typename SCALAR, int FLAGS, typename STORAGE_INDEX, typename U>
struct SFloatingPoint<Eigen::SparseMatrix<SCALAR, FLAGS, STORAGE_INDEX>, U> {
using Type = Eigen::SparseMatrix<typename SFloatingPoint<SCALAR, U>::Type, FLAGS, STORAGE_INDEX>;
};
//! \brief Defines an Eigen sparse vector on a suitable floating point type.
template<typename SCALAR, int FLAGS, typename STORAGE_INDEX, typename U>
struct SFloatingPoint<Eigen::SparseVector<SCALAR, FLAGS, STORAGE_INDEX>, U> {
using Type = Eigen::SparseVector<typename SFloatingPoint<SCALAR, U>::Type, FLAGS, STORAGE_INDEX>;
};
//! \brief Defines CAnnotatedVector on a suitable floating point type.
template<typename VECTOR, typename ANNOTATION, typename U>
struct SFloatingPoint<CAnnotatedVector<VECTOR, ANNOTATION>, U> {
using Type = CAnnotatedVector<typename SFloatingPoint<VECTOR, U>::Type, ANNOTATION>;
};
//! \brief Extracts the coordinate type for a vector or matrix.
template<typename T>
struct SCoordinate {
using Type = T;
};
//! \brief Extracts the coordinate type for CVectorNx1.
template<typename T, std::size_t N>
struct SCoordinate<CVectorNx1<T, N>> {
using Type = T;
};
//! \brief Extracts the coordinate type for CVector.
template<typename T>
struct SCoordinate<CVector<T>> {
using Type = T;
};
//! \brief Extracts the coordinate type for CSymmetricMatrixNxN.
template<typename T, std::size_t N>
struct SCoordinate<CSymmetricMatrixNxN<T, N>> {
using Type = T;
};
//! \brief Extracts the coordinate type for CSymmetricMatrix.
template<typename T>
struct SCoordinate<CSymmetricMatrix<T>> {
using Type = T;
};
//! \brief Extracts the coordinate type for an Eigen dense matrix.
template<typename SCALAR>
struct SCoordinate<CDenseMatrix<SCALAR>> {
using Type = SCALAR;
};
//! \brief Extracts the coordinate type for an Eigen dense vector.
template<typename SCALAR>
struct SCoordinate<CDenseVector<SCALAR>> {
using Type = SCALAR;
};
//! \brief Extracts the coordinate type for an Eigen memory mapped matrix.
template<typename SCALAR, Eigen::AlignmentType ALIGNMENT>
struct SCoordinate<CMemoryMappedDenseMatrix<SCALAR, ALIGNMENT>> {
using Type = SCALAR;
};
//! \brief Extracts the coordinate type for an Eigen memory mapped vector.
template<typename SCALAR, Eigen::AlignmentType ALIGNMENT>
struct SCoordinate<CMemoryMappedDenseVector<SCALAR, ALIGNMENT>> {
using Type = SCALAR;
};
//! \brief Extracts the coordinate type for an Eigen sparse matrix.
template<typename SCALAR, int FLAGS, typename STORAGE_INDEX>
struct SCoordinate<Eigen::SparseMatrix<SCALAR, FLAGS, STORAGE_INDEX>> {
using Type = SCALAR;
};
//! \brief Extracts the coordinate type for an Eigen sparse vector.
template<typename SCALAR, int FLAGS, typename STORAGE_INDEX>
struct SCoordinate<Eigen::SparseVector<SCALAR, FLAGS, STORAGE_INDEX>> {
using Type = SCALAR;
};
//! \brief Extracts the coordinate type for the underlying vector type.
template<typename VECTOR, typename ANNOTATION>
struct SCoordinate<CAnnotatedVector<VECTOR, ANNOTATION>> {
using Type = typename SCoordinate<VECTOR>::Type;
};
//! \brief Extracts the conformable matrix type for a vector.
template<typename VECTOR>
struct SConformableMatrix {
static_assert(sizeof(VECTOR) < 0, "No conformable matrix type defined");
};
//! \brief Extracts the conformable matrix type for a CVectorNx1.
template<typename T, std::size_t N>
struct SConformableMatrix<CVectorNx1<T, N>> {
using Type = CSymmetricMatrixNxN<T, N>;
};
//! \brief Extracts the conformable matrix type for a CVector.
template<typename T>
struct SConformableMatrix<CVector<T>> {
using Type = CSymmetricMatrix<T>;
};
//! \brief Extracts the conformable matrix type for an Eigen dense vector.
template<typename SCALAR>
struct SConformableMatrix<CDenseVector<SCALAR>> {
using Type = CDenseMatrix<SCALAR>;
};
//! \brief Extracts the conformable matrix type for an Eigen memory mapped vector.
template<typename SCALAR, Eigen::AlignmentType ALIGNMENT>
struct SConformableMatrix<CMemoryMappedDenseVector<SCALAR, ALIGNMENT>> {
using Type = CMemoryMappedDenseMatrix<SCALAR, ALIGNMENT>;
};
//! \brief Extracts the conformable matrix type for an Eigen sparse vector.
template<typename SCALAR, int FLAGS, typename STORAGE_INDEX>
struct SConformableMatrix<Eigen::SparseVector<SCALAR, FLAGS, STORAGE_INDEX>> {
using Type = Eigen::SparseMatrix<SCALAR, FLAGS, STORAGE_INDEX>;
};
//! \brief Extracts the conformable matrix type for the underlying vector type.
template<typename VECTOR, typename ANNOTATION>
struct SConformableMatrix<CAnnotatedVector<VECTOR, ANNOTATION>> {
using Type = typename SConformableMatrix<VECTOR>::Type;
};
//! \brief Defines the type of a singular value decomposition of a matrix.
template<typename MATRIX>
struct SJacobiSvd {
static_assert(sizeof(MATRIX) < 0, "SVD not supported for type");
};
//! \brief Defines the type of a singular value decomposition of our decorator
//! of an Eigen dense matrix.
template<typename SCALAR>
struct SJacobiSvd<CDenseMatrix<SCALAR>> {
using Type =
Eigen::JacobiSVD<Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic, 0, Eigen::Dynamic, Eigen::Dynamic>,
Eigen::ColPivHouseholderQRPreconditioner>;
};
//! \brief Defines the type of a singular value decomposition an Eigen dense matrix.
template<typename SCALAR, int ROWS, int COLS, int OPTIONS, int MAX_ROWS, int MAX_COLS>
struct SJacobiSvd<Eigen::Matrix<SCALAR, ROWS, COLS, OPTIONS, MAX_ROWS, MAX_COLS>> {
using Type =
Eigen::JacobiSVD<Eigen::Matrix<SCALAR, ROWS, COLS, OPTIONS, MAX_ROWS, MAX_COLS>, Eigen::ColPivHouseholderQRPreconditioner>;
};
//! \brief Defines a type which strips off any annotation from a vector.
//! This is the raw vector type by default.
template<typename VECTOR>
struct SUnannotated {
using Type = VECTOR;
};
//! \brief Specialisation for annotated vectors. This is the underlying
//! vector type.
template<typename VECTOR, typename ANNOTATION>
struct SUnannotated<CAnnotatedVector<VECTOR, ANNOTATION>> {
using Type = VECTOR;
};
}
}
}
#endif // INCLUDED_ml_maths_common_CTypeTraits_h