Operating on Superclass Property with Subclass - matlab

To all,
I'm a novice programmer (I haven't taken a structured course) trying to pick up MATLAB. Currently, I'm trying to understand MATLAB's object-oriented programming tools. I want to cleanly divide up my project in the steps below. I would like to inherit the substantiated data and work on it in validate. I'm running into this error You cannot set the read-only property 'data' of validations.
How would I go about doing this? Would this be the appropriate way to organize myself in MATLAB?
classdef formatData.m
properties
data = []
end
methods
function formatData(data)
% This should initialize the data
end
function columnShift(data)
% Simple changes
end
end
end
classdef validateData.m < formatData
properties
error = logical(false)
end
methods
function validateData(data)
if nargin > 0
obj.data = obj#formatData;
end
end
function checkValues()
% check values on data from formatData
end
end
end

The sad new is that MATLAB often changes the object-oriented codes. The code that I have posted is referenced from the latest documents. It seems completely different with a book that I have owned for one year. 
classdef formatData
properties
data = [];
end
methods
function obj = formatData(DataIn)
%formatData This should initialize the data
obj.data = DataIn;
end
function [DataOut] = columnShift(obj)
%columnShift ? How to shift the column?
DataOut = (obj.data)';
end
end
end
classdef validateData < formatData
%validateData
properties
error = false;
end
methods
function obj = validateData(DataIn)
%validateData
obj#formatData(DataIn);
end
function [] = checkValues(obj)
%checkValues
end
end
end

Related

Matlab class dynamic filling of a property

I'm trying to dynamically fill a property in a Matlab class.
I pass vectors to a method function and then compute various parameters. I would like to fill the properties in a for loop, see code example. The OwnClassFunction is just an example of a further function in the class, but is not implemented in the code example. How can I do this correctly?
classdef Sicherung < handle
properties
x = ([],1)
end
methods
function examplefunction(object,...
single_parameter_vector) % (n,1) n can be any size
for i=1:length(param_vector)
[object.x(i,1)] = object.OwnClassFunction(single_parameter_vector(i,1));
end
end
end
end
If i try something like that
...
properties
x = []
end
...
function ...(object,parameter)
for i=1:length(parameter)
[object.x(i)] = function(parameter(i));
end
I get the error message Subscripted assignment dimension mismatch.
I don’t have MATLAB in hand to test, but the following should work.
Your code is pretty close to a correctly functioning method. Change it as follows:
classdef Sicherung < handle
properties
x = [] % initialize to empty array
end
methods
function examplefunction(object,param_vector)
if ~isvector(param_vector)
error('vector expected') % check input
end
n = numel(param_vector)
object.x = zeros(n,1); % preallocate
for i=1:n
object.x(i) = object.OwnClassFunction(param_vector(i));
end
end
end
end

MATLAB: Conditionally define get/set class methods

I have created some MATLAB classes to do some error-checking when I use certain types of structures. This improve development time by preventing errors in the code, but significantly slow down execution time.
One way to get around this is to comment out the set methods inside the class. Is it possible to do this programmatically? For example, only define these methods if a parameter in the constructor is true.
classdef MWE
%MWE Minimum working example
properties
A
B
C
end
methods
function obj = MWE(A, B, C)
if nargin ~= 3
error('A, B and C must all be provided.');
end
obj.A = A;
obj.B = B;
obj.C = C;
end
% function obj = set.A(obj, value)
% validate(obj, value, 'A');
% obj.A = value;
% end
%
% function obj = set.B(obj, value)
% validate(obj, value, 'B');
% obj.B = value;
% end
%
% function obj = set.C(obj, value)
% validate(obj, value, 'C');
% obj.C = value;
% end
end
methods (Access = private)
function validate(obj, value, name)
% Code here
end
end
end
Is it possible to do this programmatically? For example, only define these methods if a parameter in the constructor is true.
After some discussion, I see there are different ways of looking at your question. And, indeed, it may be that you cannot do what you are asking as interpreted by some. Here are two cases, however, that may suffice.
Case 1
You have computationally intensive or otherwise time consuming methods, that you use to "do some error-checking", in a development setting, but want to turn off in a production environment. And, these checks occur when the class is instantiated.
Place these methods in a wrapper function that is called from the constructor.
Here's an example
classdef classFoo
properties(Access=private)
fbar;
end
methods
function this = classFoo(arg1, argN, debugMode)
if(nargin>2 && debugMode)
if(~this.verifyStuff(arg1, argN))
throw(MException('classFoo:ConstructFailure','Could not verify'));
else
this.fbar = timeConsumingFunction();
end
else
this.fbar = 42; % defaultValue;
end
% continue construction
end
function didVerify = verifyStuff(this, varargin)
% complex code
didVerify = randi(2)-1; % 50/50
end
end
end
Then when creating objects you can choose to pass the debug mode flag as true like this:
a=classFoo(1,2,true)
or as false, like this:
a=classFoo(1,2,false)
or not at all, which is the same as the false case, like this:
a=classFoo(1,2)
Case 2
You have two different versions of a get/set method that you are commenting out depending on your development environment.
Add a private member parameter (e.g. isDebugging) and set it at time of construction. Now, instead of commenting out code in your get and set methods, you can handle the different cases with a simple if/else, predicated on your debug state like this:
classdef classFoo
properties(Access=private)
fbar;
isDebugging;
end
methods
function this = classFoo(debugMode)
if(nargin<1 || ~islogical(debugMode))
debugMode = false;
end
this.isDebugging = debugMode;
end
function setfbar(this, fIn)
if(this.isDebugging)
this.fbar = timeConsumingFunction(fIn);
else
this.fbar = fIn; % defaultValue;
end
end
end
end

