numtools

perform numerical operations on vectors and matrices in unix pipes
git clone git://src.adamsgaard.dk/numtools # fast
git clone https://src.adamsgaard.dk/numtools.git # slow
Log | Files | Refs | README | LICENSE Back to index

util.c (1495B)


      1 #include <err.h>
      2 #include <stdlib.h>
      3 #include <stdio.h>
      4 #include "util.h"
      5 
      6 size_t
      7 allocarr(double **arr, const char *str, size_t maxlen)
      8 {
      9 	size_t i, nf = 0;
     10 
     11 	if (maxlen > 0)
     12 		nf = 1;
     13 	for (i = 0; i < maxlen && str[i] != '\0'; i++)
     14 		if (str[i] == DELIM)
     15 			nf++;
     16 	if (!(*arr = calloc(nf, sizeof(double))))
     17 		err(1, "calloc");
     18 
     19 	return nf;
     20 }
     21 
     22 int
     23 scannextval(char **str, double *val)
     24 {
     25 	int offset;
     26 
     27 	if (sscanf(*str, "%lg%n", val, &offset) != 1)
     28 		return 0;
     29 	*str += offset;
     30 
     31 	return 1;
     32 }
     33 
     34 void
     35 printarr(double *arr, size_t len)
     36 {
     37 	size_t i;
     38 
     39 	for (i = 0; i < len; i++) {
     40 		printf("%.17g", arr[i]);
     41 		if (i < len)
     42 			printf(DELIMSTR);
     43 	}
     44 	putchar('\n');
     45 }
     46 
     47 void
     48 printfarr(char *delimstr, int prec, double *arr, size_t len)
     49 {
     50 	size_t i;
     51 
     52 	for (i = 0; i < len; i++) {
     53 		printf("%.*g", prec, arr[i]);
     54 		if (i < len - 1)
     55 			fputs(delimstr, stdout);
     56 	}
     57 }
     58 
     59 size_t
     60 fscanmatrix(FILE *stream, double ***arr, size_t *nf)
     61 {
     62 	size_t i, nr = 0, linesize = 0;
     63 	char *line = NULL, *data = NULL;
     64 	double val;
     65 
     66 	*arr = calloc(1, sizeof(double *));
     67 
     68 	while (getline(&line, &linesize, stream) > 0) {
     69 		if (nr > 0)
     70 			if (!(*arr = xreallocarray(*arr, nr + 1, sizeof(double *))))
     71 				err(1, "reallocarray");
     72 		if ((*nf = allocarr(&(*arr)[nr], line, linesize)) == 0)
     73 			errx(1, "no fields in input");
     74 		data = line;
     75 		for (i = 0; i < *nf; i++) {
     76 			if (!scannextval(&data, &val))
     77 				errx(1, "could not parse line %ld, field %ld", nr + 1, i + 1);
     78 			(*arr)[nr][i] = val;
     79 		}
     80 		nr++;
     81 	}
     82 
     83 	free(line);
     84 
     85 	return nr;
     86 }