The `Tensor`

class is probably the most important class in
`Torch`

. Almost every package depends on this class. It is * the*
class for handling numeric data. As with pretty much anything in
Torch7, tensors are
serializable.

**Multi-dimensional matrix**

A `Tensor`

is a potentially multi-dimensional matrix. The number of
dimensions is unlimited that can be created using
LongStorage with more dimensions.

Example:

```
--- creation of a 4D-tensor 4x5x6x2
z = torch.Tensor(4,5,6,2)
--- for more dimensions, (here a 6D tensor) one can do:
s = torch.LongStorage(6)
s[1] = 4; s[2] = 5; s[3] = 6; s[4] = 2; s[5] = 7; s[6] = 3;
x = torch.Tensor(s)
```

The number of dimensions of a `Tensor`

can be queried by
nDimension() or
dim(). Size of the `i-th`

dimension is
returned by size(i). A LongStorage
containing all the dimensions can be returned by
size().

```
> print(x:nDimension())
6
> print(x:size())
4
5
6
2
7
3
[torch.LongStorage of size 6]
```

**Internal data representation**

The actual data of a `Tensor`

is contained into a
Storage. It can be accessed using
`storage()`

. While the memory of a
`Tensor`

has to be contained in this unique `Storage`

, it might
not be contiguous: the first position used in the `Storage`

is given
by `storageOffset()`

(starting at
`1`

). And the *jump* needed to go from one element to another
element in the `i-th`

dimension is given by
`stride(i)`

. In other words, given a 3D
tensor

```
x = torch.Tensor(7,7,7)
```

accessing the element `(3,4,5)`

can be done by

```
= x[3][4][5]
```

or equivalently (but slowly!)

```
= x:storage()[x:storageOffset()
+(3-1)*x:stride(1)+(4-1)*x:stride(2)+(5-1)*x:stride(3)]
```

One could say that a `Tensor`

is a particular way of *viewing* a
`Storage`

: a `Storage`

only represents a chunk of memory, while the
`Tensor`

interprets this chunk of memory as having dimensions:

```
> x = torch.Tensor(4,5)
> s = x:storage()
> for i=1,s:size() do -- fill up the Storage
>> s[i] = i
>> end
> print(x) -- s is interpreted by x as a 2D matrix
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
[torch.DoubleTensor of dimension 4x5]
```

