Re: [eigen] On a flexible API for submatrices, slicing, indexing, masking, etc. |
[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]
On Fri, Jan 6, 2017 at 10:35 PM, Yuanchen Zhu <yuanchen.zhu@xxxxxxxxx> wrote:On Fri, Jan 6, 2017 at 3:50 AM, Massimiliano Janes <max.jns@xxxxxxxxx> wrote:[…]. Last Massimilliano's post seems to imply that APL also uses this strategy to define bounds...gaelI didn’t mean that sorry, I was just referring to the general idea behind APL's iota function, eg. transforman integer N into the sequence [1,…,N], then *lazily* apply operations like arithmetics, transpositions,etc… to create/manipulate vectors.the API you’re proposing clearly differs in that N is given by the 'source’ vector, and the resulting index setis clamped to fit in, but the idea ( and its benefits ) seems the same conceptually …as an alternative to gael’s iota < bounds, one could follow more closely APL by introducing an _expression_representing the number of source elements:A(iota(all)) // as A(all)A(iota(5)) // first five elementsA(2+iota(5)) // from index 2 to 6A(2*iota(all) ) // even numbersIn general, I think the behavior of how Iota or Iota(all) is auto-bounded needs further discussion.Are out of bounds indices automatically pruned for expr involving Iota? Does A(-3 + Iota) generate an error upon indexing? What about A(-3 + iota(3))?ok, I think I made big mistake in naming Iota as iota(n), it clearly confuses you. Let's rename it "any_nat" for now and interpret it as a placeholder. This is really what I had in mind first, but I somehow thought it would be nice to merge the initial iota(n) API with this "any_nat+optional bounds" one. So once you completely separate them and think in terms of a any-natural-number placeholder, everything should become clear:- The initial, APL-like iota(n) function defines a sequence with precise bounds that you can then manipulate. No implicit bounds here. So if size(A)==n, then:A(2*iota(n) )will raise an out-of-bound assertion. Writing A( 2*iota(n) <= last ) would not be allowed, as you noticed, this would be too confusing. Basically, we could also apply the same principle to seq, seqN. iota(n) would then simply be a shortcut for seqN(0,n)==seq(0,n+1).- Then, for the "any_nat" approach, the general syntax would be:a <= (an _expression_ using any_nat) <= bOf course, you can use <= or <. Then, as in python, it is convenient to define default values for the bounds: a=0, and b=last. That's all.So for instance, A(a<(-3+any_nat)<b) == A(a<any_nat<b). Adding an offset to any_nat makes sense only if you change the increment as in the "all odd numbers in [a,b]" example:A(a<=(2*any_nat+1)<=b)This one is a pain to express with all other API if you cannot guarantee that 'a' is odd itself. Want to reverse the order? just use -any_nat. Nothing else to worry about.
And yes, a<=any_nat does not return a boolean or a vector of booleans, but once put using this new wording, how could it be?gaelA(2*iota(5) ) // even numbers up to 8A(3+2*iota(all-2) ) // 3,5,7,… up to N-2A(all - iota(5) ) // N-1,N-2,..,N-5...where bound checking is meant to follow Eigen habits ( eg. hard error if compile time, assert on runtime )
Mail converted by MHonArc 2.6.19+ | http://listengine.tuxfamily.org/ |