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

// This unit test cannot be easily written to work with EIGEN_DEFAULT_TO_ROW_MAJOR
#ifdef EIGEN_DEFAULT_TO_ROW_MAJOR
#undef EIGEN_DEFAULT_TO_ROW_MAJOR
#endif

#define TEST_ENABLE_TEMPORARY_TRACKING
#define TEST_CHECK_STATIC_ASSERTIONS
#include "main.h"

// test Ref.h

// Deal with i387 extended precision
#if EIGEN_ARCH_i386 && !(EIGEN_ARCH_x86_64)

#if EIGEN_COMP_GNUC_STRICT && EIGEN_GNUC_AT_LEAST(4,4)
#pragma GCC optimize ("-ffloat-store")
#else
#undef VERIFY_IS_EQUAL
#define VERIFY_IS_EQUAL(X,Y) VERIFY_IS_APPROX(X,Y)
#endif

#endif

template<typename MatrixType> void ref_matrix(const MatrixType& m)
{
  typedef typename MatrixType::Scalar Scalar;
  typedef typename MatrixType::RealScalar RealScalar;
  typedef Matrix<Scalar,Dynamic,Dynamic,MatrixType::Options> DynMatrixType;
  typedef Matrix<RealScalar,Dynamic,Dynamic,MatrixType::Options> RealDynMatrixType;
  
  typedef Ref<MatrixType> RefMat;
  typedef Ref<DynMatrixType> RefDynMat;
  typedef Ref<const DynMatrixType> ConstRefDynMat;
  typedef Ref<RealDynMatrixType , 0, Stride<Dynamic,Dynamic> > RefRealMatWithStride;

  Index rows = m.rows(), cols = m.cols();
  
  MatrixType  m1 = MatrixType::Random(rows, cols),
              m2 = m1;
  
  Index i = internal::random<Index>(0,rows-1);
  Index j = internal::random<Index>(0,cols-1);
  Index brows = internal::random<Index>(1,rows-i);
  Index bcols = internal::random<Index>(1,cols-j);
  
  RefMat rm0 = m1;
  VERIFY_IS_EQUAL(rm0, m1);
  RefDynMat rm1 = m1;
  VERIFY_IS_EQUAL(rm1, m1);
  RefDynMat rm2 = m1.block(i,j,brows,bcols);
  VERIFY_IS_EQUAL(rm2, m1.block(i,j,brows,bcols));
  rm2.setOnes();
  m2.block(i,j,brows,bcols).setOnes();
  VERIFY_IS_EQUAL(m1, m2);
  
  m2.block(i,j,brows,bcols).setRandom();
  rm2 = m2.block(i,j,brows,bcols);
  VERIFY_IS_EQUAL(m1, m2);
  
  ConstRefDynMat rm3 = m1.block(i,j,brows,bcols);
  m1.block(i,j,brows,bcols) *= 2;
  m2.block(i,j,brows,bcols) *= 2;
  VERIFY_IS_EQUAL(rm3, m2.block(i,j,brows,bcols));
  RefRealMatWithStride rm4 = m1.real();
  VERIFY_IS_EQUAL(rm4, m2.real());
  rm4.array() += 1;
  m2.real().array() += 1;
  VERIFY_IS_EQUAL(m1, m2);
}

