For what it's worth, working with transposed arrays results in a trivial (~12%) speedup for a cross product using the 1&|. 2&|. approach.
Mechanically converting to tacit form gains nothing measurable (the arrays are large enough that parsing overhead is trivial). Trying to get clever with the rotates slows things down by a factor of 2. cross1: 0.039993 1.00665e8 cross2: 0.068693 2.01329e8 cross1t: 0.039664 1.00665e8 CROSS1: 0.03203 1.00665e8 CROSS1t: 0.034982 1.00665e8 Where: rand=: ?@# 0: ts=: timespacex pm1=: 1&|."1 NB. 1st cyclic permutation pm2=: 2&|."1 NB. 2nd cyclic permutation pm12=: 4 : '(pm1 x)*pm2 y' cross1=: pm12 - pm12~ NB. cross products of vectors cross2=:4 :0 -/(1 2 |."0 1/ x)*2 1|."0 1/ y ) pm12t=: 13 : '(pm1 x)*pm2 y' cross1t=: (pm12t - pm12t~)f. PM1=: 1&|. NB. 1st cyclic permutation PM2=: 2&|. NB. 2nd cyclic permutation PM12=: 4 : '(PM1 x)*PM2 y' CROSS1=: PM12 - PM12~ PM12t=: 13 : '(PM1 x)*PM2 y' CROSS1t=: (PM12t - PM12t~) f. a=: 1e6 3$rand 3e6 b=: 1e6 3$rand 3e6 A=: |:a B=: |:b echo 'cross1:' echo ts'z=: a cross1 b' echo 'cross2:' echo ts'zz=: a cross2 b' assert z-:zz echo 'cross1t:' echo ts'zt=: a cross1t b' assert z-:zt echo 'CROSS1:' echo ts'Z=: A CROSS1 B' assert z-:|:Z echo 'CROSS1t:' echo ts'Zt=: A CROSS1t B' assert Z-:Zt FYI, -- Raul On Sat, Feb 8, 2020 at 1:17 PM J. Patrick Harrington <[email protected]> wrote: > > Apologies & the last word. My original cross product was this: > > pm1=: 1&|."1 NB. 1st cyclic permutation > pm2=: 2&|."1 NB. 2nd cyclic permutation > pm12=: 4 : '(pm1 x)*pm2 y' > cross=: pm12 - pm12~ NB. cross products of vectors > > (The version I gave before > crossX=: ((1: |.[)*(_1: |. ]))-((_1: |.[)*(1:|.])) > I messed up in making a tacit form.) > > With the proper form given above > u=. 1e6 3$rand 3e6 > v=. 1e6 3$rand 3e6 > ts'z=. u cross v' > 0.032281 1.00665e8 > The timing on cp=: (1 _1 1 * 1 (-/ . *)\. ])@,. > ts'z=. u cp"(1 1) v' > 2.12978 3.3558e7 > which is 66 times slower. Both give same results. > > Patrick > > On Sat, 8 Feb 2020, J. Patrick Harrington wrote: > > > And a little more noise: > > u=. 1e6 3$rand 3e6 > > v=. 1e6 3$rand 3e6 > > ts'z1=. u cross"(1 1) v' > > 0.88737 3.35571e7 > > ts'z2=. u cp"(1 1) v' > > 2.12978 3.3558e7 > > ind=. 3e5+ i. 4 > > ind{z1 > > _0.0415101 0.458711 _0.371054 > > _0.0240905 _0.0474326 0.0622632 > > 0.108878 _0.558303 0.207895 > > _0.294769 0.605469 _0.617259 > > ind{z2 > > _0.0415101 0.458711 _0.371054 > > _0.0240905 _0.0474326 0.0622632 > > 0.108878 _0.558303 0.207895 > > _0.294769 0.605469 _0.617259 > > > > So u cross"(1 1) v is faster. > > But u cross v is broken. > > Will look into that :-( > > > > On Sat, 8 Feb 2020, J. Patrick Harrington wrote: > > > >> Oh-oh. I've screwed something up. > >> We can get correct results for arrays thus > >> u cp"(1 1) v > >> which agrees with > >> u cross"(1 1) v > >> but seems *not* to agree with my > >> u cross v > >> I'll need to look into this! And into timings. > >> > >> Sorry for the noise... > >> Patrick > >> > >> On Sat, 8 Feb 2020, J. Patrick Harrington wrote: > >> > >>> The formula referenced there > >>> cp=:(1 _1 1 * 1 (-/ . *)\. ])@,. > >>> compared to mine > >>> cross=: ((1: |.[)*(_1: |. ]))-((_1: |.[)*(1:|.])) > >>> agree for single vectors of course > >>> ] u=. rand 3 > >>> 0.622471 0.324707 0.907825 > >>> ] v=. rand 3 > >>> 0.0631566 0.38662 0.338598 > >>> u cp v > >>> _0.241038 _0.153432 0.220153 > >>> u cross v > >>> _0.241038 _0.153432 0.220153 > >>> but for arays of vectors > >>> ] u=. 4 3$rand 12 > >>> 0.095767 0.601479 0.285658 > >>> 0.926716 0.299674 0.417604 > >>> 0.687686 0.837773 0.792088 > >>> 0.465073 0.605581 0.190086 > >>> ] v=. 4 3$rand 12 > >>> 0.732158 0.199016 0.654682 > >>> 0.925557 0.409382 0.619391 > >>> 0.891663 0.888594 0.716629 > >>> 0.9962 0.477721 0.946355 > >>> u cross v > >>> 0.492744 _0.104753 0.277464 > >>> 0.418103 _0.36774 0.313855 > >>> _0.492744 0.104753 _0.277464 > >>> _0.418103 0.36774 _0.313855 > >>> u cp v > >>> | length error: cp > >>> | u cp v > >>> > >>> How do you generalize this for such arrays (or |:u arrays)? > >>> I often take cross products of millions of vectors as part > >>> of Monte Carlo scattering computations, so it must be fast. > >>> > >>> Patrick > >>> > >>> On Sat, 8 Feb 2020, R.E. Boss wrote: > >>> > >>>> https://code.jsoftware.com/wiki/Phrases/Matrices#Vector_cross_product > >>>> > >>>> > >>>> R.E. Boss > >>>> > >>>> > >> ---------------------------------------------------------------------- > >> 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 ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm
