# API Reference¶

## pybbfmm¶

pybbfmm.limits(prob)[source]

Calculates the geometric limits to the problem

Parameters

prob – a problem.

Returns

A (2, D)-tensor of the maximum and minimum extents of the problem.

pybbfmm.scale(prob)[source]

Scales a problem to lie in $$[-1, +1]^D$$.

Parameters

prob – a problem.

Returns

a scaled problem with the limits and scale as additional keys.

pybbfmm.weights(scaled, cheb, tree, indices)[source]

Calculates the weights used in a solution.

Parameters
Returns

a (n_boxes, n_cheb_coeffs dim)-tensor of weights.

pybbfmm.v_interactions(W, scaled, cheb, tree, scheme)[source]

Calculates the v-interactions used in a solution.

Parameters
Returns

a (n_boxes, n_cheb_coeffs dim)-tensor of interactions.

pybbfmm.x_interactions(scaled, cheb, tree, indices, scheme)[source]

Calculates the x-interactions used in a solution.

Parameters
Returns

a (n_boxes, n_cheb_coeffs dim)-tensor of interactions.

pybbfmm.w_interactions(W, scaled, cheb, tree, indices, scheme)[source]

Calculates the w-interactions used in a solution.

Parameters
Returns

a (n_targets)-tensor of interactions.

pybbfmm.u_interactions(scaled, indices, scheme)[source]

Calculates the u-interactions used in a solution.

Parameters
Returns

a (n_targets)-tensor of interactions.

pybbfmm.far_field(W, v, x, cheb, tree)[source]

Calculates the far-field contributions for each box.

Parameters
Returns

a (n_boxes, n_cheb_coeffs dim)-tensor of far-field contributions

pybbfmm.target_far_field(F, scaled, cheb, tree, indices, chunksize=1000000)[source]

Calculates the far-field contributions for each target.

Parameters
Returns

a (n_targets,)-tensor of far-field contributions.

pybbfmm.presolve(prob, N=4, capacity=8)[source]

Presolves a problem, returning a dotdict full of information that can be used to evaluate() any problem with the same points and kernel.

Parameters
• prob – the problem to presolve.

• N – the number of Chebyshev nodes to use.

• capacity – the maximum number of sources or targets per box.

Returns

a dotdict full of presolve data.

pybbfmm.evaluate(cheb, scaled, tree, scheme, indices, depths)[source]

Evaluates a problem using presolve() data. This lets you do the expensive part - the presolve - once for any configuration of points.

The arguments are as returned by presolve(). You can swap out the scale()’d problem to solve a different problem to the one you presolved.

Returns

a (n_target,)-tensor of field intensities at the targets.

pybbfmm.solve(prob, N=4)[source]

Solves the given problem.

Parameters
• prob – the problem to solve.

• N – the number of Chebyshev nodes to use.

Returns

a (n_target,)-tensor of field intensities at the targets.

## chebyshev¶

class pybbfmm.chebyshev.Chebyshev(N, D, device=None)[source]

Helps with Chebyshev interpolation.

Interpolation is assumed to happen on $$[-1, +1]^D$$.

Parameters
• N – the number of Chebyshev nodes along each dimension.

• D – the number of dimensions

• device – the device to cache things on. Typically 'cuda'.

property nodes[source]

A cached copy of the locations of the Chebyshev nodes, given as a (N:superscript:D, D)-tensor.

similarity(a, b)[source]

Calculates the Chebyshev ‘similarity’ between each pair of two sets of points.

Don’t know if it’s called similarity anywhere else, but it’s the matrix of weights that lets you go from concrete values to interpolation weights and vice versa.

Parameters
• a – a (*ms, d)-tensor of points

• b – a (*ns, d)-tensor of points

Returns

a (*ms, *ns)-tensor of similarities between a and b’s points.

interpolate(x, w)[source]

Calculate values at points x from the interpolation weights w.

The weights w are typically generated from anterpolate().

anterpolate(x, v)[source]

Calculate interpolation weights from values v at points x.

The weights returned are for the interpolation points given by nodes.

upwards_coeffs()[source]

Calculates the coefficients needed to interpolate from one level of the tree to the next one up.

downwards_coeffs()[source]

Calculates the coefficients needed to interpolate from one level of the tree to the next one down.

## orthantree¶

pybbfmm.orthantree.orthantree(scaled, capacity=8)[source]

Constructs a tree for the given scale()’d problem.

This is a bit of a mess of a function, but long story short it starts with all the sources allocated to the root and repeatedly subdivides overfull boxes, constructing the various tree tensors as it goes.

Parameters
• scaledscale()’d problem.

• capacity – the max number of sources or targets per box.

Returns

A tree.

pybbfmm.orthantree.neighbour_boxes(tree, indices, directions)[source]

Finds the neighbour of indices in the tree in the given direction.

There’s a non-vectorized (and easier to understand) version of this function here.

pybbfmm.orthantree.u_scheme(tree, neighbours)[source]

Calculates the u-scheme.

pybbfmm.orthantree.v_scheme(tree, depths, directions, neighbours)[source]

Calculates the v-scheme.

pybbfmm.orthantree.w_pairs(tree, directions, neighbours)[source]

Metadata needed for calculating w- and x-scheme.

pybbfmm.orthantree.interaction_scheme(tree, depths)[source]

Returns the datastructures needed to calculate the interactions between boxes.

The datastructures are pretty heterogeneous because, well, performance. They’re set up so the data needed can be got at fast without blowing up the memory budget.

Parameters
• tree – a tree.

• depths – the depths to go with the tree.

Returns

a scheme.

## ragged¶

class pybbfmm.ragged.Ragged(image, cardinalities)[source]

A ragged tensor, which is to a tensor of different-length tensors.

The different-length sub-tensors are concatenated together to make a single backing tensor. This makes for fast element-wise operations.

A lot of the language in this class’s implementation comes from thinking of a ragged tensor as a mapping from indices to sub-tensors.

Parameters
• image – the sub-tensors, concatenated together in order. The image of the mapping.

• cardinalities – the number of elements in each sub-tensor.

property domain[source]

Returns the size of the domain - ie the number of sub-tensors.

property range[source]

Returns the size of the arnge - ie the sum of the lengths of all the subtensors, or equivalently the size of the backing tensor.

kth(qs, c)[source]

For each q in qs, returns the c th element of the q th subtensor.

Only returns valid values - ie it only returns the results for which q is at least c+1 elements long. To indicate which q were valid, it also returns a mask.

For example,

# Sub-tensors are [1, 2], [10, 11, 12], [20]
r = Ragged([1, 2, 10, 11, 12, 20], [2, 3, 1])
r.kth([1, 2], 1)
# [11], [True, False]


q c 0   1   2
0  [1,  2]
1  [10, 11, 12]
2  [20]


Calling r.kth([1, 2], 1) means taking rows [1, 2] and column 1. We get back the values that exist in this column - [11] and a mask saying which rows stretch as far as column c.

slice(idx)[source]

Returns the slice corresponding to the idx th sub-tensor.

image(idx)[source]

Returns the idx th sub-tensor.

## sets¶

pybbfmm.sets.cartesian_product(xs, D)[source]

Returns all D-tuples of xs as a (n_xs, n_xs, …, *tail_dims)-tensor.

pybbfmm.sets.flat_cartesian_product(xs, D)[source]

Returns all D-tuples of xs as a (n_xs D, *tail_dims)-tensor.