Во многих случаях можно
изменить поведение операторов и функций системы
MATLAB, когда в качестве аргумента выступает объект.
Это осуществляется путем переопределения
соответствующих функций. Переопределение класса
открывает возможность обработки с помощью этой
функции различных типов данных при произвольном
количестве входных аргументов. Переопределение
арифметических операций. Каждый встроенный
оператор в системе MATLAB имеет имя. Поэтому любой
оператор может быть переопределен путем
создания М-файла с соответствующим названием в
каталоге классов. Например, если p или q - полиномы,
то выражение вида p + q задает вызов метода
@polynom/plus.m, если он существует.
В данном случае это M-файл вида:
function r = plus(p, q)
% POLYNOM/PLUS
Реализовать операцию p + q для объектов polynom..
p = polynom(p);
q = polynom(q);
k = length(q.c) - length(p.c);
r = polynom([zeros(1, k) p.c] + [zeros(1, -k) q.c]);
Прежде всего М-функция метода преобразует оба
аргумента входа к классу polynom. Это гарантирует,
что выражения типа p + 1, которые включают как
объект типа polynom, так и объект типа double, будут
вычисляться правильно.
Функция затем обращается к двум векторам
коэффициентов и в случае необходимости,
дополняет один из них с нулями, чтобы выравнять
их длины. Фактическое сложение - просто сумма
двух векторов коэффициентов, к которой
применяется в третий раз конструктор polynom, чтобы
сформировать правильный тип результата.
Другой пример - это метод @polynom/mtimes.m, который
вычисляет произведение полиномов p*q. Буква m в
начале имени функции обусловлена тем, что это
есть переопределение функции умножения матриц.
Умножение двух многочленов - просто свертка их
векторов коэффициентов.
function r = mtimes(p, q)
% POLYNOM/MTIMES Реализует операцию умножения p * q для
объектов
% polynom.
p = polynom(p);
q = polynom(q);
r = polynom(conv(p.c, q.c));
Операторы
q
= p + 1
r =
p*q,
используя описанные функции, дают следующие
результаты
q
= x^3 - 2*x - 4
r =
x^6 - 4*x^4 - 9*x^3 + 4*x^2 + 18*x + 20.
Переопределение операторов. Табл. 8.1
устанавливает символьные имена для большинства
встроенных операторов системы MATLAB’.
Оператор |
Имя М-файла |
Описание |
a + b |
plus(a,b) |
Двоичное сложение |
a - b |
minus(a, b) |
Двоичное вычитание |
-a |
uminus(a) |
Унарное вычитание |
+a |
uplus(a) |
Унарное сложение |
a.*b |
times(a, b) |
Поэлементное умножение |
a*b |
mtimes(a, b) |
Умножение матриц |
a./b |
rdivide(a, b) |
Правое поэлементное деление |
a.\b |
ldivide(a, b) |
Левое поэлементное деление |
a/b |
mrdivide(a, b) |
Правое деление матриц |
a\b |
mldivide(a, b) |
Левое деление матриц |
a.^b |
power(a, b) |
Поэлементное возведение в
степень |
a^b |
mpower(a, b) |
Возведение матрицы в степеннь |
a b |
lt(a, b) |
Меньше |
a b |
gt(a, b) |
Больше |
a = b |
le(a, b) |
Меньше или равно |
a = b |
ge(a, b) |
Больше или равно |
a ~= b |
ne(a, b) |
Не равно |
a == b |
eq(a, b) |
Тождественно |
a & b |
and(a, b) |
Логическое И |
a | b |
or(a, b) |
Логическое ИЛИ |
~a |
not(a, b) |
Логическое НЕТ |
a:d:b
a:b |
colon(a, d, b)
colon(a, b) |
Формирование вектора |
a' |
ctranspose(a) |
Транспонирование матрицы |
a.' |
transpose(a) |
Транспонирование массива |
command window output |
display(a) |
Вывод на терминал |
[a b] |
horzcat(a, b, ...) |
Объединение в строку |
[a; b] |
vertcat(a, b, ...) |
Объединение в столбец |
a(s1,s2,...sn) |
subsref(a, s) |
Индексная ссылка |
a(s1,...,sn) = b |
subsasgn(a, s, b) |
Индексное выражение |
b(a) |
subsindex(a, b) |
Индекс подмассива |
Переопределение функций. Можно
переопределить любую М-функцию, создавая функцию
с тем же именем в каталоге класса. Когда функция
применяется к объекту, MATLAB прежде всего
просматривает каталог соответствующего класса,
а уже потом другие пути доступа. Чтобы
переопределить функцию plot для некоторого класса,
надо просто разместить М-файл plot.m в
соответствующем каталоге класса. Далее
приведено несколько примеров, относящихся к
объектам из класса polynom.
В состав ядра системы MATLAB включены функции для
работы с полиномами, описываемыми векторами их
коэффициентов. При создании новых
полиномиальных объектов эти функции должны быть
переопределены. Во многих случаях
переопределяемая функция может просто применять
исходную функцию к полю соответствующей
структуры.
Например, имеется метод @polynom/roots.m:
function r = roots(p)
% POLYNOM/ROOTS. ROOTS(p) - это вектор, содержащий корни
полинома p.
r = roots(p.c);
Оператор roots(p) дает следующий результат
roots(p)
ans =
2.0946
-1.0473+ 1.1359i
-1.0473- 1.1359i
Функция polyval вычисляет полином для заданного
множества точек.
В данном случае это метод @polynom/polyval.m. Он основан
на методе Горнера.
function
y = polyval(p,x)
%
POLYNOM/POLYVAL POLYVAL(p,x) вычисляет значение полинома p в
точке x.
y =
0;
for a
= p.c
y = y.*x + a;
end
Обе эти функции используются при
переопределении функции plot. Область изменения
независимой переменной выбирается, чтобы быть
немного большей, чем интервал, содержащий все
действительные корни. Затем используется
функция polyval, чтобы вычислить значения полинома в
нескольких сотнях точек области.
Результирующий метод @polynom/plot.m имеет вид: function
plot(p)
% POLYNOM/PLOT
% Функция
PLOT(p) строит график полиномиального объекта p.
r =
max(abs(roots(p)));
x =
(-1.1:.01:1.1)*r;
y = polyval(p,x);
plot(x,y);
title(char(p))
grid on
Наконец, рассмотрим метод @polynom/diff.m, который
позволяет дифференцировать полиномы путем
умножения коэффициентов на соответствующие
степени переменной:
function
q = diff(p)
%
POLYNOM/DIFF
%
Функция DIFF(p) - производная полинома p.
c = p.c;
d =
length(c) - 1; % степень полинома
q =
polynom(p.c(1:d).*(d:-1:1));
Функция methods('polynom') или в форме команды methods polynom
выводит на экран все методы для данного класса в
следующем виде:
methods
polynom
Methods for class polynom:
char
display minus plot polynom roots
diff
double mtimes plus polyval
Большинство этих методов будет вызвано при
выполнении операторов
p
= polynom([1 0 -2 -5]);
plot(diff(p*p + 10*p + 20*x) - 20)
Рис. 8.2
|