triangularmap.tmap.TMap

class triangularmap.tmap.TMap(arr, linearise_blocks=False, _n=None, *args, **kwargs)[source]

Bases: object

A wrapper around a 1D array that provides access in triangular (or ternary) coordinates. A 1D array of length N = n (n + 1) / 2 is mapped to a triangular layout as follows (here with N=21 and n=6):

                       /\         depth  level
                      /0 \            0      6
                     /\  /\
                    /1 \/ 2\          1      5
                   /\  /\  /\
                  /3 \/4 \/5 \        2      4
                 /\  /\  /\  /\
                /6 \/7 \/8 \/9 \      3      3
               /\  /\  /\  /\  /\
              /10\/11\/12\/13\/14\    4      2
             /\  /\  /\  /\  /\  /\
            /15\/16\/17\/18\/19\/20\  5      1
           |   |   |   |   |   |   |
start/end: 0   1   2   3   4   5   6

Values can be accessed by start and end index (0 \leq start < end \leq n) as follows:

               (0, 6)
            (0, 5) (1, 6)
         (0, 4) (1, 5) (2, 6)
      (0, 3) (1, 4) (2, 5) (3, 6)
   (0, 2) (1, 3) (2, 4) (3, 5) (4, 6)
(0, 1) (1, 2) (2, 3) (3, 4) (4, 5) (5, 6)

That is (start, end) is mapped to the linear index depth (depth + 1) / 2 + end - level, where depth = n - (end - start) and level = n - depth. Advanced integer index arrays are processed in the same way and are applied to the underlying array following standard numpy rules (e.g. direct assignment works but otherwise a copy of the values is returned instead of a view). Additionally, slices by depth or level return views of the underlying array segment. Slices by start or end index are also supported but internally use advanced indexing, so they return a copy, not a view.

Public Data Attributes:

n

Size of the triangular map, i.e., the width at the triangle base.

arr

Underlying storage container.

value_shape

Shape of the values stored in the map.

linearise_blocks

lslice

A convenience property that uses get_lslice() and set_lslice() as getter and setter, respectively.

dslice

A convenience property that uses get_dslice() and set_dslice() as getter and setter, respectively.

sslice

A convenience property that uses get_sslice() and set_sslice() as getter and setter, respectively.

eslice

A convenience property that uses get_eslice() and set_eslice() as getter and setter, respectively.

sblock

A convenience property that uses get_sblock() and set_sblock() as getter and setter, respectively.

eblock

A convenience property that uses get_eblock() and set_eblock() as getter and setter, respectively.

Public Methods:

size_from_n(n)

Calculate the size N of the underlying 1D array for a given width n of the triangular map: N = n (n + 1)) / 2.

n_from_size(n)

Calculate width n of the map given the size N of the underlying 1D array: n = (\sqrt{8 * N + 1} - 1) / 2.

get_reindex_from_start_end_to_top_down(n)

For a map of width n, get an index array of length n (n + 1)) / 2 to reindex from start-end order to top-down order.

reindex_from_start_end_to_top_down(arr)

Reindex arr from start-end order to top-down order.

get_reindex_from_top_down_to_start_end(n)

For a map of width n, get an index array of length n (n + 1)) / 2 to reindex from top-down order to start-end order.

reindex_from_top_down_to_start_end(arr)

Reindex arr from top-down order to start-end order.

__init__(arr[, linearise_blocks, _n])

depth(start, end)

Compute the depth d corresponding to (start, end): d = n - (end - start).

level(*args)

Compute the level from depth or (start, end).

linear_from_start_end(start, end)

Compute the linear index (in the underlying 1D array) corresponding to a (start, end) pair.

__getitem__(item)

Get the item corresponding to (start, end) or the sub-map corresponding to slice start:end.

__setitem__(key, value)

Set the item corresponding to (start, end).

copy()

Copy the map.

top([depth])

