Организация циклов
Многие задачи в системе Mathematica решаются с использованием линейных алгоритмов и программ. Они могут быть представлены непрерывной цепочкой выражений, выполняемых последовательно от начала до конца.
Однако в большинстве случаев серьезные вычисления базируются на использовании циклических и разветвленных алгоритмов и программ. При этом, в зависимости от промежуточных или исходных данных, вычисления могут идти по разным ветвям программы, циклически повторяться и т. д. Для реализации разветвленных программ язык программирования должен содержать управляющие структуры, то есть специальные конструкции языка, реализующие в программах ветвление. Они используются при различных методах программирования, в том числе при процедурном и функциональном программировании.
Циклы типа Do
К важнейшим управляющим структурам в языках программирования относятся циклы. С их помощью осуществляется циклическое исполнение некоторого выражения ехрr заданное число раз. Это число нередко определяется значением некоторой управляющей переменной (например, i, j и т. д.), меняющейся либо с шагом +1, либо от начального значения imin до конечного значения imax с шагом di. Циклы могут быть одинарными или множественными — вложенными друг в друга. Последние используют ряд управляющих переменных. Такого рода циклы организуются с помощью функции Do: О Do [expr, {imax} ] — выполняет imax раз вычисление ехрг; О Do [expr, {i, imax}] — вычисляет ехрг с переменной i, последовательно принимающей значения от 1 до imax (с шагом 1);
-
Do [expr, {i, imin, imax} ]—вычисляет ехрr с переменной i, последовательно принимающей значения от imin до imax с шагом 1;
-
Do [expr, {i, imin, imax, di}] — вычисляет ехрг с переменной i, последовательно принимающей значения от 1 до imax с шагом di;
-
Do [expr, {i, imin, imax}, {j, jmin, j max},...] — вычисляет expr, организуя ряд вложенных циклов с управляющими переменными j, i и т. д.
Примеры организации цикла Do и его исполнения представлены ниже:
Do[Print["hello"], {5}]
hello
hello
hello
hello
hello
Do[Print[i], {i, 3}]
1
2
3
Do[Print[i], {i, 5, 8}]
5
6
7
8
Do[Print[i], {i, 0 , 1, 0.25}]
0
0.25
0.5
0.75
1.
Нетрудно убедиться в том, что переменная i в теле цикла (итератор) является локальной и по выходе из цикла ее значение остается тем же, что было до входа:
i=2
2
Do[Print[i], i, 1, 5]
1
2
3
4
5
1
2
Вся программа с циклом является содержанием одной ячейки, и ее листинг охвачен квадратной скобкой. Для иллюстрации вывода здесь использована команда Print в теле цикла. Нетрудно заметить, что управляющая переменная цикла может принимать как целочисленные, так и вещественные значения. Возможность организации цикла в цикле иллюстрируется следующим примером:
Do [Do [Print [i, " ", j, " ", i + j], {j, 1, 3}], {i, 1, 3}];
1 1 2
1 2 3
1 3 4
2 1 3
2 2 4
2 3 5
3 1 4
3 2 5
3 3 6
Здесь используются два цикла с управляющими переменными i и j. Командой Print выводятся значения переменных i и j, а также их суммы i+j.
Следующий пример показывает применение цикла Do для задания функции, вычисляющей п-е число Фибоначчи:
fibonacci[(n_Integer)?Positive] :=
Module[fnl = 1, fn2 =0,
Do[fnl, fn2 = fnl + fn2, fnl, n- 1] ; fnl]
fibonacci[10]
55
fibonacci[100]
354224848179261915075
fibonacci[-10]
fibonacci[-10]
Обратите внимание на применение в этом примере функции Module. Она создает программный модуль с локальными переменными (в нашем случае fnl и fп2), в котором организовано рекуррентное вычисление чисел Фибоначчи.
Наконец, последний пример показывает применение цикла Do для создания цепной дроби:
х = у; Do[x = 1/(1 + k х), {k, 2, 8, 2}]; х
Циклы типа For
Другой вид цикла — цикл For — реализуется одноименной функцией:
For[start, test, incr, body]
В ней сначала один раз вычисляется выражение start, а затем поочередно вычисляются выражения body и incr до тех пор, пока условие test не перестанет давать логическое значение True.
Когда это случится, то есть когда test даст False, цикл заканчивается.
Следующий пример показывает создание простой программы с циклом For и результат ее выполнения:
Print["i x"]
For [x=0; i=0, i < 4, i++
[x += 5*i, Print[i, " ", x]]]
i x
15 ,
2 15
3 30
4 50
Return[x]
Return[50]
Программа, приведенная выше, позволяет наблюдать за изменением значений управляющей переменной цикла i и переменной х, получающей за каждый цикл приращение, равное 5*i. В конце документа показан пример на использование функции возврата значений Return [x]. В цикле For не предусмотрено задание локальных переменных, так что надо следить за назначением переменных — при использовании глобальных переменных неизбежны побочные эффекты.
Циклы типа While
Итак, функция For позволяет создавать циклы, которые завершаются при выполнении (эволюции) какого-либо условия. Такие циклы можно организовать и с помощью функции While [test, expr], которая выполняет expr до тех пор, пока test не перестанет давать логическое значение True.
Ниже дан практический пример организации и использования цикла While:
i := 1; х := 1; Print["i x"] ;
While[i < 5, i += 1; x += 2*i; Print[i, " ", N[x]]]
i x
2 5.
3 11.
4 19.
5 29.
Return[x]
Return[29]
Циклы типа While, в принципе, могут заменить другие, рассмотренные выше, типы циклов. Однако это усложняет запись и понимание программ. Аппарат локальных переменных в этом типе циклов не используется.
Директивы-функции прерывания и продолжения циклов
В указанных типах циклов и в иных управляющих структурах можно использовать следующие директивы-функции:
-
Abort [ ] — вызывает прекращение вычислений с сообщением $ Aborted;
-
Break [ ] — выполняет выход из тела цикла или уровня вложенности программы, содержащего данный оператор (циклы типа Do, For и While или тело оператора-переключателя Switch). Оператор возвращает Null-значение (без генерации секции выхода);
-
Continue [ ] — задает переход на следующий шаг текущего цикла Do, For или While;
-
Interrupt [ ] — прерывает вычисления с возможностью их возобновления;
-
Return [ ] — прерывает выполнение с возвратом значения Null;
-
Return [expr] — прерывает выполнение с выводом значения выражения ехрr;
-
Throw [value] — задает прекращение выполнения цикла Catch, если в ходе эволюции ехрг встречается значение value (см.примеры выше).
На рис. 10.4 представлено применение директив Abort [ ] и Interrupt [ ] в середине набора команд. Нетрудно заметить, что директива Abort [ ] просто прерывает выполнение цепочки команд и выводит сообщение $ Aborted. А вот директива Interrupt [ ] выводит диалоговое окно, с помощью которого можно либо прервать вычисления, либо продолжить их.
Рис. 10.4.
Действие директив Abort[] и lnterrupt[]
Если продолжить вычисления (нажав кнопку Continue Evaluation), то вывод выражений командами Print будет продолжен, что видно из рис. 10.5.
Содержание раздела