Thanks to all the contributors to this thread, esp. Dan Bron.

The question was stimulated by the need for an adverb which takes a state m, some new information a, and updates the state for some function f. This is such a common problem that it could be a candidate for special code, a special train, or a primitive. However the simple adverb upd below performs very well.

The simple example using + as an update function was merely a simple case and is of no particular interest.

My experiments show Dan is right in saying that his gu does not generalise.

The simple case used for illustration gave the timings below which seem comparable with Dan's. The Quintana seq function provides the key ideas. I believe the upd adverb provides the best current solution and will try that out with a range of much more complex updating functions which modify and change the shape of multidimensional arrays. The solutions showed how significant some aspects of coding style are for performance.

I was surprised by the range of numbers observed in repetitions of test comparisons. Roger is quite right in saying we should not be too concerned about relatively close performance figures. The best alternatives have ranged over ratios from about 0.8 to 1.4 in repetitions of the same code for small data sets. Clearly some careful statistical analysis would be required to make confident assertions about performance differences in that range.

The remainder of this post just summarises my comparisons using information from the thread:

    Note 'An update adverb'
The following adverb seems to do precisely what is required.  It
uses ideas from several of the contributions. It uses suffix to exploit calculation order
)


  upd =: 1 : 0
:
|. u&.> /\. (|. <"_1 x),<y
)


  NB. My original explicit form using control structures

  recf=: 1 : 0
:
s =. y
r =. ,:s
for_i.
 i. # x
do. s =. (i{x) u s
    r =. r,s
end.
r
)

  NB.  the Quintana adverb
  seq =:  ((&.>) /) (@:((|.@:[) , (<@:]))) (>@:)
  NB.  Requires boxed items in left argument, hence

  bron0 =: (+ seq f. ~ <"_1 )~

  NB.  Dan's second solution
ug =. 2 : '[: >@:({."1) (2&(u&.>/@:{. , }.)^:(1 < #)^:n @: (; <"_1@:|.)~)'
  bron1   =:  + ug a: f.

  NB.  test utilities
  ts =: 6!:2,7!:2

  NB. string noun to array
  stoa =: 3 : '> < ;._2 y'


  compare =: 3 : 0
tlist =. stoa y
tims =. ts"1 tlist
t=. 0{"1 tims
m =. <./t
mi =. {. t i. m
(tlist,.' '),.' ',.": tims % "1 _ mi{tims
)

  NB.  Some tests
  tests =: 0 : 0
a + zc m
a bron1 m
a [EMAIL PROTECTED] m
a + recf m
(<"0 a) + seq m
a bron0 m
)

  NB.  set nouns used as arguments
  a =: +:>: i.500
  m =: i. 2 2

  compare tests
a + zc m               1        1
a bron1 m         144.77  21.9665
a [EMAIL PROTECTED] m  44.6661 0.469405
a + recf m       7.00055 0.113579
(<"0 a) + seq m  1.09524  0.26907
a bron0 m        1.07225 0.256915
    a =: +: >: i.5000
  compare tests
a + zc m               1        1
a bron1 m        1397.39  230.132
a [EMAIL PROTECTED] m  413.078 0.504823
a + recf m       6.18148 0.147159
(<"0 a) + seq m  1.04003 0.292697
a bron0 m        1.24939 0.291521


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

Reply via email to