* Inverse Matrix Implementation Problem...
@ 2002-07-02 16:27 W L A Au
2002-07-03 7:23 ` zhenggen
2002-07-04 7:08 ` Edmund Green
0 siblings, 2 replies; 3+ messages in thread
From: W L A Au @ 2002-07-02 16:27 UTC (permalink / raw)
To: gcc-help
[-- Attachment #1: Type: text/plain, Size: 2151 bytes --]
Dear Sir/Madam,
Please help me. I've encounter some problems when I try to implement the
inverse matrix function by using the Gauss-Jordan Elimination routine,
which is provided by the Numerical Recipes in C, Chapter 2.1
http://www.ulib.org/webRoot/Books/Numerical_Recipes/bookcpdf.html
What exactly I want to do is:
First, put in the values of a 2D matrix, A
3 5 0
for example, A= 6 1 4
1 1 2
Then, add an equal dimension 2D identity matrix to A
3 5 0 1 0 0
=> 6 1 4 0 1 0
1 1 2 0 0 1
After that, do row elementary operation (eg. addition, multiplication, swap
row...) in order to form an identity matrix on the left
1 0 0 1/23 5/23 -10/23
=> 0 1 0 4/23 -3/23 6/23
0 0 1 -5/46 -1/23 27/46
When the left hand side become an identity matrix, the right hand side will
become the inverse of A. So, I use the gaussj() function
provided by the book to achieve this. However, when I use the gcc compiler
command:
gcc test2.c -o test2
I've got the following error message:
Undefined first referenced
symbol in file
free_ivector /var/tmp/cc4v8fRq.o
ivector /var/tmp/cc4v8fRq.o
nrerror /var/tmp/cc4v8fRq.o
ld: fatal: Symbol referencing errors. No output written to test2
collect2: ld returned 1 exit status
It seems I can not include the nrutil.h header file. But I've put it in the
same subdirectory with test2.c already. How this can be fix?
Also, the 2D matrix, a. Is already declared as "float **a" in the routine.
I've try to use it by substitude values in, like
a[0][0] = 3; a[1][0] = 5; a[2][0] = 0;
a[0][1] = 6; a[1][1] = 1; a[2][1] = 4;
a[0][2] = 1; a[1][2] = 1; a[2][2] = 2;
in order to find the inverse matrix of a. But error massage come out as
well. I guess this is not right at all. How can I make it right?
Finally, I'm not sure did I use the gaussj() function correctly. Did I miss
something in my implementation?
I would like to thank you in advance for helping me. Thank a lot!
Yours Sincerely,
Alderick
PS. The test2.c and nrutil.h files are attached with this email.
[-- Attachment #2: test2.c --]
[-- Type: , Size: 1739 bytes --]
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "nrutil.h"
#define SWAP(a,b) {temp=(a);(a)=(b);(b)=temp;}
void gaussj(float **a, int n, float **b, int m)
{
int *indxc,*indxr,*ipiv;
int i,icol,irow,j,k,l,ll;
float big,dum,pivinv,temp;
indxc=ivector(1,n);
indxr=ivector(1,n);
ipiv=ivector(1,n);
for (j=1;j<=n;j++) ipiv[j]=0;
for (i=1;i<=n;i++) {
big=0.0;
for (j=1;j<=n;j++)
if (ipiv[j] != 1)
for (k=1;k<=n;k++) {
if (ipiv[k] == 0) {
if (fabs(a[j][k]) >= big) {
big=fabs(a[j][k]);
irow=j;
icol=k;
}
} else if (ipiv[k] > 1) nrerror("gaussj: Singular Matrix-1");
}
++(ipiv[icol]);
if (irow != icol) {
for (l=1;l<=n;l++) SWAP(a[irow][l],a[icol][l])
for (l=1;l<=m;l++) SWAP(b[irow][l],b[icol][l])
}
indxr[i]=irow;
indxc[i]=icol;
if (a[icol][icol] == 0.0) nrerror("gaussj: Singular Matrix-2");
pivinv=1.0/a[icol][icol];
a[icol][icol]=1.0;
for (l=1;l<=n;l++) a[icol][l] *= pivinv;
for (l=1;l<=m;l++) b[icol][l] *= pivinv;
for (ll=1;ll<=n;ll++)
if (ll != icol) {
dum=a[ll][icol];
a[ll][icol]=0.0;
for (l=1;l<=n;l++) a[ll][l] -= a[icol][l]*dum;
for (l=1;l<=m;l++) b[ll][l] -= b[icol][l]*dum;
}
}
for (l=n;l>=1;l--) {
if (indxr[l] != indxc[l])
for (k=1;k<=n;k++)
SWAP(a[k][indxr[l]],a[k][indxc[l]]);
}
free_ivector(ipiv,1,n);
free_ivector(indxr,1,n);
free_ivector(indxc,1,n);
}
main()
{
float **a, **b;
int n, m;
a[0][0] = 3; a[1][0] = 5; a[2][0] = 0;
a[0][1] = 6; a[1][1] = 1; a[2][1] = 4;
a[0][2] = 1; a[1][2] = 1; a[2][2] = 2;
gaussj(a, n, b, m);
}
[-- Attachment #3: nrutil.h --]
[-- Type: , Size: 2995 bytes --]
// Here is a listing of nrutil.h:
#ifndef _NR_UTILS_H_
#define _NR_UTILS_H_
static float sqrarg;
#define SQR(a) ((sqrarg=(a)) == 0.0 ? 0.0 : sqrarg*sqrarg)
static double dsqrarg;
#define DSQR(a) ((dsqrarg=(a)) == 0.0 ? 0.0 : dsqrarg*dsqrarg)
static double dmaxarg1,dmaxarg2;
#define DMAX(a,b) (dmaxarg1=(a),dmaxarg2=(b),(dmaxarg1) > (dmaxarg2) ? (dmaxarg1) : (dmaxarg2))
static double dminarg1,dminarg2;
#define DMIN(a,b) (dminarg1=(a),dminarg2=(b),(dminarg1) < (dminarg2) ? (dminarg1) : (dminarg2))
static float maxarg1,maxarg2;
#define FMAX(a,b) (maxarg1=(a),maxarg2=(b),(maxarg1) > (maxarg2) ? (maxarg1) : (maxarg2))
static float minarg1,minarg2;
#define FMIN(a,b) (minarg1=(a),minarg2=(b),(minarg1) < (minarg2) ? (minarg1) : (minarg2))
static long lmaxarg1,lmaxarg2;
#define LMAX(a,b) (lmaxarg1=(a),lmaxarg2=(b),(lmaxarg1) > (lmaxarg2) ? (lmaxarg1) : (lmaxarg2))
static long lminarg1,lminarg2;
#define LMIN(a,b) (lminarg1=(a),lminarg2=(b),(lminarg1) < (lminarg2) ? (lminarg1) : (lminarg2))
static int imaxarg1,imaxarg2;
#define IMAX(a,b) (imaxarg1=(a),imaxarg2=(b),(imaxarg1) > (imaxarg2) ? (imaxarg1) : (imaxarg2))
static int iminarg1,iminarg2;
#define IMIN(a,b) (iminarg1=(a),iminarg2=(b),(iminarg1) < (iminarg2) ? (iminarg1) : (iminarg2))
#define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
#if defined(__STDC__) || defined(ANSI) || defined(NRANSI) /* ANSI */
void nrerror(char error_text[]);
float *vector(long nl, long nh);
int *ivector(long nl, long nh);
unsigned char *cvector(long nl, long nh);
unsigned long *lvector(long nl, long nh);
double *dvector(long nl, long nh);
float **matrix(long nrl, long nrh, long ncl, long nch);
double **dmatrix(long nrl, long nrh, long ncl, long nch);
int **imatrix(long nrl, long nrh, long ncl, long nch);
float **submatrix(float **a, long oldrl, long oldrh, long oldcl, long oldch, long newrl, long newcl);
float **convert_matrix(float *a, long nrl, long nrh, long ncl, long nch);
float ***f3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh);
void free_vector(float *v, long nl, long nh);
void free_ivector(int *v, long nl, long nh);
void free_cvector(unsigned char *v, long nl, long nh);
void free_lvector(unsigned long *v, long nl, long nh);
void free_dvector(double *v, long nl, long nh);
void free_matrix(float **m, long nrl, long nrh, long ncl, long nch);
void free_dmatrix(double **m, long nrl, long nrh, long ncl, long nch);
void free_imatrix(int **m, long nrl, long nrh, long ncl, long nch);
void free_submatrix(float **b, long nrl, long nrh, long ncl, long nch);
void free_convert_matrix(float **b, long nrl, long nrh, long ncl, long nch);
void free_f3tensor(float ***t, long nrl, long nrh, long ncl, long nch, long ndl, long ndh);
#else /* ANSI */
/* traditional - K&R */
void nrerror();
float *vector();
// Rest of traditional declarations are here on the diskette.
#endif /* ANSI */
#endif /* _NR_UTILS_H_ */
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Inverse Matrix Implementation Problem...
2002-07-02 16:27 Inverse Matrix Implementation Problem W L A Au
@ 2002-07-03 7:23 ` zhenggen
2002-07-04 7:08 ` Edmund Green
1 sibling, 0 replies; 3+ messages in thread
From: zhenggen @ 2002-07-03 7:23 UTC (permalink / raw)
To: W L A Au; +Cc: gcc-help
W L A Au wrote:
>Dear Sir/Madam,
>
>Please help me. I've encounter some problems when I try to implement the
>inverse matrix function by using the Gauss-Jordan Elimination routine,
>which is provided by the Numerical Recipes in C, Chapter 2.1
>
>http://www.ulib.org/webRoot/Books/Numerical_Recipes/bookcpdf.html
>
>What exactly I want to do is:
>
There are two basic concepts which you should grasp before you can
continue your work.
(1) The declaration of array(one-dimensional or multi-dimensional):
" float **a ;" will not declare an array, rather it declares a
pointer. "a" is a pointer which can point to an array of float pointers.
The simplest way to declare a 3 by 3 array is : float a[3][3];
(2) header files and library files.
In a .C file, a "#include ..." statement only tells the compiler to
find ,in this header file, the definition of symbols appeared in this C
file . The compile stage will pass smoothly if you don't provide the
respective object file, which is normally put in an archived library
file together with other object files. The object file, which is created
from the relevant C file, is needed in link phase. If the archived
library file is named libmath.a, then you have to tell ld to attach this
library in the following way:
gcc test2.c -o test2 -lmath
Please notice the notation. It should be "-lmath" ,not "-llibmath.a"
In your codes, there is a line:
#include "nrutil.h"
but no library is given explicitly in the command line. Surely you will
fail.
There are one exception. When you put line like "#include <stdlib.h>"
in your c file, the relavant object file, or library will be
automatically attached to your execute file. It is called C runtime library.
I hope this will help you.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Inverse Matrix Implementation Problem...
2002-07-02 16:27 Inverse Matrix Implementation Problem W L A Au
2002-07-03 7:23 ` zhenggen
@ 2002-07-04 7:08 ` Edmund Green
1 sibling, 0 replies; 3+ messages in thread
From: Edmund Green @ 2002-07-04 7:08 UTC (permalink / raw)
To: W L A Au; +Cc: gcc-help
re:
> Please help me. I've encounter some problems when I try to implement the
> inverse matrix function by using the Gauss-Jordan Elimination routine,
> which is provided by the Numerical Recipes in C, Chapter 2.1
...
> However, when I use the gcc compiler command:
> gcc test2.c -o test2
>
> I've got the following error message:
>
> Undefined first referenced
> symbol in file
> free_ivector /var/tmp/cc4v8fRq.o
> ivector /var/tmp/cc4v8fRq.o
> nrerror /var/tmp/cc4v8fRq.o
> ld: fatal: Symbol referencing errors. No output written to test2
> collect2: ld returned 1 exit status
These missing library routines are found in the nrutil.c file (see
Appendix B of the book), to save having to duplicate them for each
example in the book.
This makes your compilation more complex, you should really be using
makefiles for anything with more than 1 source file (see "info make").
They are a very powerful but can also get very complicated.
However in this simple case, if you don't mind 'make' doing a few things
behind your back with its built in implicit rules, create a file called
"makefile" with the following single line in it
test2 : test2.o nrutil.o
and put in in a directory that also contains "test2.c", "nrutil.h" and
"nrutil.c", then run the command "make".
Edmund.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2002-07-04 14:08 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-07-02 16:27 Inverse Matrix Implementation Problem W L A Au
2002-07-03 7:23 ` zhenggen
2002-07-04 7:08 ` Edmund Green
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).