Clear Filters
Clear Filters

How to overload A{n} in a custom class?

2 views (last 30 days)
fa wu
fa wu on 2 Sep 2023
Answered: fa wu on 2 Sep 2023
Background knowledge
Some explanations in the book (published in 2014):
When overloading the subsref method, you can use a switch statement to select the type of index and obtain the actual index value. The following three code snippets illustrate how to handle the input parameters. In each case, the function must return a value, which is the result of the indexing.
Parentheses indexing, operation
%Parentheses indexing, operation:A(n)
switch S.type
case '()'
B = A(S.subs{:});
end
Brace indexing, operation
%Brace indexing, operation:A{n}
switch S.type
case '{}'
B = A.CellProperty{S.subs{:}}; %What is CellProperty????
end
Member indexing, operation
%Member indexing, operation:A.name1
switch S.type
case '.'
switch S.subs
case 'name1'
B = A.name1;
case 'name2'
B = A.name2;
end
end
The other two pieces of code are easy to understand, but Brace indexing is a bit confusing. What is .CellProperty? Why can't we use B = A{S.subs{:}}?
To clarify this issue, I conducted an experiment in the following example code, hoping to achieve an overload for p{2}.
Example Code
line34 is key point
classdef MPolynom
properties
coef; %多项式系数
end
methods
function obj = MPolynom(c) %构造函数
if isa(c,'MPolynom')
obj.coef = c.coef;
else
obj.coef = c(:)';
end
end
function plot(obj) %重载plot函数
r = max(abs(roots(obj.coef)));
x = (-1.1:0.01:1.1)*r;
y = polyval(obj.coef,x);
plot(x,y);
xlabel('X')
ylabel('Y','Rotation',0)
grid on
end
function r = plus(obj1,obj2)
if ~isa(obj1,'MPolynom') %如果第一个参数不是类MPolynom对象
obj1 = MPolynom(obj1); %创建一个类MPolynom对象obj1
end
if ~isa(obj2,'MPolynom') %如果第二个参数不是类MPolynom对象
obj2 = MPolynom(obj2); %创建一个类MPolynom对象obj2
end
k = length(obj2.coef) - length(obj1.coef); %计算两个阵列的长度差
%创建一个类MPolynom对象作为返回值
r = MPolynom([zeros(1,k) obj1.coef]+[zeros(1,-k) obj2.coef]);
end
function b = subsref(a,s) %下标索引引用的实现
switch s(1).type
case '()' %圆括号类型的引用 This is the key point You can set a program breakpoint here
ind = s.subs{:};
b = polyval(a.coef,ind); %返回多项式的值 This is the key point
case '.' %“.”类型的引用
switch s(1).subs
case 'coef'
b = a.coef;
case 'plot' %由于方法plot没有返回值,这里单独列出访问过程
a.plot;
otherwise %其他带返回值方法的引用
if length(s)>1
b = a.(s(1).subs)(s(2).subs{:}); %带输入参数的方法引用
else
b = a.(s.subs); %不带输入参数的方法引用
end
end
otherwise
error('Specify value for x as obj(x)')
end
end
function y = polyval(obj,x) %计算多项式对象obj在x处的值
y = polyval(obj.coef,x);
end
end
end
Running the following code will yield the correct result
p=MPolynom([1,3,2,5]);
p(2)
ans =
29
Next, I will attempt to implement P{2}
I wish ans=29,
I will try modifying lines 35 to 36 of the Example Code
This approach has an error; I cannot add breakpoints
p=MPolynom([1,3,2,5]); cannot be executed
classdef MPolynom
properties
coef; %多项式系数
end
methods
function obj = MPolynom(c) %构造函数
if isa(c,'MPolynom')
obj.coef = c.coef;
else
obj.coef = c(:)';
end
end
function plot(obj) %重载plot函数
r = max(abs(roots(obj.coef)));
x = (-1.1:0.01:1.1)*r;
y = polyval(obj.coef,x);
plot(x,y);
xlabel('X')
ylabel('Y','Rotation',0)
grid on
end
function r = plus(obj1,obj2)
if ~isa(obj1,'MPolynom') %如果第一个参数不是类MPolynom对象
obj1 = MPolynom(obj1); %创建一个类MPolynom对象obj1
end
if ~isa(obj2,'MPolynom') %如果第二个参数不是类MPolynom对象
obj2 = MPolynom(obj2); %创建一个类MPolynom对象obj2
end
k = length(obj2.coef) - length(obj1.coef); %计算两个阵列的长度差
%创建一个类MPolynom对象作为返回值
r = MPolynom([zeros(1,k) obj1.coef]+[zeros(1,-k) obj2.coef]);
end
function b = subsref(a,s) %下标索引引用的实现
switch s(1).type
case '{}' %圆括号类型的引用
ind = a.{s.subs{:}};
b = polyval(a.coef,ind); %返回多项式的值
case '.' %“.”类型的引用
switch s(1).subs
case 'coef'
b = a.coef;
case 'plot' %由于方法plot没有返回值,这里单独列出访问过程
a.plot;
otherwise %其他带返回值方法的引用
if length(s)>1
b = a.(s(1).subs)(s(2).subs{:}); %带输入参数的方法引用
else
b = a.(s.subs); %不带输入参数的方法引用
end
end
otherwise
error('Specify value for x as obj(x)')
end
end
function y = polyval(obj,x) %计算多项式对象obj在x处的值
y = polyval(obj.coef,x);
end
end
end
Another approach
p=MPolynom([1,3,2,5]); can be executed
But when executing p{2}
the program throws an error at line 36, 'Unrecognized method, property, or field 'CellProperty' of class 'MPolynom'.
Error in MPolynom/subsref (line 36) ind = a.CellProperty{s.subs{:}};
So, how should we implement an overload for p{2}?
classdef MPolynom
properties
coef; %多项式系数
end
methods
function obj = MPolynom(c) %构造函数
if isa(c,'MPolynom')
obj.coef = c.coef;
else
obj.coef = c(:)';
end
end
function plot(obj) %重载plot函数
r = max(abs(roots(obj.coef)));
x = (-1.1:0.01:1.1)*r;
y = polyval(obj.coef,x);
plot(x,y);
xlabel('X')
ylabel('Y','Rotation',0)
grid on
end
function r = plus(obj1,obj2)
if ~isa(obj1,'MPolynom') %如果第一个参数不是类MPolynom对象
obj1 = MPolynom(obj1); %创建一个类MPolynom对象obj1
end
if ~isa(obj2,'MPolynom') %如果第二个参数不是类MPolynom对象
obj2 = MPolynom(obj2); %创建一个类MPolynom对象obj2
end
k = length(obj2.coef) - length(obj1.coef); %计算两个阵列的长度差
%创建一个类MPolynom对象作为返回值
r = MPolynom([zeros(1,k) obj1.coef]+[zeros(1,-k) obj2.coef]);
end
function b = subsref(a,s) %下标索引引用的实现
switch s(1).type
case '{}' %圆括号类型的引用
ind = a.CellProperty{s.subs{:}};
b = polyval(a.coef,ind); %返回多项式的值
case '.' %“.”类型的引用
switch s(1).subs
case 'coef'
b = a.coef;
case 'plot' %由于方法plot没有返回值,这里单独列出访问过程
a.plot;
otherwise %其他带返回值方法的引用
if length(s)>1
b = a.(s(1).subs)(s(2).subs{:}); %带输入参数的方法引用
else
b = a.(s.subs); %不带输入参数的方法引用
end
end
otherwise
error('Specify value for x as obj(x)')
end
end
function y = polyval(obj,x) %计算多项式对象obj在x处的值
y = polyval(obj.coef,x);
end
end
end

