Tester si deux matrices 12x12 ont le même déterminant

11

On me donne une matrice symétrique, inversible, définie positive et dense. Je dois tester si où J est la matrice des uns.12×12QJ

det(Q)=det(12IQJ)(1)
J

Je fais actuellement cela avec la bibliothèque de tatou mais cela s'avère trop lent. Le fait est que je dois le faire pour un billion de matrices et il s'avère que le calcul des deux déterminants est le goulot d'étranglement de mon programme. J'ai donc deux questions

  1. Y a-t-il une astuce que je pourrais utiliser pour calculer le déterminant plus rapidement étant donné que je connaissais sa taille? Une extension désordonnée pour les matrices 12×12 pourrait-elle fonctionner dans ce cas?

  2. Existe-t-il un autre moyen efficace de tester l'égalité (1)

Éditer. Pour répondre aux commentaires. J'ai besoin de calculer tous les graphes connectés non auto-complémentaires G d'ordre 13 telle sorte que G et G¯ aient le même nombre d'arbres couvrant. La motivation pour cela peut être trouvée dans ce post de mathoverflow . En ce qui concerne la machine, je l'exécute en parallèle sur une machine à 8 cœurs 3,4 GHz.

Éditer. J'ai pu réduire le temps d'exécution prévu de 50% en créant un programme C pour calculer spécifiquement le déterminant d'une matrice 12×12 . Les suggestions sont toujours les bienvenues.

Jernej
la source
6
Comment lent est trop lent? Combien de temps faut-il sur quel matériel? Les milliers de milliards de ces sont-ils indépendants pour que vous puissiez calculer plusieurs de ces déterminants en parallèle? Si oui, quelle taille pouvez-vous utiliser sur une machine? Qu'est-ce qui a provoqué ce problème? Êtes-vous sûr de devoir calculer les déterminants? Q
Bill Barth
3
À quelle fréquence (pour quelle fraction des cas) les déterminants sont-ils identiques / différents? S'ils sont différents la plupart du temps, il peut y avoir un test moins cher pour déterminer qu'ils peuvent être différents et vous vérifierez qu'ils ne sont identiques que si le premier test échoue. Inversement s'ils sont les mêmes la plupart du temps.
Wolfgang Bangerth
1
Comme déjà demandé: pourriez-vous fournir des détails sur la provenance de ? Il y a peut-être une meilleure approche que de calculer aveuglément les déterminants. Q
JM
4
L'idée que cette condition doit être testée "pour un billion de matrices" suggère 1) que est connu apriori pour avoir une certaine structure spéciale (sinon l'attente que la condition tient au hasard est faible), et 2) qu'une meilleure approche pourrait être de caractériser toutes les matrices avec cette propriété (avec une formulation vérifiable efficacement). QQQ
hardmath
1
@hardmath Oui, est une matrice entière ayant des entrées diagonales allant de à et comme éléments hors diagonale1 12 - 1Q1121
Jernej

Réponses:

8

Puisque vous utilisez déjà C ++ et que vos matrices sont définies positives symétriques, j'effectuerais une factorisation pivotée de et également de . Ici, je suppose que est également défini positif, sinon le nécessitera un pivotement pour la stabilité numérique (il est également possible que même s'il n'est pas défini positif, le pivotement ne soit pas nécessaire, mais vous devez l'essayer). Q 12 I - Q - J 12 I - Q - J L D L TLDLTQ12IQJ12IQJLDLT

C'est plus rapide qu'une factorisation LU, et aussi plus rapide que Cholesky car les racines carrées sont évitées. Le déterminant est simplement le produit des éléments de la matrice diagonale . Le code pour effectuer une factorisation LDL est si simple que vous pouvez l'écrire en moins de 50 lignes de C. La page Wikipedia à ce sujet décrit l'algorithme, et j'ai un code simple pour faire Cholesky ici . Vous pouvez grandement simplifier cela et le modifier pour éviter que la racine carrée implémente la factorisationL D L TDLDLT

