What is the best way to work with variable size class properties?

29 visualizzazioni (ultimi 30 giorni)
Hi,
I would like to generate C++ code for a object oriented matlab algorithm that fully exploits dynamic memory allocation.
Right now my code contains data objects (see obj_data_fixedsize10000) that include a property 'data' with fixed size. For the code generation I'm using the following configuration:
cfgexe = coder.config('exe');
cfgexe.DynamicMemoryAllocation = 'Off';
The memory that is allocated after code generation is huge, so this approach won't work for my project.
Instead I'd like to work with variable size arrays. Unfortunately, this feature is currently explicity not supported for class properties ('coder.varsize' is not supported for class properties, see [1]).
I figured out a way to use a persistent variable 'data_pers' (see obj_data_persistent below) that can be declared as variable size to accomplish my needs. However, the object obj_data_persistent can be instanced only once since a second instance would use the same persistent variable.
Besides, I assume that it could also be kind of tricky to pass an instance of obj_data_persistent as an input to an entry point function.
Therefore my question: Are there any more elegant procedures to work with objects that contain variable size variables?
Thanks
Johannes
classdef obj_data_fixedsize10000
properties (Access = private)
data = zeros(10000,1);
n_valid = 1;
end
properties (Constant = true)
n_max = 10000;
end
methods
function val = getData(obj)
val = obj.data(1:obj.n_valid);
end
function obj = setData(obj,val)
obj.n_valid = min([length(val) obj.n_max]);
obj.data(1:obj.n_valid) = val(1:obj.n_valid);
end
end
end
classdef obj_data_persistent
methods
function val = getData(obj)
val = obj.persData;
end
function obj = setData(obj,val)
obj.persData(val);
end
end
methods (Access = private)
% Handling Persistent Data
function varargout = persData(~,varargin)
persistent data_pers
if isempty(data_pers)
data_pers = 0;
end
coder.varsize('data_pers',[inf 1],[1 0]);
if nargin == 2
data_pers = varargin{1};
end
if nargout == 1
varargout{1} = data_pers;
end
end
end
end

Risposta accettata

Denis Gurchenkov
Denis Gurchenkov il 17 Set 2019
Hi John,
MATLAB Coder does support variable-sized arrays inside classes. I think you got confused by the fact that coder.varsize does not work for class properties. There are other ways to tell Coder that this property is variable-sized, without using coder.varsize (and that is a good catch, we should make the documentation more clear). The end result should be gneration of C or C++ code that uses dynamic memory allocation.
In your example, try this:
classdef obj_data
properties
data
end
methods
function obj = obj_data
% These two sequential assignments with same base type, but different sizes
% tell MATLAB Coder that obj.data is a variable-sized array that should
% be allocated in the heap.
obj.data = 1;
obj.data = zeros(1,0);
end
function val = getData(obj)
val = obj.data;
end
function obj = setData(obj,val)
obj.data = val;
end
end
end
And use it like this:
function out = main(n)
x = obj_data;
if n < 10
x = x.setData(1:10);
else
x = x.setData([]);
end
for i = 1:n
x = x.setData([x.getData(), i]);
end
out = x.getData();
end
Now code generation should work fine:
codegen main -args {1}
  1 Commento
Johnop
Johnop il 17 Set 2019
Thanks Denis! Indeed, it was not clear to me that varsize not working does not imply that variable size variables do not work.

Accedi per commentare.

Più risposte (0)

Prodotti


Release

R2018b

Community Treasure Hunt

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

Start Hunting!

Translated by