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