Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Красавин Компютерныы практикум в среде МатЛаб 2015

.pdf
Скачиваний:
121
Добавлен:
12.11.2022
Размер:
9.22 Mб
Скачать

k = primes(999);

k = sum(k); % суммирование всех элементов вектора k и запись результата в переменную с тем же именем k

disp(k)

Аналогично используется цикл for для вычисления произведений:

k =

1;

 

for

i = 1:10

% вычисление факториала 10

k = k * i;

end

 

 

disp(k)

 

4.2. While

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

while condition operators

end

Выполнение операторов operators внутри этого цикла будет выполняться до тех пор, пока условие цикла condition имеет значение true. Соответственно, операторы operators должны влиять на значение условия цикла и в какой-то момент сделать его равным false, иначе цикл будет длиться бесконечно.

Пример 4.3.

function [fact, i] = factgthigh(high)

% функция factgthigh, находящая наименьшее число i, факториал которого fact больше входного числа high

i = 0; fact = 1;

while fact < high % условие выполнения цикла: факториал fact числа i меньше входного параметра high

i = i + 1;

41

fact = fact * i; end % конец цикла end % конец функции

В результате выполнения функции получаем:

[fact, i] = factgthigh(4000)

fact =

5040

i =

7

Часто при использовании цикла while требуется знать, сколько же раз цикл был проитерирован, прежде чем прерваться. Для этого в цикл нужно поместить счетчик. Счетчик инициализируется до начала цикла нулевыми значением и увеличивается на единицу при каждой итерации:

counter = 0; % инициализация счетчика while condition

counter = counter + 1; operators

end

В качестве условия цикла могут фигурировать и сложные логические конструкции, формируемые логическими операторами ИЛИ (||) и И (&&), например:

while (x >= 0) && (x <= 100)

while (a == b) || (c ~= d) % при проверке условия знак равенства указывается дважды

42

4.3. Конвертация цикла for в цикл while

Любой цикл for может быть переписан в цикл while. Для этого необходимо выполнить три шага:

1)инициализировать переменную цикла;

2)создать условие, которое изначально истинно, но становится ложным, когда необходимо прервать выполнение цикла; часто этим условием является область значений переменной цикла;

3)перед каждой новой итерацией цикла while необходимо изменять переменную цикла.

Пример 4.4 показывает пример конвертации цикла for в цикл while.

Пример 4.4.

% цикл for

for x = 1:2:15 disp(x)

end

% эквивалентный цикл while x = 1; % шаг 1

while (x < 15) % шаг 2 disp(x)

x = x + 2; % шаг 3 end

4.4. Вложенные циклы

Циклы for и while могут размещаться внутри друг друга, такие циклы называются вложенными. Необходимым условием при этом является то, что оператор начала вложенного цикла for или while и оператор окончания этого цикла end должны размещаться между началом и концом цикла, в который они вложены. На рис. 4.1 показана одна из возможных схем вложенных циклов.

Вложенные циклы являются эффективным средством при работе с матрицами, особенно тогда, когда встроенных в MatLab

43

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

Рис. 4.1. Вложенные циклы

Пример 4.5.

for x = 1:3 for y = 1:2

fprintf('x= %.0f and y= %.0f\n',x,y) end

end

Выполнение этой программы приводит к следующемурезультату:

x= 1 and y= 1 x= 1 and y= 2 x= 2 and y= 1 x= 2 and y= 2 x= 3 and y= 1 x= 3 and y= 2

44

Таким образом, переменные внутреннего цикла меняются быстрее переменных внешнего цикла. Команда fprintf в данном случае действует следующим образом: выводит строку x=; далее – первую переменную, стоящую после запятой (т.е. переменную x) по формату %.0f (число с плавающей точкой и нулем знаков после запятой); потом – строку and y= и вторую переменную, стоящую после запятой (т.е. переменную y) по тому же формату; и после этого переходит на новую строку.

В примере 4.6 рассматривается преобразование матрицы в вектор, состоящий из элементов матрицы, взятых построчно.

Пример 4.6.

% дана исходная матрица M

[r, c] = size (M) % оператор size вычисляет размерность аргументамассива; при этом в переменную r заносится число строк массива M, а в переменную c – число столбцов

V = []; % инициализация вектора V в виде пустого множества for col = 1:c % цикл по столбцам

for row = 1:r % цикл по строкам

V(end + 1) = M(row,col); % значение элемента матрицы M,

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

end end disp(V)

Если в качестве матрицы M взять магическую матрицуразмера 4,

