0

I am trying to create a numpy matrix with each matrix element as output element of a function, using numpy's fromfunction. Below is my code and it fails with an error message IndexError: arrays used as indices must be of integer (or boolean) type. I read some resources on Stackoverflow which said that the documentation is misleading (Parameters to numpy's fromfunction) and it sometimes doesn't work as expected. After reading these threads, I suspect that the problem is that I access two arrays, q_x and rs in the input function. Any idea on how to get rid of the error?

import numpy as np
q_x = np.array([1,2,3,4,5,6,7,8])
rs = np.array([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8])

def ift_weight(i,j):
    qr = q_x[i]*rs[j]
    return qr*np.sin(qr)

print(np.fromfunction(ift_weight, (5,5)))

Remarks: There are of course some workarounds such as creating an empty matrix and then iterate each element. I am curious whether numpy's fromfunction can achieve such task more elegantly.

Edit: np.vectorize perfectly solved the problem. I might have made some typo so that my previous trial with np.vectorize fails. This question is a duplicate of Parameters to numpy's fromfunction

Mayan
  • 492
  • 4
  • 11
  • Read the `[source]`. This is a simple function, nearly useless. It creates `indices` and passes them (whole) to your function. It's docs are misleading because people **want** it to do something else. It is **not** a 'vectorizing' magic. – hpaulj Jun 10 '21 at 07:59

1 Answers1

1

The link that you attached already addressed the problem perfectly. Could you elaborate on the case that it doesn't work?

So the problem here is that np.fromfunction is handing over the whole meshgrid instead of a single index.

(Pdb) p i
array([[0., 0., 0., 0., 0.],
       [1., 1., 1., 1., 1.],
       [2., 2., 2., 2., 2.],
       [3., 3., 3., 3., 3.],
       [4., 4., 4., 4., 4.]])
(Pdb) p j
array([[0., 1., 2., 3., 4.],
       [0., 1., 2., 3., 4.],
       [0., 1., 2., 3., 4.],
       [0., 1., 2., 3., 4.],
       [0., 1., 2., 3., 4.]])

Applying the np.vectorize and specifying dtype=int for indexing solves the problem.

import numpy as np
q_x = np.array([1, 2, 3, 4, 5, 6, 7, 8])
rs = np.array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8])


def ift_weight(i, j):
    qr = q_x[i]*rs[j]
    return qr*np.sin(qr)


f = np.vectorize(ift_weight)

print(np.fromfunction(f, (5, 5), dtype=int))
Jinu
  • 536
  • 1
  • 4
  • 12
  • You are right. Thanks. I thought I had done something the exact same as yours here, but I also got an error message. I have deleted my previous code and I can't reproduce the error again. Anyway, thanks! – Mayan Jun 10 '21 at 07:45