+
135Output_
direct(Value_* value, Index_ num_nonzero, Index_ num_all,
bool skip_nan) {
+
+
+
+
139 if (num_nonzero == num_all) {
+
140 return direct<Output_>(value, num_all, skip_nan);
+
+
+
143 ::tatami_stats::internal::nanable_ifelse<Value_>(
+
+
+
146 auto lost = internal::translocate_nans(value, num_nonzero);
+
+
+
+
+
+
+
+
+
+
+
157 if (num_nonzero < num_all - num_nonzero) {
+
+
+
+
161 size_t halfway = num_all / 2;
+
162 bool is_even = (num_all % 2 == 0);
+
+
164 size_t num_zero = num_all - num_nonzero;
+
165 size_t num_negative = 0;
+
166 for (Index_ i = 0; i < num_nonzero; ++i) {
+
167 num_negative += (value[i] < 0);
+
+
+
+
171 if (num_negative > halfway) {
+
172 std::nth_element(value, value + halfway, value + num_nonzero);
+
173 return value[halfway];
+
+
175 }
else if (halfway >= num_negative + num_zero) {
+
176 size_t skip_zeros = halfway - num_zero;
+
177 std::nth_element(value, value + skip_zeros, value + num_nonzero);
+
178 return value[skip_zeros];
+
+
+
+
+
+
+
185 Output_ baseline = 0, other = 0;
+
186 if (num_negative > halfway) {
+
187 std::nth_element(value, value + halfway, value + num_nonzero);
+
188 baseline = value[halfway];
+
189 other = *(std::max_element(value, value + halfway));
+
+
191 }
else if (num_negative == halfway) {
+
192 size_t below_halfway = halfway - 1;
+
193 std::nth_element(value, value + below_halfway, value + num_nonzero);
+
194 other = value[below_halfway];
-
196 }
else if (num_negative + num_zero == halfway) {
-
197 size_t skip_zeros = halfway - num_zero;
-
198 std::nth_element(value, value + skip_zeros, value + num_nonzero);
-
199 tmp = value[skip_zeros];
-
-
-
202 size_t skip_zeros = halfway - num_zero;
-
203 std::nth_element(value, value + skip_zeros, value + num_nonzero);
-
204 tmp = value[skip_zeros] + *(std::max_element(value, value + skip_zeros));
-
-
-
-
+
196 }
else if (num_negative < halfway && num_negative + num_zero > halfway) {
+
+
+
199 }
else if (num_negative + num_zero == halfway) {
+
200 size_t skip_zeros = halfway - num_zero;
+
201 std::nth_element(value, value + skip_zeros, value + num_nonzero);
+
202 other = value[skip_zeros];
+
+
+
205 size_t skip_zeros = halfway - num_zero;
+
206 std::nth_element(value, value + skip_zeros, value + num_nonzero);
+
207 baseline = value[skip_zeros];
+
208 other = *(std::max_element(value, value + skip_zeros));
+
+
+
+
212 return baseline + (other - baseline) / 2;
+