## 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 object `p` at each value in `x`.

• 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 of `double` values..

`char`

Creates a formatted display of the `DocPolynom` object as powers of x. This method is used by the `disp` 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 of `double` values.

`parenReference`

Enables evaluation of a polynomial using parentheses indexing syntax. `p(x)` evaluates the polynomial object `p` at each value in `x`.

#### 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 CodeDescription
`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` object

• A vector of doubles

``` 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 double

• Removes leading zeros from the coefficient vector

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

Convert `DocPolynom` object to `double` by returning the coefficients.

``` 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 `DocPolynom` object to `char`. For more information, see Convert DocPolynom Objects to Other Classes.

``` 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.

``` 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.

``` 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 subtraction

• Polynomial multiplication

``` 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 object `p` for each value in `x`.

### 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 existing `DocPolynom` object as an input argument returns a new `DocPolynom` 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 the `coef` property.

The `coef` 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 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.

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 -5```

#### The 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

`plus(a,b)`

`minus(a,b)`

Subtraction

`mtimes(a,b)`

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 `DocPolynom` objects so that expressions that involve a `DocPolynom` and a `double` 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. 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 to 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 - 5```

The 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 end```

The method performs these steps:

1. Extract the indexing values from `indexOp`, which is an instance of the `matlab.indexing.IndexingOperation` class. The `indexOp` object stores them as a cell array, and the method converts them to a numeric array and stores them in `n`.

2. Calculate the number of indexing operations in the expression.

3. Evaluate the polynomial at the values in `n`. The intended use of this syntax includes one parentheses indexing operation.

4. 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 its `coef` property at the same time errors.

`p(5).coef(1)`
`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.