The R Project SVN R

Rev

Rev 7003 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 7003 Rev 7192
Line 25... Line 25...
25
 
25
 
26
#include "Defn.h"
26
#include "Defn.h"
27
#include "Print.h"		/*for printRealVector()*/
27
#include "Print.h"		/*for printRealVector()*/
28
#include "Mathlib.h"
28
#include "Mathlib.h"
29
#include "Applic.h"
29
#include "Applic.h"
30
#include "R_ext/Memory.h"	/* for the Calloc and Free macros */
30
#include "S.h"			/*for Memcpy */
31
 
31
 
32
/* WARNING : As things stand, these routines should not be called
32
/* WARNING : As things stand, these routines should not be called
33
 *	     recursively because of the way global variables are used.
33
 *	     recursively because of the way global variables are used.
34
 *	     This could be fixed by saving and restoring these global variables.
34
 *	     This could be fixed by saving and restoring these global variables.
35
 */
35
 */
Line 217... Line 217...
217

217

218
 
218
 
219
 
219
 
220
/* General Nonlinear Optimization */
220
/* General Nonlinear Optimization */
221
 
221
 
222
/* These are unevaluated calls to R functions supplied by the user.
-
 
223
 * When the optimizer needs a value, the functions below insert
-
 
224
 * the function argument and then evaluate the call.
-
 
225
 */
-
 
226
static SEXP R_fcall;	/* function */
-
 
227
static SEXP R_env;	/* where to evaluate the calls */
-
 
228
 
-
 
229
#ifdef NOT_yet_used
-
 
230
static SEXP R_gcall;	/* gradient */
-
 
231
static SEXP R_hcall;	/* hessian */
-
 
232
#endif
-
 
233
 
-
 
234
static SEXP R_gradientSymbol;
-
 
235
static SEXP R_hessianSymbol;
-
 
236
 
-
 
237
static int have_gradient;
-
 
238
static int have_hessian;
-
 
239
 
-
 
240
#define FT_SIZE 5		/* size of table to store computed
222
#define FT_SIZE 5		/* default size of table to store computed
241
				   function values */
223
				   function values */
242
static int FT_last;		/* Newest entry in the table */
-
 
243
/*static int xdim;		-* length of the parameter (x) vector */
-
 
244
 
224
 
245
static struct {
225
typedef struct {
246
    double   fval;
226
  double   fval;
247
    double  *x;
227
  double  *x;
248
    double  *grad;
228
  double  *grad;
249
    double  *hess;
229
  double  *hess;
-
 
230
} ftable;
-
 
231
 
-
 
232
typedef struct {
-
 
233
  SEXP R_fcall;       /* unevaluated call to R function */
-
 
234
  SEXP R_env;         /* where to evaluate the calls */
-
 
235
  int have_gradient;
-
 
236
  int have_hessian;
-
 
237
/*  int n;	      -* length of the parameter (x) vector */
-
 
238
  int FT_size;        /* size of table to store computed
-
 
239
			 function values */
-
 
240
  int FT_last;        /* Newest entry in the table */
250
} Ftable[FT_SIZE];
241
  ftable *Ftable;
-
 
242
} function_info;
251
 
243
 
252
/* Initialize the storage in the table of computed function values */
244
/* Initialize the storage in the table of computed function values */
253
 
245
 
