chiark / gitweb /
minimisation works but initial solution is bust
authorIan Jackson <ian@davenant.relativity.greenend.org.uk>
Mon, 31 Dec 2007 13:45:53 +0000 (13:45 +0000)
committerIan Jackson <ian@davenant.relativity.greenend.org.uk>
Mon, 31 Dec 2007 13:45:53 +0000 (13:45 +0000)
.bzrignore
bgl.cpp
common.h
energy.c
view.c

index 57e94d5d6324362a0583d2cfe1b8a179aab3fc48..8935d75ca60423bc26fac55f8a4b7b2bc25fdd1a 100644 (file)
@@ -1,5 +1,6 @@
 minimise
 primer
 initial
-project
+view
+best
 *.d
diff --git a/bgl.cpp b/bgl.cpp
index 0d1f355323cb9f064281e0079e709f1e55f61d9d..28c6ee6fe45816724bf5148d931f40ea3a40ef70 100644 (file)
--- a/bgl.cpp
+++ b/bgl.cpp
@@ -201,14 +201,18 @@ double graph_layout_cost(const Vertices v, const double vertex_areas[N]) {
     double a1= vertex_areas[v1];
     single_source_shortest_paths(v1, edge_weights, vertex_distances);
     FOR_VERTEX(v2) {
+      if (v1 == v2) continue;
       double a2= vertex_areas[v2];
       double d2= hypotD2plus(v[v1],v[v2], d2_epsilon);
       double s= vertex_distances[v2];
-      double sd= s / d2;
-      double sd2= sd*sd;
+      double s2= s*s + d2_epsilon;
+      double sd2= s2 / d2;
       double cost_contrib= a1*a2 * (sd2 - 1) / (d2*d2);
-      //printf("layout %03x..%03x (a=%g,%g) s=%g d2=%g cost+=%g\n",
-      //            v1,v2, a1,a2, s,d2, cost_contrib);
+      if (cost_contrib < -1e-4) {
+       printf("layout %03x..%03x (a=%g,%g) s=%g s2=%g d2=%g sd2=%g"
+              " cost+=%g\n", v1,v2, a1,a2, s,s2,d2,sd2, cost_contrib);
+       abort();
+      }
       total_cost += cost_contrib;
     }
   }
index 88ec865226297a1bcced0312bdd8c91a40febf82..cb45e8107b2af322854f67b1065ea70a2ea692b8 100644 (file)
--- a/common.h
+++ b/common.h
@@ -17,6 +17,7 @@
 #include <assert.h>
 #include <errno.h>
 #include <string.h>
+#include <unistd.h>
 
 #include <gsl/gsl_vector.h>
 #include <gsl/gsl_matrix.h>
