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 example using + as an update function was merely used for illustration 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 but with modified a 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 + upd 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 + upd 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 + upd 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