Sparse move
diff --git a/Eigen/src/SparseCore/SparseMatrix.h b/Eigen/src/SparseCore/SparseMatrix.h
index ecf406f..849970a 100644
--- a/Eigen/src/SparseCore/SparseMatrix.h
+++ b/Eigen/src/SparseCore/SparseMatrix.h
@@ -788,8 +788,11 @@
     Base::operator=(other);
   }
 
-  inline SparseMatrix(SparseMatrix&& other)
-      : Base(), m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0) {
+  /** Move constructor */
+  inline SparseMatrix(SparseMatrix&& other) : SparseMatrix() { this->swap(other); }
+
+  template <typename OtherDerived>
+  inline SparseMatrix(SparseCompressedBase<OtherDerived>&& other) : SparseMatrix() {
     *this = other.derived().markAsRValue();
   }
 
@@ -857,7 +860,10 @@
     return *this;
   }
 
-  inline SparseMatrix& operator=(SparseMatrix&& other) { return *this = other.derived().markAsRValue(); }
+  inline SparseMatrix& operator=(SparseMatrix&& other) {
+    this->swap(other);
+    return *this;
+  }
 
 #ifndef EIGEN_PARSED_BY_DOXYGEN
   template <typename OtherDerived>
@@ -872,6 +878,12 @@
   template <typename OtherDerived>
   EIGEN_DONT_INLINE SparseMatrix& operator=(const SparseMatrixBase<OtherDerived>& other);
 
+  template <typename OtherDerived>
+  inline SparseMatrix& operator=(SparseCompressedBase<OtherDerived>&& other) {
+    *this = other.derived().markAsRValue();
+    return *this;
+  }
+
 #ifndef EIGEN_NO_IO
   friend std::ostream& operator<<(std::ostream& s, const SparseMatrix& m) {
     EIGEN_DBG_SPARSE(
diff --git a/Eigen/src/SparseCore/SparseVector.h b/Eigen/src/SparseCore/SparseVector.h
index 0733718..fac162e 100644
--- a/Eigen/src/SparseCore/SparseVector.h
+++ b/Eigen/src/SparseCore/SparseVector.h
@@ -304,6 +304,24 @@
     return *this;
   }
 
+  inline SparseVector(SparseVector&& other) : SparseVector() { this->swap(other); }
+
+  template <typename OtherDerived>
+  inline SparseVector(SparseCompressedBase<OtherDerived>&& other) : SparseVector() {
+    *this = other.derived().markAsRValue();
+  }
+
+  inline SparseVector& operator=(SparseVector&& other) {
+    this->swap(other);
+    return *this;
+  }
+
+  template <typename OtherDerived>
+  inline SparseVector& operator=(SparseCompressedBase<OtherDerived>&& other) {
+    *this = other.derived().markAsRValue();
+    return *this;
+  }
+
 #ifndef EIGEN_PARSED_BY_DOXYGEN
   template <typename Lhs, typename Rhs>
   inline SparseVector& operator=(const SparseSparseProduct<Lhs, Rhs>& product) {
diff --git a/test/sparse_basic.cpp b/test/sparse_basic.cpp
index 364aac0..a9c6f4c 100644
--- a/test/sparse_basic.cpp
+++ b/test/sparse_basic.cpp
@@ -39,7 +39,7 @@
   typedef Matrix<Scalar, Dynamic, Dynamic> DenseMatrix;
   typedef Matrix<Scalar, Dynamic, 1> DenseVector;
   typedef Matrix<Scalar, Dynamic, Dynamic, SparseMatrixType::IsRowMajor ? RowMajor : ColMajor> CompatibleDenseMatrix;
-  Scalar eps = 1e-6;
+  Scalar eps = Scalar(1e-6);
 
   Scalar s1 = internal::random<Scalar>();
   {
@@ -948,6 +948,27 @@
     SparseMatrixType m2(rows, 0);
     m2.reserve(ArrayXi::Constant(m2.outerSize(), 1));
   }
+
+  // test move
+  {
+    using TransposedType = SparseMatrix<Scalar, SparseMatrixType::IsRowMajor ? ColMajor : RowMajor,
+                                        typename SparseMatrixType::StorageIndex>;
+    DenseMatrix refMat1 = DenseMatrix::Random(rows, cols);
+    SparseMatrixType m1(rows, cols);
+    initSparse<Scalar>(density, refMat1, m1);
+    // test move ctor
+    SparseMatrixType m2(std::move(m1));
+    VERIFY_IS_APPROX(m2, refMat1);
+    // test move assignment
+    m1 = std::move(m2);
+    VERIFY_IS_APPROX(m1, refMat1);
+    // test move ctor (SparseMatrixBase)
+    TransposedType m3(std::move(m1.transpose()));
+    VERIFY_IS_APPROX(m3, refMat1.transpose());
+    // test move assignment (SparseMatrixBase)
+    m2 = std::move(m3.transpose());
+    VERIFY_IS_APPROX(m2, refMat1);
+  }
 }
 
 template <typename SparseMatrixType>
@@ -994,7 +1015,7 @@
   g_dense_op_sparse_count = 0;  // Suppresses compiler warning.
   for (int i = 0; i < g_repeat; i++) {
     int r = Eigen::internal::random<int>(1, 200), c = Eigen::internal::random<int>(1, 200);
-    if (Eigen::internal::random<int>(0, 4) == 0) {
+    if (Eigen::internal::random<int>(0, 3) == 0) {
       r = c;  // check square matrices in 25% of tries
     }
     EIGEN_UNUSED_VARIABLE(r + c);
@@ -1011,7 +1032,7 @@
 
     r = Eigen::internal::random<int>(1, 100);
     c = Eigen::internal::random<int>(1, 100);
-    if (Eigen::internal::random<int>(0, 4) == 0) {
+    if (Eigen::internal::random<int>(0, 3) == 0) {
       r = c;  // check square matrices in 25% of tries
     }
 
diff --git a/test/sparse_vector.cpp b/test/sparse_vector.cpp
index 83ad324..8d47fb0 100644
--- a/test/sparse_vector.cpp
+++ b/test/sparse_vector.cpp
@@ -108,6 +108,33 @@
   VERIFY_IS_APPROX(refV3 = v1.transpose(), v1.toDense());
   VERIFY_IS_APPROX(DenseVector(v1), v1.toDense());
 
+  // test move
+  {
+    SparseVectorType v3(std::move(v1));
+    VERIFY_IS_APPROX(v3, refV1);
+    v1 = v3;
+  }
+
+  {
+    SparseVectorType v3;
+    v3 = std::move(v1);
+    VERIFY_IS_APPROX(v3, refV1);
+    v1 = v3;
+  }
+
+  {
+    SparseVectorType v3(std::move(mv1));
+    VERIFY_IS_APPROX(v3, refV1);
+    mv1 = v3;
+  }
+
+  {
+    SparseVectorType v3;
+    v3 = std::move(mv1);
+    VERIFY_IS_APPROX(v3, refV1);
+    mv1 = v3;
+  }
+
   // test conservative resize
   {
     std::vector<StorageIndex> inc;