how to add method to extend built-in class

25 views (last 30 days)
Erik Johnson
Erik Johnson on 7 May 2013
Commented: Jan Siegmund on 23 Apr 2020
Prior to R2008a, it was possible to extend a class and a new method by just creating, somewhere in the path, the file @classname/methodname.m. Starting with R2008a, this still works ONLY if the class is defined using the older formulation; for classes defined using the newer classdef introduced in R2008a, how can I add a new method for a standard class (e.g., ss or sym) (without the complications introduced by subclassing)?
For example, if x and y are symbolic values, the minimum of the two can be written x*heaviside(y-x)+y*heaviside(x-y). I had a pre-R2008a function @sym/min.m that (in its simplest implementation) had:
function out = min(x,y)
out = heaviside(y-x).*x + heaviside(x-y).*y;
% a more complicated version handled matrix inputs,
% the dimension over which to minimize, and so forth
My @sym method directory could live anywhere on my path. Once the sym class was implemented with classdef, this no longer worked (consistent with the documentation at http://www.mathworks.com/help/matlab/matlab_oop/organizing-classes-in-folders.html). (Though, strangely, MATLAB's help command still sees methods in my @sym folder.)
The only solution I can find is to define, earlier on the path, a file min.m that uses an if isa(...) formulation to use my min code if one of the arguments is symbolic, and the built-in min otherwise -- something like:
function [varargout] = min(varargin)
varargout = cell(1,max(1,nargout));
if nargin==2 && (isa(varargin{1},'sym') || isa(varargin{2},'sym'))
x = varargin{1};
y = varargin{2};
varargout{1} = heaviside(y-x).*x + heaviside(x-y).*y;
else
[varargout{:}] = builtin('min',varargin{:});
end;
This seems like an overly-complicated solution, and it gives constant messages: Warning: Function /Users/username/matlab/min.m has the same name as a MATLAB builtin. We suggest you rename the function to avoid a potential name conflict.
An alternate idea was to move my @sym/min.m file into MATLAB's toolbox directory (which would be matlabroot/toolbox/symbolic/symbolic/@sym/min.m in this case); however, MATLAB seems to ignore this file, and this seems like a bad idea in any case.
Subclassing and creating my own symbolic class is possible, but more complicated than necessary for a simple extension like this, and would require recasting every symbolic variable to my subclass before calling the subclassed min method.
What is the alternate solution?
  2 Comments

Sign in to comment.

Answers (1)

Rudy
Rudy on 29 Jul 2014
Since I had no luck trying to find a solution, I had to find one on my own. This is the method I came up with.
The toolbox had three new method for the zpk class. I created a new class, called sdzpk, and declared it to be a subclass of the built in zpk class. Then, wherever any of the new methods were used, I first converted the object to the new class before passing it to the method.
The following code may ilustrate that better:
Class definition file:
classdef sdzpk < zpk & sdlti
methods (Access = public)
function obj = sdzpk(varargin)
% Constructor method. Long code here to perform data validation
% and pass information to the zpk constructor
obj = obj@zpk(args{:});
end
% Existing methods
% This are the old files I inherited. No need to edit them.
tsys = ctranspose(sys);
sys = delay2z(sys);
sysr = minreal(sys,tol);
F = minreals(F,tol);
FP = setpoles(F,p);
F = symmetr(F,type,tol);
F = z2zeta(F,tol);
end
end
At several locations within the toolbox, the function minreals is called. All those calls were replaced with:
minreals(sdzpk(obj))
In that way, I make sure the new class is used and the correct method is applied.
I hope this helps somebody.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by