Программирование в Scilab Микаэль Боден Micha
Скачать 1.35 Mb.
|
булевы переменные, целочисленные и другие типы структур данных. Функции type и typeof позволяют узнать конкретный тип данной переменной. Функция type возвращает целое чис- ло с плавающей запятой, а функция typeof возвращает строку. Эти функции представлены на рисунке 7 type Возвращает строку typeof Возвращает целое число с плавающей запятой Рис. 7: Функции для вычисления типа переменной. Рисунок 8 представляет различные выходные значения функций type и typeof. type typeof описание 1 constant матрица вещественных или комплексных кон- стант 2 polynomial матрица многочленов 4 boolean булева матрица 5 sparse разреженная матрица 6 boolean sparse разреженная булева матрица 7 Matlab sparse разреженная матрица Matlab’а 8 int8, int16, int32, uint8, uint16 или uint32 матрица целочисленных значений, хранимых в 1, 2 или 4 байтах 9 handle матрица указателей графиков 10 string матрица символьных строк 11 function некомпилированная функция (код Scilab) 13 function скомпилированная функция (код Scilab) 14 library библиотека функций 15 list список 16 rational, state-space или тип типизированный список (tlist) 17 hypermat, st, ce или тип типизированный список ориентированный на матрицу (mlist) 128 pointer разреженная матрица LU-разложения 129 size implicit размер неявного многочлена, используемый для индексации 130 fptr код, свойственный Scilab’у (C или Fortran’у) Рис. 8: Возвращаемые значения функций type и typeof. 17 В следующем примере мы создаём матрицу 2 × 2 чисел типа double и используем type и typeof для получения типа этой матрицы. - - > A = eye (2 ,2) A = 1. 0. 0. 1. - - > t y p e ( A ) ans = 1. - - > t y p e o f ( A ) ans = c o n s t a n t Эти две функции полезны во время обработки входных аргументов функции. Эта тема будет ещё раз рассмотрена в данном документе позднее, в разделе 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’а был переработан [ 41 ]. С другой стороны, Scilab сохраняет этот довольно старый способ управления памятью. Некоторые дополнительные подробности об управлении памятью в Matlab даны в [ 34 ]. В технических заметках [ 35 ] авторы представляют методы, избегающие ошибки памяти в Matlab. В технических заметках [ 36 ] авторы представляют максимальный размер матри- цы, доступный в Matlab на различных платформах. В технических заметках [ 37 ] авторы представляют выгоду использования 64 х -битного Matlab’а перед 32 х -битным. 2.8 Упражнения Упражнение 2.1 (Максимальный размер стека ) Проверьте максимальный размер стека вашей ма- шины. Упражнение 2.2 (who_user ) Запустите Scilab, выполните следующий код и посмотрите результат на вашей машине. w h o _ u s e r () A = o n e s ( 1 0 0 , 1 0 0 ) ; w h o _ u s e r () Упражнение 2.3 (whos ) Запустите Scilab, выполните следующий код и посмотрите результат на вашей машине. w h o s () 18 3 Специальные типы данных В этом разделе мы анализируем типы данных Scilab’a, которые наиболее часто ис- пользуются на практике. Мы рассмотрим строки, целочисленные значения, многочлены, гиперматрицы, list’ы и tlist’ы. Мы представим некоторые из наиболее полезных свойств системы перегрузки, которые позволяют определять новые поведения для типизированных списков. В последнем разделе мы кратко рассмотрим cell, struct и mlist и сравним их с другими структурами данных. 3.1 Строки Хотя Scilab не разрабатывался изначально в качестве инструмента управления стро- ками, он предоставляет солидный и мощный набор функций для управления этим типом данных. Список команд, которые связаны со строками Scilab’а представлены на рисунке 9 string преобразование в строку sci2exp преобразовать выражение в строку ascii преобразовать строку в коды ascii (и обратно) blanks создать строку из пробелов convstr преобразовать регистры символов emptystr строка нулевой длины grep найти соответствия строки в векторе строк justify выравнять символы в столбцах матрицы length длина объекта part выделение части строки regexp найти подстроки, которые соответствуют строке регулярного выражения strcat конкатенировать символьные строки strchr найти первую встречу символа в строке strcmp сравнить символьные строки strcmpi сравнить символьные строки (независимо от регистра) strcspn получить интервал до указанного символа в строке strindex найти позицию символьной строки в другой строке stripblanks обрезает пробелы (и табуляторы) в начале и в конце строк strncpy копирует символы из строк strrchr найти последнюю встречу символа в строке strrev возвращает строку задом наперёд strsplit разбивает строку на векторы строк strspn получить интервал символов в строке strstr определить позицию подстроки strsubst заменить символьную строку другой символьной строкой strtod преобразование строки в число типа double strtok разделение строки на лексемы tokenpos возвращает позиции лексем в символьной строке tokens возвращает лексемы символьной строки str2code возвращает целочисленные коды Scilab, связанные с символьной строкой code2str возвращает символьную строку, связанную с целочисленными кодами Scilab Рис. 9: Символьные функции Scilab. 19 Для того, чтобы создать матрицу строк, мы можем использовать символ « " » и обыч- ный синтаксис для матриц. В следующем примере мы создаём матрицу строк размером 2 × 3. - - > x = [ " 1 1 1 1 1 " " 22 " " 333 " ; " 4 4 4 4 " " 5 " " 666 " ] x = ! 1 1 1 1 1 22 333 ! ! ! ! 4 4 4 4 5 666 ! Для того, чтобы вычислить размер матрицы, мы можем использовать функцию size как для обычных матриц. - - > s i z e ( x ) ans = 2. 3. Функция length, с другой стороны, возвращает число символов в каждом элементе матрицы - - > l e n g t h ( x ) ans = 5. 2. 3. 4. 1. 3. Возможно, что самая распространённая функция, которую мы используем, это функ- ция string. Эта функция позволяет преобразовать свой входной аргумент в строку. В сле- дующем примере мы определим вектор-строку и используем функцию string для преобра- зования его в строку. Затем мы используем функцию typeof и проверим, что переменная str действительно является строкой. Наконец, мы используем функцию size и проверим, что переменная str является матрицей строк размером 1 × 5 - - > x = [1 2 3 4 5]; - - > str = s t r i n g ( x ) str = !1 2 3 4 5 ! - - > t y p e o f ( str ) ans = s t r i n g - - > s i z e ( str ) ans = 1. 5. Функция string может принимать любой тип входного аргумента. Позже мы увидим, что tlist может быть использован для определения нового типа данных. В этом случае мы можем определить функцию, которая делает так, что функция string может работать с этим новым типом данных способом, определённым пользователем. Эта тема рассматривается в разделе 3.8 , где мы представим метод, который позволяет опре- делить поведение функции string, когда её входной аргумент является типизированным списком, когда её входной аргумент является типизированным списком. Функция strcat конкатенирует свой первый входной аргумент с разделителем, опре- делённым во втором входном аргументе. В следующем примере мы используем функцию strcat для получения строки, представляющую сумму целых от 1 до 5. - - > s t r c a t ([ " 1 " " 2 " " 3 " " 4 " " 5 " ] , " + " ) ans = 1 + 2 + 3 + 4 + 5 20 Мы можем сочетать функции string и strcat для получения строк, которые могут быть легко скопированы и вставлены в файлы-сценарии или доклады. В следующем примере мы определяем вектор-строку x, который состоит из целых чисел с плавающей запятой. Затем мы используем функцию strcat с пробелом в качестве разделителя для получения чистой строки целых чисел. - - > x = [1 2 3 4 5] x = 1. 2. 3. 4. 5. - - > s t r c a t ( s t r i n g ( x ) , " " ) ans = 1 2 3 4 5 Предыдущая строка может быть напрямую скопирована и вставлена в исходный код или доклад. Давайте рассмотрим задачу разработки функции, которая печатает данные в кон- соли. Предыдущая комбинация функций является эффективным способом формирования компактных сообщений. В следующем примере мы используем функцию mprintf для отоб- ражения содержимого переменной x. Мы используем формат %s, который соответствует строкам. Для того, чтобы получить строку, мы объединяем функции strcat и string. - - > m p r i n t f ( " x =[ %s ]\ n " , s t r c a t ( s t r i n g ( x ) , " " )) x =[1 2 3 4 5] Функция sci2exp преобразует выражение в строку. Это может быть использовано в тех же целях, что и предыдущий метод, основанный на strcat, но форматирование ме- нее гибко. В следующем примере мы используем функцию sci2exp для преобразования матрицы-строки целых чисел в матрицу строк размером 1 × 1. - - > x = [1 2 3 4 5]; - - > str = s c i 2 e x p ( x ) str = [1 ,2 ,3 ,4 ,5] - - > s i z e ( str ) ans = 1. 1. Операторы сравнения, такие как «<» или «>», например, не определены, когда ис- пользуются строки, т. е., команда "a "b" приводит к ошибке. Вместо этого, мы можем использовать функцию strcmp для этих целей. Она возвращает 1, если первый аргумент лексикографически меньше второго, она возвращает 0, если две строки равны или возвра- щает −1, если второй аргумент лексикографически меньше первого. Поведение функции strcmp представлено в следующем примере. - - > s t r c m p ( " a " , " b " ) ans = - 1. - - > s t r c m p ( " a " , " a " ) ans = 0. - - > s t r c m p ( " b " , " a " ) ans = 1. Функции, представленные в таблице 10 позволяют различить различные классы строк, таких как ASCII-символы, цифры, буквы и числа. Например, функция isdigit возвращает матрицу логических значений, где каждый элемент i является истиной, если символ в позиции i строки является цифрой. В следующем 21 примере мы используем функцию isdigit, чтобы проверить, что "0" является цифрой, а "d" — нет. - - > i s d i g i t ( " 0 " ) ans = T - - > i s d i g i t ( " 12 " ) ans = T T - - > i s d i g i t ( " d 3 s 4 " ) ans = F T F T Функция regexp является мощным движком регулярных выражений. Этот компонент был включён в пятой версии Scilab. Он основан на библиотеке PCRE [ 22 ], которая предназна- чена для PERL-совместимости. Шаблон должен быть задан как строка, которая окружена слешами в виде "/x/", где x — регулярное выражение. Далее мы представляем пример использования функции regexp. Символ i в конце регулярного выражения обозначает, что мы не хотим учитывать регистр символов. Первая буква a заставляет выражение соответствовать только строкам, которые начинаются с этой буквы. - - > r e g e x p ( " A X Y Z C " , " / a .*? c / i " ) ans = 1. Регулярные выражения являются чрезвычайно мощным инструментом для манипу- ляций с текстом и данными. Очевидно, что этот документ не может даже оцарапать по- верхность данной темы. Для дополнительной информации о функции regexp пользователь может обратиться к страницам помощи, предоставленных Scilab’ом. Для более глубокого введения читатель может поинтересоваться в [ 20 ] Фридла. Как выразился Дж. Фридл, «ре- гулярные выражения позволяют вам кодировать сложную и изощрённую обработку текста, которую вы не когда не могли и представить себе как закодировать». Упражнение 3.1 представляет практический пример использования функции regexp. 3.2 Многочлены Scilab позволяет управлять одномерными многочленами.Реализация основана на век- торе, содержащем коэффициенты многочлена. На уровне пользователя мы можем управлять матрицей многочленов. Основные операции, такие как сложение, вычитание, умножение и деление, применимы для многочленов. Мы можем, конечно, вычислить значение многочле- на p(x) для отдельного входного значения x. Более того, Scilab может выполнять операции isalphanum проверить, являются ли символы алфавитно-цифровыми isascii проверить, являются ли символы 7-битным US-ASCII-кодом isdigit проверить, являются ли символы цифрами от 0 до 9 isletter проверить, являются ли символы буквами алфавита isnum проверить, являются ли символы числами Рис. 10: Функции, связанные с особым классом строк. 22 более высокого уровня, такие, как вычисление корней, разложение на множители и вычис- ление наибольшего общего делителя или наименьшего общего кратного двух многочленов. Когда мы делим один многочлен на другой многочлен, мы получаем новую структуру дан- ных, представляющую рациональную функцию. В этом разделе мы сделаем краткий обзор данной темы. Многочлены и рациональные типы данных представлены на рис. 11 . Некоторые из наиболее используемых функций, от- носящихся к многочленам, представлены на рис. 12 . Полный список функций, относящихся к многочленам, представлен на рис. 13 polynomial многочлен, определённый своими коэффициентами rational отношение двух многочленов Рис. 11: Типы данных, относящихся к многочленам. poly определяет многочлен horner вычисляет значение многочлена coeff коэффициенты многочлена degree степень многочлена roots корни многочлена factors вещественное разложение полиномов gcd наибольший общий делитель lcm наименьшее общее кратное Рис. 12: Некоторые основные функции, относящиеся к многочленам. bezout clean cmndred coeff coffg colcompr degree denom derivat determ detr diophant factors gcd hermit horner hrmt htrianr invr lcm lcmdiag ldiv numer pdiv pol2des pol2str polfact residu roots rowcompr sfact simp simp_mode sylm systmat Рис. 13: Функции, относящиеся к многочленам. Функция poly позволяет определить многочлены. Есть два способа определить их: с помощью их коэффициентов или с помощью их корней. В следующем примере мы создаём многочлен p(x) = (x−1)(x−2) с помощью функции poly. Корни этого многочлена, очевидно, x = 1 и x = 2 — вот почему первым входным аргументом функции poly является матрица [1 2]. Второй входной аргумент — это символьная строка, используемая для отображения многочлена. - - > p = p o l y ([1 2] , " x " ) p = 2 2 - 3 x + x В следующем примере мы вызываем функцию typeof и проверяем, что переменная p явля- ется многочленом (polynomial). 23 - - > t y p e o f ( p ) ans = p o l y n o m i a l Мы можем также определить многочлен на основе его коэффициентов в порядке воз- растания. В следующем примере мы определяем многочлен q(x) = 1 + 2x. Мы передаём функции poly третий аргумент "coeff", так что она знает, что матрица [1 2] представляет коэффициенты многочлена. - - > q = p o l y ([1 2] , " x " , " c o e f f " ) q = 1 + 2 x Теперь, когда многочлены p и q определены, мы можем выполнять с ними алгебраические операции. В следующем примере мы суммируем, вычитаем, умножаем и делим многочлены p и q. - - > p + q ans = 2 3 - x + x - - >p - q ans = 2 1 - 5 x + x - - > p * q ans = 2 3 2 + x - 5 x + 2 x - - > r = q / p r = 1 + 2 x - - - - - - - - - - 2 2 - 3 x + x Когда мы делим многочлен p на многочлен q, то получаем рациональную функцию r. Это показано в следующем примере. - - > t y p e o f ( r ) ans = r a t i o n a l Для того, чтобы вычислить значение многочлена p(x) для конкретного значения x, мы можем использовать функцию horner. В следующем примере мы определяем многочлен p(x) = (x − 1)(x − 2) и вычисляем его значение для точек x = 0, x = 1, x = 3 и x = 3, представленных матрицей [0 1 2 3]. - - > p = p o l y ([1 2] , " x " ) p = 2 2 - 3 x + x - - > h o r n e r ( p ,[0 1 2 3]) ans = 2. 0. 0. 2. Название функции horner происходит от математика Хорнера (Horner), который разработал алгоритм, используемый в Scilab для вычисления значений многочлена. Этот алгоритм поз- 24 воляет уменьшить число умножений и сложений, требуемых для этих вычислений. (смотри [ 26 ], раздел 4.6.4, "Evaluation of Polynomials"). Если в качестве первого аргумента функции poly квадратная матрица, то она возвра- щает характеристический многочлен, связанный с матрицей. То есть, если A — вещественная квадратная матрица размером n × n, то функция poly может дать многочлен det(A − xI), где I — единичная матрица. Это представлено на следующем примере. - - > A = [1 2;3 4] A = 1. 2. 3. 4. - - > p = po l y ( A , " x " ) p = 2 - 2 - 5 x + x Мы легко можем проверить, что предыдущий результат верен с помощью его матема- тического определения. Во-первых, мы можем вычислить корни многочлена p с помощью функции roots, как в предыдущем примере. Во-вторых мы можем вычислить собственные значения матрицы A с помощью функции spec. - - > r o o t s ( p ) ans = - 0 . 3 7 2 2 8 1 3 5 . 3 7 2 2 8 1 3 - - > s p e c ( A ) ans = - 0 . 3 7 2 2 8 1 3 5 . 3 7 2 2 8 1 3 Есть другой способ получить тот же самый многочлен p. В следующем примере мы определяем многочлен px, который представляем одночлен x. Затем мы используем функ- цию det для вычисления детерминанта матрицы B = A − xI. Мы используем функцию eye для получения единичной матрицы размером 2 × 2. - > px = po l y ([0 1] , " x " , " c o e f f " ) px = x - - > B = A - px * eye () B = 1 - x 2 3 4 - x - - > det ( B ) ans = 2 - 2 - 5 x + x Если мы сравним этот результат с предыдущим, то увидим, что они одинаковы. Мы ви- дим, что функция det определена для многочлена A-px*eye(). Это пример того факта, что множество функций определены для входных аргументов многочлена. |