cell array of classes

Hi,
Consider a simple class Aclass:
classdef Aclass
properties
w
end
methods
function a = Aclass(b)
a.w = b;
end
end
end
The only data member is a vector. Now say I have a very large matrix that I'd like to turn into a cell array of Aclass objects:
n = 60000; k = 20;
l = zeros(n,k);
% Convert to a cell array of Aclass objects,
sz = size(l,1);
l2 = mat2cell(l,ones(1,sz),k);
l2 = reshape(cellfun(@Aclass,l2,'UniformOutput',0),[sz 1]);
Here, the matrix l with n rows is converted into a cell array with n members, each of which is an Aclass.
My question is: is this the best way to do this? The problem is that it's quite slow when n becomes large. Is there a way to make a "custom" constructor that would return a cell array of Aclass rapidly, perhaps using a MEX file?
Many thanks,
JLT

 채택된 답변

per isakson
per isakson 2012년 1월 13일

1 개 추천

R2010b doc says:
Building Arrays in the Constructor
A constructor function can return an object array by making the necessary assignments when initializing the output argument. ...

추가 답변 (1개)

David Young
David Young 2012년 1월 13일

1 개 추천

Is there any reason to use a cell array rather than an array of Aclass objects? The latter should be more efficient in both time and storage.
You can make such an array in various ways, but probably the neatest is to provide the functionality in the class constructor. Per isakson's link gives the framework. Here's what it might look like for your case:
classdef Aclass
properties
w
end
methods
function a = Aclass(b)
if nargin > 0
a(size(b,1)) = Aclass; % preallocate array
for k = 1:size(b,1)
a(k).w = b(k,:);
end
end
end
end
end
and to create the array you simply do
arr = Aclass(l);
I think this goes faster than your cell-based code, but I haven't checked very carefully.

댓글 수: 9

Jean-Luc
Jean-Luc 2012년 1월 15일
Thanks, David and Per! This is indeed *much* faster: for some reason I thought that arrays of classes were not allowed.
But then the member functions for Aclass must all be written to potentially deal with a array? For instance, would it be reasonable to write
function disp(obj)
for i = 1:length(obj)
disp(['( ' num2str(obj(i).w) ' )']);
end
end
as a member function in Aclass, to display each row as a vector bracketed by parentheses?
Best,
Jean-Luc
Jean-Luc
Jean-Luc 2012년 1월 15일
And another quick question: what is the best way to convert *back* from an array of Aclass to a vector w. For instance, if arr is an Aclass array:
w = cell2mat({arr.w}')
works but is slow. The problem is that arr.w returns a bunch of w, on each line, rather than a 2D array. Is the solution to provide get.w explicitly?
jL
David Young
David Young 2012년 1월 15일
Yes, I'd go for explicit get.w, essentially reversing the constructor. Make sure to preallocate the output matrix before the loop to fill its rows.
per isakson
per isakson 2012년 1월 15일
"cell2mat({arr.w}')" looks strange to me. Why not use [arr.w]'
Jean-Luc
Jean-Luc 2012년 1월 16일
Per: you're right, [arr.w] works better. I guess it's not clear to me what the internal "status" of the object arr.w is within Matlab, and how [arr.w] makes that into a proper array.
David: could you provide me with some tip as to how to write the code for get.w? I tried but I don't see how to avoid recursion.
Best,
jL
David Young
David Young 2012년 1월 16일
What a.w is is a comma-separated list. It's equivalent to a(1).w, a(2).w, a(3).w (in the case where a has length 3). So [a.w] does a horizontal concatenation of the w's. However, to reconstruct your original matrix, you need vertical concatenation.
On reflection, I'd probably go for a normal method rather than get.w, as you might want to retain the possibility of getting the comma-separated list. Such a method just looks like:
function b = getw(a)
b = vertcat(a.w);
end
Jean-Luc
Jean-Luc 2012년 1월 17일
David: brilliant, thanks! I'm still grappling with some Matlab concepts, but a "comma-separated list" explains a lot.
jL
Jean-Luc
Jean-Luc 2012년 1월 17일
Update: cell2mat({arr.w}') is about the same speed (and maybe even slightly faster) that vertcat(arr.w). Weird.
Also, I don't see how one could use get.w instead of getw:
function b = get.w(a)
b = vertcat(a.w);
end
leads to an infinite recursion, I think, since a.w calls get.w.
jL
David Young
David Young 2012년 1월 17일
In fact, it looks like get.w does not work, but for a different reason.
There is no recursion, because within get.w a reference to a.w goes directly to the property. (Oddly enough, the documentation doesn't seem to say this for get methods, though it does say it for set methods. However, it has to be the case that recursion is avoided, or get methods just wouldn't be useful.)
The reason get.w fails is that it is called once for each element of the array, rather than being passed the whole array. (I don't understand the rationale for this.) What it boils down to is that it looks like you have to use an ordinary method like getw.

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Matrix Indexing에 대해 자세히 알아보기

제품

질문:

2012년 1월 13일

Community Treasure Hunt

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

Start Hunting!

Translated by