Provides a unified interface for computing, comparing, and examining distances, dissimilarities, divergences, and selected similarities for bioinformatics data. The core installation exposes 60 canonical named routes for numerical data and more than 90 when the suggested 'philentropy' backend is installed; aliases, user-defined functions, and mixed-data combinations are not included in these counts. Weighted Minkowski distances can be computed through 'parallelDist', an internal multicore implementation, or optional 'OpenCL' kernels, while the established weighted Euclidean GPU implementation is retained as the optimized p = 2 route. The package also supports theory-guided comparison of distance distributions for clustering, explicit mathematical property classifications, mixed-data constructions through 'manydist', and a specialized Gene Ontology-derived TF-IDF distance.
BIDistances provides a common interface for calculating, comparing, and examining distances, dissimilarities, divergences, and selected similarities. The package connects four tasks that are usually treated separately:
DistanceMatrix().DistanceProperties().DistanceDistributions().p = 2.Additional domain-specific functionality includes a Gene Ontology-derived TF-IDF distance, time-series distances, nearest-neighbour distances, toroidal Euclidean distances, and mixed-data constructions.
DistanceMatrix() interface for native BIDistances methods and all predefined methods supplied by parallelDist, with optional access to philentropy and manydist.philentropy is installed. This count excludes aliases, user-defined C++ functions, direct-only functions, and the configurable mixed-data constructions in manydist.parallelDist, an internal RcppParallel multicore backend, or optional OpenCL kernels.p = 2 OpenCL route.DistanceDistributions() for comparing candidate distance distributions and identifying multimodality under the goal of finding distance-based cluster structures. Distance vectors above 72,000 values use the integrated batch dip-test backend, while smaller vectors retain diptest::dip.test().Tfidf_Distance() for deriving distances between genes from a gene-by-Gene-Ontology-term feature matrix.DistanceProperties() for documenting the mathematical properties and conditions of native methods.| Access layer | Canonical named routes | Counting rule |
|---|---|---|
Package-defined DistanceMatrix() routes |
19 | 12 native routes, six correlation routes, and squared Euclidean |
Predefined parallelDist methods |
41 | The user-defined custom route is excluded |
| Core installation | 60 | Package-defined routes plus parallelDist |
Additional philentropy identifiers |
34 | Exact overlaps and aliases already resolved by DistanceMatrix() are excluded |
Numerical-data total with philentropy |
94 | Canonical names only |
manydist adds preset-based and custom mixed-type distance constructions. These are not included in the total because their specifications are configurable rather than a fixed list of independent methods. Direct-only functions such as TWED_Distance() and ToroidalEuclidean_Distance() are also outside the dispatcher count.
From CRAN:
install.packages("BIDistances")
From GitHub:
install.packages("remotes")
remotes::install_github("Mthrun/BIDistances")
System requirements are R >= 3.5.0, GNU make, and a suitable C++ toolchain. An OpenCL library and the R package OpenCL are optional and are required only for GPU acceleration. Pandoc is required when rebuilding the vignette.
library(BIDistances)
data("Hepta")
Data = Hepta$Data
D_euclidean = DistanceMatrix(
Data,
method = "euclidean"
)
D_minkowski = DistanceMatrix(
Data,
method = "minkowski",
p = 3
)
D_cosine = DistanceMatrix(
Data,
method = "Cosine_Distance"
)
D_euclidean[1:5, 1:5]
DistanceMatrix() first checks for a native BIDistances route. Other method names are evaluated by parallelDist; methods unavailable there can be obtained from philentropy when it is installed. Mixed numerical and categorical data can be handled through manydist.
For finite p >= 1, Minkowski_Distance() computes
$$ d_{p,w}(x,y) = \left(\sum_k w_k |x_k-y_k|^p\right)^{1/p}. $$
Data = as.matrix(iris[1:30, 1:4])
Weights = c(1, 2, 0.5, 1)
D_parallel = Minkowski_Distance(
Data = Data,
p = 3,
Weights = Weights,
backend = "parallelDist",
threads = 2
)
D_multicore = Minkowski_Distance(
Data = Data,
p = 3,
Weights = Weights,
backend = "multicore",
threads = 2
)
max(abs(D_parallel - D_multicore))
The optional OpenCL route uses separate kernels for general p and delegates p = 2 to the established weighted Euclidean GPU implementation:
# Requires an installed OpenCL implementation and a usable device.
D_opencl = Minkowski_Distance(
Data = Data,
p = 3,
Weights = Weights,
backend = "opencl",
Mem = 2
)
Use backend = "auto" to try OpenCL and fall back to the internal multicore backend with a warning. For p = Inf, unit weights are required and the maximum or Chebyshev distance is returned. Values 0 < p < 1 are available through Fractional_Distance() but are generally not metrics.
The same weighted route is available through DistanceMatrix():
D_dispatch = DistanceMatrix(
Data,
method = "Minkowski_Distance",
p = 3,
Weights = Weights,
backend = "multicore",
threads = 2
)
The memory planner can be inspected before a large OpenCL calculation:
MemoryPlan = calculateMemoryDemandGPU(
n = 70000,
d = 784,
mem = 6
)
MemoryPlan
The Euclidean-related entry points have deliberately different roles:
| Entry point | Role |
|---|---|
DistanceMatrix(Data, method = "euclidean") |
Euclidean distance through parallelDist |
EuclideanMulticore_Distance(Data) |
Internal unweighted multicore Euclidean implementation |
EuclideanGPU_Distance(Data, Weights, backend = ...) |
Weighted Euclidean CPU/OpenCL implementation |
Minkowski_Distance(Data, p = 2, ...) |
Unified weighted Minkowski interface using the optimized Euclidean OpenCL route |
ToroidalEuclidean_Distance(Points, Lines, Columns) |
Euclidean distance on a two-dimensional torus |
library(BIDistances)
data("Hepta")
set.seed(42)
Selection = DistanceDistributions(
Data = Hepta$Data,
DistanceMethods = c(
"euclidean",
"manhattan",
"minkowski",
"chord"
),
CosineNonParallel = TRUE,
CorrelationDist = TRUE,
PlotIt = FALSE
)
Selection$DistanceChoice
Selection$SelectionStatistics[, c(
"Distance", "DipStatistic", "DipPValue", "BimodalityAmplitude", "Status"
)]
if (!is.null(Selection$DistanceMatrix)) {
Selection$DistanceMatrix[1:5, 1:5]
}
Selection$ggobject
The workflow ranks candidate distributions using multimodality-related information under the explicit goal of finding distance-based cluster structures. SelectionStatistics reports both the Hartigan dip statistic and its p-value. For at most 72,000 pairwise values the established diptest::dip.test() path is retained; larger candidate columns are processed together by the integrated C++ batch with explicit asymptotic calibration. The result is exploratory: multimodality supports this structural goal, but it is not a universal proof of cluster validity or biological relevance.
library(BIDistances)
data("Hearingloss_N109")
Result = Tfidf_Distance(
Hearingloss_N109$FeatureMatrix_Gene2Term,
tf_fun = mean
)
Distance = Result$Distance
TfidfWeights = Result$TfidfWeights
Distance[1:5, 1:5]
TfidfWeights[1:5]
Rows represent genes and columns represent GO terms. The function returns pairwise absolute differences between scalar TF-IDF weights together with those weights. Because different annotation rows can receive the same scalar weight, the construction is a pseudometric on the original rows.
library(BIDistances)
TimeSeries = cbind(
SeriesA = c(0, 1, 2, 1, 0),
SeriesB = c(0, 1, 1.5, 1, 0),
SeriesC = c(2, 1, 0, 1, 2)
)
D_msmd = DistanceMatrix(
TimeSeries,
method = "MSMD_Distance",
ParameterC = 1
)
D_msmd
For MSMD_Distance and DTW_Distance, every column is one time series and row order is the temporal order. No separate time variable should be supplied. TWED_Distance() requires explicit timestamps and is therefore called directly rather than through DistanceMatrix().
[1:n,1:d] numerical matrix with n cases, d variables[1:d,1:d] numerical matrix of distancesMost methods compare the rows of Data. The documented exceptions are:
DTW_Distance and MSMD_Distance, which compare time series stored in columns.EndresSchindelin_Distance, which compares columns as samples of variables.TWED_Distance, which compares two time series directly and requires explicit time vectors.The word distance is used as a broad software convention. Not every returned quantity is a mathematical metric. The complete machine-readable classification is available through:
Properties = DistanceProperties()
Properties[, c(
"Function",
"Classification",
"Conditions"
)]
Examples include:
p >= 1 with strictly positive weights and can become a pseudometric when zero weights remove distinguishing coordinates.Fractional_Distance() with 0 < p < 1 generally violates the triangle inequality.Mahalanobis_Distance() returns squared Mahalanobis dissimilarities; applying sqrt() yields the metric form.Cosine_Distance() returns 1 - cosine similarity and is not a metric in general.Tfidf_Distance() is a pseudometric on the original gene-annotation rows.Kullback_Leibler_div() returns a divergence, including when symmetrized.See ?distance-conventions and ?DistanceProperties for details. The registry documents mathematical conditions; it is not a runtime proof for arbitrary user-supplied data.
DistanceMatrix() routesCanonical package methods available through DistanceMatrix() are:
Cosine_DistanceEndresSchindelin_DistanceFractional_DistanceGini_DistanceJaccard_DistanceMahalanobis_DistanceMinkowski_DistanceSharedNeighbor_DistanceTfidf_DistanceWasserstein_DistanceDTW_DistanceMSMD_DistanceTWED_Distance() is intentionally excluded from the dispatcher because its explicit time vectors cannot be inferred from the standard matrix interface.
Some functions require suggested packages only when they are used:
OpenCL for the GPU backend.philentropy for additional probability-distribution methods.manydist for mixed numerical and categorical data.dtw and proxy for DTW_Distance().ineq for Gini_Distance().transport for Wasserstein_Distance().ScatterDensity for sample-based Endres-Schindelin calculations.The full manual is available at CRAN.
The package vignette can be opened from R with:
vignette("BIDistances")
Citation information is available with:
citation("BIDistances")
[Thrun, 2021] Thrun, M. C.: The Exploitation of Distance Distributions for Clustering, International Journal of Computational Intelligence and Applications, Vol. 20(3), 2150016, doi:10.1142/S1469026821500164, 2021.
[Stier & Thrun, 2023] Stier, Q., & Thrun, M. C.: Deriving Homogeneous Subsets from Gene Sets by Exploiting the Gene Ontology, Informatica, Vol. 34(2), pp. 357-386, doi:10.15388/23-INFOR517, 2023.