Hello,
i am new in use of nr in C. i borrowed me the 2nd edition of nr in a university libary. in the book was also a diskette (lovely DOS :-) ). i install the diskette an get many files... thats good.
but my problem is that i don't know how can i import my data set (x,y over 1500 points) in the c code and how can i purport a fit.
can someone show me an example?
It is very important. I hope someone helps me.
Thanks and see you
kepi
davekw7x
08-15-2009, 05:54 PM
... how can i import my data set (x,y over 1500 points)...
In the following example, I hard-coded the name of the file into the program. You can, obviously, change the program to meet your needs. For example you could change it to get the name from the user from the command line or from a prompt within the main program. Or whatever...
I added a line at the beginning of the file to tell the program how many data points follow. There are other ways to handle it, but putting in the count value is easy and straightforward. At least, that's what I would (probably) do. Your Mileage May Vary.
/*
* Demonstration of NR routine svdfit
*
* Data points are in a file.
*
* The first line of the file has an integer that indicates
* the number of points.
* The lines after that have x and y values for each point.
*
* This program uses the NR function fpoly with svdfit to
* obtain a "best fit" polynomial from the data points, and
* then calls svdvar to calculate the covariance matrix
* to obtain a chi-square estimate of "goodness of fit."
*
*
* davekw7x
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "nr.h"
#include "nrutil.h"
int main()
{
int num_coeffs = 5; /* Fourth order polynomial has five coefficients */
float noise = 0.02; /* Estimate of std deviation of measurement error */
float chisq, *x, *y, *sig, *a, *w, **cvm, **u, **v;
int i;
int num_points;
int num_values;
char inbuf[BUFSIZ];
char *inname = "test.txt";
FILE *infile = fopen(inname, "r");
if (!infile) {
printf("Can't open file %s for reading.\n", inname);
return EXIT_FAILURE;
}
printf("Opened file %s for reading.\n", inname);
if (!fgets(inbuf, sizeof(inbuf), infile)) {
printf("Couldn't read the first line.\n");
return EXIT_FAILURE;
}
if ((sscanf(inbuf, "%d", &num_points) < 1) || (num_points <= 0)) {
printf("First line must contain a positive integer.\n");
return EXIT_FAILURE;
}
x = vector(1, num_points);
y = vector(1, num_points);
sig = vector(1, num_points);
a = vector(1, num_coeffs);
w = vector(1, num_coeffs);
cvm = matrix(1, num_coeffs, 1, num_coeffs);
u = matrix(1, num_points, 1, num_coeffs);
v = matrix(1, num_coeffs, 1, num_coeffs);
for (i = 1; i <= num_points; i++) {
if (!fgets(inbuf, sizeof(inbuf), infile)) {
printf("Couldn't read line number %d\n", i);
break;
}
if (sscanf(inbuf, "%f %f", &x[i], &y[i]) != 2) {
printf("Error reading line number %d\n", i);
break;
}
sig[i] = noise * y[i];
}
num_values = i-1;
printf("Number of data points = %d\n\n", num_values);
/*
* Calculate best-fit polynomial coefficients.
*/
svdfit(x, y, sig, num_values, a, num_coeffs, u, v, w, &chisq, fpoly);
/*
* Calculate covariance matrix to get a chi-square
* estimate of goodness of fit
*/
svdvar(v, num_coeffs, w, cvm);
printf("Coefficients for polynomial of order %d:\n\n", num_coeffs-1);
for (i = 1; i <= num_coeffs; i++) {
printf("%12.6f %s %10.6f\n", a[i], " +-", sqrt(cvm[i][i]));
}
printf("\nChi-squared %12.6f\n", chisq);
free_matrix(v, 1, num_coeffs, 1, num_coeffs);
free_matrix(u, 1, num_points, 1, num_coeffs);
free_matrix(cvm, 1, num_coeffs, 1, num_coeffs);
free_vector(w, 1, num_coeffs);
free_vector(a, 1, num_coeffs);
free_vector(sig, 1, num_points);
free_vector(y, 1, num_points);
free_vector(x, 1, num_points);
return EXIT_SUCCESS;
}
Regards,
Dave
hallo dave,
thank you for your help. i think my svdfit.c code is absolute damaged by someone.... the gcc compiler gives this message
svdfit.c: In function ‘svdfit’:
svdfit.c:6: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘_’
svdfit.c:15: error: invalid type argument of ‘unary *’ (have ‘int’)
svdfit.c:30: error: invalid type argument of ‘unary *’ (have ‘int’)
can you post me your svdfit.c code?
in your last post you have write this comment:
* This program uses the NR function fpoly with svdfit to
* obtain a "best fit" polynomial from the data points, and
* then calls svdvar to calculate the covariance matrix
* to obtain a chi-square estimate of "goodness of fit."
and in the svdfit function it uses the fpoly.c file. but i want to give a another fit formula like this:
a*x^2 + b*x + c/x + d*log(x) + e
the parameters are a,b,c,d,e
how can i get then my coefficients??
thanks and see you
kepi
davekw7x
08-16-2009, 11:07 AM
...
can you post me your svdfit.c code? I am using code from the Numerical Recipes distribution CD. The code is the same as the listings in the book. It is copyrighted, and it would be illegal to post it.
...i want to give a another fit formula like this:
a*x^2 + b*x + c/x + d*log(x) + e
the parameters are a,b,c,d,e
Your basis functions are x^2, x, 1.0/x, log(x) and 1, so you would use something like the following function instead of fpoly in the example program of my previous post:
/*
* Note that np is not used in this function but it still has to
* have this signature.
*/
void foo(float x, float p[], int np)
{
p[1] = x*x;
p[2] = x;
p[3] = 1.0/x;
p[4] = log(x);
p[5] = 1.0;
}
.
.
.
int main()
{
.
.
.
svdfit(x, y, sig, num_values, a, num_coeffs, u, v, w, &chisq, foo);
Regards,
Dave
hello dave,
I have tried to make a same routine for lfit.c like svdfit.c. but i don't managed it. can you explain me, how can i change the code, that you send me yesterday?
i don't know the inputs of lfit.c and if have the test.txt file three coloums??? where the 3rd coloum is sig??
thanks and see you
kepi
i have forgotten to say, that the coefficients from the svdfit.c are not precisely and i want to compare it with lfit.c.
davekw7x
08-17-2009, 09:30 AM
I have tried to make a same routine for lfit.c
int main()
{
.
.
.
int *ia;
.
.
.
ia = ivector(1, num_coeffs);
for (i = 1; i <= num_coeffs; i++) {
ia[i] = 1;
}
.
.
.
for (i = 1; i <= num_points; i++) {
if (!fgets(buffer, sizeof(buffer), infile)) {
printf("Couldn't read line number %d\n", i);
break;
}
if (sscanf(buffer, "%f %f %f", &x[i], &y[i], &sig[i]) != 3) {
printf("Couldn't read data on line number %d\n", i);
break;
}
}
num_values = i-1;
printf("Read %d lines.\n", num_values);
lfit(x, y, sig, num_values, a, ia, num_coeffs, cvm, &chisq, foo);
.
.
.
Regards,
Dave