// 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/.
// SPDX-License-Identifier: MPL-2.0

#ifndef EIGEN_SPARSE_DOT_H
#define EIGEN_SPARSE_DOT_H

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

namespace Eigen {

template <typename Derived>
template <typename OtherDerived>
inline typename internal::traits<Derived>::Scalar SparseMatrixBase<Derived>::dot(
    const MatrixBase<OtherDerived>& other) const {
  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
  EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
  EIGEN_STATIC_ASSERT(
      (std::is_same<Scalar, typename OtherDerived::Scalar>::value),
      YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)

  EIGEN_INTERNAL_ASSERT_SAME_SIZE(*this, other);
  if (size() == 0) return Scalar(0);

  internal::evaluator<Derived> thisEval(derived());
  typename internal::evaluator<Derived>::InnerIterator i(thisEval, 0);
  // Two accumulators, which breaks the dependency chain on the accumulator
  // and allows more instruction-level parallelism in the following loop.
  Scalar res1(0);
  Scalar res2(0);
  for (; i; ++i) {
    res1 = numext::madd<Scalar>(numext::conj(i.value()), other.coeff(i.index()), res1);
    ++i;
    if (i) {
      res2 = numext::madd<Scalar>(numext::conj(i.value()), other.coeff(i.index()), res2);
    }
  }
  return res1 + res2;
}

template <typename Derived>
template <typename OtherDerived>
inline typename internal::traits<Derived>::Scalar SparseMatrixBase<Derived>::dot(
    const SparseMatrixBase<OtherDerived>& other) const {
  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
  EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
  EIGEN_STATIC_ASSERT(
      (std::is_same<Scalar, typename OtherDerived::Scalar>::value),
      YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)

  EIGEN_INTERNAL_ASSERT_SAME_SIZE(*this, other);
  if (size() == 0) return Scalar(0);

  internal::evaluator<Derived> thisEval(derived());
  typename internal::evaluator<Derived>::InnerIterator i(thisEval, 0);

  internal::evaluator<OtherDerived> otherEval(other.derived());
  typename internal::evaluator<OtherDerived>::InnerIterator j(otherEval, 0);

  Scalar res(0);
  while (i && j) {
    if (i.index() == j.index()) {
      res = numext::madd<Scalar>(numext::conj(i.value()), j.value(), res);
      ++i;
      ++j;
    } else if (i.index() < j.index())
      ++i;
    else
      ++j;
  }
  return res;
}

template <typename Derived>
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real SparseMatrixBase<Derived>::squaredNorm()
    const {
  return numext::real((*this).cwiseAbs2().sum());
}

template <typename Derived>
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real SparseMatrixBase<Derived>::norm() const {
  using std::sqrt;
  return sqrt(squaredNorm());
}

template <typename Derived>
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real SparseMatrixBase<Derived>::blueNorm()
    const {
  // blueNorm_impl walks Derived::InnerIterator, which only storage types provide.
  return internal::blueNorm_impl(Ref<const PlainObject>(derived()));
}
}  // end namespace Eigen

#endif  // EIGEN_SPARSE_DOT_H
