// 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_shuffle(innerIndices.begin(), innerIndices.end());
    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());
}

