[Numpy-discussion] vectorizing recursive sequences
Bago
mrbago at gmail.com
Sun Oct 27 00:33:55 EDT 2013
This behavior seems to depend on the order in which elements of the arrays
are processes. That seems like a dangerous thing to rely on, the main
reason I can thing of that someone would want to change the loop order is
to implement parallel ufuncs.
Bago
On Fri, Oct 25, 2013 at 12:32 PM, Jaime Fernández del Río <
jaime.frio at gmail.com> wrote:
> I recently came up with a way of vectorizing some recursive sequence
> calculations. While it works, I am afraid it is relying on implementation
> details potentially subject to change. The basic idea is illustrated by
> this function, calculating the first n items of the Fibonacci sequence:
>
> def fibonacci(n):
>
> fib = np.empty(n, dtype=np.intp)
>
> fib[:2] = 1
>
> np.add(fib[:-2], fib[1:-1], out=fib[2:])
>
> return fib
>
>
> >>> fibonacci(10)
>
> array([ 1, 1, 2, 3, 5, 8, 13, 21, 34, 55], dtype=int64)
>
>
> I believe that the biggest issue that could break this is if the ufunc
> decided to buffer the arrays, as this is relying on the inputs and outputs
> of np.add sharing the same memory.
>
>
> You can use the same idea to do more complicated things, for instance to
> calculate the items of the sequence:
>
>
> f[0] = a[0]
>
> f[n] = a[n] + x * f[n-1]
>
>
> from numpy.lib.stride_tricks import as_strided
>
> from numpy.core.umath_tests import inner1d
>
>
> def f(a, x):
>
> out = np.array(a, copy=True, dtype=np.double)
>
> n = len(a)
>
> out_view = as_strided(out, shape=(n-1, 2), strides=out.strides*2)
>
> inner1d(out_view, [x, 1], out=out[1:])
>
> return out
>
>
> >>> f(np.arange(10), 0.1)
>
> array([ 0. , 1. , 2.1 , 3.21 , 4.321 ,
>
> 5.4321 , 6.54321 , 7.654321 , 8.7654321 , 9.87654321])
>
> Again, I think buffering is the clearest danger of doing something like
> this, as the first input and output must share the same memory for this to
> work. That this is a real concern is easy to see: since `inner1d` only has
> loops registered for long ints and double floats:
>
> >>> inner1d.types
> ['ll->l', 'dd->d']
>
> the above function `f` doesn't work if the `out` array is created, e.g. as
> np.float32, since there will be buffering happening because of the type
> casting.
>
> So I have two questions:
>
> 1. Is there some other reason, aside from buffering, that could go wrong,
> or change in a future release?
> 2. As far as buffering is concerned, I thought of calling
> `np.setbuffer(1)` before any of these functions, but it complains and
> requests that the value be a multiple of 16. Is there any other way to
> ensure that the data is fetched from an updated array in every internal
> iteration?
>
> Thanks!
>
> Jaime
>
> --
> (\__/)
> ( O.o)
> ( > <) Este es Conejo. Copia a Conejo en tu firma y ayúdale en sus planes
> de dominación mundial.
>
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion at scipy.org
> http://mail.scipy.org/mailman/listinfo/numpy-discussion
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20131026/89552b6f/attachment.html>
More information about the NumPy-Discussion
mailing list