OOP how to calculate a variable only if asked by a function

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.
Hi Adam,
thank you for your answer! The problem is that I would like "FULLe_r" to be empty until I call its function. Some properties that can be filled only if required.
Let's say my class has a function like that
function FULLe_r = interpolate(mat)
xx = ...
yy = ...
FULLe_r = [x, y]
end
in this way, if I call object.interpolate FULLe_r becomes a property filled, and that I can use for plotting it for example. I'm sorry, I am very bad at explaining myself!
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.
Oh yes, now I see what you mean! But if I now want to use a regular function, how can I store its results in the properties of the object? Doing something like that
function FULLe_r = inter(mat)
xx = mat.e_r(1,1):0.005:mat.e_r(end,1);
FULLe_r = xx;
end
and then (let's call the instance "iron")
>> iron.FULLe_r = iron.inter
would be a solution, but how is there any way to implement it in the class itself? For example, even if wrong:
function mat.FULLe_r = inter(mat)
xx = mat.e_r(1,1):0.005:mat.e_r(end,1);
mat.FULLe_r = xx;
end
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( );

Sign in to comment.

Answers (1)

Thank you very much, I'll try both and I'll tell you what I get! Thank you again!

Tags

Asked:

on 15 Aug 2018

Answered:

on 15 Aug 2018

Community Treasure Hunt

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

Start Hunting!