2017-10-13 1 views
-1

Les résultats de mon code Gauss Elimination sont -nan dans Visual Studio, mais pas sous Linux.Pourquoi mon code renvoie -nan dans Visual Studio, mais pas sous Linux?

Et les résultats de Linux sont affreux car à la fonction Gauss_Eli combien j'augmente la variable k à pour les blocs que la fonction fonctionne ... ne se produit pas d'erreur de segment.

Quel est le problème avec mon code?

float ** Gauss_Eli(float ** matrix, int n) { 

    // ----------------------------------------------------- 
    // |             | 
    // | Eliminate elements except (i, i) element  | 
    // |             | 
    // ----------------------------------------------------- 

    // Eliminate elements at lower triangle part 

    for (int i = 0; i < n; i++) { 
     for (int j = i + 1; j < n; j++) { 
      for (int k = 0; k < n + 1; k++) { 
       float e; 
       e = matrix[i][k] * (matrix[j][i]/matrix[i][i]); 
       matrix[j][k] -= e; 
      } 
     } 
    } 

    // Eliminate elements at upper triangle part 

    for (int i = n - 1; i >= 0; i--) { 
     for (int j = i - 1; j >= 0; j--) { 
      for (int k = 0; k < n + 1; k++) { 
       float e; 
       e = matrix[i][k] * (matrix[j][i]/matrix[i][i]); 
       matrix[j][k] -= e; 
      } 
     } 
    } 

    // Make 1 elements i, i 

    for (int i = 0; i < n; i++) 
     for (int j = 0; j < n + 1; j++) matrix[i][j] /= matrix[i][i]; 

    return matrix; 
} 

int main() { 
    float ** matrix; 
    int n; 
    printf("Matrix Size : "); 
    scanf("%d", &n); 

    // Malloc variable matrix for Matrix 

    matrix = (float**)malloc(sizeof(float) * n); 
    for (int i = 0; i < n; i++) matrix[i] = (float*)malloc(sizeof(float) * (n + 1)); 

    printf("Input elements : \n"); 
    for (int i = 0; i < n; i++) 
     for (int j = 0; j < n + 1; j++) scanf("%f", &matrix[i][j]); 

    matrix = Gauss_Eli(matrix, n); 
    printf("Output result : \n"); 

    //Print matrix after elimination 

    for (int i = 0; i < n; i++) { 
     for (int j = 0; j < n + 1; j++) printf("%.6f ", matrix[i][j]); 
     printf("\n"); 
    } 
    return 0; 
} 
+0

Vous avez une division par zéro quelque part. Vérifiez toutes les divisions que vous avez. –

+0

Bien sûr 'matrix [i] [i]' n'est jamais 0.0 avant utilisation dans '.../matrix [i] [i]);'? – chux

+1

'matrice = (float **) malloc (sizeof (float) * n);' est faux. Utilisez 'matrix = malloc (sizeof * matrix * n);' et évitez l'erreur d'utiliser la mauvaise taille. – chux

Répondre

0

1.) L'OP alloue la mémoire en utilisant un mauvais type. Cela peut conduire à des problèmes de mémoire insuffisante et de toutes sortes d'UB et expliquer la différence entre les systèmes car ils peuvent avoir des pointeurs différents et des tailles différentes.

float ** matrix;      
//         v--- wrong type  
// matrix = (float**)malloc(sizeof(float) * n); 

Au lieu d'allouer à la taille de la variable référencée. Plus facile à coder (et à corriger), à revoir et à maintenir.

matrix = malloc(sizeof *matrix * n); 
if (matrix == NULL) Handle_Error(); 

2.) Code devrait chercher division par 0.0

 //for (int k = 0; k < n + 1; k++) { 
     // float e; 
     // e = matrix[i][k] * (matrix[j][i]/matrix[i][i]); 
     // matrix[j][k] -= e; 
     //} 
     if (matrix[i][i] == 0.0) Handle_Error(); 
     float m = matrix[j][i]/matrix[i][i]; 
     for (int k = 0; k < n + 1; k++) { 
      matrix[j][k] -= matrix[i][k]*m; 
     } 

3.) Problème général des conseils de résolution:

Vérifier les valeurs de retour de scanf("%f", &matrix[i][j]);. C'est 1?

Activer tous les avertissements.

Spécialement pour le débogage, imprimez FP en utilisant "%e" plutôt que "%f".

4.) pointe d'analyse numérique: Assurer la soustraction exacte lorsque i==j

 if (i == j) { 
      for (int k = 0; k < n + 1; k++) { 
      matrix[j][k] = 0.0; 
      } 
     else { 
      if (matrix[i][i] == 0.0) Handle_Divide_by_0(); 
      float m = matrix[j][i]/matrix[i][i]; 
      for (int k = 0; k < n + 1; k++) { 
      matrix[j][k] -= matrix[i][k]*m; 
      } 
     }