2

In the script below, I want to apply a rotation matrix to the first two columns of a (Nx3) array.

rotate_mat = lambda theta: np.array([[np.cos(theta),-np.sin(theta)],[np.sin(theta),np.cos(theta)]])

rot_mat = rotate_mat(np.deg2rad(90))

basis1 = np.array([[i+1,j+1,k+1] for k in range(3) for j in range(3) for i in range(3)])
basis2 = basis1.copy()
rot = basis2[:,0:2] @ rot_mat

print('rot','\n',rot[:3],'\n')
print('basis2','\n',basis2[:3],'\n')

basis2[:,0:2] = rot
print('basis2 after','\n',basis2[:3])

after I ran this script, I obtained this output

rot 
 [[ 1. -1.]
 [ 1. -2.]
 [ 1. -3.]] 

basis2 
 [[1 1 1]
 [2 1 1]
 [3 1 1]] 

basis2 after 
 [[ 1  0  1]
 [ 1 -2  1]
 [ 1 -3  1]]

as you can see by basis2[:,0:2] = rot, the first row of basis2 is [1,0,1], however, the first row of rot is clearly [1,-1], where does this 0 come from?

meTchaikovsky
  • 7,478
  • 2
  • 15
  • 34

1 Answers1

5

If you take a look at the entries of rot you will see that rot[0,1] is -0.9999999999999999. Furthermore basis2.dtype == dtype('int32'). So during the assignment the new entries get converted to int32 which rounds them towards zero. You can verify that

np.int32(rot[0, 1]) == 0

and

np.int32(rot[0, 1] - 1e-16) == -1

This is due to rounding, as np.cos(np.deg2rad(90)) == 6.123233995736766e-17, when you'd probably expect it to be exactly 0.

flawr
  • 10,814
  • 3
  • 41
  • 71
  • Odd, though, that a number that is close to `-1`, gets rounded off to `0`. Isn't it? – fountainhead Oct 16 '20 at 08:21
  • @fountainhead, odd things often happen when mixing `float` and `int` datatypes. If you're rotating, you always want everything's dtype to be float. – Daniel F Oct 16 '20 at 08:30
  • @fountainhead converting from an floating point type to an integer type (typecasting) is always done by using the integer part of the input, in pretty much all common languages. If you want something else you explicitly need to specify that. – flawr Oct 16 '20 at 08:33
  • Truncation is a better description than rounding. – hpaulj Oct 16 '20 at 14:19