83Output_
direct(Value_* ptr, Index_ num,
bool skip_nan) {
84 ::tatami_stats::internal::nanable_ifelse<Value_>(
87 auto lost = internal::translocate_nans(ptr, num);
95 return std::numeric_limits<Output_>::quiet_NaN();
98 Index_ halfway = num / 2;
99 bool is_even = (num % 2 == 0);
101 std::nth_element(ptr, ptr + halfway, ptr + num);
102 Output_ medtmp = *(ptr + halfway);
112 Output_ other = *std::max_element(ptr, ptr + halfway);
114 if (medtmp == other) {
117 return medtmp + (other - medtmp) / 2;
139Output_
direct(Value_* value, Index_ num_nonzero, Index_ num_all,
bool skip_nan) {
143 if (num_nonzero == num_all) {
147 ::tatami_stats::internal::nanable_ifelse<Value_>(
150 auto lost = internal::translocate_nans(value, num_nonzero);
161 if (num_nonzero < num_all - num_nonzero) {
165 Index_ halfway = num_all / 2;
166 bool is_even = (num_all % 2 == 0);
168 Index_ num_zero = num_all - num_nonzero;
169 Index_ num_negative = 0;
170 for (Index_ i = 0; i < num_nonzero; ++i) {
171 num_negative += (value[i] < 0);
175 if (num_negative > halfway) {
176 std::nth_element(value, value + halfway, value + num_nonzero);
177 return value[halfway];
179 }
else if (halfway >= num_negative + num_zero) {
180 Index_ skip_zeros = halfway - num_zero;
181 std::nth_element(value, value + skip_zeros, value + num_nonzero);
182 return value[skip_zeros];
189 Output_ baseline = 0, other = 0;
190 if (num_negative > halfway) {
191 std::nth_element(value, value + halfway, value + num_nonzero);
192 baseline = value[halfway];
193 other = *(std::max_element(value, value + halfway));
195 }
else if (num_negative == halfway) {
196 Index_ below_halfway = halfway - 1;
197 std::nth_element(value, value + below_halfway, value + num_nonzero);
198 other = value[below_halfway];
200 }
else if (num_negative < halfway && num_negative + num_zero > halfway) {
203 }
else if (num_negative + num_zero == halfway) {
204 Index_ skip_zeros = halfway - num_zero;
205 std::nth_element(value, value + skip_zeros, value + num_nonzero);
206 other = value[skip_zeros];
209 Index_ skip_zeros = halfway - num_zero;
210 std::nth_element(value, value + skip_zeros, value + num_nonzero);
211 baseline = value[skip_zeros];
212 other = *(std::max_element(value, value + skip_zeros));
215 if (baseline == other) {
218 return baseline + (other - baseline) / 2;
239 auto dim = (row ? mat.
nrow() : mat.
ncol());
240 auto otherdim = (row ? mat.
ncol() : mat.
nrow());
250 auto vbuffer = buffer.data();
251 for (Index_ x = 0; x < l; ++x) {
252 auto range = ext->fetch(vbuffer, NULL);
262 for (Index_ x = 0; x < l; ++x) {
263 auto ptr = ext->fetch(buffer.data());