This is a complete reference to the ranking expressions used to configure application specific ranking functions. For examples and an overview of how to use ranking expressions, see the ranking overview.
Ranking expressions are written in a simple language similar to ordinary functional notation. The atoms in ranking expressions are rank features and constants. These atoms can be combined by arithmetic operations and other builtin functions over scalars and tensor.
Rank Features 
A rank feature is a named value calculated or looked up by vespa for each query/document combination. See the rank feature reference for a list of all the rank features available to ranking expressions. 

Constants 
A constant is either a floating point number, a boolean (true/false) or a quoted string. Since ranking expressions can only work on scalars and tensors, strings and booleans are immediately converted to scalars  true becomes 1.0, false 0.0 and a string its hash value. This means that strings can only be used for equality comparisons, other purposes such as parametrizing the key to slice out of a tensor will not work correctly. 
Basic mathematical operations are expressed in infix notation:
a + b * c
Arithmetic operations work on any tensor in addition to scalars, and are a short form
of joining the tensors with the arithmetic operation used to join the cells.
For example tensorA * tensorB
is the same as join(tensorA, tensorB, f(a,b)(a * b))
.
All arithmetic operators in order of decreasing precedence:
Arithmetic operator  Description 

^  Power 
%  Modulo 
/  Division 
*  Multiplication 
  Subtraction 
+  Addition 
&&  And: 1 if both arguments are nonzero, 0 otherwise. 
  Or: 1 if either argument is nonzero, 0 otherwise. 
Function  Description 

acos(x)  Inverse cosine of x 
asin(x)  Inverse sine of x 
atan(x)  Inverse tangent of x 
atan2(y, x)  Inverse tangent of y / x, using signs of both arguments to determine correct quadrant. 
bit(x, y)  Returns value of bit y in value x (for int8 values) 
ceil(x)  Lowest integral value not less than x 
cos(x)  Cosine of x 
cosh(x)  Hyperbolic cosine of x 
elu(x)  The Exponential Linear Unit activation function for value x 
erf(x)  The Gauss error function for value x 
exp(x)  Basee exponential function. 
fabs(x)  Absolute value of (floatingpoint) number x 
floor(x)  Largest integral value not greater than x 
fmod(x, y)  Remainder of x / y 
isNan(x)  Returns 1.0 if x is NaN, 0.0 otherwise 
ldexp(x, exp)  Multiply x by 2 to the power of exp 
log(x)  Basee logarithm of x 
log10(x)  Base10 logarithm of x 
max(x, y)  Larger of x and y 
min(x, y)  Smaller of x and y 
pow(x, y)  Return x raised to the power of y 
relu(x)  The Rectified Linear Unit activation function for value x 
sigmoid(x)  The sigmoid (logistic) activation function for value x 
sin(x)  Sine of x 
sinh(x)  Hyperbolic sine of x 
sqrt(x)  Square root of x 
tan(x)  Tangent of x 
tanh(x)  Hyperbolic tangent of x 
hamming(x, y)  Hamming (bitwise) distance between x and y (considered as 8bit integers). 
x
and y
may be any ranking expression.
The if
function chooses between two subexpressions based on the truth value of a condition.
if (expression1 operator expression2, trueExpression, falseExpression)
If the condition given in the first argument is true, the expression in argument 2 is used, otherwise argument 3. The four expressions may be any ranking expression. Conditional operators in ranking expression if functions:
Boolean operator  Description 

<=  Less than or equal 
<  Less than 
==  Equal 
~=  Approximately equal 
>=  Greater than or equal 
>  Greater than 
The in
membership operator uses a slightly modified ifsyntax:
if (expression1 in [expression2, expression3, ..., expressionN], trueExpression, falseExpression)
If expression1 is equal to either of expression1 through expressionN, then trueExpression is used, otherwise falseExpression.
The foreach function is not really part of the expression language but implemented as a rank feature.
The following set of tensors functions are available to use in ranking expressions. The functions are grouped in primitive functions and convenience functions that can be implemented in terms of the primitive ones.
Function  Description 

