Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // solution.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
- #include <memory>
- #include <vector>
- #include <algorithm>
- #include <cstdint>
- #include <iostream>
- #include <numeric>
- template <class T> class TensorImpl {
- public:
- virtual std::vector<size_t> dim() const = 0;
- virtual const T &operator[](const std::vector<size_t> &pos) const = 0;
- virtual T &operator[](const std::vector<size_t> &pos) = 0;
- };
- template <class T> class TensorImplData : public TensorImpl<T> {
- private:
- std::vector<size_t> dimSizes_;
- std::vector<T> data_;
- public:
- TensorImplData(std::vector<size_t> dimSizes, size_t data_size)
- : dimSizes_(dimSizes), data_(data_size) {};
- static std::shared_ptr<TensorImpl<T>>
- New(const std::vector<size_t> &dimSizes) {
- size_t data_size = std::accumulate(dimSizes.begin(), dimSizes.end(), 1,
- std::multiplies<int>());
- return std::make_shared<TensorImplData<T>>(dimSizes, data_size);
- };
- virtual std::vector<size_t> dim() const override { return dimSizes_; };
- virtual const T &operator[](const std::vector<size_t> &pos) const override {
- if (pos.size() != dimSizes_.size())
- throw std::invalid_argument("Wrong pos");
- size_t pos_in_data = 0;
- for (size_t i = 0; i < pos.size(); ++i) {
- pos_in_data *= dimSizes_[i];
- pos_in_data += pos[i];
- }
- return data_[pos_in_data];
- };
- virtual T &operator[](const std::vector<size_t> &pos)override {
- if (pos.size() != dimSizes_.size())
- throw std::invalid_argument("Wrong pos");
- size_t pos_in_data = 0;
- for (size_t i = 0; i < pos.size(); ++i) {
- pos_in_data *= dimSizes_[i];
- pos_in_data += pos[i];
- }
- return data_[pos_in_data];
- }
- };
- template <class T> class TensorImplRed : public TensorImpl<T> {
- std::shared_ptr<TensorImpl<T>> prev_;
- size_t pos_;
- public:
- TensorImplRed(std::shared_ptr<TensorImpl<T>> prev, size_t pos)
- : prev_(prev), pos_(pos) {};
- static std::shared_ptr<TensorImpl<T>> New(std::shared_ptr<TensorImpl<T>> prev,
- size_t pos) {
- return std::make_shared<TensorImplRed>(prev, pos);
- }
- virtual std::vector<size_t> dim() const override {
- std::vector<size_t> tmp = prev_->dim();
- return std::vector<size_t>(tmp.begin() + 1, tmp.end());
- };
- virtual const T &operator[](const std::vector<size_t> &pos) const override {
- std::vector<size_t> pos_in_prev(pos.size() + 1);
- pos_in_prev[0] = pos_;
- std::copy(pos.begin(), pos.end(), pos_in_prev.begin() + 1);
- return (*prev_)[pos_in_prev];
- }
- virtual T &operator[](const std::vector<size_t> &pos)override {
- std::vector<size_t> pos_in_prev(pos.size() + 1);
- pos_in_prev[0] = pos_;
- std::copy(pos.begin(), pos.end(), pos_in_prev.begin() + 1);
- return (*prev_)[pos_in_prev];
- }
- };
- template <class T> class TensorImplRange : public TensorImpl<T> {
- std::shared_ptr<TensorImpl<T>> prev_;
- size_t low_;
- size_t high_;
- public:
- TensorImplRange(std::shared_ptr<TensorImpl<T>> prev, size_t low, size_t high)
- : prev_(prev), low_(low), high_(high) {};
- static std::shared_ptr<TensorImpl<T>> New(std::shared_ptr<TensorImpl<T>> prev,
- size_t low, size_t high) {
- return std::make_shared<TensorImplRange<T>>(prev, low, high);
- }
- virtual std::vector<size_t> dim() const override {
- std::vector<size_t> tmp = prev_->dim();
- tmp[0] = high_ - low_;
- return tmp;
- };
- virtual const T &operator[](const std::vector<size_t> &pos) const override {
- std::vector<size_t> pos_in_prev = pos;
- pos_in_prev[0] += low_;
- return (*prev_)[pos_in_prev];
- }
- virtual T &operator[](const std::vector<size_t> &pos)override {
- std::vector<size_t> pos_in_prev = pos;
- pos_in_prev[0] += low_;
- return (*prev_)[pos_in_prev];
- }
- };
- template <class T> class Tensor {
- public:
- /*
- * Empty constructor initialized empty tensor
- */
- Tensor() = default;
- /*
- * Constructor with dimensions sizes
- * data is initialized by default T ()
- */
- Tensor(const std::vector<size_t> &dimSizes)
- : ptr(TensorImplData<T>::New(dimSizes)) {}
- /*
- * Copy - constructor
- */
- Tensor(const Tensor &rhs) = default;
- /*
- * Returns dimensions sizes of tensor
- */
- std::vector<size_t> dim() const { return ptr->dim(); }
- /*
- * Returns sub - tensor with indices in first dimension [ low ,
- high )
- */
- const Tensor operator()(size_t low, size_t high) const {
- Tensor new_tensor;
- new_tensor.ptr = TensorImplRange<T>::New(ptr, low, high);
- return new_tensor;
- }
- /*
- * Returns sub - tensor with indices in first dimension [ low ,
- high )
- * !!! All changes applied further to sub - tensor would be
- applied to this tensor as well and vice versa as well ,
- in other words they would share their content !!!
- 1
- */
- Tensor operator()(size_t low, size_t high) {
- Tensor new_tensor;
- new_tensor.ptr = TensorImplRange<T>::New(ptr, low, high);
- return new_tensor;
- }
- /*
- * Returns sub - tensor with index in first dimension pos
- */
- const Tensor operator()(size_t pos) const {
- Tensor new_tensor;
- new_tensor.ptr = TensorImplRed<T>::New(ptr, pos);
- return new_tensor;
- }
- /*
- * Returns sub - tensor with index in first dimension pos
- * !!! All changes applied further to sub - tensor would be
- applied to this tensor as well and vice versa as well ,
- in other words they would share their content !!!
- */
- Tensor operator()(size_t pos) {
- Tensor new_tensor;
- new_tensor.ptr = TensorImplRed<T>::New(ptr, pos);
- return new_tensor;
- }
- /*
- * Returns value indexed by { pos [0] , pos [1] , pos [2]... pos [
- dim - 1]}
- * pos . size () should be equal to dim
- */
- const T &operator[](std::vector<size_t> pos) const { return (*ptr)[pos]; }
- /*
- * Returns value indexed by { pos [0] , pos [1] , pos [2]... pos [
- dim - 1]}
- * pos . size () should be equal to dim
- */
- T &operator[](std::vector<size_t> pos) { return (*ptr)[pos]; };
- private:
- std::shared_ptr<TensorImpl<T>> ptr;
- };
- template <class T> void print_tensor(const Tensor<T> tensor) {
- std::cout << "{ 'Tensor': { 'dim': ";
- for (auto &&n : tensor.dim()) {
- std::cout << n << ", ";
- }
- std::cout << "}}\n";
- }
- int main() {
- //Tensor<double> A({ 9, 8, 7, 6 });
- //print_tensor(A);
- //print_tensor(A(1, 2));
- //print_tensor(A(1)(2));
- //A[{1, 2, 3, 4}] = 3.1415926;
- //std::cout << (A(1)(2)(3)[{4}]) << std::endl;
- //std::cout << (A(1, 2)[{0, 2, 3, 4}]) << std::endl;
- Tensor <int> t({ 3,5 });
- t[{1, 0}] = 5;
- // cout << t[{1, 2}];
- Tensor <int> t2 = t;
- //cout << t2[{1, 2}];
- //Tensor <int> *test = &t(1);
- Tensor <int> subT = t(1);
- std::cout << (subT)[{0}];
- return 0;
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement