Forth и другие саморасширяющиеся системы программирования Locations of visitors to this page
Текущее время: Сб сен 22, 2018 18:44

...
Google Search
Forth-FAQ Spy Grafic

Часовой пояс: UTC + 3 часа [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 39 ]  На страницу 1, 2, 3  След.
Автор Сообщение
 Заголовок сообщения: Возможность работать с многомерными массивами
СообщениеДобавлено: Вс июл 25, 2010 15:43 
Не в сети

Зарегистрирован: Вс апр 25, 2010 11:14
Сообщения: 200
Откуда: Москва
Благодарил (а): 0 раз.
Поблагодарили: 2 раз.
Возможность работать с многомерными массивами?


M Тема выделена из viewtopic.php?f=18&t=2601



Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Есть ли в SP-Forth
СообщениеДобавлено: Вс июл 25, 2010 18:19 
Не в сети
Moderator
Moderator
Аватара пользователя

Зарегистрирован: Чт май 04, 2006 00:53
Сообщения: 4949
Откуда: был Крым, теперь Новосибирск
Благодарил (а): 18 раз.
Поблагодарили: 56 раз.
Antender писал(а):
Возможность работать с многомерными массивами?

Многомерные массивы делаются на основе одномерных с помощью обычных операций @ и !
Однако, как всегда возникают вопросы и о мерности массива и о его размерах о том, что он хранит.

_________________
Мне бы только мой крошечный вклад внести,
За короткую жизнь сплести
Хотя бы ниточку шёлка.
fleur


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Есть ли в SP-Forth
СообщениеДобавлено: Вс июл 25, 2010 18:42 
Не в сети
Аватара пользователя

Зарегистрирован: Чт июл 20, 2006 11:31
Сообщения: 2120
Откуда: Екб
Благодарил (а): 0 раз.
Поблагодарили: 40 раз.
Antender писал(а):
Возможность работать с многомерными массивами?

Что значит работать - складывать массивы, вычитать, умножать, сравнивать ...
Нужно определиться что надо.
Форт расширяемый - написать нужные библиотеки-расширения в данном случае не сложно.

_________________
С уважением, chess


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Есть ли в SP-Forth
СообщениеДобавлено: Вс июл 25, 2010 19:04 
Не в сети

Зарегистрирован: Вт май 09, 2006 12:31
Сообщения: 3438
Благодарил (а): 5 раз.
Поблагодарили: 16 раз.
Массив задаётся "предельными размерами" каждого измерения, затем стандартная процедура (она и в С такая же внутри) умножается соответствующий индекс массива на максимальное количество элементов, которое может содержать одно "деление", сначала старший индекс, затем то же проделывается с младшим, затем результаты складываются, так до последнего уровня - младший индекс не требует вычисления максимальной "вместимости" деления, и просто складывается. Хм, кажется, это только запутывает.

Скажем, есть 3-мерный массив
в С он задавался бы int arr[2][3][4]
Это значит, что доступ до ячейки под номером [1][1][1] мы получаем, умножив
(первый уровень) 1 * ( 1 * 12 ) - один максимальный шаг из 3 рядов по 4 элемента
затем к нему прибавляется 1 * 4 - один шаг из 4 элементов
затем ещё 1
полукчается 12 + 4 + 1 = 17


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Есть ли в SP-Forth
СообщениеДобавлено: Вс июл 25, 2010 21:35 
Не в сети

Зарегистрирован: Вс апр 25, 2010 11:14
Сообщения: 200
Откуда: Москва
Благодарил (а): 0 раз.
Поблагодарили: 2 раз.
Вопрос был в том реализовано ли это в SPF и нужно ли кому-нибудь, так как свою реализацию я уже написал Тем не менее всем спасибо за ответы.
Код:
0 [IF]
Библиотека работы с многомерными массивами компилирующимися в словарь.
Используется одна глобальная переменная.
Есть проверка выхода за границы и автоподсчёт занимаемой памяти.
По адресу массива находится количество измерений.
[ELSE]
VARIABLE (NCOUNT)
: NARRAY ( n*u n2 n1 u | name -- ) ( n* - индексы в порядке убывания измерения, u - количество измерений, name - имя массива) ( слово создаёт массив)
CREATE
DUP HERE ! 1 + 1 ?DO HERE I CELLS + ! LOOP ;
: NINDEX ( u name -- u ) ( выдаёт размерность по номеру, 0 - выход за границы )
2DUP @ > ROT DUP 1 < ROT OR IF DROP DROP 0 ELSE CELLS + @ THEN ;
: NSIZECOUNT  ( name -- u ) ( считает занимаемую массивом память в байтах )
1 SWAP DUP @ 1 + 1 ?DO DUP I CELLS + @ ROT * SWAP LOOP  @ 1 + + CELLS ;
: NCOUNT ( nu nu-1 ... n1 -- addr / 0 ) ( считает адрес ячейки массива по заданным координатам , 0 - выход за границы )
0 SWAP DUP (NCOUNT) ! @ 1 + 1
?DO I PICK DUP (NCOUNT) @ I CELLS + @ 1 - > SWAP 0 < OR OR LOOP
IF (NCOUNT) @ @ 0
?DO DROP LOOP 0
ELSE 0 (NCOUNT) @ @ 1 + 1
?DO I PICK I 1 ?DO I PICK * LOOP + LOOP
(NCOUNT) @ @ + CELLS (NCOUNT) @ +
(NCOUNT) @ @ 0
?DO SWAP DROP LOOP -1
THEN
;
[THEN]


