diff --git a/src/Classic/Fields/Interpolation/SquarePolynomialVector.cpp b/src/Classic/Fields/Interpolation/SquarePolynomialVector.cpp
index b375fe636ca700accf7d41bfe16ed7f5687514ff..bc352bb28b1e662b9a3f71124c4ee999cad5d2bf 100644
--- a/src/Classic/Fields/Interpolation/SquarePolynomialVector.cpp
+++ b/src/Classic/Fields/Interpolation/SquarePolynomialVector.cpp
@@ -114,7 +114,8 @@ void  SquarePolynomialVector::F(const double*   point,    double* value)
     for(unsigned int i=0; i<ValueDimension(); i++) value[i]  = valueV(i+1);
 }
 
-void  SquarePolynomialVector::F(const MVector<double>& point,   MVector<double>& value) const
+void  SquarePolynomialVector::F(const MVector<double>& point,
+                                MVector<double>& value) const
 {
     MVector<double> polyVector(_polyCoeffs.num_col(), 1);
     MakePolyVector(point, polyVector);
@@ -123,7 +124,9 @@ void  SquarePolynomialVector::F(const MVector<double>& point,   MVector<double>&
 }
 
 
-MVector<double>& SquarePolynomialVector::MakePolyVector(const MVector<double>& point, MVector<double>& polyVector) const
+MVector<double>& SquarePolynomialVector::MakePolyVector(
+                                const MVector<double>& point,
+                                MVector<double>& polyVector) const
 {
     for(unsigned int i=0; i<_polyCoeffs.num_col(); i++) {
         polyVector(i+1) = 1.;
@@ -161,7 +164,7 @@ void SquarePolynomialVector::IndexByPowerRecursive(std::vector<int> check, size_
 std::vector<int> SquarePolynomialVector::IndexByPower(int index, int point_dim) {
     if (point_dim < 1)
         throw(GeneralClassicException(
-            "PPSolveFactory::GetNearbyPointsSquares",
+            "SquarePolynomialVector::IndexByPower",
             "Point dimension must be > 0"
         ));
     while (int(_polyKeyByPower.size()) < point_dim)
@@ -253,5 +256,50 @@ unsigned int SquarePolynomialVector::PolynomialOrder() const {
     return maxPower;
 }
 
+SquarePolynomialVector SquarePolynomialVector::Deriv(const int* derivPower) const {
+    if (derivPower == NULL) {
+        throw(GeneralClassicException(
+            "SquarePolynomialVector::Deriv",
+            "Derivative points to NULL"
+        ));
+    }
+    MMatrix<double> newPolyCoeffs(_polyCoeffs.num_row(),  _polyCoeffs.num_col(), 0.);
+    std::vector< std::vector<int> > powerKey = _polyKeyByPower[_pointDim-1];
+    for (size_t j = 0; j < _polyCoeffs.num_col(); ++j) {
+        std::vector<int> thisPower = powerKey[j];
+        std::vector<int> newPower(_pointDim);
+        // f(x) = Product(x_i^t_i)
+        // d^n f(x)  / Product(d x_j^d_j) =
+        //       t_i >= d_j ... Product(x_i^(t_i - d_j) * t_i!/(t_i-d_j)!
+        //       t_i < d_j  ... 0
+        double newCoeff = 1.;
+        // calculate the coefficient
+        for (size_t k = 0; k < thisPower.size(); ++k) {
+            newPower[k] = thisPower[k] - derivPower[k];
+            if (newPower[k] < 0) {
+                newCoeff = 0.;
+                break;
+            }
+            newCoeff *= gsl_sf_fact(thisPower[k])/gsl_sf_fact(newPower[k]);
+        }
+        // put it in the matrix of coefficients
+        for (size_t k = 0; k < powerKey.size(); ++k) {
+            bool match = true;
+            for (size_t l = 0; l < powerKey[k].size(); ++l) {
+                if (powerKey[k][l] != newPower[l]) {
+                    match = false;
+                    break;
+                }
+            }
+            if (match) {
+                for (size_t i = 0; i < _polyCoeffs.num_row(); ++i) {
+                    newPolyCoeffs(i+1, k+1) = newCoeff*_polyCoeffs(i+1, j+1);
+                }
+            }
+        }
+    }
+    SquarePolynomialVector vec(_pointDim, newPolyCoeffs);
+    return vec;
+}
 
 }
\ No newline at end of file
diff --git a/src/Classic/Fields/Interpolation/SquarePolynomialVector.h b/src/Classic/Fields/Interpolation/SquarePolynomialVector.h
index 0ff53fca824b5d908c3156c0e73a64a70eb30963..46ffdfd38abf77737c24949ae442eef7441a5a26 100644
--- a/src/Classic/Fields/Interpolation/SquarePolynomialVector.h
+++ b/src/Classic/Fields/Interpolation/SquarePolynomialVector.h
@@ -58,7 +58,7 @@ namespace interpolation {
  *  \f$ w_i = x_{i_1}x_{i_2} \ldots x_{i_n} \f$ \n
  *  \n
  *
- *  Nb: it is a SquarePolynomialVector because coefficients include all
+ *  Nb: it is a *Square*PolynomialVector because coefficients include all
  *  polynomial coefficients with \f$ i_ j <= n \f$; coefficients sit within an
  *  n-dimensional square. The distinction should be made with a PolynomialVector
  *  where coefficients include all polynomial coefficients with 
@@ -137,6 +137,17 @@ class SquarePolynomialVector {
      */
     void  F(const MVector<double>& point, MVector<double>& value) const;
 
+    /** Generate polynomial corresponding to the partial derivative of y
+     * 
+     *  @returns \f$ \frac{\partial^{j_1+j_2+\ldots} \vec{y}}
+     *                    {\partial x^j_1 \partial x^j_2 \ldots} \f$
+     *  at some set point \f$ \vec{x} \f$.
+     *
+     *  derivPower is an array with indices of the derivative in the 
+     *      "IndexByPower" style, of length PointDimension()
+     */
+    SquarePolynomialVector Deriv(const int* derivPower) const;
+
     /** Length of the input point (x) vector. */
     unsigned int PointDimension()         const {return _pointDim;}
 
diff --git a/tests/classic_src/Fields/Interpolation/SquarePolynomialVectorTest.cpp b/tests/classic_src/Fields/Interpolation/SquarePolynomialVectorTest.cpp
index bad61c86ede53d21a68219086bb769f3ca571fa4..dcda97b99294a2a89dc938f4049c3668046a9415 100644
--- a/tests/classic_src/Fields/Interpolation/SquarePolynomialVectorTest.cpp
+++ b/tests/classic_src/Fields/Interpolation/SquarePolynomialVectorTest.cpp
@@ -108,4 +108,27 @@ TEST(SquarePolynomialVectorTest, TestF) {
     ref.F(&point3[0], &value[0]);
     EXPECT_EQ(value[0], refValue(1)); // sum (0, ..., 8)
     EXPECT_EQ(value[1], refValue(2)); // sum (9, ..., 17)
-}
\ No newline at end of file
+}
+
+TEST(SquarePolynomialVectorTest, TestDeriv) {
+    std::vector<double> data(32);
+    for (size_t i = 0; i < data.size(); ++i)
+        data[i] = i;
+    // Up to x^3
+    MMatrix<double> inputCoeffs(2, 16, &data[0]);
+    SquarePolynomialVector input(2, inputCoeffs);
+    std::vector<int> derivPower({1, 2});
+    SquarePolynomialVector test = input.Deriv(&derivPower[0]);
+    std::vector<double> refCoeffs({
+        28, 64, 156, 336, 132, 540, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        30, 68, 162, 348, 138, 558, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+    });
+    MMatrix<double> testCoeffs = test.GetCoefficientsAsMatrix();
+    size_t index = 0;
+    for (size_t i = 0; i < testCoeffs.num_row(); ++i) {
+        for (size_t j = 0; j < testCoeffs.num_col(); ++j) {
+            EXPECT_NEAR(testCoeffs(i+1, j+1), refCoeffs[index], 1e-12);
+            index++;
+        }
+    }
+}