Object
Tnsr is an ordered, integer-indexed collection of one type of objects. The types of objects include
Ruby object, number, string, and bool (just like in JavaScript)
char, uchar, short, ushort, int, unsigned, long, llong, ullong, float, double, and ldouble (but note that there is no ulong, because it is used for Ruby object)
cchar, cuchar, cshort, cushort, cint, cunsigned, clong, culong, cllong, cullong, cfloat, cdouble, and cldouble (for the corresponding Complex types)
Tnsr indexing consists of two types: single-indexing and multi-indexing. Single-indexing can be used by considering the Tnsr as one long array whereas multi-indexing by treating the Tnsr as multi-dimensional array. The single-index idx ranges from Tsr::Begin to Tsr::Begin + Tnsr#size - 1. A negative index is assumed to be relative to the end of the array and ranges from Tsr::End to Tsr::End + Tnsr#size + 1. The multi-index midx can be given as an array [idx0, idx1, idx2, ...] where each index idxk ranges from Tsr::Begin to Tsr::Begin + Tnsr#size(k) - 1 and a negative index is also assumed to be relative to the end of dimension k.
Tnsr includes the module Enumerable, so all the methods of that module are available.
For numerical-related methods, please consider the derived class, Tensor.
(Note that Tnsr and Tensor classes have not been fully optimized yet; a lot of operations still require redundant steps. Also, the sparse tensors are really redundant in operations; when they are operated, they will be converted to full/regular tensors and then the results are put back into sparse forms. Therefore the sparse tensors currently cannot be used for very large tensors, and this defeats their original purpose. This does not happen for self-operations such as add!, except on object type.)
To create a Tnsr :
Tnsr::new() # Form 0
Tnsr::new(type, ...) # Form 1
Tnsr::new(sprs, ...) # Form 2
Tnsr::new(dim, type, ...) # Form 3
Tnsr::new(ary, rowOrd, ...) # Form 4
Tnsr::new(ary, dim, ...) # Form 5
Tnsr::new(dft, dim, ...) # Form 6
Tnsr::new(tsr) # Form 7
Tnsr::new(ary, ...) # Form 8
To copy a Tnsr :
Tnsr::new(tsr) # row order-ness is preserved
[] = tsr # have to be of the same type; row order-ness is preserved
= tsr[] # row order-ness will follow $RowOrder
Shortcuts:
To access Tnsr elements/rows/columns/subtensor:
Tnsr#row ==> must be 2D
Tnsr#col ==> must be 2D
Tnsr#diag ==> must be 2D
Tnsr#minor ==> must be 2D
Tnsr#map ==> alias for Tnsr#collect
To access Tnsr elements/rows/columns/subtensor using [ ]:
[int1, ..., intN] ==> yields object
[int] ==> yields object
[] ==> yields tensor
[All] ==> yields vector
[IRange] ==> yields vector
[mask] ==> yields vector
[indirect] ==> yields vector
[int1, ..., All, ..., intN] ==> yields tensor
[IRange1, ..., All, ..., IRangeN] ==> yields tensor
[mask1, ..., All, ..., maskN] ==> yields tensor
[indirect1, ..., All, ..., indirectN] ==> yields tensor
[..., mix of all the above, ...] ==> yields tensor
Properties of Tnsr :
Tnsr#size ==> alias for Tnsr#length
Tnsr#size1 ==> alias for Tnsr#row_size
Tnsr#size2 ==> alias for Tnsr#col_size
Tnsr operations:
+ (addition)
* (element-by-element multiplication)
+@ (unary plus)
-@ (unary minus)
! (unary not)
~ (unary complement)
Tnsr#t ==> alias for Tnsr#transpose
Tnsr#h ==> alias for Tnsr#hermitian
Tnsr#fliplr ==> must be 2D
Tnsr#flipud ==> must be 2D
Tnsr self operations:
Tnsr#map! ==> alias for Tnsr#collect!
Tnsr self operations using []=:
[int1, ..., intN] = val # sets one element to val
[int] = val # sets one element to val
[] = val # sets all elements to val
[] = tsr # sets to be a copy of tsr
[All] = tsr or val
[IRange] = tsr or val
[mask] = tsr or val
[indirect] = tsr or val
[..., mix of all the above, ...] = tsr or val
Tnsr functions:
Tnsr#sum ==> must be 2D
Tnsr#trace ==> must be 2D
Tnsr#tr ==> ==> alias for Tnsr#trace
Complex arithmetic:
Tnsr#imag ==> alias for Tnsr#imaginary
Tnsr#conj ==> alias for Tnsr#conjugate
Tnsr#arg ==> alias for Tnsr#angle
Conversion to other data types:
Tnsr#to_matrix ==> require ‘matrix’, must be 2D
String representations:
Tnsr checking:
Tnsr#ensure_square ==> must be 2D
Returns a new Tnsr. The following parameters can be included:
ary - the elements of the Tnsr, given as a (multi-dimensional) array. The default is given by the empty array.
dim - the dimensions of the Tnsr, given as an array. The default is given by the empty array. The total number of elements is determined by dim, where the remaining elements (if any) is filled in with dft; if dim is empty or zero, then the dimensions of Tnsr are determined by ary. A special case is when the dimension of ary is one and dim has only one component; in this case dim specifies how many elements of ary are taken.
type - the type of the Tnsr and this must be given as a symbol. The default is given by the global variable $TType (and for Tensor is $TsrType). The symbol :- can be used and it will translated into the content of $TType (or $TsrType).
dft - the default value of the elements of the Tnsr. The default is nil (and for Tensor is 0 (zero)).
rowOrd - whether the given ary is in Row Order. The default is true.
sprs - whether the Tnsr will be sparse. The default is false. If the value is false or nil, the Tnsr will be regular; otherwise it will be sparse.
Also aliased as: Tsr#s
There are many forms, and here they are sorted based on precedence:
(0) There is no argument. The Tnsr is empty.
def initialize ( ) end
(1) The first argument is a symbol. A block can be given where the single-index and multi-index are passed, and the return value is stored for each element.
def initialize (type, dim = [], dft = nil, sprs = false) {|idx, midx| block}
end
(2) The first argument is true or false.
def initialize (sprs, type = $TType, dft = nil) end
(3) The first argument is an array and the second argument is a symbol. A block can be given where the single-index and multi-index are passed, and the return value is stored for each element.
def initialize (dim, type, dft = nil, sprs = false) {|idx, midx| block}
end
(4) The first argument is an array and the second argument is true or false.
def initialize (ary, rowOrd, dft = nil, type = $TType, dim = [], sprs = false) end
(5) The first and second arguments are arrays.
def initialize (ary, dim, type = $TType, dft = nil, rowOrd = true, sprs = false) end
(6) The second argument is an array.
def initialize (dft, dim, ttpe = $TType, sprs = false) end
(7) The first argument is a tensor. This will create a copy of the tensor (but for Ruby objects only the references are copied). The row order-ness is preserved. (In fact, this is based on C++ copy constructor.)
def initialize (tsr) end
(8) For anything else as the first argument:
def initiliaze (ary, dft = nil, type = $TType, dim = [], sprs = false) end
# File rtensor_api.rb, line 478
478: def initialize ( ... )
479: end
Returns a new tensor by performing “unary !“ (not) to each element. Except for object and bool types, this does not perform any operation (besides returning a new tensor).
!Tsr.s([false, 3]) => [ true false ] ==> Tnsr "object": 1 x 2 = 2 (C; dft = nil)
For “unary ~“ (complement), see Tnsr #~.
# File rtensor_api.rb, line 533
533: def ! ( ) # => new_tsr
534: end
Returns a new tensor by performing element-by-element multiplication. If t is a tensor, the two tensors must have equal number of total elements and currently they have to be of exactly the same type; else each element is multiplied by t. The default value and sparseness follow the tensor on the left of the * sign. For bool type, this is the same as performing element-by-element AND operation. For string type, this is the same as + (addition).
Tsr.s([[2, 4], [6, 8]], 0, :object) * Tsr.identity(2)
=>
[ 2 0
0 8 ]
==> Tnsr "object": 2 x 2 = 4 (C; dft = 0)
Tsr[[2, 4], [6, 8]] * 2
=>
[ 4 8
12 16 ]
==> Tensor "object": 2 x 2 = 4 (C; dft = 0)
For matrix multiplication, see Tensor #*. For element-by-element division, see Tensor #/.
# File rtensor_api.rb, line 493
493: def * ( t ) # => new_tsr
494: end
Returns a new tensor by performing element-by-element addition. If t is a tensor, the two tensors must have equal number of total elements and currently they have to be of exactly the same type; else each element is added by t. The default value and sparseness follow the tensor on the left of the + sign. For bool type, this is the same as performing element-by-element OR operation.
Tsr.scalar(2, 5) + Tsr[[1, 0], [-4, 7]]
=>
[ 6 0
-4 12 ]
==> Tensor "object": 2 x 2 = 4 (C; dft = 0)
Tsr.scalar(2, 5) + 2
=>
[ 7 2
2 7 ]
==> Tensor "object": 2 x 2 = 4 (C; dft = 0)
For element-by-element subtraction, see Tensor #-.
# File rtensor_api.rb, line 508
508: def + ( t ) # => new_tsr
509: end
Returns a new tensor by performing “unary +“ to each element. For string type, this does not perform any operation (besides returning a new tensor).
+Tsr.s([1, 2]) => [ 1 2 ] ==> Tnsr "object": 1 x 2 = 2 (C; dft = nil)
# File rtensor_api.rb, line 516
516: def +@ ( ) # => new_tsr
517: end
Returns a new tensor by performing “unary -“ to each element. For bool type, this is the same as performing “unary !“ to each element. For bool type, this is the same as performing NOT operation to each element. For string type, this does not perform any operation (besides returning a new tensor).
-Tsr.s([1, 2]) => [ -1 -2 ] ==> Tnsr "object": 1 x 2 = 2 (C; dft = nil)
# File rtensor_api.rb, line 524
524: def -@ ( ) # => new_tsr
525: end
Returns the element(s) at single-index idx or at multi-index idx, idx2, idx3, …. If the index(es) is beyond the range, then it will raise an index error.
If idx is an IRange or an array of boolean values (a mask) or an array of indices (an indirect) or All, then it will return a column vector (if $RowOrder is false) or a row vector (if $RowOrder is true). If idx is an Integer, then it will return a single element. If idx is omitted, the it will return a copy of the tensor. For IRange, mask and indirect, the order is determined by Tnsr#row_order?. For mask and indirect, the size of mask/indirect array should be less than or equal to Tnsr#size. For indirect, the indices in idx cannot be repeated. If idx is equal to All, then it will return all the elements (as a column or row vector).
If idx, idx2, idx3, … are several IRange ’s or several arrays of boolean values (masks) or several arrays of indices (indirects), then it will return a new tensor. If idx, idx2, idx3, … are several Integer’s, then it will return a single element. When they are several IRange ’s, they can be mixed with Integer, All and empty array. When they are several masks, then can be mixed with All and empty array. When they are several indirects, they can be mixed with All and empty array. (In multi-index, for any argument idxY, if idxY is an array, the first element idxY[0] will determine if it is a mask or indirect. And in multi-index, the empty array is equivalent to All, whereas in single-index, the empty array means no element is selected.)
Examples for the many forms:
t = Tsr.s([2, 4, 2], :-) {|i, m| m[0] * 4 + m[1] + m[2] * 10}
=>
mtrx{:,:,1} (of size 2 x 4 = 8; index starts at 1) =
[ 15 16 17 18
19 20 21 22 ]
mtrx{:,:,2} (of size 2 x 4 = 8; index starts at 9) =
[ 25 26 27 28
29 30 31 32 ]
==> Tnsr "object": 2 x 4 x 2 = 16 (C; dft = nil)
(0) No Argument. This will return a copy of the tensor, and the row order will follow the current value of $RowOrder (unlike the Tnsr(self)). Also for Ruby objects only the references are copied.
t[]
=>
mtrx{:,:,1} (of size 2 x 4 = 8; index starts at 1) =
[ 15 16 17 18
19 20 21 22 ]
mtrx{:,:,2} (of size 2 x 4 = 8; index starts at 9) =
[ 25 26 27 28
29 30 31 32 ]
==> Tnsr "object": 2 x 4 x 2 = 16 (C; dft = nil)
(1) Multiple Integers. This will return a single element. If the number of integers are at least two but fewer than the number of tensor dimensions, the rest will considered as “Begin“.
t[Tsr::End, Tsr::Begin, Tsr::End] => 29 t[Tsr::End, Tsr::Begin] => 19
(2) Single Integer. This will return a single element. The element ordering is based on row_order?.
t[Tsr::Begin + 3] => 20 t[Tsr::End - 1] => 28
(3) Single “All“. This will return all the elements as column or row vector, depending on $RowOrder.
$RowOrder = true t[Tsr::All] => [ 15 19 16 20 17 21 18 22 25 29 26 30 27 31 28 32 ] ==> Tnsr "object": 1 x 16 = 16 (C; dft = nil)
(4) Single IRange. This will return some elements as column or row vector, depending on $RowOrder. The element ordering is based on row_order?. Note that with IRange, the elements in tensor are never presented backward even though the IRange seems like backward.
t[Tsr::r(Tsr::Begin + 3, 4, Tsr::End)]
=>
[ 20 22 30 32 ]
==> Tnsr "object": 1 x 4 = 4 (C; dft = nil)
t[Tsr::r(Tsr::End - 2, -2, Tsr::Begin + 2)]
=>
[ 20 21 22 29 30 31 ]
==> Tnsr "object": 1 x 6 = 6 (C; dft = nil)
(5) Single Mask. A mask is an Array with values of true or false. This will return some elements as column or row vector, depending on $RowOrder. The element ordering is based on row_order? and only elements with true values are presented.
t[[false, true, false, true, true]]
=>
[ 19 20 17 ]
==> Tnsr "object": 1 x 3 = 3 (C; dft = nil)
(6) Single Indirect. An indirect is an Array with values of indices. This will return some elements as column or row vector, depending on $RowOrder. The element ordering is based on row_order? and only elements with indices included are presented. Note that the indices cannot be repeated.
t[[Tsr::End, Tsr::Begin, Tsr::End - 2]]
=>
[ 32 15 31 ]
==> Tnsr "object": 1 x 3 = 3 (C; dft = nil)
(7) Multiple Integers mixed with “All“ (or empty array). This will return a tensor. If the number of integers and All’s are at least two but fewer than the number of tensor dimensions, the rest will considered as “Begin“.
t[Tsr::Begin + 1, Tsr::All] # the second row
=>
[ 19 20 21 22 ]
==> Tnsr "object": 1 x 4 = 4 (C; dft = nil)
t[Tsr::All, Tsr::End] # the last column of the first matrix
=>
[ 18
22 ]
==> Tnsr "object": 2 x 1 = 2 (C; dft = nil)
t[Tsr::All, Tsr::End, Tsr::All] # the last columns
=>
mtrx{:,:,1} (of size 2 x 1 = 2; index starts at 1) =
[ 18
22 ]
mtrx{:,:,2} (of size 2 x 1 = 2; index starts at 3) =
[ 28
32 ]
==> Tnsr "object": 2 x 1 x 2 = 4 (C; dft = nil)
(8) Multiple IRange ’s. This will return a tensor. They can be mixed with “All“ (or empty array). If the number of IRange ’s and All’s are at least two but fewer than the number of tensor dimensions, the rest will considered as “Begin“.
t[Tsr::All, Tsr.r(Tsr::Begin, 3, Tsr::End), Tsr::All]
=>
mtrx{:,:,1} (of size 2 x 2 = 4; index starts at 1) =
[ 15 18
19 22 ]
mtrx{:,:,2} (of size 2 x 2 = 4; index starts at 5) =
[ 25 28
29 32 ]
==> Tnsr "object": 2 x 2 x 2 = 8 (C; dft = nil)
(9) Multiple Mask’s. This will return a tensor. They can be mixed with “All“ (or empty array). If the number of mask’s and All’s are at least two but fewer than the number of tensor dimensions, the rest will considered as “Begin“.
t[[false, true], [true, false, true, true]]
=>
[ 19 21 22 ]
==> Tnsr "object": 1 x 3 = 3 (C; dft = nil)
(10) Multiple Indirect’s. This will return a tensor. They can be mixed with “All“ (or empty array). If the number of indirect’s and All’s are at least two but fewer than the number of tensor dimensions, the rest will considered as “Begin“.
t[[Tsr::End, Tsr::Begin], [Tsr::End, Tsr::End - 1, Tsr::End - 2, Tsr::End - 3]]
=>
[ 22 21 20 19
18 17 16 15 ]
==> Tnsr "object": 2 x 4 = 8 (C; dft = nil)
(11) Mix of all the above. This case may be slower compared to the other cases.
t[Tsr.r(Tsr::End), [4, 1, 3, 2], [false, true]]
=>
[ 32 29 31 30 ]
==> Tnsr "object": 1 x 4 = 4 (C; dft = nil)
# File rtensor_api.rb, line 651
651: def [] ( { idx, { idx2, idx3, ... } } ) # => new_tsr or obj
652: end
Sets the element at single-index idx or at multi-index idx, idx2, idx3, … to the value val. Returns the value val. If the index(es) is beyond the range, then it will automatically expands the tensor.
Examples for the many forms (for more information, see also examples on [ ] above):
t = Tsr.s([[1, 2], 3])
=>
[ 1 2
3 nil ]
==> Tnsr "object": 2 x 2 = 4 (C; dft = nil)
(0) No Argument. If val is a tensor, then this will copy the tensor (but for Ruby objects only the references are copied) and the row order-ness will be preserved, exactly like the Tnsr(self) (in fact, this is based on C++ assignment operator); otherwise it will assign the value val to each element. Note that if val is a tensor, it has to be of the same tensor type.
t[] = Tsr.s([[7, 8, 9], 1])
=>
[ 7 8 9
1 nil nil ]
==> Tnsr "object": 2 x 3 = 6 (C; dft = nil)
t[] = 9; t
=>
[ 9 9 9
9 9 9 ]
==> Tnsr "object": 2 x 3 = 6 (C; dft = nil)
(1) Multiple Integers. This will set a single element to val.
t[Tsr::Begin, Tsr::End] = 1; t
=>
[ 9 9 1
9 9 9 ]
==> Tnsr "object": 2 x 3 = 6 (C; dft = nil)
t[Tsr::Begin, Tsr::Begin + 4] = 3; t
=>
[ 9 9 1 nil 3
9 9 9 nil nil ]
==> Tnsr "object": 2 x 5 = 10 (C; dft = nil)
(2) Single Integer. This will set a single element to val. The element ordering is based on row_order?. If the index(es) is beyond the range, then it will generate an error, unless the tensor is a vector.
t[Tsr::End - 2] = 5; t
=>
[ 9 9 1 nil 3
9 9 9 5 nil ]
==> Tnsr "object": 2 x 5 = 10 (C; dft = nil)
(3) Single “All“. If val is a tensor, then this will copy the tensor (but for Ruby objects only the references are copied); otherwise it will assign the value val to each element. Note that if val is a tensor, it has to be of the same tensor type and has the same Tnsr#length.
t[Tsr::All] = Tsr[1,2,3,4,5,6,7,8,9,10]; t
=>
[ 1 3 5 7 9
2 4 6 8 10 ]
==> Tnsr "object": 2 x 5 = 10 (C; dft = nil)
t[Tsr::All] = -3; t
=>
[ -3 -3 -3 -3 -3
-3 -3 -3 -3 -3 ]
==> Tnsr "object": 2 x 5 = 10 (C; dft = nil)
(4) Single IRange. If val is a tensor, then this will copy the tensor (but for Ruby objects only the references are copied); otherwise it will assign the value val to each element. Note that if val is a tensor, it has to be of the same tensor type and has the same Tnsr#length as the number of elements in the IRange.
t[Tsr::r(Tsr::Begin, 2, Tsr::End)] = Tsr[1,2,3,4,5]; t
=>
[ 1 2 3 4 5
-3 -3 -3 -3 -3 ]
==> Tnsr "object": 2 x 5 = 10 (C; dft = nil)
t[Tsr::r(Tsr::Begin + 1, 2, Tsr::End)] = 9; t
=>
[ 1 2 3 4 5
9 9 9 9 9 ]
==> Tnsr "object": 2 x 5 = 10 (C; dft = nil)
(5) Single Mask. If val is a tensor, then this will copy the tensor (but for Ruby objects only the references are copied); otherwise it will assign the value val to each element. Note that if val is a tensor, it has to be of the same tensor type and has the same Tnsr#length as the number of true’s in the mask.
t[[false, true, false, true]] = Tsr[6, 7]; t
=>
[ 1 2 3 4 5
6 7 9 9 9 ]
==> Tnsr "object": 2 x 5 = 10 (C; dft = nil)
t[[false, false, true, false, true]] = 8; t
=>
[ 1 8 8 4 5
6 7 9 9 9 ]
==> Tnsr "object": 2 x 5 = 10 (C; dft = nil)
(6) Single Indirect. If val is a tensor, then this will copy the tensor (but for Ruby objects only the references are copied); otherwise it will assign the value val to each element. Note that if val is a tensor, it has to be of the same tensor type and has the same Tnsr#length as the number of elements in the indirect.
t[[Tsr::Begin + 4, Tsr::Begin + 7]] = Tsr[2, 3]; t
=>
[ 1 8 2 4 5
6 7 9 3 9 ]
==> Tnsr "object": 2 x 5 = 10 (C; dft = nil)
t[[Tsr::Begin + 8, Tsr::Begin + 9]] = 0; t
=>
[ 1 8 2 4 0
6 7 9 3 0 ]
==> Tnsr "object": 2 x 5 = 10 (C; dft = nil)
(7) Mix of all the above. If val is a tensor, then this will copy the tensor (but for Ruby objects only the references are copied); otherwise it will assign the value val to each element. Note that if val is a tensor, it has to be of the same tensor type and has the same Tnsr#length as the number of elements in the mix.
t[Tsr::All, Tsr::End] = Tsr[5, 10]; t
=>
[ 1 8 2 4 5
6 7 9 3 10 ]
==> Tnsr "object": 2 x 5 = 10 (C; dft = nil)
t[[], [true,false,false,false,true]] = 0; t
=>
[ 0 8 2 4 0
0 7 9 3 0 ]
==> Tnsr "object": 2 x 5 = 10 (C; dft = nil)
# File rtensor_api.rb, line 745
745: def []= ( { idx, { idx2, idx3, ... } } val ) # => obj
746: end
Returns the absolute values of the tensor.
Tsr[[Complex(1,1), -5, 3.0/7], [true, '']].abs
=>
[ 1.4142135623730951 5 0.42857142857142855
true "" 0 ]
==> Tensor "object": 2 x 3 = 6 (C; dft = 0)
# File rtensor_sup.rb, line 22
22: def abs ( ) # => new_tsr
23: collect do |e|
24: if e.kind_of?(Numeric)
25: e.abs
26: else
27: e
28: end
29: end
30: end
Returns the squares of absolute values of the tensor.
Tsr[[Complex(1,1), -5, 3.0/7], [true, '']].abs2
=>
[ 2 25 0.18367346938775508
true "" 0 ]
==> Tensor "object": 2 x 3 = 6 (C; dft = 0)
# File rtensor_sup.rb, line 40
40: def abs2 ( ) # => new_tsr
41: collect do |e|
42: if e.kind_of?(Numeric)
43: e.abs2
44: else
45: e
46: end
47: end
48: end
Returns an object which is the result of accumulation (“+“ or addition) with the optional init value. If different operation is required, see Enumerable#inject or Enumerable#reduce.
Tsr.t([1, 2, 3]).accumulate
=> 6.0
Tsr.s([1, 2, 3], '', :string).accumulate('#: ')
=> "#: 123"
See also Tnsr#tot_sum.
# File rtensor_api.rb, line 1008
1008: def accumulate ( init = 0 ) # => object
1009: end
Returns self after performing element-by-element addition. If t is a tensor, the two tensors must have equal number of total elements and currently they have to be of exactly the same type; else each element is added by t. For bool type, this is the same as performing element-by-element OR operation.
Tsr.scalar(2, 5).add!(Tsr[[1, 0], [-4, 7]])
=>
[ 6 0
-4 12 ]
==> Tensor "object": 2 x 2 = 4 (C; dft = 0)
Tsr.scalar(2, 5).add!(2)
=>
[ 7 2
2 7 ]
==> Tensor "object": 2 x 2 = 4 (C; dft = 0)
For element-by-element subtraction, see Tensor#sub!.
# File rtensor_api.rb, line 760
760: def add! ( t ) # => self
761: end
Returns the angle values of the tensor.
Tsr[[Complex(1,1), -5, 3.0/7], [true, '']].angle
=>
[ 0.7853981633974483 3.141592653589793 0
true "" 0 ]
==> Tensor "object": 2 x 3 = 6 (C; dft = 0)
# File rtensor_sup.rb, line 58
58: def angle ( ) # => new_tsr
59: collect do |e|
60: if e.kind_of?(Numeric)
61: e.angle
62: else
63: e
64: end
65: end
66: end
Returns an array of self and other.
# File rtensor_api.rb, line 779
779: def coerce ( other ) # => [self, other]
780: end
Returns a 1D-tensor (column vector) which is the jth column of the 2D-tensor (matrix).
Tsr[[1, 2, 3], [4, 5, 6]].col(Tsr::End)
=>
[ 3
6 ]
==> Tensor "object": 2 x 1 = 2 (C; dft = 0)
# File rtensor_sup.rb, line 78
78: def col ( j ) # => new_tsr
79: ensure_2D
80: self[All, j]
81: end
Returns the number of columns.
# File rtensor_sup.rb, line 86
86: def col_size ( ) # => int
87: size(Begin + 1)
88: end
Returns a new tensor containing the results of running block once for each element. If the optional parameter flag is not nil or false, the single-index and multi-indexed are also passed. If no block is given, an enumerator is returned instead.
Tsr[[1, 2], [3, 4]].collect {|e| e ** 2}
=>
[ 1 4
9 16 ]
==> Tensor "object": 2 x 2 = 4 (C; dft = 0)
Also aliased as: Tnsr#map
# File rtensor_api.rb, line 789
789: def collect ( { flag } { | elm, { idx, midx } | block } ) # => new_tsr or enumerator
790: end
Invokes block once for each element, replacing that element with the value returned by block. If the optional parameter flag is not nil or false, the single-index and multi-indexed are also passed. If no block is given, an enumerator is returned instead.
Tsr[[1, 2], [3, 4]].collect!(true) {|e, i, m| m }
=>
[ [1, 1] [1, 2]
[2, 1] [2, 2] ]
==> Tensor "object": 2 x 2 = 4 (C; dft = 0)
Also aliased as: Tnsr#map!
# File rtensor_api.rb, line 799
799: def collect! ( { flag } { | elm, { idx, midx } | block } ) # => orig_tsr or enumerator
800: end
Returns true if Tnsr is complex.
Tsr.s(:cdouble).complex? => true
# File rtensor_sup.rb, line 97
97: def complex? ( ) # => true or false
98: if ttype == 'object'
99: any? {|e| e.kind_of?(Complex)}
100: else
101: _complex?
102: end
103: end
Returns the conjugate of the tensor.
Tsr[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]].imaginary
=>
[ (1-2i) (0-1i) 0
1 2 3 ]
==> Tensor "object": 2 x 3 = 6 (C; dft = 0)
# File rtensor_sup.rb, line 113
113: def conjugate ( ) # => new_tsr
114: collect do |e|
115: if e.kind_of?(Numeric)
116: e.conjugate
117: else
118: e
119: end
120: end
121: end
Returns a new tensor with elements cyclicly shifted by the amount given by integer k (by considering the tensor as one long array). It shifts left when given a positive argument and right when given a negative argument.
Tsr.s([1, 2, 3, 4, 5, 6, 7, 8]).cshift(2) => [ 3 4 5 6 7 8 1 2 ] ==> Tnsr "object": 1 x 8 = 8 (C; dft = nil) Tsr.s([1, 2, 3, 4, 5, 6, 7, 8]).cshift(-2) => [ 7 8 1 2 3 4 5 6 ] ==> Tnsr "object": 1 x 8 = 8 (C; dft = nil)
For logical shift, see Tnsr#shift.
# File rtensor_api.rb, line 904
904: def cshift ( k ) # => new_tsr
905: end
Returns a 1D-tensor (vector) which is the main diagonal of the 2D-tensor (matrix). It will return a column vector if $RowOrder is false and a row vector if true.
Tsr[[1, 2, 3], [4, 5, 6]].diag
=>
[ 1
5 ]
==> Tensor "object": 2 x 1 = 2 (C; dft = 0)
# File rtensor_sup.rb, line 133
133: def diag ( ) # => new_tsr
134: ensure_2D
135: unless row_order?
136: self[Tsr.r(Begin, row_size + 1, End)]
137: else
138: self[Tsr.r(Begin, col_size + 1, End)]
139: end
140: end
Returns a new tensor which describes the dimensions of the tensor as a column vector (if $RowOrder is false) or a row vector (if $RowOrder is true).
Tsr.s(:string, [3, 4, 5]).dim
=>
[ 3
4
5 ]
==> Tnsr "unsigned": 3 x 1 = 3 (C; dft = 0)
# File rtensor_api.rb, line 809
809: def dim ( ) # => new_tsr
810: end
Calls block once for each element, passing that element as a parameter. If no block is given, an enumerator is returned instead. Returns the original tensor.
Tsr[[1, 2], [3, 4]].each {|e| print e, ' '}
1 3 2 4 =>
[ 1 2
3 4 ]
==> Tensor "object": 2 x 2 = 4 (C; dft = 0)
# File rtensor_api.rb, line 818
818: def each ( { | elm | block } ) # => orig_tsr or enumerator
819: end
Returns true if Tnsr contains no elements.
Tsr.s.empty? => true
# File rtensor_api.rb, line 824
824: def empty? ( ) # => true or false
825: end
Raises an error if is_2D? is false.
# File rtensor_sup.rb, line 145
145: def ensure_2D ( ) # => nil or error
146: raise(ArgumentError, 'The tensor must be 2D (a matrix).') unless is_2D?
147: end
Raises an error if the tensor is not 2D or not square.
# File rtensor_sup.rb, line 152
152: def ensure_square ( ) # => nil or error
153: ensure_2D
154: raise(ArgumentError, 'The matrix must be square.') unless row_size == col_size
155: end
Returns a new tensor which is a left-right flipped version of the 2D-tensor (matrix).
Tsr.t([[1, 2, 3], [4, 5, 6]]).fliplr
=>
[ 3 2 1
6 5 4 ]
==> Tensor "double": 2 x 3 = 6 (C; dft = 0)
# File rtensor_sup.rb, line 165
165: def fliplr # => new_tsr
166: ensure_2D
167: ans = self[]
168: (Begin...Begin + row_size).each {|r| ans[r, All] = self[r, Tsr.b]}
169: ans
170: end
Returns a new tensor which is an up-down flipped version of the 2D-tensor (matrix).
Tsr.t([[1, 2, 3], [4, 5, 6]]).flipud
=>
[ 4 5 6
1 2 3 ]
==> Tensor "double": 2 x 3 = 6 (C; dft = 0)
# File rtensor_sup.rb, line 180
180: def flipud # => new_tsr
181: ensure_2D
182: ans = self[]
183: (Begin...Begin + col_size).each {|c| ans[All, c] = self[Tsr.b, c]}
184: ans
185: end
Returns the Tnsr default value.
Tsr.s([], 7).get_dft => 7
# File rtensor_api.rb, line 830
830: def get_dft ( ) # => obj
831: end
Returns a new tensor which is the conjugate transpose of the original tensor.
Tsr.s([[-1, 0, 1], [Tsr::c(1, 1)]], 0, :cdouble).hermitian
=>
[ (-1,-0) (1,-1)
(0,-0) (0,-0)
(1,-0) (0,-0) ]
==> Tnsr "double" (cplx): 3 x 2 = 6 (C; dft = (0,0))
# File rtensor_sup.rb, line 196
196: def hermitian ( ) # => new_tsr
197: transpose.conjugate
198: end
Returns the imaginary part of the tensor.
Tsr[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]].imaginary
=>
[ 2 1 0
0 0 0 ]
==> Tensor "object": 2 x 3 = 6 (C; dft = 0)
# File rtensor_sup.rb, line 210
210: def imaginary ( ) # => new_tsr
211: collect do |e|
212: case e
213: when Numeric
214: e.imag
215: when String
216: ''
217: when TrueClass, FalseClass
218: false
219: else
220: 0
221: end
222: end
223: end
Returns an object which is the result of inner product of self with t with the init, symbol sym and optional symbol sym2 values. If t is a tensor, t must have elements at least as many as self; else t will be considered as a constant tensor. The inner product is defined as the sym of the element-by-element sym2 of the two tensor (for all elements: init = init sym (elm1 sym2 elm2)). Or, if a block is given, then the symbols are not allowed and the init defaults to 0, and the accumulator, first element and second element are passed. Compared to the other form of inner_product, this form utilizes only Ruby (and not C++) functions.
Tsr.t([1, 2, 3]).inner_product(Tsr.t([4, 5, 6]), 0, :-, :+)
=> -21.0
Tsr.t([1, 2, 3]).inner_product(2, 100, :-)
=> 88.0
Tsr.t([1, 2, 3]).inner_product(Tsr.t([4,5,6]), 100) {|a, e1, e2| a - e1*e2}
=> 68.0
Tsr.t([1, 2, 3]).inner_product(2) {|a, e1, e2| a + e1**e2}
=> 14.0
# File rtensor_api.rb, line 999
999: def inner_product ( t, init, sym, sym2 = :* ) # => object
1000: end
Returns an object which is the result of inner product of self with t with the optional init value. If t is a tensor, t must have elements at least as many as self and currently they have to be of exactly the same type; else t will be considered as a constant tensor. The inner product is defined as the sum of the element-by-element multiplications of the two tensor. For string type, the multiplication (*) is the same as addition (+).
Tsr.t([1, 2, 3]).inner_product(Tsr.t([4, 5, 6])) => 32.0 Tsr.t([1, 2, 3]).inner_product(2, 100) => 112.0
# File rtensor_api.rb, line 987
987: def inner_product ( t, init = 0 ) # => object
988: end
Returns true if the tensor is 2D (a matrix). This is the same as “self.dim.length == 2“. Note that because tensor dimensions are at least two, this will return true for matrix (dim m X n), vector (dim m X 1 or dim 1 X n), scalar (dim 1 X 1), or even empty tensor (dim 0 X 0).
Tsr.s(:bool, [4,3,2]).is_2D? => false
# File rtensor_api.rb, line 853
853: def is_2D? ( ) # => true or false
854: end
Without any argument, returns the total number of elements in Tnsr. With a single argument k, returns the number of elements in dimension k. Therefore, this is an equality: length() = ... * length(1) * length(2) * length(3) * .... Note that the precise value of k is influenced by $IdxOfs.
Tsr.s(:string, [3, 4, 5]).length => 60 Tsr.s(:string, [3, 4, 5]).length(Tsr::Begin + 1) => 4
Also aliased as: Tnsr#size
# File rtensor_api.rb, line 839
839: def length ( { k } ) # => int
840: end
Alias for: Tnsr#collect
# File rtensor_api.rb, line 843
843: def map ( { flag } { | elm, { idx, midx } | block } ) # => new_tsr
844: end
Alias for: Tnsr#collect!
# File rtensor_api.rb, line 847
847: def map! ( { flag } { | elm, { idx, midx } | block } ) # => orig_tsr
848: end
Returns a new tensor which is the (i, j) minor of the 2D-tensor (matrix). The (i, j) minor is defined as the matrix (not the determinant as usually in math) that remains after the ith row and jth column are deleted.
Tsr[[1,2,3], [4,5,6]].minor(Tsr::Begin, Tsr::End) => [ 4 5 ] ==> Tensor "object": 1 x 2 = 2 (C; dft = 0)
# File rtensor_sup.rb, line 234
234: def minor ( i, j ) # => new_tsr
235: ensure_2D
236: self[i, j] # to make sure i, j are within range
237: r = Array.new(row_size, true)
238: c = Array.new(col_size, true)
239: if i >= 0
240: r[i - $IdxOfs] = false
241: else
242: r[i] = false
243: end
244: if j >= 0
245: c[j - $IdxOfs] = false
246: else
247: c[j] = false
248: end
249: self[r, c]
250: end
Returns self after performing element-by-element multiplication. If t is a tensor, the two tensors must have equal number of total elements and currently they have to be of exactly the same type; else each element is multiplied by t. For bool type, this is the same as performing element-by-element AND operation. For string type, this is the same as add! (addition).
Tsr.s([[2, 4], [6, 8]], 0, :object).mul!(Tsr.identity(2))
=>
[ 2 0
0 8 ]
==> Tnsr "object": 2 x 2 = 4 (C; dft = 0)
Tsr[[2, 4], [6, 8]].mul!(2)
=>
[ 4 8
12 16 ]
==> Tensor "object": 2 x 2 = 4 (C; dft = 0)
For element-by-element division, see Tensor#div!.
# File rtensor_api.rb, line 775
775: def mul! ( t ) # => self
776: end
Returns a (multiple-line) string which describes the numeric limits for the Tnsr type as given in C++ numeric_limits.
print Tsr.s(:number).num_limits
double: is_specialized = true
radix = 2
digits = 53
...
=> nil
# File rtensor_api.rb, line 863
863: def num_limits ( ) # => string
864: end
Returns a new tensor which is the partial sum of the original tensor and the order is determined by Tnsr#row_order? and it preserves this row-orderness. Given a sequence a, b, c, d, etc., partial_sum produces a, a+b, a+b+c, a+b+c+d, etc. If the symbol sym is given, it utilizes only Ruby (and not C++) functions and it produces a, a sym b, a sym b sym c, a sym b sym c sym d, etc.
Tsr.t([17, 2, 1, 0, -3]).partial_sum => [ 17 19 20 20 17 ] ==> Tensor "double": 1 x 5 = 5 (C; dft = 0) Tsr.s([1, 2, 3, 4]).partial_sum(:*) => [ 1 2 6 24 ] ==> Tnsr "object": 1 x 4 = 4 (C; dft = nil)
See also Tensor#adjacent_diff which is the inverse.
# File rtensor_api.rb, line 1021
1021: def partial_sum ( sym = :+ ) # => new_tsr
1022: end
Returns the real part of the tensor.
Tsr[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]].real
=>
[ 1 0 0
1 2 3 ]
==> Tensor "object": 2 x 3 = 6 (C; dft = 0)
# File rtensor_sup.rb, line 260
260: def real ( ) # => new_tsr
261: collect do |e|
262: if e.kind_of?(Numeric)
263: e.real
264: else
265: e
266: end
267: end
268: end
Returns a 1D-tensor (row vector) which is the ith row of the 2D-tensor (matrix).
Tsr[[1, 2, 3], [4, 5, 6]].row(Tsr::Begin) => [ 1 2 3 ] ==> Tensor "object": 1 x 3 = 3 (C; dft = 0)
# File rtensor_sup.rb, line 277
277: def row ( i ) # => new_tsr
278: ensure_2D
279: self[i, All]
280: end
Returns true if Tnsr is in row order (instead of column order).
Tsr.s.row_order? => false
# File rtensor_api.rb, line 869
869: def row_order? ( ) # => true or false
870: end
Returns the number of rows.
# File rtensor_sup.rb, line 285
285: def row_size ( ) # => int
286: size(Begin)
287: end
Sets the Tnsr default value. Returns the original tensor. Note: This will have some effect on sparse tensor if the sparse tensor is actually full or its other values are the same as def; in that case, elements which have values equal to dft will be deleted.
Tsr[[1, 2], [3]].set_dft(7)
=>
[ 1 2
3 0 ]
==> Tensor "object": 2 x 2 = 4 (C; dft = 7)
# File rtensor_api.rb, line 878
878: def set_dft ( dft ) # => orig_tsr
879: end
Returns a new Array which describes the dimensions of the tensor.
Tsr.s(:string, [3, 4, 5]).shape => [3, 4, 5]
# File rtensor_sup.rb, line 296
296: def shape ( ) # => array
297: dim.to_a
298: end
Returns a new tensor with elements logically shifted by the amount given by integer k (by considering the tensor as one long array). It shifts left when given a positive argument and right when given a negative argument. The “empty” elements are filled with the default value.
Tsr.s([1, 2, 3, 4, 5, 6, 7, 8]).shift(2) => [ 3 4 5 6 7 8 nil nil ] ==> Tnsr "object": 1 x 8 = 8 (C; dft = nil) Tsr.s([1, 2, 3, 4, 5, 6, 7, 8]).shift(-2) => [ nil nil 1 2 3 4 5 6 ] ==> Tnsr "object": 1 x 8 = 8 (C; dft = nil)
For cyclic shift, see Tnsr#cshift.
# File rtensor_api.rb, line 891
891: def shift ( k ) # => new_tsr
892: end
Alias for: Tnsr#length
# File rtensor_api.rb, line 908
908: def size ( { k } ) # => int
909: end
Returns true if Tnsr is sparse.
Tsr.s(true).sparse? => true
# File rtensor_api.rb, line 914
914: def sparse? ( ) # => true or false
915: end
Returns the sum tensor of the 2D-tensor (matrix). If the tensor is a vector, then a scalar tensor is returned. Else, if $RowOrder if false, the sums of each columns are returned as a row vector; otherwise the sums of each rows are returned as a column vector.
Tsr.t([[1, 2, 3], [4]]).sum => [ 5 2 3 ] ==> Tensor "double": 1 x 3 = 3 (C; dft = 0) Tsr.s(['ab', 'cd'], '', :string).sum => [ "abcd" ] ==> Tnsr "string": 1 x 1 = 1 (C; dft = "")
# File rtensor_sup.rb, line 311
311: def sum ( ) # => new_tsr
312: ensure_2D
313: if vector?
314: tpe = ttype
315: tpe = 'c' + tpe if complex?
316: ans = Tnsr.new(tot_sum, get_dft, tpe.to_sym, sparse?)
317: elsif $RowOrder
318: ans = self[All, Begin]
319: (Begin...Begin + row_size).each {|r| ans[r] = self[r, All].tot_sum}
320: else
321: ans = self[Begin, All]
322: (Begin...Begin + col_size).each {|c| ans[c] = self[All, c].tot_sum}
323: end
324: ans
325: end
Alias for: Tnsr#transpose
# File rtensor_api.rb, line 925
925: def t ( ) # => new_tsr
926: end
Returns a “multi-dimensional” array representation. (The “flat” array representation is given by the Enumerable’s to_a method.)
Tsr.s([[1, 2, 3], 4, [5, 6]]).to_array => [[1, 2, 3], [4, nil, nil], [5, 6, nil]]
# File rtensor_sup.rb, line 332
332: def to_array ( rowOrd = true ) # => array
333: indices = shape
334: if rowOrd
335: indices[0] = size(Begin + 1)
336: indices[1] = size(Begin)
337: end
338: if rowOrd && row_order? || ! rowOrd && ! row_order?
339: ary = to_a
340: else
341: ary = transpose.to_a
342: end
343: v = []
344: _to_array_rcs(v, indices.size - 1, indices, ary)
345: end
Returns a string representation of the multi-dimensional array format.
print Tsr.s(7, [2, 4, 2]).to_ary_str
[ [ [ 7, 7, 7, 7 ],
[ 7, 7, 7, 7 ] ],
[ [ 7, 7, 7, 7 ],
[ 7, 7, 7, 7 ] ] ]
=> nil
# File rtensor_api.rb, line 935
935: def to_ary_str ( rowOrd = true ) # => str
936: end
Returns a Matrix representation of the 2D-tensor.
Tsr[[25, 93], [-1, 66]].to_matrix => Matrix[[25, 93], [-1, 66]]
# File rtensor_sup.rb, line 365
365: def to_matrix ( ) # => Matrix
366: ensure_2D
367: require 'matrix'
368: rows = []
369: (Begin...Begin + row_size()).each {|i| rows.push(row(i).to_a)}
370: Matrix.rows(rows)
371: end
Returns a new tensor which is a regular (not sparse) tensor. The order of the new tensor will follow the current boolean value of $RowOrder.
Tsr.s(true).to_regular => [] ==> Tnsr "object": 0 x 0 = 0 (C; dft = nil)
# File rtensor_api.rb, line 943
943: def to_regular ( ) # => new_tsr
944: end
Returns a string representation.
# File rtensor_api.rb, line 947
947: def to_s ( ) # => str
948: end
Returns a new tensor which is a sparse tensor with default value given by optional argument dft. If dft is given by the symbol :-, it means it is equal to the default value of the current tensor. The order of the new tensor will follow the current boolean value of $RowOrder.
Tsr.s.to_sparse => [ ] ==> Tnsr<sprs> "object": 0 x 0 = 0 (C; dft = nil)
# File rtensor_api.rb, line 956
956: def to_sparse ( dft = :- ) # => new_tsr
957: end
Returns the total sum of all elements in the tensor.
Tsr.s([1, 2, 3]).tot_sum => 6
See also Tnsr#accumulate.
# File rtensor_api.rb, line 921
921: def tot_sum ( ) # => obj
922: end
Returns the trace (sum of diagonal elements) of the 2D-tensor (matrix).
Tsr[[7, 6], [3, 9]].trace => 16
# File rtensor_sup.rb, line 378
378: def trace ( ) # => numeric
379: diag.tot_sum
380: end
Returns a new tensor which is the transpose of the original tensor.
Tsr[[1, 2], [3, 4], [5, 6]]
=>
[ 1 2
3 4
5 6 ]
==> Tensor "object": 3 x 2 = 6 (C; dft = 0)
Tsr[[1, 2], [3, 4], [5, 6]].transpose
=>
[ 1 3 5
2 4 6 ]
==> Tensor "object": 2 x 3 = 6 (C; dft = 0)
Also aliased as: Tnsr#t
# File rtensor_api.rb, line 973
973: def transpose ( ) # => new_tsr
974: end
Returns a string of the Tnsr type (i.e., Ruby objects, string, bool, double, etc.).
Tsr.s(:cldouble).ttype => "ldouble"
# File rtensor_api.rb, line 979
979: def ttype ( ) # => str
980: end
Returns true if the tensor is 2D and either row size is equal to 1 or column size is equal to 1.
# File rtensor_sup.rb, line 387
387: def vector? ( ) # => true or false
388: if is_2D? && (row_size == 1 || col_size == 1)
389: true
390: else
391: false
392: end
393: end
Returns a new tensor by performing “unary ~“ (complement) to each element. For string type, this does not perform any operation (besides returning a new tensor). This operation is undefined for Float and Complex types.
~Tsr.s([1,2,3]) => [ -2 -3 -4 ] ==> Tnsr "object": 1 x 3 = 3 (C; dft = nil)
For “unary !“ (not), see Tnsr #!.
# File rtensor_api.rb, line 542
542: def ~ ( ) # => new_tsr
543: end
# File rtensor_sup.rb, line 348
348: def _to_array_rcs(v, lvl, indices, ary)
349: (0...indices[lvl]).each do
350: unless lvl == 0
351: to_array_rcs(v.push([]).last, lvl - 1, indices, ary)
352: else
353: v.push(ary.shift)
354: end
355: end
356: v
357: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.