282 const std::initializer_list<std::initializer_list<Scalar>>& list)
283 : m_diagonal(list) {}
286 EIGEN_DEVICE_FUNC
constexpr explicit inline DiagonalMatrix(DiagonalVectorType&& diag) : m_diagonal(std::move(diag)) {}
289 template <
typename OtherDerived>
293#ifndef EIGEN_PARSED_BY_DOXYGEN
302 template <
typename OtherDerived>
304 : m_diagonal(other) {}
307 template <
typename OtherDerived>
313#ifndef EIGEN_PARSED_BY_DOXYGEN
325 DiagonalVectorType::MaxSizeAtCompileTime == Dynamic &&
326 std::is_nothrow_move_assignable<DiagonalVectorType>::value) {
327 EIGEN_IF_CONSTEXPR (DiagonalVectorType::MaxSizeAtCompileTime == Dynamic) {
328 m_diagonal = std::move(other.m_diagonal);
331 m_diagonal = other.m_diagonal;
336 using InitializeReturnType =
339 using ZeroInitializeReturnType =
343 EIGEN_DEVICE_FUNC
static const ZeroInitializeReturnType
Zero() {
return DiagonalVectorType::Zero().asDiagonal(); }
346 return DiagonalVectorType::Zero(
size).asDiagonal();
349 EIGEN_DEVICE_FUNC
static const InitializeReturnType
Identity() {
return DiagonalVectorType::Ones().asDiagonal(); }
352 return DiagonalVectorType::Ones(
size).asDiagonal();
358 EIGEN_DEVICE_FUNC
inline void setZero() { m_diagonal.setZero(); }
362 EIGEN_DEVICE_FUNC
inline void setIdentity() { m_diagonal.setOnes(); }
382template <
typename DiagonalVectorType_>
383struct traits<DiagonalWrapper<DiagonalVectorType_>> {
384 using DiagonalVectorType = DiagonalVectorType_;
385 using Scalar =
typename DiagonalVectorType::Scalar;
386 using StorageIndex =
typename DiagonalVectorType::StorageIndex;
387 using StorageKind = DiagonalShape;
388 using XprKind =
typename traits<DiagonalVectorType>::XprKind;
390 RowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
391 ColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
392 MaxRowsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime,
393 MaxColsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime,
399template <
typename DiagonalVectorType_>
402#ifndef EIGEN_PARSED_BY_DOXYGEN
403 using DiagonalVectorType = DiagonalVectorType_;
408 EIGEN_DEVICE_FUNC
constexpr explicit inline DiagonalWrapper(DiagonalVectorType& a_diagonal)
409 : m_diagonal(a_diagonal) {}
412 EIGEN_DEVICE_FUNC
constexpr const DiagonalVectorType&
diagonal()
const {
return m_diagonal; }
415 typename DiagonalVectorType::Nested m_diagonal;
427template <
typename Derived>
440template <
typename Derived>
442 if (cols() != rows())
return false;
443 RealScalar maxAbsOnDiagonal =
static_cast<RealScalar
>(-1);
444 for (Index j = 0; j < cols(); ++j) {
445 RealScalar absOnDiagonal = numext::abs(coeff(j, j));
446 if (absOnDiagonal > maxAbsOnDiagonal) maxAbsOnDiagonal = absOnDiagonal;
448 for (Index j = 0; j < cols(); ++j)
449 for (Index i = 0; i < j; ++i) {
450 if (!internal::isMuchSmallerThan(coeff(i, j), maxAbsOnDiagonal, prec))
return false;
451 if (!internal::isMuchSmallerThan(coeff(j, i), maxAbsOnDiagonal, prec))
return false;
465template <
typename Derived>
466template <
int DiagIndex_>
470 DiagType diag(this->derived());
471 return ReturnType(diag);
475template <
typename Derived>
476template <
int DiagIndex_>
481 DiagType diag(this->derived());
482 return ReturnType(diag);
486template <
typename Derived>
491 DiagType diag(this->derived(), index);
492 return ReturnType(diag);
496template <
typename Derived>
501 DiagType diag(this->derived(), index);
502 return ReturnType(diag);
508struct storage_kind_to_shape<DiagonalShape> {
509 using Shape = DiagonalShape;
517template <
typename XprType>
518struct diagonal_matrix_evaluator : evaluator_base<XprType> {
519 using DiagonalVectorType =
typename XprType::DiagonalVectorType;
520 using Scalar =
typename XprType::Scalar;
521 using CoeffReturnType = Scalar;
523 static constexpr int CoeffReadCost =
524 int(evaluator<DiagonalVectorType>::CoeffReadCost) + int(NumTraits<Scalar>::AddCost);
525 static constexpr unsigned int Flags = 0;
526 static constexpr int Alignment = 0;
528 EIGEN_DEVICE_FUNC
explicit diagonal_matrix_evaluator(
const XprType& xpr) : m_diagonal(xpr.diagonal()) {
529 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
532 EIGEN_DEVICE_FUNC Scalar coeff(Index row, Index col)
const {
return row == col ? m_diagonal.coeff(row) : Scalar(0); }
535 EIGEN_DEVICE_FUNC Scalar coeff(Index index)
const {
536 eigen_assert(index == 0);
537 return m_diagonal.coeff(index);
541 evaluator<DiagonalVectorType> m_diagonal;
544template <
typename Scalar_,
int SizeAtCompileTime,
int MaxSizeAtCompileTime>
545struct evaluator<DiagonalMatrix<Scalar_, SizeAtCompileTime, MaxSizeAtCompileTime>>
546 : diagonal_matrix_evaluator<DiagonalMatrix<Scalar_, SizeAtCompileTime, MaxSizeAtCompileTime>> {
547 using XprType = DiagonalMatrix<Scalar_, SizeAtCompileTime, MaxSizeAtCompileTime>;
548 EIGEN_DEVICE_FUNC
explicit evaluator(
const XprType& xpr) : diagonal_matrix_evaluator<XprType>(xpr) {}
551template <
typename DiagonalVectorType_>
552struct evaluator<DiagonalWrapper<DiagonalVectorType_>>
553 : diagonal_matrix_evaluator<DiagonalWrapper<DiagonalVectorType_>> {
554 using XprType = DiagonalWrapper<DiagonalVectorType_>;
555 EIGEN_DEVICE_FUNC
explicit evaluator(
const XprType& xpr) : diagonal_matrix_evaluator<XprType>(xpr) {}
558struct Diagonal2Dense {};
561struct AssignmentKind<DenseShape, DiagonalShape> {
562 using Kind = Diagonal2Dense;
566template <
typename DstXprType,
typename SrcXprType,
typename Functor>
567struct Assignment<DstXprType, SrcXprType, Functor, Diagonal2Dense> {
568 static EIGEN_DEVICE_FUNC
void run(
569 DstXprType& dst,
const SrcXprType& src,
570 const internal::assign_op<typename DstXprType::Scalar, typename SrcXprType::Scalar>& ) {
571 Index dstRows = src.rows();
572 Index dstCols = src.cols();
573 if ((dst.rows() != dstRows) || (dst.cols() != dstCols)) dst.resize(dstRows, dstCols);
576 dst.diagonal() = src.diagonal();
579 static EIGEN_DEVICE_FUNC
void run(
580 DstXprType& dst,
const SrcXprType& src,
581 const internal::add_assign_op<typename DstXprType::Scalar, typename SrcXprType::Scalar>& ) {
582 dst.diagonal() += src.diagonal();
585 static EIGEN_DEVICE_FUNC
void run(
586 DstXprType& dst,
const SrcXprType& src,
587 const internal::sub_assign_op<typename DstXprType::Scalar, typename SrcXprType::Scalar>& ) {
588 dst.diagonal() -= src.diagonal();
600template <
typename Functor>
601struct additive_assign_sign : std::integral_constant<int, 0> {};
602template <
typename Scalar>
603struct additive_assign_sign<assign_op<Scalar, Scalar>> : std::integral_constant<int, 1> {};
604template <
typename Scalar>
605struct additive_assign_sign<add_assign_op<Scalar, Scalar>> : std::integral_constant<int, 1> {};
606template <
typename Scalar>
607struct additive_assign_sign<sub_assign_op<Scalar, Scalar>> : std::integral_constant<int, -1> {};
609template <
typename Functor>
610struct is_plain_assign : std::false_type {};
611template <
typename Scalar>
612struct is_plain_assign<assign_op<Scalar, Scalar>> : std::true_type {};
614template <
typename BinaryOp>
615struct is_additive_binary_op : std::false_type {};
616template <
typename Scalar>
617struct is_additive_binary_op<scalar_sum_op<Scalar, Scalar>> : std::true_type {};
618template <
typename Scalar>
619struct is_additive_binary_op<scalar_difference_op<Scalar, Scalar>> : std::true_type {};
622struct is_dense_shape : std::is_same<typename evaluator_traits<T>::Shape, DenseShape> {};
624struct is_diagonal_shape : std::is_same<typename evaluator_traits<T>::Shape, DiagonalShape> {};
626struct is_default_product : std::false_type {};
627template <
typename Lhs,
typename Rhs>
628struct is_default_product<Product<Lhs, Rhs, DefaultProduct>> : std::true_type {};
632struct is_permutation_dense_xpr : std::false_type {};
634template <
typename BinaryOp>
635struct is_difference_op : std::false_type {};
636template <
typename Scalar>
637struct is_difference_op<scalar_difference_op<Scalar, Scalar>> : std::true_type {};
642template <
typename Scalar,
typename Functor,
bool NegateDense>
643struct dense_block_pass_cannot_overflow
644 : bool_constant<!(NumTraits<Scalar>::IsInteger && std::numeric_limits<Scalar>::is_signed) ||
645 (is_plain_assign<Functor>::value && !NegateDense)> {};
648template <
typename Dst,
typename DenseXpr,
typename DiagonalXpr,
typename Functor,
bool NegateDense>
649struct dense_diagonal_sum_fast_path
650 : bool_constant<is_dense_shape<DenseXpr>::value && !is_permutation_dense_xpr<DenseXpr>::value &&
651 is_diagonal_shape<DiagonalXpr>::value && additive_assign_sign<Functor>::value != 0 &&
652 std::is_same<typename Dst::Scalar, typename DenseXpr::Scalar>::value &&
653 std::is_same<typename DenseXpr::Scalar, typename DiagonalXpr::Scalar>::value &&
654 dense_block_pass_cannot_overflow<typename Dst::Scalar, Functor, NegateDense>::value> {};
658template <
bool Assign,
int Sign>
659struct dense_block_update;
661struct dense_block_update<true, 1> {
662 template <
typename Block,
typename DenseBlock>
663 EIGEN_DEVICE_FUNC
static void run(Block&& block,
const DenseBlock& dense) {
668struct dense_block_update<true, -1> {
669 template <
typename Block,
typename DenseBlock>
670 EIGEN_DEVICE_FUNC
static void run(Block&& block,
const DenseBlock& dense) {
675struct dense_block_update<false, 1> {
676 template <
typename Block,
typename DenseBlock>
677 EIGEN_DEVICE_FUNC
static void run(Block&& block,
const DenseBlock& dense) {
682struct dense_block_update<false, -1> {
683 template <
typename Block,
typename DenseBlock>
684 EIGEN_DEVICE_FUNC
static void run(Block&& block,
const DenseBlock& dense) {
690template <
typename DiagonalXpr>
691struct diagonal_column_nonzeros {
692 using Scalar =
typename DiagonalXpr::Scalar;
693 EIGEN_DEVICE_FUNC
explicit diagonal_column_nonzeros(
const DiagonalXpr& diagonal) : m_diagonal(diagonal) {}
694 EIGEN_DEVICE_FUNC Index row(Index k)
const {
return k; }
695 EIGEN_DEVICE_FUNC Scalar value(Index k)
const {
return m_diagonal.coeff(k, k); }
696 evaluator<DiagonalXpr> m_diagonal;
701template <
bool Transpose>
702struct column_major_view {
703 template <
typename Xpr>
704 EIGEN_DEVICE_FUNC
static Xpr& run(Xpr& xpr) {
709struct column_major_view<true> {
710 template <
typename Xpr>
711 EIGEN_DEVICE_FUNC
static auto run(Xpr& xpr) {
712 return xpr.transpose();
721template <
bool DenseOnLeft>
722struct dense_structured_sum_assignment {
723 template <
typename Dst,
typename DenseXpr,
typename Structured,
typename BinaryOp,
typename Functor>
724 EIGEN_DEVICE_FUNC
static void run(Dst& dst,
const DenseXpr& dense,
const Structured& structured,
const BinaryOp& op,
725 const Functor& func) {
726 using Scalar =
typename Dst::Scalar;
727 constexpr bool kNegateDense = !DenseOnLeft && std::is_same<BinaryOp, scalar_difference_op<Scalar, Scalar>>::value;
728 constexpr int kSign = additive_assign_sign<Functor>::value * (kNegateDense ? -1 : 1);
729 constexpr Index kBlockColumns = 32;
730 using Update = dense_block_update<is_plain_assign<Functor>::value, kSign>;
731 const evaluator<DenseXpr> denseEval(dense);
732 Scalar values[kBlockColumns];
733 for (Index j = 0; j < dst.cols(); j += kBlockColumns) {
734 const Index columns = numext::mini(Index(kBlockColumns), dst.cols() - j);
735 for (Index k = 0; k < columns; ++k) {
736 const Index r = structured.row(j + k);
737 const Scalar s = structured.value(j + k);
738 const Scalar d = denseEval.coeff(r, j + k);
739 EIGEN_IF_CONSTEXPR (!is_plain_assign<Functor>::value) {
740 values[k] = dst.coeff(r, j + k);
742 func.assignCoeff(values[k], DenseOnLeft ? op(d, s) : op(s, d));
744 Update::run(dst.middleCols(j, columns), dense.middleCols(j, columns));
745 for (Index k = 0; k < columns; ++k) {
746 dst.coeffRef(structured.row(j + k), j + k) = values[k];
751 template <
typename Dst,
typename SrcXprType,
typename DenseXpr,
typename Structured,
typename Functor>
752 EIGEN_DEVICE_FUNC
static void assign(Dst& dst,
const SrcXprType& src,
const DenseXpr& denseXpr,
753 const Structured& structured,
const Functor& func) {
755 const typename nested_eval<DenseXpr, 1>::type dense(denseXpr);
756 resize_if_allowed(dst, src, func);
757 auto&& dstView = column_major_view<bool(Dst::IsRowMajor)>::run(dst);
758 run(dstView, column_major_view<
bool(Dst::IsRowMajor)>::run(dense), structured, src.functor(), func);
762template <
typename DstXprType,
typename BinaryOp,
typename Lhs,
typename Rhs,
typename Functor>
763struct Assignment<DstXprType, CwiseBinaryOp<BinaryOp, const Lhs, const Rhs>, Functor, Dense2Dense,
764 std::enable_if_t<is_additive_binary_op<BinaryOp>::value &&
765 dense_diagonal_sum_fast_path<DstXprType, Lhs, Rhs, Functor, false>::value>> {
766 using SrcXprType = CwiseBinaryOp<BinaryOp, const Lhs, const Rhs>;
767 EIGEN_DEVICE_FUNC
static void run(DstXprType& dst,
const SrcXprType& src,
const Functor& func) {
768 dense_structured_sum_assignment<true>::assign(dst, src, src.lhs(), diagonal_column_nonzeros<Rhs>(src.rhs()), func);
773template <
typename DstXprType,
typename BinaryOp,
typename Lhs,
typename Rhs,
typename Functor>
774struct Assignment<DstXprType, CwiseBinaryOp<BinaryOp, const Lhs, const Rhs>, Functor, Dense2Dense,
775 std::enable_if_t<is_additive_binary_op<BinaryOp>::value &&
776 dense_diagonal_sum_fast_path<DstXprType, Rhs, Lhs, Functor,
777 is_difference_op<BinaryOp>::value>::value &&
778 !is_default_product<Rhs>::value>> {
779 using SrcXprType = CwiseBinaryOp<BinaryOp, const Lhs, const Rhs>;
780 EIGEN_DEVICE_FUNC
static void run(DstXprType& dst,
const SrcXprType& src,
const Functor& func) {
781 dense_structured_sum_assignment<false>::assign(dst, src, src.rhs(), diagonal_column_nonzeros<Lhs>(src.lhs()), func);