Representing Polynomials with Classes - MATLAB & Simulink (original) (raw)
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 objectp
at 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
double
array 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 |
---|---|---|---|
coef | double | [] | 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 |
---|---|
DocPolynom | Class constructor |
double | Converts the DocPolynom object to a double. In other words, this method returns the coefficients in a vector ofdouble values. |
char | Creates a formatted display of theDocPolynom object as powers of_x_. This method is used by thedisp method. |
disp | Defines how MATLAB displays DocPolynom objects on the command line. |
plus | Adds DocPolynom objects. |
minus | Subtracts DocPolynom objects. |
mtimes | Multiplies DocPolynom objects. |
dispPoly | Evaluates the polynomial for one or more values and returns the results in an organized list instead of a vector ofdouble values. |
parenReference | Enables evaluation of a polynomial using parentheses indexing syntax. p(x) evaluates the polynomial objectp at each value inx. |
Using the DocPolynom
Class
These examples show the basic use of the DocPolynom
class. Create DocPolynom
objects to represent f(x) =x_3 − 2_x − 5 and f(x) = 2_x_4 + 3_x_2 + 2_x_ − 7.
p1 = DocPolynom([1 0 -2 -5])
p2 = DocPolynom([2 0 3 2 -7])
p2 = 2x^4 + 3x^2 + 2*x - 7
Find the roots of the polynomial p1
. Use thedouble
method of the object and pass the result to the roots function.
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 theDocPolynom
class when you add two DocPolynom
objects.
ans =
2x^4 + x^3 + 3x^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 matlab.mixin.Scalar, which enforces scalar class behavior and also provides functionality to customize parentheses indexing. For more information on the superclass, see matlab.mixin.Scalar. |
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:An existing DocPolynom objectA vector of doublesFor 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 coef property:Restricts coefficients to type doubleRemoves leading zeros from the coefficient vectorFor more information, see Remove Leading Zeros. |
function c = double(obj) c = obj.coef; end | Convert DocPolynom object todouble by returning the coefficients.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 |
function disp(obj) c = char(obj); if iscell(c) disp([' ' c{:}]) else disp(c) end end | Overload disp function. This method displays objects as output of the char method.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 polyval in a loop to evaluate the polynomial at specified values of the independent variable.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:Polynomial additionPolynomial subtractionPolynomial multiplicationFor information about this code, see Define Arithmetic Operators.For general information about defining operators, seeOperator 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 DocPolynom objects. This implementation of parenReference enables users to evaluate a polynomial using parentheses indexing syntax.p(x) evaluates the polynomial represented by objectp for each value inx.For more information, see Redefine Parentheses Indexing. |
classdef DocPolynom < matlab.mixin.Scalar
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;
else
obj.coef = val(ind(1):end);
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
function disp(obj)
c = char(obj);
if iscell(c)
disp([' ' c{:}])
else
disp(c)
end
end
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
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
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
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
DocPolynom
object — Calling the constructor with an existingDocPolynom
object as an input argument returns a newDocPolynom
object with the same coefficients as the input argument. The isa function checks for this input. - Coefficient vector — When the input argument is not a
DocPolynom
object, the constructor attempts to reshape the values into a row vector and assign them to thecoef
property.
Thecoef
property 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 theDocPolynom
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 convertDocPolynom
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)
The Character Converter
The char
method returns a char
vector that represents the polynomial displayed as powers of x
. Thechar
vector returned is a syntactically correct MATLAB expression.
The char
method uses a cell array to collect thechar
vector components that make up the displayed polynomial. The disp
method uses the char
method to format the DocPolynom
object for display. Users ofDocPolynom
objects are not likely to call thechar
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. Thisdisp
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])
Display Evaluated Expression
The dispPoly
method evaluates the polynomial for one or more values of x
. The method loops through the input values ofx
and uses the polyval
function with thecoef
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])
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.
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 |
---|---|
plus(a,b) | Addition |
minus(a,b) | Subtraction |
mtimes(a,b) | Matrix multiplication |
The overloaded plus
, minus
, andmtimes
methods accept argument pairs that include at least oneDocPolynom
object.
Define the +
Operator
If either p
or q
is aDocPolynom
object, this expression generates a call to theplus
method overload defined by DocPolynom
unless the other object is of higher precedence.
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
DocPolynom
objects so that expressions that involve aDocPolynom
and adouble
work 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
DocPolynom
constructor 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. Theminus
method computes p
-q
. The dominant argument must be aDocPolynom
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 = x^3 - 2*x - 4
r = x^6 - 4x^4 - 9x^3 + 4x^2 + 18x + 20
Redefine Parentheses Indexing
The DocPolynom
class inherits from matlab.mixin.Scalar, which in turn inherits from the modular indexing classmatlab.mixin.indexing.RedefinesParen. Overloading theparenReference
method of RedefinesParen
enables users to evaluate a polynomial represented by a DocPolynom
object using parentheses indexing syntax.
For example, create a DocPolynom
objectp
.
p = DocPolynom([1 0 -2 -5])
The overloaded parenReference
method evaluates the value of the polynomial at x = 3
and at x = 4
using this command.
Modular Indexing Implementation Details
The parenReference
method handles expressions of the formp(x)
, where p
is aDocPolynom
object and x
contains numeric inputs. Instead of a traditional MATLAB indexing operation, however, parenReference
usespolyval
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 end
The method performs these steps:
- Extract the indexing values from
indexOp
, which is an instance of the matlab.indexing.IndexingOperation class. TheindexOp
object 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
polyval
to 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 itscoef
property at the same time errors.
Dot indexing is not supported for variables of this type.
For more information on forwarding operations with modular indexing, see Forward Indexing Operations.
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.