И ещё вопрос: нужны ли кому нибудь операции сравнения над массивами?


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Есть ли в SP-Forth
СообщениеДобавлено: Пн июл 26, 2010 04:32 
Не в сети
Moderator
Moderator
Аватара пользователя

Зарегистрирован: Чт май 04, 2006 00:53
Сообщения: 4949
Откуда: был Крым, теперь Новосибирск
Благодарил (а): 18 раз.
Поблагодарили: 56 раз.
Antender писал(а):
: NARRAY ( n*u n2 n1 u | name -- ) ( n* - индексы в порядке убывания измерения, u - количество измерений, name - имя массива) ( слово создаёт массив)
CREATE DUP HERE ! 1 + 1 ?DO HERE I CELLS + ! LOOP ;

а где резервирование пространства ( ALLOT )?
если вы создадите вслед за созданным с помощью NARRAY определение, оно попадет внутрь вашего массива!
Правильно сначала место в памяти зарезервировать, а потом его уже инициализировать!!

Antender писал(а):
: NCOUNT ( nu nu-1 ... n1 -- addr / 0 ) ( считает адрес ячейки массива по заданным координатам , 0 - выход за границы )

а в этом насчитал 4 цикла DO LOOP не многовато ли для индексации?

_________________
Мне бы только мой крошечный вклад внести,
За короткую жизнь сплести
Хотя бы ниточку шёлка.
fleur


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Есть ли в SP-Forth
СообщениеДобавлено: Пн июл 26, 2010 09:08 
Не в сети

Зарегистрирован: Вс апр 25, 2010 11:14
Сообщения: 200
Откуда: Москва
Благодарил (а): 0 раз.
Поблагодарили: 2 раз.
Создаем кубический массив:
4 по ширине
3 по высоте
2 по глубине
2 3 4 3 NARRAY VASYA
VASYA NSIZECOUNT ALLOT

Или можно определить NSIZECOUNT раньше и исправить NARRAY:
Код:
: NARRAY ( n*u n2 n1 u | name -- ) ( n* - индексы в порядке убывания измерения, u - количество измерений, name - имя массива) ( слово создаёт массив)
CREATE
DUP HERE ! 1 + 1 ?DO HERE I CELLS + ! LOOP ;
HERE NSIZECOUNT ALLOT



1 цикл - проверка выхода за границы всех индексов,
2 цикл, 3 цикл - сама индексация
4 цикл - чистка стека от отработавших данных

Сделано всё по единой формуле => подходит даже для массивами со 100 измерениями, только памяти не хватит и считать будет долго.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Есть ли в SP-Forth
СообщениеДобавлено: Пн июл 26, 2010 10:09 
Не в сети
Moderator
Moderator
Аватара пользователя

Зарегистрирован: Чт май 04, 2006 00:53
Сообщения: 4949
Откуда: был Крым, теперь Новосибирск
Благодарил (а): 18 раз.
Поблагодарили: 56 раз.
Antender писал(а):
2 3 4 3 NARRAY VASYA
VASYA NSIZECOUNT ALLOT

так делать черевато, лучше ALLOT внутрь NARRAY поместить(я уже сказал, что в незарезервированную память лучше ничего не писать, т.е. ваше HERE ! лучше никогда-никогда-никогда не делать!!!! лучше: HERE CELL ALLOT ! -- так значение будет гарантированно помещаться на свое место и не будет никем перезаписано, что особенно актуально в многопоточных программах, где, кстати, память лучше сразу одним куском выделять! ).
кроме того, посмотрите конструкцию: CREATE ... DOES> ... ;
может сильно упростить жизнь, например, если вы захотите поместить ваши массивы в хипе.

Antender писал(а):
1 цикл - проверка выхода за границы всех индексов,2 цикл, 3 цикл - сама индексация4 цикл - чистка стека от отработавших данных

