// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2011 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/.

#include "sparse.h"

template<typename Scalar,typename StorageIndex> void sparse_vector(int rows, int cols)
{
  double densityMat = (std::max)(8./(rows*cols), 0.01);
  double densityVec = (std::max)(8./(rows), 0.1);
  typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;
  typedef Matrix<Scalar,Dynamic,1> DenseVector;
  typedef Matrix<DenseIndex,Dynamic,1> DenseIndexVector;
  typedef SparseVector<Scalar,0,StorageIndex> SparseVectorType;
  typedef SparseMatrix<Scalar,0,StorageIndex> SparseMatrixType;
  Scalar eps = 1e-6;

  SparseMatrixType m1(rows,rows);
  SparseVectorType v1(rows), v2(rows), v3(rows);
  DenseMatrix refM1 = DenseMatrix::Zero(rows, rows);
  DenseVector refV1 = DenseVector::Random(rows),
              refV2 = DenseVector::Random(rows),
              refV3 = DenseVector::Random(rows);

  std::vector<int> zerocoords, nonzerocoords;
  initSparse<Scalar>(densityVec, refV1, v1, &zerocoords, &nonzerocoords);
  initSparse<Scalar>(densityMat, refM1, m1);

  initSparse<Scalar>(densityVec, refV2, v2);
  initSparse<Scalar>(densityVec, refV3, v3);

  Scalar s1 = internal::random<Scalar>();

  // test coeff and coeffRef
  for (unsigned int i=0; i<zerocoords.size(); ++i)
  {
    VERIFY_IS_MUCH_SMALLER_THAN( v1.coeff(zerocoords[i]), eps );
    //VERIFY_RAISES_ASSERT( v1.coeffRef(zerocoords[i]) = 5 );
  }
  {
    VERIFY(int(nonzerocoords.size()) == v1.nonZeros());
    int j=0;
    for (typename SparseVectorType::InnerIterator it(v1); it; ++it,++j)
    {
      VERIFY(nonzerocoords[j]==it.index());
      VERIFY_IS_EQUAL(it.value(), v1.coeff(it.index()));
      VERIFY_IS_EQUAL(it.value(), refV1.coeff(it.index()));
    }
  }
  VERIFY_IS_APPROX(v1, refV1);
  
  // test coeffRef with reallocation
  {
    SparseVectorType v4(rows);
    DenseVector v5 = DenseVector::Zero(rows);
    for(int k=0; k<rows; ++k)
    {
      int i = internal::random<int>(0,rows-1);
      Scalar v = internal::random<Scalar>();
      v4.coeffRef(i) += v;
      v5.coeffRef(i) += v;
    }
    VERIFY_IS_APPROX(v4,v5);
  }

  v1.coeffRef(nonzerocoords[0]) = Scalar(5);
  refV1.coeffRef(nonzerocoords[0]) = Scalar(5);
  VERIFY_IS_APPROX(v1, refV1);

  VERIFY_IS_APPROX(v1+v2, refV1+refV2);
  VERIFY_IS_APPROX(v1+v2+v3, refV1+refV2+refV3);

  VERIFY_IS_APPROX(v1*s1-v2, refV1*s1-refV2);

  VERIFY_IS_APPROX(v1*=s1, refV1*=s1);
  VERIFY_IS_APPROX(v1/=s1, refV1/=s1);

  VERIFY_IS_APPROX(v1+=v2, refV1+=refV2);
  VERIFY_IS_APPROX(v1-=v2, refV1-=refV2);

  VERIFY_IS_APPROX(v1.dot(v2), refV1.dot(refV2));
  VERIFY_IS_APPROX(v1.dot(refV2), refV1.dot(refV2));

  VERIFY_IS_APPROX(m1*v2, refM1*refV2);
  VERIFY_IS_APPROX(v1.dot(m1*v2), refV1.dot(refM1*refV2));
  {
    int i = internal::random<int>(0,rows-1);
    VERIFY_IS_APPROX(v1.dot(m1.col(i)), refV1.dot(refM1.col(i)));
  }


  VERIFY_IS_APPROX(v1.squaredNorm(), refV1.squaredNorm());
  
  VERIFY_IS_APPROX(v1.blueNorm(), refV1.blueNorm());

  // test aliasing
  VERIFY_IS_APPROX((v1 = -v1), (refV1 = -refV1));
  VERIFY_IS_APPROX((v1 = v1.transpose()), (refV1 = refV1.transpose().eval()));
  VERIFY_IS_APPROX((v1 += -v1), (refV1 += -refV1));
  
  // sparse matrix to sparse vector
  SparseMatrixType mv1;
  VERIFY_IS_APPROX((mv1=v1),v1);
  VERIFY_IS_APPROX(mv1,(v1=mv1));
  VERIFY_IS_APPROX(mv1,(v1=mv1.transpose()));
  
  // check copy to dense vector with transpose
  refV3.resize(0);
  VERIFY_IS_APPROX(refV3 = v1.transpose(),v1.toDense()); 
  VERIFY_IS_APPROX(DenseVector(v1),v1.toDense());

  // test conservative resize
  {
    std::vector<StorageIndex> inc;
    if(rows > 3)
      inc.push_back(-3);
    inc.push_back(0);
    inc.push_back(3);
    inc.push_back(1);
    inc.push_back(10);

    for(std::size_t i = 0; i< inc.size(); i++) {
      StorageIndex incRows = inc[i];
      SparseVectorType vec1(rows);
      DenseVector refVec1 = DenseVector::Zero(rows);
      initSparse<Scalar>(densityVec, refVec1, vec1);

      vec1.conservativeResize(rows+incRows);
      refVec1.conservativeResize(rows+incRows);
      if (incRows > 0) refVec1.tail(incRows).setZero();

      VERIFY_IS_APPROX(vec1, refVec1);

      // Insert new values
      if (incRows > 0)
        vec1.insert(vec1.rows()-1) = refVec1(refVec1.rows()-1) = 1;

      VERIFY_IS_APPROX(vec1, refVec1);
    }
  }

  // test sort
  if(rows > 1)
  {
    SparseVectorType vec1(rows);
    DenseVector refVec1 = DenseVector::Zero(rows);
    DenseIndexVector innerIndices(rows);
    innerIndices.setLinSpaced(0, rows - 1);
    std::random_device rd;
    std::mt19937 g(rd());
    std::shuffle(innerIndices.begin(), innerIndices.end(), g);
    Index nz = internal::random<Index>(2, rows / 2);
    for (Index k = 0; k < nz; k++)
    {
        Index i = innerIndices[k];
        Scalar val = internal::random<Scalar>();
        refVec1.coeffRef(i) = val;
        vec1.insert(i) = val;
    }

    vec1.template sortInnerIndices<std::greater<>>();
    VERIFY_IS_APPROX(vec1, refVec1);
    VERIFY_IS_EQUAL(vec1.template innerIndicesAreSorted<std::greater<>>(), 1);
    VERIFY_IS_EQUAL(vec1.template innerIndicesAreSorted<std::less<>>(), 0);
    vec1.template sortInnerIndices<std::less<>>();
    VERIFY_IS_APPROX(vec1, refVec1);
    VERIFY_IS_EQUAL(vec1.template innerIndicesAreSorted<std::greater<>>(), 0);
    VERIFY_IS_EQUAL(vec1.template innerIndicesAreSorted<std::less<>>(), 1);
  }

}
void test_pruning() {
    using SparseVectorType = SparseVector<double, 0, int>;

    SparseVectorType vec;
    auto init_vec = [&](){;
        vec.resize(10);
        vec.insert(3) = 0.1;
        vec.insert(5) = 1.0;
        vec.insert(8) = -0.1;
        vec.insert(9) = -0.2;
    };
    init_vec();

    VERIFY_IS_EQUAL(vec.nonZeros(), 4);
    VERIFY_IS_EQUAL(vec.prune(0.1, 1.0), 2);
    VERIFY_IS_EQUAL(vec.nonZeros(), 2);
    VERIFY_IS_EQUAL(vec.coeff(5), 1.0);
    VERIFY_IS_EQUAL(vec.coeff(9), -0.2);

    init_vec();
    VERIFY_IS_EQUAL(vec.prune([](double v) { return v >= 0; }), 2);
    VERIFY_IS_EQUAL(vec.nonZeros(), 2);
    VERIFY_IS_EQUAL(vec.coeff(3), 0.1);
    VERIFY_IS_EQUAL(vec.coeff(5), 1.0);
}

EIGEN_DECLARE_TEST(sparse_vector)
{
  for(int i = 0; i < g_repeat; i++) {
    int r = Eigen::internal::random<int>(1,500), c = Eigen::internal::random<int>(1,500);
    if(Eigen::internal::random<int>(0,4) == 0) {
      r = c; // check square matrices in 25% of tries
    }
    EIGEN_UNUSED_VARIABLE(r+c);

    CALL_SUBTEST_1(( sparse_vector<double,int>(8, 8) ));
    CALL_SUBTEST_2(( sparse_vector<std::complex<double>, int>(r, c) ));
    CALL_SUBTEST_1(( sparse_vector<double,long int>(r, c) ));
    CALL_SUBTEST_1(( sparse_vector<double,short>(r, c) ));
  }

  CALL_SUBTEST_1(test_pruning());
}

