OOP how to calculate a variable only if asked by a function
Show older comments
Hello,
that's probably a silly question but I couldn't find the answer in the matlab manual. I've been using matlab for years, but I'm fairly new to the OOP here (despite having used it in C++, and here is probably why I am wrong). I am going to build a simple class which retrieves data from a txt file but I would like it to compute the interpolation ONLY if asked. I've tried to define this variable as dependent, which I thought it would start from "empty" if never called. It is not a big deal for this small piece of software, but I find it annoying and I wonder how to avoid it if, in the future, I will have a bigger program where every spared calculation is good.
Here the code:
classdef material
% Definition of a material proprieties through the class material.
properties
link % Path for retrieving data (mandatory input)
e_r % Permittivity [units]
mu_r % Permeability [units]
end
properties (Dependent)
FULLe_r
end
methods
%%Overloaded constructor
function mat = material(filename)
mat.link = filename;
mat.e_r = importdata(mat.link);
end
%%Interpolation function
function f = get.FULLe_r(mat)
xx = mat.e_r(1,1):0.005:mat.e_r(end,1);
%yy = spline(mat.e_r(:,1),mat.e_r(:,2),xx);
f = xx;
end
%%Plot material data
function plot(mat)
plot(mat.e_r(:,1),mat.e_r(:,2),'o',mat.FULLe_r(:,1),mat.FULLe_r(:,2))
end
end
end
I've tried many times in different ways. The interpolation for example is wrong here, just to see if I could get any values when asked as a test. This class gives me the following object:
link: 'C:\Users\Downloads\somemat.txt'
e_r: [26×2 double]
mu_r: []
FULLe_r: [1×443 double]
I suppose a solution is to use superclasses and inheritance, but I was hoping an easier way existed. Thank you in advance,
René
5 Comments
I'm not really sure what your problem is. What aspect of your solution is not working?
One thing you have to be aware of with dependent properties and 'noseying' at a class object on the command line is that viewing the object will count as requesting the dependent properties to be calculated (because you asked to display the object and that depenent property is a public part of the object and thus will get calculated in order to display the object). They do not get stored, however.
René Gaio
on 15 Aug 2018
Adam
on 15 Aug 2018
Your dependent property will do this, although it will recalculate it every time you ask for it. If that is not what you want then you should just turn it into a regular function that stores its result in a normal variable. This will then only happen when you call the function.
As mentioned in my last comment though, viewing the object on command line implicitly calls the get.FULLe_r function as you asked to display the object. The result will not be stored anywhere though and will be recalculated next time you ask for it.
This is good for calculations that are fast and where you expect to change the inputs so that you don't have to deal with the hassle of ensuring that a stored property is updated every time you do this. The dependent property will never store anything - it always recalculates the result when you call it and thus will never be out of date.
If it is a slow calculation though and you request it regularly without having changed any of the properties it depends on then a dependent property is not an ideal solution.
René Gaio
on 15 Aug 2018
There are two options (probably more).
My favoured one would be to simply store the result of your inter function in a non-dependent variable as e.g.
mat.FULLe_r = xx;
and not return anything. Then after calling the function you can ask for the result afterwards in a separate call:
res = iron.FULLe_r;
The other option is similar to what you tried to do - store it in the property as well as returning it from the function:
function [FULLe_r, mat] = inter(mat)
mat.FULLe_r = mat.e_r(1,1):0.005:mat.e_r(end,1);
FULLe_r = mat.FULLe_r;
end
or something similar to that. You can't return mat.FULLe_r from the function, but you can assign a local function variable to that property and also return that local variable from the function.
Beware though that in your case you will need to also return the object itself out of any function that assigns to the object's properties (as shown above) because you class is a value class, not a handle (pass by reference) class.
Whether it is the first or second or any other output argument does not matter, but you need to reassign it to the object e.g.
[FULLe_r, iron] = iron.inter( );
Answers (1)
René Gaio
on 15 Aug 2018
0 votes
Categories
Find more on Spectral Analysis 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!