19 #ifdef NDARRAY_OPS_IMPL
27 T
sum(
const NdArray<T>& array) {
32 NdArray<T>
sum(
const NdArray<T>& array,
int axis) {
34 axis = array.shape().size() + axis;
37 if (static_cast<std::size_t>(axis) >= array.shape().size()) {
41 if (array.shape().size() == 1) {
42 NdArray<T> output{{1}};
43 output.at(0) =
sum(array);
47 auto output_shape = array.shape();
48 auto axis_size = output_shape[axis];
50 output_shape.erase(output_shape.begin() + axis);
51 NdArray<T> output(output_shape);
53 for (
std::size_t out_i = 0; out_i < output.size(); ++out_i) {
56 in_coordinates.insert(in_coordinates.begin() + axis, 0ul);
58 auto& output_val = output.at(out_coordinates);
59 for (
std::size_t axis_i = 0; axis_i < axis_size; ++axis_i) {
60 in_coordinates[axis] = axis_i;
61 output_val += array.at(in_coordinates);
68 template <
typename T,
typename Iterator>
69 NdArray<T>
trapz(
const NdArray<T>& array,
const Iterator kbegin,
const Iterator kend,
int axis) {
71 axis = array.shape().size() + axis;
74 if (static_cast<std::size_t>(axis) >= array.shape().size()) {
78 auto output_shape = array.shape();
79 auto axis_size = output_shape[axis];
81 if (static_cast<std::size_t>(kend - kbegin) != axis_size) {
82 throw std::length_error(
"Integration axis value does not match the size of the array axis");
85 bool output_scalar = (array.shape().size() == 1);
88 output_shape.emplace_back(1);
90 output_shape.erase(output_shape.begin() + axis);
92 NdArray<T> output(output_shape);
94 for (
std::size_t out_i = 0; out_i < output.size(); ++out_i) {
98 in_coordinates.insert(in_coordinates.begin() + axis, 0ul);
101 auto& output_val = output.at(out_coordinates);
102 auto ki = kbegin + 1;
103 for (
std::size_t axis_i = 1; axis_i < axis_size; ++axis_i, ++ki) {
104 auto dx = (*ki) - *(ki - 1);
105 in_coordinates[axis] = axis_i;
106 auto b = array.at(in_coordinates);
107 --in_coordinates[axis];
108 auto a = array.at(in_coordinates);
109 output_val += ((a + b) * dx) / 2;
116 template <
typename T>
119 auto max_pos = max_iter - array.begin();
123 template <
typename T>
126 auto max_pos = max_iter - array.begin();
130 template <
typename T>
132 if (array.shape().size() != 2) {
137 const auto& array_attrs = array.attributes();
138 for (
size_t i = 0; i < attrs.
size(); ++i) {
140 if (pos == attrs.
end()) {
143 attr_idx[i] = pos - array_attrs.
begin();
146 size_t count = array.shape()[0];
147 size_t row_size = array.shape()[1] *
sizeof(T);
150 auto compare = [](
void* context,
const void* a,
const void* b) {
152 auto compare = [](
const void* a,
const void* b,
void* context) {
154 const T* arow =
static_cast<const T*
>(a);
155 const T* brow =
static_cast<const T*
>(b);
157 for (
auto& idx : *attr_idx_ptr) {
158 if (*(arow + idx) < *(brow + idx)) {
160 }
else if (*(arow + idx) > *(brow + idx)) {
168 qsort_r(&(*array.begin()), count, row_size, &attr_idx, compare);
170 qsort_r(&(*array.begin()), count, row_size, compare, &attr_idx);
std::vector< std::size_t > argmax(const NdArray< T > &array)
NdArray< T > trapz(const NdArray< T > &array, const Iterator kbegin, const Iterator kend, int axis)
std::vector< std::size_t > unravel_index(std::size_t index, const std::vector< std::size_t > &shape)
void sort(NdArray< T > &array, const std::vector< std::string > &attrs)
T sum(const NdArray< T > &array)
std::vector< std::size_t > argmin(const NdArray< T > &array)