WWW.DISS.SELUK.RU

БЕСПЛАТНАЯ ЭЛЕКТРОННАЯ БИБЛИОТЕКА
(Авторефераты, диссертации, методички, учебные программы, монографии)

 

Pages:     || 2 | 3 | 4 |

«Аннотация В этом документе мы представляем программирование в Scilab1. В первой части мы представляем управление памятью в Scilab. Во второй части мы представляем различные типы данных и анализируем методы ...»

-- [ Страница 1 ] --

Программирование в Scilab

Мишель Боден (Michal Baudin)

e

Сентябрь 2011 года

Аннотация

В этом документе мы представляем программирование в Scilab1. В первой части мы

представляем управление памятью в Scilab. Во второй части мы представляем различные типы данных и анализируем методы программирования, связанные с теми структурами данных. В третьей части мы представляем характеристики для разработки гибких и устойчивых функций. В последней части мы представляем методы, которые позволяют получить наилучшие характеристики, основанные на вызовах высокооптимизированных числовых библиотек. Предоставляется много примеров, которые позволят увидеть эффективность методов, которые мы представляем.

Прим. перев. произносится сайлаб Содержание 1 Введение 2 Управление переменными и памятью 2.1 Стек........................................... 2.2 Подробнее об управлении памятью......................... 2.2.1 Ограничения памяти со стороны Scilab................... 2.2.2 Ограничения памяти в 32х - и 64х -битных системах............ 2.2.3 Алгоритм в stacksize............................ 2.3 Список переменных и функция who......................... 2.4 Переносимость переменных и функций....................... 2.5 Уничтожение переменных : clear.......................... 2.6 Функции type и typeof................................ 2.7 Заметки и ссылки................................... 2.8 Упражнения...................................... 3 Специальные типы данных 3.1 Строки......................................... 3.2 Многочлены...................................... 3.3 Гиперматрицы..................................... 3.4 Типы и размерности выделенной гиперматрицы.................. 3.5 Тип данных list (список).............................. 3.6 Тип данных tlist................................... 3.7 Имитация объектно-ориентированного программирования с помощью типизированных списков................................... 3.7.1 Ограничения позиционных аргументов................... 3.7.2 Класс person в Scilab............................ 3.7.3 Расширение класса.............................. 3.8 Перегрузка типизированных списков........................ 3.9 Тип данных mlist................................... 3.10 Тип данных struct.................................. 3.11 Массив структур struct............................... 3.12 Тип данных cell.................................... 3.13 Сравнение типов данных............................... 3.14 Заметки и ссылки................................... 3.15 Упражнения...................................... 4 Управление функциями 4.1 Продвинутое управление функциями........................ 4.1.1 Как сделать запрос о функции........................ 4.1.2 Функции не зарезервированы........................ 4.1.3 Функции это переменные......................... 4.1.4 Функции обратного вызова.......................... 4.2 Разработка гибких функций............................. 4.2.1 Обзор функции argn............................. 4.2.2 Практические вопросы............................ 4.2.3 Использование переменных аргументов на практике........... 4.2.4 Значения по умолчанию для необязательных аргументов........ 4.2.5 Функции с переменным типом входных аргументов............ 4.3 Устойчивые функции................................. 4.3.1 Функции warning и error.......................... 4.3.2 Общая схема для проверок входных аргументов.............. 4.3.3 Пример устойчивой функции......................... 4.4 Использование parameters.............................. 4.4.1 Обзор модуля.................................. 4.4.2 Практический случай............................. 4.4.3 Проблемы с модулем parameters...................... 4.5 Область видимости переменных в стеке вызовов................. 4.5.1 Обзор области видимости переменных................... 4.5.2 Плохая функция: неоднозначный случай.................. 4.5.3 Плохая функция: случай тихого обрушения................ 4.6 Проблемы с функциями обратного вызова..................... 4.6.1 Бесконечная рекурсия............................. 4.6.2 Неправильный индекс............................. 4.6.3 Решения..................................... 4.6.4 Функции обратного вызова с дополнительными аргументами...... 4.7 Мета-программирование: execstr и deff...................... 4.7.1 Основное использование execstr...................... 4.7.2 Основное использование deff........................ 4.7.3 Практический пример оптимизации..................... 4.8 Заметки и ссылки................................... 5 Производительность 5.1 Измерение производительности........................... 5.1.1 Основные применения............................. 5.1.2 Пользовательское время и время ЦП.................... 5.1.3 Профилирование функции.......................... 5.1.4 Функция benchfun............................... 5.2 Основы векторизации................................. 5.4.3 Установка оптимизированных библиотек линейной алгебры для Scilab 5.4.4 Установка оптимизированных библиотек линейной алгебры для Scilab 5.5 Измерение числа операций с плавающей запятой за секунду (флопс)..... Copyright c 2008-2010 - Michael Baudin Copyright c 2010-2011 - DIGITEO - Michael Baudin Copyright c 2011 - Stanislav Kroter (translation into Russian) Этот файл должен использоваться на условиях Creative Commons Attribution-ShareAlike 3.0 Unported License:



http://creativecommons.org/licenses/by-sa/3. 1 Введение Этот документ является проектом с открытым исходным кодом. Исходный код на L TEXдоступен на Scilab Forge:

http://forge.scilab.org/index.php/p/docprogscilab Исходные коды на L TEXпредоставляются на условиях лицензии Creative Commons AttributionA ShareAlike 3.0 Unported License:

http://creativecommons.org/licenses/by-sa/3. Файлы-сценарии Scilab предоставляются на Forge, внутри проекта в подкаталоге scripts.

Файлы-сценарии распространяются на условиях лицензии CeCiLL:

http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt 2 Управление переменными и памятью В этом разделе мы опишем несколько характеристик Scilab, которые позволяют управлять переменными и памятью. На самом деле, мы иногда обращаемся к большим вычислениям, так что, для того, чтобы взять от Scilab всё, мы должны увеличить память, доступную для переменных.

Мы начнём с представления стека, который Scilab использует для управления своей памятью. Мы представим как использовать функцию stacksize для того, чтобы настроить размер стека. Затем мы проанализируем максимально доступную память для Scilab, в зависимости от ограничений операционной системы. Мы кратко представим функцию who в качестве инструмента осведомления о переменных, определённых в данный момент. Затем мы выделим переносимость переменных и функций, так что мы сможем разрабатывать сценарии, которые будут работать одинаково хорошо в различных операционных системах.

Мы представим функцию clear, которая позволяет уничтожать переменные когда кончается память. Наконец, мы представим две функции часто используемые когда мы хотим динамически менять поведение алгоритма в зависимости от типа переменной, то есть мы представим функции type и typeof.

Информация, представленная в этом разделе будет интересна тем пользователям, которые хотят более глубоко понять внутреннее устройство Scilab. Между прочим, точное управление памятью является ключевой характеристикой, которая позволит выполнить вычисления наиболее требовательные к памяти. Команды, которые позволяют управлять переменными и памятью представлены на рисунке 1.

2.1 Стек В Scilab версии 5 (и прежних версиях), память управляется с помощью стека. При запуске Scilab распределяет фиксированное количество памяти для хранения переменных данной сессии. Некоторые переменные уже предопределены при запуске, что потребляет небольшое количество памяти, но бльшая часть памяти свободна и предоставлена польо зователю. Когда бы пользователь ни определил переменную, внутри стека используется соответствующая память и в соответствующее количество памяти удаляется из оставшейся clearglobal уничтожить глобальные переменные isglobal проверить является ли переменная глобальной gstacksize установить/получить размер стека Scilab who_user листинг пользовательских переменных свободной части стека. Эта ситуация представлена на рисунке 2. Когда не остаётся свободной памяти в стеке, пользователь больше не может создать новую переменную. В этом случае пользователь должен либо разрушить существующую переменную, либо увеличить размер стека.

Всегда есть некоторое сомнение о бите и байтах, их обозначениях и их единицах измерения. Бит (двоичная цифра) это переменная, которая может быть равна только 0 или 1. Байт (обозначается латинской B или Б) состоит из восьми битов. Есть два разных типа обозначений единиц измерения для множества байтов. В десятичной системе единиц измерения один килобайт состоит из 1000 байт, так что используется обозначение (латинское KB или КБ) (103 байт), MB (106 байт), GB (109 байт) и более (такие как TB для терабайт и PB для петабайт). В двоичной системе единиц измерения один килобайт состоит из 1024 байт, так что обозначения включают в себя строчную букву i в своих единицах измерения: KiB, MiB, и так далее.... В данном документе мы используем только десятичную систему единиц измерения.

Функция stacksize позволяет узнать текущее состояние стека. В сессии, выполняемой после запуска Scilab’а, мы вызываем stacksize для того, чтобы получить текущие свойства стека.

--> stacksize () Первое число, 5 000 000, это общее число 64х -битных слов, которые могут быть сохранены в стеке. Второе число, 33 360, это число 64х -битных слов, которые уже используются. Это значит, что только 5 000 000 – 33 360 = 4 966 640 64х -битных слов доступны для пользователя.

Число 5 000 000 равно числу 64х -битных чисел с плавающей запятой двойной точности (т. е. double ), которые могут быть сохранены, если стек содержит только этот тип данных. Общий размер стека 5 000 000 соответствует 40 МБ, поскольку 5 000 0008 = 40 000 000.

Эта память может быть полностью заполнена плотной квадратной матрицей размерами на 2236 с числами двойной точности (double), поскольку 5000000 2236.

Действительно, стек используется для хранения как действительных значений, целочисленных, строковых, так и более сложных структур данных. Когда хранится 8и -битное целочисленное значение, это соответствует 1/8 памяти, требуемой для хранения 64х -битного слова (поскольку 8 8 = 64). В данном случае требуется только 1/8 часть памяти, требуемой для хранения 64х -битного слова, чтобы сохранить целочисленное значение. В общем, второе целочисленное значение сохраняется во 2/8 части того же слова, так что память не теряется.

Установка по умолчанию возможно достаточна для большинства случаев, но может быть ограничение для некоторых приложений В сессии Scilab’а мы видим, что создание случайной плотной матрицы генерирует ошибку в то время, как создание матрицы 2200 2200 возможно.

\ begin { scriptsize } rand : Превышен допустимый размер стека (используйте функцию stacksize для его увеличения).

-->A = rand (2200,2200);

В том случае, где нам нужно сохранить большие наборы данных, нам нужно увеличить размер стека. Команда stacksize("max") позволяет настроить размер стека таким, чтобы распределить максимально возможное количество памяти системы. Следующий файлсценарий предоставляет пример этой функции, выполненной на ноутбуке с операционной системой GNU/Linux с объёмом памяти 1 ГБ. Функция format используется для того чтобы отображались все знаки."

--> stacksize () Мы можем видеть на этот раз, что общая доступная память в стеке соответствует 28 176 384 единицам 64х -битных слов, что соответствует 225 МБ (поскольку 28 176 8 = 225 411 072). Максимальная плотная матрица, которая может быть сохранена, сейчас размером 5308 на 5308, поскольку 28176384 5308.

Теперь увеличим размер стека до максимума и создадим плотную квадратную матрицу чисел типа double размером 3000 на 3000.

-->A = rand (3000,3000);

Предположим, что у нас 32х -битная машина с Windows XP и 4 ГБ памяти. На этой машине у нас установлен Scilab 5.2.2. Определим плотную квадратную матрицу чисел типа double размером 12 000 на 12 000. Это соответствует приблизительно 1,2 ГБ памяти.

