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

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


Скачать 1.35 Mb.
НазваниеПрограммирование в Scilab Микаэль Боден Micha
Дата18.09.2022
Размер1.35 Mb.
Формат файлаpdf
Имя файлаprogscilab-v.0.10_ru.pdf
ТипРеферат
#683094
страница4 из 13
1   2   3   4   5   6   7   8   9   ...   13
В предыдущем примере матрица B была матрицей многочленов размером 2 × 2. Таким же образом мы можем определить матрицу рациональной функции, как это показано на следующем примере.
- - > x = p o l y (0 , " x " );
- - > A =[1 x ; x 1+ x ^ 2 ] ;
- - > B = [ 1 / x 1 / ( 1 + x ) ; 1 / ( 1 + x ) 1/ x ^2]
25

B
=
!
1 1
!
! - - - - - -
- - - - - - !
!
x
1 + x
!
!
!
!
1 1
!
!
- - -
- - -
!
!
2
!
!
1 + x x
!
Это очень полезная возможность Scilab’а для теории систем. Связь между типами данных многочленов, рациональных функций с одной стороны и теорией управления с другой крат- ко проанализирована в разделе
3.14 3.3
Гиперматрицы
Матрица — это структура данных, к которым можно получить доступ с помощью двух целочисленных индексов (например, i и j). Гиперматрицы являются более обобщённым ти- пом матриц, к которым можно обратиться с помощью более двух индексов. Эта характе- ристика знакома разработчикам на фортране, где многомерные массивы являются одной из основных структур данных. Несколько функций, имеющих отношение к гиперматрицам,
представлены на рисунке
14
hypermat
Создаёт гиперматрицу zeros
Создаёт гиперматрицу нулей ones
Создаёт гиперматрицу единиц matrix
Создаёт матрицу с новыми размерностями squeeze
Удаление измерений с единичным размером
Рис. 14: Функции, имеющие отношение к гиперматрицам.
В большинстве ситуаций мы можем управлять гиперматрицами как обычными мат- рицами. В следующем примере мы создаём гиперматрицу A размерами 4 × 3 × 2 значений типа double с помощью функции ones. Затем мы используем функцию size для вычисления размеров этой гиперматрицы.
- - > A = o n e s (4 ,3 ,2)
A
=
(: ,: ,1)
1.
1.
1.
1.
1.
1.
1.
1.
1.
1.
1.
1.
(: ,: ,2)
1.
1.
1.
1.
1.
1.
1.
1.
1.
1.
1.
1.
- - > s i z e ( A )
ans
=
4.
3.
2.
26

В следующем примере мы создаём гиперматрицу размерами 4×2×3. Первый аргумент функции hypermat является матрицей, содержащей число измерений гиперматрицы.
- - > A = h y p e r m a t ([4 ,3 ,2])
A
=
(: ,: ,1)
0.
0.
0.
0.
0.
0.
0.
0.
0.
0.
0.
0.
(: ,: ,2)
0.
0.
0.
0.
0.
0.
0.
0.
0.
0.
0.
0.
Чтобы ввести или выделить значение из гиперматрицы, мы можем использовать тот же са- мый синтаксис, что и для матриц. В следующем примере мы установим и получим значение элемента (3,1,2).
- - > A (3 ,1 ,2)=7
A
=
(: ,: ,1)
0.
0.
0.
0.
0.
0.
0.
0.
0.
0.
0.
0.
(: ,: ,2)
0.
0.
0.
0.
0.
0.
7.
0.
0.
0.
0.
0.
- - > A (3 ,1 ,2)
ans
=
7.
Оператор двоеточие «:» может использоваться для гиперматрицы, как это показано в сле- дующем примере.
- - > A (2 ,: ,2)
ans
=
0.
0.
0.
Большинство операций, которые могут быть сделаны с матрицами, могут быть так же сделаны с гиперматрицами. В следующем примере мы определим гиперматрицу B и сложим её с A.
- - > B =2 * o n e s (4 ,3 ,2);
- - > A + B
ans
=
(: ,: ,1)
3.
3.
3.
3.
3.
3.
3.
3.
3.
3.
3.
3.
(: ,: ,2)
3.
3.
3.
3.
3.
3.
3.
3.
3.
27

