diff --git a/README.md b/README.md index 75d8831..cd9dbe3 100644 --- a/README.md +++ b/README.md @@ -92,24 +92,29 @@ lengths are computed based solely on the number of hops, and there currently isn't any way to specify a "weight/distance" variable for the links. -## Description of primitives in src-more directory +## Transition guide -These primitives are written in the style used by built-in NetLogo primitives. To be brought back to life, they'd need to be changed to use the extensions API instead. +### Renamed primitives -###__create-network-preferential +The primitives in this extension were present in NetLogo 4.1, but with different names. +They were renamed as follows: -syntax: __create-network-preferential TURTLESET LINK-BREED AVG-DEGREE +* `__network-distance` to `network:link-distance` +* `__in-network-radius` to `network:extended-link-neighbors` +* `__average-path-length` to `network:mean-path-length` +* `__network-shortest-path-turtles` to `network:path-turtles` +* `__network-shortest-path-links` to `network:path-links` -example: __create-network-preferential bankers friendships 3 - (note that you should create the banker turtles ahead of time - this -primitive just creates a BA preferential attachment model network -between the turtles you specify. +### Omitted primitives -### __layout-magspring +The following primitives, present in NetLogo 4.1 but not NetLogo 5.0, are not included in this extension either: -### __layout-quick +* `__create-network-preferential`, +* `__layout-magspring` +* `__layout-quick` +* `__layout-sphere`. -### __layout-sphere +For the source code for these primitives, see . But note they are written in the style used by built-in NetLogo primitives. To be brought back to life, they'd need to be changed to use the extensions API instead. ## Credits diff --git a/more/Layouts.java b/more/Layouts.java deleted file mode 100644 index 2943edd..0000000 --- a/more/Layouts.java +++ /dev/null @@ -1,301 +0,0 @@ - // layout-sphere - // experimental - - // An experimental "__layout-sphere" for 3D. Not polished yet. - // Also not sure if it's a worthwhile primitive or not, - // especially given how slow it runs for large numbers of turtles. - // ~Forrest (12/5/2006) - public static void sphere(AgentSet nodeset, double radius, double initialTemp, - org.nlogo.util.MersenneTwisterFast random) { - World3D world = (World3D) nodeset.world(); - int nodeCount = nodeset.count(); - if (nodeCount == 0) { - return; - } - double[] nx = new double[nodeCount]; - double[] ny = new double[nodeCount]; - double[] nz = new double[nodeCount]; - - Turtle3D[] agt = new Turtle3D[nodeCount]; - int i = 0; - for (AgentSet.Iterator it = nodeset.iterator(); it.hasNext(); i++) { - Turtle3D t = (Turtle3D) it.next(); - agt[i] = t; - nx[i] = t.xcor(); - ny[i] = t.ycor(); - nz[i] = t.zcor(); - if (nx[i] == 0.0 && ny[i] == 0.0 && nz[i] == 0.0) { - nz[i] = random.nextDouble() * 2.0 - 1.0; - double remainder = StrictMath.sqrt(1.0 * 1.0 - nz[i] * nz[i]); - double angle = random.nextDouble() * StrictMath.PI * 2; - nx[i] = remainder * StrictMath.sin(angle); - ny[i] = remainder * StrictMath.cos(angle); - } - } - - double temperature = initialTemp / nodeCount; - for (int k = 0; k < 30; k++) { - for (i = 0; i < nodeCount; i++) { - for (int j = i + 1; j < nodeCount; j++) { - double dx = nx[j] - nx[i]; - double dy = ny[j] - ny[i]; - double dz = nz[j] - nz[i]; - - double distSq = dx * dx + dy * dy + dz * dz; - if (distSq < 1.0E-20) { - dx = temperature * (random.nextDouble() - 0.5); - dy = temperature * (random.nextDouble() - 0.5); - dz = temperature * (random.nextDouble() - 0.5); - } else { - // repulse according to an inverse cubic function - double f = temperature / (distSq * distSq); - dx = -(f * dx); - dy = -(f * dy); - dz = -(f * dz); - } - - nx[i] += dx; - ny[i] += dy; - nz[i] += dz; - double magnitude = StrictMath.sqrt(nx[i] * nx[i] + ny[i] * ny[i] + nz[i] * nz[i]); - nx[i] = nx[i] / magnitude; - ny[i] = ny[i] / magnitude; - nz[i] = nz[i] / magnitude; - - nx[j] -= dx; - ny[j] -= dy; - nz[j] -= dz; - magnitude = StrictMath.sqrt(nx[j] * nx[j] + ny[j] * ny[j] + nz[j] * nz[j]); - nx[j] = nx[j] / magnitude; - ny[j] = ny[j] / magnitude; - nz[j] = nz[j] / magnitude; - } - } - temperature *= 0.75; - } - - for (i = 0; i < nodeCount; i++) { - double newx = nx[i] * radius; - double newy = ny[i] * radius; - double newz = nz[i] * radius; - - if (newx > world.maxPxcor()) { - newx = world.maxPxcor(); - } else if (newx < world.minPxcor()) { - newx = world.minPxcor(); - } - - if (newy > world.maxPycor()) { - newy = world.maxPycor(); - } else if (newy < world.minPycor()) { - newy = world.minPycor(); - } - if (newz > world.maxPzcor()) { - newz = world.maxPzcor(); - } else if (newz < world.minPzcor()) { - newz = world.minPzcor(); - } - - agt[i].xyandzcor(newx, newy, newz); - } - } - - - /// magspring - - private static final double MAGSPRING_SMALL_THRESHOLD = 0.0000001; - - private static final int FIELD_NONE = 0; - private static final int FIELD_NORTH = 1; - private static final int FIELD_NORTHEAST = 2; - private static final int FIELD_EAST = 3; - private static final int FIELD_SOUTHEAST = 4; - private static final int FIELD_SOUTH = 5; - private static final int FIELD_SOUTHWEST = 6; - private static final int FIELD_WEST = 7; - private static final int FIELD_NORTHWEST = 8; - private static final int FIELD_POLAR = 9; - private static final int FIELD_CONCENTRIC = 10; - - public static void magspring(AgentSet nodeset, AgentSet linkset, - double spr, double len, double rep, - double magStr, int fieldType, - boolean bidirectional, - org.nlogo.util.MersenneTwisterFast random) { - World world = nodeset.world(); - - int nodeCount = nodeset.count(); - - Turtle[] agt = new Turtle[nodeCount]; - double[] ax = new double[nodeCount]; - double[] ay = new double[nodeCount]; - int ctr = 0; - - for (AgentSet.Iterator iter = nodeset.shufflerator(random); iter.hasNext(); ctr++) { - agt[ctr] = (Turtle) iter.next(); - } - - for (int i = 0; i < nodeCount; i++) { - Turtle t = agt[i]; - - double fx = 0, fy = 0; - for (AgentSet.Iterator it = world.links().shufflerator(random); it.hasNext();) { - Link link = (Link) it.next(); - if ((link.end1() == t || link.end2() == t) && - (linkset.contains(link))) { - Turtle other = link.end1(); - if (t == link.end1()) { - other = link.end2(); - } - double dist = world.protractor().distance(t, other, false); - double dx = other.xcor() - t.xcor(); - double dy = other.ycor() - t.ycor(); - if (StrictMath.abs(dist) < MAGSPRING_SMALL_THRESHOLD) { - if (t == link.end1()) { - fx += (spr * len); - } else { - fx -= (spr * len); - } - } else { - // calculate attractive force - double f = spr * (dist - len); - fx = fx + (f * dx / dist); - fy = fy + (f * dy / dist); - - // calculate magnetic force - java.awt.geom.Point2D.Double mf = magForce(t.xcor(), t.ycor(), fieldType); - - // we want to know the angle between the link and the magnetic field - // calculate dotProduct first - double dot = mf.x * dx + mf.y * dy; - // then calculate the cosine of - double cosAngle = StrictMath.abs(dot) / dist; - - // keep track of whether the dotProduct was negative - // so we can push or pull, accordingly - double negFlag = (dot < 0) ? 1 : -1; - - if (!bidirectional) { - negFlag = 1; - } - - // cosAngle can be > 1 because of weird float rounding. - // if cosAngle >= 1, then angle = 0, and no magnetism occurs. - if (cosAngle < 1) { - double angle = StrictMath.abs(StrictMath.acos(cosAngle)); - // 1.5 is an arbitrary choice, chosen because it seemed to work well - // some other power > 1 could be used as well. - fx = fx + negFlag * magStr * mf.x * StrictMath.pow(angle, 1.5); - fy = fy + negFlag * magStr * mf.y * StrictMath.pow(angle, 1.5); - } - } - } - } - for (AgentSet.Iterator it = nodeset.shufflerator(random); it.hasNext();) { - Turtle other = (Turtle) it.next(); - if (other != t) { - double dx = other.xcor() - t.xcor(); - double dy = other.ycor() - t.ycor(); - - if (dx == 0 && dy == 0) { - double ang = 360 * random.nextDouble(); - fx = fx - (rep * StrictMath.sin(StrictMath.toRadians(ang))); - fy = fy - (rep * StrictMath.cos(StrictMath.toRadians(ang))); - } else { - double dist = StrictMath.sqrt((dx * dx) + (dy * dy)); - //if ( dist <= 2 * len ) - //{ - double f = rep / (dist * dist); - fx = fx - (f * dx / dist); - fy = fy - (f * dy / dist); - //} - - } - } - } - double limit = 1; - if (fx > limit) { - fx = limit; - } else { - if (fx < -limit) { - fx = -limit; - } - } - if (fy > limit) { - fy = limit; - } else { - if (fy < -limit) { - fy = -limit; - } - } - fx += t.xcor(); - fy += t.ycor(); - if (fx > world.maxPxcor()) { - fx = world.maxPxcor(); - } else { - if (fx < world.minPxcor()) { - fx = world.minPxcor(); - } - } - if (fy > world.maxPycor()) { - fy = world.maxPycor(); - } else { - if (fy < world.minPycor()) { - fy = world.minPycor(); - } - } - ax[i] = fx; - ay[i] = fy; - } - - // we need to bump some node a small amount, in case all nodes - // are stuck on a single line - if (nodeCount > 1) { - double perturbAmt = (world.worldWidth() + world.worldHeight()) / (1.0E10); - ax[0] += random.nextDouble() * perturbAmt - perturbAmt / 2.0; - ay[0] += random.nextDouble() * perturbAmt - perturbAmt / 2.0; - } - - reposition(agt, ax, ay); - } - - private static final double COS45 = StrictMath.sqrt(2.0) / 2.0; - - private static java.awt.geom.Point2D.Double magForce(double x, double y, int fieldType) { - double dist; - switch (fieldType) { - case FIELD_NORTH: - return new java.awt.geom.Point2D.Double(0, 1); - case FIELD_NORTHEAST: - return new java.awt.geom.Point2D.Double(COS45, COS45); - case FIELD_EAST: - return new java.awt.geom.Point2D.Double(1, 0); - case FIELD_SOUTHEAST: - return new java.awt.geom.Point2D.Double(COS45, -COS45); - case FIELD_SOUTH: - return new java.awt.geom.Point2D.Double(0, -1); - case FIELD_SOUTHWEST: - return new java.awt.geom.Point2D.Double(-COS45, -COS45); - case FIELD_WEST: - return new java.awt.geom.Point2D.Double(-1, 0); - case FIELD_NORTHWEST: - return new java.awt.geom.Point2D.Double(-COS45, COS45); - case FIELD_POLAR: - dist = StrictMath.sqrt((x * x) + (y * y)); - if (StrictMath.abs(dist) < MAGSPRING_SMALL_THRESHOLD) { - return new java.awt.geom.Point2D.Double(0, 0); - } - return new java.awt.geom.Point2D.Double(x / dist, y / dist); - case FIELD_CONCENTRIC: - dist = StrictMath.sqrt((x * x) + (y * y)); - if (StrictMath.abs(dist) < MAGSPRING_SMALL_THRESHOLD) { - return new java.awt.geom.Point2D.Double(0, 0); - } - return new java.awt.geom.Point2D.Double(y / dist, -x / dist); - case FIELD_NONE: - return new java.awt.geom.Point2D.Double(0, 0); - default: - throw new IllegalStateException(); - } - } - diff --git a/more/_createnetworkpreferential.java b/more/_createnetworkpreferential.java deleted file mode 100644 index 1bd7187..0000000 --- a/more/_createnetworkpreferential.java +++ /dev/null @@ -1,103 +0,0 @@ -package org.nlogo.prim.etc; - -import org.nlogo.agent.Agent; -import org.nlogo.agent.AgentSet; -import org.nlogo.agent.Link; -import org.nlogo.agent.Turtle; -import org.nlogo.api.LogoException; -import org.nlogo.nvm.Command; -import org.nlogo.nvm.EngineException; -import org.nlogo.nvm.Syntax; - -/** - * This primitive creates links between an agentset of turtles, - * by using Barabasi's preferential attachment model. - *

- * ~Forrest (3/9/2007) - */ - -public final strictfp class _createnetworkpreferential extends Command { - @Override - public Syntax syntax() { - return Syntax.commandSyntax - (new int[] - {Syntax.TYPE_TURTLESET, Syntax.TYPE_LINKSET, - Syntax.TYPE_NUMBER}, - "O---", true); - } - - @Override - public void perform(final org.nlogo.nvm.Context context) - throws LogoException { - AgentSet nodeSet = argEvalAgentSet(context, 0, Turtle.class); - AgentSet linkBreed = argEvalAgentSet(context, 1, Link.class); - int mEdges = argEvalIntValue(context, 2); - - if (linkBreed.isDirected()) { - throw new EngineException(context, "This command only supports undirected link breeds."); - } - if (mEdges < 1) { - throw new EngineException(context, "The number of neighbors to link to in each step must be at least 1."); - } - - int numNodes = nodeSet.count(); - - if (numNodes < mEdges + 1) { - throw new EngineException(context, "This agentset has only " + numNodes + " members, so it is impossible to attach any turtle to " + mEdges + " neighbors!"); - } - - Turtle[] nodes = new Turtle[numNodes]; - int[] degreeCounts = new int[numNodes]; - boolean[] usedAlready = new boolean[numNodes]; - - int i = 0; - for (AgentSet.Iterator iter = nodeSet.iterator(); iter.hasNext();) { - Agent agt = iter.next(); - if (!(agt instanceof Turtle)) { - throw new EngineException - (context, "You can only create links between turtles!"); - } - nodes[i] = (Turtle) agt; - i++; - } - - int totalDegCount = 0; - for (i = 0; i < mEdges; i++) { - if (world.linkManager.findLink(nodes[i], nodes[mEdges], linkBreed, false) == null) { - world.linkManager.createLink(nodes[i], nodes[mEdges], linkBreed); - } - degreeCounts[i]++; - degreeCounts[mEdges]++; - totalDegCount += 2; - } - - for (i = mEdges + 1; i < nodes.length; i++) { - int tempTotal = totalDegCount; - for (int k = 0; k < i; k++) { - usedAlready[k] = false; - } - for (int j = 0; j < mEdges; j++) { - int randVal = context.job.random.nextInt(tempTotal); - for (int k = 0; k < i; k++) { - if (usedAlready[k]) { - continue; - } - randVal -= degreeCounts[k]; - if (randVal > 0) { - continue; - } - if (world.linkManager.findLink(nodes[i], nodes[k], linkBreed, false) == null) { - world.linkManager.createLink(nodes[i], nodes[k], linkBreed); - } - tempTotal -= degreeCounts[k]; - degreeCounts[k]++; - degreeCounts[i]++; - totalDegCount += 2; - usedAlready[k] = true; - break; - } - } - } - context.ip = next; - } -} diff --git a/more/_layoutmagspring.java b/more/_layoutmagspring.java deleted file mode 100644 index 3834547..0000000 --- a/more/_layoutmagspring.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.nlogo.prim.etc; - -import org.nlogo.agent.AgentSet; -import org.nlogo.agent.Link; -import org.nlogo.agent.Turtle; -import org.nlogo.api.LogoException; -import org.nlogo.nvm.Command; -import org.nlogo.nvm.Context; -import org.nlogo.nvm.Syntax; - -public final strictfp class _layoutmagspring - extends Command { - @Override - public Syntax syntax() { - int[] right = {Syntax.TYPE_TURTLESET, Syntax.TYPE_LINKSET, - Syntax.TYPE_NUMBER, Syntax.TYPE_NUMBER, Syntax.TYPE_NUMBER, - Syntax.TYPE_NUMBER, Syntax.TYPE_NUMBER, Syntax.TYPE_BOOLEAN}; - return Syntax.commandSyntax(right, true); - } - - @Override - public void perform(final Context context) - throws LogoException { - AgentSet nodeset = argEvalAgentSet(context, 0, Turtle.class); - AgentSet linkset = argEvalAgentSet(context, 1, Link.class); - double spr = argEvalDoubleValue(context, 2); - double len = argEvalDoubleValue(context, 3); - double rep = argEvalDoubleValue(context, 4); - double magStr = argEvalDoubleValue(context, 5); - int fieldType = argEvalIntValue(context, 6); - boolean bidirectional = argEvalBooleanValue(context, 7); - - org.nlogo.agent.Layouts.magspring - (nodeset, linkset, spr, len, rep, magStr, fieldType, bidirectional, - context.job.random); - context.ip = next; - } -} diff --git a/more/_layoutquick.java b/more/_layoutquick.java deleted file mode 100644 index 7591786..0000000 --- a/more/_layoutquick.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.nlogo.prim.etc; - -import org.nlogo.agent.Layouts; -import org.nlogo.nvm.Command; -import org.nlogo.nvm.Context; -import org.nlogo.nvm.Syntax; - -public final strictfp class _layoutquick - extends Command { - @Override - public Syntax syntax() { - return Syntax.commandSyntax(true); - } - - @Override - public void perform(final Context context) { - Layouts.spring - (world.turtles(), world.links(), - 0.2, world.worldWidth() / 5, 0.2, - context.job.random); - context.ip = next; - } -} diff --git a/more/_layoutsphere.java b/more/_layoutsphere.java deleted file mode 100644 index da6fc21..0000000 --- a/more/_layoutsphere.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.nlogo.prim.threed; - -import org.nlogo.agent.AgentSet; -import org.nlogo.agent.Turtle; -import org.nlogo.api.LogoException; -import org.nlogo.nvm.Command; -import org.nlogo.nvm.Context; -import org.nlogo.nvm.EngineException; -import org.nlogo.nvm.Syntax; - -public final strictfp class _layoutsphere - extends Command { - @Override - public Syntax syntax() { - return Syntax.commandSyntax - (new int[]{Syntax.TYPE_TURTLESET, - Syntax.TYPE_NUMBER, - Syntax.TYPE_NUMBER}, - true); - } - - @Override - public void perform(final Context context) throws LogoException { - AgentSet set = argEvalAgentSet(context, 0); - double radius = argEvalDoubleValue(context, 1); - double initTemp = argEvalDoubleValue(context, 2); - - if (set.type() != Turtle.class) { - throw new EngineException - (context, this, - "Patches are immovable."); - } - org.nlogo.agent.Layouts.sphere(set, radius, initTemp, context.job.random); - context.ip = next; - } -} diff --git a/more/magspring-bidirectional.gif b/more/magspring-bidirectional.gif deleted file mode 100644 index d66c668..0000000 Binary files a/more/magspring-bidirectional.gif and /dev/null differ diff --git a/more/magspring-layout.gif b/more/magspring-layout.gif deleted file mode 100644 index 05898a8..0000000 Binary files a/more/magspring-layout.gif and /dev/null differ diff --git a/more/magspring-tests.txt b/more/magspring-tests.txt deleted file mode 100644 index b01718a..0000000 --- a/more/magspring-tests.txt +++ /dev/null @@ -1,8 +0,0 @@ -MagSpring_2D - OPEN> test/models/Preferential Attachment Tester.nlogo - to mag-layout repeat 3 [ __layout-magspring turtles links 0.5 1.0 0.4 0.4 0 false ] end - O> random-seed 2342 - O> setup - O> repeat 50 [ go ] - O> repeat 5000 [ mag-layout ] - any? links with [ any? other links with [ bad-intersections self myself ] ] => false diff --git a/more/magspring.html b/more/magspring.html deleted file mode 100644 index f94b41c..0000000 --- a/more/magspring.html +++ /dev/null @@ -1,128 +0,0 @@ -

