3 votes

Y a-t-il un moyen rapide d'agrandir les matrices n fois en dupliquant chaque ligne ?

Par exemple, [1 1 ; 2 2 ; 3 3] devient

[1 1
 1 1
 1 1
 2 2
 2 2
 2 2
 3 3
 3 3
 3 3]

J'utilise ceci : expander(orig,mult::Int) = orig[ceil(Int,(1:size(orig,1)*mult)/mult),:]; en Julia et ce qui suit en Matlab :

function expanded = expander(original,multiplier)
   expanded = original(ceil((1:size(original,1)*multiplier)/multiplier),:);
end

Une autre méthode seulement disponible en Matlab est la suivante :

expanded = kron(original,ones(multiplier,1));

Je préférerais une option Julia ultra-rapide si elle existe.

2voto

Michael Ohlrogge Points 6401

Cela ne prouve pas que kron est le plus rapide, mais j'ai comparé son temps à celui qu'il faudrait pour simplement remplir un tableau de même taille avec des uns, et kron s'en est très bien sorti:

original = [1 1 ; 2 2 ; 3 3];
multiplier = 3*10^6;

@time begin
    for idx = 1:100
        expanded = kron(original,ones(multiplier));
    end
end
## 9.199143 seconds (600 allocations: 15.646 GB, 9.05% gc time)

@time begin
    for idx = 1:100
        myones = [ones(multiplier*size(original,1))  ones(multiplier*size(original,1))];
    end
end
## 12.746123 seconds (800 allocations: 26.822 GB, 14.86% gc time)

Mise à jour En réponse aux commentaires de David Sanders, voici des tests encapsulés dans une fonction. La raison pour laquelle j'ai effectué les tests globalement, ce qui n'est pas une pratique optimale, est que j'ai trouvé assez plausible que les objets pourraient être créés globalement.

function kron_test(original, multiplier)
    for idx = 1:100
        expanded = kron(original,ones(multiplier));
    end
end

function ones_test(original, multiplier)
    for idx = 1:100
        myones = [ones(multiplier*size(original,1))  ones(multiplier*size(original,1))];
    end
end

## temps donnés après le premier appel de fonction pour compiler
@time kron_test(original, multiplier);  ## 11.107632 seconds (604 allocations: 15.646 GB, 23.98% gc time)
@time ones_test(original, multiplier);  ## 15.849761 seconds (604 allocations: 26.822 GB, 33.50% gc time)

1voto

isebarn Points 1803

Malheureusement, je n'ai aucune idée si cette méthode est "super rapide" mais elle est relativement simple et intuitive

a = [1 1 ; 2 2 ; 3 3]
a = a' #matrices are in column major order in julia, should  be faster this way
a = repmat(a,1,n) 
a = sortcols(a)

1voto

Matt B. Points 7271

Personnellement, je voudrais simplement utiliser repeat:

repeat(original, inner=[multiplier, 1])

Contrairement à kron, c'est très lisible et compréhensible. Malheureusement, c'est un peu plus lent. Malgré tout, je n'utiliserais kron que si vous l'avez identifié comme un goulot d'étranglement en termes de performances. Même si c'est plus rapide pour les ordinateurs d'exécuter, c'est beaucoup plus lent pour les humains de comprendre ce qui se passe… et les performances de repeat devraient éventuellement s'améliorer (c'est issue #15553).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X