Thread: PGPLOT help please!!

  1. #1
    Registered User
    Join Date
    Nov 2018
    Posts
    3

    PGPLOT help please!!

    Hi, I'm brand new to C programming and coding in general and I am getting
    " %PGPLOT, invalid x limits in PGENV: XMIN = XMAX."
    when I run my program.
    This is my code:
    Code:
    #include <stdio.h>
    #include <math.h>
    
    
    /*float N(float S[n], float I[n], float R[n])
    {
      N[n] = 400.0;
      N[n] = S[n] + I[n] + R[n];
      return N[n];
    }*/
    
    
    float dSdt(float N, float S, float I, float R, float mu, float beta)
      {
        return mu*N - (beta*S*I) - mu*S; 
      }
      float dIdt(float S, float I, float R, float mu, float beta, float gam)  
      {
        return (beta*S*I) - gam*I - mu*I;
      }
      float dRdt(float I, float R, float mu, float gam)
      {
        return gam*I - mu*R;
      }
    
    
    int main ()
    {
      
      int i;
      int n=20;
      int t=10;
      float S[n], I[n], R[n];
      S[0]=1.;
      I[0]=0.;
      R[0]=0.;
      //N=S+I+R therefore N=1 *** explain in write up this means that i can delete all "/N" because its just dividing by 1
      float N, mu, beta, gam; 
      
    
    
      float Sk1, Sk2, Sk3, Sk4, Ik1, Ik2, Ik3, Ik4, Rk1, Rk2, Rk3, Rk4;
      float h = (float)t/(float)n;
      /*printf("Input numbers for x0, y0, h, and n.\n");
      scanf("%f %f %f %f %f", &x0, &y0, &h, &n0); */
      for (i=1;i<=n;i++) //??
        {
          Sk1 = dSdt(N, S[i-1], I[i-1], R[i-1], mu, beta);
          Ik1 = dIdt(S[i-1], I[i-1], R[i-1], mu, beta, gam);
          Rk1 = dRdt(I[i-1], R[i-1], mu, gam);
    
    
          Sk2 = dSdt(N, S[i-1]+Sk1*h/2.0, I[i-1]+Ik1*h/2.0, R[i-1]+Rk1*h/2.0, mu, beta);
          Ik2 = dIdt(S[i-1]+Sk1*h/2.0, I[i-1]+Ik1*h/2.0, R[i-1]+Rk1*h/2.0, mu, beta, gam);
          Rk2 = dRdt(I[i-1]+Ik1*h/2.0, R[i-1]+Rk1*h/2.0, mu, gam);
    
    
          Sk3 = dSdt(N, S[i-1]+Sk2*h/2.0, I[i-1]+Ik2*h/2.0, R[i-1]+Rk2*h/2.0, mu, beta);
          Ik3 = dIdt(S[i-1]+Sk2*h/2.0, I[i-1]+Ik2*h/2.0, R[i-1]+Rk2*h/2.0, mu, beta, gam);
          Rk3 = dRdt(I[i-1]+Ik2*h/2.0, R[i-1]+Rk2*h/2.0, mu, gam);
    
    
          Sk4 = dSdt(N, S[i-1]+Sk3*h/2.0, I[i-1]+Ik3*h/2.0, R[i-1]+Rk3*h/2.0, mu, beta); 
          Ik4 = dIdt(S[i-1]+Sk3*h/2.0, I[i-1]+Ik3*h/2.0, R[i-1]+Rk3*h/2.0, mu, beta, gam);
          Rk4 = dRdt(I[i-1]+Ik3*h/2.0, R[i-1]+Rk3*h/2.0, mu, gam);
    
    
          S[i] = S[i-1] + (h/6.0)*(Sk1 + 2.0*Sk2 + 2.0*Sk3 + Sk4);
          I[i] = I[i-1] + (h/6.0)*(Ik1 + 2.0*Ik2 + 2.0*Ik3 + Ik4);
          R[i] = R[i-1] + (h/6.0)*(Rk1 + 2.0*Rk2 + 2.0*Rk3 + Rk4);
        }
    
    
    /*----------------------------------------------------------------------------------------------------------------*/
    /*PLOT IT*/
    /*----------------------------------------------------------------------------------------------------------------*/
    
    
     // Open a plot window
      if (!cpgopen("/XWINDOW")) return 1;
    
    
      // Set-up plot axes
      cpgenv(0.,1.,0.,1.,0,1);
    
    
      // Label axes
      cpglab("x", "y", "project");
    
    
      //set colour to yellow
      cpgsci(7);
    
    
      //plot
      cpgline(n+1,t,S);
      // Pause and then close plot window
      cpgclos();
    
    
    }
    Any help would be so greatly appreciated!!! Thank you so much in advance!

  2. #2
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    cpgline's second parameter is supposed to be a pointer to a float, but you are passing an int. One way to fix it:
    Code:
      float ft = t;
      cpgline(n+1, &ft, S);
    Or maybe you should make t a float in the first place (and pass it's address like I did with ft above).
    A little inaccuracy saves tons of explanation. - H.H. Munro

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    There are a bunch of problems before you even get to plotting.
    Code:
    $ gcc -Wall -Wextra foo.c
    foo.c: In function ‘dSdt’:
    foo.c:13:45: warning: unused parameter ‘R’ [-Wunused-parameter]
     float dSdt(float N, float S, float I, float R, float mu, float beta)
                                                 ^
    foo.c: In function ‘dIdt’:
    foo.c:17:38: warning: unused parameter ‘R’ [-Wunused-parameter]
       float dIdt(float S, float I, float R, float mu, float beta, float gam)
                                          ^
    foo.c: In function ‘main’:
    foo.c:48:11: warning: ‘N’ may be used uninitialized in this function [-Wmaybe-uninitialized]
           Sk1 = dSdt(N, S[i-1], I[i-1], R[i-1], mu, beta);
               ^
    foo.c:48:11: warning: ‘mu’ may be used uninitialized in this function [-Wmaybe-uninitialized]
    foo.c:48:11: warning: ‘beta’ may be used uninitialized in this function [-Wmaybe-uninitialized]
    foo.c:49:11: warning: ‘gam’ may be used uninitialized in this function [-Wmaybe-uninitialized]
           Ik1 = dIdt(S[i-1], I[i-1], R[i-1], mu, beta, gam);
               ^
    All those maybe-uninitialized are actually uninitialised, which means you're computing with garbage.

    > S[i] = S[i-1] + (h/6.0)*(Sk1 + 2.0*Sk2 + 2.0*Sk3 + Sk4);
    > I[i] = I[i-1] + (h/6.0)*(Ik1 + 2.0*Ik2 + 2.0*Ik3 + Ik4);
    > R[i] = R[i-1] + (h/6.0)*(Rk1 + 2.0*Rk2 + 2.0*Rk3 + Rk4);
    On the last iteration of the loop, when i == n, the assignments are out of bounds.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Nov 2018
    Posts
    3
    Thank you both very much for your input! I have updated my code to change t to a float and also to fix the problems that have been pointed out. I am unfortunately getting the same response when I try to run my program. Any other insights would be greatly appreciated!!

    Code:
    #include <stdio.h>
    #include <math.h>
    
    
    /*float N(float S[n], float I[n], float R[n])
    {
      N[n] = 400.0;
      N[n] = S[n] + I[n] + R[n];
      return N[n];
    }*/
    
    
    float dSdt(float N, float S, float I, float mu, float beta)
      {
        return mu*N - (beta*S*I) - mu*S; 
      }
      float dIdt(float S, float I, float mu, float beta, float gam)  
      {
        return (beta*S*I) - gam*I - mu*I;
      }
      float dRdt(float I, float R, float mu, float gam)
      {
        return gam*I - mu*R;
      }
    
    
    int main ()
    {
      
      int i;
      int n=100;
      int t=0;
      float S[n], I[n], R[n];
      S[0]=1.;
      I[0]=0.;
      R[0]=0.;
      
    
    
      //N=S+I+R therefore N=1 *** explain in write up this means that i can delete all "/N" because its just dividing by 1
      float N, mu, beta, gam; 
      N = 1.;
    
    
      float Sk1, Sk2, Sk3, Sk4, Ik1, Ik2, Ik3, Ik4, Rk1, Rk2, Rk3, Rk4;
      float h = (float)t/(float)n;
      /*printf("Input numbers for x0, y0, h, and n.\n");
      scanf("%f %f %f %f %f", &x0, &y0, &h, &n0); */
      for (i=1;i<=n;i++) //??
        {
          Sk1 = dSdt(N, S[i-1], I[i-1], mu, beta);
          Ik1 = dIdt(S[i-1], I[i-1], mu, beta, gam);
          Rk1 = dRdt(I[i-1], R[i-1], mu, gam);
    
    
          Sk2 = dSdt(N, S[i-1]+Sk1*h/2.0, I[i-1]+Ik1*h/2.0, mu, beta);
          Ik2 = dIdt(S[i-1]+Sk1*h/2.0, I[i-1]+Ik1*h/2.0, mu, beta, gam);
          Rk2 = dRdt(I[i-1]+Ik1*h/2.0, R[i-1]+Rk1*h/2.0, mu, gam);
    
    
          Sk3 = dSdt(N, S[i-1]+Sk2*h/2.0, I[i-1]+Ik2*h/2.0, mu, beta);
          Ik3 = dIdt(S[i-1]+Sk2*h/2.0, I[i-1]+Ik2*h/2.0, mu, beta, gam);
          Rk3 = dRdt(I[i-1]+Ik2*h/2.0, R[i-1]+Rk2*h/2.0, mu, gam);
    
    
          Sk4 = dSdt(N, S[i-1]+Sk3*h/2.0, I[i-1]+Ik3*h/2.0, mu, beta); 
          Ik4 = dIdt(S[i-1]+Sk3*h/2.0, I[i-1]+Ik3*h/2.0, mu, beta, gam);
          Rk4 = dRdt(I[i-1]+Ik3*h/2.0, R[i-1]+Rk3*h/2.0, mu, gam);
    
    
          S[i] = S[i-1] + (h/6.0)*(Sk1 + 2.0*Sk2 + 2.0*Sk3 + Sk4);
          I[i] = I[i-1] + (h/6.0)*(Ik1 + 2.0*Ik2 + 2.0*Ik3 + Ik4);
          R[i] = R[i-1] + (h/6.0)*(Rk1 + 2.0*Rk2 + 2.0*Rk3 + Rk4);
        }
    
    
    /*----------------------------------------------------------------------------------------------------------------*/
    /*PLOT IT*/
    /*----------------------------------------------------------------------------------------------------------------*/
    
    
     // Open a plot window
      if (!cpgopen("/XWINDOW")) return 1;
    
    
      // Set-up plot axes
      cpgenv(0.,10.,0.,1.,0,1);
    
    
      // Label axes
      cpglab("x", "y", "project");
    
    
      //set colour to yellow
      cpgsci(7);
    
    
      //plot
      float ft = t;
      cpgline(n+1, &ft, S);
      
      // Pause and then close plot window
      cpgclos();
    
    
    }
    Thanks again in advance!

  5. #5
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    You ignored Salem's last point and are still accessing S[n], I[n] and R[n] (which are out-of-bounds) on the last iteration of your loop.
    A little inaccuracy saves tons of explanation. - H.H. Munro

  6. #6
    Registered User
    Join Date
    Nov 2018
    Posts
    3
    Oh right, thank you!!

Popular pages Recent additions subscribe to a feed

Tags for this Thread