так делать не стоит, лучше сделать 3-4 отдельных слова, каждое из которых будет делать что-то одно. (если, конечно, не хочется бегать по граблям в будущем).
потом, проверка границ все же чаще нужна при отладке, и очень сильно тормозит скорость работы системы.
Можно перестраховаться с помощью операции MOD (AND), например, если у вас адресоваться должны индексы от нуля до 15, то достаточно написать 15 AND rec_size * + на каждое измерение (либо MOD , если количество ячеек не кратно степени двойки).
такие вот замечательные мысли ;)

_________________
Мне бы только мой крошечный вклад внести,
За короткую жизнь сплести
Хотя бы ниточку шёлка.
fleur


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Есть ли в SP-Forth
СообщениеДобавлено: Пн июл 26, 2010 12:24 
Не в сети

Зарегистрирован: Вс апр 25, 2010 11:14
Сообщения: 200
Откуда: Москва
Благодарил (а): 0 раз.
Поблагодарили: 2 раз.
Немного переделал:
1 ALLOT внутри NARRAY
2 Выделяется по ячейке
3 Проверка выхода за границы сделана через условную компиляцию
Код:
0 [IF]
Библиотека работы с многомерными массивами компилирующимися в словарь.
Используется одна глобальная переменная.
Автоподсчёт занимаемой памяти.
По адресу массива находится количество измерений.
Если нужна при отладке ( в случае выхода за границу выдаёт 0 вместо результата )- оставляем на стеке TRUE перед подключением, в противном случае FALSE

[THEN]


VARIABLE (NCOUNT)
: NSIZECOUNT  ( flag name -- u ) ( считает занимаемую массивом память в байтах, flag=TRUE - считать служебные ячейки, flag=FALSE - не считать )
1 SWAP DUP @ 1 + 1 ?DO DUP I CELLS + @ ROT * SWAP LOOP ROT IF @ 1 + + ELSE DROP THEN CELLS ;
: NARRAY ( n*u n2 n1 u | name -- ) ( n* - индексы в порядке убывания измерения, u - количество измерений, name - имя массива) ( слово создаёт массив)
CREATE
HERE (NCOUNT) ! DUP HERE ! 1 CELLS ALLOT
1 + 1 ?DO HERE ! 1 CELLS ALLOT LOOP
FALSE (NCOUNT) @ NSIZECOUNT ALLOT ;
: NINDEX ( u name -- u ) ( выдаёт размерность по номеру, 0 - выход за границы )
2DUP @ > ROT DUP 1 < ROT OR IF DROP DROP 0 ELSE CELLS + @ THEN ;
: NCOUNT
0 (NCOUNT) @ @ 1 + 1
?DO I PICK I 1 ?DO I PICK * LOOP + LOOP
(NCOUNT) @ @ + CELLS (NCOUNT) @ +
(NCOUNT) @ @ 0
?DO SWAP DROP LOOP -1
;

[IF]

: NCOUNT ( nu nu-1 ... n1 -- addr / 0 ) ( считает адрес ячейки массива по заданным координатам , 0 - выход за границы )
DUP (NCOUNT) ! 0 SWAP @ 1 + 1
?DO I PICK DUP (NCOUNT) @ I CELLS + @ 1 - > SWAP 0 < OR OR LOOP
IF (NCOUNT) @ @ 0
?DO DROP LOOP 0
ELSE NCOUNT
THEN
;
[ELSE]

: NCOUNT ( nu nu-1 ... n1 -- addr / 0 ) ( считает адрес ячейки массива по заданным координатам, даже в случае выхода за границы )
(NCOUNT) ! NCOUNT
;
[THEN]


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Есть ли в SP-Forth
СообщениеДобавлено: Пн июл 26, 2010 16:37 
Не в сети
Аватара пользователя

Зарегистрирован: Чт июл 20, 2006 11:31
Сообщения: 2120
Откуда: Екб
Благодарил (а): 0 раз.
Поблагодарили: 40 раз.
Если нет контроля, то реализация попроще и побыстрее ( правда использованы лок.переменные)
Код:
: CREATE[]
1 s! 1 cnt!
CREATE DUP ,
0 DO DUP s * is s I IF cnt * DUP is cnt , ELSE 1 , DROP THEN
   LOOP s CELLS ALLOT
DOES>  >R 0 R@ R@ @ 1+ CELLS + R@ CELL+
   DO SWAP I @ * +  CELL +LOOP CELLS R> DUP @ 1+ CELLS + + ;


Код:
\ пример

4 5 6 3 CREATE[] ARR

111 4 3 2 ARR !
222 2 3 4 ARR !

2 3 4 ARR @
4 3 2 ARR @


пс. это самое простое - создать массивы и организовать доступ к их элементам
операции над массивами написать будет посложнее.

