matlab初始化对象数组

时间:2011-05-25 18:17:58

标签: arrays oop matlab

我在MATLAB中玩OOP,我有以下构造函数:

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

那个临时变量'a'闻起来很可怕。有没有更好的方法来初始化一个对象数组,我希望有一个推/弹方法。我相信有更好的方法可以做到这一点。

2 个答案:

答案 0 :(得分:10)

看起来您正在尝试创建一个句柄对象数组(Shooters)并将其存储在另一个句柄对象(Squardron)的属性中。我有一个非常similar problem discussion可能会帮助你。

简而言之:你在做什么可能并不漂亮 - 但可能已经很好了。

在Matlab中创建数组时,通常需要进行一些预分配以保留内存,从而显着提高性能。

正常情况下是这样的:

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

(这里a = 1:1000;会更好)

对于对象,预分配通过将其中一个对象分配给数组中的最后一个字段来工作。然后Matlab通过调用没有参数的该对象的构造函数来填充其创建的对象(句柄)之前的其他字段(请参阅Matlab help)。因此,对象的预分配可能如下所示:

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

或只是

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

确保可以在没有参数的情况下调用Shooter,您应该可以执行以下操作:

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

然而,事实证明,由于某种原因,将对象数组直接存储在另一个对象的属性中会产生非常糟糕的性能。 (在这种情况下,阵列预分配可能效果不佳)。因此,在这种情况下,使用辅助变量并立即将完整数组分配给属性是一个提高性能的好主意。

我会尝试:

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

再次 - 有关详细信息,请参阅this discussion

答案 1 :(得分:4)

有几种方法可以解决这种情况......

  • Building object arrays in the constructor:

    您可以修改Shooter类,以便在传递值数组时创建一个对象数组。然后你可以像这样初始化ShooterArray

    obj.ShooterArray = Shooter(repmat(num_targets,1,num_fighters),...
                               repmat(time_steps,1,num_fighters));
    
  • 复制值类的实例:

    如果Shootervalue class,并且每个对象将完全相同(即您没有将其任何默认属性初始化为随机值) ,然后你可以只创建一个对象并使用REPMAT复制它:

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

    不幸的是,如果Shooterhandle class的子类,则不能只使用值类复制它。当你真的需要一些单独的对象时,你实际上只会将引用复制到一个对象,每个对象都有自己独特的引用。在这种情况下,您当前的代码可能是最佳解决方案。