Accepted Answer

fa wu
fa wu on 2 Sep 2023
Although I'm still not entirely clear about the meaning of the following code segment (I feel like it's misleading), I have successfully modified lines 35 and 36 of the Example Code to achieve overloading of {}.
%Brace indexing, operation:A{n}
switch S.type
case '{}'
B = A.CellProperty{S.subs{:}}; %What is CellProperty????
end
The modified Example Code
classdef MPolynom
properties
coef; %多项式系数
end
methods
function obj = MPolynom(c) %构造函数
if isa(c,'MPolynom')
obj.coef = c.coef;
else
obj.coef = c(:)';
end
end
function plot(obj) %重载plot函数
r = max(abs(roots(obj.coef)));
x = (-1.1:0.01:1.1)*r;
y = polyval(obj.coef,x);
plot(x,y);
xlabel('X')
ylabel('Y','Rotation',0)
grid on
end
function r = plus(obj1,obj2)
if ~isa(obj1,'MPolynom') %如果第一个参数不是类MPolynom对象
obj1 = MPolynom(obj1); %创建一个类MPolynom对象obj1
end
if ~isa(obj2,'MPolynom') %如果第二个参数不是类MPolynom对象
obj2 = MPolynom(obj2); %创建一个类MPolynom对象obj2
end
k = length(obj2.coef) - length(obj1.coef); %计算两个阵列的长度差
%创建一个类MPolynom对象作为返回值
r = MPolynom([zeros(1,k) obj1.coef]+[zeros(1,-k) obj2.coef]);
end
function b = subsref(a,s) %下标索引引用的实现
switch s(1).type
case '{}' %圆括号类型的引用
ind = s.subs{:};
b = polyval(a.coef,ind); %返回多项式的值
case '.' %“.”类型的引用
switch s(1).subs
case 'coef'
b = a.coef;
case 'plot' %由于方法plot没有返回值,这里单独列出访问过程
a.plot;
otherwise %其他带返回值方法的引用
if length(s)>1
b = a.(s(1).subs)(s(2).subs{:}); %带输入参数的方法引用
else
b = a.(s.subs); %不带输入参数的方法引用
end
end
otherwise
error('Specify value for x as obj(x)')
end
end
function y = polyval(obj,x) %计算多项式对象obj在x处的值
y = polyval(obj.coef,x);
end
end
end
p=MPolynom([1,3,2,5]);
p{2}
ans =
29

More Answers (0)

Categories

Find more on 输入命令 in Help Center and File Exchange

Products


Release

R2020a

Community Treasure Hunt

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

Start Hunting!