exponenta event banner

Представление многочленов классами

Требования к объектам

В этом примере реализуется класс для представления многочленов на языке MATLAB ®. Проектные требования:

  • Поведение класса значений - полиномиальный объект должен вести себя подобно числовым переменным MATLAB при копировании и передаче функциям.

  • Специализированное отображение и индексирование

  • Объекты могут быть только скалярными. Специализация функций отображения и индексирования исключает нормальное поведение массива.

  • Арифметические операции

  • Двойной преобразователь, упрощающий использование полиномиального объекта с существующими функциями MATLAB, принимающими числовые входные данные.

DocPolynom Члены класса

Определение класса задает свойство для хранения данных и определяет папку (@DocPolynom), который содержит определение класса.

В следующей таблице представлены свойства, определенные для DocPolynom класс.

DocPolynom Свойства класса

Имя

Класс

Дефолт

Описание

coef

double

[]

Вектор полиномиальных коэффициентов [высший порядок... самый низкий порядок]

В следующей таблице представлены методы для DocPolynom класс.

DocPolynom Методы классов

Имя

Описание

DocPolynom

Конструктор класса

double

Преобразует DocPolynom объект к двойнику (то есть возвращает его коэффициенты в векторе)

char

Создание форматированного отображения DocPolynom объект как полномочия x и используется disp метод

disp

Определяет способ отображения MATLAB DocPolynom объекты в командной строке

subsref

Позволяет указать значение независимой переменной в виде подстрочного индекса, получить доступ к coef свойство с точечной нотацией и методы вызова с точечной нотацией.

plus

Реализует добавление DocPolynom объекты

minus

Осуществляет вычитание DocPolynom объекты

mtimes

Реализует умножение DocPolynom объекты

Использование 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

Задать метод для coef свойство:

  • Допускает коэффициенты только двойного типа

  • Удаление начальных нулей из вектора коэффициентов.

См. раздел Удаление неуместных коэффициентов

      function c = double(obj)
         c = obj.coef;
      end

Новообращенный DocPolynom объект в double возвращая коэффициенты.

См. раздел Преобразование объектов DocPolynom в другие типы

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

Новообращенный DocPolynom объект в char которое представляет выражение:

y = f (x)

См. раздел Преобразование объектов DocPolynom в другие типы

      function disp(obj)
         c = char(obj);
         if iscell(c)
            disp(['     ' c{:}])
         else
            disp(c)
         end
      end 

Перегрузка disp функция. Экранные объекты как выходные данные char способ.

Сведения об этом коде см. в разделе Устранение перегрузки для 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

Возвращает вычисленное выражение с отформатированным выводом.

Использует выходные данные char способ оценки полинома при заданных значениях независимой переменной.

Сведения об этом коде см. в разделе Отображение вычисляемого выражения

      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

Переопределить индексированную ссылку для DocPolynom объекты.

Дополнительные сведения об этом коде см. в разделе Переопределение индексированной ссылки

      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

end инструкции для methods и для classdef.

 Развернуть для кода класса

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 

Когда MATLAB вызывает 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(a,b)

Дополнение

minus(a,b)

Вычитание

mtimes(a,b)

Умножение матрицы

При перегрузке арифметических операторов следует учитывать типы данных, которые необходимо поддерживать. plus, minus, иmtimes методы определены для DocPolynom класс для обработки сложения, вычитания и умножения DocPolynomDocPolynom и DocPolynomdouble комбинации операндов.

Определить + Оператор

Если либо 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