chiark / gitweb /
fix threading bugs and arrangements
[moebius2.git] / energy.c
index e43ecede21c987bdc638805ccc069d2ab10eff6a..ae592cf4817fb6895f40cf2454cda90b190153bd 100644 (file)
--- a/energy.c
+++ b/energy.c
@@ -23,8 +23,12 @@ typedef struct {
 } CostContribution;
 
 static const CostContribution costs[]= {
+#define PRECOMP(compute) { 0,(compute) },
 #define COST(weight, compute) { (weight),(compute) },
 
+  PRECOMP(compute_edge_lengths)
+  PRECOMP(compute_vertex_areas)
+
 #if XBITS==3
 #define STOP_EPSILON 1e-6
     COST(  3e3,   line_bending_cost)
@@ -59,51 +63,53 @@ void energy_init(void) {
   stop_epsilon= STOP_EPSILON;
 }
 
-void compute_energy_separately(const struct Vertices *vs,
-                        int section, void *energies_v, void *totals_v) {
-  double *energies= energies_v;
-  int ci;
-    
-  compute_edge_lengths(vs->a, section);
-  compute_vertex_areas(vs->a, section);
+/*---------- energy computation machinery ----------*/
 
-  for (ci=0; ci<NCOSTS; ci++)
-    energies[ci]= costs[ci].fn(vs->a, section);
-}
+typedef struct {
+  double total;
+  const CostContribution *cc;
+} CostComputationData;
 
-/*---------- energy computation machinery ----------*/
+void compute_energy_separately(const struct Vertices *vs,
+                        int section, void *energy_v, void *ccd_v) {
+  CostComputationData *ccd= ccd_v;
+  double *energy= energy_v;
+  *energy= ccd->cc->fn(vs->a, section);
+}
 
 void compute_energy_combine(const struct Vertices *vertices,
-                        int section, void *energies_v, void *totals_v) {
-  int ci;
-  
-  double *energies= energies_v;
-  double *totals= totals_v;
-
-  for (ci=0; ci<NCOSTS; ci++)
-    totals[ci] += energies[ci];
+                        int section, void *energy_v, void *ccd_v) {
+  CostComputationData *ccd= ccd_v;
+  double *energy= energy_v;
+  ccd->total += *energy;
 }
 
 double compute_energy(const struct Vertices *vs) {
   static int bests_unprinted;
 
-  double totals[NCOSTS], energy;
+  double energy;
   int ci, printing;
+  CostComputationData ccd;
 
   printing= printing_check(pr_cost,0);
 
   if (printing) printf("%15lld c>e |", evaluations);
 
-  inparallel(vs,
-            compute_energy_separately,
-            compute_energy_combine,
-            sizeof(totals) /* really, size of energies */,
-            totals);
-
   energy= 0;
 
-  for (ci=0; ci<NCOSTS; ci++)
-    addcost(&energy, costs[ci].weight, totals[ci], printing);
+  for (ci=0; ci<NCOSTS; ci++) {
+    ccd.total= 0;
+    ccd.cc= &costs[ci];
+    
+    inparallel(vs,
+              compute_energy_separately,
+              compute_energy_combine,
+              sizeof(energy),
+              &ccd);
+
+    if (ccd.cc->weight != 0)
+      addcost(&energy, costs[ci].weight, ccd.total, printing);
+  }
 
   if (printing) printf("| total %# e |", energy);
 
@@ -143,14 +149,16 @@ static void addcost(double *energy, double tweight, double tcost, int pr) {
 
 /*---------- Precomputations ----------*/
 
-void compute_edge_lengths(const Vertices vertices, int section) {
+double compute_edge_lengths(const Vertices vertices, int section) {
   int v1,e,v2;
 
   FOR_EDGE(v1,e,v2, OUTER)
     edge_lengths[v1][e]= hypotD(vertices[v1],vertices[v2]);
+
+  return 0;
 }
 
-void compute_vertex_areas(const Vertices vertices, int section) {
+double compute_vertex_areas(const Vertices vertices, int section) {
   int v0,v1,v2, e1,e2;
 //  int k;
 
@@ -178,6 +186,8 @@ void compute_vertex_areas(const Vertices vertices, int section) {
     vertex_areas[v0]= total / count;
     vertex_mean_edge_lengths[v0]= edges_total / count;
   }
+
+  return 0;
 }
 
 /*---------- Edgewise vertex displacement ----------*/