_________________
С уважением, chess


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Есть ли в SP-Forth
СообщениеДобавлено: Пт июл 30, 2010 15:04 
Не в сети
Аватара пользователя

Зарегистрирован: Чт июл 20, 2006 11:31
Сообщения: 2120
Откуда: Екб
Благодарил (а): 0 раз.
Поблагодарили: 40 раз.
небольшое движение по теме многомерные массивы

Код:
: []CREATE \ 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 CELLS ALLOT DOES> ;

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

: []HLEN \ A -- LEN  длина заголовка массива
  @ 1+ CELLS 2* ;

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

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

: []@  \ N..N A -- N  прочитать элемент по его координатам
  []A @ ;

: []!  \ A -- []A     записать элемент  по его координатам
  []A ! ;

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

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

: []0 \ A -- A[0] дать адрес первого элемента массива
  DUP []HLEN + ;

: []MAX \ A -- NMAX
  >R 0x80000001  R@ DUP []SIZE CELLS + R> []0
  DO I @ MAX CELL +LOOP ;

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


\ примеры

STARTLOG

4 5 6 7 4 []CREATE ARR

777  3 4 5 6 ARR []!
222  0 0 0 0 ARR []!
-345  2 2 2 2 ARR []!

0 0 0 0 ARR []@ . CR

ARR []0   DUP  . @ . CR

ARR []MAX    . CR

ARR []MIN    . CR

ARR []SIZE   . CR

ARR []LIMITS


log

222
5963072 222
777
-345
840

Ok ( 4 5 6 7 4 )

пс. Сложная структура заголовка массива сделана для ускорения доступа к элементам массива по наборам координат.
Некоторая арифметика сделана еще на этапе компиляции - в момент создания массива. Эти операции
по вычислению номера по координатам будут частыми и займут основное время

_________________
С уважением, chess


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Есть ли в SP-Forth
СообщениеДобавлено: Пт июл 30, 2010 16:13 
Не в сети

Зарегистрирован: Вт май 09, 2006 12:31
Сообщения: 3438
Благодарил (а): 5 раз.
Поблагодарили: 16 раз.
Цитата:
[]CREATE

А нельзя было иначе назвать :)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Есть ли в SP-Forth
СообщениеДобавлено: Пт июл 30, 2010 17:34 
Не в сети
Аватара пользователя

Зарегистрирован: Чт июн 25, 2009 11:12
Сообщения: 412
Благодарил (а): 41 раз.
Поблагодарили: 8 раз.
например :[]


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Есть ли в SP-Forth
СообщениеДобавлено: Пт июл 30, 2010 18:08 
Не в сети
Аватара пользователя

Зарегистрирован: Чт июл 20, 2006 11:31
Сообщения: 2120
Откуда: Екб
Благодарил (а): 0 раз.
Поблагодарили: 40 раз.
вопрос писал(а):
Цитата:
[]CREATE

А нельзя было иначе назвать

dynamic-wind писал(а):
например :[]


На этом этапе название не главное.
Лучше всего с массивами, на мой взгляд, обстоит дело в языке J,
можно потом оттуда синтаксис позаимствовать.

_________________
С уважением, chess


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Есть ли в SP-Forth
СообщениеДобавлено: Пт июл 30, 2010 21:52 
Не в сети
Аватара пользователя

Зарегистрирован: Чт июл 20, 2006 11:31
Сообщения: 2120
Откуда: Екб
Благодарил (а): 0 раз.
Поблагодарили: 40 раз.
макетные варианты арифметических операций над массивами
Код:
: []+ \ A1 A2 -- к массиву A1 прибавляем массив A2
  a2! a1!
  a1 []SIZE CELLS 0
  DO I a1 []0 + @ I a2 []0 + @ + I a1 []0 + ! CELL +LOOP ;

: []- \ A1 A2 -- из массива A1 вычитаем массив A2
  a2! a1!
  a1 []SIZE CELLS 0
  DO I a1 []0 + @ I a2 []0 + @ - I a1 []0 + ! CELL +LOOP ;

: []* \ A1 A2 -- массив A1 умножаем на массив A2
  a2! a1!
  a1 []SIZE CELLS 0
  DO I a1 []0 + @ I a2 []0 + @ * I a1 []0 + ! CELL +LOOP ;

\ примеры

4 5 6 7 4 []CREATE ARR
4 5 6 7 4 []CREATE ARR1


777  3 4 5 6 ARR  []!
223  3 4 5 6 ARR1 []!

ARR ARR1 []* ARR []MAX   . CR

_________________
С уважением, chess


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 39 ]  На страницу 1, 2, 3  След.

Часовой пояс: UTC + 3 часа [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4


Вы не можете начинать темы
Вы можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
phpBB сборка от FladeX // Русская поддержка phpBB