Orbital library

orbital.math
Interface Tensor

All Superinterfaces:
Arithmetic, Normed
All Known Subinterfaces:
Matrix, Vector

public interface Tensor
extends Arithmetic

Represents a tensor t∈Rn0×n1×…×nr-1 of dimensions n0×n1×…×nr-1 and rank r.

If you intend to use mutable arithmetic elements, note the discussion of mutations per reference vs. explicit cloning in set(int[],Arithmetic) which generally holds for all operations that set component values.

Also note that some few methods will change its instance and explicitly return this to allow chaining of structural changes, whilst arithmetic methods will leave a tensor unchanged but return a modified version. Refer to the documentation of the individual methods for details.

Author:
André Platzer
See Also:
ValueFactory.tensor(Arithmetic[]), ValueFactory.tensor(Arithmetic[][]), ValueFactory.tensor(Arithmetic[][][]), ValueFactory.tensor(Object)
Invariants:
succeedes(#clone()) ∧ (overwrites(#clone()) ∨ this implements Cloneable)
Structure:
extends Arithmetic, extends Iteratable

Field Summary
 
Fields inherited from interface orbital.math.Arithmetic
numerical
 
Method Summary
 Tensor add(Tensor b)
          Adds two tensors returning a tensor.
 java.lang.Object clone()
           
 int[] dimensions()
          Returns the dimensions of the tensor.
 java.util.Iterator entries()
          Returns an iterator over our (relevant) entries (index, coefficient)-pairs.
 Arithmetic get(int[] i)
          Get the component specified by index.
 java.util.Iterator indices()
          Returns an iterator over the (relevant) indices.
 java.util.ListIterator iterator()
          Returns an iterator over all components.
 Tensor multiply(Tensor b)
          Inner product of a tensor with a tensor returning a tensor.
 int rank()
          Get the rank of the tensor.
 void set(int[] i, Arithmetic vi)
          Sets the component specified by index.
 void setSubTensor(int level, int index, Tensor part)
          Sets a part of lesser rank in this tensor.
 Tensor subTensor(int[] i1, int[] i2)
          Get a sub-tensor view ranging (i1:i2) inclusive.
 Tensor subTensor(int level, int index)
          Get a view on a part of the tensor of a lesser rank.
 Tensor subTensorTransposed(int[] permutation)
          Returns a view on this tensor transposed.
 Tensor subtract(Tensor b)
          Subtracts two tensors returning a tensor.
 Tensor tensor(Tensor b)
          Tensor product of a tensor with a tensor returning a tensor.
 
Methods inherited from interface orbital.math.Arithmetic
add, divide, equals, inverse, isOne, isZero, minus, multiply, one, power, scale, subtract, toString, valueFactory, zero
 
Methods inherited from interface orbital.math.Normed
norm
 

Method Detail

clone

java.lang.Object clone()
Postconditions:
RES≠RES ∧ RES≠this ∧ RES.equals(this)

rank

int rank()
Get the rank of the tensor. The rank is the number of dimensions needed as indices for the components of this tensor. It is the grade for the tensor algebra T(M) over the underlying module M.

See Also:
Matrix.linearRank()
Postconditions:
RES≥0

dimensions

int[] dimensions()
Returns the dimensions of the tensor.

If n0×n1×…×nr-1 are the dimensions of this tensor of rank r, then all (valid) indices i∈Nr to this tensor satisfy ∀k ik∈{0,…,nk-1}.

Returns:
an array d containing the dimensions of this tensor.
Postconditions:
RES.length == rank()

get

Arithmetic get(int[] i)
Get the component specified by index.

Of course, this method only has a meaning for tensors of free modules like vector spaces.

Parameters:
i - the index i of the component value to get.
Returns:
ti[0].i[1],…i[i.length-1] ∈ R.
Preconditions:
valid(i) := (i.length == rank() ∧ ∀k 0≤i[k]≤dimensions()[k]-1)

set

void set(int[] i,
         Arithmetic vi)
         throws java.lang.UnsupportedOperationException
Sets the component specified by index.

Of course, this method only has a meaning for tensors of free modules like vector spaces.

Depending upon the implementation, the value vi might be kept per reference, if possible. However, whether it is kept per reference is a matter of performance and subject to free interpretation by the implementation class. So if vi is mutable, and a tensor implementation decides to keep it per reference, any modifications of vi would also appear in that tensor, rendering it useless. Since every implementation is allowed to choose the tensor's internal data representation freely, you should not rely on such behaviour of mutable arithmetic objects to provoke inner state changes. Instead you should carefully avoid setting a value by reference without cloning, if you intend to change its state, afterwards. Explicitly cloning vi prior to setting it as an element of this tensor is always safe (provided that you do not keep additional references to it). If, however, vi is immutable (which should be the usual case), no such sources of mistakes exist.

Parameters:
i - the index i of the component value to set.
vi - the value to set for the component vi at position i.
Throws:
java.lang.UnsupportedOperationException - if this tensor is constant and does not allow modifications.
Preconditions:
valid(i)

iterator

java.util.ListIterator iterator()
Returns an iterator over all components.

Note: the list iterator returned is not required to support ListIterator.nextIndex() and ListIterator.previousIndex(), or ListIterator.add(Object) and ListIterator.remove(), and won't usually do so. The reason is that one-dimensional indices are meaningless for tensors of rank r>1 and that adding a single component to a tensor is not allowed as it would destroy its rectangular form. Nevertheless, vectors (rank 1) may support those operations.

Returns:
an iterator that iterates over v0,…,0,…,v1,…,0,……,vn1-1,…,nr-1.

indices

java.util.Iterator indices()
Returns an iterator over the (relevant) indices.

The order of this iterator is not generally defined, but should be deterministic. Particularly, the iterator may - but need not - be restricted to occurring indices with coefficients ≠0.

Returns:
an iterator over a finite set of indices in Vector<Integer> at least containing all indices of coefficients ≠0.
Postconditions:
∀i∈Vector<Integer>∖RES get(i)=0

entries

java.util.Iterator entries()
Returns an iterator over our (relevant) entries (index, coefficient)-pairs.

The order of this iterator is not generally defined, but should be deterministic. Particularly, the iterator may - but need not - be restricted to occurring indices with coefficients ≠0.

Returns:
an iterator over a finite set of pairs of indices in Vector<Integer> and coefficients in R at least containing all pairs for coefficients ≠0.
Postconditions:
∀(i,c)∈Vector<Integer>×R∖RES get(i)=0

subTensor

Tensor subTensor(int[] i1,
                 int[] i2)
Get a sub-tensor view ranging (i1:i2) inclusive.

The resulting tensor is a (sub-)view of this tensor. Therefore, the returned tensor is backed by this tensor, so changes in the returned tensor are reflected in this tensor, and vice-versa.

The semantics of the tensor returned by this method becomes undefined if the backing tensor (i.e., this object) is structurally modified in any way other than via the returned tensor. (Structural modifications are those that change the dimensions, or otherwise perturb it in such a fashion that iterations in progress may yield incorrect results.)

The resulting tensor is structurally unmodifiable in order to prevent it from inducing undefined behaviour on its backing tensor. Query operations on the returned tensor "read through" to this object, and attempts to structurally modify the returned vector, whether direct or via its iterator, result in an UnsupportedOperationException. However, setting single components will "write through" to the this object.

Returns:
a tensor view of the specified part of this tensor.
t(i1:i2) = (ml)l∈{l∈Nr ¦ ∀k i1[k]≤l[k]≤i2[k]}
Preconditions:
i1.length==rank() ∧ i2.length==rank() ∧ ∀k i1[k]≤i2[k] ∧ valid(i1) ∧ valid(i2)

subTensor

Tensor subTensor(int level,
                 int index)
Get a view on a part of the tensor of a lesser rank.

The returned tensor is a structurally unmodifiable view.

Parameters:
level - the level l of indices to fix for this view.
index - the index cl of the tensor part view at the level-th index.
Returns:
a tensor view of the specified part ti0×i1×…×il-1×&cl×il+1&×l…×ir-1 in this tensor.
See Also:
setSubTensor(int,int,Tensor), Functionals.bindFirst(orbital.logic.functor.BinaryFunction, Object), Functionals.bindSecond(orbital.logic.functor.BinaryFunction, Object)
Postconditions:
RES.rank() = rank() - 1 ∧ ....

setSubTensor

void setSubTensor(int level,
                  int index,
                  Tensor part)
Sets a part of lesser rank in this tensor.

See Also:
subTensor(int,int)
Preconditions:
part.rank()==rank()-1 ∧ Utilities.equalsAll(part.dimensions(), subTensor(level,index).dimensions())

subTensorTransposed

Tensor subTensorTransposed(int[] permutation)
Returns a view on this tensor transposed.

The returned tensor is a view.

Parameters:
permutation - the mapping table of a permutation σ∈Srank() mapping i↦permutation[i] for permuting the indices.
Returns:
a tensor view of the transposed tensor tiσ(0)×iσ(1)×…×iσ(r-1) with permuted indices.
Preconditions:
permutation∈Srank()
Postconditions:
RES.rank() = rank() ∧ RES.get(i) = get(permutation(i))

add

Tensor add(Tensor b)
Adds two tensors returning a tensor.

Preconditions:
Arrays.equals(dimensions(), b.dimension()) otherwise there can only be a purely symbolic result in tensor algebra.
Postconditions:
Arrays.equals(RES.dimensions(), dimensions()) && RES.get(i) == get(i) + b.get(i)
Attributes:
associative, neutral (0), inverse (-v), commutative

subtract

Tensor subtract(Tensor b)
Subtracts two tensors returning a tensor.

Preconditions:
Arrays.equals(dimensions(), b.dimension()) otherwise there can only be a purely symbolic result in tensor algebra.
Postconditions:
Arrays.equals(RES.dimensions(), dimensions()) && RES.get(i) == get(i) - b.get(i)
Attributes:
associative

multiply

Tensor multiply(Tensor b)
Inner product of a tensor with a tensor returning a tensor.
· Rn0×…×nr-1×h×Rh×m0×…×ms-1 Rn0×…×nr-1×h×Rh×m0×…×ms-1
((ai0,…,ir-1,ir)i0,…,ir-1,ir , (bj-1,j0,…,js-1)j-1,j0,…,js-1) (∑ν=0h-1 ai0,…,ir-1⋅bν,j0,…,js-1)i0,…,ir-1,j0,…,js-1

Returns:
the inner product a·b.
Preconditions:
dimensions()[rank()-1] == b.dimensions()[0]
Postconditions:
RES.dimensions() = {dimensions()[0],…dimensions()[rank()-2]}∪{b.dimensions()[1],…b.dimensions()[b.rank()-1]}
Note:
inner product is only one (partial) multiplication on graded tensor algebra

tensor

Tensor tensor(Tensor b)
Tensor product of a tensor with a tensor returning a tensor.
Rn0×…×nr-1×Rm0×…×ms-1 Rn0×…×nr-1×m0×…×ms-1
((ai0,…,ir-1)i0,…,ir-1 , (bj0,…,js-1)j0,…,js-1)
=(a,b)
(ai0,…,ir-1⋅bj0,…,js-1)i0,…,ir-1,j0,…,js-1 =̂ (ai0,…,ir-1·b)i0,…,ir-1
At least formally, the last form of the calculation resembles the scalar multiplication b·a if a was a vector of a left-Rm0×…×ms-1-modules.

Returns:
the tensor product (or outer product) a⊗b.
Postconditions:
RES.dimensions() = dimensions()∪b.dimensions()
Note:
tensor product is only one multiplication on graded tensor algebra T(M). Although it is always defined, a more "natural" multiplication on tensors of rank 2, for example, is the inner product which therefore plays the role of the default (though partial) ring multiplication.

Orbital library
1.3.0: 11 Apr 2009

Copyright © 1996-2009 André Platzer
All Rights Reserved.