template<typename VectorType> void ref_vector(const VectorType& m)
{
  typedef typename VectorType::Scalar Scalar;
  typedef typename VectorType::RealScalar RealScalar;
  typedef Matrix<Scalar,Dynamic,1,VectorType::Options> DynMatrixType;
  typedef Matrix<Scalar,Dynamic,Dynamic,ColMajor> MatrixType;
  typedef Matrix<RealScalar,Dynamic,1,VectorType::Options> RealDynMatrixType;
  
  typedef Ref<VectorType> RefMat;
  typedef Ref<DynMatrixType> RefDynMat;
  typedef Ref<const DynMatrixType> ConstRefDynMat;
  typedef Ref<RealDynMatrixType , 0, InnerStride<> > RefRealMatWithStride;
  typedef Ref<DynMatrixType , 0, InnerStride<> > RefMatWithStride;

  Index size = m.size();
  
  VectorType  v1 = VectorType::Random(size),
              v2 = v1;
  MatrixType mat1 = MatrixType::Random(size,size),
             mat2 = mat1,
             mat3 = MatrixType::Random(size,size);
  
  Index i = internal::random<Index>(0,size-1);
  Index bsize = internal::random<Index>(1,size-i);
  
  { RefMat    rm0 = v1;                   VERIFY_IS_EQUAL(rm0, v1); }
  { RefMat    rm0 = v1.block(0,0,size,1); VERIFY_IS_EQUAL(rm0, v1); }
  { RefDynMat rv1 = v1;                   VERIFY_IS_EQUAL(rv1, v1); }
  { RefDynMat rv1 = v1.block(0,0,size,1); VERIFY_IS_EQUAL(rv1, v1); }

  RefDynMat rv2 = v1.segment(i,bsize);
  VERIFY_IS_EQUAL(rv2, v1.segment(i,bsize));
  rv2.setOnes();
  v2.segment(i,bsize).setOnes();
  VERIFY_IS_EQUAL(v1, v2);
  
  v2.segment(i,bsize).setRandom();
  rv2 = v2.segment(i,bsize);
  VERIFY_IS_EQUAL(v1, v2);
  
  ConstRefDynMat rm3 = v1.segment(i,bsize);
  v1.segment(i,bsize) *= 2;
  v2.segment(i,bsize) *= 2;
  VERIFY_IS_EQUAL(rm3, v2.segment(i,bsize));
  
  RefRealMatWithStride rm4 = v1.real();
  VERIFY_IS_EQUAL(rm4, v2.real());
  rm4.array() += 1;
  v2.real().array() += 1;
  VERIFY_IS_EQUAL(v1, v2);
  
  RefMatWithStride rm5 = mat1.row(i).transpose();
  VERIFY_IS_EQUAL(rm5, mat1.row(i).transpose());
  rm5.array() += 1;
  mat2.row(i).array() += 1;
  VERIFY_IS_EQUAL(mat1, mat2);
  rm5.noalias() = rm4.transpose() * mat3;
  mat2.row(i) = v2.real().transpose() * mat3;
  VERIFY_IS_APPROX(mat1, mat2);
}

