                                   Chapter 6

                                 USING J : RANK


      Verb ranks in J
      frames & cells, what are these "things"
      Rank 0 catenation.


*========================================
# Verb ranks in J

+------------------
| Paul Moore
| <1991Nov12.210417.24850@demon.co.uk>

I may be missing something here, but...

The Dictionary of J defines (for example) the monadic rank of + as _ (ie,
unbounded), and its dyadic ranks as (0 0). I've been thinking about the
difference, and I can't see any case where + having a monadic rank of 0
would make a difference (ie, as far as I can tell, +"0 is equivalent to +).
Also, a monadic rank of 0 seems more intuitive to me, as I think of + as
acting on atoms, rather than acting on arrays (by conjugating all their
atoms).

Can anybody explain this? (If this is the sort of thing that is covered
in "Programming in J", I'd be interested - I've ordered my copy but it's
not arrived yet...)

Thanks, Gustav


+------------------
| Roger Hui
| <1991Nov17.141138.15934@yrloc.ipsa.reuter.COM>

Paul Moore/Gustav writes:

 The Dictionary of J defines (for example) the monadic rank of + as _ (ie,
 unbounded), and its dyadic ranks as (0 0). I've been thinking about the
 difference, and I can't see any case where + having a monadic rank of 0
 would make a difference (ie, as far as I can tell, +"0 is equivalent to +).
 Also, a monadic rank of 0 seems more intuitive to me, as I think of + as
 acting on atoms, rather than acting on arrays (by conjugating all their
 atoms).

The consequences of specifying 0 or _ monadic rank for verbs such as +
manifest themselves in phrases involving adverbs and conjunctions,
wherein infinite rank leads to more useful results.  For example:

   %.@-           Inverse of the negative of a matrix
   +/@*:          Sum of squares

The conjunction @ is defined to "inherit" the ranks of the right argument.
In the examples, if - had monadic rank 0, then the verb %.@- would have
monadic rank 0, and would be computing (in effect) the reciprocal of the
negative of each atom; if *: had monadic rank 0, +/@*: would too, and
would be computing just squares.

The dyadic ranks of + are 0 0 because such ranks result directly in
the "scalar extension" behaviour of APL\360 (3+i.3 4 applies 3 against
each atom of i.3 4), and inner and outer product work as expected.

The rank conjunction (") specifies ranks for a verb.  @: and &: are
non-heritable counterparts to the heritable @ and & .  For example:

   +/                 sum the whole thing (infinite rank)
   +/"1               sum lists
   +/"2               sum tables

   +"0 _              defn of outer product +

   +/@((<0 1)&|:)@%.  trace of inverse matrix
   #@>                number of items in each box
   +/@:(#@>)          total number of items in boxes



*========================================
# frames & cells, what are these "things"

+------------------
| Mark Keil
| <1991Dec3.222657.19182@apollo.hp.com>

I'm having a little trouble picturing  frames & cells.

cells have something to do with axes, but exactly what?

Are frames all of the cells except the current one?

What are the properties of frames & cells. How do they
behave?are there any tricks to using them?

These frame & cell objects seem key higher rank oerations,
but I don't have a feel for them, and there isn't enough
background about them in the dictionary to understand what
is going on.

Thanks for any enlightment.


+------------------
| Michael J. A. Berry
| <MJAB.91Dec4110009@thoon.think.com>

In article <1991Dec3.222657.19182@apollo.hp.com> keil@apollo.hp.com (Mark Keil)
 writes:

   I'm having a little trouble picturing  frames & cells.

   cells have something to do with axes, but exactly what?

   Are frames all of the cells except the current one?

   What are the properties of frames & cells. How do they
   behave?are there any tricks to using them?

   These frame & cell objects seem key higher rank oerations,
   but I don't have a feel for them, and there isn't enough
   background about them in the dictionary to understand what
   is going on.

   Thanks for any enlightment.


Frames and cells are a way of talking about multi-dimensional arrays as
collections of arrays of lower rank. For instance, an array of shape

4 3 5 7

May be viewed as a collection of 4 arrays of shape 3 5 7

or

a 4 by 3 array of subarrays ("cells") of shape 5 7

or

a 4 by 3 by 5 array of length 7 vectors

(and so on).

The term "frame" is used to refer to the outer shape, while "cell" refers
to the inner shape.  Think of functions as being defined on cells. The rank
operator (spelled " in J and little-circle-overstruck-with-diareses in
Sharp APL) is used to control how a function carves up its argument into
cells.

The result shape will therefor be the frame shape (in other words the
outer elements of the shape vector not used up by the cell), followed by
the shape of the result of applying the function to an object with the
cell shape.

Some examples:

   a =: i. 4 3 5 7

   $a
4 3 5 7
        a has shape 4 3 5 7

   #a
4
        a has four "major cells" (by default, the frame shape has one
        element)

   $ ,"2 a
4 3 35
        ravel rank 2 applies , to each of the 5 by 7 cells

   $ ,"3 a
4 105
        ravel rank 3 applies ravel to each of the 3 by 5 by 7 cells


On machines such as the Connection Machine model CM2 where arrays are layed
out across many processors, one often specifies the serial axes and the
parallel axes.  The parallel axes define the "cell" and the serial axes
define the "frame".  For example, a three dimensional array might have a
frame axis describing time, and two parallel axes which are spatial
coordinates. If the algorithm involves doing operations to all elements of
one plane at a particular time-step, those elements should be spread out
across the processors but since only one plane is active at a time, the
time axis should run up processor memory.  If there were APL or J for
Connection Machines, the rank operator would describe this splitting of
arrays into serial and parallel axes very nicely.  As it is, we resort to
"structured comments" in CM Fortran programs which let the compiler know
how to lay out the arrays since the Fortran language itself has no notion
of cell and frame.



*========================================
# Rank 0 catenation.

+------------------
| L.J.Dickey
| <1991Jun24.161151.12366@watmath.waterloo.edu>


Someone wrote recently asking about how to glue some given
arrays together to create certain specified results.
Here is the question.

 ========================= ========================== =========================
Suppose one is given the three arrays:

   a =. < " 0  m =. i. 2 3
   b =. < "(0) m + 12
   c =. < "(0) m + 24

How does one use these to create arrays d and e, whose displays are

   d
+----+----+----+
|0 12|1 13|2 14|
+----+----+----+
|3 15|4 16|5 17|
+----+----+----+
   e
+-------+-------+-------+
|0 12 24|1 13 25|2 14 26|
+-------+-------+-------+
|3 15 27|4 16 28|5 17 29|
+-------+-------+-------+
 ========================= ========================== =========================

I found that these expressions do the job:

   d =. a   ,"0  &. > b
   e =. d (,,"0) &. > c

My question is, do you know other ways of doing this?


+------------------
| Raul Rockwell
| <ROCKWELL.91Jun24202553@socrates.umd.edu>

L. J. Dickey (paraphrased, slightly):
   Suppose one is given the three arrays:
      c =. 12+&.> b =. 12+&.>  a=. <"0 i. 2 3

   How does one use these to create arrays d and e, whose displays are
      d                              e
   +----+----+----+               +-------+-------+-------+
   |0 12|1 13|2 14|               |0 12 24|1 13 25|2 14 26|
   +----+----+----+               +-------+-------+-------+
   |3 15|4 16|5 17|               |3 15 27|4 16 28|5 17 29|
   +----+----+----+               +-------+-------+-------+

   I found that these expressions do the job:
      d =. a   ,"0  &. > b
      e =. d (,,"0) &. > c
   My question is, do you know other ways of doing this?

======================================================================

How about:
     d =. a ,&.> b
     e =. ,&.>/ a,b,c

?

CAUTION: I don't have a working copy of J on my system so I honestly
don't know if that will even work.


+------------------
| Raul Rockwell
| <ROCKWELL.91Jun24223131@socrates.umd.edu>

I wrote:
        e =. ,&.>/ a,b,c

but that won't work.  This should work:
   e =. a ,&.> b ,&.> c
or
   e =. d ,&.> c            NB.  ,&.>  is associative


+------------------
| Roger Hui
| <1991Jun25.033445.14615@yrloc.ipsa.reuter.COM>

Article <1991Jun24.161151.12366@watmath.waterloo.edu> ljdickey@watmath.waterloo.
edu (L.J.Dickey):

Lee, here are some other ways to generate the desired results:

   d =. a ,&.> b
   e =. d ,&.> c
   e =. a ,&.> b ,&.> c

   d =. <"1 (i.2 3)+/0 12
   e =. <"1 (i.2 3)+/0 12 24

   d =. (<0 12) +&.> i.2 3
   e =. (<0 12 24) +&.> i.2 3


+------------------
| Roger Hui
| <1991Jun25.131306.17756@yrloc.ipsa.reuter.COM>

Article <ROCKWELL.91Jun24223131@socrates.umd.edu> by rockwell@socrates.umd.edu
(Raul Rockwell):
>I wrote:
>       e =. ,&.>/ a,b,c
>
>but that won't work.     [more stuff]

   e =. ,&.> / a,b,:c
   d =. ,&.> / a,:b


+------------------
| Robert J Frey
| <594@kepler1.kepler.com>

In article <1991Jun24.161151.12366@watmath.waterloo.edu> ljdickey@watmath.
waterloo.edu (L.J.Dickey) writes:
>
>Suppose one is given the three arrays:
>
>   a =. < " 0  m =. i. 2 3
>   b =. < "(0) m + 12
>   c =. < "(0) m + 24
>
>How does one use these to create arrays d and e, whose displays are
>
>   d
>+----+----+----+
>|0 12|1 13|2 14|
>+----+----+----+
>|3 15|4 16|5 17|
>+----+----+----+
>   e
>+-------+-------+-------+
>|0 12 24|1 13 25|2 14 26|
>+-------+-------+-------+
>|3 15 27|4 16 28|5 17 29|
>+-------+-------+-------+
>
>I found that these expressions do the job:
>
>   d =. a   ,"0  &. > b
>   e =. d (,,"0) &. > c
>
>My question is, do you know other ways of doing this?
>
>
>--
Well, I wouldn't do that way ;-)! But given your original definition of a, b
and c, you can also do:

        each =. '&.>':1

        a=. <"0 i.2 3
        b=. 12 +each a
        c=. 24 +each a

then:

        e=. a ,each b ,each c

Also, if list is a vector of boxed arrays of boxes:

        list=. (<a),(<b),<c

then this works:


        e=. >,each each/list


note that '$each e' is:

        +-+-+-+
        |3|3|3|
        +-+-+-+
        |3|3|3|
        +-+-+-+

as expected.

In the case of J I would defer the use of arrays of boxes until the 'last'
step:

        a=. i.2 3
        b=. a+12
        c=. b+24

        e=. <"1&.|:a,b,:c

I think that a comparison of the two approaches suggests that the latter is
probably a better way to do it.

I was more familiar with APL2ish APL rather than Sharpish APL, so I tended to
use a lot each's on boxed nouns when I first started using J. Because J
treats a boxed noun as a reference to data, rather than as the data themselves,
that often led to some pretty convolved sentences on my part.

Does anyone know why people seem to feel that "data nesting" as in APL2
enclosed variables and "data referencing" as in J boxed nouns are incompatible
with one another? They are probably implemented pretty much the same way as a
data structure, the difference being the way the various verbs/functions of
the language deals with them.

A rank operator would be great to have in APL2 instead of all that function
with axis stuff, and a foreach adverb and depth verb would be great to have
in J (sometimes the way J pads out ragged results with zeroes/blanks/empty
boxes makes me nervous).

All that being said, I'm finding J extremely interesting. I'm quickly becoming
one of the converted.


+------------------
| Eythan Weg
| <WEG.91Jun25125303@convx1.convx1.ccit.arizona.edu>

In article <ROCKWELL.91Jun24223131@socrates.umd.edu> rockwell@socrates.umd.edu
(Raul Rockwell) writes:


   I wrote:
           e =. ,&.>/ a,b,c

   but that won't work. [...]

but this would (I think):
e=.,&.>/a,b,:c

Any time I start playing with this toy I find new ways to recombine
its constituents.  Is it the language equivalent to Lego?  I am
confident that this is a common experience.  But here is a point that
puzzles me.  I wish J to possess a regular expression automaton to be
used in much the same way as it is used in unix utilities.  Is there
anything wrong with this desire?  I thought it might be used with E.
for example.

Any comments?


+------------------
| L.J.Dickey
| <1991Jun26.171808.3998@watmath.waterloo.edu>

In article <594@kepler1.kepler.com> rjfrey@kepler1.UUCP (Robert J Frey) writes:
> ...
>
>Does anyone know why people seem to feel that "data nesting" as in APL2
>enclosed variables and "data referencing" as in J boxed nouns are incompatible
>with one another? They are probably implemented pretty much the same way as a
>data structure, the difference being the way the various verbs/functions of
>the language deals with them.

They need not be incompatible.  I would refer you to the programming
language APL90, designed by Jean-Jacques Girardot, of the School of
Mines in St-Etienne, France, and to papers by Girardot.   With APL90,
which runs only on Macintosh computers, one may have both types of
generalized arrays in your workspace at the same time.

It was Girardot who made at the conference APL90 what is, I believe,
the first public observation that boxed arrays behave very much like
pointers to arrays.  In his paper, "Arrays and References", there is
a section called "A comparison of nested arrays, boxed arrays and
references" in which he notes a profound analogy between boxed arrays
and References.

Girardot may be reached at  girardot@cambur.emse.fr .  I don't know
if he reads this news group.


+------------------
| William Ricker
| <b7mykb.n3a@wang.com> 26 Jun 91 17:14:34 GMT

rockwell@socrates.umd.edu (Raul Rockwell) writes:
>       e =. ,&.>/ a,b,c
>but that won't work.  This should work:
>   e =. a ,&.> b ,&.> c

Nope.  That also gives
+---------------+---------------+---------------+
|0 3 12 15 24 27|1 4 13 16 25 28|2 5 14 17 26 29|
+---------------+---------------+---------------+

To insert (,&.>) between three arrays of similar size, you can
   ]    e =. ,&.> /   >  a;b;<c

which has the desired result of

+-----------------------+
|0 12 24|1 13 25|2 14 26|
+-------+-------+-------|
|3 15 27|4 16 28|5 17 29|
+-----------------------+

(The close or box < on c is needed since c is alread boxed, and thus
 won't get the extra layer needed for symmetry from ; for free; we
 then discard one layer of box  and work under the other.)


+------------------
| Eythan Weg
| <WEG.91Jun26151113@convx1.convx1.ccit.arizona.edu>

In article <b7mykb.n3a@wang.com> wdr@wang.com (William Ricker) writes:


   rockwell@socrates.umd.edu (Raul Rockwell) writes:
   >    e =. ,&.>/ a,b,c
   >but that won't work.  This should work:
   >   e =. a ,&.> b ,&.> c

   Nope.  That also gives
   +---------------+---------------+---------------+
   |0 3 12 15 24 27|1 4 13 16 25 28|2 5 14 17 26 29|
   +---------------+---------------+---------------+

Yes, it does work, at least on J/pc version 3.0.
And should, by the dictionary.

[[NB. sws. It also works fine for J 4.1 ]]


+------------------
| Roger Hui
| <1991Jun27.052421.809@yrloc.ipsa.reuter.COM>

In article <WEG.91Jun25125303@convx1.convx1.ccit.arizona.edu> weg@convx1.ccit.
arizona.edu (Eythan Weg) writes:

>    [stuff]
>
> Any time I start playing with this toy I find new ways to recombine
> its constituents.  Is it the language equivalent to Lego?  I am
> confident that this is a common experience.  But here is a point that
> puzzles me.  I wish J to possess a regular expression automaton to be
> used in much the same way as it is used in unix utilities.  Is there
> anything wrong with this desire?  I thought it might be used with E.
> for example.

a) It is not so unusual that the same nontrivial idea can be expressed
in more than one way.  One can say "to be or not to be" or "what now?"
as appropriate; does that make English a Lego language? :-)

b) If the regular expression automaton in UNIX is to your liking,
you can invoke it from within J by 0!:0 or by using LinkJ.

I have some epsilon-baked ideas on how a FSM can be introduced.
A gerund is an array of atomic representations of verbs.
The conjunction ` returns gerund results, for example, +`-`*`(+/)
is a 4-element gerund; and the conjunction g`:n defined various
verbs from a gerund.  (See Bernecky & Hui, APL91.)

If g is a gerund matrix, one can define:  fsm =. g`:57
fsm is applied to successive elements of an integer vector of inputs.
The initial state is 0.  If the current state is i and the current input
is j, then the verb represented by  (<i;j){g  is applied to i and j,
resulting in the pair (newstate;output).  The result of fsm is the
collection of the outputs.


+------------------
| Robert Bernecky
| <1991Jun27.062017.1276@yrloc.ipsa.reuter.COM>

(Whoever posted this...)

>use a lot each's on boxed nouns when I first started using J. Because J
>treats a boxed noun as a reference to data, rather than as the data themselves,
>that often led to some pretty convolved sentences on my part.
>
>Does anyone know why people seem to feel that "data nesting" as in APL2
>enclosed variables and "data referencing" as in J boxed nouns are incompatible
>with one another? They are probably implemented pretty much the same way as a
>data structure, the difference being the way the various verbs/functions of
>the language deals with them.

They are NOT incompatible. Perhaps my evil twin, xxx xxxxx, from IBM,
has been passing such rumours around. APL2 arrays are a proper subset of
SHARP APL arrays, and anyone  who can't see that will  deserve all theyget...

1. I doubt if they are even close in terms of a naive implementation.
   As the original implemenetor of boxes arrays on SHARP APL, and
   as one with at least ne appendage on the pulse of APL implementations
   around this planet, I doubt if they are close at all:
     a. SAPL stuff tends to work on the underlying primitive without
        bothering to call a function to bust it up, in common rank
        and similar expressions. Oddball ones, which are rarely used,
        such as reshape with a left argument rank specification, ARE
        done in a brute force manner. At least, they were when I worked
        there, and I sorta soubt, but cannot prove, that things have changed
        in that area.
     b. A lot of the functions with rank can be implemented by either
        introducing another level of looping, or altering the extant
        loop structure, in a rather obvious fashion:pass the rank
         expression to the primitive as Yey-Another_argument.
        It's not clear to me how this would work with apl2 and the world
        of eachness.

2. Beata hell outa me what (2) was. Perhaps the tail end of 1b?

3. A lot of the stuff with J  (or SAPL) vs APL2 is that the each/
enclose-along-axis stuff , is that a naive implementation can do MUCH
better with rank than with each/enclose with axis. Far fewer operations
involving storage management, data movement, and so on.

In SHARP APL, we observed speedups of typcally 5-500 when primitives
included rank adverb support directly.

>
>A rank operator would be great to have in APL2 instead of all that function
>with axis stuff, and a foreach adverb and depth verb would be great to have
>in J (sometimes the way J pads out ragged results with zeroes/blanks/empty
>boxes makes me nervous).

I also have to admit to being disturbed by J's lack of errors, both in
the padding of ragged arrays, and in the tolerance for negative elements
in index expressions. Life's tough that way...


+------------------
| Robert Bernecky
| <1991Jun27.062352.1353@yrloc.ipsa.reuter.COM>

In article <1991Jun27.052421.809@yrloc.ipsa.reuter.COM> hui@yrloc.ipsa.reuter.
COM (Roger Hui) writes:

>I have some epsilon-baked ideas on how a FSM can be introduced.
>A gerund is an array of atomic representations of verbs.
>The conjunction ` returns gerund results, for example, +`-`*`(+/)
>is a 4-element gerund; and the conjunction g`:n defined various
>verbs from a gerund.  (See Bernecky & Hui, APL91.)

If you want to see some earlier work that sets the stage for ROger and my
APL91 paper (which won't appear until August-ish), see my earlier
work in APL84:
"Function Arrays".



 