3.
3.
3.
Функция hypermat может быть использована когда мы хотим создать гиперматрицу из вектора. В следующем примере мы определяем гиперматрицу размерами 2 × 3 × 2, где значения взяты из набора {1, 2, . . . , 12}.
- - > h y p e r m a t ([2 3 2 ] , 1 : 1 2 )
ans
=
(: ,: ,1)
!
1.
3.
5. !
!
2.
4.
6. !
(: ,: ,2)
!
7.
9.
11. !
!
8.
10.
12. !
Заметим особый порядок значений в полученной гиперматрице. Этот порядок соответствует правилу, по которому самые левые индексы перебираются в первую очередь. Это просто следствие того факта, что для двумерной матрицы значения хранятся столбец за столбцом.
Гиперматрица может также содержать строки, как показано в следующем примере.
- - > A = h y p e r m a t ([3 ,1 ,2] ,[ " a " , " b " , " c " , " d " , " e " , " f " ])
A
=
(: ,: ,1)
! a
!
!
!
! b
!
!
!
! c
!
(: ,: ,2)
! d
!
!
!
! e
!
!
!
! f
!
Важным свойством гиперматриц является то, что все элементы должны быть одно- го типа. Например, если мы попытаемся ввести число типа double в гиперматрицу строк,
созданную прежде, то мы получим сообщение об ошибке:
- - > A (1 ,1 ,1)=0
! - - e r r o r 43
Не реализовано в scilab...
at l i n e
8 of f u n c t i o n % s _ i _ c c a l l e d by :
at l i n e
103 of f u n c t i o n g e n e r i c _ i _ h m c a l l e d by :
at l i n e
21 of f u n c t i o n % s _ i _ h m c a l l e d by :
A (1 ,1 ,1)=0 3.4
Типы и размерности выделенной гиперматрицы
В этом разделе мы представляем выделение гиперматрицы у которых одно измерение единичного размера. Мы представляем эффект, который это производит это может иметь на характеристики и описываем функцию squeeze.
Мы можем выделить срезы гиперматрицы, производя различные размерности вы- ходных переменных. Например, давайте рассмотрим трёхмерную гиперматрицу размерами
2 × 4 × 3. Иногда полезно использовать оператор двоеточие : для выделения целых строк
28
или столбцов матрицы или гиперматрицы. Например, команда A(1,:,:) выделяет значения,
связанные с первым индексом, равным 1, и формирует гиперматрицу размерами 1 × 4 × 3.
Похожим образом команда A(:,1,:) выделяет значения, связанные со вторым индексом,
равным 1, и формирует гиперматрицу размерами 2 × 1 × 3. С другой стороны, команда
A(:,:,1) выделяет значения, связанные с третьим индексом, равным 1, но формирует мат- рицу размерами 4 × 3. Следовательно, и тип и форма выделенной гиперматрицы могут измениться, в зависимости от индексов, по которым мы выделяем.
Этот факт исследован на следующем примере.
- - > A = h y p e r m a t ( [ 2 , 4 , 3 ] , [ 1 : 2 4 ] )
A
=
(: ,: ,1)
1.
3.
5.
7.
2.
4.
6.
8.
(: ,: ,2)
9.
11.
13.
15.
10.
12.
14.
16.
(: ,: ,3)
17.
19.
21.
23.
18.
20.
22.
24.
Сначала мы экспериментируем с командой выделения B=A(1,:,:).
- - > B = A (1 ,: ,:)
B
=
(: ,: ,1)
1.
3.
5.
7.
(: ,: ,2)
9.
11.
13.
15.
(: ,: ,3)
17.
19.
21.
23.
- - > t y p e o f ( B )
ans
=
h y p e r m a t
- - > s i z e ( B )
ans
=
1.
4.
3.
Мы могли бы поэкспериментировать с командой B=A(:,1,:) и получить похожее поведение.
Вместо этого, мы поэкспериментируем с командой B=A(:,:,1). Мы видим, что в этом случае выделенная переменная является матрицей вместо гиперматрицы.
- - > B = A (: ,: ,1)
B
=
1.
3.
5.
7.
2.
4.
6.
8.
- - > t y p e o f ( B )
ans
=
c o n s t a n t
- - > s i z e ( B )
ans
=
2.
4.
Общее правило гласит, что, если последнее измерение выделенной гиперматрицы яв- ляется единичным, то оно удаляется. Это правило применимо к результатам выделения,
получающем в конечном счёте либо гиперматрицу, либо обычную двумерную матрицу. Точ- нее, когда мы выделяем гиперматрицу размерами n
1
× . . . × n j
× n j+1
× . . . × n k
, где n j
6= 1 и
29
n
j+1
= n j+2
= . . . = n k
= 1, мы получили гиперматрицу размерами n
1
× n j
. Более того, если выделяемая гиперматрица является обычной, т. е. двумерной матрицей, то есть j
6 2, то вы- деленная переменная является матрицей, а не гиперматрицей. Эти два правила доказывают,
что Scilab совместим с Matlab в выделении гиперматриц.
Такое поведение может иметь существенное влияние на характеристики выделения гиперматриц. В следующем примере мы создаём гиперматрицу 2 × 4 × 3 чисел типа double и измеряем характеристики выделения по второму или третьему индексам. Мы объединяем выделение и команду matrix для того, чтобы получить обычную двумерную матрицу B в обоих случаях. Поскольку это выделение чрезвычайно быстрое, мы сделаем это 100 000 раз в цикле и измерим пользовательское время с помощью функций tic и toc. Мы можем видеть,
что выделение второго измерения гораздо медленнее, чем выделение третьего измерения.
- - > A = h y p e r m a t ([2 ,4 ,3] ,1:24);
- - > B = m a t r i x ( A (: ,2 ,:) ,2 ,3)
B
=
3.
11.
19.
4.
12.
20.
- - > tic (); for i = 1 : 1 0 0 0 0 0 ; B = m a t r i x ( A (: ,2 ,:) ,2 ,3); end ; toc ()
ans
=
7 . 8 3 2
- - > B = m a t r i x ( A (: ,: ,2) ,2 ,4)
B
=
9.
11.
13.
15.
10.
12.
14.
16.
- - > tic (); for i = 1 : 1 0 0 0 0 0 ; B = m a t r i x ( A (: ,: ,2) ,2 ,4); end ; toc ()
ans
=
0 . 8 8
Причина такого различия характеристик в том, что A(:,2,:) — это гиперматрица размером 2 × 1 × 3, а A(:,:,2) — это обычная матрица размером 2 × 4.
В самом деле, команда matrix(A(:,2,:),2,3) заставляет функцию matrix преобразо- вать гиперматрицу A(:,2,:) размерами 2×1×3 в матрицу 2×3, что требует дополнительных шагов от интерпретатора.
С
другой стороны,
команда matrix(A(:,:,2),2,4) не требует какой-либо обработки от функции matrix function, что в этом случае не требует операций.
Мы можем захотеть просто игнорировать промежуточные подматрицы с размером 1,
которые созданы системой выделения подматриц. В этом случае мы можем использовать функцию squeeze, которая удаляет измерения с единичным размером.
- - > A = h y p e r m a t ([3 ,1 ,2] ,1:6)
A
=
(: ,: ,1)
1.
2.
3.
(: ,: ,2)
4.
5.
6.
- - > s i z e ( A )
ans
=
3.
1.
2.
- - > B = s q u e e z e ( A )
B
=
30

