Index: trunk/psLib/src/math/psPolynomial.c
===================================================================
--- trunk/psLib/src/math/psPolynomial.c	(revision 10598)
+++ trunk/psLib/src/math/psPolynomial.c	(revision 10605)
@@ -7,6 +7,6 @@
 *  polynomials.  It also contains a Gaussian functions.
 *
-*  @version $Revision: 1.153 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2006-12-09 14:19:56 $
+*  @version $Revision: 1.154 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2006-12-10 04:13:25 $
 *
 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -690,5 +690,5 @@
 {
     if (out == NULL) {
-        psPolynomial2DAlloc (poly->type, poly->nX, poly->nY);
+        out = psPolynomial2DAlloc (poly->type, poly->nX, poly->nY);
     } else {
         psPolynomial2DRecycle (out, poly->type, poly->nX, poly->nY);
Index: trunk/psLib/src/math/psPolynomialUtils.c
===================================================================
--- trunk/psLib/src/math/psPolynomialUtils.c	(revision 10598)
+++ trunk/psLib/src/math/psPolynomialUtils.c	(revision 10605)
@@ -180,18 +180,36 @@
 psPolynomial2D *psPolynomial2D_dX (psPolynomial2D *out, psPolynomial2D *poly)
 {
+    psPolynomial2D *dest = NULL;
     int nXout = poly->nX - 1;
     int nYout = poly->nY;
 
+    if (poly->nX == 0)
+        return NULL;
+
+    bool inPlace = false;
+
     if (out == NULL) {
-        out = psPolynomial2DAlloc (PS_POLYNOMIAL_ORD, nXout, nYout);
-    } else {
-        psPolynomial2DRecycle (out, poly->type, nXout, nYout);
+        dest = psPolynomial2DAlloc (PS_POLYNOMIAL_ORD, nXout, nYout);
+        out = dest;
+    } else {
+        if (out == poly) {
+            inPlace = true;
+            dest = psPolynomial2DAlloc (PS_POLYNOMIAL_ORD, nXout, nYout);
+        } else {
+            dest = out;
+            psPolynomial2DRecycle (dest, poly->type, nXout, nYout);
+        }
     }
 
     for (int i = 0; i < nXout + 1; i++) {
         for (int j = 0; j < nYout + 1; j++) {
-            out->mask[i][j] = poly->mask[i+1][j];
-            out->coeff[i][j] = poly->coeff[i+1][j] * (i+1);
-        }
+            dest->mask[i][j] = poly->mask[i+1][j];
+            dest->coeff[i][j] = poly->coeff[i+1][j] * (i+1);
+        }
+    }
+
+    if (inPlace) {
+        psFree (poly);
+        out = dest;
     }
     return out;
@@ -200,19 +218,36 @@
 psPolynomial2D *psPolynomial2D_dY (psPolynomial2D *out, psPolynomial2D *poly)
 {
-
-    int nXout = poly->nX - 1;
-    int nYout = poly->nY;
+    psPolynomial2D *dest = NULL;
+    int nXout = poly->nX;
+    int nYout = poly->nY - 1;
+
+    if (poly->nY == 0)
+        return NULL;
+
+    bool inPlace = false;
 
     if (out == NULL) {
-        out = psPolynomial2DAlloc (PS_POLYNOMIAL_ORD, nXout, nYout);
-    } else {
-        psPolynomial2DRecycle (out, poly->type, nXout, nYout);
+        dest = psPolynomial2DAlloc (PS_POLYNOMIAL_ORD, nXout, nYout);
+        out = dest;
+    } else {
+        if (out == poly) {
+            inPlace = true;
+            dest = psPolynomial2DAlloc (PS_POLYNOMIAL_ORD, nXout, nYout);
+        } else {
+            dest = out;
+            psPolynomial2DRecycle (dest, poly->type, nXout, nYout);
+        }
     }
 
     for (int i = 0; i < nXout + 1; i++) {
         for (int j = 0; j < nYout + 1; j++) {
-            out->mask[i][j] = poly->mask[i][j+1];
-            out->coeff[i][j] = poly->coeff[i][j+1] * (j+1);
-        }
+            dest->mask[i][j] = poly->mask[i][j+1];
+            dest->coeff[i][j] = poly->coeff[i][j+1] * (j+1);
+        }
+    }
+
+    if (inPlace) {
+        psFree (poly);
+        out = dest;
     }
     return out;
Index: trunk/psLib/test/math/tap_psPolynomialUtils_Derivatives.c
===================================================================
--- trunk/psLib/test/math/tap_psPolynomialUtils_Derivatives.c	(revision 10598)
+++ trunk/psLib/test/math/tap_psPolynomialUtils_Derivatives.c	(revision 10605)
@@ -8,5 +8,5 @@
 int main (void)
 {
-    plan_tests(48);
+    plan_tests(72);
 
     diag("psPolynomial2D Derivative tests");
@@ -109,4 +109,51 @@
     }
 
+    // test psPolynomial2D_dX (inPlace: supplied output == supplied input)
+    {
+        psMemId id = psMemGetId();
+
+        diag ("test psPolynomial2D_dX (supplied output)");
+
+        psPolynomial2D *poly = psPolynomial2DAlloc(PS_POLYNOMIAL_ORD, 2, 2);
+        ok(poly != NULL, "psPolynomial2D successfully allocated");
+        skip_start(poly == NULL, 5, "Skipping tests because psPolynomial2DAlloc() failed");
+
+        // build sample polynomial (upper-left elements only)
+        // z = 5 + 2x + 3y - 3x^2 + 4xy - 2y^2
+        // dz/dx = 2 - 6x + 4y
+        poly->coeff[0][0] = 5.0;
+        poly->coeff[1][0] = 2.0;
+        poly->coeff[0][1] = 3.0;
+        poly->coeff[2][0] = -3.0;
+        poly->coeff[1][1] = 4.0;
+        poly->coeff[0][2] = -2.0;
+
+        // mask remaining elements
+        poly->mask[2][1] = 1;
+        poly->mask[1][2] = 1;
+        poly->mask[2][2] = 1;
+
+        poly = psPolynomial2D_dX (poly, poly);
+
+        ok(poly->nX == 1, "new x order is %d", poly->nX);
+        ok(poly->nY == 2, "new y order is %d", poly->nY);
+
+        ok_float(poly->coeff[0][0], +2.0, "x^0 y^0 coeff is %f", poly->coeff[0][0]);
+        ok_float(poly->coeff[1][0], -6.0, "x^1 y^0 coeff is %f", poly->coeff[1][0]);
+        ok_float(poly->coeff[0][1], +4.0, "x^0 y^1 coeff is %f", poly->coeff[0][1]);
+
+        ok(!poly->mask[0][0], "x^0 y^0 coeff is unmasked");
+        ok(!poly->mask[1][0], "x^1 y^0 coeff is unmasked");
+        ok(!poly->mask[0][1], "x^0 y^1 coeff is unmasked");
+
+        ok(poly->mask[1][1], "x^1 y^1 coeff is masked");
+        ok(poly->mask[1][2], "x^1 y^2 coeff is masked");
+
+        psFree (poly);
+
+        skip_end();
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
     // test psPolynomial2D_dY (no supplied output)
     {
@@ -136,6 +183,6 @@
         psPolynomial2D *dY = psPolynomial2D_dY (NULL, poly);
 
-        ok(dY->nX == 1, "new x order is %d", dY->nX);
-        ok(dY->nY == 2, "new y order is %d", dY->nY);
+        ok(dY->nX == 2, "new x order is %d", dY->nX);
+        ok(dY->nY == 1, "new y order is %d", dY->nY);
 
         ok_float(dY->coeff[0][0], +3.0, "x^0 y^0 coeff is %f", dY->coeff[0][0]);
@@ -185,6 +232,6 @@
         psPolynomial2D_dY (dY, poly);
 
-        ok(dY->nX == 1, "new x order is %d", dY->nX);
-        ok(dY->nY == 2, "new y order is %d", dY->nY);
+        ok(dY->nX == 2, "new x order is %d", dY->nX);
+        ok(dY->nY == 1, "new y order is %d", dY->nY);
 
         ok_float(dY->coeff[0][0], +3.0, "x^0 y^0 coeff is %f", dY->coeff[0][0]);
@@ -206,4 +253,51 @@
     }
 
+    // test psPolynomial2D_dY (supplied output)
+    {
+        psMemId id = psMemGetId();
+
+        diag ("test psPolynomial2D_dY (supplied output)");
+
+        psPolynomial2D *poly = psPolynomial2DAlloc(PS_POLYNOMIAL_ORD, 2, 2);
+        ok(poly != NULL, "psPolynomial2D successfully allocated");
+        skip_start(poly == NULL, 5, "Skipping tests because psPolynomial2DAlloc() failed");
+
+        // build sample polynomial (upper-left elements only)
+        // z = 5 + 2x + 3y - 3x^2 + 4xy - 2y^2
+        // dz/dy = 3 + 4x - 4y
+        poly->coeff[0][0] = 5.0;
+        poly->coeff[1][0] = 2.0;
+        poly->coeff[0][1] = 3.0;
+        poly->coeff[2][0] = -3.0;
+        poly->coeff[1][1] = 4.0;
+        poly->coeff[0][2] = -2.0;
+
+        // mask remaining elements
+        poly->mask[2][1] = 1;
+        poly->mask[1][2] = 1;
+        poly->mask[2][2] = 1;
+
+        poly = psPolynomial2D_dY (poly, poly);
+
+        ok(poly->nX == 2, "new x order is %d", poly->nX);
+        ok(poly->nY == 1, "new y order is %d", poly->nY);
+
+        ok_float(poly->coeff[0][0], +3.0, "x^0 y^0 coeff is %f", poly->coeff[0][0]);
+        ok_float(poly->coeff[1][0], +4.0, "x^1 y^0 coeff is %f", poly->coeff[1][0]);
+        ok_float(poly->coeff[0][1], -4.0, "x^0 y^1 coeff is %f", poly->coeff[0][1]);
+
+        ok(!poly->mask[0][0], "x^0 y^0 coeff is unmasked");
+        ok(!poly->mask[1][0], "x^1 y^0 coeff is unmasked");
+        ok(!poly->mask[0][1], "x^0 y^1 coeff is unmasked");
+
+        ok(poly->mask[1][1], "x^1 y^1 coeff is masked");
+        ok(poly->mask[1][2], "x^1 y^2 coeff is masked");
+
+        psFree (poly);
+
+        skip_end();
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
     return exit_status();
 }
