7
votes

Produit extérieur / tensor dans R

donné p code> vecteurs x1, x2, ..., xp code> chacun des dimensions d code>, quel est le meilleur moyen de calculer leur tenseur / Produit extérieur / kruskal (le p code> -Array x avec entrées x [i1, i2,. ip] = x1 [I1] x2 [I2] ... XP [IP]) ? La boucle est triviale, mais stupide. Utilisation d'appels répétés sur OUTER CODE> fonctionne OK, mais ne semble pas être la solution optimale (et sera plus lente que P augmente, évidemment). Existe-t-il une meilleure façon?

Edit: P>

Mon meilleur actuel est P>

d=3
x1 = 1:d
x2 = 1:d+3
x3 = 1:d+6
array(apply(expand.grid(x1, x2, x3), 1, prod), dim=rep(d, 3))

, , 1

     [,1] [,2] [,3]
[1,]   28   35   42
[2,]   56   70   84
[3,]   84  105  126

, , 2

     [,1] [,2] [,3]
[1,]   32   40   48
[2,]   64   80   96
[3,]   96  120  144

, , 3

     [,1] [,2] [,3]
[1,]   36   45   54
[2,]   72   90  108
[3,]  108  135  162


6 commentaires

Cela pourrait répondre à votre question - Stackoverflow.com/questions/6192848/...


La réponse acceptée est assez lente; Il semble être plus lent que les appels répétés à l'extérieur (sans surprise donnés à quel point il est général). Mais je pense que peut-être que la seconde peut être adaptée ...


Je serais très surpris si la solution expand.grid était plus rapide que la solution externe .


@Dwin, vous auriez raison d'être surpris; J'ai écrit trop tôt. Les applications répétées de l'extérieur () l'ont à ce moment-là - c'est environ deux fois plus vite dans certains tests limités. Tant pis.


Les opérations généralement matricielles (kronecker et externe) surperformeront des opérations de Dataframe (expand.grid), souvent par une marge substantielle.


En effet. Je pensais que peut-être appeler externe (extérieur (extérieur ... se rattraperait-il, mais ce n'est pas pour des problèmes de taille raisonnable, de toute façon). Je pensais peut-être qu'il y avait une seule fonction, ou une bibliothèque de tenseur appelant le code compilé, mais apparemment pas.


3 Réponses :


1
votes

Vous pouvez utiliser TENSOR Package.

et Aussi % o% fonction xxx


3 commentaires

Eh bien, % o% est exactement externe (x, y, '*') de sorte que cela n'aidera pas le problème de la vitesse. Comme toujours, :-) Je dois demander: "Quel est le problème que vous essayez de résoudre?" Il est possible qu'il y a une manière différente de vos données.


Je sais comment prendre le produit extérieur d'une échéance de deux matrices (ou deux vecteurs); Ce n'est pas ce dont j'ai besoin. En regardant le paquet Tensor, il n'est pas immédiatement clair pour moi comment cela aiderait.


@CARL WITTHOFT Le tableau résultant est (presque) la PMF conjointe d'une variable discrète multivariée. J'ai besoin de ce PMF approximatif ou un moyen de renvoyer toutes ses entrées supérieures à une valeur, ainsi que la somme des entrées.



1
votes

Je me trouve me demandant si le produit Kronecker est ce que vous voulez. Je ne peux pas dire à votre problème de description exactement ce qui est souhaité, mais les éléments de ceci sur un petit ensemble d'arguments sont les mêmes (bien que dans un autre arrangement que ceux de la solution chalasani, vous critiquiez comme lents: xxx < / pré>

Si vous voulez des produits, remplacez-le, sous prod ou "*". Dans tout cas, offrant un ensemble d'échantillons de vecteurs et la sortie souhaitée est une meilleure pratique dans la pose de questions.


2 commentaires

Désolé, je pensais qu'il était clair de la question que la sortie doit être une matrice, pas une matrice. J'ai ajouté un exemple pour clarifier. Toutes mes entrées sont des vecteurs, de sorte que Kronecker et externe sont équivalents. Remplacement de la fonction Kronecker dans votre réponse avec un autre appel à l'extérieur a été la solution que j'ai initialement eue, qui retourne un tableau.


Oui, c'était la raison pour laquelle j'ai mentionné l'arrangement différent. Votre cas d'utilisation n'a pas été décrit, je pensais que cela pourrait satisfaire.



7
votes

Il sera difficile de battre les performances de externe . Cela finit par faire une multiplication de matrice qui se fait par la bibliothèque de Blas. Appelant externe n'a pas d'importance à plusieurs reprises non plus, car le dernier appel dominera la vitesse et la mémoire sage. Par exemple, pour les vecteurs de longueur 100, le dernier appel est d'au moins 100 fois plus lentement que le précédent ...

Votre meilleur pari pour obtenir la meilleure performance ici est d'obtenir la meilleure bibliothèque Blas pour R. Le par défaut ISN 't très bien. Sur Linux, vous pouvez configurer assez facilement R pour utiliser Atlas Blas. Sous Windows, il est plus difficile, mais possible. Voir R pour FAQ Windows . xxx

J'ai remplacé mon Windows rblas.dll avec la version dynamic_arch de goto blas à Cet endroit qui améliore le temps de 0,5 à 0,35 sec, comme indiqué ci-dessus.


3 commentaires

Logique. Je me demandais principalement s'il y avait quelque chose à la base, je me manquais, mais je suppose que c'est vraiment une sorte de chose spécialisée. Merci.


Plutôt que de créer mouteur Vous pouvez utiliser réduire : réduire ("% o%", liste (x1, x2, x3)) . Ne pensez pas que la performance changerait beaucoup cependant.


/ Ref: Les estimations de la vitesse d'accélération à partir d'une blas optimisée peuvent être un ordre de grandeur plus élevé: blog.felixriedel.com/2012/10/...