MATLAB: Object Array Property Assignment with Deal - arrays

I have a class constructor that takes multiple numeric arrays of the same size and creates an object array of the same size. In the constructor, I am trying to use deal to assign data from each input array to a single index of the object array's only property:
classdef myClass
properties
data
end
methods
function obj = myClass(varargin)
nArg = length(varargin);
for iArg = 1:nArg
dataArg = num2cell(varargin{iArg});
[obj.data(iArg)] = deal(dataArg{:});
end
end
end
end
Unfortunately, I get the following error from deal: The number of outputs should match the number of inputs.
I believe that this is probably occurring because I haven't preallocated the object array before the for loop in the constructor, e.g.:
szObj = size(varargin{1});
cellSzObj = num2cell(szObj);
obj(cellSzObj{:}) = myClass.empty;
However, for various reasons, I want to be able to make this assignment without preallocating the object array.
Is there a way to do this?

Related

Matlab: Calculate function of each object in an object arrays

this is my first question so i hope I am doiung the tagging and so on right.
I have an array of objects of the same class. When I want to access a property of the objects I can use:
Data = [ObjectArray.property];
Now I want to call a mehtod of the class for each object and get back the result as Vektor/ matrice:
result = [ObjectArray.myfun(X)]
here I get an error saying:
Expected one output from curly brace or dot indexing expression
I tried brute force several different annotation but nothing works and i can't find a solution online.
Anybody knows how to make this work?
Thanks and Cheers!
It's slightly unclear what the structure of your array is, but you should be able to use arrayfun.
result = arrayfun( #(obj) obj.myfun(x), ObjectArray );
If you function myfun returns anything other than a scalar, you will need to set the UniformOutput flag to be false. This will make the result a cell array, with one cell per result.
result = arrayfun( #(obj) obj.myfun(x), ObjectArray, 'uni', false );
% If you want to concatenate results, could use something like
% result = [result{:}];
Note that this is basically shorthand for a loop, but it saves you pre-allocating an output and writing the loop.
You can also do this directly inside of your myfun:
If the item you operate your method on is an array, the first parameter of your myfun method will be an array. This can be used, and call itself one by one:
vec = [MyClass(1), MyClass(2)];
list = vec.myfun();
classdef MyClass
properties
prop1
end
methods
function obj = MyClass(val)
obj.prop1 = val;
end
function val = myfun(obj)
if numel(obj) > 1
val = arrayfun(#(o) o.myfun(), obj);
return;
end
val = obj.prop1;
end
end
end

Access 2d arrays in julia of my own type

I have created my own type:
type T
name
pos
end
What i want to do is create a 2d array of this type. This is how i did it:
arr = Array{T}(10,10) #create 2d Array
This creates the 2d array (10 by 10) with all the elements being undefined. (im thinking my problem is here)
So when i try to change just one element of the array
arr[1,1].name = "Hi"
I get this error:
ERROR: UndefRefError: access to undefined reference
What how I tried to fix the issue is by creating a default instance of T and iterate through the array and set every element equal to the default.
default = T("Hi",1)
for i = 1:10
for j = 1:10
arr[i,j] = default
end
end
Now, this sets every element in the array to the default value succesfully but now the problem is that if i try to change the value of just one element of the array, every element of the array is changed to that value.
arr[2,4].name ="Hello"
After that line all the elements have the value of "Hello".
Is that not how you are supposed to change values in an array? When i do the same on an Int64 2d array everything works how i would expect.
Everything is working as it should.
arr[i,j] = default
sets arr[i,j] to the reference default which is the instance of T("Hi",1). So every single arr[i,j] is referring to the same instance of the type.
arr[1,1].name = "Hi"
does not work because when you do arr = Array{T}(10,10) you create a 10x10 empty array with the ability of holding Ts, but you haven't put any Ts in there!
Thus what you want to be doing is:
arr[i,j] = T("Hi",1)
which will both make a T and make a[i,j] refer to it. Since each line is making a new T, they will refer to different instances and act separately.

Matlab - Extract properties as array from object-array

how do I extract an array of object properties from an object array (where each of the objects within that array has that property?)
Ex.:
classdef myClass
properties
myProperty = 1
end
end
--
myObjectMatrix(1:1000) = myClass()
myObjectMatrix(100:234).myProperty % what I thought would work but results in lots of individual results
[myObjectMatrix(100:234)..myProperty] works, but only in one dimension. I need to use reshape() if I have more than one dimension to 'fold' my results back.
Is there a better way?
Thanks!
Basically that code would act on each member in turn and return a separate answer, so in the end you only get a 1x1 output.
The solution in that example is to use arrayfun(), such as:
myObjectMatrix(1:1000) = myClass()
output = arrayfun(#(x) x.myProperty,myObjectMatrix(100:234))
That would give you a 1x135 array containing the value of each of the myProperty member from each of the elements selected from the class array.
In arrayfun you give a function to perform on each element in the array and then the array to act on. In this case I created an anonymous function which simply accesses myProperty on x - where x will be each object in the array in turn.
It is important to note that the above will only work if the property is a single value, not a matrix/array. If it is an array then the output will be nonuniform, and you will have to do:
output = arrayfun(#(x) x.myProperty,myObjectMatrix(100:234),'UniformOutput', false)
In this case 'output' will be a cell array containing the value of the property of each class.

how to get array of properties from array of objects in matlab

I am using an array of objects in my program, and each object has several attributes. I want to be able to extract separate arrays from this array of objects, one array for each attribute.
here is a snippet of the relevant code:
dailyDataMatrix(m,n)=dailyData('',''); %creates an mxn array of dailyData objects
for i=1:m
for j=1:n
dailyDataMatrix(i,j)=dailyData(datainput1, datainput2)%dailyData constructor, sets attributes
end
end
dailyDataMatrix.attribute
But when I try to access a certain attribute as in the code above, say of type string, I get a strange result. Instead of getting an array of strings, I get something else. When I try to print it, rather than printing an array, it prints a series of individual values
ans = 'string1'
ans = 'string2'
...
When I try to call
size(dailyDataMatrix.attribute)
className = class(dailyDataMatrix.attribute)
I get
"error using size: too many input arguments" and
"error using class: The CLASS function must be called from a class constructor."
However, when I write this as
thing=dailyDataMatrix.attribute
className = class(thing)
size(thing)
I get the response
classname = 'double' and size = 1x1.
Why is this not returning an array the same size as dailyDataMatrix? And an aside question is why the two different ways of writing the code above give different results? and how can I get the result that I want?
Thanks,
Paul
You can capture all the outputs using a cell array or using square brackets if the types are same. For regular array when all values are of same type use,
thing=[dailyDataMatrix.attribute];
If the types are different you can use
thing = cell(1,N); % N is the number of elements in dailyDataMatrix
[thing{:}] = dailyDataMatrix.attribute;

Matlab class incrementing static number

I've created an object with an Id property.
I'm trying to create an array which will automatically fill the Id property according to the location in the array or a static incrementing int starting from 1.
How do I implement this?
I tried to create a constructor with id as input, but writing
myArr(100) = myObj throws an error.
How do I initialize this also with the id (using static id or any other way).
Thanks
I know this is only a partial solution, but suppose you have a matrix M where the first index is the ID value, then here is what you can do:
M(:,1) = 1:size(M,1)
Or if you have a matrix M where the first column needs to be added with ID values:
M = [1:size(M,1) M]
classdef a_class < handle
properties
id
end
methods
function obj = a_class(size_of_matrix)
if nargin == 0 %default constructor
%something constant. Do not try to place counter here.
else
if numel(size_of_matrix)==1
size_of_matrix = [size_of_matrix size_of_matrix];
end;
obj(size_of_matrix(:)) = a_class; % Preallocate object array
id_cell = num2cell(1:prod(size_of_matrix));
[obj(1:prod(size_of_matrix)).id] = id_cell{:};
end
end
end
end
I'm afraid, this is the best possible solution.
Note you can't define a counter in default constructor, and then allocate an array, as, in fact, it would be called only once.
PS
They use even more naive for-based syntax in official tutorial...

Resources