Is it a good idea to overload subsref to mimic MATLAB's griddedInterpolant behavior?
1 visualización (últimos 30 días)
Mostrar comentarios más antiguos
Federico Miretti
el 8 de Mzo. de 2022
Respondida: James Lebak
el 8 de Mzo. de 2022
As you know, griddedInterpolant and scatteredInterpolant create an interpolant object (say, F) that can be used to interpolate data by simply calling it as
Vq = F(Xq)
I was trying to reproduce the same behavior with a custom class. For example, let's say I want to create a quadraticPoly object that can be created with
F = quadraticPoly(x_data, y_data)
and then evaluated as Vq = F(Xq), rather than using a dedicated method such as Vq = F.evaluate(Xq).
How would one do that? The only thing that comes to my mind is to overload subsref as in my example implementation below, which seems to work.
However, I wonder if this is a good idea. Skimming trough the documentation, it just doesn't look like subsref was designed to be used like this. Is there a better way to do this? And in case there is no good way to do this and this is simply a bad idea, then how and why do griddedInterpolant and scatteredInterpolant work?
Example class usage:
F = quadraticPoly([0:0.1:2], [0:0.1:2].^2);
F([1.5 2; 1 0])
Example class:
classdef quadraticPoly
properties
xData
coefs
end
methods
function obj = quadraticPoly(x, y)
obj.xData = x;
obj.coefs = polyfit(x,y,2);
end
function res = subsref(obj, x)
if length(x) > 1
error("AAAH")
end
switch x(1).type
case '()'
res = polyvalm(obj.coefs, x(1).subs{1});
case '.'
error('MYDataClass:subsref',...
'Not a supported subscripted reference')
case '{}'
error('MYDataClass:subsref',...
'Not a supported subscripted reference')
end
end
end
end
0 comentarios
Respuesta aceptada
James Lebak
el 8 de Mzo. de 2022
Subsref is the way that griddedInterpolant does this. Another way is to inherit from matlab.mixin.indexing.RedefinesParen, or from matlab.mixin.Scalar. In either of the latter cases you redefine parenReference to do the function call (where you call it in the '()' case inside subsref now).
@Sean de Wolski correctly points out reasons why you might not want to do this by overloading indexing, and those reasons apply to both approaches.
0 comentarios
Más respuestas (1)
Sean de Wolski
el 8 de Mzo. de 2022
Editada: Sean de Wolski
el 8 de Mzo. de 2022
Personally, i.e. not speaking for my corporate overlords, I don't like this design pattern. I prefer a well-named "evaluate" method (e.g. for griddedInterpolant, an interpolate method) that takes the object as input and does whatever with it. A few reasons why:
- I think this is clearer and easier to learn. Going back to college and learning fit() objects was painful. I remember taking while to figure it out even now 13 years later. interpolate(gi, x) is much clearer than gi(x).
- Overloading indexing is slower for many things than function or method invocation.
- You can't have object arrays unless you put a lot of effort into it. E.g. rather have an array of interpolant objects and be able to call interpolate(gi(3), x).
- No tab-complete.
0 comentarios
Ver también
Categorías
Más información sobre Whos 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!