compiling problem in Jacobi routine


mvww
09-01-2012, 05:31 PM
Hello. I'm new here. It's the first time I try to use a NR routine. I'm fouding problems in compiling a program that uses "Jacobi Transformations of a Symmetric Matrix" routine (section 11.1 of "Numerical recipes in C - 2nd edition).

I got a file with the main function, main.c, and a file with the Jacobi function, jacobi.c.
In addition, I have 2 header files, that, for what I could see, are standard for all Numerical Recipes routines: nrutil.h and nr.h.

Here the are the codes:


main.c:
#include <stdio.h>
#include "nr.h"
#include "nrutil.h"

int main(void)
{
int i, j, nrot;

int n = 2;
/*
We need a Numerical Recipes-style "matrix" to use
as an argument to call the jacobi function.
Here are the matrix values stored in row-major
order in a 1-D array. This array name will be used
as an argument for the convert_matrix function.
*/
float a_array[] = {
5.0, -2.0, /* First row */
-2.0, 2.0 /* Second row */
};

float *d = vector(1, n);
float *r = vector(1, n);
float **v = matrix(1, n, 1, n);
float **a = convert_matrix(&a_array[0], 1, n, 1, n);

printf("Matrix:\n");
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
printf(" %+13.6e", a[i][j]);
}
printf("\n");
}
printf("\n");

jacobi(a, n, d, v, &nrot);

printf("Eigenvalues:\n");
for (i = 1; i <= n; i++) {
printf(" Number %d:%+14.6e\n", i, d[i]);
}
printf("\n");

printf("Eigenvectors:\n");
for (i = 1; i <= n; i++) {
printf(" Number %d:", i);
for (j = 1; j <= n; j++) {
printf("%+14.6e", v[j][i]);
}
printf("\n");
}
printf("\n");

printf("Number of Jacobi rotations = %d\n", nrot);

free_convert_matrix(a, 1, n, 1, n);
free_matrix(v, 1, n, 1, n);
free_vector(r, 1, n);
free_vector(d, 1, n);

return 0;
}


jacobi.c:
#include <math.h>
#include "nrutil.h"
#define ROTATE(a,i,j,k,l) g=a[i][j];h=a[k][l];a[i][j]=g-s*(h+g*tau);\
a[k][l]=h+s*(g-h*tau);
void jacobi(float **a, int n, float d[], float **v, int *nrot)
{
int j,iq,ip,i;
float tresh,theta,tau,t,sm,s,h,g,c,*b,*z;
b=vector(1,n);
z=vector(1,n);
for (ip=1;ip<=n;ip++) {
for (iq=1;iq<=n;iq++) v[ip][iq]=0.0;
v[ip][ip]=1.0;
}
for (ip=1;ip<=n;ip++) {
b[ip]=d[ip]=a[ip][ip];
z[ip]=0.0;
}
*nrot=0;
for (i=1;i<=50;i++) {
sm=0.0;
for (ip=1;ip<=n-1;ip++) {
for (iq=ip+1;iq<=n;iq++)
sm += fabs(a[ip][iq]);
}
if (sm == 0.0) {
free_vector(z,1,n);
free_vector(b,1,n);
return;
}
if (i < 4)
tresh=0.2*sm/(n*n);
else
tresh=0.0;
for (ip=1;ip<=n-1;ip++) {
for (iq=ip+1;iq<=n;iq++) {
g=100.0*fabs(a[ip][iq]);
if (i > 4 && (float)(fabs(d[ip])+g) == (float)fabs(d[ip])
&& (float)(fabs(d[iq])+g) == (float)fabs(d[iq]))
a[ip][iq]=0.0;
else if (fabs(a[ip][iq]) > tresh) {
h=d[iq]-d[ip];
if ((float)(fabs(h)+g) == (float)fabs(h))
t=(a[ip][iq])/h;
else {
theta=0.5*h/(a[ip][iq]);
t=1.0/(fabs(theta)+sqrt(1.0+theta*theta));
if (theta < 0.0) t = -t;
}
c=1.0/sqrt(1+t*t);
s=t*c;
tau=s/(1.0+c);
h=t*a[ip][iq];
z[ip] -= h;
z[iq] += h;
d[ip] -= h;
d[iq] += h;
a[ip][iq]=0.0;
for (j=1;j<=ip-1;j++) {
ROTATE(a,j,ip,j,iq)
}
for (j=ip+1;j<=iq-1;j++) {
ROTATE(a,ip,j,j,iq)
}
for (j=iq+1;j<=n;j++) {
ROTATE(a,ip,j,iq,j)
}
for (j=1;j<=n;j++) {
ROTATE(v,j,ip,j,iq)
}
++(*nrot);
}
}
}
for (ip=1;ip<=n;ip++) {
b[ip] += z[ip];
d[ip]=b[ip];
z[ip]=0.0;
}
}
/*nrerror("Too many iterations in routine jacobi");*/
}


When I try to compile it (I use MingW compilator on windows 7) using the command "gcc -Wall -o jacobi.exe main.c jacobi.c", I get errors like the following:
C:\Users\mvww\AppData\Local\Temp\ccOHhLuL.o:jacobi .c:(.text+0x16): undefined reference to `vector'
C:\Users\mvww\AppData\Local\Temp\ccOHhLuL.o:jacobi .c:(.text+0x2c): undefined reference to `vector'
C:\Users\mvww\AppData\Local\Temp\ccOHhLuL.o:jacobi .c:(.text+0x170): undefined reference to `free_vector'
C:\Users\mvww\AppData\Local\Temp\ccOHhLuL.o:jacobi .c:(.text+0x18a): undefined reference to `free_vector'
c:/mingw/bin/../lib/gcc/mingw32/4.6.2/../../../libmingw32.a(main.o): In function `main':
C:\MinGW\msys\1.0\src\mingwrt/../mingw/main.c:73: undefined reference to `WinMain@16'
collect2: ld returned 1 exit status
Compilation failed.

I'm sorry if I'm commiting a rookie mistake.
Thanks in advance,
mvww.

davekw7x
09-02-2012, 11:01 PM
... "gcc -Wall -o jacobi.exe main.c jacobi.c", I get errors like the following:
C:\Users\mvww\AppData\Local\Temp\ccOHhLuL.o:jacobi .c:(.text+0x16): undefined reference to `vector'
C:\Users\mvww\AppData\Local\Temp\ccOHhLuL.o:jacobi .c:(.text+0x2c): undefined reference to `vector'
C:\Users\mvww\AppData\Local\Temp\ccOHhLuL.o:jacobi .c:(.text+0x170): undefined reference to `free_vector'
C:\Users\mvww\AppData\Local\Temp\ccOHhLuL.o:jacobi .c:(.text+0x18a): undefined reference to `free_vector'
c:/mingw/bin/../lib/gcc/mingw32/4.6.2/../../../libmingw32.a(main.o): In function `main':
...

You also have to compile nrutil.c in from the recipes directory so that its routines can be linked in.

Output:
[code]
Matrix:
+5.000000e+00 -2.000000e+00
-2.000000e+00 +2.000000e+00

Eigenvalues:
Number 1: +6.000000e+00
Number 2: +1.000000e+00

Eigenvectors:
Number 1: +8.944272e-01 -4.472136e-01
Number 2: +4.472136e-01 +8.944272e-01

Number of Jacobi rotations = 1

Regards,

Dave