malt-wr
region.c
Go to the documentation of this file.
1 /* the simpicial method */
2 
3 #include <math.h>
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
7 
8 #include "constype.h"
9 #include "qnrutil.h"
10 #include "points.h"
11 
12 #define DEBUG 0
13 #define DEBUG_ADD 0
14 
15 
17 {
18  double dist;
19  double alpha;
20  double delta;
21  int start_pnt;
22  int end_pnt;
24 };
25 
26 typedef struct
27 {
28  double x;
29  double y;
30  double mx;
31  double my;
32  double alpha;
33 } REGION_PNT;
34 
36 
37 
39 static double minimum_alpha;
40 
41 
42 static void add_to_crv_list(REGION_CRV *new)
43 {
44  REGION_CRV *tmp;
45 
46 
47  if(largest_crv==NULL) {
48  largest_crv=new;
49  return;
50  }
51 
52  if(new->dist>largest_crv->dist) {
53  new->next=largest_crv;
54  largest_crv = new;
55  return;
56  }
57 
58  tmp = largest_crv;
59  while(tmp->next!=NULL) {
60  if(new->dist>tmp->next->dist) {
61  new->next=tmp->next;
62  tmp->next=new;
63  break;
64  }
65  tmp=tmp->next;
66  }
67 
68  if(tmp->next==NULL)
69  tmp->next=new;
70 }
71 
72 #if DEBUG_PREVIOUS
73 
74 static int modify_region_crv_list(int x, int y)
75 {
76  REGION_CRV *nc1, *nc2, *tmp;
77  double dist;
78 
79  nc1 = (REGION_CRV *)calloc(1, sizeof(REGION_CRV));
80  nc2 = (REGION_CRV *)calloc(1, sizeof(REGION_CRV));
81 
82  if((nc1==NULL) || (nc2==NULL))
83  return 0;
84 
85  nc1->alpha = largest_crv->alpha - largest_crv->delta;
86  nc1->start_pnt = largest_crv->start_pnt;
87  nc1->end_pnt = pntcount;
88  nc1->delta = largest_crv->delta/2;
89  nc1->dist = 0;
90  nc1->dist += (hullpnts[pntcount][x] - hullpnts[nc1->start_pnt][x])*
91  (hullpnts[pntcount][x] - hullpnts[nc1->start_pnt][x]);
92  nc1->dist += (hullpnts[pntcount][y] - hullpnts[nc1->start_pnt][y])*
93  (hullpnts[pntcount][y] - hullpnts[nc1->start_pnt][y]);
94 
95  nc2->start_pnt = pntcount;
96  nc2->end_pnt = largest_crv->end_pnt;
97  nc2->alpha = largest_crv->alpha + largest_crv->delta;
98  nc2->delta = largest_crv->delta/2;
99  nc2->dist = 0;
100  nc2->dist += (hullpnts[nc2->end_pnt][x] - hullpnts[pntcount][x])*
101  (hullpnts[nc2->end_pnt][x] - hullpnts[pntcount][x]);
102  nc2->dist += (hullpnts[nc2->end_pnt][y] - hullpnts[pntcount][y])*
103  (hullpnts[nc2->end_pnt][y] - hullpnts[pntcount][y]);
104 
105  tmp = largest_crv;
106  largest_crv = largest_crv->next;
107  free(tmp);
108 
109  add_to_crv_list(nc1);
110  add_to_crv_list(nc2);
111  return 1;
112 }
113 
114 #endif
115 
116 
117 static double angle(double x, double y)
118 /* translation of the tangent of the angle into angle in the range of
119  0 .. 2*PI */
120 {
121  double alpha;
122 
123  alpha = atan(y/x);
124  if(x<0)
125  alpha+=M_PI;
126  if(alpha<0)
127  alpha+=2*M_PI;
128 
129  return alpha;
130 }
131 
132 
133 static int modify_region_crv_list(int x, int y)
134 {
135  REGION_CRV *nc1, *nc2, *tmp;
136  double dist;
137  double new_point_x, new_point_y;
138  double last_alpha;
139 
140  nc1 = (REGION_CRV *)calloc(1, sizeof(REGION_CRV));
141  nc2 = (REGION_CRV *)calloc(1, sizeof(REGION_CRV));
142 
143  if((nc1==NULL) || (nc2==NULL))
144  return 0;
145 
146  nc1->start_pnt = largest_crv->start_pnt;
147  nc1->end_pnt = pntcount;
148 
149  new_point_x = (hullpnts[nc1->end_pnt][x] + hullpnts[nc1->start_pnt][x])/2;
150  new_point_y = (hullpnts[nc1->end_pnt][y] + hullpnts[nc1->start_pnt][y])/2;
151 
152  nc1->alpha = angle(new_point_x-centerpnt[x], new_point_y-centerpnt[y]);
153 
154  nc1->dist = 0;
155  nc1->dist += (hullpnts[pntcount][x] - hullpnts[nc1->start_pnt][x])*
156  (hullpnts[pntcount][x] - hullpnts[nc1->start_pnt][x]);
157  nc1->dist += (hullpnts[pntcount][y] - hullpnts[nc1->start_pnt][y])*
158  (hullpnts[pntcount][y] - hullpnts[nc1->start_pnt][y]);
159 
160  nc2->start_pnt = pntcount;
161  nc2->end_pnt = largest_crv->end_pnt;
162 
163  new_point_x = (hullpnts[nc2->end_pnt][x] + hullpnts[nc2->start_pnt][x])/2;
164  new_point_y = (hullpnts[nc2->end_pnt][y] + hullpnts[nc2->start_pnt][y])/2;
165 
166  nc2->alpha = angle(new_point_x-centerpnt[x], new_point_y-centerpnt[y]);
167 
168  nc2->dist = 0;
169  nc2->dist += (hullpnts[nc2->end_pnt][x] - hullpnts[pntcount][x])*
170  (hullpnts[nc2->end_pnt][x] - hullpnts[pntcount][x]);
171  nc2->dist += (hullpnts[nc2->end_pnt][y] - hullpnts[pntcount][y])*
172  (hullpnts[nc2->end_pnt][y] - hullpnts[pntcount][y]);
173 
174  last_alpha = largest_crv->alpha;
175 
176  tmp = largest_crv;
177  largest_crv = largest_crv->next;
178  free(tmp);
179 
180  if(fabs(nc1->alpha-last_alpha) > minimum_alpha)
181  add_to_crv_list(nc1);
182  else
183  free(nc1);
184  if(fabs(nc2->alpha-last_alpha) > minimum_alpha)
185  add_to_crv_list(nc2);
186  else
187  free(nc2);
188  return 1;
189 }
190 
191 
192 static show_list()
193 {
194  REGION_CRV *tmp=largest_crv;
195 
196  printf("\n");
197  while(tmp!=NULL) {
198  printf("start=%d\tend=%d\tdist= %5.5lg\talpha=%5.2lf\n",
199  tmp->start_pnt, tmp->end_pnt, tmp->dist, 180*tmp->alpha/M_PI);
200  tmp=tmp->next;
201  }
202  printf("\n");
203 }
204 
205 
206 #if DEBUG
207 static int addpoint_debug(double *pc, double*po)
208 {
209  int i;
210 
211  pntcount++;
212  for (i=1; i<=dim; i++)
213  hullpnts[pntcount][i]=po[i];
214 
215  return 1;
216 }
217 #endif
218 
219 
220 static int pointcomp(REGION_PNT *rp1, REGION_PNT *rp2)
221 {
222  if(rp1->alpha > rp2->alpha)
223  return 1;
224  else
225  if(rp1->alpha < rp2->alpha)
226  return -1;
227  else
228  return 0;
229 }
230 
231 
232 static void set_and_print_point(double alpha, int x, int y,
233  REGION_PNT *region_points)
234 {
235  region_points[pntcount].x=hullpnts[pntcount][x]*scale[x];
236  region_points[pntcount].y=hullpnts[pntcount][y]*scale[y];
237  region_points[pntcount].alpha=180*alpha/M_PI;
238 
239  printf("%5.2lf\t%9.5lf\t%9.5lf\t",
240  180*alpha/M_PI,
241  hullpnts[pntcount][x]*scale[x],
242  hullpnts[pntcount][y]*scale[y]);
243 
244  region_points[pntcount].mx=
245  100.0*(hullpnts[pntcount][x]-centerpnt[x])/centerpnt[x];
246  region_points[pntcount].my=
247  100.0*(hullpnts[pntcount][y]-centerpnt[y])/centerpnt[y];
248  printf("%5.2lf\t%5.2lf\n",
249  region_points[pntcount].mx,
250  region_points[pntcount].my);
251 
252 }
253 
254 
256 {
257  int x, y;
258  int i, k;
259  double xbound_x, xbound_y, ybound_x, ybound_y;
260  double alpha, delta_alpha=M_PI/4;
261  int points_nr;
262  REGION_CRV *tmp;
263  PARAMETER_SET *tmp_param_set=parameter_list;
264 
265  FILE *fp;
266  char outfile[LINE_LENGTH];
267  char errmsg[LINE_LENGTH];
269 
270  double marginsx, marginsy;
271  double *po, *pc;
272  REGION_PNT *region_points;
273 
274  double minx_x, minx_y, maxx_x, maxx_y;
275  int min_i, max_i;
276 
277  double new_point_x, new_point_y;
278 
279 
280  while (tmp_param_set!=NULL) {
281 
282  x=tmp_param_set->x;
283  y=tmp_param_set->y;
284  points_nr=tmp_param_set->points_nr;
285 
286  strcpy(outfile, param.output_dir);
287  strcat(outfile, param.circuit_name);
288  strcat(outfile, param.region_ext);
289  strcat(outfile, param.opt_num);
290  i=strlen(outfile);
291  sprintf(&outfile[i], ".%d_%d", x, y);
292 
293  if ((fp=fopen(outfile,"w")) == NULL) {
294  strcpy(errmsg, "Can't write to the '");
295  strcat(errmsg, outfile);
296  strcat(errmsg, "' file.\n");
297  nrerror(errmsg);
298  }
299 
300  pc=vector(1,dim);
301  po=vector(0,dim);
302  hullpnts = matrix(1,points_nr+1,0,dim);
303  region_points = (REGION_PNT *)calloc(points_nr+1, sizeof(REGION_PNT));
304  pntcount=0;
305 
306 
307 #if DEBUG
308  printf("%9.5f\t%9.5f\t%9.5f\t%9.5f\n\n\n",
309  lower[x], upper[x], lower[y], upper[y]);
310 #endif
311 
313 
314 /* alpha = 0 */
315  alpha = 0;
316  for (i=1; i<=dim; i++)
317  pc[i]=po[i]=centerpnt[i];
318 
319  po[x] = upper[x];
320  po[y] = centerpnt[y];
321 
322 #if DEBUG_ADD
323  if (!addpoint_debug(pc,po))
324  nrerror("parameter values failed");
325 #else
326  if (!addpoint(pc,po))
327  nrerror("parameter values failed");
328 #endif
329 
330  set_and_print_point(alpha, x, y, region_points);
331 
332 
333  for(alpha=M_PI/2; alpha<=2*M_PI; alpha+=M_PI/2) {
334 
335  tmp = (REGION_CRV*)calloc(1, sizeof(REGION_CRV));
336  tmp->start_pnt = pntcount;
337  tmp->end_pnt = 1+pntcount%4;
338 
339 
340 #if DEBUG_PREVIOUS
341  tmp->alpha = alpha - delta_alpha;
342  tmp->delta = delta_alpha/2;
343 #endif
344 
345  if(tmp->end_pnt!=1) {
346 
347  for (i=1; i<=dim; i++)
348  pc[i]=po[i]=centerpnt[i];
349 
350  if(alpha == M_PI/2) {
351  po[x] = centerpnt[x];
352  po[y] = upper[y];
353  }
354  else if(alpha == M_PI) {
355  po[x] = lower[x];
356  po[y] = centerpnt[y];
357  } else if (alpha==3*M_PI/2) {
358  po[x] = centerpnt[x];
359  po[y] = lower[y];
360  }
361 
362 
363 #if DEBUG_ADD
364  if (!addpoint_debug(pc,po))
365  nrerror("parameter values failed");
366 #else
367  if (!addpoint(pc,po))
368  nrerror("parameter values failed");
369 #endif
370  set_and_print_point(alpha, x, y, region_points);
371  }
372 
373  new_point_x = (hullpnts[tmp->end_pnt][x] + hullpnts[tmp->start_pnt][x])/2;
374  new_point_y = (hullpnts[tmp->end_pnt][y] + hullpnts[tmp->start_pnt][y])/2;
375 
376  tmp->alpha = angle(new_point_x-centerpnt[x], new_point_y-centerpnt[y]);
377 
378 
379  tmp->dist = 0;
380  tmp->dist += (hullpnts[tmp->end_pnt][x]
381  - hullpnts[tmp->start_pnt][x])*
382  (hullpnts[tmp->end_pnt][x]
383  - hullpnts[tmp->start_pnt][x]);
384  tmp->dist += (hullpnts[tmp->end_pnt][y]
385  - hullpnts[tmp->start_pnt][y])*
386  (hullpnts[tmp->end_pnt][y]
387  - hullpnts[tmp->start_pnt][y]);
388  add_to_crv_list(tmp);
389 #if DEBUG
390  show_list();
391 #endif
392  } /* for */
393 
394 
395  for(k=0; k<points_nr-4; k++) {
396 
397  for (i=1; i<=dim; i++)
398  pc[i]=po[i]=centerpnt[i];
399 
400 
401  alpha = largest_crv->alpha;
402 
403  if((alpha<M_PI/2) || (alpha>3*M_PI/2))
404  xbound_x = upper[x];
405  else
406  xbound_x = lower[x];
407  if(alpha<M_PI)
408  ybound_y = upper[y];
409  else
410  ybound_y = lower[y];
411 
412  xbound_y=centerpnt[y]+tan(alpha)*(xbound_x-centerpnt[x]);
413 
414  if(fabs(xbound_y-centerpnt[y]) <=fabs(ybound_y-centerpnt[y])) {
415  po[x] = xbound_x;
416  po[y] = xbound_y;
417  }
418  else {
419  ybound_x =
420  (ybound_y - centerpnt[y])/tan(alpha) +
421  centerpnt[x];
422  po[x] = ybound_x;
423  po[y] = ybound_y;
424  }
425 
426 #if DEBUG_ADD
427  if (!addpoint_debug(pc,po))
428  nrerror("parameter values failed");
429 #else
430  if (!addpoint(pc,po))
431  nrerror("parameter values failed");
432 #endif
433 
434  set_and_print_point(alpha, x, y, region_points);
436 #if DEBUG
437  show_list();
438 #endif
439  } /* for */
440 
441  qsort(&region_points[1], points_nr, sizeof(REGION_PNT),
442  (int (*)())pointcomp);
443 
444 
445  for(i=0; i<=points_nr; i++) {
446  k=1+i%points_nr;
447  fprintf(fp, "%5.2lf\t%9.5lf\t%9.5lf\t%5.2lf\t%5.2lf\n",
448  region_points[k].alpha,
449  region_points[k].x,
450  region_points[k].y,
451  region_points[k].mx,
452  region_points[k].my);
453  }
454 
455  free_vector(pc, 1,dim);
456  free_vector(po, 0,dim);
457  free_matrix(hullpnts,1,points_nr+1,0,dim);
458  free(region_points);
459  fclose(fp);
460 
461  printf("\n\n");
462 
463  tmp_param_set=tmp_param_set->next;
464  } /* while */
465 }
466 
static double angle(double x, double y)
Definition: region.c:117
static void add_to_crv_list(REGION_CRV *new)
Definition: region.c:42
double * scale
Definition: points.c:14
char circuit_name[NAME_LENGTH]
Definition: constype.h:184
double dist
Definition: region.c:18
double alpha
Definition: region.c:19
double delta
Definition: region.c:20
char output_dir[NAME_LENGTH]
Definition: constype.h:149
#define LONG_LINE_LENGTH
Definition: constype.h:5
double mx
Definition: region.c:30
void free_vector(double *v, int nl, int nh)
Definition: qnrutil.c:95
PARAMETER_SET * parameter_list
Definition: points.c:17
int dim
Definition: points.c:11
int pntcount
Definition: points.c:12
PARAMETERS param
Definition: init.c:10
double ** hullpnts
Definition: points.c:14
void nrerror(char *error_text)
Definition: lineread.c:7
static double minimum_alpha
Definition: region.c:39
static int pointcomp(REGION_PNT *rp1, REGION_PNT *rp2)
Definition: region.c:220
double * lower
Definition: points.c:14
char opt_num[NAME_LENGTH]
Definition: constype.h:196
double * vector(int nl, int nh)
Definition: qnrutil.c:16
static int modify_region_crv_list(int x, int y)
Definition: region.c:133
double * upper
Definition: points.c:14
struct REGION_CRV_STRUCT * next
Definition: region.c:23
double x
Definition: region.c:28
double * centerpnt
Definition: points.c:14
#define LINE_LENGTH
Definition: constype.h:4
double my
Definition: region.c:31
void free_matrix(double **m, int nrl, int nrh, int ncl, int nch)
Definition: qnrutil.c:108
int get_regions()
Definition: region.c:255
double alpha
Definition: region.c:32
char region_ext[NAME_LENGTH]
Definition: constype.h:179
static REGION_CRV * largest_crv
Definition: region.c:38
#define MINIMUM_ALPHA_DIVIDER
Definition: points.h:5
double y
Definition: region.c:29
int addpoint(double *pc, double *po)
Definition: points.c:40
static char outline[LONG_LINE_LENGTH]
Definition: optimize.c:39
struct PARAMETER_SET_STRUCT * next
Definition: constype.h:537
static void set_and_print_point(double alpha, int x, int y, REGION_PNT *region_points)
Definition: region.c:232
double ** matrix(int nrl, int nrh, int ncl, int nch)
Definition: qnrutil.c:40
static show_list()
Definition: region.c:192