В этом примере реализуется класс для представления многочленов на языке 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 | Конструктор класса создает объекты с помощью:
|
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 object - при вызове функции конструктора с входным аргументом, который уже является DocPolynom объект, конструктор возвращает новый DocPolynom с теми же коэффициентами, что и входной аргумент. isa функция проверяет этот ввод.
Входной аргумент является вектором коэффициентов - если входной аргумент не является DocPolynom объект, конструктор пытается изменить форму значений в вектор и назначить их coef собственность.
coef метод набора свойств ограничивает значения свойств двойными значениями. Описание метода набора свойств см. в разделе Удаление неуместных коэффициентов.
Пример использования DocPolynom конструктором является оператор:
p = DocPolynom([1 0 -2 -5]) p = x^3 - 2*x -5
Этот оператор создает экземпляр DocPolynom класс с заданными коэффициентами. Обратите внимание, что при отображении объекта отображается эквивалентный многочлен с использованием синтаксиса языка MATLAB. DocPolynom класс реализует этот дисплей с помощью disp и char методы классов.
Программное обеспечение MATLAB представляет многочлены как векторы строк, содержащие коэффициенты, упорядоченные по степеням убывания. Нули в векторе коэффициентов представляют члены, выпадающие из полинома. Таким образом, ведущие нули могут игнорироваться при формировании многочлена.
Некоторые DocPolynom методы класса используют длину вектора коэффициентов для определения степени многочлена. Поэтому полезно удалить начальные нули из вектора коэффициентов, чтобы его длина представляла истинное значение.
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 Объекты для других типов 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
disp МетодУтверждение:
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 метод должен определять все индексированные варианты поведения ссылок, а не только конкретный случай, который требуется изменить.
DocPolynom subsref метод реализует следующие варианты поведения:
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, и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 и 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]);
Следующие две арифметические операции вызывают 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