254
static void FT_init(int n)
246
static void FT_init(int n, int FT_size, function_info *state)
255
{
247
{
256
    int i, j;
248
    int i, j;
-
 
249
    int have_gradient, have_hessian;
-
 
250
    ftable *Ftable;
-
 
251
 
-
 
252
    have_gradient = state->have_gradient;
-
 
253
    have_hessian = state->have_hessian;
257
 
254
 
-
 
255
    Ftable = (ftable *)R_alloc(FT_size, sizeof(ftable));
-
 
256
 
258
    for (i = 0; i < FT_SIZE; i++) {
257
    for (i = 0; i < FT_size; i++) {
259
	Ftable[i].x =  Calloc(n, double);
258
	Ftable[i].x = (double *)R_alloc(n, sizeof(double));
260
				/* initialize to unlikely parameter values */
259
				/* initialize to unlikely parameter values */
261
	for (j = 0; j < n; j++) {
260
	for (j = 0; j < n; j++) {
262
	    Ftable[i].x[j] = DBL_MAX;
261
	    Ftable[i].x[j] = DBL_MAX;
263
	}
262
	}
264
	if (have_gradient) {
263
	if (have_gradient) {
265
	    Ftable[i].grad =  Calloc(n, double);
264
	    Ftable[i].grad = (double *)R_alloc(n, sizeof(double));
266
	    if (have_hessian) {
-
 
267
		Ftable[i].hess =  Calloc(n * n, double);
-
 
268
	    }
-
 
269
	}
-
 
270
    }
-
 
271
    FT_last = -1;
-
 
272
}
-
 
273
 
-
 
274
/* Free the storage from the table of computed function values */
-
 
275
 
-
 
276
static void FT_free()
-
 
277
{
-
 
278
    int i;
-
 
279
    for (i = 0; i < FT_SIZE; i++) {
-
 
280
	Free(Ftable[i].x);
-
 
281
	if (have_gradient) {
-
 
282
	    Free(Ftable[i].grad);
-
 
283
	    if (have_hessian) {
265
	    if (have_hessian) {
284
		Free(Ftable[i].hess);
266
		Ftable[i].hess = (double *)R_alloc(n * n, sizeof(double));
285
	    }
267
	    }
286
	}
268
	}
287
    }
269
    }
-
 
270
    state->Ftable = Ftable;
-
 
271
    state->FT_size = FT_size;
288
    FT_last = -1;
272
    state->FT_last = -1;
289
}
273
}
290
 
274
 
291
/* Store an entry in the table of computed function values */
275
/* Store an entry in the table of computed function values */
292
 
276
 
293
static void FT_store(int n, double f, double *x, double *grad, double *hess)
277
static void FT_store(int n, const double f, const double *x, const double *grad,
-
 
278
		     const double *hess, function_info *state)
294
{
279
{
295
    int ind;
280
    int ind;
296
 
281
 
297
    ind = (++FT_last) % FT_SIZE;
282
    ind = (++(state->FT_last)) % (state->FT_size);
298
    Ftable[ind].fval = f;
283
    state->Ftable[ind].fval = f;
299
    Memcpy(Ftable[ind].x, x, n);
284
    Memcpy(state->Ftable[ind].x, x, n);
300
    if (grad) {
285
    if (grad) {
301
        Memcpy(Ftable[ind].grad, grad, n);
286
        Memcpy(state->Ftable[ind].grad, grad, n);
302
	if (hess) {
287
	if (hess) {
303
	    Memcpy(Ftable[ind].hess, hess, n * n);
288
	    Memcpy(state->Ftable[ind].hess, hess, n * n);
304
	}
289
	}
305
    }
290
    }
306
}
291
}
307
 
292
 
308
/* Check for stored values in the table of computed function values.
293
/* Check for stored values in the table of computed function values.
309
   Returns the index in the table or -1 for failure */
294
   Returns the index in the table or -1 for failure */
310
 
295
 