Saving variables in MATLAB

I am working on a MATLAB program where I will have a class, here represented as Dummy, and a function which is supposed to create and save a set of Dummy objects, say to the current folder. How can I do this? I thought about creating a matfile containing the constructor arguments for each Dummy object, as done in the code example below. However, save expects a string, so my code doesn't work.
classdef Dummy < handle
properties
foo
end
methods
function D = Dummy(foo)
D.foo = foo;
end
end
end
function generateDummies(n)
for i = 1:n
Df = matfile(strcat('Df',int2str(i)),'Writable',true);
Df.foo = i;
save(Df); %(?)
end
end
Any help would be greatly appreciated!

How to pass parameter by reference in Matlab

I am a beginner in matlab and learn about the following question online and was having trouble solving it. I have a 1 x 20 matrix called current_load that I need to update periodically. This matrix resides in the main workspace of Matlab (as shown in the code bellow).
current_loads = zeros(1, 20);
for col=1:20
current_loads(1,col)=10; %// Initially give all nodes a current value of 10
end
Object = HandleObject(current_load);%To pass by reference
recursive_remove(Object, 0);
In order to pass current_load by reference, I have created the following class HandleObject.m
classdef HandleObject < handle
properties
Object=[];
end
methods
function obj=HandleObject(receivedObject)
obj.Object=receivedObject;
end
end
end
This matrix will be passed to a function call recursive_remove (shown bellow).
function recursive_remove( current_load, val )
current_load.object = new matrix;
if(val<10)
current_load.object(1,3) = 2+val; %Not the correct way of using current_load ??
end
recursive_remove( current_load, current_load.object (1,3) )
end
Intention here is to modify current_load variable in this function and later I can see these same changes from the main. But This code doesn't work since I don't know how to pass by reference. I need to pass by reference since I am calling this recursively without returning to the main to make it overwrite its variable at the caller. Please show with an example if possible.
If you really need this feature, you can look into turning your HandleObject class into a Singleton like this:
classdef HandleObject < handle
properties
Object=[];
end
methods(Static)
function obj = Instance(receivedObject)
persistent uniqueInstance
try
if isempty(uniqueInstance)
obj = HandleObject(receivedObject);
uniqueInstance = obj;
else
obj = uniqueInstance;
end
catch ME
disp(ME.getReport);
end
end
end
methods
function obj=HandleObject(receivedObject)
obj.Object=receivedObject;
end
end
end
Your recursive function would become a bit simpler then:
function recursive_remove(val )
current_load = HandleObject.Instance();
current_load.object = new matrix;
if(val<10)
current_load.object(1,3) = 2+val;
end
recursive_remove(current_load.object (1,3) )
end
And to create an instance of your HandleObject class, you do something like:
Object = HandleObject.Instance(current_load);
Hope this helps you further.

parfor and handle classes

I have a handle class:
classdef A<handle
properties
a;
end
methods
function obj = A(a)
obj.a=a;
end
end
end
And I have a cell array of A objects:
arr={};
for i=1:3
arr{i}=A(i);
end
What I would like to do is pass that cell array to a parfor loop so that each object's value will change:
parfor i=1:3
arr{i}.a=i*5;
end
However, this code does not change arr at all. Indeed, here it states that
Changes made to handle classes on the workers during loop iterations are not automatically propagated to the client.
How can I overcome this?
An interesting question; I actually never encountered this problem. It's always good to know everything about parfor limitations, so I did some googlin' and came up with this:
I have received an answer to this issue from technical support.
Apparently the Mathworks regard it as a 'feature' that changes to
objects are not returned - though I can't see that it's a very useful
feature. Anyway, the way to get modified class properties returned
from a parfor loop is to make an explicit change which can be
recognised by parfor. Here are two examples which work for the above
example object:
parfor n = 1:num
exArray(n).data = n:n+5;
end
or
parfor n = 1:num
temp = exArray(n);
setData(temp,n:n+5);
exArray(n) = temp;
end
Actually, if you change any object property it also seems to work. So
for example this also works, if there is a second property data2 which
is set explicitly, both data and data2 are correctly returned:
parfor n = 1:num
setData(exArray(n),n:n+5);
exArray(n).data2 = n:n+5;
end
Where the example object is given by
classdef Example < handle
properties
data
end
methods
function obj = Example(data)
obj.data = data;
end
function setData(obj,data)
obj.data = data;
end
function data = getData(obj)
data = obj.data;
end
end
end
and the array is initialized simply as
% Initialise array of objects
for n = 1:num
exArray(n) = Example(zeros(1,6));
end