--> sqrt (152611536) 12353. -->A = zeros (12000,12000);

Мы задали размер плотной матрицы типа double для того, чтобы получить грубое представление о том, чему эти числа соответствуют на практике. Конечно, пользователь может по-прежнему управлять гораздо бльшими матрицами, например, если они являются разреженными матрицами. Но в любом случае общая используемая память может превысить размер стека.

Scilab версии 5 (и ранние) может адресовать 231 2,1 109 байт, т. е. 2,1 ГБ памяти.

Это соответствует 231 /8 = 268 435 456 чисел типа double, которыми может быть заполнена плотная квадратная матрица типа double размером 16 384 на 16 384. Это ограничение вызвана внутренним устройством Scilab в любой операционной системе. Более того, ограничения, налагаемые операционной системой могут больше ограничить эту память. Эти темы детально рассматриваются в следующем разделе, который представляет внутренние ограничения Scilab и ограничения, вызванные различными операционными системами, на которых может быть запущен Scilab.

2.2 Подробнее об управлении памятью В этом разделе мы расскажем более детально о доступной памяти в Scilab с точки зрения пользователя. Мы отделим ограничения памяти, вызванные устройством Scilab от ограничений, вызванных устройством операционной системы.

В первом разделе мы анализируем внутреннее устройство Scilab и способ управления памятью с помощью 32х -битных целых чисел со знаком. Затем мы покажем ограничение распределения памяти на различных 32х - и 64х -битных операционных системах. В последнем разделе мы представляем алгоритм, используемый функцией stacksize.

Эти разделы скорее технические и могут быть пропущены большинством пользователей. Но пользователи, более опытные в теме памяти, или те, кто хочет узнать как точное устройство Scilab версии 5, могут узнать о точных причинах этих ограничений.

2.2.1 Ограничения памяти со стороны Scilab Scilab версии 5 (и ранние) обращается к своей внутренней памяти (т. е. стеку) 32х битными целыми числами со знаком в любой операционной системе на которой он запущен.

Это объясняет то, что максимальное количество памяти, которое Scilab может использовать, равно 2,1 ГБ. В этом разделе мы расскажем как это реализовано в большинстве частей Scilab’а, которые управляют памятью.

В Scilab, шлюз это функция C или Fortran, которая даёт пользователю особую функцию. А конкретнее, она соединяет интерпретатор с отдельным набором библиотечных функций чтением входных аргументов, заданных пользователем, и записью выходных аргументов, затребованных пользователем.

Рассмотрим следующий пример Scilab.

Здесь переменные x и y являются матрицами типа double. В шлюзе функции sin мы проверяем число входных аргументов и их тип. Как только переменная x проходит проверку, мы создаём выходную переменную y в стеке. Наконец, мы вызываем функцию sin, предоставленную математической библиотекой и кладём результат в y.

Шлюз точно получает доступ к адресам в стеке, который содержит данные переменных x и y. Для этой цели заголовок шлюза Fortran может содержать объявление, такое как:

где il переменная, которая хранит положение в стеке, который хранит переменную, которая используется. Внутри стека каждый адрес соответствует одному байту и точно управляется с помощью исходного кода каждого шлюза. Целые числа представляют различные места в стеке, т. е. различные адреса байтов. Рисунок 3 демонстрирует способ, которым ядро Scilab’а версии 5 управляет байтами в стеке. Если целочисленная переменная il связана с отдельным адресом в стеке, выражение il+1 идентифицирует следующий адрес стека.

Рис. 3: Детали управления стеком. – Адреса управляются точно ядром Scilab с помощью 32х -битных чисел со знаком.

Каждая переменная хранится в виде пары связанных друг с другом заголовка и данных. Это изображено на рисунке 4, который раскрывает детали заголовка переменной. Следующий исходный код Fortran является типичным кодом первой строки в шлюзе наследия в Scilab. Переменная il содержит адрес начала текущей переменной, скажем x для примера. В действительном исходном коде, мы уже проверили, что текущая переменная является матрицей чисел типа double, то есть, мы уже проверили тип переменной. Затем переменная m устанавливается равной числу строк матрицы, а переменная n числу столбцов. Наконец, переменная it обнуляется, если матрица вещественная, и устанавливается равной 1, если матрица комплексная (т. e. содержит как вещественную, так и мнимую часть).

Как мы можем видеть, мы просто используем такое выражение как il+1 или il+2 для того, чтобы переместиться от одного адреса к другому, то есть, от одного бита к следующему.

Из-за целочисленной арифметике, используемой в шлюзах на целых числах, таких как il, мы должны обратить внимание на диапазон значений, которые мы можем достичь этим отдельным типом данных.

Рис. 4: Детали управления стеком. – Каждая переменная связана с заголовком, который позволяет доступ к данным.

Тип данных integer в Fortran является 32х -битным целым числом со знаком. 32х битные целые числа со знаком лежат в диапазоне от 231 = 2 147 483 648 до 231 1 = 2 147 483 647. В ядре Scilab мы не используем отрицательные целые числа, для идентификации адресов внутри стека. Это напрямую подразумевает, что Scilab не может адресовать более 2 147 483 647 байт, т. e. 2,1 ГБ.

Из-за множества шлюзов в Scilab, нельзя непосредственно передать управление памятью от стека более динамичному распределению памяти. Это является проектом Scilab версии 6, которая сейчас разрабатывается и появится в следующих годах.

Ограничения, связанные с различными операционными системами анализируются в следующих разделах.

Ограничения памяти в 32х - и 64х -битных системах 2.2. В этом разделе мы анализируем ограничения памяти Scilab версии 5 в зависимости от версии операционной системы, на которой запущен Scilab.

В 32х -битных операционных системах память адресуется оперированием 32х -битными целыми числами без знака. Следовательно в 32х -битной системе мы можем адресовать 4,2 ГБ, то есть 232 = 4 294 967 296. В зависимости от конкретной операционной системы (Windows, Linux) и в зависимости от конкретной версии этой операционной системы (Windows XP, Windows Vista, версия ядра Linux и т. д.), этот предел может (или не может) быть достигнут.

В 64х -битных системах память адресуется операционной системой с помощью 64х битными целыми числами без знака. Следовательно, очевидно, что максимально доступная память в Scilab равна 264 1,8 1010 ГБ. Это больше, чем любая доступная физическая память на рынке (на момент написания этой статьи).

Но будь это 32х - или 64х -битная операционная система, будь это Windows или Linux, стек Scilab по-прежнему управляется внутри через 32х -битные целые числа со знаком. Следовательно, можно использовать не более 2,1 ГБ памяти для переменных Scilab, которые хранятся внутри стека.

На практике мы можем иметь дело с некоторыми отдельными работами по линейной алгебре или графике в 64х -битных системах, которые не работают в 32х -битных системах.

Это может быть вызвано временным использованием памяти операционной системы в противовес стеку Scilab’а. Например, разработчик может использовать функции malloc/free вместо использования части стека. Это также может случиться, если память выделена не библиотекой Scilab, а на более низком уровне подбиблиотекой, используемой Scilab’ом. В некоторых случаях этого достаточно, чтобы заставить файл-сценарий работать в 64х -битной системе, в то время как этот же самый файл-сценарий не будет работать в 32х -битной системе.

2.2.3 Алгоритм в stacksize В этом разделе мы представляем алгоритм, используемый функцией stacksize для распределения памяти.

Когда вызывается команда stacksize("max"), мы сначала вычисляем размер текущего стека. Затем, мы вычисляем размер наибольшей области свободной памяти. Если текущий размер стека равен наибольшей области свободной памяти, мы немедленно возвращаемся.

Если нет, то мы устанавливаем размер стека в минимум, который распределяет минимальное количество памяти, которое позволяет сохранить используемую в данный момент память.

Используемые переменные затем копируются в новое пространство памяти, а старый стек перераспределяется. Затем мы устанавливаем размер стека в максимум.

Мы уже видели, что Scilab может адресовать 231 2,1 109 байт, т. е. 2,1 ГБ памяти.

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

2.3 Список переменных и функция who Следующая команда показывает поведение функции who, которая показывает текущий список переменных, а также состояние стека.

-->who Ваши переменные:

используются 7936 элементов из 5000000.

Ваши глобальные переменные:

используется 601 елементов из 999.

Все переменные, чьи имена оканчиваются на lib (как optimizationlib, например) связаны с библиотеками внутренних функций Scilab’а. Некоторые переменные, начинающиеся со знака %, т. е. %i, %e и %pi, связаны с предопределёнными переменными Scilab, поскольку они являются математическими константами. Другие переменные, чьи имена начинаются со знака % являются связанными с точностью чисел с плавающей запятой и стандартом IEEE. Эти переменные %eps, %nan и %inf. Переменные в именами в верхнем регистре SCI, SCIHOME, MSDOS и TMPDIR позволяют создать переносимые файлы-сценарии, т. е. файлы-сценарии, которые могут выполняться независимо от директории установки или операционной системы. Эти переменные описаны в следующем разделе.

2.4 Переносимость переменных и функций Есть несколько предопределённых переменных и функций, которые позволяют создавать переносимые файлы-сценарии, то есть, файлы-сценарии, которые одинаково хорошо работают в Windows, Linux или Mac. Эти переменные представлены на рисунках 5 и 6. Эти переменные и функции используются главным образом для создания внешних модулей, но могут быть иметь практическую ценность в широком наборе ситуаций.

SCIHOME

TMPDIR

[OS,Version]=getos() f = fullfile(p1,p2,...) формирование пути файла из частей В следующем примере мы проверяем значения некоторых предопределённых переменных на Linux-машине.

/ home / myname / Programs / Scilab -5.1/ scilab -5.1/ share / scilab / home / myname /. Scilab / scilab -5. Переменная TMPDIR, которая содержт имя временной директории, связана с текущей сессией Scilab: каждая сессия Scilab имеет уникальную временную директорию.

Временная директория Scilab’а создаётся при запуске Scilab’а (и не уничтожается до самого выхода из Scilab). На практике, мы можем использовать переменную TMPDIR в тестовых файлах-сценариях, где мы должны создавать временные файлы. В этом случае файловая система не засоряется временными файлами и гораздо меньше шансов переписать важные файлы.

Мы часто используем переменную SCIHOME для размещения файла.startup на текущей машине.

Для того, чтобы проиллюстрировать использование переменной SCIHOME, мы рассмотрим задачу поиска файла.startup Scilab’а.

Например, мы иногда вручную загружаем некоторые специфичные внешние модули при запуске Scilab’а. Чтобы это сделать, мы вводим команды exec в файл.startup, который автоматически загружается при запуске Scilab’а. Для того, чтобы открыть файл.startup мы можем использовать следующую команду.

editor ( fullfile ( SCIHOME, ". scilab " )) На самом деле, функция fullfile создаёт абсолютное имя директории из директории SCIHOME до файла.startup. Более того, функция fullfile автоматически использует разделитель директорий, соответствующий операционной системе / для Linux и \ для Windows. Следующий пример показывает результат работы функции fullfile в операционной системе Windows.

--> fullfile ( SCIHOME, ". scilab " ) C :\ DOCUME ~1\ Root \ APPLIC ~1\ Scilab \ scilab -5.3.0 - beta -2\. scilab Функция filesep возвращает строку, представляющую разделитель директорий в текущей операционной системе. В следующем примере мы вызовем функцию filesep в Windows.

В Linux-системах, функция filesep вернёт /.

В Scilab’е есть две возможности, которые позволяют получить имя операционной системы: функция getos и переменная MSDOS. Обе возможности позволяют создавать файлысценарии, которые управляют особыми настройками, зависящими от операционной системы. Функция getos позволяет управлять единообразно во всех операционных системах, что ведёт к улучшенной переносимости. Вот почему первым мы выбрали представление этой функции Функция getos возвращает строку, содержащую имя текущей операционной системы и, по выбору, её версию. В следующем примере мы вызываем функцию getos в Windows XP.

Функция getos может быть обычно использована в командах select, как показано ниже.

case Windows " then error ( " Scilab on Unknown platform " ) Обычное использование переменной MSDOS представлено на следующем примере.

На практике рассмотрим ситуацию, где мы хотим вызвать внешнюю программу с максимально возможной переносимостью. Предположим, что под Windows эта программа файлом-сценарием.bat, под Linux эта программа вызывается скриптом.sh. В данном случае мы могли бы написать файл-сценарий, используя переменную MSDOS и функцию unix, которая выполняет внешнюю программу. Несмотря на своё имя, функция unix работает одинаково под Linux и Windows.

Предыдущий пример показывает, что можно написать переносимую Scilab-программу, которая работает одинаково в разных операционных системах. Может возникнуть более сложная ситуация, поскольку часто случается, что путь, ведущий к программе, также зависит от операционной системы. Другая ситуация состоит в том, что когда мы хотим скомпилировать исходный код при помощи Scilab, используя, например, функции ilib_for_link или tbx_build_src. В этом случае мы хотели бы передать компилятору некоторые особенные опции, которые зависят от операционной системы. Во всех этих ситуациях переменная MSDOS позволяет сделать единый исходный код, который остаётся переносимым в различных системах.

Переменная SCI позволяет вычислить пути относительно текущей установки Scilab.

Следующий пример демонстрирует образец использования этой переменной. Сначала мы получаем путь макроса, указанного Scilab’ом. Затем объединяем переменную SCI с относительным путём до файла и передаём это в функцию ls. Наконец, мы конкатенируем переменную SCI со строкой, содержащей относительный путь до файла-сценария и передаём это в функцию editor. В обоих случаях команды не зависят от абсолютного пути до файла, что делает их более переносимыми.

--> get_ function _path ( " numdiff " ) / home / myname / Programs / Scilab -5.1/ scilab -5.1/...

share / scilab / modules / optimization / macros / numdiff. sci --> ls ( fullfile ( SCI, " / modules / optimization / macros / numdiff. sci " )) / home / myname / Programs / Scilab -5.1/ scilab -5.1/...

share / scilab / modules / optimization / macros / numdiff. sci --> editor ( fullfile ( SCI, " / modules / optimization / macros / numdiff. sci " )) В общих ситуациях часто кажется, что проще писать файл-сценарий только для конкретной операционной системы, поскольку она единственная, которую мы используем в данный момент. В этом случае мы склонны использовать инструменты, которые недоступны для других операционных систем. Например, мы можем полагаться на особое расположение файла, который может быть найден только в Linux. Или мы можем использовать какую-нибудь консоль, зависящую от операционной системы, или инструкции управления файлами. В конечном счёте, полезный файл-сценарий имеет высокую вероятность быть использованным в операционной системе, которая не была первичной целью исходного автора. В данной ситуации тратится много времени, чтобы обновить файл-сценарий так, чтобы он заработал на новой платформе.

Поскольку Scilab сам по себе является переносимым языком, то в большинстве случаев было бы неплохо подумать о том, как этот файл-сценарий будет переноситься прямо с начала разработки. Если есть действительно трудный или неизбежный пункт, то, конечно, разумно снизить переносимость и просто решить задачу так, чтобы сократить разработку.

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

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

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

-->A = rand (2000,2000);

-->B = rand (2000,2000);

rand : Превышен допустимый размер стека (используйте функцию stacksize для его увеличения).

-->B = rand (2000,2000);

Функцию clear следует использовать только по необходимости, то есть, когда вычисление не может быть выполнено из-за памяти. Это предупреждение верно для разработчиков, которые используют компилируемые языки, где памятью управляют напрямую. В языке Scilab’а память управляется Scilab’ом и, вообще, нет причин управлять ею самостоятельно.

Родственной темой является управление переменными в функциях. Когда тело функции выполнилось интерпретатором, все переменные, которые были использованы в теле, и которые не являются выходными аргументами, автоматически удаляются. Следовательно нет нужды напрямую вызывать функцию clear в этом случае.

2.6 Функции type и typeof Scilab может создавать различные типы переменных, такие как матрицы, полиномы, булевы переменные, целочисленные и другие типы структур данных. Функции type и typeof позволяют узнать конкретный тип данной переменной. Функция type возвращает целое число с плавающей запятой, а функция typeof возвращает строку. Эти функции представлены на рисунке 7.

typeof Возвращает целое число с плавающей запятой Рисунок 8 представляет различные выходные значения функций type и typeof.

8 int8, int16, int32, uint8, матрица целочисленных значений, хранимых 16 rational, state-space или тип типизированный список (tlist) 17 hypermat, st, ce или тип типизированный список ориентированный на Рис. 8: Возвращаемые значения функций type и typeof.

В следующем примере мы создаём матрицу 2 2 чисел типа double и используем type и typeof для получения типа этой матрицы.

Эти две функции полезны во время обработки входных аргументов функции. Эта тема будет ещё раз рассмотрена в данном документе позднее, в разделе 4.2.5, когда мы рассмотрим функции с переменным типом входных аргументов.

Если тип переменной tlist или mlist, то значение, возвращаемое функцией typeof, находится в первой строке первого пункта списка. Эта тема ещё раз затрагивается в разделе 3.6, где мы представляем типизированные списки.

Типы данных cell и struct являются особыми формами mlist’ов, поэтому они связаны с type, равным 17 или typeof, равным ce и st.

2.7 Заметки и ссылки Похоже, что в будущих версиях Scilab’а, память Scilab’а не будет управляться стеком.

На самом деле, эта характерная черта является наследием предшественника Scilab’а, т. е.

Matlab’а. Мы подчёркиваем, что Matlab не использует стек уже давно, приблизительно с 80х годов, со времени, когда исходный код Matlab’а был переработан [42]. С другой стороны, Scilab сохраняет этот довольно старый способ управления памятью.

Некоторые дополнительные подробности об управлении памятью в Matlab даны в [35].

В технических заметках [36] авторы представляют методы, избегающие ошибки памяти в Matlab. В технических заметках [37] авторы представляют максимальный размер матрицы, доступный в Matlab на различных платформах. В технических заметках [38] авторы представляют выгоду использования 64х -битного Matlab’а перед 32х -битным.

2.8 Упражнения Упражнение 2.1 (Максимальный размер стека) Проверьте максимальный размер стека вашей машины.

Упражнение 2.2 (who_user ) Запустите Scilab, выполните следующий код и посмотрите результат на вашей машине.

Упражнение 2.3 (whos ) Запустите Scilab, выполните следующий код и посмотрите результат на вашей машине.

3 Специальные типы данных В этом разделе мы анализируем типы данных Scilab’a, которые наиболее часто используются на практике. Мы рассмотрим строки, целочисленные значения, многочлены, гиперматрицы, list’ы и tlist’ы. Мы представим некоторые из наиболее полезных свойств системы перегрузки, которые позволяют определять новые поведения для типизированных списков. В последнем разделе мы кратко рассмотрим cell, struct и mlist и сравним их с другими структурами данных.

3.1 Строки Хотя Scilab не разрабатывался изначально в качестве инструмента управления строками, он предоставляет солидный и мощный набор функций для управления этим типом данных. Список команд, которые связаны со строками Scilab’а представлены на рисунке 9.

sci2exp преобразовать выражение в строку ascii преобразовать строку в коды ascii (и обратно) convstr преобразовать регистры символов emptystr строка нулевой длины grep найти соответствия строки в векторе строк justify выравнять символы в столбцах матрицы regexp найти подстроки, которые соответствуют строке регулярного выражения strcat конкатенировать символьные строки strchr найти первую встречу символа в строке strcmp сравнить символьные строки strcmpi сравнить символьные строки (независимо от регистра) strcspn получить интервал до указанного символа в строке strindex найти позицию символьной строки в другой строке stripblanks обрезает пробелы (и табуляторы) в начале и в конце строк strncpy копирует символы из строк strrchr найти последнюю встречу символа в строке strrev возвращает строку задом наперёд strsplit разбивает строку на векторы строк strspn получить интервал символов в строке strstr определить позицию подстроки strsubst заменить символьную строку другой символьной строкой strtod преобразование строки в число типа double strtok разделение строки на лексемы tokenpos возвращает позиции лексем в символьной строке tokens возвращает лексемы символьной строки str2code возвращает целочисленные коды Scilab, связанные с символьной строкой code2str возвращает символьную строку, связанную с целочисленными кодами Scilab Для того, чтобы создать матрицу строк, мы можем использовать символ " и обычный синтаксис для матриц. В следующем примере мы создаём матрицу строк размером Для того, чтобы вычислить размер матрицы, мы можем использовать функцию size как для обычных матриц.

Функция length, с другой стороны, возвращает число символов в каждом элементе матрицы Возможно, что самая распространённая функция, которую мы используем, это функция string. Эта функция позволяет преобразовать свой входной аргумент в строку. В следующем примере мы определим вектор-строку и используем функцию string для преобразования его в строку. Затем мы используем функцию typeof и проверим, что переменная str действительно является строкой. Наконец, мы используем функцию size и проверим, что переменная str является матрицей строк размером Функция string может принимать любой тип входного аргумента.

Позже мы увидим, что tlist может быть использован для определения нового типа данных. В этом случае мы можем определить функцию, которая делает так, что функция string может работать с этим новым типом данных способом, определённым пользователем.

Эта тема рассматривается в разделе 3.8, где мы представим метод, который позволяет определить поведение функции string, когда её входной аргумент является типизированным списком, когда её входной аргумент является типизированным списком.

Функция strcat конкатенирует свой первый входной аргумент с разделителем, определённым во втором входном аргументе. В следующем примере мы используем функцию strcat для получения строки, представляющую сумму целых от 1 до 5.

Мы можем сочетать функции string и strcat для получения строк, которые могут быть легко скопированы и вставлены в файлы-сценарии или доклады. В следующем примере мы определяем вектор-строку x, который состоит из целых чисел с плавающей запятой.

Затем мы используем функцию strcat с пробелом в качестве разделителя для получения чистой строки целых чисел.

Предыдущая строка может быть напрямую скопирована и вставлена в исходный код или доклад. Давайте рассмотрим задачу разработки функции, которая печатает данные в консоли. Предыдущая комбинация функций является эффективным способом формирования компактных сообщений. В следующем примере мы используем функцию mprintf для отображения содержимого переменной x. Мы используем формат %s, который соответствует строкам. Для того, чтобы получить строку, мы объединяем функции strcat и string.

Функция sci2exp преобразует выражение в строку. Это может быть использовано в тех же целях, что и предыдущий метод, основанный на strcat, но форматирование менее гибко. В следующем примере мы используем функцию sci2exp для преобразования матрицы-строки целых чисел в матрицу строк размером 1 1.

