Главная страница

Программирование в Scilab Микаэль Боден Micha


Скачать 1.35 Mb.
НазваниеПрограммирование в Scilab Микаэль Боден Micha
Дата18.09.2022
Размер1.35 Mb.
Формат файлаpdf
Имя файлаprogscilab-v.0.10_ru.pdf
ТипРеферат
#683094
страница7 из 13
1   2   3   4   5   6   7   8   9   10   ...   13

Если мы выделим несколько ячеек за раз с помощью поля entries, то мы получим список.
В следующем примере мы выделяем все ячейки в первом столбце.
- - > x = c ( 1 : 2 , 1 ) . e n t r i e s x
=
x (1)
[]
x (2)
12.
- - > t y p e o f ( x )
ans
=
l i s t
Мы можем создать многоиндексные массивы с помощью cell-массивов. Например,
команда c=cell(2,3,4) создаёт массив размером 2 × 3 × 4. Эту особенность можно будет сравнить с гиперматрицами с тем дополнительным преимуществом, что ячейки cell могут иметь различные типы, а все ячейки гиперматрицы должны быть одного типа.
Поведение cell можно также сравнить со списком list. Но к ячейкам cell можно получить доступ с помощью синтаксиса, похожего на матрицы, что может быть удобно в некоторых ситуациях.
Одна из особенностей cell заключается в том, что он частично совместим с Matlab и Octave. В Scilab’е cell ведёт себя не полностью идентично, та что эта совместимость только частичная. Например ячейка (2,1) cell-массива может быть выделена с помощью синтаксиса c{2,1} (заметьте «{}»): этот синтаксис недоступен в Scilab.
Синтаксис для выделения значений из массива cell может быть особенно полезным в некоторых ситуациях. Эта особенность разделяется со списками tlist и mlist, где выделе- ние может быть перегружено.
3.13
Сравнение типов данных
В этом разделе мы сравним различные типы данных, которые мы представили. На рисунке
18
представлен обзор этих типов данных.
Рисунок
19
представляет различные типы данных, которые мы уже встретили, и пред- лагает другие типы данных для замены.
Замена одного типа данных другим может быть интересна, например в ситуации, где производительность играет значение. В этой ситуации эксперименты с различными реали- зациями и измерения производительности каждой из них может помочь улучшить произво- дительность данного алгоритма.
Некоторые типы данных разнородны, т. е. эти типы данных могут содержать пере- менные, которые могут быть разных типов. Это ситуации структуры struct, матрично- ориентированного списка mlist и массива cell. Другие типы данных могут содержать толь- ко один тип переменных: это ситуация матрицы и гиперматрицы. Если все переменные, чей тип данных должен управляться, имеют один и тот же тип, то без сомнения следует выби- рать матрицу или гиперматрицу.
50

Тип данных
Назначение
Преимущества
Недостатки matrix
2
х
-индексная матрица эффективная, простая однородная hypermatrix многоиндексная матрица однородная list
Упорядоченный набор эле- ментов не перегружается tlist типизированный список можно перегружать mlist матрично-ориентированный список выделение/вставка,
может быть определе- на пользователем.
struct
Неупорядоченный набор эле- ментов совместим с Matlab не перегружается cell частично совместим не перегружается
Рис. 18: Структуры данных Scilab.
Типы данных
Реализация
Разнородность
Вложенность matrix встроено
Нет
Нет hypermatrix mlist
Нет
Нет list встроено
Да
Да tlist встроено
Да
Да mlist встроено
Да
Да struct mlist
Да
Да cell mlist
Да
Да
Рис. 19: Сравнение типов данных. Столбец «Реализация» указывает на реализацию этих типов данных в Scilab версии 5.
Вложение может быть полезным, когда мы хотим создать дерево структур данных. В
этом случае ни матрица, ни гиперматрица не могут использоваться. Это действительно один из главных практических применений списка list. Столбец «Вложенность» на рисунке
19
представляет эту функциональность для всех структур данных.
Одна из причин, которой можно объяснить разницу производительностей заключает- ся в реализации различных типов данных. Это представлено в столбце «Реализация» на рисунке
19
где мы представляем реализацию этих типов данных в Scilab версии 5.
Например, мы представляли гиперматрицы в разделе
3.3
. В разделе
3.4
мы уже ана- лизировали влияние производительности, которую может иметь выделение из гиперматриц.
В Scilab версии 5 гиперматрицы реализованы через mlist, поддерживаемые как скомпили- рованным исходным кодом, так и макросами Scilab’а. Например, выделение гиперматриц чисел типа double основано на скомпилированном исходном коде, а выделение гипермат- риц строковых переменных основано на макросе: это может также привести к различиям производительностей.
3.14
Заметки и ссылки
В первой части данного раздела мы представляем некоторые заметки и ссылки по теме имитации ООП в Scilab’е. Во второй части мы описываем связь между типом данных polynomial и функциями управления в Scilab’е.
51

Структура абстрактных данных для имитации ООП зависит от языка.
• В Си структура абстрактных данных выбора является структурой. Этот метод расши- рения Си частот используется для обеспечения общей схемы ООП [
47
,
45
] когда исполь- зование C++ нежелательно или невозможно. Этот метод уже используется внутри ис- ходного кода Scilab, в графическом модуле, для конфигурации свойств графики. Он из- вестен как
«handles»
(дескрипторы):
смотри заголовочный файл
ObjectStructure.h [
43
].
• В Fortran 77 достаточна команда «common» (но она редко используется для имитации
ООП).
• В Fortran 90 был разработан «производный тип» для этих целей (но редко используется для имитации истинного ООП). Стандарт Fortran 2003 — это Fortran с реальным ООП,
основанным на производных типах.
• В Tcl, структура данных «array» является подходящей ТАД (он используется масси- вом STOOOOP [
19
] например). Но это можно также сделать с командой «variable»,
объединённой с пространствами имён (это сделано, к примеру, в пакете SNIT [
17
])
«Новый» конструктор имитируется возвратом образца ТАД. «Новый» метод может потребовать выделения памяти. «Свободный» деструктор берёт «this» в качестве первого аргумента и освобождает память которая была выделена ранее. Этот подход возможен в
Фортране, Си и других компилируемых языках, если первый аргумент «this» может быть модифицирован методом. В Си это сделано переводом указателя на ТАД. В Fortran 90 это сделано добавлением «intent(inout)» к декларации (или ничего вообще).
Теперь обсудим связь между типом данных polynomial и управлением. Когда преж- ний открытый проект Matlab рассматривался исследователями в IRIA (French Institute for Research in Computer Science and Control) в начале 80
х годов, то они хотели создать программное обеспечение компьютеризированного проектирования систем управления —
Computer Aided Control System Design (C.A.C.S.D.). В то время главными разработчиками были Франсуа Делебек (Fran¸cois Delebecque) и Серж Стир (Serge Steer). В контексте теории управления мы анализируем поведение динамических систем. В случае систем управления с одним входом и одним выходом (SISO), мы можем использовать преобразование Лапла- са над переменными, что приводит к передаточной функции. Следовательно, тип данных rational был введён для поддержки анализа передаточных функций полученных для линей- ных систем. Есть много других функций, относящихся к CACSD в Scilab и представлять их не входит в задачи данного документа.
3.15
Упражнения
Упражнение 3.1 (Поиск файлов) Интерпретируемые языки часто используются для задач автоматиза- ции, таких как поиск и переименование файлов на жёстком диске. В этой ситуации может быть использована функция regexp, чтобы обнаружить файлы с совпадением с заданным шаблоном. Например, мы можем ис- пользовать её для поиска файлов-сценариев Scilab в папке. Это легко, поскольку файлы-сценарии Scilab имеют расширения «.sci» (для файлов, определяющих функцию) и «.sce» (для файлов, выполняющих ин- струкции Scilab).
Разработайте функцию searchSciFilesInDir, которая ищет эти файлы в заданной директории. Мы предлагаем дать следующий заголовок.
f u n c t i o n f i l e m a t r i x = s e a r c h S c i F i l e s I n D i r ( d i r e c t o r y , f u n n a m e )
52