map( tensor, f(x)(expr) ) 
Returns a new tensor with the lambda function defined in Arguments:
tensor . Examples:
map(t, f(x)(log(x))) map(t, f(i)(if(i < 0, 0, i))) 
reduce( tensor, aggregator, dim1, dim2, ... ) 
Returns a new tensor with the Arguments:
Returns a new tensor with the aggregator applied across dimensions
Available aggregators are:
reduce(t, sum) # Sum all values in tensor reduce(t, count, x) # Count number of cells along dimension x 
join( tensor1, tensor2, f(x,y)(expr) ) 
Returns a new tensor constructed from the natural join between Arguments:
Returns a new tensor constructed from the natural join
between
Formally, the result of the Examples: # With tensors 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} # ... you get 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 
merge( tensor1, tensor2, f(x,y)(expr) ) 
Returns a new tensor consisting of all cells from both the arguments, where the lambda function is used to produce a single value in the cases where both arguments provide a value for a cell. Arguments:
Returns a new tensor having all the cells of both arguments, where the lambda is invoked to produce a single value only when both arguments have a value for the same cell. The argument tensors must have the same type, and that will be the type of the resulting tensor. Example: # With tensors t1 := tensor(key{},x[4]):{a:[1,2],b:[3,4]} t2 := tensor(key{},x[2]):{b:[5,6],c:[7,8]} # ... you get merge(t1, t2, f(left,right)(right)) == tensor(key{},x[2]):{a:[1,2],b:[5,6],c:[7,8]} 
tensor( tensortypespec )(expr) 
Generates new tensors according to type specification and expression Arguments:
Generates new tensors according to the type specification and expression Useful for creating transformation tensors. Examples: # With tensor t1 := tensor(x[4]):[1.0, 2.0, 3.0, 4.0] # ... you get tensor<float>(x[3])(x) == [0.0, 1.0, 2.0] tensor<float>(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 } # Create a size 2 1d tensor by accessing t1 at two indexes given by adding # the index of it (f  which is 0 and 1) by a function also named f. tensor(f[2])(t1{x: f + f()})) 
rename( tensor, dimtorename, newnames ) 
Renames one or more dimensions in the tensor. Arguments:
# With tensors 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} # ... you get 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( tensor1, tensor2, dim ) 
Concatenates two tensors along dimension Arguments:
tensor1 and
tensor2 concatenated along dimension dim . Examples:
# With tensors t1 := {{x:0}: 0.0, {x:1}: 1.0} t2 := {{x:0}: 2.0, {x:1}: 3.0} # You get concat(t1,t2,x) == {{x:0}: 0.0, {x:1}: 1.0}, {x:2}: 2.0, {x:3}: 3.0}} 
(tensor)partialaddress 
Slice  returns a new tensor containing the cells matching the partial address. Arguments:
# With tensors t1 := tensor(x[2]):[1.0, 2.0] t2 := tensor(key{}):{ key1:1.0, key2:2.0 } t3 := tensor(key{},x[2]):{ key1:[1.0, 2.0], key2:[3.0, 4.0] } # ... you get t1[1] == {2.0} t2{key1} == {1.0} t3{key1} == tensor(x[2]):[1.0, 2.0] t3[1] == tensor(key{}):{key1:2.0, key2:4.0} t3{key:key1,x:1} == {2.0} t3{key:key1,x:(32)} == {2.0} t3{key:key1,x:myFunctionReturning1()} == {2.0} 
tensorliteralform 
Returns a new tensor having the type and cell values given explicitly. Each cell value may be supplied by a lambda which can access other features. Returns a new tensor from the literal form, where the type must be specified explicitly. Each value may be supplied by a lambda, which  in contrast to all other lambdas  may refer to features and expressions from the context. Examples: # With tensor t1 := tensor(x[2]):[1.0, 2.0]] # ... you get tensor(x{}):{x1:3, x2:4} == tensor(x{}):{x1:3.0, x2:4.0} # Used in conjunction with slice, to convert an indexed tensor to mapped form: tensor(x{}):{x1:t1[1], x2:t1[0]} = tensor(x{}):{x1:2.0, x2:1.0} 
cell_cast( tensor, cell_type ) 
Returns a new tensor that is the same as the argument, except that all cell values are converted to the given cell type. Arguments:
# With tensors t1 := tensor<float>(x[5])(x+1) t2 := tensor<bfloat16>(x[5])(x+1) # ... you get t2 == cell_cast(t1, bfloat16) 
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)(log(x)) f(x,y)(if(x < y, 0, 1))
Nonprimitive functions can be implemented by primitive functions, but are not necessarily so for performance reasons.
Function  Description  

