// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// 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_RANDOM_H
#define EIGEN_RANDOM_H

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

namespace Eigen {

namespace internal {

template <typename Scalar>
struct scalar_random_op {
  inline Scalar operator()() const { return random<Scalar>(); }
};

template <typename Scalar>
struct functor_traits<scalar_random_op<Scalar> > {
  enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false, IsRepeatable = false };
};

}  // end namespace internal

/** \returns a random matrix expression
 *
 * Numbers are uniformly spread through their whole definition range for integer types,
 * and in the [-1:1] range for floating point scalar types.
 *
 * The parameters \a rows and \a cols are the number of rows and of columns of
 * the returned matrix. Must be compatible with this MatrixBase type.
 *
 * \not_reentrant
 *
 * This variant is meant to be used for dynamic-size matrix types. For fixed-size types,
 * it is redundant to pass \a rows and \a cols as arguments, so Random() should be used
 * instead.
 *
 *
 * Example: \include MatrixBase_random_int_int.cpp
 * Output: \verbinclude MatrixBase_random_int_int.out
 *
 * This expression has the "evaluate before nesting" flag so that it will be evaluated into
 * a temporary matrix whenever it is nested in a larger expression. This prevents unexpected
 * behavior with expressions involving random matrices.
 *
 * See DenseBase::NullaryExpr(Index, const CustomNullaryOp&) for an example using std random generators.
 *
 * \sa DenseBase::setRandom(), DenseBase::Random(Index), DenseBase::Random()
 */
template <typename Derived>
inline const typename DenseBase<Derived>::RandomReturnType DenseBase<Derived>::Random(Index rows, Index cols) {
  return NullaryExpr(rows, cols, internal::scalar_random_op<Scalar>());
}

/** \returns a random vector expression
 *
 * Numbers are uniformly spread through their whole definition range for integer types,
 * and in the [-1:1] range for floating point scalar types.
 *
 * The parameter \a size is the size of the returned vector.
 * Must be compatible with this MatrixBase type.
 *
 * \only_for_vectors
 * \not_reentrant
 *
 * This variant is meant to be used for dynamic-size vector types. For fixed-size types,
 * it is redundant to pass \a size as argument, so Random() should be used
 * instead.
 *
 * Example: \include MatrixBase_random_int.cpp
 * Output: \verbinclude MatrixBase_random_int.out
 *
 * This expression has the "evaluate before nesting" flag so that it will be evaluated into
 * a temporary vector whenever it is nested in a larger expression. This prevents unexpected
 * behavior with expressions involving random matrices.
 *
 * \sa DenseBase::setRandom(), DenseBase::Random(Index,Index), DenseBase::Random()
 */
template <typename Derived>
inline const typename DenseBase<Derived>::RandomReturnType DenseBase<Derived>::Random(Index size) {
  return NullaryExpr(size, internal::scalar_random_op<Scalar>());
}

/** \returns a fixed-size random matrix or vector expression
 *
 * Numbers are uniformly spread through their whole definition range for integer types,
 * and in the [-1:1] range for floating point scalar types.
 *
 * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you
 * need to use the variants taking size arguments.
 *
 * Example: \include MatrixBase_random.cpp
 * Output: \verbinclude MatrixBase_random.out
 *
 * This expression has the "evaluate before nesting" flag so that it will be evaluated into
 * a temporary matrix whenever it is nested in a larger expression. This prevents unexpected
 * behavior with expressions involving random matrices.
 *
 * \not_reentrant
 *
 * \sa DenseBase::setRandom(), DenseBase::Random(Index,Index), DenseBase::Random(Index)
 */
template <typename Derived>
inline const typename DenseBase<Derived>::RandomReturnType DenseBase<Derived>::Random() {
  return NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, internal::scalar_random_op<Scalar>());
}

/** Sets all coefficients in this expression to random values.
 *
 * Numbers are uniformly spread through their whole definition range for integer types,
 * and in the [-1:1] range for floating point scalar types.
 *
 * \not_reentrant
 *
 * Example: \include MatrixBase_setRandom.cpp
 * Output: \verbinclude MatrixBase_setRandom.out
 *
 * \sa class CwiseNullaryOp, setRandom(Index), setRandom(Index,Index)
 */
template <typename Derived>
EIGEN_DEVICE_FUNC inline Derived& DenseBase<Derived>::setRandom() {
  return *this = Random(rows(), cols());
}

/** Resizes to the given \a newSize, and sets all coefficients in this expression to random values.
 *
 * Numbers are uniformly spread through their whole definition range for integer types,
 * and in the [-1:1] range for floating point scalar types.
 *
 * \only_for_vectors
 * \not_reentrant
 *
 * Example: \include Matrix_setRandom_int.cpp
 * Output: \verbinclude Matrix_setRandom_int.out
 *
 * \sa DenseBase::setRandom(), setRandom(Index,Index), class CwiseNullaryOp, DenseBase::Random()
 */
template <typename Derived>
EIGEN_STRONG_INLINE Derived& PlainObjectBase<Derived>::setRandom(Index newSize) {
  resize(newSize);
  return setRandom();
}

/** Resizes to the given size, and sets all coefficients in this expression to random values.
 *
 * Numbers are uniformly spread through their whole definition range for integer types,
 * and in the [-1:1] range for floating point scalar types.
 *
 * \not_reentrant
 *
 * \param rows the new number of rows
 * \param cols the new number of columns
 *
 * Example: \include Matrix_setRandom_int_int.cpp
 * Output: \verbinclude Matrix_setRandom_int_int.out
 *
 * \sa DenseBase::setRandom(), setRandom(Index), class CwiseNullaryOp, DenseBase::Random()
 */
template <typename Derived>
EIGEN_STRONG_INLINE Derived& PlainObjectBase<Derived>::setRandom(Index rows, Index cols) {
  resize(rows, cols);
  return setRandom();
}

/** Resizes to the given size, changing only the number of columns, and sets all
 * coefficients in this expression to random values. For the parameter of type
 * NoChange_t, just pass the special value \c NoChange.
 *
 * Numbers are uniformly spread through their whole definition range for integer types,
 * and in the [-1:1] range for floating point scalar types.
 *
 * \not_reentrant
 *
 * \sa DenseBase::setRandom(), setRandom(Index), setRandom(Index, NoChange_t), class CwiseNullaryOp, DenseBase::Random()
 */
template <typename Derived>
EIGEN_STRONG_INLINE Derived& PlainObjectBase<Derived>::setRandom(NoChange_t, Index cols) {
  return setRandom(rows(), cols);
}

/** Resizes to the given size, changing only the number of rows, and sets all
 * coefficients in this expression to random values. For the parameter of type
 * NoChange_t, just pass the special value \c NoChange.
 *
 * Numbers are uniformly spread through their whole definition range for integer types,
 * and in the [-1:1] range for floating point scalar types.
 *
 * \not_reentrant
 *
 * \sa DenseBase::setRandom(), setRandom(Index), setRandom(NoChange_t, Index), class CwiseNullaryOp, DenseBase::Random()
 */
template <typename Derived>
EIGEN_STRONG_INLINE Derived& PlainObjectBase<Derived>::setRandom(Index rows, NoChange_t) {
  return setRandom(rows, cols());
}

}  // end namespace Eigen

#endif  // EIGEN_RANDOM_H
