[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
They also show that having both a end and last "keyword" might be handy,
but not mandatory.
Finally, these examples also reveal that the "expression-based" API
outperforms all other alternatives, in all cases. For instance, can you
guess the intent from the following python code:
A[:-(k-1)*s-2:-s] ?????
compared to:
A(last-iota(k)*s)
??
The solution is: "pick k elements from the last one with step s in
descending order".
For the record, the aseq-based version is:
A(aseq(last,last-(k-1)*s,-s))
that I found a little clearer than python because it's clear that we start
from the last, compared to "A[:" that suggests you start from the begin
until you see that the increment is negative... and there isn't this
cryptic "-2" offset to get an exclusive upper-bound.
gael
On Thu, Jan 5, 2017 at 10:02 AM, Gael Guennebaud <gael.guennebaud@xxxxxxxxx>
wrote:
>
>
> On Wed, Jan 4, 2017 at 7:21 PM, Yuanchen Zhu <yuanchen.zhu@xxxxxxxxx>
> wrote:
>
>>
>>>> yes, my favorites so far are: ic<N>, fix<N>, fixed<N>
>>>
>>
>> There is a std::fixed, so fixed<N> is probably not good.
>>
>
> std::fixed is completely different (not a function, completely different
> semantic and context), so I don't think that's a concern.
>
>
>> I personally find ic<N> too obscure. I would never be able to guess its
>> meaning.
>>
>
> Sure, you need to look up the doc at least once.
>
> Regarding fix<N>, I think that 3 characters is short enough to not make
> too distracting, though using a transitive verb here is a bit borderline.
>
>
>> BTW, regarding inclusive vs exclusive upper bound, python's users seem to
>>> have several arguments, all grounded on the zero-based indexing thing:
>>> http://stackoverflow.com/questions/11364533/why-are-s
>>> lice-and-range-upper-bound-exclusive.
>>>
>>>
>> I think half-open interval is very reasonable and conceptually clean with
>> positive strides, but can get confusing with negative strides. For example,
>> to express (n-1, ..., 0), aseq(n-1, -1, -1) looks really strange. With
>> python you cannot even write A[n-1:-1:-1] since -1 is interpreted as n-1,
>> so you write A[n-1::-1] instead, which does not fly with the notion of aseq
>> defining a vector by itself.
>>
>
> Using negative indices to index from the end is not an option for us, for
> at three reasons:
> 1) in python your saved because you can (and sometimes have too) omit the
> bounds. You provided one example, another simpler one with incr==1 is to
> get the last k elements in ascending order, you have to write: A[-k:], you
> cannot write: A[-k:-1+1],though in python -1 means last. In contrast,
> A[-k:last+1] would be fine.
> 2) we need to known this information at compile-time, we don't want to
> branch at runtime!
> 3) outside the indexing context, qseq(-4,-1)==[-4,-3,-2,-1] is what we
> want.
>
>
>> But then again, aseq cannot stand on its own if we allow the "last"
>> literal: what exactly is aseq(0, last)?
>>
>
> same for matlab colon syntax, compilation error. Negative indices, rev(),
> or whatever else won't save you here.
>
>
>> At this point of discussion, maybe we need to think more carefully about
>> handling indexing relative to end. Here're some not very well-thought out
>> ideas:
>>
>
>> 1. Have a "last" literal, and overload the shit out of its relevant
>> arithmetic. This is a lot of work, and breaks as soon as an unsuspecting
>> user invokes a function on "last". This is in the wiki.
>>
>> 2. Allow negative indices like python, so all indices are understood to
>> be (mod size)?
>>
>
> not an option.
>
>
>> 3. Similar to 2, but use a special "rev" mark to indicate the an index is
>> taken with respect to end, e.g., A(aseq(0, rev(0))); A(aseq(0, rev(some
>> complex computation)));
>>
>
> not as flexible/extensible as last, for instance with some work we could
> allow last/2
>
>
>> 4: Differentiate between a forward aseq and backward aseq, i.e., A(seq(0,
>> n-1)) gives A[0, ..., n-1], and A(rseq(n-1, 0)) gives A[n-1, ... 0]
>>
>
> rseq is too confusing regarding parameter orders, on the other hand,
> reverse( aseq(i,j) ) would be fine, and we already have a reverse
> expression in Eigen.
>
> Also recall that indexing from the end and negative increment are
> orthogonal, so we have to consider all 4 cases.
>
> gael
>
>
>>
>>
>>>
>>> gael
>>>
>>>
>>>
>>
>
--f403045daa429c008c054556e6ad
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div>I added a list of examples comparing aseq (inclus=
ive), aseqn, a aseqX version with exclusive upper-bound, python, and the ex=
perimental "expression-based" API:</div><div><br></div><div><a hr=
ef=3D"http://eigen.tuxfamily.org/index.php?title=3DWorking_notes_-_Indexing=
%2B%2B#Q:_Inclusive_vs_exclusive.3F">http://eigen.tuxfamily.org/index.php?t=
itle=3DWorking_notes_-_Indexing%2B%2B#Q:_Inclusive_vs_exclusive.3F</a></div=
><div><br></div><div>From these examples, having aseq inclusive still seems=
to be more handy, and the size-based aseqn function is still there for som=
e simple cases for which an exclusive upper-bound is more handy.</div><div>=
<br></div><div>They also show that having both a end and last "keyword=
" might be handy, but not mandatory.</div><div><br></div><div>Finally,=
these examples also reveal that the "expression-based" API outpe=
rforms all other alternatives, in all cases. For instance, can you guess th=
e intent from the following python code:</div><div><br></div><div>A[:-(k-1)=
*s-2:-s]<span class=3D"gmail-Apple-tab-span" style=3D"white-space:pre"> ???=
??</span></div><div><br></div><div>compared to:</div><div><br></div><div>A(=
last-iota(k)*s)<br></div><div><br></div><div>??</div><div><br></div><div>Th=
e solution is: "pick k elements from the last one with step s in desce=
nding order".</div><div><br></div><div>For the record, the aseq-based =
version is:</div><div><br></div><div>A(aseq(last,last-(k-1)*s,-s))<br></div=
><div><br></div><div>that I found a little clearer than python because it&#=
39;s clear that we start from the last, compared to "A[:" that su=
ggests you start from the begin until you see that the increment is negativ=
e... and there isn't this cryptic "-2" offset to get an exclu=
sive upper-bound.</div><div><br></div><div>gael</div><div><br></div></div><=
div class=3D"gmail_extra"><br><div class=3D"gmail_quote">On Thu, Jan 5, 201=
7 at 10:02 AM, Gael Guennebaud <span dir=3D"ltr"><<a href=3D"mailto:gael=
..guennebaud@xxxxxxxxx" target=3D"_blank">gael.guennebaud@xxxxxxxxx</a>><=
/span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><div c=
lass=3D"gmail_extra"><br><div class=3D"gmail_quote"><span class=3D"">On Wed=
, Jan 4, 2017 at 7:21 PM, Yuanchen Zhu <span dir=3D"ltr"><<a href=3D"mai=
lto:yuanchen.zhu@xxxxxxxxx" target=3D"_blank">yuanchen.zhu@xxxxxxxxx</a>>=
;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0p=
x 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div d=
ir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><span clas=
s=3D"m_-5536668234787999244gmail-"><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding=
-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_=
quote"><span class=3D"m_-5536668234787999244gmail-m_7209921063649064802gmai=
l-m_1731634635769892246gmail-"><blockquote class=3D"gmail_quote" style=3D"m=
argin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left=
:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote=
"><span class=3D"m_-5536668234787999244gmail-m_7209921063649064802gmail-m_1=
731634635769892246gmail-m_5771676892524027818gmail-"><br></span></div></div=
></div></blockquote></span><div>yes, my favorites so far are: ic<N>, =
fix<N>, fixed<N></div></div></div></div></blockquote><div><br><=
/div></span><div><div style=3D"font-family:georgia,serif">There is a std::f=
ixed, so fixed<N> is probably not good.</div></div></div></div></div>=
</blockquote><div><br></div></span><div>std::fixed is completely different =
(not a function, completely different semantic and context), so I don't=
think that's a concern.</div><span class=3D""><div>=C2=A0</div><blockq=
uote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1p=
x solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div class=3D"g=
mail_extra"><div class=3D"gmail_quote"><div><div style=3D"font-family:georg=
ia,serif">I personally find ic<N> too obscure. I would never be able =
to guess its meaning.</div></div></div></div></div></blockquote><div><br></=
div></span><div>Sure, you need to look up the doc at least once.</div><div>=
<br></div><div>Regarding fix<N>, I think that 3 characters is short e=
nough to not make too distracting, though using a transitive verb here is a=
bit borderline.</div><span class=3D""><div>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rg=
b(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra=
"><div class=3D"gmail_quote"><span class=3D"m_-5536668234787999244gmail-"><=
blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-l=
eft:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div clas=
s=3D"gmail_extra"><div class=3D"gmail_quote"><div>BTW, regarding inclusive =
vs exclusive upper bound, python's users seem to have several arguments=
, all grounded on the zero-based indexing thing:=C2=A0<a href=3D"http://sta=
ckoverflow.com/questions/11364533/why-are-slice-and-range-upper-bound-exclu=
sive" target=3D"_blank">http://stackoverflow.co<wbr>m/questions/11364533/wh=
y-are-s<wbr>lice-and-range-upper-bound-exc<wbr>lusive</a>.</div><span class=
=3D"m_-5536668234787999244gmail-m_7209921063649064802gmail-m_17316346357698=
92246gmail-HOEnZb"><font color=3D"#888888"><div><br></div></font></span></d=
iv></div></div></blockquote><div style=3D"font-family:georgia,serif"><br></=
div></span><div style=3D"font-family:georgia,serif">I think half-open inter=
val is very reasonable and conceptually clean with positive strides, but ca=
n get confusing with negative strides. For example, to express (n-1, ..., 0=
), =C2=A0aseq(n-1, -1, -1) looks really strange. With python you cannot eve=
n write A[n-1:-1:-1] since -1 is interpreted as n-1, so you write A[n-1::-1=
] instead, which does not fly with the notion of aseq defining a vector by =
itself. </div></div></div></div></blockquote><div><br></div></span><div><di=
v>Using negative indices to index from the end is not an option for us, for=
at three reasons:</div><div>1) in python your saved because you can (and s=
ometimes have too) omit the bounds. You provided one example, another simpl=
er one with incr=3D=3D1 is to get the last k elements in ascending order, y=
ou have to write: A[-k:], you cannot write: A[-k:-1+1],though in python -1 =
means last. In contrast, A[-k:last+1] would be fine.</div><div>2) we need t=
o known this information at compile-time, we don't want to branch at ru=
ntime!</div><div>3) outside the indexing context, qseq(-4,-1)=3D=3D[-4,-3,-=
2,-1] is what we want.</div></div><span class=3D""><div>=C2=A0</div><blockq=
uote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1p=
x solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div class=3D"g=
mail_extra"><div class=3D"gmail_quote"><div style=3D"font-family:georgia,se=
rif">But then again, aseq cannot stand on its own if we allow the "las=
t" literal: what exactly is aseq(0, last)?</div></div></div></div></bl=
ockquote><div><br></div></span><div>same for matlab colon syntax, compilati=
on error. Negative indices, rev(), or whatever else won't save you here=
..</div><span class=3D""><div>=C2=A0</div><blockquote class=3D"gmail_quote" =
style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);pa=
dding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"g=
mail_quote"><div style=3D"font-family:georgia,serif">At this point of discu=
ssion, maybe we need to think more carefully about handling indexing relati=
ve to end. Here're some not very well-thought out ideas:=C2=A0<span sty=
le=3D"font-family:arial,sans-serif">=C2=A0</span></div></div></div></div></=
blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.=
8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"lt=
r"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div style=3D"font=
-family:georgia,serif"><br></div><div style=3D"font-family:georgia,serif">1=
.. Have a "last" literal, and overload the shit out of its relevan=
t arithmetic. This is a lot of work, and breaks as soon as an unsuspecting =
user invokes a function on "last".=C2=A0 This is in the wiki.</di=
v><div style=3D"font-family:georgia,serif"><br></div><div style=3D"font-fam=
ily:georgia,serif">2. Allow negative indices like python, so all indices ar=
e understood to be (mod size)?</div></div></div></div></blockquote><div><br=
></div></span><div>not an option.</div><span class=3D""><div>=C2=A0</div><b=
lockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-le=
ft:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div class=
=3D"gmail_extra"><div class=3D"gmail_quote"><div style=3D"font-family:georg=
ia,serif">3. Similar to 2, but use a special "rev" mark to indica=
te the an index is taken with respect to end, e.g.,=C2=A0<span style=3D"fon=
t-family:monospace,monospace">A(aseq(0, rev(0))); A(aseq(0, rev(some comple=
x computation)));</span></div></div></div></div></blockquote><div><br></div=
></span><div>not as flexible/extensible as last, for instance with some wor=
k we could allow last/2</div><span class=3D""><div>=C2=A0</div><blockquote =
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px sol=
id rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_=
extra"><div class=3D"gmail_quote"><div><font face=3D"georgia, serif">4: Dif=
ferentiate between a forward aseq and backward aseq, i.e.,</font><font face=
=3D"georgia, serif">=C2=A0</font><font face=3D"monospace, monospace">A(seq(=
0, n-1))</font><font face=3D"georgia, serif"> gives </font><font face=3D"mo=
nospace, monospace">A[0, ..., n-1]</font><font face=3D"georgia, serif">, an=
d =C2=A0</font><font face=3D"monospace, monospace">A(rseq(n-1, 0))</font><f=
ont face=3D"georgia, serif"> gives </font><font face=3D"monospace, monospac=
e">A[n-1, ... 0]</font></div></div></div></div></blockquote><div><br></div>=
</span><div>rseq is too confusing regarding parameter orders, on the other =
hand, reverse( aseq(i,j) ) would be fine, and we already have a reverse exp=
ression in Eigen.</div><div><br></div><div>Also recall that indexing from t=
he end and negative increment are orthogonal, so we have to consider all 4 =
cases.</div><div><br></div><div>gael</div><div>=C2=A0</div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid r=
gb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extr=
a"><div class=3D"gmail_quote"><div>=C2=A0<br></div><blockquote class=3D"gma=
il_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,2=
04,204);padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div =
class=3D"gmail_quote"><span class=3D"m_-5536668234787999244gmail-m_72099210=
63649064802gmail-m_1731634635769892246gmail-HOEnZb"><font color=3D"#888888"=
><div></div><div><br></div><div>gael</div><div>=C2=A0</div></font></span></=
div><br></div></div>
</blockquote></div><br></div></div>
</blockquote></div><br></div></div>
</blockquote></div><br></div>
--f403045daa429c008c054556e6ad--