Операторы сравнения, такие как < или >, например, не определены, когда используются строки, т. е., команда "a "b" приводит к ошибке. Вместо этого, мы можем использовать функцию strcmp для этих целей. Она возвращает 1, если первый аргумент лексикографически меньше второго, она возвращает 0, если две строки равны или возвращает 1, если второй аргумент лексикографически меньше первого. Поведение функции strcmp представлено в следующем примере.

Функции, представленные в таблице 10 позволяют различить различные классы строк, таких как ASCII-символы, цифры, буквы и числа.

Например, функция isdigit возвращает матрицу логических значений, где каждый элемент i является истиной, если символ в позиции i строки является цифрой. В следующем примере мы используем функцию isdigit, чтобы проверить, что "0" является цифрой, а "d" нет.

Функция regexp является мощным движком регулярных выражений. Этот компонент был включён в пятой версии Scilab. Он основан на библиотеке PCRE [23], которая предназначена для PERL-совместимости. Шаблон должен быть задан как строка, которая окружена слешами в виде "/x/", где x регулярное выражение.

Далее мы представляем пример использования функции regexp. Символ i в конце регулярного выражения обозначает, что мы не хотим учитывать регистр символов. Первая буква a заставляет выражение соответствовать только строкам, которые начинаются с этой буквы.

Регулярные выражения являются чрезвычайно мощным инструментом для манипуляций с текстом и данными. Очевидно, что этот документ не может даже оцарапать поверхность данной темы. Для дополнительной информации о функции regexp пользователь может обратиться к страницам помощи, предоставленных Scilab’ом. Для более глубокого введения читатель может поинтересоваться в [21] Фридла. Как выразился Дж. Фридл, регулярные выражения позволяют вам кодировать сложную и изощрённую обработку текста, которую вы не когда не могли и представить себе как закодировать.

Упражнение 3.1 представляет практический пример использования функции regexp.

3.2 Многочлены Scilab позволяет управлять одномерными многочленами.Реализация основана на векторе, содержащем коэффициенты многочлена. На уровне пользователя мы можем управлять матрицей многочленов. Основные операции, такие как сложение, вычитание, умножение и деление, применимы для многочленов. Мы можем, конечно, вычислить значение многочлена p(x) для отдельного входного значения x. Более того, Scilab может выполнять операции isalphanum проверить, являются ли символы алфавитно-цифровыми более высокого уровня, такие, как вычисление корней, разложение на множители и вычисление наибольшего общего делителя или наименьшего общего кратного двух многочленов.

Когда мы делим один многочлен на другой многочлен, мы получаем новую структуру данных, представляющую рациональную функцию.

В этом разделе мы сделаем краткий обзор данной темы. Многочлены и рациональные типы данных представлены на рис. 11. Некоторые из наиболее используемых функций, относящихся к многочленам, представлены на рис. 12. Полный список функций, относящихся к многочленам, представлен на рис. 13.

polynomial многочлен, определённый своими коэффициентами Рис. 12: Некоторые основные функции, относящиеся к многочленам.

simp_mode sylm systmat Функция poly позволяет определить многочлены. Есть два способа определить их: с помощью их коэффициентов или с помощью их корней. В следующем примере мы создаём многочлен p(x) = (x1)(x2) с помощью функции poly. Корни этого многочлена, очевидно, x = 1 и x = 2 вот почему первым входным аргументом функции poly является матрица [1 2]. Второй входной аргумент это символьная строка, используемая для отображения многочлена.

В следующем примере мы вызываем функцию typeof и проверяем, что переменная p является многочленом (polynomial).

Мы можем также определить многочлен на основе его коэффициентов в порядке возрастания. В следующем примере мы определяем многочлен q(x) = 1 + 2x. Мы передаём функции poly третий аргумент "coeff", так что она знает, что матрица [1 2] представляет коэффициенты многочлена.

Теперь, когда многочлены p и q определены, мы можем выполнять с ними алгебраические операции. В следующем примере мы суммируем, вычитаем, умножаем и делим многочлены p и q.

Когда мы делим многочлен p на многочлен q, то получаем рациональную функцию r. Это показано в следующем примере.

Для того, чтобы вычислить значение многочлена p(x) для конкретного значения x, мы можем использовать функцию horner. В следующем примере мы определяем многочлен p(x) = (x 1)(x 2) и вычисляем его значение для точек x = 0, x = 1, x = 3 и x = 3, представленных матрицей [0 1 2 3].

Название функции horner происходит от математика Хорнера (Horner), который разработал алгоритм, используемый в Scilab для вычисления значений многочлена. Этот алгоритм позволяет уменьшить число умножений и сложений, требуемых для этих вычислений. (смотри [27], раздел 4.6.4, "Evaluation of Polynomials").

Если в качестве первого аргумента функции poly квадратная матрица, то она возвращает характеристический многочлен, связанный с матрицей. То есть, если A вещественная квадратная матрица размером n n, то функция poly может дать многочлен det(A xI), где I единичная матрица. Это представлено на следующем примере.

Мы легко можем проверить, что предыдущий результат верен с помощью его математического определения. Во-первых, мы можем вычислить корни многочлена p с помощью функции roots, как в предыдущем примере. Во-вторых мы можем вычислить собственные значения матрицы A с помощью функции spec.

Есть другой способ получить тот же самый многочлен p. В следующем примере мы определяем многочлен px, который представляем одночлен x. Затем мы используем функцию det для вычисления детерминанта матрицы B = A xI. Мы используем функцию eye для получения единичной матрицы размером 2 2.

Если мы сравним этот результат с предыдущим, то увидим, что они одинаковы. Мы видим, что функция det определена для многочлена A-px*eye(). Это пример того факта, что множество функций определены для входных аргументов многочлена.

В предыдущем примере матрица B была матрицей многочленов размером 2 2. Таким же образом мы можем определить матрицу рациональной функции, как это показано на следующем примере.

-->B =[1/ x 1/(1+ x );1/(1+ x ) 1/ x ^2] Это очень полезная возможность Scilab’а для теории систем. Связь между типами данных многочленов, рациональных функций с одной стороны и теорией управления с другой кратко проанализирована в разделе 3.14.

3.3 Гиперматрицы Матрица это структура данных, к которым можно получить доступ с помощью двух целочисленных индексов (например, i и j). Гиперматрицы являются более обобщённым типом матриц, к которым можно обратиться с помощью более двух индексов. Эта характеристика знакома разработчикам на фортране, где многомерные массивы являются одной из основных структур данных. Несколько функций, имеющих отношение к гиперматрицам, представлены на рисунке 14.

Рис. 14: Функции, имеющие отношение к гиперматрицам.

В большинстве ситуаций мы можем управлять гиперматрицами как обычными матрицами. В следующем примере мы создаём гиперматрицу A размерами 4 3 2 значений типа double с помощью функции ones. Затем мы используем функцию size для вычисления размеров этой гиперматрицы.

В следующем примере мы создаём гиперматрицу размерами 423. Первый аргумент функции hypermat является матрицей, содержащей число измерений гиперматрицы.

-->A = hypermat ([4,3,2]) Чтобы ввести или выделить значение из гиперматрицы, мы можем использовать тот же самый синтаксис, что и для матриц. В следующем примере мы установим и получим значение элемента (3,1,2).

Оператор двоеточие : может использоваться для гиперматрицы, как это показано в следующем примере.

Большинство операций, которые могут быть сделаны с матрицами, могут быть так же сделаны с гиперматрицами. В следующем примере мы определим гиперматрицу B и сложим её с A.

-->B =2 * ones (4,3,2);

Функция hypermat может быть использована когда мы хотим создать гиперматрицу из вектора. В следующем примере мы определяем гиперматрицу размерами 2 3 2, где значения взяты из набора {1, 2,..., 12}.

--> hypermat ([2 3 2],1:12) Заметим особый порядок значений в полученной гиперматрице. Этот порядок соответствует правилу, по которому самые левые индексы перебираются в первую очередь. Это просто следствие того факта, что для двумерной матрицы значения хранятся столбец за столбцом.

Гиперматрица может также содержать строки, как показано в следующем примере.

Важным свойством гиперматриц является то, что все элементы должны быть одного типа. Например, если мы попытаемся ввести число типа double в гиперматрицу строк, созданную прежде, то мы получим сообщение об ошибке:

Не реализовано в scilab...

3.4 Типы и размерности выделенной гиперматрицы В этом разделе мы представляем выделение гиперматрицы у которых одно измерение единичного размера. Мы представляем эффект, который это производит это может иметь на характеристики и описываем функцию squeeze.

Мы можем выделить срезы гиперматрицы, производя различные размерности выходных переменных. Например, давайте рассмотрим трёхмерную гиперматрицу размерами 2 4 3. Иногда полезно использовать оператор двоеточие : для выделения целых строк или столбцов матрицы или гиперматрицы. Например, команда A(1,:,:) выделяет значения, связанные с первым индексом, равным 1, и формирует гиперматрицу размерами 1 4 3.

Похожим образом команда A(:,1,:) выделяет значения, связанные со вторым индексом, равным 1, и формирует гиперматрицу размерами 2 1 3. С другой стороны, команда A(:,:,1) выделяет значения, связанные с третьим индексом, равным 1, но формирует матрицу размерами 4 3. Следовательно, и тип и форма выделенной гиперматрицы могут измениться, в зависимости от индексов, по которым мы выделяем.

Этот факт исследован на следующем примере.

-->A = hypermat ([2,4,3],[1:24]) Сначала мы экспериментируем с командой выделения B=A(1,:,:).

Мы могли бы поэкспериментировать с командой B=A(:,1,:) и получить похожее поведение.

Вместо этого, мы поэкспериментируем с командой B=A(:,:,1). Мы видим, что в этом случае выделенная переменная является матрицей вместо гиперматрицы.

Общее правило гласит, что, если последнее измерение выделенной гиперматрицы является единичным, то оно удаляется. Это правило применимо к результатам выделения, получающем в конечном счёте либо гиперматрицу, либо обычную двумерную матрицу. Точнее, когда мы выделяем гиперматрицу размерами n1... nj nj+1... nk, где nj = 1 и nj+1 = nj+2 =... = nk = 1, мы получили гиперматрицу размерами n1 nj. Более того, если выделяемая гиперматрица является обычной, т. е. двумерной матрицей, то есть j 2, то выделенная переменная является матрицей, а не гиперматрицей. Эти два правила доказывают, что Scilab совместим с Matlab в выделении гиперматриц.

Такое поведение может иметь существенное влияние на характеристики выделения гиперматриц. В следующем примере мы создаём гиперматрицу 2 4 3 чисел типа double и измеряем характеристики выделения по второму или третьему индексам. Мы объединяем выделение и команду matrix для того, чтобы получить обычную двумерную матрицу B в обоих случаях. Поскольку это выделение чрезвычайно быстрое, мы сделаем это 100 000 раз в цикле и измерим пользовательское время с помощью функций tic и toc. Мы можем видеть, что выделение второго измерения гораздо медленнее, чем выделение третьего измерения.

-->A = hypermat ([2,4,3],1:24);

--> tic (); for i =1:100000; B = matrix ( A (:,2,:),2,3); end ; toc () --> tic (); for i =1:100000; B = matrix ( A (:,:,2),2,4); end ; toc () Причина такого различия характеристик в том, что A(:,2,:) это гиперматрица размером 2 1 3, а A(:,:,2) это обычная матрица размером 2 4.

