diff --git a/README.md b/README.md index 22397df..e4372e9 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ **Fastnet is a Julia package that allows very fast (linear-time) simulation of discrete-state dynamical processes on networks, such as commonly studied models of epidemics** Fastnet achieves linear-time performance by using an innovative data structure. The underlying network is a potentially directed and potentially non-simple graph. -The package provides a convenient syntax that allows to implement common models in a few simple lines of code. The simulations are done using an event-driven (Gillespie) algortithm offering fast performance and excellent agreement with real world continuous-time processes. Using Fastnet models with millions of nodes can be run within minutes on a standard laptop. +The package provides a convenient syntax that allows to implement common models in a few simple lines of code. The simulations are done using an event-driven (Gillespie) algorithm offering fast performance and excellent agreement with real world continuous-time processes. Using Fastnet models with millions of nodes can be run within minutes on a standard laptop. ## Example @@ -35,7 +35,7 @@ for i=1:20 # Infect 20 susceptible nodes at random nodestate!(net,node,I) end -function rates!(rates,t) # This functins computes the rates of processes +function rates!(rates,t) # This function computes the rates of processes infected=countnodes_f(net,I) # count the infected nodes activelinks=countlinks_f(net,SI) # count the SI links rates[1]=p*activelinks # compute total infection rate diff --git a/docs/src/about.md b/docs/src/about.md index 2488025..71c011e 100644 --- a/docs/src/about.md +++ b/docs/src/about.md @@ -1,13 +1,13 @@ # About Fastnet -The Fastnet package was developed by Thilo Gross at the Helmholtz Institute for Functional Mariene Diversity (HIFMB) in Oldenburg Germnany. +The Fastnet package was developed by Thilo Gross at the Helmholtz Institute for Functional Mariene Diversity (HIFMB) in Oldenburg Germany. ## Funding Thilo's work is funded by the Ministry for Science and Culture of Lower Saxony (MWK) and the Volkswagen Foundation through the “Niedersächsisches Vorab” grant program (grant number ZN3285). ## Publication -The package is also decribed in the following publication: +The package is also described in the following publication: ``` TBA @@ -25,5 +25,5 @@ Germany ``` ## About the name -This package is called Fastnet because it can simulate networks fast. However the name also reminds of Fastnet rock. A small rocky island off the Irish coast that boasts a distinctive lighthouse. Before the lighthouse was built, many sailors died in wrecks on this lonely rock. This image serves as a reminder of our solidarity that blooms in harsh environments and our ability to make the world a better, safer place by making contributions toward a common good. One way to make such a contribution today is to advance humanity's knowledge and capabilites through freely accessible research and free software. If you use Fastnet, consider making also the results of your work freely available. Please build a lighthouse on the foundations I laid by providing this package. +This package is called Fastnet because it can simulate networks fast. However the name also reminds of Fastnet rock. A small rocky island off the Irish coast that boasts a distinctive lighthouse. Before the lighthouse was built, many sailors died in wrecks on this lonely rock. This image serves as a reminder of our solidarity that blooms in harsh environments and our ability to make the world a better, safer place by making contributions toward a common good. One way to make such a contribution today is to advance humanity's knowledge and capabilities through freely accessible research and free software. If you use Fastnet, consider making also the results of your work freely available. Please build a lighthouse on the foundations I laid by providing this package. diff --git a/docs/src/background.md b/docs/src/background.md index e5a101a..d2693f8 100644 --- a/docs/src/background.md +++ b/docs/src/background.md @@ -4,15 +4,15 @@ This section contains some background information about the way in which fastnet ## How to simulate processes on networks If we think about simulating processes on networks, the first idea that usually comes to mind are to update all nodes simultaneously in small time steps. This idea is attractive because it makes thinking about the simulation seemingly easier, however it entails a number of problems. -1. Update order -- How do we actually implement our timesteps? Do we update every node in every timestep? And if so in which order do we update them. If the order is always the same we will create artifacts (unrealistic artifical behavior), so we need to randomize. But such randomization can lead to further problems, for instance do we keep track of who has already been updated etc. +1. Update order -- How do we actually implement our timesteps? Do we update every node in every timestep? And if so in which order do we update them. If the order is always the same we will create artifacts (unrealistic artificial behavior), so we need to randomize. But such randomization can lead to further problems, for instance do we keep track of who has already been updated etc. 2. Collisions -- What do we do if different events that occur in one timestep are contradictory? For example what if a node in an epidemic situation infects another node and recovers from the disease at the same time. Does the infection always go first? Or can the recovery occur first making the infection event impossible? -3. Timing artifacts -- Even if we find elegant solutions for event collisions and update order, we are still approximating a real-word system in which time flows continously by a model in which time proceeds in discrete steps. This in itself can cause some artifacts. For example it can lead to the formation of certain patterns which won't occur in the continuous time system. +3. Timing artifacts -- Even if we find elegant solutions for event collisions and update order, we are still approximating a real-word system in which time flows continuously by a model in which time proceeds in discrete steps. This in itself can cause some artifacts. For example it can lead to the formation of certain patterns which won't occur in the continuous time system. 4. Efficiency -- The most common solution to the problems above is to make timesteps tiny. While this lessens the impact of the artifacts it does not prevent them altogether. Moreover, it comes at a high cost in terms of efficiency. We will need to simulate many timesteps to cover the desired stretch of time, and in each of these steps we will be checking a large number of nodes for possible updates. However, since our timesteps are now tiny the probability that a given node is affected by an event in a given timestep is tiny, often in below 1 in a million. This means we spent a lot of computation time to do updates on nodes in which nothing changes at all. -Simulations that work with discrete timesteps can still be a good idea if the underlying system fundamentally works in discrete timesteps. However, in the vast majority of cases we can simulate systems better, faster, and more elgantly by not using timesteps at all... +Simulations that work with discrete timesteps can still be a good idea if the underlying system fundamentally works in discrete timesteps. However, in the vast majority of cases we can simulate systems better, faster, and more elegantly by not using timesteps at all... ## The Gillespie Algorithms In 1976 Daniel T. Gillespie published the idea for an event-driven simulation algorithm @@ -40,4 +40,4 @@ The basic idea for the bookkeeping used in Fastnet was born while we were workin ``` T. Gross, C.J. Dommar D’Lima and B. Blasius (2006) "Epidemic dynamics on an adaptive network." Phys. Rev. Lett. 96, 208701. ``` -The underlying datastructure that makes the bookkeeping possible is also available in Julia, on its own in the [Repos package](https://github.com/bridgewalker/Repos.jl) Fastnet does not use this package but rather reimplements the Repos structure in an opimized way for its current application. +The underlying datastructure that makes the bookkeeping possible is also available in Julia, on its own in the [Repos package](https://github.com/bridgewalker/Repos.jl) Fastnet does not use this package but rather reimplements the Repos structure in an optimized way for its current application. diff --git a/docs/src/concepts.md b/docs/src/concepts.md index de05d54..480f5ed 100644 --- a/docs/src/concepts.md +++ b/docs/src/concepts.md @@ -5,7 +5,7 @@ In Fastnet there are two ways to refer to a specific network node: 1. Node ID -- Every node has a unique ID number that never changes. The ID number may be recycled if a node is destroyed and later another node is created. All ID numbers are integers in the range 1:N, where N is the maximal node number that was passed to the FastNet constructor when the network was created. Node IDs are not necessarily consecutive so a network containing two nodes could contain the nodes with IDs 17 and 23 for example. -2. Node state and position -- We can also identify nodes by saying "the n'th node in state x" where n is one of the allowed node states and x is the so-called positon in this state. So in the epidemic model from the tutorial we might say we want the first infected node. A state-position pair will not always refer to the same node, but the positions are always numbered consecutively, so if there are two infected nodes these will have the positions 1 and 2 in the infected state. +2. Node state and position -- We can also identify nodes by saying "the n'th node in state x" where n is one of the allowed node states and x is the so-called position in this state. So in the epidemic model from the tutorial we might say we want the first infected node. A state-position pair will not always refer to the same node, but the positions are always numbered consecutively, so if there are two infected nodes these will have the positions 1 and 2 in the infected state. In general the FastNet functions expect you to refer to nodes by node ID. However, class and position is useful for example if you want to iterate over all nodes in a certain state. You can obtain the ID of a node at a certain position using the function ```julia @@ -29,7 +29,7 @@ So there can in principle be a link that connects a node to itself and a given p The network has been implemented in this way mainly to improve the efficiency of models that should almost always remain simple graphs. Allowing the occasional multi-link or self-loop eliminates the need for constant checking if a given operation would make the graph non-simple. By contrast models that make extensive use of self-loops or multi-links are rare. As a result this feature presently remains a bit undertested, so use with caution. In the underlying data structure of Fastnet, every link is represented as a directed link (an arc in math-speak). -This comes at no addional computational or memory cost and actually makes many nuances of the implementation easier. +This comes at no additional computational or memory cost and actually makes many nuances of the implementation easier. Nevertheless the package has been developed with undirected networks in mind and we can often simply ignore the underlying directedness of links. What this means is that Fastnet can be used to implement models that use directed links, models that use undirected (or bidirectional) links, and even models that mix the two types. One (mildly beneficial) effect of the directed nature of links is that there is a unique way to refer to the nodes at the end of the link. They can be determined by the functions diff --git a/docs/src/customization.md b/docs/src/customization.md index d8291ce..3625f55 100644 --- a/docs/src/customization.md +++ b/docs/src/customization.md @@ -12,7 +12,7 @@ MyReportingFunction(sim::FastSim,head::Bool) ``` The first argument that is passed is a reference to the sim that should be reported on. The second argument is a bool that tells the function whether a header needs to be printed. For example the default reporting function prints first the column heads of the output table and then the network state if true is passed. It prints only the network state if false is passed. -Once called your custom reporting function should handle all the neccessary printing, writing to disk, etc. +Once called your custom reporting function should handle all the necessary printing, writing to disk, etc. Also your reporting function should push the node and link counts to the *sim.results* dataframe, if you want the results to be stored there. You can do this by including ```julia @@ -39,7 +39,7 @@ Some useful information can be read from the first argument *sim*: The *printresults* field contains either true, if output should be printed to the terminal, false if no output should be printed to the terminal or an IOStream to which terminal output should be redirected. -Information about the network can be gained by calling the typeical functions (countnodes, etc.) on *sim.net*. In addition the FastNet object *sim.net* contains two fields that may be useful +Information about the network can be gained by calling the typical functions (countnodes, etc.) on *sim.net*. In addition the FastNet object *sim.net* contains two fields that may be useful - *sim.net.nodealias* -- A Vector of strings containing names for the node states - *sim.net.linkalias* -- A Vector of strings containing names for the tracked link states diff --git a/docs/src/faq.md b/docs/src/faq.md index 87ec328..086a641 100644 --- a/docs/src/faq.md +++ b/docs/src/faq.md @@ -1,7 +1,7 @@ # Frequently Asked Questions ## How large can I make the network? -This depends mainly on how much memory you have. Fastnet can simulate networks with several million nodes with relative ease. At some point you will see performance drop on the number of hard disk accesses on your operating system will spike. That is the point where Julia runs out of memory and some of the data needs to get parked on the hard disk. By contrast if you have a lot of memory available Fastnet can conceivably simulate sparce networks with billions of nodes. +This depends mainly on how much memory you have. Fastnet can simulate networks with several million nodes with relative ease. At some point you will see performance drop on the number of hard disk accesses on your operating system will spike. That is the point where Julia runs out of memory and some of the data needs to get parked on the hard disk. By contrast if you have a lot of memory available Fastnet can conceivably simulate sparse networks with billions of nodes. ## Can I use my own seed / random number generator? Yes, you can initialize your random number generator however you want and then pass it as an argument in the FastNet constructor. diff --git a/docs/src/index.md b/docs/src/index.md index 32e770f..7e6cc41 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -2,7 +2,7 @@ **Fastnet is a Julia package that allows very fast (linear-time) simulation of discrete-state dynamical processes on networks, such as commonly studied models of epidemics** -Fastnet achieves linear-time performance by using an innovative data structure. The underlying network is a potentially directed and potentially non-simple graph. The package provides a convenient syntax that allows to implement common models in a few simple lines of code. The simulations are done using an event-driven (Gillespie) algortithm offering fast performance and excellent agreement with real world continuous-time processes. Using fastnet models with millions of nodes can be run within minutes on a standard laptop. +Fastnet achieves linear-time performance by using an innovative data structure. The underlying network is a potentially directed and potentially non-simple graph. The package provides a convenient syntax that allows to implement common models in a few simple lines of code. The simulations are done using an event-driven (Gillespie) algorithm offering fast performance and excellent agreement with real world continuous-time processes. Using fastnet models with millions of nodes can be run within minutes on a standard laptop. ## Publication This package is described also in the following publication diff --git a/docs/src/tutorial.md b/docs/src/tutorial.md index a63e80b..28c28b1 100644 --- a/docs/src/tutorial.md +++ b/docs/src/tutorial.md @@ -104,7 +104,7 @@ Finally we fill the `rates` vector with the results. Here we chose to put the in The final `nothing` tells Julia that the function does not have a return value. -(One may wonder whether it would be more efficient to squeeze the six lines of code into two lines and avoid the definition of intermediate variables. The answer is generally no. Julia is a compiled language and the compiler will take care of such small scale optimizations for us, so it won't make a difference in performance. In this case the longer form makes the code more readable and makes it easier to fnd bugs.) +(One may wonder whether it would be more efficient to squeeze the six lines of code into two lines and avoid the definition of intermediate variables. The answer is generally no. Julia is a compiled language and the compiler will take care of such small scale optimizations for us, so it won't make a difference in performance. In this case the longer form makes the code more readable and makes it easier to find bugs.) ## Implementing the processes As the final piece of our model we need to define what happens when the processes occur we do this by defining two more functions @@ -128,7 +128,7 @@ If a recovery event occurs a random node recovers, so in our `recovery!` functio In an infection event the disease gets passed along a random SI-link, so we use `randomlink` to pick an SI link at random. Then we find the two endpoints of the link with `linksrc` and `linkdst`. We could then use an `if` statement to find out which one of the two endpoints is the susceptible node, but ifs create control hazards which aren't great for performance so its probably a bit quicker to set both of the endpoints to the infected state. (One of them was infected anyway and the other is the one that we need to infect.) -Again the fuctions used in our implementation of these processes run either in constant time (`randomnode`, `randomlink`, `linksrc`, `linkdst`), or they scale only with the degree of the affected node and the number of link states that we are tracking (`nodestate!`), hence the runtime required to simulate one event won't depend on the network size. Simulating a network for a finite time will still scale linearly with network size as larger networks have more nodes and links on which events can occur. +Again the functions used in our implementation of these processes run either in constant time (`randomnode`, `randomlink`, `linksrc`, `linkdst`), or they scale only with the degree of the affected node and the number of link states that we are tracking (`nodestate!`), hence the runtime required to simulate one event won't depend on the network size. Simulating a network for a finite time will still scale linearly with network size as larger networks have more nodes and links on which events can occur. ### Simulation Now that we have all the pieces, we can set up and run the simulation @@ -152,7 +152,7 @@ Before the `runsim` I have added Julia's `@time` macro which times the performan But before we run really large simulations we should make one final improvement... ## Faster functions -To help with debugging, functions such as `nodestate!` carry out a number of checks and try to provide meaningful error message if their arguments look iffy. This comes at a price in terms of performance. Because your rates and process functions might be called billions of times in large simulations, you may want to avoid these extra checks. For this purpose Fastnet provides faster implementations for some of the key functions. The names of these functions are identical to the other function names with an added `_f` at the end, so in addion to `nodestate!` there is also +To help with debugging, functions such as `nodestate!` carry out a number of checks and try to provide meaningful error message if their arguments look iffy. This comes at a price in terms of performance. Because your rates and process functions might be called billions of times in large simulations, you may want to avoid these extra checks. For this purpose Fastnet provides faster implementations for some of the key functions. The names of these functions are identical to the other function names with an added `_f` at the end, so in addition to `nodestate!` there is also ```julia nodestate_f!(net::FastNet,node,newstate) diff --git a/examples/SIRS.jl b/examples/SIRS.jl index 89558df..b24a08f 100644 --- a/examples/SIRS.jl +++ b/examples/SIRS.jl @@ -21,7 +21,7 @@ for i=1:20 # Infect 20 nodes at random nodestate!(net,node,I) end -function rates!(rates,t) # This functins computes the rates of processes +function rates!(rates,t) # This function computes the rates of processes infected=countnodes_f(net,I) # count the infected nodes recovered=countnodes_f(net,R) # count the infected nodes activelinks=countlinks_f(net,SI) # count the SI links diff --git a/examples/SIS.jl b/examples/SIS.jl index 8046282..ab2016e 100644 --- a/examples/SIS.jl +++ b/examples/SIS.jl @@ -19,7 +19,7 @@ for i=1:20 # Infect 20 nodes at random nodestate!(net,node,I) end -function rates!(rates,t) # This functins computes the rates of processes +function rates!(rates,t) # This function computes the rates of processes infected=countnodes_f(net,I) # count the infected nodes activelinks=countlinks_f(net,SI) # count the SI links infrate=p*activelinks # compute total infection rate diff --git a/examples/aSIS.jl b/examples/aSIS.jl index 8451633..a198970 100644 --- a/examples/aSIS.jl +++ b/examples/aSIS.jl @@ -27,7 +27,7 @@ for i=1:96000 # Infect 20 nodes at random nodestate!(net,node,I) end -function rates!(rates,t) # This functins computes the rates of processes +function rates!(rates,t) # This function computes the rates of processes infected=countnodes_f(net,I) # count the infected nodes activelinks=countlinks_f(net,SI) # count the SI links infrate=p*activelinks # compute total infection rate diff --git a/examples/metafoodchain.jl b/examples/metafoodchain.jl index ad744e7..42aecf4 100644 --- a/examples/metafoodchain.jl +++ b/examples/metafoodchain.jl @@ -38,7 +38,7 @@ for i=1:n # Assign patch state at random nodestate_f!(net,node_f(net,i),rand_init[i]) end -function rates!(rates,t) # This functins computes the rates of processes +function rates!(rates,t) # This function computes the rates of processes rates[1]=mortality[1]*countnodes(net,present1) # species 1 death rates[2]=mortality[2]*countnodes(net,present2) # species 2 death rates[3]=mortality[3]*countnodes(net,present3) # species 3 death diff --git a/src/Fastnet.jl b/src/Fastnet.jl index 6e4544b..d98b838 100644 --- a/src/Fastnet.jl +++ b/src/Fastnet.jl @@ -48,7 +48,7 @@ export FastNet,FastSim,LinkType, showlinks,shownodes, # Debug Functions healthcheck, - listnodes, # Analaysis functions + listnodes, # Analysis functions listlinks, listnodesinstate, listneighbors, diff --git a/src/access.jl b/src/access.jl index 348233d..7fb6409 100644 --- a/src/access.jl +++ b/src/access.jl @@ -2,7 +2,7 @@ """ results(FastNet) -Return a refernce to the results of *sim* as a DataFrame +Return a reference to the results of *sim* as a DataFrame # Example ```jldoctest @@ -106,7 +106,7 @@ end """ listneighbors(FastNet,nid) -Return a vector of the IDs of all nodes that are asjacent to node *nid* in FastNet *net*. +Return a vector of the IDs of all nodes that are adjacent to node *nid* in FastNet *net*. This function is comparatively slow as it needs to allocate the vector. In your *rates!* and process functions it is preferable to iterate over the neighbors using firstlinkout, @@ -289,13 +289,13 @@ end Save network link list of network *net* to file *filename*. -The file is written in text mode. Each line that is written correosponds to +The file is written in text mode. Each line that is written corresponds to one link. The lines have the form LINKID SOURCE DESTINATION Where LINKID is the respective link, SOURCE is the node id of the source node and DESTINATION -is the node id of the destination node. The elemnts are separated by space. The line is ended by a line feed '\\n'. +is the node id of the destination node. The elements are separated by space. The line is ended by a line feed '\\n'. See also [linklist](#Fastnet.linklist) """ @@ -322,7 +322,7 @@ end Save information about the nodes to file *filename*. -The file is written in text mode. Each line that is written correosponds to +The file is written in text mode. Each line that is written corresponds to one nodes. The lines have the form NODEID STATE INDEGREE OUTDEGREE IN-NEIGHBORS OUT-NEIGBORS diff --git a/src/debug.jl b/src/debug.jl index 1e0aa0a..f20c78a 100644 --- a/src/debug.jl +++ b/src/debug.jl @@ -374,7 +374,7 @@ function check_linkstateification(net::FastNet) cc=net.ttable[sc,dc] if cc!=c error=true - print("\n + Link $kid is in state $c but it connects node $src (state $sc) to $dst (state $dc) which means it schould be in state $cc") + print("\n + Link $kid is in state $c but it connects node $src (state $sc) to $dst (state $dc) which means it should be in state $cc") end end end @@ -392,15 +392,15 @@ end """ healthcheck(net) -Perform an internal consistencey check on a FastNet *net*. +Perform an internal consistency check on a FastNet *net*. -To achieve the desired performance Fastnet engages in a certain amount of double bookeeping. +To achieve the desired performance Fastnet engages in a certain amount of double bookkeeping. In an ideal world the FastNet structures should always stay internally consistent. However, -inconsistencies could arise from a number of sources including software bugs, CPU and memeory +inconsistencies could arise from a number of sources including software bugs, CPU and memory errors. This function checks the internal data stored in FastNet for consistency to make sure that everything is alright. -The return value is true if all chacks have been passed, false otherwise. +The return value is true if all checks have been passed, false otherwise. See also [link](#Fastnet.link) diff --git a/src/helpers.jl b/src/helpers.jl index 9e3a1b9..6c400b1 100644 --- a/src/helpers.jl +++ b/src/helpers.jl @@ -51,7 +51,7 @@ function make_linkstate_table(tlist,c,L) continue end if (m[i,j]!=L-1) - throw(ArgumentError("LinkTyoe number $rule, passed to the FastNet constructure, seems to say that links of the form from state $i to state $j are of type $rule, but they were previously defined as LinkType $(m[i,j]).")) + throw(ArgumentError("LinkTyoe number $rule, passed to the FastNet constructor, seems to say that links of the form from state $i to state $j are of type $rule, but they were previously defined as LinkType $(m[i,j]).")) end m[i,j]=rule end @@ -73,7 +73,7 @@ function make_linkstate_table(tlist,c,L) continue end if (m[i,j]!=L-1) - throw(ArgumentError("LinkTyoe number $rule, passed to the FastNet constructure, seems to say that links of the form from state $i to state $j are of type $rule, but they were previously defined as LinkType $(m[i,j]).")) + throw(ArgumentError("LinkTyoe number $rule, passed to the FastNet constructor, seems to say that links of the form from state $i to state $j are of type $rule, but they were previously defined as LinkType $(m[i,j]).")) end m[i,j]=rule end diff --git a/src/nettools.jl b/src/nettools.jl index 116df18..4832210 100644 --- a/src/nettools.jl +++ b/src/nettools.jl @@ -112,7 +112,7 @@ The algorithm will try to match the desired degree distribution as closely as po but small discrepancies can appear if the degree distribution would result in an odd degree sum or non integer numbers of nodes of certain degrees. -If there FastNet is not large enough to accomodate the desired number of links or nodes an argument error +If there FastNet is not large enough to accommodate the desired number of links or nodes an argument error will be thrown. The keyword arguments are @@ -191,7 +191,7 @@ The network generation is fast and unbiased, but isn't guaranteed to result in a Note that finite regular graphs with odd node degree and odd number of nodes do not exist. Hence either *deg* or the number of nodes must be even. -If there FastNet is not large enough to accomodate the desired number of links or nodes an argument error +If there FastNet is not large enough to accommodate the desired number of links or nodes an argument error will be thrown. The keyword arguments are @@ -287,7 +287,7 @@ The network in *net* is replaced with the new topology, that is a lattice specif Alternatively, *dims* can be a vector of Ints. In this case the dimension of the lattice is identical to the length of *dims* and each element of *dims* specifies the length of the lattice in one of these dimensions. -If there FastNet is not large enough to accomodate the desired number of nodes or links an argument error +If there FastNet is not large enough to accommodate the desired number of nodes or links an argument error will be thrown. Keyword arguments are @@ -381,13 +381,13 @@ Create a network with given adjacency matrix. The network in *net* is replaced with the new topology that is specified by the adjacency matrix *mat*. If direction of links matters note that the element *mat[i,j]* corresponds to the link from j to i. -Symmeric matrices will not result in parallel links, instead the link is placed in an arbitrary direction. +Symmetric matrices will not result in parallel links, instead the link is placed in an arbitrary direction. Note that node *n* in the matrix will be the node in position *n* in *net* after creation, which is not necessarily the node with ID *n*, if you need to find a particular node at a later time then it is best to save its id using the node(net,pos) function directly after calling adjacency!(net,mat). -If *net* is not large enough to accomodate the desired number of nodes or links an argument error +If *net* is not large enough to accommodate the desired number of nodes or links an argument error will be thrown. Keyword arguments are @@ -480,10 +480,10 @@ The network in *net* is replaced with the new topology in which each node has *d from (0,1). A maximal connection distance is calculated from the given mean degree and nodes get connected, when their euclidean distance is smaller than the maximal connection distance. -If there FastNet is not large enough to accomodate the desired number of links or nodes an argument error +If there FastNet is not large enough to accommodate the desired number of links or nodes an argument error will be thrown. -Additionaly, if the calculated maximal connection distance results in more links being generated than supported by the net, +Additionally, if the calculated maximal connection distance results in more links being generated than supported by the net, an argument error will be thrown as well. The keyword arguments are diff --git a/src/safelink.jl b/src/safelink.jl index f6f63bb..7976098 100644 --- a/src/safelink.jl +++ b/src/safelink.jl @@ -9,10 +9,10 @@ Determine link id from relative *rp* position and node state *s*. The link function provides a way to access links form the set of nodes in a certain link state, or from the set of all links. The two-argument version returns the id of the -link at poition *rp* in network *net*. The three-argument version returns the id of the link at -poition *rp* within the set of links that are in state *s*. +link at position *rp* in network *net*. The three-argument version returns the id of the link at +position *rp* within the set of links that are in state *s*. -All version of this function run in constant time, but fast (_f) verions sacrifice some safty +All versions of this function run in constant time, but fast (_f) versions sacrifice some safety checks for better performance. See [basic concepts](concepts.md) for details. See also [adjacent](#Fastnet.adjacent) @@ -66,7 +66,7 @@ end linkcounts(net) linkcounts_f(net) -Return an Array containing the number of link in the vairous link states. +Return an Array containing the number of link in the various link states. The elements of the array will show the counts in the same order in which the link types were passed to the FastNet Constructor. @@ -117,7 +117,7 @@ Return the state of the link with id *kid* in network *net*. Note that the link states are numbered in the order in which they were passed to the FastNet Constructor. -All version of this function run in constant time, but fast (_f) verion sacrifices some safty +All versions of this function run in constant time, but fast (_f) versions sacrifice some safety checks for better performance. See [basic concepts](concepts.md) for details. See also [nodestate!](#Fastnet.nodestate!), [FastNet](#FastNet.FastNet) @@ -155,7 +155,7 @@ Create a new link from node *src* to node*dst* in the network *net* and return i Worst-case performance of both versions of this function scales only with the number of tracked link states. -The fast (_f) verions sacrifice some safty checks for better performance. +The fast (_f) versions sacrifice some safety checks for better performance. See [basic concepts](concepts.md) for details. See also [destroylink!](#Fastnet.destrolink!) @@ -196,7 +196,7 @@ end Destroy the link with id *kid* in network *net*. All versions of this function run in constant time. -The fast (_f) verions sacrifice some safty checks for better performance. +The fast (_f) versions sacrifice some safety checks for better performance. See [basic concepts](concepts.md) for details. See also [makelink!](#Fastnet.makelink!) @@ -239,7 +239,7 @@ end Return the id of the node at the source of link *kid* in *net*. All versions of this function run in constant time. -The fast (_f) verion sacrifices some safty checks for better performance. +The fast (_f) version sacrifices some safety checks for better performance. See [basic concepts](concepts.md) for details. See also [makelink!](#Fastnet.makelink!) @@ -275,7 +275,7 @@ end Return the id of the node at the destination of link *kid* in *net*. All versions of this function run in constant time. -The fast (_f) verion sacrifices some safty checks for better performance. +The fast (_f) version sacrifices some safety checks for better performance. See [basic concepts](concepts.md) for details. See also [makelink!](#Fastnet.makelink!) @@ -314,7 +314,7 @@ This function can be used to iterate over the outgoing links of a node. If *kid* last link the return value is zero. All versions of this function run in constant time. -The fast (_f) verion sacrifices some safty checks for better performance. +The fast (_f) version sacrifices some safety checks for better performance. See [basic concepts](concepts.md) for details. See also [firstlinkout](#Fastnet.firstlinkout), [nextlinkin](#Fastnet.nextlinkin) @@ -371,7 +371,7 @@ This function can be used to iterate over the incoming links of a node. If *kid* last link the return value is zero. All versions of this function run in constant time. -The fast (_f) verion sacrifices some safty checks for better performance. +The fast (_f) version sacrifices some safety checks for better performance. See [basic concepts](concepts.md) for details. See also [firstlinkin](#Fastnet.firstlinkin), [nextlinkout](#Fastnet.nextlinkout) @@ -429,10 +429,10 @@ Count the links in state *s*, or, if no state is provided, in the entire network Instead of the state *s* also an Array or Tuple of states can be passed. In this case the total number of nodes in all of the listed states is returned. -The links in a sincle class or the entire network are counted in constant time. +The links in a single class or the entire network are counted in constant time. For the tuples or array arguments the performance scales with the number of elements in the Tulps/Array. -The fast (_f) verions sacrifice some safty checks for better performance. +The fast (_f) versions sacrifice some safety checks for better performance. See [basic concepts](concepts.md) for details. If performance is critical use this function rather than linkcounts. @@ -497,7 +497,7 @@ end Return true node with id *kid* exists in *net*, false otherwise. This function runs in constant time. -The fast (_f) verions sacrifice some safty checks for better performance. +The fast (_f) versions sacrifice some safety checks for better performance. See [basic concepts](concepts.md) for details. See also [makelink!](#Fastnet.makelink!) diff --git a/src/safenode.jl b/src/safenode.jl index 1f22816..a61250b 100644 --- a/src/safenode.jl +++ b/src/safenode.jl @@ -11,10 +11,10 @@ Determine node id from relative position and node state. The node function provides a way to access nodes form a the set of nodes in certain states, or from the set of all nodes in a simple way. The two-argument version returns the id of the -node at poition *rp* in network *net*. The three-argument version returns the id of the node at -poition *rp* within all nodes in state *s*. +node at position *rp* in network *net*. The three-argument version returns the id of the node at +position *rp* within all nodes in state *s*. -All version of this function run in constant time, but fast (_f) verions sacrifice some safty +All version of this function run in constant time, but fast (_f) versions sacrifice some safety checks for better performance. See [basic concepts](concepts.md) for details. # Examples @@ -67,7 +67,7 @@ end nodecounts(net) nodecounts_f(net) -Return an Array containing the number of nodes in the vairous node states. +Return an Array containing the number of nodes in the various node states. The time required for this function scales only with the number of node states (it is independent of the number of nodes). @@ -108,7 +108,7 @@ end Return the state of the node with id *nid* in network *net*. -All version of this function run in constant time, but fast (_f) verions sacrifice some safty +All version of this function run in constant time, but fast (_f) versions sacrifice some safety checks for better performance. See [basic concepts](concepts.md) for details. See also [nodestate!](#Fastnet.nodestate!) @@ -148,7 +148,7 @@ Set the node with id *nid* in net *net* to *s*. Worst-case performance of both versions of this function is O(ks\\*k)+O(ns) where ks is the number of tracked link states, k is the degree of the affected node and ns is the number of node states. -The fast (_f) verions sacrifice some safty checks for better performance. +The fast (_f) versions sacrifice some safety checks for better performance. See [basic concepts](concepts.md) for details. See also [nodestate](#Fastnet.nodestate) @@ -187,7 +187,7 @@ Create a new node in state *s* in the network *net* and return it's id. Worst-case performance of both versions of this function scales only with the number of node states. -The fast (_f) verions sacrifice some safty checks for better performance. +The fast (_f) versions sacrifice some safety checks for better performance. See [basic concepts](concepts.md) for details. See also [destroynode!](#Fastnet.destroynode!), [makenodes!](#Fastnet.makenodes!) @@ -227,7 +227,7 @@ Destroy the node with id *nid* in network *net*. Worst-case performance of both versions of this function is O(ks\\*k)+O(ns) where ks is the number of tracked link states, k is the degree of the affected node and ns is the number of node states. -The fast (_f) verions sacrifice some safty checks for better performance. +The fast (_f) versions sacrifice some safety checks for better performance. See [basic concepts](concepts.md) for details. See also [makenode!](#Fastnet.makenode!) @@ -269,7 +269,7 @@ Instead of the state *s* also an Array or Tuple of states can be passed. In this case the total number of nodes in all of the listed states is returned. All versions of this function run in constant time. -The fast (_f) verions sacrifice some safty checks for better performance. +The fast (_f) versions sacrifice some safety checks for better performance. See [basic concepts](concepts.md) for details. If performance is critical use this function rather than nodecounts. @@ -328,7 +328,7 @@ Return the link id of the first incoming link to the node with id *nid* in netwo If there are no incoming links then the return value is 0 All versions of this function run in constant time. -The fast (_f) verions sacrifice some safty checks for better performance. +The fast (_f) versions sacrifice some safety checks for better performance. See [basic concepts](concepts.md) for details. See also [firstlinkout](#Fastnet.firstlinkout), [nextlinkin](#Fastnet.nextlinkin) @@ -374,7 +374,7 @@ Return the link id of the first outgoing link from the node with id *nid* in net If there are no outgoing links then the return value is 0 All versions of this function run in constant time. -The fast (_f) verions sacrifice some safty checks for better performance. +The fast (_f) versions sacrifice some safety checks for better performance. See [basic concepts](concepts.md) for details. See also [firstlinkout](#Fastnet.firstlinkin), [nextlinkin](#Fastnet.nextlinkout) @@ -421,7 +421,7 @@ Here degree is interpreted as the number of times this node appears an an endpoi hence self-loops contribute 2 to the degree of the node that they link to. The worst case performance scales only with the degree of the affected node. -The fast (_f) verions sacrifice some safty checks for better performance. +The fast (_f) versions sacrifice some safety checks for better performance. See [basic concepts](concepts.md) for details. See also [indegree](#Fastnet.indegree), [outdegree](#Fastnet.outdegree) @@ -464,7 +464,7 @@ end Return the incoming degree of the node with id *nid* in network *net*. The worst case performance scales only with the indegree of the affected node. -The fast (_f) verions sacrifice some safty checks for better performance. +The fast (_f) versions sacrifice some safety checks for better performance. See [basic concepts](concepts.md) for details. See also [degree](#Fastnet.degree), [outdegree](#Fastnet.outdegree) @@ -507,7 +507,7 @@ end Return the outgoing degree of the node with id *nid* in network *net*. The worst case performance scales only with the outdegree of the affected node. -The fast (_f) verions sacrifice some safty checks for better performance. +The fast (_f) versions sacrifice some safety checks for better performance. See [basic concepts](concepts.md) for details. See also [degree](#Fastnet.degree), [indegree](#Fastnet.indegree) @@ -550,7 +550,7 @@ end Return if a node with id *nid* exists in *net*, false otherwise. This function runs in constant time. -The fast (_f) verions sacrifice some safty checks for better performance. +The fast (_f) versions sacrifice some safety checks for better performance. See [basic concepts](concepts.md) for details. See also [makenode!](#Fastnet.makenode!), [destroynode!](#Fastnet.destroynode!) @@ -582,7 +582,7 @@ end Create *N* nodes in state *s* in the network *net. Worst case performance of this function scales only with the number of node states. -The fast (_f) verions sacrifice some safty checks for better performance. +The fast (_f) versions sacrifice some safety checks for better performance. See [basic concepts](concepts.md) for details. See also [makenode!](#Fastnet.makenode!), [destroynode!](#Fastnet.destroynode!) @@ -622,7 +622,7 @@ drawn uniformly from the nodes in the states listed. This function runs in constant time if *s* is integer or omitted. If *s* is an Array or Tuple the worst case performance scales only with the number of node states. -The fast (_f) verions sacrifice some safty checks for better performance. +The fast (_f) versions sacrifice some safety checks for better performance. See [basic concepts](concepts.md) for details. The safe versions of this function will throw an ArgumentError with an informative error message @@ -687,7 +687,7 @@ a->b if such a link exists. Calling adjacent(net,a,a) will return a self-loop on a if one exists. The worst case performance of this function scales with the degree of node a. -The fast (_f) verions sacrifice some safty checks for better performance. +The fast (_f) versions sacrifice some safety checks for better performance. See [basic concepts](concepts.md) for details. # Examples diff --git a/src/simulation.jl b/src/simulation.jl index 0f6f08a..6045a0c 100644 --- a/src/simulation.jl +++ b/src/simulation.jl @@ -61,7 +61,7 @@ Simulate the next event in *sim*. This function will always advance the sim by exactly one event. If no event is possible it will advance time by one timeunit. -Output is generated at start time and directly after the event has occured. +Output is generated at start time and directly after the event has occurred. See also [FastSim](#Fastnet.FastSim),[simstep](#Fastnet.simstep) @@ -133,10 +133,10 @@ be updated to reflect the current state of the network (though see notes on the simulation time, [here](#Fastnet.FastSim)). This function simulates the FastSim **at least** for a certain time. If there -are still events occuring in the simulation by the end of the simulation run +are still events occurring in the simulation by the end of the simulation run the simulation will stop directly after the first event that happens after *dur*. So the simulation time will always be greater than *dur*. In general the difference and -the actual simulation time will be tiny, but in case events are extreley rare the +the actual simulation time will be tiny, but in case events are extremely rare the simulation may run significantly beyond *dur*. This behaviour is necessary to avoid a watchdog-paradox artifact when repeatedly starting short runs. diff --git a/src/structure.jl b/src/structure.jl index 6260cea..f5768e3 100644 --- a/src/structure.jl +++ b/src/structure.jl @@ -63,7 +63,7 @@ end """ FastNet(n,k,c,tlist;) -Create a FastNet object that represents a network structe. +Create a FastNet object that represents a network structure. Memory will be allocated for up to *n* nodes, up to *k* links. Nodes can be in one of *c* different states. @@ -73,7 +73,7 @@ infected and susceptible nodes. FastNet will do the necessary bookkeeping, to en of the links that are in a state listed in tlist. Note that the order of elements of tlist is not arbitrary. FastNet will think of links that match the first element -of tlist as being in link state 1. The links that match the sceond type in link state 2, and so on. +of tlist as being in link state 1. The links that match the second type in link state 2, and so on. WARNING: Each link in the network can only be in any one state at any time passing a tlist that contains overlapping link types (e.g. [LinkType([1,2],3),LinkType(3,1)] ) will result in an ArgumentError being thrown. @@ -263,11 +263,11 @@ filling the array that was passed as the first argument. The rates! should not h Note that when rates are time dependent then the rates! function should use the time value passed to it rather than obtaining a time form the simulation structure. The simulation code assumes that the rates will remain constant until the next event. This should be harmless in almost all cases but can cause inaccuracy if your -rates depend explicitely on time, the rates are very senstitive to time and events are rare. +rates depend explicitly on time, the rates are very sensitive to time and events are rare. The third argument is a Vector of functions that implements the processes. The processes are functions -without arguments when they are called they should implement effect of the respecive process running once. -Note that elemets of the process function vector should be in the same order as the corresponding rates computed by +without arguments when they are called they should implement effect of the respective process running once. +Note that elements of the process function vector should be in the same order as the corresponding rates computed by the *rates!* vector. FastSim supports a number of optional keyword arguments: