Trying to compile a source code in C

  • #1
MathematicalPhysicist
Gold Member
4,471
275
The source code is as follows:
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.
 

Answers and Replies

  • #2
wle
336
158
Try compiling with the -lm option:

gcc -lm -o exe_file src_file.c

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

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.
 
  • #3
MathematicalPhysicist
Gold Member
4,471
275
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.
I typed in the sh line:
Code:
gcc -lm -o exe_file main.c
and after that executed the code, but got the error:
Code:
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.
 
  • #4
wle
336
158
I typed in the sh line:
Code:
gcc -lm -o exe_file main.c
and after that executed the code, but got the error:
Code:
main: command not found

Why doesn't it seem to work, is it because the code is old?

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:
$ 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:
$ 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:
  • #6
jtbell
Mentor
15,803
4,038
You could have run the program without recompiling, by using the command

Code:
$ ./exe_file

In fact, I bet you probably still have that file lying around, unless you deleted it explicitly with the rm command!
 

Related Threads on Trying to compile a source code in C

Replies
25
Views
13K
Replies
7
Views
235
  • Last Post
Replies
12
Views
5K
  • Last Post
Replies
0
Views
2K
Replies
3
Views
3K
  • Last Post
Replies
3
Views
1K
  • Last Post
Replies
15
Views
3K
  • Last Post
Replies
0
Views
3K
Replies
14
Views
2K
Top