Representing Polynomials with Classes
You can use classes to define new data types. This example implements a class that represents polynomials. The class stores the coefficients of the polynomial terms in a vector and overrides the default MATLAB® display to show the polynomials as powers of x. Using customized indexing, the class also enables you to evaluate the polynomials at one or more values of x using parentheses indexing syntax.
Class Requirements
The design requirements for the DocPolynom class are:
Value class behavior —Behave like MATLAB numeric variables when copied and passed to functions.
Scalar object behavior — Polynomial objects cannot be concatenated, and polynomial array size must always be (1,1).
Customized indexing behavior — Evaluate a polynomial using parentheses indexing syntax.
p(x)evaluates the polynomial represented by objectpat each value inx.Specialized display — Use the coefficients stored in the polynomial object to display the polynomial as an algebraic expression.
Override addition, subtraction, and multiplication — Adding, subtracting, or multiplying polynomial objects returns the result of the corresponding algebraic operation on the two polynomials.
Double converter — Convert a polynomial object to a
doublearray so it can be used with existing MATLAB functions that accept numeric inputs.
DocPolynom Class Members
The class defines the property coef for storage of the
polynomial coefficients.
DocPolynom Class Properties
Name | Class | Default | Description |
|---|---|---|---|
|
|
| Vector of polynomial coefficients, in order of the highest exponent of x to lowest. |
This table summarizes the methods for the DocPolynom class.
DocPolynom Class Methods
Name | Description |
|---|---|
| Class constructor |
| Converts the |
| Creates a formatted display of the
|
| Defines how MATLAB displays |
| Adds |
| Subtracts |
| Multiplies |
| Evaluates the polynomial for one or more values and returns the
results in an organized list instead of a vector of
|
| Enables evaluation of a polynomial using parentheses indexing
syntax. |
Using the DocPolynom Class
These examples show the basic use of the DocPolynom class.
Create DocPolynom objects to represent f(x) =
x3 − 2x −
5 and f(x) =
2x4 +
3x2 + 2x −
7.
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
Find the roots of the polynomial p1. Use the
double method of the object and pass the result to the roots function.
roots(double(p1))
ans = 2.0946 + 0.0000i -1.0473 + 1.1359i -1.0473 - 1.1359i
Add the two polynomials p1 and p2.
MATLAB calls the plus method defined for the
DocPolynom class when you add two DocPolynom
objects.
p1 + p2
ans = 2*x^4 + x^3 + 3*x^2 - 12
DocPolynom Class Synopsis
| Class Code | Description |
|---|---|
classdef DocPolynom < matlab.mixin.Scalar | Value class that implements a data type for polynomials. The class
inherits from |
properties
coef
end | Vector of polynomial coefficients. |
methods
function obj = DocPolynom(c)
if nargin > 0
if isa(c,'DocPolynom')
obj.coef = c.coef;
else
obj.coef = c(:).';
end
end
end | Class constructor that creates objects using either:
For more information, see The DocPolynom Constructor. |
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; else obj.coef = val(ind(1):end); end end | Set method for
For more information, see Remove Leading Zeros. |
function c = double(obj) c = obj.coef; end | Convert For more information, see Convert DocPolynom Objects to Other Classes. |
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 | Convert |
function disp(obj) c = char(obj); if iscell(c) disp([' ' c{:}]) else disp(c) end end | Overload For more information, see Overload disp for DocPolynom. |
function dispPoly(obj,x) p = char(obj); y = zeros(length(x)); disp(['f(x) = ',p]) for k = 1:length(x) y(k) = polyval(obj.coef,x(k)); disp([' f(',num2str(x(k)),') = ',num2str(y(k))]) end end | Return evaluated polynomial with formatted output. This method
uses For more information, see Display Evaluated Expression. |
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 | Define three arithmetic operators:
For information about this code, see Define Arithmetic Operators. For general information about defining operators, see Operator Overloading. |
methods (Access = protected)
function f = parenReference(obj,indexOp)
n = cell2mat(indexOp(1).Indices);
if numel(indexOp) == 1
f = polyval(obj.coef,n);
else
f = polyval(obj.coef,n).(indexOp(2:end));
end
end
end
end | Customize parentheses reference for For more information, see Redefine Parentheses Indexing. |
The DocPolynom Constructor
This is the DocPolynom class constructor:
function obj = DocPolynom(c) if nargin > 0 if isa(c,'DocPolynom') obj.coef = c.coef; else obj.coef = c(:).'; end end end
Constructor Calling Syntax
The DocPolynom constructor can accept two different input
arguments:
An existing
DocPolynomobject — Calling the constructor with an existingDocPolynomobject as an input argument returns a newDocPolynomobject with the same coefficients as the input argument. Theisafunction checks for this input.Coefficient vector — When the input argument is not a
DocPolynomobject, the constructor attempts to reshape the values into a row vector and assign them to thecoefproperty.The
coefproperty set method restricts property values to doubles. See Remove Leading Zeros for a description of the property set method.
This example uses a vector as the input argument to the
DocPolynom constructor:
p = DocPolynom([1 0 -2 -5]) p = x^3 - 2*x -5
This statement creates an instance of the DocPolynom class with
the specified coefficients. The display of the object shows the equivalent polynomial
using MATLAB language syntax. The DocPolynom class implements
this display using the disp and char class
methods.
Remove Leading Zeros
The DocPolynom class represents polynomials as row vectors
containing coefficients ordered by descending powers. Zeros in the coefficient vector
represent terms that are not in the polynomial. Leading zeros, therefore, can be
ignored when forming the polynomial. In fact, some DocPolynom
class methods use the length of the coefficient vector to determine the degree of the
polynomials, so removing leading zeros from the coefficient vector ensures that the
vector length represents the correct polynomial degree.
The DocPolynom class stores the coefficient vector in a
property that uses a set method to remove leading zeros from the specified
coefficients before setting the property value.
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; else obj.coef = val(ind(1):end); end end
Convert DocPolynom Objects to Other Classes
The DocPolynom class defines two methods to convert
DocPolynom objects to other classes:
double— Converts to the double numeric type so functions can perform mathematical operations on the coefficients.char— Converts to characters used to format output for display in the Command Window.
The Double Converter
The double converter method for the DocPolynom
class returns the coefficient vector:
function c = double(obj) c = obj.coef; end
For the DocPolynom object p,
double returns a vector of class double.
p = DocPolynom([1 0 -2 -5]); c = double(p)
c =
1 0 -2 -5The Character Converter
The char method returns a char vector that
represents the polynomial displayed as powers of x. The
char vector returned is a syntactically correct MATLAB expression.
The char method uses a cell array to collect the
char vector components that make up the displayed polynomial.
The disp method uses the char method to format
the DocPolynom object for display. Users of
DocPolynom objects are not likely to call the
char or disp methods directly, but these
methods enable the DocPolynom class to behave like other data
classes in MATLAB.
Overload disp for DocPolynom
To provide a more useful display of DocPolynom objects, this class
overloads disp in the class definition. This
disp method relies on the char method to
produce a text representation of the polynomial, which it then displays.
The char method returns a cell array or the character
'0' if the coefficients are all zero.
function disp(obj) c = char(obj); if iscell(c) disp([' ' c{:}]) else disp(c) end end
When MATLAB Calls the disp Method
This statement creates a DocPolynom object. Because the
statement is not terminated with a semicolon, the resulting output is displayed on
the command line using the overloaded disp method.
p = DocPolynom([1 0 -2 -5])
p =
x^3 - 2*x - 5
Display Evaluated Expression
The dispPoly method evaluates the polynomial for one or more
values of x. The method loops through the input values of
x and uses the polyval function with the
coef property to evaluate the polynomial.
function dispPoly(obj,x) p = char(obj); y = zeros(length(x)); disp(['f(x) = ',p,]) for k = 1:length(x) y(k) = polyval(obj.coef,x(k)); disp([' f(',num2str(x(k)),') = ',num2str(y(k))]) end end
Create a DocPolynom object p:
p = DocPolynom([1 0 -2 -5])
p = x^3 - 2*x - 5
Evaluate the polynomial at three values of x, [3 5
9]. Instead of returning a vector of values, the method uses function
notation to present the results in an organized list.
dispPoly(p,[3 5 9])
f(x) = x^3 - 2*x - 5 f(3) = 16 f(5) = 110 f(9) = 706
Define Arithmetic Operators
The DocPolynom class implements methods for three arithmetic
operations.
Method and Syntax | Operation |
|---|---|
| Addition |
| Subtraction |
| Matrix multiplication |
The overloaded plus, minus, and
mtimes methods accept argument pairs that include at least one
DocPolynom object.
Define the + Operator
If either p or q is a
DocPolynom object, this expression generates a call to the
plus method overload defined by DocPolynom
unless the other object is of higher precedence.
p + q
This method overloads the plus (+) operator
for the DocPolynom class.
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
The plus method performs these actions:
Ensure that both input arguments are
DocPolynomobjects so that expressions that involve aDocPolynomand adoublework correctly.Access the two coefficient vectors and, if necessary, pad one of them with zeros to make both the same length. The actual addition is simply the vector sum of the two coefficient vectors.
Call the
DocPolynomconstructor to create a properly typed object that is the result of adding the polynomials.
Define the - Operator
The minus operator (-) uses the same
approach as the plus (+) operator. The
minus method computes p -
q. The dominant argument must be a
DocPolynom object.
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
Define the * Operator
The mtimes method computes the product p*q.
The mtimes method implements matrix
multiplication because the multiplication of two polynomials is the convolution
(conv) of their coefficient
vectors:
methods function r = mtimes(obj1,obj2) obj1 = DocPolynom(obj1); obj2 = DocPolynom(obj2); r = DocPolynom(conv(obj1.coef,obj2.coef)); end end
Using the Arithmetic Operators
Create a DocPolynom object.
p = DocPolynom([1 0 -2 -5]);
These two arithmetic operations call the DocPolynom
plus and mtimes methods.
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
Redefine Parentheses Indexing
The DocPolynom class inherits from matlab.mixin.Scalar, which in turn inherits from the modular indexing class
matlab.mixin.indexing.RedefinesParen. Overloading the
parenReference method of RedefinesParen enables users
to evaluate a polynomial represented by a DocPolynom object using
parentheses indexing syntax.
For example, create a DocPolynom object
p.
p = DocPolynom([1 0 -2 -5])
p =
x^3 - 2*x - 5The overloaded parenReference method evaluates the value of the
polynomial at x = 3 and at x = 4 using this
command.
p([3 4])
ans =
16 51
Modular Indexing Implementation Details
The parenReference method handles expressions of the form
p(x), where p is a
DocPolynom object and x contains numeric
inputs. Instead of a traditional MATLAB indexing operation, however, parenReference uses
polyval to evaluate the polynomial using the coefficients
stored in the coef property.
methods (Access = protected)
function f = parenReference(obj,indexOp)
n = cell2mat(indexOp(1).Indices);
if numel(indexOp) == 1
f = polyval(obj.coef,n);
else
f = polyval(obj.coef,n).(indexOp(2:end));
end
end
endThe method performs these steps:
Extract the indexing values from
indexOp, which is an instance of thematlab.indexing.IndexingOperationclass. TheindexOpobject stores them as a cell array, and the method converts them to a numeric array and stores them inn.Calculate the number of indexing operations in the expression.
Evaluate the polynomial at the values in
n. The intended use of this syntax includes one parentheses indexing operation.If the method finds more than one indexing operation, it uses
polyvalto evaluate the polynomial and then forwards the rest of the indexing operations to MATLAB using the forwarding syntax,.(indexOp(2:end)). The class does not support any additional customized indexing operations, so MATLAB returns an error.For example, attempting to evaluate a polynomial object while also using dot indexing to try to access its
coefproperty at the same time errors.p(5).coef(1)
For more information on forwarding operations with modular indexing, see Forward Indexing Operations.Dot indexing is not supported for variables of this type.
Using the modular indexing class in this way means that only parentheses reference operations are customized. Dot access to properties and methods are unaffected and are handled by MATLAB as expected.
Note
The matlab.mixin.Scalar and matlab.mixin.indexing.RedefinesParen functionality was introduced in
R2021b.
