diff --git a/.idea/.name b/.idea/.name index 9170364..b78656a 100644 --- a/.idea/.name +++ b/.idea/.name @@ -1 +1 @@ -Equations \ No newline at end of file +GraphModelODESystem \ No newline at end of file diff --git a/Equations.txt b/Equations.txt deleted file mode 100644 index 30b8d72..0000000 --- a/Equations.txt +++ /dev/null @@ -1,50 +0,0 @@ - *** Equations for an SIR model on a Toast Graph *** - -0: 0 1 1 1 -1: 1 0 1 0 -2: 1 1 0 1 -3: 1 0 1 0 -Numbers of equations of each size: [8, 10, 16, 8] - -[〈S3〉] = - β〈S3 I0〉- β〈S3 I2〉 -[〈S2〉] = - β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉 -[〈S1〉] = - β〈S1 I0〉- β〈S1 I2〉 -[〈S0〉] = - β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉 -[〈I3〉] = γ〈S3 I0〉+ γ〈S3 I2〉- γ〈I3〉 -[〈I2〉] = γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉 -[〈I1〉] = γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉 -[〈I0〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉 -[〈I3〉, 〈S2〉] = γ〈S3 I0〉+ γ〈S3 I2〉- γ〈I3〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉 -[〈I3〉, 〈S0〉] = γ〈S3 I0〉+ γ〈S3 I2〉- γ〈I3〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉 -[〈I2〉, 〈S3〉] = γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉- β〈S3 I0〉- β〈S3 I2〉 -[〈I2〉, 〈S1〉] = γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉- β〈S1 I0〉- β〈S1 I2〉 -[〈I2〉, 〈S0〉] = γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉 -[〈I1〉, 〈S2〉] = γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉 -[〈I1〉, 〈S0〉] = γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉 -[〈I0〉, 〈S3〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉- β〈S3 I0〉- β〈S3 I2〉 -[〈I0〉, 〈S2〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉 -[〈I0〉, 〈S1〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉- β〈S1 I0〉- β〈S1 I2〉 -[〈I3〉, 〈S0〉, 〈S2〉] = γ〈S3 I0〉+ γ〈S3 I2〉- γ〈I3〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉 -[〈I3〉, 〈S0〉, 〈S1〉] = γ〈S3 I0〉+ γ〈S3 I2〉- γ〈I3〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉- β〈S1 I0〉- β〈S1 I2〉 -[〈I2〉, 〈S0〉, 〈S3〉] = γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉- β〈S3 I0〉- β〈S3 I2〉 -[〈I2〉, 〈S0〉, 〈S1〉] = γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉- β〈S1 I0〉- β〈S1 I2〉 -[〈I2〉, 〈I3〉, 〈S0〉] = γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉+ γ〈S3 I0〉+ γ〈S3 I2〉- γ〈I3〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉 -[〈I1〉, 〈S2〉, 〈S3〉] = γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉- β〈S3 I0〉- β〈S3 I2〉 -[〈I1〉, 〈S0〉, 〈S3〉] = γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉- β〈S3 I0〉- β〈S3 I2〉 -[〈I1〉, 〈S0〉, 〈S2〉] = γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉 -[〈I1〉, 〈I2〉, 〈S3〉] = γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉+ γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉- β〈S3 I0〉- β〈S3 I2〉 -[〈I1〉, 〈I2〉, 〈S0〉] = γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉+ γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉 -[〈I0〉, 〈S2〉, 〈S3〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉- β〈S3 I0〉- β〈S3 I2〉 -[〈I0〉, 〈S1〉, 〈S2〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉- β〈S1 I0〉- β〈S1 I2〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉 -[〈I0〉, 〈I3〉, 〈S2〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉+ γ〈S3 I0〉+ γ〈S3 I2〉- γ〈I3〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉 -[〈I0〉, 〈I2〉, 〈S3〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉+ γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉- β〈S3 I0〉- β〈S3 I2〉 -[〈I0〉, 〈I2〉, 〈S1〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉+ γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉- β〈S1 I0〉- β〈S1 I2〉 -[〈I0〉, 〈I1〉, 〈S2〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉+ γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉 -[〈I3〉, 〈S0〉, 〈S1〉, 〈S2〉] = γ〈S3 I0〉+ γ〈S3 I2〉- γ〈I3〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉- β〈S1 I0〉- β〈S1 I2〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉 -[〈I2〉, 〈I3〉, 〈S0〉, 〈S1〉] = γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉+ γ〈S3 I0〉+ γ〈S3 I2〉- γ〈I3〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉- β〈S1 I0〉- β〈S1 I2〉 -[〈I1〉, 〈S0〉, 〈S2〉, 〈S3〉] = γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉- β〈S3 I0〉- β〈S3 I2〉 -[〈I1〉, 〈I2〉, 〈S0〉, 〈S3〉] = γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉+ γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉- β〈S3 I0〉- β〈S3 I2〉 -[〈I1〉, 〈I2〉, 〈I3〉, 〈S0〉] = γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉+ γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉+ γ〈S3 I0〉+ γ〈S3 I2〉- γ〈I3〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉 -[〈I0〉, 〈S1〉, 〈S2〉, 〈S3〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉- β〈S1 I0〉- β〈S1 I2〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉- β〈S3 I0〉- β〈S3 I2〉 -[〈I0〉, 〈I1〉, 〈S2〉, 〈S3〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉+ γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉- β〈S3 I0〉- β〈S3 I2〉 -[〈I0〉, 〈I1〉, 〈I2〉, 〈S3〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉+ γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉+ γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉- β〈S3 I0〉- β〈S3 I2〉 diff --git a/src/io/github/ethankelly/ODESystem.java b/src/io/github/ethankelly/ODESystem.java index 248863e..fa32b74 100644 --- a/src/io/github/ethankelly/ODESystem.java +++ b/src/io/github/ethankelly/ODESystem.java @@ -4,6 +4,7 @@ import io.github.ethankelly.graph.GraphGenerator; import io.github.ethankelly.graph.Vertex; import io.github.ethankelly.symbols.Greek; +import io.github.ethankelly.symbols.Maths; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.ode.FirstOrderDifferentialEquations; @@ -71,24 +72,29 @@ public static void main(String[] args) { // Print the initial state System.out.println("Initial state:\n" + Arrays.toString(y0)); + // Specify the initial condition used in this test + System.out.println("I.e. " + Maths.L_ANGLE.uni() + "S0_I1_S2" + Maths.R_ANGLE.uni()); + // Print relevant system information + System.out.println(triangle); + // Empty array to contain derivative values double[] yDot = Arrays.copyOf(y0, y0.length); - integrator.integrate(triangle, 0, y0, 2, yDot); - + // Integrate up to specified t value + integrator.integrate(triangle, 0, y0, 10, yDot); + // Compute derivatives based on equations generation triangle.computeDerivatives(0, y0, yDot); + // Print found values to 2 d.p. for clarity of system output DecimalFormat df = new DecimalFormat(); df.setMaximumFractionDigits(2); - System.out.println("Final state:\n"); + System.out.println("Final state at t=10:\n"); for (Tuple t : triangle.requiredTuples.getTuples()) { - System.out.print(t + " = "); - double result = yDot[triangle.getIndicesMapping().get(t)]; - if (result > 1) System.out.print("1.00"); - else if (result > 0) System.out.print(df.format(result)); - else if (result <= 0) System.out.print("0.00"); + System.out.print(t + Maths.PRIME.uni() + " = "); + double resultPrime = yDot[triangle.getIndicesMapping().get(t)]; + System.out.print(df.format(resultPrime)); System.out.println(); } - System.out.println(triangle); + } /** diff --git a/src/io/github/ethankelly/RequiredTuples.java b/src/io/github/ethankelly/RequiredTuples.java index 94c9bc0..9b75460 100644 --- a/src/io/github/ethankelly/RequiredTuples.java +++ b/src/io/github/ethankelly/RequiredTuples.java @@ -41,13 +41,57 @@ public RequiredTuples(Graph graph, char[] states, boolean closures) { * @param args command-line arguments (ignored). */ public static void main(String[] args) { - RequiredTuples t1 = new RequiredTuples(GraphGenerator.getTriangle(), new char[] {'S', 'I', 'R'}, false); - System.out.println(t1.findSingles()); - System.out.println(t1.getTuples() + "\nSize: " + t1.getTuples().size()); +// RequiredTuples t1 = new RequiredTuples(GraphGenerator.getTriangle(), new char[] {'S', 'I', 'R'}, false); +// System.out.println(t1.findSingles()); +// System.out.println(t1.getTuples() + "\nSize: " + t1.getTuples().size()); +// +// RequiredTuples t2 = new RequiredTuples(GraphGenerator.getTriangle(), new char[] {'S', 'I', 'R'}, true); +// System.out.println(t2.findSingles()); +// System.out.println(t2.getTuples() + "\nSize: " + t2.getTuples().size()); + + RequiredTuples complete5 = new RequiredTuples(GraphGenerator.complete(5), new char[]{'S', 'I', 'R'}, false); + RequiredTuples cycle5 = new RequiredTuples(GraphGenerator.cycle(5), new char[]{'S', 'I', 'R'}, false); + RequiredTuples complete3 = new RequiredTuples(GraphGenerator.complete(3), new char[]{'S', 'I', 'R'}, false); + RequiredTuples cycle3 = new RequiredTuples(GraphGenerator.cycle(3), new char[]{'S', 'I', 'R'}, false); + RequiredTuples complete4 = new RequiredTuples(GraphGenerator.complete(4), new char[]{'S', 'I', 'R'}, false); + RequiredTuples cycle4 = new RequiredTuples(GraphGenerator.cycle(4), new char[]{'S', 'I', 'R'}, false); + + System.out.println("CYCLE 3"); +// System.out.println(cycle3.findSingles()); + System.out.println( +// cycle3.getTuples() + + "Size: " + cycle3.getTuples().size()); + + System.out.println("\nCOMPLETE 3"); +// System.out.println(complete3.findSingles()); + System.out.println( +// complete3.getTuples() + + "Size: " + complete3.getTuples().size()); + + System.out.println("\nCYCLE 4"); +// System.out.println(cycle4.findSingles()); + System.out.println( + cycle4.getTuples() + + "Size: " + cycle4.getTuples().size()); + + System.out.println("\nCOMPLETE 4"); +// System.out.println(complete4.findSingles()); + System.out.println( +// complete4.getTuples() + + "Size: " + complete4.getTuples().size()); + + System.out.println("\nCYCLE 5"); +// System.out.println(cycle5.findSingles()); + System.out.println( + cycle5.getTuples() + + "Size: " + cycle5.getTuples().size()); + + System.out.println("\nCOMPLETE 5"); +// System.out.println(complete5.findSingles()); + System.out.println( +// complete5.getTuples() + + "Size: " + complete5.getTuples().size()); - RequiredTuples t2 = new RequiredTuples(GraphGenerator.getTriangle(), new char[] {'S', 'I', 'R'}, true); - System.out.println(t2.findSingles()); - System.out.println(t2.getTuples() + "\nSize: " + t2.getTuples().size()); } /** diff --git a/src/io/github/ethankelly/Tuple.java b/src/io/github/ethankelly/Tuple.java index 30d08cf..deaac63 100644 --- a/src/io/github/ethankelly/Tuple.java +++ b/src/io/github/ethankelly/Tuple.java @@ -61,7 +61,7 @@ public boolean areStatesDifferent(boolean reqClosures) { /** * Given some list of vertices (some tuple), this method checks whether the index locations of every element of the * tuple are all distinct. If even two of the vertices have the same location, it is not a valid tuple for our - * purposes and we will not hve to consider the associated equation in the final system of equations that describes + * purposes, and we will not have to consider the associated equation in the final system of equations that describes * our compartmental model. * * @return true if no index location is repeated in the vertices, false otherwise. @@ -81,7 +81,7 @@ public boolean areLocationsDifferent() { /** * Given a potential tuple, this method checks that the states of each probability are not all the same, that each - * probability corresponds to a different vertex and that all of the vertices involved are in fact connected. If + * probability corresponds to a different vertex and that all the vertices involved are in fact connected. If * these three conditions are met, then it is a tuple that we are required to express in the total set of equations * describing the system dynamics. * diff --git a/src/io/github/ethankelly/graph/GraphGenerator.java b/src/io/github/ethankelly/graph/GraphGenerator.java index 40fef51..97f1b35 100644 --- a/src/io/github/ethankelly/graph/GraphGenerator.java +++ b/src/io/github/ethankelly/graph/GraphGenerator.java @@ -417,7 +417,13 @@ public static Graph erdosRenyi(int numVertices, double probability) { * @return the complete graph on the given number of vertices. */ public static Graph complete(int numVertices) { - return erdosRenyi(numVertices, 1.0).setName("Complete"); + Graph complete = new Graph(numVertices, "Complete"); + for (int i = 0; i < complete.getNumVertices(); i++) { + for (int j = 0; j < complete.getNumVertices(); j++) { + if (i != j && !complete.hasEdge(i, j)) complete.addEdge(i, j); + } + } + return complete; } /** @@ -541,9 +547,8 @@ public static Graph binaryTree(int numVertices) { */ public static Graph cycle(int numVertices) { Graph g = new Graph(numVertices, "Cycle"); - // Generate an array: [0, 1, ..., numVertices] and randomly shuffle it. + // Generate an array: [0, 1, ..., numVertices] int[] vertices = IntStream.range(0, numVertices).toArray(); - Rand.shuffle(vertices); // Connect vertices from 0 to 2 less than the number of vertices consecutively for (int i = 0; i < numVertices - 1; i++) { g.addEdge(vertices[i], vertices[i + 1]); diff --git a/src/io/github/ethankelly/symbols/Maths.java b/src/io/github/ethankelly/symbols/Maths.java index ed6e1a1..3704cac 100644 --- a/src/io/github/ethankelly/symbols/Maths.java +++ b/src/io/github/ethankelly/symbols/Maths.java @@ -8,9 +8,10 @@ public enum Maths { L_ANGLE("\u3008"), - R_ANGLE("\u3009"); + R_ANGLE("\u3009"), + PRIME("\u2032"); - private final String uni; + private final String uni; Maths(String uni) { this.uni = uni;