Perhaps it is useful to elaborate on my solution.

Let's take as an example

   [Y=: 1,p:i.8
1 2 3 5 7 11 13 17 19

First notice that the original problem 
(http://www.jsoftware.com/pipermail/programming/2008-May/010762.html)

   3([: (+/ % #) (*/ |.)\)Y
87.71 71.29    54
117.1 95.14 71.29
146.1 117.1 87.71

is equivalent to 

   3 |."1@([: (+/ % #) (*/~)\)Y
87.71 71.29    54
117.1 95.14 71.29
146.1 117.1 87.71

where reversing (the rows) is done afterwards.

The resulting matrix is the average of (using Kobchenko's solution)

   [r0=: 3 ([: <@(*/~)"1 ]\ ) Y
+-----+--------+--------+---------+----------+-----------+-----------+
|1 2 3| 4  6 10| 9 15 21|25 35  55|49  77  91|121 143 187|169 221 247|
|2 4 6| 6  9 15|15 25 35|35 49  77|77 121 143|143 169 221|221 289 323|
|3 6 9|10 15 25|21 35 49|55 77 121|91 143 169|187 221 289|247 323 361|
+-----+--------+--------+---------+----------+-----------+-----------+

All these products can be found in a few main diagonals of (*/~)Y

   ['r1 r2'=: ((*/~)Y) ([;+) (_ 0{~ 3>[:|@(-/"1) 9&#.^:_1) i.9 9 
+-------------------------------+-----------------------------+
| 1  2  3  5   7  11  13  17  19|1  2  3  _  _   _   _   _   _|
| 2  4  6 10  14  22  26  34  38|2  4  6 10  _   _   _   _   _|
| 3  6  9 15  21  33  39  51  57|3  6  9 15 21   _   _   _   _|
| 5 10 15 25  35  55  65  85  95|_ 10 15 25 35  55   _   _   _|
| 7 14 21 35  49  77  91 119 133|_  _ 21 35 49  77  91   _   _|
|11 22 33 55  77 121 143 187 209|_  _  _ 55 77 121 143 187   _|
|13 26 39 65  91 143 169 221 247|_  _  _  _ 91 143 169 221 247|
|17 34 51 85 119 187 221 289 323|_  _  _  _  _ 187 221 289 323|
|19 38 57 95 133 209 247 323 361|_  _  _  _  _   _ 247 323 361|
+-------------------------------+-----------------------------+

Almost all these products are calculated more than once:

   (|:({.,#)/.~,;r0) rpl r2     NB. see [1] for rpl
1 2 2 _ _ _ _ _ _
2 2 4 2 _ _ _ _ _
2 4 3 4 2 _ _ _ _
_ 2 4 3 4 2 _ _ _
_ _ 2 4 3 4 2 _ _
_ _ _ 2 4 3 4 2 _
_ _ _ _ 2 4 3 4 2
_ _ _ _ _ 2 4 2 2
_ _ _ _ _ _ 2 2 1

So this brings up the idea of calculating the first 3 diagonals (due to
symmetry) only once and constructing the average from it.
First the coordinates are determined.

   ;/ z=: (|:x#,:t),:(t=.i.#y)+/i.x ['x y'=.3;Y
+-----+------+
|0 0 0|0 1  2|
|1 1 1|1 2  3|
|2 2 2|2 3  4|
|3 3 3|3 4  5|
|4 4 4|4 5  6|
|5 5 5|5 6  7|
|6 6 6|6 7  8|
|7 7 7|7 8  9|
|8 8 8|8 9 10|
+-----+------+

Since the first diagonals are shorter, they are extended so all have equal
length. For that reason, y is appended with zeroes.

   [v=: */((x#0),~ y){~ z
  1   2   3
  4   6  10
  9  15  21
 25  35  55
 49  77  91
121 143 187
169 221 247
289 323   0
361   0   0

These are the values of the diagonals in r2.

Now the forward sums are calculated

   |."1(s=.>:(#y)-x)+/\ v
 378 499 614
 666 820 611
1023 814 601

and for each diagonal a different subset is taken

   (|.>:i.x)<@{."_1 |."1(s=.>:(#y)-x)+/\ v
+-----------+-------+----+
|378 499 614|666 820|1023|
+-----------+-------+----+

averaging it to get the final figures

   [w=: s%~;(|.>:i.x)<@{."_1 |."1(s=.>:(#y)-x)+/\ v
54 71.29 87.71 95.14 117.1 146.1

The rest is putting the values of w in the right order for the output matrix

   r rpl~ (2,@#,:w),:~(|.->:i.x)([:; (2,@#,:@[) <@{."0 1 (,|:)@])r=.i.2#x
   54 71.29 87.71
71.29 95.14 117.1
87.71 117.1 146.1

So this leaves us with 

cAO=: 4 : 0  NB.This solution is different from a former version.
z=. (|:x#,:t),:(t=.i.#y)+/|.i.x
v=. */((x#0),~ y){~ z
w=. s%~;(|.>:i.x)<@{."_1 |."1(s=.>:(#y)-x)+/\ v 
r rpl~ (2,@#,:w),:~(|.->:i.x)([:; (2,@#,:@[) <@{."0 1 (,|:)@])r=.i.2#x
)

   3 |."[EMAIL PROTECTED] Y
87.71 71.29    54
117.1 95.14 71.29
146.1 117.1 87.71


[1] rpl=: ] - (-/ , 0:)@[ {~ [EMAIL PROTECTED] i. ]     NB. from rpl2a in
http://www.jsoftware.com/pipermail/programming/2007-July/007303.html


R.E. Boss



----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to