Class constructor that can create either a single object or an object array depending on number of the argument

1 view (last 30 days)
Hey guys,
Thanks in advance for taking your time to read my question!
I'm currently building a class called "secOrdIdentifier" where I'm trying to write a constructor that can create either a single object or an object array depending on number of the argument, and I used IF statement together with varargin as illustrated below.
A common quantity called Lyapunov Function is needed for both cases. I found it no problem if I solve the Lyapunov function under each case (shown as in Version_0). In order to reduce the redundancy of the code, it would be preferred if I can only write it once, so I tried to write it before the IF statement as indicated in Version_1, and I got an error msg when running Version_1:
Index exceeds the number of array elements (0).
Error in secOrdIdentifier (line 22)
A = varargin{1};
Error in secOrdIdentifier (line 41)
obj(1,n) = obj;
and I'm wondering what is the reason and how should I solve it?
PS. In case you want to run my code, here are the arguments
x0 = [0;0];
z0 = [0;0];
theta0 = [3;2];
A = [0,1;-1,-1];
F = 10*rand(6,4);
% To create a single object:
identifier = identifier(A,x0,z0,theta0)
% To create an object array
identifier = identifier(A,F)
Thanks
Lihao
EDIT: I have modified my code according to Mr. Steve Lord's suggestion, and now it works! Here's the edited version:
% Edited Version
classdef secOrdIdentifier
properties
x = [0;0]
z = [0;0]
theta (2,1)
coeMatrix (2,2)
LyapunovFx
end
methods
function obj = secOrdIdentifier(A,var)
% When var is a double singlet, the input has the following structure:
% A,theta0
% When var is a double matrix, the input has the following structure:
% A, F
if nargin==0
elseif nargin==2
% -----------------------------------
% Start solving the Lyapunov function
syms x y z
P = [x,y;y,z];
eqs = A'*P+P*A==-eye(2);
sol = solve([eqs(1,1),eqs(1,2),eqs(2,2)],[x,y,z]);
% End solving the Lyapunov function
% -----------------------------------
if ~ismatrix(var)
% Properties assignment
obj.theta = var;
obj.coeMatrix = A;
obj.LyapunovFx = double([sol.x,sol.y;sol.y,sol.z]);
else
% Array generation
n = size(var,2);
obj(1,n) = obj;
for i=1:n
obj(i).theta = var(1:2);
obj(i).LyapunovFx = double([sol.x,sol.y;sol.y,sol.z]);
obj(i).coeMatrix = A;
end
end
else
erorr('Error\nThe number of input must be 0 or 2.')
end
end
end
end
Here's the class definition (version_0 and version_1)
% Version_0
classdef secOrdIdentifier
properties
x (2,1)
z (2,1)
theta (2,1)
coeMatrix (2,2)
LyapunovFx
end
methods
function obj = secOrdIdentifier(varargin)
% When nargin=4, the input has the following structure:
% A, x0,z0,theta0
% When nargin=2, the input has the following structure:
% A, F
% Case 1: Generate a single object
if nargin==4
% -----------------------------------
% Start solving the Lyapunov function
syms x y z
A = varargin{1};
P = [x,y;y,z];
eqs = A'*P+P*A==-eye(2);
sol = solve([eqs(1,1),eqs(1,2),eqs(2,2)],[x,y,z]);
obj.LyapunovFx = double([sol.x,sol.y;sol.y,sol.z]);
% End solving the Lyapunov function
% -----------------------------------
% Properties assignment
obj.x = varargin{2};
obj.z = varargin{3};
obj.theta = varargin{4};
obj.coeMatrix = A;
% Case 2: Generate an object array
elseif nargin==2
% -----------------------------------
% Start solving the Lyapunov function
syms x y z
A = varargin{1};
P = [x,y;y,z];
eqs = A'*P+P*A==-eye(2);
sol = solve([eqs(1,1),eqs(1,2),eqs(2,2)],[x,y,z]);
% End solving the Lyapunov function
% -----------------------------------
% Array generation
n = size(varargin{2},2);
obj(1,n) = obj;
for i=1:n
% Properties Assignment
obj(i).x = varargin{2}(1:2);
obj(i).z = varargin{2}(3:4);
obj(i).theta = varargin{2}(5:6);
obj(i).LyapunovFx = double([sol.x,sol.y;sol.y,sol.z]);
obj(i).coeMatrix = A;
end
end
end
end
end
% Version_1
classdef secOrdIdentifier
properties
x (2,1)
z (2,1)
theta (2,1)
coeMatrix (2,2)
LyapunovFx
end
methods
function obj = secOrdIdentifier(varargin)
% When nargin=4, the input has the following structure:
% A, x0,z0,theta0
% When nargin=2, the input has the following structure:
% A, F
% -----------------------------------
% Start solving the Lyapunov function
syms x y z
A = varargin{1};
P = [x,y;y,z];
eqs = A'*P+P*A==-eye(2);
sol = solve([eqs(1,1),eqs(1,2),eqs(2,2)],[x,y,z]);
% End solving the Lyapunov function
% -----------------------------------
% Case 1: Generate a single object
if nargin==4
% Properties assignment
obj.x = varargin{2};
obj.z = varargin{3};
obj.theta = varargin{4};
obj.coeMatrix = A;
obj.LyapunovFx = double([sol.x,sol.y;sol.y,sol.z]);
% Case 2: Generate an object array
elseif nargin==2
% Array generation
n = size(varargin{2},2);
obj(1,n) = obj;
for i=1:n
% Properties Assignment
obj(i).x = varargin{2}(1:2);
obj(i).z = varargin{2}(3:4);
obj(i).theta = varargin{2}(5:6);
obj(i).LyapunovFx = double([sol.x,sol.y;sol.y,sol.z]);
obj(i).coeMatrix = A;
end
end
end
end
end

Accepted Answer

Steven Lord
Steven Lord on 27 Jul 2022
Your constructor needs to accept the case where it is called with 0 input arguments. See the section "No Input Argument Constructor Requirement" on this documentation page for more information.

More Answers (0)

Categories

Find more on Argument Definitions in Help Center and File Exchange

Products


Release

R2021a

Community Treasure Hunt

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

Start Hunting!