Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOC: numpy.fromfunction docs should be clearer about how the wrapped function is called #26454

Open
disa-star opened this issue May 16, 2024 · 4 comments

Comments

@disa-star
Copy link

Describe the issue:

When define a simple function like foo = lambda i,j : 3
numpy.fromfunction will only return a value instead of an array.
And this is going to be my very first time to write an issue report, but I will try my best.

Reproduce the code example:

import numpy as np
def foo(i,j):
  return 3+i*0

array = np.fromfunction(lambda i, j: foo(i,j), (2, 2), dtype=float)
print(array) 
bar = lambda i,j : 3
print(np.fromfunction(bar, (2, 2), dtype=float))

Error message:

[[3. 3.]
 [3. 3.]]
3

Python and NumPy Versions:

Name: numpy
Version: 1.25.2

Python 3.10.12 (google colab)

Runtime Environment:

[{'numpy_version': '1.25.2',
'python': '3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0]',
'uname': uname_result(system='Linux', node='696c451497cf', release='6.1.58+', version='#1 SMP PREEMPT_DYNAMIC Sat Nov 18 15:31:17 UTC 2023', machine='x86_64')},
{'simd_extensions': {'baseline': ['SSE', 'SSE2', 'SSE3'],
'found': ['SSSE3',
'SSE41',
'POPCNT',
'SSE42',
'AVX',
'F16C',
'FMA3',
'AVX2'],
'not_found': ['AVX512F',
'AVX512CD',
'AVX512_KNL',
'AVX512_KNM',
'AVX512_SKX',
'AVX512_CLX',
'AVX512_CNL',
'AVX512_ICL']}},
{'architecture': 'Haswell',
'filepath': '/usr/local/lib/python3.10/dist-packages/numpy.libs/libopenblas64_p-r0-5007b62f.3.23.dev.so',
'internal_api': 'openblas',
'num_threads': 2,
'prefix': 'libopenblas',
'threading_layer': 'pthreads',
'user_api': 'blas',
'version': '0.3.23.dev'}]
None

Context for the issue:

This is counterintuitive, and I think it violates the integrity.

@seberg
Copy link
Member

seberg commented May 16, 2024

I agree with you, at the very least the documentation is wrong since it gives the impression that the function will be called with scalar values.
But it is not, fromfunction is just the same as: your_function(*np.indices((2, 2)).

In other words, NumPy passes arrays into your function and doesn't call the function for each element. np.frompyfunc can achieve that a bit.

I would prefer to not consider it a bug, since the code that does use it would just slow down if we changed it. Although, I have to say I am not sure I think it is a useful helper at all compared to writing:

i, j = np.indices((2, 2))  # or np.ogrid, meshgrid, ...
arr = func(res)

(TBH, I wonder if we should deprecate it, but I also suspect there will be a fair amount of users.)

@seberg seberg changed the title BUG: numpy.fromfunction has an unintended behavior when the function returns a non-numpy type value DOC: numpy.fromfunction calls function with arrays not scalars May 16, 2024
@disa-star
Copy link
Author

Thanks a lot, that helps explain why I can not use np.fromfunction to get a random array obeying certain distribution.

@seberg
Copy link
Member

seberg commented May 16, 2024

Note that most random number generation functions in NumPy (and probably also scipy) support size= to pass the shape you want or even passing in arrays for parameters.
So you can hopefully generate what you want more directly and conveniently.

@ngoldbaum
Copy link
Member

There is a note about this behavior in the fromfunction docs under "Returns" but I agree the docs could be clearer about what it actually does (and that it is kind of useless). I do see many usages on github search.

@ngoldbaum ngoldbaum changed the title DOC: numpy.fromfunction calls function with arrays not scalars DOC: numpy.fromfunction docs should be clearer about how the wrapped function is called May 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants