File: array.h

package info (click to toggle)
gemmi 0.7.4%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,644 kB
  • sloc: cpp: 64,445; python: 5,425; ansic: 4,545; sh: 374; makefile: 112; javascript: 86; f90: 42
file content (64 lines) | stat: -rw-r--r-- 2,383 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#pragma once
#include <array>
#include <vector>
#include "common.h"
#include <nanobind/ndarray.h>

template<typename T>
using cpu_array = nb::ndarray<T, nb::shape<-1>, nb::device::cpu>;
template<typename T>
using cpu_c_array = nb::ndarray<T, nb::shape<-1>, nb::device::cpu, nb::c_contig>;
using cpu_miller_array = nb::ndarray<int, nb::shape<-1,3>, nb::device::cpu>;
using cpu_c_miller_array = nb::ndarray<int, nb::shape<-1,3>, nb::device::cpu, nb::c_contig>;

template<typename T>
auto numpy_array_from_vector(std::vector<T>&& original_vec) {
  using V = std::vector<T>;
  auto v = new V(std::move(original_vec));
  nb::capsule owner(v, [](void* p) noexcept { delete static_cast<V*>(p); });
  return nb::ndarray<nb::numpy, T, nb::shape<-1>>(v->data(), {v->size()}, owner);
}

template<typename T, size_t N>
auto py_array2d_from_vector(std::vector<std::array<T,N>>&& original_vec) {
  using V = std::vector<std::array<T,N>>;
  auto v = new V(std::move(original_vec));
  nb::capsule owner(v, [](void* p) noexcept { delete static_cast<V*>(p); });
  return nb::ndarray<nb::numpy, T, nb::shape<-1, N>>(v->data(), {v->size(), N}, owner);
}

// to be used with rv_policy::reference_internal
template<typename T, typename S>
auto vector_member_array(std::vector<S>& vec, T S::*ptr) {
  constexpr int64_t stride = static_cast<int64_t>(sizeof(S) / sizeof(T));
  static_assert(stride * sizeof(T) == sizeof(S),
                "vector_member_array(): problem with stride");
  return nb::ndarray<nb::numpy, T, nb::shape<-1>>(
          &(vec.data()->*ptr),
          {vec.size()},
          nb::handle(),
          {stride});
}

template<typename T>
auto make_numpy_array(std::initializer_list<size_t> size,
                      std::initializer_list<int64_t> strides={}) {
  size_t total_size = 1;
  for (size_t i : size)
    total_size *= i;
  T* c_array = new T[total_size];
  nb::capsule owner(c_array, [](void* p) noexcept { delete [] static_cast<T*>(p); });
  return nb::ndarray<nb::numpy, T>(c_array, size, owner, strides);
}

template<typename Ret, typename Obj, typename Func>
auto miller_function(const Obj& obj, Func func, const cpu_miller_array& hkl) {
  auto h = hkl.view();
  size_t n = h.shape(0);
  auto result = make_numpy_array<Ret>({n});
  Ret* rptr = result.data();
  for (size_t i = 0; i < n; ++i)
    rptr[i] = (obj.*func)({h(i, 0), h(i, 1), h(i, 2)});
  return result;
}