Hi Cristiano!
I had no trouble making the example work!
Dependencies: sudo apt install clang gnuplot gsl-bin libgsl-dev libcsv-dev valgrind gnuplot Build: gcc -g -O0 -o fitting my_fitting_C99.c -lcsv -lgsl Test: valgrind -s --undef-value-errors=no --leak-check=yes ./fitting
Here is the code modified to use libcsv
#include #include #include #include #include #include #include #include #include
#define SKIP_HEADER 3 #define COLUMN_X 0 #define COLUMN_Y 1
void skip_header(FILE * input_file, int number_off_lines_to_skip);
struct data_point { double x; double y; SLIST_ENTRY(data_point) entries; };
struct csv_data { double x; double y; int column; int rows; SLIST_HEAD(data_list, data_point) head; };
#pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" void cb1(void *s, size_t len, void *data) { struct csv_data *d = (struct csv_data *)data; if (d->column < 2) { const char *field = (const char *)s; double value; sscanf(field, "%lf", &value); if (COLUMN_X == d->column) { d->x = value; } else if (COLUMN_Y == d->column) { d->y = value; } } d->column += 1; } #pragma GCC diagnostic pop
#pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" void cb2(int c, void *data) { struct csv_data *d = (struct csv_data *)data; struct data_point *datum = malloc(sizeof(struct data_point)); datum->x = d->x; datum->y = d->y; SLIST_INSERT_HEAD(&d->head, datum, entries); d->x = 0; d->y = 0; d->column = 0; d->rows += 1; } #pragma GCC diagnostic pop
void skip_header(FILE * input_file, int number_off_lines_to_skip) { int row = 0; while (!ferror(input_file) && !feof(input_file) && row < number_off_lines_to_skip) { size_t buffer_size = 0; char *buffer = NULL; getline(&buffer, &buffer_size, input_file); free(buffer); row += 1; } }
#pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" int main(int argc, char *argv[]) { FILE *fp; struct csv_parser p; char buf[1024]; size_t bytes_read; struct csv_data d = { 0, 0, 0, 0, SLIST_HEAD_INITIALIZER(head) }; const char *input_file_name = "anscombe.csv"; const char *output_file_name = "fit_C99.csv"; const unsigned int N = 100;
SLIST_INIT(&d.head);
if (csv_init(&p, CSV_APPEND_NULL) != 0) exit(EXIT_FAILURE);
csv_set_delim(&p, '\t'); csv_set_quote(&p, '\0');
printf("#### Anscombe's first set with C99 ####\n");
fp = fopen(input_file_name, "rb"); if (!fp) { printf("ERROR: Unable to open file: %s", input_file_name); exit(EXIT_FAILURE); }
skip_header(fp, SKIP_HEADER);
while ((bytes_read = fread(buf, 1, 1024, fp)) > 0) if (csv_parse(&p, buf, bytes_read, cb1, cb2, &d) != bytes_read) { fprintf(stderr, "Error while parsing file: %s\n", csv_strerror(csv_error(&p))); exit(EXIT_FAILURE); }
csv_fini(&p, cb1, cb2, &d);
fclose(fp);
csv_free(&p);
double *x = malloc(sizeof(double) * d.rows); double *y = malloc(sizeof(double) * d.rows);
if (!x || !y) { printf("ERROR: Unable to allocate data arrays\n"); return EXIT_FAILURE; }
double min_x, max_x;
struct data_point *datum; unsigned int i = 0;
datum = SLIST_FIRST(&d.head);
min_x = datum->x; max_x = datum->x;
SLIST_FOREACH(datum, &d.head, entries) { const double current_x = datum->x; const double current_y = datum->y;
x[i] = current_x; y[i] = current_y; printf("x: %f, y: %f\n", x[i], y[i]); if (current_x < min_x) { min_x = current_x; } if (current_x > max_x) { max_x = current_x; } i += 1; } while (!SLIST_EMPTY(&d.head)) { struct data_point *datum = SLIST_FIRST(&d.head); SLIST_REMOVE_HEAD(&d.head, entries); free(datum); }
double slope; double intercept; double cov00, cov01, cov11; double chi_squared;
gsl_fit_linear(x, 1, y, 1, d.rows, &intercept, &slope, &cov00, &cov01, &cov11, &chi_squared); const double r_value = gsl_stats_correlation(x, 1, y, 1, d.rows);
printf("Slope: %f\n", slope); printf("Intercept: %f\n", intercept); printf("Correlation coefficient: %f\n", r_value);
FILE *output_file = fopen(output_file_name, "w");
if (!output_file) { printf("ERROR: Unable to open file: %s", output_file_name);
return EXIT_FAILURE; }
const double step_x = ((max_x + 1) - (min_x - 1)) / N;
for (unsigned int i = 0; i < N; i += 1) { const double current_x = (min_x - 1) + step_x * i; const double current_y = intercept + slope * current_x;
fprintf(output_file, "%f\t%f\n", current_x, current_y); }
free(x); free(y);
fclose(output_file);
exit(EXIT_SUCCESS); } #pragma GCC diagnostic pop
Regards,
Marcelo Módolo
Hi!
I think def add_one_word(words, word): return words.set(words.get(word, 0) + 1) Is def add_one_word(words, word): return words.set(word, words.get(word, 0) + 1)
Thanks
Authored Comments
Hi Cristiano!
I had no trouble making the example work!
Dependencies: sudo apt install clang gnuplot gsl-bin libgsl-dev libcsv-dev valgrind gnuplot
Build: gcc -g -O0 -o fitting my_fitting_C99.c -lcsv -lgsl
Test: valgrind -s --undef-value-errors=no --leak-check=yes ./fitting
Here is the code modified to use libcsv
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define SKIP_HEADER 3
#define COLUMN_X 0
#define COLUMN_Y 1
void skip_header(FILE * input_file, int number_off_lines_to_skip);
struct data_point
{
double x;
double y;
SLIST_ENTRY(data_point) entries;
};
struct csv_data
{
double x;
double y;
int column;
int rows;
SLIST_HEAD(data_list, data_point) head;
};
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
void cb1(void *s, size_t len, void *data)
{
struct csv_data *d = (struct csv_data *)data;
if (d->column < 2)
{
const char *field = (const char *)s;
double value;
sscanf(field, "%lf", &value);
if (COLUMN_X == d->column)
{
d->x = value;
}
else if (COLUMN_Y == d->column)
{
d->y = value;
}
}
d->column += 1;
}
#pragma GCC diagnostic pop
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
void cb2(int c, void *data)
{
struct csv_data *d = (struct csv_data *)data;
struct data_point *datum = malloc(sizeof(struct data_point));
datum->x = d->x;
datum->y = d->y;
SLIST_INSERT_HEAD(&d->head, datum, entries);
d->x = 0;
d->y = 0;
d->column = 0;
d->rows += 1;
}
#pragma GCC diagnostic pop
void skip_header(FILE * input_file, int number_off_lines_to_skip)
{
int row = 0;
while (!ferror(input_file) && !feof(input_file)
&& row < number_off_lines_to_skip)
{
size_t buffer_size = 0;
char *buffer = NULL;
getline(&buffer, &buffer_size, input_file);
free(buffer);
row += 1;
}
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
int main(int argc, char *argv[])
{
FILE *fp;
struct csv_parser p;
char buf[1024];
size_t bytes_read;
struct csv_data d = { 0, 0, 0, 0, SLIST_HEAD_INITIALIZER(head) };
const char *input_file_name = "anscombe.csv";
const char *output_file_name = "fit_C99.csv";
const unsigned int N = 100;
SLIST_INIT(&d.head);
if (csv_init(&p, CSV_APPEND_NULL) != 0)
exit(EXIT_FAILURE);
csv_set_delim(&p, '\t');
csv_set_quote(&p, '\0');
printf("#### Anscombe's first set with C99 ####\n");
fp = fopen(input_file_name, "rb");
if (!fp)
{
printf("ERROR: Unable to open file: %s", input_file_name);
exit(EXIT_FAILURE);
}
skip_header(fp, SKIP_HEADER);
while ((bytes_read = fread(buf, 1, 1024, fp)) > 0)
if (csv_parse(&p, buf, bytes_read, cb1, cb2, &d) != bytes_read)
{
fprintf(stderr, "Error while parsing file: %s\n",
csv_strerror(csv_error(&p)));
exit(EXIT_FAILURE);
}
csv_fini(&p, cb1, cb2, &d);
fclose(fp);
csv_free(&p);
double *x = malloc(sizeof(double) * d.rows);
double *y = malloc(sizeof(double) * d.rows);
if (!x || !y)
{
printf("ERROR: Unable to allocate data arrays\n");
return EXIT_FAILURE;
}
double min_x, max_x;
struct data_point *datum;
unsigned int i = 0;
datum = SLIST_FIRST(&d.head);
min_x = datum->x;
max_x = datum->x;
SLIST_FOREACH(datum, &d.head, entries)
{
const double current_x = datum->x;
const double current_y = datum->y;
x[i] = current_x;
y[i] = current_y;
printf("x: %f, y: %f\n", x[i], y[i]);
if (current_x < min_x)
{
min_x = current_x;
}
if (current_x > max_x)
{
max_x = current_x;
}
i += 1;
}
while (!SLIST_EMPTY(&d.head))
{
struct data_point *datum = SLIST_FIRST(&d.head);
SLIST_REMOVE_HEAD(&d.head, entries);
free(datum);
}
double slope;
double intercept;
double cov00, cov01, cov11;
double chi_squared;
gsl_fit_linear(x, 1, y, 1, d.rows,
&intercept, &slope, &cov00, &cov01, &cov11, &chi_squared);
const double r_value = gsl_stats_correlation(x, 1, y, 1, d.rows);
printf("Slope: %f\n", slope);
printf("Intercept: %f\n", intercept);
printf("Correlation coefficient: %f\n", r_value);
FILE *output_file = fopen(output_file_name, "w");
if (!output_file)
{
printf("ERROR: Unable to open file: %s", output_file_name);
return EXIT_FAILURE;
}
const double step_x = ((max_x + 1) - (min_x - 1)) / N;
for (unsigned int i = 0; i < N; i += 1)
{
const double current_x = (min_x - 1) + step_x * i;
const double current_y = intercept + slope * current_x;
fprintf(output_file, "%f\t%f\n", current_x, current_y);
}
free(x);
free(y);
fclose(output_file);
exit(EXIT_SUCCESS);
}
#pragma GCC diagnostic pop
Regards,
Marcelo Módolo
Hi!
I think
def add_one_word(words, word):
return words.set(words.get(word, 0) + 1)
Is
def add_one_word(words, word):
return words.set(word, words.get(word, 0) + 1)
Thanks