Merge lp:~mathieu-jacomy/gephi/forceatlas2-multithread into lp:~gephi.team/gephi/0.8

Proposed by Mathieu Bastian
Status: Needs review
Proposed branch: lp:~mathieu-jacomy/gephi/forceatlas2-multithread
Merge into: lp:~gephi.team/gephi/0.8
Diff against target: 628 lines (+345/-32)
11 files modified
LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/Bundle.properties (+5/-0)
LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/Bundle_fr.properties (+5/-0)
LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/ForceAtlas2.java (+88/-27)
LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/ForceFactory.java (+46/-3)
LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/NodesThread.java (+64/-0)
LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/Operation.java (+13/-0)
LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/OperationNodeNodeAttract.java (+32/-0)
LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/OperationNodeNodeRepulse.java (+29/-0)
LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/OperationNodeRegionRepulse.java (+32/-0)
LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/OperationNodeRepulse.java (+29/-0)
LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/Region.java (+2/-2)
To merge this branch: bzr merge lp:~mathieu-jacomy/gephi/forceatlas2-multithread
Reviewer Review Type Date Requested Status
Mathieu Bastian Pending
Review via email: mp+69478@code.launchpad.net

Description of the change

Multithread version of ForceAtlas2

To post a comment you must log in.
2260. By Mathieu Jacomy

ForceAtlas2 Multithread - better strategy. Tested and working.

2261. By Mathieu Jacomy

Better ThreadPool implementation, added strong gravity

Unmerged revisions

2261. By Mathieu Jacomy

Better ThreadPool implementation, added strong gravity

2260. By Mathieu Jacomy

ForceAtlas2 Multithread - better strategy. Tested and working.

2259. By Mathieu Jacomy

