Is there a 'self' to refer own struct in MATLAB? - matlab

I'm grouping a set of anonymous functions into a structure and some variables within that structure. Is there a way to refer 'self', i.e, own structure? What I'd like to accomplish is to have a function returns some values based on the member variables. For simplicity, say I have a struct a, where
a.value_1 = 3;
a.value_2 = 2;
a.sum = #()(self.value_1 + self.value_2)
Is there something like that possible in MATLAB?

Before objected-oriented programming was introduced in MATLAB (including both classdef-style and the obsolete #-directory style classes), one could create lightweight objects using closures and nested functions (lacking inheritance of course). This concept also exists in other languages.
Here is an example:
function s = mystruct()
s = struct('value_1',[], 'value_2',2, 'sum',#mysum);
s.value_1 = 3;
function out = mysum()
out = s.value_1 + s.value_2;
end
end
Which is used as:
>> s = mystruct()
s =
value_1: 3
value_2: 2
sum: #mystruct/mysum
>> s.value_1 = 10; % NOTE: this wont do what you expect!
>> s.sum()
ans =
5
Note that variables are immediately captured when creating a closure (functions have their own private copy if you will). So if you change one of the exposed fields from the returned structure, it will not be reflected in the enclosed state (think of them as read-only properties).
One solution is to provide accessor methods:
function obj = mystruct()
% think of those as private properties
value_1 = 3;
value_2 = 2;
% returned object (this or self)
obj = struct();
% public accessors for properties
obj.value_1 = #accessValue1;
function out = accessValue1(in)
if nargin > 0, value_1 = in; end
out = value_1;
end
obj.value_2 = #accessValue2;
function out = accessValue2(in)
if nargin > 0, value_2 = in; end
out = value_2;
end
% member method
obj.sum = #mysum;
function out = mysum()
out = value_1 + value_2;
end
end
So now we could say:
>> s = mystruct()
s =
value_1: #mystruct/accessValue1
value_2: #mystruct/accessValue1
sum: #mystruct/mysum
>> x = s.value_1(); % get
>> s.value_1(10); % set
>> s.sum()
ans =
12
Which is starting to look like the current recommended approach to create classes:
classdef mystruct < handle
properties
value_1 = 3;
value_2 = 2;
end
methods
function out = sum(obj)
out = obj.value_1 + obj.value_2;
end
end
end
Used in a similar manner:
>> s = mystruct()
s =
mystruct with properties:
value_1: 3
value_2: 2
>> s.value_1 = 10;
>> s.sum
ans =
12
We could also define get/set access methods as before..

This seems to work but I think you should rather create a class than a struct to do this:
a.value_1 = 3;
a.value_2 = 2;
a.sum = #(x)(x.value_1 + x.value_2)
a.sum(a)

With this change
a.value_1 = 3;
a.value_2 = 2;
a.sum = #()(a.value_1 + a.value_2)
Then a.sum() returns 5. But what happens when you change one of the values, later on, e.g., set a.value_1 = 5? Now a.sum() returns ... still 5. The parameters passed into the anonymous function are evaluated upon instantiation. If you want the second behavior to work properly you need to use a class. See my answer to this question for more. The only reason to use a function handle like you have is to avoid evaluating and storing a large output of a function until it's needed.

Related

Fibonacci Function in MATLAB

I am attempting to create a function for the Fibonacci numbers using a for loop. My code is as follows:
function fib = fibGenerator(N)
fib(1) = 0;
fib(2) = 1;
for i = 3:N
fib(i) = fib(i-1)+fib(i-2);
end
The following error message is displayed: Variable fib must be of data type uint32. It is currently of type double. Check where the variable is assigned a value.
I'm unsure of how to correct this.
Update
function fib = fibGenerator(N)
fibGenerator(1) = uint32(0);
fibGenerator(2) = uint32(1);
for i = 3:N
fibGenerator(i) = fibGenerator(i-1)+fibGenerator(i-2);
end
You have to cast when you initially create fib: fib(1) = uint32(0);
Here is an example demonstrating this. When creating x you decide the type. Even if later assignments are double or of other types, it will keep its type.
>> x=uint32(1)
x =
uint32
1
>> x(2)=double(2)
x =
1×2 uint32 row vector
1 2

How to define and access to static properties as a top-level member in Matlab?

I want to have a simple static member in a class with simple access i.e I like to have a class_name.static_data instead of class_name.shared_obj.static_data.
I've searched and find the standard method of defining static members in Matlab classes, on mathwork.com as you can see below.
classdef SharedData < handle % an auxiliary class to keep static data
properties
Data1
Data2
end
end
classdef UseData % main class
properties (Constant)
Data = SharedData
end
% Class code here
end
and then we can use it with something like this:
k = UseData
k.Data.Data1=5; % Want to be `k.Data1=5;` instead.
BUT I'm looking to have a top-level static member
( something like
obj_of_UseData.Data1=5;
NOT
obj_of_UseData.Data.Data1=5; )
(i.e. like a top-level member, not second-level one). I seek a method to implement top-level static member , not second-level one.
Thanks
It is possible to follow the advice from the MathWorks related to static data, and still create behavior that makes it look like those variables are members. You can do so by overloading the subsref and subsasgn methods like below. This codes uses the static method way of creating static data, since it is simplest, but the idea translates to the other method, using a handle class, as well.
classdef UseData
properties
Data3
end
methods (Static)
function out = setgetVar(name,value)
persistent data;
if isempty(data)
data = struct('Data1',[],'Data2',[]);
end
if nargin==2
data.(name) = value;
end
out = data.(name);
end
end
methods
function obj = subsref(obj,S)
if isequal(S(1).type,'.')
if strcmp(S(1).subs,'Data1') || strcmp(S(1).subs,'Data2')
obj = UseData.setgetVar(S(1).subs);
return
end
end
obj = builtin('subsref',obj,S);
end
function obj = subsasgn(obj,S,value)
if isequal(S(1).type,'.')
if strcmp(S(1).subs,'Data1') || strcmp(S(1).subs,'Data2')
UseData.setgetVar(S(1).subs,value);
return
end
end
obj = builtin('subsasgn',obj,S,value);
end
end
end
To see it working:
>> x = UseData;
>> y = UseData;
>> x.Data1 = 'bla';
>> y.Data2 = [5,6];
>> x.Data3 = 0;
>> y.Data3 = 10;
>> y.Data1
ans = bla
>> x.Data2
ans =
5 6
>> x.Data3
ans = 0
>> y.Data3
ans = 10

flatten a struct of arbitrarily nested arrays of integers into a flat array of integers

Is it possible to flatten an array of arbitrarily nested arrays of integers into a flat array of integers in Matlab? For example,
[[1,2,[3]],4] -> [1,2,3,4]
Any kind of guidance will be helpful. Thanks.
For example,
a.c = [5,4];
a.b.a=[9];
a.b.d=[1,2];
a= b: [1x1 struct]
c: [5 4]
In this case, my output will be
output= [9,1,2,5,4]
I think you will have to adapt the flatten function from the file exchange to use struct2cell so something like this:
function C = flatten_struct(A)
A = struct2cell(A);
C = [];
for i=1:numel(A)
if(isstruct(A{i}))
C = [C,flatten_struct(A{i})];
else
C = [C,A{i}];
end
end
end
This results in:
a.c = [5,4];
a.b.a=[9];
a.b.d=[1,2];
flatten_struct(a)
ans =
5 4 9 1 2
So the order is in the order you declared your struct instead of in your example order which I presume is alphabetical. But you have control over this so it shouldn't be a problem.
I have a preliminary hack which does work but rather clumsily. It descends recursively, saving structure names and unpacking the returned structure at each "level" .
% struct2sims converter
function simout = struct2sims(structin)
fnam = fieldnames(structin);
for jf = 1:numel(fnam)
subnam = [inputname(1),'_',fnam{jf}];
if isstruct(structin.(fnam{jf}) ) ,
% need to dive; build a new variable that's not a substruct
eval(sprintf('%s = structin.(fnam{jf});', fnam{jf}));
eval(sprintf('simtmp = struct2sims(%s);',fnam{jf}) );
% try removing the struct before getting any farther...
simout.(subnam) = simtmp;
else
% at bottom, ok
simout.(subnam) = structin.(fnam{jf});
end
end
% need to unpack structs here, after each level of recursion
% returns...
subfnam = fieldnames(simout);
for kf = 1:numel(subfnam)
if isstruct(simout.(subfnam{kf}) ),
subsubnam = fieldnames(simout.(subfnam{kf}));
for fk = 1:numel(subsubnam)
simout.([inputname(1),'_',subsubnam{fk}])...
= simout.(subfnam{kf}).(subsubnam{fk}) ;
end
simout = rmfield(simout,subfnam{kf});
end
end
% if desired write to file with:
% save('flattened','-struct','simout');
end

Matlab - Function taking no arguments within a class

As I do not seem to be able to edit my old question (Matlab - Function taking no arguments but not static), here it is again:
I am trying to implement the following:
classdef asset
properties
name
values
end
methods
function AS = asset(name, values)
AS.name = name;
AS.values = values;
end
function out = somefunction1
ret = somefunction2(asset.values);
out = mean(ret);
return
end
function rets = somefunction2(vals)
n = length(vals);
rets = zeros(1,n-1);
for i=1:(n-1)
rets(i) = vals(i)/vals(i+1);
end
return
end
end
end
But I am getting the error that somefunction1 should be static. But if it's static then it can't access the properties anymore. How would I resolve this issue?
Basically I want to be able to write something like this:
AS = asset('testname',[1 2 3 4 5]);
output = AS.somefunction1();
as opposed to writing
AS = asset('testname',[1 2 3 4 5]);
output = AS.somefunction1(AS);
For accessing the properties of an object in a method, you need to pass that object as argument to the method. If you don't need a specific object in order to perform a function, then make it static (belongs to the class, but does not operate on a specific object).
So, compare the original code:
methods
% ...
function out = somefunction1
ret = somefunction2(asset.values);
out = mean(ret);
return
end;
function rets = somefunction2(vals)
n = length(vals);
rets = zeros(1,n-1);
for i=1:(n-1)
rets(i) = vals(i)/vals(i+1);
end
return
end
end
with the correct code:
methods
% ...
% this function needs an object to get the data from,
% so it's not static, and has the object as parameter.
function out = somefunction1(obj)
ret = asset.somefunction2(obj.values);
out = mean(ret);
end;
end;
methods(Static)
% this function doesn't depend on a specific object,
% so it's static.
function rets = somefunction2(vals)
n = length(vals);
rets = zeros(1,n-1);
for i=1:(n-1)
rets(i) = vals(i)/vals(i+1);
end;
end;
end;
To call the method, you'd write indeed (please test):
AS = asset('testname',[1 2 3 4 5]);
output = AS.somefunction1();
because, in MATLAB, this is 99.99% of cases equivalent to:
AS = asset('testname',[1 2 3 4 5]);
output = somefunction1(AS);
The differences appear when you're overriding subsref for the class, or when the object passed to the method is not the first in the argument list (but these are cases that you should not concern with for now, until you clarify the MATLAB class semantics).

MATLAB - create reference (handle?) to variable

Suppose I have the following class:
classdef myClass < handle
properties
A = 1
end
methods
function obj = myClass(val)
obj.A = val;
end
end
end
Say I instantiate an instance of this class, then manipulate it slightly and then copy it. As it's a handle class, the "copy" is really just another instance of the same object:
>> q = myClass(10);
>> q.A = 15;
>> w = q;
>> disp(w.A)
15
But I would like to watch A without needing to instantiate myClass. Naively doing
>> value = w.A
doesn't work, since this just copies the value; changning w.A later on will not change value.
Is there a way to provide a "pointer" or "reference" to w.A without having to create a separate handle class? I'd rather keep the notation w.A rather than something like w.A.value (with me having to create the handle class to contain that value).
EDIT: I am using this functionality in order to help encapsulate my code for use with my research lab. I am designing an interface between MATLAB and Arduino to control air and ground vehicles; I was hoping to access stuff like "vehicle.pwmMax", "vehicle.flightCeiling", etc, to encapsulate the underlying object: "vehicle.Globals.pwmMax.value", etc.
You could do this by with a PropertyReference class
classdef PropertyReference < handle
%PropertyReference Reference to a property in another object
properties
sourceHandle
sourceFieldName
end
properties (Dependent = true)
Value
end
methods
function obj = PropertyReference (source, fieldName)
obj.sourceHandle = source;
obj.sourceFieldName = fieldName
end
function value = get.Value( obj )
value = obj.sourceHandle.(obj.sourceFieldName);
end
function set.Value( obj, value )
obj.sourceHandle.(obj.sourceFieldName) = value;
end
function disp( obj )
disp(obj.Value);
end
end
end
Continuing your example, you could then use PropertyReference as follows:
q = myClass(10);
>> q.A = 15;
>> ref = PropertyReference(q,'A');
>> disp(ref)
15
>> q.A = 42;
>> disp(ref)
42
Usage of the PropertyReference class is a bit awkward but the original class remains unchanged.
EDIT - Added disp function overload as per strictlyrude27 comment
I don't think there is anything that will do exactly as you want, given all your constraints.
However, I'm not really clear on your notational issues. Why do you want to retain the notation w.A while you are considered about value not changing? Keeping the notation w.A similar is not a real issue.
Using some modified code, I can produce following execution:
>> q = myClass(10);
>> q.A = 15;
>> w = q;
>> w.A
15
>> value = w.Aref;
>> value()
15
>> w.A = 20;
>> value()
ans =
20
But there is no way around the notation value() as that is the turning point of the implementation; which I think is the closest you can get to what you want. You get the behavior above when you use the following code to implement myClass:
classdef myClass < handle
properties
A = 1;
end
methods
function obj = myClass(val)
obj.A = val;
end
function a = Aref(obj)
a = #()(obj.A);
end
end
end
So you see that the Aref method actually returns a function handle which fetches the value from the object. This also means that this reference is read-only!
Also note that you will have to instantiate a myClass instance before you are able to get the value of A (where would you get the value of A from otherwise?). This instance does not have to be visible inside your current workspace (e.g. another function scope), since the myClass instance is stored within the function handle value.
Drawback of this method is that you only get a read-only reference, you will have to use the call value() to get the actual value instead of the function handle (so that changes the notation, but not the one you wanted to keep (or at least it can be made so by substituting A in my code by Aval and renaming Aref to A). Another drawback is that resolving value might be a bit slower than simply resolving a variable (whether that's a problem will depend on your usage of value()).
If you want some of the notations changed, this can be done by using dependent properties:
classdef myClass < handle
properties (Access=private)
Aval = 1;
end
properties (Dependent)
A;
end
methods
function obj = myClass(val)
obj.A = val;
end
function a = get.A(obj)
a = #()(obj.Aval);
end
function set.A(obj,value)
obj.Aval = value;
end
end
end
The equivalent execution of above is given by:
>> q = myClass(10);
>> q.A = 15;
>> w = q;
>> w.A()
15
>> value = w.A;
>> value()
15
>> w.A = 20;
>> value()
ans =
20
edit: I thought of another way to implement this, which is simpler (i.e. just keep the class of your original post) but it requires you to change the code in other places. The basic idea behind it is the same as the first ones, but without encapsulating it in the object itself (which makes the object cleaner, IMHO).
>> q = myClass(10);
>> q.A = 15;
>> w = q;
>> w.A()
15
>> value = #()(w.A);
>> value()
15
>> w.A = 20;
>> value()
ans =
20
Since you are working with a handle class, both q and w in your example refer to the same object in memory; they are themselves a "pointer"/"reference" to the object they represent.
So continuing your example, if you make changes to one, it will be reflected in the other.
>> q = myClass(10);
>> w = q;
>> q.A = 99;
>> disp(w.A)
99
Also note that you are not creating another instance of the class when you call w = q;. Compare the following examples in terms of memory space:
>> q = myClass(rand(7000));
>> m = memory; disp(m.MemUsedMATLAB)
792870912
>> w = q;
>> m = memory; disp(m.MemUsedMATLAB)
792834048
Against:
>> q = myClass(rand(7000));
>> w = myClass(rand(7000));
??? Error using ==> rand
Out of memory. Type HELP MEMORY for your options.
EDIT
Playing around with this, I came up with the following hackish solution.
First we create a wrapper function around the class constructor. It creates an object as usual, plus it returns a function handle that acts as a read-only accessor to a closure variable synced with the original object property using a "PostSet" events listener.
The only change to the original class is to add the SetObservable property attribute:
myClass.m
classdef myClass < handle
properties (SetObservable)
A
end
methods
function obj = myClass(val)
obj.A = val;
end
end
end
myClassWrapper.m
function [w A] = myClassWrapper(varargin)
w = myClass(varargin{:});
A = #getWA;
%# closure variable
a = w.A;
%# add listener to when w.A changes
addlistener(w, 'A', 'PostSet',#changeCallback);
function val = getWA()
%# return the value of the closure variable
val = a;
end
function changeCallback(obj,ev)
%# update the closure variable
a = ev.AffectedObject.A;
%#fprintf('Value Changed to %g\n',a)
end
end
Now we can use the wrapper as:
>> [w a] = myClassWrapper(10);
>> a()
ans =
10
>> w.A = 99;
>> a()
ans =
99