malt-wr
optimize.c
Go to the documentation of this file.
1 /* the simpicial method */
2 
3 /* minimum distance out from old plane */
4 #define STEP (param.accuracy/200.0)
5 /* distance out from search boundary */
6 #define OUT (param.accuracy/200.0)
7 #define DEFINED 1.0e-18
8 #define INSCRIBE 1.0e-8
9 
10 #include <math.h>
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <string.h>
14 
15 #include "qnrutil.h"
16 #include "qdet.h"
17 #include "dsimplx.h"
18 #include "constype.h"
19 #include "filenames.h"
20 #include "init.h"
21 #include "points.h"
22 #include "yield.h"
23 
24 void intpickpnts(int, int *);
25 void makeaplane(int *);
26 int findface(double *,double *);
27 int postcenter(int *,double *);
28 int postshift(int *,double *);
29 double det(double **, int);
30 int simplx(double **,int,int,int *,int *);
31 void make_more_mem(void);
32 
33 static int **abpnts;
34 static double **ab;
35 static char filename[LINE_LENGTH], NAMES[80];
36 static int plncount=0, maxplane=10;
37 static int stop=0;
38 static FILE *fpout;
40 static double **aNmatrix, *temp;
41 
42 #define OUT_SCREEN_FILE \
43  printf("%s", outline); \
44  fprintf(fpout, "%s", outline);
45 
46 static int read_opt_command_line(int argc, char *argv[])
47 {
48  if((argc<3) || (argc>4))
49  return 0;
50 
51  if(argc==3)
52  if(argv[1][0]!='-')
53  return 1;
54  else
55  return 0;
56 
57  if((argc==4) && (argv[2][0]!='-'))
58  {
59  if(strcmp(argv[1], "-B")==0)
60  {
62  return 1;
63  }
64  else
65  return 0;
66  }
67  else
68  return 0;
69 }
70 
71 #ifdef MAIN
72 #define opt_main main
73 #endif
74 
75 int opt_main(int argc, char *argv[])
76 {
77  FILE *fp, *ftest;
78  char outfile[LINE_LENGTH];
79  double *pc, *po, *facecenter, *radius, *direction;
80  double bound, cbig, c, out, distance, step, dist;
81  int *pntstack, *tang;
82  int x, y, xx;
83  int good, count, big, oldcount, lowcount, concave;
84  int iterate=0, direcount=0;
85  double yest1=1.0, yest3=1.0, *ypnt;
86  double gpdf3, gpdf1, total3, total1, ycount3, ycount1, gint3, gint1;
87  int outside;
88  long tick, z, seed=-1;
89 
90 /* load filename variables and stuff (Kris's) */
92 
93 /* check syntax */
94  if(!read_opt_command_line(argc, argv)) {
95  printf("SYNOPSIS:\n\topt [-B] <circuit_name> <parameter_set_number>\n\n");
96  exit(255);
97  }
98 
100  printf("Can't read the '");
101  printf(INIT_CONFIG_FILE);
102  printf("' file.\n");
103  exit(255);
104  }
105 /* read name of input file */
106  strncpy(param.circuit_name, argv[argc-2], NAME_LENGTH);
107 /* read name of input number */
108  strncpy(param.opt_num, argv[argc-1], NAME_LENGTH);
109 
111  strcat(param.spice_name, " -b ");
112 
114 
116 
117 /* create the ITERATE file*/
118  if ((fp=fopen("ITERATE","w")) == NULL) {
119  printf("Can't write the 'ITERATE' file.\n");
120  exit(255);
121  }
122  fprintf(fp,"Delete this file to terminate the optimization program intelligently.\n");
123  fclose(fp);
124 /* read input file, create and initialize global arrays */
125  readinit();
126 
127  for (x=1; dim >= x; ++x) maxplane *=2;
128  ab=matrix(1,maxplane,0,dim);
129  abpnts=imatrix(1,maxplane,0,dim);
130  hullpnts=matrix(1,param.maxiter+3*dim+1,1,dim);
131  aNmatrix=matrix(1,dim,1,dim);
132  temp=vector(0,dim);
133 /* open the output file */
134  strcpy(outfile, param.output_dir);
135  strcat(outfile, param.circuit_name);
136  strcat(outfile, param.opt_ext);
137  strcat(outfile, param.opt_num);
138 
139  if ((fpout=fopen(outfile,"w")) == NULL) {
140  printf("Can't write to the '");
141  printf(outfile);
142  printf("' file.\n");
143  exit(255);
144  }
145 /* check values of MIN_ITER and MAX_ITER */
146  if (param.miniter > param.maxiter) {
147  sprintf(outline,"MIN_ITER = %d is greater than MAX_ITER = %d. MAX_ITER will supercede.\n",param.miniter,param.maxiter);
149  }
150 
151 /* initialize local arrays */
152  facecenter=vector(1,dim);
153  radius=vector(0,dim+1);
154  for (x=0; dim+1 >= x; ++x)
155  radius[x]=0.0;
156  direction=vector(1,dim);
157  for (x=1; dim >= x; ++x)
158  direction[x]=0.0;
159  pntstack=ivector(1,dim);
160  pc=vector(1,dim);
161  po=vector(0,dim);
162 /* find initial dim*2 points, print margins */
163 /* turn the margins into points, print margins */
164  sprintf(outline, "Margins calculated to within +/-%5.2f percent.\n",param.accuracy);
166  sprintf(outline, " Margins: Percent:\n");
168  for (x=1; dim >= x; ++x) {
169  for (y=1; dim >= y; ++y)
170  pc[y]=po[y]=centerpnt[y];
171  pc[x]=centerpnt[x]-STEP/scale[x];
172  po[x]=lower[x]-OUT/scale[x];
173  if (!addpoint(pc,po))
174  nrerror("parameter values failed");
175  else {
176  sprintf(outline, "%s\t%9.5f%s...%9.5f ...",
177  names[x-1],
178  hullpnts[pntcount][x]*scale[x],
179  (hullpnts[pntcount][x]<lower[x])?"*":" ",
180  centerpnt[x]*scale[x]);
182  }
183  pc[x]=centerpnt[x]+STEP/scale[x];
184  po[x]=upper[x]+OUT/scale[x];
185  if (!addpoint(pc,po))
186  nrerror("parameter values failed");
187  else {
188  sprintf(outline, "%9.5f%s -%5.1f +%5.1f\n",
189  hullpnts[pntcount][x]*scale[x],
190  (hullpnts[pntcount][x]>upper[x])?"*":" ",
191  100.0*(centerpnt[x]-hullpnts[pntcount-1][x])/centerpnt[x],
192  100.0*(hullpnts[pntcount][x]-centerpnt[x])/centerpnt[x]
193  );
195  }
196  }
197 /* pick combinations of dim points and make the hull */
198  intpickpnts(1,pntstack);
199  sprintf(outline, "hull planes: %i total\n\n",plncount);
201 
202 /* LOOP */
203  do {
204 /* stick a sphere inside the scaled hull (same as an ellipse) */
205  sprintf(outline, "%i\n", ++iterate);
207 
208  if (!(big=findface(facecenter, radius))) {
209  sprintf(outline, "Could not expand in any critical direction.\n");
211  stop=2;
212  }
213 
214  if (!stop) {
215 /* print the results */
216  sprintf(outline, "center ");
218  for (x=1; dim >= x; ++x) {
219  sprintf(outline, "%9.4f ",centerpnt[x]*scale[x]);
221  }
222  sprintf(outline, "\naxes ");
224  for (x=1; dim >= x; ++x) {
225  sprintf(outline, "%9.3f ",radius[0]*scale[x]);
227  }
228  sprintf(outline, "\ndirection ");
230  for (x=1; dim >= x; ++x) {
231  sprintf(outline, "%9.3f ",c=-ab[big][x]);
233  direction[x] +=c*c;
234  }
235  sprintf(outline, "\n");
237  ++direcount;
238 /* find the closest boundary and calculate the search points */
239  cbig=0.0;
240  for (x=1; dim >= x; ++x) {
241  bound=((ab[big][x] > 0.0) ? lower[x] : upper[x]);
242  if ((c=ab[big][x]/(facecenter[x]-bound)) > cbig)
243  cbig=c;
244  }
245 /* pc on plane, po on the boundary */
246 /* in 1-D step=STEP/scale[x] */
247 /* in 2-D step equals smallest of the above */
248  step = STEP/scale[x];
249  for (x=2; dim >= x; ++x)
250  if (STEP/scale[x] < step)
251  step = STEP/scale[x];
252 /* check that we are not against search boundary */
253  for (x=1; dim >= x; ++x) {
254  out=facecenter[x]-2*step*ab[big][x];
255  if ((out>=upper[x])||(out<=lower[x]))
256  abpnts[big][0]=1;
257  }
258  if (abpnts[big][0]) {
259  sprintf(outline, "Could not expand in above direction.\n");
261  } else {
262 
263 /* pc and po shifted out a little bit */
264  for (x=1; dim >= x; ++x) {
265  pc[x]=facecenter[x]-step*ab[big][x];
266  po[x]=facecenter[x]-ab[big][x]/cbig-OUT/scale[x]*ab[big][x];
267  }
268  lowcount=oldcount=plncount;
269 /* flag plane if not convex */
270  if (!addpoint(pc,po)) {
271  abpnts[big][0]=1;
272  sprintf(outline, "New point is not outside hull.\n");
274  } else {
275 /* print the new point */
276  sprintf(outline, "new point ");
278  for (x=1; dim >= x; ++x) {
279  sprintf(outline,"%9.3f%s",
280  hullpnts[pntcount][x]*scale[x],
281  (hullpnts[pntcount][x]<lower[x])||(hullpnts[pntcount][x]>upper[x])?"*":" "
282  );
284  }
285  sprintf(outline, "\n");
287 /* flag planes the new point is exterior to */
288  for (y=1; oldcount >= y; ++y) {
289  distance=ab[y][0];
290  for (x=1; dim >= x; ++x)
291  distance +=ab[y][x]*hullpnts[pntcount][x];
292  if (distance < 0.0) {
293  abpnts[y][0]=2;
294  --lowcount;
295  }
296  }
297 /* find new planes, using new point and old plane combinations */
298  for (xx=1; oldcount >= xx; ++xx) {
299  if (abpnts[xx][0] == 2) {
300  for (x=1; x <= dim; ++x) {
301  for (y=1; y <= dim; ++y)
302  pntstack[y] = abpnts[xx][y];
303  pntstack[x] = pntcount;
304  makeaplane(pntstack);
305 /* memory */
306  if (plncount == maxplane)
307  make_more_mem();
308  }
309  }
310  }
311 /* delete old planes */
312  for (y=1; oldcount >= y; ) {
313  if (abpnts[y][0] == 2) {
314  for (x=0; dim >= x; ++x) {
315  ab[y][x]=ab[plncount][x];
316  abpnts[y][x]=abpnts[plncount][x];
317  }
318  --plncount;
319  } else ++y;
320  }
321 
322  }
323  }
324  }
325  sprintf(outline, "hull planes: %i deleted, %i added, %i total\n",oldcount-lowcount, plncount-lowcount,plncount);
327 /* check if loop should terminate */
328 /* maximum number of iterations */
329  if (iterate == param.maxiter) {
330  stop=2;
331  sprintf(outline, "Number of iterations equals MAX_ITER.\n");
333  }
334 /* maximum number of planes */
335  if (stop == 3) {
336  sprintf(outline,"Number of hull planes exceeds MAX_PLANE.\n");
338  }
339 /* radius */
340  if (!(stop>=2)&&(radius[0] - radius[dim+1])/radius[0] < STEP*2) {
341  stop=1;
342  sprintf(outline, "Axes of inscribed ellipse increasing slowly.\n");
344  }
345  for (x=dim+1; 1 <= x; --x)
346  radius[x]=radius[x-1];
347 /* minimum number of iterations */
348  if (!(stop>=2) && param.miniter > iterate) stop=0;
349 /* ITERATE file gone */
350  if ((fp=fopen("ITERATE","r")) == NULL) {
351  stop=2;
352  sprintf(outline, "The ITERATE file was deleted.\n");
354  }
355  fclose(fp);
356  } while (!stop);
357 /* end loop */
358  sprintf(outline, "\nResults.");
360 /* inscribe one more time */
361  tang=ivector(1,dim+1-pin);
362  postcenter(tang, radius);
363  sprintf(outline, "\nCENTER ");
365  for (x=1; dim >= x; ++x) {
366  sprintf(outline, "%9.4f ",centerpnt[x]*scale[x]);
368  }
369  sprintf(outline, "\nAXES ");
371  for (x=1; dim >= x; ++x) {
372  sprintf(outline, "%9.3f ",radius[0]*scale[x]);
374  }
375  sprintf(outline, "\nAVE DIRECTION ");
377  for (x=1; dim >= x; ++x) {
378  sprintf(outline, "%5.3f ",sqrt(direction[x]/direcount));
380  }
381 
382  sprintf(outline, "\n\ncriticalness ");
384  for (x=1; dim >= x; ++x) {
385  direction[x]=0.0;
386  for (y=1; dim+1-pin >= y; ++y)
387  direction[x] +=(ab[tang[y]][x])*(ab[tang[y]][x]);
388  sprintf(outline, "%6.3f ",sqrt(direction[x]/(dim+1-pin)));
390  }
391 
392 /* convexity check along critical vectors */
393  sprintf(outline, "\n\ndistance to boundary (normalized) ... critical direction\n");
395  for (y=1; dim+1-pin >= y; ++y) {
396  for (x=1; dim >= x; ++x) {
397 /* find the closest boundary and calculate the search points */
398  cbig=0.0;
399  for (xx=1; dim >= xx; ++xx) {
400  bound=((ab[tang[y]][xx] > 0.0) ? lower[xx] : upper[xx]);
401  if ((c=ab[tang[y]][xx]/(centerpnt[xx]-bound)) > cbig)
402  cbig=c;
403  }
404 /* pc at center, po on boundary */
405  pc[x]=centerpnt[x];
406  po[x]=centerpnt[x]-ab[tang[y]][x]/cbig-OUT/scale[x]*ab[tang[y]][x];
407  }
408 /* find boundary */
409  if (!addpoint(pc,po))
410  nrerror("parameter values failed");
411  else {
412  dist=0.0;
413  for (x=1; dim >= x; ++x)
414  dist +=(hullpnts[pntcount][x]-centerpnt[x])*(hullpnts[pntcount][x]-centerpnt[x]);
415  dist=sqrt(dist);
416  sprintf(outline, "%6.4f ... ",(dist/radius[0]));
418  for (x=1; dim >= x; ++x) {
419  sprintf(outline, "%7.3f ",-ab[tang[y]][x]);
421  }
422  }
423  sprintf(outline, "\n");
425  }
426  sprintf(outline, "\n");
428 /* yield calculations assuming three and one sigma */
429  if (var > 0) {
430  sprintf(outline, "Yield calculation for parameter(s):\t");
432  for (x=1; dim >= x; ++x) if (yield[x]) {
433  sprintf(outline, "%s\t",names[x-1]);
435  }
436 
437  sprintf(outline, "\nAssuming 1 sigma variations of :\t");
439  for (x=1; dim >= x; ++x) if (yield[x]) {
440  sprintf(outline, "%4.1f\t",1.0/(3.0*centerpnt[x]));
442  }
443 
444 /* ellipse estimate */
445  yest3=multiarea(300.0*radius[0],var);
446  yest1=multiarea(100.0*radius[0],var);
447 /* hull estimate */
448  tick=0;
449  ypnt=vector(1,dim);
450  total3=total1=ycount3=ycount1=0.0;
451  for (z=1; 10000 >= z && tick <= 1000 && (z-tick) <= 1000; ++z) {
452  outside=0;
453  gpdf3=gpdf1=1.0;
454  for (x=1; dim >= x; ++x) {
455  ypnt[x]=(yield[x])?lower[x]+(upper[x]-lower[x])*uniform_deviate(&seed):centerpnt[x];
456  gpdf3 *=normal(300.0*(ypnt[x]-centerpnt[x]));
457  gpdf1 *=normal(100.0*(ypnt[x]-centerpnt[x]));
458  }
459  for (y=1; plncount >= y && !outside; ++y) {
460  distance=ab[y][0];
461  for (x=1; dim >= x; ++x)
462  distance +=ab[y][x]*ypnt[x];
463  if (distance < 0.0) outside=1;
464  }
465  if (!outside) {
466  ycount3 +=gpdf3;
467  ycount1 +=gpdf1;
468  ++tick;
469  }
470  total3 +=gpdf3;
471  total1 +=gpdf1;
472  }
473  gint3 = gint1 = 1.0;
474  for (x=1; dim >= x; ++x) {
475  gint3 *=area(300.0*(upper[x]-centerpnt[x]),300.0*(centerpnt[x]-lower[x]));
476  gint1 *=area(100.0*(upper[x]-centerpnt[x]),100.0*(centerpnt[x]-lower[x]));
477  }
478  sprintf(outline, "\nYield within ellipse, yield within hull: %7.3f %5.1f",100.0*yest3,100.0*gint3*(ycount3/total3));
480  sprintf(outline, "\n\nAssuming 1 sigma variations of :\t");
482  for (x=1; dim >= x; ++x) if (yield[x]) {
483  sprintf(outline, "%4.1f\t",1.0/centerpnt[x]);
485  }
486 
487  sprintf(outline, "\nYield within ellipse, yield within hull: %7.3f %5.1f\n\n",100.0*yest1,100.0*gint1*(ycount1/total1));
489  }
490  fclose(fpout);
491  return (0);
492 }
493 
494 int postcenter(int *tang, double *radius)
495 {
496  double **tab;
497  int *right, *left;
498  int x, y;
499 
500 /* inscribe the sphere */
501 /* initialize the input tabeau */
502  tab=matrix(1,dim+3,1,plncount+1+2*pin);
503  left=ivector(1,dim+1);
504  right=ivector(1,plncount+2*pin);
505 
506  for (y=0; dim >= y; ++y)
507  tab[y+1][1]=0.0;
508  tab[dim+2][1]=1.0;
509  for (x=1; plncount >= x; ++x)
510  tab[1][x+1]=-ab[x][0];
511  for (x=1; pin >= x; ++x) {
512  tab[1][x*2+plncount]=-centerpnt[xyz[x]]-INSCRIBE;
513  tab[1][x*2+1+plncount]=centerpnt[xyz[x]]-INSCRIBE;
514  }
515 
516  for (x=1; plncount >= x; ++x)
517  tab[dim+2][x+1]=-1.0;
518  for (x=plncount+1; plncount+2*pin >= x; ++x)
519  tab[dim+2][x+1]=0.0;
520 
521  for (y=1; dim >= y; ++y)
522  for (x=1; plncount >= x; ++x)
523  tab[y+1][x+1]=ab[x][y];
524  for (y=1; dim >= y; ++y)
525  for (x=1; pin >= x; ++x) {
526  tab[y+1][x*2+plncount]=(y == xyz[x]?-1.0:0.0);
527  tab[y+1][x*2+1+plncount]=(y == xyz[x]?1.0:0.0);
528  }
529 /* call the linear program */
530  if (0 != simplx(tab,dim+1,plncount+2*pin,right,left))
531  nrerror("inscribing in hull failed");
532  radius[0]=-tab[1][1];
533  for (y=1; dim >= y; ++y)
534  for (x=1; plncount+2*pin >= x; ++x)
535  if (right[x] == y+plncount+2*pin)
536  centerpnt[y]=-tab[1][x+1];
537  x=0;
538  for (y=1; dim+1 >= y; ++y)
539  if (left[y] <= plncount)
540  tang[++x]=left[y];
541 
542  free_matrix(tab,1,dim+3,1,plncount+1+2*pin);
543  free_ivector(left,1,dim+1);
544  free_ivector(right,1,plncount+2*pin);
545 }
546 
547 static int iter=0;
548 int findface(double *centface,double *radius)
549 {
550  double **tab, *sine;
551  double cos, facevalue=0.0;
552  int *right, *left, *tang, *intsect;
553  int x, y, z, fail, plane, yy, share, noshare, count, face=0, tnum;
554 
555 /* inscribe the sphere */
556 /* initialize the input tabeau */
557  tab=matrix(1,dim+3,1,plncount+1+2*pin);
558  left=ivector(1,dim+1);
559  right=ivector(1,plncount+2*pin);
560  sine=vector(1,dim+1);
561  tang=ivector(1,dim+1-pin);
562  intsect=ivector(1,dim+1);
563 
564  for (y=0; dim >= y; ++y)
565  tab[y+1][1]=0.0;
566  tab[dim+2][1]=1.0;
567  for (x=1; plncount >= x; ++x)
568  tab[1][x+1]=-ab[x][0];
569  for (x=1; pin >= x; ++x) {
570  tab[1][x*2+plncount]=-startpnt[xyz[x]]-INSCRIBE;
571  tab[1][x*2+1+plncount]=startpnt[xyz[x]]-INSCRIBE;
572  }
573 
574  for (x=1; plncount >= x; ++x)
575  tab[dim+2][x+1]=-1.0;
576  for (x=plncount+1; plncount+2*pin >= x; ++x)
577  tab[dim+2][x+1]=0.0;
578 
579  for (y=1; dim >= y; ++y)
580  for (x=1; plncount >= x; ++x)
581  tab[y+1][x+1]=ab[x][y];
582  for (y=1; dim >= y; ++y)
583  for (x=1; pin >= x; ++x) {
584  tab[y+1][x*2+plncount]=(y == xyz[x]?-1.0:0.0);
585  tab[y+1][x*2+1+plncount]=(y == xyz[x]?1.0:0.0);
586  }
587 /* call the linear program */
588  if (0 != simplx(tab,dim+1,plncount+2*pin,right,left)) {
589  stop=2;
590  sprintf(outline, "Hull simplex failed.\n");
592  goto bailed;
593  }
594  radius[0]=-tab[1][1];
595  for (y=1; dim >= y; ++y)
596  for (x=1; plncount+2*pin >= x; ++x)
597  if (right[x] == y+plncount+2*pin)
598  centerpnt[y]=-tab[1][x+1];
599  x=0;
600  for (y=1; dim+1 >= y; ++y)
601  if (left[y] <= plncount)
602  if (x+1 > dim+1-pin) {
603  sprintf(outline,"One tangent plane is being ignored\n");
605  } else tang[++x]=left[y];
606 
607  if ((tnum=x) != dim+1-pin) {
608  sprintf(outline,"One or more tangent planes are missing.\n");
610  }
611 /* find largest of the tangetial faces */
612  for (z=1; tnum >= z; ++z) {
613  plane=tang[z];
614  if (!abpnts[plane][0]) {
615 
616 /* find the intersecting planes, which share N-1 points (noshare is 1) */
617  count=0;
618  for (x=1; plncount >= x; ++x) {
619  noshare=0;
620  for (y=1; noshare < 2 && dim >= y; ++y) {
621  share = 0;
622  for (yy=1; !share && dim >= yy; ++yy)
623  share=(abpnts[plane][yy]==abpnts[x][y]);
624  if (!share) ++noshare;
625  }
626  if (noshare == 1)
627  if (++count <= dim)
628  intsect[count]=x;
629  }
630  if (count != dim) {
631  abpnts[plane][0]=1;
632  } else {
633 
634  intsect[dim+1]=plane;
635 /* find the angles for the plane */
636  sine[dim+1]=0.0;
637  for (y=1; dim >= y; ++y) {
638  cos=0.0;
639  for (x=1; dim >= x; ++x)
640  cos=cos+ab[intsect[y]][x]*ab[plane][x];
641  sine[y]=sqrt(1.0 - cos*cos);
642  }
643  for (y=0; dim >= y; ++y)
644  tab[y+1][1]=0.0;
645  tab[dim+2][1]=1.0;
646  for (x=1; dim+1 >= x; ++x)
647  tab[1][x+1]=-ab[intsect[x]][0];
648  for (x=1; dim+1 >= x; ++x)
649  tab[dim+2][x+1]=-sine[x];
650  for (y=1; dim >= y; ++y)
651  for (x=1; dim+1 >= x; ++x)
652  tab[y+1][x+1]=ab[intsect[x]][y];
653  for (y=0; dim+1 >= y; ++y)
654  tab[y+1][dim+3]=-tab[y+1][dim+2];
655  tab[1][dim+2] -=INSCRIBE;
656  tab[1][dim+3] -=INSCRIBE;
657 /* call the linear program */
658  if (0 != simplx(tab,dim+1,dim+2,right,left)) {
659  abpnts[plane][0]=1;
660  } else {
661 /* save face is the biggest so far */
662  if (-tab[1][1] > facevalue) {
663  facevalue=(-tab[1][1]);
664  face=plane;
665  for (y=1; dim >= y; ++y)
666  for (x=1; dim+2 >= x; ++x)
667  if (right[x] == y+dim+2)
668  centface[y]=-tab[1][x+1];
669  }
670  }
671 
672  }
673  if (abpnts[plane][0]==1) {
674  sprintf(outline, " ");
676  for (x=1; dim >= x; ++x) {
677  sprintf(outline, "%9.3f ",-ab[plane][x]);
679  }
680  sprintf(outline, "\nCould not expand in above direction.\n");
682  }
683 
684  }
685  }
686  bailed:
687  free_matrix(tab,1,dim+3,1,plncount+1+2*pin);
688  free_ivector(left,1,dim+1);
689  free_ivector(right,1,plncount+2*pin);
690  free_vector(sine,1,dim+1);
691  free_ivector(tang,1,dim+1-pin);
692  free_ivector(intsect,1,dim+1);
693  return face;
694 }
695 
696 void intpickpnts(int depth, int *pp)
697 {
698  for (pp[depth]=depth*2-1; depth*2 >= pp[depth]; ++pp[depth])
699  if (depth == dim)
700  makeaplane(pp);
701  else
702  intpickpnts(depth+1, pp);
703 }
704 
705 void makeaplane(int *pp)
706 {
707  double distance, sumsqr, norm;
708  int n, a, y, posd=0, negd=0, pntinpln, def;
709 
710 /* B */
711  for (a=1; dim >= a; ++a)
712  for (y=1; dim >= y; ++y)
713  aNmatrix[a][y]=hullpnts[pp[a]][y];
714  temp[0]=det(aNmatrix,dim);
715 /* A */
716  for (n=1; dim >= n; ++n) {
717  for (a=1; dim >= a; ++a) {
718  for (y=1; dim >= y; ++y)
719  aNmatrix[a][y]=hullpnts[pp[a]][y];
720  aNmatrix[a][n]=-1.0;
721  }
722  temp[n]=det(aNmatrix,dim);
723  }
724 /* check that plane is well defined */
725  for (n=1; !(def=(fabs(temp[n]) > DEFINED)) && dim >= n; ++n);
726 
727  if (def) {
728 
729 /* check that all points (not in the plane) are on the same side of the plane */
730  for (y=1; !(posd && negd) && pntcount >= y; y++) {
731  for (a=1; !(pntinpln=(y == pp[a])) && dim >= a; a++);
732  if (!pntinpln) {
733  distance=temp[0];
734  for (n=1; dim >= n; ++n)
735  distance +=temp[n]*hullpnts[y][n];
736  if (distance >= 0.0) posd=1;
737  else negd=1;
738  }
739  }
740 /* save the good planes */
741  if (!(posd && negd)) {
742  ++plncount;
743 /* normalize */
744  sumsqr=0.0;
745  for (n=1; n <= dim; n++)
746  sumsqr +=temp[n]*temp[n];
747  norm=1/(sqrt(sumsqr));
748  for (n=0; n <= dim; n++)
749  temp[n] *=norm;
750  distance=temp[0];
751  for (n=1; n <= dim; n++)
752  distance +=temp[n]*centerpnt[n];
753  if (distance < 0.0)
754  for (n=0; n <= dim; n++)
755  temp[n] *=-1.0;
756 /* store plane in global array */
757  for (n=0; n <= dim; n++)
758  ab[plncount][n]=temp[n];
759  abpnts[plncount][0]=0;
760  for (n=1; n <= dim; n++)
761  abpnts[plncount][n]=pp[n];
762  }
763  }
764 }
765 
766 void make_more_mem(void)
767 {
768  int newmax;
769 
770  if (maxplane >= param.maxplane) {
771  stop=3;
772  newmax = maxplane+1000;
773  } else {
774  newmax=maxplane*2;
775  if (newmax > param.maxplane) newmax=param.maxplane;
776  }
777  ab=reallocmatrix(ab,1,maxplane,newmax,0,dim);
779  maxplane = newmax;
780 }
int * ivector(int nl, int nh)
Definition: qnrutil.c:8
int var
Definition: points.c:11
static double * temp
Definition: optimize.c:40
double * scale
Definition: points.c:14
#define OUT_SCREEN_FILE
Definition: optimize.c:42
char circuit_name[NAME_LENGTH]
Definition: constype.h:184
void makeaplane(int *)
Definition: optimize.c:705
#define BATCH_SET
Definition: constype.h:35
static int iter
Definition: optimize.c:547
double det(double **, int)
Definition: qdet.c:6
#define STEP
Definition: optimize.c:4
char output_dir[NAME_LENGTH]
Definition: constype.h:149
int input_options
Definition: constype.h:199
#define LONG_LINE_LENGTH
Definition: constype.h:5
double ** reallocmatrix(double **oldm, int nrl, int nrh, int newnrh, int ncl, int nch)
Definition: qnrutil.c:73
int read_config(char *filename)
Definition: init.c:189
void free_vector(double *v, int nl, int nh)
Definition: qnrutil.c:95
void make_more_mem(void)
Definition: optimize.c:766
int * yield
Definition: points.c:11
void intpickpnts(int, int *)
Definition: optimize.c:696
static char NAMES[80]
Definition: optimize.c:35
int dim
Definition: points.c:11
TIME accuracy
Definition: constype.h:122
int miniter
Definition: constype.h:71
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 int stop
Definition: optimize.c:37
int * xyz
Definition: points.c:11
int postshift(int *, double *)
#define NAME_LENGTH
Definition: constype.h:3
int opt_main(int argc, char *argv[])
Definition: optimize.c:75
void readinit(void)
Definition: points.c:159
char spice_name[NAME_LENGTH]
Definition: constype.h:152
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
int program
Definition: constype.h:193
int findface(double *, double *)
Definition: optimize.c:548
double * upper
Definition: points.c:14
static int ** abpnts
Definition: optimize.c:33
double * centerpnt
Definition: points.c:14
int generate_jspice_config()
Definition: init.c:967
#define INSCRIBE
Definition: optimize.c:8
double * startpnt
Definition: points.c:14
#define OPT_PROGRAM
Definition: constype.h:246
void free_ivector(int *v, int nl, int nh)
Definition: qnrutil.c:90
#define LINE_LENGTH
Definition: constype.h:4
#define DEFINED
Definition: optimize.c:7
#define OUT
Definition: optimize.c:6
void free_matrix(double **m, int nrl, int nrh, int ncl, int nch)
Definition: qnrutil.c:108
double multiarea(double r, int dim)
Definition: yield.c:129
char(* names)[NAME_LENGTH]
Definition: points.c:15
static double ** aNmatrix
Definition: optimize.c:40
double area(double leftmargin, double rightmargin)
Definition: yield.c:123
int maxiter
Definition: constype.h:68
static int plncount
Definition: optimize.c:36
#define INIT_CONFIG_FILE
Definition: filenames.h:4
int simplx(double **, int, int, int *, int *)
Definition: dsimplx.c:11
int ** imatrix(int nrl, int nrh, int ncl, int nch)
Definition: qnrutil.c:24
char opt_ext[NAME_LENGTH]
Definition: constype.h:177
static int maxplane
Definition: optimize.c:36
static FILE * fpout
Definition: optimize.c:38
int maxplane
Definition: constype.h:65
int addpoint(double *pc, double *po)
Definition: points.c:40
static char filename[LINE_LENGTH]
Definition: optimize.c:35
static char outline[LONG_LINE_LENGTH]
Definition: optimize.c:39
static double ** ab
Definition: optimize.c:34
static int read_opt_command_line(int argc, char *argv[])
Definition: optimize.c:46
int postcenter(int *, double *)
Definition: optimize.c:494
void init_parameters()
Definition: init.c:39
int pin
Definition: points.c:11
double uniform_deviate(long *idum)
Definition: yield.c:150
double ** matrix(int nrl, int nrh, int ncl, int nch)
Definition: qnrutil.c:40
int ** ireallocmatrix(int **oldm, int nrl, int nrh, int newnrh, int ncl, int nch)
Definition: qnrutil.c:57
double normal(double x)
Definition: yield.c:56