5 /* gcc interpolation.c -o interpolation */
8 err(int eval, const char *fmt, ...)
12 errx(int eval, const char *fmt, ...)
17 #define ED_MAX_SAMPLES_NO 1000
18 #define ED_MAX_LINE_LEN 128
20 #define EX_UNAVAILABLE 3
21 #define ED_TOK_DELAY "delay"
22 #define ED_TOK_PROB "prob"
23 #define ED_SEPARATORS " \t\n"
24 #define ED_TOK_PROFILE_NO "profile_no"
33 char filename[128]; /* profile filename */
34 int samples[ED_MAX_SAMPLES_NO+1]; /* may be shorter */
35 int samples_no; /* actual len of samples[] */
39 * returns 1 if s is a non-negative number, with at least one '.'
42 is_valid_number(const char *s)
45 int i, dots_found = 0;
48 for (i = 0; i<len; ++i)
49 if (!isdigit(s[i]) && (s[i] !='.' || ++dots_found > 1))
56 compare_points(const void *vp1, const void *vp2)
58 const struct point *p1 = vp1;
59 const struct point *p2 = vp2;
62 res = p1->prob - p2->prob;
64 res = p1->delay - p2->delay;
73 #define ED_EFMT(s) 1,"error in %s at line %d: "#s,filename,lineno
76 * The points defined by the user are stored in the ponts structure.
77 * The number of user defined points is stored in points_no.
78 * We assume that The last point for the '1' value of the
79 * probability should be defined. (XXX add checks for this)
80 * The user defined sampling value is stored in samples_no.
81 * The resulting samples are in the "samples" pointer.
84 interpolate_samples(struct point *p, int points_no,
85 int *samples, int samples_no, const char *filename)
87 double dy; /* delta on the y axis */
88 double y; /* current value of y */
89 double x; /* current value of x */
90 double m; /* the y slope */
91 int i; /* samples index */
92 int curr; /* points current index */
97 for (i=0, curr = 0; i < samples_no; i++, y+=dy) {
98 /* This statment move the curr pointer to the next point
99 * skipping the points with the same x value. We are
100 * guaranteed to exit from the loop because the
101 * last possible value of y is stricly less than 1
102 * and the last possible value of the y points is 1 */
103 while ( y >= p[curr+1].prob ) curr++;
105 /* compute the slope of the curve */
106 m = (p[curr+1].delay - p[curr].delay) / (p[curr+1].prob - p[curr].prob);
107 /* compute the x value starting from the current point */
108 x = p[curr].delay + (y - p[curr].prob) * m;
112 /* add the last sample */
113 samples[i] = p[curr+1].delay;
118 interpolate_samples_old(struct point *points, int points_no,
119 int *samples, int samples_no, const char *filename)
121 int i; /* pointer to the sampled array */
122 int j = 0; /* pointer to user defined samples */
123 double dy; /* delta y */
124 double y; /* current value of y */
125 int x; /* computed value of x */
126 double m; /* slope of the line */
127 double y1, x1, y2, x2; /* two points of the current line */
129 /* make sure that there are enough points. */
130 /* XXX Duplicated shoule be removed */
132 errx(EX_DATAERR, "%s too few samples, need at least %d",
135 qsort(points, points_no, sizeof(struct point), compare_points);
139 printf("\nsamples no is %d dy is %f ", samples_no, dy);
141 /* start with the first two points */
142 y1 = points[j].prob * samples_no;
143 x1 = points[j].delay;
145 y2 = points[j].prob * samples_no;
146 x2 = points[j].delay;
150 printf("\n\tCurrent points x1 y1 %f %f next point x2y2 %f %f m %f\n",
156 for(i=0; i < samples_no+1; i++, y+=dy) {
157 printf("\ni:%d j:%d y:%f real y:%f", i, j, y, y*samples_no);
158 if ( (y*samples_no) >= y2 ) { /* move to the next point */
160 if ( j >= points_no ) {
161 printf("\n\tNo more points, exit with j: %d i: %d and y:%f %f\n",
162 j, i, y, (y*samples_no));
163 break; /* no more user defined points */
165 /* load a new point */
168 y2 = points[j].prob * samples_no;
169 x2 = points[j].delay;
171 if (x1==x2) { /* m = infinito */
175 /* very small m problem */
176 printf ("\ndelta %f\n", (y1 - y2));
177 if (abs(y1 - y2) < 0.00001) { /* m = 0 XXX Should this magic number depend on samples_no ? */
181 printf("\n\tCurrent points x1 y1 %f %f next point x2y2 %f %f (%f/%f)=m \n",
182 x1, y1, x2, y2, (y2-y1), (x2-x1), m);
184 printf("\n\tcompute step y %f x[%d]=%d ",
186 if ((m != -1) && ( m != 0 )) {
187 x = x + (dy * samples_no)/m;
190 printf(" dy %f x new %d\n", dy*samples_no, x);
191 printf(" m %f (dy * samples_no)/m %f \n", m, (dy * samples_no)/m);
195 printf("Finish i is %d samples_no is %d\n", i, samples_no);
196 /* The last point has a probability less than 1 */
197 for (; i <= samples_no; i++)
203 load_profile(struct profile *p)
205 FILE *f; /* file handler */
206 char line[ED_MAX_LINE_LEN];
209 int delay_first = -1;
212 struct point points[1000]; /* MAX_POINTS_NO */
215 char *filename = p->filename;
216 f = fopen(filename, "r");
218 err(EX_UNAVAILABLE, "fopen: %s", filename);
222 while (fgets(line, ED_MAX_LINE_LEN, f)) { /* read commands */
223 char *s, *cur = line, *name = NULL, *arg = NULL;
229 s = strsep(&cur, ED_SEPARATORS);
230 if (s == NULL || *s == '#')
235 errx(ED_EFMT("too many arguments"));
245 if (!strcasecmp(name, ED_TOK_DELAY)) {
247 errx(ED_EFMT("duplicated token: %s"), name);
251 } else if (!strcasecmp(name, ED_TOK_PROB)) {
253 errx(ED_EFMT("duplicated token: %s"), name);
258 if (!strcasecmp(name, ED_TOK_PROFILE_NO)) {
259 int p_no = atof(arg);
262 printf("invalid interpolation samples, using %d\n",
265 if (p_no > ED_MAX_SAMPLES_NO) {
266 p_no = ED_MAX_SAMPLES_NO;
267 printf("invalid interpolation samples, using %d\n",
271 p->samples_no = p_no;
274 } else if (do_points) {
275 if (!is_valid_number(name) || !is_valid_number(arg))
276 errx(ED_EFMT("invalid point found"));
278 points[points_no].delay = atof(name);
279 points[points_no].prob = atof(arg);
281 points[points_no].delay = atof(arg);
282 points[points_no].prob = atof(name);
284 if (points[points_no].prob > 1.0)
285 errx(ED_EFMT("probability greater than 1.0"));
287 /* XXX no more that 1000 */
290 errx(ED_EFMT("unrecognised command '%s'"), name);
294 for(i=0; i < p->samples_no; i++) {
298 /* This code assume the user define a value of X for the sampling value,
300 * - the value stored in the emulator structure is X;
301 * - the allocated structure for the samples is X+1;
303 interpolate_samples(points, points_no, p->samples, p->samples_no, filename);
305 // User defined samples
306 printf("\nLoaded %d points:\n", points_no);
307 for(i=0; i < points_no; i++) {
308 printf("%f %f\n", points[i].prob, points[i].delay);
311 printf("The sample value is %d \n", p->samples_no);
315 int main(int argc, char **argv)
318 printf("Usage: ./interpolation <filename>\n");
328 strncpy(p.filename, filename, 128);
330 printf("-----------\n");
331 for (i=0; i<=p.samples_no; i++)
332 printf("%d %d\n", i, p.samples[i]);
333 printf("-----------\n");