Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
практикум по матлабу.pdf
Скачиваний:
150
Добавлен:
29.03.2015
Размер:
1.19 Mб
Скачать

6. M-файлы

MATLAB может выполнять последовательность операторов, записанных в файл на диске. Такие файлы называются m-файлами, потому что имена этих файлов имеют вид <имя>.m. Большая часть вашей работы в MATLAB будет состоять в создании, редактировании и выполнении таких m-файлов. Имеется два типа m- файлов: файлы-программы, или сценарии, и файлы-функции.

6.1. Файлы-программы, или сценарии

Файлы-программы состоят из последовательности обычных операторов MATLAB. Если файл с таким сценарием имеет имя, например, rotate.m, то команда rotate, введенная в командной строке, вызовет выполнение соответствующей последовательности операторов. Переменные в программе являются глобальными и изменят значения таких же переменных (если таковые есть) в рабочей области текущей сессии. Программы или сценарии часто используются для ввода данных в большие матрицы; в таких файлах легко исправить ошибки ввода. Если, например, файл на диске с именем data.m содержит строки

A = [ 1 2 3 4 5 6 7 8 ];

тогда команда data приведет к тому, что написанное выше присвоение будет выполнено. Внутри m-файлов можно ссылаться на другие m-файлы, в том числе и на самого себя рекурсивно.

6.2. Файлы-функции

Файлы-функции фактически дают возможность расширять MATLAB, поскольку определенные вами новые функции, специфические для решения ваших задач, имеют тот же статус, что и другие функции MATLAB. Переменные в функциях являются по умолчанию локальными, но в версиях 4.0 и выше разрешено объявлять требуемые переменные глобальными (global). Для начала рассмотрим простой пример файла-функции.

function r = randint(m,n)

%RANDINT случайная матрица с целыми элементами.

%randint(m,n) возвращает матрицу mxn с целыми

123

% элементами между 0 и 9. a = floor(10*rand(m,n));

Более общая версия такой функции может иметь такой вид:

function r = randint(m,n,a,b)

%RANDINT случайная матрица с целыми элементами.

%randint(m,n) возвращает матрицу mxn с целыми

%элементами между 0 и 9.

%rand(m,n,a,b) возвращает матрицу с целыми

%элементами в диапазоне между целыми a и b.

if nargin < 3, a = 0; b = 9; end

r = floor((b-a+1)*rand(m,n)) + a;

Этот текст должен быть записан на диск в виде файла с именем randint.m (в соответствие с именем функции - это обязательное условие для функции).

Первая строка функции - объявление имени функции, входные аргументы, выходные аргументы. Без такой строки весь следующий файл является программой, или сценарием, а не функцией. Так, например, оператор z = randint(4,5) приведет к передаче чисел 4 и 5 переменным m и n, а выходной результат будет передан переменной z. Поскольку переменные в файле-функции локальные, их имена никак не влияют на имена и значения переменных в текущей рабочей области MATLAB.

Отметим роль функции nargin (число входных аргументов). Использование этой функции в данном примере позволяет установить значение отсутствующих входных аргументов по умолчанию – таких переменных, как a и b в примере. В общем случае наличие такой функции позволяет использовать функции с переменным числом входных аргументов и в зависимости от их числа направлять вычисления по разным логическим веткам функции.

Функция может иметь множественные выходные аргументы. Например

function [mean, stdev] = stat(x)

%STAT Среднее и стандартное отклонение

%Для вектора x, stat(x) возвращает среднее

%значение и стандартное отклонение x.

%Для матрицы x, stat(x) возвращает два

%вектора-строки, содержащие, соответственно,

%среднее и стандартное отклонение каждого

%столбца матрицы x.

[m n] = size(x);

124

if m == 1

m = n; % обработка в случае ввода вектор-строки end

mean = sum(x)/m;

stdev = sqrt(sum(x.^2)/m - mean.^2);

Если этот файл записать на диск под именем stat.m, то команда [xm,xd]=stat(x) присвоит среднее значение элементов x переменной xm, а стандартное отклонение переменной xd. Несмотря на наличие нескольких выходных аргументов, можно присвоить значение функции одной переменной. Например, xm = stat(x) (никаких скобок вокруг xm не требуется) присвоит xm среднее значение x. Символ % указывает на то, что вся строка символов после него является комментарием и игнорируется при исполнении. Тем не менее, несколько первых строк-комментариев, которые являются кратким описанием данной функции, доступны при вводе оператора, т.е. являются той помощью, которая вызывается с помощью команды help stat. Такую документацию всегда следует включать в файл-функцию. Приведенная выше функция демонстрирует некоторые возможности MATLAB, которые позволяют написать эффективный код. Отметим, например, оператор x.ˆ2, который является возведением в степень каждого элемента вектора x, оператор с функцией sum, которая является векторной функцией (п. 5.2), функцию sqrt, которая является скалярной функцией (см. 5.1), и деление в выражении sum(x)/m, которое является матрично-скалярной операцией.

Приведенная далее функция, которая вычисляет наибольший общий делитель двух целых чисел с помощью алгоритма Евклида, иллюстрирует использование функции вывода сообщений об ошибках (см. п. 6.3).

function a = gcd(a,b)

%GCD Наибольший общий делитель.

%gcd(a,b) является наибольшим общим делителем

%целых чисел a и b, оба не равны нулю.

a = round(abs(a)); b = round(abs(b)); if a == 0 & b == 0

error(’gcd не определено, если оба числа равны нулю’) else

while b ~= 0 r = rem(a,b); a = b; b = r; end

end

125

Некоторые дополнительные продвинутые возможности иллюстрируются в следующей функции. Как было отмечено ранее, некоторые входные аргументы функции, например такие, как tol, могут быть сделаны необязательными с помощью функции nargin (число входных аргументов). Аналогично может быть использована функция nargout (число выходных аргументов). Отметим, что используется тот факт, что результатом оператора отношения является число (1 - если истинно и 0 - если ложь). Так, если в операторах while или if используются отношения, то nonzero означает “истина”, а 0 означает “ложь”. Использованная в конце функция feval позволяет в качестве входной переменной использовать строку, содержащую имя другой функции.

function [b, steps] = bisect(fun, x, tol)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%BISECT Нуль функции одной переменной методом

%деления пополам.

%bisect(fun,x) возвращает нуль функции.

%fun - строка, содержащая имя вещественной

%функции одной вещественной переменной;

%обычно эта функция определяется в m-файле.

%x начальное приближение. Возвращается значение

%вблизи точки, в которой fun меняет знак.

%Например, bisect(’sin’,3) равна pi.

%Обратите внимание на кавычки вокруг sin.

%Необязательный третий аргумент определяет

%относительную точность результата. По умолчанию

%эта точность eps.

%Второй выходной аргумент (необязательный)

%содержит протокол процесса;

%строки матрицы имеют вид [c f(c)].

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%Инициализация

if nargin < 3, tol = eps; end trace = (nargout == 2);

if x ~= 0, dx = x/20; else, dx = 1/20; end a = x - dx; fa = feval(fun,a);

b = x + dx; fb = feval(fun,b);

% Поиск изменения знака. while (fa > 0) == (fb > 0)

126