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

Reply via email to