Tensor Evaluation Reference
A tensor is a set of named dimensions defining its order and a set of values located in the space of those dimensions:
 Cell: A value located in the dimension space. Consists of a cell address and the floating point value at that address.
 Address: A set of keyvalues where each key is a dimension from the set of dimensions of the tensor, and each value is a label (integer or identifier) determining the cells location in that dimension.
[0,N>
(like an array), where N is the size of the dimension.
The dimensions of a tensor defines its type, see the tensor type spec.
Literal Form
The standard literal form of tensors specified verbatim in ranking expressions is as follows (expressed in EBNF):literal tensor = "{" cells "}" ; cells =  cell , { "," cell } ; cell = "{" address "}:" scalar ; address =  element, { "," element } ; element = dimension ":" label ; dimension = integer  string ; label = integer  string ;
Literal form examples
An empty tensor:
{}A single value tensor with a single mapped dimension x:
{ {x:foo}:5.0 }A tensor with multiple values and mapped dimensions x and y:
{ {x:foo, y:bar}:5.0, {x:foo, y:baz}:7.0 }A tensor with a single indexed dimension x representing a vector:
{ {x:0}:3.0, {x:1}:5.0, {x:2}:7.0 }
Operations
The following set of tensors operations are available to use in ranking expressions. We group the operations in primitive functions and convenience functions that can be implemented by primitive functions.
Primitive functions
map  map(tensor, f(x)(expr))  Returns a new tensor with the lambda function defined in f(x)(expr) applied to each cell. 
reduce  reduce(tensor, aggregator, dim1, dim2, ...)  Returns a new tensor with the aggregator applied across dimensions dim1, dim2, etc. If no dimensions are specified, reduce over all dimensions. 
join  join(tensor1, tensor2, f(x,y)(expr))  Returns a new tensor constructed from the natural join between tensor1 and tensor2 , with the resulting cells having the value as calculated from f(x,y)(expr) , where x is the cell value from tensor1 and y from tensor2 . 
tensor  tensor(tensortypespec)(expr)  Generates new tensors according to type specification and expression expr . 
rename  rename(tensor, dimensionstorename, newnames)  Renames one or more dimensions in the tensor. 
concat  concat(tensor1, tensor2, dim)  Concatenates two tensors along dimension dim . 
Lambda functions in primitive functions
Some of the primitive functions accept lambda functions that are evaluated and applied to a set of tensor cells. The functions contain a single expression that have the same format and builtin functions as general ranking expressions. However, the atoms are the arguments defined in the argument list of the lambda.
The expression cannot access variables or data structures outside of the lambda, i.e. they are not closures.
Examples:
f(x)(abs(x)) f(x,y)(if(x < y, 0, 1))
 Map
Arguments:
tensor
: a tensor.f(x)(expr)
: a lambda function with one argument.
Returns a new tensor where the expression in the lambda function is
evaluated in each cell in tensor
.
Examples:
map(t, f(x)(abs(x))) map(t, f(i)(if(i < 0, 0, i)))
 Reduce
Arguments:
tensor
: a tensor.aggregator
: the aggregator to use. See below.dim1, dim2, ...
: the dimensions to reduce over. Optional.
Returns a new tensor with the aggregator applied across dimensions
dim1
, dim2
, etc.
If no dimensions are specified, reduce over all dimensions.
Available aggregators are:
avg
: arithmetic meancount
: number of elementsprod
: product of all valuessum
: sum of all valuesmax
: maximum valuemin
: minimum value
Examples:
reduce(t, sum) # Sum all values in tensor reduce(t, count, x) # Count number of cells along dimension x
 Join
Arguments:
tensor1
: a tensor.tensor2
: a tensor.f(x,y)(expr)
: a lambda function with two arguments.
Returns a new tensor constructed from the natural join
between tensor1
and tensor2
, with the
resulting cells having the value as calculated from f(x,y)(expr)
,
where x
is the cell value from tensor1
and
y
from tensor2
.
Formally, the result of the join
is a new tensor with dimensions
the union of dimension between tensor1
and tensor2
.
The cells are the set of all combinations of cells that have equal values
on their common dimensions.
Examples:
t1 = {{x:0}: 1.0, {x:1}: 2.0} t2 = {{x:0,y:0}: 3.0, {x:0,y:1}: 4.0, {x:1,y:0}: 5.0, {x:1,y:1}: 6.0} join(t1, t2, f(x,y)(x * y)) = {{x:0,y:0}: 3.0, {x:0,y:1}: 4.0, {x:1,y:0}: 10.0, {x:1,y:1}: 12.0} reduce(join(t1, t2, f(x,y)(x * y)), sum) = 29.0
 tensor
Arguments:
tensortypespec
: a bound indexed tensor type specification.(expr)
: a lambda function expressing how to generate the tensor.
Generates new tensors according to the type specification and expression expr
. The tensor
type must be a bound indexed tensor (e.g. tensor(x[10])
) for Vespa to be able to
generate the tensor. The expression in expr
will be evaluated for each cell.
The arguments in the expression is implicitly the names of the dimensions defined in the type spec.
Useful for creating transformation tensors.
Examples:
tensor(x[3])(x) = {{x:0}: 0.0, {x:1}: 1.0, {x:2}: 2.0} tensor(x[2],y[2])(x == y) = {{x:0,y:0}: 1.0, {x:0,y:1}: 0.0, {x:1,y:0}: 0.0, {x:1,y:1}: 1.0}
 rename
Arguments:
tensor
: a tensor.dimtorename
: a dimension, or list of dimensions, to rename.newnames
: new names for the dimensions listed above.
Returns a new tensor with one or more dimension renamed.
Examples:
t1 = {{x:0,y:0}: 1.0, {x:0,y:1}: 0.0, {x:1,y:0}: 0.0, {x:1,y:1}: 1.0} rename(t1,x,z) = {{z:0,y:0}: 1.0, {z:0,y:1}: 0.0, {z:1,y:0}: 0.0, {z:1,y:1}: 1.0} rename(t1,(x,y),(i,j)) = {{i:0,j:0}: 1.0, {i:0,j:1}: 0.0, {i:1,j:0}: 0.0, {i:1,j:1}: 1.0}
 concat
Arguments:
tensor1
: a tensor or scalar.tensor2
: a tensor or scalar.dim
: the dimension to concatenate along.
Returns a new tensor with the two tensors tensor1
and
tensor2
concatenated along dimension dim
. The tensors
can also be scalars.
Examples:
t1 = {{x:0}: 0.0, {x:1}: 1.0} t2 = {{x:0}: 2.0, {x:1}: 3.0} concat(t1,t2,x) = {{x:0}: 0.0, {x:1}: 1.0}, {x:2}: 2.0, {x:3}: 3.0}}
Nonprimitive functions
Nonprimitive functions can be implemented by primitive functions, but are not necessarily so for performance reasons.
abs(t) 
map(t, f(x)(abs(x))) Absolute value of all elements. 
acos(t) 
map(t, f(x)(acos(x))) Arc cosine of all elements. 
t1 + t2 (add) 
join(t1, t2, f(x,y)(x + y)) Join and sum tensors t1 and t2 .

