3

I have written a notebook with a few functions I defined. These functions describe a way of generating graphs using 2 inputs.
e.g. graph[n_,s_] := Graph[...]

I have also defined a function animating the process of drawing the graph.

animateGraph[n_Integer, s_List, p_Integer : 0] :=
 Module[{
   pathList = path[aiList[n, s, p]],
   verts = Range[n] - 1,
   coords = vertCoords[n]},
  Animate[
   Graph[
    verts,
    pathList[[;; i]],
    VertexLabels -> Automatic,
    VertexCoordinates -> coords,
    EdgeShapeFunction -> esf],
   {i, 0, Length@pathList, 1},
   AnimationRunning -> False,
   AnimationRepetitions -> 1]]  

It just takes more and more of the vertices until the graph is complete.
The problem, however, is that when I close the kernel and start again, the Animator is still trying to use the temporary variables from the last time it was evaluated. For example, with animateGraph[5,{1}], the Animator window displays:

Graph[{0, 1, 2, 3, 4, 5}, pathList$12323[[1 ;; 5]], 
 VertexLabels -> Automatic, VertexCoordinates -> coords$12323, 
 EdgeShapeFunction -> esf]  

instead of the animation I want.
And I get a repeated error message: Symbol::argx
I want to upload my work to the Community blog, but the notebook doesn't display the animations correctly. Is there a way I can have each call of animateGraph evaluate on startup so that new temporary variables are created?
I'm not sure if this helps, but I did try evaluating the definitions of the relevant functions in the Initialization option of Animate, but that doesn't seem to work either.

For completeness, I will include all the definitions needed to run graph, and animateGraph. If you want to generate a random graph, or animateGraph, just evaluate graph[ranomnS[]], or animateGraph[randomnS[]]

j[i_Integer, k_Integer] := Mod[i, k, 1];
sj[i_Integer, s_List] := s[[j[i, Length@s]]];

ai[0, n_Integer, s_List, p_Integer : 0] := p~Mod~n; ai[i_Integer, n_Integer, s_List, p_Integer : 0] := (ai[i - 1, n, s, p] + sj[i, s])~Mod~n;

t[n_Integer, s_List] := (n*Length[s])/GCD[n, Total[s]];

aiList[n_Integer, s_List, p_Integer : 0] := Table[ai[i, n, s, p], {i, 0, t[n, s]}];

randomnS[nMax_Integer : 20, kMax_Integer : 20] := Module[ {n = RandomInteger[{3, nMax}], k = RandomInteger[{1, kMax}], s}, s = RandomInteger[{-n, n}, k]; Unevaluated[Sequence[n, s]]];

path[vertices_List, directed_Symbol : Rule] := directed @@@ Partition[vertices, 2, 1];

vertCoords[n_] := Table[{Cos[(2 [Pi] i)/n], Sin[(2 [Pi] i)/n]}, {i, n}];

esf[el_, ___] := {Black, Arrowheads[0.02], Arrow[el, 0.05]};
Options[graph] = {"Union" -> False}; graph[n_Integer, s_List, p_Integer : 0, OptionsPattern[]] := Graph[ Range[n] - 1, If[OptionValue["Union"], Union, (# &)]@path[aiList[n, s, p]], VertexLabels -> Automatic, VertexCoordinates -> vertCoords[n], EdgeShapeFunction -> esf, ImageSize -> Medium];

Please let me know if there is more information I should add.

Michael E2
  • 235,386
  • 17
  • 334
  • 747
  • 3
    Basically, Module variables from outside a Dynamic[..] should not appear inside it. That includes Animate and Manipulate. See (29459), (55121), and possible fix (72422). Some rules by the lead developer: https://groups.google.com/g/comp.soft-sys.math.mathematica/c/XcLM5xDRqHE/m/V0FghIKeO_QJ -- Also, Animate (which produces a Manipulate btw) has an Initialization option you might use. – Michael E2 Dec 12 '20 at 18:49

1 Answers1

1

It is kind of cool to see these graphs being drawn. I made a Manipulate to play with it. It may not be useful, but here it is. Delay controls the speed at which new arrows are added.

Manipulate[
 animateGraph[n_Integer, s_List, p_Integer : 0] :=

DynamicModule[{i = 1, pathList = path[aiList[n, s, p]], verts = Range[n] - 1, coords = vertCoords[n]}, Dynamic[ Refresh[Graph[verts, pathList[[;; If[i < Length[pathList], Pause[x]; i = i + 1, i]]], VertexLabels -> Automatic, VertexCoordinates -> coords, EdgeShapeFunction -> esf]] ]]; animateGraph[n, s], Control[{{n, 1, "Points"}, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}}] , Control[{{s, {1}, "List"}, ControlType -> InputField}], Control[{{x, 0.1, "Delay"}, 0, 1}], Initialization -> (j[i_Integer, k_Integer] := Mod[i, k, 1]; sj[i_Integer, s_List] := s[[j[i, Length@s]]];

ai[0, n_Integer, s_List, p_Integer : 0] := p~Mod~n; ai[i_Integer, n_Integer, s_List, p_Integer : 0] := (ai[i - 1, n, s, p] + sj[i, s])~Mod~n; t[n_Integer, s_List] := (n*Length[s])/GCD[n, Total[s]];

aiList[n_Integer, s_List, p_Integer : 0] := Table[ai[i, n, s, p], {i, 0, t[n, s]}];

path[vertices_List, directed_Symbol : Rule] := directed @@@ Partition[vertices, 2, 1];

vertCoords[n_] := Table[{Cos[(2 [Pi] i)/n], Sin[(2 [Pi] i)/n]}, {i, n}];

esf[el_, ___] := {Black, Arrowheads[0.02], Arrow[el, 0.05]}; Options[graph] = {"Union" -> False}; )]

enter image description here

Jean-Pierre
  • 5,187
  • 8
  • 15