Dan Bron <[EMAIL PROTECTED]> wrote:
> There is probably a mechanical way to rewrite sequences such that all
> instances
> of @ and @: are removed, but the results would be long, hard to read,
> kludgy,
> and inefficient (e.g. using a lot of boxing & unboxing).
While parentheses are required, boxing and unboxing aren't.
You can avoid @ and @:
You can write (u@:v) as ([:u v)
You can write ([EMAIL PROTECTED]) as (u@:v"v), hence (([:u v)"v)
or (([:u v)"n) since you can usually compute the rank manually
(which is useful in cases where v is not a simple primitive).
You can write (m&u@:v) as (m u v)
(and similarly (m&[EMAIL PROTECTED]) as ((m u v)"v) or ((m u v)"n)
You can write (u&m@:v) as (m u~ v) etc.
You can write (u&[EMAIL PROTECTED]) as ((m u~ v)"v) or ((m u~ v)"n)
You can avoid & &: &. &.: but it's messier:
You can rewrite (u&:v) as (([:u v) : (([:v[)u[:v]))
You can rewrite (u&v) as ((([:u v) : (([:v[)u[:v]))"({.v b.0)) (or "n)
You can rewrite (u&.:v) as ([:v^:_1([:u v) : (([:v[)u[:v]))
You can rewrite (u&.v) as (([:v^:_1(([:u v) : (([:v[)u[:v]))"({.v b.0)) (or "n)
You can avoid hooks:
You can rewrite (u v) as ([u v@:]) or ([u[:v])
You can avoid even/odd:
You can rewrite (u ..v) as ([:-:u+u&v) or ([:-:[EMAIL PROTECTED]) or ([:-:(+&:u
v)) or ([:-:u+[:u v)
You can rewrite (u .:v) as ([:-:u-u&v) or ([:-:[EMAIL PROTECTED]) or ([:-:(-&:u
v)) or ([:-:u-[:u v)
(NOTE: These last two options on even/odd only work if [EMAIL PROTECTED] -:
u@:v)
> Try rewriting the following as tacit verbs without using @ or @: :
>
> Y =: 2+i. 10
> [EMAIL PROTECTED]: Y
> 1 1 2 1 2 1 3 2 2 1
([:#q:)"0 Y NB. 10% slower, 25% larger (2.5%/0% with Y=:2+i.1000000)
> Y =: #: 10 ?. 100
> 10&[EMAIL PROTECTED] Y
> 1345 156 2456 12345 135 134 34 46 4 123456
(10#.I.)"1 Y NB. same speed, 15% larger (0%/0% with Y=#:?.~1000000)
> Y =: i. 4 2
> <@i. Y
> +-+-----+--------------+--------------------+
> | |0 1 2| 0 1 2 3 4| 0 1 2 3 4 5 6|
> | |3 4 5| 5 6 7 8 9| 7 8 9 10 11 12 13|
> | | |10 11 12 13 14|14 15 16 17 18 19 20|
> | | |15 16 17 18 19|21 22 23 24 25 26 27|
> | | | |28 29 30 31 32 33 34|
> | | | |35 36 37 38 39 40 41|
> +-+-----+--------------+--------------------+
([:<i.)"1 Y NB 50% larger and slower (0%/0% with Y=:i.500 2)
> Y =: _4 }:\ 0&".;._2 noun :0
> 0.971444 1.02703 1.08578
> 0.971778 1.0574 1.15056
> 0.971756 1.05538 1.14619
>
> 0.993723 1.17813 1.39672
> 0.992743 1.2449 1.56111
> 0.992862 1.23705 1.5413
>
> 0.998822 1.2964 1.68263
> 0.998688 1.36822 1.87448
> 0.998552 1.43703 2.06803
>
> )
>
> (-/ .*)@%. Y
> _561830 _31029.4 1429.68
([:-/ .*%.)"2 Y NB. 1% slower, 2% larger (2%/0% with 100 100 100-:$Y)
Measurements on small arrays tend to be overwhelmed by processing overhead,
and differences of a few percent are statistically insignificant. When
arrays of a million items are used, the performance of @ and trains are
very similar.
Note that in the last case, "2 is not required, since %. is rank 2 and
produces a rank-2 result, but -/ .* is also rank 2, so the result is the
same regardless of whether it is applied to all the inverse matrices
simultaneously, or one at a time, since the determinant treats them
one at a time anyway.)
([:-/ .*%.) Y NB. 1% slower, 5% larger (2%/1000% with 100 100 100-:$Y)
Curiously, this is ten times worse in terms of memory usage, since the
intermediate inverted matrices must all be stored (and similar results
occur with (-/ .*@:%.)). However, computing time is the same in all cases.
> When you're done, compare your verbs to the original in length, elegance, and
> efficiency.
As far as efficiency, they seem to be about the same in the long run.
In terms of length, the examples you've given require an additional 5 characters
each (your matrix example didn't need parentheses). In very long trains,
(a@:b@:c@:d@:e) and ([:a[:b[:c[:[:d e) are approximately equivalent.
You gain a bit if you use a lot of @ (but I've generally found that most long
trains I have used have been of the @: variety in most cases except sometimes
in the rightmost position). There are also some cases in which using
conjunctions like @ requires that the rightmost expression be parenthesized,
while this is not needed in the case of a train. For example, (u@:(v&.w))
as opposed to ([:u v&.w). As far as elegance goes, both forms have their
places. Sometimes @ is better, sometimes trains are better, sometimes
a combination is better. The only time you lose is if you slavishly
use one form even when the other makes more sense.
-- Mark D. Niemiec <[EMAIL PROTECTED]>
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm