From luann@cognigencorp.com Fri Aug 23 10:36:40 1996
Subject: LOG(F) Error Model/Machine Differences

NONMEM Users,

We have recently been working with analyses requiring error models incorporating LOG(F). During this process, we discovered that this type of $ERROR model is handled differently for a DEC Alpha machine versus a SUN workstation. I have outlined the problem and the solution below. I've also included my interpretation of why the problem occurs and one exception for which the `solution' does not work (Many thanks, to Alison). I have been told that the VAX performs similar to the DEC. I have not heard how the MAINFRAME handles this error model.

Luann

/**************************************/
/* ERROR MODELS INVOLVING LOG(F) */
/**************************************/

PROBLEM:
$ERROR
Y=LOG(F) + EPS(1) or any other model with log(F)
SUN: Will successfully complete the NONMEM run as it appears unless the data file contains concentrations prior to the first dose of drug. In the later case, NONMEM gives an INTRA-INDIVIDUAL VARIABILITY ESTIMATED TO BE ZERO error.
DEC: Produces an immediate fortran error code of DIVIDE BY ZERO.
SOLUTION:
$ERROR
FLAG=0
IF(AMT.NE.0) FLAG=1
Y=LOG(F+FLAG) + EPS(1)
For dose records, Y=LOG(F+1) + EPS(1).
For other records, Y=LOG(F) + EPS(1).

WHY: For first dose records, NONMEM estimates F=0. For the error model Y=LOG(F)+EPS(1), this requires NONMEM to compute LOG(0) which is -infinity. Since the DEC FORTRAN compiler is set to disallow exceptional values(I believe this is the default), the run results in a FORTRAN error code. SUN FORTRAN compilers allow exceptional values and therefore the run is completed. Since the predicted Cp for DOSE records does NOT impact the fit of a model, the above code will allow both the DEC and the SUN to fit the LOG CP model.

EXCEPTION: If NONMEM predicts a Cp of zero for a concentration record, the DEC and SUN will still result in the errors described above. If this occurs, the use of the LOG CP model should be revaluated or the problematic data records should be deleted from the analysis.

****

From n.holford@auckland.ac.nz Sun Aug 25 13:49:10 1996
Subject: Re: LOG(F) Error Model/Machine Differences

> We have recently been working with analyses requiring error models
> incorporating LOG(F). During this process, we discovered that this
> type of $ERROR model is handled differently for a DEC Alpha machine
> versus a SUN workstation.

This note is a helpful observation about some of the subtle requirements for successful use of NONMEM. But it seems that the problem is incorrectly described as a machine difference when it would appear to be a difference in the compiler options used on the two machines. Can Luann or anyone else clarify if my interpretation is correct? And if so what compiler options control whether DIVIDE BY ZERO raises an error?

Using the HP f77 compiler the +T option causes division by zero to raise an error while the default option returns +INF as the result (Note however that LOG(0) with HP f77 always returns -INF irrespective of the +T option!).

If the DIVIDE BY ZERO error produced by LOG(0) and the DEC compiler can be trapped then an error handler can probably be added to the NONMEM code that returns -INF. This would only have to be done once instead of having to remember to use the work around Luann described in every NMTRAN control stream that uses the LOG(F) model.

--
Nick Holford, Dept Pharmacology & Clinical Pharmacology
University of Auckland, Private Bag 92019, Auckland, New Zealand
email:n.holford@auckland.ac.nz tel:+64(9)373-7599x6730 fax:373-7556
http://www.phm.auckland.ac.nz/Staff/NHolford/nholford.html

****

From alison Tue Aug 27 13:17:20 1996
Subject: LOG(F) error model/ machine differences

Luann Phillips and Nick Holford recently sent email about the difficulty of computing LOG(0).

Both have given useful advice.

As for Nick's remarks, there is some question in my mind if all hardware / compiler platforms can be made to adhere to the IEEE standard and allow floating point exceptions to occur without stopping the run, by developing default values such as Inf and NaN.

Even if they can be made to do this, there are risks when NONMEM is allowed to compute with these IEEE default values. They should *never* be allowed to contribute to the NONMEM objective function. I.e., the user must insure that invalid floating point operations such as LOG(0) do not occur with observation records.

The only floating point exception that should be permitted is underflow, and underflow must always produce zero as the result.

I think that Luann has the right idea: if any floating point exception other than underflow occurs, fix the abbreviated code and/or model to avoid it.

Granted that Luann' workaround for LOG(F) when F=0 on a dose record is tedious to code, it is the best way to proceed. A more general way to code it is as follows:

FLAG=0
IF(F.EQ.0) FLAG=1
Y=(1-FLAG)*LOG(F+FLAG) + EPS(1)

Alison Boeckmann

****

