Forth
http://fforum.winglion.ru/

Возможность работать с многомерными массивами
http://fforum.winglion.ru/viewtopic.php?f=18&t=2627
Страница 2 из 4

Автор:  chess [ Сб июл 31, 2010 07:36 ]
Заголовок сообщения:  Re: Есть ли в SP-Forth

более быстрый вариант реализации арифм. операций (для сокращения писанины используем макросы)

Код:
M: []OP(
   []0 a2! DUP []0 a1! []SIZE CELLS
   0 DO I a1 + @ I a2 + @ ;
M: )[]OP
   I a1 + ! CELL +LOOP ;

: []+ \ A1 A2 -- к массиву A1 прибавляем массив A2
  []OP( + )[]OP ;

: []- \ A1 A2 -- из массива A1 вычитаем массив A2
  []OP( - )[]OP ;

: []* \ A1 A2 -- массив A1 умножаем на массив A2
  []OP( * )[]OP ;

: []/ \ A1 A2 -- массив A1 делим на массив A2
  []OP( / )[]OP ;

: []MOD \ A1 A2 -- массив A1 остатки от деления массива A1 на массив A2
  []OP( MOD )[]OP ;


пс. В дальнейшем код по массивам нужно перевести на уровень ассемблера для ускорения.

Автор:  WingLion [ Сб июл 31, 2010 08:13 ]
Заголовок сообщения:  Re: Есть ли в SP-Forth

А заглянуть в учебник Высшей Алгебры никто не догадался?
На предмет "операций с массивами"...
А то они начинают выглядеть уж очень смешно.
Особенно поэлементное умножение и деление.
А над остатком от деления - ржунимагу...

E$ли непонятно, отчего смех,
смотрим хотя бы сюда: http://ru.wikipedia.org/wiki/Basic_Line ... ubprograms

Автор:  mOleg [ Сб июл 31, 2010 09:04 ]
Заголовок сообщения:  Re: Есть ли в SP-Forth

Мне кажется, что обсуждение работы с массивами стоит выделить в отдельную тему.

Автор:  mOleg [ Сб июл 31, 2010 09:07 ]
Заголовок сообщения:  Re: Есть ли в SP-Forth

кстати в пакете СПФа работа с матрицами есть как минимум у ~diver см .\devel\~diver\matrix
и еще .\devel\~day\fsim\source\MATRIX.F

Автор:  вопрос [ Сб июл 31, 2010 21:26 ]
Заголовок сообщения:  Re: Есть ли в SP-Forth

WingLion писал(а):
А заглянуть в учебник Высшей Алгебры никто не догадался?
На предмет "операций с массивами"...
А то они начинают выглядеть уж очень смешно.
Особенно поэлементное умножение и деление.
А над остатком от деления - ржунимагу...

E$ли непонятно, отчего смех,
смотрим хотя бы сюда: http://ru.wikipedia.org/wiki/Basic_Line ... ubprograms

:? и что должны были бы делать фортеры :wink:

Автор:  WingLion [ Сб июл 31, 2010 22:58 ]
Заголовок сообщения:  Re: Возможность работать с многомерными массивами

вопрос писал(а):
:? и что должны были бы делать фортеры :wink:


Как минимум - не выдумывать бессмысленные операции с массивами.

Автор:  chess [ Чт авг 05, 2010 10:53 ]
Заголовок сообщения:  Re: Возможность работать с многомерными массивами

Многомерные массивы(одномерные как частный случай многомерных, при k=1)

Код:
: ARRAY \ N1 N2 .. Nk k --  создание массива
  1 sz! 1 ct! CREATE DUP , HERE beg! 0 DO , LOOP HERE beg
  DO I @ DUP sz * is sz I beg <> IF ct * DUP is ct , ELSE 1 , DROP THEN CELL +LOOP
  sz 1+ CELLS ALLOT DOES> ;