-

- __layout-magspring -

-

- __layout-magspring turtle-set link-set - spring-constant spring-length - repulsion-constant magnetic-field-strength - magnetic-field-type bidirectional? -

-

- Very similar to layout-spring, but - with an added layer of complexity. The turtles in turtle-set - attract and repel each other depending on the links (that are in - link-set) between them, but there is also a magnetic field - which the links try to align with. -

- The link-set is the set of links that exert forces on the - turtles they are connected to. Turtles that are connected to links - in the link agentset but are not included in the turtle agentset - are treated as anchors. If there are no turtles with fixed - positions the entire network will probably collapse on itself. -

- spring-constant is a measure of the "tautness" of - the spring. (See layout-spring) -

- spring-length is the "zero-force" length or the - natural length of the springs. (See layout-spring) -

- repulsion-constant is a measure of repulsion between the - nodes. (See layout-spring) -

- magnetic-field-strength is the force of the magnetic field. - (Reasonable values range from 0 to 1, but 0.05 is a good default.) -

- magnetic-field-type is a number in the range from 0 to 10. - Choices are listed in the table below. - - - - - - - - - - - - - - -
- magnetic-field-type - - Description -
- NONE = 0 - - If no field is used, then this command works just like - layout-spring. -
- NORTH = 1 - - Magnetic field runs toward the North -
- NORTHEAST = 2 - - Magnetic field runs toward the Northeast -
- EAST = 3 - - ... -
- SOUTHEAST= 4 - - ... -
- SOUTH = 5 - - ... -
- SOUTHWEST= 6 - - ... -
- WEST = 7 - - ... -
- NORTHWEST = 8 - - ... -
- POLAR = 9 - - Magnetic field runs outward at all angles from the origin. -
- CONCENTRIC = 10 -
-
- Magnetic field runs clockwise around the origin in concentric - circles. -
-

- If bidirectional? is true then links try to align with the - magnetic field by pushing attached turtles both in the direction of - the field, and in the opposite direction. Otherwise, the links just - push in a single direction. -

-to make-a-tree
-  set-default-shape turtles "circle"
-  crt 5
-  ask turtle 0 [ 
-    create-link-with turtle 1
-    create-link-with turtle 2
-  ]
-  ask turtle 1 [
-    create-link-with turtle 3
-    create-link-with turtle 4
-  ]
-  ; layout with a fairly strong SOUTH magnetic field
-  repeat 50 [ __layout-magspring 
-              turtles with [who != 0] links 0.3 4 1 .50 5 false ] 
-end
-
-