操作符#

操作符对集合的各个元素进行操作。GraphBLAS中有各种操作符类,每个类都有定义的数学属性。

一元运算符#

一元运算符将一个输入值映射到可能不同的域中的另一个值。

示例用法:

# Compute the absolute value of each element in M
M_abs = gb.unary.abs(M).new()

常见的一元运算符有:

  • identity – 返回未更改的输入

  • abs – 绝对值

  • ainv – 加法逆元 (f(x) = -x)

  • minv – 乘法逆元 (f(x) = 1/x)

  • lnot – 逻辑非 (True -> False)

  • bnot – 二进制取反 (110010 -> 001101)

  • one – 结果始终为1.0(或对应数据类型的等效值)

  • round – 浮点数舍入函数

  • floor – 浮点数向下取整函数

  • ceil – 浮点数向上取整函数

  • sin – 三角函数正弦函数

  • cos – 三角函数余弦函数

  • tan – 三角函数正切函数

  • exp – 指数

  • log – 对数

一元运算符位于graphblas.unary命名空间中。从numpy注册的额外一元运算符位于graphblas.unary.numpy

二元运算符#

二元运算符接受两个输入并返回一个值。输入域和输出域不需要匹配。

输出累加器是二元运算符。

示例用法:

# Element-wise union, taking the max for intersecting element
# Accumulate the result into M via addition
M(accum=gb.binary.plus) << gb.binary.max(A | B)

常见的二元运算符有:

  • pair – 结果始终为1.0(或对应数据类型的等效值)

  • 第一个 – f(a, b) = a

  • second – f(a, b) = b

  • min – min(a, b)

  • max – max(a, b)

  • eq – a == b

  • ne – a != b

  • gt – a > b

  • lt – a < b

  • ge – a >= b

  • le – a <= b

  • plus – a + b

  • minus – a - b

  • times – a * b

  • truediv – a / b

  • fmod – a % b

  • pow – a ** b

  • atan2 – math.atan2(a, b)

  • lor – 逻辑或 (a | b)

  • land – 逻辑与 (a & b)

  • lxor – 逻辑异或 (a ^ b)

  • lxnor – 逻辑异或非 ~(a ^ b)

  • bor – 二进制或

  • band – 二进制与

  • bxor – 二进制异或

  • bxnor – 二进制异或非

二元运算符位于graphblas.binary命名空间中。从numpy注册的额外二元运算符位于graphblas.binary.numpy中。

幺半群#

Monoids 扩展了二元操作符的概念,要求所有输入和输出都在同一个域内。 Monoids 也是结合的,因此操作的顺序无关紧要 (例如,(a + b) + c == a + (b + c))。 GraphBLAS 主要使用交换性 monoids(例如,a + b == b + a), 并且 python-graphblas 中的所有标准 monoids 都是交换的。 最后,monoids 有一个默认的恒等元素,使得 A op identity == A

幺半群通常用于归约,将所有元素折叠为单个值。

示例用法:

# Sum up all non-empty elements in M
total = M.reduce_scalar(gb.monoid.plus).value

常见的幺半群有:

  • any – 返回任一输入

  • min – min(a, b)

  • max – max(a, b)

  • plus – a + b

  • times – a * b

  • land – a & b

  • lor – a | b

  • lxor – a ^ b

  • lxnor – ~(a ^ b)

Monoids 位于 graphblas.monoid 命名空间中。从 numpy 注册的额外 monoids 位于 graphblas.monoid.numpy

半环#

半环是幺半群和二元运算符的组合。二元运算符用于点积的“乘法”部分,而幺半群用于归约。

标准矩阵乘法使用“plus_times”半环。

半环主要用于矩阵乘法期间。

示例用法:

C << gb.semiring.min_plus(A @ B)

常见的半环有:

  • plus_times(标准矩阵乘法)

  • min_plus(用于最短路径计算)

  • max_plus

  • min_times

  • max_times

  • min_max

  • max_min

  • min_first

  • min_second

  • max_first

  • max_second

  • plus_min

  • lor_land

  • land_lor

半环位于graphblas.semiring命名空间中。从numpy注册的额外半环位于graphblas.semiring.numpy

索引一元运算符#

一元运算符的一个变体是索引一元运算符。它们的行为与一元运算符完全相同,但输入是值、该值的索引位置和一个thunk参数。

例如,应用于矩阵的IndexUnary运算符将获得每个元素的值、行和列(加上thunk)。运算符可以使用所有这些部分来确定适当的输出。

IndexUnary 运算符主要用于 select 中,以根据索引位置进行过滤。

示例用法:

# Select the upper triangle
A_upper = gb.select.triu(A).new(name="A_upper")
../_images/Matrix-A-upper.png

使用 thunk 参数的示例:

# Select the upper triangle, excluding the diagonal
A_upper = gb.select.triu(A, 1).new(name="A_strictly_upper")
../_images/Matrix-A-strictly-upper.png

定义的索引一元运算符有:

  • index – 返回向量索引

  • rowindex – 返回矩阵的行索引

  • colindex – 返回矩阵的列索引

  • diagindex – 返回矩阵对角线的索引(即列 - 行)

  • tril – 下三角矩阵(如果列 >= 行则为真)

  • triu – 上三角矩阵(如果列 <= 行则为真)

  • diag – 矩阵对角线(如果行 == 列则为True)

  • offdiag – 矩阵的非对角线部分(如果行 != 列则为True)

  • indexle – 向量索引 <= 阈值

  • indexgt – 向量索引 > 阈值

  • rowle – 矩阵行索引 <= thunk

  • rowgt – 矩阵行索引 > thunk

  • colle – 矩阵列索引 <= thunk

  • colgt – 矩阵列索引 > thunk

  • valueeq – 值 == thunk

  • valuene – 值 != thunk

  • valuelt – 值 < thunk

  • valuele – 值 <= thunk

  • valuegt – 值 > thunk

  • valuege – 值 >= 阈值

