Sherlock, Ric wrote:
> 
> I think versions 4 and 5 are a good example of why Henry suggests to use
> @: rather than @ by default in J4C Programmers.  They (especially
> normalrand5) are so slow because the use of @ causes J to "loop through"
> many of the arrays item by item rather than processing them as a whole.
> See normalrand4a for comparison:
> 
> normalrand4a=: ({.,)(2 1&o."1 0@: +:@:o.@:rand01  *
> [:%:-@:+:@:^.@:rand01)@>[EMAIL PROTECTED]:
> 
> By making sure that you iterate over the short left array rather than the
> long right array also makes a big difference see normalrand6a:
> 
> normalrand6a=: ({.,)((2 1 o."0 1 +:@:o.@:rand01) *"1 [: %:
> -@:+:@:^.@:rand01)@>[EMAIL PROTECTED]:
> 
> Tacit normalrand6a is now leaner and faster than all the other candidates
> 
These two moves, going from 2 1 o."1 0 and * to 2 1 o."0 1  and *"1
and going from @ to @: did speed up a great deal the tacit code and
made it comparable in speed with non-tacit versions.

I'm not that excited about going from @ to @: by default (except of course 
in this case :-), since these are two different operations each with its own
properties.  As far as the speed is concerned, [EMAIL PROTECTED]@h suggests 
using a 
pipeline kind of processing, thus being (only) in principle faster than 
f@:g@:h which processes the same array over and over (at least that's how I 
would implement it, although a pipeline evaluation is also possible).  
In practice, the latter is faster probably because of efficient
vectorizations 
of each individual f, g and h, while, in contradistinction, evaluation of
[EMAIL PROTECTED]@h 
for each element of the argument probably requires some overhead work of 
the interpreter.

Furthermore, it seems to me that plenty of verb applications are 
implemented implicitly as @:, so that should also help keep things fast 
without bothering with converting things explicitly into @: versions.

. . . . . . . . . . . . . .

I'd like to add an another routine, normalrandom, that generates normal 
deviates with a specified standard deviation as the x argument and 
the number of i.i.d realizations as the y argument.  For readability and
speed I split it into two parts:

BM=:(2 1 o."0 1 [EMAIL PROTECTED]:@[ * [EMAIL PROTECTED])*"1(* 
[:%:_2*^.@:[EMAIL PROTECTED])
normalrandom=:] $ ,@(BM >[EMAIL PROTECTED]:@(*/))

It compares well with other fast tacit routines, normalrand6a as well as

normalrand6b=: ] $ ,@((2 1 o."0 1 +:@:o.@:rand01) *"1 [: %:
_2&*@:^.@:rand01)@>[EMAIL PROTECTED]:@(*/)

normalrand6c=: ] $ ,@((2 1 o."0 1 (o.2)*rand01) *"1 [: %:
_2&*@:^.@:rand01)@>[EMAIL PROTECTED]:@(*/)

according to:

   ts'normalrand6a 10000000'
2.563797633 335545472
   ts'normalrand6b 10000000'
2.683788303 335545536
   ts'normalrand6c 10000000'
2.567413456 335545536
   ts'1 normalrandom 10000000'
2.672494968 335545408


-- 
View this message in context: 
http://www.nabble.com/generating-standard-normal-variates-tp18898408s24193p19022898.html
Sent from the J Programming mailing list archive at Nabble.com.

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

Reply via email to