Members of the Forum -
I have this function:
NB.* ncile: break vector into x equally-sized pieces based on ascending
values.
ncile=: 4 : 0"(0 1)
grd=. /:y
brkptixs=. roundNums (>:i.<:x)*x%~#y NB. Internal breakpoints only
brkptixs=. (grd{y) i. brkptixs{grd{y NB. Adjust for breaks across
=values.
ptn=. (1) (0,brkptixs)}0$~#y
ptn<;.1 grd{y
)
This is supposed to break up a vector into (roughly) equal-sized pieces,
for example:
]rnn=. ?12$10
7 4 0 2 7 6 8 4 6 9 8 4
4 ncile rnn
+---+-----+-------+-----+
|0 2|4 4 4|6 6 7 7|8 8 9|
+---+-----+-------+-----+
The pieces are not equal-sized because it's more important that the
divisions
be non-overlapping, so all three "4"s have to be in the same group.
The companion to this returns a list of partition indexes:
NB.* ncileix: index vector by ncile into which it falls.
ncileix=: 4 : 0"(0 1)
grd=. /:y
brkptixs=. roundNums (>:i.<:x)*x%~#y NB. Internal breakpoints only
brkptixs=. (grd{y) i. brkptixs{grd{y NB. Adjust for breaks across
=values.
ptn=. (1) (0,brkptixs)}0$~#y
ptnix=. (#&>ptn<;.1]1$~#ptn)#i.+/ptn NB. Partition indexes/graded values
ptnix{~/:grd NB. Back in original input order
)
So, for example (matching the divisions above):
rnn,:4 ncileix rnn
7 4 0 2 7 6 8 4 6 9 8 4
2 1 0 0 2 2 3 1 2 3 3 1
However, my feeling is this code is a bit clumsy. Can anyone think of
a neater pair of solutions?
P.S. I don't really care about this behavior that fails to return "x"
values as my left arguments will probably be hundreds of nearly distinct
values and I'll usually want no more than 10 partitions:
4 ncile 20$1
+---------------------------------------+
|1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1|
+---------------------------------------+
4 ncileix 20$1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Thanks,
Devon McCormick, CFA
^me^ at acm.
org is my
preferred e-mail
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm