Calcul de la matrice inverse Java
Je suis en train de calculer la matrice inverse en Java.
Je suis l'adjoint de la méthode (premier calcul de l'adjoint de la matrice, puis de transposer cette matrice et, enfin, de le multiplier par l'inverse de la valeur du déterminant).
Il fonctionne lorsque la matrice n'est pas trop grand. J'ai vérifié que pour les matrices jusqu'à une taille de 12 x 12, le résultat est rapidement fourni. Toutefois, lorsque la matrice est plus grand que 12x12 le temps qu'il faut pour compléter le calcul augmente de façon exponentielle.
La matrice j'ai besoin d'inverser est 19x19, et ça prend trop de temps. La méthode qui consomme plus de temps est la méthode utilisée pour le calcul du déterminant.
Le code que j'utilise est:
public static double determinant(double[][] input) {
int rows = nRows(input); //number of rows in the matrix
int columns = nColumns(input); //number of columns in the matrix
double determinant = 0;
if ((rows== 1) && (columns == 1)) return input[0][0];
int sign = 1;
for (int column = 0; column < columns; column++) {
double[][] submatrix = getSubmatrix(input, rows, columns,column);
determinant = determinant + sign*input[0][column]*determinant(submatrix);
sign*=-1;
}
return determinant;
}
Quelqu'un sait comment calculer le déterminant d'une matrice de grande taille de manière plus efficace? Si non, personne ne sait comment calcultate l'inverse d'une matrice de grande taille à l'aide d'autres algorithme?
Grâce
source d'informationauteur dedalo | 2010-01-02
Vous devez vous connecter pour publier un commentaire.
De façon exponentielle? Non, je crois inversion de matrice est O(N^3).
Je vous conseille d'utiliser La décomposition LU pour résoudre une équation matricielle. Vous n'avez pas à régler pour le facteur déterminant lorsque vous l'utilisez.
Mieux encore, se tournent vers un forfait pour vous aider. JAMA vient à l'esprit.
12x12 ou 19x19 ne sont pas de grandes matricies. Il est commun pour résoudre des problèmes avec des dizaines ou des centaines de milliers de degrés de liberté.
Voici un exemple de la façon d'utiliser le JAMA. Vous devez avoir le JAMA JAR dans le CLASSPATH lorsque vous compilez et exécutez:
Ici est le même problème, résolu en utilisant Apache Commons Mathématiques, par quant_dev recommandation:
Les adapter à votre situation.
Je vous conseille d'utiliser Apache Commons Mathématiques 2.0 pour cela. JAMA est un projet mort. ACM 2.0 a effectivement eu l'algèbre linéaire à partir de la JAMA et développée.
Inversion de matrice est de calcul intensif. Comme duffymo répondu LU est un bon algorithme, et il existe d'autres variantes (QR, par exemple).
Malheureusement, vous ne pouvez pas vous débarrasser de la lourde calculs... et peut-être le bottelneck est le getSubmatrix méthode si vous n'êtes pas à l'aide d'une bibliothèque optimisée.
Aussi, spéciale structures de la matrice (bande-matricity, la symétrie, la diagonality, sparsity) ont un impact considérable en termes de performance si, considérée dans les calculs. Votre kilométrage peut varier...
Vous ne voulez JAMAIS à calculer une matrice inverse de cette façon. Ok, le calcul de l'inverse de lui-même est à éviter, car il est presque toujours préférable d'utiliser une factorisation comme une LU.
Calcul du déterminant à l'aide de calculs récursifs est un numériquement obscène chose à faire. Il s'avère que le meilleur choix est d'utiliser une factorisation LU pour le calcul d'un déterminant. Mais, si vous allez à la peine de calculer LU facteurs, alors pourquoi voudriez-vous pour calculer l'inverse? Vous avez déjà fait le travail difficile par le calcul de la LU facteurs.
Une fois que vous avez LU les facteurs, vous pouvez les utiliser pour n'en arrière et en avant la substitution.
Autant qu'une 19x19 matrice être grand, il n'est même pas proche de ce que j'avais penser aussi grand.
Votre algorithme pour calculer un déterminant est exponentielle. Le problème de base est que vous êtes le calcul de la définition, et le droit de la définition conduit à une exponentielle de la quantité de subdeterminants à calculer. Vous avez vraiment besoin pour transformer la matrice d'abord avant de calculer son déterminant ou de son inverse. (J'ai pensé à expliquer la dynamique de la programmation, mais ce problème ne peut être résolu par programmation dynamique comme le nombre de sous-problèmes est exponentielle).
La décomposition LU, comme recommandé par d'autres, est un bon choix. Si vous êtes nouveau à la matrice de calcul, vous pouvez également regarder l'élimination de Gauss pour calculer les déterminants et inverses, qui pourraient être un peu plus facile à comprendre au premier abord.
Et n'oubliez pas une chose dans l'inversion de matrice est stabilité numérique, car vous avez affaire à des nombres à virgule flottante. Toutes les bonnes algorithme inclure des permutations de lignes et/ou colonnes de choisir le convenable pivots, comme ils sont appelés. Au moins dans l'élimination de Gauss, vous souhaitez, à chaque étape, de permuter les colonnes de sorte que l'élément le plus important en valeur absolue est choisi comme pivot, comme c'est le stablest choix.
La la4j (Algèbre Linéaire pour Java) bibliothèque prend en charge inversion de matrice. Voici le bref exemple:
Il est difficile à battre Matlab à leur jeu. Ils sont aussi cautiou au sujet de la précision. Si vous avez 2.0 et 2.00001 comme pivots - attention! Votre réponse pourrait être très imprécise. Aussi, découvrez Python de mise en œuvre (c'est dans numpy /scipy quelque part ...)
Avez-vous d'avoir une solution exacte? Une évaluation approximative du solveur (Gauss-Seidel est très performante et facile à mettre en œuvre) sera probablement travailler pour vous, et convergent très rapidement. 19x19 est une petite matrice. Je pense que le Gauss-Seidel code que j'ai utilisé pourrait résoudre un 128x128 pixels de la matrice dans le clignotement d'un oeil (mais ne pas me citer, ça fait un moment).
Depuis ACM de la bibliothèque a mis à jour au fil des ans, ici est la mise en œuvre conforme à la dernière définition pour l'inversion de matrice.