Josh
Josh

Reputation: 1278

- vs -= operators with numpy

I'm having some strange behavior in my python code related to - and -=. I'm writing a QR decomposition using numpy, and have the following line of code in a double loop:

v = v - r[i,j] * q[:,i]

where q and r are both numpy.array, and v is a slice of another numpy.array taken as v = x[:,j].

The above code doesn't work as expected in all cases. However, if I make the following change:

v -= r[i,j] * q[:,i]

Then everything works flawlessly.

I was under the impression that those two lines should be identical. To test whether -= and _ = _ - were working differently, I created the following snippet

import numpy

x = numpy.array(range(0,6))
y = numpy.array(range(0,6))

u = x[3:5]
v = y[3:5]

print u,v

u = u - [1,1]
v -= [1,1]

print u,v

which again works as expected, producing [2 3] [2 3] at both print statements.

So I'm entirely confused why those two lines perform differently. The only possible thing I can think of is that I am dealing with extremely small numbers sometimes (on the order of 10^-8 or smaller) and there is some precision issue that -= is better at? The first line performs increasingly worse as the elements of x get smaller.

I apologize if there's any other posts about this similar issue, I can't search for - and -= and I don't know if there's any correct terms for these besides assignment/operators.

Thanks for any help!

Upvotes: 19

Views: 5975

Answers (3)

Bi Rico
Bi Rico

Reputation: 25813

+1 to both other answers to this questions. They cover two important differences between = and -= but I wanted to highlight one more. Most of the time x -= y is the same as x[:] = x - y, but not when x and y are slices of the same array. For example:

x = np.ones(10)
y = np.ones(10)

x[1:] += x[:-1]
print x
[  1.   2.   3.   4.   5.   6.   7.   8.   9.  10.]

y[1:] = y[1:] + y[:-1]
print y
[ 1.  2.  2.  2.  2.  2.  2.  2.  2.  2.]

Upvotes: 5

Fred Foo
Fred Foo

Reputation: 363547

When v is a slice, then v -= X and v = v - X produce very different results. Consider

>>> x = np.arange(6)
>>> v = x[1:4]
>>> v -= 1
>>> v
array([0, 1, 2])
>>> x
array([0, 0, 1, 2, 4, 5])

where v -= 1 updates the slice, and therefore the array that it views, in-place, vs.

>>> x = np.arange(6)
>>> v = x[1:4]
>>> v = v - 1
>>> v
array([0, 1, 2])
>>> x
array([0, 1, 2, 3, 4, 5])

where v = v - 1 resets the variable v while leaving x untouched. To obtain the former result without -=, you'd have to do

v[:] = v - 1

Upvotes: 29

NPE
NPE

Reputation: 500317

You could get different results from x - y and x -= y if the data types of x and y differ.

For example:

import numpy as np

x = np.array(range(0,6))
y = np.array(np.arange(0,3,0.5))

print x - y
x -= y
print x

This prints out:

[ 0.   0.5  1.   1.5  2.   2.5]
[0 0 1 1 2 2]

It may be worth making sure your arrays' dtypes are exactly as you expect (e.g. you're not inadvertently using integer or float32 arrays instead of float64), paying particular attention to arrays used on the left-hand side of -=.

Upvotes: 14

Related Questions