diff -bru levmar-2.4/Axb_core.c levmar-2.4.new_errors/Axb_core.c
--- levmar-2.4/Axb_core.c	2009-04-29 12:05:01.000000000 +0200
+++ levmar-2.4.new_errors/Axb_core.c	2009-09-01 10:44:40.000000000 +0200
@@ -146,7 +146,7 @@
       buf_sz=tot_sz;
       buf=(LM_REAL *)malloc(buf_sz*sizeof(LM_REAL));
       if(!buf){
-        fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_QR) "() failed!\n");
+        PRINT_ERROR(RCAT("memory allocation in ", AX_EQ_B_QR) "() failed!\n");
         exit(1);
       }
     }
@@ -154,7 +154,7 @@
       buf_sz=tot_sz;
       buf=(LM_REAL *)malloc(buf_sz*sizeof(LM_REAL));
       if(!buf){
-        fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_QR) "() failed!\n");
+        PRINT_ERROR(RCAT("memory allocation in ", AX_EQ_B_QR) "() failed!\n");
         exit(1);
       }
 #endif /* LINSOLVERS_RETAIN_MEMORY */
@@ -175,11 +175,11 @@
   /* error treatment */
   if(info!=0){
     if(info<0){
-      fprintf(stderr, RCAT(RCAT("LAPACK error: illegal value for argument %d of ", GEQRF) " in ", AX_EQ_B_QR) "()\n", -info);
+      PRINT_ERROR(RCAT(RCAT("LAPACK error: illegal value for argument %d of ", GEQRF) " in ", AX_EQ_B_QR) "()\n", -info);
       exit(1);
     }
     else{
-      fprintf(stderr, RCAT(RCAT("Unknown LAPACK error %d for ", GEQRF) " in ", AX_EQ_B_QR) "()\n", info);
+      PRINT_ERROR(RCAT(RCAT("Unknown LAPACK error %d for ", GEQRF) " in ", AX_EQ_B_QR) "()\n", info);
 #ifndef LINSOLVERS_RETAIN_MEMORY
       free(buf);
 #endif
@@ -196,11 +196,11 @@
   ORGQR((int *)&m, (int *)&m, (int *)&m, a, (int *)&m, tau, work, (int *)&worksz, (int *)&info);
   if(info!=0){
     if(info<0){
-      fprintf(stderr, RCAT(RCAT("LAPACK error: illegal value for argument %d of ", ORGQR) " in ", AX_EQ_B_QR) "()\n", -info);
+      PRINT_ERROR(RCAT(RCAT("LAPACK error: illegal value for argument %d of ", ORGQR) " in ", AX_EQ_B_QR) "()\n", -info);
       exit(1);
     }
     else{
-      fprintf(stderr, RCAT("Unknown LAPACK error (%d) in ", AX_EQ_B_QR) "()\n", info);
+      PRINT_ERROR(RCAT("Unknown LAPACK error (%d) in ", AX_EQ_B_QR) "()\n", info);
 #ifndef LINSOLVERS_RETAIN_MEMORY
       free(buf);
 #endif
@@ -221,11 +221,11 @@
   /* error treatment */
   if(info!=0){
     if(info<0){
-      fprintf(stderr, RCAT(RCAT("LAPACK error: illegal value for argument %d of ", TRTRS) " in ", AX_EQ_B_QR) "()\n", -info);
+      PRINT_ERROR(RCAT(RCAT("LAPACK error: illegal value for argument %d of ", TRTRS) " in ", AX_EQ_B_QR) "()\n", -info);
       exit(1);
     }
     else{
-      fprintf(stderr, RCAT("LAPACK error: the %d-th diagonal element of A is zero (singular matrix) in ", AX_EQ_B_QR) "()\n", info);
+      PRINT_ERROR(RCAT("LAPACK error: the %d-th diagonal element of A is zero (singular matrix) in ", AX_EQ_B_QR) "()\n", info);
 #ifndef LINSOLVERS_RETAIN_MEMORY
       free(buf);
 #endif
@@ -291,7 +291,7 @@
 #endif /* LINSOLVERS_RETAIN_MEMORY */
    
     if(m<n){
-		  fprintf(stderr, RCAT("Normal equations require that the number of rows is greater than number of columns in ", AX_EQ_B_QRLS) "() [%d x %d]! -- try transposing\n", m, n);
+		  PRINT_ERROR(RCAT("Normal equations require that the number of rows is greater than number of columns in ", AX_EQ_B_QRLS) "() [%d x %d]! -- try transposing\n", m, n);
 		  exit(1);
 	  }
       
@@ -317,7 +317,7 @@
       buf_sz=tot_sz;
       buf=(LM_REAL *)malloc(buf_sz*sizeof(LM_REAL));
       if(!buf){
-        fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_QRLS) "() failed!\n");
+        PRINT_ERROR(RCAT("memory allocation in ", AX_EQ_B_QRLS) "() failed!\n");
         exit(1);
       }
     }
@@ -325,7 +325,7 @@
       buf_sz=tot_sz;
       buf=(LM_REAL *)malloc(buf_sz*sizeof(LM_REAL));
       if(!buf){
-        fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_QRLS) "() failed!\n");
+        PRINT_ERROR(RCAT("memory allocation in ", AX_EQ_B_QRLS) "() failed!\n");
         exit(1);
       }
 #endif /* LINSOLVERS_RETAIN_MEMORY */
@@ -353,11 +353,11 @@
   /* error treatment */
   if(info!=0){
     if(info<0){
-      fprintf(stderr, RCAT(RCAT("LAPACK error: illegal value for argument %d of ", GEQRF) " in ", AX_EQ_B_QRLS) "()\n", -info);
+      PRINT_ERROR(RCAT(RCAT("LAPACK error: illegal value for argument %d of ", GEQRF) " in ", AX_EQ_B_QRLS) "()\n", -info);
       exit(1);
     }
     else{
-      fprintf(stderr, RCAT(RCAT("Unknown LAPACK error %d for ", GEQRF) " in ", AX_EQ_B_QRLS) "()\n", info);
+      PRINT_ERROR(RCAT(RCAT("Unknown LAPACK error %d for ", GEQRF) " in ", AX_EQ_B_QRLS) "()\n", info);
 #ifndef LINSOLVERS_RETAIN_MEMORY
       free(buf);
 #endif
@@ -381,11 +381,11 @@
   /* error treatment */
   if(info!=0){
     if(info<0){
-      fprintf(stderr, RCAT(RCAT("LAPACK error: illegal value for argument %d of ", TRTRS) " in ", AX_EQ_B_QRLS) "()\n", -info);
+      PRINT_ERROR(RCAT(RCAT("LAPACK error: illegal value for argument %d of ", TRTRS) " in ", AX_EQ_B_QRLS) "()\n", -info);
       exit(1);
     }
     else{
-      fprintf(stderr, RCAT("LAPACK error: the %d-th diagonal element of A is zero (singular matrix) in ", AX_EQ_B_QRLS) "()\n", info);
+      PRINT_ERROR(RCAT("LAPACK error: the %d-th diagonal element of A is zero (singular matrix) in ", AX_EQ_B_QRLS) "()\n", info);
 #ifndef LINSOLVERS_RETAIN_MEMORY
       free(buf);
 #endif
@@ -399,11 +399,11 @@
   /* error treatment */
   if(info!=0){
     if(info<0){
-      fprintf(stderr, RCAT(RCAT("LAPACK error: illegal value for argument %d of ", TRTRS) " in ", AX_EQ_B_QRLS) "()\n", -info);
+      PRINT_ERROR(RCAT(RCAT("LAPACK error: illegal value for argument %d of ", TRTRS) " in ", AX_EQ_B_QRLS) "()\n", -info);
       exit(1);
     }
     else{
-      fprintf(stderr, RCAT("LAPACK error: the %d-th diagonal element of A is zero (singular matrix) in ", AX_EQ_B_QRLS) "()\n", info);
+      PRINT_ERROR(RCAT("LAPACK error: the %d-th diagonal element of A is zero (singular matrix) in ", AX_EQ_B_QRLS) "()\n", info);
 #ifndef LINSOLVERS_RETAIN_MEMORY
       free(buf);
 #endif
@@ -476,7 +476,7 @@
       buf_sz=tot_sz;
       buf=(LM_REAL *)malloc(buf_sz*sizeof(LM_REAL));
       if(!buf){
-        fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_CHOL) "() failed!\n");
+        PRINT_ERROR(RCAT("memory allocation in ", AX_EQ_B_CHOL) "() failed!\n");
         exit(1);
       }
     }
@@ -484,7 +484,7 @@
       buf_sz=tot_sz;
       buf=(LM_REAL *)malloc(buf_sz*sizeof(LM_REAL));
       if(!buf){
-        fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_CHOL) "() failed!\n");
+        PRINT_ERROR(RCAT("memory allocation in ", AX_EQ_B_CHOL) "() failed!\n");
         exit(1);
       }
 #endif /* LINSOLVERS_RETAIN_MEMORY */
@@ -508,12 +508,12 @@
   /* error treatment */
   if(info!=0){
     if(info<0){
-      fprintf(stderr, RCAT(RCAT(RCAT("LAPACK error: illegal value for argument %d of ", POTF2) "/", POTRF) " in ",
+      PRINT_ERROR(RCAT(RCAT(RCAT("LAPACK error: illegal value for argument %d of ", POTF2) "/", POTRF) " in ",
                       AX_EQ_B_CHOL) "()\n", -info);
       exit(1);
     }
     else{
-      fprintf(stderr, RCAT(RCAT(RCAT("LAPACK error: the leading minor of order %d is not positive definite,\nthe factorization could not be completed for ", POTF2) "/", POTRF) " in ", AX_EQ_B_CHOL) "()\n", info);
+      PRINT_ERROR(RCAT(RCAT(RCAT("LAPACK error: the leading minor of order %d is not positive definite,\nthe factorization could not be completed for ", POTF2) "/", POTRF) " in ", AX_EQ_B_CHOL) "()\n", info);
 #ifndef LINSOLVERS_RETAIN_MEMORY
       free(buf);
 #endif
@@ -525,7 +525,7 @@
   /* solve using the computed Cholesky in one lapack call */
   POTRS("U", (int *)&m, (int *)&nrhs, a, (int *)&m, b, (int *)&m, &info);
   if(info<0){
-    fprintf(stderr, RCAT(RCAT("LAPACK error: illegal value for argument %d of ", POTRS) " in ", AX_EQ_B_CHOL) "()\n", -info);
+    PRINT_ERROR(RCAT(RCAT("LAPACK error: illegal value for argument %d of ", POTRS) " in ", AX_EQ_B_CHOL) "()\n", -info);
     exit(1);
   }
 
@@ -535,11 +535,11 @@
   /* error treatment */
   if(info!=0){
     if(info<0){
-      fprintf(stderr, RCAT(RCAT("LAPACK error: illegal value for argument %d of ", TRTRS) " in ", AX_EQ_B_CHOL) "()\n", -info);
+      PRINT_ERROR(RCAT(RCAT("LAPACK error: illegal value for argument %d of ", TRTRS) " in ", AX_EQ_B_CHOL) "()\n", -info);
       exit(1);
     }
     else{
-      fprintf(stderr, RCAT("LAPACK error: the %d-th diagonal element of A is zero (singular matrix) in ", AX_EQ_B_CHOL) "()\n", info);
+      PRINT_ERROR(RCAT("LAPACK error: the %d-th diagonal element of A is zero (singular matrix) in ", AX_EQ_B_CHOL) "()\n", info);
 #ifndef LINSOLVERS_RETAIN_MEMORY
       free(buf);
 #endif
@@ -553,11 +553,11 @@
   /* error treatment */
   if(info!=0){
     if(info<0){
-      fprintf(stderr, RCAT(RCAT("LAPACK error: illegal value for argument %d of ", TRTRS) "in ", AX_EQ_B_CHOL) "()\n", -info);
+      PRINT_ERROR(RCAT(RCAT("LAPACK error: illegal value for argument %d of ", TRTRS) "in ", AX_EQ_B_CHOL) "()\n", -info);
       exit(1);
     }
     else{
-      fprintf(stderr, RCAT("LAPACK error: the %d-th diagonal element of A is zero (singular matrix) in ", AX_EQ_B_CHOL) "()\n", info);
+      PRINT_ERROR(RCAT("LAPACK error: the %d-th diagonal element of A is zero (singular matrix) in ", AX_EQ_B_CHOL) "()\n", info);
 #ifndef LINSOLVERS_RETAIN_MEMORY
       free(buf);
 #endif
@@ -631,7 +631,7 @@
       buf_sz=tot_sz;
       buf=(LM_REAL *)malloc(buf_sz);
       if(!buf){
-        fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_LU) "() failed!\n");
+        PRINT_ERROR(RCAT("memory allocation in ", AX_EQ_B_LU) "() failed!\n");
         exit(1);
       }
     }
@@ -639,7 +639,7 @@
       buf_sz=tot_sz;
       buf=(LM_REAL *)malloc(buf_sz);
       if(!buf){
-        fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_LU) "() failed!\n");
+        PRINT_ERROR(RCAT("memory allocation in ", AX_EQ_B_LU) "() failed!\n");
         exit(1);
       }
 #endif /* LINSOLVERS_RETAIN_MEMORY */
@@ -660,11 +660,11 @@
 	GETRF((int *)&m, (int *)&m, a, (int *)&m, ipiv, (int *)&info);  
 	if(info!=0){
 		if(info<0){
-      fprintf(stderr, RCAT(RCAT("argument %d of ", GETRF) " illegal in ", AX_EQ_B_LU) "()\n", -info);
+      PRINT_ERROR(RCAT(RCAT("argument %d of ", GETRF) " illegal in ", AX_EQ_B_LU) "()\n", -info);
 			exit(1);
 		}
 		else{
-      fprintf(stderr, RCAT(RCAT("singular matrix A for ", GETRF) " in ", AX_EQ_B_LU) "()\n");
+      PRINT_ERROR(RCAT(RCAT("singular matrix A for ", GETRF) " in ", AX_EQ_B_LU) "()\n");
 #ifndef LINSOLVERS_RETAIN_MEMORY
       free(buf);
 #endif
@@ -677,11 +677,11 @@
   GETRS("N", (int *)&m, (int *)&nrhs, a, (int *)&m, ipiv, b, (int *)&m, (int *)&info);
 	if(info!=0){
 		if(info<0){
-			fprintf(stderr, RCAT(RCAT("argument %d of ", GETRS) " illegal in ", AX_EQ_B_LU) "()\n", -info);
+			PRINT_ERROR(RCAT(RCAT("argument %d of ", GETRS) " illegal in ", AX_EQ_B_LU) "()\n", -info);
 			exit(1);
 		}
 		else{
-			fprintf(stderr, RCAT(RCAT("unknown error for ", GETRS) " in ", AX_EQ_B_LU) "()\n");
+			PRINT_ERROR(RCAT(RCAT("unknown error for ", GETRS) " in ", AX_EQ_B_LU) "()\n");
 #ifndef LINSOLVERS_RETAIN_MEMORY
       free(buf);
 #endif
@@ -769,7 +769,7 @@
     buf_sz=tot_sz;
     buf=(LM_REAL *)malloc(buf_sz);
     if(!buf){
-      fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_SVD) "() failed!\n");
+      PRINT_ERROR(RCAT("memory allocation in ", AX_EQ_B_SVD) "() failed!\n");
       exit(1);
     }
   }
@@ -777,7 +777,7 @@
     buf_sz=tot_sz;
     buf=(LM_REAL *)malloc(buf_sz);
     if(!buf){
-      fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_SVD) "() failed!\n");
+      PRINT_ERROR(RCAT("memory allocation in ", AX_EQ_B_SVD) "() failed!\n");
       exit(1);
     }
 #endif /* LINSOLVERS_RETAIN_MEMORY */
@@ -801,11 +801,11 @@
   /* error treatment */
   if(info!=0){
     if(info<0){
-      fprintf(stderr, RCAT(RCAT(RCAT("LAPACK error: illegal value for argument %d of ", GESVD), "/" GESDD) " in ", AX_EQ_B_SVD) "()\n", -info);
+      PRINT_ERROR(RCAT(RCAT(RCAT("LAPACK error: illegal value for argument %d of ", GESVD), "/" GESDD) " in ", AX_EQ_B_SVD) "()\n", -info);
       exit(1);
     }
     else{
-      fprintf(stderr, RCAT("LAPACK error: dgesdd (dbdsdc)/dgesvd (dbdsqr) failed to converge in ", AX_EQ_B_SVD) "() [info=%d]\n", info);
+      PRINT_ERROR(RCAT("LAPACK error: dgesdd (dbdsdc)/dgesvd (dbdsqr) failed to converge in ", AX_EQ_B_SVD) "() [info=%d]\n", info);
 #ifndef LINSOLVERS_RETAIN_MEMORY
       free(buf);
 #endif
@@ -920,7 +920,7 @@
     buf_sz=tot_sz;
     buf=(void *)malloc(tot_sz);
     if(!buf){
-      fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_LU) "() failed!\n");
+      PRINT_ERROR(RCAT("memory allocation in ", AX_EQ_B_LU) "() failed!\n");
       exit(1);
     }
   }
@@ -928,7 +928,7 @@
     buf_sz=tot_sz;
     buf=(void *)malloc(tot_sz);
     if(!buf){
-      fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_LU) "() failed!\n");
+      PRINT_ERROR(RCAT("memory allocation in ", AX_EQ_B_LU) "() failed!\n");
       exit(1);
     }
 #endif /* LINSOLVERS_RETAIN_MEMORY */
@@ -958,7 +958,7 @@
 			if((tmp=FABS(a[i*m+j]))>max)
         max=tmp;
 		  if(max==0.0){
-        fprintf(stderr, RCAT("Singular matrix A in ", AX_EQ_B_LU) "()!\n");
+        PRINT_ERROR(RCAT("Singular matrix A in ", AX_EQ_B_LU) "()!\n");
 #ifndef LINSOLVERS_RETAIN_MEMORY
         free(buf);
 #endif
Only in levmar-2.4: Makefile.so
diff -bru levmar-2.4/lm.h levmar-2.4.new_errors/lm.h
--- levmar-2.4/lm.h	2009-04-24 15:03:11.000000000 +0200
+++ levmar-2.4.new_errors/lm.h	2009-09-01 13:48:54.000000000 +0200
@@ -44,6 +44,9 @@
 #define LM_DBL_PREC  /* comment this if you don't want the double precision routines to be compiled */
 #define LM_SNGL_PREC /* comment this if you don't want the single precision routines to be compiled */
 
+/* Undefine the following if you don't want errors to be printed.*/
+#define ENABLE_PRINT_ERROR
+
 /****************** End of configuration options, no changes necessary beyond this point ******************/
 
 
@@ -51,6 +54,24 @@
 extern "C" {
 #endif
 
+#ifdef ENABLE_PRINT_ERROR
+ #define PRINT_ERROR(...) (fprintf(stderr, __VA_ARGS__))
+#else
+ #define PRINT_ERROR(...)
+#endif
+
+enum lmerror
+{ LM_ERROR_LAPACK_ERROR                        = -1
+, LM_ERROR_NO_JACOBIAN                         = -2
+, LM_ERROR_NO_BOX_CONSTRAINTS                  = -3
+, LM_ERROR_FAILED_BOX_CHECK                    = -4
+, LM_ERROR_MEMORY_ALLOCATION_FAILURE           = -5
+, LM_ERROR_CONSTRAINT_MATRIX_ROWS_GT_COLS      = -6
+, LM_ERROR_CONSTRAINT_MATRIX_NOT_FULL_ROW_RANK = -7
+, LM_ERROR_TOO_FEW_MEASUREMENTS                = -8
+, LM_ERROR_SINGULAR_MATRIX                     = -9
+, LM_ERROR_SUM_OF_SQUARES_NOT_FINITE           = -10
+};
 
 #define FABS(x) (((x)>=0.0)? (x) : -(x))
 
@@ -80,7 +101,6 @@
 
 #define LM_OPTS_SZ    	 5 /* max(4, 5) */
 #define LM_INFO_SZ    	 10
-#define LM_ERROR         -1
 #define LM_INIT_MU    	 1E-03
 #define LM_STOP_THRESH	 1E-17
 #define LM_DIFF_DELTA    1E-06
diff -bru levmar-2.4/lm_core.c levmar-2.4.new_errors/lm_core.c
--- levmar-2.4/lm_core.c	2009-04-24 17:15:48.000000000 +0200
+++ levmar-2.4.new_errors/lm_core.c	2009-09-01 12:27:46.000000000 +0200
@@ -50,7 +50,7 @@
  * This function requires an analytic Jacobian. In case the latter is unavailable,
  * use LEVMAR_DIF() bellow
  *
- * Returns the number of iterations (>=0) if successful, LM_ERROR if failed
+ * Returns the number of iterations (>=0) if successful, or an error code (<0) on failure
  *
  * For more details, see K. Madsen, H.B. Nielsen and O. Tingleff's lecture notes on 
  * non-linear least squares at http://www.imm.dtu.dk/pubdb/views/edoc_download.php/3215/pdf/imm3215.pdf
@@ -114,14 +114,14 @@
   mu=jacTe_inf=0.0; /* -Wall */
 
   if(n<m){
-    fprintf(stderr, LCAT(LEVMAR_DER, "(): cannot solve a problem with fewer measurements [%d] than unknowns [%d]\n"), n, m);
-    return LM_ERROR;
+    PRINT_ERROR(LCAT(LEVMAR_DER, "(): cannot solve a problem with fewer measurements [%d] than unknowns [%d]\n"), n, m);
+    return LM_ERROR_TOO_FEW_MEASUREMENTS;
   }
 
   if(!jacf){
-    fprintf(stderr, RCAT("No function specified for computing the Jacobian in ", LEVMAR_DER)
+    PRINT_ERROR(RCAT("No function specified for computing the Jacobian in ", LEVMAR_DER)
         RCAT("().\nIf no such function is available, use ", LEVMAR_DIF) RCAT("() rather than ", LEVMAR_DER) "()\n");
-    return LM_ERROR;
+    return LM_ERROR_NO_JACOBIAN;
   }
 
   if(opts){
@@ -143,8 +143,8 @@
     worksz=LM_DER_WORKSZ(m, n); //2*n+4*m + n*m + m*m;
     work=(LM_REAL *)malloc(worksz*sizeof(LM_REAL)); /* allocate a big chunk in one step */
     if(!work){
-      fprintf(stderr, LCAT(LEVMAR_DER, "(): memory allocation request failed\n"));
-      return LM_ERROR;
+      PRINT_ERROR(LCAT(LEVMAR_DER, "(): memory allocation request failed\n"));
+      return LM_ERROR_MEMORY_ALLOCATION_FAILURE;
     }
     freework=1;
   }
@@ -417,7 +417,11 @@
   if(linsolver) (*linsolver)(NULL, NULL, NULL, 0);
 #endif
 
-  return (stop!=4 && stop!=7)?  k : LM_ERROR;
+  switch (stop) {
+    case 4:  return LM_ERROR_SINGULAR_MATRIX;
+    case 7:  return LM_ERROR_SUM_OF_SQUARES_NOT_FINITE;
+    default: return k;
+  }
 }
 
 
@@ -489,8 +493,8 @@
   updjac=newjac=0; /* -Wall */
 
   if(n<m){
-    fprintf(stderr, LCAT(LEVMAR_DIF, "(): cannot solve a problem with fewer measurements [%d] than unknowns [%d]\n"), n, m);
-    return LM_ERROR;
+    PRINT_ERROR(LCAT(LEVMAR_DIF, "(): cannot solve a problem with fewer measurements [%d] than unknowns [%d]\n"), n, m);
+    return LM_ERROR_TOO_FEW_MEASUREMENTS;
   }
 
   if(opts){
@@ -518,8 +522,8 @@
     worksz=LM_DIF_WORKSZ(m, n); //4*n+4*m + n*m + m*m;
     work=(LM_REAL *)malloc(worksz*sizeof(LM_REAL)); /* allocate a big chunk in one step */
     if(!work){
-      fprintf(stderr, LCAT(LEVMAR_DIF, "(): memory allocation request failed\n"));
-      return LM_ERROR;
+      PRINT_ERROR(LCAT(LEVMAR_DIF, "(): memory allocation request failed\n"));
+      return LM_ERROR_MEMORY_ALLOCATION_FAILURE;
     }
     freework=1;
   }
@@ -821,7 +825,11 @@
   if(linsolver) (*linsolver)(NULL, NULL, NULL, 0);
 #endif
 
-  return (stop!=4 && stop!=7)?  k : LM_ERROR;
+  switch (stop) {
+    case 4:  return LM_ERROR_SINGULAR_MATRIX;
+    case 7:  return LM_ERROR_SUM_OF_SQUARES_NOT_FINITE;
+    default: return k;
+  }
 }
 
 /* undefine everything. THIS MUST REMAIN AT THE END OF THE FILE */
diff -bru levmar-2.4/lmbc_core.c levmar-2.4.new_errors/lmbc_core.c
--- levmar-2.4/lmbc_core.c	2009-04-28 10:32:58.000000000 +0200
+++ levmar-2.4.new_errors/lmbc_core.c	2009-09-01 12:28:07.000000000 +0200
@@ -264,7 +264,7 @@
  * This function requires an analytic Jacobian. In case the latter is unavailable,
  * use LEVMAR_BC_DIF() bellow
  *
- * Returns the number of iterations (>=0) if successful, LM_ERROR if failed
+ * Returns the number of iterations (>=0) if successful, or an error code (<0) on failure.
  *
  * For details, see C. Kanzow, N. Yamashita and M. Fukushima: "Levenberg-Marquardt
  * methods for constrained nonlinear equations with strong local convergence properties",
@@ -344,19 +344,19 @@
   mu=jacTe_inf=t=0.0;  tmin=tmin; /* -Wall */
 
   if(n<m){
-    fprintf(stderr, LCAT(LEVMAR_BC_DER, "(): cannot solve a problem with fewer measurements [%d] than unknowns [%d]\n"), n, m);
-    return LM_ERROR;
+    PRINT_ERROR(LCAT(LEVMAR_BC_DER, "(): cannot solve a problem with fewer measurements [%d] than unknowns [%d]\n"), n, m);
+    return LM_ERROR_TOO_FEW_MEASUREMENTS;
   }
 
   if(!jacf){
-    fprintf(stderr, RCAT("No function specified for computing the Jacobian in ", LEVMAR_BC_DER)
+    PRINT_ERROR(RCAT("No function specified for computing the Jacobian in ", LEVMAR_BC_DER)
         RCAT("().\nIf no such function is available, use ", LEVMAR_BC_DIF) RCAT("() rather than ", LEVMAR_BC_DER) "()\n");
-    return LM_ERROR;
+    return LM_ERROR_NO_JACOBIAN;
   }
 
   if(!LEVMAR_BOX_CHECK(lb, ub, m)){
-    fprintf(stderr, LCAT(LEVMAR_BC_DER, "(): at least one lower bound exceeds the upper one\n"));
-    return LM_ERROR;
+    PRINT_ERROR(LCAT(LEVMAR_BC_DER, "(): at least one lower bound exceeds the upper one\n"));
+    return LM_ERROR_FAILED_BOX_CHECK;
   }
 
   if(opts){
@@ -378,8 +378,8 @@
     worksz=LM_BC_DER_WORKSZ(m, n); //2*n+4*m + n*m + m*m;
     work=(LM_REAL *)malloc(worksz*sizeof(LM_REAL)); /* allocate a big chunk in one step */
     if(!work){
-      fprintf(stderr, LCAT(LEVMAR_BC_DER, "(): memory allocation request failed\n"));
-      return LM_ERROR;
+      PRINT_ERROR(LCAT(LEVMAR_BC_DER, "(): memory allocation request failed\n"));
+      return LM_ERROR_MEMORY_ALLOCATION_FAILURE;
     }
     freework=1;
   }
@@ -406,7 +406,7 @@
   BOXPROJECT(p, lb, ub, m); /* project to feasible set */
   for(i=0; i<m; ++i)
     if(pDp[i]!=p[i])
-      fprintf(stderr, RCAT("Warning: component %d of starting point not feasible in ", LEVMAR_BC_DER) "()! [%g projected to %g]\n",
+      PRINT_ERROR(RCAT("Warning: component %d of starting point not feasible in ", LEVMAR_BC_DER) "()! [%g projected to %g]\n",
                       i, pDp[i], p[i]);
 
   /* compute e=x - f(p) and its L2 norm */
@@ -814,7 +814,11 @@
 printf("%d LM steps, %d line search, %d projected gradient\n", nLMsteps, nLSsteps, nPGsteps);
 #endif
 
-  return (stop!=4 && stop!=7)?  k : LM_ERROR;
+  switch (stop) {
+    case 4:  return LM_ERROR_SINGULAR_MATRIX;
+    case 7:  return LM_ERROR_SUM_OF_SQUARES_NOT_FINITE;
+    default: return k;
+  }
 }
 
 /* following struct & LMBC_DIF_XXX functions won't be necessary if a true secant
@@ -895,15 +899,15 @@
 struct LMBC_DIF_DATA data;
 int ret;
 
-  //fprintf(stderr, RCAT("\nWarning: current implementation of ", LEVMAR_BC_DIF) "() does not use a secant approach!\n\n");
+  //PRINT_ERROR(RCAT("\nWarning: current implementation of ", LEVMAR_BC_DIF) "() does not use a secant approach!\n\n");
 
   data.ffdif=!opts || opts[4]>=0.0;
 
   data.func=func;
   data.hx=(LM_REAL *)malloc(2*n*sizeof(LM_REAL)); /* allocate a big chunk in one step */
   if(!data.hx){
-    fprintf(stderr, LCAT(LEVMAR_BC_DIF, "(): memory allocation request failed\n"));
-    return LM_ERROR;
+    PRINT_ERROR(LCAT(LEVMAR_BC_DIF, "(): memory allocation request failed\n"));
+    return LM_ERROR_MEMORY_ALLOCATION_FAILURE;
   }
   data.hxx=data.hx+n;
   data.adata=adata;
diff -bru levmar-2.4/lmblec_core.c levmar-2.4.new_errors/lmblec_core.c
--- levmar-2.4/lmblec_core.c	2009-04-29 13:25:38.000000000 +0200
+++ levmar-2.4.new_errors/lmblec_core.c	2009-09-01 11:55:51.000000000 +0200
@@ -176,7 +176,7 @@
  * This function requires an analytic Jacobian. In case the latter is unavailable,
  * use LEVMAR_BLEC_DIF() bellow
  *
- * Returns the number of iterations (>=0) if successful, LM_ERROR if failed
+ * Returns the number of iterations (>=0) if successful, or an error code (<0) on failure.
  *
  * For more details on the algorithm implemented by this function, please refer to
  * the comments in the top of this file.
@@ -227,28 +227,28 @@
   register int i;
 
   if(!jacf){
-    fprintf(stderr, RCAT("No function specified for computing the Jacobian in ", LEVMAR_BLEC_DER)
+    PRINT_ERROR(RCAT("No function specified for computing the Jacobian in ", LEVMAR_BLEC_DER)
       RCAT("().\nIf no such function is available, use ", LEVMAR_BLEC_DIF) RCAT("() rather than ", LEVMAR_BLEC_DER) "()\n");
-    return LM_ERROR;
+    return LM_ERROR_NO_JACOBIAN;
   }
 
   if(!lb && !ub){
-    fprintf(stderr, RCAT(LCAT(LEVMAR_BLEC_DER, "(): lower and upper bounds for box constraints cannot be both NULL, use "),
+    PRINT_ERROR(RCAT(LCAT(LEVMAR_BLEC_DER, "(): lower and upper bounds for box constraints cannot be both NULL, use "),
           LEVMAR_LEC_DER) "() in this case!\n");
-    return LM_ERROR;
+    return LM_ERROR_NO_BOX_CONSTRAINTS;
   }
 
   if(!LEVMAR_BOX_CHECK(lb, ub, m)){
-    fprintf(stderr, LCAT(LEVMAR_BLEC_DER, "(): at least one lower bound exceeds the upper one\n"));
-    return LM_ERROR;
+    PRINT_ERROR(LCAT(LEVMAR_BLEC_DER, "(): at least one lower bound exceeds the upper one\n"));
+    return LM_ERROR_FAILED_BOX_CHECK;
   }
 
   /* measurement vector needs to be extended by m */
   if(x){ /* nonzero x */
     data.x=(LM_REAL *)malloc((n+m)*sizeof(LM_REAL));
     if(!data.x){
-      fprintf(stderr, LCAT(LEVMAR_BLEC_DER, "(): memory allocation request #1 failed\n"));
-      return LM_ERROR;
+      PRINT_ERROR(LCAT(LEVMAR_BLEC_DER, "(): memory allocation request #1 failed\n"));
+      return LM_ERROR_MEMORY_ALLOCATION_FAILURE;
     }
 
     for(i=0; i<n; ++i)
@@ -261,9 +261,9 @@
 
   data.w=(LM_REAL *)malloc(m*sizeof(LM_REAL) + m*sizeof(int)); /* should be arranged in that order for proper doubles alignment */
   if(!data.w){
-    fprintf(stderr, LCAT(LEVMAR_BLEC_DER, "(): memory allocation request #2 failed\n"));
+    PRINT_ERROR(LCAT(LEVMAR_BLEC_DER, "(): memory allocation request #2 failed\n"));
     if(data.x) free(data.x);
-    return LM_ERROR;
+    return LM_ERROR_MEMORY_ALLOCATION_FAILURE;
   }
   data.bctype=(int *)(data.w+m);
 
@@ -342,22 +342,22 @@
   LM_REAL locinfo[LM_INFO_SZ];
 
   if(!lb && !ub){
-    fprintf(stderr, RCAT(LCAT(LEVMAR_BLEC_DIF, "(): lower and upper bounds for box constraints cannot be both NULL, use "),
+    PRINT_ERROR(RCAT(LCAT(LEVMAR_BLEC_DIF, "(): lower and upper bounds for box constraints cannot be both NULL, use "),
           LEVMAR_LEC_DIF) "() in this case!\n");
-    return LM_ERROR;
+    return LM_ERROR_NO_BOX_CONSTRAINTS;
   }
 
   if(!LEVMAR_BOX_CHECK(lb, ub, m)){
-    fprintf(stderr, LCAT(LEVMAR_BLEC_DER, "(): at least one lower bound exceeds the upper one\n"));
-    return LM_ERROR;
+    PRINT_ERROR(LCAT(LEVMAR_BLEC_DER, "(): at least one lower bound exceeds the upper one\n"));
+    return LM_ERROR_FAILED_BOX_CHECK;
   }
 
   /* measurement vector needs to be extended by m */
   if(x){ /* nonzero x */
     data.x=(LM_REAL *)malloc((n+m)*sizeof(LM_REAL));
     if(!data.x){
-      fprintf(stderr, LCAT(LEVMAR_BLEC_DER, "(): memory allocation request #1 failed\n"));
-      return LM_ERROR;
+      PRINT_ERROR(LCAT(LEVMAR_BLEC_DER, "(): memory allocation request #1 failed\n"));
+      return LM_ERROR_MEMORY_ALLOCATION_FAILURE;
     }
 
     for(i=0; i<n; ++i)
@@ -370,9 +370,9 @@
 
   data.w=(LM_REAL *)malloc(m*sizeof(LM_REAL) + m*sizeof(int)); /* should be arranged in that order for proper doubles alignment */
   if(!data.w){
-    fprintf(stderr, LCAT(LEVMAR_BLEC_DER, "(): memory allocation request #2 failed\n"));
+    PRINT_ERROR(LCAT(LEVMAR_BLEC_DER, "(): memory allocation request #2 failed\n"));
     if(data.x) free(data.x);
-    return LM_ERROR;
+    return LM_ERROR_MEMORY_ALLOCATION_FAILURE;
   }
   data.bctype=(int *)(data.w+m);
 
diff -bru levmar-2.4/lmdemo.c levmar-2.4.new_errors/lmdemo.c
--- levmar-2.4/lmdemo.c	2009-04-29 10:38:50.000000000 +0200
+++ levmar-2.4.new_errors/lmdemo.c	2009-09-01 10:44:38.000000000 +0200
@@ -721,7 +721,7 @@
 #endif /* HAVE_LAPACK */
 				
   switch(problem){
-  default: fprintf(stderr, "unknown problem specified (#%d)! Note that some minimization problems require LAPACK.\n", problem);
+  default: PRINT_ERROR("unknown problem specified (#%d)! Note that some minimization problems require LAPACK.\n", problem);
            exit(1);
     break;
   case 0:
@@ -772,7 +772,7 @@
    { double *work, *covar;
     work=malloc((LM_DIF_WORKSZ(m, n)+m*m)*sizeof(double));
     if(!work){
-    	fprintf(stderr, "memory allocation request failed in main()\n");
+    	PRINT_ERROR("memory allocation request failed in main()\n");
       exit(1);
     }
     covar=work+LM_DIF_WORKSZ(m, n);
diff -bru levmar-2.4/lmlec_core.c levmar-2.4.new_errors/lmlec_core.c
--- levmar-2.4/lmlec_core.c	2009-04-29 12:05:44.000000000 +0200
+++ levmar-2.4.new_errors/lmlec_core.c	2009-09-01 11:56:38.000000000 +0200
@@ -76,7 +76,7 @@
  *
  * The function accepts A, b and computes c, Y, Z. If b or c is NULL, c is not
  * computed. Also, Y can be NULL in which case it is not referenced.
- * The function returns LM_ERROR in case of error, A's computed rank if successful
+ * The function returns an error code (<0) in case of error or A's computed rank if successful.
  *
  */
 static int LMLEC_ELIM(LM_REAL *A, LM_REAL *b, LM_REAL *c, LM_REAL *Y, LM_REAL *Z, int m, int n)
@@ -91,8 +91,8 @@
 register int i, j, k;
 
   if(m>n){
-    fprintf(stderr, RCAT("matrix of constraints cannot have more rows than columns in", LMLEC_ELIM) "()!\n");
-    return LM_ERROR;
+    PRINT_ERROR(RCAT("matrix of constraints cannot have more rows than columns in", LMLEC_ELIM) "()!\n");
+    return LM_ERROR_CONSTRAINT_MATRIX_ROWS_GT_COLS;
   }
 
   tm=n; tn=m; // transpose dimensions
@@ -112,8 +112,8 @@
   tot_sz=(a_sz + tau_sz + r_sz + worksz + Y_sz)*sizeof(LM_REAL) + jpvt_sz*sizeof(int); /* should be arranged in that order for proper doubles alignment */
   buf=(LM_REAL *)malloc(tot_sz); /* allocate a "big" memory chunk at once */
   if(!buf){
-    fprintf(stderr, RCAT("Memory allocation request failed in ", LMLEC_ELIM) "()\n");
-    return LM_ERROR;
+    PRINT_ERROR(RCAT("Memory allocation request failed in ", LMLEC_ELIM) "()\n");
+    return LM_ERROR_MEMORY_ALLOCATION_FAILURE;
   }
 
   a=buf;
@@ -142,13 +142,13 @@
   /* error checking */
   if(info!=0){
     if(info<0){
-      fprintf(stderr, RCAT(RCAT("LAPACK error: illegal value for argument %d of ", GEQP3) " in ", LMLEC_ELIM) "()\n", -info);
+      PRINT_ERROR(RCAT(RCAT("LAPACK error: illegal value for argument %d of ", GEQP3) " in ", LMLEC_ELIM) "()\n", -info);
     }
     else if(info>0){
-      fprintf(stderr, RCAT(RCAT("unknown LAPACK error (%d) for ", GEQP3) " in ", LMLEC_ELIM) "()\n", info);
+      PRINT_ERROR(RCAT(RCAT("unknown LAPACK error (%d) for ", GEQP3) " in ", LMLEC_ELIM) "()\n", info);
     }
     free(buf);
-    return LM_ERROR;
+    return LM_ERROR_LAPACK_ERROR;
   }
   /* the upper triangular part of a now contains the upper triangle of the unpermuted R */
 
@@ -169,10 +169,10 @@
     else break; /* diagonal is arranged in absolute decreasing order */
 
   if(rank<tn){
-    fprintf(stderr, RCAT("\nConstraints matrix in ",  LMLEC_ELIM) "() is not of full row rank (i.e. %d < %d)!\n"
+    PRINT_ERROR(RCAT("\nConstraints matrix in ",  LMLEC_ELIM) "() is not of full row rank (i.e. %d < %d)!\n"
             "Make sure that you do not specify redundant or inconsistent constraints.\n\n", rank, tn);
     free(buf);
-    return LM_ERROR;
+    return LM_ERROR_CONSTRAINT_MATRIX_NOT_FULL_ROW_RANK;
   }
 
   /* compute the permuted inverse transpose of R */
@@ -189,13 +189,13 @@
   /* error checking */
   if(info!=0){
     if(info<0){
-      fprintf(stderr, RCAT(RCAT("LAPACK error: illegal value for argument %d of ", TRTRI) " in ", LMLEC_ELIM) "()\n", -info);
+      PRINT_ERROR(RCAT(RCAT("LAPACK error: illegal value for argument %d of ", TRTRI) " in ", LMLEC_ELIM) "()\n", -info);
     }
     else if(info>0){
-      fprintf(stderr, RCAT(RCAT("A(%d, %d) is exactly zero for ", TRTRI) " (singular matrix) in ", LMLEC_ELIM) "()\n", info, info);
+      PRINT_ERROR(RCAT(RCAT("A(%d, %d) is exactly zero for ", TRTRI) " (singular matrix) in ", LMLEC_ELIM) "()\n", info, info);
     }
     free(buf);
-    return LM_ERROR;
+    return LM_ERROR_LAPACK_ERROR;
   }
   /* then, transpose r in place */
   for(i=0; i<rank; ++i)
@@ -223,13 +223,13 @@
   /* error checking */
   if(info!=0){
     if(info<0){
-      fprintf(stderr, RCAT(RCAT("LAPACK error: illegal value for argument %d of ", ORGQR) " in ", LMLEC_ELIM) "()\n", -info);
+      PRINT_ERROR(RCAT(RCAT("LAPACK error: illegal value for argument %d of ", ORGQR) " in ", LMLEC_ELIM) "()\n", -info);
     }
     else if(info>0){
-      fprintf(stderr, RCAT(RCAT("unknown LAPACK error (%d) for ", ORGQR) " in ", LMLEC_ELIM) "()\n", info);
+      PRINT_ERROR(RCAT(RCAT("unknown LAPACK error (%d) for ", ORGQR) " in ", LMLEC_ELIM) "()\n", info);
     }
     free(buf);
-    return LM_ERROR;
+    return LM_ERROR_LAPACK_ERROR;
   }
 
   /* compute Y=Q_1*R^-T*P^T. Y is tm x rank */
@@ -415,22 +415,22 @@
   LM_REAL locinfo[LM_INFO_SZ];
 
   if(!jacf){
-    fprintf(stderr, RCAT("No function specified for computing the Jacobian in ", LEVMAR_LEC_DER)
+    PRINT_ERROR(RCAT("No function specified for computing the Jacobian in ", LEVMAR_LEC_DER)
       RCAT("().\nIf no such function is available, use ", LEVMAR_LEC_DIF) RCAT("() rather than ", LEVMAR_LEC_DER) "()\n");
-    return LM_ERROR;
+    return LM_ERROR_NO_JACOBIAN;
   }
 
   mm=m-k;
 
   if(n<mm){
-    fprintf(stderr, LCAT(LEVMAR_LEC_DER, "(): cannot solve a problem with fewer measurements + equality constraints [%d + %d] than unknowns [%d]\n"), n, k, m);
-    return LM_ERROR;
+    PRINT_ERROR(LCAT(LEVMAR_LEC_DER, "(): cannot solve a problem with fewer measurements + equality constraints [%d + %d] than unknowns [%d]\n"), n, k, m);
+    return LM_ERROR_TOO_FEW_MEASUREMENTS;
   }
 
   ptr=(LM_REAL *)malloc((2*m + m*mm + n*m + mm)*sizeof(LM_REAL));
   if(!ptr){
-    fprintf(stderr, LCAT(LEVMAR_LEC_DER, "(): memory allocation request failed\n"));
-    return LM_ERROR;
+    PRINT_ERROR(LCAT(LEVMAR_LEC_DER, "(): memory allocation request failed\n"));
+    return LM_ERROR_MEMORY_ALLOCATION_FAILURE;
   }
   data.p=p;
   p0=ptr;
@@ -444,9 +444,9 @@
   data.adata=adata;
 
   ret=LMLEC_ELIM(A, b, data.c, NULL, Z, k, m); // compute c, Z
-  if(ret==LM_ERROR){
+  if(ret<0){
     free(ptr);
-    return LM_ERROR;
+    return ret;
   }
 
   /* compute pp s.t. p = c + Z*pp or (Z^T Z)*pp=Z^T*(p-c)
@@ -471,7 +471,7 @@
     for(j=0, tmp=data.c[i]; j<mm; ++j)
       tmp+=Zimm[j]*pp[j]; // tmp+=Z[i*mm+j]*pp[j];
     if(FABS(tmp-p0[i])>LM_CNST(1E-03))
-      fprintf(stderr, RCAT("Warning: component %d of starting point not feasible in ", LEVMAR_LEC_DER) "()! [%.10g reset to %.10g]\n",
+      PRINT_ERROR(RCAT("Warning: component %d of starting point not feasible in ", LEVMAR_LEC_DER) "()! [%.10g reset to %.10g]\n",
                       i, p0[i], tmp);
   }
 
@@ -549,14 +549,14 @@
   mm=m-k;
 
   if(n<mm){
-    fprintf(stderr, LCAT(LEVMAR_LEC_DIF, "(): cannot solve a problem with fewer measurements + equality constraints [%d + %d] than unknowns [%d]\n"), n, k, m);
-    return LM_ERROR;
+    PRINT_ERROR(LCAT(LEVMAR_LEC_DIF, "(): cannot solve a problem with fewer measurements + equality constraints [%d + %d] than unknowns [%d]\n"), n, k, m);
+    return LM_ERROR_TOO_FEW_MEASUREMENTS;
   }
 
   ptr=(LM_REAL *)malloc((2*m + m*mm + mm)*sizeof(LM_REAL));
   if(!ptr){
-    fprintf(stderr, LCAT(LEVMAR_LEC_DIF, "(): memory allocation request failed\n"));
-    return LM_ERROR;
+    PRINT_ERROR(LCAT(LEVMAR_LEC_DIF, "(): memory allocation request failed\n"));
+    return LM_ERROR_MEMORY_ALLOCATION_FAILURE;
   }
   data.p=p;
   p0=ptr;
@@ -570,9 +570,9 @@
   data.adata=adata;
 
   ret=LMLEC_ELIM(A, b, data.c, NULL, Z, k, m); // compute c, Z
-  if(ret==LM_ERROR){
+  if(ret<0){
     free(ptr);
-    return LM_ERROR;
+    return ret;
   }
 
   /* compute pp s.t. p = c + Z*pp or (Z^T Z)*pp=Z^T*(p-c)
@@ -597,7 +597,7 @@
     for(j=0, tmp=data.c[i]; j<mm; ++j)
       tmp+=Zimm[j]*pp[j]; // tmp+=Z[i*mm+j]*pp[j];
     if(FABS(tmp-p0[i])>LM_CNST(1E-03))
-      fprintf(stderr, RCAT("Warning: component %d of starting point not feasible in ", LEVMAR_LEC_DIF) "()! [%.10g reset to %.10g]\n",
+      PRINT_ERROR(RCAT("Warning: component %d of starting point not feasible in ", LEVMAR_LEC_DIF) "()! [%.10g reset to %.10g]\n",
                       i, p0[i], tmp);
   }
 
@@ -619,9 +619,9 @@
 
     hx=(LM_REAL *)malloc((2*n+n*m)*sizeof(LM_REAL));
     if(!hx){
-      fprintf(stderr, LCAT(LEVMAR_LEC_DIF, "(): memory allocation request failed\n"));
+      PRINT_ERROR(LCAT(LEVMAR_LEC_DIF, "(): memory allocation request failed\n"));
       free(ptr);
-      return LM_ERROR;
+      return LM_ERROR_MEMORY_ALLOCATION_FAILURE;
     }
 
     wrk=hx+n;
diff -bru levmar-2.4/matlab/levmar.c levmar-2.4.new_errors/matlab/levmar.c
--- levmar-2.4/matlab/levmar.c	2009-02-09 09:08:58.000000000 +0100
+++ levmar-2.4.new_errors/matlab/levmar.c	2009-09-01 11:48:23.000000000 +0200
@@ -47,6 +47,8 @@
 #define MIN_CONSTRAINED_LEC   2
 #define MIN_CONSTRAINED_BLEC  3
 
+#define ERROR_FAILED_FUNC_AND_JACOBIAN_CHECK -1
+
 struct mexdata {
   /* matlab names of the fitting function & its Jacobian */
   char *fname, *jacname;
@@ -177,12 +179,12 @@
   /* attempt to call the supplied func */
   i=mexCallMATLAB(1, lhs, dat->nrhs, dat->rhs, dat->fname);
   if(i){
-    fprintf(stderr, "levmar: error calling '%s'.\n", dat->fname);
+    PRINT_ERROR("levmar: error calling '%s'.\n", dat->fname);
     ret=1;
   }
   else if(!mxIsDouble(lhs[0]) || mxIsComplex(lhs[0]) || !(mxGetM(lhs[0])==1 || mxGetN(lhs[0])==1) ||
       __MAX__(mxGetM(lhs[0]), mxGetN(lhs[0]))!=n){
-    fprintf(stderr, "levmar: '%s' should produce a real vector with %d elements (got %d).\n",
+    PRINT_ERROR("levmar: '%s' should produce a real vector with %d elements (got %d).\n",
                     dat->fname, n, __MAX__(mxGetM(lhs[0]), mxGetN(lhs[0])));
     ret=1;
   }
@@ -193,16 +195,16 @@
     /* attempt to call the supplied jac  */
     i=mexCallMATLAB(1, lhs, dat->nrhs, dat->rhs, dat->jacname);
     if(i){
-      fprintf(stderr, "levmar: error calling '%s'.\n", dat->jacname);
+      PRINT_ERROR("levmar: error calling '%s'.\n", dat->jacname);
       ret=1;
     }
     else if(!mxIsDouble(lhs[0]) || mxIsComplex(lhs[0]) || mxGetM(lhs[0])!=n || mxGetN(lhs[0])!=m){
-      fprintf(stderr, "levmar: '%s' should produce a real %dx%d matrix (got %dx%d).\n",
+      PRINT_ERROR("levmar: '%s' should produce a real %dx%d matrix (got %dx%d).\n",
                       dat->jacname, n, m, mxGetM(lhs[0]), mxGetN(lhs[0]));
       ret=1;
     }
     else if(mxIsSparse(lhs[0])){
-      fprintf(stderr, "levmar: '%s' should produce a real dense matrix (got a sparse one).\n", dat->jacname);
+      PRINT_ERROR("levmar: '%s' should produce a real dense matrix (got a sparse one).\n", dat->jacname);
       ret=1;
     }
     /* delete the matrix created by matlab */
@@ -281,7 +283,7 @@
 
 #ifdef DEBUG
   fflush(stderr);
-  fprintf(stderr, "LEVMAR: %s analytic Jacobian\n", havejac? "with" : "no");
+  PRINT_ERROR("LEVMAR: %s analytic Jacobian\n", havejac? "with" : "no");
 #endif /* DEBUG */
 
 /* CHECK 
@@ -340,7 +342,7 @@
 #ifdef DEBUG
   else{
     fflush(stderr);
-    fprintf(stderr, "LEVMAR: empty options vector, using defaults\n");
+    PRINT_ERROR("LEVMAR: empty options vector, using defaults\n");
   }
 #endif /* DEBUG */
 
@@ -443,7 +445,7 @@
     mdata.rhs[i+1]=(mxArray *)prhs[nrhs-nextra+i]; /* discard 'const' modifier */
 #ifdef DEBUG
   fflush(stderr);
-  fprintf(stderr, "LEVMAR: %d extra args\n", nextra);
+  PRINT_ERROR("LEVMAR: %d extra args\n", nextra);
 #endif /* DEBUG */
 
   if(mdata.isrow_p0){ /* row vector */
@@ -463,7 +465,7 @@
 
   /* ensure that the supplied function & Jacobian are as expected */
   if(checkFuncAndJacobian(p, m, n, havejac, &mdata)){
-    status=LM_ERROR;
+    status=ERROR_FAILED_FUNC_AND_JACOBIAN_CHECK;
     goto cleanup;
   }
 
@@ -479,7 +481,7 @@
         status=dlevmar_dif(func,          p, x, m, n, itmax, opts, info, NULL, covar, (void *)&mdata);
 #ifdef DEBUG
   fflush(stderr);
-  fprintf(stderr, "LEVMAR: calling dlevmar_der()/dlevmar_dif()\n");
+  PRINT_ERROR("LEVMAR: calling dlevmar_der()/dlevmar_dif()\n");
 #endif /* DEBUG */
     }
     else{ /* linear constraints */
@@ -494,7 +496,7 @@
 
 #ifdef DEBUG
   fflush(stderr);
-  fprintf(stderr, "LEVMAR: calling dlevmar_lec_der()/dlevmar_lec_dif()\n");
+  PRINT_ERROR("LEVMAR: calling dlevmar_lec_der()/dlevmar_lec_dif()\n");
 #endif /* DEBUG */
     }
   }
@@ -506,7 +508,7 @@
         status=dlevmar_bc_dif(func,          p, x, m, n, lb, ub, itmax, opts, info, NULL, covar, (void *)&mdata);
 #ifdef DEBUG
   fflush(stderr);
-  fprintf(stderr, "LEVMAR: calling dlevmar_bc_der()/dlevmar_bc_dif()\n");
+  PRINT_ERROR("LEVMAR: calling dlevmar_bc_der()/dlevmar_bc_dif()\n");
 #endif /* DEBUG */
     }
     else{ /* box & linear constraints */
@@ -521,7 +523,7 @@
 
 #ifdef DEBUG
   fflush(stderr);
-  fprintf(stderr, "LEVMAR: calling dlevmar_blec_der()/dlevmar_blec_dif()\n");
+  PRINT_ERROR("LEVMAR: calling dlevmar_blec_der()/dlevmar_blec_dif()\n");
 #endif /* DEBUG */
     }
   }
@@ -575,6 +577,6 @@
   mxFree(mdata.rhs);
   if(covar) mxFree(covar);
 
-  if(status==LM_ERROR)
+  if(status<0)
     mexWarnMsgTxt("levmar: optimization returned with an error!");
 }
diff -bru levmar-2.4/misc_core.c levmar-2.4.new_errors/misc_core.c
--- levmar-2.4/misc_core.c	2009-04-29 12:06:44.000000000 +0200
+++ levmar-2.4.new_errors/misc_core.c	2009-09-01 11:00:16.000000000 +0200
@@ -265,7 +265,7 @@
 
   buf=(LM_REAL *)malloc((fvec_sz + fjac_sz + pp_sz + fvecp_sz)*sizeof(LM_REAL));
   if(!buf){
-    fprintf(stderr, LCAT(LEVMAR_CHKJAC, "(): memory allocation request failed\n"));
+    PRINT_ERROR(LCAT(LEVMAR_CHKJAC, "(): memory allocation request failed\n"));
     exit(1);
   }
   fvec=buf;
@@ -353,7 +353,7 @@
     buf_sz=tot_sz;
     buf=(LM_REAL *)malloc(buf_sz);
     if(!buf){
-      fprintf(stderr, RCAT("memory allocation in ", LEVMAR_PSEUDOINVERSE) "() failed!\n");
+      PRINT_ERROR(RCAT("memory allocation in ", LEVMAR_PSEUDOINVERSE) "() failed!\n");
       return 0; /* error */
     }
 
@@ -376,10 +376,10 @@
   /* error treatment */
   if(info!=0){
     if(info<0){
-      fprintf(stderr, RCAT(RCAT(RCAT("LAPACK error: illegal value for argument %d of ", GESVD), "/" GESDD) " in ", LEVMAR_PSEUDOINVERSE) "()\n", -info);
+      PRINT_ERROR(RCAT(RCAT(RCAT("LAPACK error: illegal value for argument %d of ", GESVD), "/" GESDD) " in ", LEVMAR_PSEUDOINVERSE) "()\n", -info);
     }
     else{
-      fprintf(stderr, RCAT("LAPACK error: dgesdd (dbdsdc)/dgesvd (dbdsqr) failed to converge in ", LEVMAR_PSEUDOINVERSE) "() [info=%d]\n", info);
+      PRINT_ERROR(RCAT("LAPACK error: dgesdd (dbdsdc)/dgesvd (dbdsqr) failed to converge in ", LEVMAR_PSEUDOINVERSE) "() [info=%d]\n", info);
     }
     free(buf);
     return 0;
@@ -440,7 +440,7 @@
   buf_sz=tot_sz;
   buf=(void *)malloc(tot_sz);
   if(!buf){
-    fprintf(stderr, RCAT("memory allocation in ", LEVMAR_LUINVERSE) "() failed!\n");
+    PRINT_ERROR(RCAT("memory allocation in ", LEVMAR_LUINVERSE) "() failed!\n");
     return 0; /* error */
   }
 
@@ -459,7 +459,7 @@
 			if((tmp=FABS(a[i*m+j]))>max)
         max=tmp;
 		  if(max==0.0){
-        fprintf(stderr, RCAT("Singular matrix A in ", LEVMAR_LUINVERSE) "()!\n");
+        PRINT_ERROR(RCAT("Singular matrix A in ", LEVMAR_LUINVERSE) "()!\n");
         free(buf);
 
         return 0;
@@ -622,7 +622,7 @@
 
 
   if((hx=(LM_REAL *)malloc(n*sizeof(LM_REAL)))==NULL){
-    fprintf(stderr, RCAT("memory allocation request failed in ", LEVMAR_R2) "()\n");
+    PRINT_ERROR(RCAT("memory allocation request failed in ", LEVMAR_R2) "()\n");
     exit(1);
   }
 
@@ -678,13 +678,13 @@
   /* error treatment */
   if(info!=0){
 		if(info<0){
-      fprintf(stderr, "LAPACK error: illegal value for argument %d of dpotf2 in %s\n", -info, LCAT(LEVMAR_CHOLESKY, "()"));
+      PRINT_ERROR("LAPACK error: illegal value for argument %d of dpotf2 in %s\n", -info, LCAT(LEVMAR_CHOLESKY, "()"));
 		}
 		else{
-			fprintf(stderr, "LAPACK error: the leading minor of order %d is not positive definite,\n%s()\n", info,
+			PRINT_ERROR("LAPACK error: the leading minor of order %d is not positive definite,\n%s()\n", info,
 						RCAT("and the Cholesky factorization could not be completed in ", LEVMAR_CHOLESKY));
 		}
-    return LM_ERROR;
+    return LM_ERROR_LAPACK_ERROR;
   }
 
   /* the decomposition is in the upper part of W (in column-major order!).
