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

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

Этот пример реализует класс, чтобы представлять полиномы в MATLAB® язык. Требования к проектированию:

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

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

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

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

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

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

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

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

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

Имя

Класс

Дефолт

Описание

coef

double

[]

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

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

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

Имя

Описание

DocPolynom

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

double

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

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

Класс 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

Установите метод для coef свойство:

  • Позволяет коэффициенты только типа double

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

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

      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.

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

The 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 

Когда MATLAB вызывает 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 класс реализует следующие методы:

Метод и синтаксис

Оператор реализован

plus(a,b)

Сложение

minus(a,b)

Вычитание

mtimes(a,b)

Матричное умножение

При перегрузке арифметических операторов примите во внимание типы данных, которые вы должны поддержать. The 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 и 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