Ich habe eine Funktion in einer generischen Klasse, die eine Determinante einer Matrix berechnet. Die Funktion funktioniert für einige Eingaben mit beliebigem Typ und für andere gibt sie die falsche Antwort (basierend auf dem Typ). HierUnterschiedliche Antwort basierend auf dem verwendeten arithmetischen Typ (kein Überlauf)
ist die Funktion:
public T Determinant()
{
checked
{
int n = dimension;
Matrix<T> a = new Matrix<T>(baseArray);
int i, j, k;
T det = (dynamic)0;
for (i = 0; i < n - 1; i++)
{
for (j = i + 1; j < n; j++)
{
det = (dynamic)a[j, i]/a[i, i];
for (k = i; k < n; k++)
a[j, k] = a[j, k] - (dynamic)det * a[i, k];
}
}
det = (dynamic)1;
for (i = 0; i < n; i++)
det = (dynamic)det * a[i, i];
return det;
}
}
ich hinzugefügt, um den checked
Block zu sehen, ob ein Überlauf war stattfindet, aber anscheinend gibt es keinen Überlauf passiert.
Eine Probe eingegeben wird, wenn die baseArray new double[,] {{11, 11, 12, 17, 21, 29}, {16, 9, 25, 30, 29, 33}, {3, 13, 9, 24, 21, 24}, {23, 6, 29, 21, 23, 23}, {22, 19, 14, 30, 21, 24}, {22, 28, 20, 17, 25, 28}};
ist, wird es die richtige Antwort geben (ganz in der Nähe -942.755), aber wenn baseArray statt new int[,] {{11, 11, 12, 17, 21, 29}, {16, 9, 25, 30, 29, 33}, {3, 13, 9, 24, 21, 24}, {23, 6, 29, 21, 23, 23}, {22, 19, 14, 30, 21, 24}, {22, 28, 20, 17, 25, 28}};
ist gibt es 15.934.050 als Antwort (nicht einmal in der Nähe).
Der Indexer auf der Matrix gibt nur die i-ten j-ten Elemente der Matrix zurück, also sind sie nicht das Problem.
Ich bin verwirrt, was das Problem sein könnte, da es kein Überlauf ist. Irgendwelche Ideen?
-Code zu reproduzieren:
public class Matrix<T>
where T : IConvertible
{
private int dimension;
private T[][] baseArray;
public Matrix(int dimensions, T[,] baseArray)
{
this.dimension = dimensions;
this.baseArray = new T[dimension][];
for (int i = 0; i < dimension; i++)
{
this.baseArray[i] = new T[dimension];
for (int j = 0; j < dimension; j++)
{
this[i, j] = baseArray[i, j];
}
}
}
public T this[int a, int b]
{
get
{
return baseArray[a][b];
}
set
{
baseArray[a][b] = value;
}
}
public T Determinant()
{
checked
{
int n = dimension;
Matrix<T> a = new Matrix<T>(baseArray);
int i, j, k;
T det = (dynamic)0;
for (i = 0; i < n - 1; i++)
{
for (j = i + 1; j < n; j++)
{
det = (dynamic)a[j, i]/a[i, i];
for (k = i; k < n; k++)
a[j, k] = a[j, k] - (dynamic)det * a[i, k];
}
}
det = (dynamic)1;
for (i = 0; i < n; i++)
det = (dynamic)det * a[i, i];
return det;
}
}
}
Jon ist natürlich richtig. Offensichtlich erhalten Sie unterschiedliche Ergebnisse, wenn Sie ganze Zahlen durch ganze Zahlen und doppelt durch doppelte Zahlen teilen. Was ich nicht verstehe, ist * warum gibt es überhaupt eine Einteilung in diesen Algorithmus *? Die Determinante kann unter Verwendung von Addition, Multiplikation und Subtraktion berechnet werden. –
@EricLippert, Link zum Beispiel? – soandos