template<typename Scalar, int Rows, int Cols>
void ref_vector_fixed_sizes()
{
  typedef Matrix<Scalar,Rows,Cols,RowMajor> RowMajorMatrixType;
  typedef Matrix<Scalar,Rows,Cols,ColMajor> ColMajorMatrixType;
  typedef Matrix<Scalar,1,Cols> RowVectorType;
  typedef Matrix<Scalar,Rows,1> ColVectorType;
  typedef Matrix<Scalar,Cols,1> RowVectorTransposeType;
  typedef Matrix<Scalar,1,Rows> ColVectorTransposeType;
  typedef Stride<Dynamic, Dynamic> DynamicStride;

  RowMajorMatrixType mr = RowMajorMatrixType::Random();
  ColMajorMatrixType mc = ColMajorMatrixType::Random();

  Index i = internal::random<Index>(0,Rows-1);
  Index j = internal::random<Index>(0,Cols-1);

  // Reference ith row.
  Ref<RowVectorType, 0, DynamicStride> mr_ri = mr.row(i);
  VERIFY_IS_EQUAL(mr_ri, mr.row(i));
  Ref<RowVectorType, 0, DynamicStride> mc_ri = mc.row(i);
  VERIFY_IS_EQUAL(mc_ri, mc.row(i));

  // Reference jth col.
  Ref<ColVectorType, 0, DynamicStride> mr_cj = mr.col(j);
  VERIFY_IS_EQUAL(mr_cj, mr.col(j));
  Ref<ColVectorType, 0, DynamicStride> mc_cj = mc.col(j);
  VERIFY_IS_EQUAL(mc_cj, mc.col(j));

  // Reference the transpose of row i.
  Ref<RowVectorTransposeType, 0, DynamicStride> mr_rit = mr.row(i);
  VERIFY_IS_EQUAL(mr_rit, mr.row(i).transpose());
  Ref<RowVectorTransposeType, 0, DynamicStride> mc_rit = mc.row(i);
  VERIFY_IS_EQUAL(mc_rit, mc.row(i).transpose());

  // Reference the transpose of col j.
  Ref<ColVectorTransposeType, 0, DynamicStride> mr_cjt = mr.col(j);
  VERIFY_IS_EQUAL(mr_cjt, mr.col(j).transpose());
  Ref<ColVectorTransposeType, 0, DynamicStride> mc_cjt = mc.col(j);
  VERIFY_IS_EQUAL(mc_cjt, mc.col(j).transpose());
  
  // Const references without strides.
  Ref<const RowVectorType> cmr_ri = mr.row(i);
  VERIFY_IS_EQUAL(cmr_ri, mr.row(i));
  Ref<const RowVectorType> cmc_ri = mc.row(i);
  VERIFY_IS_EQUAL(cmc_ri, mc.row(i));

  Ref<const ColVectorType> cmr_cj = mr.col(j);
  VERIFY_IS_EQUAL(cmr_cj, mr.col(j));
  Ref<const ColVectorType> cmc_cj = mc.col(j);
  VERIFY_IS_EQUAL(cmc_cj, mc.col(j));

  Ref<const RowVectorTransposeType> cmr_rit = mr.row(i);
  VERIFY_IS_EQUAL(cmr_rit, mr.row(i).transpose());
  Ref<const RowVectorTransposeType> cmc_rit = mc.row(i);
  VERIFY_IS_EQUAL(cmc_rit, mc.row(i).transpose());

  Ref<const ColVectorTransposeType> cmr_cjt = mr.col(j);
  VERIFY_IS_EQUAL(cmr_cjt, mr.col(j).transpose());
  Ref<const ColVectorTransposeType> cmc_cjt = mc.col(j);
  VERIFY_IS_EQUAL(cmc_cjt, mc.col(j).transpose());
}

template<typename PlainObjectType> void check_const_correctness(const PlainObjectType&)
{
  // verify that ref-to-const don't have LvalueBit
  typedef typename internal::add_const<PlainObjectType>::type ConstPlainObjectType;
  VERIFY( !(internal::traits<Ref<ConstPlainObjectType> >::Flags & LvalueBit) );
  VERIFY( !(internal::traits<Ref<ConstPlainObjectType, Aligned> >::Flags & LvalueBit) );
  VERIFY( !(Ref<ConstPlainObjectType>::Flags & LvalueBit) );
  VERIFY( !(Ref<ConstPlainObjectType, Aligned>::Flags & LvalueBit) );
}

template<typename B>
EIGEN_DONT_INLINE void call_ref_1(Ref<VectorXf> a, const B &b) { VERIFY_IS_EQUAL(a,b); }
template<typename B>
EIGEN_DONT_INLINE void call_ref_2(const Ref<const VectorXf>& a, const B &b) { VERIFY_IS_EQUAL(a,b); }
template<typename B>
EIGEN_DONT_INLINE void call_ref_3(Ref<VectorXf,0,InnerStride<> > a, const B &b) { VERIFY_IS_EQUAL(a,b); }
template<typename B>
EIGEN_DONT_INLINE void call_ref_4(const Ref<const VectorXf,0,InnerStride<> >& a, const B &b) { VERIFY_IS_EQUAL(a,b); }
template<typename B>
EIGEN_DONT_INLINE void call_ref_5(Ref<MatrixXf,0,OuterStride<> > a, const B &b) { VERIFY_IS_EQUAL(a,b); }
template<typename B>
EIGEN_DONT_INLINE void call_ref_6(const Ref<const MatrixXf,0,OuterStride<> >& a, const B &b) { VERIFY_IS_EQUAL(a,b); }
template<typename B>
EIGEN_DONT_INLINE void call_ref_7(Ref<Matrix<float,Dynamic,3> > a, const B &b) { VERIFY_IS_EQUAL(a,b); }

