modolo

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