\ слово ARRAY формирует сл. структуру данных:
\ ------------------------- ЗАГОЛОВОК----------------------------------           --- ДАННЫЕ ---
\ k Nk Nk-1 ........ N1  1 Nk-1 Nk-1*Nk-2 ................... Nk-1*..*N1         N1 ........... Nn
\ 1 пределы координат    коэф-ты для расчета номера элемента по его координатам   собственно массив

: [DIM  ( A -- k  дать мерность массива )  @ ;
: [HLEN  ( A -- LEN  длина заголовка массива ) @ A++ $ 3 #A<< ;

: C[A  \ CRD A -- A[i]  дать адрес элемента массива по его координатам
  >R 0 R@ DUP @ 1+ CELLS + DUP R@ @ CELLS + SWAP
  DO SWAP I @ * + CELL +LOOP CELLS R@ [HLEN + R> + ;

: N[C \ N A -- K1 .. Kk  получение координат элемента по его номеру
  >R R@ DUP @ 1+ CELLS + R> DUP @ 2* CELLS +
  DO I @ /MOD SWAP -4 +LOOP DROP ;

: C[@  ( CRD A -- N  читать элемент по его координатам ) C[A @ ;
: C[!  ( n CRD A --  писать элемент по его координатам ) C[A ! ;

: [SIZE \ A -- N=N1*..*Nk  дать размер массива
  >R 1 R@ DUP @ 1+ CELLS + R> CELL+ DO I @ * CELL +LOOP ;

: [LIMC \ A -- N1 ... Nk k  дать пределы по координатам и их кол-во
  >R R@ R> DUP @ CELLS + DO I @ -4 +LOOP ;

: [A0 ( A -- A[0] дать адрес первого элемента массива) B=A [HLEN A+B ;

\ операции над одним массивом
: [MAX \ A -- NMAX
  >R 0x80000001  R@ DUP [SIZE CELLS + R> [A0
  DO I @ MAX CELL +LOOP ;

: [MIN \ A -- NMAX
  >R 0x7FFFFFFF R@ DUP [SIZE CELLS + R> [A0
  DO I @ MIN CELL +LOOP ;

\ обнулить массив
: [ERASE ( A --) DUP [A0 SWAP [SIZE CELLS ERASE ;

\ заполнить массив со стека параметров
: S[! ( n..n A -- ) DUP [A0 a! [SIZE 0 DO I CELLS a + ! LOOP ;

M: 1O[  DUP >R DUP [A0 a! [SIZE CELLS 0 DO I a + DUP @ ;
M: ]1O  SWAP ! CELL +LOOP R> ;

: [NOT ( A -- )  1O[ INVERT ]1O ;
: [NEG ( A -- )  1O[ NEGATE ]1O ;
: [ABS ( A -- )  1O[ ABS    ]1O ;

\ операции над массивом и константой

\ заполнить массив константой
: [#!  ( A # -- )
  SWAP DUP [A0 SWAP [SIZE CELLS OVER + SWAP DO DUP I ! CELL +LOOP DROP ;

\ заполнить часть массива (от CRD-BEG до CRD-END включительно) константой
: C[#! ( CRD-BEG CRD-END A # --)
  >R DUP >R C[A R> SWAP >R C[A R> CELL+ SWAP R> -ROT DO DUP I ! CELL +LOOP DROP ;

M: #[   con! DUP >R DUP [A0 a! [SIZE CELLS 0 DO I a + DUP @ con ;
M: ]#   SWAP ! CELL +LOOP R> ;

: [+#  #[ + ]#   ;  : [-#  #[ - ]#  ;  : [*#  #[ * ]#   ;  : [/#  #[ * ]# ;
: [%#  #[ MOD ]# ;  : [|#  #[ OR ]# ;  : [^#  #[ XOR ]# ;  : [&#  #[ AND ]# ;

\ операции над двумя массивами
M: 2O[ [A0 a2! DUP DUP >R [A0 a1! [SIZE CELLS 0 DO I a1 + @ I a2 + @  ;
M: ]2O  I a1 + ! CELL +LOOP R> ;

: [+ ( A1 A2 -- A1 = A1  +  A2) 2O[  +  ]2O ;
: [- ( A1 A2 -- A1 = A1  -  A2) 2O[  -  ]2O ;
: [* ( A1 A2 -- A1 = A1  *  A2) 2O[  *  ]2O ;
: [/ ( A1 A2 -- A1 = A1  /  A2) 2O[  /  ]2O ;
: [% ( A1 A2 -- A1 = A1 MOD A2) 2O[ MOD ]2O ;
: [| ( A1 A2 -- A1 = A1 OR  A2) 2O[  OR ]2O ;
: [^ ( A1 A2 -- A1 = A1 XOR A2) 2O[ XOR ]2O ;
: [& ( A1 A2 -- A1 = A1 AND A2) 2O[ AND ]2O ;

\ утилиты
: [DUMP ( A -- ) DUP [SIZE CELLS SWAP [A0 SWAP DUMP CR ;

В качестве примера:
моделирование модулярной арифметики
(арифметика в Системе Остаточных Классов)
Код:
\ EOF
\ набор оснований для диапазона представления чисел в СОК
\ от 0 до 2*3*5*7*11*13*17*19*23*29*31 (основания - взаимно-простые числа)

11  1 ARRAY modbase \ набор оснований

2 3 5 7 11 13 17 19 23 29 31 modbase S[!

11  1 ARRAY n1  n1 88888 [#!          \ первое число
11  1 ARRAY n2  n2 11111 [#!          \ второе
11  1 ARRAY n3  n3 88888 11111 - [#!  \ третье для проверки

\ Модулярное представление чисел n1 и n2 (в системе остаточных классов)

n1 modbase [% DROP
n2 modbase [% DROP
n3 modbase [% DROP

\ определим операции над числами в СОК
\ сложение
: %+ ( A1 A2 -- A1 ) [+ modbase [% ;

\ умножение
: %* ( A1 A2 -- A1 ) [* modbase [% ;

\ вычитание
: %NEG ( A -- A ) [NEG modbase [+ ;
: %- ( A1 A2 -- A1 ) DUP >R %NEG %+ R> %NEG DROP ;


\ n1 n2 %* [DUMP    \ умножение - результат в n1
\ n1 n2 %+ [DUMP    \ сложение
  n1 n2 %- [DUMP

\ проверка
n3 [DUMP

лог.
Код:
5B1304   1D 00 00 00  1C 00 00 00  0E 00 00 00  0A 00 00 00 ................
5B1314   02 00 00 00  0B 00 00 00  07 00 00 00  00 00 00 00 ................
5B1324   02 00 00 00  02 00 00 00  01 00 00 00  3F 13 5B 00 ............?.[.

5B13A4   1D 00 00 00  1C 00 00 00  0E 00 00 00  0A 00 00 00 ................
5B13B4   02 00 00 00  0B 00 00 00  07 00 00 00  00 00 00 00 ................
5B13C4   02 00 00 00  02 00 00 00  01 00 00 00  DF 13 5B 00 ............Я.[.

Ok
пс.
Умножение таких чисел сводится к умножению в модулярных частях без переносов между ними
(с последующим приведением к модулярному представлению )
так можно быстро(за счет параллельности вычислений)
работать с очень большими числами (конечно такие вычисления надо реализовывать
в спец. многопроцессорных машинах).
Сами модули по разрядности как раз маленькие(здесь 5 разрядов).

Автор:  chess [ Пт авг 06, 2010 15:29 ]
Заголовок сообщения:  Re: Возможность работать с многомерными массивами

Несколько изменил синтаксис оперирования с массивами. Теперь оно напоминает оперирование с числами в форте.
(Изменения сделаны в пред. посте.)
Например сложение массивов:
: [+ ( A1 A2 -- A1 ) ... ;
После сложения , которое заключается в прибавлении элементов второго массива к соответствующим элементам первого
массива, на стеке остается адрес первого массива(того, элементы, которого стали суммой).
Аналогично с операциями над массивом и константой(за исключением загрузки массива константой).

Автор:  Hishnik [ Пт авг 06, 2010 15:32 ]
Заголовок сообщения:  Re: Возможность работать с многомерными массивами

chess писал(а):
на стеке остается адрес первого массива(того, элементы, которого стали суммой).

А если немного попользоваться такой операцией, может создасться впечатление, что на стеке ничего оставлять не надо.

Автор:  chess [ Пт авг 06, 2010 15:38 ]
Заголовок сообщения:  Re: Возможность работать с многомерными массивами

Хищник писал(а):
А если немного попользоваться такой операцией, может создасться впечатление, что на стеке ничего оставлять не надо.

А если побольше попользоваться такой операцией, впечатление становится обратным. В конце концов есть DROP, или сделать
второй комплект операций без адреса на стеке.

Автор:  Hishnik [ Пт авг 06, 2010 17:29 ]
Заголовок сообщения:  Re: Возможность работать с многомерными массивами

Побольше - это сколько? Вот если бы в процессе вычислений создавался новый массив, адрес которого был бы изначально неизвестен, тогда да, его необходимо оставить на стеке. А так это просто "размер для справки".

Автор:  in4 [ Пт авг 06, 2010 21:13 ]
Заголовок сообщения:  Re: Возможность работать с многомерными массивами

Broud4 писал(а):
СОВЕТ
Пусть определения поглощают свои аргументы.

Автор:  chess [ Вс авг 08, 2010 11:29 ]
Заголовок сообщения:  Re: Возможность работать с многомерными массивами

Хищник писал(а):
Побольше - это сколько?

Немного и еще немного. :)
Хищник писал(а):
Вот если бы в процессе вычислений создавался новый массив, адрес которого был бы изначально неизвестен, тогда да, его необходимо оставить на стеке. А так это просто "размер для справки".

Оставлять на стеке адрес нового массива и в этом случае необязательно. Достаточно
в дальнейшем использовать имя этого нового массива. Именно к имени и привязывается
адрес массива и эта привязка будет произведена той операцией над массивами, в результате действия которой и будет создан новый массив.
Оставлять адрес измененного или нового массива проще чем класть адрес по их именам.
Я уже говорил, что по аналогии с числами( а массивы это расширенные числа) операция над массивами оставляет результат.

Автор:  Hishnik [ Вс авг 08, 2010 12:25 ]
Заголовок сообщения:  Re: Возможность работать с многомерными массивами

chess писал(а):
Я уже говорил, что по аналогии с числами( а массивы это расширенные числа) операция над массивами оставляет результат.

Это неподходящая аналогия, поскольку при операциях с числами на стеке остается число, несущее новую информацию, которую и запрашивает программист. Странно было бы не сообщать результат вычисления. А в случае с массивами искомой информацией является содержимое массива, а не его начальный адрес или имя, которые и так известны.

Автор:  chess [ Вс авг 08, 2010 18:01 ]
Заголовок сообщения:  Re: Возможность работать с многомерными массивами

Хищник писал(а):
в случае с массивами искомой информацией является содержимое массива, а не его начальный адрес или имя, которые и так известны.

Все проще. Вот пример:
Код:
10 1 ARRAY a1   a1 1 [#!
10 1 ARRAY a2   a2 2 [#!
10 1 ARRAY a3   a3 3 [#!
10 1 ARRAY a4   a4 4 [#!

: S1
  a1 a2 [+ a3 [* a4 [- ;

Результат в массиве a1
Без получения адреса после операций запись определения была бы громоздкой.

Страница 2 из 4 Часовой пояс: UTC + 3 часа [ Летнее время ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/