Я сейчас создаю пример xtensor «структуры, включающие форму и шаги», чтобы использовать его для класса изображения с собственной информацией заголовка. Я дошел до этого:
#include <xtensor/xadapt.hpp>
#include <xtensor/xstrides.hpp>
// see https://github.com/xtensor-stack/xtensor/blob/master/docs/source/external-structures.rst
template <class T>
struct raw_tensor {
using container_type = std::vector<T>;
using shape_type = std::vector<std::size_t>;
container_type
m_data;
shape_type
m_shape,
m_strides,
m_backstrides;
static constexpr xt::layout_type
layout = xt::layout_type::dynamic;
};
template <class T>
class raw_tensor_adaptor;
template <class T>
struct xt::xcontainer_inner_types<raw_tensor_adaptor<T>> {
using container_type = typename raw_tensor<T>::container_type;
using inner_shape_type = typename raw_tensor<T>::shape_type;
using inner_strides_type = inner_shape_type;
using inner_backstrides_type = inner_shape_type;
using shape_type = inner_shape_type;
using strides_type = inner_shape_type;
using backstrides_type = inner_shape_type;
static constexpr layout_type layout = raw_tensor<T>::layout;
};
template <class T>
struct xt::xiterable_inner_types<raw_tensor_adaptor<T>>
: xcontainer_iterable_types<raw_tensor_adaptor<T>> {
};
template <class T>
class raw_tensor_adaptor : public xt::xcontainer<raw_tensor_adaptor<T>>,
public xt::xcontainer_semantic<raw_tensor_adaptor<T>> {
public:
using self_type = raw_tensor_adaptor<T>;
using base_type = xt::xcontainer<self_type>;
using semantic_base = xt::xcontainer_semantic<self_type>;
raw_tensor_adaptor(const raw_tensor_adaptor&) = default;
raw_tensor_adaptor& operator=(const raw_tensor_adaptor&) = default;
raw_tensor_adaptor(raw_tensor_adaptor&&) = default;
raw_tensor_adaptor& operator=(raw_tensor_adaptor&&) = default;
template <class E>
raw_tensor_adaptor(const xt::xexpression<E>& e) : base_type() {
semantic_base::assign(e);
}
template <class E>
self_type& operator=(const xt::xexpression<E>& e) {
return semantic_base::operator=(e);
}
};
int main() {
raw_tensor<double> i,j,k; // this works
using tensor_type = raw_tensor_adaptor<double>;
// tensor_type a, b, c; // but not this if un-commented
// .... init a, b, c
// tensor_type d = a + b - c; raw_tensor < int > a;
return 0;
}
При использовании функции main()
, которая просто объявляет объекты класса raw_tensor<double>
, компиляция завершается без ошибок.
В Linux (с gcc-11) я могу (повторно) запустить этот пример, выполнив:
$ cd /tmp && mkdir -p xtensor-test && cd xtensor-test
$ git clone https://github.com/xtensor-stack/xtensor.git
$ git clone https://github.com/xtensor-stack/xtl.git
$ vi xtensor-test.cpp # insert the code block above and save
$ g++ -o xtensor-test xtensor-test.cpp -Ixtensor/include -Ixtl/include
Однако я не могу сделать следующее:
resize()
или аксессора: когда я добавляю функции resize()
(без параметра шаблона T
) внутри класса, это не работает, поскольку внутренние типы и члены shape_type
, m_shape
и т. д. неизвестны. Но это единственное место, где можно перегрузиться resize()
, правда?using tensor_type = raw_tensor_adaptor<double>;
tensor_type a, b, c;
Когда я объявляю эти адаптеры, строка a, b, c
генерирует следующие ошибки:
include/xtensor/xiterable.hpp:288:19: error: no type named 'xexpression_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >’
include/xtensor/xaccessible.hpp:35:15: error: no type named 'reference' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >’
include/xtensor/xaccessible.hpp:36:15: error: no type named 'const_reference' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >’
include/xtensor/xaccessible.hpp:37:15: error: no type named 'size_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >’
include/xtensor/xaccessible.hpp:47:48: error: no type named 'const_reference' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >’
include/xtensor/xaccessible.hpp:111:26: error: 'at' has not been declared in 'using base_type = class
include/xtensor/xaccessible.hpp:112:35: error: 'operator[]' has not been declared in 'using base_type = class xt::xconst_accessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xconst_accessible<raw_tensor_adaptor<double> >’}
include/xtensor/xaccessible.hpp:113:26: error: 'back' has not been declared in 'using base_type = class xt::xconst_accessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xconst_accessible<raw_tensor_adaptor<double> >’}
include/xtensor/xaccessible.hpp:114:26: error: 'front' has not been declared in 'using base_type = class xt::xconst_accessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xconst_accessible<raw_tensor_adaptor<double> >’}
include/xtensor/xaccessible.hpp:115:26: error: 'periodic' has not been declared in 'using base_type = class xt::xconst_accessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xconst_accessible<raw_tensor_adaptor<double> >’}
include/xtensor/xcontainer.hpp:79:15: error: no type named 'storage_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:80:15: error: no type named 'storage_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:82:15: error: no type named 'reference' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:83:15: error: no type named 'const_reference' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:86:15: error: no type named 'size_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:88:15: error: no type named 'storage_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:89:15: error: no type named 'storage_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:107:15: error: no type named 'storage_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:108:15: error: no type named 'storage_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >'
include/xtensor/xcontainer.hpp:140:32: error: 'at' has not been declared in 'using accessible_base = class xt::xaccessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xaccessible<raw_tensor_adaptor<double> >’}
include/xtensor/xcontainer.hpp:141:32: error: 'shape' has not been declared in 'using accessible_base = class xt::xaccessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xaccessible<raw_tensor_adaptor<double> >’}
include/xtensor/xcontainer.hpp:142:41: error: 'operator[]' has not been declared in 'using accessible_base = class xt::xaccessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xaccessible<raw_tensor_adaptor<double> >’}
include/xtensor/xcontainer.hpp:143:32: error: 'back' has not been declared in 'using accessible_base = class xt::xaccessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xaccessible<raw_tensor_adaptor<double> >’}
include/xtensor/xcontainer.hpp:144:32: error: 'front' has not been declared in 'using accessible_base = class xt::xaccessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xaccessible<raw_tensor_adaptor<double> >’}
include/xtensor/xcontainer.hpp:146:32: error: 'periodic' has not been declared in 'using accessible_base = class xt::xaccessible<raw_tensor_adaptor<double> >’ {aka ‘class xt::xaccessible<raw_tensor_adaptor<double> >’}
include/xtensor/xcontainer.hpp:182:15: error: no type named 'storage_type' in 'struct
include/xtensor/xsemantic.hpp:64:15: error: no type named 'temporary_type' in 'struct xt::xcontainer_inner_types<raw_tensor_adaptor<double> >’
из заголовков xtensor
и
xtensor-test.cpp:70:13: error: no matching function for call to ‘raw_tensor_adaptor<double>::raw_tensor_adaptor()’
tensor_type a, b, c; // but not this if un-commented
^
xtensor-test.cpp:55:5: note: candidate: ‘template<class E> raw_tensor_adaptor<T>::raw_tensor_adaptor(const xt::xexpression<E>&)’
raw_tensor_adaptor(const xt::xexpression<E>& e) : base_type() {
^~~~~~~~~~~~~~~~~~
xtensor-test.cpp:55:5: note: template argument deduction/substitution failed:
xtensor-test.cpp:70:13: note: candidate expects 1 argument, 0 provided
tensor_type a, b, c; // but not this if un-commented
^
xtensor-test.cpp:51:5: note: candidate: ‘raw_tensor_adaptor<T>::raw_tensor_adaptor(raw_tensor_adaptor<T>&&) [with T = double]’
raw_tensor_adaptor(raw_tensor_adaptor&&) = default;
^~~~~~~~~~~~~~~~~~
xtensor-test.cpp:51:5: note: candidate expects 1 argument, 0 provided
xtensor-test.cpp:49:5: note: candidate: ‘raw_tensor_adaptor<T>::raw_tensor_adaptor(const raw_tensor_adaptor<T>&) [with T = double]’
raw_tensor_adaptor(const raw_tensor_adaptor&) = default;
^~~~~~~~~~~~~~~~~~
xtensor-test.cpp:49:5: note: candidate expects 1 argument, 0 provided
xtensor-test.cpp:49:5: note: candidate: ‘raw_tensor_adaptor<T>::raw_tensor_adaptor(const raw_tensor_adaptor<T>&) [with T = double]’
raw_tensor_adaptor(const raw_tensor_adaptor&) = default;
^~~~~~~~~~~~~~~~~~
из файла .cpp
На веб-странице указано определить семантику и реализовать методы и функции, специфичные для структуры raw_tensor. Но у меня такое ощущение, что я делаю это не в том месте.
Есть ли у кого-нибудь этот пример для работы с экземпляром raw_tensor_adaptor? Большое спасибо!
Это прямо упомянуто в как спросить: ссылки допустимы как дополнение, а не как замена рассматриваемого кода. «80 строк» звучит не слишком долго. Взамен вы можете удалить текст, объясняющий, какие классы вы определили, потому что это будет очевидно после публикации реального кода.
Спасибо @user12002570 и @pptaszni; Я поместил сюда код и удалил ссылку/объяснение того, что находится в файле. Я также добавил минимально возможное количество команд, чтобы повторить пример в Linux.
Вы пытались добавить конструктор по умолчанию для raw_tensor_adaptor
?
Я пробовал, но, как и в случае с методами resize()
из примера, похоже, я делаю что-то не так, потому что внутренние типы и свойства не видны. Я должен их инициализировать, но они уже должны были быть объявлены?
На веб-странице указано реализовать интерфейс класса table_adaptor
, который определяет все типы, которые, учитывая ваши ошибки времени компиляции, на данный момент неизвестны. Однако указанная выше часть класса отсутствует в вашем примере. Вы включили это?
Действительно, веб-страница, похоже, предлагает сложную систему взаимозависимых классов, и поэтому невозможно объявить только некоторые из них, чтобы получить правильно сформированную программу.
Действительно? У меня сложилось впечатление, что «структуры, включающие форму и шаги» и «встраивающие полную тензорную структуру» — это два разных примера. Я думал, что код первого будет ближе к работающей программе.
Ошибки времени компиляции относятся к некоторым заголовкам, например xcontainer.hpp
. Это означает, что в примере отсутствуют другие части. Вам тоже необходимо их реализовать.
Боюсь, ничего не работает - я понимаю, что мне нужно предоставить операторы типа at()
и back()
, но недостающие типы, такие как storage_type
, я не понимаю, что там должно происходить. Это суть данного поста.
Я хотел использовать этот пример, чтобы создать класс для изображений NIfTI , сканирований мозга, которые могут быть 2D, 3D или 4D (тип данных допускает до 7D). Информация о пространственной ориентации и т. д. приведена в заголовке, и мне показалось, что класс со всей функциональностью xtensor, но также с присоединенной информацией заголовка, был бы идеальным.
Глядя на стандартный способ доступа к этим файлам на Python (с помощью nibabel ), я понял, что полезнее иметь класс, который имеет как заголовок , так и данные пикселя в качестве отдельных свойств. , а математические операции лучше выполнять с данными пикселей (как с объектом xtensor) вне объекта nifti. Этот класс не наследуется от xtensor, что делает многие вещи намного проще для всех.
Приведите минимально воспроизводимый пример