Another numel/subsref/subasgn question: Why doesn't numel get called in subsref for matlab's table class but it does for my class?

1 view (last 30 days)
I've done a fair bit of searching online to try to understand this question, but I still don't understand why I can't get the functionality that I'm looking for. I've defined a class over which I'd like to overload many of the functions of the double class to perform automatic differentiation. There are a few examples of this on the Matlab File Exchange (<http://www.mathworks.com/matlabcentral/fileexchange/15235-automatic-differentiation-for-matlab>) but for various reasons and for my own edification, I'd like to write something like this on my own.
Here's a simple version of the class, without any of the operator overloading.
classdef ADfwd_example
properties
val
der
end
methods
function obj = ADfwd_example(x,d)
if nargin == 1
obj.val = x(:);
obj.der = speye(numel(x));
end
if nargin == 2
obj.val = x(:);
obj.der = d;
end
end
% overloaded subsasgn
function y = subsasgn(y, S, varargin)
if isempty(S.subs{1})
return;
end
x = varargin{1};
if isa(x, 'ADfwd_example')
if isa(y, 'ADfwd_example')
y.val(S.subs{:},1) = x.val;
y.der(:,S.subs{1}) = x.der;
else
y = ADfwd_example(y, sparse(numel(y),size(x.der)*[0 1]'));
y.val(S.subs{:},1) = x.val;
y.der(:,S.subs{1}) = x.der;
end
else
y.val(S.subs{:},1) = x;
y.der(:,S.subs{1}) = 0;
end
end
% overloaded subsref
function [varargout] = subsref(x, S)
switch S(1).type
case '()'
y = x;
y.val = x.val(S.subs{:});
y.der = x.der(:,S.subs{1});
case '.'
y = x.(S.subs);
otherwise
error(['type ' S(1).type ' not supported by ' mfilename('class')])
end
varargout{1} = y;
end
% % % overloaded numel
% % function n = numel(x,varargin)
% % n = numel(x.val);
% % end
end
end
And here is a simple code I'm using to test functionality.
% run tests for the ADfwd_example class
clear
x = 1:10;
y = ADfwd_example(x);
g = y(1:4);
disp(g.val)
n = numel(g)
for i=1:numel(g)
disp(['processing for i = ' num2str(i)])
% this would be g(i) = y(i) .* g(i) or something, but I haven't implemented those operators yet
g(i) = y(i);
end
Numel(g) returns as 1, which is not what I want if I'm looking for a code that would functionally do the same operation if g and y were doubles. I want the look to go over all 4 elements of the internal val variable. However, if I implement the commented out overloading of numel, I run into the well documented problems due to the hidden call to numel during subsref, which produces an error in the test code at disp(g.val).
I've been looking for ways around this, but nothing has worked yet. For inspiration, I started looking at the matlab table class (C:\Program Files\MATLAB\R2014b\toolbox\matlab\datatypes\@table on my filesystem) , since it successfully overloads numel, doing ostensibly what I'd like to do, but doesn't run into any issues.
But, to my surprise, if I put a breakpoint in C:\Program Files\MATLAB\R2014b\toolbox\matlab\datatypes\@table\numel.m and run operations that cause the execution of C:\Program Files\MATLAB\R2014b\toolbox\matlab\datatypes\@table\subsref.m, the breakpoint in numel never gets activated! Is @table doing something special as a matlab built-in function that I can't do with my class definition, or is there some way around having subsref automatically call numel, which seems to be the thing messing with my intended functionality?
As a sub-note, I've tried defining my class as a subclass of double, which does give me the right numel behavior. My issue with that approach is that, as an approach to Automatic Differentiation, masks areas of code using functions that have not been defined for ADfwd_example, but run just fine as doubles, returning doubles. Basically, it causes a debugging nightmare, and I'd rather have the code throw an error if a function has not been defined by the ADfwd_example class, rather than continue along happily but give an incorrect answer.

Answers (0)

Categories

Find more on Customize Object Indexing in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!