acos(t) 
Arc cosine of all elements. 

t1 + t2 (add) 
Join and sum tensors 

argmax(t, dim) 
Returns a tensor with cell(s) of the highest value(s) in the tensor set to 1. The dimension argument follows the same format as reduce as multiple dimensions can be given and is optional. 

argmin(t, dim) 
Returns a tensor with cell(s) of the lowest value(s) in the tensor set to 1. The dimension argument follows the same format as reduce as multiple dimensions can be given and is optional. 

asin(t) 
Arc sine of all elements. 

atan(t) 
Arc tangent of all elements. 

atan2(t1, t2) 
Arctangent of 

avg(t, dim) 
Reduce the tensor with the 

ceil(t) 
Ceiling of all elements. 

count(t, dim) 
Reduce the tensor with the 

cos(t) 
Cosine of all elements. 

cosh(t) 
Hyperbolic cosine of all elements. 

diag(n1, n2) 
Returns a tensor with the diagonal set to 1.0. 

t1 / t2 (div) 
Join and divide tensors 

elu(t) 


t1 == t2 (equal) 
Join and determine if each element in 

exp(t) 
Exponential function (e^x) of each element. 

expand(t, dim) 
Adds an indexed dimension with name 

floor(t) 
Floor of each element. 

t1 > t2 (greater) 
Join and determine if each element in 

t1 >= t2 (greater or equals) 
Join and determine if each element in 

t1 < t2 (less) 
Join and determine if each element in 

t1 <= t2 (less or equals) 
Join and determine if each element in 

l1_normalize(t, dim) 
L1 normalization: 

l2_normalize(t, dim) 
L2 normalization: 

log(t) 
Natural logarithm of each element. 

log10(t) 
Logarithm with base 10 of each element. 

matmul(t1, t2, dim) 
Matrix multiplication of two tensors. This is the product of the two tensors summed along a shared dimension. 

max(t, dim) 
Reduce the tensor with the 

max(t1, t2) 
Join and return the max of 

hamming(t1, t2) 
Join and return the Hamming distance between matching cells of
Note that the cell values are always treated as if they were both 8bit integers in the range [128,127], and only then counting the number of bits that are different. See also the corresponding distance metric. Arguments can be scalars. 

median(t, dim) 
Reduce the tensor with the 

min(t, dim) 
Reduce the tensor with the 

min(t1, t2) 
Join and return the minimum of 

mod(t, constant) 
Modulus of 

t1 * t2 (mul) 
Join and multiply tensors 

t1 != t2 (not equal) 
Join and determine if each element in 

pow(t, constant) 
Raise each element to the power of 

prod(t, dim) 
Reduce the tensor with the 

random(n1, n2, ...) 
Returns a tensor with random values between 0.0 and 1.0, uniform distribution. 

range(n) 
Returns a tensor with increasing values. 

relu(t) 
Rectified linear unit. 

sigmoid(t) 
Returns the sigmoid of each element. 

sin(t) 
Sinus of each element. 

sinh(t) 
Hyperbolic sinus of each element. 

softmax(t, dim) 
The softmax of the tensor, e.g. 

sqrt(t) 
The square root of each element. 

t1  t2 (subtract) 
Join and subtract tensors 

sum(t, dim) 
Reduce the tensor with the 

tan(t) 
The tangent of each element. 

tanh(t) 
The hyperbolic tangent of each element. 

xw_plus_b(x, w, b, dim) 
Matrix multiplication of 