X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=energy.c;h=867330cbf2da74a6293cdf55c58ba58edffc77af;hb=72f8ad06842d28b84b9ec4f15e0890a1caedf3d0;hp=8961f549979ddf5eed7f0b5c9773b67d1d442df0;hpb=f1dc8f4f3623b15deddba8db85d181a0e1011c9e;p=moebius2.git diff --git a/energy.c b/energy.c index 8961f54..867330c 100644 --- a/energy.c +++ b/energy.c @@ -3,40 +3,52 @@ */ #include "common.h" -#include "bgl.h" +#include "minimise.h" #include "mgraph.h" #include #include +#include +#include + static const char *input_file, *output_file; static char *output_file_tmp; static void compute_vertex_areas(const Vertices vertices, double areas[N]); static double best_energy= DBL_MAX; -static void addcost(double *energy, double tweight, double tcost); -#define COST(weight, compute) addcost(&energy, (weight), (compute)) +enum printing_instance { pr_cost, pr_size, pr__max }; + +static void addcost(double *energy, double tweight, double tcost, int pr); +#define COST(weight, compute) addcost(&energy, (weight), (compute), printing) +static int printing_check(enum printing_instance); +static void printing_init(void); /*---------- main energy computation and subroutines ----------*/ static double compute_energy(const Vertices vertices) { double vertex_areas[N], energy; + int printing; compute_vertex_areas(vertices,vertex_areas); energy= 0; - printf("cost > energy |"); - COST(1e4, edgewise_vertex_displacement_cost(vertices)); -// COST(1e2, graph_layout_cost(vertices,vertex_areas)); -// COST(1e4, noncircular_rim_cost(vertices)); + printing= printing_check(pr_cost); + + if (printing) printf("cost > energy |"); + + COST(1e2, edgewise_vertex_displacement_cost(vertices)); +// COST(1e0, graph_layout_cost(vertices,vertex_areas)); + COST(1e4, noncircular_rim_cost(vertices)); + + if (printing) printf("| total %# e |", energy); - printf("| total %# e |", energy); if (energy < best_energy) { FILE *best_f; int r; - printf(" BEST"); + if (printing) printf(" BEST"); best_f= fopen(output_file_tmp,"wb"); if (!best_f) diee("fopen new out"); r= fwrite(vertices,sizeof(Vertices),1,best_f); if (r!=1) diee("fwrite"); @@ -45,15 +57,17 @@ static double compute_energy(const Vertices vertices) { best_energy= energy; } - putchar('\n'); - flushoutput(); + if (printing) { + putchar('\n'); + flushoutput(); + } return energy; } -static void addcost(double *energy, double tweight, double tcost) { +static void addcost(double *energy, double tweight, double tcost, int pr) { double tenergy= tweight * tcost; - printf(" %# e > %# e |", tcost, tenergy); + if (pr) printf(" %# e > %# e |", tcost, tenergy); *energy += tenergy; } @@ -133,6 +147,9 @@ int main(int argc, const char *const *argv) { output_file= argv[2]+2; if (asprintf(&output_file_tmp,"%s.new",output_file) <= 0) diee("asprintf"); + graph_layout_prepare(); + printing_init(); + minimiser= gsl_multimin_fminimizer_alloc (gsl_multimin_fminimizer_nmsimplex, DIM); if (!minimiser) { perror("alloc minimiser"); exit(-1); } @@ -170,7 +187,8 @@ int main(int argc, const char *const *argv) { size= gsl_multimin_fminimizer_size(minimiser); r= gsl_multimin_test_size(size, stop_epsilon); - printf("%*s size %# e, r=%d\n", 135,"", size, r); + if (printing_check(pr_size)) + printf("%*s size %# e, r=%d\n", 135,"", size, r); flushoutput(); if (r==GSL_SUCCESS) break; @@ -221,7 +239,7 @@ int main(int argc, const char *const *argv) { */ double edgewise_vertex_displacement_cost(const Vertices vertices) { - static const double /*d_epsilon= 1e-6,*/ axb_epsilon= 1e-6; + static const double axb_epsilon= 1e-6; int pi,e,qi,ri,si, k; double m[D3], a[D3], b[D3], axb[D3]; @@ -237,12 +255,8 @@ double edgewise_vertex_displacement_cost(const Vertices vertices) { xprod(axb,a,b); - double l= 1; //hypotD(vertices[pi], vertices[qi]); - double d= 1; //hypotD(vertices[ri], vertices[si]) + d_epsilon; double delta= atan2(magnD(axb) + axb_epsilon, dotprod(a,b)); - - double cost= l * delta * delta / d; - + double cost= delta * delta; total_cost += cost; } return total_cost; @@ -269,3 +283,56 @@ double noncircular_rim_cost(const Vertices vertices) { } return cost; } + +/*---------- printing rate limit ----------*/ + +static volatile unsigned print_todo; +static sigset_t print_alarmset; + +static int printing_check(enum printing_instance which) { + static int skipped[pr__max]; + + unsigned bits= 1u << which; + int sk; + + if (!(print_todo & bits)) { + skipped[which]++; + return 0;; + } + + sigprocmask(SIG_BLOCK,&print_alarmset,0); + print_todo &= ~bits; + sigprocmask(SIG_UNBLOCK,&print_alarmset,0); + + sk= skipped[which]; + if (sk) printf("[%4d] ",sk); + else printf(" "); + skipped[which]= 0; + + return 1; +} + +static void alarmhandler(int ignored) { + print_todo= ~0u; +} + +static void printing_init(void) { + struct sigaction sa; + struct itimerval itv; + + sigemptyset(&print_alarmset); + sigaddset(&print_alarmset,SIGALRM); + + sa.sa_handler= alarmhandler; + sa.sa_mask= print_alarmset; + sa.sa_flags= SA_RESTART; + if (sigaction(SIGALRM,&sa,0)) diee("sigaction ALRM"); + + itv.it_interval.tv_sec= 0; + itv.it_interval.tv_usec= 200000; + itv.it_value= itv.it_interval; + + if (setitimer(ITIMER_REAL,&itv,0)) diee("setitimer REAL"); + + raise(SIGALRM); +}