Этот пример реализует класс, чтобы представлять полиномы на языке MATLAB®. Конструктивные требования:
Поведение класса значения — полиномиальный объект должен вести себя как числовые переменные MATLAB, когда скопировано и передано функциям.
Специализированное отображение и индексация
Объекты могут быть скаляром только. Специализация отображения и функциональности индексации устраняет нормальное поведение массивов.
Арифметические операции
Двойной конвертер, упрощающий использование полиномиального объекта с существующими функциями MATLAB, которые принимают числовые входные параметры.
Члены класса DocPolynom
Определение класса задает свойство для хранения данных и задает папку (@DocPolynom
), который содержит определение класса.
Следующая таблица обобщает свойства, заданные для класса DocPolynom
.
Свойства класса DocPolynom
Имя | Класс | Значение по умолчанию | Описание |
---|---|---|---|
|
|
| Вектор полиномиальных коэффициентов [самый высокий порядок... самый низкоуровневый] |
Следующая таблица обобщает методы для класса DocPolynom
.
Методы класса DocPolynom
Имя | Описание |
---|---|
| Конструктор класса |
| Преобразовывает объект |
| Создает отформатированное отображение объекта |
| Определяет, как MATLAB отображает объекты |
| Позволяет вам задать значение для независимой переменной как индекс, получить доступ к свойству |
| Сложение реализаций объектов |
| Вычитание реализаций объектов |
| Умножение реализаций объектов |
Используя класс DocPolynom
Следующие примеры иллюстрируют основное использование класса DocPolynom
.
Создайте объекты DocPolynom
представлять следующие полиномы. Аргумент к функции конструктора содержит полиномиальные коэффициенты и.
p1 = DocPolynom([1 0 -2 -5])
p1 = x^3 - 2*x - 5
p2 = DocPolynom([2 0 3 2 -7])
p2 = 2*x^4 + 3*x^2 + 2*x - 7
Найдите корни полинома путем передачи коэффициентов функции roots
.
roots(p1.coef)
ans = 2.0946 + 0.0000i -1.0473 + 1.1359i -1.0473 - 1.1359i
Добавьте эти два полинома p1
и p2
.
MATLAB вызывает метод plus
, заданный для класса DocPolynom
, когда вы добавляете два объекта DocPolynom
.
p1 + p2
ans = 2*x^4 + x^3 + 3*x^2 - 12
Резюме класса DocPolynom
Пример кода | Обсуждение |
---|---|
classdef DocPolynom
| Класс значения, который реализует тип данных для полиномов. |
properties coef end | Вектор полиномиальных коэффициентов [самый высокий порядок... самый низкоуровневый] |
methods | Для получения общей информации о методах, см. Обычные Методы |
function obj = DocPolynom(c) if nargin > 0 if isa(c,'DocPolynom') obj.coef = c.coef; else obj.coef = c(:).'; end end end | Конструктор класса создает использование объектов:
Смотрите конструктора DocPolynom |
function obj = set.coef(obj,val) if ~isa(val,'double') error('Coefficients must be doubles') end ind = find(val(:).'~=0); if ~isempty(ind); obj.coef = val(ind(1):end); else obj.coef = val; end end | Метод установки для свойства
|
function c = double(obj) c = obj.coef; end | Преобразуйте объект |
function str = char(obj) if all(obj.coef == 0) s = '0'; str = s; return else d = length(obj.coef)-1; s = cell(1,d); ind = 1; for a = obj.coef; if a ~= 0; if ind ~= 1 if a > 0 s(ind) = {' + '}; ind = ind + 1; else s(ind) = {' - '}; a = -a; ind = ind + 1; end end if a ~= 1 || d == 0 if a == -1 s(ind) = {'-'}; ind = ind + 1; else s(ind) = {num2str(a)}; ind = ind + 1; if d > 0 s(ind) = {'*'}; ind = ind + 1; end end end if d >= 2 s(ind) = {['x^' int2str(d)]}; ind = ind + 1; elseif d == 1 s(ind) = {'x'}; ind = ind + 1; end end d = d - 1; end end str = [s{:}]; end | Преобразуйте объект y = f (x) |
function disp(obj) c = char(obj); if iscell(c) disp([' ' c{:}]) else disp(c) end end | Перегрузка функция Для получения информации об этом коде смотрите Перегрузку disp для DocPolynom |
function dispPoly(obj,x) p = char(obj); e = @(x)eval(p); y = zeros(length(x)); disp(['y = ',p]) for k = 1:length(x) y(k) = e(x(k)); disp([' ',num2str(y(k)),... ' = f(x = ',... num2str(x(k)),')']) end end | Возвратите выполненное выражение с отформатированным выводом. Использование вывод метода Для получения информации об этом коде смотрите Отображение Выполненное Выражение |
function b = subsref(a,s) switch s(1).type case '()' ind = s.subs{:}; b = polyval(a.coef,ind); case '.' switch s(1).subs case 'coef' b = a.coef; case 'disp' disp(a) otherwise if length(s)>1 b = a.(s(1).subs)(s(2).subs{:}); else b = a.(s.subs); end end otherwise error('Specify value for x as obj(x)') end end | Переопределите индексированную ссылку для объектов Для получения информации об этом коде смотрите, Переопределяют Индексируемую Ссылку |
function r = plus(obj1,obj2) obj1 = DocPolynom(obj1); obj2 = DocPolynom(obj2); k = length(obj2.coef) - length(obj1.coef); zp = zeros(1,k); zm = zeros(1,-k); r = DocPolynom([zp,obj1.coef] + [zm,obj2.coef]); end function r = minus(obj1,obj2) obj1 = DocPolynom(obj1); obj2 = DocPolynom(obj2); k = length(obj2.coef) - length(obj1.coef); zp = zeros(1,k); zm = zeros(1,-k); r = DocPolynom([zp,obj1.coef] - [zm,obj2.coef]); end function r = mtimes(obj1,obj2) obj1 = DocPolynom(obj1); obj2 = DocPolynom(obj2); r = DocPolynom(conv(obj1.coef,obj2.coef)); end end | Задайте три арифметических оператора:
Для получения информации об этом коде смотрите, Задают Арифметические операторы. Для получения общей информации об определении операторов, см. Перегрузку операторов |
end end | Операторы |
Конструктор DocPolynom
Следующая функция является конструктором класса DocPolynom
, который находится в файле @DocPolynom/DocPolynom.m
:
methods function obj = DocPolynom(c) if isa(c,'DocPolynom') obj.coef = c.coef; else obj.coef = c(:).'; end end end
Это возможно всему конструктору DocPolynom
с двумя различными аргументами:
Входной параметр является объектом DocPolynom
— Если вы вызываете функцию конструктора с входным параметром, который уже является объектом DocPolynom
, конструктор возвращает новый объект DocPolynom
с теми же коэффициентами как входной параметр. Функция isa
проверяет на этот вход.
Входной параметр является вектором коэффициентов — Если входной параметр не является объектом DocPolynom
, конструктор пытается изменить значения в вектор и присвоить их свойству coef
.
Метод набора свойств coef
ограничивает значения свойств, удваивается. Смотрите Удаляют Несоответствующие Коэффициенты для описания метода набора свойств.
Использование в качестве примера конструктора DocPolynom
является оператором:
p = DocPolynom([1 0 -2 -5]) p = x^3 - 2*x -5
Этот оператор создает экземпляр класса DocPolynom
с заданными коэффициентами. Обратите внимание на то, что отображение объекта показывает эквивалентный полином с помощью синтаксиса языка MATLAB. Класс DocPolynom
реализует это отображение с помощью методов класса char
и disp
.
Программное обеспечение MATLAB представляет полиномы как векторы - строки, содержащие коэффициенты, упорядоченные убывающими степенями. Нули в векторе коэффициентов представляют условия, которые выпадают из полинома. Начальные нули, поэтому, могут быть проигнорированы при формировании полинома.
Некоторые методы класса DocPolynom
используют длину вектора коэффициентов, чтобы определить степень полинома. Полезно, поэтому, удалить начальные нули из вектора коэффициентов так, чтобы его длина представляла истинное значение.
Класс DocPolynom
хранит вектор коэффициентов в свойстве, которое использует метод установки удалить начальные нули из заданных коэффициентов прежде, чем установить значение свойства.
methods function obj = set.coef(obj,val) if ~isa(val,'double') error('Coefficients must be doubles') end ind = find(val(:).'~=0); if ~isempty(ind); obj.coef = val(ind(1):end); else obj.coef = val; end end end
Преобразование объектов DocPolynom в другие типы
Класс DocPolynom
задает два метода, чтобы преобразовать объекты DocPolynom
в другие классы:
'double'
Преобразовывает в двойной числовой тип, таким образом, функции могут выполнить математические операции на коэффициентах.
'char'
Преобразовывает в символы, используемые к формату вывода для отображения в командном окне
Двойной метод конвертера для класса DocPolynom
просто возвращает вектор коэффициентов:
methods function c = double(obj) c = obj.coef; end end
Для объекта DocPolynom
p
:
p = DocPolynom([1 0 -2 -5]);
оператор:
c = double(p)
возвращается:
c= 1 0 -2 -5
который имеет класс double
:
class(c) ans = double
Метод char
производит вектор char
, который представляет полином, отображенный как степени x
. Возвращенный вектор char
является синтаксически правильным выражением MATLAB.
Метод char
использует массив ячеек, чтобы собрать компоненты вектора char
, которые составляют отображенный полином.
Метод disp
использует метод char
, чтобы отформатировать объект DocPolynom
для отображения. Метод evalPoly
использует char
, чтобы создать выражение MATLAB, чтобы оценить.
Пользователи объектов DocPolynom
вряд ли вызовут char
или методы disp
непосредственно, но эти методы позволяют классу DocPolynom
вести себя как другие классы данных в MATLAB.
Вот метод char
.
methods function str = char(obj) if all(obj.coef == 0) s = '0'; str = s; return else d = length(obj.coef)-1; s = cell(1,d); ind = 1; for a = obj.coef; if a ~= 0; if ind ~= 1 if a > 0 s(ind) = {' + '}; ind = ind + 1; else s(ind) = {' - '}; a = -a; ind = ind + 1; end end if a ~= 1 || d == 0 if a == -1 s(ind) = {'-'}; ind = ind + 1; else s(ind) = {num2str(a)}; ind = ind + 1; if d > 0 s(ind) = {'*'}; ind = ind + 1; end end end if d >= 2 s(ind) = {['x^' int2str(d)]}; ind = ind + 1; elseif d == 1 s(ind) = {'x'}; ind = ind + 1; end end d = d - 1; end end str = [s{:}]; end end
Перегрузка disp для DocPolynom
Обеспечить более полезное отображение объектов DocPolynom
, этот класс перегрузки disp
в определении класса.
Этот метод disp
полагается на метод char
, чтобы произвести текстовое представление полинома, который это затем отображает на экране.
Метод char
возвращает массив ячеек или символьный '0'
, если коэффициенты являются всем нулем.
methods function disp(obj) c = char(obj); if iscell(c) disp([' ' c{:}]) else disp(c) end end end
Оператор:
p = DocPolynom([1 0 -2 -5])
создает объект DocPolynom
. Поскольку оператор не отключен с точкой с запятой, получившийся вывод отображен на командной строке:
p = x^3 - 2*x - 5
Метод конвертера char
формирует выражение MATLAB для полинома, представленного объектом DocPolynom
. Метод dispPoly
выполняет выражение, возвращенное методом char
с заданным значением для x
.
methods function dispPoly(obj,x) p = char(obj); e = @(x)eval(p); y = zeros(length(x)); disp(['y = ',p]) for k = 1:length(x) y(k) = e(x(k)); disp([' ',num2str(y(k)),... ' = f(x = ',... num2str(x(k)),')']) end end end
Создайте объект DocPolynom
p
:
p = DocPolynom([1 0 -2 -5])
p = x^3 - 2*x - 5
Оцените полином в x
, равном трем значениям, [3 5 9]
:
dispPoly(p,[3 5 9])
y = x^3 - 2*x - 5 16 = f(x = 3) 110 = f(x = 5) 706 = f(x = 9)
Класс DocPolynom
переопределяет индексированную ссылку, чтобы поддержать использование объектов, представляющих полиномы. В классе DocPolynom
преобразованная в нижний индекс ссылка на объект вызывает оценку полинома со значением независимой переменной, равной индексу.
Например, учитывая следующий полином:
Создайте объект DocPolynom
p
:
p = DocPolynom([1 0 -2 -5])
p = x^3 - 2*x - 5
Следующее преобразованное в нижний индекс выражение оценивает значение полинома в x = 3
и в x = 4
и возвращает получившиеся значения:
p([3 4])
ans = 16 51
Переопределите значение по умолчанию преобразованное в нижний индекс ссылочное поведение путем реализации метода subsref
.
Если класс задает метод subsref
, MATLAB вызывает этот метод для объектов этого класса каждый раз, когда преобразованная в нижний индекс ссылка происходит. Метод subsref
должен задать все индексируемые ссылочные поведения, не только конкретный случай, который вы хотите изменить.
Метод subsref
DocPolynom
реализует следующие поведения:
p(x = [a1...an])
— Оцените полином в x = a
.
p.coef
— Доступ к значению свойства coef
p.disp
— Отобразите полином как выражение MATLAB, не присваивая вывод.
obj = p.method(args)
— Используйте запись через точку, чтобы вызвать аргументы методов и возвратить измененный объект.
obj = p.method
— Используйте запись через точку, чтобы вызвать методы без аргументов и возвратить измененный объект.
детали реализации subsref
Метод subsref
перегружает функцию subsref
.
Например, рассмотрите вызов функции polyval
:
p = DocPolynom([1 0 -2 -5]) p = x^3 - 2*x - 5 polyval(p.coef,[3 5 7]) ans = 16 110 324
Функция polyval
требует:
Полиномиальные коэффициенты
Значения независимой переменной, в которой можно оценить полином
Функция polyval
возвращает значение f(x)
в этих значениях. subsref
вызывает polyval
через операторы:
case '()' ind = s.subs{:}; b = polyval(a.coef,ind);
При реализации subsref
, чтобы поддержать вызов метода с аргументами с помощью записи через точку, и type
и поля структуры subs
содержат несколько элементов.
Метод subsref
реализует всю преобразованную в нижний индекс ссылку явным образом, как показывают в следующем листинге кода.
methods function b = subsref(a,s) switch s(1).type case '()' ind = s.subs{:}; b = polyval(a.coef,ind); case '.' switch s(1).subs case 'coef' b = a.coef; case 'disp' disp(a) otherwise if length(s)>1 b = a.(s(1).subs)(s(2).subs{:}); else b = a.(s.subs); end end otherwise error('Specify value for x as obj(x)') end end end
Несколько арифметических операций значимы на полиномах. Класс DocPolynom
реализует эти методы:
Метод и синтаксис | Реализованный оператор |
---|---|
| Сложение |
| Вычитание |
| Умножение матриц |
При перегрузке арифметических операторов рассмотрите типы данных, которые необходимо поддержать. plus
, minus
, andmtimes
методы заданы для класса DocPolynom
, чтобы обработать сложение, вычитание и умножение на DocPolynom
— DocPolynom
и DocPolynom
— комбинации double
операндов.
Определение + оператор
Если или p
или q
являются объектом DocPolynom
, этим выражением:
p + q
Генерирует вызов функционального @DocPolynom/plus
, если другой объект не имеет более высокого приоритета.
Следующий метод перегружает plus
(+
) оператор для класса DocPolynom
:
methods function r = plus(obj1,obj2) obj1 = DocPolynom(obj1); obj2 = DocPolynom(obj2); k = length(obj2.coef) - length(obj1.coef); zp = zeros(1,k); zm = zeros(1,-k); r = DocPolynom([zp,obj1.coef] + [zm,obj2.coef]); end end
Вот то, как функция работает:
Гарантируйте, что оба входных параметра являются объектами DocPolynom
так, чтобы выражения такой как
p + 1
это включает и DocPolynom
и double
, работает правильно.
Доступ к этим двум векторам коэффициентов и, при необходимости, заполняет одного из них с нулями, чтобы сделать обоих той же длиной. Фактическое сложение является просто векторной суммой этих двух векторов коэффициентов.
Вызовите конструктора DocPolynom
, чтобы создать правильно типизированный объект, который является результатом добавления полиномов.
-
Реализуйте оператор minus
(-
) с помощью того же подхода в качестве plus
(+
) оператор.
Метод minus
вычисляет p
- q
. Доминирующий аргумент должен быть объектом DocPolynom
.
methods function r = minus(obj1,obj2) obj1 = DocPolynom(obj1); obj2 = DocPolynom(obj2); k = length(obj2.coef) - length(obj1.coef); zp = zeros(1,k); zm = zeros(1,-k); r = DocPolynom([zp,obj1.coef] - [zm,obj2.coef]); end end
Определение оператора *
Реализуйте метод mtimes
, чтобы вычислить продукт p*q
. Метод mtimes
реализует умножение матриц, поскольку умножение двух полиномов является сверткой (conv
) их векторов коэффициентов:
methods function r = mtimes(obj1,obj2) obj1 = DocPolynom(obj1); obj2 = DocPolynom(obj2); r = DocPolynom(conv(obj1.coef,obj2.coef)); end end
Учитывая объект DocPolynom
:
p = DocPolynom([1 0 -2 -5]);
Следующие две арифметических операции вызывают plus
DocPolynom
и методы mtimes
:
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