1#ifndef SCRAN_NEIGHBOR_SCALING_HPP
2#define SCRAN_NEIGHBOR_SCALING_HPP
4#include "../utils/macros.hpp"
9#include "knncolle/knncolle.hpp"
10#include "tatami/stats/medians.hpp"
109 std::pair<double, double>
compute_distance(
int ndim,
size_t ncells,
const double* data)
const {
110 std::unique_ptr<knncolle::Base<> > ptr;
112 ptr.reset(
new knncolle::VpTreeEuclidean<>(ndim, ncells, data));
114 ptr.reset(
new knncolle::AnnoyEuclidean<>(ndim, ncells, data));
127 template<
class Search>
129 size_t nobs = search->nobs();
130 std::vector<double> dist(nobs);
132 tatami::parallelize([&](
size_t,
size_t start,
size_t length) ->
void {
133 for (
size_t i = start, end = start + length; i < end; ++i) {
134 auto neighbors = search->find_nearest_neighbors(i, num_neighbors);
135 dist[i] = neighbors.back().second;
139 double med = tatami::stats::compute_median<double>(dist.data(), nobs);
141 for (
auto d : dist) {
144 rmsd = std::sqrt(rmsd);
145 return std::make_pair(med, rmsd);
159 static std::vector<double>
compute_scale(
const std::vector<std::pair<double, double> >& distances) {
160 std::vector<double> output(distances.size());
163 bool found_ref =
false;
165 for (
size_t e = 0; e < distances.size(); ++e) {
166 if (distances[e].second) {
175 const auto& dref = distances[ref];
176 for (
size_t e = 0; e < distances.size(); ++e) {
177 output[e] = (e == ref ? 1 :
compute_scale(dref, distances[e]));
200 static double compute_scale(
const std::pair<double, double>& ref,
const std::pair<double, double>& target) {
201 if (target.first == 0 || ref.first == 0) {
202 if (target.second == 0) {
203 return std::numeric_limits<double>::infinity();
204 }
else if (ref.second == 0) {
207 return ref.second / target.second;
210 return ref.first / target.first;
232 template<
typename Embed>
233 static void combine_scaled_embeddings(
const std::vector<int>& ndims,
size_t ncells,
const std::vector<Embed>& embeddings,
const std::vector<double>& scaling,
double* output) {
234 size_t nembed = ndims.size();
235 if (embeddings.size() != nembed || scaling.size() != nembed) {
236 throw std::runtime_error(
"'ndims', 'embeddings' and 'scale' should have the same length");
239 int ntotal = std::accumulate(ndims.begin(), ndims.end(), 0);
242 for (
size_t e = 0; e < nembed; ++e) {
243 size_t curdim = ndims[e];
244 auto inptr = embeddings[e];
245 auto outptr = output + offset;
251 for (
size_t c = 0; c < ncells; ++c, inptr += curdim, outptr += ntotal) {
252 std::fill(outptr, outptr + curdim, 0);
255 for (
size_t c = 0; c < ncells; ++c, inptr += curdim, outptr += ntotal) {
256 for (
size_t d = 0; d < curdim; ++d) {
257 outptr[d] = inptr[d] * s;
Scale multi-modal embeddings to adjust for differences in variance.
Definition ScaleByNeighbors.hpp:38
static std::vector< double > compute_scale(const std::vector< std::pair< double, double > > &distances)
Definition ScaleByNeighbors.hpp:159
static double compute_scale(const std::pair< double, double > &ref, const std::pair< double, double > &target)
Definition ScaleByNeighbors.hpp:200
ScaleByNeighbors & set_num_threads(int n=Defaults::num_threads)
Definition ScaleByNeighbors.hpp:88
std::pair< double, double > compute_distance(int ndim, size_t ncells, const double *data) const
Definition ScaleByNeighbors.hpp:109
std::pair< double, double > compute_distance(const Search *search) const
Definition ScaleByNeighbors.hpp:128
ScaleByNeighbors & set_approximate(int a=Defaults::approximate)
Definition ScaleByNeighbors.hpp:79
static void combine_scaled_embeddings(const std::vector< int > &ndims, size_t ncells, const std::vector< Embed > &embeddings, const std::vector< double > &scaling, double *output)
Definition ScaleByNeighbors.hpp:233
ScaleByNeighbors & set_neighbors(int n=Defaults::neighbors)
Definition ScaleByNeighbors.hpp:66
Functions for single-cell RNA-seq analyses.
Definition AggregateAcrossCells.hpp:18
Default parameter settings.
Definition ScaleByNeighbors.hpp:43
static constexpr int num_threads
Definition ScaleByNeighbors.hpp:57
static constexpr bool approximate
Definition ScaleByNeighbors.hpp:52
static constexpr int neighbors
Definition ScaleByNeighbors.hpp:47