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 4:54 PM, Gael Guennebaud <gael.guennebaud@xxxxxxxxx> wrote:


On Fri, Jan 6, 2017 at 10:28 PM, Yuanchen Zhu <yuanchen.zhu@xxxxxxxxx> wrote:
FYI I've updated the wiki page:
- describe the predicate syntax for boudns
- clean up the seq vs seqX vs expr table
   + merge seq and seqn column
   + rename aseqXXX to seqXXX
   + added a predicate syntax column
- added some altenrative to fix<N>: int_, int_c, integral_c (used by MPL and hana)

Thanks. For the record, regarding your question on -Iota:

YZ: Regarding _expression_ A(2*-Iota), This is fishy, Iota means (0, 1, ...) but -Iota means (last, last-1, last-2, ...)? 
GG: Not at all, Iota means (.... -2 -1 0 1 2 ...) and -Iota means (... 2 1 0 -1 -2 ...) --> we should really rename Iota to something meaning any i in N, (N=set of natural integers)

​okay.... Iota is a terrible name then.​..
 

Then to comment on your predicate suggestion, using operator| to mimic s.t. is interesting. But I could advance the same argument as yours to rule it out: I would expect "vec | b" to apply the bitmask b to each element of vec. Actually,

Wait I am not sure I get you. So vec is vector of ints. Do you mean b as a vector of boolean, or just an int, or a single boolean? The filter and predicate syntax is only meaningful when b is conceptually a unary function from int to bool, i.e., 

vec<int> | vec<bool> = undefined, unless you auto cast bool to int

vec<int> | bool = undefined, uless you auto cast bool to int. Also maybe defined if you relax filter predicate to work on nullnary functions, i.e., constants, but that's kind of pointless.

vec<int> | int  = vec<int> with all elements or'ed with the int

vec<int> | int->bool function = filtered vec<int> 
 
bitmasking the infinite sequence produced by Iota or some transformations of Iota might even find real applications. I also found that the need to introduce an arbitrary place holder or countless functions (?bound, le, lt, ge, gt...) is kind of detrimental to the legibility.
 
gael



On Fri, Jan 6, 2017 at 8:42 AM, Yuanchen Zhu <yuanchen.zhu@xxxxxxxxx> wrote:

the new sequence. However, with proper overloads, we can recognize expressions such as "10 <= _1 < n" as bounding predicate. Any arithmetic progression filtered by a bounding predicate will simply return another arithmetic progression.

​Actually I just realized that "10 <= _1 < n"​ is really syntax abuse in C++, as operator "<=" returns a bool and it does not make sense to compare a bool with a number using "<" (unless you case the bool to an int, which is what will happen in practice if you write something like 10 < x <= 100, which always returns true). The fact that it's doable doesn't mean we should do it. It should really be just 

10 <= _1 && _1 < n

or just

bound(10, n-1)

Unfortunately, "&&" has a lower precedence than "|", so we can either write

(A) a + iota * s | (10 <= _1 && _1 < n)
(B) a + iota * s | 10 <= _1 | _1 < n

Or overload "||" instead

(C) ​a + iota * s || 10 <= _1 && _1 < n

I think (A) and (B) both look fine to me, and (C) looks strange.

Actually using explicit bound functions has the benefit that you no longer need fixed<C>, i.e.:

aseq(a, 10, s) =  a + iota * s | _1 <= fixed<10> 
aseq(a, 10, s) =  a + iota * s | ubound<10>








Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/