4

As mentioned here and here, this doesn't work anymore in numpy 1.7+ :

import numpy
A = numpy.array([1, 2, 3, 4], dtype=numpy.int16)
B = numpy.array([0.5, 2.1, 3, 4], dtype=numpy.float64)
A *= B

A workaround is to do:

def mult(a,b):
    numpy.multiply(a, b, out=a, casting="unsafe")

def add(a,b):
    numpy.add(a, b, out=a, casting="unsafe")

mult(A,B)

but that's way too long to write for each matrix operation!

How can override the numpy *= operator to do this by default?

Should I subclass something?

4
  • A *= B saves you only 3 characters over mult(A,B). Can you articulate why you need to have the shortest method possible? Commented Jul 30, 2016 at 18:55
  • @SethMMorton : better explicit than implicit : *= is standard among all major programming languages ; having to define a mult function is not natural Commented Jul 30, 2016 at 19:11
  • What do you want A to end up as here? Commented Jul 30, 2016 at 19:28
  • @Eric As A is an int array, and that we do inplace *=, I want A to stay an int at the end. Commented Jul 30, 2016 at 20:21

2 Answers 2

6

You can use np.set_numeric_ops to override array arithmetic methods:

import numpy as np

def unsafe_multiply(a, b, out=None):
    return np.multiply(a, b, out=out, casting="unsafe")

np.set_numeric_ops(multiply=unsafe_multiply)

A = np.array([1, 2, 3, 4], dtype=np.int16)
B = np.array([0.5, 2.1, 3, 4], dtype=np.float64)
A *= B

print(repr(A))
# array([ 0,  4,  9, 16], dtype=int16)
Sign up to request clarification or add additional context in comments.

Comments

1

You can create a general function and pass the intended attribute to it:

def calX(a,b, attr):
    try:
        return getattr(numpy, attr)(a, b, out=a, casting="unsafe")
    except AttributeError:
        raise Exception("Please enter a valid attribute")

Demo:

>>> import numpy
>>> A = numpy.array([1, 2, 3, 4], dtype=numpy.int16)
>>> B = numpy.array([0.5, 2.1, 3, 4], dtype=numpy.float64)
>>> calX(A, B, 'multiply')
array([ 0,  4,  9, 16], dtype=int16)
>>> calX(A, B, 'subtract')
array([ 0,  1,  6, 12], dtype=int16)

Note that if you want to override the result you can just assign the function's return to the first matrix.

A = calX(A, B, 'multiply')

3 Comments

Nice but this is not shorter than mult(A,B) with def mult(a,b): numpy.multiply(a, b, out=a, casting="unsafe")... What I want is override A*=B
@Basj This is a general way, which makes you don't define a function for all operations. Also you don't need to override anything.
@Basj If you consist to use in-place operators you better to create a custom matrix object and define it's operators manually which still you'd need to do this for all the operators.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.