chromium/third_party/eigen3/src/Eigen/src/Core/GeneralProduct.h

// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2006-2008 Benoit Jacob <[email protected]>
// Copyright (C) 2008-2011 Gael Guennebaud <[email protected]>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef EIGEN_GENERAL_PRODUCT_H
#define EIGEN_GENERAL_PRODUCT_H

// IWYU pragma: private
#include "./InternalHeaderCheck.h"

namespace Eigen {

enum {};

// Define the threshold value to fallback from the generic matrix-matrix product
// implementation (heavy) to the lightweight coeff-based product one.
// See generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,GemmProduct>
// in products/GeneralMatrixMatrix.h for more details.
// TODO This threshold should also be used in the compile-time selector below.
#ifndef EIGEN_GEMM_TO_COEFFBASED_THRESHOLD
// This default value has been obtained on a Haswell architecture.
#define EIGEN_GEMM_TO_COEFFBASED_THRESHOLD
#endif

namespace internal {

template <int Rows, int Cols, int Depth>
struct product_type_selector;

template <int Size, int MaxSize>
struct product_size_category {};

template <typename Lhs, typename Rhs>
struct product_type {};

/* The following allows to select the kind of product at compile time
 * based on the three dimensions of the product.
 * This is a compile time mapping from {1,Small,Large}^3 -> {product types} */
// FIXME I'm not sure the current mapping is the ideal one.
product_type_selector<M, N, 1>;
product_type_selector<M, 1, 1>;
product_type_selector<1, N, 1>;
product_type_selector<1, 1, Depth>;
template <>
struct product_type_selector<1, 1, 1> {};
template <>
struct product_type_selector<Small, 1, Small> {};
template <>
struct product_type_selector<1, Small, Small> {};
template <>
struct product_type_selector<Small, Small, Small> {};
template <>
struct product_type_selector<Small, Small, 1> {};
template <>
struct product_type_selector<Small, Large, 1> {};
template <>
struct product_type_selector<Large, Small, 1> {};
template <>
struct product_type_selector<1, Large, Small> {};
template <>
struct product_type_selector<1, Large, Large> {};
template <>
struct product_type_selector<1, Small, Large> {};
template <>
struct product_type_selector<Large, 1, Small> {};
template <>
struct product_type_selector<Large, 1, Large> {};
template <>
struct product_type_selector<Small, 1, Large> {};
template <>
struct product_type_selector<Small, Small, Large> {};
template <>
struct product_type_selector<Large, Small, Large> {};
template <>
struct product_type_selector<Small, Large, Large> {};
template <>
struct product_type_selector<Large, Large, Large> {};
template <>
struct product_type_selector<Large, Small, Small> {};
template <>
struct product_type_selector<Small, Large, Small> {};
template <>
struct product_type_selector<Large, Large, Small> {};

}  // end namespace internal

/***********************************************************************
 *  Implementation of Inner Vector Vector Product
 ***********************************************************************/

// FIXME : maybe the "inner product" could return a Scalar
// instead of a 1x1 matrix ??
// Pro: more natural for the user
// Cons: this could be a problem if in a meta unrolled algorithm a matrix-matrix
// product ends up to a row-vector times col-vector product... To tackle this use
// case, we could have a specialization for Block<MatrixType,1,1> with: operator=(Scalar x);

/***********************************************************************
 *  Implementation of Outer Vector Vector Product
 ***********************************************************************/

/***********************************************************************
 *  Implementation of General Matrix Vector Product
 ***********************************************************************/

/*  According to the shape/flags of the matrix we have to distinghish 3 different cases:
 *   1 - the matrix is col-major, BLAS compatible and M is large => call fast BLAS-like colmajor routine
 *   2 - the matrix is row-major, BLAS compatible and N is large => call fast BLAS-like rowmajor routine
 *   3 - all other cases are handled using a simple loop along the outer-storage direction.
 *  Therefore we need a lower level meta selector.
 *  Furthermore, if the matrix is the rhs, then the product has to be transposed.
 */
namespace internal {

template <int Side, int StorageOrder, bool BlasCompatible>
struct gemv_dense_selector;

}  // end namespace internal

namespace internal {

template <typename Scalar, int Size, int MaxSize, bool Cond>
struct gemv_static_vector_if;

gemv_static_vector_if<Scalar, Size, MaxSize, false>;

gemv_static_vector_if<Scalar, Size, Dynamic, true>;

gemv_static_vector_if<Scalar, Size, MaxSize, true>;

// The vector is on the left => transposition
gemv_dense_selector<OnTheLeft, StorageOrder, BlasCompatible>;

template <>
struct gemv_dense_selector<OnTheRight, ColMajor, true> {};

template <>
struct gemv_dense_selector<OnTheRight, RowMajor, true> {};

template <>
struct gemv_dense_selector<OnTheRight, ColMajor, false> {};

template <>
struct gemv_dense_selector<OnTheRight, RowMajor, false> {};

}  // end namespace internal

/***************************************************************************
 * Implementation of matrix base methods
 ***************************************************************************/

/** \returns the matrix product of \c *this and \a other.
 *
 * \note If instead of the matrix product you want the coefficient-wise product, see Cwise::operator*().
 *
 * \sa lazyProduct(), operator*=(const MatrixBase&), Cwise::operator*()
 */
template <typename Derived>
template <typename OtherDerived>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Product<Derived, OtherDerived> MatrixBase<Derived>::operator*(
    const MatrixBase<OtherDerived>& other) const {}

/** \returns an expression of the matrix product of \c *this and \a other without implicit evaluation.
 *
 * The returned product will behave like any other expressions: the coefficients of the product will be
 * computed once at a time as requested. This might be useful in some extremely rare cases when only
 * a small and no coherent fraction of the result's coefficients have to be computed.
 *
 * \warning This version of the matrix product can be much much slower. So use it only if you know
 * what you are doing and that you measured a true speed improvement.
 *
 * \sa operator*(const MatrixBase&)
 */
template <typename Derived>
template <typename OtherDerived>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Product<Derived, OtherDerived, LazyProduct>
MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived>& other) const {}

}  // end namespace Eigen

#endif  // EIGEN_PRODUCT_H