| 31 | |
| 32 | template<typename T> |
| 33 | static double median(const af_array& in) { |
| 34 | dim_t nElems = getInfo(in).elements(); |
| 35 | dim4 dims(nElems, 1, 1, 1); |
| 36 | ARG_ASSERT(0, nElems > 0); |
| 37 | |
| 38 | af_array temp = 0; |
| 39 | AF_CHECK(af_moddims(&temp, in, 1, dims.get())); |
| 40 | const Array<T>& input = getArray<T>(temp); |
| 41 | |
| 42 | // Shortcut cases for 1 or 2 elements |
| 43 | if (nElems == 1) { |
| 44 | T result; |
| 45 | AF_CHECK(af_get_data_ptr((void*)&result, in)); |
| 46 | return result; |
| 47 | } |
| 48 | if (nElems == 2) { |
| 49 | T result[2]; |
| 50 | AF_CHECK(af_get_data_ptr((void*)&result, in)); |
| 51 | return division( |
| 52 | (static_cast<double>(result[0]) + static_cast<double>(result[1])), |
| 53 | 2.0); |
| 54 | } |
| 55 | |
| 56 | double mid = static_cast<double>(nElems + 1) / 2.0; |
| 57 | af_seq mdSpan[1] = {af_make_seq(mid - 1, mid, 1)}; |
| 58 | |
| 59 | Array<T> sortedArr = sort<T>(input, 0, true); |
| 60 | |
| 61 | af_array sarrHandle = getHandle<T>(sortedArr); |
| 62 | |
| 63 | double result; |
| 64 | T resPtr[2]; |
| 65 | af_array res = 0; |
| 66 | AF_CHECK(af_index(&res, sarrHandle, 1, mdSpan)); |
| 67 | AF_CHECK(af_get_data_ptr((void*)&resPtr, res)); |
| 68 | |
| 69 | AF_CHECK(af_release_array(res)); |
| 70 | AF_CHECK(af_release_array(sarrHandle)); |
| 71 | AF_CHECK(af_release_array(temp)); |
| 72 | |
| 73 | if (nElems % 2 == 1) { |
| 74 | result = resPtr[0]; |
| 75 | } else { |
| 76 | result = division( |
| 77 | static_cast<double>(resPtr[0]) + static_cast<double>(resPtr[1]), |
| 78 | 2.0); |
| 79 | } |
| 80 | |
| 81 | return result; |
| 82 | } |
| 83 | |
| 84 | template<typename T> |
| 85 | static af_array median(const af_array& in, const dim_t dim) { |
no test coverage detected