scran_variances
Model per-gene variance in expression
Loading...
Searching...
No Matches
fit_variance_trend.hpp
Go to the documentation of this file.
1#ifndef SCRAN_VARIANCES_FIT_VARIANCE_TREND_H
2#define SCRAN_VARIANCES_FIT_VARIANCE_TREND_H
3
4#include <algorithm>
5#include <vector>
6#include <array>
8
14namespace scran_variances {
15
25 double minimum_mean = 0.1;
26
31 bool mean_filter = true;
32
37 bool transform = true;
38
43 double span = 0.3;
44
51 bool use_minimum_width = false;
52
58 double minimum_width = 1;
59
66
71 int num_threads = 1;
72};
73
79template<typename Float_>
85
86 std::vector<uint8_t> sort_workspace;
87
88 std::vector<Float_> xbuffer, ybuffer;
92};
93
119template<typename Float_>
121 auto& xbuffer = workspace.xbuffer;
122 xbuffer.resize(n);
123 auto& ybuffer = workspace.ybuffer;
124 ybuffer.resize(n);
125
126 auto quad = [](Float_ x) -> Float_ {
127 return x * x * x * x;
128 };
129
130 size_t counter = 0;
131 Float_ min_mean = options.minimum_mean;
132 for (size_t i = 0; i < n; ++i) {
133 if (!options.mean_filter || mean[i] >= min_mean) {
134 xbuffer[counter] = mean[i];
135 if (options.transform) {
136 ybuffer[counter] = std::pow(variance[i], 0.25); // Using the same quarter-root transform that limma::voom uses.
137 } else {
139 }
140 ++counter;
141 }
142 }
143
144 if (counter < 2) {
145 throw std::runtime_error("not enough observations above the minimum mean");
146 }
147
148 auto& sorter = workspace.sorter;
149 sorter.set(counter, xbuffer.data());
150 auto& work = workspace.sort_workspace;
151 sorter.permute(std::array<Float_*, 2>{ xbuffer.data(), ybuffer.data() }, work);
152
154 if (options.use_minimum_width) {
155 smooth_opt.span = options.minimum_window_count;
156 smooth_opt.span_as_proportion = false;
157 smooth_opt.minimum_width = options.minimum_width;
158 } else {
159 smooth_opt.span = options.span;
160 }
161 smooth_opt.num_threads = options.num_threads;
162
163 // Using the residual array to store the robustness weights as a placeholder;
164 // we'll be overwriting this later.
165 WeightedLowess::compute(counter, xbuffer.data(), ybuffer.data(), fitted, residuals, smooth_opt);
166
167 // Determining the left edge before we unpermute.
168 Float_ left_x = xbuffer[0];
169 Float_ left_fitted = (options.transform ? quad(fitted[0]) : fitted[0]);
170
171 sorter.unpermute(fitted, work);
172
173 // Walking backwards to shift the elements back to their original position
174 // (i.e., before filtering on the mean) on the same array. We need to walk
175 // backwards to ensure that writing to the original position on this array
176 // doesn't clobber the first 'counter' positions containing the fitted
177 // values, at least not until each value is shifted to its original place.
178 for (size_t i = n; i > 0; --i) {
179 auto j = i - 1;
180 if (!options.mean_filter || mean[j] >= min_mean) {
181 --counter;
182 fitted[j] = (options.transform ? quad(fitted[counter]) : fitted[counter]);
183 } else {
184 fitted[j] = mean[j] / left_x * left_fitted; // draw a y = x line to the origin from the left of the fitted trend.
185 }
186 }
187
188 for (size_t i = 0; i < n; ++i) {
189 residuals[i] = variance[i] - fitted[i];
190 }
191 return;
192}
193
202template<typename Float_>
208
217 std::vector<Float_> fitted;
218
222 std::vector<Float_> residuals;
223};
224
237template<typename Float_>
244
245}
246
247#endif
void compute(size_t num_points, const Data_ *x, const PrecomputedWindows< Data_ > &windows, const Data_ *y, Data_ *fitted, Data_ *robust_weights, const Options< Data_ > &opt)
Variance modelling for single-cell expression data.
Definition choose_highly_variable_genes.hpp:14
std::vector< Index_ > choose_highly_variable_genes_index(Index_ n, const Stat_ *statistic, const ChooseHighlyVariableGenesOptions &options)
Definition choose_highly_variable_genes.hpp:256
void fit_variance_trend(size_t n, const Float_ *mean, const Float_ *variance, Float_ *fitted, Float_ *residuals, FitVarianceTrendWorkspace< Float_ > &workspace, const FitVarianceTrendOptions &options)
Definition fit_variance_trend.hpp:120
Options for fit_variance_trend().
Definition fit_variance_trend.hpp:19
int num_threads
Definition fit_variance_trend.hpp:71
double minimum_width
Definition fit_variance_trend.hpp:58
bool use_minimum_width
Definition fit_variance_trend.hpp:51
double span
Definition fit_variance_trend.hpp:43
bool transform
Definition fit_variance_trend.hpp:37
int minimum_window_count
Definition fit_variance_trend.hpp:65
bool mean_filter
Definition fit_variance_trend.hpp:31
double minimum_mean
Definition fit_variance_trend.hpp:25
Results of fit_variance_trend().
Definition fit_variance_trend.hpp:203
std::vector< Float_ > residuals
Definition fit_variance_trend.hpp:222
std::vector< Float_ > fitted
Definition fit_variance_trend.hpp:217
Workspace for fit_variance_trend().
Definition fit_variance_trend.hpp:80