Both >./ and ([ >. +)/\. are linear; thus kad ought to be linear. I think a
more representative test is,

   kad=. >./@:(([ >. +)/\.)

   Y4=. ?1e4#0
   Y5=. ?1e5#0
   Y6=. ?1e6#0
   Y7=. ?1e7#0
   Y8=. ?1e8#0


   stp 5
kad Y4
kad Y5
kad Y6
kad Y7
kad Y8
)
Mismatch!
┌────────┬──────────┬──────────┬────────────┐
│Sentence│Space     │Time      │Space * Time│
├────────┼──────────┼──────────┼────────────┤
│kad Y4  │132256    │0.00064946│85.895      │
├────────┼──────────┼──────────┼────────────┤
│kad Y5  │1049760   │0.00708874│7441.48     │
├────────┼──────────┼──────────┼────────────┤
│kad Y6  │8389792   │0.0835266 │700771      │
├────────┼──────────┼──────────┼────────────┤
│kad Y7  │134218912 │0.756735  │1.01568e8   │
├────────┼──────────┼──────────┼────────────┤
│kad Y8  │1073743008│7.56513   │8.123e9     │
└────────┴──────────┴──────────┴────────────┘

This seems pretty linear to me


On Fri, Apr 7, 2023 at 3:54 AM Raul Miller <rauldmil...@gmail.com> wrote:

> Actually, my summary line should have been
>
>    2 %/\ 5.98958 0.57413 0.0674812 0.0142999 0.002802
> 10.4324 8.508 4.719 5.10346
>
> Also, for comparison:
>
>    timex '?1e4#0'
> 0.0002895
>    timex '?1e5#0'
> 0.0034291
>    timex '?1e6#0'
> 0.0150786
>    timex '?1e7#0'
> 0.081682
>    timex '?1e8#0'
> 0.927786
>
>    2 %/\ 0.927786 0.081682 0.0150786 0.0034291 0.0002895
> 11.3585 5.41708 4.39725 11.8449
>
> There's two major sources of timing discrepancies here for what would
> "theoretically" be a linear (factor of 10) increase:
>
> (1) arbitrary conflicts with system processes, and
>
> (2) memory cache.
>
> FYI,
>
> --
> Raul
>
> On Fri, Apr 7, 2023 at 3:47 AM Raul Miller <rauldmil...@gmail.com> wrote:
> >
> > This does't look like O(n^2)
> >
> >    kad=. >./@:(([ >. +)/\.)
> >    timex 'kad ?1e4#0'
> > 0.002802
> >    timex 'kad ?1e5#0'
> > 0.0142999
> >    timex 'kad ?1e6#0'
> > 0.0674812
> >    timex 'kad ?1e7#0'
> > 0.57413
> >    timex 'kad ?1e8#0'
> > 5.98958
> >
> >    2 %~/\ 5.98958 0.57413 0.0674812 0.0142999 0.002802
> > 0.0958548 0.117536 0.211909 0.195945
> >
> > --
> > Raul
> >
> > On Fri, Apr 7, 2023 at 3:09 AM Thomas McGuire <tmcguir...@gmail.com>
> wrote:
> > >
> > > In my haste to produce an email after finally figuring out how Pepe’s
> elegant J implementation of the maximal sum of the subsequences worked ,I
> can see how you might interpret this as I was disappointed in the
> implementation as not being “pure” kadane. I meant only to classify the
> implementation so that the CPU times I was recording made sense
> > >
> > > From the perspective of big O analysis. Pure kadane is O(n). Where
> Pepe’s algorithm is being applied to a list (of length n)  of lists of
> varying length 1..n, The operation performed 1+1+2+…+n-1 times. Which
> places it about O(n^2) though it’s been a while since I have done any
> algorithm analysis.
> > >
> > > In terms of a J implementation of the broader category of maximal sum
> of the subsequences of a list of numbers, Pepe’s algorithm is fantastic.
> From the perspective of my tutorial it is an incredibly insightful jump
> from the naive brute force implementations I had used.  It is such a
> concise J implementation that highlights a significant portion of J’s
> advanced techniques. I intend on adding it to my tutorial I just hope I can
> explain it well enough to make it accessible to my target audience.
> > >
> > >
> > > > On Apr 6, 2023, at 10:55 PM, Henry Rich <henryhr...@gmail.com>
> wrote:
> > > >
> > > > I think that when you say Pepe's code is not the Kadane algorithm
> you are conflating algorithm and implementation.
> > > >
> > > > Kadane's idea is that (1) at each new prospective starting point for
> the maximal sequence, you have the option of starting at 0 or the previous
> best total; (2) every position is a prospective ending point.  Pepe's
> algorithm follows these observations.
> > > >
> > > > The usual implementations keep two values through the loop: (a) the
> maximum value found on sequences that have ended; (b) the current total on
> sequences that the new value may add onto.
> > > >
> > > > Well, that's one way to do it.  Another is to produce (a) as an
> intermediate result for each possible ending position, and then at the end
> see which of those values is the largest.  That's what Pepe did.  I approve
> his decision, since keeping two values through the scan would require
> ponderous indexing operations. This is the sort of implementation decision
> that surprises users of compiled languages.
> > > >
> > > > Pepe's implementation in no way changes the algorithm.  It's merely
> a reordering of when comparisons are made.  Pepe's algorithm is O(n), just
> as the usual algorithms are.
> > >
> > > As I tried to explain above the ([ >. +)/ is O(n) but when used on
> suffixes with the ‘\.’ operator it becomes O(n^2). the kadane”0
> implementation that Elijah proposed operates through the array one at a
> time in O(n) producing a list of possible maximal sums which is extracted
> with >./ also in O(n). That kadane algorithm uses your technique in Chapter
> 25 Loopless Code VI, to perform a single run through the array.
> > >
> > > Just trying to be accurate so I can explain the implementations
> correctly in my essay.
> > > >
> > > > Pepe knew that >./ is very fast, probably 10% of the time of the
> other bit.  The time spent in (([ >. +)/\.) is O(n), not worth our
> discussion; but if you want to blame someone for the speed, blame the
> implementation (i. e. me), not the algorithm. Perhaps (+ 00&>.)~/\. would
> be faster; I haven't tested it, but we're down to minute questions of
> instruction ordering.
> > >
> > > No complaints about J’s speed. Even the naive brute force
> implementation runs in less than a second on a 10000 element array. I have
> been using the timings as a relative guage that the various implementations
> work the way I think they are supposed to.
> > >
> > > The one thing I did have a question on now that I’ve drawn you into
> this thread. Is that the memory requirement for Pepe’s algorithm is about
> 1/5 the size of the kadane”0 algorithm. The global variable assignment
> appears to be the operation that causes the large amount of memory to be
> used. Elijah tried to explain it and hsi explanation is valid for some of
> the implementations such as the use of ‘\’ and Fold. But I don’t understand
> in the setting of a global variable.
> > >
> > > Tom McGuire
> > > >
> > > > Henry Rich
> > > >
> > > >
> > > >
> > > >
> > > > On 4/6/2023 8:12 PM, Thomas McGuire wrote:
> > > >>
> > > >>> On Apr 3, 2023, at 1:28 PM, Jose Mario Quintana <
> jose.mario.quint...@gmail.com> wrote:
> > > >>>
> > > >>> For what it is worth...
> > > >>>
> > > >>> kad=. >./@:(([ >. +)/\.)
> > > >>>
> > > >> OK that is worth a lot. But it’s not really the kadane algorithm.
> It inserts a kadane-like summation in between elements for each suffix
> generated. Kadane obtains the sum on a single pass through the array.
> However it’s an incredibly elegant refactoring of the brute force example
> and saves performing partial sums on the suffixes.
> > > >>
> > > >> I will say after figuring out exactly what is was doing it wasn’t
> intuitively obvious (to me anyway) that this should work. A naive view is
> that the largest sum in the example below is produced by the subsequence :
> > > >> 4 _1 2 1
> > > >>
> > > >> So that sequence is never generated in Jose’s version of maximum
> sum. However due to it’s Kadane-like properties it is generating the
> highest sum for each suffix as if the partial sum started at the first
> element. In essence using a kadane-like approach in place of performing
> partial sums. Therefore in one pass on each suffix you find the greatest
> partial sum without having to calculate each partial sum individually.
> > > >>
> > > >> Jose’s version is fairly quick coming in at about double the
> processing time of Jose’s kadane”0 version and well below the brute force
> method of taking the partial sums of all the suffixes.
> > > >>
> > > >> Tom McGuire
> > > >>
> > > >>> For example, the maximum sum subarray,
> > > >>>
> > > >>>
> > > >>>  kad _2 1 _3 4 _1 2 1 _5 4
> > > >>> 6
> > > >>>
> > > >>>
> > > >>>   kad i.0
> > > >>> __
> > > >>>
> > > >>>
> > > >>>
> > > >>>
> > > >>>
> > > >>> On Mon, Apr 3, 2023 at 5:22 AM Elijah Stone <elro...@elronnd.net>
> wrote:
> > > >>>
> > > >>>> Your kadane routines are all bound to have asymptotically poor
> space usage
> > > >>>> under the present interpreter because >./ is not fused; so they
> all must
> > > >>>> create an intermediate result array whose length is the same as
> ranvec,
> > > >>>> and
> > > >>>> then apply >./.  I think (haven't looked very closely) that
> locmax is the
> > > >>>> same
> > > >>>> as your final answer; so you could skip generating the
> intermediate array
> > > >>>> and
> > > >>>> simply look at locmax.  Better yet, get rid of the global
> variable, and
> > > >>>> turn
> > > >>>> this all into a fold single (rather than fold multiple), where
> locmax
> > > >>>> becomes
> > > >>>> the running value.
> > > >>>>
> > > >>>> On Mon, 3 Apr 2023, Elijah Stone wrote:
> > > >>>>
> > > >>>>>  7!:2 '>./ 1 kadane\ ranvec' [ locmax=: __
> > > >>>>> 1412576
> > > >>>>>   7!:2 '>./ kadane"0 ranvec' [ locmax=: __
> > > >>>>> 772960
> > > >>>>>   7!:2 '>./ kadane"1 ranvec2' [ locmax=: __ [ ranvec2=: ,.ranvec
> > > >>>>> 1412960
> > > >>>>>   1 <@$@$\ i.5
> > > >>>>> ┌─┬─┬─┬─┬─┐
> > > >>>>> │1│1│1│1│1│
> > > >>>>> └─┴─┴─┴─┴─┘
> > > >>>>>   <@$@$"0 i.5
> > > >>>>> ┌─┬─┬─┬─┬─┐
> > > >>>>> │0│0│0│0│0│
> > > >>>>> └─┴─┴─┴─┴─┘
> > > >>>>>
> > > >>>>> 1 kadane\ y applies kadane to length-1 subsequences of y--that
> is, in
> > > >>>> this
> > > >>>>> case, vectors, which have length 1.  Whereas kadane"0 applies to
> cells
> > > >>>> of y,
> > > >>>>> which have rank 0.  More space is required to store a length-1
> vector
> > > >>>> than a
> > > >>>>> scalar, since in the former case the length also needs to be
> stored.
> > > >>>>>
> > > >>>>> On Mon, 3 Apr 2023, Thomas McGuire wrote:
> > > >>>>>
> > > >>>>>> I’m wondering if someone with more J internals knowledge can
> tell me
> > > >>>> why my
> > > >>>>> Kadane algorithm implementation is taking up more memory than my
> naive
> > > >>>> brute
> > > >>>>> force method that generates all subsequences then sums them. The
> time is
> > > >>>>> about what I would expect except for the FOLD operation. The
> time space
> > > >>>> data
> > > >>>>> were generated on a MacBook Pro 2019 era I9 processor 2.3GHz.
> > > >>>>>>  ranvec =: _5 + ?10000$10
> > > >>>>>>  kadane =: 3 : 'locmax =: y >. locmax + y'
> > > >>>>>>  kadane1 =: 3 : 'locmax =: (] >. locmax&+) y'
> > > >>>>>>
> > > >>>>>>  NB. first brute force implementation
> > > >>>>>>  timespacex '>./(>./@(+/\))\.ranvec'
> > > >>>>>> 0.032948 396448
> > > >>>>>>
> > > >>>>>>  NB. fork version brute force
> > > >>>>>>  timespacex '>./([: >./ (+/\))\. ranvec'
> > > >>>>>> 0.034208 396448
> > > >>>>>>
> > > >>>>>>  NB. first kadane implementation
> > > >>>>>>  locmax =: __
> > > >>>>>>  timespacex '>./ 1 kadane\ranvec'
> > > >>>>>> 0.004034 1.41251e6
> > > >>>>>>
> > > >>>>>>  NB. fork kadane version
> > > >>>>>>  locmax =: __
> > > >>>>>>  timespacex '>./ 1 kadane1\ranvec'
> > > >>>>>> 0.005267 1.41277e6
> > > >>>>>>
> > > >>>>>>  NB. new dnfs anonymous kadane function
> > > >>>>>>  locmax =: __
> > > >>>>>>  timespacex '>./ 1 {{locmax =: y >. locmax + y}}\ranvec'
> > > >>>>>> 0.003625 1.41347e6
> > > >>>>>>
> > > >>>>>>  NB. fork dnfs anonymous kadane function
> > > >>>>>>  locmax =: __
> > > >>>>>>  timespacex '>./ 1 {{locmax =: (] >. locmax&+) y}}\ranvec'
> > > >>>>>> 0.004776 1.41386e6
> > > >>>>>>
> > > >>>>>>  NB. Fold kadane implementation
> > > >>>>>>  timespacex '>./ __ ] F:. ([ >. +) ranvec'
> > > >>>>>> 0.017393 905792
> > > >>>>>>
> > > >>>>>> This was all part of a J Tutorial I have written
> > > >>>>>
> https://code.jsoftware.com/wiki/User:Tom_McGuire/KadaneAlgorithmTutorial
> > > >>>>>> Tom McGuire
> > > >>>>>>
> ----------------------------------------------------------------------
> > > >>>>>> For information about J forums see
> http://www.jsoftware.com/forums.htm
> > > >>>>>
> ----------------------------------------------------------------------
> > > >>>>> For information about J forums see
> http://www.jsoftware.com/forums.htm
> > > >>>>>
> > > >>>>
> ----------------------------------------------------------------------
> > > >>>> For information about J forums see
> http://www.jsoftware.com/forums.htm
> > > >>>>
> > > >>>
> ----------------------------------------------------------------------
> > > >>> For information about J forums see
> http://www.jsoftware.com/forums.htm
> > > >>
> ----------------------------------------------------------------------
> > > >> For information about J forums see
> http://www.jsoftware.com/forums.htm
> > > >
> > > >
> ----------------------------------------------------------------------
> > > > For information about J forums see
> http://www.jsoftware.com/forums.htm
> > >
> > > ----------------------------------------------------------------------
> > > For information about J forums see http://www.jsoftware.com/forums.htm
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
>
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to