On Fri, May 4, 2012 at 2:19 PM, Zsbán Ambrus <amb...@math.bme.hu> wrote:
> On 5/3/12, Joe Groff <arc...@gmail.com> wrote:
>> However, it appears that (m1,m2,...)&|@:^ doesn't get the same
>> treatment and falls back to power-then-residue, causing it to blow up
>> for large exponents:
>>
>> ---
>>     5 7 11 (10 14 22&|@:^) 400 4000 40000
>> |NaN error
>> |   5 7 11    (10 14 22&|@:^)400 4000 40000
>> ---
>
> Here's an alternative.
>
>   powmod =: 1 :(':';'(m|*)/(|.|:b)^~(m|*:)^:(<#{.b=.#:y) x')
>   5 7 11 (10 14 22 powmod) 40 4000 40000
> 5 7 11
>
> Note that this is fully array-based, I never explicitly iterate on the
> values.  This is, however, also a disadvantage as if one of the powers
> is much greater than the others then I'll do some unnecessary extra
> computation.
>
> This might of course be slower than calling the special code for each
> modulus separately the way Raul Miller has recommended.

Thanks! I was trying to cook something up like that myself. Here's a
tweaked version that works with heterogeneous ranks:

---
   powmod2 =: 1 :(':';'(m|*)/(|.(i.<:#$b)|:b)^~(m|*:)^:(<{:$b=.#:y) x')
   5 6 7 (10 powmod2) 3 2 $ 40 0 0 41 42 0
5 1
1 6
9 1
---

Since Marshall's and Raul's solutions relied on stitching the
arguments together into a single table, I'm not sure if they could be
as easily generalized to heterogeneous ranks. One question: Is there a
cleaner way to write (i.<:#$b)|:b , in other words, to transpose the
tail rank to the head without affecting the head ranks?

-Joe
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to