Если такой файл найдётся, мы добавим его в матрицу строковых переменных filematrix, которая воз- вращается в качестве выходного аргумента. Более того, мы вызовем функцию funname. Это позволит нам обработать файл если потребуется. Следовательно, мы можем использовать эту функциональность для отображения имени файла, перемещения файла в другую папку, удаления его и т. д.
Разработайте функцию mydisplay со следующим заголовком:
f u n c t i o n m y d i s p l a y ( f i l e n a m e )
и используйте эту функцию совместно с searchSciFilesInDir для того, чтобы распечатать файлы в дирек- тории.
Упражнение 3.2 (Запрос типизированных списков) Функции, которые мы рассмотрели, позволяют программировать типизированные списки очень динамичным образом. Мы посмотрим сейчас как использо- вать функции definedfields для динамического вычисления: определено ли поле, идентифицированное по его строке, или нет. Это позволит получить немного больше практики с типизированными списками. Вспом- ните, что мы можем создавать типизированные списки без действительного определения значений полей.
Эти поля могут быть определены позже, так что, в отдельный момент времени, мы не знаем были ли все поля определены или нет. Следовательно, нам может потребоваться функция isfielddef, которая бы вела себя как в следующем примере.
- - > p = t l i s t ([ " p e r s o n " , " f i r s t n a m e " , " n a m e " , " b i r t h y e a r " ]);
- - > i s f i e l d d e f ( p , " n a m e " )
ans
=
F
- - > p . n a m e = " S m i t h " ;
- - > i s f i e l d d e f ( p , " n a m e " )
ans
=
T
Напишите реализацию функции isfielddef. Чтобы это сделать, вы можете объединить функции find и definedfields.
4
Управление функциями
В этом разделе мы рассмотрим управление функциями и представим возможности раз- работки гибких функций. Мы представляем методы получения информации о функциях и отделения макросов от примитивов. Мы обращаем внимание, что функции не зарезервиро- ваны в Scilab’е и предупреждаем об ошибках функции funcprot. Мы представляем исполь- зование вызовов, которые позволяет пользователю функции настроить часть алгоритма. Мы анализируем методы разработки функций с переменным числом входных и выходных пере- менных на основе команд argn, varargin и varargout. Мы покажем общие способы обеспе- чения значений по умолчанию для входных аргументов. Мы представляем как использовать пустую матрицу [] для преодоления проблемы, вызванной позиционными входными аргу- ментами. Мы также рассматриваем определение функций, где выходные аргументы могут иметь различные типы. Затем мы представляем возможности, которые позволяют разраба- тывать надёжные функции. Мы представляем практические примеры для функций error,
warning и gettext. Мы представляем модуль parameters, который позволяет решить зада- чу проектирования функции с большим числом параметров. Детально анализируется обзор переменных через стек вызовов. Ошибки, вызванные плохим использованием этой возмож- ности анализируются на основе типичных случаев использования. Мы представляем ошибки с вызовами и анализируем методы разрешения их. Мы представляем метод, основанный на списках, для обеспечения дополнительных аргументов для вызовов. Наконец, мы представ- ляем инструменты мета-программирования, основанных на функциях execstr и deff.
53

4.1
Продвинутое управление функциями
В этом разделе мы представляем продвинутое управление функциями. В первой части мы представляем различия между макросами и примитивами. Затем мы обращаем внимание на то, что функции не зарезервированы, что подразумевает возможность переопределить функцию, которая уже существует. Мы покажем, что это вызвано тем фактом, что функции являются переменными. Мы представляем функцию funcprot и покажем как использовать вызовы функций.
4.1.1
Как сделать запрос о функции
В этом разделе мы представляем различия между макросами и примитивами. Мы ана- лизируем различные значения, возвращённые функциями type и typeof для входных ар- гументов функций. Мы вводим функцию deff, которая позволяет динамически определять новую функцию на основе строк. Наконец, мы представляем функцию get_function_path,
которая возвращает путь к файлу, определяющему макрос.
Есть два главных типа функций:
• макросы, которые написаны на языке Scilab,
• примитивы, которые написаны на компилируемом языке, таком, как, например, C,
C++ или Fortran.
В большинстве случаев нет прямого способа найти различия между этими двумя типами функций, и эта хорошая черта: когда мы используем функцию, то не заботимся о языке,
на котором эта функция написана, поскольку только результат имеет значение. Вот почему мы обычно используем имя function без дополнительных подробностей. Однако, иногда это важно, например, когда мы хотим проанализировать или отладить конкретную функцию: в этом случае необходимо знать откуда функция приходит.
Есть несколько возможностей, которые позволяют запрашивать информацию о кон- кретной функции. В этом разделе мы сосредотачиваемся на функциях type, typeof, deff и get_function_path.
Тип макроса равен или 11 или 13, а тип примитива равен 130. Эти типы сведены на рисунке
20
type typeof
Описание
11
"function"
Некомпилированный макрос
13
"function"
Компилированный макрос
130
"fptr"
Примитив
Рис. 20: Различные типы функций.
В следующем примере мы определяем функцию командой function. Затем мы вычис- ляем её тип с помощью функций type и typeof
- - > f u n c t i o n y = m y f u n c t i o n ( x )
- - >
y = 2 * x
- - > e n d f u n c t i o n
- - > t y p e ( m y f u n c t i o n )
ans
=
54

