Here's a fft method, it doesn't work with 1e9 bases, but with 10000 base (same 
as internal J) it does with a lot of fiddling:

there is a function in misc/numeric.ijs called clean, which I think is supposed 
to help with converting from imaginary, but I don't really get it.


require '~addons/math/fftw'
xtoa5 =: (10 }. _4 ,@:((_2&ic)\) 1 (3!:1) ])"0 


1000000x p.~ x: 0.1 <.@+  ifftw  ([: */@:(fftw"_1) [ }:@,], 0 ,:@#~ <:@+&#)~ 
xtoa5 1231231232342348209348203492039482341233x

It would take a really huge number of digits before n logn on 4tuples is less 
than a fast C with n^2 on 9tuples.

at 340 digits, my approach stays 5 times faster than just *, and there is no 
need to evaluate the polynomial to return the integer result.


----- Original Message -----
From: Henry Rich <henryhr...@nc.rr.com>
To: programm...@jsoftware.com
Cc: 
Sent: Tuesday, August 25, 2015 7:21 PM
Subject: Re: [Jprogramming] Some extended integer types with math operations

There is definitely faster multiplication code, based on FFT.  Roger 
worked on it for a while & as I understand it worked, but was never 
released.

Henry Rich

On 8/25/2015 6:05 PM, 'Pascal Jasmin' via Programming wrote:
> xtoa =: ([ (-@[ |.@:(0&".@:|.\)&.> <@|.@]) ":@:])"0  NB. dyad
> xtoa9 =: >^:(1=#)@:(9&xtoa)
> atox =: (0 ". 'x' ,~ [: ; ": each)"1
>
> NB.list of extended ints to binary.  Uses bit31 to indicate last number.  
> Also stores var 32/64bit ints
> xatobN =: (([: ; (2 ic }:@] , (1000000000) + {:@])each))  NB. call with 
> @xtoa9 to go direct from xint. positive extended ints only.
> xatobZ =: (([: ; (2 ic }:@] , (1000000000 * *@{:@]) + {:@])each))  NB. 
> modified to allow negatives.
> btoxaN =: ([: (}: , (1000000000) -~ {:)each 1000000000 (] <;.2~  <) [: , _4 
> (_2&ic)\ ])
> btoxaZ =: ([: (}: , (1000000000 * *@{:) -~ {:)each 1000000000 (] <;.2~  (<|)) 
> [: , _4 (_2&ic)\ ])
>
>
>
> All of the above are one liners.  The main motivation was to create a quick 
> and compact storage method for lists of extended ints.  It works for lists of 
> ints of any size including 32 to 64 bit range, and so is compatible for 
> storing lists to be read by either 32 or 64 bit versions of J.
>
> aar =. 
> 9876878623423422342342342342034820934203948203948229837429384729348723948723948273492837429384729384727394870394820349820349820348x
>
>    xtoa9 aar
> 9876 878623423 422342342 342342034 820934203 948203948 229837429 384729348 
> 723948723 948273492 837429384 729384727 394870394 820349820 349820348
>
> simply makes a list of ints in base 1e9. xtoa9r reverses them, which keeps 
> them in useful form for several operations, and as lists of ints with fills.
>
> The xatobN and btoxaN functions make a binary string from the list of ints 
> (The Z versions support negative ints).  Its quicker and/or much smaller than 
> other methods.
>
> a =. 2147483304598340953804093234 234234 434332323 248203948203498203492 
> 83049283402394820  
> 12301928310298310293810293810293810293810293881301982301928310239839482039482834825
>  112312 1 0 29348239429384729347293874293870923409283498647x
>
>    # xatobN@:xtoa9 a
> 120
>
> this stores the list without any item counts.  An unused bit in the last 
> number of a field indicates whether it is the last item in "its" list.
>
> for comparison,
>
>    # 3!:1 a
> 1000
>
> While it would be slightly smaller to store bytes, along with a leading count 
> (if under 256 byte long integers), it would be much slower with the count 
> offset, and that alternative is already slow without tracking counts.  
> Roundtrip comparison:
>
>    10 timespacex '256x #. every a.&i. each  (3!:2) 3!:1 {&a. each 256#.inv 
> each a'
> 0.000643872 211840
>
>
>    10 timespacex 'atox every btoxaN xatobN@:xtoa9 a'
> 0.000176384 13056
>
>
> 4 times faster and low memory.  And leaving it boxed is 5 times the size.
>
>    # 3!:1 {&a. each 256#.inv each a
> 672
>
>
> Leaving numbers in array form can also have some speed advantages in certain 
> operations.  Some math routines:
>
> coclass 'xint'
> square =: +//.@:(*/~)
> mult =: +//.@:(*/)
> join =: ,:&.|.  NB. take multiple xints in reverse order so fills line up.  
> used for addition/sub. xtoa9r better constructor
> multreduce =: [: +//. 1000000000&(<.@%~ ,. |)  NB. use twice ^:2 for final 
> answer.  Once usually ok to prevent overflow
> m =: multreduce^:2@:mult
>
>
> a2 =. xtoa9r a NB. results: matrix of integers in array form. wrong endian.
>
>    10 timespacex '+/ a2'
> 1.344e_6 2304 NB. close to factor of 6
>    10 timespacex '+/ a'
> 7.328e_6 3328
>
>
>    10 timespacex '|. m_xint_&.|./ 7{. a2'
> 7.2448e_5 16640
>    10 timespacex '*/ 7{.   a' NB. mult is a bit slower... but this is in J 
> not C.
> 3.3344e_5 4352
>
>
> though faster boxed without fills
>
>
>    a3 =. xtoa9 each a
>    10 timespacex 'm_xint_ each/ 7{. a3'
> 4.2528e_5 7680
>
>
>
>    aa =. xtoa9 aar
>
>
> 10 timespacex 'm_xint_^:4~ aa'
> 4.4608e_5 13184  NB. exponentiation 5x faster
>    10 timespacex 'aar ^ 5'
> 0.000263232 12928
>
>
> Other ways to do small multiplication and division and convert to x:
>
> (2*aar) = 1000000000x p.~ 2 * |. aa
> (2%~aar) = 1000000000x p.~ 1r2 * |. aa
>
>
> It would be much appreciated if you can make or point me to fast modular 
> exponentiation code... And other math functions.  There is probably better 
> multiplication algorithm too.
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm

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

Reply via email to