Return the sub-map corresponding to the top-most levels.

linear_start_end_from_level(level)

Compute the linear 1D start and end index corresponding to all values in the respective level of the map.

get_lslice(level)

Slice the map at the given level, returning a view of the values.

set_lslice(level, value)

get_dslice(depth)

Slice the map at the given depth, returning a view of the values.

set_dslice(depth, value)

get_sslice(item)

Return a slice for the given start index.

set_sslice(key, value)

Like get_sslice but set value instead of returning values.

get_eslice(item)

Return a slice for the given end index.

set_eslice(key, value)

Like get_eslice but set value instead of returning values.

get_sblock(item)

Return a block of sslices down from the specified level.

set_sblock(key, value)

Like get_sblock but set value.

get_eblock(item)

Return a block of eslices down from the specified level.

set_eblock(key, value)

Like get_sblock but set value.

flatten([order])

Return map in linear order.

__repr__()

Return repr(self).

__str__()

Return a string representation of the map, consisting of consecutive dslices.

pretty([cut, str_func, detach_pytorch, scf, ...])

Pretty-print a triangular map.

Private Data Attributes:

_flatten_regex

Private Methods:

_to_int(i)

Convert i to integer, no matter whether it is a single number or a numpy array.

_unpack_item(item)

_is_pytorch()

_check(start, end)

Check whether 0 <= start < end < n.

_end_indices_for_sslice(start)

Compute the end indices corresponding to a slice at the give start index.

_start_indices_for_eslice(end)

Compute the start indices corresponding to a slice at the give end index.

_get_sblock_index(item)

_get_eblock_index(item)


class GetSetWrapper(getter, setter)[source]

Bases: object

Wrapper class that delegates __getitem__ and __setitem__ to custom functions

class UnDef[source]

Bases: object

Class to indicate undefined indices

property arr

Underlying storage container.

copy()[source]

Copy the map. If the underlying data is a lists, tuple, numpy array or pytorch tensor, the appropriate functions are called, otherwise a deepcopy of the data is made.

Returns:

Copied map.

depth(start, end)[source]

Compute the depth d corresponding to (start, end): d = n - (end - start). This function also works with arrays.

Parameters:
  • start – start index or array of indices

  • end – end index or array of indices

Returns:

depth or array of depth values

property dslice

A convenience property that uses get_dslice() and set_dslice() as getter and setter, respectively.

property eblock

A convenience property that uses get_eblock() and set_eblock() as getter and setter, respectively.

property eslice

A convenience property that uses get_eslice() and set_eslice() as getter and setter, respectively.

flatten(order='-l+s')[source]

Return map in linear order. The different orders correspond to iteration using two nested for loops where the first letter indicates the outer dimension and the second the inner: s: start, e: end, l: level. A minus sign reverses the order of the respective dimension.

Parameters:

order – string specifying order of linearisation: ‘+s+e’, ‘+e+s’, ‘+l+s’ (+ can be omitted or replaced with -)

Returns:

1D array with values in given order

get_dslice(depth)[source]

Slice the map at the given depth, returning a view of the values.

Parameters:

depth – depth to use for slicing

Returns:

view of the values

get_eblock(item)[source]

Return a block of eslices down from the specified level.

get_eslice(item)[source]

Return a slice for the given end index. Internally, advanced indexing is used, so the returned values are a copy, not a view. item can be a tuple to further slice down before retrieving the values.

Parameters:

item – end index or tuple of end index and additional indices/slices

Returns:

copy of slice at end index

get_lslice(level)[source]

Slice the map at the given level, returning a view of the values.

Parameters:

level – level to use for slicing

Returns:

view of the values

classmethod get_reindex_from_start_end_to_top_down(n)[source]

For a map of width n, get an index array of length n (n + 1)) / 2 to reindex from start-end order to top-down order. This is used in reindex_from_start_end_to_top_down() to perform the reindexing.

Parameters:

n – width of map

Returns:

index array of length n (n + 1)) / 2

classmethod get_reindex_from_top_down_to_start_end(n)[source]

For a map of width n, get an index array of length n (n + 1)) / 2 to reindex from top-down order to start-end order. This is used in reindex_from_top_down_to_start_end() to perform the reindexing.

Parameters:

n – width of map

Returns:

index array of length n (n + 1)) / 2

get_sblock(item)[source]

Return a block of sslices down from the specified level.

get_sslice(item)[source]

Return a slice for the given start index. Internally, advanced indexing is used, so the returned values are a copy, not a view. item can be a tuple to further slice down before retrieving the values.

Parameters:

item – start index or tuple of start index and additional indices/slices

Returns:

copy of slice at start index

level(*args)[source]

Compute the level from depth or (start, end). If (start, end) is given, the depth function is used to first compute the depth. This function also works with arrays.

Parameters:

args – either one argument (depth) or two (start, end), which can also be arrays

Returns:

depth or array of depth values

linear_from_start_end(start, end)[source]

Compute the linear index (in the underlying 1D array) corresponding to a (start, end) pair. This function also works with arrays.

Parameters:
  • start – start index or array of indices

  • end – end index or array of indices

Returns:

linear index or array of linear indices

linear_start_end_from_level(level)[source]

Compute the linear 1D start and end index corresponding to all values in the respective level of the map. Slicing the underlying array as arr[start:end + 1] will return a view of the values on the level.

Parameters:

level – level for which to compute the indices

Returns:

linear 1D start and end index

property linearise_blocks
property lslice

A convenience property that uses get_lslice() and set_lslice() as getter and setter, respectively.

property n

Size of the triangular map, i.e., the width at the triangle base. This is not the total size of the underlying storage (use size_from_n() to convert to that).

classmethod n_from_size(n)[source]

Calculate width n of the map given the size N of the underlying 1D array: n = (\sqrt{8 * N + 1} - 1) / 2. Checks for valid size (i.e. if the resulting n is actually an integer) and raises a ValueError otherwise. This function also works with arrays.

Parameters:

n – size of the underlying 1D array

Returns:

width of the map

pretty(cut=None, str_func=None, detach_pytorch=True, scf=None, pos=None, rnd=None, align='r', crosses=False, cross_border=True, fill_char=' ', pad_char=' ', top_char=' ', bottom_char=' ', fill_lines=True, haxis=False, daxis=False, laxis=False, left_border_char='╱', left_inner_char='╱', right_border_char='╲', right_inner_char='╲', left_border_cross_char='╳', right_border_cross_char='╳', inner_cross_char='╳', top_cross_char='╳', grid_off=False)[source]

Pretty-print a triangular map. See the gallery for usage examples.

Parameters:
  • cut – cut at specified level, printing only the bottom ‘cut’ levels of the map

  • str_func – function to convert values to strings (default: str)

  • detach_pytorch – whether to detach tensors if the underlying array is a pytorch tensor

  • scf – kwargs to use np.format_float_scientific to format value

  • pos – kwargs to use np.format_float_positional to format value

  • rnd – kwargs to use np.around to format value

  • align – right-align (‘r’) or left-align (‘l’) content within cells

  • crosses – use a different style for plotting the triangular map

  • cross_border – in ‘crosses’ style, use crosses also at the border, otherwise use straight lines

  • fill_char – character used for indenting lines (and filling lines; see fill_lines)

  • pad_char – character used for padding content (left or right; depending on align)

  • top_char – character used to fill remaining space at the top within cells

  • bottom_char – character used to fill remaining space at the bottom within cells

  • fill_lines – whether to fill lines to same length on the right side

  • haxis – plot a horizontal axis with ticks and tick labels

  • daxis – plot a depth axis on the right (not compatible with ‘laxis’)

  • laxis – plot a level axis on the right (not compatible with ‘daxis’)

