Unbekannter Bug in C Program - Bitte um Hilfe



  • Th schrieb:

    Netter Bug:

    Du hast in der Schleife bei "coupen += ..." an einigen Stellen nicht die Schleifenvariablen abgefragt, sondern setzt sie immer wieder:

    (k=0 && ...) // <- falsch
    (k==0 && ...) // <- richtig
    

    Und dies mehrfach und weiter unten bei 'flipping' auch (C&P-Fehler?).

    Gibt dein Compiler keine Warnungen aus? Sonst schalte mal alle Warnungen ein (-w-all oder so ähnlich).

    AHA! Ja das war der entscheidene Bug, alles andere sollte jetzt schnell zu debuggen sein! Vielen, vielen Dank fuer diesen Tipp!!!! Wenn ich dich kennen wuerde wuerd ich dir sofort ein Bier ausgeben!
    Juhu! 😃

    Herzlichen Dank fuer die Hilfe aller Beteiligter!

    PS. -Wall war auch ein sehr guter Tipp uebrigens! Haette ich auch vorher dran denken sollen...
    PPS. Werd Annotationen einfuegen worauf die Klammern sich beziehen obwohl ich nicht finde, dass die Einrueckungen miserabel sind..
    PPS. ^^ \n stimmt auch! Danke!



  • Hallo,

    ein weitere Fehler ist die Bedingung der for-Schleife in Zeile 91

    for(m=1;m==end;m++)
    

    Schon für m==1 ist die Bedingung nicht erfüllt: 1==500?

    Ich nehme mal an, es sollte

    for (m=1; m<=500; ++m)
    

    heißen.

    Gruß mcr



  • So ein Blitzmerker 😃 den Fehler hatte ich schon in der ersten Anwort erwähnt



  • CStoll schrieb:

    So ein Blitzmerker 😃 den Fehler hatte ich schon in der ersten Anwort erwähnt

    Stimmt, sorry. 🙂

    Hatte ich überlesen.

    @edit: Aber es ist schon schwer, die richtigen Zeilennummer zu zitieren.



  • Hallo,

    mir hat dieser Block coupen += () ? .. : ..; nicht gefallen. Dabei ist
    mir aufgefallen, dass man es wie folgt kürzen kann:

    coupen += spin[k][l] * (spin[(k+N-1)%N][l] + spin[(k+1)%N][l] + spin[k][(l+N-1)%N] + spin[k][(l+1)%N]);
    

    Ebenso die Zeile dcoupen += ...;

    Gruß mcr



  • mcr schrieb:

    Hallo,

    ein weitere Fehler ist die Bedingung der for-Schleife in Zeile 91

    for(m=1;m==end;m++)
    

    Schon für m==1 ist die Bedingung nicht erfüllt: 1==500?

    Ich nehme mal an, es sollte

    for (m=1; m<=500; ++m)
    

    heißen.

    Gruß mcr

    Vielen Dank fuer den Hinweis! Den Fehler hatte ich allerdings zwischendurch schon korrigiert nach Hinweis von CStoll
    ...trotzdem natuerlich vielen Dank!



  • duck schrieb:

    Wenn ich dich kennen wuerde wuerd ich dir sofort ein Bier ausgeben!

    Ist wohl gut so, denn ich trinke keinen Alkohol!



  • Th schrieb:

    duck schrieb:

    Wenn ich dich kennen wuerde wuerd ich dir sofort ein Bier ausgeben!

    Ist wohl gut so, denn ich trinke keinen Alkohol!

    hehe nagut dann eben einen O-Saft oder so..



  • Th schrieb:

    duck schrieb:

    Wenn ich dich kennen wuerde wuerd ich dir sofort ein Bier ausgeben!

    Ist wohl gut so, denn ich trinke keinen Alkohol!

    dann gib mir das bier!
    🙂



  • Hallo noch einmal,

    das Program scheint jetzt endlich zu funktionieren. Allerdings hab ich ein Problem mit dem array am Anfang spin[][], wenn ich 20x20 als Groess nehme funktioniert alles, aber ab 25x25 bekomme ich Berechnungsfehler und auf einmal negative Werte fuer Variablen die nicht negativ werden koennen, m z.B. Kann ich das irgendwie vermeiden indem ich dem Program mehr Speicher zuteile o.A.? Wenn ja, wie?

    Vielen Dank!

    Hier die aktuelle Version des Codes:

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h> /* Don't forget to link the maths library when compiling the program -lm */
    #include <time.h>
    
    int main(int argc, char **argv)
    {
      // Declaring variables, end: total no of sweeps, N:lattice size NxN 
      // B and J are actually B/KT etc.
    
      int end=1000, N=20;
      int i, j, k, l, m=0, n;        /* m: total number of sweeps, n: flip attempts within one sweep */
      int mod=0, identical;
      int spin[20][20];
      int M=0, CM=0;
    
      char setup;
    
      double B=0, J=0.4;
      double a, b, z;
    
      FILE *fout;
    
      double dcoupen, dexten, dE, d;
      double r;
    
      // Get command line input
    
      switch (argc)
      {
      case 6:
        sscanf(argv[5], "%d", &mod);
      case 5:
        sscanf(argv[4], "%d", &end);
      case 4:
        sscanf(argv[3], "%lf", &B);
      case 3:
        sscanf(argv[2], "%lf", &J);
      }
    
      printf("Syntax is: ./main file J B end mod\n");
      printf("Default is: output.data 0.4 0 1000 0\n");
      printf("Do you wish to set up the lattice randomly or magnetized (r/m)?(r) \n");
      scanf("%s", &setup);
    
      // Setting up the lattice
    
      srand48((unsigned int) time(NULL)); /* Seed random number generator */ 
    
      if(setup=='m')
        {
          for(i=0;i<=(N-1);i++)
    	{
    	  for(j=0;j<=(N-1);j++)
    	    {
    	      spin[i][j]=1;
    	    }
    	  printf("|\n");
    	}
        }
      else                                  /* Default is randomized setup */
        for(i=0;i<=(N-1);i++)               /* Assgin a random value to each spin */
          {
    	for(j=0;j<=(N-1);j++)
    	  {
    	    do                          /* Do ... while as to execute the loop at least once */
    	    {
    	      a = drand48();
    	      b = drand48();
    	      identical = 0;
    
    	      if(a>b)
    		{
    		  spin[i][j] = 1.0;
    		}
    	      else if(b>a)
    		{
    		  spin[i][j] = -1.0;
    		}
    	      else
    		identical = 1;
    	    } while(identical==1);
    	  }
          }
    
      // Check whether file is accessible
    
      if(argc>=2) /* Use entered file name */
        {
          if ((fout = fopen(argv[1], "w")) == NULL)
    	{
    	  printf("Cannot open file '%s'\n", argv[1]);
    	  exit(1);
    	}
        }
      else /* Otherwise use default file name */
        {
          if ((fout = fopen("output.data", "w")) == NULL)
    	{
    	  printf("Cannot open file 'output.data'\n");
    	  exit(1);
    	}
        }
    
      fprintf(fout, "# Sweep   M\t\tCM\n");   /* # makes gnuplot ignore this line*/
    
      // Print out initial state 
    
      for(i=0;i<=(N-1);i++)
        {
          for(j=0;j<=(N-1);j++)
    	    {
    	      M += spin[i][j];
    	    }		
        }
    
      CM += M;
    
      fprintf(fout, "%3d\t%4d\t%4d\n", m, M, CM);
    
      // Flipping 
        for(m=1;m<=end;m++)
          {                       /* Initialises sweep loop */
          for(n=1;n<=(N*N);n++)   /* Flip attempts withing one sweep */
    	{                     /* Initialises flipping loop */
            // Get random numbers
            k = (int) ceil(N * drand48()); 
            l = (int) ceil(N * drand48());
            z = drand48();
    
            d = 2.0 * J * spin[k][l]; /* dcoupen = - 2 spin[k][l] * (-J) * sum of neighbouring spins */
            dcoupen = (k==0 && l==0) ? d * (spin[(N-1)][l] + spin[(k+1)][l] + spin[k][(N-1)] +spin[k][(l+1)]) :
    	  (k==0 && l!=0 && l!=(N-1)) ? d * (spin[(N-1)][l] + spin[(k+1)][l] + spin[k][(l-1)] +spin[k][(l+1)]) :
    	  (k==0 && l==(N-1)) ? d * (spin[(N-1)][l] + spin[(k+1)][l] + spin[k][(l-1)] +spin[k][0]) :
    	  (k!=0 && k!=(N-1) && l==0) ? d * (spin[(k-1)][l] + spin[(k+1)][l] + spin[k][(N-1)] +spin[k][(l+1)]) :
    	  (k==(N-1) && l==0) ? d * (spin[(k-1)][l] + spin[0][l] + spin[k][(N-1)] +spin[k][(l+1)]) :
    	  (k!=0 && k!=(N-1) && l==(N-1)) ? d * (spin[(k-1)][l] + spin[(k+1)][l] + spin[k][(l-1)] +spin[k][0]) :
    	  (k==(N-1) && l!=0 && l!=(N-1)) ? d * (spin[(k-1)][l] + spin[0][l] + spin[k][(l-1)] +spin[k][(l+1)]) :
    	  (k==(N-1) && l==(N-1)) ? d * (spin[(k-1)][l] + spin[0][l] + spin[k][(l-1)] +spin[k][0]) : 
    	  d * (spin[(k-1)][l] + spin[(k+1)][l] + spin[k][(l-1)] +spin[k][(l+1)]);  	
    
        	dexten = -2.0 * B * spin[k][l];
        	dE = dcoupen + dexten;
    
        	r = exp(dE);
    
    	// Only if r>z perform the flip
    	if(r>z)
    	  {
    	    spin[k][l] = - spin[k][l];
    	  }
    
    	}   /* Closes flipping loop */
    
          // Print configuration to screen after each sweep, as + and -
          for(i=0;i<=(N-1);i++)
    	{
    	  for(j=0;j<=(N-1);j++)
    	    {
    	      if(spin[i][j]==1.0)
    		printf("+");
    	      if(spin[i][j]==-1.0)
    		printf("-");
    	    }
    	  printf("|\n");
    	}
          printf("\n\n\n\n");
    
          // Calculate M and CM and save them to file, cumulation starts after 50 sweeps
    
          M = 0; /* Reset M to 0 between flips */
    
          for(i=0;i<=(N-1);i++)
    	{
    	  for(j=0;j<=(N-1);j++)
    	    {
    	      M += spin[i][j];
    	    }		
    	}
    
    	  CM += M;
    
          fprintf(fout, "%3d\t%4d\t%4d\n", m, M, CM);
    
          } /* Closes sweep loop */	
    
        fclose(fout);
        return 0;
    }
    


  • mcr schrieb:

    Hallo,

    mir hat dieser Block coupen += () ? .. : ..; nicht gefallen. Dabei ist
    mir aufgefallen, dass man es wie folgt kürzen kann:

    coupen += spin[k][l] * (spin[(k+N-1)%N][l] + spin[(k+1)%N][l] + spin[k][(l+N-1)%N] + spin[k][(l+1)%N]);
    

    Ebenso die Zeile dcoupen += ...;

    Gruß mcr

    Hallo,

    tut mir leid, ich hatte den post ganz uebersehen. Ich glaube das funktioniert leider nicht, obwohl es natuerlich sehr sehr nett waere. Fuer

    (k==0 && l!=0 && l!=(N-1)) ? d * (spin[(N-1)][l] + spin[(k+1)][l] + spin[k][(l-1)] +spin[k][(l+1)]) :
    

    wuerde man an der ERSTEN Stelle spin[k-1][l] bekommen anstelle von spin[N-1][l], oder nicht?

    Danke



  • duck schrieb:

    int N=20;
    ...
    int spin[20][20];
    if(setup=='m')
    {
      for(i=0;i<=(N-1);i++)
      {
        for(j=0;j<=(N-1);j++)
        {
          spin[i][j]=1;
        }
        printf("|\n");
      }
    }
    

    Hast du bei deiner Anpassung auch daran gedacht, N zu korrigieren? (btw, das ist ein guter Zeitpunkt, über benannte Konstanten nachzudenken)



  • CStoll schrieb:

    duck schrieb:

    int N=20;
    ...
    int spin[20][20];
    if(setup=='m')
    {
      for(i=0;i<=(N-1);i++)
      {
        for(j=0;j<=(N-1);j++)
        {
          spin[i][j]=1;
        }
        printf("|\n");
      }
    }
    

    Hast du bei deiner Anpassung auch daran gedacht, N zu korrigieren? (btw, das ist ein guter Zeitpunkt, über benannte Konstanten nachzudenken)

    Wo muss ich N korrigieren?
    Danke



  • Wenn du dein Array auf 25*25 vergößerst, mußt du auch den Wert für N auf 25 setzen, sonst bleibt ein Teil des Arrays undefiniert/ungenutzt. (btw, aussagekräftige Namen haben noch niemandem geschadet)



  • CStoll schrieb:

    Wenn du dein Array auf 25*25 vergößerst, mußt du auch den Wert für N auf 25 setzen, sonst bleibt ein Teil des Arrays undefiniert/ungenutzt. (btw, aussagekräftige Namen haben noch niemandem geschadet)

    Achso. Ja hab ich gemacht...
    N ist schon kurz deswegen hab ich N gewaehlt auch in Analogie zu NxN Matrix etc...
    Danke


Anmelden zum Antworten