Question

I have a 2x3 array

a =. 2 3 $  2 3
   a
2 3 2
3 2 3

And I want to add all the elements together using +/ to get 15.

So

+/a
5 5 5

Hmmm. This is clearly adding columns. I know that +/ rank is _ _ _ (i.e. infinity) and a is rank 2. I can't translate this into imagining why it adds columns, unfortunately. (I am reading "J for C Programmers")

So just for fun I did:

+/"1 a
7 8

So now it's adding rows. Clearly I changed the rank of +/ to 1, which is less then 2 (the rank of a) which means... I don't know. Why am I now adding rows by switching form infinity to 1?

What about

+/"0 a
2 3 2
3 2 3

So now we are just adding single cells with nothing so we get an array equal to the original a. Again I don't know why, although I can just about muddle through an argument to get here: verb rank is less than a (the noun) rank, so we use this value, which is zero, so we add 0-cells, ie. we add each cell in turn individually.

And once more for luck:

+/"2 a
5 5 5

And I'm adding columns again. I don't know the mechanism which is choosing which rows/columns/cells get added as the verb rank is changed. We're adding columns but form my point of view, we could just as easily be adding rows.

I would like this explained if possible. As I said I'm reading some literature but I'm still finding it tough.

Was it helpful?

Solution

When you have an n-array, you can access each nesting "level" using the appropriate rank.

Ranks/shapes of a NOUN

First you have atoms (rank 0):

a =: 1

their shape ($a) is empty.

Then you have lists (rank 1), which are just some atoms put together:

b =: a,a,a
b =: 3 # a
b =: 3 $ a

their shape ($b) is the length of the list.

$b
3

Then, tables (rank 2): lists put together (stiched or otherwise):

c =: b,.b,.b

their shape is a 2 item list: rows, columns.

$c
3 3

Then, up to rank-n array (rank n).

Rank of a VERB

The rank of a verb is a somewhat different story. It's the rank on which the verb will apply. So, when you box-0 (<"0) a noun, you always box the atoms of this noun, when you box-1 (<"1), you always box the lists of the noun, etc. Eg:

 ]n =: 2 3 4 $ i.24
 0  1  2  3
 4  5  6  7
 8  9 10 11

12 13 14 15
16 17 18 19
20 21 22 23

0-rank:

<"0 n
┌──┬──┬──┬──┐
│0 │1 │2 │3 │
├──┼──┼──┼──┤
│4 │5 │6 │7 │
├──┼──┼──┼──┤
│8 │9 │10│11│
└──┴──┴──┴──┘

┌──┬──┬──┬──┐
│12│13│14│15│
├──┼──┼──┼──┤
│16│17│18│19│
├──┼──┼──┼──┤
│20│21│22│23│
└──┴──┴──┴──┘

1-rank:

  <"1 n
┌───────────┬───────────┬───────────┐
│0 1 2 3    │4 5 6 7    │8 9 10 11  │
├───────────┼───────────┼───────────┤
│12 13 14 15│16 17 18 19│20 21 22 23│
└───────────┴───────────┴───────────┘

2-rank:

 <"2 n
┌─────────┬───────────┐
│0 1  2  3│12 13 14 15│
│4 5  6  7│16 17 18 19│
│8 9 10 11│20 21 22 23│
└─────────┴───────────┘

3 rank:

 <"3 n
┌───────────┐
│ 0  1  2  3│
│ 4  5  6  7│
│ 8  9 10 11│
│           │
│12 13 14 15│
│16 17 18 19│
│20 21 22 23│
└───────────┘

In this example, ranks higher than 3 are the same as 3.

You can also use negative ranks, btw, which count backwards from the highest rank.

You can also mix the ranks.

Summing

You can see now, how changing the rank of +/, changes the result of the summation. For example, +/"1 sums every rank-1 list:

    <"1 n
┌───────────┬───────────┬───────────┐
│0 1 2 3    │4 5 6 7    │8 9 10 11  │
├───────────┼───────────┼───────────┤
│12 13 14 15│16 17 18 19│20 21 22 23│
└───────────┴───────────┴───────────┘
   +/"1 n
 6 22 38
54 70 86

To sum a rank-n array you have to perform n +/s:

(+/^:3) n
276
+/+/+/ n
276

or you can ravel (,) the array before summing:

+/,n
276

OTHER TIPS

The phrases +/"1 and +/ appear to act on the rows and columns of a matrix, but this is not an accurate description of what they do and doesn't help to really get a idea of the simplicity and power of the concept of rank.

Let's start by understanding the phrase +/ (we'll confine ourselves to the monadic form for now i.e. only a right argument). This phrase consists of the adverb / which takes the verb to its left, in this case +, and inserts it between the items of the right argument. The items of a list/vector are the numbers/atoms in the list so +/ 3 4 5 6 is really just shorthand for 3 + 4 + 5 + 6. The items of a table/matrix (rank 2) are its rows (rank 1) and the items of a rank 3 array are its tables (rank 2)

   ]a=: i. 2 3
0 1 2         NB. 1st item of a
3 4 5         NB. 2nd item of a

   ]b=: i. 2 3 4 
 0  1  2  3
 4  5  6  7   NB. 1st item of b
 8  9 10 11

12 13 14 15
16 17 18 19   NB. 2nd item of b
20 21 22 23

Remember +/ inserts + between the items of its right argument so:

   +/ i. 2 3
3 5 7   

Is essentially just:

   0 1 2 + 3 4 5
3 5 7

And:

   +/ i. 2 3 4
12 14 16 18
20 22 24 26
28 30 32 34

is just adding two matrices together

   (i. 3 4) + (12 + i. 3 4)
12 14 16 18
20 22 24 26
28 30 32 34

So how does the rank conjunction " fit in? I find the easiest way to think about it is that you can use it to control how big a chunk of the right argument is fed to the verb at a time. So +/"1 is the same as +/, but any right argument will only be fed to +/ a list/vector/row at a time. So:

   +/"1 i. 2 3

feeds the matrix i. 2 3 to +/ a row-at-a-time. +/ will then insert the + between the items of the row, evaluate the expression and then move on to the next chunk, appending the results for each chunk together as it goes. In other words, the actual calculation looks something like this

   +/"1 i. 2 3 -->
   (+/ 0 1 2) , (+/ 3 4 5) -->
   (0 + 1 + 2) , (3 + 4 + 5)
3 12

   +/"1 i. 2 3 4   NB. Feed right arg to +/ a row-at-a-time
 6 22 38           NB. + inserted between items of each row
54 70 86           NB. result has row for each item (matrix) in original argument

   +/"2 i. 2 3 4   NB. feed right arg to +/ a table/matrix-at-a-time
12 15 18 21        NB. + inserted between rows of each matrix
48 51 54 57

   +/"0 i. 2 3 4   NB. feed right arg to +/ an atom at a time
0  1  2  3         NB. this is essentially an identity function because
4  5  6  7         NB. the sum of a number is itself: (+/ 3) is just 3.
8  9 10 11

12 13 14 15
16 17 18 19
20 21 22 23
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top