Этот пример реализует класс, чтобы представлять полиномы в 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
| Класс Value, который реализует тип данных для полиномов. |
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 | Перегрузка Для получения информации об этом коде смотрите Перегрузка диска для 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
свойство.
The coef
метод набора свойств ограничивает значения свойств двойными. Описание метода набора свойств см. в разделе «Удаление нерелевантных коэффициентов».
Пример использования DocPolynom
конструктор является оператором:
p = DocPolynom([1 0 -2 -5]) p = x^3 - 2*x -5
Этот оператор создает образец DocPolynom
класс с заданными коэффициентами. Обратите внимание, что отображение объекта показывает эквивалентный полином с помощью синтаксиса языка MATLAB. The DocPolynom
класс реализует это отображение с помощью disp
и char
методы классов.
Программное обеспечение MATLAB представляет полиномы как векторы-строки, содержащие коэффициенты, упорядоченные по нисходящим степеням. Нули в векторе коэффициентов представляют условия, которые выпадают из полинома. Ведущие нули, поэтому, могут быть проигнорированы при формировании полинома.
Некоторые DocPolynom
Классы методы используют длину вектора коэффициента, чтобы определить степень полинома. Поэтому полезно удалить начальные нули из вектора коэффициента так, чтобы его длина представляла истинное значение.
The DocPolynom
класс хранит вектор коэффициента в свойстве, которое использует метод set, чтобы удалить начальные нули из заданных коэффициентов перед установкой значения свойства.
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
Объекты другим типамThe 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
The char
метод создает char
вектор, который представляет полином, отображаемый как степени x
. The char
возвращенный вектор является синтаксически правильным выражением MATLAB.
The char
метод использует массив ячеек, чтобы собрать char
векторные компоненты, которые составляют отображаемый полином.
The disp
метод использует char
метод для форматирования DocPolynom
Объект для отображения. The 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
метод для создания текстового представления полинома, который затем отображается на экране.
The char
метод возвращает массив ячеек или символ '0'
если все коэффициенты равны нулю.
methods function disp(obj) c = char(obj); if iscell(c) disp([' ' c{:}]) else disp(c) end end end
disp
МетодДалее оператор:
p = DocPolynom([1 0 -2 -5])
создает DocPolynom
объект. Поскольку оператор не завершен точкой с запятой, результат выхода отображается в командной строке:
p = x^3 - 2*x - 5
The char
метод конвертера формирует выражение MATLAB для полинома, представленного DocPolynom
объект. The 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)
The 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 вызывает этот метод для объектов этого класса всякий раз, когда происходит подписанная ссылка. The subsref
метод должен определять все индексированные модели поведения ссылок, а не только конкретный случай, который вы хотите изменить.
The DocPolynom
subsref
способ реализует следующее поведение:
p(x = [a1...an])
- Вычислите полином в x = a
.
p.coef
- Доступ к coef
значение свойства
p.disp
- Отображать полином как выражение MATLAB, не присваивая выход.
obj = p.method(args)
- Используйте запись через точку для вызова аргументов методов и возврата измененного объекта.
obj = p.method
- Используйте запись через точку для вызова методов без аргументов и возврата измененного объекта.
subsref
Детали реализацииThe 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
структурные поля содержат несколько элементов.
The 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
Несколько арифметических операций значимы для полиномов. The DocPolynom
класс реализует следующие методы:
Метод и синтаксис | Оператор реализован |
---|---|
| Сложение |
| Вычитание |
| Матричное умножение |
При перегрузке арифметических операторов примите во внимание типы данных, которые вы должны поддержать. The plus
, minus
, и mtimes
методы определены для 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
и a double
, работайте правильно.
Получите доступ к двум векторам коэффициентов и, при необходимости, дополните один из них нулями, чтобы сделать оба эти вектора одинаковыми по длине. Фактическое сложение является просто векторной суммой двух векторов коэффициентов.
Вызовите DocPolynom
конструктор, чтобы создать правильно введенный объект, который является результатом добавления полиномов.
-
ОператорРеализуйте minus
оператор (-
) с использованием того же подхода, что и plus
(+
) оператор.
The 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 продукта
. The 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]);
Следующие две арифметические операции вызывают DocPolynom
plus
и 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