1.
4.
2.
5.
3.
6.
- - > s i z e ( B )
ans
=
3.
2.
3.5
Тип данных list (список)
В этом разделе мы опишем тип данных list (список), который используется для управ- ления коллекцией объектов различных типов. Мы очень часто используем списки, когда хотим собрать в один объект набор переменных, которые нельзя сохранить в один, более основной, тип данных. Список может содержать любые уже обсуждённые типы данных
(включая функции), а также другие списки. Это позволяет создавать вложенные списки,
которые могут быть использованы для создания дерева структур данных. Списки чрезвы- чайно полезны для определения объектов структурированных данных. Некоторые функции,
относящиеся к спискам, представлены на рисунке
15
list создать список null удалить элемент списка lstcat конкатенировать списки size для списка число элементов (для списка то же, что и length)
Рис. 15: Функции, относящиеся к спискам.
На самом деле в Scilab’е есть различные типы списков: обычные списки, типизирован- ные списки и mlist. Этот раздел касается обычных списков. Типизированные списки будут рассмотрены в следующем разделе. Тип данных mlist будет рассматриваться в разделе
3.9
В следующем примере мы определяем целые числа с плавающей запятой, строку и матрицу. Затем мы используем функцию list, чтобы создать список mylist, содержащий эти три элемента.
- - > m y f l i n t = 12;
- - > m y s t r = " foo " ;
- - > m y m a t r i x = [1 2 3 4];
- - > m y l i s t = l i s t ( m y f l i n t , m y s t r , m y m a t r i x )
m y l i s t
=
m y l i s t (1)
12.
m y l i s t (2)
foo m y l i s t (3)
1.
2.
3.
4.
Однажды создав, мы можем получить доступ к i-тому элементу списка mylist с помощью команды mylist(i), как в следующем примере.
- - > m y l i s t (1)
ans
=
12.
- > m y l i s t (2)
ans
=
31
foo
- - > m y l i s t (3)
ans
=
1.
2.
3.
4.
Число элементов списка может быть вычислено с помощью size.
- - > s i z e ( m y l i s t )
ans
=
3.
В случае, когда мы хотим получить несколько элементов одной командой, мы можем исполь- зовать оператор двоеточие «:». В этом случае мы должны установить столько выходных ар- гументов, сколько элементов требуется получить. В следующем примере мы получаем два элемента с индексами 2 и 3 и устанавливаем переменные s и m.
- - >[ s , m ] = m y l i s t ( 2 : 3 )
m
=
1.
2.
3.
4.
s
=
foo
Элемент №3 в нашем списке является матрицей. Предположим, что мы хотим получить четвёртое значение в этой матрице. Мы можем иметь доступ к нему непосредственно с помощью следующего синтаксиса.
- - > m y l i s t ( 3 ) ( 4 )
ans
=
4.
Это гораздо быстрее, чем хранение третьего элемента списка во временной переменной и выделение его четвёртого элемента. В случае, если мы хотим установить значение этого элемента, мы можем использовать тот же синтаксис и обычный оператор =, как показано ниже.
- - > m y l i s t ( 3 ) ( 4 ) = 12
m y l i s t
=
m y l i s t (1)
12.
m y l i s t (2)
foo m y l i s t (3)
1.
2.
3.
12.
Очевидно, мы могли бы сделать ту же операцию несколькими промежуточными операция- ми: выделение третьего элемента списка, обновление матрицы и снова хранение матрицы в списке. Но использование команды mylist(3)(4) = 12 действительно проще и быстрее.
Для того, чтобы просматривать элементы списка, мы можем использовать прямой ме- тод или метод, основанный, в частности, на команде for . Сначала используется прямой метод для того, чтобы подсчитать количество элементов в списке с помощью функции size.
Затем мы получаем доступ к элементам одному за другим как показано на следующем при- мере.
for i = 1: si z e ( m y l i s t )
e = m y l i s t ( i );
m p r i n t f ( " E l e m e n t # %d : t y p e = %s .\ n " ,i , t y p e o f ( e ))
end
Предыдущие примеры производят следующий вывод.
32

