methods in separate files

3 views (last 30 days)
Le Xuan Thang
Le Xuan Thang on 7 Oct 2024
Commented: Matt J on 7 Oct 2024
Hello Community,
I am working on a custom class called mcsignal that serves as a metadata class for multi-channel signal data. I have implemented custom methods display.m, disp.m (the codes in bellow), to handle property and method access in a flexible manner. I also put all methods and mcsignal.m in a class folder @mcsignal. and call main.m from outside. However, I'm running into an issue "Out of memory" when I call main.m. I think matlab doesn't understand I want to call it in my methods.
Please, take a look and help me!
main.m
% Tạo dữ liệu giả định
data = randn(1000, 3); % 1000 mẫu, 3 kênh
sig = mcsignal(data)
codes:
classdef mcsignal
properties (Hidden)
nch = 0 % Number of channels
N = 0 % Number of samples
end
methods (Hidden)
% Constructor
function obj = mcsignal(data)
if nargin > 0
% Assign values based on input arguments
obj.data = data;
obj.nch = size(data, 2);
obj.N = size(data, 1);
end
end
end
methods
function display(obj)
display(obj)
end
end
methods
% Use external subsref without redefining it here
function y = subsref(obj, ref)
y = builtin('subsref', obj, ref)
end
end
end
display.m file
function display(x)
fprintf('\n%s = (mcsignal)\n\n',inputname(1));
disp(x);
disp.m
function disp(x)
fprintf([' nch: %i\n' ...
' N: %i\n'], ...
nch(x),n_(x));
nch.m
function y=nch(varargin)
x=mcsarg(varargin{:});
y=size(x.tdata,2);
tdata.m
function y=tdata(varargin)
[x,ich1]=mcsarg(varargin{:});
y=x.tdata(:,ich1);
mcsarg.m
function [x,ich1,ich0,arg]=mcsarg(varargin);
if isa(varargin{1},'mcsignal')
x=varargin{1};
if nargout>1
ich1=[1:nch(x)];
ich0=[];
for ich=1:nch(x)
if isempty(find(ich==ich1));
ich0=[ich0 ich];
end
end
arg=varargin(2:end);
end
else
x=varargin{2};
if nargout>1
if isnan(varargin{1})
ich1=[];
else
ich1=varargin{1};
end
ich0=[];
for ich=1:nch(x)
if isempty(find(ich==ich1));
ich0=[ich0 ich];
end
end
arg=varargin(3:end);
end
end
subsref.m
function y=subsref(x,ref)
switch ref(1).type
case '.' % References to methods
% Define arg and ich1.
ich1={};
arg={};
ich1specified=0;
if length(ref)>=2
if ref(2).type=='()'
ich1={};
arg=ref(2).subs;
ich1specified=0;
elseif ref(2).type=='{}'
ich1=ref(2).subs;
arg={};
ich1specified=1;
end
end
if length(ref)>=3
if (ref(2).type=='{}') & (ref(3).type=='()')
ich1=ref(2).subs;
arg=ref(3).subs;
ich1specified=1;
end
end
% Convert ich1 cell array to double array.
tmp=[];
for iich=1:length(ich1)
tmp=[tmp ich1{iich}(:).'];
end
ich1=tmp;
clear('tmp');
% Set ich1 to NaN if an empty matrix was passed.
if ich1specified & isempty(ich1)
ich1=nan;
end
% Define command: filename = reference where capitals 'A' are replaced by 'A_'
% and underscores '_' by '__'
command=ref(1).subs;
for ichar=length(command):-1:1
if (command(ichar)~=lower(command(ichar))) | (command(ichar)=='_')
command=[command(1:ichar) '_' command(ichar+1:end)];
end
end
% Check if method exists
path=which('mcsignal');
path=[path(1:end-10) command '.m'];
if ~exist(path,'file')
error(['Not a mcsignal method: ' lower(command)]);
end
% Evaluate command(ich1,x,arg{:})
if isempty(ich1)
eval(['y=' lower(command) '(x,arg{:});']);
else
eval(['y=' lower(command) '(ich1,x,arg{:});']);
end
case '()' % Direct reference to tdata (readonly)
y=subsref(x.tdata,ref);
case '{}' % Direct reference to tdata (readonly)
y=tdata(x);
y=y(:,ref(1).subs{:});
end
% Try to evaluate sub-subsref
if (length(ref)>1) & ~isa(y,'mcsignal') & ~isa(y,'dummy')
nextref=ref(2:end);
if nextref(1).type=='{}'
nextref=nextref(2:end);
end
if length(nextref)>0
try
y=subsref(y,nextref);
end
end
end
Thank you everyone.
  1 Comment
Stephen23
Stephen23 on 7 Oct 2024
As an aside, replace those evil EVALs:
eval(['y=' lower(command) '(x,arg{:});']);
with FEVAL:
y = feval(lower(command),x,arg{:});
Or even better: with function handles.

Sign in to comment.

Answers (2)

Sandeep Mishra
Sandeep Mishra on 7 Oct 2024
Hi Le,
Upon running the provided code snippet in MATLAB R2024a, the error occurred with the following message: “Out of memory. The likely cause is an infinite recursion within the program.”
This error indicates that the code is taking excessive memory due to infinite recursive calls to the “display” function within the “mcsignal” class. Specifically, the “display” function defined inside the “mcsignal” class is being prioritized over external “display” function with the same name, leading to this issue.
To resolve the issue, you can modify the external “display” function to a different name, such as “displayFunction,” and then use this renamed function for display operations. Here’s the modified code snippet:
function displayFunction(x)
fprintf('\n%s = (mcsignal)\n\n',inputname(1));
disp(x);
end
Additionally, update the “mcsignal” class as follows to use the renamed function:
function display(obj)
displayFunction(obj)
end
Refer to the following MathWorks Documentation to learn more about Overloading the disp Function”: https://www.mathworks.com/help/releases/R2024a/matlab/matlab_oop/displaying-objects-in-the-command-window.html
I hope this helps you in resolving the issue.

Catalytic
Catalytic on 7 Oct 2024
You cannot have both a method and a property named nch.
  2 Comments
Le Xuan Thang
Le Xuan Thang on 7 Oct 2024
I want to keep the methods. How I can fix this?
Matt J
Matt J on 7 Oct 2024
Rename them?

Sign in to comment.

Categories

Find more on Programming Utilities in Help Center and File Exchange

Products


Release

R2024a

Community Treasure Hunt

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

Start Hunting!