matlab initialize array of objects

15,411

Solution 1

Looks like you are trying to create an array of handle objects (Shooters) and store it inside the property of another handle object (a Squardron). I have had a very similar problem discussion that might help you.

In short: What you are doing might not be pretty - but might be pretty good already.

When creating an array in Matlab it is usually a good Idea to do some pre-allocation to reserve memory which speeds up performance significantly.

In a normal case something like this:

a=zeros(1,1000);
for n=1:1000
    a(n)=n;
end

(here a=1:1000; would be even better)

For objects the pre-allocation works by assigning one of the objects to the very last field in the array. Matlab then fills the other fields before that with objects (handles) that it creates by calling the constructor of that object with no arguments (see Matlab help). Hence a pre-allocation for objects could look like this:

a(1,1000)=ObjectConstructor();
for n=1:1000
    a(n)=ObjectConstructor();
end

or simply

for n=1000:-1:1
    a(n)=ObjectConstructor();
end

Making sure Shooter can be called with no arguments you should be able to do something like:

for iShooter = obj.num_shooters:-1:1
   obj.ShooterArray(iShooter) = Shooter(num_targets, time_steps);
end

However, it turns out that for some reason this direct storing of an array of objects in another object's property creates very bad performance. (Probably the array pre-allocation does not work well in this case). Hence using an auxiliary variable and allocating the full array at once to the property is in this case is a good idea to increase performance.

I would try:

for iShooter = obj.num_shooters:-1:1
   a(iShooter) = Shooter(num_targets, time_steps);
end
obj.ShooterArray = a;

Again - for more detail see this discussion

Solution 2

There are a couple of ways to handle this situation...

  • Building object arrays in the constructor:

    You could modify your Shooter class such that when you pass arrays of values it creates an array of objects. Then you could initialize ShooterArray like so:

    obj.ShooterArray = Shooter(repmat(num_targets,1,num_fighters),...
                               repmat(time_steps,1,num_fighters));
    
  • Replicating instances of a value class:

    If Shooter is a value class, and each object is going to be exactly the same (i.e. you don't initialize any of its default properties to random values), then you can create just one object and replicate it using REPMAT:

    obj.ShooterArray = repmat(Shooter(num_targets,time_steps),1,num_fighters);
    

    Unfortunately, if Shooter is a subclass of the handle class, you can't just replicate it as you can with a value class. You would actually be replicating references to just one object, when you really need a number of separate objects each with their own unique reference. In such a case, your current code is likely the best solution.

Share:
15,411
bonhoffer
Author by

bonhoffer

I work with anything that helps me do math: MATLAB, Excel, Python, FORTRAN or open-source web-development (PHP, Ruby/Rails, MySQL, Ajax, Jquery). I like GIS coding and working with maps, graphics. My research area is in stochastic processes.

Updated on June 11, 2022

Comments

  • bonhoffer
    bonhoffer almost 2 years

    I am playing around with OOP in MATLAB, and I have the following constructor:

    function obj = Squadron(num_fighters, num_targets, time_steps)            
        if nargin == 0
            num_targets = 100;
            time_steps = 100;
            num_fighters = 10;
        end
        obj.num_shooters = num_fighters;
        for iShooter = 1:obj.num_shooters
           a(iShooter) = Shooter(num_targets, time_steps);
        end
        obj.ShooterArray = a;
        obj.current_detections = zeros(num_fighters, num_targets);
    end
    

    That temporary variable 'a' smells terrible. Is there a better way to initialize an array of objects, I wish there was a push/pop method. I am sure there is a better way to do this.

    • Mikhail Poda
      Mikhail Poda almost 13 years
      Surprisingly you can also allocate Shooter array directly in Shooter constructor: mathworks.com/help/techdoc/matlab_oop/brd4btr.html
    • bonhoffer
      bonhoffer almost 13 years
      i am allocating it in the constructor, do you know of a cleaner way to do it than using a temporary variable? Maybe I'm missing something.
    • Mikhail Poda
      Mikhail Poda almost 13 years
      "Cleaner way" is subjective ... My message: it works not only in Squadron but also directly in Shooter constructor.
    • bonhoffer
      bonhoffer almost 13 years
      got you. I see what you are saying. That is cleaner.
    • Amro
      Amro over 12 years