В самом деле, команда matrix(A(:,2,:),2,3) заставляет функцию matrix преобразовать гиперматрицу A(:,2,:) размерами 213 в матрицу 23, что требует дополнительных matrix(A(:,:,2),2,4) не требует какой-либо обработки от функции matrix function, что в этом случае не требует операций.

Мы можем захотеть просто игнорировать промежуточные подматрицы с размером 1, которые созданы системой выделения подматриц. В этом случае мы можем использовать функцию squeeze, которая удаляет измерения с единичным размером.

-->A = hypermat ([3,1,2],1:6) 3.5 Тип данных list (список) В этом разделе мы опишем тип данных list (список), который используется для управления коллекцией объектов различных типов. Мы очень часто используем списки, когда хотим собрать в один объект набор переменных, которые нельзя сохранить в один, более основной, тип данных. Список может содержать любые уже обсуждённые типы данных (включая функции), а также другие списки. Это позволяет создавать вложенные списки, которые могут быть использованы для создания дерева структур данных. Списки чрезвычайно полезны для определения объектов структурированных данных. Некоторые функции, относящиеся к спискам, представлены на рисунке 15.

На самом деле в Scilab’е есть различные типы списков: обычные списки, типизированные списки и mlist. Этот раздел касается обычных списков. Типизированные списки будут рассмотрены в следующем разделе. Тип данных mlist будет рассматриваться в разделе 3.9.

В следующем примере мы определяем целые числа с плавающей запятой, строку и матрицу. Затем мы используем функцию list, чтобы создать список mylist, содержащий эти три элемента.

--> mylist = list ( myflint, mystr, mymatrix ) Однажды создав, мы можем получить доступ к i-тому элементу списка mylist с помощью команды mylist(i), как в следующем примере.

Число элементов списка может быть вычислено с помощью size.

В случае, когда мы хотим получить несколько элементов одной командой, мы можем использовать оператор двоеточие :. В этом случае мы должны установить столько выходных аргументов, сколько элементов требуется получить. В следующем примере мы получаем два элемента с индексами 2 и 3 и устанавливаем переменные s и m.

Элемент №3 в нашем списке является матрицей. Предположим, что мы хотим получить четвёртое значение в этой матрице. Мы можем иметь доступ к нему непосредственно с помощью следующего синтаксиса.

--> mylist (3)(4) Это гораздо быстрее, чем хранение третьего элемента списка во временной переменной и выделение его четвёртого элемента. В случае, если мы хотим установить значение этого элемента, мы можем использовать тот же синтаксис и обычный оператор =, как показано ниже.

--> mylist (3)(4) = Очевидно, мы могли бы сделать ту же операцию несколькими промежуточными операциями: выделение третьего элемента списка, обновление матрицы и снова хранение матрицы в списке. Но использование команды mylist(3)(4) = 12 действительно проще и быстрее.

Для того, чтобы просматривать элементы списка, мы можем использовать прямой метод или метод, основанный, в частности, на команде for. Сначала используется прямой метод для того, чтобы подсчитать количество элементов в списке с помощью функции size.

Затем мы получаем доступ к элементам одному за другим как показано на следующем примере.

Предыдущие примеры производят следующий вывод.

Element #1: type = constant.

Element #2: type = string.

Element #3: type = constant.

Это более простой способ, который использует напрямую список как аргумент команды for.

Мы можем заполнить список динамически, добавляя новые элементы к концу. В следующем примере мы определяем пустой список с помощью команды list(). Затем, мы используем оператор $+1 для введения новых элементов в конец списка. Это даёт точно такой же список, что и раньше.

3.6 Тип данных tlist Типизированные списки позволяют определять новые структуры данных, которые могут быть настроены в зависимости от конкретных задач, которые необходимо решить. Эти новые структуры данных ведут себя подобно базовым типам данных Scilab’а. В частности, любая обычная функция, такая как size, disp или string может быть перегружена так, что у неё будет особое поведение, если её входным аргументом является новый tlist. Это позволяет расширить возможности, предоставляемые Scilab’ом и вводить новые объекты.

На самом деле, типизированный список также используется внутри числовыми функциями Scilab’а из-за его гибкости. Бльшую часть времени мы даже не знаем, что мы используем список, что показывает насколько этот тип данных удобен.

В этом разделе мы создадим и используем непосредственно tlist для получения близкой с ней структуры данных. В следующем разделе мы представим общую схему, которая позволит имитировать объектно-ориентированное программирование с типизированными списками.

Рисунок 16 представляет все функции, относящиеся к типизированным спискам.

Для того, чтобы создать типизированный список, мы используем функцию tlist, чей ка. Остальные строковые элементы определяют поля типизированного списка. В следующем разделе мы определим типизированный список person, который позволяет сохранить информацию о человеке. Поля person являются именем, фамилией и годом рождения.

-->p = tlist ([ " person "," firstname "," name "," birthyear " ]) ! person firstname name birthyear !

В этом месте создаётся person p, но его поля не определены. Для того, чтобы установить поля p, мы используем точку., которая ставится после имени поля. В следующем примере мы определим три поля, связанных с гипотетическим Полом Смитом (Paul Smith), который родился в 1997.

p. birthyear = 1997;

Все поля теперь определены и мы можем использовать переменное имя p для того, чтобы увидеть содержимое типизированного списка как в следующем примере.

Для того, чтобы получить поле типизированного списка, мы можем использовать синтаксис p(i), как в следующем примере.

Но может быть более удобно получать значение поля firstname с помощью синтаксиса p.firstname как показано в следующем примере.

Мы также можем использовать функцию getfield, который принимает в качестве входных аргументов индексы полей и типизированный список.

Тот же синтаксис может быть использован для установки значения поля. В следующем примере мы обновляем значение имени с Paul на John.

-->p. firstname = " John " Мы также можем использовать функцию setfield для смены поля имени с John на Ringo.

--> setfield (2, " Ringo ",p ) Может так случиться, что мы знаем значения полей во время создания типизированного списка. Мы можем добавить эти значения ко входным аргументам функции tlist в строгом порядке. В следующем примере мы определим person p и установим значения полей во время создания типизированного списка.

--> [ " person "," firstname "," name "," birthyear " ],..

! person firstname name birthyear !

Интересной чертой типизированного списка является то, что функция typeof возвращает текущий тип списка. В следующем примере мы проверяем что функция type возвращает 16, что соответствует списку. Но функция typeof возвращает строку person.

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

Теперь мы рассмотрим функции, которые позволяют динамически получать информацию о типовых списках. Для того, чтобы получить список полей person, мы можем использовать синтаксис p(1) и получить матрицу строк размером 1 4, как в следующем примере.

Тот факт, что первый строковый элемент представляет тип, может быть полезен или мешать, в зависимости от ситуации. Если мы только хотим получить поля типизированного списка (и не распечатывать), то мы можем использовать функцию fieldnames.

Когда мы создаём типизированный список, мы можем определить его поля без установки его значений. Действующее значение поля может быть на самом деле позже установлено динамически в файле-сценарии. В этом случае было бы полезно знать, определено ли поле уже ли нет.

Следующий пример показывает как функция definedfields возвращает матрицу целых чисел с плавающей запятой, представляющую поля, которые уже определены. Мы начинаем с определения p человека без установки какого-либо значения любого из полей.

Вот почему единственное определённое поле равно числу 1. Затем мы устанавливаем поле rstname, которое соответствует индексу 2.

-->p = tlist ([ " person "," firstname "," name "," birthyear " ]) ! person firstname name birthyear !

--> definedfields ( p ) --> definedfields ( p ) Как мы можем видеть, индекс 2 был добавлен к матрице с помощью определённых полей, возвращённых функцией definedfields.

Функции, которые мы рассмотрели, позволяют программировать типизированные списки очень динамичным образом. Теперь мы увидим как использовать функции definedfields для динамического вычисления определено ли поле, идентифицированное по его строке, или нет. Это позволит получить немного больше практики с типизированными списками.

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

-->p = tlist ([ " person "," firstname "," name "," birthyear " ]);

Целью упражнения 3.2 является динамическое определение: существует ли в типизированном списке поле, связанное с заданным полем, определённым по его строке.

3.7 Имитация объектно-ориентированного программирования с помощью типизированных списков В этом разделе мы рассмотрим как типизированные списки могут использоваться для имитации объектно-ориентированного программирования (ООП). Это обсуждение частично было представлено в вики Scilab [7].

Мы представляем простой метод имитирования ООП с текущими функциями Scilab’а.

Предлагаемый метод является классическим, когда мы хотим имитировать ООП на не-ООП языке, например, на Си или фортране. В первой части мы анализировали ограничения функций, которые используют позиционные аргументы. Далее мы представляем метод имитации ООП в Scilab с помощью типизированных списков.

В заметках, связанных с этим разделом, мы представляем похожие методы на других языках. Мы подчёркиваем тот факт, что объектно-ориентированное программирование использовалось и используется десятками не-ООП языков, таких как Си или фортран, например, методами, которые очень похожи на тот, что мы собираемся представить.

3.7.1 Ограничения позиционных аргументов Перед тем как перейти к деталям, мы сначала представим причины того, почему имитация ООП в Scilab’е удобна и, иногда, необходима. В самом деле, метод, который мы защищаем, может позволить упростить многие функции, которые основаны на необязательных, позиционных аргументах. Факт, что входные и выходные аргументы функции являются жёстким ограничением в некоторых случаях, как мы вскоре увидим.

Например, примитив optim является встроенной функцией, которая выполняет неограниченную и частично ограниченную числовую оптимизацию. Эта функция имеет 20 аргументов, некоторые из которых необязательные. Далее приводим заголовок функции, где квадратные скобки [...] обозначают необязательные параметры.

Эта усложнённая последовательность вызова делает практическое использование optim сложным (но работоспособным), особенно если мы хотим настроить его аргументы. Например, переменная является списком четырёх необязательных аргументов:

Многие параметры алгоритма могут быть сконфигурированы, но, довольно удивительно, что многие не могут быть сконфигурированы пользователем функции optim. Например, в случае квази-Ньютоновского алгоритма без ограничений, процедуры фортрана позволяют сконфигурировать длину, представляющую оценку расстояния до оптимума. Этот параметр не может быть сконфигурирован на уровне Scilab и по умолчанию используется значение 0,1. Причина, которая кроется за этим выбором, очевидна: есть уже слишком много параметров для функции optim и добавление других необязательных параметров привело бы к невозможности пользования функцией.

Более того, пользователи и разработчики хотят добавлять новые возможности в примитив optim, но это может привести к нескольким трудностям.

• Расширение текущего шлюза optim очень сложно из-за сложного управления 20-ю внутренними необязательными аргументами. Более того, поддержка и разработка интерфейса в течение жизни проекта Scilab трудны, поскольку порядок аргументов имеет значение. Например, мы можем осознавать, что один аргумент может быть ненужным (из-за того, например, что эта же самая информация может быть получена через другую переменную). В этом случае мы не можем удалить аргумент из последовательности вызова, поскольку это сломает обратную совместимость всех файловсценариев, которые используют эту функцию.

• Трудно расширить список выходных аргументов. Например, нас может заинтересовать целое число, представляющее статус оптимизации (например, достигнута ли сходимость, достигнуто ли максимальное число итераций, максимальное число вызовов функций и т. д.). Мы могли бы быть также заинтересованы в числе итераций, числе вызовов функций, конечном значении аппроксимации матрицы Гессе, и в другой информации. Ограниченное число выходных аргументов на самом деле ограничивает количество информации, которую пользователь может вытянуть из имитации. Более того, если мы захотим получить выходной аргумент №6, например, то мы должны вызвать функцию со всеми аргументами от №1 до №6. Это может породить много ненужных данных.