E l e m e n t #1: t y p e = c o n s t a n t .
E l e m e n t #2: t y p e = s t r i n g .
E l e m e n t #3: t y p e = c o n s t a n t .
Это более простой способ, который использует напрямую список как аргумент команды for.
- - > for e = m y l i s t
- - >
m p r i n t f ( " T y p e = %s .\ n " , t y p e o f ( e ))
- - > end
T y p e = c o n s t a n t .
T y p e = s t r i n g .
T y p e = c o n s t a n t .
Мы можем заполнить список динамически, добавляя новые элементы к концу. В сле- дующем примере мы определяем пустой список с помощью команды list(). Затем, мы используем оператор $+1 для введения новых элементов в конец списка. Это даёт точно такой же список, что и раньше.
m y l i s t = l i s t ();
m y l i s t ( $ +1) = 12;
m y l i s t ( $ +1) = " foo " ;
m y l i s t ( $ +1) = [1 2 3 4];
3.6
Тип данных tlist
Типизированные списки позволяют определять новые структуры данных, которые мо- гут быть настроены в зависимости от конкретных задач, которые необходимо решить. Эти новые структуры данных ведут себя подобно базовым типам данных Scilab’а. В частности,
любая обычная функция, такая как size, disp или string может быть перегружена так,
что у неё будет особое поведение, если её входным аргументом является новый tlist. Это позволяет расширить возможности, предоставляемые Scilab’ом и вводить новые объекты.
На самом деле, типизированный список также используется внутри числовыми функциями
Scilab’а из-за его гибкости. Б´
ольшую часть времени мы даже не знаем, что мы используем список, что показывает насколько этот тип данных удобен.
В этом разделе мы создадим и используем непосредственно tlist для получения близ- кой с ней структуры данных. В следующем разделе мы представим общую схему, которая позволит имитировать объектно-ориентированное программирование с типизированными списками.
Рисунок
16
представляет все функции, относящиеся к типизированным спискам.
tlist создать типизированный список typeof получить тип данного типизированного списка fieldnames вернуть все поля типизированного списка definedfields вернуть все поля, которые определены setfield установить поле типизированного списка getfield получить поле типизированного списка
Рис. 16: Функции, относящиеся к tlist.
Для того, чтобы создать типизированный список, мы используем функцию tlist, чей первый аргумент является матрицей строковых элементов. Первая строка — это тип спис-
33
ка. Остальные строковые элементы определяют поля типизированного списка. В следую- щем разделе мы определим типизированный список person, который позволяет сохранить информацию о человеке. Поля person являются именем, фамилией и годом рождения.
- - > p = t l i s t ([ " p e r s o n " , " f i r s t n a m e " , " n a m e " , " b i r t h y e a r " ])
p
=
p (1)
! p e r s o n f i r s t n a m e n a m e b i r t h y e a r
!
В этом месте создаётся person p, но его поля не определены. Для того, чтобы установить поля p, мы используем точку «.», которая ставится после имени поля. В следующем примере мы определим три поля, связанных с гипотетическим Полом Смитом (Paul Smith), который родился в 1997.
p . f i r s t n a m e = " P a ul " ;
p . n a m e = " S m i t h " ;
p . b i r t h y e a r = 1 9 9 7 ;
Все поля теперь определены и мы можем использовать переменное имя p для того, чтобы увидеть содержимое типизированного списка как в следующем примере.
- - > p p
=
p (1)
! p e r s o n f i r s t n a m e n a m e b i r t h y e a r
!
p (2)
P a u l p (3)
S m i t h p (4)
1 9 9 7 .
Для того, чтобы получить поле типизированного списка, мы можем использовать синтаксис p(i), как в следующем примере.
- - > p (2)
ans
=
P a u l
Но может быть более удобно получать значение поля firstname с помощью синтаксиса p.firstname как показано в следующем примере.
- - > fn = p . f i r s t n a m e fn
=
P a u l
Мы также можем использовать функцию getfield, который принимает в качестве входных аргументов индексы полей и типизированный список.
- > fn = g e t f i e l d (2 , p )
fn
=
P a u l
Тот же синтаксис может быть использован для установки значения поля. В следующем примере мы обновляем значение имени с «Paul» на «John».
- - > p . f i r s t n a m e = " J o h n "
p
=
p (1)
! p e r s o n f i r s t n a m e n a m e b i r t h y e a r
!
34
p (2)
J o h n p (3)
S m i t h p (4)
1 9 9 7 .
Мы также можем использовать функцию setfield для смены поля имени с «John» на
1   2   3   4   5   6   7   8   9   ...   13


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