argmax(t) 
join(t, max(t), f(x,y)(if (x == y, 1, 0))) Returns a tensor with cell(s) of the highest value(s) in the tensor set to 1. 
argmin(t) 
join(t, min(t), f(x,y)(if (x >= y, 0, 1))) Returns a tensor with cell(s) of the lowest value(s) in the tensor set to 1. 
asin(t) 
map(t, f(x)(asin(x))) Arc sine of all elements. 
atan(t) 
map(t, f(x)(atan(x))) Arc tangent of all elements. 
atan2(t1,t2) 
join(t1, t2, f(x,y)(atan2(x,y))) Arctangent of t1 and t2 /

avg(t, dim) 
reduce(t, avg, dim) Reduce the tensor with the average aggregator along dimension dim .

ceil(t) 
map(t, f(x)(ceil(x))) Ceiling of all elements. 
count(t, dim) 
reduce(t, count, dim) Reduce the tensor with the count aggregator along dimension dim .

cos(t) 
map(t, f(x)(cos(x))) Cosine of all elements. 
cosh(t) 
map(t, f(x)(cosh(x))) Hyperbolic cosine of all elements. 
diag(n1,n2) 
tensor(i[n1],j[n2])(if (i==j, 1.0, 0.0))) Returns a tensor with the diagonal set to 1.0. 
t1 / t2 (div) 
join(t1, t2, f(x,y)(x / y)) Join and divide tensors t1 and t2 .

