Matlab class dynamic filling of a property - matlab

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

Related

Passing additional iteration-dependent inputs to ode45

I'm trying to solve differential equation using the ode45 function. Consider the following code,
[t1,X2] = ode45(#(t,x)fun(t,x,C1,C2,C3,C4),t0,X01);
where parameters C1, C2, C3 and C4 are column vectors, which should be available to the function that ode45 is referring to (fun.m). I want the values to change after every iteration, so for example, at the beginning the entry of C1 I want in is C1(1), in the next iteration it's C1(2), etc.
How can I implement that?
You may have noticed that the official docs are not too helpful in this scenario (as they pretty much force you to use global variables - which is doable, but discouraged). Instead, I'll show you how this can be done with classes and function handles. Consider the following:
classdef SimpleQueue < handle
%SIMPLEQUEUE A simple FIFO data structure.
properties (Access = private)
data
position
end
methods (Access = public)
function obj = SimpleQueue(inputData)
%SIMPLEQUEUE Construct an instance of this class
obj.data = inputData;
rewind(obj);
end % constructor
function out = pop(obj, howMany)
%POP return the next howMany elements.
if nargin < 2
howMany = 1; % default amount of values to return
end
finalPosition = obj.position + howMany;
if finalPosition > numel(obj.data)
error('Too many elements requested!');
end
out = obj.data(obj.position + 1 : obj.position + howMany);
obj.position = finalPosition;
end % pop
function [] = rewind(obj)
%REWIND restarts the element tracking
% Subsequent calls to pop() shall return elements from the beginning.
obj.position = 0;
end % rewind
end % methods
end % classdef
How to use this? Simple:
C1q = SimpleQueue(C1);
C2q = SimpleQueue(C2);
C3q = SimpleQueue(C3);
C4q = SimpleQueue(C4);
[t1,X2] = ode45(#(t,x)fun(t,x,#C1q.pop,#C2q.pop,#C3q.pop,#C4q.pop),t0,X01);
As you can see, inside fun we use C1q() instead of C1.

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

Array of objects in generable matlab function

In simulink model I have a matlab function block. Inside the function I would like to create an array of objects in a way it is compatible with code generation.
My question is similar to the one answered here: Construct an array of objects in MATLAB
The problem is "compatible with code generation" part.
When I try to do it with repmatmatlab returns:
Arrays of objects are not supported for code generation.
When I try to do it with array of objects I see:
Recursive calls are not allowed. Function 'dummyClass.dummyClass'
participated in a recursive call.
Please find below the code I run:
embedded matlab function
function y = fcn(u)
%#codegen
x = [1 2 3];
% %% repmat way
% aa = dummyClass(x(1));
% aaArray = repmat(aa,1,3);
%% array of objects
aa = dummyClass(x);
y = u;
class file
classdef dummyClass
properties
value
end
methods
function obj = dummyClass(value)
%% array of objects
if nargin~=0
m = size(value,1);
n = size(value,2);
obj(m,n) = dummyClass;
for i = 1:m
for j = 1:n
obj(a,b).value = value(a,b);
end
end
end
% %% repmat
% obj.value = value;
end
end
end
Uncomment
As of MATLAB R2017a, there's no way to create arrays of objects that is compatible with code generation using MATLAB Coder or Simulink Coder.
As the first error message says, "arrays of objects are not supported for code generation" - it's not a problem with any specific way you're attempting to create them, they're just not supported at all.
MathWorks may introduce this feature in a future version, but it's not there right now.

How to access variables in the properties block of a Matlab System Object?

I am working on a simple System Object in Matlab/Simulink.
It looks like this :
classdef realtime_header_detectorSO < matlab.System & matlab.system.mixin.Propagates
% correlateHeader
%
% This template includes the minimum set of functions required
% to define a System object with discrete state.
properties
Header
%nrOfBitsInPreviousStep=0;
s=100;
d=zeros(1,s);
end
properties (DiscreteState)
end
properties (Access = private)
max_nr_of_packets=20;
max_packet_length_in_bytes=300;
current_packet=1;
% Pre-computed constants.
% h = commsrc.pn('GenPoly', [9 5 0],'NumBitsOut', 8,'InitialStates',ones(1,9));
% data=logical(zeros(max_nr_of_packets,max_packet_length_in_bytes*8));
end
methods (Access = protected)
function setupImpl(obj,u)
% Implement tasks that need to be performed only once,
% such as pre-computed constants.
end
function [maxCorr]= stepImpl(obj,u)
eml.extrinsic('num2str');
coder.extrinsic('sprintf');
% Implement algorithm. Calculate y as a function of
% input u and discrete states.
%y = size(u,1);
symbols=sign(u);
c=abs(conv(flipud(obj.Header),[symbols; symbols]));
maxCorr=max(c);
% maxCorr
if(maxCorr==36)
idx36=find(c(1:size(symbols,1))==36);
disp('header(s) detected at the following location(s) in bytes:');
disp(sprintf('%15.4f \n',idx36/8));
nrOfSymbols=size(symbols,1);
disp(['out of nr. of total symbols: ' num2str(nrOfSymbols)]);
disp('------');
% maxCorr
end
% y=obj.pBufferIdx;
end
function resetImpl(obj)
% Initialize discrete-state properties.
end
function varargout = isOutputFixedSizeImpl(~)
varargout = {true};
end
function varargout = getOutputSizeImpl(obj)
varargout = {[1 1]};
end
end
end
However when I compile/run it I get the following error:
The System object name 'realtime_header_detectorSO' specified in MATLAB System block 'freqScanningRT/Sync and
Find Header/detect header' is invalid.
Caused by:
Undefined function or variable 's'.
However (!) the following code compiles and runs just fine :
classdef realtime_header_detectorSO < matlab.System & matlab.system.mixin.Propagates
% correlateHeader
%
% This template includes the minimum set of functions required
% to define a System object with discrete state.
properties
Header
%nrOfBitsInPreviousStep=0;
s=100;
% d=zeros(1,s);
end
properties (DiscreteState)
end
properties (Access = private)
max_nr_of_packets=20;
max_packet_length_in_bytes=300;
current_packet=1;
% Pre-computed constants.
% h = commsrc.pn('GenPoly', [9 5 0],'NumBitsOut', 8,'InitialStates',ones(1,9));
% data=logical(zeros(max_nr_of_packets,max_packet_length_in_bytes*8));
end
methods (Access = protected)
function setupImpl(obj,u)
% Implement tasks that need to be performed only once,
% such as pre-computed constants.
end
function [maxCorr]= stepImpl(obj,u)
eml.extrinsic('num2str');
coder.extrinsic('sprintf');
% Implement algorithm. Calculate y as a function of
% input u and discrete states.
%y = size(u,1);
disp(obj.s);
symbols=sign(u);
c=abs(conv(flipud(obj.Header),[symbols; symbols]));
maxCorr=max(c);
% maxCorr
if(maxCorr==36)
idx36=find(c(1:size(symbols,1))==36);
disp('header(s) detected at the following location(s) in bytes:');
disp(sprintf('%15.4f \n',idx36/8));
nrOfSymbols=size(symbols,1);
disp(['out of nr. of total symbols: ' num2str(nrOfSymbols)]);
disp('------');
% maxCorr
end
% y=obj.pBufferIdx;
end
function resetImpl(obj)
% Initialize discrete-state properties.
end
function varargout = isOutputFixedSizeImpl(~)
varargout = {true};
end
function varargout = getOutputSizeImpl(obj)
varargout = {[1 1]};
end
end
end
So I can access s in the stepImpl(obj,u) as obj.s but I cannot access s inside the properties block, where it is defined !
Now this is confusing.
Is there way to access s inside the properties block ?
The problem is that I have to use the properties block because if I try this :
function setupImpl(obj,u)
% Implement tasks that need to be performed only once,
% such as pre-computed constants.
d=zeros(1,obj.s);
end
then I get :
Error due to multiple causes.
Caused by:
Problem creating simulation target MEX-file for model 'freqScanningRT'.
Simulink detected an error
'Computed maximum size is not bounded.
Static memory allocation requires all sizes to be bounded.
The computed size is [1 x :?].'.
The error occurred for MATLAB System block 'freqScanningRT/Sync and Find Header/detect header'. See line
34, column 15 in file
'path/realtime_header_detectorSO.m'.
The error was detected during code generation phase.
Start code generation report.
To prevent this error, use one of the following:
* Modify the System object to avoid code that does not support code generation.
* Change 'Simulate using' parameter to 'Interpreted Execution'.
Any idea how to refer to variables in the properties blocks ?
There must be a way to do this.
You should be able to use
properties
s = 100;
d = zeros(1,100);
end
right? If you already have the 100 as a default for s, you should also be able to provide this as part of the default for d.
I'm guessing that you're trying to avoid doing that because you feel uncomfortable repeating the "100". But I'd also guess that really, "100" is some sort of magic number that your system depends on; so really, you should try to pull it out as a constant in any case, whether it's repeated or not.
So in that case, you might improve things with
properties (Constant)
MYCONSTANT = 100;
end
properties
% Reference Constant class properties with the class name
s = realtime_header_detectorSO.MYCONSTANT;
d = zeros(1, realtime_header_detectorSO.MYCONSTANT);
end
You're not going to be able to do what you're originally trying to do - it's not possible to reference the name of one property within the property definition block when defining another property (even though you can perfectly well reference it within a method). I guess I understand why you find that confusing - but to clear up your confusion, note that you have no guarantee over the order in which MATLAB instantiates default values for properties. If it tried to create d before it had created s, it would obviously fail.
You can avoid this problem all together by initializing the properties in the constructor.

Matlab - Manipulating datasets within subclass methods

I am having some difficulty designing a subclass of dataset in Matlab (R2010b). I am experienced programming Matlab, but new to using its OOP features. My constructor seems to be fine, but when I try to build some methods that access data in the dataset, I can't seem to get it to work. Here is an example:
classdef mydataset < dataset
properties
end
methods
function [obj] = mydataset(obs,array)
% obs is N x 1 cell array of strings
% array is N x 2 double array
obj = obj#dataset({array,'Field1','Field2'},'ObsNames',obs)
end
function [val] = computeValue(obj)
col = obj.Field1;
% I get an error above regardless of how I try to access the dataset.
% e.g. col = double(obj(obs,'Field1')) also does not work.
% Some more code using col to determine val
end
end
end
In my method computeValue, I am trying to access the data in the dataset using dataset syntax, i.e. on the command line I could access Field1 using ".". It complains there is no method, property, or field Field1 for class mydataset. If I try the alternate syntax
col = double(obj(:,'Field1'));
it complains about the size of obj, e.g. "Index exceeds matrix dimensions".
I found a workaround using subsref:
methods
function [val] = computeValue(obj)
s.type = '.';
s.subs = 'Field1';
col = subsref(obj,s);
% Some more code using col to determine val
end
end
Although the workaround works, it is not very convenient and largely defeats the purpose of wanting a subclass of dataset. Is there some attribute or something simple I am missing?
Thank you very much.
Eric
Can you post the complete code of your class. I suppose you didn't declare your property "factor" and try to access it.
Your class should look like this :
classdef MyClass
properties
factor;
end
methods
function obj = MyClass(factor)
% The constructor set the property factor
obj.factor = factor;
end
function val = computeValue(obj)
col = obj.factor;
% ...
end
end
end