13.
- - > t y p e o f ( m y f u n c t i o n )
ans
=
f u n c t i o n
Функция eye является примитивом, который возвращает единичную матрицу. В сле- дующем примере мы упражняемся с функциями type и typeof с входным аргументом eye.
- - > t y p e ( eye )
ans
=
1 3 0 .
- - > t y p e o f ( eye )
ans
=
f p t r
Функция deff позволяет динамически определять функцию, основанную на строках,
представляющих её определение. Это позволяет динамически определять новую функцию,
например для инкапсуляции одной функции в другую. Функция deff принимает необяза- тельный входной аргумент, который позволяет изменить то, как функция обрабатывается интерпретатором. Такая функция может быть скомпилирована, скомпилирована и профили- рована или некомпилирована. Процесс компиляции позволяет формировать более быстрый байт-код, который может быть использован интерпретатором непосредственно без дополни- тельный операций. Но она так же делает отладку невозможной и поэтому эта возможность может быть отключена. Мы рассмотрим deff более тщательно в разделе
4.7
этого документа
По умолчанию функция deff создаёт компилированный макрос. В следующем примере мы определим некомпилированный макрос с помощью функции deff. Первый аргумент функции deff является заголовком функции. В нашем случае функция myplus принимает два входных аргумента y и z и возвращает выходной аргумент x. Второй аргумент функции deff — это строка, определяющая тип функции, которую надо создать. Мы можем выбирать между "c" для компилированного макроса, "p" для компилированного и профилированного макроса и "n" для некомпилированного макроса.
- - > d e f f ( " x = m y p l u s ( y , z ) " , " x = y + z " , " n " )
- - > t y p e ( m y p l u s )
ans
=
11.
- - > t y p e o f ( m y p l u s )
ans
=
f u n c t i o n
Предыдущий пример позволяет проверить что тип некомпилированной функции равен 11.
Когда функция предоставлена в библиотеке, то функция get_function_path позволя- ет получить путь к функции. Например, модуль оптимизации, предоставляемый Scilab’ом содержит как примитивы (например функцию optim) и макросы (например функцию derivative). Макросы оптимизации собраны в библиотеку optimizationlib, которая анализи- руется в следующем примере.
- - > o p t i m i z a t i o n l i b o p t i m i z a t i o n l i b
=
Расположение файлов функций: SCI \ m o d u l e s \ o p t i m i z a t i o n \ m a c r o s \.
a p l a t b v o d e S
d a t a f i t d e r i v a t i v e f i t _ d a t k a r m a r k a r l e a s t s q l i s t 2 v e c l m i s o l v e r l m i t o o l
N D c o s t n u m d i f f p a c k p e n c o s t q p s o l v e r e c o n s u n p a c k v e c 2 l i s t
55

Предыдущий пример не говорит нам является ли любая из функций, предоставленных optimizationlib, макросом или примитивом. Для этой цели мы можем вызвать функцию typeof, как в следующем примере, который показывает, что функция derivative является макросом.
- - > t y p e o f ( d e r i v a t i v e )
ans
=
f u n c t i o n
В следующем примере мы вычисляем путь, ведущий к функции derivative используя функ- ции get_function_path и editor для редактирования этого макроса.
- - > g e t _ f u n c t i o n _ p a t h ( " d e r i v a t i v e " )
ans
=
D :/ P r o g r a m s / S C I L A B

1.1 - B \ m o d u l e s \ o p t i m i z a t i o n \ m a c r o s \ d e r i v a t i v e . sci
- - > e d i t o r ( g e t _ f u n c t i o n _ p a t h ( " d e r i v a t i v e " ))
Заметим, что функция get_function_path не работает, когда входной аргумент явля- ется функцией, предоставляемой на компилируемом языке, например, функция optim.
- - > t y p e o f ( o p t i m )
ans
=
f p t r
- - > g e t _ f u n c t i o n _ p a t h ( " o p t i m " )
W A R N I N G :
" o p t i m " is not a l i b r a r y f u n c t i o n ans
=
[]
4.1.2
Функции не зарезервированы
Можно переопределять функции, которые уже существуют. Часто, это является ошиб- кой, которая заставляет Scilab формировать сообщение об ошибке. В следующем примере мы определим функцию rand как обычную функцию и проверим, что мы можем вызвать её
как любую другую, определённую пользователем, функцию.
- - > f u n c t i o n y = r a n d ( t )
- - >
y = t + 1
- - > e n d f u n c t i o n
Предупреждение : переопределение функции: r a n d .
Используйте f u n c p r o t (0) чтобы не выводить это сообщение
- - > y = ra n d (1)
y
=
2.
Предупреждение о том, что мы переопределили функцию rand должно заставить нас почувствовать себя некомфортно с нашим файлом-сценарием. Оно говорит нам, что функ- ция rand уже существует в Scilab, что может быть легко проверено командой help rand.
1   2   3   4   5   6   7   8   9   10   ...   13


написать администратору сайта