elu(t) 
map(t, f(x)(if(x < 0, exp(x)1, x))) Exponential linear unit. 
t1 == t2 (equal) 
join(t1, t2, f(x,y)(x == y)) Join and determine if each element in t1 and t2 are equal.

exp(t) 
map(t, f(x)(exp(x))) Exponential function (e^x) of each element. 
floor(t) 
map(t, f(x)(floor(x))) Floor of each element. 
t1 > t2 (greater) 
join(t1, t2, f(x,y)(x > y)) Join and determine if each element in t1 is greater than t2 .

t1 >= t2 (greater or equals) 
join(t1, t2, f(x,y)(x >= y)) Join and determine if each element in t1 is greater than or equals t2 .

t1 < t2 (less) 
join(t1, t2, f(x,y)(x < y)) Join and determine if each element in t1 is less than t2 .

t1 <= t2 (less equals) 
join(t1, t2, f(x,y)(x <= y)) Join and determine if each element in t1 is less than or equals t2 .

l1_normalize(t, dim) 
join(t, reduce(t, sum, dim), f(x,y) (x / y)) L1 normalization: t / sum(t, dim) .

l2_normalize(t, dim) 
join(t, map(reduce(map(t, f(x)(x * x)), sum, dim), f(x)(sqrt(x))), f(x,y)(x / y)) L2 normalization: t / sqrt(sum(t^2, dim) .

log(t) 
map(t, f(x)(log(x))) Natural logarithm of each element. 
log10(t) 
map(t, f(x)(log10(x))) Logarithm with base 10 of each element. 
matmul(t1, t2, dim) 
reduce(join(t1, t2, f(x,y)(x * y)), sum, dim) Matrix multiplication of two tensors. This is the product of the two tensors summed along a shared dimension. 
max(t, dim) 
reduce(t, max, dim) Reduce the tensor with the max aggregator along dimension dim .

max(t1,t2) 
join(t1, t2, f(x,y)(max(x,y))) Join and return the max of t1 or t2 . Arguments can be scalars.

min(t, dim) 
reduce(t, min, dim) Reduce the tensor with the min aggregator along dimension dim .

min(t1,t2) 
join(t1, t2, f(x,y)(min(x,y))) Join and return the minimum of t1 or t2 . Arguments can be scalars.

mod(t,constant) 
map(t, f(x)(mod(x,constant))) Modulus of constant with each element.

t1 * t2 (mul) 
join(t1, t2, f(x,y)(x * y)) Join and multiply tensors t1 and t2 .

t1 != t2 (not equal) 
join(t1, t2, f(x,y)(x != y)) Join and determine if each element in t1 and t2 are not equal.

pow(t,constant) 
map(t, f(x)(pow(x,constant))) Raise each element to the power of constant .

prod(t, dim) 
reduce(t, prod, dim) Reduce the tensor with the product aggregator along dimension dim .

random(n1, n2, ...) 
tensor(i1[n1],i2[n2],...)(random(1.0)) Returns a tensor with random values between 0.0 and 1.0, uniform distribution. 
range(n) 
tensor(i[n])(i) Returns a tensor with increasing values. 
relu(t) 
map(t, f(x)(max(0,x))) Rectified linear unit. 
round(t) 
map(t, f(x)(round(x))) Round each element. 
sigmoid(t) 
map(t, f(x)(1.0 / (1.0 + exp(0.0x)))) Returns the sigmoid of each element. 
sin(t) 
map(t, f(x)(sin(x))) Sinus of each element. 
sinh(t) 
map(t, f(x)(sinh(x))) Hyperbolic sinus of each element. 
sign(t) 
map(t, f(x)(if(x < 0, 1.0, 1.0))) The sign of each element. 
softmax(t, dim) 
join(map(t, f(x)(exp(x))), reduce(map(t, f(x)(exp(x))), sum, dim), f(x,y)(x / y)) The softmax of the tensor, e.g. e^x / sum(e^x) .

sqrt(t) 
map(t, f(x)(sqrt(x))) The square root of each element. 
square(t) 
map(t, f(x)(square(x))) The square of each element. 
t1  t2 (subtract) 
join(t1, t2, f(x,y)(x  y)) Join and subtract tensors t1 and t2 .

sum(t, dim) 
reduce(t, sum, dim) Reduce the tensor with the summation aggregator along dimension dim .

tan(t) 
map(t, f(x)(tan(x))) The tangent of each element. 
tanh(t) 
map(t, f(x)(tanh(x))) The hyperbolic tangent of each element. 
xw_plus_b(x,w,b,dim) 
join(reduce(join(x, w, f(x,y)(x * y)), sum, dim), b, f(x,y)(x+y)) Matrix multiplication of x (usually a vector) and w (weights), with b added (bias). A typical operation for activations in a neural network layer, e.g. sigmoid(xw_plus_b(x,w,b))) .

