diff --git a/R/games.R b/R/games.R index 57a106e4d9e..d2900e70a5a 100644 --- a/R/games.R +++ b/R/games.R @@ -2149,9 +2149,13 @@ smallworld <- function(...) constructor_spec(sample_smallworld, ...) #' @param n Number of vertices. #' @param edges Number of edges per step. #' @param agebins Number of aging bins. +#' Must be at least 1. +#' This determines how finely the aging process is discretized. #' @param pref Vector (`sample_last_cit()` and `sample_cit_types()` or #' matrix (`sample_cit_cit_types()`) giving the (unnormalized) citation #' probabilities for the different vertex types. +#' For `sample_last_cit()`, this should be a numeric vector of length `agebins + 1`. +#' A common choice is a power-law decay, e.g., `(1:(agebins + 1))^-3`. #' @param directed Logical scalar, whether to generate directed networks. #' @param types Vector of length \sQuote{`n`}, the types of the vertices. #' Types are numbered from zero. @@ -2161,12 +2165,20 @@ smallworld <- function(...) constructor_spec(sample_smallworld, ...) #' @author Gabor Csardi \email{csardi.gabor@@gmail.com} #' @keywords graphs #' @family games +#' @examples +#' # Create a citation graph with 100 vertices, 5 age bins, +#' # and preferential attachment following a t^-3 power-law decay +#' g <- sample_last_cit(100, edges = 1, agebins = 5, pref = (1:6)^-3) +#' +#' # The preference vector determines how likely vertices in each age bin +#' # are to receive citations. Newer vertices (lower indices) are preferred. +#' g2 <- sample_last_cit(200, edges = 2, agebins = 10, pref = (1:11)^-2) #' @export sample_last_cit <- function( n, edges = 1, - agebins = n / 7100, - pref = (1:(agebins + 1))^-3, + agebins, + pref, directed = TRUE ) { on.exit(.Call(R_igraph_finalizer)) diff --git a/man/cited.type.game.Rd b/man/cited.type.game.Rd index 97671da1979..2cbd81ec7e2 100644 --- a/man/cited.type.game.Rd +++ b/man/cited.type.game.Rd @@ -23,7 +23,9 @@ Types are numbered from zero.} \item{pref}{Vector (\code{sample_last_cit()} and \code{sample_cit_types()} or matrix (\code{sample_cit_cit_types()}) giving the (unnormalized) citation -probabilities for the different vertex types.} +probabilities for the different vertex types. +For \code{sample_last_cit()}, this should be a numeric vector of length \code{agebins + 1}. +A common choice is a power-law decay, e.g., \code{(1:(agebins + 1))^-3}.} \item{directed}{Logical scalar, whether to generate directed networks.} diff --git a/man/citing.cited.type.game.Rd b/man/citing.cited.type.game.Rd index 71f467eede2..c8e768c17f0 100644 --- a/man/citing.cited.type.game.Rd +++ b/man/citing.cited.type.game.Rd @@ -23,7 +23,9 @@ Types are numbered from zero.} \item{pref}{Vector (\code{sample_last_cit()} and \code{sample_cit_types()} or matrix (\code{sample_cit_cit_types()}) giving the (unnormalized) citation -probabilities for the different vertex types.} +probabilities for the different vertex types. +For \code{sample_last_cit()}, this should be a numeric vector of length \code{agebins + 1}. +A common choice is a power-law decay, e.g., \code{(1:(agebins + 1))^-3}.} \item{directed}{Logical scalar, whether to generate directed networks.} diff --git a/man/lastcit.game.Rd b/man/lastcit.game.Rd index 3cc3232c1fa..d024c6d2941 100644 --- a/man/lastcit.game.Rd +++ b/man/lastcit.game.Rd @@ -17,11 +17,15 @@ lastcit.game( \item{edges}{Number of edges per step.} -\item{agebins}{Number of aging bins.} +\item{agebins}{Number of aging bins. +Must be at least 1. +This determines how finely the aging process is discretized.} \item{pref}{Vector (\code{sample_last_cit()} and \code{sample_cit_types()} or matrix (\code{sample_cit_cit_types()}) giving the (unnormalized) citation -probabilities for the different vertex types.} +probabilities for the different vertex types. +For \code{sample_last_cit()}, this should be a numeric vector of length \code{agebins + 1}. +A common choice is a power-law decay, e.g., \code{(1:(agebins + 1))^-3}.} \item{directed}{Logical scalar, whether to generate directed networks.} } diff --git a/man/sample_last_cit.Rd b/man/sample_last_cit.Rd index a5a55001a91..e4c91582866 100644 --- a/man/sample_last_cit.Rd +++ b/man/sample_last_cit.Rd @@ -9,13 +9,7 @@ \alias{cit_cit_types} \title{Random citation graphs} \usage{ -sample_last_cit( - n, - edges = 1, - agebins = n/7100, - pref = (1:(agebins + 1))^-3, - directed = TRUE -) +sample_last_cit(n, edges = 1, agebins, pref, directed = TRUE) last_cit(...) @@ -46,11 +40,15 @@ cit_cit_types(...) \item{edges}{Number of edges per step.} -\item{agebins}{Number of aging bins.} +\item{agebins}{Number of aging bins. +Must be at least 1. +This determines how finely the aging process is discretized.} \item{pref}{Vector (\code{sample_last_cit()} and \code{sample_cit_types()} or matrix (\code{sample_cit_cit_types()}) giving the (unnormalized) citation -probabilities for the different vertex types.} +probabilities for the different vertex types. +For \code{sample_last_cit()}, this should be a numeric vector of length \code{agebins + 1}. +A common choice is a power-law decay, e.g., \code{(1:(agebins + 1))^-3}.} \item{directed}{Logical scalar, whether to generate directed networks.} @@ -78,6 +76,15 @@ graph is growing. but the probability of an edge depends on the (potentially) cited vertex only. } +\examples{ +# Create a citation graph with 100 vertices, 5 age bins, +# and preferential attachment following a t^-3 power-law decay +g <- sample_last_cit(100, edges = 1, agebins = 5, pref = (1:6)^-3) + +# The preference vector determines how likely vertices in each age bin +# are to receive citations. Newer vertices (lower indices) are preferred. +g2 <- sample_last_cit(200, edges = 2, agebins = 10, pref = (1:11)^-2) +} \seealso{ Random graph models (games) \code{\link{bipartite_gnm}()}, diff --git a/src/.gitignore b/src/.gitignore index ee17235499e..e2d2a204f79 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -5,3 +5,4 @@ /Makevars *.gcda *.gcno +*.dd diff --git a/src/cpp11.dd b/src/cpp11.dd deleted file mode 100644 index 9abbae1fcad..00000000000 --- a/src/cpp11.dd +++ /dev/null @@ -1,4 +0,0 @@ -# Generated by deps.mk, do not edit by hand and do not add dependencies to system headers -cpp11.o: \ - cpp11.cpp \ - igraph_types.hpp \ diff --git a/src/cpprinterface.dd b/src/cpprinterface.dd deleted file mode 100644 index b919122a665..00000000000 --- a/src/cpprinterface.dd +++ /dev/null @@ -1,4 +0,0 @@ -# Generated by deps.mk, do not edit by hand and do not add dependencies to system headers -cpprinterface.o: \ - cpprinterface.cpp \ - igraph_vector.hpp \ diff --git a/src/init.dd b/src/init.dd deleted file mode 100644 index d13367a3b5c..00000000000 --- a/src/init.dd +++ /dev/null @@ -1,3 +0,0 @@ -# Generated by deps.mk, do not edit by hand and do not add dependencies to system headers -init.o: \ - init.cpp \ diff --git a/src/rinterface.dd b/src/rinterface.dd deleted file mode 100644 index 4e60bfc2463..00000000000 --- a/src/rinterface.dd +++ /dev/null @@ -1,4 +0,0 @@ -# Generated by deps.mk, do not edit by hand and do not add dependencies to system headers -rinterface.o: \ - rinterface.c \ - rinterface.h \ diff --git a/src/rinterface_extra.dd b/src/rinterface_extra.dd deleted file mode 100644 index 8abe00ad47b..00000000000 --- a/src/rinterface_extra.dd +++ /dev/null @@ -1,5 +0,0 @@ -# Generated by deps.mk, do not edit by hand and do not add dependencies to system headers -rinterface_extra.o: \ - rinterface.h \ - rinterface_extra.c \ - rrandom.h \ diff --git a/src/rrandom.dd b/src/rrandom.dd deleted file mode 100644 index f7531c7896f..00000000000 --- a/src/rrandom.dd +++ /dev/null @@ -1,3 +0,0 @@ -# Generated by deps.mk, do not edit by hand and do not add dependencies to system headers -rrandom.o: \ - rrandom.c \ diff --git a/src/simpleraytracer.dd b/src/simpleraytracer.dd deleted file mode 100644 index 70dce28800b..00000000000 --- a/src/simpleraytracer.dd +++ /dev/null @@ -1,3 +0,0 @@ -# Generated by deps.mk, do not edit by hand and do not add dependencies to system headers -simpleraytracer.o: \ - simpleraytracer.cpp \ diff --git a/src/uuid.dd b/src/uuid.dd deleted file mode 100644 index 272f3e70166..00000000000 --- a/src/uuid.dd +++ /dev/null @@ -1,3 +0,0 @@ -# Generated by deps.mk, do not edit by hand and do not add dependencies to system headers -uuid.o: \ - uuid.c \ diff --git a/tests/testthat/test-games.R b/tests/testthat/test-games.R index 0c786e1d23a..73be959e704 100644 --- a/tests/testthat/test-games.R +++ b/tests/testthat/test-games.R @@ -839,3 +839,47 @@ test_that("Dot product rng gives warnings", { paste0("Greater than 1 connection probability ", "in dot-product graph") ) }) + +test_that("sample_last_cit() works with explicit parameters", { + withr::local_seed(42) + # Basic test with small graph + g <- sample_last_cit(100, edges = 1, agebins = 5, pref = (1:6)^-3) + expect_equal(vcount(g), 100) + expect_equal(ecount(g), 99) + expect_true(is_directed(g)) + + # Test with more edges per step + g2 <- sample_last_cit(50, edges = 2, agebins = 3, pref = (1:4)^-2) + expect_equal(vcount(g2), 50) + expect_equal(ecount(g2), 98) # (50 - 1) * 2 + + # Test undirected version + g3 <- sample_last_cit( + 30, + edges = 1, + agebins = 2, + pref = c(1, 0.5, 0.25), + directed = FALSE + ) + expect_equal(vcount(g3), 30) + expect_false(is_directed(g3)) +}) + +test_that("sample_last_cit() requires agebins and pref parameters", { + expect_error( + sample_last_cit(100), + 'argument "agebins" is missing, with no default' + ) + + expect_error( + sample_last_cit(100, agebins = 5), + 'argument "pref" is missing, with no default' + ) +}) + +test_that("sample_last_cit() validates agebins > 0", { + expect_error( + sample_last_cit(100, edges = 1, agebins = 0, pref = c(1)), + "Number of age bins must be at least 1" + ) +})