From n.holford@auckland.ac.nz Sat Aug 31 16:55:18 1996
Subject: Re: LOG(F) error model

> Even if they can be made to do this, there are risks when NONMEM is
> allowed to compute with these IEEE default values. They should *never*
> be allowed to contribute to the NONMEM objective function. I.e., the
> user must insure that invalid floating point operations such as LOG(0)
> do not occur with observation records.

Ok. So if this is the case then one must ALWAYS use the code you suggest

>
> FLAG=0
> IF(F.EQ.0) FLAG=1
> Y=(1-FLAG)*LOG(F+FLAG) + EPS(1)
>

because compilers which do not raise errors with LOG(0) will presumably return -INF or NaN and you say this should *never*be allowed to happen. No compiler will return 0 as LOG(0) which is what your code is equivalent to. In a more general way - is'nt this a problem for NMTRAN to address? If the above code fragment is always needed for safe operation then why not get NMTRAN to generate it? Or why not make NONMEM `aware' of the problem and to ignore when F is 0 and the LOG transformed model is being used?
--
Nick Holford, Dept Pharmacology & Clinical Pharmacology
University of Auckland, Private Bag 92019, Auckland, New Zealand
email:n.holford@auckland.ac.nz tel:+64(9)373-7599x6730 fax:373-7556
http://www.phm.auckland.ac.nz/Staff/NHolford/nholford.html

****

From alison Wed Sep 4 10:20:40 1996
Subject: More about LOG(F)

My comments on this follow.

I realize that no compiler will return 0 as LOG(0). But with a dose event MDV is 1 ("missing dependent variable"), and the value computed for Y is moot. It might as well be 0 as any other value, and 0 is less confusing than any other number one might compute. What did the user do when taking the LOG's of the DV values? With the dose record, DV was not measured, so presumably was recorded as . or 0. If the user left the 0 as-is, then this is reasonable for the value of Y as well.

It is difficult to know what NM-TRAN can do about the LOG(0) problem. Perhaps it is clear when the abbreviated code is "Y=LOG(F)+EPS(1)" in $ERROR or $PRED, and F=0 only occurs when MDV=1. But there are other cases when it is less clear what NM-TRAN should do. E.g., what if there are pre-dose observations (which can happen with lag time), or observations so late in time (or for an individual with such extremely rapid clearance) that the preditions underflow to 0. The LOG(F) model is not appropriate, and the user must deal with this.

Perhaps it should be up to NONMEM to compute the LOG of DV and/or the LOG of the prediction. But for now, the user must take the responsibility.

There is one other option, however. With a simple $ERROR block, an no simulation, why not simply include CALLFL=0?

$ERROR
CALLFL=0
Y=LOG(F)+EPS(1)

This says to PREDPP:

DURING SIMULATION, ERROR SUBROUTINE CALLED WITH EVERY EVENT RECORD. OTHERWISE, ERROR SUBROUTINE CALLED ONLY WITH OBSERVATION EVENTS.

With dose events the ERROR routine is not called (i.e,. the $ERROR statements are not evaluated), and so LOG(0) is never computed.

****

From n.holford@auckland.ac.nz Wed Sep 4 13:53:35 1996
Subject: Re: More about LOG(F)

Alison,

Thanks for your further comments on this issue.

My point relates to the consequences of a compiler returning -INF for LOG(0). First of all consider the case when MDV=1. As far as I can tell it should make no difference to NONMEM what is returned. The only difference is in terms of what gets written to the TABLE output for the model prediction. On my HP system LOG(0) is -INF and EXP(-INF) is 0. So I think that I will get the "correct" prediction.

The situation when MDV=0 is different. I think this is very much the responsibility of the user. If the prediction is 0 e.g. at a time before a lagged dose enters the system or at a very late time when the prediction underflows to zero then if the user should be prepared to recognse that an additive component to the error model is probably appropriate and a simple proportional one as implied by the LOG() model is not sufficient. Your earlier suggestion of returning 0 when F=0 (even when MDV=0) should only be done with a full understanding by the user that they may be introducing serious error model misspecification.

So to sum up:

1. If your compiler produces a run time error when asked to compute LOG(0) then you need to use one of the workarounds (A. use special code when F=0 B. Use CALLFL=0 C. Change your compiler error trapping) to deal with MDV=1 and F=0.

2. If MDV=0 and F=0 you are (probably) introducing model misspecification for your error model. The work arounds may or may not be the right thing to do. Personally I would always add an additive component to the error model in this situation.
--
Nick Holford, Dept Pharmacology & Clinical Pharmacology
University of Auckland, Private Bag 92019, Auckland, New Zealand
email:n.holford@auckland.ac.nz tel:+64(9)373-7599x6730 fax:373-7556
http://www.phm.auckland.ac.nz/Staff/NHolford/nholford.html