void call_ref()
{
  VectorXcf ca  = VectorXcf::Random(10);
  VectorXf a    = VectorXf::Random(10);
  RowVectorXf b = RowVectorXf::Random(10);
  MatrixXf A    = MatrixXf::Random(10,10);
  RowVector3f c = RowVector3f::Random();
  const VectorXf& ac(a);
  VectorBlock<VectorXf> ab(a,0,3);
  const VectorBlock<VectorXf> abc(a,0,3);
  

  VERIFY_EVALUATION_COUNT( call_ref_1(a,a), 0);
  VERIFY_EVALUATION_COUNT( call_ref_1(b,b.transpose()), 0);
//   call_ref_1(ac,a<c);           // does not compile because ac is const
  VERIFY_EVALUATION_COUNT( call_ref_1(ab,ab), 0);
  VERIFY_EVALUATION_COUNT( call_ref_1(a.head(4),a.head(4)), 0);
  VERIFY_EVALUATION_COUNT( call_ref_1(abc,abc), 0);
  VERIFY_EVALUATION_COUNT( call_ref_1(A.col(3),A.col(3)), 0);
//   call_ref_1(A.row(3),A.row(3));    // does not compile because innerstride!=1
  VERIFY_EVALUATION_COUNT( call_ref_3(A.row(3),A.row(3).transpose()), 0);
  VERIFY_EVALUATION_COUNT( call_ref_4(A.row(3),A.row(3).transpose()), 0);
//   call_ref_1(a+a, a+a);          // does not compile for obvious reason

  MatrixXf tmp = A*A.col(1);
  VERIFY_EVALUATION_COUNT( call_ref_2(A*A.col(1), tmp), 1);     // evaluated into a temp
  VERIFY_EVALUATION_COUNT( call_ref_2(ac.head(5),ac.head(5)), 0);
  VERIFY_EVALUATION_COUNT( call_ref_2(ac,ac), 0);
  VERIFY_EVALUATION_COUNT( call_ref_2(a,a), 0);
  VERIFY_EVALUATION_COUNT( call_ref_2(ab,ab), 0);
  VERIFY_EVALUATION_COUNT( call_ref_2(a.head(4),a.head(4)), 0);
  tmp = a+a;
  VERIFY_EVALUATION_COUNT( call_ref_2(a+a,tmp), 1);            // evaluated into a temp
  VERIFY_EVALUATION_COUNT( call_ref_2(ca.imag(),ca.imag()), 1);      // evaluated into a temp

  VERIFY_EVALUATION_COUNT( call_ref_4(ac.head(5),ac.head(5)), 0);
  tmp = a+a;
  VERIFY_EVALUATION_COUNT( call_ref_4(a+a,tmp), 1);           // evaluated into a temp
  VERIFY_EVALUATION_COUNT( call_ref_4(ca.imag(),ca.imag()), 0);

  VERIFY_EVALUATION_COUNT( call_ref_5(a,a), 0);
  VERIFY_EVALUATION_COUNT( call_ref_5(a.head(3),a.head(3)), 0);
  VERIFY_EVALUATION_COUNT( call_ref_5(A,A), 0);
//   call_ref_5(A.transpose(),A.transpose());   // does not compile because storage order does not match
  VERIFY_EVALUATION_COUNT( call_ref_5(A.block(1,1,2,2),A.block(1,1,2,2)), 0);
  VERIFY_EVALUATION_COUNT( call_ref_5(b,b), 0);             // storage order do not match, but this is a degenerate case that should work
  VERIFY_EVALUATION_COUNT( call_ref_5(a.row(3),a.row(3)), 0);

  VERIFY_EVALUATION_COUNT( call_ref_6(a,a), 0);
  VERIFY_EVALUATION_COUNT( call_ref_6(a.head(3),a.head(3)), 0);
  VERIFY_EVALUATION_COUNT( call_ref_6(A.row(3),A.row(3)), 1);           // evaluated into a temp thouth it could be avoided by viewing it as a 1xn matrix
  tmp = A+A;
  VERIFY_EVALUATION_COUNT( call_ref_6(A+A,tmp), 1);                // evaluated into a temp
  VERIFY_EVALUATION_COUNT( call_ref_6(A,A), 0);
  VERIFY_EVALUATION_COUNT( call_ref_6(A.transpose(),A.transpose()), 1);      // evaluated into a temp because the storage orders do not match
  VERIFY_EVALUATION_COUNT( call_ref_6(A.block(1,1,2,2),A.block(1,1,2,2)), 0);
  
  VERIFY_EVALUATION_COUNT( call_ref_7(c,c), 0);
}

