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
* Вычисления с матрицей с непостоянным, но кратным 3 числом столбцов.

* ВОПРОС:
Мне нужно написать синтаксис, который бы производил вычисления с матрицей, 
имена и число колонок в которой могут меняться, но число колонок при этом 
остается кратным 3.
Мне нужно построить другую матрицу, число колонок в которой будет в 3 раза меньше, 
чем в исходной, и каждая колонка будет строиться на основе 3 соответствующих колонок
исходной матрицы.

То есть, 

R(X) = f( c(3(X-1)+1, c(3(X-1)+2), c(3(X-1)+3) ), где
X - номер столбца итоговой матрицы. с() - указание на соответствующий номер столбца исходной матрицы.


* РЕШЕНИЕ размещено в новостной группе 11.05.2001. Автор: rlevesque@videotron.ca.

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

* Создадим исходную матрицу v с 9 столбцами и заполним её какими-либо данными для примера.
VECTOR v(9F8.0).
LOOP #cnt=1 TO 9.
COMPUTE v(#cnt)=#cnt+casenb.
END LOOP.

SET MPRINT=yes.

* Определим рабочий макрос.
*/////////////////////////.
DEFINE !calc (result=!TOKENS(1) /dim=!TOKENS(1) /initial=!TOKENS(1))
/* result = имя результирующей матрицы                           */.
/* dim = вертикальная размерность результирующей матрицы         */.
/* initial = имя исходной матрицы, чья вертикальная размерность равна 3*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,')').
******************************.
* Исправьте формулу ниже под ваши нужды.
******************************.
COMPUTE !CONCAT(!result,!idx)=#c1 + 2*#c2 / #c3.
!IFEND
!DOEND
!ENDDEFINE.
*/////////////////////////.


* Пример вызова макроса.

* Примеч.: матрица 'initial' должна существовать (быть определена) перед вызовом макроса.
* Определяется - командой VECTOR.
!calc result=r dim=3 initial=v.
EXECUTE.