Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Tensor Filtering with Dynamic Thresholds

TL;DR:

function filter_subspaces_above_threshold(t, threshold) {
    expression: filter_subspaces(t - threshold, f(x)(x > 0)) + threshold
}

function filter_subspaces_below_threshold(t, threshold) {
    expression: filter_subspaces(t - threshold, f(x)(x < 0)) + threshold
}

The Issue

The somewhat new builtin filter_subspaces function promises to produce a new tensor containing only the subspaces that match the filter. The main limitation is that filtering is done with a lambda and in Vespa lambda expressions

cannot access variables or data structures outside the lambda, i.e., they are not closures.

i.e., the filter cannot access neither document attributes, nor query inputs, nor constants, and not even other functions, i.e., you need to know the filter value at application build time, i.e., the threshold can’t be dynamic[1].

The Workaround

There is a neat trick to filter on a dynamic scalar value:

  1. subtract the threshold value from the tensor

  2. filter_subspaces on (1) for being larger or smaller than 0

  3. add the threshold value back to (2)[2].

Or one-liner:

filter_subspaces(t - threshold, f(x)(x > 0)) + threshold

Example:

filter_subspaces(
    tensor<float>(chunk{}):{0:13,1:7,2:5,3:15,4:30,5:2} - 10, 
    f(x)(x > 0)
) + 10
=> tensor<float>(chunk{}):{0:13.0, 3:15.0, 4:30.0}

Check the Tensor Playground runnable example.

The Discussion

The inconvenient part is that we need two functions for filtering above or below the threshold.

If your threshold is another tensor[3], make sure it has all the same dimensions as the tensor you want to filter because the - is join’ed on the target tensor, i.e., non-common dimensions are dropped.

What if the tensor has an indexed dimension?

filter_subspaces(tensor(a{},x[2]):{"q": [1,5], "w": [10,20]}, f(x)(x > 5))
=> tensor(a{},x[2]):{w:[10.0, 20.0]}

i.e., at least one value within the indexed dimension should pass the threshold.

Final Thoughts

I believe filtering on some threshold is a pretty common use case of filter_subspaces, and this trick should be mentioned somewhere. Or maybe even become a built-in function.

P.S.

For more tensor fun, check The Advent fo Tensors

Footnotes
  1. Also, there is another approach of filtering by a dynamic value in the Tensor Playground with masking.

  2. Yeah, like back in the calculus class, we’ve been adding and then subtracting 1 to rewrite the expression.

  3. i.e., a collection of thresholds.