M = magic(4)

M =

16

2

3

13

5

11

10

8

9

7

6

12

4

14

15

1

то в результате выполнения программы вектор V будет выглядеть следующим образом:

16

5

9

4

2

11

7

14

3

10

6

15

13

8

12

1

45

4.5. Эффективность

Конструкции циклов for и while являются достаточно простыми по структуре и легкими при программировании. Однако часто они не являются наиболее эффективными с точки зрения времени, затрачиваемого компьютером на их реализацию. Для определения времени, затраченного на выполнение операции или группы операций, в MatLab предусмотрены команды tic и toc. Первая из них включает счетчик времени, вторая – останавливает его. Пример 4.7 демонстрирует, насколько предварительная инициализация массивов, а также использование встроенных функций ускоряет работу программы.

Пример 4.7. В примере рассматриваются три программы, каждая из которых создает вектор длиной 1000000, заполненный единицами.

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

clear; % удаление всех переменных из оперативной памяти tic; % запуск счетчика времени

for j = 1 : 1000000 x(j) = 1;

end

time = toc % прошедшее время в секундах заносится в переменную time

В этом случае получается следующий результат:

time =

0.464753821381304

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

clear; % удаление всех переменных из оперативной памяти tic; % запуск счетчика времени

x = zeros(1,1000000); for j = 1 : 1000000

x(j) = 1;

46

end

time = toc

На том же компьютере вторая программа даст результат, в несколько раз быстрее первой:

time =

0.081696345144139

Теперь получим вектор x, использовав встроенную функцию MatLab:

clear; % удаление всех переменных из оперативной памяти tic; % запуск счетчика времени

x = ones(1,1000000); time = toc

В этом случае расчет еще на порядок быстрее:

time =

0.004765046808881

4.6. Отладка

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

Пример 4.8.

A = 1;

B = 1;

C = A + B;

count = 3; % первые три числа Фибоначчи уже сосчитаны, это A, B, и

С

while (C < 100000)

47

fprintf('A: %.0f, B: %.0f, C: %.0f, count: %.0f \n’, A,B,C,count);

A = B;

B = C;

C = A + B;

count = count + 1; end

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

Задания

4.1. Написать цикл for, который выводит на экран в столбец числа от 0.3 до 2.7 с шагом 0.2. Переписать этот цикл в цикл while.

4.2.При помощи цикла for написать функцию steps2, вычисляющую сумму чисел от 1 до n с шагом 2, где n – аргумент функции. Переписать этот цикл в цикл while.

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

1

24

36 9

48 12 16

510 15 20 25

4.4.Написать программу, вычисляющую приближенное

значение числа

по формуле:

 

1

 

 

1

1

.

 

 

48

 

 

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

4.5. Написать программу, которая выводила бы на экран элементы входного вектора vec в виде предложений. Например, для вектора vec = [3.31 2.3 4.87] результат должен быть таким:

Элемент 1: 3.31 Элемент 2: 2.30 Элемент 3: 4.87

Длина входного вектора vec может быть произвольной.

4.6. Вычислить с использованием циклов сумму из задания 1.4. При помощи операторов tic и toc сравнить время расчета с использованием циклов и с использованием поэлементных операций.

49

5

2D-Графики

5.1. Простой график

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

Простейший график может быть построен при помощи функции plot. Скрипт, представленный в примере 5.1, строит график

функции

 

, задает цвет и стиль линии графика,

определяет

параметры осей и их обозначений, а также добавляет

cos 6

 

легенду на график. Результат выполнения скрипта приведен на рис. 5.1.

Пример 5.1.

function simple_plot

x= linspace(-3,3,300); задание сетки точек, в которых будет рассчитана функция

y= cos(6*x).*exp(-x.^2); расчет значений функции

figure(1) % создание графического окна с номером 1 plot(x,y,'k','LineWidth',2) % построение графика; линия черного цвета толщиной 2

axis([-2.75 2.753 -0.85 1.05]) % установка пределов по осям set(gca, 'LineWidth',1) % толщина линий осей

set(gca, 'FontName', 'Trebuchet MS') % установка шрифта обозначений по осям

set(gca, 'FontSize', 8) % установка размера обозначений по осям set(gca, 'FontWeight', 'bold') % установка полужирного шрифта обозначений по осям

xlabel('x', 'FontName', 'Trebuchet MS', 'FontAngle', 'italic', 'FontSize', 10, 'FontWeight', 'bold') % задание названия оси x и

его стиля

50

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]