diff --git a/.travis.yml b/.travis.yml index 54d7ef4f..237efc7f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,12 +14,12 @@ os: julia: - 0.6 - 0.7 + - 1.0 - nightly matrix: fast_finish: true allow_failures: - - julia: 0.7 - julia: nightly before_install: @@ -27,13 +27,14 @@ before_install: - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E084DAB9; fi - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo add-apt-repository -y "deb http://cran.rstudio.com/bin/linux/ubuntu $(lsb_release -s -c)/"; fi - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq -y; fi - - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install git libxml2-dev r-base r-base-dev r-recommended -y; fi + - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install git libxml2-dev r-base r-base-dev r-recommended -y --allow-unauthenticated; fi script: - if [[ -a .git/shallow ]]; then git fetch --unshallow; fi - - if [ "$TRAVIS_OS_NAME" == "linux" ]; then JULIA_MUST_CROSSVALIDATE=1 julia -e 'Pkg.init(); Pkg.clone(pwd()); Pkg.build("Diversity"); Pkg.test("Diversity", coverage=true)'; fi - - if [ "$TRAVIS_OS_NAME" == "osx" ]; then julia -e 'Pkg.init(); Pkg.clone(pwd()); Pkg.build("Diversity"); Pkg.test("Diversity", coverage=true)'; fi + - if [ "$TRAVIS_OS_NAME" == "linux" ]; then JULIA_MUST_CROSSVALIDATE=1 julia -e '(try using Pkg; true catch; false end || Pkg.init()); Pkg.clone(pwd()); Pkg.build("Diversity"); Pkg.test("Diversity", coverage=true)'; fi + # (VERSION >= v"0.7.0-" && (ENV["JULIA_MUST_CROSSVALIDATE"] = "0")); + - if [ "$TRAVIS_OS_NAME" == "osx" ]; then julia -e '(try using Pkg; true catch; false end || Pkg.init()); Pkg.clone(pwd()); Pkg.build("Diversity"); Pkg.test("Diversity", coverage=true)'; fi after_success: - - julia -e 'cd(Pkg.dir("Diversity", "test")); include("coverage.jl")' - - julia -e 'Pkg.add("Documenter"); cd(Pkg.dir("Diversity")); include(joinpath("docs", "make.jl"))' + - julia -e '(try using Pkg; catch end); using Diversity; cd(Diversity.path()); include("coverage.jl")' + - julia -e '(try using Pkg; catch end); Pkg.add("Documenter"); using Diversity; cd(Diversity.path(;dir=".")); include(joinpath("docs", "make.jl"))' diff --git a/README.md b/README.md index b9d8bc36..7ca7ec32 100644 --- a/README.md +++ b/README.md @@ -146,11 +146,11 @@ A complete list of these functions is shown below: * `norm_meta_beta()` : effective number of distinct subcommunities * `meta_gamma()` : metacommunity similarity-sensitive diversity -#### Diversity.Phylogenetics +#### Phylogenetics Phylogenetic diversity (described [here][leinster-cobbold-url]) is -included in the Diversity.Phylogenetics submodule. Documentation for -these diversity measures can be found +automatically included in the Diversity module when the `Phylo` package +is loaded. Documentation for these diversity measures can be found [here](http://richardreeve.github.io/Diversity.jl/latest/phylogenetics/). The phylogenetics code relies on the [Phylo][phylo-url] package to generate trees to incorporate into the diversity code, and the @@ -158,7 +158,7 @@ generate trees to incorporate into the diversity code, and the main packages are loaded: ```julia-repl -julia> using Diversity, Phylo, Diversity.Phylogenetics +julia> using Diversity, Phylo Creating Diversity to Phylo interface... julia> communities = [4 1; 3 2; 1 0; 0 1] / 12; @@ -171,16 +171,11 @@ String["tip 1", "tip 2", "tip 3", "tip 4"] julia> metaphylo = Metacommunity(communities, PhyloTypes(nt)); julia> raw_meta_rho(metaphylo, [1, 2]) -2×7 DataFrames.DataFrame -│ Row │ measure │ q │ type_level │ type_name │ partition_level │ -├─────┼──────────┼───┼────────────┼───────────┼─────────────────┤ -│ 1 │ "RawRho" │ 1 │ "types" │ "" │ "metacommunity" │ -│ 2 │ "RawRho" │ 2 │ "types" │ "" │ "metacommunity" │ - -│ Row │ partition_name │ diversity │ -├─────┼────────────────┼───────────┤ -│ 1 │ "" │ 1.66187 │ -│ 2 │ "" │ 1.51391 │ +2×8 DataFrames.DataFrame +│ Row │ div_type │ measure │ q │ type_level │ type_name │ partition_level │ partition_name │ diversity │ +├─────┼──────────────┼─────────┼───┼────────────┼───────────┼─────────────────┼────────────────┼───────────┤ +│ 1 │ Phylogenetic │ RawRho │ 1 │ types │ │ metacommunity │ │ 1.75622 │ +│ 2 │ Phylogenetic │ RawRho │ 2 │ types │ │ metacommunity │ │ 1.61371 │ ``` The package also provides some other sub-modules for related measures: diff --git a/appveyor.yml b/appveyor.yml index 45b99d39..9193b8bc 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,8 +1,9 @@ environment: matrix: - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe" + - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/1.0/julia-1.0-latest-win64.exe" - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe" - + branches: only: - master @@ -40,8 +41,8 @@ install: build_script: # Need to convert from shallow to complete for Pkg.clone to work - IF EXIST .git\shallow (git fetch --unshallow) - - C:\projects\julia\bin\julia -e "versioninfo(); + - C:\projects\julia\bin\julia -e "(try using Pkg; true catch; false end || Pkg.init()); Pkg.clone(pwd(), \"Diversity\"); Pkg.build(\"Diversity\")" test_script: - - C:\projects\julia\bin\julia -e "Pkg.test(\"Diversity\")" + - C:\projects\julia\bin\julia -e "(try using Pkg; catch end); Pkg.test(\"Diversity\")" diff --git a/docs/diversity.md b/docs/diversity.md index 725539c7..3be10940 100644 --- a/docs/diversity.md +++ b/docs/diversity.md @@ -66,7 +66,7 @@ meta = Metacommunity(pop) ``` #### Calculating diversity -First we need to calculate the low-level diversity component seperately, by passing a `metacommunity` object to the appropriate function; `RawAlpha()`, `NormalisedAlpha()`, `RawBeta()`, `NormalisedBeta()`, `RawRho()`, `NormalisedRho()`, or `Gamma()`. +First we need to calculate the low-level diversity component seperately, by passing a `metacommunity` object to the appropriate function; `RawAlpha()`, `NormalisedAlpha()`, `RawBeta()`, `NormalisedBeta()`, `RawRho()`, `NormalisedRho()`, or `Gamma()`. ```julia # First, calculate the normalised alpha component @@ -128,6 +128,7 @@ generate trees to incorporate into the diversity code: ```julia-repl julia> using Diversity, Phylo, Diversity.Phylogenetics +Creating Diversity to Phylo interface... julia> communities = [4 1; 3 2; 1 0; 0 1] / 12; @@ -139,16 +140,11 @@ String["tip 1", "tip 2", "tip 3", "tip 4"] julia> metaphylo = Metacommunity(communities, PhyloTypes(nt)); julia> raw_meta_rho(metaphylo, [1, 2]) -2×7 DataFrames.DataFrame -│ Row │ measure │ q │ type_level │ type_name │ partition_level │ -├─────┼──────────┼───┼────────────┼───────────┼─────────────────┤ -│ 1 │ "RawRho" │ 1 │ "types" │ "" │ "metacommunity" │ -│ 2 │ "RawRho" │ 2 │ "types" │ "" │ "metacommunity" │ - -│ Row │ partition_name │ diversity │ -├─────┼────────────────┼───────────┤ -│ 1 │ "" │ 1.66187 │ -│ 2 │ "" │ 1.51391 │ +2×8 DataFrames.DataFrame +│ Row │ div_type │ measure │ q │ type_level │ type_name │ partition_level │ partition_name │ diversity │ +├─────┼──────────────┼─────────┼───┼────────────┼───────────┼─────────────────┼────────────────┼───────────┤ +│ 1 │ Phylogenetic │ RawRho │ 1 │ types │ │ metacommunity │ │ 1.80666 │ +│ 2 │ Phylogenetic │ RawRho │ 2 │ types │ │ metacommunity │ │ 1.7056 │ ``` [docs-latest-img]: https://img.shields.io/badge/docs-latest-blue.svg diff --git a/docs/make.jl b/docs/make.jl index 0f9503c9..5097ae58 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -1,7 +1,7 @@ using Documenter using Diversity -makedocs(modules = [Diversity, Diversity.Phylogenetics, +makedocs(modules = [Diversity, Diversity.Ecology, Diversity.Jost, Diversity.Hill], clean = false) diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index cda5e9d3..76509d6c 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -27,8 +27,8 @@ docs_dir: 'build' pages: - Introduction: index.md +- Phylogenetics: phylogenetics.md - Submodules: - - Phylogenetics: phylogenetics.md - API: api.md - Other related measures: - Ecology: ecology.md diff --git a/docs/src/ecology.md b/docs/src/ecology.md index 6bcdf44a..ae10cc42 100644 --- a/docs/src/ecology.md +++ b/docs/src/ecology.md @@ -20,55 +20,34 @@ julia> community /= sum(community); julia> diversity = simpson(community) 1×7 DataFrames.DataFrame -│ Row │ measure │ q │ type_level │ type_name │ partition_level │ -├─────┼───────────┼───┼────────────┼───────────┼─────────────────┤ -│ 1 │ "Simpson" │ 2 │ "types" │ "" │ "subcommunity" │ - -│ Row │ partition_name │ diversity │ -├─────┼────────────────┼───────────┤ -│ 1 │ "1" │ 0.36 │ - +│ Row │ div_type │ measure │ type_level │ type_name │ partition_level │ partition_name │ diversity │ +├─────┼──────────┼─────────┼────────────┼───────────┼─────────────────┼────────────────┼───────────┤ +│ 1 │ Unique │ Simpson │ types │ │ subcommunity │ 1 │ 0.36 │ julia> ecosystem = [2 2 0.; 0 2 2]'; julia> ecosystem /= sum(ecosystem); julia> jaccard(ecosystem) -1×7 DataFrames.DataFrame -│ Row │ measure │ q │ type_level │ type_name │ partition_level │ -├─────┼───────────┼───┼────────────┼───────────┼─────────────────┤ -│ 1 │ "Jaccard" │ 0 │ "types" │ "" │ "metacommunity" │ - -│ Row │ partition_name │ diversity │ -├─────┼────────────────┼───────────┤ -│ 1 │ "" │ 0.333333 │ +1×8 DataFrames.DataFrame +│ Row │ div_type │ measure │ q │ type_level │ type_name │ partition_level │ partition_name │ diversity │ +├─────┼──────────┼─────────┼───┼────────────┼───────────┼─────────────────┼────────────────┼───────────┤ +│ 1 │ Unique │ Jaccard │ 0 │ types │ │ metacommunity │ │ 0.333333 │ julia> generalisedjaccard(ecosystem, [0, 1, 2]) -3×7 DataFrames.DataFrame -│ Row │ measure │ q │ type_level │ type_name │ partition_level │ -├─────┼───────────┼───┼────────────┼───────────┼─────────────────┤ -│ 1 │ "Jaccard" │ 0 │ "types" │ "" │ "metacommunity" │ -│ 2 │ "Jaccard" │ 1 │ "types" │ "" │ "metacommunity" │ -│ 3 │ "Jaccard" │ 2 │ "types" │ "" │ "metacommunity" │ - -│ Row │ partition_name │ diversity │ -├─────┼────────────────┼───────────┤ -│ 1 │ "" │ 0.333333 │ -│ 2 │ "" │ 0.414214 │ -│ 3 │ "" │ 0.5 │ +3×8 DataFrames.DataFrame +│ Row │ div_type │ measure │ q │ type_level │ type_name │ partition_level │ partition_name │ diversity │ +├─────┼─────────────┼─────────┼───┼────────────┼───────────┼─────────────────┼────────────────┼───────────┤ +│ 1 │ Arbitrary Z │ Jaccard │ 0 │ types │ │ metacommunity │ │ 0.333333 │ +│ 2 │ Arbitrary Z │ Jaccard │ 1 │ types │ │ metacommunity │ │ 0.414214 │ +│ 3 │ Arbitrary Z │ Jaccard │ 2 │ types │ │ metacommunity │ │ 0.5 │ julia> generalisedjaccard(ecosystem, [0, 1, 2], eye(3)) -3×7 DataFrames.DataFrame -│ Row │ measure │ q │ type_level │ type_name │ partition_level │ -├─────┼───────────┼───┼────────────┼───────────┼─────────────────┤ -│ 1 │ "Jaccard" │ 0 │ "types" │ "" │ "metacommunity" │ -│ 2 │ "Jaccard" │ 1 │ "types" │ "" │ "metacommunity" │ -│ 3 │ "Jaccard" │ 2 │ "types" │ "" │ "metacommunity" │ - -│ Row │ partition_name │ diversity │ -├─────┼────────────────┼───────────┤ -│ 1 │ "" │ 0.333333 │ -│ 2 │ "" │ 0.414214 │ -│ 3 │ "" │ 0.5 │ +3×8 DataFrames.DataFrame +│ Row │ div_type │ measure │ q │ type_level │ type_name │ partition_level │ partition_name │ diversity │ +├─────┼─────────────┼─────────┼───┼────────────┼───────────┼─────────────────┼────────────────┼───────────┤ +│ 1 │ Arbitrary Z │ Jaccard │ 0 │ types │ │ metacommunity │ │ 0.333333 │ +│ 2 │ Arbitrary Z │ Jaccard │ 1 │ types │ │ metacommunity │ │ 0.414214 │ +│ 3 │ Arbitrary Z │ Jaccard │ 2 │ types │ │ metacommunity │ │ 0.5 │ ``` ```@contents diff --git a/docs/src/hill.md b/docs/src/hill.md index ae238d45..cfcf8a78 100644 --- a/docs/src/hill.md +++ b/docs/src/hill.md @@ -6,25 +6,19 @@ Accessing the main functionality in the package is simple: ```jldoctest -julia> using Diversity.Hill +ulia> using Diversity.Hill julia> community = [10, 20, 20, 0, 3]; julia> community /= sum(community); julia> diversities = hillnumber(community, [0, 1, 2]) -3×7 DataFrames.DataFrame -│ Row │ measure │ q │ type_level │ type_name │ partition_level │ -├─────┼──────────────┼───┼────────────┼───────────┼─────────────────┤ -│ 1 │ "HillNumber" │ 0 │ "types" │ "" │ "subcommunity" │ -│ 2 │ "HillNumber" │ 1 │ "types" │ "" │ "subcommunity" │ -│ 3 │ "HillNumber" │ 2 │ "types" │ "" │ "subcommunity" │ - -│ Row │ partition_name │ diversity │ -├─────┼────────────────┼───────────┤ -│ 1 │ "1" │ 4.0 │ -│ 2 │ "1" │ 3.36264 │ -│ 3 │ "1" │ 3.09021 │ +3×8 DataFrames.DataFrame +│ Row │ div_type │ measure │ q │ type_level │ type_name │ partition_level │ partition_name │ diversity │ +├─────┼──────────┼────────────┼───┼────────────┼───────────┼─────────────────┼────────────────┼───────────┤ +│ 1 │ Unique │ HillNumber │ 0 │ types │ │ subcommunity │ 1 │ 4.0 │ +│ 2 │ Unique │ HillNumber │ 1 │ types │ │ subcommunity │ 1 │ 3.36264 │ +│ 3 │ Unique │ HillNumber │ 2 │ types │ │ subcommunity │ 1 │ 3.09021 │ ``` ```@contents diff --git a/docs/src/index.md b/docs/src/index.md index 1dcb8056..6a021e24 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -33,20 +33,13 @@ julia> # Create Metacommunity object meta = Metacommunity(pop); julia> diversities = norm_meta_alpha(meta, [0, 1, 2, Inf]) -4×7 DataFrames.DataFrame -│ Row │ measure │ q │ type_level │ type_name │ partition_level │ -├─────┼───────────────────┼─────┼────────────┼───────────┼─────────────────┤ -│ 1 │ "NormalisedAlpha" │ 0.0 │ "types" │ "" │ "metacommunity" │ -│ 2 │ "NormalisedAlpha" │ 1.0 │ "types" │ "" │ "metacommunity" │ -│ 3 │ "NormalisedAlpha" │ 2.0 │ "types" │ "" │ "metacommunity" │ -│ 4 │ "NormalisedAlpha" │ Inf │ "types" │ "" │ "metacommunity" │ - -│ Row │ partition_name │ diversity │ -├─────┼────────────────┼───────────┤ -│ 1 │ "" │ 2.16667 │ -│ 2 │ "" │ 1.86121 │ -│ 3 │ "" │ 1.63636 │ -│ 4 │ "" │ 1.0 │ +4×8 DataFrames.DataFrame +│ Row │ div_type │ measure │ q │ type_level │ type_name │ partition_level │ partition_name │ diversity │ +├─────┼──────────┼─────────────────┼─────┼────────────┼───────────┼─────────────────┼────────────────┼───────────┤ +│ 1 │ Unique │ NormalisedAlpha │ 0.0 │ types │ │ metacommunity │ │ 2.16667 │ +│ 2 │ Unique │ NormalisedAlpha │ 1.0 │ types │ │ metacommunity │ │ 1.86121 │ +│ 3 │ Unique │ NormalisedAlpha │ 2.0 │ types │ │ metacommunity │ │ 1.63636 │ +│ 4 │ Unique │ NormalisedAlpha │ Inf │ types │ │ metacommunity │ │ 1.0 │ julia> Z = [1.0 0 0; 0 1 1; 1 1 1]; @@ -55,18 +48,12 @@ julia> meta_z = Metacommunity(pop, Z); julia> rho = RawRho(meta_z); julia> redundancies = subdiv(rho, 2) -3×7 DataFrames.DataFrame -│ Row │ measure │ q │ type_level │ type_name │ partition_level │ -├─────┼──────────┼───┼────────────┼───────────┼─────────────────┤ -│ 1 │ "RawRho" │ 2 │ "types" │ "" │ "subcommunity" │ -│ 2 │ "RawRho" │ 2 │ "types" │ "" │ "subcommunity" │ -│ 3 │ "RawRho" │ 2 │ "types" │ "" │ "subcommunity" │ - -│ Row │ partition_name │ diversity │ -├─────┼────────────────┼───────────┤ -│ 1 │ "1" │ 2.0 │ -│ 2 │ "2" │ 3.0 │ -│ 3 │ "3" │ 3.0 │ +3×8 DataFrames.DataFrame +│ Row │ div_type │ measure │ q │ type_level │ type_name │ partition_level │ partition_name │ diversity │ +├─────┼─────────────┼─────────┼───┼────────────┼───────────┼─────────────────┼────────────────┼───────────┤ +│ 1 │ Arbitrary Z │ RawRho │ 2 │ types │ │ subcommunity │ 1 │ 2.0 │ +│ 2 │ Arbitrary Z │ RawRho │ 2 │ types │ │ subcommunity │ 2 │ 3.0 │ +│ 3 │ Arbitrary Z │ RawRho │ 2 │ types │ │ subcommunity │ 3 │ 3.0 │ ``` ```@contents diff --git a/docs/src/jost.md b/docs/src/jost.md index 9d029cd4..f3d069ad 100644 --- a/docs/src/jost.md +++ b/docs/src/jost.md @@ -15,18 +15,12 @@ julia> ecosystem = [2 2 0; 0 2 2]'; julia> ecosystem /= sum(ecosystem); julia> diversities = jostbeta(ecosystem, [0, 1, 2]) -3×7 DataFrames.DataFrame -│ Row │ measure │ q │ type_level │ type_name │ partition_level │ -├─────┼────────────┼───┼────────────┼───────────┼─────────────────┤ -│ 1 │ "JostBeta" │ 0 │ "types" │ "" │ "metacommunity" │ -│ 2 │ "JostBeta" │ 1 │ "types" │ "" │ "metacommunity" │ -│ 3 │ "JostBeta" │ 2 │ "types" │ "" │ "metacommunity" │ - -│ Row │ partition_name │ diversity │ -├─────┼────────────────┼───────────┤ -│ 1 │ "" │ 1.5 │ -│ 2 │ "" │ 1.41421 │ -│ 3 │ "" │ 1.33333 │ +3×8 DataFrames.DataFrame +│ Row │ div_type │ measure │ q │ type_level │ type_name │ partition_level │ partition_name │ diversity │ +├─────┼──────────┼──────────┼───┼────────────┼───────────┼─────────────────┼────────────────┼───────────┤ +│ 1 │ Unique │ JostBeta │ 0 │ types │ │ metacommunity │ │ 1.5 │ +│ 2 │ Unique │ JostBeta │ 1 │ types │ │ metacommunity │ │ 1.41421 │ +│ 3 │ Unique │ JostBeta │ 2 │ types │ │ metacommunity │ │ 1.33333 │ ``` ```@contents diff --git a/docs/src/phylogenetics.md b/docs/src/phylogenetics.md index fff751ed..64cb001d 100644 --- a/docs/src/phylogenetics.md +++ b/docs/src/phylogenetics.md @@ -1,4 +1,4 @@ -In the **Diversity.Phylogenetics** submodule, we generate Phylogenetic +In the **Phylogenetics** code, we generate Phylogenetic diversity measures, based on Faith PD and extended by Chao. #### Usage @@ -11,7 +11,7 @@ Using the functionality in the package is simple: - Calculate diversity! ```julia-repl -julia> using Phylo, Diversity, Diversity.Phylogenetics +julia> using Phylo, Diversity julia> species = ["Dog", "Cat", "Human", "Potato"]; @@ -57,7 +57,7 @@ julia> meta_gamma(metaphylo, 0) ``` ```@autodocs -Modules = [Diversity.Phylogenetics] +Modules = [Diversity] Private = false ``` diff --git a/ext/EcoBase/src/Interface.jl b/ext/EcoBase/src/Interface.jl index 8d3d6937..1c94df72 100644 --- a/ext/EcoBase/src/Interface.jl +++ b/ext/EcoBase/src/Interface.jl @@ -1,43 +1,49 @@ +using Compat + # Functions - most have to be implemented with the concrete type -occurrences(com::AbstractAssemblage) = error("function not defined for this type") -view(com::AbstractAssemblage) = error("function not defined for this type") +occurrences(asm::AbstractAssemblage) = error("function not defined for this type") +view(asm::AbstractAssemblage) = error("function not defined for this type") places(asm::AbstractAssemblage) = error("function not defined for this type") things(asm::AbstractAssemblage) = error("function not defined for this type") -nplaces(com::AbstractPlaces) = error("function not defined for this type") -placenames(com::AbstractPlaces) = error("function not defined for this type") +nplaces(plc::AbstractPlaces) = error("function not defined for this type") +placenames(plc::AbstractPlaces) = error("function not defined for this type") -nthings(com::AbstractThings) = error("function not defined for this type") -thingnames(com::AbstractThings) = error("function not defined for this type") +nthings(thg::AbstractThings) = error("function not defined for this type") +thingnames(thg::AbstractThings) = error("function not defined for this type") -nzrows(a::AbstractMatrix) = find(sum(a .> 0, 2) .> 0) -nzcols(a::AbstractMatrix) = find(sum(a .> 0, 1) .> 0) +nzrows(a::AbstractMatrix) = LinearIndices(Compat.sum(a .> 0; dims=2))[findall(Compat.sum(a .> 0; dims=2) .> 0)] +nzcols(a::AbstractMatrix) = LinearIndices(Compat.sum(a .> 0; dims=1))[findall(Compat.sum(a .> 0; dims=1) .> 0)] nnz(a::AbstractArray) = sum(a .> 0) -occurring(com::AbstractAssemblage) = nzrows(occurrences(com)) -occupied(com::AbstractAssemblage) = nzcols(occurrences(com)) -occupied(com::AbstractAssemblage, idx) = findn(occurrences(com)[idx, :]) -occurring(com::AbstractAssemblage, idx) = findn(occurrences(com)[:, idx]) - +occurring(asm::AbstractAssemblage) = nzrows(occurrences(asm)) +occupied(asm::AbstractAssemblage) = nzcols(occurrences(asm)) +if VERSION < v"0.7.0-" + occupied(asm::AbstractAssemblage, idx) = collect(zip(findn(occurrences(asm)[idx, :]))) + occurring(asm::AbstractAssemblage, idx) = collect(zip(findn(occurrences(asm)[:, idx]))) +else + occupied(asm::AbstractAssemblage, idx) = findall(!iszero, occurrences(asm)[idx, :]) + occurring(asm::AbstractAssemblage, idx) = findall(!iszero, occurrences(asm)[:, idx]) +end noccurring(x) = length(occurring(x)) noccupied(x) = length(occupied(x)) noccurring(x, idx) = length(occurring(x, idx)) noccupied(x, idx) = length(occupied(x, idx)) -thingoccurrences(com::AbstractAssemblage, idx) = view(occurrences(com), idx, :) -placeoccurrences(com::AbstractAssemblage, idx) = view(occurrences(com), :, idx) # make certain that the view implementation also takes thing or place names +thingoccurrences(asm::AbstractAssemblage, idx) = view(occurrences(asm), idx, :) +placeoccurrences(asm::AbstractAssemblage, idx) = view(occurrences(asm), :, idx) # make certain that the view implementation also takes thing or place names -richness(com::AbstractAssemblage{Bool, T, P}) where {T, P} = vec(sum(occurrences(com), 1)) -richness(com::AbstractAssemblage) = vec(mapslices(nnz, occurrences(com), 1)) +richness(asm::AbstractAssemblage{Bool, T, P}) where {T, P} = vec(sum(occurrences(asm), dims=1)) +richness(asm::AbstractAssemblage) = vec(mapslices(nnz, occurrences(asm), dims=1)) -occupancy(com::AbstractAssemblage{Bool, T, P}) where {T, P} = vec(sum(occurrences(com), 2)) -occupancy(com::AbstractAssemblage) = vec(mapslices(nnz, occurrences(com), 2)) +occupancy(asm::AbstractAssemblage{Bool, T, P}) where {T, P} = vec(sum(occurrences(asm), dims=2)) +occupancy(asm::AbstractAssemblage) = vec(mapslices(nnz, occurrences(asm), dims=2)) -records(com::AbstractAssemblage) = nnz(occurrences(com)) +records(asm::AbstractAssemblage) = nnz(occurrences(asm)) -cooccurring(com::AbstractAssemblage, inds...) = cooccurring(com, [inds...]) -function cooccurring(com::AbstractAssemblage, inds::AbstractVector) - sub = view(com, species = inds) +cooccurring(asm::AbstractAssemblage, inds...) = cooccurring(asm, [inds...]) +function cooccurring(asm::AbstractAssemblage, inds::AbstractVector) + sub = view(asm, species = inds) richness(sub) .== nthings(sub) end @@ -49,48 +55,40 @@ function createsummaryline(vec::AbstractVector{<:AbstractString}) end -function show(io::IO, com::T) where T <: AbstractAssemblage - sp = createsummaryline(thingnames(com)) - si = createsummaryline(placenames(com)) +function show(io::IO, asm::T) where T <: AbstractAssemblage + tn = createsummaryline(thingnames(asm)) + pn = createsummaryline(placenames(asm)) println(io, - """$T with $(nthings(com)) things in $(nplaces(com)) places + """$T with $(nthings(asm)) things in $(nplaces(asm)) places Thing names: - $(sp) + $(tn) Place names: - $(si) + $(pn) """) end - -macro forward_func(ex, fs) - T, field = ex.args[1], ex.args[2].args[1] - T = esc(T) - fs = Meta.isexpr(fs, :tuple) ? map(esc, fs.args) : [esc(fs)] - :($([:($f(x::$T, args...) = (Base.@_inline_meta; $f($(field)(x), args...))) - for f in fs]...); - nothing) -end - -@forward_func AbstractAssemblage.places nplaces, placenames -@forward_func AbstractAssemblage.things nthings, thingnames +nplaces(asm::AbstractAssemblage, args...) = nplaces(places(asm), args...) +placenames(asm::AbstractAssemblage, args...) = placenames(places(asm), args...) +nthings(asm::AbstractAssemblage, args...) = nthings(things(asm), args...) +thingnames(asm::AbstractAssemblage, args...) = thingnames(things(asm), args...) # TODO: # accessing cache -xmin(g::AbstractGrid) = error("function not defined for this type") -ymin(g::AbstractGrid) = error("function not defined for this type") -xcellsize(g::AbstractGrid) = error("function not defined for this type") -ycellsize(g::AbstractGrid) = error("function not defined for this type") -xcells(g::AbstractGrid) = error("function not defined for this type") -ycells(g::AbstractGrid) = error("function not defined for this type") -cellsize(g::AbstractGrid) = xcellsize(g), ycellsize(g) -cells(g::AbstractGrid) = xcells(g), ycells(g) -xrange(g::AbstractGrid) = xmin(g):xcellsize(g):xmax(g) #includes intermediary points -yrange(g::AbstractGrid) = ymin(g):ycellsize(g):ymax(g) -xmax(g::AbstractGrid) = xmin(g) + xcellsize(g) * (xcells(g) - 1) -ymax(g::AbstractGrid) = ymin(g) + ycellsize(g) * (ycells(g) - 1) +xmin(grd::AbstractGrid) = error("function not defined for this type") +ymin(grd::AbstractGrid) = error("function not defined for this type") +xcellsize(grd::AbstractGrid) = error("function not defined for this type") +ycellsize(grd::AbstractGrid) = error("function not defined for this type") +xcells(grd::AbstractGrid) = error("function not defined for this type") +ycells(grd::AbstractGrid) = error("function not defined for this type") +cellsize(grd::AbstractGrid) = xcellsize(grd), ycellsize(grd) +cells(grd::AbstractGrid) = xcells(grd), ycells(grd) +xrange(grd::AbstractGrid) = xmin(grd):xcellsize(grd):xmax(grd) #includes intermediary points +yrange(grd::AbstractGrid) = ymin(grd):ycellsize(grd):ymax(grd) +xmax(grd::AbstractGrid) = xmin(grd) + xcellsize(grd) * (xcells(grd) - 1) +ymax(grd::AbstractGrid) = ymin(grd) + ycellsize(grd) * (ycells(grd) - 1) indices(grd::AbstractGrid, idx) = error("function not defined for this type") #Implement this in SpatialEcology! diff --git a/src/API.jl b/src/API.jl index 4dbe6bec..db00604d 100644 --- a/src/API.jl +++ b/src/API.jl @@ -1,4 +1,6 @@ using Diversity +using Compat.InteractiveUtils +using Compat ### AbstractPartition API @@ -74,6 +76,33 @@ function _counttypes(t::T, raw::Bool) where T <: AbstractTypes return length(_gettypenames(t, raw)) end +""" + _getdiversityname(::AbstractTypes) + +Returns the name of the diversity type used to calculate. +""" +function _getdiversityname end + +_getdiversityname(::AbstractTypes) = "Unknown diversity" + +""" + _addedoutputcols(::AbstractTypes) + +Returns the name of any additional columns needed to be added to outputs. +""" +function _addedoutputcols end + +_addedoutputcols(::AbstractTypes) = Dict{Symbol, Type}() + +""" + _getaddedoutput(::AbstractTypes) + +Returns the name of any additional columns needed to be added to outputs. +""" +function _getaddedoutput end + +_getaddedoutput(::AbstractTypes) = nothing + """ _calcabundance(t::AbstractTypes, a::AbstractArray) @@ -154,11 +183,18 @@ Returns the metacommunity abundances of the metacommunity. May be implemented by each AbstractMetacommunity subtype. """ function _getmetaabundance end -function _getmetaabundance(m::AbstractMetacommunity, raw::Bool) - return reduce(+, SubcommunityIterator(m) do mc - return _getabundance(mc, raw) - end - ) +_getmetaabundance(mc::Meta, raw::Bool) where +{FP, AProcessed, Sim, Part, + Meta <: Diversity.API.AbstractMetacommunity{FP, <: AbstractVector, + AProcessed, Sim, Part}} = + _getabundance(mc, raw) + +function _getmetaabundance(mc::Meta, raw::Bool) where + {FP, AProcessed, Sim, Part, + Meta <: Diversity.API.AbstractMetacommunity{FP, <: AbstractMatrix, + AProcessed, Sim, Part}} + ab = Compat.sum(_getabundance(mc, raw), dims=2) + return reshape(ab, length(ab)) end """ @@ -177,11 +213,18 @@ Returns the subcommunity weights of the metacommunity. May be implemented by each AbstractMetacommunity subtype. """ function _getweight end -function _getweight(m::AbstractMetacommunity) - return reduce(+, TypeIterator(m) do mc - return _getabundance(mc, false) - end - ) +_getweight(::Meta) where +{FP, AProcessed, Sim, Part, + Meta <: Diversity.API.AbstractMetacommunity{FP, <: AbstractVector, + AProcessed, Sim, Part}} = [one(FP)] + +function _getweight(mc::Meta) where + {FP, AProcessed, Sim, Part, + Meta <: Diversity.API.AbstractMetacommunity{FP, <: AbstractMatrix, + AProcessed, Sim, Part}} + ab = _getabundance(mc, false) + w = Compat.sum(ab, dims=1) + return reshape(w, length(w)) end """ @@ -204,8 +247,18 @@ metacommunity as a whole. May be implemented by each AbstractMetacommunity subtype. """ function _getmetaordinariness! end -function _getmetaordinariness!(m::AbstractMetacommunity) - return reduce(+, SubcommunityIterator(_getordinariness!, m)) +_getmetaordinariness!(mc::Meta) where +{FP, AProcessed, Sim, Part, + Meta <: Diversity.API.AbstractMetacommunity{FP, <: AbstractVector, + AProcessed, Sim, Part}} = + _getordinariness!(mc) + +function _getmetaordinariness!(mc::Meta) where + {FP, AProcessed, Sim, Part, + Meta <: Diversity.API.AbstractMetacommunity{FP, <: AbstractMatrix, + AProcessed, Sim, Part}} + ord = Compat.sum(_getordinariness!(mc), dims=2) + return reshape(ord, length(ord)) end ### Other optional APIs to implement diff --git a/src/Diversity.jl b/src/Diversity.jl index b8775a21..fa2a7b7a 100644 --- a/src/Diversity.jl +++ b/src/Diversity.jl @@ -38,6 +38,7 @@ export _countsubcommunities # optional export AbstractTypes export _gettypenames, _calcsimilarity, _getscale # required export _counttypes, _calcabundance, _calcordinariness # optional +export _getdiversityname, _addedoutputcols, _getaddedoutput # optional # Base class and functions required for each metacommunity export AbstractMetacommunity @@ -59,6 +60,7 @@ export gettypenames, getsubcommunitynames export getabundance, getmetaabundance, getweight export getordinariness!, getmetaordinariness! export calcsimilarity # Needed because it sometimes doesn't exist unless requested +export getdiversityname, addedoutputcols, getaddedoutput include("Iterators.jl") export TypeIterator, SubcommunityIterator @@ -106,13 +108,22 @@ end export getName, getASCIIName, getFullName -module Phylogenetics -export PhyloTypes +# Does PhyloTypes need to exist already? using Requires -@require Phylo begin - println("Creating Diversity to Phylo interface...") - include("Phylogenetics.jl") -end +@static if VERSION < v"0.7.0-" + @require Phylo begin + println("Creating Diversity to Phylo interface...") + include("Phylogenetics.jl") + export PhyloTypes + end +else + function __init__() + @require Phylo="aea672f4-3940-5932-aa44-993d1c3ff149" begin + println("Creating Diversity to Phylo interface...") + include("Phylogenetics.jl") + export PhyloTypes + end + end end include("GeneralisedDiversities.jl") @@ -168,4 +179,7 @@ export hillnumber end # sub-module Hill +# Path into package +path(path...; dir::String = "test") = joinpath(@__DIR__, "..", dir, path...) + end # module diff --git a/src/DiversityMeasure.jl b/src/DiversityMeasure.jl index 29af9326..80c59d4e 100644 --- a/src/DiversityMeasure.jl +++ b/src/DiversityMeasure.jl @@ -67,41 +67,8 @@ diversity of a metacommunity. """ abstract type DiversityMeasure{FP <: AbstractFloat, AbMatrix <: AbstractMatrix, - DivArray <: AbstractArray} end - -""" - getscnames(dm::DiversityMeasure) - -Return the names of the subcommunities of the metacommunity being analysed - -# Arguments: - -- `dm`: DiversityMeasure - -# Returns: - -- Vector of Strings of names of subcommunities. -""" -function getscnames(dm::DiversityMeasure) - return dm.scnames -end - -""" - gettypenames(dm::DiversityMeasure) - -Return the names of the types of the metacommunity being analysed - -# Arguments: - -- `dm`: DiversityMeasure - -# Returns: - -- Vector of Strings of names of types. -""" -function gettypenames(dm::DiversityMeasure) - return dm.typenames -end + DivArray <: AbstractArray, + MC <: AbstractMetacommunity} end """ getASCIIName(dm::DiversityMeasure) @@ -117,8 +84,8 @@ Return the ASCII name of the DiversityMeasure - String containing simple ASCII name of DiversityMeasure """ function getASCIIName(dm::DiversityMeasure) - s = replace(string(typeof(dm)), "Diversity.", "") - replace(s, r"{.*}$", "") + s = replace(string(typeof(dm)), "Diversity." => "") + replace(s, r"{.*}$" => "") end """ @@ -151,6 +118,17 @@ Return the full name of the DiversityMeasure. """ function getFullName end +""" + _getmeta(dm::DiversityMeasure) + +Return the metacommunity belonging to the DiversityMeasure. +""" +function _getmeta end + +getsubcommunitynames(dm::DiversityMeasure) = getsubcommunitynames(_getmeta(dm)) +gettypenames(dm::DiversityMeasure) = gettypenames(_getmeta(dm)) +getdiversityname(dm::DiversityMeasure) = getdiversityname(_getmeta(dm)) + (dl::DiversityLevel)(dm::DiversityMeasure) = getPartitionFunction(dm, dl) (dl::DiversityLevel)(dm::DiversityMeasure, qs) = getPartitionFunction(dm, dl)(qs) @@ -162,8 +140,8 @@ diversity measures which are straight power means. PowerMeanMeasure subtypes allow you to calculate and cache any kind of diversity of a metacommunity. """ -abstract type PowerMeanMeasure{FP, AbMatrix, DivArray} <: - DiversityMeasure{FP, AbMatrix, DivArray} end +abstract type PowerMeanMeasure{FP, AbMatrix, DivArray, MC} <: + DiversityMeasure{FP, AbMatrix, DivArray, MC} end """ RelativeEntropyMeasure @@ -173,8 +151,8 @@ diversity measures which are relative entropy-based diversity measures. RelativeEntropyMeasure subtypes allow you to calculate and cache any kind of diversity of a metacommunity. """ -abstract type RelativeEntropyMeasure{FP, AbMatrix, DivArray} <: - DiversityMeasure{FP, AbMatrix, DivArray} end +abstract type RelativeEntropyMeasure{FP, AbMatrix, DivArray, MC} <: + DiversityMeasure{FP, AbMatrix, DivArray, MC} end """ inddiv(measure::DiversityMeasure, q::Real) @@ -198,16 +176,27 @@ function inddiv end @inline function inddiv(measure::DiversityMeasure, q::Real) raw = inddiv_raw(measure, q) types = gettypenames(measure) - scn = getscnames(measure) + scn = getsubcommunitynames(measure) scs = reshape(scn, 1, length(scn)) - dfs = broadcast((div, tn, pn) -> DataFrame(measure=getASCIIName(measure), - q=q, - type_level="type", type_name=tn, - partition_level="subcommunity", - partition_name=pn, - diversity=div), + dfs = broadcast((div, tn, pn) -> + DataFrame(div_type=getdiversityname(measure), + measure=getASCIIName(measure), + q=q, + type_level="type", type_name=tn, + partition_level="subcommunity", + partition_name=pn, + diversity=div), raw, types, scs) - return reduce(append!, dfs) + df = reduce(append!, dfs) + cols = addedoutputcols(_getmeta(measure)) + if length(cols) > 0 + len = length(df) + data = getaddedoutput(_getmeta(measure)) + for col in keys(cols) + insert!(df, length(df) + 1, data[col], col) + end + end + return df end @inline function inddiv(measure::DiversityMeasure, qs::AbstractVector) @@ -246,14 +235,24 @@ function subdiv end @inline function subdiv(measure::DiversityMeasure, q::Real) raw = subdiv_raw(measure, q) - scs = getscnames(measure) - dfs = broadcast((div, pn) -> DataFrame(measure=getASCIIName(measure), q=q, + scs = getsubcommunitynames(measure) + dfs = broadcast((div, pn) -> DataFrame(div_type=getdiversityname(measure), + measure=getASCIIName(measure), q=q, type_level="types", type_name="", partition_level="subcommunity", partition_name=pn, diversity=div), raw, scs) - return reduce(append!, dfs) + df = reduce(append!, dfs) + cols = addedoutputcols(_getmeta(measure)) + if length(cols) > 0 + len = length(df) + data = getaddedoutput(_getmeta(measure)) + for col in keys(cols) + insert!(df, length(df) + 1, data[col], col) + end + end + return df end @inline function subdiv(measure::DiversityMeasure, qs::AbstractVector) @@ -269,11 +268,11 @@ end end @inline function subdiv_raw(measure::PowerMeanMeasure, q::Real) - powermean(inddiv_raw(measure, q), 1.0 - q, measure.abundances) + powermean(inddiv_raw(measure, q), one(q) - q, measure.abundances) end @inline function subdiv_raw(measure::RelativeEntropyMeasure, q::Real) - powermean(inddiv_raw(measure, q), q - 1.0, measure.abundances) + powermean(inddiv_raw(measure, q), q - one(q), measure.abundances) end """ @@ -297,11 +296,21 @@ function metadiv end @inline function metadiv(measure::DiversityMeasure, q::Real) raw = metadiv_raw(measure, q) - return DataFrame(measure=getASCIIName(measure), q=q, - type_level="types", type_name="", - partition_level="metacommunity", - partition_name="", - diversity=raw) + df = DataFrame(div_type=getdiversityname(measure), + measure=getASCIIName(measure), q=q, + type_level="types", type_name="", + partition_level="metacommunity", + partition_name="", + diversity=raw) + cols = addedoutputcols(_getmeta(measure)) + if length(cols) > 0 + len = length(df) + data = getaddedoutput(_getmeta(measure)) + for col in keys(cols) + insert!(df, length(df) + 1, data[col], col) + end + end + return df end @inline function metadiv(measure::DiversityMeasure, qs::AbstractVector) @@ -317,7 +326,7 @@ end end @inline function metadiv_raw(measure::DiversityMeasure, q::Real) - powermean(subdiv_raw(measure, q), 1.0 - q, measure.weights) + powermean(subdiv_raw(measure, q), one(q) - q, measure.weights) end function getPartitionFunction(measure::DiversityMeasure, level::DiversityLevel) @@ -350,29 +359,25 @@ measures are simple powermeans of the individual measures. - `meta`: a Metacommunity """ -struct RawAlpha{FP, AbMatrix, DivArray} <: - PowerMeanMeasure{FP, AbMatrix, DivArray} +struct RawAlpha{FP, AbMatrix, DivArray, MC} <: + PowerMeanMeasure{FP, AbMatrix, DivArray, MC} abundances::AbMatrix weights::Vector{FP} diversities::DivArray - typenames::Vector{String} - scnames::Vector{String} + meta::MC end function RawAlpha(meta::M) where M <: AbstractMetacommunity ab = getabundance(meta) ws = getweight(meta) value = getordinariness!(meta) .^ -1 - types = gettypes(meta) - part = getpartition(meta) - RawAlpha{eltype(ab), typeof(ab), typeof(value)}(ab, ws, value, - gettypenames(types), - getsubcommunitynames(part)) - + return RawAlpha{eltype(ab), typeof(ab), + typeof(value), M}(ab, ws, value, meta) end getName(::RawAlpha) = "α" getFullName(::RawAlpha) = "raw alpha diversity" +_getmeta(m::RawAlpha) = m.meta """ NormalisedAlpha @@ -386,29 +391,25 @@ measures are simple powermeans of the individual measures. - `meta`: a Metacommunity """ -struct NormalisedAlpha{FP, AbMatrix, DivArray} <: - PowerMeanMeasure{FP, AbMatrix, DivArray} +struct NormalisedAlpha{FP, AbMatrix, DivArray, MC} <: + PowerMeanMeasure{FP, AbMatrix, DivArray, MC} abundances::AbMatrix weights::Vector{FP} diversities::DivArray - typenames::Vector{String} - scnames::Vector{String} + meta::MC end function NormalisedAlpha(meta::M) where M <: AbstractMetacommunity ab = getabundance(meta) ws = getweight(meta) value = ws' ./ getordinariness!(meta) - types = gettypes(meta) - part = getpartition(meta) - NormalisedAlpha{eltype(ab), typeof(ab), - typeof(value)}(ab, ws, value, - gettypenames(types), - getsubcommunitynames(part)) + return NormalisedAlpha{eltype(ab), typeof(ab), + typeof(value), M}(ab, ws, value, meta) end getName(::NormalisedAlpha) = "ᾱ" getFullName(::NormalisedAlpha) = "normalised alpha diversity" +_getmeta(m::NormalisedAlpha) = m.meta """ RawBeta @@ -423,30 +424,27 @@ composite types are powermeans of those measures. - `meta`: a Metacommunity """ -struct RawBeta{FP, AbMatrix, DivArray} <: - RelativeEntropyMeasure{FP, AbMatrix, DivArray} +struct RawBeta{FP, AbMatrix, DivArray, MC} <: + RelativeEntropyMeasure{FP, AbMatrix, DivArray, MC} abundances::AbMatrix weights::Vector{FP} diversities::DivArray - typenames::Vector{String} - scnames::Vector{String} + meta::MC end function RawBeta(meta::M) where M <: AbstractMetacommunity ab = getabundance(meta) ws = getweight(meta) value = getordinariness!(meta) ./ getmetaordinariness!(meta) - types = gettypes(meta) - part = getpartition(meta) - RawBeta{eltype(ab), typeof(ab), typeof(value)}(ab, ws, value, - gettypenames(types), - getsubcommunitynames(part)) + return RawBeta{eltype(ab), typeof(ab), + typeof(value), M}(ab, ws, value, meta) end const Distinctiveness = RawBeta getName(::RawBeta) = "β" getFullName(::RawBeta) = "distinctiveness" +_getmeta(m::RawBeta) = m.meta """ NormalisedBeta @@ -461,29 +459,25 @@ composite types are powermeans of those measures. - `meta`: a Metacommunity """ -struct NormalisedBeta{FP, AbMatrix, DivArray} <: - RelativeEntropyMeasure{FP, AbMatrix, DivArray} +struct NormalisedBeta{FP, AbMatrix, DivArray, MC} <: + RelativeEntropyMeasure{FP, AbMatrix, DivArray, MC} abundances::AbMatrix weights::Vector{FP} diversities::DivArray - typenames::Vector{String} - scnames::Vector{String} + meta::MC end function NormalisedBeta(meta::M) where M <: AbstractMetacommunity ab = getabundance(meta) ws = getweight(meta) value = getordinariness!(meta) ./ (getmetaordinariness!(meta) .* ws') - types = gettypes(meta) - part = getpartition(meta) - NormalisedBeta{eltype(ab), typeof(ab), - typeof(value)}(ab, ws, value, - gettypenames(types), - getsubcommunitynames(part)) + return NormalisedBeta{eltype(ab), typeof(ab), + typeof(value), M}(ab, ws, value, meta) end getName(::NormalisedBeta) = "β̄" getFullName(::NormalisedBeta) = "effective number of subcommunities" +_getmeta(m::NormalisedBeta) = m.meta """ RawRho @@ -498,30 +492,27 @@ measures. - `meta`: a Metacommunity """ -struct RawRho{FP, AbMatrix, DivArray} <: - PowerMeanMeasure{FP, AbMatrix, DivArray} +struct RawRho{FP, AbMatrix, DivArray, MC} <: + PowerMeanMeasure{FP, AbMatrix, DivArray, MC} abundances::AbMatrix weights::Vector{FP} diversities::DivArray - typenames::Vector{String} - scnames::Vector{String} + meta::MC end function RawRho(meta::M) where M <: AbstractMetacommunity ab = getabundance(meta) ws = getweight(meta) value = getmetaordinariness!(meta) ./ getordinariness!(meta) - types = gettypes(meta) - part = getpartition(meta) - RawRho{eltype(ab), typeof(ab), typeof(value)}(ab, ws, value, - gettypenames(types), - getsubcommunitynames(part)) + return RawRho{eltype(ab), typeof(ab), + typeof(value), M}(ab, ws, value, meta) end const Redundancy = RawRho getName(::RawRho) = "ρ" getFullName(::RawRho) = "redundancy" +_getmeta(m::RawRho) = m.meta """ NormalisedRho @@ -536,31 +527,27 @@ measures. - `meta`: a Metacommunity """ -struct NormalisedRho{FP, AbMatrix, DivArray} <: - PowerMeanMeasure{FP, AbMatrix, DivArray} +struct NormalisedRho{FP, AbMatrix, DivArray, MC} <: + PowerMeanMeasure{FP, AbMatrix, DivArray, MC} abundances::AbMatrix weights::Vector{FP} diversities::DivArray - typenames::Vector{String} - scnames::Vector{String} + meta::MC end function NormalisedRho(meta::M) where M <: AbstractMetacommunity ab = getabundance(meta) ws = getweight(meta) value = (getmetaordinariness!(meta) .* ws') ./ getordinariness!(meta) - types = gettypes(meta) - part = getpartition(meta) - NormalisedRho{eltype(ab), typeof(ab), - typeof(value)}(ab, ws, value, - gettypenames(types), - getsubcommunitynames(part)) + return NormalisedRho{eltype(ab), typeof(ab), + typeof(value), M}(ab, ws, value, meta) end const Representativeness = NormalisedRho getName(::NormalisedRho) = "ρ̄" getFullName(::NormalisedRho) = "representativeness" +_getmeta(m::NormalisedRho) = m.meta """ Gamma @@ -574,25 +561,21 @@ measures are simple powermeans of the individual measures. - `meta`: a Metacommunity """ -struct Gamma{FP, AbMatrix, DivArray} <: - PowerMeanMeasure{FP, AbMatrix, DivArray} +struct Gamma{FP, AbMatrix, DivArray, MC} <: + PowerMeanMeasure{FP, AbMatrix, DivArray, MC} abundances::AbMatrix weights::Vector{FP} diversities::DivArray - typenames::Vector{String} - scnames::Vector{String} + meta::MC end function Gamma(meta::M) where M <: AbstractMetacommunity ab = getabundance(meta) ws = getweight(meta) - value = ones(ws)' ./ getmetaordinariness!(meta) - types = gettypes(meta) - part = getpartition(meta) - Gamma{eltype(ab), typeof(ab), typeof(value)}(ab, ws, value, - gettypenames(types), - getsubcommunitynames(part)) + value = fill!(similar(ws), 1)' ./ getmetaordinariness!(meta) + return Gamma{eltype(ab), typeof(ab), typeof(value), M}(ab, ws, value, meta) end getName(::Gamma) = "γ" getFullName(::Gamma) = "gamma diversity" +_getmeta(m::Gamma) = m.meta diff --git a/src/Ecology.jl b/src/Ecology.jl index 3f122008..4e2809c5 100644 --- a/src/Ecology.jl +++ b/src/Ecology.jl @@ -1,8 +1,13 @@ using Diversity using Diversity.ShortNames +using Diversity.API +using Compat.LinearAlgebra """ - generalisedrichness(level::DiversityLevel, proportions::AbstractArray, Z::AbstractMatrix) + generalisedrichness(level::DiversityLevel, proportions::AbstractArray, + Z::AbstractMatrix) + generalisedrichness(level::DiversityLevel, proportions::AbstractArray, + sim::AbstractTypes) Calculates species richness (diversity at q = 0) of a series of columns representing subcommunity counts, allowing a similarity matrix @@ -14,15 +19,20 @@ for the types / species. - `proportions`: population proportions -- `Z`: similarity matrix +- `Z`: similarity matrix or +- `sim`: instance of AbstractTypes # Returns: - diversity (at ecosystem level) or diversities (of subcommunities) """ +generalisedrichness(level::DiversityLevel, + proportions::AbstractArray, + Z::AbstractMatrix = Matrix(1.0I, size(proportions, 1), size(proportions, 1))) = + generalisedrichness(level, proportions, GeneralTypes(Z)) function generalisedrichness(level::DiversityLevel, proportions::AbstractArray, - Z::AbstractMatrix = eye(size(proportions, 1))) + sim::AbstractTypes) if (level == subcommunityDiversity) dm = ᾱ elseif (level == metacommunityDiversity) @@ -30,7 +40,7 @@ function generalisedrichness(level::DiversityLevel, else error("Can't calculate richness for $level") end - gr=level(dm(Metacommunity(proportions, Z)), 0) + gr=level(dm(Metacommunity(proportions, sim)), 0) gr[:measure] = "Richness" return gr end @@ -47,12 +57,15 @@ columns representing independent subcommunity counts. #### Returns: - diversities of subcommunities """ -function richness(proportions::AbstractVecOrMat) - generalisedrichness(subcommunityDiversity, proportions) -end +richness(proportions::AbstractVecOrMat) = + generalisedrichness(subcommunityDiversity, proportions, + UniqueTypes(size(proportions, 1))) """ - generalisedshannon(level::DiversityLevel, proportions::AbstractArray, Z::AbstractMatrix) + generalisedshannon(level::DiversityLevel, proportions::AbstractArray, + Z::AbstractMatrix) + generalisedshannon(level::DiversityLevel, proportions::AbstractArray, + sim::AbstractTypes) Calculates Shannon entropy (log of diversity at q = 1) of a series of columns representing independent subcommunity counts, allowing a @@ -63,14 +76,21 @@ similarity matrix for the types / species. - `proportions`: population proportions -- `Z`: similarity matrix +- `Z`: similarity matrix or +- `sim`: instance of AbstractTypes #### Returns: - entropy (at metacommunity level) or entropies (of subcommunities) """ +function generalisedshannon end +generalisedshannon(level::DiversityLevel, + proportions::AbstractArray, + Z::AbstractMatrix = Matrix(1.0I, size(proportions, 1), size(proportions, 1))) = + generalisedshannon(level, proportions, GeneralTypes(Z)) + function generalisedshannon(level::DiversityLevel, proportions::AbstractArray, - Z::AbstractMatrix = eye(size(proportions, 1))) + sim::AbstractTypes) if (level == subcommunityDiversity) dm = ᾱ elseif (level == metacommunityDiversity) @@ -78,14 +98,15 @@ function generalisedshannon(level::DiversityLevel, else error("Can't calculate richness for $level") end - gs = level(dm(Metacommunity(proportions, Z)), 1) + gs = level(dm(Metacommunity(proportions, sim)), 1) gs[:diversity] = log.(gs[:diversity]) gs[:measure] = "Shannon" + delete!(gs, :q) return gs end """ -### Calculate Shannon entropy of populations + shannon(proportions::AbstractVecOrMat) Calculates shannon entropy (log of diversity at q = 1) of a series of columns representing independent subcommunity counts. @@ -96,12 +117,15 @@ columns representing independent subcommunity counts. #### Returns: - entropies of subcommunities """ -function shannon(proportions::AbstractVecOrMat) - generalisedshannon(subcommunityDiversity, proportions) -end +shannon(proportions::AbstractVecOrMat) = + generalisedshannon(subcommunityDiversity, proportions, + UniqueTypes(size(proportions, 1))) """ -### Calculate a generalised version of Simpson's index + generalisedsimpson(level::DiversityLevel, proportions::AbstractArray, + Z::AbstractMatrix) + generalisedsimpson(level::DiversityLevel, proportions::AbstractArray, + sim::AbstractTypes) Calculates Simpson's index (1 / diversity at q = 2) of a series of columns representing independent subcommunity counts, allowing a @@ -112,14 +136,21 @@ similarity matrix for the types / species. - `proportions`: population proportions -- `Z`: similarity matrix +- `Z`: similarity matrix or +- `sim`: instance of AbstractTypes #### Returns: - concentration (at ecosystem level) or concentrations (of subcommunities) """ +function generalisedsimpson end +generalisedsimpson(level::DiversityLevel, + proportions::AbstractArray, + Z::AbstractMatrix = Matrix(1.0I, size(proportions, 1), size(proportions, 1))) = + generalisedsimpson(level, proportions, GeneralTypes(Z)) + function generalisedsimpson(level::DiversityLevel, proportions::AbstractArray, - Z::AbstractMatrix = eye(size(proportions, 1))) + sim::AbstractTypes) if (level == subcommunityDiversity) dm = ᾱ elseif (level == metacommunityDiversity) @@ -127,9 +158,10 @@ function generalisedsimpson(level::DiversityLevel, else error("Can't calculate richness for $level") end - gs = level(dm(Metacommunity(proportions, Z)), 2) + gs = level(dm(Metacommunity(proportions, sim)), 2) gs[:diversity] = gs[:diversity] .^ -1 gs[:measure] = "Simpson" + delete!(gs, :q) return gs end @@ -147,12 +179,13 @@ columns representing independent subcommunity counts. - concentrations of subcommunities """ -function simpson(proportions::AbstractVecOrMat) - generalisedsimpson(subcommunityDiversity, proportions) -end +simpson(proportions::AbstractVecOrMat) = + generalisedsimpson(subcommunityDiversity, proportions, + UniqueTypes(size(proportions, 1))) """ generalisedjaccard(proportions::AbstractArray, qs, Z::AbstractMatrix) + generalisedjaccard(proportions::AbstractArray, qs, sim::AbstractTypes) Calculates a generalisation of the Jaccard index of two columns representing the counts of two subcommunities. This evaluates to raw @@ -168,22 +201,32 @@ better properties. - `qs`: single number or vector of values of parameter q -- `Z`: similarity matrix +- `Z`: similarity matrix or +- `sim`: instance of AbstractTypes # Returns: - Jaccard-related distinctivess measures """ -function generalisedjaccard(proportions::AbstractArray, qs, - Z::AbstractMatrix = eye(size(proportions, 1))) - meta = Metacommunity(proportions, Z) +function generalisedjaccard end + +generalisedjaccard(proportions::AbstractMatrix, qs, + Z::AbstractMatrix = + Matrix(1.0I, size(proportions, 1), + size(proportions, 1))) = + generalisedjaccard(proportions, qs, GeneralTypes(Z)) + +function generalisedjaccard(proportions::AbstractMatrix, qs, + sim::AbstractTypes) + meta = Metacommunity(proportions, sim) countsubcommunities(meta) == 2 || error("Can only calculate Jaccard index for 2 subcommunities") ab = metadiv(α(meta), qs) g = metadiv(Γ(meta), qs) - j = join(ab, g, on=[:q, :type_level, :type_name, :partition_level, :partition_name], + j = join(ab, g, on=[:q, :type_level, :type_name, + :partition_level, :partition_name, :div_type], makeunique=true) - j[:diversity] = j[:diversity] ./ j[:diversity_1] - 1 + j[:diversity] = j[:diversity] ./ j[:diversity_1] .- 1 j[:measure] = "Jaccard" delete!(j, [:diversity_1, :measure_1]) return j @@ -204,6 +247,6 @@ normmetaalpha(proportions, 0) / metagamma(proportions, 0) - 1 - the Jaccard index """ -function jaccard(proportions::AbstractMatrix) - generalisedjaccard(proportions, 0) -end +jaccard(proportions::AbstractMatrix) = + generalisedjaccard(proportions, 0, + UniqueTypes(size(proportions, 1))) diff --git a/src/EffectiveNumbers.jl b/src/EffectiveNumbers.jl index 3caf3606..f2834914 100644 --- a/src/EffectiveNumbers.jl +++ b/src/EffectiveNumbers.jl @@ -13,35 +13,52 @@ is 1, so this is just the arithmetic mean. #### Returns: - weighted power mean(s) """ -function powermean(values::V, order::R = 1, weights::V = ones(values)) where +function powermean(values::V, order::R = 1, weights::V = fill!(similar(values), 1)) where {R <: Real, FP <: AbstractFloat, V <: AbstractVector{FP}} length(values) == length(weights) || throw(DimensionMismatch("powermean: Weight and value vectors must be the same length")) - # Normalise weights to sum to 1 (as per Rényi) - proportions = weights / sum(weights) - - # Check whether all proportions are NaN - happens in normalisation when all - # weights are zero in group. In that case we want to propagate the NaN - if all(isnan.(proportions)) - return(convert(FP, NaN)) + # Check whether all weights are zero in group. + # In that case we want to return a NaN + if iszero(weights) + return convert(FP, NaN) end - # Extract values with non-zero weights - present = [(proportions[i], values[i]) - for i=1:length(proportions) if !(proportions[i] ≈ zero(eltype(proportions)))] if isinf(order) if order > 0 # +Inf -> Maximum - reduce((a, b) -> a[2] > b[2] ? a : b, present)[2] + s = zero(FP) + for i in eachindex(values, weights) + @inbounds if (weights[i] > eps(FP)) & (values[i] > s) + s = values[i] + end + end + return s else # -Inf -> Minimum - reduce((a, b) -> a[2] < b[2] ? a : b, present)[2] + s = convert(FP, Inf) + for i in eachindex(values, weights) + @inbounds if (weights[i] > eps(FP)) & (values[i] < s) + s = values[i] + end + end + return s end else if order ≈ zero(order) - mapreduce(pair -> pair[2] ^ pair[1], *, present) + s = zero(FP) + for i in eachindex(values, weights) + @inbounds if weights[i] > eps(FP) + s += weights[i] * log(values[i]) + end + end + return exp(s / sum(weights)) else - mapreduce(pair -> pair[1] * pair[2] ^ order, +, present) ^ - (one(order) / order) + s = zero(FP) + for i in eachindex(values, weights) + @inbounds if weights[i] > eps(FP) + s += weights[i] * values[i] ^ order + end + end + return (s / sum(weights)) ^ (one(FP) / order) end end end @@ -49,21 +66,20 @@ end # This is the next most common case - a vector of orders function powermean(values::V, orders::VR, - weights::V = ones(values)) where + weights::V = fill!(similar(values), 1.0)) where {R <: Real, VR <: AbstractVector{R}, FP <: AbstractFloat, V <: AbstractVector{FP}} - map(order -> powermean(values, order, weights), orders) + return map(order -> powermean(values, order, weights), orders) end # This is the next most simple case - matrices with subcommunities, and an order or orders -function powermean(values::M, orders, weights::M = ones(values)) where +function powermean(values::M, orders, weights::M = fill!(similar(values), 1)) where {FP <: AbstractFloat, M <: AbstractMatrix{FP}} size(values) == size(weights) || throw(DimensionMismatch("powermean: Weight and value matrixes " * "must be the same size")) - - map(col -> powermean(view(values, :, col), orders, - view(weights, :, col)), 1:size(values, 2)) + @views map(col -> powermean(values[:, col], orders, + weights[:, col]), 1:size(values, 2)) end """ @@ -89,7 +105,7 @@ function qD(meta::M, qs) where M <: AbstractMetacommunity countsubcommunities(meta) == 1 || throw(DimensionMismatch("Can only calculate diversity of a single community")) - powermean(getabundance(meta), qs - 1, getabundance(meta))[1] .^ -1 + powermean(getabundance(meta), qs .- 1, getabundance(meta))[1] .^ -1 end function qD(proportions::V, qs) where {FP <: AbstractFloat, @@ -123,7 +139,7 @@ function qDZ(meta::M, qs) where M <: AbstractMetacommunity countsubcommunities(meta) == 1 || throw(DimensionMismatch("Can only calculate diversity of a single community")) - powermean(getordinariness!(meta), qs - 1, getabundance(meta))[1] .^ -1 + powermean(getordinariness!(meta), qs .- 1, getabundance(meta))[1] .^ -1 end function qDZ(proportions::V, qs, diff --git a/src/GeneralisedDiversities.jl b/src/GeneralisedDiversities.jl index 08e39b76..726d01ee 100644 --- a/src/GeneralisedDiversities.jl +++ b/src/GeneralisedDiversities.jl @@ -1,4 +1,4 @@ -using Diversity.API.AbstractMetacommunity +using Diversity.API: AbstractMetacommunity using Diversity.ShortNames function norm_sub_alpha(meta::AbstractMetacommunity, qs) diff --git a/src/Hill.jl b/src/Hill.jl index 6550735d..0f6a4d10 100644 --- a/src/Hill.jl +++ b/src/Hill.jl @@ -10,7 +10,7 @@ population(s) with given relative proportions - `proportions`: relative proportions of different individuals / species in population (vector, or matrix where columns are - individual populations) + individual populations) - `qs`: single number or vector of orders of diversity measurement @@ -21,5 +21,6 @@ population(s) with given relative proportions function hillnumber(proportions, qs) hill = subdiv(NormalisedAlpha(Metacommunity(proportions)), qs) hill[:measure] = "HillNumber" + delete!(hill, :div_type) return hill end diff --git a/src/Interface.jl b/src/Interface.jl index 24eb0d07..a85101a2 100644 --- a/src/Interface.jl +++ b/src/Interface.jl @@ -74,6 +74,39 @@ function gettypenames(t::AbstractTypes, raw::Bool = false) return _gettypenames(t, raw) end +""" + getdiversityname(m::AbstractMetacommunity) + getdiversityname(t::AbstractTypes) + +Returns the name of the diversity type used. +""" +function getdiversityname end + +getdiversityname(t::AbstractTypes) = getdiversityname(t) +getdiversityname(m::AbstractMetacommunity) = _getdiversityname(_gettypes(m)) + +""" + addedoutputcols(m::AbstractMetacommunity) + addedoutputcols(t::AbstractTypes) + +Returns the name of any additional columns needed to disambiguate the +diversity type used. +""" +function addedoutputcols end + +addedoutputcols(t::AbstractTypes) = _addedoutputcols(t) +addedoutputcols(m::AbstractMetacommunity) = addedoutputcols(_gettypes(m)) + +""" + getaddedoutput(::AbstractTypes) + +Returns the contents of any additional columns to be added to outputs. +""" +function getaddedoutput end + +getaddedoutput(t::AbstractTypes) = _getaddedoutput(t) +getaddedoutput(m::AbstractMetacommunity) = _getaddedoutput(_gettypes(m)) + """ getsubcommunitynames(m::AbstractMetacommunity) getsubcommunitynames(p::AbstractPartition) diff --git a/src/Iterators.jl b/src/Iterators.jl index 668452ec..5f135a49 100644 --- a/src/Iterators.jl +++ b/src/Iterators.jl @@ -1,7 +1,6 @@ using Compat using Diversity.API -import Base.start, Base.next, Base.done import Compat.IteratorSize, Base.length, Compat.IteratorEltype, Base.eltype abstract type AbstractIterator{M <: AbstractMetacommunity} end @@ -27,6 +26,8 @@ function TypeIterator(meta::M) where M <: AbstractMetacommunity return TypeIterator(getabundance, meta) end +if VERSION < v"0.7.0-" +import Base.start, Base.next, Base.done function start(ti::TypeIterator) return 1 end @@ -39,6 +40,17 @@ function done(ti::TypeIterator, state) return state > counttypes(ti.metacommunity) end +else +import Base.iterate +function iterate(ti::TypeIterator, state = 1) + if state > counttypes(ti.metacommunity) + return nothing + end + return ti.viewfn(ti.metacommunity, state), state + 1 +end + +end + function IteratorSize(ti::Type{TypeIterator}) return HasLength() end @@ -78,6 +90,7 @@ function SubcommunityIterator(meta::M) where M <: AbstractMetacommunity return SubcommunityIterator(getabundance, meta) end +if VERSION < v"0.7.0-" function start(si::SubcommunityIterator) return 1 end @@ -90,6 +103,18 @@ function done(si::SubcommunityIterator, state) return state > countsubcommunities(si.metacommunity) end +else + +function iterate(si::SubcommunityIterator, state = 1) + if state > countsubcommunities(si.metacommunity) + return nothing + end + return si.viewfn(si.metacommunity, state), state + 1 +end + +end + + function IteratorSize(si::Type{SubcommunityIterator}) return HasLength() end diff --git a/src/Jost.jl b/src/Jost.jl index fa27f775..e5b6b688 100644 --- a/src/Jost.jl +++ b/src/Jost.jl @@ -22,8 +22,9 @@ divided by the naive-community beta diversity. """ function jostalpha(proportions::AbstractMatrix, qs) md = metacommunityDiversity(RawAlpha(Metacommunity(proportions)), qs) - md[:diversity] = md[:diversity] ./ qD(reshape(mapslices(sum, proportions, (1,)), - size(proportions)[2]), qs) + md[:diversity] = md[:diversity] ./ + qD(reshape(mapslices(sum, proportions, dims=(1,)), + size(proportions)[2]), qs) md[:measure] = "JostAlpha" return md end @@ -51,7 +52,8 @@ Jost's alpha diversity function jostbeta(proportions::AbstractMatrix, qs) md = metacommunityDiversity(Gamma(Metacommunity(proportions)), qs) ja = jostalpha(proportions, qs) - j = join(md, ja, on=[:q, :type_level, :type_name, :partition_level, :partition_name], + j = join(md, ja, on=[:q, :type_level, :type_name, + :partition_level, :partition_name, :div_type], makeunique=true) j[:diversity] = j[:diversity] ./ j[:diversity_1] j[:measure] = "JostBeta" diff --git a/src/Metacommunity.jl b/src/Metacommunity.jl index e8a20ee0..df67cc31 100644 --- a/src/Metacommunity.jl +++ b/src/Metacommunity.jl @@ -153,7 +153,7 @@ function _getordinariness!(meta::Metacommunity) if ismissing(meta.ordinariness) meta.ordinariness = _calcordinariness(meta.types, meta.processedabundances, meta.scale) end - meta.ordinariness + return meta.ordinariness end import Diversity.API._getscale diff --git a/src/Phylogenetics.jl b/src/Phylogenetics.jl index 18458313..2bc3ac78 100644 --- a/src/Phylogenetics.jl +++ b/src/Phylogenetics.jl @@ -1,7 +1,8 @@ -using Phylo +using .Phylo using Diversity +using Diversity.API +using Compat.Statistics -import Diversity.Phylogenetics: PhyloTypes struct PhyloTypes{Tree <: AbstractTree} <: Diversity.API.AbstractTypes tree::Tree nleaf::Int64 @@ -10,78 +11,100 @@ struct PhyloTypes{Tree <: AbstractTree} <: Diversity.API.AbstractTypes ancestralnames::Vector{String} ancestralmatrix::Matrix{Float64} Zmatrix::Matrix{Float64} +end - function PhyloTypes(tree::Tree) where Tree <: AbstractTree - leafnames = getleafnames(tree) - nleaf = length(leafnames) - nleaf > 0 || error("Too few species") - leafinfo = Dict{String, Float64}() - speciesinfo = Dict{String, Tuple{String, String, Float64}}() - for leaf in leafnames - branches = branchhistory(tree, leaf) - leafinfo["$leaf"] = heighttoroot(tree, leaf) - for branch in branches - name = "$leaf : $branch" - speciesinfo[name] = tuple("$leaf", "$branch", - getlength(tree, branch) / leafinfo["$leaf"]) - end +function PhyloTypes(tree::Tree) where Tree <: AbstractTree + leafnames = getleafnames(tree) + nleaf = length(leafnames) + nleaf > 0 || error("Too few species") + leafinfo = Dict{String, Float64}() + speciesinfo = Dict{String, Tuple{String, String, Float64}}() + for leaf in leafnames + branches = branchhistory(tree, leaf) + leafinfo["$leaf"] = heighttoroot(tree, leaf) + for branch in branches + name = "$leaf : $branch" + speciesinfo[name] = tuple("$leaf", "$branch", + getlength(tree, branch) / leafinfo["$leaf"]) end - ancestralnames = collect(keys(speciesinfo)) - nancestral = length(ancestralnames) - Lbar = mean(values(leafinfo)) - ancestralmatrix = Matrix{Float64}(nancestral, nleaf) - fill!(ancestralmatrix, 0) - for i in 1:nancestral - for j in 1:nleaf - if speciesinfo[ancestralnames[i]][1] == leafnames[j] - ancestralmatrix[i, j] = - speciesinfo[ancestralnames[i]][3] * leafinfo[leafnames[j]] - end + end + ancestralnames = collect(keys(speciesinfo)) + nancestral = length(ancestralnames) + Lbar = Compat.Statistics.mean(collect(values(leafinfo))) + ancestralmatrix = fill(zero(Float64), (nancestral, nleaf)) + for i in 1:nancestral + for j in 1:nleaf + if speciesinfo[ancestralnames[i]][1] == leafnames[j] + ancestralmatrix[i, j] = + speciesinfo[ancestralnames[i]][3] * leafinfo[leafnames[j]] end end - Zmatrix = Matrix{Float64}(nancestral, nancestral) - fill!(Zmatrix, 0) - for i in 1:nancestral - for j in 1:nancestral - if haskey(speciesinfo, - "$(speciesinfo[ancestralnames[j]][1]) : " * - "$(speciesinfo[ancestralnames[i]][2])") - Zmatrix[i, j] = 1.0 / - leafinfo[speciesinfo[ancestralnames[j]][1]] - end + end + Zmatrix = fill(zero(Float64), (nancestral, nancestral)) + fill!(Zmatrix, 0) + for i in 1:nancestral + for j in 1:nancestral + if haskey(speciesinfo, + "$(speciesinfo[ancestralnames[j]][1]) : " * + "$(speciesinfo[ancestralnames[i]][2])") + Zmatrix[i, j] = 1.0 / + leafinfo[speciesinfo[ancestralnames[j]][1]] end end - new{Tree}(tree, nleaf, nancestral, leafnames, ancestralnames, - ancestralmatrix, Zmatrix) end + return PhyloTypes{Tree}(tree, nleaf, nancestral, + leafnames, ancestralnames, + ancestralmatrix, Zmatrix) end -import Diversity.API._gettypenames -function _gettypenames(phy::PhyloTypes, raw::Bool) +function PhyloTypes(treeset::TS) where TS <: TreeSet + ntrees(treeset) == 1 || + error("Can currently only handle one tree in a PhyloSet") + pt = PhyloTypes(first(treeset)) + return PhyloTypes{TS}(treeset, pt.nleaf, pt.nancestral, + pt.leafnames, pt.ancestralnames, + pt.ancestralmatrix, pt.Zmatrix) +end + +import Diversity.API: _gettypenames +function _gettypenames(phy::Diversity.PhyloTypes, raw::Bool) return raw ? phy.leafnames : phy.ancestralnames end -import Diversity.API._counttypes -function _counttypes(phy::PhyloTypes, raw::Bool) +import Diversity.API: _counttypes +function _counttypes(phy::Diversity.PhyloTypes, raw::Bool) return raw ? phy.nleaf : phy.nancestral end -import Diversity.API._calcabundance -function _calcabundance(phy::PhyloTypes, raw::M) where {FP <: AbstractFloat, - M <: AbstractMatrix{FP}} +import Diversity.API: _calcabundance +function _calcabundance(phy::Diversity.PhyloTypes, raw::M) where + {M <: AbstractMatrix{<:AbstractFloat}} processed = phy.ancestralmatrix * raw scale = sum(processed) processed ./= scale return processed, scale end -import Diversity.API._calcsimilarity -function _calcsimilarity(phy::PhyloTypes, scale::R) where R <: Real +import Diversity.API: _calcsimilarity +function _calcsimilarity(phy::Diversity.PhyloTypes, scale::R) where R <: Real return phy.Zmatrix .* scale end -import Diversity.API._calcordinariness -function _calcordinariness(phy::PhyloTypes, processed::M, scale::R) where +import Diversity.API: _calcordinariness +function _calcordinariness(phy::Diversity.PhyloTypes, processed::M, scale::R) where {FP <: AbstractFloat, M <: AbstractMatrix{FP}, R <: Real} return (phy.Zmatrix * processed) .* scale end + +import Diversity.API: _getdiversityname +_getdiversityname(::Diversity.PhyloTypes) = "Phylogenetic" + +import Diversity.API: _addedoutputcols +_addedoutputcols(::Diversity.PhyloTypes{TS}) where + {LABEL, NL, BL, TS <: TreeSet{LABEL, NL, BL, <: AbstractTree}} = + Dict{Symbol, Type}(:treename => LABEL) + +import Diversity.API: _getaddedoutput +_getaddedoutput(pt::Diversity.PhyloTypes{TS}) where + {LABEL, NL, BL, TS <: TreeSet{LABEL, NL, BL, <: AbstractTree}} = + Dict{Symbol, LABEL}(:treename => first(treenameiter(pt.tree))) diff --git a/src/Types.jl b/src/Types.jl index f21cfa0d..71002505 100644 --- a/src/Types.jl +++ b/src/Types.jl @@ -1,5 +1,6 @@ using DataFrames -using Compat: @warn +using Compat: @warn, DomainError +using Compat.LinearAlgebra """ UniqueTypes @@ -38,7 +39,7 @@ end import Diversity.API._calcsimilarity function _calcsimilarity(ut::UniqueTypes, ::Real) - return eye(ut.num) + return Matrix(1.0I, ut.num, ut.num) end import Diversity.API._calcordinariness @@ -46,6 +47,9 @@ function _calcordinariness(::UniqueTypes, abundances::AbstractArray, ::Real) return abundances end +import Diversity.API._getdiversityname +_getdiversityname(::UniqueTypes) = "Unique" + """ Species @@ -67,13 +71,13 @@ struct Taxonomy{FP <: AbstractFloat} <: Diversity.API.AbstractTypes speciesinfo::DataFrame taxa::Dict{Symbol, FP} typelabel::Symbol - + function Taxonomy{FP}(speciesinfo::DataFrame, taxa::Dict{Symbol, FP}, typelabel::Symbol) where FP <: AbstractFloat - sort(speciesinfo.colindex.names) == sort([keys(taxa)...]) || + sort(describe(speciesinfo)[:variable]) == sort([keys(taxa)...]) || error("Taxon labels do not match similarity values") - typelabel ∈ speciesinfo.colindex.names || + typelabel ∈ describe(speciesinfo)[:variable] || error("$typelabel not found in DataFrame column names") new{FP}(speciesinfo, taxa, typelabel) end @@ -101,6 +105,8 @@ function _calcsimilarity(::Taxonomy, ::Real) error("Can't generate a taxonomic similarity matrix yet") end +_getdiversityname(::Taxonomy) = "Taxonomy" + """ GeneralTypes{FP, M} @@ -140,7 +146,8 @@ struct GeneralTypes{FP <: AbstractFloat, size(zmatrix, 1) == size(zmatrix, 2) || throw(DimensionMismatch("Similarity matrix is not square")) - minimum(zmatrix) ≥ 0 || throw(DomainError()) + minimum(zmatrix) ≥ 0 || throw(DomainError(minimum(zmatrix), + "Similarities must be ≥ 0")) maximum(zmatrix) ≤ 1 || @warn "Similarity matrix has values above 1" new{FP, M}(zmatrix, map(x -> "$x", 1:size(zmatrix, 1))) @@ -151,7 +158,8 @@ struct GeneralTypes{FP <: AbstractFloat, size(zmatrix, 1) == size(zmatrix, 2) || throw(DimensionMismatch("Similarity matrix is not square")) - minimum(zmatrix) ≥ 0 || throw(DomainError()) + minimum(zmatrix) ≥ 0 || throw(DomainError(minimum(zmatrix), + "Similarities must be ≥ 0")) maximum(zmatrix) ≤ 1 || @warn "Similarity matrix has values above 1" length(names) == size(zmatrix, 1) || @@ -177,3 +185,5 @@ end function _calcsimilarity(gt::GeneralTypes, ::Real) return gt.z end + +_getdiversityname(::GeneralTypes) = "Arbitrary Z" diff --git a/test/REQUIRE b/test/REQUIRE index 507a79b8..99d464cd 100644 --- a/test/REQUIRE +++ b/test/REQUIRE @@ -1,4 +1,4 @@ Distances 0.3.2 StatsBase 0.10.0 -RCall 0.10.0 -Phylo 0.2.0 +RCall +Phylo 0.3.1 diff --git a/test/pkg_Distances.jl b/test/pkg_Distances.jl index 633036aa..d2921f0f 100644 --- a/test/pkg_Distances.jl +++ b/test/pkg_Distances.jl @@ -1,5 +1,7 @@ module ValidateDistances using Compat.Test +using Compat +using Compat.Statistics using Diversity using Diversity.ShortNames @@ -12,7 +14,12 @@ using Distances pops = rand(types, sc) # Make sure not to remove all of the non-zeros from any column for j in 1:sc - pops[pops[:, j] .< median(pops[:, j])/2, j] = 0.0 + vals = pops[:, j] .< Compat.Statistics.median(pops[:, j])/2 + for k in 1:types + if vals[k] + pops[k, j] = 0.0 + end + end end pops /= sum(pops) meta = Metacommunity(pops) diff --git a/test/pkg_RCall.jl b/test/pkg_RCall.jl index d588286d..bb40d998 100644 --- a/test/pkg_RCall.jl +++ b/test/pkg_RCall.jl @@ -1,310 +1,26 @@ -module ValidateRCall_rcall -macro R_str(script) - script -end -macro rput(script) - script -end -macro rget(script) - script -end -export @R_str, @rput, @rget -end - -module ValidateRCall_rdiversity -using Compat.Test +module ValidateRCall using Compat: @warn -using Diversity -using Diversity.ShortNames -using Diversity.Phylogenetics -using DataFrames -using Phylo - # Environment variable to avoid boring R package builds mustCrossvalidate = haskey(ENV, "JULIA_MUST_CROSSVALIDATE") && ENV["JULIA_MUST_CROSSVALIDATE"] == "1" # Only run R on unix or when R is installed because JULIA_MUST_CROSSVALIDATE is set to 1 -skipR = !mustCrossvalidate && !is_unix() -Rinstalled = false +global skipR = !mustCrossvalidate && + !((VERSION < v"0.7.0-" && is_unix()) || + (VERSION >= v"0.7.0-" && Sys.isunix())) try skipR && error("Skipping R testing...") using RCall - # Pkg.dir("Phylo") doesn't guarantee to give the correct directory for the package, - # but nor does anything else insanely! Skips cross-validation on failure. - include(joinpath(dirname(dirname(dirname(@__FILE__))), "Phylo", "src", "rcall.jl")) - Rinstalled = true + global skipR = false catch - if mustCrossvalidate + global skipR = true + if mustCrossvalidate && VERSION < v"0.7.0-" error("R not installed, but JULIA_MUST_CROSSVALIDATE is set") else @warn "R or appropriate Phylo package not installed, skipping R cross-validation." end - using ValidateRCall_rcall end -if Rinstalled - # Create a temporary directory to work in - libdir = mktempdir(); - - if !skipR && !rcopy(R"require(ape)") - rcall(Symbol(".libPaths"), libdir); - reval("install.packages(\"ape\", lib=\"$libdir\", " * - "repos=\"http://cran.r-project.org\")"); - skipR = !rcopy(R"require(ape, lib.loc=c(\"$libdir\", .libPaths()))") && - !mustCrossvalidate; - skipR && @warn "ape R package not installed and would not install, " * - "skipping R crossvalidation" - end - - if !skipR && !rcopy(R"require(rdiversity)") - rcall(Symbol(".libPaths"), libdir); - reval("install.packages(\"rdiversity\", lib=\"$libdir\", " * - "repos=\"http://cran.r-project.org\")"); - skipR = !rcopy(R"require(rdiversity, lib.loc=c(\"$libdir\", .libPaths()))") && - !mustCrossvalidate; - skipR && @warn "rdiversity R package not installed and would not install, " * - "skipping R crossvalidation" - end - - if !skipR - # Run diversity comparisons on increasing numbers of types and subcommunities - @testset "RCall - testing boydorr/rdiversity" begin - @testset "Random rdiversity $i" for i in 1:20 - types = rand(2:(i*10)) - sc = rand(2:(i*10)) - pops = rand(types, sc) - Zasym = rand(types, types) - Zsym = Zasym/2 + Zasym'/2 - for j in 1:types - Zsym[j, j] = 1.0 - end - Zsym[Zsym .< median(Zsym)] = 0.0 - # Make sure not to remove all of the non-zeros from any column - for j in 1:sc - pops[pops[:, j] .< median(pops[:, j])/2, j] = 0.0 - end - pops /= sum(pops) - qs = sort([rand(7)*10..., 0, 1, Inf]) - names = ["symmetric", "asymmetric"] - Zs = [Zsym, Zasym] - @testset "Z matrix - $(names[k])" for k in 1:length(Zs) - Z = Zs[k] - meta = Metacommunity(pops, Z) - diversities = Dict(:raw_alpha => α(meta), - :norm_alpha => ᾱ(meta), - :raw_beta => β(meta), - :norm_beta => β̄(meta), - :raw_rho => ρ(meta), - :norm_rho => ρ̄(meta), - :raw_gamma => Γ(meta)); - # Create the metacommunity in R - r_meta = rcall(:metacommunity, pops, Z) - - for (r_func, juliadiv) in diversities - r_div = rcall(r_func, r_meta); - # Check the metacommunity diversity - @test metadiv(juliadiv, qs)[:diversity] ≈ - rcopy(rcall(:metadiv, r_div, qs)[:diversity]) - # and subcommunity diversity - @test subdiv(juliadiv, qs)[:diversity] ≈ - rcopy(rcall(:subdiv, r_div, qs)[:diversity]) - end - end - end - - @testset "Trying out empty types and subcommunities" begin - types = 10 - sc = 10 - pops = rand(types, sc) - Zasym = rand(types, types) - Z = Zasym/2 + Zasym'/2 - for j in 1:types - Z[j, j] = 1.0 - end - Z[Z .< median(Z)] = 0.0 - # Make sure not to remove all of the non-zeros from any column - for j in 1:sc - pops[pops[:, j] .< median(pops[:, j])/2, j] = 0.0 - end - qs = sort([rand(7)*10..., 0, 1, Inf]) - - # Check they match when there's an empty type - pops[rand(1:types), :] = 0 - pops /= sum(pops) - meta = Metacommunity(pops, Z) - diversities = Dict(:raw_alpha => α(meta), - :norm_alpha => ᾱ(meta), - :raw_beta => β(meta), - :norm_beta => β̄(meta), - :raw_rho => ρ(meta), - :norm_rho => ρ̄(meta), - :raw_gamma => Γ(meta)); - # Create the metacommunity in R - r_meta = rcall(:metacommunity, pops, Z) - - for (r_func, juliadiv) in diversities - r_div = rcall(r_func, r_meta); - # Check the metacommunity diversity - jmd = metadiv(juliadiv, qs); - rmd = rcall(:metadiv, r_div, qs); - @test Set(map(string, names(jmd))) == - Set(rcopy(rcall(:colnames, rmd))) - @test jmd[:diversity] ≈ rcopy(rmd[:diversity]) - # and subcommunity diversity - @test subdiv(juliadiv, qs)[:diversity] ≈ - rcopy(rcall(:subdiv, r_div, qs)[:diversity]) - end - - # Check they match when there's an empty subcommunity too - pops[:, rand(1:sc)] = 0 - pops /= sum(pops) - meta = Metacommunity(pops, Z) - diversities = Dict(:raw_alpha => α(meta), - :norm_alpha => ᾱ(meta), - :raw_beta => β(meta), - :norm_beta => β̄(meta), - :raw_rho => ρ(meta), - :norm_rho => ρ̄(meta), - :raw_gamma => Γ(meta)); - # Create the metacommunity in R - r_meta = rcall(:metacommunity, pops, Z) - - for (r_func, juliadiv) in diversities - r_div = rcall(r_func, r_meta); - # Check out metacommunity diversity - @test metadiv(juliadiv, qs)[:diversity] ≈ - rcopy(rcall(:metadiv, r_div, qs)[:diversity]) - # and subcommunity diversity - sdj = subdiv(juliadiv, qs)[:diversity] - sdr = rcopy(rcall(:subdiv, r_div, qs)[:diversity]) - for (r, j) in zip(sdr, sdj) - @test isnan(j) == isnan(r) && (isnan(j) || j ≈ r) - end - end - end - end - - # Run phylogenetic comparisons - @testset "RCall - testing .Phylogenetics with boydorr/rdiversity" begin - @testset "Random phylogeny $i" for i in 1:10 - types = rand(2:(i*5)) - nu = Nonultrametric(types) - tree = rand(nu) - sc = rand(2:(i*10)) - pops = rand(types, sc) - for j in 1:sc - pops[pops[:, j] .< median(pops[:, j])/2, j] = 0.0 - end - pops /= sum(pops) - qs = sort([rand(7)*10..., 0, 1, Inf]) - meta = Metacommunity(pops, PhyloTypes(tree)) - diversities = Dict(:raw_alpha => α(meta), - :norm_alpha => ᾱ(meta), - :raw_beta => β(meta), - :norm_beta => β̄(meta), - :raw_rho => ρ(meta), - :norm_rho => ρ̄(meta), - :raw_gamma => Γ(meta)); - # Create the metacommunity in R - @rput pops - @rput tree - tipnames = getleafnames(tree) - @rput tipnames - r_meta = R""" - rownames(pops) <- tipnames - metacommunity(pops, tree) - """ - - for (r_func, juliadiv) in diversities - r_div = rcall(r_func, r_meta); - # Check the metacommunity diversity - @test metadiv(juliadiv, qs)[:diversity] ≈ - rcopy(rcall(:metadiv, r_div, qs)[:diversity]) - # and subcommunity diversity - @test subdiv(juliadiv, qs)[:diversity] ≈ - rcopy(rcall(:subdiv, r_div, qs)[:diversity]) - end - end - - @testset "Trying out empty types and subcommunities" begin - types = 10 - nu = Nonultrametric(types) - tree = rand(nu) - sc = 10 - pops = rand(types, sc) - qs = sort([rand(7)*10..., 0, 1, Inf]) - - # Check they match when there's an empty type - pops[rand(1:types), :] = 0 - pops /= sum(pops) - meta = Metacommunity(pops, PhyloTypes(tree)) - diversities = Dict(:raw_alpha => α(meta), - :norm_alpha => ᾱ(meta), - :raw_beta => β(meta), - :norm_beta => β̄(meta), - :raw_rho => ρ(meta), - :norm_rho => ρ̄(meta), - :raw_gamma => Γ(meta)); - # Create the metacommunity in R - @rput pops - @rput tree - tipnames = getleafnames(tree) - @rput tipnames - r_meta = R""" - rownames(pops) <- tipnames - r_meta <- metacommunity(pops, tree) - """ - - for (r_func, juliadiv) in diversities - r_div = rcall(r_func, r_meta); - # Check the metacommunity diversity - jmd = metadiv(juliadiv, qs); - rmd = rcall(:metadiv, r_div, qs); - @test Set(map(string, names(jmd))) == - Set(rcopy(rcall(:colnames, rmd))) - @test jmd[:diversity] ≈ rcopy(rmd[:diversity]) - # and subcommunity diversity - @test subdiv(juliadiv, qs)[:diversity] ≈ - rcopy(rcall(:subdiv, r_div, qs)[:diversity]) - end - - # Check they match when there's an empty subcommunity too - pops[:, rand(1:sc)] = 0 - pops /= sum(pops) - meta = Metacommunity(pops, PhyloTypes(tree)) - diversities = Dict(:raw_alpha => α(meta), - :norm_alpha => ᾱ(meta), - :raw_beta => β(meta), - :norm_beta => β̄(meta), - :raw_rho => ρ(meta), - :norm_rho => ρ̄(meta), - :raw_gamma => Γ(meta)); - # Create the metacommunity in R - @rput pops - @rput tree - tipnames = getleafnames(tree) - @rput tipnames - r_meta = R""" - rownames(pops) <- tipnames - metacommunity(pops, tree) - """ - for (r_func, juliadiv) in diversities - r_div = rcall(r_func, r_meta); - # Check out metacommunity diversity - @test metadiv(juliadiv, qs)[:diversity] ≈ - rcopy(rcall(:metadiv, r_div, qs)[:diversity]) - # and subcommunity diversity - sdj = subdiv(juliadiv, qs)[:diversity] - sdr = rcopy(rcall(:subdiv, r_div, qs)[:diversity]) - for (r, j) in zip(sdr, sdj) - @test isnan(j) == isnan(r) && (isnan(j) || j ≈ r) - end - end - end - end - end - rm(libdir, force=true, recursive=true); -end +!skipR && include("run_rcall.jl") end diff --git a/test/pkg_StatsBase.jl b/test/pkg_StatsBase.jl index 338f0329..87b73ff3 100644 --- a/test/pkg_StatsBase.jl +++ b/test/pkg_StatsBase.jl @@ -1,5 +1,7 @@ module ValidateEntropies using Compat.Test +using Compat +using Compat.Statistics using Diversity using Diversity.ShortNames @@ -9,8 +11,8 @@ using StatsBase @testset "Random renyientropy $i" for i in 1:20 types = rand(1:(i*10)) pop = rand(types) - pop[pop .< median(pop)/2] = 0.0 - pop /= sum(pop) + pop[pop .< Compat.Statistics.median(pop)/2] .= 0.0 + pop ./= sum(pop) meta = Metacommunity(pop) g = Γ(meta) na = ᾱ(meta) diff --git a/test/run_rcall.jl b/test/run_rcall.jl new file mode 100644 index 00000000..5bceb4dd --- /dev/null +++ b/test/run_rcall.jl @@ -0,0 +1,283 @@ +module ValidateRCall_rdiversity +using Compat.Test +using Compat: @warn +using Compat +using Compat.Statistics + +using Diversity +using Diversity.ShortNames +using DataFrames +using Phylo +using RCall + +# Create a temporary directory to work in +libdir = mktempdir(); + +global skipR = false +if !skipR && !rcopy(R"require(ape)") + rcall(Symbol(".libPaths"), libdir); + reval("install.packages(\"ape\", lib=\"$libdir\", " * + "repos=\"http://cran.r-project.org\")"); + global skipR = !rcopy(R"require(ape, lib.loc=c(\"$libdir\", .libPaths()))") && + !mustCrossvalidate; + skipR && @warn "ape R package not installed and would not install, " * + "skipping R crossvalidation" +end + +if !skipR && !rcopy(R"require(rdiversity)") + rcall(Symbol(".libPaths"), libdir); + reval("install.packages(\"rdiversity\", lib=\"$libdir\", " * + "repos=\"http://cran.r-project.org\")"); + global skipR = !rcopy(R"require(rdiversity, lib.loc=c(\"$libdir\", .libPaths()))") && + !mustCrossvalidate; + skipR && @warn "rdiversity R package not installed and would not install, " * + "skipping R crossvalidation" +end + +if !skipR + # Run diversity comparisons on increasing numbers of types and subcommunities + @testset "RCall - testing boydorr/rdiversity" begin + @testset "Random rdiversity $i" for i in 1:20 + types = rand(2:(i*10)) + sc = rand(2:(i*10)) + pops = rand(types, sc) + Zasym = rand(types, types) + Zsym = Zasym/2 .+ Zasym'/2 + for j in 1:types + Zsym[j, j] = 1.0 + end + Zsym[Zsym .< Compat.Statistics.median(Zsym)] .= 0.0 + # Make sure not to remove all of the non-zeros from any column + for j in 1:sc + pops[pops[:, j] .< Compat.Statistics.median(pops[:, j])/2, j] .= 0.0 + end + pops /= sum(pops) + qs = sort([rand(7)*10..., 0, 1, Inf]) + names = ["symmetric", "asymmetric"] + Zs = [Zsym, Zasym] + @testset "Z matrix - $(names[k])" for k in 1:length(Zs) + Z = Zs[k] + meta = Metacommunity(pops, Z) + diversities = Dict(:raw_alpha => α(meta), + :norm_alpha => ᾱ(meta), + :raw_beta => β(meta), + :norm_beta => β̄(meta), + :raw_rho => ρ(meta), + :norm_rho => ρ̄(meta), + :raw_gamma => Γ(meta)); + # Create the metacommunity in R + r_meta = rcall(:metacommunity, pops, Z) + + for (r_func, juliadiv) in diversities + r_div = rcall(r_func, r_meta); + # Check the metacommunity diversity + @test metadiv(juliadiv, qs)[:diversity] ≈ + rcopy(rcall(:metadiv, r_div, qs)[:diversity]) + # and subcommunity diversity + @test subdiv(juliadiv, qs)[:diversity] ≈ + rcopy(rcall(:subdiv, r_div, qs)[:diversity]) + end + end + end + + @testset "Trying out empty types and subcommunities" begin + types = 10 + sc = 10 + pops = rand(types, sc) + Zasym = rand(types, types) + Z = Zasym/2 + Zasym'/2 + for j in 1:types + Z[j, j] = 1.0 + end + Z[Z .< Compat.Statistics.median(Z)] .= 0.0 + # Make sure not to remove all of the non-zeros from any column + for j in 1:sc + vals = pops[:, j] .< Compat.Statistics.median(pops[:, j])/2 + for k in 1:types + if vals[k] + pops[k, j] = 0.0 + end + end + end + qs = sort([rand(7)*10..., 0, 1, Inf]) + + # Check they match when there's an empty type + pops[rand(1:types), :] .= 0 + pops /= sum(pops) + meta = Metacommunity(pops, Z) + diversities = Dict(:raw_alpha => α(meta), + :norm_alpha => ᾱ(meta), + :raw_beta => β(meta), + :norm_beta => β̄(meta), + :raw_rho => ρ(meta), + :norm_rho => ρ̄(meta), + :raw_gamma => Γ(meta)); + # Create the metacommunity in R + r_meta = rcall(:metacommunity, pops, Z) + + for (r_func, juliadiv) in diversities + r_div = rcall(r_func, r_meta); + # Check the metacommunity diversity + jmd = metadiv(juliadiv, qs); + rmd = rcall(:metadiv, r_div, qs); + @test Set(rcopy(rcall(:colnames, rmd))) ⊆ + Set(map(string, names(jmd))) + + @test jmd[:diversity] ≈ rcopy(rmd[:diversity]) + # and subcommunity diversity + @test subdiv(juliadiv, qs)[:diversity] ≈ + rcopy(rcall(:subdiv, r_div, qs)[:diversity]) + end + + # Check they match when there's an empty subcommunity too + pops[:, rand(1:sc)] .= 0 + pops /= sum(pops) + meta = Metacommunity(pops, Z) + diversities = Dict(:raw_alpha => α(meta), + :norm_alpha => ᾱ(meta), + :raw_beta => β(meta), + :norm_beta => β̄(meta), + :raw_rho => ρ(meta), + :norm_rho => ρ̄(meta), + :raw_gamma => Γ(meta)); + # Create the metacommunity in R + r_meta = rcall(:metacommunity, pops, Z) + + for (r_func, juliadiv) in diversities + r_div = rcall(r_func, r_meta); + # Check out metacommunity diversity + @test metadiv(juliadiv, qs)[:diversity] ≈ + rcopy(rcall(:metadiv, r_div, qs)[:diversity]) + # and subcommunity diversity + sdj = subdiv(juliadiv, qs)[:diversity] + sdr = rcopy(rcall(:subdiv, r_div, qs)[:diversity]) + for (r, j) in zip(sdr, sdj) + @test isnan(j) == isnan(r) && (isnan(j) || j ≈ r) + end + end + end + end + + # Run phylogenetic comparisons + @testset "RCall - testing Phylogenetics with boydorr/rdiversity" begin + @testset "Random phylogeny $i" for i in 1:10 + types = rand(2:(i*5)) + nu = Nonultrametric(types) + tree = rand(nu) + sc = rand(2:(i*10)) + pops = rand(types, sc) + for j in 1:sc + pops[pops[:, j] .< Compat.Statistics.median(pops[:, j])/2, j] .= 0.0 + end + pops ./= sum(pops) + qs = sort([rand(7)*10..., 0, 1, Inf]) + meta = Metacommunity(pops, PhyloTypes(tree)) + diversities = Dict(:raw_alpha => α(meta), + :norm_alpha => ᾱ(meta), + :raw_beta => β(meta), + :norm_beta => β̄(meta), + :raw_rho => ρ(meta), + :norm_rho => ρ̄(meta), + :raw_gamma => Γ(meta)); + # Create the metacommunity in R + @rput pops + @rput tree + tipnames = getleafnames(tree) + @rput tipnames + r_meta = R""" + rownames(pops) <- tipnames + metacommunity(pops, tree) + """ + + for (r_func, juliadiv) in diversities + r_div = rcall(r_func, r_meta); + # Check the metacommunity diversity + @test metadiv(juliadiv, qs)[:diversity] ≈ + rcopy(rcall(:metadiv, r_div, qs)[:diversity]) + # and subcommunity diversity + @test subdiv(juliadiv, qs)[:diversity] ≈ + rcopy(rcall(:subdiv, r_div, qs)[:diversity]) + end + end + + @testset "Trying out empty types and subcommunities" begin + types = 10 + nu = Nonultrametric(types) + tree = rand(nu) + sc = 10 + pops = rand(types, sc) + qs = sort([rand(7)*10..., 0, 1, Inf]) + + # Check they match when there's an empty type + pops[rand(1:types), :] .= 0 + pops /= sum(pops) + meta = Metacommunity(pops, PhyloTypes(tree)) + diversities = Dict(:raw_alpha => α(meta), + :norm_alpha => ᾱ(meta), + :raw_beta => β(meta), + :norm_beta => β̄(meta), + :raw_rho => ρ(meta), + :norm_rho => ρ̄(meta), + :raw_gamma => Γ(meta)); + # Create the metacommunity in R + @rput pops + @rput tree + tipnames = getleafnames(tree) + @rput tipnames + r_meta = R""" + rownames(pops) <- tipnames + r_meta <- metacommunity(pops, tree) + """ + + for (r_func, juliadiv) in diversities + r_div = rcall(r_func, r_meta); + # Check the metacommunity diversity + jmd = metadiv(juliadiv, qs); + rmd = rcall(:metadiv, r_div, qs); + @test Set(rcopy(rcall(:colnames, rmd))) ⊆ + Set(map(string, names(jmd))) + + @test jmd[:diversity] ≈ rcopy(rmd[:diversity]) + # and subcommunity diversity + @test subdiv(juliadiv, qs)[:diversity] ≈ + rcopy(rcall(:subdiv, r_div, qs)[:diversity]) + end + + # Check they match when there's an empty subcommunity too + pops[:, rand(1:sc)] .= 0 + pops ./= sum(pops) + meta = Metacommunity(pops, PhyloTypes(tree)) + diversities = Dict(:raw_alpha => α(meta), + :norm_alpha => ᾱ(meta), + :raw_beta => β(meta), + :norm_beta => β̄(meta), + :raw_rho => ρ(meta), + :norm_rho => ρ̄(meta), + :raw_gamma => Γ(meta)); + # Create the metacommunity in R + @rput pops + @rput tree + tipnames = getleafnames(tree) + @rput tipnames + r_meta = R""" + rownames(pops) <- tipnames + metacommunity(pops, tree) + """ + for (r_func, juliadiv) in diversities + r_div = rcall(r_func, r_meta); + # Check out metacommunity diversity + @test metadiv(juliadiv, qs)[:diversity] ≈ + rcopy(rcall(:metadiv, r_div, qs)[:diversity]) + # and subcommunity diversity + sdj = subdiv(juliadiv, qs)[:diversity] + sdr = rcopy(rcall(:subdiv, r_div, qs)[:diversity]) + for (r, j) in zip(sdr, sdj) + @test isnan(j) == isnan(r) && (isnan(j) || j ≈ r) + end + end + end + end +end +rm(libdir, force=true, recursive=true); + +end diff --git a/test/runtests.jl b/test/runtests.jl index d37eba93..4bc9eec5 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -5,9 +5,10 @@ using Compat: @info # - src/Source.jl will be matched by test/test_Source.jl filebase = map(file -> replace(file, r"(.*).jl" => s"\1"), - filter(file -> contains(file, r".*\.jl"), readdir("../src"))) + filter(file -> occursin(r".*\.jl", file), + readdir("../src"))) testbase = map(file -> replace(file, r"test_(.*).jl" => s"\1"), - filter(str -> contains(str, r"^test_.*\.jl$"), readdir())) + filter(str -> occursin(r"^test_.*\.jl$", str), readdir())) @info "Running tests for files:" for t in testbase @@ -47,7 +48,8 @@ end # test/pkg_Package.jl should validate results against the Package package pkgbase = map(file -> replace(file, r"pkg_(.*).jl" => s"\1"), - filter(str -> contains(str, r"^pkg_.*\.jl$"), readdir())) + filter(str -> occursin(r"^pkg_.*\.jl$", str), + readdir())) if length(pkgbase) > 0 @info "Running cross-validation against:" @@ -55,7 +57,7 @@ if length(pkgbase) > 0 println(" = $p") end println() - + @info "Running validation..." for p in pkgbase fn = "pkg_$p.jl" diff --git a/test/test_API.jl b/test/test_API.jl index 16eaf761..836bcedc 100644 --- a/test/test_API.jl +++ b/test/test_API.jl @@ -1,4 +1,4 @@ -module TestInterface +module TestAPI using Compat.Test using Diversity.API diff --git a/test/test_Diversity.jl b/test/test_Diversity.jl index 2250b966..620b28af 100644 --- a/test/test_Diversity.jl +++ b/test/test_Diversity.jl @@ -5,9 +5,6 @@ using Diversity @testset "Deprecations" begin # Only run deprecation checks on macs - if is_apple() - # No current deprecations? - end end end diff --git a/test/test_DiversityMeasure.jl b/test/test_DiversityMeasure.jl index f3798614..b0b6e128 100644 --- a/test/test_DiversityMeasure.jl +++ b/test/test_DiversityMeasure.jl @@ -1,5 +1,7 @@ module TestDiversityMeasure using Compat.Test +using Compat.LinearAlgebra +using Compat using Diversity using Diversity.ShortNames @@ -47,8 +49,8 @@ weights /= sum(weights); Z1 = ones(typeof(weights[1]), (length(weights), length(weights))); numcommunities = 8; manyweights = rand(numspecies, numcommunities); -manyweights *= diagm(reshape(mapslices(v -> 1. / sum(v), manyweights, 1), - (numcommunities))); +manyweights *= Diagonal(reshape(mapslices(v -> 1. / sum(v), manyweights; + dims=1), numcommunities)); @testset "inddiv / subdiv / metadiv" begin @test individualDiversity(nab, 0)[:diversity] ≈ inddiv(nab, 0)[:diversity] @@ -78,8 +80,8 @@ manyweights *= diagm(reshape(mapslices(v -> 1. / sum(v), manyweights, 1), @test nrow(sna) == length(qs) * size(communities, 2) for q in qs @test sna[isapprox.(sna[:q], q), :diversity] ≈ ones(size(communities, 2)) - end - @test subdiv(RawAlpha(Metacommunity(communities)), 0)[:diversity] ≈ numspecies * vec(mapslices(v -> 1. / sum(v), communities, 1)) + end + @test subdiv(RawAlpha(Metacommunity(communities)), 0)[:diversity] ≈ numspecies * vec(mapslices(v -> 1. / sum(v), communities; dims=1)) even = ones((numspecies, numcommunities)) / (numspecies * numcommunities); qs = [0, 1, 2, 3, 4, 5, 6, Inf]; @@ -88,7 +90,8 @@ manyweights *= diagm(reshape(mapslices(v -> 1. / sum(v), manyweights, 1), md2 = metadiv(meta2, Inf) @test md2[md2[:measure] .== "Gamma", :diversity] ≈ metadiv(Gamma(meta2), Inf)[:diversity] - probs = reshape(mapslices(sum, communities, 2), (size(communities, 1))); + probs = reshape(mapslices(sum, communities; dims=2), + size(communities, 1)); @test metadiv(Gamma(Metacommunity(communities)), qs)[:diversity] ≈ qD(probs, qs) @test metadiv(Gamma(Metacommunity(communities, Z1)), qs)[:diversity] ≈ qDZ(probs, qs, Z1) @@ -98,7 +101,7 @@ manyweights *= diagm(reshape(mapslices(v -> 1. / sum(v), manyweights, 1), colweights = rand(numcommunities) colweights /= sum(colweights) allthesame = probs * colweights' - @test metadiv(RawBeta(Metacommunity(allthesame, Z)), qs)[:diversity] ≈ 1.0 ./ qD(colweights, 2 - qs) + @test metadiv(RawBeta(Metacommunity(allthesame, Z)), qs)[:diversity] ≈ 1.0 ./ qD(colweights, 2 .- qs) @test metadiv(NormalisedBeta(Metacommunity(allthesame, Z)), qs)[:diversity] ≈ ones(length(qs)) @test metadiv(NormalisedRho(Metacommunity(allthesame, Z)), qs)[:diversity] ≈ ones(length(qs)) @test metadiv(RawRho(Metacommunity(allthesame, Z)), qs)[:diversity] ≈ qD(colweights, qs) @@ -112,10 +115,11 @@ manyweights *= diagm(reshape(mapslices(v -> 1. / sum(v), manyweights, 1), @test metadiv(RawRho(Metacommunity(distinct)), qs)[:diversity] ≈ ones(length(qs)) subnr = subdiv(NormalisedRho(Metacommunity(distinct)), qs) for q in qs - @test subnr[isapprox.(subnr[:q], q), :diversity] ≈ vec(sum(distinct, 1)) + @test subnr[isapprox.(subnr[:q], q), :diversity] ≈ + vec(Compat.sum(distinct; dims=1)) end @test metadiv(NormalisedBeta(Metacommunity(distinct)), qs)[:diversity] ≈ - qD(reshape(sum(distinct, 1), numcommunities), qs) + qD(reshape(Compat.sum(distinct; dims=1), numcommunities), qs) @test metadiv(RawBeta(Metacommunity(distinct)), qs)[:diversity] ≈ ones(length(qs)) # many (unexported!) diversity levels not yet implemented diff --git a/test/test_Ecology.jl b/test/test_Ecology.jl index 005659bc..3c889184 100644 --- a/test/test_Ecology.jl +++ b/test/test_Ecology.jl @@ -18,12 +18,12 @@ Z1 = ones(typeof(weights[1]), (length(weights), length(weights))); @testset "Standard ecological diversities" begin @test richness(communities)[:diversity] ≈ subdiv(ᾱ(eco), 0)[:diversity] - + @test shannon(communities)[:diversity] ≈ log.(subdiv(ᾱ(eco), 1)[:diversity]) - + @test simpson(communities)[:diversity] ≈ subdiv(ᾱ(eco), 2)[:diversity] .^ -1 - - @test jaccard([1 0 0; 0 1 1]'/3)[:diversity] + 1.0 ≈ [1.0] + + @test jaccard([1 0 0; 0 1 1]'/3)[:diversity] .+ 1.0 ≈ [1.0] @test jaccard([1 0 1; 0 1 1]'/4)[:diversity] ≈ [1.0 / 3.0] @test_throws ErrorException jaccard([1 1 0; 0 1 1; 1 1 1]/7) end @@ -31,19 +31,29 @@ end @testset "Generalised ecological diversities" begin @test generalisedrichness(metacommunityDiversity, communities, Z1)[:diversity] ≈ [1] + @test generalisedrichness(subcommunityDiversity, + communities)[:diversity] ≈ + richness(communities)[:diversity] + @test_throws ErrorException generalisedrichness(individualDiversity, communities, Z1) - + @test generalisedshannon(metacommunityDiversity, - communities, Z1)[:diversity] + 1.0 ≈ [1.0] + communities, Z1)[:diversity] .+ 1.0 ≈ [1.0] + @test generalisedshannon(subcommunityDiversity, + communities)[:diversity] ≈ + shannon(communities)[:diversity] @test_throws ErrorException generalisedshannon(individualDiversity, communities, Z1) - + @test generalisedsimpson(metacommunityDiversity, communities, Z1)[:diversity] ≈ [1.0] + @test generalisedsimpson(subcommunityDiversity, + communities)[:diversity] ≈ + simpson(communities)[:diversity] @test_throws ErrorException generalisedsimpson(individualDiversity, communities, Z1) - + @test generalisedjaccard([1 0 1; 0 1 1]'/4, [0, Inf])[:diversity] ≈ [1.0/3.0, 1.0] @test generalisedjaccard([1 1 1; 1 1 1]'/6, [0, 1])[:diversity] ≈ [1.0, 1.0] end diff --git a/test/test_EffectiveNumbers.jl b/test/test_EffectiveNumbers.jl index c21b8159..02dc1d9e 100644 --- a/test/test_EffectiveNumbers.jl +++ b/test/test_EffectiveNumbers.jl @@ -1,8 +1,10 @@ module TestEffectiveNumbers using Compat.Test +using Compat.LinearAlgebra +using Compat using Diversity -using Diversity.powermean +using Diversity: powermean numbers = [1.0, 2, 4, 8, 16]; numspecies = 100; @@ -12,8 +14,8 @@ weights /= sum(weights); Z1 = ones(typeof(weights[1]), (length(weights), length(weights))); numcommunities = 8; manyweights = rand(numspecies, numcommunities); -manyweights *= diagm(reshape(mapslices(v -> 1. / sum(v), manyweights, 1), - (numcommunities))); +manyweights *= Diagonal(reshape(mapslices(v -> 1. / sum(v), manyweights, dims=1), + numcommunities)); # Simple power means - we no longer export these, but we should check # them anyway as everything relies on them @@ -21,7 +23,7 @@ manyweights *= diagm(reshape(mapslices(v -> 1. / sum(v), manyweights, 1), @testset "powermean" begin # Check that an exception is thrown when 'values' and weights are different lengths @test_throws DimensionMismatch powermean(numbers, 0, weights) - + # Some simple values @test powermean([1.0], 0.0, [1.0]) ≈ 1.0 @test powermean(numbers, 0.0) ≈ 4.0 @@ -29,10 +31,10 @@ manyweights *= diagm(reshape(mapslices(v -> 1. / sum(v), manyweights, 1), @test powermean(numbers, [1.0, -1.0]) ≈ [31.0/5.0, 80.0/31.0] @test powermean(numbers, Inf, [1.0, 1.0, 1.0, 1.0, 0.0]) ≈ 8 @test isnan(powermean(numbers, 0.0, 0.0 * numbers)) - + # Power mean with some random numbers @test powermean(fragments, 0) ≈ prod(fragments .^ (1. / numspecies)) - @test powermean(fragments, 1) ≈ mean(fragments) + @test powermean(fragments, 1) ≈ Compat.Statistics.mean(fragments) @test powermean(fragments, Inf) ≈ maximum(fragments) @test powermean(fragments, 0, weights) ≈ prod(fragments .^ weights) @test powermean(fragments, 1, weights) ≈ sum(fragments .* weights) @@ -45,7 +47,7 @@ end @test qD(weights, 1) ≈ prod(weights .^ -weights) @test qD(weights, 2) ≈ 1.0 / sum(weights .^ 2) @test qD(weights, Inf) ≈ 1.0 / maximum(weights) - + @test qD(weights, [1, 2]) ≈ [qD(weights, 1), qD(weights, 2)] @test typeof(qD(manyweights[:,1], 0)) <: AbstractFloat @@ -56,7 +58,9 @@ end end # Diversities are not normalised, so generate an error - @test_warn "Abundances not normalised to 1, correcting..." qD([0.1, 0.1], 1) + if VERSION < v"0.7.0-" + @test_warn "Abundances not normalised to 1, correcting..." qD([0.1, 0.1], 1) + end end @testset "qDZ" begin @@ -64,15 +68,17 @@ end @test qDZ(weights, [1, 2]) ≈ qD(weights, [1, 2]) @test qDZ(weights, [0, 1, 2, 3, Inf], Z1) ≈ [1, 1, 1, 1, 1] - + for i in 1:size(manyweights, 2) @test qDZ(manyweights[:,i], [0, 1, 2, Inf], ones((size(manyweights[:,i], 1), size(manyweights[:,i], 1)))) ≈ ones((4, size(manyweights[:,i], 2))) end - - # Diversities are not normalised, so generate an error - @test_warn "Abundances not normalised to 1, correcting..." qDZ([0.1, 0.1], 1) + + if VERSION < v"0.7.0-" + # Diversities are not normalised, so generate an warning + @test_warn "Abundances not normalised to 1, correcting..." qDZ([0.1, 0.1], 1) + end end end diff --git a/test/test_GeneralisedDiversities.jl b/test/test_GeneralisedDiversities.jl index 51edc09c..dd32880e 100644 --- a/test/test_GeneralisedDiversities.jl +++ b/test/test_GeneralisedDiversities.jl @@ -9,7 +9,7 @@ metacom = Metacommunity([1 2; 1 2]/6) # Basic checks for the diversity() function @testset "diversity()" begin @test diversity([metacommunityDiversity], [ρ̄], metacom, 1)[:diversity] ≈ [1.0] - @test diversity(Set([subcommunityDiversity]), Set([ρ̄]), metacom, 1)[:diversity] ≈ [1.0, 1.0] + @test diversity([subcommunityDiversity], [ρ̄], metacom, 1)[:diversity] ≈ [1.0, 1.0] end pops = rand(5, 4) diff --git a/test/test_Hill.jl b/test/test_Hill.jl index d7502e51..cd2abad0 100644 --- a/test/test_Hill.jl +++ b/test/test_Hill.jl @@ -1,5 +1,6 @@ module TestHill using Compat.Test +using Compat.LinearAlgebra # Checking Hill numbers using Diversity @@ -8,7 +9,7 @@ using Diversity.Hill numspecies = 100; numcommunities = 8; manyweights = rand(numspecies, numcommunities); -manyweights *= diagm(reshape(mapslices(v -> 1. / sum(v), manyweights, 1), +manyweights *= Diagonal(reshape(mapslices(v -> 1. / sum(v), manyweights, dims=1), (numcommunities))); @testset "Hill numbers" begin diff --git a/test/test_Iterators.jl b/test/test_Iterators.jl index 1ef6489d..fadb8006 100644 --- a/test/test_Iterators.jl +++ b/test/test_Iterators.jl @@ -3,7 +3,6 @@ using Compat.Test using Phylo using Diversity -using Diversity.Phylogenetics @testset "Iterators" begin species = 10 @@ -14,9 +13,8 @@ using Diversity.Phylogenetics m = Metacommunity(abund, PhyloTypes(ru)) @test length(TypeIterator(m)) == counttypes(PhyloTypes(ru)) @test length(SubcommunityIterator(m)) == sc - @test all(broadcast(≈, reduce(+, SubcommunityIterator(m)), - getmetaabundance(m))) - @test all(broadcast(≈, reduce(+, TypeIterator(m)), getweight(m))) + @test all(reduce(+, SubcommunityIterator(m)) .≈ getmetaabundance(m)) + @test all(reduce(+, TypeIterator(m)) .≈ getweight(m)) end end diff --git a/test/test_Jost.jl b/test/test_Jost.jl index 3b58844b..05078bfe 100644 --- a/test/test_Jost.jl +++ b/test/test_Jost.jl @@ -1,5 +1,6 @@ module TestJost using Compat.Test +using Compat # Checking Jost's diversities using Diversity @@ -12,7 +13,7 @@ numspecies = 100; numcommunities = 8; communities = rand(numspecies, numcommunities); communities /= sum(communities); -probs = reshape(mapslices(sum, communities, 2), (size(communities, 1))); +probs = reshape(mapslices(sum, communities, dims=2), (size(communities, 1))); colweights = rand(numcommunities); colweights /= sum(colweights); allthesame = probs * colweights'; @@ -21,12 +22,12 @@ allthesame = probs * colweights'; @test jostbeta(communities, 1)[:diversity] ≈ (1.0 ./ metadiv(ρ̄(Metacommunity(communities)), 1)[:diversity]) - @test jostbeta(allthesame, qs)[:diversity] ≈ ones(qs) - + @test jostbeta(allthesame, qs)[:diversity] ≈ fill!(similar(qs), 1) + ## Check Jost's alpha diversity works for all the same subcommunity - @test jostalpha(allthesame, qs)[:diversity] ≈ metadiv(ᾱ(Metacommunity(allthesame)), - qs)[:diversity] - + @test jostalpha(allthesame, qs)[:diversity] ≈ + metadiv(ᾱ(Metacommunity(allthesame)), qs)[:diversity] + ## And for all different subcommunities and any subcommunities with the same sizes weights = rand(numspecies); weights /= sum(weights); @@ -35,17 +36,17 @@ allthesame = probs * colweights'; for i in 1:numspecies distinct[i, communitylist[i]] = weights[i] end - evendistinct = mapslices((x) -> x / (sum(x) * numcommunities), distinct, 1) - - @test jostalpha(evendistinct, qs)[:diversity] ≈ metadiv(ᾱ(Metacommunity(evendistinct)), - qs)[:diversity] - + evendistinct = mapslices((x) -> x / (sum(x) * numcommunities), distinct, dims=1) + + @test jostalpha(evendistinct, qs)[:diversity] ≈ + metadiv(ᾱ(Metacommunity(evendistinct)), qs)[:diversity] + # Now some even communities, should see that raw and normalised # diversities are the same - smoothed = communities ./ mapslices(sum, communities, 1); + smoothed = communities ./ mapslices(sum, communities, dims=1); smoothed /= numcommunities; - @test jostalpha(smoothed, qs)[:diversity] ≈ metadiv(ᾱ(Metacommunity(smoothed)), - qs)[:diversity] + @test jostalpha(smoothed, qs)[:diversity] ≈ + metadiv(ᾱ(Metacommunity(smoothed)), qs)[:diversity] end end diff --git a/test/test_Metacommunity.jl b/test/test_Metacommunity.jl index 3d4a5170..da21ed1c 100644 --- a/test/test_Metacommunity.jl +++ b/test/test_Metacommunity.jl @@ -1,5 +1,7 @@ module TestMetacommunity using Compat.Test +using Compat.LinearAlgebra +using Compat using Diversity using Diversity.API @@ -28,7 +30,7 @@ sim = [1.0 0.0 0.0 1.0 1.0 1.0] ms = GeneralTypes(sim) @testset "GeneralTypes" begin - @test _calcsimilarity(ms, 1.0) == sim + @test calcsimilarity(ms, 1.0) == sim @test_throws DomainError GeneralTypes(-sim) @test_throws MethodError GeneralTypes(ab3) @test_throws DimensionMismatch GeneralTypes(convert(Matrix{Float64}, ab3)) @@ -38,7 +40,7 @@ tax = Taxonomy(DataFrame(Species=["This", "That"]), Dict(:Species=>1.0)) @testset "Taxonomy" begin @test counttypes(tax) == 2 @test gettypenames(tax) == ["This", "That"] - @test_throws ErrorException _calcsimilarity(tax, 1.0) + @test_throws ErrorException calcsimilarity(tax, 1.0) @test_throws ErrorException _calcordinariness(tax, abnorm, 1.0) @test_throws ErrorException Taxonomy(DataFrame(Species=["This", "That"]), Dict(:Species=>1.0, :Genus=>0.5)) @@ -51,7 +53,7 @@ end @testset "Type names" begin @test gettypenames(Species(3)) == map(x -> "$x", 1:3) @test gettypenames(Species(["My species"])) == ["My species"] - @test gettypenames(GeneralTypes(eye(1), ["My species"])) == ["My species"] + @test gettypenames(GeneralTypes(Diagonal([1.0]), ["My species"])) == ["My species"] @test gettypenames(UniqueTypes(["One", "Two"])) == ["One", "Two"] end @@ -59,7 +61,7 @@ meta = Metacommunity(three, ms, oc_count) sp = Species(size(ab3, 1)) abf = ab3 ./ sum(ab3) meta2 = Metacommunity(abf, sp, sc) -g2 = GeneralTypes(eye(2)) +g2 = GeneralTypes(Matrix(1.0I, 2, 2)) @testset "Metacommunity" begin @test gettypes(meta) == ms @test getpartition(meta) == oc_count @@ -68,17 +70,19 @@ g2 = GeneralTypes(eye(2)) @test !ismissing(meta.ordinariness) @test getabundance(Metacommunity(ab3, g2, sc)) ≈ getabundance(Metacommunity(abf, g2, sc)) - @test_warn "not normalised" Metacommunity(ab3 * 1.0, eye(2)) - @test_warn "not normalised" Metacommunity([1.0, 2.0], eye(2)) - @test_warn "not normalised" Metacommunity(ab3 * 1.0, meta2) - @test_nowarn Metacommunity([0.5, 0.5], eye(2)) + if VERSION < v"0.7.0-" + @test_warn "not normalised" Metacommunity(ab3 * 1.0, Matrix(1.0I, 2, 2)) + @test_warn "not normalised" Metacommunity([1.0, 2.0], Matrix(1.0I, 2, 2)) + @test_warn "not normalised" Metacommunity(ab3 * 1.0, meta2) + end + @test_nowarn Metacommunity([0.5, 0.5], Matrix(1.0I, 2, 2)) @test_throws ErrorException Metacommunity(abf, ms, sc) @test_throws DimensionMismatch Metacommunity([1, 2, 3]/6, meta2) @test_throws DimensionMismatch getabundance(Metacommunity([0.5, 0.5], meta2)) - @test getabundance(Metacommunity(abf, eye(2))) ≈ + @test getabundance(Metacommunity(abf, Matrix(1.0I, 2, 2))) ≈ getabundance(Metacommunity(abf, meta2)) #@test_throws ErrorException Metacommunity(-abf, g2, sc) - @test _calcsimilarity(gettypes(meta2), _getscale(meta2)) ≈ eye(size(ab3, 1)) + @test calcsimilarity(gettypes(meta2), _getscale(meta2)) ≈ Matrix(1.0I, size(ab3, 1), size(ab3, 1)) @test Diversity.floattypes(meta) ⊆ mapreduce(Diversity.floattypes, ∩, [getabundance(meta), getpartition(meta), diff --git a/test/test_Phylogenetics.jl b/test/test_Phylogenetics.jl index d913d0cc..01680a1c 100644 --- a/test/test_Phylogenetics.jl +++ b/test/test_Phylogenetics.jl @@ -3,7 +3,6 @@ using Compat.Test using Phylo using Diversity -using Diversity.Phylogenetics @testset "Phylo" begin species = ["Dog", "Human", "Cat"]