一元运算符位于两个位置。

  • graphblas.indexunary

    所有的IndexUnary操作符都包含在这里。 在indexunary命名空间中调用操作符将执行apply操作。

  • graphblas.select

    仅包含返回布尔值的IndexUnary操作符在此命名空间中 (即除了rowindex、colindex和diagindex之外的所有操作符)。调用select命名空间中的操作符将执行select操作。

聚合器#

聚合器是高级的归约器。它们类似于幺半群,但不需要相同的输入和输出域。它们通常是高效构建的配方,需要多次调用后端的GraphBLAS实现,但通常被其他科学库视为单个计算单元。

例如,argmax 将向量的所有元素减少为一个单一值,但它不返回最大值,而是返回最大值的索引。这需要比简单的幺半群所能提供的更多的工作。

示例用法:

pos_of_largest = v.reduce(gb.agg.argmax).value

常见的聚合器有:

  • count - 非空元素的数量

  • argmax - 最大元素的位置

  • argmin - 最小元素的位置

  • mean - 平均值(即总和 / 数量)

  • stdp - 总体标准差

  • stds - 样本标准差

  • first - 第一个元素

  • last - 最后一个元素

聚合器位于 graphblas.agg 命名空间中。

使用集合调用聚合器将执行缩减到标量操作。 指定 rowwise=Truecolumnwise=True 允许执行矩阵到向量的缩减,而不是完全缩减到标量。

操作符类型特化#

当调用后端的GraphBLAS实现时,所有操作符都是类型化的,这意味着根据后端的不同,min_FP32min_INT64 是不同的操作符。为了避免用户需要担心这个细节,操作符类会根据输入参数自动确定要使用的正确类型变体。

如果需要,用户可以显式使用操作符的类型化变体来强制某种行为。请注意,如果集合类型与操作符类型不匹配,集合元素将在后端使用C语言类型转换规则进行类型转换。

示例用法:

# This is the normal way to compute the minimum of a Vector
minval = v.reduce(gb.monoid.min).value

# This will force the FP32 version of min to be used, possibly type casting the elements
minvalFP32 = v.reduce(gb.monoid.min["FP32"]).value

gb.op 命名空间#

为了方便使用运算符,存在一个单一的 graphblas.op 命名空间,它结合了所有来自

  • graphblas.unary

  • graphblas.binary

  • graphblas.monoid

  • graphblas.semiring

这有助于编写更简洁的代码,例如:

from graphblas import op

cur_min(accum=op.min) << op.min_plus(A @ B).reduce_rowwise(op.min)

在名称冲突的情况下(例如 binary.min 和 monoid.min),只有一个会存在于 graphblas.op 命名空间中。然而,几乎所有需要特定类型操作符的函数都有一种机制,可以从不同类型的同名操作符进行转换。

例如,使用 monoid.min 作为累加器将自动访问 binary.min 代替。 这意味着从 op 命名空间中使用正确的名称几乎总是“正常工作”。

中缀表示法#

标准的Python中缀表示法在python-graphblas中有效,但每个符号可能有特定的含义。每个符号的详细说明如下。

以下对象将用于演示行为。

Vector v#

0

1

2

3

4

5

1.0

2.0

3.5

9.0

Vector w#

0

1

2

3

4

5

7.0

5.2

3.0

2.5

标量操作#

所有涉及标量的中缀运算符将仅作用于集合中的非空元素。

例如,A + 1 将具有与 A 相同数量的元素,并且不会变得完全密集。换句话说,缺失值被视为 0 + 1 = 1。相反,它们被视为 missing + 1 = missing

加法#

加法在集合之间执行元素级的联合,添加重叠的元素。

v + w

0

1

2

3

4

5

8.0

5.2

2.0

6.5

11.5

减法#

减法在集合之间执行元素级的联合操作,减去重叠的元素,并从右侧对象中否定任何独立的元素。

v - w

0

1

2

3

4

5

-6.0

-5.2

2.0

0.5

6.5

乘法#

乘法在集合之间执行元素级的交集,对重叠的元素进行相乘。

v * w

0

1

2

3

4

5

7.0

10.5

22.5

除法#

真除法(/)在集合之间执行元素级的交集,将重叠的元素相除,并且结果始终为浮点型数据类型。

  • 0 / 0 = nan

  • +x / 0 = inf

  • -x / 0 = -inf

v / w

0

1

2

3

4

5

0.142857

1.166667

3.6

地板除法(//)在集合之间执行元素级的交集,对重叠元素执行整数除法。对于浮点数输入,结果仍然是浮点数,但所有元素都是整数。

使用地板除法除以零将会引发一个 ZeroDivisionError

v // w

0

1

2

3

4

5

0.0

1.0

3.0

模数#

模数在集合之间执行元素级的交集运算,计算重叠元素的余数。

v % w

0

1

2

3

4

5

1.0

0.5

1.5

功率#

Power 在集合之间执行元素级的交集运算,计算重叠元素的 x 的 y 次方。

v**w

0

1

2

3

4

5

1.0

42.875

243.0

比较#

比较操作(==, !=, >, >=, <, <=)在集合之间执行元素级的交集操作,对重叠元素执行比较。结果始终为布尔值。

注意: 要比较两个集合的完全相等性,请使用 .isequal.isclose 而不是 all(A == B)

v > w

0

1

2

3

4

5

v == w

0

1

2

3

4

5