Returns:

pretty-printed string

classmethod reindex_from_start_end_to_top_down(arr)[source]

Reindex arr from start-end order to top-down order.

Parameters:

arr – linear array in start-end order

Returns:

linear array in top-down order

Given a linear array [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], assuming start-end order translates to the triangular map:

       ╱╲
      ╱ 3╲
     ╱╲  ╱╲
    ╱ 2╲╱ 6╲
   ╱╲  ╱╲  ╱╲
  ╱ 1╲╱ 5╲╱ 8╲
 ╱╲  ╱╲  ╱╲  ╱╲
╱ 0╲╱ 4╲╱ 7╲╱ 9╲

Assuming top-down order translates into:

       ╱╲
      ╱ 0╲
     ╱╲  ╱╲
    ╱ 1╲╱ 2╲
   ╱╲  ╱╲  ╱╲
  ╱ 3╲╱ 4╲╱ 5╲
 ╱╲  ╱╲  ╱╲  ╱╲
╱ 6╲╱ 7╲╱ 8╲╱ 9╲

Applying reindex_from_start_end_to_top_down() to the array [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] reorders it to [3, 2, 6, 1, 5, 8, 0, 4, 7, 9], so that the upper triangular map is produced using the lower ordering principle. This is the inverse function of reindex_from_top_down_to_start_end().

classmethod reindex_from_top_down_to_start_end(arr)[source]

Reindex arr from top-down order to start-end order.

Parameters:

arr – linear array in top-down order

Returns:

linear array in start-end order

Given a linear array [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], assuming top-down order translates to the triangular map:

       ╱╲
      ╱ 0╲
     ╱╲  ╱╲
    ╱ 1╲╱ 2╲
   ╱╲  ╱╲  ╱╲
  ╱ 3╲╱ 4╲╱ 5╲
 ╱╲  ╱╲  ╱╲  ╱╲
╱ 6╲╱ 7╲╱ 8╲╱ 9╲

Assuming start-end order translates into:

       ╱╲
      ╱ 3╲
     ╱╲  ╱╲
    ╱ 2╲╱ 6╲
   ╱╲  ╱╲  ╱╲
  ╱ 1╲╱ 5╲╱ 8╲
 ╱╲  ╱╲  ╱╲  ╱╲
╱ 0╲╱ 4╲╱ 7╲╱ 9╲

Applying reindex_from_top_down_to_start_end() to the array [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] reorders it to [6, 3, 1, 0, 7, 4, 2, 8, 5, 9], so that the upper triangular map is produced using the lower ordering principle. This is the inverse function of reindex_from_start_end_to_top_down()

property sblock

A convenience property that uses get_sblock() and set_sblock() as getter and setter, respectively.

set_dslice(depth, value)[source]
set_eblock(key, value)[source]

Like get_sblock but set value.

set_eslice(key, value)[source]

Like get_eslice but set value instead of returning values.

set_lslice(level, value)[source]
set_sblock(key, value)[source]

Like get_sblock but set value.

set_sslice(key, value)[source]

Like get_sslice but set value instead of returning values.

classmethod size_from_n(n)[source]

Calculate the size N of the underlying 1D array for a given width n of the triangular map: N = n (n + 1)) / 2. This function also works with arrays.

Parameters:

n – Width (number of entries at the bottom of the map)

Returns:

Length of underlying 1D array (total number of entries in the map)

property sslice

A convenience property that uses get_sslice() and set_sslice() as getter and setter, respectively.

top(depth=None)[source]

Return the sub-map corresponding to the top-most levels. A view of the underlying data is used, so the returned TMap shares the same buffer and modification affect both objects.

Parameters:

depth – How many levels from the top to include

Returns:

sub-map

property value_shape

Shape of the values stored in the map. If the underlying array has more than one dimension, the first one is used for the map and value_shape() corresponds to the remaining dimensions.