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

Reply via email to