Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

C/++/# Trying to compile a source code in C

  1. Feb 14, 2017 #1

    MathematicalPhysicist

    User Avatar
    Gold Member

    The source code is as follows:
    Code (C):

    #include <stdio.h>
    #include <math.h>
    #define pi 3.14159265
    #define nbin 10000
    #define small 1.e-12
    int addj(int data[nbin],double *tw,double x,double y,double vx,double vy, int xn,int j,double tc);
    void billiard(int data[nbin],int nx,int nt,double x);
    void bindist(int data[nbin], int nb, int nt);
    int menue(void);
    double ran1(long *idum);
    void tabulate(int data[nbin], int nb, int rows);
    void main(void)
    {
        int c;            /* menue variable*/
        int col;        /*number of columns in table*/
        int data[nbin];         /* array of binned data*/
        int i;            /*dummy index*/
        long idum;        /*randum number generator seed*/
        int j;            /*dummy index*/
        int nb;            /*number of bins*/
        int nt;            /*number of data points collected*/
        int nx;            /*number of bins in x-direction*/
        double x;        /*initial x-coordinate, the initial
                    y-coordinate is set to zero*/


        printf("input integer random number generator seed ");
        scanf("%d",&idum);
        idum=-idum;        /*random number generator is initialized
                    by negative integer seed*/

        while((c=menue()) !=1)
        {
            switch (c)
            {
            case 2:    
                printf("input number of points nt ");
                scanf("%d",&nt);
                printf("input number of bins ");
                scanf("%d",&nb);
                for (i=0;i<nb;i++) data[i]=0;
                for(i=0;i<nt;i++)
                    {
                    j=ran1(&idum)*nb;
                    data[j]++;
                    }
                break;
            case 3:
                printf("sqrt of no of bins ");
                scanf("%d", &nx);
                nb=nx*nx;
                printf("input  0<x <1, or x<0 for random start ");
                scanf("%lf",&x);
                if (x<0) x=ran1(&idum);
                printf("input number of points nt ");
                scanf("%d",&nt);
                for(i=0;i<nb;i++)data[i]=0;
                billiard(data,nx,nt,x);
                break;          
            case 4:
                bindist(data,nb,nt);
                break;
            case 5:
                col=10;
                tabulate(data,nb,col);  
                break;
            }  
        }
    }

    int addj(int data[nbin],double *tw,double x,double y,double vx,double vy,int nx,int j, double tc)
        {
        int k;            /*column and bin number*/
        int l;            /*row number*/
        double xn;
        xn=((double)nx)-small;
        while (*tw>=1)
            {
            x+=(1.-tc)*vx;
            y+=(1-tc)*vy;
            *tw+=-1;
            tc=0;
            l=y*xn;
            k=x*xn;
            k+=l*nx;
        /*printf("x= %f, y= %f, k= %d, vx= %f,tw=%f \n",x,y,k,vx,*tw);*/
            data[k]++;
            j++;
            }
        return j;
        }

    void billiard(int data[nbin],int nx,int nt,double x)
        {
        int i=0;            /*switch label*/
        int j=0;            /*time for next data point*/
        double tc;            /*current time*/
        double tw;                    /*time to hit the wall*/
        double xx;            /*temporary x-coordinate*/
        double y;            /*y-coordinate*/
        double yy;            /*temporary y-coordinate*/
        double vx;            /*magnitude of x-velocity*/
        double vy;            /*magnitude of y-velocity*/
        double vxm;            /* -vx*/
        double vym;            /* -vy*/
        printf("x-initial= %f\n",x);
        printf("input vx>0 ");
        scanf("%lf",&vx);
        printf("input vy>0 ");
        scanf("%lf",&vy);
        vxm=-vx;
        vym=-vy;
        tw=y=0;
        while (j<nt)
            {
            tc=tw;
            /*printf("i=%d\n",i);*/
            switch (i)
                {
                case 0:     /* 0<x<1,y=0, xspeed >0, y speed >0 */
                    yy=(1.-x)*vy/vx;
                    if (yy<1.)
                        {
                        tw+=yy/vy;
                        i=1;
                        j=addj(data,&tw,x,y,vx,vy,nx,j,tc);
                        x=1.;
                        y=yy;
                        }
                    else
                        {
                        tw+=1./vy;
                        i=6;
                        j=addj(data,&tw,x,y,vx,vy,nx,j,tc);
                        x+=vx/vy;
                        y=1;
                        }                                  
                    break;
                case 1:     /* x=1,0<y=1;xspeed <0, yspeed >0 */
                    xx=1.-(1.-y)*vx/vy;
                    if (xx>0)
                        {
                        tw+=(1.-xx)/vx;
                        i=2;
                        j=addj(data,&tw,x,y,vxm,vy,nx,j,tc);
                        y=1;
                        x=xx;
                        }
                    else
                        {
                        tw+=1./vx;
                        i=7;
                        j=addj(data,&tw,x,y,vxm,vy,nx,j,tc);
                        x=0;
                        y+=vy/vx;
                        }
                    break;
                case 2:        /* 0<x<1,y=1, xspeed <0, y speed <0 */
                    yy=1-x*vy/vx;
                    if (yy>0)
                        {
                        tw+=(1.-yy)/vy;
                        i=3;
                        j=addj(data,&tw,x,y,vxm,vym,nx,j,tc);
                        x=0.;
                        y=yy;
                        }
                    else
                        {
                        tw+=1./vy;
                        i=4;
                        j=addj(data,&tw,x,y,vxm,vym,nx,j,tc);
                        x+=-vx/vy;
                        y=0;
                        }                                  
                    break;
                case 3:     /* x=0,0<y=1;xspeed >0, yspeed <0 */
                    xx=y*vx/vy;
                    if (xx<1)
                        {
                        tw+=xx/vx;
                        i=0;
                        j=addj(data,&tw,x,y,vx,vym,nx,j,tc);
                        y=0;
                        x=xx;
                        }
                    else
                        {
                        tw+=1./vx;
                        i=5;
                        j=addj(data,&tw,x,y,vx,vym,nx,j,tc);
                        x=1;
                        y+=-vy/vx;
                        }
                    break;
                case 4:     /* 0<x<1,y=0, xspeed <0, y speed >0 */
                    yy=x*vy/vx;
                    if (yy<1)
                        {
                        tw+=yy/vy;
                        i=7;
                        j=addj(data,&tw,x,y,vxm,vy,nx,j,tc);
                        x=0.;
                        y=yy;
                        }
                    else
                        {
                        tw+=1./vy;
                        i=2;
                        j=addj(data,&tw,x,y,vxm,vy,nx,j,tc);
                        x+=-vx/vy;
                        y=1;
                        }                                  
                    break;
                case 5:     /* x=1,0<y=1;xspeed <0, yspeed <0 */
                    xx=1.-y*vx/vy;
                    if (xx>0)
                        {
                        tw+=(1.-xx)/vx;
                        i=4;
                        j=addj(data,&tw,x,y,vxm,vym,nx,j,tc);
                        y=0;
                        x=xx;
                        }
                    else
                        {
                        tw+=1./vx;
                        i=3;
                        j=addj(data,&tw,x,y,vxm,vym,nx,j,tc);
                        x=0;
                        y+=-vy/vx;
                        }
                    break;
                case 6:        /* 0<x<1,y=1, xspeed >0, y speed <0 */
                    yy=1.-(1.-x)*vy/vx;
                    if (yy>0)
                        {
                        tw+=(1.-yy)/vy;
                        i=5;
                        j=addj(data,&tw,x,y,vx,vym,nx,j,tc);
                        x=1.;
                        y=yy;
                        }
                    else
                        {
                        tw+=1./vy;
                        i=0;
                        j=addj(data,&tw,x,y,vx,vym,nx,j,tc);
                        x+=vx/vy;
                        y=0;
                        }                                    
                    break;
                case 7:     /* x=0,0<y=1;xspeed <0, yspeed >0 */
                    xx=(1.-y)*vx/vy;
                    if (xx<1)
                        {
                        tw+=xx/vx;
                        i=6;
                        j=addj(data,&tw,x,y,vx,vy,nx,j,tc);
                        y=1;
                        x=xx;
                        }
                    else
                        {
                        tw+=1./vx;
                        i=1;
                        j=addj(data,&tw,x,y,vx,vy,nx,j,tc);
                        x=1;
                        y+=vy/vx;
                        }
                    break;
                }
            }
        }          
    /* This routine checks if deviation of number of elements in each bin follows a Gaussian distribution*/
    void bindist(int data[nbin], int n, int nt)
        {
        double ave, adev, sdev, var, skew, curt;
        int j;
        double x,y,s=0,p,a,b,c;  
            x=(double) n;
        y=(double) nt;
        if (n <= 0) printf("nb must be at least 1 in moment\n");
        for (j=0;j<n;j++) s += data[j];
        ave=s/n;
        adev=var=skew=curt=0.0;
        for (j=0;j<n;j++)
            {
            adev += fabs(s=data[j]-ave);
            var += (p=s*s);
            skew += (p *= s);
            curt += (p *= s);
            }
        adev /= x;
        var /=x;
        sdev=sqrt(var);
        if (var)
            {
            skew /= n*var*sdev;
            curt=curt/(n*var*var)-3.0;
            }
        printf("%39s %11s\n\n","calculated","expected");
        a=y/x;
        printf("%s %17s %12.4f %12.4f\n","Mean :"," ",ave,a);
        c=sqrt(2.*a/pi);
        printf("%s %4s %12.4f %12.4f\n","Average Deviation :"," ",adev,c);
        b=sqrt(a);
        printf("%s %3s %12.4f %12.4f\n","Standard Deviation :"," ",sdev,b);  
        printf("%s %13s %12.4f %12.4f\n","Variance :"," ",var,a);
        printf("%s %13s %12.4f %12.4f\n","Skewness :"," ",skew,0.0);
        printf("%s %13s %12.4f %12.4f\n","Kurtosis :"," ",curt,0);
        }

    /* to generate menue*/
    int menue()
        {
        int x;
        printf("1 to quit \n");
        printf("2 to generate random distribution of points\n");
        printf("3 to generate billiard distribution of points \n");
        printf("4 to analyze data\n");
        printf("5 to tabulate data\n");
        scanf("%d", &x);
        return x;
        }

    /* modified version of ran1 of numerical recipies. NOTE the initial seed should be NEGATIVE!!!!*/
    #define IA 16807
    #define IM 2147483647
    #define AM (1.0/IM)
    #define IQ 127773
    #define IR 2836
    #define NTAB 32
    #define NDIV (1+(IM-1)/NTAB)
    #define EPS 1.2e-7
    #define RNMX (1.0-EPS)
    double ran1(long *idum)
    {
        int j;
        long k;
        static long iy=0;
        static long iv[NTAB];
        double temp;

        if (*idum <= 0 || !iy) {
            if (-(*idum) < 1) *idum=1;
            else *idum = -(*idum);
            for (j=NTAB+7;j>=0;j--) {
                k=(*idum)/IQ;
                *idum=IA*(*idum-k*IQ)-IR*k;
                if (*idum < 0) *idum += IM;
                if (j < NTAB) iv[j] = *idum;
            }
            iy=iv[0];
        }
        k=(*idum)/IQ;
        *idum=IA*(*idum-k*IQ)-IR*k;
        if (*idum < 0) *idum += IM;
        j=iy/NDIV;
        iy=iv[j];
        iv[j] =*idum;
        if((temp=AM*iy)>RNMX)return RNMX;
        else return temp;
    }
    #undef IA
    #undef IM
    #undef AM
    #undef IQ
    #undef IR
    #undef NTAB
    #undef NDIV
    #undef EPS
    #undef RNMX

    /* to tabulate an integer array, nb is total number of entries,
    co is number of columns*/

    void tabulate(int data[nbin], int nb, int co)
        {
        int i,j,k,x, y;
        x=nb/co;
        y=nb%co;
        k=0;
        for (i=0;i<x;i++)
            {
            for (j=0;j<co;j++)
                {
                printf("%6d",data[k]);
                k++;
                }
            printf("\n");
            }
        for (i=0;i<y;i++)
            {
            printf("%6d",data[k]);
            k++;
            }
        printf("\n");
        }
     
    I tried this webpage here:
    https://www.tutorialspoint.com/compile_c_online.php

    to compile and execute the source code (I didn't write this file, I got it from someone);

    I get the following errors:
    sh-4.2$ gcc -o main *.c
    /tmp/cc42Vpoo_O: In function `bindist':
    main.c:(.text+0x1308): undefined reference to `sqrt'
    main.c:(.text+0x1400): undefined reference to `sqrt'
    main.c:(.text+0x146a): undefined reference to `sqrt'
    collect2: error: ld returned 1 exit status
    sh-4.2$ main
    sh: main: command not found

    Isn't the sqrt operation defined in the library of math?

    How to fix this code so that it will run appropriately?, btw it's a bit dated from the nineties of the 20th century. :-)

    Thanks.
     
  2. jcsd
  3. Feb 14, 2017 #2

    wle

    User Avatar

    Try compiling with the -lm option:

    gcc -lm -o exe_file src_file.c

    No. The math.h header file only contains (among other things) a function prototype which declares that sqrt is a function and that it accepts a double-precision floating-point number as an argument and produces a double-precision floating-point number as its result. It doesn't contain the definition (i.e., the code) of the sqrt function. That is normally already compiled and stored in a library somewhere, and you need to tell the compiler explicitly to link against that library. That is what the -lm switch does for gcc.
     
  4. Feb 14, 2017 #3

    MathematicalPhysicist

    User Avatar
    Gold Member

    I typed in the sh line:
    Code (Text):

    gcc -lm -o exe_file main.c
     
    and after that executed the code, but got the error:
    Code (Text):
    main: command not found
    Why doesn't it seem to work, is it because the code is old? has C changed drastically since the nineties?! I don't think so.
     
  5. Feb 14, 2017 #4

    wle

    User Avatar

    No*. You called the wrong program name. The "-o exe_file" part of the command tells gcc to compile the program into an executable file called "exe_file". You should replace "exe_file" with whatever program name you like. Assuming the source code is in the file "main.c", if you literally want the program to be called "main" then you should do
    Code (Text):
    $ gcc -lm -o main main.c
    $ ./main
    to compile and run the file ('$' here represents the prompt -- don't type that). The "./" tells the shell to look in the current directory for the program.

    The -o switch is optional. If you omit it, gcc will use the default program name "a.out":
    Code (Text):
    $ gcc -lm main.c
    $ ./a.out

    ----------

    *Not that this looks like particularly correct C code, for that matter. void main(void) is strictly speaking wrong, though C compilers will often compile it anyway.
     
    Last edited: Feb 14, 2017
  6. Feb 14, 2017 #5

    MathematicalPhysicist

    User Avatar
    Gold Member

    OK, thanks @wle it works.
     
  7. Feb 14, 2017 #6

    jtbell

    User Avatar

    Staff: Mentor

    You could have run the program without recompiling, by using the command

    Code (Text):

    $ ./exe_file
     
    In fact, I bet you probably still have that file lying around, unless you deleted it explicitly with the rm command!
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?
Draft saved Draft deleted