Tensor Rank Features
The following rank features can be used to reference tensors when doing tensor operations in ranking expressions. The tensors can come from the document, the query or be constant for a deployment of your application.
Please take a look at the following reference documentations on how use tensors in documents:
 attribute(tensor_attribute)
Returns the tensor value found in the given tensor attribute.
Take a look at tensor type and tensortypespec reference doc for how to setup a tensor attribute in your search definition.
Example tensor attribute field in a sdfile where the tensor has 2 mapped dimensions, x and y:
field tensor_attribute type tensor(x{},y{}) { indexing: attribute  summary }
 query(tensor_feature)
Returns the tensor value passed down with the query as a feature.
In order to use this feature you must define the tensor type of the query feature in a query profile type. In the following example the tensor type is defined to have one mapped dimension x:
<queryprofiletype id="myProfileType"> <field name="ranking.features.query(tensor_feature)" type="tensor(x{})" /> </queryprofiletype>The tensor value itself must be set in a searcher using the com.yahoo.search.query.ranking.RankFeatures instance that is associated with an instance of com.yahoo.search.Query. In the following example we create a tensor with a single cell with value 500:
package com.yahoo.example; import com.yahoo.search.Query; import com.yahoo.search.Result; import com.yahoo.search.Searcher; import com.yahoo.search.searchchain.Execution; import com.yahoo.tensor.MappedTensor; import com.yahoo.tensor.TensorType; public class TensorInQuerySearcher extends Searcher { @Override public Result search(Query query, Execution execution) { query.getRanking().getFeatures().put("query(tensor_feature)", new MappedTensor.Builder(TensorType.fromSpec("tensor(x{})")).cell().label("x", "foo").value(500).build()); return execution.search(query); } }
Take a look at query profile field type reference doc for more information on how to specify a field as a tensor in a query profile type.
 constant(tensor_constant)
Returns the constant tensor value with the given name as specified in your sdfile.
Take a look at constant reference documentation for how to specify constant tensors in your sdfile.
 tensorFromWeightedSet(source, dimension)
Creates a tensor with one mapped dimension from the given integer or string weighted set source. The source can be either an attribute field or a query parameter. The source parameter is required and must be specified as follows:
 attribute(attributeName): The tensor is created based on the content of the weighted set attribute attributeName.
 query(propertyName): The tensor is created based on the weighted set passed down with the query using
&ranking.properties.propertyName={k1:w1,k2:w2,...,kN:wN}
.
Example:
Assume we have the following weighted set with keys and corresponding weights, and the dimension dim:
{k1:w1,k2:w1,...,kN:wN}The tensor representation of this weighted set has the dimension dim with the following content:
{ {dim:k1}:w1, {dim:k2}:w2, ..., {dim:kN}:wN} }
 tensorFromLabels(source, dimension)
Creates a tensor with one mapped dimension from the given integer or string array source. The source can be either an attribute field or a query parameter. The source parameter is required and must be specified as follows:
 attribute(attributeName): The tensor is created based on the content of the array attribute attributeName.
 query(propertyName): The tensor is created based on the array passed down with the query using
&ranking.properties.propertyName=[v1 v2 ... vN]
.
Example:
Assume we have the following array with values and the dimension dim
:
[v1 v2 ... vN]The tensor representation of this array has the dimension dim with the following content:
{ {dim:v1}:1.0, {dim:v2}:1.0, ..., {dim:vN}:1.0} }