Imagine I have a class A
that is outside of my control (numpy.ndarray
is the specific application), and class B
within my control (scipy.sparse.coo_matrix
). I want to implement in-place addition of B
to A
without touching class A
.
Is this at all possible? Is it a bad idea? If this isn't possible in general, is it possible with numpy arrays specifically?
For a specific example consider:
class A:
foo = 0
def __iadd__(self, other):
print("Avoid calling this function.")
return self
class B:
def __add__(self, other):
if isinstance(other, A):
other.foo += 1
return other
__radd__ = __add__
# Modify this class to make assertion below pass
a1, a2 = A(), A()
a1 += B()
a2 = a2 + B()
assert a1.foo == a2.foo == 1, "How to make this work"
EDIT: Actual application.
In-place addition of a sparse coordinate matrix to a dense numpy array has an efficient implementation:
from time import time
import numpy as np
from scipy import sparse
N = 1000
a = np.zeros((N, N))
b = sparse.identity(N, format="coo")
t_slow = -time()
a += b # Want to override, converts b to array—slow!
t_slow += time()
t_fast = -time()
a[b.row, b.col] += b.data # Desired implementation
t_fast += time()
print(f"{t_slow=:.2}s, {t_fast=:.2}s")
# t_slow=0.0017s, t_fast=0.00024s