• Мы могли бы захотеть установить необязательный входной аргумент №7, а не необязательный аргумент №6, который отсутствует в данном интерфейсе. Это из-за того, что система обработки аргументов основана на порядке аргументов.

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

Если окружение объектно-ориентированного программирования было бы доступно для Scilab’а, то управление аргументами было бы решено с меньшими трудностями.

3.7.2 Класс person в Scilab В этом разделе мы даём конкретный пример метода, основанного на разработке класса person.

Метод, который мы представляем в этом документе, для имитации объектно-ориентированного программирования является классическим для других языков. На самом деле о общий для расширения необъектных языков в ООП-системе. Возможный метод:

• мы создаём тип абстрактных данных (ТАД) со структурами основных данных языка, • мы имитируем методы с помощью функций, у которых первый элемент, по имени this, представляет текущий объект.

Мы будем использовать этот метод и имитировать в качестве примера отдельный класс person.

Класс person сделан из следующих функций.

• Функция person_new, конструктор, создаёт новый объект person.

• Функция person_free, деструктор, разрушает существующий объект person.

• Функция person_configure и функция person_cget, позволяют сконфигурировать и опросить поля существующего объекта person.

• Функция person_display, метод, который отображает текущий объект в консоли.

В этих функциях текущий объект будет храниться в переменной this. Чтобы реализовать наш класс, мы используем типизированный список.

Следующая функция person_new возвращает this нового объекта person. Этот новый person определён по своим фамилии, имени, номеру телефона и адресу электронной почты. Мы выбираем для использования пустые значения строк для всех полей.

function this = person_new () this = tlist ([ " TPERSON "," name "," firstname "," phone "," email " ]) endfunction Следующая функция person_free разрушает существующий объект person.

function this = person_free ( this ) // Нет никаких действий.

endfunction Поскольку сейчас нет никаких действий, то тело функции person_free пустое. По-прежнему, в силу разумных причин и из-за того, что реальное тело функции может развиться позже во время разработки компонента, мы создаём эту функцию в любом случае.

Мы подчёркиваем, что переменная this является как входным, так и выходным аргументом функции person_free. В самом деле, текущий объект person, в принципе, является модифицируемым через работу функции person_free.

Функция person_configure позволяет сконфигурировать поле текущего объекта person.

Каждое поле идентифицируется строкой, ключом, который соответствует значению. Следовательно, это просто отображение ключ-значение. Функция устанавливает значение value, соответствующее заданному ключу key, и возвращает обновлённый объект this. Для класса person ключами являются "-name", "-firstname", "-phone" и "-email".

function this = person_configure ( this, key, value ) errmsg = sprintf ( "Неизвестный ключ %s ", key ) endfunction Мы выбрали префиксацию каждого ключа знаком минус -. В последовательностях вызова это позволит легко отличить ключ от значения.

Мы подчёркиваем, что переменная this является как входным, так и выходным аргументом функции person_configure. Она похожа на функцию person_free, которую мы создали прежде.

Аналогично, функция person_cget позволяет получить заданное поле текущего объекта person. person_cget возвращает значение value, соответствующее заданному ключу key текущего объекта.

function value = person_cget ( this, key ) errmsg = sprintf ( "Неизвестный ключ %s ", key ) endfunction Точнее, функция person_cget позволяет получить значение конфигурируемого ключа. c в cget относится к первой букве congure (настроить). Если, вместо этого, мы захотим создать функцию, которая возвращает значение ненастраиваемого ключа, мы можем назвать её person_get.

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

function person_display ( this ) mprintf ( " First name : %s \ n ", this. firstname ) endfunction Теперь мы представим простое использование класса person, который мы только что разработали. В следующем примере мы создаём новый объект person с помощью вызова функции person_new. Затем мы вызовем функцию person_configure несколько раз для того, чтобы сконфигурировать различные поля объекта person.

p1 = person_configure ( p1, " - name "," Backus " );

p1 = person_configure ( p1, " - firstname "," John " );

p1 = person_configure ( p1, " - phone "," 01.23.45.67.89 " );

p1 = person_configure ( p1, " - email "," john. backus@company. com " );

В следующем примере мы вызовем функцию person_display и распечатаем текущий person.

--> person_display ( p1 ) Phone : 01.23.45.67. E - mail : john. backus@company. com Мы можем также запросить имя текущего person вызовом функции person_get.

Наконец, мы уничтожим текущий person.

3.7.3 Расширение класса В этом разделе мы обсудим способы расширения класса, основанные на имитации метода, который мы представили. Наша цель возможность управлять более сложными компонентами с бльшим количеством полей, бльшим количеством методов или бльшим коо о о личеством классов.

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

Новый ключ в класс добавляется напрямую. Сначала мы должны обновить функцию person_new, добавив новое поле к типизированному списку. Мы можем решить, какое значение по умолчанию использовать для нового поля. Заметим, что существующие файлысценарии, использующие класс person, будут работать. Если требуется, то файл-сценарий может быть обновлён для того, чтобы конфигурировать новый ключ значением не по умолчанию.

Мы можем решить различать публичные поля, которые могут быть сконфигурированы пользователем или классом, и частные поля, которые не могут. Для того, чтобы добавить новое частное поле в класс person, скажем bankaccount (банковский счёт), мы изменяем функцию person_new и добавляем соответствующую строку в типизированный список.

Следовательно, нам не нужно делать его доступным ни в функции person_configure, ни в функции person_cget, пользователь класса не сможет получить доступ к нему.

Мы можем быть немного гибче, позволяя пользователю класса получать значения полей без возможности изменения значения. В этом случае нам следует создать отдельную функцию person_get (заметим отсутствие буквы c ). Это позволяет отделить конфигурируемые опции от неконфигурируемых опций.

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

К примеру, допустим, что мы хотим создать класс company. Эта company определяется по её имени, адресу, назначению и списком всех людей ( person ), работающих в ней. Следующая функция company_new предлагает возможную реализацию.

function this = company_new () this = tlist ([ " TCOMPANY "," name "," address "," purpose "," employees " ]) endfunction Следующая функция company_addperson позволяет добавлять нового человека в список работников.

function this = compan y_addpers on ( this, person ) this. employees ( $ +1) = person endfunction На самом деле, методы, которые широко используются в ООП, могут применяться используя эту схему имитации. Это позволяет создавать отдельные компоненты, предоставляющие прозрачный публичный интерфейс и избегающие необходимости в сложных функциях, использующих большое количество позиционных аргументов.

3.8 Перегрузка типизированных списков В этом разделе мы увидим как перегрузить функцию string так, что бы мы могли преобразовать типизированный список в строку. Мы также рассмотрим как перегрузить функцию disp, т. е. систему печати, которая позволяет настраивать печать типизированных списков.

Следующая функция %TPERSON_string возвращает матрицу строковых значений, содержащую описание текущего объекта person. Она сначала создаёт пустую матрицу. Затем она добавляет строки одну за другой с помощью выходного значения функции sprintf, которая позволяет форматировать строки.

function str = %TPERSON_string ( this ) str ( k ) = sprintf ( " First name : %s ", this. firstname ) endfunction Функция %TPERSON_string позволяет перегрузить функцию string для любого объекта с типом TPERSON.

Следующая функция %TPERSON_p распечатывает текущий объект person. Она сначала вызывает функцию string для того, чтобы вычислить матрицу строк, описывающих объект person. Затем она делает циклы по рядам матрицы и распечатывает их один за другим в консоли.

function %TPERSON_p ( this ) endfunction Функция %TPERSON_p позволяет перегрузить распечатку объектов с типом TPERSON (буква p обозначает распечатку ( print )).

В следующем примере мы вызываем функцию string с объектом person p1.

--> p1 = person_new ();

--> p1 = person_configure ( p1, " - name "," Backus " );

--> p1 = person_configure ( p1, " - firstname "," John " );

--> p1 = person_configure ( p1, " - phone "," 01.23.45.67.89 " );

--> p1 = person_configure ( p1, " - email "," john. backus@company. com " );

!E - mail : john. backus@company. com !

В предыдущем примере функция string автоматически вызвала функцию %TPERSON_string, которую мы определили ранее.

В следующем примере мы просто напечатаем имя переменной p1 (и немедленно нажмём клавишу enter в консоли), как и с любой другой переменной. Это распечатает содержимое нашей переменной p1.

====================== First name : John Phone : 01.23.45.67. E - mail : john. backus@company. com В предыдущем примере система печати автоматически вызвала функцию %TPERSON_p, которую мы уже определили ранее. Заметим, что будет сделан тот же вывод как если бы мы использовали команду disp(p1).

Наконец, мы уничтожим текущий объект person.

p1 = person_free ( p1 );

Есть много других функций, которые могли бы быть определены для типизированных списков. Например, мы можем перегрузить оператор + так, что мы можем суммировать два объекта person. Это описано более подробно на страницах справки, посвящённых перегрузке:

help overloading 3.9 Тип данных mlist В этом разделе мы представляем тип данных mlist, который является матричноориентированным списком. В первой части этого раздела мы представляем главную мотивацию для типа данных mlist сравнивая с tlist. Затем мы представляем пример mlist, где мы определяем функцию выделения.

Главная разница между tlist и mlist состоит в отношении к выделению и вставке функций. В самом деле, для tlist M выделение, основанное на индексах, т. е. команда x=M(2), например, определена по умолчанию. Она может быть перегружена пользователем, но это не обязательно, как мы увидим далее.

В следующем примере мы определяем tlist с типом V. Этот типизированный список имеет два поля, name (имя) и age (возраст).

Как ожидалось от tlist, команда M(2) позволяет выделить второе поле, т. е. name (имя) переменной.

То же самое для вставки (т. е. M(2)=x) в list (или tlist).

С другой стороны, для mlist выделение и вставка функций должна быть определена.

Если нет, то формируется ошибка.

В следующем примере мы определяем mlist с типом V. Как и прежде, этот список матриц имеет два поля, name и age.

В следующем примере мы видим, что не можем напрямую выделять второе поле этого списка Операция для заданных операндов не определена.

отметьте или определите функцию %l_e как перегружаемую.

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

Давайте рассмотрим предыдущий пример и предположим, что M это tlist. Особая проблема с M заключается в том, что второй элемент M(2) может не соответствовать тому, что нам надо. В самом деле, переменная M(2) является матрицей строковых переменных ["a","b";"c" "d"]. Но возможны такие ситуации, где нам бы хотелось выразить, что второй элемент представляет особый элемент, который не соответствует особому значению, которое связано с tlist.

К примеру, мы можем захотеть конкатенировать имя со значением для формирования строки Name: b, age: 2, которая бы была вторым элементом нашей матрицы M. Следовательно, кажется, что нам нужно переопределить выделение (или вставку) значений для tlist. Но это невозможно, поскольку система перегрузки позволяет только определять функции, которые не существуют: в этом случае функция выделения уже существует, так что мы не можем определять её. Это случай, когда полезен mlist: мы можем определить функции выделения и вставки для mlist и настроить их поведение. Фактически, мы даже принуждаем делать так: поскольку, как мы видели до этого, это обязательно.