ForceAtlas2 Multithreading (basic implementation: consumer-producer paradigm)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/Bundle.properties'
2--- LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/Bundle.properties 2011-06-05 21:30:01 +0000
3+++ LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/Bundle.properties 2011-08-30 14:28:25 +0000
4@@ -4,11 +4,14 @@
5 ForceAtlas2.tuning=Tuning
6 ForceAtlas2.behavior=Behavior Alternatives
7 ForceAtlas2.performance=Performance
8+ForceAtlas2.threads=Threads
9
10 ForceAtlas2.scalingRatio.name=Scaling
11 ForceAtlas2.scalingRatio.desc=How much repulsion you want. More makes a more sparse graph.
12 ForceAtlas2.gravity.name=Gravity
13 ForceAtlas2.gravity.desc=Attracts nodes to the center. Prevents islands from drifting away.
14+ForceAtlas2.strongGravityMode.name=Stronger Gravity
15+ForceAtlas2.strongGravityMode.desc=A stronger gravity law
16 ForceAtlas2.distributedAttraction.name=Dissuade Hubs
17 ForceAtlas2.distributedAttraction.desc=Distributes attraction along outbound edges. Hubs attract less and thus are pushed to the borders.
18 ForceAtlas2.linLogMode.name=LinLog mode
19@@ -23,3 +26,5 @@
20 ForceAtlas2.barnesHutTheta.desc=Theta of the Barnes Hut optimization.
21 ForceAtlas2.edgeWeightInfluence.name=Edge Weight Influence
22 ForceAtlas2.edgeWeightInfluence.desc=How much influence you give to the edges weight. 0 is "no influence" and 1 is "normal".
23+ForceAtlas2.threads.name=Threads number
24+ForceAtlas2.threads.desc=More threads means more speed if your cores can handle it.
25
26=== modified file 'LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/Bundle_fr.properties'
27--- LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/Bundle_fr.properties 2011-06-05 21:30:01 +0000
28+++ LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/Bundle_fr.properties 2011-08-30 14:28:25 +0000
29@@ -4,11 +4,14 @@
30 ForceAtlas2.tuning=R\u00e9glages fins
31 ForceAtlas2.behavior=Options de comportement
32 ForceAtlas2.performance=Performances
33+ForceAtlas2.threads=Processus
34
35 ForceAtlas2.scalingRatio.name=Dimensionnement
36 ForceAtlas2.scalingRatio.desc=Quantit\u00e9 de r\u00e9pulsion, par rapport \u00e0 l'attraction. Rend le graphe plus \u00e9tal\u00e9.
37 ForceAtlas2.gravity.name=Gravit\u00e9
38 ForceAtlas2.gravity.desc=Attire les noeuds vers le centre. Emp\u00eache les \u00eelots de d\u00e9river \u00e0 l'infini.
39+ForceAtlas2.strongGravityMode.name=Forte Gravit\u00e9
40+ForceAtlas2.strongGravityMode.desc=Une loi de gravit\u00e9 plus forte
41 ForceAtlas2.distributedAttraction.name=Dissuader les Hubs
42 ForceAtlas2.distributedAttraction.desc=Distribue l'attraction dans les liens sortants. Les Hubs attirent moins et sont donc repouss\u00e9s en p\u00e9riph\u00e9rie.
43 ForceAtlas2.linLogMode.name=Mode LinLog
44@@ -23,3 +26,5 @@
45 ForceAtlas2.barnesHutTheta.desc=param\u00e8tre Theta de l'optimisation de Barnes Hut.
46 ForceAtlas2.edgeWeightInfluence.name=Influence Poids des liens
47 ForceAtlas2.edgeWeightInfluence.desc=L'influence du poides des liens. 0 c'est aucune influence, 1 c'est une influence normale et au-del\u00e0 \u00e7a accentue l'importance du poids des liens dans la spatialisation.
48+ForceAtlas2.threads.name=Nb. processus
49+ForceAtlas2.threads.desc=Plus de processus multiplient les performances si vos processeurs peuvent les supporter.
50
51=== modified file 'LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/ForceAtlas2.java'
52--- LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/ForceAtlas2.java 2011-06-05 21:30:01 +0000
53+++ LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/ForceAtlas2.java 2011-08-30 14:28:25 +0000
54@@ -22,6 +22,10 @@
55
56 import java.util.ArrayList;
57 import java.util.List;
58+import java.util.concurrent.ExecutionException;
59+import java.util.concurrent.ExecutorService;
60+import java.util.concurrent.Executors;
61+import java.util.concurrent.Future;
62 import org.gephi.data.attributes.type.TimeInterval;
63 import org.gephi.dynamic.DynamicUtilities;
64 import org.gephi.dynamic.api.DynamicController;
65@@ -37,6 +41,7 @@
66 import org.gephi.layout.spi.LayoutBuilder;
67 import org.gephi.layout.spi.LayoutProperty;
68 import org.gephi.project.api.Workspace;
69+import org.openide.util.Exceptions;
70 import org.openide.util.Lookup;
71 import org.openide.util.NbBundle;
72
73@@ -60,10 +65,13 @@
74 private boolean barnesHutOptimize;
75 private double barnesHutTheta;
76 private boolean linLogMode;
77+ private boolean strongGravityMode;
78+ private int threadCount;
79 private Region rootRegion;
80 double outboundAttCompensation = 1;
81 //Dynamic Weight
82 private TimeInterval timeInterval;
83+ private ExecutorService pool;
84
85 public ForceAtlas2(ForceAtlas2Builder layoutBuilder) {
86 this.layoutBuilder = layoutBuilder;
87@@ -93,6 +101,9 @@
88 nLayout.dx = 0;
89 nLayout.dy = 0;
90 }
91+
92+ pool = Executors.newFixedThreadPool(threadCount);
93+
94 }
95
96 @Override
97@@ -140,33 +151,45 @@
98 outboundAttCompensation /= nodes.length;
99 }
100
101- // Repulsion
102+ // Repulsion (and gravity)
103+ // NB: Muti-threaded
104 RepulsionForce Repulsion = ForceFactory.builder.buildRepulsion(isAdjustSizes(), getScalingRatio());
105- if (isBarnesHutOptimize()) {
106- for (Node n : nodes) {
107- rootRegion.applyForce(n, Repulsion, getBarnesHutTheta());
108- }
109- } else {
110- for (int n1Index = 0; n1Index < nodes.length; n1Index++) {
111- Node n1 = nodes[n1Index];
112- for (int n2Index = 0; n2Index < n1Index; n2Index++) {
113- Node n2 = nodes[n2Index];
114- Repulsion.apply(n1, n2);
115- }
116- }
117- }
118-
119+
120+ int taskCount = 8*threadCount; // The threadPool Executor Service will manage the fetching of tasks and threads.
121+ // We make more tasks than threads because some tasks may need more time to compute.
122+ ArrayList<Future> threads = new ArrayList();
123+ for(int t=taskCount; t>0; t--){
124+ int from = (int) Math.floor(nodes.length*(t-1)/taskCount);
125+ int to = (int) Math.floor(nodes.length*t/taskCount);
126+ Future future = pool.submit(new NodesThread(nodes, from, to, isBarnesHutOptimize(), getBarnesHutTheta(), getGravity(), (isStrongGravityMode())?(ForceFactory.builder.getStrongGravity(getScalingRatio())):(Repulsion), getScalingRatio(), rootRegion, Repulsion));
127+ threads.add(future);
128+ }
129+ for(Future future : threads) {
130+ try {
131+ future.get();
132+ } catch (InterruptedException ex) {
133+ Exceptions.printStackTrace(ex);
134+ } catch (ExecutionException ex) {
135+ Exceptions.printStackTrace(ex);
136+ }
137+ }
138+
139 // Attraction
140 AttractionForce Attraction = ForceFactory.builder.buildAttraction(isLinLogMode(), isOutboundAttractionDistribution(), isAdjustSizes(), 1 * ((isOutboundAttractionDistribution()) ? (outboundAttCompensation) : (1)));
141- for (Edge e : edges) {
142- Attraction.apply(e.getSource(), e.getTarget(), Math.pow(getWeight(e), getEdgeWeightInfluence()));
143- }
144-
145- // Gravity
146- for (Node n : nodes) {
147- Repulsion.apply(n, getGravity() / getScalingRatio());
148- }
149-
150+ if(getEdgeWeightInfluence()==0){
151+ for (Edge e : edges) {
152+ Attraction.apply(e.getSource(), e.getTarget(), 1);
153+ }
154+ } else if(getEdgeWeightInfluence()==1){
155+ for (Edge e : edges) {
156+ Attraction.apply(e.getSource(), e.getTarget(), getWeight(e));
157+ }
158+ } else {
159+ for (Edge e : edges) {
160+ Attraction.apply(e.getSource(), e.getTarget(), Math.pow(getWeight(e), getEdgeWeightInfluence()));
161+ }
162+ }
163+
164 // Auto adjust speed
165 double totalSwinging = 0d; // How much irregular movement
166 double totalEffectiveTraction = 0d; // Hom much useful movement
167@@ -198,10 +221,10 @@
168 // when the node swings.
169 double swinging = Math.sqrt((nLayout.old_dx - nLayout.dx) * (nLayout.old_dx - nLayout.dx) + (nLayout.old_dy - nLayout.dy) * (nLayout.old_dy - nLayout.dy));
170 double factor = 0.1 * speed / (1f + speed * Math.sqrt(swinging));
171-
172+
173 double df = Math.sqrt(Math.pow(nLayout.dx, 2) + Math.pow(nLayout.dy, 2));
174 factor = Math.min(factor * df, 10.) / df;
175-
176+
177 double x = nData.x() + nLayout.dx * factor;
178 double y = nData.y() + nLayout.dy * factor;
179
180@@ -220,7 +243,7 @@
181 double swinging = Math.sqrt((nLayout.old_dx - nLayout.dx) * (nLayout.old_dx - nLayout.dx) + (nLayout.old_dy - nLayout.dy) * (nLayout.old_dy - nLayout.dy));
182 //double factor = speed / (1f + Math.sqrt(speed * swinging));
183 double factor = speed / (1f + speed * Math.sqrt(swinging));
184-
185+
186 double x = nData.x() + nLayout.dx * factor;
187 double y = nData.y() + nLayout.dy * factor;
188
189@@ -242,6 +265,7 @@
190 for (Node n : graph.getNodes()) {
191 n.getNodeData().setLayoutData(null);
192 }
193+ pool.shutdown();
194 graph.readUnlockAll();
195 }
196
197@@ -251,6 +275,7 @@
198 final String FORCEATLAS2_TUNING = NbBundle.getMessage(getClass(), "ForceAtlas2.tuning");
199 final String FORCEATLAS2_BEHAVIOR = NbBundle.getMessage(getClass(), "ForceAtlas2.behavior");
200 final String FORCEATLAS2_PERFORMANCE = NbBundle.getMessage(getClass(), "ForceAtlas2.performance");
201+ final String FORCEATLAS2_THREADS = NbBundle.getMessage(getClass(), "ForceAtlas2.threads");
202
203 try {
204 properties.add(LayoutProperty.createProperty(
205@@ -261,6 +286,13 @@
206 "getScalingRatio", "setScalingRatio"));
207
208 properties.add(LayoutProperty.createProperty(
209+ this, Boolean.class,
210+ NbBundle.getMessage(getClass(), "ForceAtlas2.strongGravityMode.name"),
211+ FORCEATLAS2_TUNING,
212+ NbBundle.getMessage(getClass(), "ForceAtlas2.strongGravityMode.desc"),
213+ "isStrongGravityMode", "setStrongGravityMode"));
214+
215+ properties.add(LayoutProperty.createProperty(
216 this, Double.class,
217 NbBundle.getMessage(getClass(), "ForceAtlas2.gravity.name"),
218 FORCEATLAS2_TUNING,
219@@ -315,6 +347,13 @@
220 FORCEATLAS2_PERFORMANCE,
221 NbBundle.getMessage(getClass(), "ForceAtlas2.barnesHutTheta.desc"),
222 "getBarnesHutTheta", "setBarnesHutTheta"));
223+
224+ properties.add(LayoutProperty.createProperty(
225+ this, Integer.class,
226+ NbBundle.getMessage(getClass(), "ForceAtlas2.threads.name"),
227+ FORCEATLAS2_THREADS,
228+ NbBundle.getMessage(getClass(), "ForceAtlas2.threads.desc"),
229+ "getThreadsCount", "setThreadsCount"));
230
231 } catch (Exception e) {
232 e.printStackTrace();
233@@ -337,6 +376,7 @@
234 } else {
235 setScalingRatio(10.0);
236 }
237+ setStrongGravityMode(false);
238 setGravity(1.);
239
240 // Behavior
241@@ -359,6 +399,7 @@
242 setBarnesHutOptimize(false);
243 }
244 setBarnesHutTheta(1.2);
245+ setThreadsCount(2);
246 }
247
248 @Override
249@@ -418,6 +459,14 @@
250 this.scalingRatio = scalingRatio;
251 }
252
253+ public Boolean isStrongGravityMode() {
254+ return strongGravityMode;
255+ }
256+
257+ public void setStrongGravityMode(Boolean strongGravityMode) {
258+ this.strongGravityMode = strongGravityMode;
259+ }
260+
261 public Double getGravity() {
262 return gravity;
263 }
264@@ -425,6 +474,18 @@
265 public void setGravity(Double gravity) {
266 this.gravity = gravity;
267 }
268+
269+ public Integer getThreadsCount() {
270+ return threadCount;
271+ }
272+
273+ public void setThreadsCount(Integer threadCount) {
274+ if(threadCount<1){
275+ setThreadsCount(1);
276+ } else {
277+ this.threadCount = threadCount;
278+ }
279+ }
280
281 public Boolean isOutboundAttractionDistribution() {
282 return outboundAttractionDistribution;
283
284=== modified file 'LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/ForceFactory.java'
285--- LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/ForceFactory.java 2011-06-05 21:30:01 +0000
286+++ LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/ForceFactory.java 2011-08-30 14:28:25 +0000
287@@ -22,6 +22,7 @@
288
289 import org.gephi.graph.api.Node;
290 import org.gephi.graph.api.NodeData;
291+import org.openide.util.Exceptions;
292
293 /**
294 * Generates the forces on demand, here are all the formulas for attraction and repulsion.
295@@ -43,6 +44,10 @@
296 return new linRepulsion(coefficient);
297 }
298 }
299+
300+ public RepulsionForce getStrongGravity(double coefficient){
301+ return new strongGravity(coefficient);
302+ }
303
304 public AttractionForce buildAttraction(boolean logAttraction, boolean distributedAttraction, boolean adjustBySize, double coefficient) {
305 if (adjustBySize) {
306@@ -75,7 +80,7 @@
307 }
308 }
309 }
310-
311+
312 public abstract class AttractionForce {
313
314 public abstract void apply(Node n1, Node n2, double e); // Model for node-node attraction (e is for edge weight if needed)
315@@ -141,7 +146,7 @@
316
317 nLayout.dx += xDist * factor;
318 nLayout.dy += yDist * factor;
319- }
320+ }
321 }
322
323 @Override
324@@ -165,7 +170,7 @@
325 }
326
327 /*
328- * Repulsion force: Linear with Anti-collision
329+ * Repulsion force: Strong Gravity (as a Repulsion Force because it is easier)
330 */
331 private class linRepulsion_antiCollision extends RepulsionForce {
332
333@@ -252,6 +257,44 @@
334 }
335 }
336
337+ private class strongGravity extends RepulsionForce {
338+
339+ private double coefficient;
340+
341+ public strongGravity(double c) {
342+ coefficient = c;
343+ }
344+
345+ @Override
346+ public void apply(Node n1, Node n2) {
347+ // Not Relevant
348+ }
349+
350+ @Override
351+ public void apply(Node n, Region r) {
352+ // Not Relevant
353+ }
354+
355+ @Override
356+ public void apply(Node n, double g) {
357+ NodeData nData = n.getNodeData();
358+ ForceAtlas2LayoutData nLayout = nData.getLayoutData();
359+
360+ // Get the distance
361+ double xDist = nData.x();
362+ double yDist = nData.y();
363+ double distance = (float) Math.sqrt(xDist * xDist + yDist * yDist);
364+
365+ if (distance > 0) {
366+ // NB: factor = force / distance
367+ double factor = coefficient * nLayout.mass * g;
368+
369+ nLayout.dx -= xDist * factor;
370+ nLayout.dy -= yDist * factor;
371+ }
372+ }
373+ }
374+
375 /*
376 * Attraction force: Linear
377 */
378
379=== added file 'LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/NodesThread.java'
380--- LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/NodesThread.java 1970-01-01 00:00:00 +0000
381+++ LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/NodesThread.java 2011-08-30 14:28:25 +0000
382@@ -0,0 +1,64 @@
383+/*
384+ * To change this template, choose Tools | Templates
385+ * and open the template in the editor.
386+ */
387+package org.gephi.layout.plugin.forceAtlas2;
388+
389+import org.gephi.graph.api.Node;
390+import org.gephi.layout.plugin.forceAtlas2.ForceFactory.RepulsionForce;
391+
392+/**
393+ *
394+ * @author Mathieu
395+ */
396+public class NodesThread implements Runnable{
397+ private Node[] nodes;
398+ private int from;
399+ private int to;
400+ private Region rootRegion;
401+ private boolean barnesHutOptimize;
402+ private RepulsionForce Repulsion;
403+ private double barnesHutTheta;
404+ private double gravity;
405+ private RepulsionForce GravityForce;
406+ private double scaling;
407+
408+ public NodesThread(Node[] nodes, int from, int to, boolean barnesHutOptimize, double barnesHutTheta, double gravity, RepulsionForce GravityForce, double scaling, Region rootRegion, RepulsionForce Repulsion){
409+ this.nodes = nodes;
410+ this.from = from;
411+ this.to = to;
412+ this.rootRegion = rootRegion;
413+ this.barnesHutOptimize = barnesHutOptimize;
414+ this.Repulsion = Repulsion;
415+ this.barnesHutTheta = barnesHutTheta;
416+ this.gravity = gravity;
417+ this.GravityForce = GravityForce;
418+ this.scaling = scaling;
419+ }
420+
421+ @Override
422+ public void run() {
423+ // Repulsion
424+ if (barnesHutOptimize) {
425+ for (int nIndex = from; nIndex < to; nIndex++) {
426+ Node n = nodes[nIndex];
427+ rootRegion.applyForce(n, Repulsion, barnesHutTheta);
428+ }
429+ } else {
430+ for (int n1Index = from; n1Index < to; n1Index++) {
431+ Node n1 = nodes[n1Index];
432+ for (int n2Index = 0; n2Index < n1Index; n2Index++) {
433+ Node n2 = nodes[n2Index];
434+ Repulsion.apply(n1, n2);
435+ }
436+ }
437+ }
438+
439+ // Gravity
440+ for (int nIndex = from; nIndex < to; nIndex++) {
441+ Node n = nodes[nIndex];
442+ GravityForce.apply(n, gravity / scaling);
443+ }
444+ }
445+
446+}
447
448=== added file 'LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/Operation.java'
449--- LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/Operation.java 1970-01-01 00:00:00 +0000
450+++ LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/Operation.java 2011-08-30 14:28:25 +0000
451@@ -0,0 +1,13 @@
452+/*
453+ * To change this template, choose Tools | Templates
454+ * and open the template in the editor.
455+ */
456+package org.gephi.layout.plugin.forceAtlas2;
457+
458+/**
459+ *
460+ * @author Mathieu
461+ */
462+public abstract class Operation {
463+ public abstract void execute();
464+}
465
466=== added file 'LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/OperationNodeNodeAttract.java'
467--- LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/OperationNodeNodeAttract.java 1970-01-01 00:00:00 +0000
468+++ LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/OperationNodeNodeAttract.java 2011-08-30 14:28:25 +0000
469@@ -0,0 +1,32 @@
470+/*
471+ * To change this template, choose Tools | Templates
472+ * and open the template in the editor.
473+ */
474+package org.gephi.layout.plugin.forceAtlas2;
475+
476+import org.gephi.graph.api.Node;
477+import org.gephi.layout.plugin.forceAtlas2.ForceFactory.AttractionForce;
478+
479+/**
480+ *
481+ * @author Mathieu
482+ */
483+public class OperationNodeNodeAttract extends Operation{
484+ private Node n1;
485+ private Node n2;
486+ private AttractionForce f;
487+ private double coefficient;
488+
489+ public OperationNodeNodeAttract(Node n1, Node n2, AttractionForce f, double coefficient){
490+ this.n1 = n1;
491+ this.n2 = n2;
492+ this.f = f;
493+ this.coefficient = coefficient;
494+ }
495+
496+ @Override
497+ public void execute() {
498+ f.apply(n1, n2, coefficient);
499+ }
500+
501+}
502
503=== added file 'LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/OperationNodeNodeRepulse.java'
504--- LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/OperationNodeNodeRepulse.java 1970-01-01 00:00:00 +0000
505+++ LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/OperationNodeNodeRepulse.java 2011-08-30 14:28:25 +0000
506@@ -0,0 +1,29 @@
507+/*
508+ * To change this template, choose Tools | Templates
509+ * and open the template in the editor.
510+ */
511+package org.gephi.layout.plugin.forceAtlas2;
512+
513+import org.gephi.graph.api.Node;
514+import org.gephi.layout.plugin.forceAtlas2.ForceFactory.RepulsionForce;
515+
516+/**
517+ *
518+ * @author Mathieu
519+ */
520+public class OperationNodeNodeRepulse extends Operation{
521+ private Node n1;
522+ private Node n2;
523+ private RepulsionForce f;
524+
525+ public OperationNodeNodeRepulse(Node n1, Node n2, RepulsionForce f){
526+ this.n1 = n1;
527+ this.n2 = n2;
528+ this.f = f;
529+ }
530+
531+ @Override
532+ public void execute() {
533+ f.apply(n1, n2);
534+ }
535+}
536
537=== added file 'LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/OperationNodeRegionRepulse.java'
538--- LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/OperationNodeRegionRepulse.java 1970-01-01 00:00:00 +0000
539+++ LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/OperationNodeRegionRepulse.java 2011-08-30 14:28:25 +0000
540@@ -0,0 +1,32 @@
541+/*
542+ * To change this template, choose Tools | Templates
543+ * and open the template in the editor.
544+ */
545+package org.gephi.layout.plugin.forceAtlas2;
546+
547+import org.gephi.graph.api.Node;
548+import org.gephi.layout.plugin.forceAtlas2.ForceFactory.RepulsionForce;
549+
550+/**
551+ *
552+ * @author Mathieu
553+ */
554+public class OperationNodeRegionRepulse extends Operation{
555+ private Node n;
556+ private Region r;
557+ private RepulsionForce f;
558+ private double theta;
559+
560+ public OperationNodeRegionRepulse(Node n, Region r, RepulsionForce f, double theta){
561+ this.n = n;
562+ this.f = f;
563+ this.r = r;
564+ this.theta = theta;
565+ }
566+
567+ @Override
568+ public void execute() {
569+ r.applyForce(n, f, theta);
570+ }
571+
572+}
573
574=== added file 'LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/OperationNodeRepulse.java'
575--- LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/OperationNodeRepulse.java 1970-01-01 00:00:00 +0000
576+++ LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/OperationNodeRepulse.java 2011-08-30 14:28:25 +0000
577@@ -0,0 +1,29 @@
578+/*
579+ * To change this template, choose Tools | Templates
580+ * and open the template in the editor.
581+ */
582+package org.gephi.layout.plugin.forceAtlas2;
583+
584+import org.gephi.graph.api.Node;
585+import org.gephi.layout.plugin.forceAtlas2.ForceFactory.RepulsionForce;
586+
587+/**
588+ *
589+ * @author Mathieu
590+ */
591+public class OperationNodeRepulse extends Operation{
592+ private Node n;
593+ private RepulsionForce f;
594+ private double coefficient;
595+
596+ public OperationNodeRepulse(Node n, RepulsionForce f, double coefficient){
597+ this.n = n;
598+ this.f = f;
599+ this.coefficient = coefficient;
600+ }
601+
602+ @Override
603+ public void execute() {
604+ f.apply(n, coefficient);
605+ }
606+}
607
608=== modified file 'LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/Region.java'
609--- LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/Region.java 2011-06-05 21:30:01 +0000
610+++ LayoutPlugin/src/org/gephi/layout/plugin/forceAtlas2/Region.java 2011-08-30 14:28:25 +0000
611@@ -51,7 +51,7 @@
612 updateMassAndGeometry();
613 }
614
615- public void updateMassAndGeometry() {
616+ private void updateMassAndGeometry() {
617 if (nodes.size() > 1) {
618 // Compute Mass
619 mass = 0;
620@@ -77,7 +77,7 @@
621 }
622 }
623
624- public void buildSubRegions() {
625+ public synchronized void buildSubRegions() {
626 if (nodes.size() > 1) {
627 ArrayList<Node> leftNodes = new ArrayList<Node>();
628 ArrayList<Node> rightNodes = new ArrayList<Node>();

Subscribers

People subscribed via source and target branches