typedef Matrix<double,Dynamic,Dynamic,RowMajor> RowMatrixXd;
int test_ref_overload_fun1(Ref<MatrixXd> )       { return 1; }
int test_ref_overload_fun1(Ref<RowMatrixXd> )    { return 2; }
int test_ref_overload_fun1(Ref<MatrixXf> )       { return 3; }

int test_ref_overload_fun2(Ref<const MatrixXd> ) { return 4; }
int test_ref_overload_fun2(Ref<const MatrixXf> ) { return 5; }

void test_ref_ambiguous(const Ref<const ArrayXd> &A, Ref<ArrayXd> B)
{
  B = A;
  B = A - A;
}

// See also bug 969
void test_ref_overloads()
{
  MatrixXd Ad, Bd;
  RowMatrixXd rAd, rBd;
  VERIFY( test_ref_overload_fun1(Ad)==1 );
  VERIFY( test_ref_overload_fun1(rAd)==2 );
  
  MatrixXf Af, Bf;
  VERIFY( test_ref_overload_fun2(Ad)==4 );
  VERIFY( test_ref_overload_fun2(Ad+Bd)==4 );
  VERIFY( test_ref_overload_fun2(Af+Bf)==5 );
  
  ArrayXd A, B;
  test_ref_ambiguous(A, B);
}

EIGEN_DECLARE_TEST(ref)
{
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( ref_vector(Matrix<float, 1, 1>()) );
    CALL_SUBTEST_1( check_const_correctness(Matrix<float, 1, 1>()) );
    CALL_SUBTEST_2( ref_vector(Vector4d()) );
    CALL_SUBTEST_2( check_const_correctness(Matrix4d()) );
    CALL_SUBTEST_3( ref_vector(Vector4cf()) );
    CALL_SUBTEST_4( ref_vector(VectorXcf(8)) );
    CALL_SUBTEST_5( ref_vector(VectorXi(12)) );
    CALL_SUBTEST_5( check_const_correctness(VectorXi(12)) );

    CALL_SUBTEST_1( ref_matrix(Matrix<float, 1, 1>()) );
    CALL_SUBTEST_2( ref_matrix(Matrix4d()) );
    CALL_SUBTEST_1( ref_matrix(Matrix<float,3,5>()) );
    CALL_SUBTEST_4( ref_matrix(MatrixXcf(internal::random<int>(1,10),internal::random<int>(1,10))) );
    CALL_SUBTEST_4( ref_matrix(Matrix<std::complex<double>,10,15>()) );
    CALL_SUBTEST_5( ref_matrix(MatrixXi(internal::random<int>(1,10),internal::random<int>(1,10))) );
    CALL_SUBTEST_6( call_ref() );

    CALL_SUBTEST_8( (ref_vector_fixed_sizes<float,3,5>()) );
    CALL_SUBTEST_8( (ref_vector_fixed_sizes<float,15,10>()) );
  }
  
  CALL_SUBTEST_7( test_ref_overloads() );
}