Для того, чтобы определить функцию выделения для mlist с V, мы должны определить функцию %V_e, где буква e обозначает extraction (выделение). Это сделано в следующем примере. Заголовок функции выделения должен быть [x1,...,xm]=%_e_(i1,...,in,a), где x1,...,xm выделенные значения, индексы значений, которые нужно выделить, и a текущая переменная.

i1,...,in Следовательно, команда M=varargin($) позволяет установить в M текущую переменную из которой выделяются значения. Затем индексы могут быть получены с помощью команды varargin(1:$-1), которая создаёт список переменных, содержащий действующие индексы. Наконец, мы создаём матрицу строковых переменных конкатенацией имени со строкой, представляющей возраст.

function r = %V_e ( varargin ) В следующем примере мы выделяем второй элемент M.

Мы можем также использовать синтаксис, который очень похож на матрицы, как в следующем примере.

3.10 Тип данных struct В этом разделе мы кратко представляем struct, которая является структурой данных, с беспорядочными составляющими разнородных типов. Мы сравним её характеристики с list.

Внутри struct все составляющие могут быть выделены по их именам. В следующем примере мы определяем переменную d как struct с тремя полями day (день), month (месяц) и year (год ).

-->d = struct ( " day ",25, " month "," DEC "," year ",2006) Заметьте, что поля структуры struct не обязаны быть одного типа: первое поле это строка, а второе поле число типа double. Для того, чтобы выделить переменную из struct, мы просто используем имя переменной после точки. и имя поля.

Для того, чтобы вставить значение в struct, мы просто используем оператор присвоения =.

Структура struct может содержать другую структуру struct, что может привести к структурам вложенных данных. Например, в следующем примере мы создаём уик-энд из двух последовательных дней.

--> d1 = struct ( " day ",01, " month "," JAN "," year ",2011);

--> d2 = struct ( " day ",02, " month "," JAN "," year ",2011);

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

Фактически, главное преимущество struct это совместимость с Matlab и Octave.

3.11 Массив структур struct Массив структур struct это массив, где каждый индекс связан со структурой struct.

Есть несколько способов создать массив структур. В первой части этого раздела мы конкатенируем несколько структур для создания массива. Во второй части мы инициализируем целый массив структур за один вызов, а затем заполняем поля одно за другим.

Если несколько структур имеют одинаковые поля, и если все эти поля имеют одинаковый размер, то они могут быть конкатенированы в один массив структур. В следующем примере мы создаём четыре отдельных структуры.

s1 = struct ( " firstname "," John "," birthyear ",1940);

s2 = struct ( " firstname "," Paul "," birthyear ",1942);

s3 = struct ( " firstname "," George "," birthyear ",1943);

s4 = struct ( " firstname "," Ringo "," birthyear ",1940);

Заметим, что поля не обязаны быть одного типа: первое поле строка, а второе поле число типа double. Затем мы конкатенируем их в один массив структур, используя синтаксис [], который схож с матрицами.

1 x4 struct array with fields :

Мы можем выделить третью структуру из массива используя синтаксис s(3), который схож с матрицами.

Мы можем получить доступ к полю rstname всех структур, как показано в следующем примере. Это даёт список строк.

-->s. firstname --> typeof ( s. firstname ) По причине производительности мы не советуем позволять структура расти динамически. Это из-за того, что это заставляет интерпретатор динамически распределять больше и больше памяти и может привести к медленным файлам-сценариям. Вместо этого, где только возможно, нам следует предопределять массивы структур, а затем заполнять существующие ячейки.

В следующем примере мы определяем массив размером 4 1 структур struct, где каждая структура содержит пустое firstname и пустое name.

t (1:4)= struct ( " firstname ",[], " birthyear ",[]) Затем мы заполняем каждую структуру как в следующем примере.

t (1). birthyear =1940;

t (2). birthyear =1942;

t (3). firstname = " George " ;

t (3). birthyear =1943;

t (4). firstname = " Ringo " ;

t (4). birthyear =1940;

Мы можем проверить, что это даёт в точности тот же массив структур, что и прежде.

4 x1 struct array with fields :

В предыдущим примерах мы видели только массивы с одним индексом. Должно быть ясно, что массив структур является в действительности 2х -индексным массивом, т. е. матрицей. Кстати, мы собираемся рассмотреть другой метод инициализации массива структур.

В следующем примере мы инициализируем массив структур размером 2 2.

-->u (2,2). firstname =[] 2 x2 struct array with fields :

-->u (2,2). birthyear =[] 2 x2 struct array with fields :

Затем мы можем заполнить ячейки с помощью синтаксиса, который похож на матрицы.

u (1,1). birthyear =1940;

u (2,1). birthyear =1942;

u (1,2). firstname = " George " ;

u (1,2). birthyear =1943;

u (2,2). birthyear =1940;

Сделав однажды, мы можем выделять структуры, связанные с индексами (2,1), например.

3.12 Тип данных cell В этом разделе мы кратко представляем cell, который является разнородным массивом переменных. Затем мы сравниваем его характеристики с характеристиками гиперматрицы hypermatrix и списка list. Рисунок 17 представляет несколько функций, связанных с массивами cell.

Функция cell позволяет создавать массив. Этот cell-массив может содержать другие типы переменных, включая double, integer, string и т. д. В следующем примере мы создаём cell-массив размером 2 3.

Размер cell-массива может быть вычислен с помощью функции size.

Для того, чтобы ввести значение в cell-массив, мы не можем использовать тот же синтаксис, что и для матриц.

Invalid assignement : for insertion in cell, use e. g. x (i, j ). entries = y Вместо этого мы можем использовать поле entries элемента (2,1), как в следующем примере.

-->c (2,1). entries = В следующем примере мы вводим строку в элемент (1,3).

Для того, чтобы удалить элемент (1,3), мы можем использовать матрицу [].

-->c (1,3). entries =[] Мы можем выделять часть cell-массива, используя синтаксис, схожий с матрицами. Заметим, что результатом является cell-массив.

С другой стороны, когда мы выделяем одну конкретную ячейку с помощью поля entries, мы получаем тот же тип данных, что и в данная конкретная ячейка. В следующем примере мы выделяем ячейку (2,1) в переменную x и проверяем, что эта переменная имеет тип double.

Если мы выделим несколько ячеек за раз с помощью поля entries, то мы получим список.

В следующем примере мы выделяем все ячейки в первом столбце.

-->x = c (1:2,1). entries Мы можем создать многоиндексные массивы с помощью 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. Другие типы данных могут содержать только один тип переменных: это ситуация матрицы и гиперматрицы. Если все переменные, чей тип данных должен управляться, имеют один и тот же тип, то без сомнения следует выбирать матрицу или гиперматрицу.

Тип данных matrix hypermatrix Упорядоченный набор элене перегружается list tlist Неупорядоченный набор элесовместим с Matlab не перегружается struct cell Рис. 19: Сравнение типов данных. Столбец Реализация указывает на реализацию этих типов данных в Scilab версии 5.

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

Одна из причин, которой можно объяснить разницу производительностей заключается в реализации различных типов данных. Это представлено в столбце Реализация на рисунке 19 где мы представляем реализацию этих типов данных в Scilab версии 5.

Например, мы представляли гиперматрицы в разделе 3.3. В разделе 3.4 мы уже анализировали влияние производительности, которую может иметь выделение из гиперматриц.

В Scilab версии 5 гиперматрицы реализованы через mlist, поддерживаемые как скомпилированным исходным кодом, так и макросами Scilab’а. Например, выделение гиперматриц чисел типа double основано на скомпилированном исходном коде, а выделение гиперматриц строковых переменных основано на макросе: это может также привести к различиям производительностей.

3.14 Заметки и ссылки В первой части данного раздела мы представляем некоторые заметки и ссылки по теме имитации ООП в Scilab’е. Во второй части мы описываем связь между типом данных polynomial и функциями управления в Scilab’е.

Структура абстрактных данных для имитации ООП зависит от языка.

• В Си структура абстрактных данных выбора является структурой. Этот метод расширения Си частот используется для обеспечения общей схемы ООП [48, 52, 19, 46] когда использование C++ нежелательно или невозможно. Этот метод уже используется внутри исходного кода Scilab, в графическом модуле, для конфигурации свойств графики. Он известен как handles (дескрипторы): смотри заголовочный файл ObjectStructure.h [44].

• В Fortran 77 достаточна команда common (но она редко используется для имитации • В Fortran 90 был разработан производный тип для этих целей (но редко используется для имитации истинного ООП). Стандарт Fortran 2003 это Fortran с реальным ООП, основанным на производных типах.

• В Tcl, структура данных array является подходящей ТАД (он используется массивом STOOOOP [20] например). Но это можно также сделать с командой 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.). В то время главными разработчиками были Франсуа Делебек (Franois Delebecque) и Серж Стир (Serge Steer). В контексте теории управления мы анализируем поведение динамических систем. В случае систем управления с одним входом и одним выходом (SISO), мы можем использовать преобразование Лапласа над переменными, что приводит к передаточной функции. Следовательно, тип данных rational был введён для поддержки анализа передаточных функций полученных для линейных систем. Есть много других функций, относящихся к CACSD в Scilab и представлять их не входит в задачи данного документа.

3.15 Упражнения Упражнение 3.1 (Поиск файлов) Интерпретируемые языки часто используются для задач автоматизации, таких как поиск и переименование файлов на жёстком диске. В этой ситуации может быть использована функция regexp, чтобы обнаружить файлы с совпадением с заданным шаблоном. Например, мы можем использовать её для поиска файлов-сценариев Scilab в папке. Это легко, поскольку файлы-сценарии Scilab имеют расширения.sci (для файлов, определяющих функцию) и.sce (для файлов, выполняющих инструкции Scilab).

Разработайте функцию searchSciFilesInDir, которая ищет эти файлы в заданной директории. Мы предлагаем дать следующий заголовок.

function filematrix = s ea r c hS c iF i l es I nD i r ( directory, funname ) Если такой файл найдётся, мы добавим его в матрицу строковых переменных filematrix, которая возвращается в качестве выходного аргумента. Более того, мы вызовем функцию funname. Это позволит нам обработать файл если потребуется. Следовательно, мы можем использовать эту функциональность для отображения имени файла, перемещения файла в другую папку, удаления его и т. д.

Разработайте функцию mydisplay со следующим заголовком:

function mydisplay ( filename ) и используйте эту функцию совместно с searchSciFilesInDir для того, чтобы распечатать файлы в директории.



Pages:     || 2 | 3 | 4 |


Похожие работы:

«Федеральная сетевая компания Единой энергетической системы Комплексный подход к подготовке, привлечению на работу, повышению уровня профессионализма и закреплению молодых специалистов в ОАО ФСК ЕЭС Наталья Климентьевна Ожегина Заместитель Председателя Правления Общие сведения о компании ФСК ЕЭС – естественная монополия в секторе передачи электроэнергии, владеет и управляет Единой национальной (общероссийской) электрической сетью (ЕНЭС) напряжением 220 кВ и выше ФСК ЕЭС входит в тройку...»

«МИНОБРНАУКИ РОССИИ ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ ВОРОНЕЖСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ (ФГБОУ ВПО ВГУ) ПРОГРАММА ХХIX КОНФЕРЕНЦИИ НАУЧНОГО ОБЩЕСТВА УЧАЩИХСЯ 6 АПРЕЛЯ 2014 ГОДА Воронеж 2014 2 Дорогие школьники, уважаемые преподаватели, учителя – участники Конференции Научного общества учащихся! Воронежский государственный университет по праву считается крупнейшим учебным, научным и культурным центром...»

«1 2 I. ОБЩИЕ ПОЛОЖЕНИЯ 1.1. Настоящее Положение определяет порядок организации и проведения практической подготовки студентов, получающих среднее медицинское или фармацевтическое образование в БОУ ОО СПО Орловский базовый медицинский колледж (далее – ОБМК, колледж), в том числе: виды практики, общие вопросы организации, формы и виды отчётности. 1.2. Положение разработано в соответствии с Конституцией РФ, ФЗ Об образовании в Российской Федерации от 29 декабря 2012 г. №273-ФЗ, действующими...»

«Приказ министерства сельского хозяйства и перерабатывающей промышленности Краснодарского края от 3 июля 2013 г. N 139 Об утверждении форм и перечня документов Во исполнение статьи 9 Закона Краснодарского края от 3 июля 2012 года N 2536-КЗ О сельских усадьбах в малых сельских населенных пунктах Краснодарского края, в целях реализации ведомственной целевой программы Организация сельских усадеб в малых сельских населнных пунктах Краснодарского края на 2013 - 2015 годы приказываю: 1. Утвердить: 1)...»

«Институт инноватики ii.spb.ru МИНИСТЕРСТВО ОБРАЗОВАНИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ УТВЕРЖДАЮ Руководитель Департамента содержания высшего профессионального образования Л.В. Попов 2004 г. ПРИМЕРНАЯ ПРОГРАММА ДИСЦИПЛИНЫ Инфраструктура нововведений Рекомендуется Министерством образования России для специальности 073500 – Управление инновациями направления подготовки дипломированных специалистов 658200 – Инноватика Санкт-Петербург Институт инноватики ii.spb.ru Программа дисциплины “Инфраструктура...»

«Роман Савин teстирование COM или Пособие по жестокому обращению с б а г а м и в интернет-стартапах Роман Савин Одна из причин, побудивших автора написать эту книгу, — осознание собственного бессилия в поисках сиюминутного практического смысла при чтении классических сочинений по теории тестирования., в особенности когда ты в поисках работы и время дорого. Наиболее эффективный подход для тренинга тестировщиков — дать им практический инструментарий, поставить в нужную сторону мозги — и в бой. Эта...»

«Автор программы М.В. Королева УЧЕБНАЯ ПРОГРАММА КУРСА КУЛЬТУРА ГЭЛЬСКОЙ ШОТЛАНДИИ Данный курс преподается студентам факультета иностранных языков и регионоведения МГУ имени М.В. Ломоносова как курс по выбору. Курс желательно прослушать студентам, выбравшим современный гэльский язык в качестве третьего языка. Новизна: это первый лекционный курс по культуре гэльской Шотландии, разработанный в России. При формировании курса учитывалась специфика факультета иностранных языков и регионоведения МГУ:...»

«МАТЕМАТИЧЕСКИЕ МЕТОДЫ В ГЕОЭКОЛОГИИ Учебная программа для специальности 1-33 01 02 Геоэкология Авто-разработчик – кандидат физико-математических наук, доцент И.К. Пирштук I. ПОЯСНИТЕЛЬНАЯ ЗАПИСКА Дисциплина Математические методы в геоэкологии знакомит студентов с основными математическими методами и алгоритмами обработки, анализа и прогнозирования информации в геоэкологических системах, возможностями и границами применения этих методов. В курсе рассматриваются методы и алгоритмы, которые могут...»

«МИНИСТЕРСТВО СЕЛЬСКОГО ХОЗЯЙСТВА РОССИЙСКОЙ ФЕДЕРАЦИИ Федеральное государственное образовательное учреждение высшего профессионального образования КУБАНСКИЙ ГОСУДАРСТВЕННЫЙ АГРАРНЫЙ УНИВЕРСИТЕТ Утверждаю: Декан факультета ветеринарной медицины, профессор _ А.А. Лысенко _2013 г. РАБОЧАЯ ПРОГРАММА Дисциплины – ОПД.Ф.06Ветеринарная пропедевтика болезней животных для специальности 110501 - Ветеринарно-санитарная экспертиза, факультета ветеринарной медицины Ведущая кафедра терапии и клинической...»

«Приложение Б15 Межрегиональный отраслевой ресурсный центр Интеграл Северо-Кавказского федерального округа Государственное бюджетное образовательное учреждение среднего профессионального образования Ардонский аграрно-технологический техникум ПРОГРАММА ПРОФЕССИОНАЛЬНОГО МОДУЛЯ Ремонт и изготовление обмоток элементов электрических машин по профессии начального профессионального образования 140446.03 Электромонтер по ремонту и обслуживанию электрооборудования (по отраслям) 2013 1239 РЕКОМЕНДОВАНО...»

«Как выбрать программу обучения в начальной школе? Часто слышишь: Мы занимаемся по Виноградовой. А у нас в классе учат по Занкову. К сожалению, большинство родителей могут лишь назвать автора учебной программы, другие скажут нам ее хвалили, третьи, может быть, расскажут о конкретных плюсах и минусах. Но в целом же, рядовой родитель с трудом понимает, чем различаются все эти программы. И не удивительно. Действительно сложно пробраться сквозь научный стиль и терминологию педагогических текстов....»

«IDB.41/5-PBC.29/5 Организация Объединенных Distr.: General Наций по промышленному 19 March 2013 Russian развитию Original: English Совет по промышленному развитию Комитет по программным и бюджетным вопросам Сорок первая сессия Вена, 24–27 июня 2013 года Двадцать девятая сессия Пункт 5 предварительной повестки дня Вена, 22–24 мая 2013 года Программа и бюджеты на 2014–2015 годы Пункт 5 предварительной повестки дня Программа и бюджеты на 2014–2015 годы ПРОГРАММА И БЮДЖЕТЫ НА 2014–2015 ГОДЫ*...»

«БЕЛОРУССКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ХИМИЧЕСКИЙ ФАКУЛЬТЕТ КАФЕДРА АНАЛИТИЧЕСКОЙ ХИМИИ ПРОГРАММА СПЕЦИАЛЬНОГО КУРСА Анализ продуктов питания ДЛЯ СТУДЕНТОВ 4 КУРСА СПЕЦИАЛЬНОСТИ ХИМИЧЕСКАЯ ЭКОЛОГИЯ СПЕЦИАЛИЗАЦИИ АНАЛИТИЧЕСКАЯ ХИМИЯ Лекции – 24 часа Семинарские занятия – 6 часов Контроль самостоятельной работы – 6 часов Лабораторные занятия - 24 часа Составитель – доцент Мельситова И.В. Утверждена Советом химического факультета _ 2006г. Председатель Совета химического факультета _ Паньков В.В....»

«Государственное образовательное учреждение высшего профессионального образования Липецкий государственный технический университет Кафедра культуры “УТВЕРЖДАЮ” Декан факультета инженеров транспорта _ Ляпин С.А. 200_ РАБОЧАЯ ПРОГРАММА ДИСЦИПЛИНЫ ЭТИКА И ЭТИКЕТ В БИЗНЕС-КОММУНИКАЦИЯХ Направление подготовки: 190600 Эксплуатация транспортно-технологических машин и комплексов Профиль подготовки: Автомобильный сервис Квалификация (степень) выпускника: бакалавр Форма обучения: очная Липецк Рабочая...»

«Положение о конкурсе на гранты Европейского университета в Санкт-Петербурге для подготовки и публикации монографий 1. В 2007-2008 году Европейский университет в Санкт-Петербурге (далее – ЕУСПб) предоставляет не более двух грантов для подготовки и публикации монографий выпускниками ЕУСПб (далее – гранты). Гранты предоставляются за счет средств бюджета ЕУСПб по статье Научная деятельность ЕУСПб согласно решению Комиссии по научному планированию ЕУСПб (далее – Комиссии). С этой целью комиссия...»

«Некоммерческая организация Ассоциация московских вузов Федеральное образовательное учреждение высшего профессионального образования Московский государственный агроинженерный университет имени В.П.Горячкина Научно-образовательный материал ПРОГРАММА ПОВЫШЕНИЯ КВАЛИФИКАЦИИ СИСТЕМЫ МЕНЕДЖМЕНТА КАЧЕСТВА Состав научно-образовательного коллектива: Леонов Олег Альбертович, д.т.н., профессор; Карпузов Василий Викторович, к.т.н., профессор; Шкаруба Нина Жоровна, к.т.н., доцент; Темасова Галина...»

«ПРИМЕРНАЯ ПРОГРАММА УЧЕБНОЙ ДИСЦИПЛИНЫ ЗАЩИТА ПРАВ ПОТРЕБИТЕЛЕЙ 2011 г. Примерная программа учебной дисциплины разработана на основе Федерального государственного образовательного стандарта по специальностям начального профессионального образования (далее – НПО) 100701.01 Продавец, контролёр-кассир Организация-разработчик: КГОУ СПО Алтайский колледж промышленных технологий и бизнеса Разработчики: Леванькова И.Г., руководитель учебного центра ТД Аникс; Объедкова Л.В., старший мастер КГОУ СПО...»

«РУССКАЯ ШКОЛЬНАЯ БИБЛИОТЕЧНАЯ АССОЦИАЦИЯ ДВИЖЕНИЕ МОЛОДАЯ РОССИЯ ЧИТАЕТ ПРОЕКТ РОДИТЕЛЬСКОЕ СОБРАНИЕ ПО ДЕТСКОМУ ЧТЕНИЮ Подсказки для взрослых Приложение для родителей, воспитателей, учителей и библиотекарей к журналу Читайка № 2, 2009 приложение к журналу Читайка № 2—2009 Дорогие наши взрослые читатели! Вот уже второй год в каждом номере журнала ЧИТАЙКА вас ожидает подарок — Подсказки для взрослых. Надеемся, наши несложные советы помогут вам в воспитании юных Читаек, подс кажут, как открыть...»

«Приложение Б24 Межрегиональный отраслевой ресурсный центр Интеграл Северо-Кавказского федерального округа Федеральное государственное бюджетное образовательное учреждение высшего профессионального образования Северо-Кавказская государственная гуманитарно-технологическая академия Среднепрофессиональный колледж, г. Черкесск ПРОГРАММА ПРОФЕССИОНАЛЬНОГО МОДУЛЯ Монтаж, эксплуатация и техническое обслуживание систем освещения по специальности среднего профессионального образования 140409...»

«МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ КРАСНОЯРСКОГО КРАЯ КРАЕВОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ НАЧАЛЬНОГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ ПРОФЕССИОНАЛЬНОЕ УЧИЛИЩЕ № 79 П. КОШУРНИКОВО УТВЕРЖДАЮ: Зам. директора по УПР _И.Ф. Копнина _20г. РАБОЧАЯ ПРОГРАММА ПРОФЕССИОНАЛЬНОГО МОДУЛЯ ПМ.05 Приготовление блюд из мяса и домашней птицы Профессия 260807.01 Повар, кондитер Нормативный срок обучения – 2 года и 5 мес. на базе основного общего образования Рабочая программа профессионального...»








 
2014 www.av.disus.ru - «Бесплатная электронная библиотека - Авторефераты, Диссертации, Монографии, Программы»

Материалы этого сайта размещены для ознакомления, все права принадлежат их авторам.
Если Вы не согласны с тем, что Ваш материал размещён на этом сайте, пожалуйста, напишите нам, мы в течении 1-2 рабочих дней удалим его.