Graphegon / pygraphblas

GraphBLAS for Python
https://graphegon.github.io/pygraphblas/pygraphblas/index.html
Apache License 2.0
343 stars 27 forks source link

Behaviour of operator / #46

Closed marci543 closed 4 years ago

marci543 commented 4 years ago

Currently, operator / is implemented as an element-wise multiplication with the division operator. https://github.com/michelp/pygraphblas/blob/fcdd70836c11dd537ff5bde560279ffee8050e0c/pygraphblas/matrix.py#L517-L518 This causes unexpected results if one of the operands is empty.

A = Vector.from_lists([0,1], [1.0]*2, 4)
B = Vector.from_lists([1,2], [5.0]*2, 4)
C = A / B

print(A, A.type); print(A.to_string())
print(B, B.type); print(B.to_string())
print(C, C.type); print(C.to_string())
<Vector (4: 2)> <class 'pygraphblas.types.FP64'>
 0|1.0
 1|1.0
 2|  
 3|  

<Vector (4: 2)> <class 'pygraphblas.types.FP64'>
 0|  
 1|5.0
 2|5.0
 3|  

<Vector (4: 1)> <class 'pygraphblas.types.FP64'>
 0|  
 1|0.2
 2|  
 3|  

The semantics should be changed to be more natural. See relevant MATLAB code from SuiteSparse and previous discussion in #27 about operator -.

michelp commented 4 years ago

The behavior of A / B is now to use eadd() with the DIV operator. This makes it consistent with scalar A / s as well.

marci543 commented 4 years ago

Thank you.

For future reference a short demo of the new behaviour:

A = Vector.from_lists([0, 1], [1.0] * 2, 4)
B = Vector.from_lists([1, 2], [5.0] * 2, 4)

print("A"); print(A)
print("B"); print(B)
print("A / B"); print(A / B)
print("A / 5"); print(A / 5)
print("1 / B"); print(1 / B)
A
 0|1.0
 1|1.0
 2|  
 3|  

B
 0|  
 1|5.0
 2|5.0
 3|  

A / B
 0|1.0
 1|0.2
 2|5.0
 3|  

A / 5
 0|0.2
 1|0.2
 2|  
 3|  

1 / B
 0|  
 1|0.2
 2|0.2
 3|