Étant donné que vous pouvez également contrôler le format de stockage, vous pouvez optimiser davantage la routine pour stocker uniquement la moitié de la matrice et l'emballer dans un tableau linéaire pour maximiser la localité de la mémoire. J'écrirais également de simples routines de mise à jour personnalisées de produits scalaires et de rang 1, car les tailles de problème sont si petites que vous devriez laisser le compilateur aligner les routines pour réduire la surcharge des appels. Puisqu'il s'agit d'une boucle de taille fixe, le compilateur devrait être en mesure d'inclure et de dérouler automatiquement les choses le cas échéant.

J'éviterais d'essayer de jouer des tours pour profiter du fait que contient à l'intérieur de l'expression. Il est probable que pour de si petites tailles de problème, ces astuces finissent par être plus lentes que de simplement effectuer deux calculs déterminants distincts. Bien sûr, la seule façon de vérifier ces affirmations est de l'essayer.Q12IQJQ

Victor Liu
la source
1
J'appuie la recommandation de mettre en œuvre , alias Cholesky sans racine, car Armadillo ne semble pas avoir un moyen de tirer parti de la définition positive / dominance diagonale. LDLT
hardmath
5

Sans quelques informations sur la construction de ces matrices symétriques réelles définies positives , les suggestions à faire sont nécessairement assez limitées.12×12

J'ai téléchargé le paquet Armadillo de Sourceforge et j'ai jeté un œil à la documentation. Essayez d'améliorer les performances du calcul séparé de et , où est la matrice de rang 1 de toutes les unités, en définissant par exemple . La documentation note que c'est la valeur par défaut pour les matrices jusqu'à la taille , donc par omission je suppose que l' option est une valeur par défaut pour le cas .det(Q)J 4 × 4 12 × 12det(12IQJ)Jdet(Q,slow=false)4×4slow=true12×12

Ce qui est slow=true vraisemblablement fait est un pivot partiel ou total pour obtenir une forme d'échelon de ligne, à partir de laquelle le déterminant est facilement trouvé. Cependant, vous savez à l'avance que la matrice est définie positive, donc le pivotement n'est pas nécessaire pour la stabilité (au moins présumément pour la majeure partie de vos calculs. Il n'est pas clair si le paquet Armadillo lève une exception si les pivots deviennent trop petits, mais cela devrait être un fonctionnalité d'un package d'algèbre linéaire numérique raisonnable. EDIT: J'ai trouvé le code Armadillo qui implémente dans le fichier d'en-tête , en utilisant des modèles C ++ pour des fonctionnalités substantielles. Le paramètre ne semble pas affecter la façon dont un12 × 12Qdetinclude\armadillo_bits\auxlib_meat.hppslow=false12×12le déterminant sera fait parce que le calcul est "jeté sur un mur" vers LAPACK (ou ATLAS) à ce point sans indication que le pivotement n'est pas requis; voir det_lapacket ses invocations dans ce fichier.

L'autre point serait de suivre leur recommandation de construire le paquet Armadillo lié aux remplacements à haute vitesse pour BLAS et LAPACK, si vous les utilisez effectivement; voir Sec. 5 du fichier README.TXT d'Armadillo pour plus de détails. [L'utilisation d'une version 64 bits dédiée de BLAS ou LAPACK est également recommandée pour la vitesse sur les machines 64 bits actuelles.]

La réduction des lignes en échelon est essentiellement une élimination gaussienne et a une complexité arithmétique . Pour les deux matrices, cela équivaut alors au double de ce travail, ou . Ces opérations peuvent bien être le "goulot d'étranglement" dans votre traitement, mais il y a peu d'espoir que sans structure spéciale dans (ou certaines relations connues parmi les milliards de cas de test permettant l'amortissement), le travail pourrait être réduit à .423n3+O(n2)QO(n2)43n3+O(n2)QO(n2)

