The MODEL Procedure |
Diagnostics and Debugging |
PROC MODEL provides several features to aid in finding errors in the model program. These debugging features are not usually needed; most models can be developed without them.
The example model program that follows is used in the following sections to illustrate the diagnostic and debugging capabilities. This example is the estimation of a segmented model.
/*--- Diagnostics and Debugging ---*/ *---------Fitting a Segmented Model using MODEL----* | | | | y | quadratic plateau | | | y=a+b*x+c*x*x y=p | | | ..................... | | | . : | | | . : | | | . : | | | . : | | | . : | | +-----------------------------------------X | | x0 | | | | continuity restriction: p=a+b*x0+c*x0**2 | | smoothness restriction: 0=b+2*c*x0 so x0=-b/(2*c)| *--------------------------------------------------*; title 'QUADRATIC MODEL WITH PLATEAU'; data a; input y x @@; datalines; .46 1 .47 2 .57 3 .61 4 .62 5 .68 6 .69 7 .78 8 .70 9 .74 10 .77 11 .78 12 .74 13 .80 13 .80 15 .78 16 ; proc model data=a list xref listcode; parms a 0.45 b 0.5 c -0.0025; x0 = -.5*b / c; /* join point */ if x < x0 then /* Quadratic part of model */ y = a + b*x + c*x*x; else /* Plateau part of model */ y = a + b*x0 + c*x0*x0; fit y; run;
The LIST option produces a listing of the model program. The statements are printed one per line with the original line number and column position of the statement.
The program listing from the example program is shown in Figure 18.85.
Listing of Compiled Program Code | ||
---|---|---|
Stmt | Line:Col | Statement as Parsed |
1 | 3712:4 | x0 = (-0.5 * b) / c; |
2 | 3713:4 | if x < x0 then |
3 | 3714:7 | PRED.y = a + b * x + c * x * x; |
3 | 3714:7 | RESID.y = PRED.y - ACTUAL.y; |
3 | 3714:7 | ERROR.y = PRED.y - y; |
4 | 3715:4 | else |
5 | 3716:7 | PRED.y = a + b * x0 + c * x0 * x0; |
5 | 3716:7 | RESID.y = PRED.y - ACTUAL.y; |
5 | 3716:7 | ERROR.y = PRED.y - y; |
The LIST option also shows the model translations that PROC MODEL performs. LIST output is useful for understanding the code generated by the %AR and the %MA macros.
The XREF option produces a cross-reference listing of the variables in the model program. The XREF listing is usually used in conjunction with the LIST option. The XREF listing does not include derivative (@-prefixed) variables. The XREF listing does not include generated assignments to equation variables, PRED., RESID., and ERROR.-prefixed variables, unless the DETAILS option is used.
The cross-reference from the example program is shown in Figure 18.86.
Cross Reference Listing For Program | |||
---|---|---|---|
Symbol----------- | Kind | Type | References (statement)/(line):(col) |
a | Var | Num | Used: 3/51043:13 5/51045:13 |
b | Var | Num | Used: 1/51041:12 3/51043:16 5/51045:16 |
c | Var | Num | Used: 1/51041:15 3/51043:22 5/51045:23 |
x0 | Var | Num | Assigned: 1/51041:15 |
Used: 2/51042:11 5/51045:16 5/51045:23 5/51045:26 | |||
x | Var | Num | Used: 2/51042:11 3/51043:16 3/51043:22 3/51043:24 |
PRED.y | Var | Num | Assigned: 3/51043:19 5/51045:20 |
The LISTCODE option lists the model code and derivatives tables produced by the compiler. This listing is useful only for debugging and should not normally be needed.
LISTCODE prints the operator and operands of each operation generated by the compiler for each model program statement. Many of the operands are temporary variables generated by the compiler and given names such as #temp1. When derivatives are taken, the code listing includes the operations generated for the derivatives calculations. The derivatives tables are also listed.
A LISTCODE option prints the transformed equations from the example shown in Figure 18.87 and Figure 18.88.
Derivatives | ||
---|---|---|
WRT-Variable | Object-Variable | Derivative-Variable |
a | RESID.y | @RESID.y/@a |
b | RESID.y | @RESID.y/@b |
c | RESID.y | @RESID.y/@c |
Listing of Compiled Program Code | ||
---|---|---|
Stmt | Line:Col | Statement as Parsed |
1 | 3712:4 | x0 = (-0.5 * b) / c; |
1 | 3712:4 | @x0/@b = -0.5 / c; |
1 | 3712:4 | @x0/@c = - x0 / c; |
2 | 3713:4 | if x < x0 then |
3 | 3714:7 | PRED.y = a + b * x + c * x * x; |
3 | 3714:7 | @PRED.y/@a = 1; |
3 | 3714:7 | @PRED.y/@b = x; |
3 | 3714:7 | @PRED.y/@c = x * x; |
3 | 3714:7 | RESID.y = PRED.y - ACTUAL.y; |
3 | 3714:7 | @RESID.y/@a = @PRED.y/@a; |
3 | 3714:7 | @RESID.y/@b = @PRED.y/@b; |
3 | 3714:7 | @RESID.y/@c = @PRED.y/@c; |
3 | 3714:7 | ERROR.y = PRED.y - y; |
4 | 3715:4 | else |
5 | 3716:7 | PRED.y = a + b * x0 + c * x0 * x0; |
5 | 3716:7 | @PRED.y/@a = 1; |
5 | 3716:7 | @PRED.y/@b = x0 + b * @x0/@b + (c * @x0/@b * x0 + c * x0 * @x0/@b); |
5 | 3716:7 | @PRED.y/@c = b * @x0/@c + ((x0 + c * @x0/@c) * x0 + c * x0 * @x0/@c); |
5 | 3716:7 | RESID.y = PRED.y - ACTUAL.y; |
5 | 3716:7 | @RESID.y/@a = @PRED.y/@a; |
5 | 3716:7 | @RESID.y/@b = @PRED.y/@b; |
5 | 3716:7 | @RESID.y/@c = @PRED.y/@c; |
5 | 3716:7 | ERROR.y = PRED.y - y; |
1 Stmt ASSIGN | line 3712 column 4. (1) arg=x0 argsave=x0 | |
Source Text: | x0 = -.5*b / c; | |
Oper * | at 3712:12 (30,0,2). | * : _temp1 <- -0.5 b |
Oper / | at 3712:15 (31,0,2). | / : x0 <- _temp1 c |
Oper eeocf | at 3712:15 (18,0,1). | eeocf : _DER_ <- _DER_ |
Oper / | at 3712:15 (31,0,2). | / : @x0/@b <- -0.5 c |
Oper - | at 3712:15 (24,0,1). | - : @1dt1_2 <- x0 |
Oper / | at 3712:15 (31,0,2). | / : @x0/@c <- @1dt1_2 c |
2 Stmt IF | line 3713 column 4. (2) arg=_temp1 argsave=_temp1 | ref.st=ASSIGN stmt number 5 at 3716:7 |
Source Text: | if x < x0 then | |
Oper < | at 3713:11 (36,0,2). | < : _temp1 <- x x0 |
3 Stmt ASSIGN | line 3714 column 7. (1) arg=PRED.y argsave=y | |
Source Text: | /* Quadratic part of model */ y = a + b*x + c*x*x; | |
Oper * | at 3714:16 (30,0,2). | * : _temp1 <- b x |
Oper + | at 3714:13 (32,0,2). | + : _temp2 <- a _temp1 |
Oper * | at 3714:22 (30,0,2). | * : _temp3 <- c x |
Oper * | at 3714:24 (30,0,2). | * : _temp4 <- _temp3 x |
Oper + | at 3714:19 (32,0,2). | + : PRED.y <- _temp2 _temp4 |
Oper eeocf | at 3714:19 (18,0,1). | eeocf : _DER_ <- _DER_ |
Oper = | at 3714:19 (1,0,1). | = : @PRED.y/@a <- 1 |
Oper = | at 3714:19 (1,0,1). | = : @PRED.y/@b <- x |
Oper * | at 3714:24 (30,0,2). | * : @1dt1_1 <- x x |
Oper = | at 3714:19 (1,0,1). | = : @PRED.y/@c <- @1dt1_1 |
3 Stmt Assign | line 3714 column 7. (1) arg=RESID.y argsave=y | |
Oper - | at 3714:7 (33,0,2). | - : RESID.y <- PRED.y ACTUAL.y |
Oper eeocf | at 3714:7 (18,0,1). | eeocf : _DER_ <- _DER_ |
Oper = | at 3714:7 (1,0,1). | = : @RESID.y/@a <- @PRED.y/@a |
Oper = | at 3714:7 (1,0,1). | = : @RESID.y/@b <- @PRED.y/@b |
Oper = | at 3714:7 (1,0,1). | = : @RESID.y/@c <- @PRED.y/@c |
3 Stmt Assign | line 3714 column 7. (1) arg=ERROR.y argsave=y | |
Oper - | at 3714:7 (33,0,2). | - : ERROR.y <- PRED.y y |
4 Stmt ELSE | line 3715 column 4. (9) | ref.st=FIT stmt number 5 at 3718:4 |
Source Text: | else | |
5 Stmt ASSIGN | line 3716 column 7. (1) arg=PRED.y argsave=y | |
Source Text: | /* Plateau part of model */ y = a + b*x0 + c*x0*x0; | |
Oper * | at 3716:16 (30,0,2). | * : _temp1 <- b x0 |
Oper + | at 3716:13 (32,0,2). | + : _temp2 <- a _temp1 |
Oper * | at 3716:23 (30,0,2). | * : _temp3 <- c x0 |
Oper * | at 3716:26 (30,0,2). | * : _temp4 <- _temp3 x0 |
Oper + | at 3716:20 (32,0,2). | + : PRED.y <- _temp2 _temp4 |
Oper eeocf | at 3716:20 (18,0,1). | eeocf : _DER_ <- _DER_ |
Oper = | at 3716:20 (1,0,1). | = : @PRED.y/@a <- 1 |
Oper * | at 3716:16 (30,0,2). | * : @1dt1_1 <- b @x0/@b |
Oper + | at 3716:16 (32,0,2). | + : @1dt1_2 <- x0 @1dt1_1 |
Oper * | at 3716:23 (30,0,2). | * : @1dt1_3 <- c @x0/@b |
Oper * | at 3716:26 (30,0,2). | * : @1dt1_4 <- @1dt1_3 x0 |
Oper * | at 3716:26 (30,0,2). | * : @1dt1_5 <- _temp3 @x0/@b |
Oper + | at 3716:26 (32,0,2). | + : @1dt1_6 <- @1dt1_4 @1dt1_5 |
Oper + | at 3716:20 (32,0,2). | + : @PRED.y/@b <- @1dt1_2 @1dt1_6 |
Oper * | at 3716:16 (30,0,2). | * : @1dt1_8 <- b @x0/@c |
Oper * | at 3716:23 (30,0,2). | * : @1dt1_9 <- c @x0/@c |
Oper + | at 3716:23 (32,0,2). | + : @1dt1_10 <- x0 @1dt1_9 |
Oper * | at 3716:26 (30,0,2). | * : @1dt1_11 <- @1dt1_10 x0 |
Oper * | at 3716:26 (30,0,2). | * : @1dt1_12 <- _temp3 @x0/@c |
Oper + | at 3716:26 (32,0,2). | + : @1dt1_13 <- @1dt1_11 @1dt1_12 |
Oper + | at 3716:20 (32,0,2). | + : @PRED.y/@c <- @1dt1_8 @1dt1_13 |
5 Stmt Assign | line 3716 column 7. (1) arg=RESID.y argsave=y | |
Oper - | at 3716:7 (33,0,2). | - : RESID.y <- PRED.y ACTUAL.y |
Oper eeocf | at 3716:7 (18,0,1). | eeocf : _DER_ <- _DER_ |
Oper = | at 3716:7 (1,0,1). | = : @RESID.y/@a <- @PRED.y/@a |
Oper = | at 3716:7 (1,0,1). | = : @RESID.y/@b <- @PRED.y/@b |
Oper = | at 3716:7 (1,0,1). | = : @RESID.y/@c <- @PRED.y/@c |
5 Stmt Assign | line 3716 column 7. (1) arg=ERROR.y argsave=y | |
Oper - | at 3716:7 (33,0,2). | - : ERROR.y <- PRED.y y |
Copyright © 2008 by SAS Institute Inc., Cary, NC, USA. All rights reserved.