-
Notifications
You must be signed in to change notification settings - Fork 5
Dynamic Subtensor Docs
Subtensors are used to adapt the shape of an dynamic_tensor
without changing it, nor copying it. Subtensors are convinient tools for assigning parts of an expression: since they do not copy the underlying tensor
, assigning to the subtensor
actually assigns to the underlying expression.
For dynamic_tensor
the following example shows the ways in which spans
can be specified.
The subtensor is an alias for the type :
template<typename T>
tensor_core<subtensor_engine<T>>
where T is the parent tensor.
Thus a subtensor for a dynamic tensor has the following type:
template<class V/*Value type*/, class L/*Layout*/>
tensor_core<subtensor_engine<tensor_dynamic<V,L>>>
#include <boost/numeric/ublas/tensor.hpp>
namespace ublas = boost::numeric::ublas;
using value = float;
using layout = ublas::layout::first_order; // storage format
using tensor = boost::numeric::ublas::tensor_dynamic<value,layout>;
constexpr auto ones = ublas::ones<value,layout>{};
using span = ublas::span<>;
tensor a = ones(3,2,4);
auto s1 = a(span(1,2), span(), span(1,2));
// => s1.extents() = {2, 2, 2}
// => s1(0, 0, 0) = a(1, 0, 1)
// => s1(1, 1, 1) = a(2 ,1, 2)
auto s2 = a(span(1,1), span(), span(0,2,3));
// => s2.extents() = {1, 2, 2}
// => s2(0, 0, 0) = a(1, 0, 0)
// => s2(0, 1, 1) = a(1, 1, 2)
We can also create subtensors of subtensors:
tensor a = ones(3,2,4);
auto s1 = a(span(1,2), span(), span(1,2));
// => s1.extents() = {2, 2, 2}
// => s1(0, 0, 0) = a(1, 0, 1)
// => s1(1, 1, 1) = a(2 ,1, 2)
auto s2 = s1(span(1,1), span(), span());
// => s2.extents() = {1, 2, 2}
// => s2(0, 0, 0) = a(1, 0, 0)
// => s2(0, 1, 1) = a(1, 1, 2)
In this case subtensor s2
still points towards the data from the parent tensor
i,e a
.
One can also create subtensors using the subtensor helper function:
tensor a = ones(3,2,4);
auto s1 = subtensor(a, span(1,2), span(), span(1,2));
// => s1.extents() = {2, 2, 2}
// => s1(0, 0, 0) = a(1, 0, 1)
// => s1(1, 1, 1) = a(2 ,1, 2)
auto v2 = subtensor(s1, span(1,1), span(), span());
// => s2.extents() = {1, 2, 2}
// => s2(0, 0, 0) = a(1, 0, 0)
// => s2(0, 1, 1) = a(1, 1, 2)
The subtensors can be used interchangeably with tensors in arithmetic and comparison expressions.
tensor t1 = ones(4,5,5);
auto A = t1(span(2), span(4), span()); // shape (3,4,5)
auto B = A(span(), span(), span()); // shape (3,4,5)
tensor t2 = ones(1,2,2);
tensor t3 = t2 * B + A;
t3 += A;
t3 = -A;
tensor t4 = ublas::inner_product(A, t2);
tensor t5 = ublas::outer_product(A, t2);
tensor c1 = ones(5, 5);
tensor c2 = c1 + A(_i,_j,_m)*A(_i,_j,_l) + 5;
tensor c1 = ones(5, 5);
tensor c2 = c1 + A(_i,_j,_m)*A(_i,_j,_l) + 5;
tensor c1 = ones(5, 5);
tensor c2 = c1 + A(_i,_j,_m)*A(_i,_j,_l) + 5;
std::cout << A << std::endl;
We both would like to thank our mentor Cem Bassoy for his constant support and help in achieving our milestones. From conducting regular meetings and providing indispensable information and suggestions, to the helpfulness in always answering our queries we always find him extremely helpful and his contribution towards our projects is massive. We are grateful for the time and efforts he devoted towards our projects. We would also like to thank Google for the Google Summer of Code Programme, without which all these wouldn't be possible. We would like to take the opportunity to thank the members of the of Boost Community for letting us be a part of this wonderful journey.