index f6907bcfda9151eea1b8cd7d4666e66f88fba7f7..ce78a54ebed9fc43c27dda82a6a27f0327463f40 100644 (file)
--- a/energy.c
+++ b/energy.c
@@ -30,9 +30,9 @@ static double compute_energy(const Vertices vertices) {
   energy= 0;
   printf("cost > energy |");
 
-  COST(1000.0, edgewise_vertex_displacement_cost(vertices));
-  COST(1.0,    graph_layout_cost(vertices,vertex_areas));
-  COST(1e-30,    noncircular_rim_cost(vertices));
+  COST(1e4, edgewise_vertex_displacement_cost(vertices));
+  COST(1e2, graph_layout_cost(vertices,vertex_areas));
+  COST(1e4, noncircular_rim_cost(vertices));
   
   printf("| total %# e |", energy);
   if (energy < best_energy) {
@@ -127,7 +127,7 @@ int main(int argc, const char *const *argv) {
   Vertices initial, step_size;
   FILE *initial_f;
   gsl_vector initial_gsl, step_size_gsl;
-  int r, v, vx,vy, k;
+  int r, v, k;
   
   if (argc>1) { fputs("takes no arguments\n",stderr); exit(8); }
 
@@ -154,9 +154,10 @@ int main(int argc, const char *const *argv) {
   step_size_gsl.data= &step_size[0][0];
 
   FOR_VERTEX(v)
-    K step_size[v][k]= 1e-4;
-  FOR_RIM_VERTEX(vx,vy,v)
-    step_size[v][3] *= 0.1;
+    K step_size[v][k]= 0.01;
+//int vx,vy;
+//  FOR_RIM_VERTEX(vx,vy,v)
+//    step_size[v][3] *= 0.1;
 
   GA( gsl_multimin_fminimizer_set(minimiser, &multimin_function,
                                  &initial_gsl, &step_size_gsl) );
@@ -167,7 +168,7 @@ int main(int argc, const char *const *argv) {
     size= gsl_multimin_fminimizer_size(minimiser);
     r= gsl_multimin_test_size(size, stop_epsilon);
 
-    printf("size %# e, r=%d\n", size, r);
+    printf("%*s size %# e, r=%d\n", 135,"", size, r);
     flushoutput();
 
     if (r==GSL_SUCCESS) break;
diff --git a/view.c b/view.c
index 1ce6db66d492867a869ed833b2a9e9c6931067a8..abecc7ca4d5fc206532f00d3f7c33dfe41281b78 100644 (file)
--- a/view.c
+++ b/view.c
@@ -5,6 +5,10 @@
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/poll.h>
+
 #include "mgraph.h"
 
 #define MAXTRIS (N*2)
@@ -18,16 +22,21 @@ static Vertices conformation;
 static double transform[D3][D3]= {{1,0,0}, {0,1,0}, {0,0,1}};
 static GSL_MATRIX(transform);
 
-const char *input_filename;
+static FILE *input_f;
+static struct stat input_stab;
+static const char *input_filename;
 
 static void read_input(void) {
-  FILE *f;
   int r;
   
-  f= fopen(input_filename, "rb");  if (!f) diee("input file");
+  if (input_f) fclose(input_f);
+  input_f= fopen(input_filename, "rb");  if (!input_f) diee("input file");
+
+  if (fstat(fileno(input_f), &input_stab)) diee("fstat input file");
+
   errno= 0;
-  r= fread(&conformation,sizeof(conformation),1,f);  if (r!=1) diee("fread");
-  fclose(f);
+  r= fread(&conformation,sizeof(conformation),1,input_f);
+  if (r!=1) diee("fread");
 }
 
 static void transform_coordinates(void) {
@@ -468,9 +477,31 @@ static void event_config(XConfigureEvent *e) {
   show();
 }
 
+static void check_input(void) {
+  struct stat newstab;
+  int r;
+
+  r= stat(input_filename, &newstab);
+  if (r<0) diee("could not check input");
+
+#define CI(x) if (newstab.st_##x == input_stab.st_##x) ; else goto changed
+  CI(dev);
+  CI(ino);
+  CI(size);
+  CI(mtime);
+#undef CI
+  return;
+
+ changed:
+  show();
+}
+
 int main(int argc, const char *const *argv) {
+  static const int wantedevents= POLLIN|POLLPRI|POLLERR|POLLHUP;
+
   XEvent event;
-  int k;
+  int k, i, r, *xfds, nxfds, polls_alloc=0;
+  struct pollfd *polls=0;
   int motion_deferred=0, motion_x=-1, motion_y=-1;
   
   if (argc != 2 || argv[1][0]=='-') {
@@ -485,16 +516,40 @@ int main(int argc, const char *const *argv) {
 
   XMapWindow(display,window);
   for (;;) {
-    if (motion_deferred) {
-      int r= XCheckMaskEvent(display,~0UL,&event);
-      if (!r) {
+
+    XA( XInternalConnectionNumbers(display, &xfds, &nxfds) );
+    if (polls_alloc <= nxfds) {
+      polls_alloc= nxfds + polls_alloc + 1;
+      polls= realloc(polls, sizeof(*polls) * polls_alloc);
+      if (!polls) diee("realloc for pollfds");
+    }
+    for (i=0; i<nxfds; i++) {
+      polls[i].fd= xfds[i];
+      polls[i].events= wantedevents;
+      polls[i].revents= 0;
+    }
+    XFree(xfds);
+
+    polls[i].fd= ConnectionNumber(display);
+    polls[i].events= wantedevents;
+
+    r= poll(polls, nxfds+1, motion_deferred ? 0 : 200);
+    if (r<0) diee("poll");
+
+    for (i=0; i<nxfds; i++)
+      if (polls[i].revents)
+       XProcessInternalConnection(display, polls[i].fd);
+
+    r= XCheckMaskEvent(display,~0UL,&event);
+    if (!r) {
+      if (motion_deferred) {
        event_motion(motion_x, motion_y);
        motion_deferred=0;
-       continue;
       }
-    } else {
-      XNextEvent(display,&event);
+      check_input();
+      continue;
     }
+    
     switch (event.type) {
 
     case ButtonPress: