summa
и входными парамет- рами, которые служат вектор
x
и число элементов
n.
Значение элементов век- тора определены в командном окне (рис. 1.5.4-14).
--> // Загрузка сценария РИС15414и выполнение функцииsumma
-->
--> clear
--> exec('РИС15414.scе');
--> x = [1 2 3 4 5]; n = length(x);
--> s = summa(x, n) // Обращение к функции пользователя summa s =
15.
-->
--> s = sum(x) // Проверка с использованием встроенной функции sum s =
15.
Рис. 1.5.4-14 Функция
summa
, вычисляющей сумму элементов массива, и обращения к функции
summa
и встроенной функции
sum
Количество элементов массива
х
определяется функцией
length
. Кроме обращения к функции
summa
в командном окне предусмотрена проверка ре- зультата вычислений с использованием встроенной функции
sum(x)
В цикле может быть использован оператор
continue
, который передает управление в следующую итерацию цикла, пропуская операторы, которые за- писаны за ним, причем во вложенном цикле он передает управление на следу- ющую итерацию основного цикла. Оператор
break
может использоваться для досрочного прерывания выполнения цикла (например, при отладке участка программы). Как только он встречается в программе, цикл прерывается. При- меры использование
break
и
continue
будут приведены ниже.
Кроме простых регулярных циклов в Scilab имеется возможность орга- низации вложенных циклов. Пример вычисления суммы элементов матрицы
а
, требующий использования вложенных циклов, приведен на рис. 1.5.4-15.
187
--> // Загрузка сценария РИС15415 и выполнение функции vzikl
-->
-->clear
--> a = [1,2,3;4,5,6;7,8,9]; n = 3;
--> exec('РИС15415.sce');
-->
--> s=vzikl(a) s =
45.
Рис. 1.5.4-15 Использование вложенных циклов для вычисления суммы элементов двумерного массива
В регулярных циклах число повторений должно быть определено зара- нее. При этом в одних случаях это число задано явно (константой или вводи- мым значением переменной), а в других случаях его надо предварительно вы- числить.
Возможны и такие случаи, когда число повторений цикла не фиксиру- ется в алгоритме в явном виде, а определяется неявно граничными значениями и шагом изменения некоторых переменных.
Рассмотрим пример реализации функции, которая вычисляет
y(x)=sin(x)
при значениях
x
, изменяющихся на отрезке
[a;b]
с шагом
h
(рис.1.5.4-16).
--> // Загрузка сценария РИС15416 и выполнение функции ziklh
-->
--> clear
--> a = 1; b = 2; h = 0.2; // Исходные данные
188
--> x = [a:h:b] // Формирование массива х
--> exec('РИС15416.sce', 0);
--> [x, y] = ziklh(a, b, h);
--> [x,y]' // Вывод таблицы значений функции y(x)=sin(x) ans =
1. 1.2 1.4 1.6 1.8 2.
0.841471 0.9320391 0.9854497 0.9995736 0.9738476 0.9092974
Рис.1.5.4-16 Вычисление таблицы значений функции
y(x)=sin(x)
Как уже отмечалось, в циклических структурах часто используются опе- раторы, влияющие на их выполнение. Так, в примере рис. 1.5.4-17 показано применение оператора
break
для досрочного прерывания выполнения цикла. В качестве условия досрочного прерывания цикла используется условие
i==5
--> // Пример досрочного прерывания цикла
-->
--> clear
--> for i = 1:10
> if i==5 break, end
> end i =
1. i =
2. i =
3. i =
4. i =
5.
Рис. 1.5.4-17 Прерывание программы с применением оператора
break
Оператор
continue
, прерывая цикл, передает управление в следующую итерацию цикла, пропуская операторы, которые записаны за ним, причем во вложенном цикле он передает управление на следующую итерацию основного цикла. На рис.1.5.4-18 приведен пример вычисления суммы и произведения положительных элементов матрицы
b(3,3)
189
--> // Пример использования оператора continue
--> // Загрузка сценария РИС15418 и выполнение функции prer
--> clear
--> b = [3 6 -1; -3 5 6 ; 2 -2 4];
--> n = 3;
--> exec('РИС15418.sce');
-->
--> [s, p] = prer(a, n) p =
362880. s =
4.
Рис. 1.5.4-18 Прерывание выполнения цикла с применением оператора
continue
Оператор
return
обеспечивает нормальный возврат в вызывающую функцию и в режим работы с клавиатурой. Пример применения оператора
return
представлен на рис. 1.5.4-19.
--> // Пример использования оператора return
--> // Загрузка сценария РИС15419 выполнение функции det
--> clear
-->
--> A = [];
--> det(A) ans =
1.
-->
--> A = [1];
--> det(A)
Неопределённая переменная 'd' в функции 'det'.
Рис. 1.5.4-19 Применение оператора
return
190
В данном примере показано, что если матрица
A
пустая, то будет выве- дено значение
1
, иначе, система выводит сообщение:
«
Неопределённая переменная 'd' в функции 'det'»
Базовые алгоритмы регулярной циклической структуры позволяют опи- сать широкий класс задач: формирования значений массивов, вычисление зна-
чений функций от одной и более переменных с заданным диапазоном и шагом
их изменения; вычисление конечных сумм и произведений значений величин;
ввод, формирование, обработка и вывод элементов массива и многие другие.
Рассмотрим несколько простых примеров, реализующие базовые алго- ритмы разветвляющих структур.
При заданных числа х
b
1
,b
2
,…,b
n
, требуется вычислить их сумму:
f(b
1
)+f(b
2
)+…+f(b
n
),
где
2
x ,если
хкратно 3 м;
f (x)
х,еслихпри делениина 3 даетостаток1;
x / 3
востальныхслучаях.
Программная реализация задачи приведена на рис.1.5.4-20. Для решения поставленной задачи создадим функцию
fb(x)
, которая реализует алгоритм вычисления значения
y=f(x)
.
Функция имеет один входной параметр –
х
, кото- рый при обращении к функции принимает текущее значение элемента массива
b(i)
,
и один выходной параметр
y
. Обращение к функции происходит в цикле, организованном для вычисления суммы значений
fb(x)
191
--> // Загрузка сценария РИС15420 и выполнение функции fb, реализующей
--> // вложенное разветвление и вычисление суммы элементов массива
--> clear
--> b =
[
3546961012
]
;
--> exec ('
РИС15420
.sce'); s =
409.66667
Рис. 1.5.4-20. Вычисление сумы элементов массива, используя функцию
fb
Для вычисления суммы значений функции fb(х)
создан сценарий
РИС15420
, в котором сначала описывается функция fb(х),
а затем задаются ко- личество чисел (
n=10
) и вектор их значений (
b
), и организован регулярный цикл для обращения в функции (
fb
)
для вычисления суммы.
Перед решением задачи созданный сценарий
РИС15420
, следует загрузить с использованием команды
exec
, а затем запустить его на выполнение из
Командного окна.
Сформировать из произвольных чисел матрицу
а(3,4)
. Вычислить и
вывести вектор
b
, каждый элемент которого есть среднее арифметиче-
ское элементов соответствующей строки матрицы
а
(рис. 1.5.4-21).
На рис. 1.5.4-21 приведен сценарий с именем
РИС15421
, где определена матрица
а
, состоящая из
3-
х строк и
4
-х столбцов и организован цикл по ко- личеству формируемых элементов матрицы
b
путем обращения к вспомога- тельной функции
sred_ar
. В самой функции
sred_ar
реализован базовый алго- ритм вычисления среднего арифметического значений элементов матрицы. В данном случае под вектором понимается
i
-я строка матрицы
а
Алгоритм за- ключается в вычислении суммы нужных элементов, реализованный в регуляр- ном цикле, с последующим делением на количество просуммированных зна- чений, то есть на количество элементов в строке (
m
).
192
--> //
Загрузка и выполнение сценария РИС15421c встроенной функцией sred_ar
-->
--> b =
[
-1256; 0.60.10.50.55; 12.36.7248
]
;
--> exec('РИС15421.sce', 0);
--> a' ans =
3. 0.4375 7.755
Рис. 1.5.4-21 Сценарий формирования матрицы
a
,вычисления среднего арифметического значения элементов матрицы и результаты его работы
Создать функцию, которая вычисляет сумму положительных зна-
чений элементов матрицы
b,
при
b(i,j)>0
.
На рис. 1.5.4-22 приведено решение задачи, а затем пример вычисления суммы элементов вектора и матрицы с использованием стандартной функции
sum
. В данном примере элементы матрицы заданы положительными значени- ями специально, чтобы проверить на совпадение результаты работы созданной функции
sumf
и встроенной функции
sum
-->
//
Загрузка сценария РИС15422и выполнение функции Sumf,
--> // вычисляющей сумму положительных элементов массиваB
-->
--> clear
--> exec('РИС15422.sce', 0);
--> B = [1 2 3; 4 5 6];
-->
--> s1 = Sumf(B) s1 =
21.
-->
--> s1 = sum(B) s1 =
21.
Рис. 1.5.4-22 Вычисление суммы положительных элементов матрицы с использованием функции пользователя
Sumf
и встроенной функции
sum
193
Создать функцию,
которая формирует из чисел матрицы A размером 3x4 одномерный вектор, каждый элемент которого есть сумма элементов соответствующих столбцов матрицы A. Решение задачи с использованием функции
Summ, вычисляющей суммы элементов в столбцах матрицы
А(3,4), и формирующий из них элементы век- тора
Х(4).
Вызов функции и результаты выполнения приведено на рис. 1.5.4-23.
--> //
Загрузка сценария РИС15423и выполнение функции Summ, --> //
которая формирует массивbиз сумм элементов в столбцах массива А -->
--> clear
--> A = [1 3 4 5; 4 7 8 9; 9 8 7 6];
--> exec('РИС15423.sce', 0);
--> X = Summ(A);
-->
--> X'
X =
14. 18. 19. 20.
Рис. 1.5.4-23 Программа формирования элементов массива
Х равным суммам элементов соответствующих столбцов массива
АКроме алгоритмов, представленных в приведенных выше примерах, к базовым алгоритмам обработки массивов можно отнести алгоритмы: форми- рования элементов массива, нахождения количества элементов матрицы при заданном условии, нахождения суммы и произведения значений элементов матрицы при заданном условии, обмен элементов столбцов или строк мат- рицы, доступ к элементам массива и многие другие.
194
Итеративные циклические структуры и while
Общий вид итеративной циклической структуры с предусловием
while…end
можно представить следующим образом:
While ЛогическоеВыражение
…
Операторы
…
end
Отличительной особенностью этой структуры является то, что
Операторы
, расположенные в теле структуры, выполняются только в том случае, если
ЛогическоеВыражение
равно –
%T
(
True
). Как только
ЛогическоеВыражение
становится
%F
(
False
), происходит выход из структуры повторения, и управление переда- ется на инструкцию, расположенную после ключевого слова
end
Рассмотрим простой пример вычисления длины окружности.
Сценарий, сохраненный в файле с именем
РИС15424
, служит для многократного вычисления длины окружности по вводимому пользователем значению ради- уса
r,
где диалог реализован с помощью команды
input
и
disp
. Cтроки, связан- ные с вводом переменной r и вычислением длины окружности, включены в управляющую структуру
while...end
. Это необходимо для циклического по- вторения вычислений при вводе различных значений
r
. Пока
r>0
, цикл повто- ряется. Но стоит задать
r<0
, вычисление длины окружности перестает выпол- няться, а цикл завершается. Поскольку во второй строке программы величина
r
определена равной
0
, цикл выполняется хотя бы один раз.
--> //Загрузка сценария РИС15424и его выполнение
-->
--> clear
--> exec('РИС15424.sce');
Введите окружность радиусом r=4
Длина окружности l =25.132741
Введите окружность радиусом r=-1 r<0
195
Рис. 1.5.4-24 Сценарий, использующий операторы итеративной циклической структуры
При организации цикла с предусловием блоки тела цикла, следующие за блоком, в котором проверяется условие выхода из цикла, выполняются всякий раз, когда логическое выражение принимает значение
True. При первом невы- полнении этого условия происходит выход из цикла. Таким образом, возмо- жен случай, когда тело цикла не будет выполнено ни разу.
При вычислении значений функций или числовых последовательностей
(например, арифметической прогрессии), их часто записывают в виде специ- альных сумм или произведений, называемых рядами. Вычисление суммы чле- нов ряда проводится с использованием итерационных циклических алгорит- мов, которые позволяют вычислять приближенное значение результата с за- данной точностью. При этом для вычисления отдельных слагаемых (или сомножителей), как правило, используются рекуррентные формулы.
Рекуррентная формула – это такая формула, которая позволяет вычис- лить значение
n-го члена последовательности, используя значение одного или нескольких предыдущих членов этой последовательности.
Рассмотрим некоторую последовательность, содержащую бесконечное число членов:
a0,a1,a2,a3,…,ai,…,an,… В таких задачах требуется вычислять члены последовательности до тех пор, пока очередной вычисленный член не будет удовлетворять некоторому условию.
Если задано некоторое число ε, условия окончания итерационного про- цесса могут, например, быть следующими:
an<ε– для убывающей последовательности;
an>ε– для возрастающей последовательности;
|an|<ε– для
убывающей знакопеременной последовательности;
|an+1-an|<ε – для некоторых других типов последовательностей.
При заданной возрастающей последовательности требуется реализовать функцию, которая вычисляет все члены последо-вательности, до тех пор, пока значение очередного члена не превысит не-которое заданное число d, например, (3
).
В нашей задаче для вычисления любого члена последовательности можно воспользоваться формулой
a
n
=x
n
/3
n
, где
n=0,1,2,… –
номер члена.
Во избежание зацикливания, в данном примере цикл будет выполняться не более
100
раз, даже если очередной член последовательности будет оста- ваться меньше
d
(рис. 1.5.4-25).
2
3
2
3
x x
x
1,
,
,
, ... (x 10).
3 3
3
196
--> // Загрузка сценария РИС15425 и выполнение функции
Pos
,
--> // реализующей вычисление членов последовательности
-->
--> clear
--> exec('РИС15425.sce', 0);
--> Pos(5,9) n =
1. a =
3. n =
2. a =
9.
Рис. 1.5.4-25 Вычисление членов последовательности с использованием итеративного цикла
К сожалению, во многих задачах непосредственный подсчет очеред- ного члена связан с вычислительными трудностями. В этом случае целесооб- разно использовать рекуррентную формулу, которая позволяет вычислить значение переменной на следующем шаге, используя ее значение на текущем шаге –
a
n+1
=a
n
q
или
a
n
=a
n-1
q
Вычислить значение функции точностью
ε=0.01
при
х=0.1
, каждый
член которой представляет собой
знакопеременную убывающую последо-
вательность:
Вычисление с заданной точностью
ε
означает, что суммирование членов ряда надо продолжать до тех пор, пока очередной вычисленный член ряда не станет меньше по абсолютной величине числа
ε
(рис.1.5.4-26).
Приведем вывод рекуррентной формулы для заданного в примере ряда.
Формула для
n
-го члена приведена в задании:
2
3
n 1
n
x
1
(x
1)
(x
1)
(x
1)
... ( 1)
...,
1!
2!
3!
(n 1)!
197
n 1
n
n
(x
1)
a
( 1)
,
(n
1)!
тогда формула (
n+1)-го члена
n 1 1
n 2
n 1
n 1
n 1
(x
1)
(x
1)
a
( 1)
( 1)
(n
1
1)!
(n
2)!
Разделив
a
n+1
член на
a
n
, получим выражение для q:
n 1
n 2
n 1
n
n 1
n
a
( 1)
(x
1)
(n
1)!
x
1
q
.
a
(n
2)! ( 1)
(x
1)
n
2
Таким образом, рекуррентная формула для данного ряда:
n 1
n
x
1
a
a
.
n
2
Выбор начального значения номера члена ряда (
n
) для нашего случая бу- дет
n = 0
, так как при подстановке этого значения в формулу
n-
го члена ряда
n 1
n
n
(x
1)
a
( 1)
,
(n
1)!
получим значение первого члена, равного
x-1
или
a
0
=x-1
.
Таким образом, выражение для
q
можно получить, разделив
(n+1)-
й член последовательности на
n-
й.
--> // Загрузка сценария РИС15426и выполнение функции
Pos2
,
--> // реализующей вычисление суммы ряда
-->
--> clear
--> exec('РИС15426.sce', 0);
-->
--> s = Pos2(0.1,0.01) s =
-0.9
Рис. 1.5.4-26 Вычисление суммы ряда c использованием рекуррентной формулы
198
1.5.5. Средства отладки sce-файлов Понятие отладки программ Отладка программ – это процесс выявления места расположения оши- бок и нахождения их причины. В Scilab для этого предусмотрено множество вспомогательных средств
[13].
Рассмотрим некоторые средства отладки
Ре-дактора sce-файлов.
Одним из таких средств является возможность отображать разными цве- тами элементы
sce-файлов (
переменные, операции, константы, операторы, ключевые слова языка программирования, комментарии и т.д.), а также,в соответствии с правилами технологии структурного и процедурного програм- мирования, имеется возможность выравнивания строк программного кода
sce-файлов в зависимости от используемых ключевых слов и управляющих кон- струкций. Одновременно с этими действиями
Редактор может автоматически выполнить
синтаксический контроль программного кода и сигнализировать об этом различными сообщениями и действиями.
Обратите внимание, что семантические (смысловые) ошибки решаемой задачи си-стема отладки Scilab идентифицировать не может! Простейшие программы обычно не нуждаются в использовании специ- альных инструментов отладки. Корректного выполнения программного кода
sce-файла, как правило, можно достичь после нескольких запусков
sce-файла с использованием контрольных (тестовых) входных данных.
Можно также задать просмотр результатов промежуточных вычислений, уда- лив в программном коде символы точки с запятой (;), которыми завершаются инструкции, либо ввести дополнительные переменные для отображения хода вычислений, а после проверки вернуть программный код
sce-файлов его ис- ходному виду.
Если ошибка возникает в процессе выполнения программного кода,
Scilab пытается ее идентифицировать самостоятельно, а затем отображает в
Командном окне сообщение, описывающее приблизительный характер ошибки и номер строки кода, в которой она обнаружена. Если щелкнуть мы- шью на подчеркнутом фрагменте данного сообщения, то соответствующий
sce-файл раскроется в окне
Редактора, и курсор будет указывать на строку с ошибкой.
Однако
Отладчик не всегда правильно отражает реально происходящие процессы. Если вы
имеете дело со сложным программным кодом, то простыми приемами проверки не обойтись. В этом случае полезно воспользоваться спе- циальными инструментами отладки.
Одним из эффективных средств отладки является размещение в тексте программного кода так называемых
Точек останова (Breakpoint), что позво-
199 ляет проводить пошаговое выполнение программного кода, при котором име- ется возможность просмотреть содержимое различных Рабочих областей(то есть получить значения всех переменных, используемых в функциях). Такая отладка может быть выполнена в Scilab c помощью функции
debug
и ее команд отладки в Командном окне.
Обычная последовательность действий при отладке программы заклю- чается в следующем:
1) Подготовка к отладке.
2) Установка (отключение) точек останова.
3) Запуск
sce
-файла и анализ результатов его выполнения.
4) Изменение программного кода
sce
-файла.
5) Устранение проблем и завершение отладки.
Рассмотрим вышеперечисленные действия более подробно.
Отладка сценариев в среде в Scilab debug
Для отладки сценариев используется функция
debug.
Этот режим позво- ляет управлять точками останова, запуском выполнения с остановкой на ошибке, выполнять сценарий по шагам и некоторыми другими действиями.
После ввода команды или функции
debug
, Scilab переходит в режим от- ладки с приглашением
debug>
, и ждет ввода одной из следующих команд:
(h)help
–получение справки отладчика;
(q)quit
– окончание режима отладки и возврат к обычному режиму
Scilab;
(w) where
или
bt
– показ содержимого стека вызовов;
(e)exec
или
(r)run
– запускает на выполнение;
(d) disp Переменная,
или
(p) print Переменная
– вывод на экран значе- ние
Переменной
;
(c) continue
–продолжение выполнения;
(a) abort
–прерывание выполнения;
step(n) next
или
next
– продолжение выполнения до следующего вы- ражения;
step (i) in
или
in
– продолжение выполнения следующего выраже- ния во вложенной функции;
step (o) out
или
out
–продолжение выполнения следующего выраже- ния в вызывающей функции;
(b) breakpointnl
или
breaknl
– остановка функции на строке
n
и по условию
l
, добавление точки останова в функцию на строке
n
, причем если указано условиеl, точка останова добавляется только в том слу- чае, если условием является %
t
;
(del) delete n
– удаление всех точек останова, или если указано зна- чение
n
, то удаляется точка останова с номером
n
;
200
enable n
– включение всех точек останова, или если указано
n
, вклю- чает точку останова с номером
n
;
disable n
– отключение всех точек останова, или если указано
n
, от- ключение точки останова с номером
n
;
(s) show n
– показ всей информации о точках останова, или если за- дано значение
n
, показ точки останова с номером
n.
Рассмотрим несколько примеров (рис. 1.5.5-1).
--> // Загрузка сценария РИС15501 и выполнение функции debug
-->
--> clear
--> exec('РИС15501.sce', 0);
--> // Начало отладки debug break test_debug exectest_debug where stepin disp val continue quit function v=compute(val) v = 1; for i = 1:val v = v * i; end endfunction debug break compute 4 "i == 5" exec compute(10) disp val disp i disp v continue quit
Рис. 1.5.5-1 Пример протокола отладки
201
1.5.6. Хранение данных и функций в библиотеках Файловая система В Scilab реализованы средства для работы с различными типами файлов, но чаще всего текстовые файлы сохраняются с расширениями
*.sce, в них можно хранить как сценарии, так и данные в текстовом виде. Если же пользо- ватель решил создать личную библиотеку, например, для
хранения созданных им внешних функций, то тексты отлаженных функций необходимо сначала со- хранить в файлах с расширением
*.sci, а затем средствами Scilab создать биб- лиотеку двоичных файлов.
Файловая система Scilab может cодержать не только текстовые файлы, двоичные библиотечные файлы и системные папки Scilab, но и папки с фай- лами данных пользователя и папки с программами пользователя. Причем, сле- дует помнить, что с точки зрения значимости системных папок особенное зна- чение для пользователя имеет системная папка
Home, в которой содержатся данные для настройки среды пользователя при загрузке системы Scilab.
Для создания
sci-файлов также используется встроенный в Scilab тек- стовый редактор
SciNotes.
Сохранение и восстановление переменных При решении серьезных задач или задач с большим объемом данных необходимо сохранять данные на диске.
Самый простой способ сохранить значения всех переменных – это со- хранить данные области
Обозревателя переменных (текущие переменные сессии в двоичном файле с расширением
*.sod) [
13
]. Для этого можно исполь- зовать функцию
save. При обращении к ней появляется диалоговое окно
, вко- тором следует указать
Путь к файлу и
Имя файла. По умолчанию предлага- ется сохранить файл в
Текущей папке, при этом всегда целесообразно файлам давать содержательные имена.
Для восстановления сохраненных ранее данных можно использовать функцию
load. При этом следует указать
Путь к файлу. После этого восста- новленные данные можно использовать во вновь вводимых командах.
Команды сохранения и восстановления переменных рабочей среды, можно вызвать из командной строки:
save(ИмяФайла, '
х1'
, '
х2'
,..., '
хп'
) load(ИмяФайла, '
х1'
, '
х2'
,..., '
хп'
), где:
ИмяФайла–символьная строка, содержащая путь к файлу;
х1,х2,...,хп – список сохраняемых или восстанавливаемых перемен- ных, каждая из которых должна быть заключена в одинарные или двойные ка- вычки.
202
Рассмотрим примеры сохранения и загрузки переменных Рабочей
среды (рис. 1.5.6-1).
--> // Пример сохранения и загрузки переменных Рабочей среды
--> a = eye(2, 2); b= ones(a);
--> save('vals.dat', a, b);
--> cleara
--> clearb
--> load('vals.dat', 'a', 'b');
-->
--> // Запись и чтение с использованием двоичного форматаsod
-->
--> a = eye(2, 2); b = ones(a);
--> save("val.sod", "a", "b");
--> clearb
--> load("val.sod", "a", "b");
Рис.1.5.6-1 Пример сохранения и загрузки переменных Рабочей среды
Проверить список сохраненных переменных в файле можно с помощью функции
listvarinfile
, которая имеет следующий формат:
listvarinfile(filename)
[names,typs,dims,vols]=listvarinfile(filename), где:
filename
– символьная строка, путь к файлу для проверки;
names
– матрица строк, показывающая имена переменных, сохраненных в файле;
dims
– матрица, из которого видны размеры переменных, сохраненных в файле;
typs
– числовая матрица, показывающая типы переменных, сохранен- ных в файле;
vols
– числовая матрица, которая представляет размер в байтах пере- менных, сохраненных в файле.
Рассмотрим пример использования функции
listvarinfile
(
рис.1.5.6-2).
--> // Пример использования функции listvarinfile
-->
--> a = eye(2, 2); b = int16(ones(a)); c = rand(2, 3, 3);
-->
--> save(fullfile(TMPDIR, "vals.sod"), 'a', 'b' , 'c')
--> [names, typs, dims, vols] = listvarinfile(fullfile(TMPDIR, "vals.sod")) vols =
203 32.8.144. dims(1)
2. 2. dims(2)
2. 2. dims(3)
2. 3. 3. typs =
1 8. 1. names =
!a !
! !
!b !
! !
!c !
Рис.1.5.6-2 Пример использования функции
listvarinfile
Создание библиотек функций пользователя
Библиотека (library) представляет собой набор функций, объединен- ных некоторой идеей или по функциональному признаку. В системе Scilab простейшая библиотека содержит только функции, написанные средствами языка Scilab, где каждая функция хранится в отдельном файле. В терминах
Scilab такие функции являются макросами [
13
]. Они не содержит файлов справки и функций на компилируемых языках (примитивов).
Объединение функций в библиотеку во многих практических ситуациях является весьма удобным средством использования внешних независимых функций при создании локальных приложений. Более сложной организацией внешних откомпилированных функций, написанных, в том числе, на универ- сальных языках программирования, является модуль.Разработка собствен- ного модуля не представляет трудностей, однако требует более детального знакомства с внутренним устройством пакета Scilab. Кроме того, модули также имеют в своей основе библиотеки, поэтому для создания модулей тре- буется понимание работы библиотек.
К преимуществам библиотеки можно отнести следующее:
библиотека загружается и выгружается целиком, что защищает все функции, входящие в нее.
библиотеки легко обслуживать, так как каждая законченная функция хранится в своем файле.
разрабатывать библиотеку может группа разработчиков, так как функции соединяются воедино только на этапе сборки.
функции библиотеки хранятся в откомпилированном виде и, следо- вательно, выполняются быстрее.
204
Рассмотрим создание простой библиотеки функций Scilab, а также спо- собы ее автоматической загрузки при запуске пакета.
Предположим, что имеется несколько
sci
.файлов, написанных сред- ствами Scilab. Причем в каждом файле хранится одна функция, имя которой совпадает с именем
sci
-файла. Тогда последовательность шагов по созданию библиотеки заключается в следующем:
1) Создать откомпилированные (бинарные файлы с расширением
*.bin
) экземпляры функций, используя функцию
genlib
. Эта функция со- здает библиотеку из функций, описания которых расположены в не- котором каталоге. Кроме того, функция
genlib
создает индексные файлы.
2) Загрузить библиотеку в Scilab, с помощью встроенная функция
lib
Для создания библиотеки функций следует придерживаться следую- щих правил:
Файлы, содержащие определения функций, должны иметь расшире- ние
*.sci
. В одном
sci-
файле могут быть определены несколько функций Scilab, однако только первая из них считается главной и до- ступна извне. Иными словами, только первая функция, определенная в файле, считается общедоступной, в то время как остальные неявно полагаются внутренними функциями;
Имя
sci
-файлов должно совпадать с именем главной функции в этом файле. Например, если имя функции
myfun
, то файл, содержащий ее, должен иметь название
myfun
.
sci
. Это требование является обязатель- ным, в противном случае функция
genlib
не будет работать кор- ректно.
После создания библиотеки в каталоге появятся новые файлы:
bin
-файлы, которые являются скомпилированными версиями функ- ций в
sci
-файлах. Из этих файлов и загружаются функции;
файл
names
– служебный файл, который содержит имена функций библиотеки;
файл с расширением
*.
lib
, который используется сценарием по- грузки и фактически является головой библиотеки.
Далее рассмотрим пример создания библиотеки (рис.1.5.6-3).
Пусть в каталоге
samplelib
размещаются два файла.
--> // Первый файл библиотеки samplelib содержит две функции
--> // C:\samplelib/fuction1.sci:
--> functionу = functionl(х) // Первая функция
> у = 1 * functionl_support(х)
> end
-->
205
--> function у = functionl_support(x) // Вторая функция
> у = 3 * x
> end
--> // Второй файл содержит одну функцию
--> // C:/samplelib/fuction2.sci:
--> function у = function2 (x)
> у = 2 * x
> end
Рис. 1.5.6-3 Файлы с функциями, размещенные в каталоге
samplelib
Создадим бинарную версию функций, воспользовавшись функцией
genlib (
рис. 1.5.6-4
).
Первый аргумент функции
genlib
представляет название будущей библиотеки, а второй указывает каталог, где размещены файлы функ- ций. Заметим, что в данном случае только функции
functionl
и
function2
явля- ются общедоступными, а функция
functionl
_
support
может использоваться только внутри библиотеки, но не вне ее.
--> // Запись файлов в каталог samplelib
--> genlib("mylibrary", "С:/samplelib")
--> mylibrary mylibrary =
Functions files location: С:\samplelib\.functionl function2
Рис.1.5.6-4 Запись файлов в каталог
samplelib
В результате функция
genlib
генерирует и помещает в каталог "
C:/samplelib
" следующие файлы:
functionl.bin
– бинарная версия файла function1.sci;
function2.bin
– бинарная версия файла function2.sci;
lib
– бинарная версия библиотеки;
names
– текстовый файл, содержащий имена всех функций в библиотеке.
Сразу же после вызова
genlib
, две новых функции становятся доступны окружению Scilab и могут быть вызваны, как показано на рис. 1.5.6-5.
--> // Пример обращения
к библиотечным функциям
--> functionl(3) ans =
9.
-->
--> function2(3) ans =
6.
Рис. 1.5.6-5 Обращение к библиотечным функциям из командного окна
206
Вместе с тем, на практике нет необходимости каждый раз генерировать библиотеку заново. Созданную ранее библиотеку можно загрузить посред- ством команды
lib
, единственный аргумент которой указывает местоположе- ние загружаемой библиотеки в файловой системе. Фрагмент на рис. 1.5.6-6 ил- люстрирует загрузку ранее созданной библиотеки.
-
--> // Загрузка файлов в библиотеку
--> mylibrary = lib("С:\samplelib\") ans =
--> functions files location: С:\samplelib\. functionl function2
Рис.1.5.6-6 Загрузка файлов в библиотеку с использованием функции
lib
Использование стартового сценария
При большом числе загружаемых библиотек, удобно поместить ин- струкции
lib
в стартовом сценарии Scilab, который автоматически исполня- ется при загрузке пакета [
13
]. В этом случае все указанные в инструкции
lib
библиотеки будут доступны сразу же после старта Scilab. Файл стартового сценария размещается в основном каталоге Scilab, путь к которому можно узнать, проверив значение переменной
SCIHOME (
рис. 1.5.6-7).
--> // Доступ к стартовому сценарию
--> SCIHOME
SCIHOME =
C:\Users\51FB1\AppData\Roaming\Scilab\scilab-6.0.1
--> // Загрузка созданной библиотеки
--> mylibrary = lib("С:/samplelib/")
Рис. 1.5.6-7 Доступ к стартовому сценарию
Стартовый сценарий имеет имя
scilab
и является обычным сценарием
Scilab (в том числе может содержать комментарии). Для загрузки созданной ранее библиотеки добавим в файл
scilab
следующие строки:
В результате библиотека
mylibrary
будет загружаться всякий раз при старте пакета Scilab.
207
1.5.7. Контрольные вопросы
1)
Какие функциональные структуры используются в Scilab?
2)
Что такое
Примитив
?
3)
Что такое
scе
-сценарий и каковы его особенности?
4)
Каким образом
scе
-сценарий запускается на выполнение?
5)
Что такое
scе
-функция?
6)
В чем отличие файла-сценария от
sce
-функции?
7)
Может ли
scе
-функция иметь несколько выходных параметров?
8)
Как происходит обращение к
sce
-функции?
9)
Для чего используется функция
exec
?
10) Какова структура кода сценария со встроенными функциями?
11) Что такое указатель на функцию?
12) Что такое видимость переменных?
13) Для чего используется переопределение функций?
14) Какие операторы реализуют линейные программные структуры?
15) Какие простейшие операторы ввода/вывода данных известны?
16) Какие операторы реализуют разветвляющиеся программные струк- туры?
17) Какие операторы реализуют регулярные циклические?
18) Какие операторы реализуют итеративные циклические структуры?
19) Какие имеются средства отладки
sce
-файлов?
20) Что представляет собой файловая системаScilab?
208
Приложение
Приложение 1.2
Системные встроенные функции. Таблица 1.2.1-1
Имя функции
Назначение
whos
whos()
whos -typeТип
whos -nameИмя
Отображает переменные в длинной форм
е
Отображает все текущие имена переменных (без учета регистра), типам и ис- пользуемой памяти.
Отображает все текущие переменные с указанным типом Тип, где
Тип –
текстовая строка, кодирующая тип данных.
Отображает все текущие переменные, имена которых начинаются Имя, где Имя
–
имена искомых переменных, либо их начальные фрагменты.
who
who()
who('local')
who('get')
who('global')
who('sorted')
Отображает переменные
Отображается текущие имена переменных и констант.
Отображается имена локальных переменных и параметры память, используемые в данных двойной точности.
Отображается имена глобальных переменных и параметры память, используе- мые в данных двойной точности.
Отображается имена всех переменных(если переменная является глобаль- ной, * появляется после имени типа).
сlear
clear('a','b',..)
Удаление из памяти объектов и
освобождение имен переменных
Удаляются все незащищенные объекты и освобождаются имена текущей сессии
Удаляются указанные незащищенные объекты и освобождаются имена текущей сессии
predef()
predef('a')
predef('с')
predef('Список')
Защищает переменные
Возвращается количество защищенных переменных.
Защищаются все переменные из списка
who('get').
Снимается защита со всех переменных списка
who('get').
Отображается
Список
защищенных переменных.
xists('Имя')
exists('Имя',
'l'
)
exists('Имя',
'
n')
exists('Имя',
'a'
)
Проверяет существование объекта с указанным им
енем
Если объект заданного типа существует, то возвращается
T
, в противном случае
F
, где
'l'
– локальный,
'n'
– нелокальный,
'a
' – все в
() (
по умолчанию).
209
Функции, позволяющие получить номера и названия типов объектов. Таблица 1.2.1-2
НомерТипаОбъекта = type(Oбъект) – Возвращает номер типа объекта.
НазваниеТипаОбъекта = typeof(Oбъект) – Возвращает названия типа объекта.
№
Типа
Название Типа
Примеры
1
Вещественные или комплекс- ные значения двойной точно- сти (double) type(42) type(%nan) type(%inf) type(1 + %i)
2
Полиномиальный
(
polynomial) type(1 - %z + %z^2)
4
Логический (boolean) type(%t)
8
Целочисленный (integer): хранятся в 1 (int8), 2
(
int16), 4 (int32) или 8
(
int64) байтах g = int8([1 - 120127312]) type(g) type(1.23 * int8(4))
9
Графические дескрипторы
(указатели) type(gdf())
10
Символьный(string) type("Текст") type('Текст')
13
Компилированные функции (function) deff('[y] = f(x)',['a = 3 * x + 1']); type(f)
14
Библиотеки функций
(
li-
brary)
15
Простые списки (list) l = list(1,["a" "b"]); type(l)
16
Типизированные списки
(
tlist)
e = tlist(["lt","f1","f2"], [], []); type(e)
17
Матрично-ориентированные типизированные списки
(
mlist)
(
Структуры,Ячейки,
Поли-
номы,Рациональные дроби)
h=mlist(['V','n','v'],['a','b';'c''d'],[12;34]); type(h) clears,s.r=%pi type(s) // структуры c={%t% pi% i%z"abc "s type(c)} //cell-массивы r=[%z/(1 - %z)(1 - %z) / %z^2] type(r) // рациональныедроби
130
Встроенные функции (fptr) type(disp)
210
Функции для работы с комплексными данными. Таблица 1.2.2-2
Функции Назначение Примеры complex(a, b) Создает комплексное число --> complex(5, 9) ans =
5. + 9.i
сonj(a, b) Создает комплексно-со-пряжённое число --> b = complex(5, 9) b =
5. + 9.i
--> conj(b) ans =
5. - 9.i
imag(Z) Выделяет мнимую