Mayan
Mayan

Reputation: 492

numpy's fromfunction accessing arrays in the input function

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

Upvotes: 0

Views: 374

Answers (1)

Jinu
Jinu

Reputation: 586

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))

Upvotes: 1

Related Questions