methods in separate files
    3 visualizaciones (últimos 30 días)
  
       Mostrar comentarios más antiguos
    
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 comentario
  Stephen23
      
      
 el 7 de Oct. de 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.
Respuestas (2)
  Sandeep Mishra
      
 el 7 de Oct. de 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. 
0 comentarios
  Catalytic
      
 el 7 de Oct. de 2024
        You cannot have both a method and a property named nch.
2 comentarios
Ver también
Categorías
				Más información sobre Class Introspection and Metadata en Help Center y File Exchange.
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!