311
static int FT_lookup(int n, double *x)
296
static int FT_lookup(int n, const double *x, function_info *state)
312
{
297
{
313
    double *ftx;
298
    double *ftx;
314
    int i, j, ind, matched;
299
    int i, j, ind, matched;
-
 
300
    int FT_size, FT_last;
-
 
301
    ftable *Ftable;
-
 
302
    
-
 
303
    FT_last = state->FT_last;
-
 
304
    FT_size = state->FT_size;
-
 
305
    Ftable = state->Ftable;
315
 
306
 
316
    for (i = 0; i < FT_SIZE; i++) {
307
    for (i = 0; i < FT_size; i++) {
317
	ind = (FT_last - i) % FT_SIZE;
308
	ind = (FT_last - i) % FT_size;
318
				/* why can't they define modulus correctly */
309
				/* why can't they define modulus correctly */
319
	if (ind < 0) ind += FT_SIZE;
310
	if (ind < 0) ind += FT_size;
320
	ftx = Ftable[ind].x;
311
	ftx = Ftable[ind].x;
321
	if (ftx) {
312
	if (ftx) {
322
	    matched = 1;
313
	    matched = 1;
323
	    for (j = 0; j < n; j++) {
314
	    for (j = 0; j < n; j++) {
324
	        if (x[j] != ftx[j]) {
315
	        if (x[j] != ftx[j]) {
Line 332... Line 323...
332
    return -1;
323
    return -1;
333
}
324
}
334
 
325
 
335
/* This how the optimizer sees them */
326
/* This how the optimizer sees them */
336
 
327
 
337
static int F77_SYMBOL(fcn)(int *n, double *x, double *f)
328
static void fcn(int n, const double x[], double *f, function_info
-
 
329
		*state)
338
{
330
{
339
    SEXP s;
331
    SEXP s, R_fcall;
-
 
332
    ftable *Ftable;
340
    double *g = (double *) 0, *h = (double *) 0;
333
    double *g = (double *) 0, *h = (double *) 0;
341
    int i;
334
    int i;
342
 
335
 
-
 
336
    R_fcall = state->R_fcall;
-
 
337
    Ftable = state->Ftable;
343
    if ((i = FT_lookup(*n, x)) >= 0) {
338
    if ((i = FT_lookup(n, x, state)) >= 0) {
344
	*f = Ftable[i].fval;
339
	*f = Ftable[i].fval;
345
	return 0;
340
	return;
346
    }
341
    }
347
				/* calculate for a new value of x */
342
				/* calculate for a new value of x */
348
    s = allocVector(REALSXP, *n);
343
    s = CADR(R_fcall);
349
    for (i = 0; i < *n; i++)
344
    for (i = 0; i < n; i++)
350
	REAL(s)[i] = x[i];
345
	REAL(s)[i] = x[i];
351
    CADR(R_fcall) = s;
-
 
352
    s = eval(R_fcall, R_env);
346
    s = eval(state->R_fcall, state->R_env);
353
    switch(TYPEOF(s)) {
347
    switch(TYPEOF(s)) {
354
    case INTSXP:
348
    case INTSXP:
355
	if (length(s) != 1) goto badvalue;
349
	if (length(s) != 1) goto badvalue;
356
	if (INTEGER(s)[0] == NA_INTEGER) {
350
	if (INTEGER(s)[0] == NA_INTEGER) {
357
	    warning("NA replaced by maximum positive value");
351
	    warning("NA replaced by maximum positive value");
Line 368... Line 362...
368
	else *f = REAL(s)[0];
362
	else *f = REAL(s)[0];
369
	break;
363
	break;
370
    default:
364
    default:
371
	goto badvalue;
365
	goto badvalue;
372
    }
366
    }
373
    if (have_gradient) {
367
    if (state->have_gradient) {
374
	g = REAL(coerceVector(getAttrib(s, R_gradientSymbol), REALSXP));
368
	g = REAL(coerceVector(getAttrib(s, install("gradient")), REALSXP));
375
	if (have_hessian) {
369
	if (state->have_hessian) {
376
	    h = REAL(coerceVector(getAttrib(s, R_hessianSymbol), REALSXP));
370
	    h = REAL(coerceVector(getAttrib(s, install("hessian")), REALSXP));
377
	}
371
	}
378
    }
372
    }
379
    FT_store(*n, *f, x, g, h);
373
    FT_store(n, *f, x, g, h, state);
380
    return 0;
374
    return;
-
 
375
 
381
 badvalue:
376
 badvalue:
382
    error("invalid function value in 'nlm' optimizer");
377
    error("invalid function value in 'nlm' optimizer");
383
    return 0;/* for -Wall */
-
 
384
}
378
}
385
 
379
 
386
 
380
 
387
static int F77_SYMBOL(Cd1fcn)(int *n, double *x, double *g)
381
static void Cd1fcn(int n, const double x[], double *g, function_info *state)
388
{
382
{
389
    /* error("optimization using analytic gradients not implemented
-
 
390
       (yet)\n"); */
-
 
391
    int ind;
383
    int ind;
392
 
384
 
393
    if ((ind = FT_lookup(*n, x)) < 0) {	/* shouldn't happen */
385
    if ((ind = FT_lookup(n, x, state)) < 0) {	/* shouldn't happen */
394
	F77_SYMBOL(fcn)(n, x, g);
386
	fcn(n, x, g, state);
395
	if ((ind = FT_lookup(*n, x)) < 0) {
387
	if ((ind = FT_lookup(n, x, state)) < 0) {
396
	    error("function value caching for optimization is seriously confused.\n");
388
	    error("function value caching for optimization is seriously confused.\n");
397
	}
389
	}
398
    }
390
    }
399
    Memcpy(g, Ftable[ind].grad, *n);
391
    Memcpy(g, state->Ftable[ind].grad, n);
400
    return 0;
-
 
401
}
392
}
402
 
393
 
403
 
394
 
404
static int F77_SYMBOL(Cd2fcn)(int *nr, int *n, double *x, double *h)
395
static void Cd2fcn(int nr, int n, const double x[], double *h,
-
 
396
		   function_info *state)
405
{
397
{
406
    /*  error("optimization using analytic Hessians not implemented
-
 
407
	(yet)\n"); */
-
 
408
    int j, ind;
398
    int j, ind;
409
 
399
 
410
    if ((ind = FT_lookup(*n, x)) < 0) {	/* shouldn't happen */
400
    if ((ind = FT_lookup(n, x, state)) < 0) {	/* shouldn't happen */
411
	F77_SYMBOL(fcn)(n, x, h);
401
	fcn(n, x, h, state);
412
	if ((ind = FT_lookup(*n, x)) < 0) {
402
	if ((ind = FT_lookup(n, x, state)) < 0) {
413
	    error("function value caching for optimization is seriously confused.\n");
403
	    error("function value caching for optimization is seriously confused.\n");
414
	}
404
	}
415
    }
405
    }
416
    for (j = 0; j < *n; j++) {  /* fill in lower triangle only */
406
    for (j = 0; j < n; j++) {  /* fill in lower triangle only */
417
        Memcpy( h + j*(*n + 1), Ftable[ind].hess + j*(*n + 1), *n - j);
407
        Memcpy( h + j*(n + 1), state->Ftable[ind].hess + j*(n + 1), n - j);
418
    }
408
    }
419
    return 0;
-
 
420
}
409
}
421
 
410
 
422
 
411
 
423
static double *fixparam(SEXP p, int *n, SEXP call)
412
static double *fixparam(SEXP p, int *n, SEXP call)
424
{
413
{
Line 530... Line 519...
530
    Rprintf("\n");
519
    Rprintf("\n");
531
}
520
}
532
 
521
 
533
SEXP do_nlm(SEXP call, SEXP op, SEXP args, SEXP rho)
522
SEXP do_nlm(SEXP call, SEXP op, SEXP args, SEXP rho)
534
{
523
{
535
    SEXP value, names, v;
524
    SEXP value, names, v, R_gradientSymbol, R_hessianSymbol;
536
 
525
 
537
    double *x, *typsiz, fscale, gradtl, stepmx,
526
    double *x, *typsiz, fscale, gradtl, stepmx,
538
	steptol, *xpls, *gpls, fpls, *a, *wrk, dlt;
527
	steptol, *xpls, *gpls, fpls, *a, *wrk, dlt;
539
 
528
 
540
    int code, i, j, k, ipr, itnlim, method, iexp, omsg, msg,
529
    int code, i, j, k, itnlim, method, iexp, omsg, msg,
541
	n, ndigit, iagflg, iahflg, want_hessian, itncnt;
530
	n, ndigit, iagflg, iahflg, want_hessian, itncnt;
542
 
531
 
543
    char *vmax;
532
    char *vmax;
544
 
533
 
-
 
534
    function_info *state;
-
 
535
 
545
    checkArity(op, args);
536
    checkArity(op, args);
546
    PrintDefaults(rho);
537
    PrintDefaults(rho);
547
    vmax = vmaxget();
538
    vmax = vmaxget();
548
 
539
 
-
 
540
    state = (function_info *) R_alloc(1, sizeof(function_info));
-
 
541
 
549
    /* the function to be minimized */
542
    /* the function to be minimized */
550
 
543
 
551
    R_env = rho;
544
    state->R_env = rho;
552
    v = CAR(args);
545
    v = CAR(args);
553
    if (!isFunction(v))
546
    if (!isFunction(v))
554
	error("attempt to minimize non-function");
547
	error("attempt to minimize non-function");
555
    PROTECT(R_fcall = lang2(v, R_NilValue));
548
    PROTECT(state->R_fcall = lang2(v, R_NilValue));
556
    args = CDR(args);
549
    args = CDR(args);
557
 
550
 
558
    /* inital parameter value */
551
    /* inital parameter value */
559
 
552
 
560
    n = 0;
553
    n = 0;
Line 603... Line 596...
603
    args = CDR(args);
596
    args = CDR(args);
604
 
597
 
605
    /* force one evaluation to check for the gradient and hessian */
598
    /* force one evaluation to check for the gradient and hessian */
606
    iagflg = 0;			/* No analytic gradient */
599
    iagflg = 0;			/* No analytic gradient */
607
    iahflg = 0;			/* No analytic hessian */
600
    iahflg = 0;			/* No analytic hessian */
608
    have_gradient = 0;
601
    state->have_gradient = 0;
609
    have_hessian = 0;
602
    state->have_hessian = 0;
610
    R_gradientSymbol = install("gradient");
603
    R_gradientSymbol = install("gradient");
611
    R_hessianSymbol = install("hessian");
604
    R_hessianSymbol = install("hessian");
612
 
605
 
613
    v = allocVector(REALSXP, n);
606
    v = allocVector(REALSXP, n);
614
    for (i = 0; i < n; i++) {
607
    for (i = 0; i < n; i++) {
615
	REAL(v)[i] = x[i];
608
	REAL(v)[i] = x[i];
616
    }
609
    }
617
    CADR(R_fcall) = v;
610
    CADR(state->R_fcall) = v;
618
    value = eval(R_fcall, R_env);
611
    value = eval(state->R_fcall, state->R_env);
619
 
612
 
620
    v = getAttrib(value, R_gradientSymbol);
613
    v = getAttrib(value, R_gradientSymbol);
621
    if (v != R_NilValue && LENGTH(v) == n && (isReal(v) || isInteger(v))) {
614
    if (v != R_NilValue && LENGTH(v) == n && (isReal(v) || isInteger(v))) {
622
      iagflg = 1;
615
      iagflg = 1;
623
      have_gradient = 1;
616
      state->have_gradient = 1;
624
       v = getAttrib(value, R_hessianSymbol);
617
       v = getAttrib(value, R_hessianSymbol);
625
       if (v != R_NilValue && LENGTH(v) == (n * n) &&
618
       if (v != R_NilValue && LENGTH(v) == (n * n) &&
626
 	  (isReal(v) || isInteger(v))) {
619
 	  (isReal(v) || isInteger(v))) {
627
 	iahflg = 1;
620
 	iahflg = 1;
628
 	have_hessian = 1;
621
 	state->have_hessian = 1;
629
       }
622
       }
630
    }
623
    }
631
    if (((msg/4) % 2) && !iahflg) { /* don't check of analytic Hessian */
624
    if (((msg/4) % 2) && !iahflg) { /* skip check of analytic Hessian */
632
      msg -= 4;
625
      msg -= 4;
633
    }
626
    }
634
    if (((msg/2) % 2) && !iagflg) { /* don't check of analytic gradient */
627
    if (((msg/2) % 2) && !iagflg) { /* skip check of analytic gradient */
635
      msg -= 2;
628
      msg -= 2;
636
    }
629
    }
637
    FT_init(n);
630
    FT_init(n, FT_SIZE, state);
638
    /* Plug in the call to the optimizer here */
631
    /* Plug in the call to the optimizer here */
639
 
632
 
640
    method = 1;	/* Line Search */
633
    method = 1;	/* Line Search */
641
    iexp = have_gradient ? 0 : 1; /* Function calls are expensive */
634
    iexp = iahflg ? 0 : 1; /* Function calls are expensive */
642
    ipr = 6;
-
 
643
    dlt = 1.0;
635
    dlt = 1.0;
644
 
636
 
645
    xpls = (double*)R_alloc(n, sizeof(double));
637
    xpls = (double*)R_alloc(n, sizeof(double));
646
    gpls = (double*)R_alloc(n, sizeof(double));
638
    gpls = (double*)R_alloc(n, sizeof(double));
647
    a = (double*)R_alloc(n*n, sizeof(double));
639
    a = (double*)R_alloc(n*n, sizeof(double));
Line 665... Line 657...
665
     *	  16 = print at every iteration
657
     *	  16 = print at every iteration
666
     *	 Using msg=9 is absolutely minimal
658
     *	 Using msg=9 is absolutely minimal
667
     *	 I think we always check gradients and hessians
659
     *	 I think we always check gradients and hessians
668
     */
660
     */
669
 
661
 
670
    F77_SYMBOL(optif9)(&n, &n, x, F77_SYMBOL(fcn), F77_SYMBOL(Cd1fcn),
662
    optif9(n, n, x, (fcn_p) fcn, (fcn_p) Cd1fcn, (d2fcn_p) Cd2fcn,
671
		       F77_SYMBOL(Cd2fcn), typsiz, &fscale,
-
 
672
		       &method, &iexp, &msg, &ndigit, &itnlim,
663
	   state, typsiz, fscale, method, iexp, &msg, ndigit, itnlim,
673
		       &iagflg, &iahflg, &ipr,
-
 
674
		       &dlt, &gradtl, &stepmx, &steptol,
664
	   iagflg, iahflg, dlt, gradtl, stepmx, steptol, xpls, &fpls,
675
		       xpls, &fpls, gpls, &code, a, wrk, &itncnt);
665
	   gpls, &code, a, wrk, &itncnt);
676
 
666
 
677
    if (msg < 0)
667
    if (msg < 0)
678
	opterror(msg);
668
	opterror(msg);
679
    if (code != 0 && (omsg&8) == 0)
669
    if (code != 0 && (omsg&8) == 0)
680
	optcode(code);
670
	optcode(code);
681
 
671
 
682
    if (want_hessian) {
672
    if (want_hessian) {
683
	PROTECT(value = allocVector(VECSXP, 6));
673
	PROTECT(value = allocVector(VECSXP, 6));
684
	PROTECT(names = allocVector(STRSXP, 6));
674
	PROTECT(names = allocVector(STRSXP, 6));
685
	F77_SYMBOL(fdhess)(&n, xpls, &fpls, F77_SYMBOL(fcn), a, &n,
675
	fdhess(n, xpls, fpls, (fcn_p) fcn, state, a, n, &wrk[0], &wrk[n],
686
			   &wrk[0], &wrk[n], &ndigit, typsiz);
676
	       ndigit, typsiz);
687
	for (i = 0; i < n; i++)
677
	for (i = 0; i < n; i++)
688
	    for (j = 0; j < i; j++)
678
	    for (j = 0; j < i; j++)
689
		a[i + j * n] = a[j + i * n];
679
		a[i + j * n] = a[j + i * n];
690
    }
680
    }
691
    else {
681
    else {
Line 729... Line 719...
729
    VECTOR(value)[k] = allocVector(INTSXP, 1);
719
    VECTOR(value)[k] = allocVector(INTSXP, 1);
730
    INTEGER(VECTOR(value)[k])[0] = itncnt;
720
    INTEGER(VECTOR(value)[k])[0] = itncnt;
731
    k++;
721
    k++;
732
 
722
 
733
    setAttrib(value, R_NamesSymbol, names);
723
    setAttrib(value, R_NamesSymbol, names);
734
    FT_free();
-
 
735
    vmaxset(vmax);
724
    vmaxset(vmax);
736
    UNPROTECT(3);
725
    UNPROTECT(3);
737
    return value;
726
    return value;
738
}
727
}
739
 
-
 
740
/*
-
 
741
 *  PURPOSE
-
 
742
 *
-
 
743
 *  Print information.	This code done in C to avoid the necessity
-
 
744
 *  of having the (vast) Fortran I/O library loaded.
-
 
745
 *
-
 
746
 *  PARAMETERS
-
 
747
 *
-
 
748
 *  nr	   --> row dimension of matrix
-
 
749
 *  n	   --> dimension of problem
-
 
750
 *  x(n)   --> iterate x[k]
-
 
751
 *  f	   --> function value at x[k]
-
 
752
 *  g(n)   --> gradient at x[k]
-
 
753
 *  a(n,n) --> hessian at x[k]
-
 
754
 *  p(n)   --> step taken
-
 
755
 *  itncnt --> iteration number k
-
 
756
 *  iflg   --> flag controlling info to print
-
 
757
 *  ipr	   --> device to which to send output [unused in C]
-
 
758
 */
-
 
759
 
-
 
760
int F77_SYMBOL(result)(int *nr, int *n, double *x, double *f, double *g,
-
 
761
		       double *a, double *p, int *itncnt, int *iflg, int *ipr)
-
 
762
{
-
 
763
    /* Print iteration number */
-
 
764
 
-
 
765
    Rprintf("iteration = %d\n", *itncnt);
-
 
766
 
-
 
767
    /* Print step */
-
 
768
 
-
 
769
    if (*iflg != 0) {
-
 
770
	Rprintf("Step:\n");
-
 
771
	printRealVector(p, *n, 1);
-
 
772
    }
-
 
773
 
-
 
774
    /* Print current iterate */
-
 
775
 
-
 
776
    Rprintf("Parameter:\n");
-
 
777
    printRealVector(x, *n, 1);
-
 
778
 
-
 
779
    /* Print function value */
-
 
780
 
-
 
781
    Rprintf("Function Value\n");
-
 
782
    printRealVector(f, 1, 1);
-
 
783
 
-
 
784
    /* Print gradient */
-
 
785
 
-
 
786
    Rprintf("Gradient:\n");
-
 
787
    printRealVector(g, *n, 1);
-
 
788
 
-
 
789
#ifdef NEVER
-
 
790
    /* Print Hessian */
-
 
791
    /* We don't do this because the printRealMatrix */
-
 
792
    /* code takes a SEXP rather than a double*. */
-
 
793
    /* We could do something ugly like use fixed */
-
 
794
    /* e format but that would be UGLY */
-
 
795
 
-
 
796
    if (*iflg != 0) {
-
 
797
    }
-
 
798
#endif
-
 
799
 
-
 
800
    Rprintf("\n");
-
 
801
    return 0;
-
 
802
}
-