1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
*(Q) I have a macro which includes a !DO - !DOEND loop. The purpose of the loop
	is to repeat a iterations until a the equation converge within a predefined 
	precision. Each iteration takes quite a long time. How can I stop the iteration
	process as the convergence criteria has been met.

* (A) Raynald Levesque 2001/09/22
	To illustrate the a solution, I first use a macro which does not
	stop once convergence has been attained. I then modify the 
	macro so that the macro exits the loop once convergence has 
	been achieved. (Actually, the loop continues but without executing 
	any commands). 
	
* File name: MacroExitsLoopWhenDataMeetConvergenceCriteria.SPS.

SET SEED=12365981.
SET MPRINT=yes.

*/////////////////////////////////.
DEFINE !eloop1 (max=!TOKENS(1))

!DO !cnt=1 !TO !max
COMPUTE cnt=!cnt.

* Next DO IF - END IF is a proxy for the real calculations.
* Assume that when we get conver=1, it means we have convergence.
DO IF $CASENUM=1.
COMPUTE conver=TRUNC(UNIFORM(10)).
ELSE.
COMPUTE conver=LAG(conver).
END IF.
LIST.
!DOEND

!ENDDEFINE.
*/////////////////////////////////.

!eloop1 max=10. /* This macro continues to loop even when conver=1*/.

exe.

***********************************************************************.
*
*	With the following modifications the above macro stops
*	 to execute the loop
*	once the convergence has been reached.
*
***********************************************************************.

SET SEED=12365981.
SET MPRINT=yes.
DEFINE !ok()0!ENDDEFINE.

DEFINE !eloop2 (max=!TOKENS(1))

!DO !cnt=1 !TO !max
COMPUTE cnt=!cnt.

DO IF !ok<>1.
+	DO IF $CASENUM=1.
+	COMPUTE conver=TRUNC(UNIFORM(10)).
+	ELSE.
+	COMPUTE conver=LAG(conver).
+	END IF.
+	DO IF $CASENUM=1.
+	FORMAT conver (F2.0).
+	WRITE OUTFILE='c:\\temp\\temp.SPS' /"DEFINE !ok()"conver"!ENDDEFINE.".
+	END IF.
+	PRINT /a 1-2 cnt 5-7 conver 9-10.
END IF.
EXECUTE.
INCLUDE FILE='c:\\temp\\temp.SPS' .
!DOEND
!ENDDEFINE.


SET MPRINT=yes.
!eloop2 max=10. /* This macro exits loop when conver=1*/.

exe.