2011-05-25 34 views
5

estoy jugando un poco con programación orientada a objetos en MATLAB, y tengo el siguiente constructor:inicializar MATLAB matriz de objetos

 
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 

Esa variable temporal 'a' huele muy mal. ¿Hay una mejor manera de inicializar una matriz de objetos, ojalá hubiera un método push/pop? Estoy seguro de que hay una mejor manera de hacer esto.

+0

Sorprendentemente también se puede asignar array '' Shooter' directamente en Shooter' constructor: http://www.mathworks.com /help/techdoc/matlab_oop/brd4btr.html – Mikhail

+0

lo estoy asignando al constructor, ¿conoces una manera más limpia de hacerlo que usar una variable temporal? Tal vez me estoy perdiendo algo. – bonhoffer

+0

"Manera más limpia" es subjetivo ... Mi mensaje: funciona no solo en 'Squadron' sino también directamente en' Shooter' constructor. – Mikhail

Respuesta

10

Parece que usted está tratando de crear una matriz de objetos mango (tiradores) y guardarlo dentro de la propiedad de otro objeto mango (un Squardron). He tenido un muy similar problem discussion que podría ayudarte.

En resumen: Lo que estás haciendo podría no ser bonito, pero ya podría ser bastante bueno.

Al crear una matriz en Matlab, generalmente es una buena idea hacer una preasignación para reservar memoria, lo que acelera significativamente el rendimiento.

En un caso algo normal como esto:

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

(aquí a = 1: 1000; sería aún mejor)

Para los objetos de los trabajos de pre-asignación mediante la asignación de uno de los objetos de el último campo de la matriz. A continuación, Matlab llena los otros campos con objetos (identificadores) que crea llamando al constructor de ese objeto sin argumentos (consulte Matlab help).De ahí que una asignación previa de los objetos podría tener este aspecto:

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

o simplemente

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

Asegurarse tirador puede ser llamado sin argumentos que debería ser capaz de hacer algo como:

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

Sin embargo, resulta que por alguna razón este almacenamiento directo de una matriz de objetos en la propiedad de otro objeto crea un rendimiento muy malo. (Probablemente, la preasignación de matriz no funciona bien en este caso). Por lo tanto, usar una variable auxiliar y asignar toda la matriz de una vez a la propiedad es en este caso una buena idea para aumentar el rendimiento.

me gustaría probar:

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

Una vez más - para más detalles ver this discussion

4

Hay un par de maneras de manejar esta situación ...

  • Building object arrays in the constructor:

    Se podría modificar la clase Shooter de tal manera que cuando se pasa matrices de valores que crea una matriz de objetos. Posteriormente, se podría inicializar ShooterArray así:

    obj.ShooterArray = Shooter(repmat(num_targets,1,num_fighters),... 
              repmat(time_steps,1,num_fighters)); 
    
  • Replicación de instancias de una clase de valor:

    Si Shooter es una value class, y cada objeto va a ser exactamente la misma (es decir, no inicialice ninguna de sus propiedades predeterminadas a valores aleatorios), entonces puede crear solo un objeto y replicarlo usando REPMAT:

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

    Desafortunadamente, si Shooter es una subclase del handle class, no puede simplemente replicarlo como puede hacerlo con una clase de valor. En realidad, estaría replicando referencias en un solo objeto, cuando realmente necesita una cantidad de objetos separados, cada uno con su propia referencia única. En tal caso, su código actual es probablemente la mejor solución.