Note also that in Torch7 ** elements in the same row** [elements along the

```
> x = torch.Tensor(4,5)
> i = 0
>
> x:apply(function()
>> i = i + 1
>> return i
>> end)
>
> print(x)
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
[torch.DoubleTensor of dimension 4x5]
> return x:stride()
5
1 -- element in the last dimension are contiguous!
[torch.LongStorage of size 2]
```

This is exactly like in C (and not `Fortran`

).

**Tensors of different types**

Actually, several types of `Tensor`

exists:

```
ByteTensor -- contains unsigned chars
CharTensor -- contains signed chars
ShortTensor -- contains shorts
IntTensor -- contains ints
FloatTensor -- contains floats
DoubleTensor -- contains doubles
```

Most numeric operations are implemented *only* for `FloatTensor`

and `DoubleTensor`

.
Other Tensor types are useful if you want to save memory space.

**Default Tensor type**

For convenience, *an alias* `torch.Tensor`

is provided, which allows the user to write
type-independent scripts, which can then ran after choosing the desired Tensor type with
a call like

```
torch.setdefaulttensortype('torch.FloatTensor')
```

See torch.setdefaulttensortype for more details.
By default, the alias "points" on `torch.DoubleTensor`

.

**Efficient memory management**

*All* tensor operations in this class do *not* make any memory copy. All
these methods transform the existing tensor, or return a new tensor
referencing *the same storage*. This magical behavior is internally
obtained by good usage of the stride() and
storageOffset(). Example:

```
> x = torch.Tensor(5):zero()
> print(x)
0
0
0
0
0
[torch.DoubleTensor of dimension 5]
> x:narrow(1, 2, 3):fill(1) -- narrow() returns a Tensor
-- referencing the same Storage as x
> print(x)
0
1
1
1
0
[torch.Tensor of dimension 5]
```

If you really need to copy a `Tensor`

, you can use the copy() method:

```
> y = torch.Tensor(x:size()):copy(x)
```

Or the convenience method

```
> y = x:clone()
```

We now describe all the methods for `Tensor`

. If you want to specify the Tensor type,
just replace `Tensor`

by the name of the Tensor variant (like `CharTensor`

).

Tensor constructors, create new Tensor object, optionally, allocating
new memory. By default the elements of a newly allocated memory are
not initialized, therefore, might contain arbitrary numbers. Here are
several ways to construct a new `Tensor`

.

Returns an empty tensor.

Returns a new tensor which reference the same
Storage than the given `tensor`

. The
size, stride, and
storage offset are the same than the
given tensor.

The new `Tensor`

is now going to "view" the same storage
as the given `tensor`

. As a result, any modification in the elements
of the `Tensor`

will have a impact on the elements of the given
`tensor`

, and vice-versa. No memory copy!

```
> x = torch.Tensor(2,5):fill(3.14)
> print(x)
3.1400 3.1400 3.1400 3.1400 3.1400
3.1400 3.1400 3.1400 3.1400 3.1400
[torch.DoubleTensor of dimension 2x5]
> y = torch.Tensor(x)
> print(y)
3.1400 3.1400 3.1400 3.1400 3.1400
3.1400 3.1400 3.1400 3.1400 3.1400
[torch.DoubleTensor of dimension 2x5]
> y:zero()
> print(x) -- elements of x are the same as y!
0 0 0 0 0
0 0 0 0 0
[torch.DoubleTensor of dimension 2x5]
```

Create a tensor up to 4 dimensions. The tensor size will be `sz1 x sz2 x sx3 x sz4`

.

Create a tensor of any number of dimensions. The
LongStorage `sizes`

gives the size in each dimension of
the tensor. The optional LongStorage `strides`

gives the
jump necessary to go from one element to the next one in the each
dimension. Of course, `sizes`

and `strides`

must have the same
number of elements. If not given, or if some elements of `strides`

are *negative*, the stride() will be
computed such that the tensor is as contiguous as possible in memory.

Example, create a 4D 4x4x3x2 tensor:

```
x = torch.Tensor(torch.LongStorage({4,4,3,2}))
```

Playing with the strides can give some interesting things:

```
x = torch.Tensor(torch.LongStorage({4}), torch.LongStorage({0})):zero() -- zeroes the tensor
x[1] = 1 -- all elements point to the same address!
print(x)
1
1
1
1
[torch.DoubleTensor of dimension 4]
```

Note that *negative strides are not allowed*, and, if given as
argument when constructing the Tensor, will be interpreted as //choose
the right stride such that the Tensor is contiguous in memory//.

Returns a tensor which uses the existing Storage
`storage`

, starting at position `storageOffset`

(>=1). The size
of each dimension of the tensor is given by the
LongStorage `sizes`

.

If only `storage`

is provided, it will create a 1D Tensor viewing
the all Storage.

The jump necessary to go from one element to the next one in each
dimension is given by the optional argument LongStorage
`strides`

. If not given, or if some elements of `strides`

are
negative, the stride() will be computed such
that the tensor is as contiguous as possible in memory.

Any modification in the elements of the `Storage`

will have an
impact on the elements of the new `Tensor`

, and vice-versa. There is
no memory copy!

```
-- creates a storage with 10 elements
> s = torch.Storage(10):fill(1)
-- we want to see it as a 2x5 tensor
> x = torch.Tensor(s, 1, torch.LongStorage{2,5})
> print(x)
1 1 1 1 1
1 1 1 1 1
[torch.DoubleTensor of dimension 2x5]
> x:zero()
> print(s) -- the storage contents have been modified
> print(s)
0
0
0
0
0
0
0
0
0
0
[torch.DoubleStorage of size 10]
```

Convenience constructor (for the previous constructor) assuming a
number of dimensions inferior or equal to 4. `szi`

is the size in
the `i-th`

dimension, and `sti`

it the stride in the `i-th`

dimension.

The argument is assumed to be a Lua array of numbers. The constructor returns a new Tensor of the size of the table, containing all the table elements. The table might be multi-dimensional.

Example:

```
> = torch.Tensor({ {1,2,3,4}, {5,6,7,8} })
1 2 3 4
5 6 7 8
[torch.DoubleTensor of dimension 2x4]
```

Returns a clone of a tensor. The memory is copied.

```
i = 0
x = torch.Tensor(5):apply(function(x)
i = i + 1
return i
end)
= x
1
2
3
4
5
[torch.DoubleTensor of dimension 5]
-- create a clone of x
y = x:clone()
= y
1
2
3
4
5
[torch.DoubleTensor of dimension 5]
-- fill up y with 1
y:fill(1)
= y
1
1
1
1
1
[torch.DoubleTensor of dimension 5]
-- the contents of x were not changed:
= x
1
2
3
4
5
[torch.DoubleTensor of dimension 5]
```

- If the given Tensor contents are contiguous in memory, returns the exact same Tensor (no memory copy).
- Otherwise (_not contiguous in memory_), returns a clone (memory
*copy*).

```
x = torch.Tensor(2,3):fill(1)
= x
1 1 1
1 1 1
[torch.DoubleTensor of dimension 2x3]
-- x is contiguous, so y points to the same thing
y = x:contiguous():fill(2)
= y
2 2 2
2 2 2
[torch.DoubleTensor of dimension 2x3]
-- contents of x have been changed
= x
2 2 2
2 2 2
[torch.DoubleTensor of dimension 2x3]
-- x:t() is not contiguous, so z is a clone
z = x:t():contiguous():fill(3.14)
= z
3.1400 3.1400
3.1400 3.1400
3.1400 3.1400
[torch.DoubleTensor of dimension 3x2]
-- contents of x have not been changed
= x
2 2 2
2 2 2
[torch.DoubleTensor of dimension 2x3]
```

**If type is nil**, returns atring containing the type name of
the given tensor.

```
= torch.Tensor():type()
torch.DoubleTensor
```

**If type is a string** describing a Tensor type, and is equal to
the given tensor typename, returns the exact same tensor (//no memory
copy//).

```
x = torch.Tensor(3):fill(3.14)
= x
3.1400
3.1400
3.1400
[torch.DoubleTensor of dimension 3]
y = x:type('torch.DoubleTensor')
= y
3.1400
3.1400
3.1400
[torch.DoubleTensor of dimension 3]
-- zero y contents
y:zero()
-- contents of x have been changed
= x
0
0
0
[torch.DoubleTensor of dimension 3]
```

**If type is a string** describing a Tensor type, different from
the type name of the given Tensor, returns a new Tensor of the
specified type, whose contents corresponds to the contents of the
original Tensor, casted to the given type (//memory copy occurs, with
possible loss of precision//).

```
x = torch.Tensor(3):fill(3.14)
= x
3.1400
3.1400
3.1400
[torch.DoubleTensor of dimension 3]
y = x:type('torch.IntTensor')
= y
3
3
3
[torch.IntTensor of dimension 3]
```

Convenience method for the type method. Equivalent to

```
type(tensor:type())
```

Convenience methods for the type method. For e.g.,

```
x = torch.Tensor(3):fill(3.14)
= x
3.1400
3.1400
3.1400
[torch.DoubleTensor of dimension 3]
-- calling type('torch.IntTensor')
= x:type('torch.IntTensor')
3
3
3
[torch.IntTensor of dimension 3]
-- is equivalent to calling int()
= x:int()
3
3
3
[torch.IntTensor of dimension 3]
```

Returns the number of dimensions in a `Tensor`

.

```
> x = torch.Tensor(4,5) -- a matrix
> = x:nDimension()
2
```

Returns the size of the specified dimension `dim`

. Example:

```
> x = torch.Tensor(4,5):zero()
> print(x)
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
[torch.DoubleTensor of dimension 4x5]
> return x:size(2) -- gets the number of columns
5
```

Returns a LongStorage containing the size of each dimension of the tensor.

```
> x = torch.Tensor(4,5):zero()
> print(x)
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
[torch.DoubleTensor of dimension 4x5]
> return x:size()
4
5
[torch.LongStorage of size 2]
```

Returns the jump necessary to go from one element to the next one in the
specified dimension `dim`

. Example:

```
> x = torch.Tensor(4,5):zero()
> print(x)
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
[torch.DoubleTensor of dimension 4x5]
--- elements in a row are contiguous in memory
> return x:stride(2)
1
--- to go from one element to the next one in a column
--- we need here to jump the size of the row
> return x:stride(1)
5
```

Note also that in `Torch`

*elements in the same row* [elements along the **last** dimension]
are contiguous in memory for a matrix [tensor].

Returns the jump necessary to go from one element to the next one in each dimension. Example:

```
> x = torch.Tensor(4,5):zero()
> print(x)
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
[torch.DoubleTensor of dimension 4x5]
> return x:stride()
5
1 -- elements are contiguous in a row [last dimension]
[torch.LongStorage of size 2]
```

Note also that in `Torch`

*elements in the same row* [elements along the **last** dimension]
are contiguous in memory for a matrix [tensor].

Returns the Storage used to store all the elements of the `Tensor`

.
Basically, a `Tensor`

is a particular way of *viewing* a `Storage`

.

```
> x = torch.Tensor(4,5)
> s = x:storage()
> for i=1,s:size() do -- fill up the Storage
>> s[i] = i
>> end
> print(x) -- s is interpreted by x as a 2D matrix
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
[torch.DoubleTensor of dimension 4x5]
```

Returns `true`

iff the elements of the `Tensor`

are contiguous in memory.

```
-- normal tensors are contiguous in memory
> x = torch.Tensor(4,5):zero()
> = x:isContiguous()
true
-- y now "views" the 3rd column of x
-- the storage of y is the same than x
-- so the memory cannot be contiguous
> y = x:select(2, 3)
> = y:isContiguous()
false
-- indeed, to jump to one element to
-- the next one, the stride is 4
> = y:stride()
5
[torch.LongStorage of size 1]
```

Returns the number of elements of a tensor.

```
> x = torch.Tensor(4,5)
> = x:nElement() -- 4x5 = 20!
20
```

Return the first index (starting at 1) used in the tensor's storage.

Elements of a tensor can be retrieved with the `[index]`

operator.

If `index`

is a number, `[index]`

operator is equivalent to a
`select(1, index)`

if the tensor has more
than one dimension. If the tensor is a 1D tensor, it returns the value
at `index`

in this tensor.

If `index`

is a table, the table must contain *n* numbers, where
*n* is the number of dimensions of the
Tensor. It will return the element at the given position.

In the same spirit, `index`

might be a LongStorage,
specifying the position (in the Tensor) of the element to be
retrieved.

Example:

```
> x = torch.Tensor(3,3)
> i = 0; x:apply(function() i = i + 1; return i end)
> = x
1 2 3
4 5 6
7 8 9
[torch.DoubleTensor of dimension 3x3]
> = x[2] -- returns row 2
4
5
6
[torch.DoubleTensor of dimension 3]
> = x[2][3] -- returns row 2, column 3
6
> = x[{2,3}] -- another way to return row 2, column 3
6
> = x[torch.LongStorage{2,3}] -- yet another way to return row 2, column 3
6
```

A `Tensor`

being a way of *viewing* a Storage, it is
possible to "set" a `Tensor`

such that it views an existing Storage.

Note that if you want to perform a set on an empty `Tensor`

like

```
y = torch.Storage(10)
x = torch.Tensor()
x:set(y, 1, 10)
```

you might want in that case to use one of the equivalent constructor.

```
y = torch.Storage(10)
x = torch.Tensor(y, 1, 10)
```

The `Tensor`

is now going to "view" the same storage
as the given `tensor`

. As the result, any modification in the elements of
the `Tensor`

will have an impact on the elements of the given `tensor`

, and
vice-versa. This is an efficient method, as there is no memory copy!

```
> x = torch.Tensor(2,5):fill(3.14)
> print(x)
3.1400 3.1400 3.1400 3.1400 3.1400
3.1400 3.1400 3.1400 3.1400 3.1400
[torch.DoubleTensor of dimension 2x5]
> y = torch.Tensor():set(x)
> print(y)
3.1400 3.1400 3.1400 3.1400 3.1400
3.1400 3.1400 3.1400 3.1400 3.1400
[torch.DoubleTensor of dimension 2x5]
> y:zero()
> print(x) -- elements of x are the same than y!
0 0 0 0 0
0 0 0 0 0
[torch.DoubleTensor of dimension 2x5]
```

The `Tensor`

is now going to "view" the given
`storage`

, starting at position `storageOffset`

(>=1)
with the given dimension `sizes`

and the optional given
`strides`

. As the result, any modification in the
elements of the `Storage`

will have a impact on the elements of the
`Tensor`

, and vice-versa. This is an efficient method, as there is no
memory copy!

If only `storage`

is provided, the whole storage will be viewed as a 1D Tensor.

```
-- creates a storage with 10 elements
> s = torch.Storage(10):fill(1)
-- we want to see it as a 2x5 tensor
> sz = torch.LongStorage({2,5})
> x = torch.Tensor()
> x:set(s, 1, sz)
> print(x)
1 1 1 1 1
1 1 1 1 1
[torch.DoubleTensor of dimension 2x5]
> x:zero()
> print(s) -- the storage contents have been modified
> print(s)
0
0
0
0
0
0
0
0
0
0
[torch.DoubleStorage of size 10]
```

This is a "shorcut" for previous method.
It works up to 4 dimensions. `szi`

is the size of the `i`

-th dimension of the tensor.
`sti`

is the stride in the `i`

-th dimension.

Copy the elements of the given `tensor`

. The
number of elements must match, but the
sizes might be different.

```
> x = torch.Tensor(4):fill(1)
> y = torch.Tensor(2,2):copy(x)
> print(x)
1
1
1
1
[torch.DoubleTensor of dimension 4]
> print(y)
1 1
1 1
[torch.DoubleTensor of dimension 2x2]
```

If a different type of `tensor`

is given, then a type conversion occurs,
which, of course, might result in loss of precision.

Fill the tensor with the given `value`

.

```
> = torch.DoubleTensor(4):fill(3.14)
3.1400
3.1400
3.1400
3.1400
[torch.DoubleTensor of dimension 4]
```

Fill the tensor with zeros.

```
> = torch.Tensor(4):zero()
0
0
0
0
[torch.DoubleTensor of dimension 4]
```

**When resizing to a larger size**, the underlying Storage is resized to fit
all the elements of the `Tensor`

.

**When resizing to a smaller size**, the underlying Storage is not resized.

**Important note:** the content of a `Tensor`

after resizing is *undertermined* as strides
might have been completely changed. In particular, *the elements of the resized tensor are contiguous in memory*.

Resize the `tensor`

as the given `tensor`

(of the same type).

Resize the `tensor`

according to the given LongStorage `size`

.

Convenience method of the previous method, working for a number of dimensions up to 4.

Each of these methods returns a `Tensor`

which is a sub-tensor of the given
tensor, *with the same Storage*. Hence, any modification in the memory of
the sub-tensor will have an impact on the primary tensor, and vice-versa.

These methods are very fast, as they do not involve any memory copy.

Returns a new `Tensor`

which is a narrowed version of the current one: the dimension `dim`

is narrowed
from `index`

to `index+size-1`

.

```
> x = torch.Tensor(5, 6):zero()
> print(x)
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
[torch.DoubleTensor of dimension 5x6]
> y = x:narrow(1, 2, 3) -- narrow dimension 1 from index 2 to index 2+3-1
> y:fill(1) -- fill with 1
> print(y)
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
[torch.DoubleTensor of dimension 3x6]
> print(x) -- memory in x has been modified!
0 0 0 0 0 0
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
0 0 0 0 0 0
[torch.DoubleTensor of dimension 5x6]
```

This method is equivalent to do a series of
narrow up to the first 4 dimensions. It
returns a new `Tensor`

which is a sub-tensor going from index
`dimis`

to `dimie`

in the `i`

-th dimension. Negative values are
interpreted index starting from the end: `-1`

is the last index,
`-2`

is the index before the last index, ...

```
> x = torch.Tensor(5, 6):zero()
> print(x)
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
[torch.DoubleTensor of dimension 5x6]
> y = x:sub(2,4):fill(1) -- y is sub-tensor of x:
> print(y) -- dimension 1 starts at index 2, ends at index 4
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
[torch.DoubleTensor of dimension 3x6]
> print(x) -- x has been modified!
0 0 0 0 0 0
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
0 0 0 0 0 0
[torch.DoubleTensor of dimension 5x6]
> z = x:sub(2,4,3,4):fill(2) -- we now take a new sub-tensor
> print(z) -- dimension 1 starts at index 2, ends at index 4
-- dimension 2 starts at index 3, ends at index 4
2 2
2 2
2 2
[torch.DoubleTensor of dimension 3x2]
> print(x) -- x has been modified
0 0 0 0 0 0
1 1 2 2 1 1
1 1 2 2 1 1
1 1 2 2 1 1
0 0 0 0 0 0
[torch.DoubleTensor of dimension 5x6]
> print(y:sub(-1, -1, 3, 4)) -- negative values = bounds
2 2
[torch.DoubleTensor of dimension 1x2]
```

Returns a new `Tensor`

which is a tensor slice at the given `index`

in the
dimension `dim`

. The returned tensor has one less dimension: the dimension
`dim`

is removed. As a result, it is not possible to `select()`

on a 1D
tensor.

Note that "selecting" on the first dimension is equivalent to use the [] operator

```
> x = torch.Tensor(5,6):zero()
> print(x)
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
[torch.DoubleTensor of dimension 5x6]
> y = x:select(1, 2):fill(2) -- select row 2 and fill up
> print(y)
2
2
2
2
2
2
[torch.DoubleTensor of dimension 6]
> print(x)
0 0 0 0 0 0
2 2 2 2 2 2
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
[torch.DoubleTensor of dimension 5x6]
> z = x:select(2,5):fill(5) -- select column 5 and fill up
> print(z)
5
5
5
5
5
[torch.DoubleTensor of dimension 5]
> print(x)
0 0 0 0 5 0
2 2 2 2 5 2
0 0 0 0 5 0
0 0 0 0 5 0
0 0 0 0 5 0
[torch.DoubleTensor of dimension 5x6]
```

The indexing operator [] can be used to combine narrow/sub and select in a concise an efficient way. It can also be used to copy, and fill (sub) tensors.

```
> x = torch.Tensor(5, 6):zero()
> print(x)
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
[torch.DoubleTensor of dimension 5x6]
> x[{ 1,3 }] = 1 -- sets element at (i=1,j=3) to 1
> print(x)
0 0 1 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
[torch.DoubleTensor of dimension 5x6]
> x[{ 2,{2,4} }] = 2 -- sets a slice of 3 elements to 2
> print(x)
0 0 1 0 0 0
0 2 2 2 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
[torch.DoubleTensor of dimension 5x6]
> x[{ {},4 }] = -1 -- sets the full 4th column to -1
> print(x)
0 0 1 -1 0 0
0 2 2 -1 0 0
0 0 0 -1 0 0
0 0 0 -1 0 0
0 0 0 -1 0 0
[torch.DoubleTensor of dimension 5x6]
> x[{ {},2 }] = torch.range(1,5) -- copy a 1D tensor to a slice of x
> print(x)
0 1 1 -1 0 0
0 2 2 -1 0 0
0 3 0 -1 0 0
0 4 0 -1 0 0
0 5 0 -1 0 0
[torch.DoubleTensor of dimension 5x6]
```

Returns a new `Tensor`

which indexes the given tensor along dimension `dim`

and using the entries in `torch.LongTensor`

`index`

. The returned tensor has the same number of dimensions as the original tensor. The returned tensor does **not** use the same storage as the original tensor.

```
t7> x = torch.rand(5,5)
t7> =x
0.8020 0.7246 0.1204 0.3419 0.4385
0.0369 0.4158 0.0985 0.3024 0.8186
0.2746 0.9362 0.2546 0.8586 0.6674
0.7473 0.9028 0.1046 0.9085 0.6622
0.1412 0.6784 0.1624 0.8113 0.3949
[torch.DoubleTensor of dimension 5x5]
t7> y = x:index(1,torch.LongTensor{3,1})
t7> =y
0.2746 0.9362 0.2546 0.8586 0.6674
0.8020 0.7246 0.1204 0.3419 0.4385
[torch.DoubleTensor of dimension 2x5]
t7> y:fill(1)
t7> =y
1 1 1 1 1
1 1 1 1 1
[torch.DoubleTensor of dimension 2x5]
t7> =x
0.8020 0.7246 0.1204 0.3419 0.4385
0.0369 0.4158 0.0985 0.3024 0.8186
0.2746 0.9362 0.2546 0.8586 0.6674
0.7473 0.9028 0.1046 0.9085 0.6622
0.1412 0.6784 0.1624 0.8113 0.3949
[torch.DoubleTensor of dimension 5x5]
```

Note the explicit `index`

function is different than the indexing operator `[]`

. The indexing operator `[]`

is a syntactic shortcut for a series of select and narrow operations, therefore it always returns a new view on the original tensor that shares the same storage. However, he explicit `index`

function can not use the same storage.

Copies the elements of `tensor`

into itself by selecting the indices in the order defined by the order given in `index`

.

```
t7> =x
0.8020 0.7246 0.1204 0.3419 0.4385
0.0369 0.4158 0.0985 0.3024 0.8186
0.2746 0.9362 0.2546 0.8586 0.6674
0.7473 0.9028 0.1046 0.9085 0.6622
0.1412 0.6784 0.1624 0.8113 0.3949
[torch.DoubleTensor of dimension 5x5]
t7> z=torch.Tensor(5,2)
t7> z:select(2,1):fill(-1)
t7> z:select(2,2):fill(-2)
t7> =z
-1 -2
-1 -2
-1 -2
-1 -2
-1 -2
[torch.DoubleTensor of dimension 5x2]
t7> x:indexCopy(2,torch.LongTensor{5,1},z)
t7> =x
-2.0000 0.7246 0.1204 0.3419 -1.0000
-2.0000 0.4158 0.0985 0.3024 -1.0000
-2.0000 0.9362 0.2546 0.8586 -1.0000
-2.0000 0.9028 0.1046 0.9085 -1.0000
-2.0000 0.6784 0.1624 0.8113 -1.0000
[torch.DoubleTensor of dimension 5x5]
```

Fills the elements of itself with value `val`

by selecting the indices in the order defined by the order given in `index`

.

```
t7> x=torch.rand(5,5)
t7> =x
0.8414 0.4121 0.3934 0.5600 0.5403
0.3029 0.2040 0.7893 0.6079 0.6334
0.3743 0.1389 0.1573 0.1357 0.8460
0.2838 0.9925 0.0076 0.7220 0.5185
0.8739 0.6887 0.4271 0.0385 0.9116
[torch.DoubleTensor of dimension 5x5]
t7> x:indexFill(2,torch.LongTensor{4,2},-10)
t7> =x
0.8414 -10.0000 0.3934 -10.0000 0.5403
0.3029 -10.0000 0.7893 -10.0000 0.6334
0.3743 -10.0000 0.1573 -10.0000 0.8460
0.2838 -10.0000 0.0076 -10.0000 0.5185
0.8739 -10.0000 0.4271 -10.0000 0.9116
[torch.DoubleTensor of dimension 5x5]
```

These methods returns a `Tensor`

which is created by replications of the
original tensor.

`sizes`

can either be a `torch.LongStorage`

or numbers. Expanding a tensor
does not allocate new memory, but only creates a new view on the existing tensor where
singleton dimensions can be expanded to multiple ones by setting the `stride`

to 0.
Any dimension that is 1 can be expanded to arbitrary value without any new memory allocation.

```
t7> x=torch.rand(10,1)
t7> =x
0.3837
0.5966
0.0763
0.1896
0.4958
0.6841
0.4038
0.4068
0.1502
0.2239
[torch.DoubleTensor of dimension 10x1]
t7> y=torch.expand(x,10,2)
t7> =y
0.3837 0.3837
0.5966 0.5966
0.0763 0.0763
0.1896 0.1896
0.4958 0.4958
0.6841 0.6841
0.4038 0.4038
0.4068 0.4068
0.1502 0.1502
0.2239 0.2239
[torch.DoubleTensor of dimension 10x2]
t7> y:fill(1)
t7> =y
1 1
1 1
1 1
1 1
1 1
1 1
1 1
1 1
1 1
1 1
[torch.DoubleTensor of dimension 10x2]
t7> =x
1
1
1
1
1
1
1
1
1
1
[torch.DoubleTensor of dimension 10x1]
t7> i=0; y:apply(function() i=i+1;return i end)
t7> =y
2 2
4 4
6 6
8 8
10 10
12 12
14 14
16 16
18 18
20 20
[torch.DoubleTensor of dimension 10x2]
t7> =x
2
4
6
8
10
12
14
16
18
20
[torch.DoubleTensor of dimension 10x1]
```

This is equivalent to self:expand(tensor:size())

`sizes`

can either be a `torch.LongStorage`

or numbers. Repeating a tensor allocates
new memory. `sizes`

specify the number of times the tensor is repeated in each dimension.

```
t7> x=torch.rand(5)
t7> =x
0.7160
0.6514
0.0704
0.7856
0.7452
[torch.DoubleTensor of dimension 5]
t7> =torch.repeatTensor(x,3,2)
0.7160 0.6514 0.0704 0.7856 0.7452 0.7160 0.6514 0.0704 0.7856 0.7452
0.7160 0.6514 0.0704 0.7856 0.7452 0.7160 0.6514 0.0704 0.7856 0.7452
0.7160 0.6514 0.0704 0.7856 0.7452 0.7160 0.6514 0.0704 0.7856 0.7452
[torch.DoubleTensor of dimension 3x10]
t7> return torch.repeatTensor(x,3,2,1)
(1,.,.) =
0.7160 0.6514 0.0704 0.7856 0.7452
0.7160 0.6514 0.0704 0.7856 0.7452
(2,.,.) =
0.7160 0.6514 0.0704 0.7856 0.7452
0.7160 0.6514 0.0704 0.7856 0.7452
(3,.,.) =
0.7160 0.6514 0.0704 0.7856 0.7452
0.7160 0.6514 0.0704 0.7856 0.7452
[torch.DoubleTensor of dimension 3x2x5]
```

Each of these methods returns a `Tensor`

which is another way of viewing
the `Storage`

of the given tensor. Hence, any modification in the memory of
the sub-tensor will have an impact on the primary tensor, and vice-versa.

These methods are very fast, are they do not involve any memory copy.

Returns a tensor where dimensions `dim1`

and `dim2`

have been swapped. For 2D tensors,
the convenience method of t() is available.

```
> x = torch.Tensor(3,4):zero()
> x:select(2,3):fill(7) -- fill column 3 with 7
> print(x)
0 0 7 0
0 0 7 0
0 0 7 0
[torch.DoubleTensor of dimension 3x4]
> y = x:transpose(1,2) -- swap dimension 1 and 2
> print(y)
0 0 0
0 0 0
7 7 7
0 0 0
[torch.DoubleTensor of dimension 4x3]
> y:select(2, 3):fill(8) -- fill column 3 with 8
> print(y)
0 0 8
0 0 8
7 7 8
0 0 8
[torch.DoubleTensor of dimension 4x3]
> print(x) -- contents of x have changed as well
0 0 7 0
0 0 7 0
8 8 8 8
[torch.DoubleTensor of dimension 3x4]
```

Convenience method of transpose() for 2D tensors. The given tensor must be 2 dimensional. Swap dimensions 1 and 2.

```
> x = torch.Tensor(3,4):zero()
> x:select(2,3):fill(7)
> y = x:t()
> print(y)
0 0 0
0 0 0
7 7 7
0 0 0
[torch.DoubleTensor of dimension 4x3]
> print(x)
0 0 7 0
0 0 7 0
0 0 7 0
[torch.DoubleTensor of dimension 3x4]
```

Returns a tensor which contains all slices of size `size`

in the dimension `dim`

. Step between
two slices is given by `step`

.

If `sizedim`

is the original size of dimension `dim`

, the size of dimension
`dim`

in the returned tensor will be `(sizedim - size) / step + 1`

An additional dimension of size `size`

is appended in the returned tensor.

```
> x = torch.Tensor(7)
> for i=1,7 do x[i] = i end
> print(x)
1
2
3
4
5
6
7
[torch.DoubleTensor of dimension 7]
> return x:unfold(1, 2, 1)
1 2
2 3
3 4
4 5
5 6
6 7
[torch.DoubleTensor of dimension 6x2]
> return x:unfold(1, 2, 2)
1 2
3 4
5 6
[torch.DoubleTensor of dimension 3x2]
```

These functions apply a function to each element of the tensor on which the
method is called (self). These methods are much faster than using a `for`

loop in `Lua`

. The results is stored in `self`

(if the function returns
something).

Apply the given function to all elements of self.

The function takes a number (the current element of the tensor) and might return a number, in which case it will be stored in self.

Examples:

```
> i = 0
> z = torch.Tensor(3,3)
> z:apply(function(x)
>> i = i + 1
>> return i
>> end) -- fill up the tensor
> = z
1 2 3
4 5 6
7 8 9
[torch.DoubleTensor of dimension 3x3]
> z:apply(math.sin) -- apply the sin function
> = z
0.8415 0.9093 0.1411
-0.7568 -0.9589 -0.2794
0.6570 0.9894 0.4121
[torch.DoubleTensor of dimension 3x3]
> sum = 0
> z:apply(function(x)
>> sum = sum + x
>> end) -- compute the sum of the elements
> = sum
1.9552094821074
> = z:sum() -- it is indeed correct!
1.9552094821074
```

Apply the given function to all elements of self and `tensor`

. The number of elements of both tensors
must match, but sizes do not matter.

The function takes two numbers (the current element of self and `tensor`

) and might return
a number, in which case it will be stored in self.

Example:

```
> x = torch.Tensor(3,3)
> y = torch.Tensor(9)
> i = 0
> x:apply(function() i = i + 1; return i end) -- fill-up x
> i = 0
> y:apply(function() i = i + 1; return i end) -- fill-up y
> = x
1 2 3
4 5 6
7 8 9
[torch.DoubleTensor of dimension 3x3]
> = y
1
2
3
4
5
6
7
8
9
[torch.DoubleTensor of dimension 9]
> x:map(y, function(xx, yy) return xx*yy end) -- element-wise multiplication
> = x
1 4 9
16 25 36
49 64 81
[torch.DoubleTensor of dimension 3x3]
```

Apply the given function to all elements of self, `tensor1`

and `tensor2`

. The number of elements of all tensors
must match, but sizes do not matter.

The function takes three numbers (the current element of self, `tensor1`

and `tensor2`

) and might return
a number, in which case it will be stored in self.

Example:

```
> x = torch.Tensor(3,3)
> y = torch.Tensor(9)
> z = torch.Tensor(3,3)
>
> i = 0; x:apply(function() i = i + 1; return math.cos(i)*math.cos(i) end)
> i = 0; y:apply(function() i = i + 1; return i end)
> i = 0; z:apply(function() i = i + 1; return i end)
>
> print(x)
0.2919 0.1732 0.9801
0.4272 0.0805 0.9219
0.5684 0.0212 0.8302
[torch.DoubleTensor of dimension 3x3]
> print(y)
1
2
3
4
5
6
7
8
9
[torch.DoubleTensor of dimension 9]
> print(z)
1 2 3
4 5 6
7 8 9
[torch.DoubleTensor of dimension 3x3]
>
> x:map2(y, z, function(xx, yy, zz) return xx+yy*zz end)
>
> print(x)
1.2919 4.1732 9.9801
16.4272 25.0805 36.9219
49.5684 64.0212 81.8302
[torch.DoubleTensor of dimension 3x3]
```