11/*
22 * R : A Computer Language for Statistical Data Analysis
3+ * Copyright (C) 1998--2025 The R Core Team
34 * Copyright (C) 1995, 1996 Robert Gentleman and Ross Ihaka
45 * Copyright (C) 2003-2004 The R Foundation
5- * Copyright (C) 1998--2023 The R Core Team
66 *
77 * This program is free software; you can redistribute it and/or modify
88 * it under the terms of the GNU General Public License as published by
@@ -219,8 +219,13 @@ static double fcn1(double x, void *arg_info)
219219 case REALSXP :
220220 if (length (s ) != 1 ) goto badvalue ;
221221 if (!R_FINITE (REAL (s )[0 ])) {
222- warning (_ ("NA/Inf replaced by maximum positive value" ));
223- return DBL_MAX ;
222+ if (REAL (s )[0 ] == R_NegInf ) { // keep sign for root finding !
223+ warning (_ ("-Inf replaced by maximally negative value" ));
224+ return - DBL_MAX ;
225+ } else {
226+ warning (_ ("%s replaced by maximum positive value" ), ISNAN (REAL (s )[0 ]) ? "NA/NaN" : "Inf" );
227+ return DBL_MAX ;
228+ }
224229 }
225230 else return REAL (s )[0 ];
226231 break ;
@@ -232,33 +237,31 @@ static double fcn1(double x, void *arg_info)
232237 return 0 ;/* for -Wall */
233238}
234239
235- /* fmin(f, xmin, xmax tol) */
240+ /* Called from optimize() as
241+ * .External2(C_do_fmin, function(arg) +/- f(arg, ...), lower, upper, tol)
242+ * fmin(f, xmin, xmax tol) */
236243SEXP do_fmin (SEXP call , SEXP op , SEXP args , SEXP rho )
237244{
238- double xmin , xmax , tol ;
239- SEXP v , res ;
240- struct callinfo info ;
241-
242245 args = CDR (args );
243246 PrintDefaults ();
244247
245248 /* the function to be minimized */
246249
247- v = CAR (args );
250+ SEXP v = CAR (args );
248251 if (!isFunction (v ))
249252 error (_ ("attempt to minimize non-function" ));
250253 args = CDR (args );
251254
252255 /* xmin */
253256
254- xmin = asReal (CAR (args ));
257+ double xmin = asReal (CAR (args ));
255258 if (!R_FINITE (xmin ))
256259 error (_ ("invalid '%s' value" ), "xmin" );
257260 args = CDR (args );
258261
259262 /* xmax */
260263
261- xmax = asReal (CAR (args ));
264+ double xmax = asReal (CAR (args ));
262265 if (!R_FINITE (xmax ))
263266 error (_ ("invalid '%s' value" ), "xmax" );
264267 if (xmin >= xmax )
@@ -267,13 +270,14 @@ SEXP do_fmin(SEXP call, SEXP op, SEXP args, SEXP rho)
267270
268271 /* tol */
269272
270- tol = asReal (CAR (args ));
273+ double tol = asReal (CAR (args ));
271274 if (!R_FINITE (tol ) || tol <= 0.0 )
272275 error (_ ("invalid '%s' value" ), "tol" );
273276
277+ struct callinfo info ;
274278 info .R_env = rho ;
275279 PROTECT (info .R_fcall = lang2 (v , R_NilValue ));
276- PROTECT ( res = allocVector (REALSXP , 1 ));
280+ SEXP res = PROTECT ( allocVector (REALSXP , 1 ));
277281 REAL (res )[0 ] = Brent_fmin (xmin , xmax , fcn1 , & info , tol );
278282 UNPROTECT (2 );
279283 return res ;
@@ -309,7 +313,7 @@ static double fcn2(double x, void *arg_info)
309313 warning (_ ("-Inf replaced by maximally negative value" ));
310314 return - DBL_MAX ;
311315 } else {
312- warning (_ ("NA/Inf replaced by maximum positive value" ));
316+ warning (_ ("%s replaced by maximum positive value" ), ISNAN ( REAL ( s )[ 0 ]) ? "NA/NaN" : "Inf" );
313317 return DBL_MAX ;
314318 }
315319 }
@@ -527,8 +531,13 @@ static void fcn(int n, double *x, double *f, void *arg_state)
527531 case REALSXP :
528532 if (length (s ) != 1 ) goto badvalue ;
529533 if (!R_FINITE (REAL (s )[0 ])) {
530- warning (_ ("NA/Inf replaced by maximum positive value" ));
531- * f = DBL_MAX ;
534+ if (REAL (s )[0 ] == R_NegInf ) { // keep sign for root finding !
535+ warning (_ ("-Inf replaced by maximally negative value" ));
536+ * f = - DBL_MAX ;
537+ } else {
538+ warning (_ ("%s replaced by maximum positive value" ), ISNAN (REAL (s )[0 ]) ? "NA/NaN" : "Inf" );
539+ * f = DBL_MAX ;
540+ }
532541 }
533542 else * f = REAL (s )[0 ];
534543 break ;
0 commit comments