Index: /trunk/psModules/src/pmObjects.c
===================================================================
--- /trunk/psModules/src/pmObjects.c	(revision 3513)
+++ /trunk/psModules/src/pmObjects.c	(revision 3514)
@@ -5,6 +5,6 @@
  *  @author GLG, MHPCC
  *
- *  @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2005-03-25 23:23:29 $
+ *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-03-26 03:44:31 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -1082,10 +1082,4 @@
 XXX: This should probably be a public function.
  
-XXX: We don't care about the model derivatives here.  So, for the individual
-model evaluation functions, we should probably separate the derivative
-calculation.
- 
-XXX: Get rid of deriv.
- 
 XXX: Use static vectors for x.
  
@@ -1096,7 +1090,4 @@
                 psU32 col)
 {
-    // XXX: You won't need this once you separate the function evaluation.
-    // from the derivative calculation.
-    psVector *deriv = psVectorAlloc(src->models->Nparams, PS_TYPE_F32);
     // XXX: The following step will not be necessary if the models->params
     // member is a psVector.
@@ -1113,20 +1104,20 @@
     switch (src->models->type) {
     case PS_MODEL_GAUSS:
-        tmpF = pmMinLM_Gauss2D(deriv, params, x);
+        tmpF = pmMinLM_Gauss2D(NULL, params, x);
         break;
     case PS_MODEL_PGAUSS:
-        tmpF = pmMinLM_PsuedoGauss2D(deriv, params, x);
+        tmpF = pmMinLM_PsuedoGauss2D(NULL, params, x);
         break;
     case PS_MODEL_TWIST_GAUSS:
-        tmpF = pmMinLM_TwistGauss2D(deriv, params, x);
+        tmpF = pmMinLM_TwistGauss2D(NULL, params, x);
         break;
     case PS_MODEL_WAUSS:
-        tmpF = pmMinLM_Wauss2D(deriv, params, x);
+        tmpF = pmMinLM_Wauss2D(NULL, params, x);
         break;
     case PS_MODEL_SERSIC:
-        tmpF = pmMinLM_Sersic(deriv, params, x);
+        tmpF = pmMinLM_Sersic(NULL, params, x);
         break;
     case PS_MODEL_SERSIC_CORE:
-        tmpF = pmMinLM_SersicCore(deriv, params, x);
+        tmpF = pmMinLM_SersicCore(NULL, params, x);
         break;
     default:
@@ -1135,5 +1126,4 @@
     }
 
-    psFree(deriv);
     psFree(params);
     psFree(x);
@@ -1388,5 +1378,4 @@
     #define MAX_PARAMS 100
 
-    psVector *deriv = psVectorAlloc(MAX_PARAMS, PS_TYPE_F32);
     psVector *params = psVectorAlloc(MAX_PARAMS, PS_TYPE_F32);
     psVector *x = psVectorAlloc(2, PS_TYPE_F32);
@@ -1410,25 +1399,24 @@
             switch (src->models->type) {
             case PS_MODEL_GAUSS:
-                pixelValue = pmMinLM_Gauss2D(deriv, params, x);
+                pixelValue = pmMinLM_Gauss2D(NULL, params, x);
                 break;
             case PS_MODEL_PGAUSS:
-                pixelValue = pmMinLM_PsuedoGauss2D(deriv, params, x);
+                pixelValue = pmMinLM_PsuedoGauss2D(NULL, params, x);
                 break;
             case PS_MODEL_TWIST_GAUSS:
-                pixelValue = pmMinLM_TwistGauss2D(deriv, params, x);
+                pixelValue = pmMinLM_TwistGauss2D(NULL, params, x);
                 break;
             case PS_MODEL_WAUSS:
-                pixelValue = pmMinLM_Wauss2D(deriv, params, x);
+                pixelValue = pmMinLM_Wauss2D(NULL, params, x);
                 break;
             case PS_MODEL_SERSIC:
-                pixelValue = pmMinLM_Sersic(deriv, params, x);
+                pixelValue = pmMinLM_Sersic(NULL, params, x);
                 break;
             case PS_MODEL_SERSIC_CORE:
-                pixelValue = pmMinLM_SersicCore(deriv, params, x);
+                pixelValue = pmMinLM_SersicCore(NULL, params, x);
                 break;
             default:
                 psError(PS_ERR_UNKNOWN, true, "Undefined psModelType");
                 psFree(x);
-                psFree(deriv);
                 psFree(params);
                 return(false);
@@ -1447,5 +1435,4 @@
     }
     psFree(x);
-    psFree(deriv);
     psFree(params);
     return(true);
@@ -1499,4 +1486,7 @@
 XXX: Consider getting rid of the parameter checks since this might consume
 a significant fraction of this function CPU time.
+ 
+XXX: I added the following.  Must conform with IfA.  If deriv==NULL, then
+we simply don't perform the derivative calculations.
  *****************************************************************************/
 psF32 pmMinLM_Gauss2D(psVector *deriv,
@@ -1504,7 +1494,4 @@
                       psVector *x)
 {
-    PS_VECTOR_CHECK_NULL(deriv, NAN);
-    PS_VECTOR_CHECK_TYPE(deriv, PS_TYPE_F32, NAN);
-    PS_VECTOR_CHECK_SIZE(deriv, 7, NAN);
     PS_VECTOR_CHECK_NULL(params, NAN);
     PS_VECTOR_CHECK_TYPE(params, PS_TYPE_F32, NAN);
@@ -1522,12 +1509,17 @@
     psF32 f = params->data.F32[1]*r + params->data.F32[0];
 
-    psF32 q = params->data.F32[1]*r;
-    deriv->data.F32[0] = +1.0;
-    deriv->data.F32[1] = +r;
-    deriv->data.F32[2] = q*(2*px*params->data.F32[4] + params->data.F32[6]*Y);
-    deriv->data.F32[3] = q*(2*py*params->data.F32[5] + params->data.F32[6]*X);
-    deriv->data.F32[4] = -2.0*q*px*X;
-    deriv->data.F32[5] = -2.0*q*py*Y;
-    deriv->data.F32[6] = -q*X*Y;
+    if (deriv != NULL) {
+        PS_VECTOR_CHECK_TYPE(deriv, PS_TYPE_F32, NAN);
+        PS_VECTOR_CHECK_SIZE(deriv, 7, NAN);
+
+        psF32 q = params->data.F32[1]*r;
+        deriv->data.F32[0] = +1.0;
+        deriv->data.F32[1] = +r;
+        deriv->data.F32[2] = q*(2*px*params->data.F32[4] + params->data.F32[6]*Y);
+        deriv->data.F32[3] = q*(2*py*params->data.F32[5] + params->data.F32[6]*X);
+        deriv->data.F32[4] = -2.0*q*px*X;
+        deriv->data.F32[5] = -2.0*q*py*Y;
+        deriv->data.F32[6] = -q*X*Y;
+    }
 
     return(f);
@@ -1588,7 +1580,4 @@
                             psVector *x)
 {
-    PS_VECTOR_CHECK_NULL(deriv, NAN);
-    PS_VECTOR_CHECK_TYPE(deriv, PS_TYPE_F32, NAN);
-    PS_VECTOR_CHECK_SIZE(deriv, 7, NAN);
     PS_VECTOR_CHECK_NULL(params, NAN);
     PS_VECTOR_CHECK_TYPE(params, PS_TYPE_F32, NAN);
@@ -1607,17 +1596,21 @@
     psF32 f = params->data.F32[1]*r + params->data.F32[0];
 
-    //
-    // note difference from a pure gaussian: q = params->data.F32[1]*r
-    //
-
-    psF32 q = params->data.F32[1]*r*r*t;
-    deriv->data.F32[0] = +1.0;
-    deriv->data.F32[1] = +r;
-    deriv->data.F32[2] = q*(2.0*px*params->data.F32[4] + params->data.F32[6]*Y);
-    deriv->data.F32[3] = q *
-                         (2.0*py*params->data.F32[5] + params->data.F32[6]*X);
-    deriv->data.F32[4] = -2.0*q*px*X;
-    deriv->data.F32[5] = -2.0*q*py*Y;
-    deriv->data.F32[6] = -q*X*Y;
+    if (deriv != NULL) {
+        PS_VECTOR_CHECK_TYPE(deriv, PS_TYPE_F32, NAN);
+        PS_VECTOR_CHECK_SIZE(deriv, 7, NAN);
+
+        //
+        // note difference from a pure gaussian: q = params->data.F32[1]*r
+        //
+        psF32 q = params->data.F32[1]*r*r*t;
+        deriv->data.F32[0] = +1.0;
+        deriv->data.F32[1] = +r;
+        deriv->data.F32[2] = q*(2.0*px*params->data.F32[4] + params->data.F32[6]*Y);
+        deriv->data.F32[3] = q *
+                             (2.0*py*params->data.F32[5] + params->data.F32[6]*X);
+        deriv->data.F32[4] = -2.0*q*px*X;
+        deriv->data.F32[5] = -2.0*q*py*Y;
+        deriv->data.F32[6] = -q*X*Y;
+    }
 
     return(f);
@@ -1682,7 +1675,4 @@
                       psVector *x)
 {
-    PS_VECTOR_CHECK_NULL(deriv, NAN);
-    PS_VECTOR_CHECK_TYPE(deriv, PS_TYPE_F32, NAN);
-    PS_VECTOR_CHECK_SIZE(deriv, 9, NAN);
     PS_VECTOR_CHECK_NULL(params, NAN);
     PS_VECTOR_CHECK_TYPE(params, PS_TYPE_F32, NAN);
@@ -1701,20 +1691,25 @@
     psF32 f = params->data.F32[1]*r + params->data.F32[0];
 
-    //
-    // note difference from gaussian: q = params->data.F32[1]*r
-    //
-    psF32 q = params->data.F32[1]*r*r*(1.0 + params->data.F32[7]*z*(1.0 + params->data.F32[8]*z/2.0));
-    deriv->data.F32[0] = +1.0;
-    deriv->data.F32[1] = +r;
-    deriv->data.F32[2] = q*(2.0*px*params->data.F32[4] + params->data.F32[6]*Y);
-    deriv->data.F32[3] = q*(2.0*py*params->data.F32[5] + params->data.F32[6]*X);
-    deriv->data.F32[4] = -2.0*q*px*X;
-    deriv->data.F32[5] = -2.0*q*py*Y;
-    deriv->data.F32[6] = -q*X*Y;
-    deriv->data.F32[7] = -100.0*params->data.F32[1]*r*r*t;
-    deriv->data.F32[8] = -100.0*params->data.F32[1]*r*r*params->data.F32[7]*(z*z*z)/6.0;
-    //
-    // The values of 100 dampen the swing of params->data.F32[7,8] */
-    //
+    if (deriv != NULL) {
+        PS_VECTOR_CHECK_TYPE(deriv, PS_TYPE_F32, NAN);
+        PS_VECTOR_CHECK_SIZE(deriv, 9, NAN);
+        //
+        // note difference from gaussian: q = params->data.F32[1]*r
+        //
+
+        psF32 q = params->data.F32[1]*r*r*(1.0 + params->data.F32[7]*z*(1.0 + params->data.F32[8]*z/2.0));
+        deriv->data.F32[0] = +1.0;
+        deriv->data.F32[1] = +r;
+        deriv->data.F32[2] = q*(2.0*px*params->data.F32[4] + params->data.F32[6]*Y);
+        deriv->data.F32[3] = q*(2.0*py*params->data.F32[5] + params->data.F32[6]*X);
+        deriv->data.F32[4] = -2.0*q*px*X;
+        deriv->data.F32[5] = -2.0*q*py*Y;
+        deriv->data.F32[6] = -q*X*Y;
+        deriv->data.F32[7] = -100.0*params->data.F32[1]*r*r*t;
+        deriv->data.F32[8] = -100.0*params->data.F32[1]*r*r*params->data.F32[7]*(z*z*z)/6.0;
+        //
+        // The values of 100 dampen the swing of params->data.F32[7,8] */
+        //
+    }
 
     return(f);
@@ -1786,7 +1781,4 @@
                            psVector *x)
 {
-    PS_VECTOR_CHECK_NULL(deriv, NAN);
-    PS_VECTOR_CHECK_TYPE(deriv, PS_TYPE_F32, NAN);
-    PS_VECTOR_CHECK_SIZE(deriv, 11, NAN);
     PS_VECTOR_CHECK_NULL(params, NAN);
     PS_VECTOR_CHECK_TYPE(params, PS_TYPE_F32, NAN);
@@ -1808,31 +1800,37 @@
 
     psF32 f = params->data.F32[5]*r + params->data.F32[6];
-    psF32 q1 = params->data.F32[5]*PS_SQR(r);
-    psF32 q2 = params->data.F32[5]*PS_SQR(r)*params->data.F32[10]*pow(z2,(params->data.F32[10]-1.0));
-    deriv->data.F32[0] = +1.0;
-    deriv->data.F32[1] = +r;
-    deriv->data.F32[2] = q1*(2.0*px1*params->data.F32[4] + params->data.F32[6]*Y) + q2*(2*px2*params->data.F32[7] + params->data.F32[9]*Y);
-    deriv->data.F32[3] = q1*(2.0*py1*params->data.F32[5] + params->data.F32[6]*X) + q2*(2*py2*params->data.F32[8] + params->data.F32[9]*X);
-
-    //
-    // These fudge factors impede the growth of params->data.F32[4] beyond
-    // params->data.F32[7].
-    //
-    psF32 f1 = fabs(params->data.F32[7]) / fabs(params->data.F32[4]);
-    psF32 f2 = (f1 < FSCALE) ? 1.0 : FFACTOR*(f1 - FSCALE) + 1.0;
-    deriv->data.F32[4] = -2.0*q1*px1*X*f2;
-
-    //
-    // These fudge factors impede the growth of params->data.F32[5] beyond
-    // params->data.F32[8].
-    //
-    f1 = fabs(params->data.F32[8]) / fabs(params->data.F32[5]);
-    f2 = (f1 < FSCALE) ? 1.0 : FFACTOR*(f1 - FSCALE) + 1.0;
-    deriv->data.F32[5] = -2.0*q1*py1*Y*f2;
-    deriv->data.F32[6] = -q1*X*Y;
-    deriv->data.F32[7] = -2.0*q2*px2*X;
-    deriv->data.F32[8] = -2.0*q2*py2*Y;
-    deriv->data.F32[9] = -q2*X*Y;
-    deriv->data.F32[10] = -q1*log(z2);
+
+    if (deriv != NULL) {
+        PS_VECTOR_CHECK_TYPE(deriv, PS_TYPE_F32, NAN);
+        PS_VECTOR_CHECK_SIZE(deriv, 11, NAN);
+
+        psF32 q1 = params->data.F32[5]*PS_SQR(r);
+        psF32 q2 = params->data.F32[5]*PS_SQR(r)*params->data.F32[10]*pow(z2,(params->data.F32[10]-1.0));
+        deriv->data.F32[0] = +1.0;
+        deriv->data.F32[1] = +r;
+        deriv->data.F32[2] = q1*(2.0*px1*params->data.F32[4] + params->data.F32[6]*Y) + q2*(2*px2*params->data.F32[7] + params->data.F32[9]*Y);
+        deriv->data.F32[3] = q1*(2.0*py1*params->data.F32[5] + params->data.F32[6]*X) + q2*(2*py2*params->data.F32[8] + params->data.F32[9]*X);
+
+        //
+        // These fudge factors impede the growth of params->data.F32[4] beyond
+        // params->data.F32[7].
+        //
+        psF32 f1 = fabs(params->data.F32[7]) / fabs(params->data.F32[4]);
+        psF32 f2 = (f1 < FSCALE) ? 1.0 : FFACTOR*(f1 - FSCALE) + 1.0;
+        deriv->data.F32[4] = -2.0*q1*px1*X*f2;
+
+        //
+        // These fudge factors impede the growth of params->data.F32[5] beyond
+        // params->data.F32[8].
+        //
+        f1 = fabs(params->data.F32[8]) / fabs(params->data.F32[5]);
+        f2 = (f1 < FSCALE) ? 1.0 : FFACTOR*(f1 - FSCALE) + 1.0;
+        deriv->data.F32[5] = -2.0*q1*py1*Y*f2;
+        deriv->data.F32[6] = -q1*X*Y;
+        deriv->data.F32[7] = -2.0*q2*px2*X;
+        deriv->data.F32[8] = -2.0*q2*py2*Y;
+        deriv->data.F32[9] = -q2*X*Y;
+        deriv->data.F32[10] = -q1*log(z2);
+    }
 
     return(f);
@@ -1896,7 +1894,4 @@
                      psVector *x)
 {
-    PS_VECTOR_CHECK_NULL(deriv, NAN);
-    PS_VECTOR_CHECK_TYPE(deriv, PS_TYPE_F32, NAN);
-    PS_VECTOR_CHECK_SIZE(deriv, 8, NAN);
     PS_VECTOR_CHECK_NULL(params, NAN);
     PS_VECTOR_CHECK_TYPE(params, PS_TYPE_F32, NAN);
@@ -1905,4 +1900,9 @@
     PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F32, NAN);
     PS_VECTOR_CHECK_SIZE(x, 2, NAN);
+
+    if (deriv != NULL) {
+        PS_VECTOR_CHECK_TYPE(deriv, PS_TYPE_F32, NAN);
+        PS_VECTOR_CHECK_SIZE(deriv, 8, NAN);
+    }
 
     psError(PS_ERR_UNKNOWN, true, "This function is not implemented yet.");
@@ -1968,7 +1968,4 @@
                          psVector *x)
 {
-    PS_VECTOR_CHECK_NULL(deriv, NAN);
-    PS_VECTOR_CHECK_TYPE(deriv, PS_TYPE_F32, NAN);
-    PS_VECTOR_CHECK_SIZE(deriv, 12, NAN);
     PS_VECTOR_CHECK_NULL(params, NAN);
     PS_VECTOR_CHECK_TYPE(params, PS_TYPE_F32, NAN);
@@ -1977,4 +1974,9 @@
     PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F32, NAN);
     PS_VECTOR_CHECK_SIZE(x, 2, NAN);
+
+    if (deriv != NULL) {
+        PS_VECTOR_CHECK_TYPE(deriv, PS_TYPE_F32, NAN);
+        PS_VECTOR_CHECK_SIZE(deriv, 12, NAN);
+    }
 
     psError(PS_ERR_UNKNOWN, true, "This function is not implemented yet.");
