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
* QUESTION:
I want to write a syntax command that works for a matrix whose the name and
the number of columns are dynamic.
The number of columns is always a multiple of 3.
I want to compute a variable based on three columns :
V(X) = f ( C(3(x-1)+1), C(3(x-1)+2), C3((x-1)+3) )


* SOLUTION posted by rlevesque@videotron.ca to newsgroup on 2001/05/11.

DATA LIST FREE /casenb.
BEGIN DATA
1 2 3 4
END DATA.
LIST.

VECTOR v(9F8.0).
LOOP #cnt=1 TO 9.
COMPUTE v(#cnt)=#cnt+casenb.
END LOOP.

SET MPRINT=yes.

* Define macro to do the job.
*/////////////////////////.
DEFINE !calc (result=!TOKENS(1) /dim=!TOKENS(1) /initial=!TOKENS(1))
/* result = name of result variable */.
/* dim = dimension of result variable */.
/* initial = name of initial vector, it's dimension is 3 times dim */.
VECTOR !CONCAT(!result,'(',!dim,')').

!DO !cnt=0 !TO !dim
!IF (!cnt !LT !dim) !THEN
!LET !idx=!LENGTH(!CONCAT(!BLANK(!cnt),!BLANK(1)))
!LET !len1=!LENGTH(!CONCAT(!BLANK(!cnt),!BLANK(!cnt),!BLANK(!cnt),!BLANK(1)))
!LET !len2=!LENGTH(!CONCAT(!BLANK(!len1),!BLANK(1)))
!LET !len3=!LENGTH(!CONCAT(!BLANK(!len2),!BLANK(1)))

COMPUTE #c1=!CONCAT(!initial,'(',!len1,')').
COMPUTE #c2=!CONCAT(!initial,'(',!len2,')').
COMPUTE #c3=!CONCAT(!initial,'(',!len3,')').
******************************.
* Change formula in next command to fit your need.
******************************.
COMPUTE !CONCAT(!result,!idx)=#c1 + 2*#c2 / #c3.
!IFEND
!DOEND
!ENDDEFINE.
*/////////////////////////.


* Example of use of the macro.

* Note: the vector 'initial' must be defined as a vector before calling the macro.
!calc result=r dim=3 initial=v.
EXECUTE.