45 my_reciprocal_sf(std::move(reciprocal_size_factors)),
46 my_reciprocal_denom(1.0 / std::log(log_base)),
47 my_pseudo(pseudo_count)
49 sanisizer::cast<Index_>(my_reciprocal_sf.size());
53 for (
const auto x : my_reciprocal_sf) {
54 if (!std::isfinite(x)) {
56 my_has_weird_sf =
true;
63 ReciprocalSizeFactors_ my_reciprocal_sf;
64 OutputValue_ my_reciprocal_denom, my_pseudo;
65 bool my_has_weird_sf =
false, my_sparse =
true;
68 std::optional<Index_> nrow()
const {
72 std::optional<Index_> ncol()
const {
73 return my_reciprocal_sf.size();
77 bool zero_depends_on_row()
const {
81 bool zero_depends_on_column()
const {
82 return my_has_weird_sf;
85 bool non_zero_depends_on_row()
const {
89 bool non_zero_depends_on_column()
const {
94 void log_normalize(
const Index_ idx,
const Index_ length,
const InputValue_* input, OutputValue_*
const output)
const {
95 const auto current_rsf = my_reciprocal_sf[idx];
96 for (Index_ i = 0; i < length; ++i) {
97 output[i] = std::log(input[i] * current_rsf + my_pseudo) * my_reciprocal_denom;
102 void dense(
const bool row,
const Index_ idx,
const Index_ start,
const Index_ length,
const InputValue_* input, OutputValue_*
const output)
const {
103 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
108 for (Index_ i = 0; i < length; ++i) {
109 output[i] = std::log(input[i] * my_reciprocal_sf[i + start] + my_pseudo) * my_reciprocal_denom;
112 log_normalize(idx, length, input, output);
116 void dense(
const bool row,
const Index_ idx,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_*
const output)
const {
117 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
120 const Index_ length = indices.size();
123 for (Index_ i = 0; i < length; ++i) {
124 output[i] = std::log(input[i] * my_reciprocal_sf[indices[i]] + my_pseudo) * my_reciprocal_denom;
127 log_normalize(idx, length, input, output);
132 bool is_sparse()
const {
140 const InputValue_* input_value,
141 const Index_*
const index,
142 OutputValue_*
const output_value
144 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
145 input_value = output_value;
149 for (Index_ i = 0; i < number; ++i) {
150 output_value[i] = std::log(input_value[i] * my_reciprocal_sf[index[i]] + my_pseudo) * my_reciprocal_denom;
153 log_normalize(idx, number, input_value, output_value);
157 OutputValue_ fill(
const bool row,
const Index_ idx)
const {
160 assert(!my_has_weird_sf);
161 return std::log(my_pseudo) * my_reciprocal_denom;
163 return std::log(
static_cast<InputValue_
>(0) * my_reciprocal_sf[idx] + my_pseudo) * my_reciprocal_denom;
236 SizeFactors_ size_factors,
241 for (
auto& x : size_factors) {
247 static_assert(std::is_floating_point<OutputValue_>::value);
248 if (
static_cast<size_t>(size_factors.size()) !=
static_cast<size_t>(counts->ncol())) {
249 throw std::runtime_error(
"length of 'size_factors' should be equal to the number of columns of 'counts'");
252 for (
auto& x : size_factors) {
253 x =
static_cast<OutputValue_
>(1.0) / x;
257 return std::make_shared<tatami::DelayedUnaryIsometricOperation<OutputValue_, InputValue_, Index_> >(
259 std::make_shared<tatami::DelayedUnaryIsometricMultiplyVectorHelper<OutputValue_, InputValue_, Index_, SizeFactors_> >(std::move(size_factors),
false)
262 return std::make_shared<tatami::DelayedUnaryIsometricOperation<OutputValue_, InputValue_, Index_> >(
264 std::make_shared<DelayedLogNormalizeHelper<OutputValue_, InputValue_, Index_, SizeFactors_> >(std::move(size_factors), options.
log_base, current_pseudo)
std::shared_ptr< tatami::Matrix< OutputValue_, Index_ > > normalize_counts(std::shared_ptr< const tatami::Matrix< InputValue_, Index_ > > counts, SizeFactors_ size_factors, const NormalizeCountsOptions &options)
Definition normalize_counts.hpp:234