A titre de comparaison, l'expansion par les cofacteurs d'une matrice générale impliqueles opérations de multiplication (et à peu près autant d'additions / soustractions), donc pour la comparaison ( vs ) favorise clairement l'élimination par rapport aux cofacteurs.n ! n = 12 12 ! = 479001600 2n×nn!n=1212!=47900160023n3=1152

Une autre approche nécessitant un travail consisterait à réduire en forme tridiagonale avec des transformations de Householder, ce qui met également en forme tridiagonale. Les calculs et peuvent ensuite être effectués dans des opérations . [L'effet de la mise à jour de rang un dans le deuxième déterminant peut être exprimé comme un facteur scalaire donné en résolvant un système tridiagonal.]Q12I-Qdet(Q)det(12I-Q-J)O(n)-J43n3+O(n2)Q12IQdet(Q)det(12IQJ)O(n)J

La mise en œuvre d'un tel calcul indépendant pourrait être utile pour vérifier les résultats des appels réussis (ou échoués) à la detfonction d'Armadillo .

Cas spécial: comme suggéré par un commentaire de Jernej, supposons que où comme avant est la matrice (rang 1) de tous les uns et est un matrice diagonale non singulière (positive). En effet, pour l'application proposée en théorie des graphes, il s'agirait de matrices entières. Alors une formule explicite pour est:J D = diag ( d 1 , , d n ) det ( Q )Q=DJJD=diag(d1,,dn)det(Q)

det(Q)=(i=1ndi)(1i=1ndi1)

Une esquisse de sa preuve donne l'occasion d'illustrer une applicabilité plus large, c'est-à-dire chaque fois que a un déterminant connu et que le système est rapidement résolu. Commencez par prendre en compte:D v = ( 1 1 ) TDDv=(11)T

det(DJ)=det(D)det(ID1J)

Maintenant est à nouveau rang 1, à savoir . Notez que le deuxième déterminant est simplement:( d - 1 1d - 1 n ) T ( 1 1 )D1J(d11dn1)T(11)

f(1)=det(ID1J)

où est le polynôme caractéristique de . En tant que matrice de rang 1, doit avoir (au moins) facteurs de pour tenir compte de son espace nul. La valeur propre "manquante" est , comme le montre le calcul:D - 1 J f ( x ) n - 1 x d - 1 if(x)D1Jf(x)n1xdi1

D1J(d11dn1)T=(di1)(d11dn1)T

Il s'ensuit que le polynôme caractéristique , et est comme indiqué ci-dessus pour , .f ( 1 ) det ( I - D - 1 J ) 1 - d - 1 if(x)=xn1(xdi1)f(1)det(ID1J)1di1

Notez également que si , alors , une matrice diagonale dont le déterminant est simplement le produit de ses entrées diagonales.12 I - Q - J = 12 I - D + J - J = 12 I - DQ=DJ12IQJ=12ID+JJ=12ID

hardmath
la source
Hm .. est en fait où est la matrice d'adjacence de donc je pense que ce résultat peut ne pas être correct. En particulier, cela impliquerait que le nombre d'arbres couvrant un graphe est déterminé par sa séquence de degrés qui ne tient pas. D - A A G GQDAAGG
Jernej
Les entrées hors diagonale de contiendront alors généralement 0 ainsi que -1. La décomposition suggérée par Victor tire parti de la symétrie et réduit le terme principal du nombre d'opérations de à . Il existe une approche en nombres entiers exacte, mais elle n'est probablement pas nécessaire pour votre matrice de taille modeste et vos entrées. Si je comprends la construction, est défini positif pour la même raison que est. L D L T 2QLDLT123n312I-Q-JQ13n312IQJQ
hardmath
@Jernej: Si vous pensez que quelque chose que j'ai déclaré est incorrect, j'ai créé une salle de chat basée sur cette question où la discussion peut être discutée sans commentaires inutiles ici.
hardmath
1

Si vous avez une façon structurée d'énumérer les graphiques dont vous souhaitez calculer les déterminants, vous pourriez peut-être trouver des mises à jour de bas rang qui vous transfèrent d'un graphique à un autre.

Si tel est le cas, vous pouvez alors utiliser le lemme déterminant de matrice pour calculer à moindre coût le déterminant du graphique suivant à énumérer en utilisant votre connaissance du déterminant du graphique actuel.

Autrement dit, pour une matrice et des vecteurs : Ceci peut être généralisé si U et V sont matrices et est : Au,v

det(A+uvT)=(1+vTA1u)det(A)
n×mAn×n
det(A+UVT)=det(Im+VTA1U)det(A)

Pour calculer efficacement l'inverse, vous pouvez utiliser la formule de Sherman-Morrison pour obtenir l'inverse de la matrice suivante à partir de la matrice actuelle:

(A+uvT)1=A1A1uvTA11+vTA1u

Richard
la source