28 NdArray<T>::Iterator<Const>::Iterator(ContainerInterface* container_ptr,
size_t offset)
29 : m_container_ptr{container_ptr}, m_offset{offset} {}
33 NdArray<T>::Iterator<Const>::Iterator(
const Iterator<false>& other)
34 : m_container_ptr{other.m_container_ptr}, m_offset{other.m_offset} {}
38 auto NdArray<T>::Iterator<Const>::operator++() -> Iterator& {
45 auto NdArray<T>::Iterator<Const>::operator++(
int) -> Iterator {
46 return Iterator{m_container_ptr, m_offset + 1};
51 bool NdArray<T>::Iterator<Const>::operator==(
const Iterator& other)
const {
52 return m_container_ptr == other.m_container_ptr && m_offset == other.m_offset;
58 return m_container_ptr != other.m_container_ptr || m_offset != other.m_offset;
63 auto NdArray<T>::Iterator<Const>::operator*() -> value_t& {
64 return m_container_ptr->at(m_offset);
69 auto NdArray<T>::Iterator<Const>::operator*() const -> value_t {
70 return m_container_ptr->at(m_offset);
75 auto NdArray<T>::Iterator<Const>::operator+=(
size_t n) -> Iterator& {
82 auto NdArray<T>::Iterator<Const>::operator+(
size_t n) -> Iterator {
83 return Iterator{m_container_ptr, m_offset + n};
88 auto NdArray<T>::Iterator<Const>::operator-=(
size_t n) -> Iterator& {
89 assert(n <= m_offset);
96 auto NdArray<T>::Iterator<Const>::operator-(
size_t n) -> Iterator {
97 assert(n <= m_offset);
98 return Iterator{m_container_ptr, m_offset - n};
101 template <
typename T>
102 template <
bool Const>
103 auto NdArray<T>::Iterator<Const>::operator-(
const Iterator& other) -> difference_type {
104 assert(m_container_ptr == other.m_container_ptr);
105 return m_offset - other.m_offset;
108 template <
typename T>
109 template <
bool Const>
110 auto NdArray<T>::Iterator<Const>::operator[](
size_t i) -> value_t& {
111 return m_container_ptr->at(m_offset + i);
114 template <
typename T>
115 template <
bool Const>
116 bool NdArray<T>::Iterator<Const>::operator<(
const Iterator& other) {
117 assert(m_container_ptr == other.m_container_ptr);
118 return m_offset < other.m_offset;
121 template <
typename T>
122 template <
bool Const>
123 bool NdArray<T>::Iterator<Const>::operator>(
const Iterator& other) {
124 assert(m_container_ptr == other.m_container_ptr);
125 return m_offset > other.m_offset;
128 template <
typename T>
132 , m_container(
new ContainerWrapper<std::vector>(m_size)) {
136 template <
typename T>
137 template <
template <
class...>
class Container>
141 , m_container{
new ContainerWrapper<Container>(data)} {
142 if (m_size != m_container->size()) {
148 template <
typename T>
149 template <
template <
class...>
class Container>
153 , m_container{
new ContainerWrapper<Container>(
std::move(data))} {
154 if (m_size != m_container->size()) {
160 template <
typename T>
161 template <
typename II>
165 , m_container{
new ContainerWrapper<std::vector>(ibegin, iend)} {
166 if (m_size != m_container->size()) {
172 template <
typename T>
173 NdArray<T>::NdArray(
const self_type* other)
174 : m_shape{other->m_shape}
175 , m_attr_names{other->m_attr_names}
177 , m_container{other->m_container->copy()} {
187 template <
typename T>
188 template <
typename... Args>
190 : NdArray{appendAttrShape(shape_, attr_names.
size()), std::forward<Args>(args)...} {
191 m_attr_names = attr_names;
194 template <
typename T>
196 if (!m_attr_names.empty())
200 if (new_size != m_size) {
201 throw std::range_error(
"New shape does not match the number of contained elements");
208 template <
typename T>
209 template <
typename... D>
210 auto NdArray<T>::reshape(
size_t i, D... rest) -> self_type& {
212 return reshape_helper(acc, rest...);
215 template <
typename T>
217 auto offset = get_offset(coords);
218 return m_container->at(offset);
221 template <
typename T>
223 auto offset = get_offset(coords);
224 return m_container->at(offset);
227 template <
typename T>
229 auto offset = get_offset(coords, attr);
230 return m_container->at(offset);
233 template <
typename T>
235 auto offset = get_offset(coords, attr);
236 return m_container->at(offset);
239 template <
typename T>
240 template <
typename... D>
241 T& NdArray<T>::at(
size_t i, D... rest) {
243 return at_helper(acc, rest...);
246 template <
typename T>
247 template <
typename... D>
248 const T& NdArray<T>::at(
size_t i, D... rest)
const {
250 return at_helper(acc, rest...);
253 template <
typename T>
254 auto NdArray<T>::begin() -> iterator {
255 return iterator{m_container.get(), 0};
258 template <
typename T>
259 auto NdArray<T>::end() -> iterator {
260 return iterator{m_container.get(), m_size};
263 template <
typename T>
264 auto NdArray<T>::begin() const -> const_iterator {
265 return const_iterator{m_container.get(), 0};
268 template <
typename T>
269 auto NdArray<T>::end() const -> const_iterator {
270 return const_iterator{m_container.get(), m_size};
273 template <
typename T>
274 size_t NdArray<T>::size()
const {
278 template <
typename T>
279 bool NdArray<T>::operator==(
const self_type& b)
const {
280 if (shape() != b.shape())
282 for (
auto ai =
begin(), bi = b.begin(); ai !=
end() && bi != b.end(); ++ai, ++bi) {
289 template <
typename T>
291 return !(*
this == b);
294 template <
typename T>
299 template <
typename T>
300 auto NdArray<T>::concatenate(
const self_type& other) -> self_type& {
302 if (m_shape.size() != other.m_shape.size()) {
303 throw std::length_error(
"Can not concatenate arrays with different dimensionality");
305 for (
size_t i = 1; i < m_shape.size(); ++i) {
306 if (m_shape[i] != other.m_shape[i])
307 throw std::length_error(
"The size of all axis except for the first one must match");
311 auto old_size = m_container->size();
312 auto new_shape = m_shape;
313 new_shape[0] += other.m_shape[0];
316 m_container->resize(new_shape);
325 template <
typename T>
327 if (coords.
size() != m_shape.size()) {
333 for (
size_t i = 0; i < coords.
size(); ++i) {
334 if (coords[i] >= m_shape[i]) {
337 offset += coords[i] * m_stride_size[i];
340 assert(offset < m_container->size());
344 template <
typename T>
346 auto i =
std::find(m_attr_names.begin(), m_attr_names.end(), attr);
347 if (i == m_attr_names.end())
349 auto last = i - m_attr_names.begin();
351 return get_offset(coords);
354 template <
typename T>
355 void NdArray<T>::update_strides() {
356 m_stride_size.resize(m_shape.size());
359 for (
size_t i = m_stride_size.size(); i > 0; --i) {
360 m_stride_size[i - 1] = acc;
361 acc *= m_shape[i - 1];
368 template <
typename T>
369 template <
typename... D>
372 return at_helper(acc, rest...);
375 template <
typename T>
380 template <
typename T>
382 return at(acc, attr);
385 template <
typename T>
386 template <
typename... D>
389 return at_helper(acc, rest...);
392 template <
typename T>
397 template <
typename T>
398 template <
typename... D>
399 auto NdArray<T>::reshape_helper(
std::vector<size_t>& acc,
size_t i, D... rest) -> self_type& {
401 return reshape_helper(acc, rest...);
404 template <
typename T>
409 template <
typename T>
410 std::ostream& operator<<(std::ostream& out, const NdArray<T>& ndarray) {
411 auto shape = ndarray.shape();
413 if (ndarray.size()) {
416 for (i = 0; i < shape.
size() - 1; ++i) {
417 out << shape[i] <<
",";
419 out << shape[i] <<
">";
421 auto iter = ndarray.
begin(), end_iter = ndarray.end() - 1;
422 for (; iter != end_iter; ++iter) {
433 #endif // NDARRAY_IMPL
bool operator!=(const Euclid::SourceCatalog::Source::id_type &a, const Euclid::SourceCatalog::Source::id_type &b)
boost::variant specifies an equality operator (==), but, in older boost versions, not an inequality o...