Topic: Linked std::table / std::matrix proposal
Author: allsey87@gmail.com
Date: Fri, 15 Apr 2016 03:25:07 -0700 (PDT)
Raw View
------=_Part_7793_452750975.1460715907154
Content-Type: multipart/alternative;
boundary="----=_Part_7794_421738122.1460715907154"
------=_Part_7794_421738122.1460715907154
Content-Type: text/plain; charset=UTF-8
Hi Everyone,
I'm considering implementing a new container called either std::table or
std::matrix. The data structure would be similar to std::list as elements
would be linked together through pointers/iterators. The aim of this data
structure is *not* to create a high performance matrix, that tries to solve
every single problem. There are always trade-offs in the design of
matrices, and for high performance situations it is probably better to use,
for example in computer vision, opencv's Mat class. Keeping this in mind,
conceptually the table/matrix I propose would like this:
| std::begin(col) | std::begin(col) |
| --------------- | --------------- | --------------- | ------------- |
| std::begin(row) | element 0,0 | element 0,1 | std::end(row) |
| std::begin(row) | element 1,0 | element 1,1 | std::end(row) |
| std::begin(row) | element 2,0 | element 2,1 | std::end(row) |
| --------------- | --------------- | --------------- | ------------- |
| std::end(col) | std::end(col) |
In this design, two bidirectional (or forward) iterators are kept in each
element for iterating across the rows and columns. I would imagine similar
to a std::list, that this would enable to removing/adding of rows/columns
without invalidating other row/column/element iterators, and also avoid the
moving elements.
The motivation for using this layout over a std::vector<std::vector<double>
> (and it's cousins) is that vector inside a vector implementation is
unsafe and bug prone. I have just written the code for removing/adding
rows/columns and while it is ok for the first dimension, working in the
second dimension is painful. Not to mention, one has to constantly check if
the table/matrix is well formed (i.e. equal number of elements in each
row/column)
The aim of this container would be to represent graphs, tables, and small
to medium size matrices. I would like to also draw attention to the point,
that although syntax to access matrix elements in most libraries often
appears as either my_matrix.at(2,3) or my_matrix[2][3], the actual access
to the data is not often random, but rather linear across a given column or
row (consider matrix multiplication). Furthermore, assuming all memory for
the matrix is allocated once dynamically in the constructor, the
performance for doing e.g. multiplication of two matrices would be
reasonable since all elements should make there way into the higher levels
of the cache after the first miss.
From a user stand point, I would like the following sorts of operations to
be possible:
/* 1. construction / use of initialization list */
std::table<double> my_table(3,2) = {
11, 12,
21, 22,
31, 32
};
std::cout << my_table.size(); // 6
// element-wise iteration - important notes 1. random access iterators not
supported, 2. individual elements can not be erased
for(auto el : my_table) {
std::cout << el << std::end;
}
// or
for(auto it_el = std::begin(my_table); it_el != std::end(my_table);
it_el++) {
std::cout << *it_el << std::end;
}
/* 2. copy all values, column by column into a std::vector and set the
table to zero */
std::vector<double> vector_values;
for(const auto& col : my_table.get_cols()) {
vector_values.insert(std::end(vector_values), std::begin(col),
std::end(col));
}
/* 3. set all elements to forty two */
for(auto& row : my_table.get_rows()) {
for(auto& el : row) {
el = 42.0f;
}
}
/* 4. insert elements from a list or vector */
// the type of iterator returned from std::end(my_table.get_rows()) or
std::end(my_table.get_cols()) determines the orientation */
std::list<double> list_values = {
42, 21;
};
// may throw exception if dimension mismatch, or alternatively
truncate/default construct missing elements */
my_table.insert(std::end(my_table.get_rows()), std::begin(list_values),
std::end(list_values));
/* 5. algorithms / erase-remove idiom applied to columns */
// note since we work with columns and rows in matrices, remove(_if) is
extended to remove(_if)_any, remove(_if)_all, remove_if_none
my_table.erase( std::remove_if_none( std::begin(my_table.get_cols()),
std::begin(my_table.get_cols()), [] (double el) { return (el == 42);} ),
std::end(my_table.get_cols));
/* 6. add row at beginning of table */
my_table.add_row(std::begin(my_table.get_rows()));
Any thoughts or counter proposals? Reasons why this is a bad idea?
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/ed043832-6d07-4f29-9de1-c140d2075d84%40isocpp.org.
------=_Part_7794_421738122.1460715907154
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><span style=3D"font-family: courier new,monospace;">Hi Eve=
ryone,<br><br></span><span style=3D"font-family: courier new,monospace;">I&=
#39;m considering implementing a new container called either std::table or =
std::matrix. The data structure would be similar to std::list as elements w=
ould be linked together through pointers/iterators. The aim of this data st=
ructure is *not* to create a high performance matrix, that tries to solve e=
very single problem. There are always trade-offs in the design of matrices,=
and for high performance situations it is probably better to use, for exam=
ple in computer vision, opencv's Mat class. Keeping this in mind, conce=
ptually the table/matrix I propose would like this:<br><br></span><br><pre>=
<code id=3D"output" data-bind=3D"text: output()"> | std::b=
egin(col) | std::begin(col) |
| --------------- | --------------- | --------------- | ------------- |
| std::begin(row) | element 0,0 | element 0,1 | std::end(row) |
| std::begin(row) | element 1,0 | element 1,1 | std::end(row) |
| std::begin(row) | element 2,0 | element 2,1 | std::end(row) |<br>=
</code><code id=3D"output" data-bind=3D"text: output()"><code id=3D"output"=
data-bind=3D"text: output()">| --------------- | --------------- | -------=
-------- | ------------- |<br></code> | std::end(col) | =
std::end(col) |</code></pre><span style=3D"font-family: courier new,monos=
pace;"><br></span><span style=3D"font-family: courier new,monospace;"><br>I=
n this design, two bidirectional (or forward) iterators are kept in each el=
ement for iterating across the rows and columns. I would imagine similar to=
a std::list, that this would enable to removing/adding of rows/columns wit=
hout invalidating other row/column/element iterators, and also avoid the mo=
ving elements.<br><br>The motivation for using this layout over a std::vect=
or<std::vector<double> > (and it's cousins) is that vector =
inside a vector implementation is unsafe and bug prone. I have just written=
the code for removing/adding rows/columns and while it is ok for the first=
dimension, working in the second dimension is painful. Not to mention, one=
has to constantly check if the table/matrix is well formed (i.e. equal num=
ber of elements in each row/column)<br><br>The aim of this container would =
be to r</span><span style=3D"font-family: courier new,monospace;"><span sty=
le=3D"font-family: courier new,monospace;">epresent graphs, tables, and sma=
ll to medium size matrices. I would like to also draw attention to the poin=
t, that although syntax to access matrix elements in most libraries often a=
ppears as either my_matrix.at(2,3) or my_matrix[2][3], the actual access to=
the data is not often random, but rather linear across a given column or r=
ow (consider matrix multiplication). Furthermore, assuming all memory for t=
he matrix is allocated once dynamically in the constructor, the performance=
for doing e.g. multiplication of two matrices would be reasonable since al=
l elements should make there way into the higher levels of the cache after =
the first miss.<br><br></span>From a user stand point, I would like the fol=
lowing sorts of operations to be possible:<br></span><span style=3D"font-fa=
mily: courier new,monospace;"><br>/* 1. construction / use of initializatio=
n list */<br>std::table<double> my_table(3,2) =3D {<br>=C2=A0=C2=A0 1=
1, 12,<br>=C2=A0=C2=A0 21, 22,<br>=C2=A0=C2=A0 31, 32<br>};<br><br>std::cou=
t << my_table.size(); // 6<br><br>// element-wise iteration - importa=
nt notes 1. random access iterators not supported, 2. individual elements c=
an not be erased<br>for(auto el : my_table) {<br>=C2=A0=C2=A0 std::cout <=
;< el << std::end;<br>}<br>// or<br>for(auto it_el =3D std::begin(=
my_table); it_el !=3D std::end(my_table); it_el++) {<br>=C2=A0=C2=A0 std::c=
out << *it_el << std::end;<br>}<br><br>/* 2. copy all values, c=
olumn by column into a std::vector and set the table to zero */<br>std::vec=
tor<double> vector_values;<br><br>for(const auto& col : my_table.=
get_cols()) {<br>=C2=A0=C2=A0 vector_values.insert(std::end(vector_values),=
std::begin(col), std::end(col));<br>}<br><br>/* 3. set all elements to for=
ty two */<br>for(auto& row : my_table.get_rows()) {<br>=C2=A0=C2=A0 for=
(auto& el : row) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 el =3D 42.0f;<br>=
=C2=A0=C2=A0 }<br>}<br><br>/* 4. insert elements from a list or vector */<b=
r>// the type of iterator returned from std::end(my_table.get_rows()) or st=
d::end(my_table.get_cols()) determines the orientation */<br>std::list<d=
ouble> list_values =3D {<br>=C2=A0=C2=A0 42, 21;<br>};<br>// may throw e=
xception if dimension mismatch, or alternatively truncate/default construct=
missing elements */<br>my_table.insert(std::end(my_table.get_rows()), std:=
:begin(list_values), std::end(list_values));<br><br>/* 5. algorithms / eras=
e-remove idiom applied to columns */<br>// note since we work with columns =
and rows in matrices, remove(_if) is extended to=C2=A0 remove(_if)_any, rem=
ove(_if)_all, remove_if_none<br><br>my_table.erase( std::remove_if_none( st=
d::begin(my_table.get_cols()), std::begin(my_table.get_cols()), [] (double =
el) { return (el =3D=3D 42);} ), std::end(my_table.get_cols));<br><br>/* 6.=
add row at beginning of table */<br>my_table.add_row(std::begin(my_table.g=
et_rows()));<br><br>Any thoughts or counter proposals? Reasons why this is =
a bad idea?<br><br></span></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/ed043832-6d07-4f29-9de1-c140d2075d84%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ed043832-6d07-4f29-9de1-c140d2075d84=
%40isocpp.org</a>.<br />
------=_Part_7794_421738122.1460715907154--
------=_Part_7793_452750975.1460715907154--
.
Author: allsey87@gmail.com
Date: Fri, 15 Apr 2016 03:38:01 -0700 (PDT)
Raw View
------=_Part_173_429122520.1460716681086
Content-Type: multipart/alternative;
boundary="----=_Part_174_366742493.1460716681087"
------=_Part_174_366742493.1460716681087
Content-Type: text/plain; charset=UTF-8
Hi Everyone,
I'm considering implementing a new container called either std::table or
std::matrix. The data structure would be similar to std::list as elements
would be linked together through pointers/iterators. The aim of this data
structure is *not* to create a high performance matrix, that tries to solve
every single problem. There are always trade-offs in the design of
matrices, and for high performance situations, it is probably better to
use, e.g. in computer vision, opencv's Mat class. Keeping this in mind,
conceptually the table/matrix that I am proposing would like this:
| std::begin(col) | std::begin(col) |
| --------------- | --------------- | --------------- | ------------- |
| std::begin(row) | element 0,0 | element 0,1 | std::end(row) |
| std::begin(row) | element 1,0 | element 1,1 | std::end(row) |
| std::begin(row) | element 2,0 | element 2,1 | std::end(row) |
| --------------- | --------------- | --------------- | ------------- |
| std::end(col) | std::end(col) |
In this design, two bidirectional (or forward) iterators are kept in each
element for iterating across the rows and columns. I would imagine similar
to a std::list, that this would enable the removing/adding of rows/columns
without invalidating other row/column/element iterators, and also avoid
moving all elements when a row/column is deleted.
The motivation for using this layout over a std::vector<std::vector<double>
> (vector inside a vector) is that the vector inside a vector approach can
be unsafe and prone to bugs. I have just written the code for
removing/adding rows/columns for the vector inside a vector approach, and
while it is ok for the first dimension, working in the second dimension is
painful. Not to mention, one has to constantly check if the table/matrix is
well formed (i.e. equal number of elements in each row/column)
The aim of this container would be to represent graphs, tables, and small
to medium size matrices. I would like to also draw attention to the fact,
that although syntax to access matrix elements in most libraries often
appears as either my_matrix.at(2,3) or my_matrix[2][3], the actual access
to the data is not often random, but rather linear across a given column or
row (consider matrix multiplication). Furthermore, assuming all memory for
the matrix is allocated once dynamically in the constructor, the
performance for doing e.g. multiplication of two matrices would be
reasonable since all elements should make there way into the higher levels
of the cache after the first miss.
From a user stand point, I would like the following sorts of operations to
be possible:
/* 1. construction / use of initialization list */
std::table<double> my_table(3,2) = {
11, 12,
21, 22,
31, 32
};
std::cout << my_table.size(); // 6
// element-wise iteration - important notes 1. random access iterators not
supported, 2. individual elements can not be erased
for(auto el : my_table) {
std::cout << el << std::end;
}
// or
for(auto it_el = std::begin(my_table); it_el != std::end(my_table);
it_el++) {
std::cout << *it_el << std::end;
}
/* 2. copy all values, column by column into a std::vector */
std::vector<double> vector_values;
for(const auto& col : my_table.get_cols()) {
vector_values.insert(std::end(vector_values), std::begin(col),
std::end(col));
}
/* 3. set all elements to forty two */
for(auto& row : my_table.get_rows()) {
for(auto& el : row) {
el = 42.0f;
}
}
/* 4. insert elements from a list or vector */
// the type of iterator returned from std::end(my_table.get_rows()) or
std::end(my_table.get_cols()) determines the orientation */
std::list<double> list_values = {
42, 21;
};
// may throw exception if dimension mismatch, or alternatively
truncate/default construct missing elements */
my_table.insert(std::end(my_table.get_rows()), std::begin(list_values),
std::end(list_values));
/* 5. algorithms / erase-remove idiom applied to columns */
// note since we work with columns and rows in matrices, remove(_if) is
extended to remove(_if)_any, remove(_if)_all, remove_if_none
my_table.erase( std::remove_if_none( std::begin(my_table.get_cols()),
std::begin(my_table.get_cols()), [] (double el) { return (el == 42);} ),
std::end(my_table.get_cols));
/* 6. add row at beginning of table */
my_table.add_row(std::begin(my_table.get_rows()));
Any thoughts or counter proposals? Reasons why this is a bad idea?
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/df7aa05f-abaa-47bc-8946-86e7817e4a63%40isocpp.org.
------=_Part_174_366742493.1460716681087
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><span style=3D"font-family: courier new,monospace;">Hi Eve=
ryone,<br><br>I'm considering implementing a new container called eithe=
r std::table or std::matrix. The data structure would be similar to std::li=
st as elements would be linked together through pointers/iterators. The aim=
of this data structure is *not* to create a high performance matrix, that =
tries to solve every single problem. There are always trade-offs in the des=
ign of matrices, and for high performance situations, it is probably better=
to use, e.g. in computer vision, opencv's Mat class. Keeping this in m=
ind, conceptually the table/matrix that I am proposing would like this:<br>=
<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | std::begin(col) | std::begin(col) |<=
br>| --------------- | --------------- | --------------- | ------------- |<=
br>| std::begin(row) | element 0,0=C2=A0=C2=A0=C2=A0=C2=A0 | element 0,1=C2=
=A0=C2=A0=C2=A0=C2=A0 | std::end(row) |<br>| std::begin(row) | element 1,0=
=C2=A0=C2=A0=C2=A0=C2=A0 | element 1,1=C2=A0=C2=A0=C2=A0=C2=A0 | std::end(r=
ow) |<br>| std::begin(row) | element 2,0=C2=A0=C2=A0=C2=A0=C2=A0 | element =
2,1=C2=A0=C2=A0=C2=A0=C2=A0 | std::end(row) |<br>| --------------- | ------=
--------- | --------------- | ------------- |<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 | std::end(col)=C2=A0=C2=A0 | std::end(col)=C2=A0=C2=A0 |<br><br><br>In=
this design, two bidirectional (or forward) iterators are kept in each ele=
ment for iterating across the rows and columns. I would imagine similar to =
a std::list, that this would enable the removing/adding of rows/columns wit=
hout invalidating other row/column/element iterators, and also avoid moving=
all elements when a row/column is deleted.<br><br>The motivation for using=
this layout over a std::vector<std::vector<double> > (vector i=
nside a vector) is that the vector inside a vector approach can be unsafe a=
nd prone to bugs. I have just written the code for removing/adding rows/col=
umns for the vector inside a vector approach, and while it is ok for the fi=
rst dimension, working in the second dimension is painful. Not to mention, =
one has to constantly check if the table/matrix is well formed (i.e. equal =
number of elements in each row/column)<br><br>The aim of this container wou=
ld be to represent graphs, tables, and small to medium size matrices. I wou=
ld like to also draw attention to the fact, that although syntax to access =
matrix elements in most libraries often appears as either my_matrix.at(2,3)=
or my_matrix[2][3], the actual access to the data is not often random, but=
rather linear across a given column or row (consider matrix multiplication=
). Furthermore, assuming all memory for the matrix is allocated once dynami=
cally in the constructor, the performance for doing e.g. multiplication of =
two matrices would be reasonable since all elements should make there way i=
nto the higher levels of the cache after the first miss.<br><br>From a user=
stand point, I would like the following sorts of operations to be possible=
:<br><br>/* 1. construction / use of initialization list */<br>std::table&l=
t;double> my_table(3,2) =3D {<br>=C2=A0=C2=A0 11, 12,<br>=C2=A0=C2=A0 21=
, 22,<br>=C2=A0=C2=A0 31, 32<br>};<br><br>std::cout << my_table.size(=
); // 6<br><br>// element-wise iteration - important notes 1. random access=
iterators not supported, 2. individual elements can not be erased<br>for(a=
uto el : my_table) {<br>=C2=A0=C2=A0 std::cout << el << std::en=
d;<br>}<br>// or<br>for(auto it_el =3D std::begin(my_table); it_el !=3D std=
::end(my_table); it_el++) {<br>=C2=A0=C2=A0 std::cout << *it_el <&=
lt; std::end;<br>}<br><br>/* 2. copy all values, column by column into a st=
d::vector */<br>std::vector<double> vector_values;<br><br>for(const a=
uto& col : my_table.get_cols()) {<br>=C2=A0=C2=A0 vector_values.insert(=
std::end(vector_values), std::begin(col), std::end(col));<br>}<br><br>/* 3.=
set all elements to forty two */<br>for(auto& row : my_table.get_rows(=
)) {<br>=C2=A0=C2=A0 for(auto& el : row) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 el =3D 42.0f;<br>=C2=A0=C2=A0 }<br>}<br><br>/* 4. insert elements fr=
om a list or vector */<br>// the type of iterator returned from std::end(my=
_table.get_rows()) or std::end(my_table.get_cols()) determines the orientat=
ion */<br>std::list<double> list_values =3D {<br>=C2=A0=C2=A0 42, 21;=
<br>};<br>// may throw exception if dimension mismatch, or alternatively tr=
uncate/default construct missing elements */<br>my_table.insert(std::end(my=
_table.get_rows()), std::begin(list_values), std::end(list_values));<br><br=
>/* 5. algorithms / erase-remove idiom applied to columns */<br>// note sin=
ce we work with columns and rows in matrices, remove(_if) is extended to=C2=
=A0 remove(_if)_any, remove(_if)_all, remove_if_none<br><br>my_table.erase(=
std::remove_if_none( std::begin(my_table.get_cols()), std::begin(my_table.=
get_cols()), [] (double el) { return (el =3D=3D 42);} ), std::end(my_table.=
get_cols));<br><br>/* 6. add row at beginning of table */<br>my_table.add_r=
ow(std::begin(my_table.get_rows()));<br><br>Any thoughts or counter proposa=
ls? Reasons why this is a bad idea?<br><br><br></span></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/df7aa05f-abaa-47bc-8946-86e7817e4a63%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/df7aa05f-abaa-47bc-8946-86e7817e4a63=
%40isocpp.org</a>.<br />
------=_Part_174_366742493.1460716681087--
------=_Part_173_429122520.1460716681086--
.
Author: Tony V E <tvaneerd@gmail.com>
Date: Fri, 15 Apr 2016 20:54:25 -0400
Raw View
<html><head></head><body lang=3D"en-US" style=3D"background-color: rgb(255,=
255, 255); line-height: initial;"> =
<div style=3D"width: 100%; fo=
nt-size: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif=
; color: rgb(31, 73, 125); text-align: initial; background-color: rgb(255, =
255, 255);">- I think table is a better name than matrix. Matrix assumes nu=
mbers and operators, etc. Table is just a container. </div><div style=
=3D"width: 100%; font-size: initial; font-family: Calibri, 'Slate Pro', san=
s-serif, sans-serif; color: rgb(31, 73, 125); text-align: initial; backgrou=
nd-color: rgb(255, 255, 255);"><br></div><div style=3D"width: 100%; font-si=
ze: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; col=
or: rgb(31, 73, 125); text-align: initial; background-color: rgb(255, 255, =
255);">- I would hope that the specification wouldn't rule out vector-of-ve=
ctor implementations. ie I'd rather have that than iterators that don't inv=
alidate. But that's just my opinion. </div><div style=3D"width: 100%;=
font-size: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-se=
rif; color: rgb(31, 73, 125); text-align: initial; background-color: rgb(25=
5, 255, 255);"><br></div><div style=3D"width: 100%; font-size: initial; fon=
t-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, =
125); text-align: initial; background-color: rgb(255, 255, 255);">- overall=
, not a bad idea. Might be hard to get consensus, as everyone will have the=
ir own requests. Might be better to start with boost?</div> =
=
<div style=3D"width: 100%; font-s=
ize: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; co=
lor: rgb(31, 73, 125); text-align: initial; background-color: rgb(255, 255,=
255);"><br style=3D"display:initial"></div> =
=
=
<div style=3D"font-size: initial; font-family: Calibri, 'Slat=
e Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: initia=
l; background-color: rgb(255, 255, 255);">Sent from my Black=
Berry portable Babbage Device</div> =
=
=
<table width=3D"100%" style=3D"background-color:white;border-spacing:0px=
;"> <tbody><tr><td colspan=3D"2" style=3D"font-size: initial; text-align: i=
nitial; background-color: rgb(255, 255, 255);"> <=
div style=3D"border-style: solid none none; border-top-color: rgb(181, 196,=
223); border-top-width: 1pt; padding: 3pt 0in 0in; font-family: Tahoma, 'B=
B Alpha Sans', 'Slate Pro'; font-size: 10pt;"> <div><b>From: </b>allsey87@=
gmail.com</div><div><b>Sent: </b>Friday, April 15, 2016 6:38 AM</div><div><=
b>To: </b>ISO C++ Standard - Future Proposals</div><div><b>Reply To: </b>st=
d-proposals@isocpp.org</div><div><b>Subject: </b>[std-proposals] Linked std=
::table / std::matrix proposal</div></div></td></tr></tbody></table><div st=
yle=3D"border-style: solid none none; border-top-color: rgb(186, 188, 209);=
border-top-width: 1pt; font-size: initial; text-align: initial; background=
-color: rgb(255, 255, 255);"></div><br><div id=3D"_originalContent" style=
=3D""><div dir=3D"ltr"><span style=3D"font-family: courier new,monospace;">=
Hi Everyone,<br><br>I'm considering implementing a new container called eit=
her std::table or std::matrix. The data structure would be similar to std::=
list as elements would be linked together through pointers/iterators. The a=
im of this data structure is *not* to create a high performance matrix, tha=
t tries to solve every single problem. There are always trade-offs in the d=
esign of matrices, and for high performance situations, it is probably bett=
er to use, e.g. in computer vision, opencv's Mat class. Keeping this in min=
d, conceptually the table/matrix that I am proposing would like this:<br><b=
r><br> &nb=
sp; | std::begin(col) | std::begin(col) |<br>=
| --------------- | --------------- | --------------- | ------------- |<br>=
| std::begin(row) | element 0,0 | element 0,1 =
| std::end(row) |<br>| std::begin(row) | element 1,0&nbs=
p; | element 1,1 | std::end(row) =
|<br>| std::begin(row) | element 2,0 | element 2,1&=
nbsp; | std::end(row) |<br>| --------------- | ----------=
----- | --------------- | ------------- |<br> =
| =
std::end(col) | std::end(col) |<br><br><br>In this =
design, two bidirectional (or forward) iterators are kept in each element f=
or iterating across the rows and columns. I would imagine similar to a std:=
:list, that this would enable the removing/adding of rows/columns without i=
nvalidating other row/column/element iterators, and also avoid moving all e=
lements when a row/column is deleted.<br><br>The motivation for using this =
layout over a std::vector<std::vector<double> > (vector inside =
a vector) is that the vector inside a vector approach can be unsafe and pro=
ne to bugs. I have just written the code for removing/adding rows/columns f=
or the vector inside a vector approach, and while it is ok for the first di=
mension, working in the second dimension is painful. Not to mention, one ha=
s to constantly check if the table/matrix is well formed (i.e. equal number=
of elements in each row/column)<br><br>The aim of this container would be =
to represent graphs, tables, and small to medium size matrices. I would lik=
e to also draw attention to the fact, that although syntax to access matrix=
elements in most libraries often appears as either my_matrix.at(2,3) or my=
_matrix[2][3], the actual access to the data is not often random, but rathe=
r linear across a given column or row (consider matrix multiplication). Fur=
thermore, assuming all memory for the matrix is allocated once dynamically =
in the constructor, the performance for doing e.g. multiplication of two ma=
trices would be reasonable since all elements should make there way into th=
e higher levels of the cache after the first miss.<br><br>From a user stand=
point, I would like the following sorts of operations to be possible:<br><=
br>/* 1. construction / use of initialization list */<br>std::table<doub=
le> my_table(3,2) =3D {<br> 11, 12,<br> 21, 22,<=
br> 31, 32<br>};<br><br>std::cout << my_table.size(); // =
6<br><br>// element-wise iteration - important notes 1. random access itera=
tors not supported, 2. individual elements can not be erased<br>for(auto el=
: my_table) {<br> std::cout << el << std::end;<br>=
}<br>// or<br>for(auto it_el =3D std::begin(my_table); it_el !=3D std::end(=
my_table); it_el++) {<br> std::cout << *it_el << st=
d::end;<br>}<br><br>/* 2. copy all values, column by column into a std::vec=
tor */<br>std::vector<double> vector_values;<br><br>for(const auto&am=
p; col : my_table.get_cols()) {<br> vector_values.insert(std::e=
nd(vector_values), std::begin(col), std::end(col));<br>}<br><br>/* 3. set a=
ll elements to forty two */<br>for(auto& row : my_table.get_rows()) {<b=
r> for(auto& el : row) {<br> =
el =3D 42.0f;<br> }<br>}<br><br>/* 4. insert elements from a li=
st or vector */<br>// the type of iterator returned from std::end(my_table.=
get_rows()) or std::end(my_table.get_cols()) determines the orientation */<=
br>std::list<double> list_values =3D {<br> 42, 21;<br>};<=
br>// may throw exception if dimension mismatch, or alternatively truncate/=
default construct missing elements */<br>my_table.insert(std::end(my_table.=
get_rows()), std::begin(list_values), std::end(list_values));<br><br>/* 5. =
algorithms / erase-remove idiom applied to columns */<br>// note since we w=
ork with columns and rows in matrices, remove(_if) is extended to rem=
ove(_if)_any, remove(_if)_all, remove_if_none<br><br>my_table.erase( std::r=
emove_if_none( std::begin(my_table.get_cols()), std::begin(my_table.get_col=
s()), [] (double el) { return (el =3D=3D 42);} ), std::end(my_table.get_col=
s));<br><br>/* 6. add row at beginning of table */<br>my_table.add_row(std:=
:begin(my_table.get_rows()));<br><br>Any thoughts or counter proposals? Rea=
sons why this is a bad idea?<br><br><br></span></div>
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/df7aa05f-abaa-47bc-8946-86e7817e4a63%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.goo=
gle.com/a/isocpp.org/d/msgid/std-proposals/df7aa05f-abaa-47bc-8946-86e7817e=
4a63%40isocpp.org</a>.<br>
<br><!--end of _originalContent --></div></body></html>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/20160416005425.4902992.3247.9842%40gm=
ail.com?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.com/a=
/isocpp.org/d/msgid/std-proposals/20160416005425.4902992.3247.9842%40gmail.=
com</a>.<br />
.
Author: Brent Friedman <fourthgeek@gmail.com>
Date: Fri, 15 Apr 2016 21:45:18 -0500
Raw View
--047d7b5d4a262cd7c00530911e7f
Content-Type: text/plain; charset=UTF-8
If the proposal is going to make any guarantees about iterator invalidation
or performance characteristics then you basically have to decide on
vector-of-vectors vs. lists.
My preference would be to call this something like list2d<T> if it's going
to use a linked list. Which raises questions about list3d, etc. A vector of
vectors implementation would be a vector2d. No need to invent new
terminology, especially if it's just going to obscure the real semantics of
the data structure.
One of the primary benefits of a linked list is being able to insert or
delete at any position with O(1) complexity. It's unclear if/how that
benefit really applies to the proposed data structure. Would each node have
prev_horizontal, next_horizontal, prev_vertical, next_vertical pointers?
That seems quite expensive.
On Fri, Apr 15, 2016 at 7:54 PM, Tony V E <tvaneerd@gmail.com> wrote:
> - I think table is a better name than matrix. Matrix assumes numbers and
> operators, etc. Table is just a container.
>
> - I would hope that the specification wouldn't rule out vector-of-vector
> implementations. ie I'd rather have that than iterators that don't
> invalidate. But that's just my opinion.
>
> - overall, not a bad idea. Might be hard to get consensus, as everyone
> will have their own requests. Might be better to start with boost?
>
> Sent from my BlackBerry portable Babbage Device
> *From: *allsey87@gmail.com
> *Sent: *Friday, April 15, 2016 6:38 AM
> *To: *ISO C++ Standard - Future Proposals
> *Reply To: *std-proposals@isocpp.org
> *Subject: *[std-proposals] Linked std::table / std::matrix proposal
>
> Hi Everyone,
>
> I'm considering implementing a new container called either std::table or
> std::matrix. The data structure would be similar to std::list as elements
> would be linked together through pointers/iterators. The aim of this data
> structure is *not* to create a high performance matrix, that tries to solve
> every single problem. There are always trade-offs in the design of
> matrices, and for high performance situations, it is probably better to
> use, e.g. in computer vision, opencv's Mat class. Keeping this in mind,
> conceptually the table/matrix that I am proposing would like this:
>
>
> | std::begin(col) | std::begin(col) |
> | --------------- | --------------- | --------------- | ------------- |
> | std::begin(row) | element 0,0 | element 0,1 | std::end(row) |
> | std::begin(row) | element 1,0 | element 1,1 | std::end(row) |
> | std::begin(row) | element 2,0 | element 2,1 | std::end(row) |
> | --------------- | --------------- | --------------- | ------------- |
> | std::end(col) | std::end(col) |
>
>
> In this design, two bidirectional (or forward) iterators are kept in each
> element for iterating across the rows and columns. I would imagine similar
> to a std::list, that this would enable the removing/adding of rows/columns
> without invalidating other row/column/element iterators, and also avoid
> moving all elements when a row/column is deleted.
>
> The motivation for using this layout over a
> std::vector<std::vector<double> > (vector inside a vector) is that the
> vector inside a vector approach can be unsafe and prone to bugs. I have
> just written the code for removing/adding rows/columns for the vector
> inside a vector approach, and while it is ok for the first dimension,
> working in the second dimension is painful. Not to mention, one has to
> constantly check if the table/matrix is well formed (i.e. equal number of
> elements in each row/column)
>
> The aim of this container would be to represent graphs, tables, and small
> to medium size matrices. I would like to also draw attention to the fact,
> that although syntax to access matrix elements in most libraries often
> appears as either my_matrix.at(2,3) or my_matrix[2][3], the actual access
> to the data is not often random, but rather linear across a given column or
> row (consider matrix multiplication). Furthermore, assuming all memory for
> the matrix is allocated once dynamically in the constructor, the
> performance for doing e.g. multiplication of two matrices would be
> reasonable since all elements should make there way into the higher levels
> of the cache after the first miss.
>
> From a user stand point, I would like the following sorts of operations to
> be possible:
>
> /* 1. construction / use of initialization list */
> std::table<double> my_table(3,2) = {
> 11, 12,
> 21, 22,
> 31, 32
> };
>
> std::cout << my_table.size(); // 6
>
> // element-wise iteration - important notes 1. random access iterators not
> supported, 2. individual elements can not be erased
> for(auto el : my_table) {
> std::cout << el << std::end;
> }
> // or
> for(auto it_el = std::begin(my_table); it_el != std::end(my_table);
> it_el++) {
> std::cout << *it_el << std::end;
> }
>
> /* 2. copy all values, column by column into a std::vector */
> std::vector<double> vector_values;
>
> for(const auto& col : my_table.get_cols()) {
> vector_values.insert(std::end(vector_values), std::begin(col),
> std::end(col));
> }
>
> /* 3. set all elements to forty two */
> for(auto& row : my_table.get_rows()) {
> for(auto& el : row) {
> el = 42.0f;
> }
> }
>
> /* 4. insert elements from a list or vector */
> // the type of iterator returned from std::end(my_table.get_rows()) or
> std::end(my_table.get_cols()) determines the orientation */
> std::list<double> list_values = {
> 42, 21;
> };
> // may throw exception if dimension mismatch, or alternatively
> truncate/default construct missing elements */
> my_table.insert(std::end(my_table.get_rows()), std::begin(list_values),
> std::end(list_values));
>
> /* 5. algorithms / erase-remove idiom applied to columns */
> // note since we work with columns and rows in matrices, remove(_if) is
> extended to remove(_if)_any, remove(_if)_all, remove_if_none
>
> my_table.erase( std::remove_if_none( std::begin(my_table.get_cols()),
> std::begin(my_table.get_cols()), [] (double el) { return (el == 42);} ),
> std::end(my_table.get_cols));
>
> /* 6. add row at beginning of table */
> my_table.add_row(std::begin(my_table.get_rows()));
>
> Any thoughts or counter proposals? Reasons why this is a bad idea?
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/df7aa05f-abaa-47bc-8946-86e7817e4a63%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/df7aa05f-abaa-47bc-8946-86e7817e4a63%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/20160416005425.4902992.3247.9842%40gmail.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/20160416005425.4902992.3247.9842%40gmail.com?utm_medium=email&utm_source=footer>
> .
>
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADbh%2BeTe1b75Sg8kwDn2RAsQf4geuGO%2BotDyGoB4f6Z1V45byQ%40mail.gmail.com.
--047d7b5d4a262cd7c00530911e7f
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">If the proposal is going to make any guarantees about iter=
ator invalidation or performance characteristics then you basically have to=
decide on vector-of-vectors vs. lists.<div><br></div><div>My preference wo=
uld be to call this something like list2d<T> if it's going to use=
a linked list. Which raises questions about list3d, etc. A vector of vecto=
rs implementation would be a vector2d. No need to invent new terminology, e=
specially if it's just going to obscure the real semantics of the data =
structure.</div><div><br></div><div>One of the primary benefits of a linked=
list is being able to insert or delete at any position with O(1) complexit=
y. It's unclear if/how that benefit really applies to the proposed data=
structure. Would each node have prev_horizontal, next_horizontal, prev_ver=
tical, next_vertical pointers? That seems quite expensive.</div></div><div =
class=3D"gmail_extra"><br><div class=3D"gmail_quote">On Fri, Apr 15, 2016 a=
t 7:54 PM, Tony V E <span dir=3D"ltr"><<a href=3D"mailto:tvaneerd@gmail.=
com" target=3D"_blank">tvaneerd@gmail.com</a>></span> wrote:<br><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div lang=3D"en-US" style=3D"background-color:rgb(25=
5,255,255);line-height:initial"> =
<div style=3D"width:100%;font-si=
ze:initial;font-family:Calibri,'Slate Pro',sans-serif,sans-serif;co=
lor:rgb(31,73,125);text-align:initial;background-color:rgb(255,255,255)">- =
I think table is a better name than matrix. Matrix assumes numbers and oper=
ators, etc. Table is just a container.=C2=A0</div><div style=3D"width:100%;=
font-size:initial;font-family:Calibri,'Slate Pro',sans-serif,sans-s=
erif;color:rgb(31,73,125);text-align:initial;background-color:rgb(255,255,2=
55)"><br></div><div style=3D"width:100%;font-size:initial;font-family:Calib=
ri,'Slate Pro',sans-serif,sans-serif;color:rgb(31,73,125);text-alig=
n:initial;background-color:rgb(255,255,255)">- I would hope that the specif=
ication wouldn't rule out vector-of-vector implementations. ie I'd =
rather have that than iterators that don't invalidate.=C2=A0 But that&#=
39;s just my opinion. </div><div style=3D"width:100%;font-size:initial;font=
-family:Calibri,'Slate Pro',sans-serif,sans-serif;color:rgb(31,73,1=
25);text-align:initial;background-color:rgb(255,255,255)"><br></div><div st=
yle=3D"width:100%;font-size:initial;font-family:Calibri,'Slate Pro'=
,sans-serif,sans-serif;color:rgb(31,73,125);text-align:initial;background-c=
olor:rgb(255,255,255)">- overall, not a bad idea. Might be hard to get cons=
ensus, as everyone will have their own requests. Might be better to start w=
ith boost?</div> =
<=
div style=3D"width:100%;font-size:initial;font-family:Calibri,'Slate Pr=
o',sans-serif,sans-serif;color:rgb(31,73,125);text-align:initial;backgr=
ound-color:rgb(255,255,255)"><br style=3D"display:initial"></div> =
=
=
<div style=3D"font-size:initial;font-fam=
ily:Calibri,'Slate Pro',sans-serif,sans-serif;color:rgb(31,73,125);=
text-align:initial;background-color:rgb(255,255,255)">Sent=C2=A0from=C2=A0m=
y=C2=A0BlackBerry=C2=A0portable=C2=A0Babbage=C2=A0Device</div> =
=
=
<table width=3D"100%" style=3D"background-color:white;border=
-spacing:0px"> <tbody><tr><td colspan=3D"2" style=3D"font-size:initial;text=
-align:initial;background-color:rgb(255,255,255)"> =
<div style=3D"border-style:solid none none;border-top-color:rgb(181,196,2=
23);border-top-width:1pt;padding:3pt 0in 0in;font-family:Tahoma,'BB Alp=
ha Sans','Slate Pro';font-size:10pt"> <div><b>From: </b><a hre=
f=3D"mailto:allsey87@gmail.com" target=3D"_blank">allsey87@gmail.com</a></d=
iv><div><b>Sent: </b>Friday, April 15, 2016 6:38 AM</div><div><b>To: </b>IS=
O C++ Standard - Future Proposals</div><div><b>Reply To: </b><a href=3D"mai=
lto:std-proposals@isocpp.org" target=3D"_blank">std-proposals@isocpp.org</a=
></div><div><b>Subject: </b>[std-proposals] Linked std::table / std::matrix=
proposal</div></div></td></tr></tbody></table><div><div class=3D"h5"><div =
style=3D"border-style:solid none none;border-top-color:rgb(186,188,209);bor=
der-top-width:1pt;font-size:initial;text-align:initial;background-color:rgb=
(255,255,255)"></div><br><div><div dir=3D"ltr"><span style=3D"font-family:c=
ourier new,monospace">Hi Everyone,<br><br>I'm considering implementing =
a new container called either std::table or std::matrix. The data structure=
would be similar to std::list as elements would be linked together through=
pointers/iterators. The aim of this data structure is *not* to create a hi=
gh performance matrix, that tries to solve every single problem. There are =
always trade-offs in the design of matrices, and for high performance situa=
tions, it is probably better to use, e.g. in computer vision, opencv's =
Mat class. Keeping this in mind, conceptually the table/matrix that I am pr=
oposing would like this:<br><br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | std::begi=
n(col) | std::begin(col) |<br>| --------------- | --------------- | -------=
-------- | ------------- |<br>| std::begin(row) | element 0,0=C2=A0=C2=A0=
=C2=A0=C2=A0 | element 0,1=C2=A0=C2=A0=C2=A0=C2=A0 | std::end(row) |<br>| s=
td::begin(row) | element 1,0=C2=A0=C2=A0=C2=A0=C2=A0 | element 1,1=C2=A0=C2=
=A0=C2=A0=C2=A0 | std::end(row) |<br>| std::begin(row) | element 2,0=C2=A0=
=C2=A0=C2=A0=C2=A0 | element 2,1=C2=A0=C2=A0=C2=A0=C2=A0 | std::end(row) |<=
br>| --------------- | --------------- | --------------- | ------------- |<=
br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | std::end(col)=C2=A0=C2=A0 | std::end(col)=
=C2=A0=C2=A0 |<br><br><br>In this design, two bidirectional (or forward) it=
erators are kept in each element for iterating across the rows and columns.=
I would imagine similar to a std::list, that this would enable the removin=
g/adding of rows/columns without invalidating other row/column/element iter=
ators, and also avoid moving all elements when a row/column is deleted.<br>=
<br>The motivation for using this layout over a std::vector<std::vector&=
lt;double> > (vector inside a vector) is that the vector inside a vec=
tor approach can be unsafe and prone to bugs. I have just written the code =
for removing/adding rows/columns for the vector inside a vector approach, a=
nd while it is ok for the first dimension, working in the second dimension =
is painful. Not to mention, one has to constantly check if the table/matrix=
is well formed (i.e. equal number of elements in each row/column)<br><br>T=
he aim of this container would be to represent graphs, tables, and small to=
medium size matrices. I would like to also draw attention to the fact, tha=
t although syntax to access matrix elements in most libraries often appears=
as either <a href=3D"http://my_matrix.at" target=3D"_blank">my_matrix.at</=
a>(2,3) or my_matrix[2][3], the actual access to the data is not often rand=
om, but rather linear across a given column or row (consider matrix multipl=
ication). Furthermore, assuming all memory for the matrix is allocated once=
dynamically in the constructor, the performance for doing e.g. multiplicat=
ion of two matrices would be reasonable since all elements should make ther=
e way into the higher levels of the cache after the first miss.<br><br>From=
a user stand point, I would like the following sorts of operations to be p=
ossible:<br><br>/* 1. construction / use of initialization list */<br>std::=
table<double> my_table(3,2) =3D {<br>=C2=A0=C2=A0 11, 12,<br>=C2=A0=
=C2=A0 21, 22,<br>=C2=A0=C2=A0 31, 32<br>};<br><br>std::cout << my_ta=
ble.size(); // 6<br><br>// element-wise iteration - important notes 1. rand=
om access iterators not supported, 2. individual elements can not be erased=
<br>for(auto el : my_table) {<br>=C2=A0=C2=A0 std::cout << el <<=
; std::end;<br>}<br>// or<br>for(auto it_el =3D std::begin(my_table); it_el=
!=3D std::end(my_table); it_el++) {<br>=C2=A0=C2=A0 std::cout << *it=
_el << std::end;<br>}<br><br>/* 2. copy all values, column by column =
into a std::vector */<br>std::vector<double> vector_values;<br><br>fo=
r(const auto& col : my_table.get_cols()) {<br>=C2=A0=C2=A0 vector_value=
s.insert(std::end(vector_values), std::begin(col), std::end(col));<br>}<br>=
<br>/* 3. set all elements to forty two */<br>for(auto& row : my_table.=
get_rows()) {<br>=C2=A0=C2=A0 for(auto& el : row) {<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 el =3D 42.0f;<br>=C2=A0=C2=A0 }<br>}<br><br>/* 4. insert el=
ements from a list or vector */<br>// the type of iterator returned from st=
d::end(my_table.get_rows()) or std::end(my_table.get_cols()) determines the=
orientation */<br>std::list<double> list_values =3D {<br>=C2=A0=C2=
=A0 42, 21;<br>};<br>// may throw exception if dimension mismatch, or alter=
natively truncate/default construct missing elements */<br>my_table.insert(=
std::end(my_table.get_rows()), std::begin(list_values), std::end(list_value=
s));<br><br>/* 5. algorithms / erase-remove idiom applied to columns */<br>=
// note since we work with columns and rows in matrices, remove(_if) is ext=
ended to=C2=A0 remove(_if)_any, remove(_if)_all, remove_if_none<br><br>my_t=
able.erase( std::remove_if_none( std::begin(my_table.get_cols()), std::begi=
n(my_table.get_cols()), [] (double el) { return (el =3D=3D 42);} ), std::en=
d(my_table.get_cols));<br><br>/* 6. add row at beginning of table */<br>my_=
table.add_row(std::begin(my_table.get_rows()));<br><br>Any thoughts or coun=
ter proposals? Reasons why this is a bad idea?<br><br><br></span></div>
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/df7aa05f-abaa-47bc-8946-86e7817e4a63%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/df7aa05f-abaa-=
47bc-8946-86e7817e4a63%40isocpp.org</a>.<br>
<br></div></div></div></div><div><div class=3D"h5">
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></div></div>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/20160416005425.4902992.3247.9842%40gm=
ail.com?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank">https=
://groups.google.com/a/isocpp.org/d/msgid/std-proposals/20160416005425.4902=
992.3247.9842%40gmail.com</a>.<br>
</blockquote></div><br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CADbh%2BeTe1b75Sg8kwDn2RAsQf4geuGO%2B=
otDyGoB4f6Z1V45byQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADbh%2BeTe1b=
75Sg8kwDn2RAsQf4geuGO%2BotDyGoB4f6Z1V45byQ%40mail.gmail.com</a>.<br />
--047d7b5d4a262cd7c00530911e7f--
.
Author: Michael Allwright <allsey87@gmail.com>
Date: Sat, 16 Apr 2016 19:06:30 +0200
Raw View
--047d7bf0c58e14499f05309d26f8
Content-Type: text/plain; charset=UTF-8
Hi Tony, Hi Brent,
I agree completely that table is a better name, and if someone wants to
implement matrix semantics on top of that they could easily inherit from a
table and add the required operators. I'm somewhat against the names
vectorNd and listNd, as vectors and lists are containers where operations
typically occur on elements. This is not the case for tables, where
operations are typically applied to rows and columns, and I think the names
vectorNd and listNd suggest semantics that don't really apply.
I'm not exactly sure what you mean by ruling out vector-of-vector
implementations, I'm suggesting adding a new container to the standard, not
removing anything. The vector-of-vectors approach is certainly ok for
situations where the layout and dimensions of the table/matrix are
relatively fixed, but in the case where we need to add/remove/shift columns
and rows, the code to do this can be quite unsafe and bloated.
Consider the following example of adding a column to the vector of vectors
approach (full example here: https://goo.gl/EAcyUl):
template <class T>
using table = vector<vector<T> >;
/* initialization */
table<double> tbl = {
{2.2, 2.3, 2.5},
{3.2, 3.3, 3.5},
{4.2, 4.3} // note: no safety against badly formed tables
};
/* insert a vector of values as a column into the table */
vector<double> vals = {2.4, 3.4, 4.4};
unsigned int col_idx = 2;
auto it_vals = begin(vals);
for(auto& row : tbl) {
auto it_el = begin(row);
advance(it_el, col_idx); // should this be checked for every row? i.e.
if(col_idx > distance(begin(row), end(row))) throw ...
row.insert(it_el, *(it_vals++)); // poor readability, manual safety
required (what if vals was to small?)
}
Even in this very simple example, there are several points where the code
is quite unsafe. The code becomes even more complicated if we need
conditional operations: consider the code removing all columns, which
contain one or more negative values... These issues are also present with
using a list-of-lists, although the time complexity of
adding/removing/shifting is obviously better.
The solution I propose would solve these issues, significantly improving
the safety and readability of the code. The downside, as you point out
Brent, is that the overhead of the pointers: horizontal_next,
vertical_next, horizontal_previous, vertical_previous. Although if memory
is critical to an application, one could also implement a forward_table
which has only two pointers: horizontal_next, vertical_next - which is no
more memory consuming than a bidirectional list.
This container doesn't aim to solve problems such as implementing large
databases or solving large sets of simultaneous equations through matrix
operations, boost already has some quite sophisticated solutions for this.
The aim of this container is to provide programmers with a tool to safely
manipulate small to medium sets of data that is organised as rows and
columns.
On 16 April 2016 at 04:45, Brent Friedman <fourthgeek@gmail.com> wrote:
> If the proposal is going to make any guarantees about iterator
> invalidation or performance characteristics then you basically have to
> decide on vector-of-vectors vs. lists.
>
> My preference would be to call this something like list2d<T> if it's going
> to use a linked list. Which raises questions about list3d, etc. A vector of
> vectors implementation would be a vector2d. No need to invent new
> terminology, especially if it's just going to obscure the real semantics of
> the data structure.
>
> One of the primary benefits of a linked list is being able to insert or
> delete at any position with O(1) complexity. It's unclear if/how that
> benefit really applies to the proposed data structure. Would each node have
> prev_horizontal, next_horizontal, prev_vertical, next_vertical pointers?
> That seems quite expensive.
>
> On Fri, Apr 15, 2016 at 7:54 PM, Tony V E <tvaneerd@gmail.com> wrote:
>
>> - I think table is a better name than matrix. Matrix assumes numbers and
>> operators, etc. Table is just a container.
>>
>> - I would hope that the specification wouldn't rule out vector-of-vector
>> implementations. ie I'd rather have that than iterators that don't
>> invalidate. But that's just my opinion.
>>
>> - overall, not a bad idea. Might be hard to get consensus, as everyone
>> will have their own requests. Might be better to start with boost?
>>
>> Sent from my BlackBerry portable Babbage Device
>> *From: *allsey87@gmail.com
>> *Sent: *Friday, April 15, 2016 6:38 AM
>> *To: *ISO C++ Standard - Future Proposals
>> *Reply To: *std-proposals@isocpp.org
>> *Subject: *[std-proposals] Linked std::table / std::matrix proposal
>>
>> Hi Everyone,
>>
>> I'm considering implementing a new container called either std::table or
>> std::matrix. The data structure would be similar to std::list as elements
>> would be linked together through pointers/iterators. The aim of this data
>> structure is *not* to create a high performance matrix, that tries to solve
>> every single problem. There are always trade-offs in the design of
>> matrices, and for high performance situations, it is probably better to
>> use, e.g. in computer vision, opencv's Mat class. Keeping this in mind,
>> conceptually the table/matrix that I am proposing would like this:
>>
>>
>> | std::begin(col) | std::begin(col) |
>> | --------------- | --------------- | --------------- | ------------- |
>> | std::begin(row) | element 0,0 | element 0,1 | std::end(row) |
>> | std::begin(row) | element 1,0 | element 1,1 | std::end(row) |
>> | std::begin(row) | element 2,0 | element 2,1 | std::end(row) |
>> | --------------- | --------------- | --------------- | ------------- |
>> | std::end(col) | std::end(col) |
>>
>>
>> In this design, two bidirectional (or forward) iterators are kept in each
>> element for iterating across the rows and columns. I would imagine similar
>> to a std::list, that this would enable the removing/adding of rows/columns
>> without invalidating other row/column/element iterators, and also avoid
>> moving all elements when a row/column is deleted.
>>
>> The motivation for using this layout over a
>> std::vector<std::vector<double> > (vector inside a vector) is that the
>> vector inside a vector approach can be unsafe and prone to bugs. I have
>> just written the code for removing/adding rows/columns for the vector
>> inside a vector approach, and while it is ok for the first dimension,
>> working in the second dimension is painful. Not to mention, one has to
>> constantly check if the table/matrix is well formed (i.e. equal number of
>> elements in each row/column)
>>
>> The aim of this container would be to represent graphs, tables, and small
>> to medium size matrices. I would like to also draw attention to the fact,
>> that although syntax to access matrix elements in most libraries often
>> appears as either my_matrix.at(2,3) or my_matrix[2][3], the actual
>> access to the data is not often random, but rather linear across a given
>> column or row (consider matrix multiplication). Furthermore, assuming all
>> memory for the matrix is allocated once dynamically in the constructor, the
>> performance for doing e.g. multiplication of two matrices would be
>> reasonable since all elements should make there way into the higher levels
>> of the cache after the first miss.
>>
>> From a user stand point, I would like the following sorts of operations
>> to be possible:
>>
>> /* 1. construction / use of initialization list */
>> std::table<double> my_table(3,2) = {
>> 11, 12,
>> 21, 22,
>> 31, 32
>> };
>>
>> std::cout << my_table.size(); // 6
>>
>> // element-wise iteration - important notes 1. random access iterators
>> not supported, 2. individual elements can not be erased
>> for(auto el : my_table) {
>> std::cout << el << std::end;
>> }
>> // or
>> for(auto it_el = std::begin(my_table); it_el != std::end(my_table);
>> it_el++) {
>> std::cout << *it_el << std::end;
>> }
>>
>> /* 2. copy all values, column by column into a std::vector */
>> std::vector<double> vector_values;
>>
>> for(const auto& col : my_table.get_cols()) {
>> vector_values.insert(std::end(vector_values), std::begin(col),
>> std::end(col));
>> }
>>
>> /* 3. set all elements to forty two */
>> for(auto& row : my_table.get_rows()) {
>> for(auto& el : row) {
>> el = 42.0f;
>> }
>> }
>>
>> /* 4. insert elements from a list or vector */
>> // the type of iterator returned from std::end(my_table.get_rows()) or
>> std::end(my_table.get_cols()) determines the orientation */
>> std::list<double> list_values = {
>> 42, 21;
>> };
>> // may throw exception if dimension mismatch, or alternatively
>> truncate/default construct missing elements */
>> my_table.insert(std::end(my_table.get_rows()), std::begin(list_values),
>> std::end(list_values));
>>
>> /* 5. algorithms / erase-remove idiom applied to columns */
>> // note since we work with columns and rows in matrices, remove(_if) is
>> extended to remove(_if)_any, remove(_if)_all, remove_if_none
>>
>> my_table.erase( std::remove_if_none( std::begin(my_table.get_cols()),
>> std::begin(my_table.get_cols()), [] (double el) { return (el == 42);} ),
>> std::end(my_table.get_cols));
>>
>> /* 6. add row at beginning of table */
>> my_table.add_row(std::begin(my_table.get_rows()));
>>
>> Any thoughts or counter proposals? Reasons why this is a bad idea?
>>
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to std-proposals+unsubscribe@isocpp.org.
>> To post to this group, send email to std-proposals@isocpp.org.
>> To view this discussion on the web visit
>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/df7aa05f-abaa-47bc-8946-86e7817e4a63%40isocpp.org
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/df7aa05f-abaa-47bc-8946-86e7817e4a63%40isocpp.org?utm_medium=email&utm_source=footer>
>> .
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to std-proposals+unsubscribe@isocpp.org.
>> To post to this group, send email to std-proposals@isocpp.org.
>> To view this discussion on the web visit
>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/20160416005425.4902992.3247.9842%40gmail.com
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/20160416005425.4902992.3247.9842%40gmail.com?utm_medium=email&utm_source=footer>
>> .
>>
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/R9jeBjwJmKo/unsubscribe
> .
> To unsubscribe from this group and all its topics, send an email to
> std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADbh%2BeTe1b75Sg8kwDn2RAsQf4geuGO%2BotDyGoB4f6Z1V45byQ%40mail.gmail.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADbh%2BeTe1b75Sg8kwDn2RAsQf4geuGO%2BotDyGoB4f6Z1V45byQ%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALcgO_5ivw4f_N4CpsogxsaOEpT-EK4UwVELtj_DCNAHfPxb9Q%40mail.gmail.com.
--047d7bf0c58e14499f05309d26f8
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Hi Tony, Hi Brent,<div><br></div><div>I agree completely t=
hat table is a better name, and if someone wants to implement matrix semant=
ics on top of that they could easily inherit from a table and add the requi=
red operators. I'm somewhat against the names vectorNd and listNd, as v=
ectors and lists are containers where operations typically occur on element=
s. This is not the case for tables, where operations are typically applied =
to rows and columns, and I think the names vectorNd and listNd suggest sema=
ntics that don't really apply.</div><div><br></div><div>I'm not exa=
ctly sure what you mean by ruling out vector-of-vector implementations, I&#=
39;m suggesting adding a new container to the standard, not removing anythi=
ng. The vector-of-vectors approach is certainly ok for situations where the=
layout and dimensions of the table/matrix are relatively fixed, but in the=
case where we need to add/remove/shift columns and rows, the code to do th=
is can be quite unsafe and bloated.</div><div><br></div><div>Consider the f=
ollowing example of adding a column to the vector of vectors approach (full=
example here: <a href=3D"https://goo.gl/EAcyUl">https://goo.gl/EAcyUl</a>)=
:</div><div><br></div><div><div>template <class T></div><div>using ta=
ble =3D vector<vector<T> >;</div><div><br></div><div><div>/* in=
itialization */</div><div>table<double> tbl =3D {</div><div>=C2=A0 =
=C2=A0{2.2, 2.3, 2.5},</div><div>=C2=A0 =C2=A0{3.2, 3.3, 3.5},</div><div>=
=C2=A0 =C2=A0{4.2, 4.3} // note: no safety against badly formed tables=C2=
=A0</div><div>};</div><div>/* insert a vector of values as a column into th=
e table */</div><div>vector<double> vals =3D {2.4, 3.4, 4.4};</div><d=
iv>unsigned int col_idx =3D 2;</div><div>auto it_vals =3D begin(vals);</div=
><div>for(auto& row : tbl) {</div><div>=C2=A0 =C2=A0auto it_el =3D begi=
n(row);</div><div>=C2=A0 =C2=A0advance(it_el, col_idx); // should this be c=
hecked for every row? i.e. if(col_idx > distance(begin(row), end(row))) =
throw ...=C2=A0</div><div>=C2=A0 =C2=A0row.insert(it_el, *(it_vals++)); // =
poor readability, manual safety required (what if vals was to small?)</div>=
<div>}</div></div></div><div><br></div><div>Even in this very simple exampl=
e, there are several points where the code is quite unsafe. The code become=
s even more complicated if we need conditional operations: consider the cod=
e removing all columns, which contain one or more negative values... These =
issues are also present with using a list-of-lists, although the time compl=
exity of adding/removing/shifting is obviously better.</div><div><br></div>=
<div>The solution I propose would solve these issues, significantly improvi=
ng the safety and readability of the code. The downside, as you point out B=
rent, is that the overhead of the pointers: horizontal_next, vertical_next,=
horizontal_previous, vertical_previous. Although if memory is critical to =
an application, one could also implement a forward_table which has only two=
pointers: horizontal_next, vertical_next - which is no more memory consumi=
ng than a bidirectional list.</div><div><br></div><div>This container doesn=
't aim to solve problems such as implementing large databases or solvin=
g large sets of simultaneous equations through matrix operations, boost alr=
eady has some quite sophisticated solutions for this. The aim of this conta=
iner is to provide programmers with a tool to safely manipulate small to me=
dium sets of data that is organised as rows and columns.</div></div><div cl=
ass=3D"gmail_extra"><br><div class=3D"gmail_quote">On 16 April 2016 at 04:4=
5, Brent Friedman <span dir=3D"ltr"><<a href=3D"mailto:fourthgeek@gmail.=
com" target=3D"_blank">fourthgeek@gmail.com</a>></span> wrote:<br><block=
quote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc=
solid;padding-left:1ex"><div dir=3D"ltr">If the proposal is going to make =
any guarantees about iterator invalidation or performance characteristics t=
hen you basically have to decide on vector-of-vectors vs. lists.<div><br></=
div><div>My preference would be to call this something like list2d<T>=
if it's going to use a linked list. Which raises questions about list3=
d, etc. A vector of vectors implementation would be a vector2d. No need to =
invent new terminology, especially if it's just going to obscure the re=
al semantics of the data structure.</div><div><br></div><div>One of the pri=
mary benefits of a linked list is being able to insert or delete at any pos=
ition with O(1) complexity. It's unclear if/how that benefit really app=
lies to the proposed data structure. Would each node have prev_horizontal, =
next_horizontal, prev_vertical, next_vertical pointers? That seems quite ex=
pensive.</div></div><div class=3D"gmail_extra"><br><div class=3D"gmail_quot=
e"><div><div class=3D"h5">On Fri, Apr 15, 2016 at 7:54 PM, Tony V E <span d=
ir=3D"ltr"><<a href=3D"mailto:tvaneerd@gmail.com" target=3D"_blank">tvan=
eerd@gmail.com</a>></span> wrote:<br></div></div><blockquote class=3D"gm=
ail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div><div class=3D"h5"><div lang=3D"en-US" style=3D"background-colo=
r:rgb(255,255,255);line-height:initial"> =
<div style=3D"width:100%=
;font-size:initial;font-family:Calibri,'Slate Pro',sans-serif,sans-=
serif;color:rgb(31,73,125);text-align:initial;background-color:rgb(255,255,=
255)">- I think table is a better name than matrix. Matrix assumes numbers =
and operators, etc. Table is just a container.=C2=A0</div><div style=3D"wid=
th:100%;font-size:initial;font-family:Calibri,'Slate Pro',sans-seri=
f,sans-serif;color:rgb(31,73,125);text-align:initial;background-color:rgb(2=
55,255,255)"><br></div><div style=3D"width:100%;font-size:initial;font-fami=
ly:Calibri,'Slate Pro',sans-serif,sans-serif;color:rgb(31,73,125);t=
ext-align:initial;background-color:rgb(255,255,255)">- I would hope that th=
e specification wouldn't rule out vector-of-vector implementations. ie =
I'd rather have that than iterators that don't invalidate.=C2=A0 Bu=
t that's just my opinion. </div><div style=3D"width:100%;font-size:init=
ial;font-family:Calibri,'Slate Pro',sans-serif,sans-serif;color:rgb=
(31,73,125);text-align:initial;background-color:rgb(255,255,255)"><br></div=
><div style=3D"width:100%;font-size:initial;font-family:Calibri,'Slate =
Pro',sans-serif,sans-serif;color:rgb(31,73,125);text-align:initial;back=
ground-color:rgb(255,255,255)">- overall, not a bad idea. Might be hard to =
get consensus, as everyone will have their own requests. Might be better to=
start with boost?</div> =
=
<div style=3D"width:100%;font-size:initial;font-family:Calibri,'=
Slate Pro',sans-serif,sans-serif;color:rgb(31,73,125);text-align:initia=
l;background-color:rgb(255,255,255)"><br style=3D"display:initial"></div> =
=
=
<div style=3D"font-size:initial;=
font-family:Calibri,'Slate Pro',sans-serif,sans-serif;color:rgb(31,=
73,125);text-align:initial;background-color:rgb(255,255,255)">Sent=C2=A0fro=
m=C2=A0my=C2=A0BlackBerry=C2=A0portable=C2=A0Babbage=C2=A0Device</div> =
=
=
<table width=3D"100%" style=3D"background-color:whit=
e;border-spacing:0px"> <tbody><tr><td colspan=3D"2" style=3D"font-size:init=
ial;text-align:initial;background-color:rgb(255,255,255)"> =
<div style=3D"border-style:solid none none;border-top-color:rgb(1=
81,196,223);border-top-width:1pt;padding:3pt 0in 0in;font-family:Tahoma,=
9;BB Alpha Sans','Slate Pro';font-size:10pt"> <div><b>From: </=
b><a href=3D"mailto:allsey87@gmail.com" target=3D"_blank">allsey87@gmail.co=
m</a></div><div><b>Sent: </b>Friday, April 15, 2016 6:38 AM</div><div><b>To=
: </b>ISO C++ Standard - Future Proposals</div><div><b>Reply To: </b><a hre=
f=3D"mailto:std-proposals@isocpp.org" target=3D"_blank">std-proposals@isocp=
p.org</a></div><div><b>Subject: </b>[std-proposals] Linked std::table / std=
::matrix proposal</div></div></td></tr></tbody></table><div><div><div style=
=3D"border-style:solid none none;border-top-color:rgb(186,188,209);border-t=
op-width:1pt;font-size:initial;text-align:initial;background-color:rgb(255,=
255,255)"></div><br><div><div dir=3D"ltr"><span style=3D"font-family:courie=
r new,monospace">Hi Everyone,<br><br>I'm considering implementing a new=
container called either std::table or std::matrix. The data structure woul=
d be similar to std::list as elements would be linked together through poin=
ters/iterators. The aim of this data structure is *not* to create a high pe=
rformance matrix, that tries to solve every single problem. There are alway=
s trade-offs in the design of matrices, and for high performance situations=
, it is probably better to use, e.g. in computer vision, opencv's Mat c=
lass. Keeping this in mind, conceptually the table/matrix that I am proposi=
ng would like this:<br><br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | std::begin(c=
ol) | std::begin(col) |<br>| --------------- | --------------- | ----------=
----- | ------------- |<br>| std::begin(row) | element 0,0=C2=A0=C2=A0=C2=
=A0=C2=A0 | element 0,1=C2=A0=C2=A0=C2=A0=C2=A0 | std::end(row) |<br>| std:=
:begin(row) | element 1,0=C2=A0=C2=A0=C2=A0=C2=A0 | element 1,1=C2=A0=C2=A0=
=C2=A0=C2=A0 | std::end(row) |<br>| std::begin(row) | element 2,0=C2=A0=C2=
=A0=C2=A0=C2=A0 | element 2,1=C2=A0=C2=A0=C2=A0=C2=A0 | std::end(row) |<br>=
| --------------- | --------------- | --------------- | ------------- |<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 | std::end(col)=C2=A0=C2=A0 | std::end(col)=C2=
=A0=C2=A0 |<br><br><br>In this design, two bidirectional (or forward) itera=
tors are kept in each element for iterating across the rows and columns. I =
would imagine similar to a std::list, that this would enable the removing/a=
dding of rows/columns without invalidating other row/column/element iterato=
rs, and also avoid moving all elements when a row/column is deleted.<br><br=
>The motivation for using this layout over a std::vector<std::vector<=
double> > (vector inside a vector) is that the vector inside a vector=
approach can be unsafe and prone to bugs. I have just written the code for=
removing/adding rows/columns for the vector inside a vector approach, and =
while it is ok for the first dimension, working in the second dimension is =
painful. Not to mention, one has to constantly check if the table/matrix is=
well formed (i.e. equal number of elements in each row/column)<br><br>The =
aim of this container would be to represent graphs, tables, and small to me=
dium size matrices. I would like to also draw attention to the fact, that a=
lthough syntax to access matrix elements in most libraries often appears as=
either <a href=3D"http://my_matrix.at" target=3D"_blank">my_matrix.at</a>(=
2,3) or my_matrix[2][3], the actual access to the data is not often random,=
but rather linear across a given column or row (consider matrix multiplica=
tion). Furthermore, assuming all memory for the matrix is allocated once dy=
namically in the constructor, the performance for doing e.g. multiplication=
of two matrices would be reasonable since all elements should make there w=
ay into the higher levels of the cache after the first miss.<br><br>From a =
user stand point, I would like the following sorts of operations to be poss=
ible:<br><br>/* 1. construction / use of initialization list */<br>std::tab=
le<double> my_table(3,2) =3D {<br>=C2=A0=C2=A0 11, 12,<br>=C2=A0=C2=
=A0 21, 22,<br>=C2=A0=C2=A0 31, 32<br>};<br><br>std::cout << my_table=
..size(); // 6<br><br>// element-wise iteration - important notes 1. random =
access iterators not supported, 2. individual elements can not be erased<br=
>for(auto el : my_table) {<br>=C2=A0=C2=A0 std::cout << el << s=
td::end;<br>}<br>// or<br>for(auto it_el =3D std::begin(my_table); it_el !=
=3D std::end(my_table); it_el++) {<br>=C2=A0=C2=A0 std::cout << *it_e=
l << std::end;<br>}<br><br>/* 2. copy all values, column by column in=
to a std::vector */<br>std::vector<double> vector_values;<br><br>for(=
const auto& col : my_table.get_cols()) {<br>=C2=A0=C2=A0 vector_values.=
insert(std::end(vector_values), std::begin(col), std::end(col));<br>}<br><b=
r>/* 3. set all elements to forty two */<br>for(auto& row : my_table.ge=
t_rows()) {<br>=C2=A0=C2=A0 for(auto& el : row) {<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 el =3D 42.0f;<br>=C2=A0=C2=A0 }<br>}<br><br>/* 4. insert eleme=
nts from a list or vector */<br>// the type of iterator returned from std::=
end(my_table.get_rows()) or std::end(my_table.get_cols()) determines the or=
ientation */<br>std::list<double> list_values =3D {<br>=C2=A0=C2=A0 4=
2, 21;<br>};<br>// may throw exception if dimension mismatch, or alternativ=
ely truncate/default construct missing elements */<br>my_table.insert(std::=
end(my_table.get_rows()), std::begin(list_values), std::end(list_values));<=
br><br>/* 5. algorithms / erase-remove idiom applied to columns */<br>// no=
te since we work with columns and rows in matrices, remove(_if) is extended=
to=C2=A0 remove(_if)_any, remove(_if)_all, remove_if_none<br><br>my_table.=
erase( std::remove_if_none( std::begin(my_table.get_cols()), std::begin(my_=
table.get_cols()), [] (double el) { return (el =3D=3D 42);} ), std::end(my_=
table.get_cols));<br><br>/* 6. add row at beginning of table */<br>my_table=
..add_row(std::begin(my_table.get_rows()));<br><br>Any thoughts or counter p=
roposals? Reasons why this is a bad idea?<br><br><br></span></div>
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/df7aa05f-abaa-47bc-8946-86e7817e4a63%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/df7aa05f-abaa-=
47bc-8946-86e7817e4a63%40isocpp.org</a>.<br>
<br></div></div></div></div><div><div>
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></div></div></div>=
</div>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/20160416005425.4902992.3247.9842%40gm=
ail.com?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank">https=
://groups.google.com/a/isocpp.org/d/msgid/std-proposals/20160416005425.4902=
992.3247.9842%40gmail.com</a>.<br>
</blockquote></div><br></div><span class=3D"">
<p></p>
-- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/R9jeBjwJmKo/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/R9jeBjwJmKo=
/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CADbh%2BeTe1b75Sg8kwDn2RAsQf4geuGO%2B=
otDyGoB4f6Z1V45byQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-p=
roposals/CADbh%2BeTe1b75Sg8kwDn2RAsQf4geuGO%2BotDyGoB4f6Z1V45byQ%40mail.gma=
il.com</a>.<br>
</blockquote></div><br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CALcgO_5ivw4f_N4CpsogxsaOEpT-EK4UwVEL=
tj_DCNAHfPxb9Q%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALcgO_5ivw4f_N4C=
psogxsaOEpT-EK4UwVELtj_DCNAHfPxb9Q%40mail.gmail.com</a>.<br />
--047d7bf0c58e14499f05309d26f8--
.
Author: allsey87@gmail.com
Date: Tue, 19 Apr 2016 05:23:58 -0700 (PDT)
Raw View
------=_Part_11577_1695999357.1461068638614
Content-Type: multipart/alternative;
boundary="----=_Part_11578_72990638.1461068638614"
------=_Part_11578_72990638.1461068638614
Content-Type: text/plain; charset=UTF-8
Hi Tony, Hi Brent,
Did my last message answer your queries?
All the best,
Michael
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/85c2624a-0cc3-4f22-ba14-bb1851d1b4b8%40isocpp.org.
------=_Part_11578_72990638.1461068638614
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Hi Tony, Hi Brent,<br><br>Did my last message answer your =
queries?<br><br>All the best,<br><br><br>Michael</div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/85c2624a-0cc3-4f22-ba14-bb1851d1b4b8%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/85c2624a-0cc3-4f22-ba14-bb1851d1b4b8=
%40isocpp.org</a>.<br />
------=_Part_11578_72990638.1461068638614--
------=_Part_11577_1695999357.1461068638614--
.
Author: Tony V E <tvaneerd@gmail.com>
Date: Tue, 19 Apr 2016 20:21:55 -0400
Raw View
--001a1135ea06d01ca80530df94bf
Content-Type: text/plain; charset=UTF-8
On Sat, Apr 16, 2016 at 1:06 PM, Michael Allwright <allsey87@gmail.com>
wrote:
>
> I'm not exactly sure what you mean by ruling out vector-of-vector
> implementations, I'm suggesting adding a new container to the standard, not
> removing anything. The vector-of-vectors approach is certainly ok for
> situations where the layout and dimensions of the table/matrix are
> relatively fixed, but in the case where we need to add/remove/shift columns
> and rows, the code to do this can be quite unsafe and bloated.
>
>
When you define a container for the standard, you don't define how it is
implemented, you only define how it looks from the outside - its API. You
_somewhat_ limit how it might be implemented by providing certain
guarantees - ie
- do iterators get invalided when adding/removing (for examples in STL:
vector yes, list no)
- what is the O(n) time for inserting, removing, etc,
- are the iterators ForwardIterators, BidirectionalIterators, or
RandomAccessIterators, etc
- etc
So, for your container, you have some high level API goals:
- ability to work with rows and columns - insert/remove/etc
- ability to iterate across rows/columns and over complete container
Given the above, I could write a container that has these abilities.
*Internally* that container might use nodes with next/prev/above/below or a
list of vectors or a vector of lists or a vector of vector or a map<Coord,
Value> or... ... a zoo of trained monkeys at internet terminals.
If you only saw the API, such as member functions insert_row(),
insert_column(),..., you wouldn't know which implementation I chose.
However, if you expect certain operations to be fast (at the cost of maybe
others being slow - ie fast insert, slower traversal), then you might wish
I implemented it one way instead of the other.
> Consider the following example of adding a column to the vector of vectors
> approach (full example here: https://goo.gl/EAcyUl):
>
> template <class T>
> using table = vector<vector<T> >;
>
> /* initialization */
> table<double> tbl = {
> {2.2, 2.3, 2.5},
> {3.2, 3.3, 3.5},
> {4.2, 4.3} // note: no safety against badly formed tables
> };
> /* insert a vector of values as a column into the table */
> vector<double> vals = {2.4, 3.4, 4.4};
> unsigned int col_idx = 2;
> auto it_vals = begin(vals);
> for(auto& row : tbl) {
> auto it_el = begin(row);
> advance(it_el, col_idx); // should this be checked for every row? i.e.
> if(col_idx > distance(begin(row), end(row))) throw ...
> row.insert(it_el, *(it_vals++)); // poor readability, manual safety
> required (what if vals was to small?)
> }
>
Given a list-based implementation, adding to a table might look like:
table<int> tab;
tab.insert_row({1,2,3,4});
Given a vector-based implementation, adding to a table might look like:
table<int> tab;
tab.insert_row({1,2,3,4});
To the user, it looks the same. Now, the *implementations* might look
different, and one might be more complicated than the other, but it is the
same to the user..
A map<> is not easy to implement. But it looks easy to use from the
outside.
And that is one of the great things about the STL - I don't need to
implement map, only use it.
> This container doesn't aim to solve problems such as implementing large
> databases or solving large sets of simultaneous equations through matrix
> operations, boost already has some quite sophisticated solutions for this.
> The aim of this container is to provide programmers with a tool to safely
> manipulate small to medium sets of data that is organised as rows and
> columns.
>
>
So this is exactly what we need to focus on - what is the aim, and was is
NOT the aim. (Like you say, NOT solving equations, etc).
So we need to decide what trade-offs to make - which operations should be
fast, which don't matter - do we expect users to traverse more, or
insert/remove more? Do they want to hold iterators, then insert/remove,
then continue to use those old iterators expecting them to still point to
where they previously did?
P.S. I specifically bring up vector of vector, because it will, in many
cases, probably be faster than a node-based container - even when doing
significant inserts etc. Vectors keep data local in memory (ie keep cache
lines happy), node-based containers spread the data out across memory. And
allocation is slow (and typically requires a lock for thread safety). So
allocating a single node vs moving a bunch of data over in a vector...
vector often wins.
For example, I recently changed a k-d-tree (see wikipedia) from node-based
to vector-based for a 40% speed up in searching. It also sped up building
the tree, but I don't really care about that - only searching matters -
that's the primary purpose of a k-d-tree.
For a table, we need to decide what matters, and what doesn't.
Tony
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOHCbivEq6bf%2B6j1AejSZvcg7zTX%3DsH6KB4eiNrWLZ5xNAzazg%40mail.gmail.com.
--001a1135ea06d01ca80530df94bf
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Sat, Apr 16, 2016 at 1:06 PM, Michael Allwright <span dir=3D"ltr">&l=
t;<a href=3D"mailto:allsey87@gmail.com" target=3D"_blank">allsey87@gmail.co=
m</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margi=
n:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex=
"><div dir=3D"ltr"><div><br></div><div>I'm not exactly sure what you me=
an by ruling out vector-of-vector implementations, I'm suggesting addin=
g a new container to the standard, not removing anything. The vector-of-vec=
tors approach is certainly ok for situations where the layout and dimension=
s of the table/matrix are relatively fixed, but in the case where we need t=
o add/remove/shift columns and rows, the code to do this can be quite unsaf=
e and bloated.</div><div><br></div></div></blockquote><div><br></div><div>W=
hen you define a container for the standard, you don't define how it is=
implemented, you only define how it looks from the outside - its API. You =
_somewhat_ limit how it might be implemented by providing certain guarantee=
s - ie<br><br></div><div>- do iterators get invalided when adding/removing =
(for examples in STL: vector yes, list no)<br></div><div>- what is the O(n)=
time for inserting, removing, etc,<br></div><div>- are the iterators Forwa=
rdIterators, BidirectionalIterators, or RandomAccessIterators, etc<br></div=
><div>- etc<br><br></div><div>So, for your container, you have some high le=
vel API goals:<br><br></div><div>- ability to work with rows and columns - =
insert/remove/etc<br></div><div>- ability to iterate across rows/columns an=
d over complete container<br><br></div><div>Given the above, I could write =
a container that has these abilities.=C2=A0 *Internally* that container mig=
ht use nodes with next/prev/above/below or a list of vectors or a vector of=
lists or a vector of vector or a map<Coord, Value> or... ... a zoo o=
f trained monkeys at internet terminals.<br><br></div><div>If you only saw =
the API, such as member functions insert_row(), insert_column(),..., you wo=
uldn't know which implementation I chose.<br><br></div><div>However, if=
you expect certain operations to be fast (at the cost of maybe others bein=
g slow - ie fast insert, slower traversal), then you might wish I implement=
ed it one way instead of the other.<br></div><div><br>=C2=A0<br></div><bloc=
kquote 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></div><d=
iv>Consider the following example of adding a column to the vector of vecto=
rs approach (full example here: <a href=3D"https://goo.gl/EAcyUl" target=3D=
"_blank">https://goo.gl/EAcyUl</a>):</div><div><br></div><div><div>template=
<class T></div><div>using table =3D vector<vector<T> >;<=
/div><div><br></div><div><div>/* initialization */</div><div>table<doubl=
e> tbl =3D {</div><div>=C2=A0 =C2=A0{2.2, 2.3, 2.5},</div><div>=C2=A0 =
=C2=A0{3.2, 3.3, 3.5},</div><div>=C2=A0 =C2=A0{4.2, 4.3} // note: no safety=
against badly formed tables=C2=A0</div><div>};</div><div>/* insert a vecto=
r of values as a column into the table */</div><div>vector<double> va=
ls =3D {2.4, 3.4, 4.4};</div><div>unsigned int col_idx =3D 2;</div><div>aut=
o it_vals =3D begin(vals);</div><div>for(auto& row : tbl) {</div><div>=
=C2=A0 =C2=A0auto it_el =3D begin(row);</div><div>=C2=A0 =C2=A0advance(it_e=
l, col_idx); // should this be checked for every row? i.e. if(col_idx > =
distance(begin(row), end(row))) throw ...=C2=A0</div><div>=C2=A0 =C2=A0row.=
insert(it_el, *(it_vals++)); // poor readability, manual safety required (w=
hat if vals was to small?)</div><div>}</div></div></div></div></blockquote>=
<div><br></div><div>Given a list-based implementation, adding to a table mi=
ght look like:<br><br></div><div>table<int> tab;<br></div><div>tab.in=
sert_row({1,2,3,4}); <br><br></div><div>Given a vector-based implementation=
, adding to a table might look like:<br><br><div>table<int> tab;<br><=
/div><div>tab.insert_row({1,2,3,4}); <br><br></div><div>To the user, it loo=
ks the same.=C2=A0 Now, the *implementations* might look different, and one=
might be more complicated than the other, but it is the same to the user..=
<br><br></div><div>A map<> is not easy to implement.=C2=A0 But it loo=
ks easy to use from the outside.<br><br></div><div>And that is one of the g=
reat things about the STL - I don't need to implement map, only use it.=
<br></div><br><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0=
px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><=
div dir=3D"ltr"><div><br></div>This container doesn't aim to solve prob=
lems such as implementing large databases or solving large sets of simultan=
eous equations through matrix operations, boost already has some quite soph=
isticated solutions for this. The aim of this container is to provide progr=
ammers with a tool to safely manipulate small to medium sets of data that i=
s organised as rows and columns.</div><div class=3D"gmail_extra"><br></div>=
</blockquote><br></div><div class=3D"gmail_quote">So this is exactly what w=
e need to focus on - what is the aim, and was is NOT the aim. (Like you say=
, NOT solving equations, etc).<br><br></div><div class=3D"gmail_quote">So w=
e need to decide what trade-offs to make - which operations should be fast,=
which don't matter - do we expect users to traverse more, or insert/re=
move more?=C2=A0 Do they want to hold iterators, then insert/remove, then c=
ontinue to use those old iterators expecting them to still point to where t=
hey previously did?<br><br></div><div class=3D"gmail_quote">P.S. I specific=
ally bring up vector of vector, because it will, in many cases, probably be=
faster than a node-based container - even when doing significant inserts e=
tc.=C2=A0 Vectors keep data local in memory (ie keep cache lines happy), no=
de-based containers spread the data out across memory.=C2=A0 And allocation=
is slow (and typically requires a lock for thread safety).=C2=A0 So alloca=
ting a single node vs moving a bunch of data over in a vector... vector oft=
en wins.<br><br></div><div class=3D"gmail_quote">For example, I recently ch=
anged a k-d-tree (see wikipedia) from node-based to vector-based for a 40% =
speed up in searching.=C2=A0 It also sped up building the tree, but I don&#=
39;t really care about that - only searching matters - that's the prima=
ry purpose of a k-d-tree.<br><br></div><div class=3D"gmail_quote">For a tab=
le, we need to decide what matters, and what doesn't.<br><br></div><div=
class=3D"gmail_quote">Tony<br></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAOHCbivEq6bf%2B6j1AejSZvcg7zTX%3DsH6=
KB4eiNrWLZ5xNAzazg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOHCbivEq6bf=
%2B6j1AejSZvcg7zTX%3DsH6KB4eiNrWLZ5xNAzazg%40mail.gmail.com</a>.<br />
--001a1135ea06d01ca80530df94bf--
.
Author: Magnus Fromreide <magfr@lysator.liu.se>
Date: Wed, 20 Apr 2016 07:49:34 +0200
Raw View
On Tue, Apr 19, 2016 at 08:21:55PM -0400, Tony V E wrote:
> On Sat, Apr 16, 2016 at 1:06 PM, Michael Allwright <allsey87@gmail.com>
> wrote:
>
> >
> > I'm not exactly sure what you mean by ruling out vector-of-vector
> > implementations, I'm suggesting adding a new container to the standard, not
> > removing anything. The vector-of-vectors approach is certainly ok for
> > situations where the layout and dimensions of the table/matrix are
> > relatively fixed, but in the case where we need to add/remove/shift columns
> > and rows, the code to do this can be quite unsafe and bloated.
> >
> >
> When you define a container for the standard, you don't define how it is
> implemented, you only define how it looks from the outside - its API. You
> _somewhat_ limit how it might be implemented by providing certain
> guarantees - ie
>
> - do iterators get invalided when adding/removing (for examples in STL:
> vector yes, list no)
> - what is the O(n) time for inserting, removing, etc,
> - are the iterators ForwardIterators, BidirectionalIterators, or
> RandomAccessIterators, etc
> - etc
I could not agree more with this and would vey much see this added as a FAQ or
something to the group.
> > This container doesn't aim to solve problems such as implementing large
> > databases or solving large sets of simultaneous equations through matrix
> > operations, boost already has some quite sophisticated solutions for this.
> > The aim of this container is to provide programmers with a tool to safely
> > manipulate small to medium sets of data that is organised as rows and
> > columns.
> >
> >
> So this is exactly what we need to focus on - what is the aim, and was is
> NOT the aim. (Like you say, NOT solving equations, etc).
>
> So we need to decide what trade-offs to make - which operations should be
> fast, which don't matter - do we expect users to traverse more, or
> insert/remove more? Do they want to hold iterators, then insert/remove,
> then continue to use those old iterators expecting them to still point to
> where they previously did?
>
> P.S. I specifically bring up vector of vector, because it will, in many
> cases, probably be faster than a node-based container - even when doing
> significant inserts etc. Vectors keep data local in memory (ie keep cache
> lines happy), node-based containers spread the data out across memory. And
> allocation is slow (and typically requires a lock for thread safety). So
> allocating a single node vs moving a bunch of data over in a vector...
> vector often wins.
Here I have to say that I think the implementation using a vector with
striding iterators should be considered as well - given that the container
is small it might end up beeing faster than both vector-of-vectors and
linked webs.
This also have the advantage that the whole thing becomes an new adaptor
rather than a new container so you could put it on top of any random-
iterable container.
/MF
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/20160420054934.GA31261%40noemi.bahnhof.se.
.
Author: allsey87@gmail.com
Date: Wed, 20 Apr 2016 06:01:44 -0700 (PDT)
Raw View
------=_Part_1066_789671155.1461157304223
Content-Type: multipart/alternative;
boundary="----=_Part_1067_420164570.1461157304223"
------=_Part_1067_420164570.1461157304223
Content-Type: text/plain; charset=UTF-8
Hi Tony, Hi Magnus
> So this is exactly what we need to focus on - what is the aim, and was is
> > NOT the aim. (Like you say, NOT solving equations, etc).
>
I would like this container to representing spreadsheets or graphs (i.e.
graphs in the computer science context), and would like to be able to
add/remove rows/columns with O(1) and perhaps sort rows/columns with ~O(n
log n).
> So we need to decide what trade-offs to make - which operations should be
> > fast, which don't matter - do we expect users to traverse more, or
> > insert/remove more? Do they want to hold iterators, then insert/remove,
> > then continue to use those old iterators expecting them to still point
> to
> > where they previously did?
The main goal here is not in terms of performance, but rather to provide
users with a clean and safe way of working with tables, and to furthest
extent possible, an implementation of a table, where the iterators to
rows/columns can be passed to the functions in algorithms library (e.g.
fill, replace, copy_if, sort, shuffle, swap, accumulate, etc).
I find Magnus's idea of specifying the table as an adaptor (using std::list
or std::vector as the container) very attractive. This way the user could
select the underlying container based on their application specific
performance requirements:
1. For a matrix class for homogeneous transformations I inherit from the
table adapter, specifying std::vector as the container (good cache
locality, fast multiplication/inversion).
2. For a spreadsheet program, I might inherit from the table adapter with
std::list as the container (good performance for sorting, adding, removal
of columns and rows, and perhaps non-invalidating iterators).
I think this post has addressed most of the questions/ideas above, let me
know in either way!
Cheers,
Michael
>
>
> >
> > P.S. I specifically bring up vector of vector, because it will, in many
> > cases, probably be faster than a node-based container - even when doing
> > significant inserts etc. Vectors keep data local in memory (ie keep
> cache
> > lines happy), node-based containers spread the data out across memory.
> And
> > allocation is slow (and typically requires a lock for thread safety).
> So
> > allocating a single node vs moving a bunch of data over in a vector...
> > vector often wins.
>
> Here I have to say that I think the implementation using a vector with
> striding iterators should be considered as well - given that the container
> is small it might end up beeing faster than both vector-of-vectors and
> linked webs.
> This also have the advantage that the whole thing becomes an new adaptor
> rather than a new container so you could put it on top of any random-
> iterable container.
>
> /MF
>
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/35b837ca-0964-44cd-8836-919fca930df5%40isocpp.org.
------=_Part_1067_420164570.1461157304223
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Hi Tony, Hi Magnus<br><br><blockquote class=3D"gmail_quote=
" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding=
-left: 1ex;">> So this is exactly what we need to focus on - what is the=
aim, and was is
<br>> NOT the aim. (Like you say, NOT solving equations, etc).
<br></blockquote><div><br>I would like this container to representing sprea=
dsheets or graphs (i.e. graphs in the computer science context), and would =
like to be able to add/remove rows/columns with O(1) and perhaps sort rows/=
columns with ~O(n log n).<br><br><blockquote style=3D"margin: 0px 0px 0px 0=
..8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;" class=
=3D"gmail_quote">> So we need to decide what trade-offs to make - which =
operations should be
<br>> fast, which don't matter - do we expect users to traverse more=
, or
<br>> insert/remove more? =C2=A0Do they want to hold iterators, then ins=
ert/remove,
<br>> then continue to use those old iterators expecting them to still p=
oint to
<br>> where they previously did?</blockquote><br>The main goal here is n=
ot in terms of performance, but rather to provide users with a clean and sa=
fe way of working with tables, and to furthest extent possible, an implemen=
tation of a table, where the iterators to rows/columns can be passed to the=
functions in algorithms library (e.g. fill, replace, copy_if, sort, shuffl=
e, swap, accumulate, etc).<br><br>I find Magnus's idea of specifying th=
e table as an adaptor (using std::list or std::vector as the container) ver=
y attractive. This way the user could select the underlying container based=
on their application specific performance requirements:<br><br>1. For a ma=
trix class for homogeneous transformations I inherit from the table adapter=
, specifying std::vector as the container (good cache locality, fast multip=
lication/inversion).<br>2. For a spreadsheet program, I might inherit from =
the table adapter with std::list as the container (good performance for sor=
ting, adding, removal of columns and rows, and perhaps non-invalidating ite=
rators).<br><br>I think this post has addressed most of the questions/ideas=
above, let me know in either way!<br><br>Cheers,<br><br>Michael<br><br><br=
><br><br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=C2=A0<br=
>=C2=A0<br>>=20
<br>> P.S. I specifically bring up vector of vector, because it will, in=
many
<br>> cases, probably be faster than a node-based container - even when =
doing
<br>> significant inserts etc. =C2=A0Vectors keep data local in memory (=
ie keep cache
<br>> lines happy), node-based containers spread the data out across mem=
ory. =C2=A0And
<br>> allocation is slow (and typically requires a lock for thread safet=
y). =C2=A0So
<br>> allocating a single node vs moving a bunch of data over in a vecto=
r...
<br>> vector often wins.
<br>
<br>Here I have to say that I think the implementation using a vector with
<br>striding iterators should be considered as well - given that the contai=
ner
<br>is small it might end up beeing faster than both vector-of-vectors and
<br>linked webs.
<br>This also have the advantage that the whole thing becomes an new adapto=
r
<br>rather than a new container so you could put it on top of any random-
<br>iterable container.
<br>
<br>/MF
<br></blockquote></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/35b837ca-0964-44cd-8836-919fca930df5%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/35b837ca-0964-44cd-8836-919fca930df5=
%40isocpp.org</a>.<br />
------=_Part_1067_420164570.1461157304223--
------=_Part_1066_789671155.1461157304223--
.
Author: allsey87@gmail.com
Date: Wed, 20 Apr 2016 06:04:37 -0700 (PDT)
Raw View
------=_Part_101_232249629.1461157477837
Content-Type: multipart/alternative;
boundary="----=_Part_102_2037764539.1461157477837"
------=_Part_102_2037764539.1461157477837
Content-Type: text/plain; charset=UTF-8
Hi Tony, Hi Magnus
So this is exactly what we need to focus on - what is the aim, and was is
> NOT the aim. (Like you say, NOT solving equations, etc).
>
I would like this container to representing spreadsheets or graphs (i.e.
graphs in the computer science context), and would like to be able to
add/remove rows/columns with O(1) and perhaps sort rows/columns with ~O(n
log n).
So we need to decide what trade-offs to make - which operations should be
> fast, which don't matter - do we expect users to traverse more, or
> insert/remove more? Do they want to hold iterators, then insert/remove,
> then continue to use those old iterators expecting them to still point to
> where they previously did?
My main focus for this container would not be not in terms of performance,
but rather to provide users with a clean and safe way of working with
tables, and to furthest extent possible, an implementation of a table where
the iterators to rows/columns can be passed to the functions in algorithms
library (e.g. fill, replace, copy_if, sort, shuffle, swap, accumulate, etc).
I find Magnus's idea of specifying the table as an adaptor (using std::list
or std::vector as the container) very attractive. This way the user could
select the underlying container based on their application specific
performance requirements:
1. For a matrix class for homogeneous transformations I inherit from the
table adapter, specifying std::vector as the container (good cache
locality, fast multiplication/inversion).
2. For a spreadsheet program, I might inherit from the table adapter with
std::list as the container (good performance for sorting, adding, removal
of columns and rows, and perhaps non-invalidating iterators).
I think this post has addressed most of the questions/ideas above, let me
know in either way!
Cheers,
Michael
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/397ebf5a-b409-4147-956e-58ec4ab27df9%40isocpp.org.
------=_Part_102_2037764539.1461157477837
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Hi Tony, Hi Magnus<br><br><blockquote class=3D"gmail_quote=
" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-le=
ft:1ex">So this is exactly what we need to focus on - what is the aim, and =
was is
<br>NOT the aim. (Like you say, NOT solving equations, etc).
<br></blockquote><br>I would like this container to representing=20
spreadsheets or graphs (i.e. graphs in the computer science context),=20
and would like to be able to add/remove rows/columns with O(1) and=20
perhaps sort rows/columns with ~O(n log n).<br><br><blockquote style=3D"mar=
gin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1=
ex" class=3D"gmail_quote">So we need to decide what trade-offs to make - wh=
ich operations should be
<br>fast, which don't matter - do we expect users to traverse more, or
<br>insert/remove more? =C2=A0Do they want to hold iterators, then insert/r=
emove,
<br>then continue to use those old iterators expecting them to still point =
to
<br>where they previously did?</blockquote><br>My main focus for this conta=
iner would not be not in terms of performance, but rather to provide users =
with a clean
and safe way of working with tables, and to furthest extent possible,=20
an implementation of a table where the iterators to rows/columns can be
passed to the functions in algorithms library (e.g. fill, replace,=20
copy_if, sort, shuffle, swap, accumulate, etc).<br><br>I find Magnus's=
=20
idea of specifying the table as an adaptor (using std::list or=20
std::vector as the container) very attractive. This way the user could=20
select the underlying container based on their application specific=20
performance requirements:<br><br>1. For a matrix class for homogeneous=20
transformations I inherit from the table adapter, specifying std::vector
as the container (good cache locality, fast multiplication/inversion).<br>=
2.
For a spreadsheet program, I might inherit from the table adapter with=20
std::list as the container (good performance for sorting, adding,=20
removal of columns and rows, and perhaps non-invalidating iterators).<br><b=
r>I think this post has addressed most of the questions/ideas above, let me=
know in either way!<br><br>Cheers,<br><br>Michael<br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/397ebf5a-b409-4147-956e-58ec4ab27df9%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/397ebf5a-b409-4147-956e-58ec4ab27df9=
%40isocpp.org</a>.<br />
------=_Part_102_2037764539.1461157477837--
------=_Part_101_232249629.1461157477837--
.
Author: John Yates <john@yates-sheets.org>
Date: Wed, 20 Apr 2016 10:21:54 -0400
Raw View
--001a113603bec9d47d0530eb5058
Content-Type: text/plain; charset=UTF-8
Is 2D truly essential to this container?
I wonder whether it might not be ultimately more useful to enable
N-dimensional tables by building a dimension abstraction / adaptor. Then
your adaptor would focus on adding to vectors and lists the missing
semantics and functionality of behaving as a dimension.
- Is a dimension homogeneous (*i.e.* do all of its elements have
identical shape / cardinality)? If yes then:
- Can its elements be "reshaped"?
- Can a dimension be sparse? If yes then
- How is logical indexing implemented?
- How is mapping from logical to physical indexing represented?
- What are the semantics of indexing to a non-existent element?
Ideally a client could answer each question as either yes or no ona
dimension by dimension basis and thereby choose varying degrees of
efficiency versus flexibility.
/john
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJnXXojNQ-2PDP3r1agdAKrFYNBxPDy1ztcASrHKJ2x6xqcf2g%40mail.gmail.com.
--001a113603bec9d47d0530eb5058
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra">Is 2D truly essential to this c=
ontainer?</div><div class=3D"gmail_extra"><br></div><div class=3D"gmail_ext=
ra">I wonder whether it might not be ultimately more useful to enable N-dim=
ensional tables by building a dimension abstraction / adaptor.=C2=A0 Then y=
our adaptor would focus on adding to vectors and lists the missing semantic=
s and functionality of behaving as a dimension.<br></div><div class=3D"gmai=
l_extra"><ul><li>Is a dimension homogeneous (<i>i.e.</i>=C2=A0do all of its=
elements have identical shape / cardinality)?=C2=A0 If yes then:</li></ul>=
<ul><ul><li>Can its elements be "reshaped"?</li></ul></ul><ul><li=
>Can a dimension be sparse?=C2=A0 If yes then<br></li><ul><li>How is logica=
l indexing implemented?</li><li>How is mapping from logical to physical ind=
exing represented?</li><li>What are the semantics of indexing to a non-exis=
tent element?</li></ul></ul><div>Ideally a client could answer each questio=
n as either yes or no ona dimension by dimension basis and thereby choose v=
arying degrees of efficiency versus flexibility.</div><div><br></div><div>/=
john</div><div><br></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAJnXXojNQ-2PDP3r1agdAKrFYNBxPDy1ztcA=
SrHKJ2x6xqcf2g%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJnXXojNQ-2PDP3r=
1agdAKrFYNBxPDy1ztcASrHKJ2x6xqcf2g%40mail.gmail.com</a>.<br />
--001a113603bec9d47d0530eb5058--
.
Author: Tony V E <tvaneerd@gmail.com>
Date: Wed, 20 Apr 2016 10:44:27 -0400
Raw View
<html><head></head><body lang=3D"en-US" style=3D"background-color: rgb(255,=
255, 255); line-height: initial;"> =
<div style=3D"width: 100%; fo=
nt-size: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif=
; color: rgb(31, 73, 125); text-align: initial; background-color: rgb(255, =
255, 255);">There is/are array_span proposal(s) that do things like this, f=
or contiguous memory, not nodes. </div> =
=
<div style=3D"width: 100%; font-size: initial; font-f=
amily: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125=
); text-align: initial; background-color: rgb(255, 255, 255);"><br style=3D=
"display:initial"></div> =
=
<div s=
tyle=3D"font-size: initial; font-family: Calibri, 'Slate Pro', sans-serif, =
sans-serif; color: rgb(31, 73, 125); text-align: initial; background-color:=
rgb(255, 255, 255);">Sent from my BlackBerry portable&=
nbsp;Babbage Device</div> =
=
<table width=3D"1=
00%" style=3D"background-color:white;border-spacing:0px;"> <tbody><tr><td c=
olspan=3D"2" style=3D"font-size: initial; text-align: initial; background-c=
olor: rgb(255, 255, 255);"> <div style=3D"border-=
style: solid none none; border-top-color: rgb(181, 196, 223); border-top-wi=
dth: 1pt; padding: 3pt 0in 0in; font-family: Tahoma, 'BB Alpha Sans', 'Slat=
e Pro'; font-size: 10pt;"> <div><b>From: </b>John Yates</div><div><b>Sent:=
</b>Wednesday, April 20, 2016 10:21 AM</div><div><b>To: </b>std-proposals@=
isocpp.org</div><div><b>Reply To: </b>std-proposals@isocpp.org</div><div><b=
>Subject: </b>Re: [std-proposals] Linked std::table / std::matrix proposal<=
/div></div></td></tr></tbody></table><div style=3D"border-style: solid none=
none; border-top-color: rgb(186, 188, 209); border-top-width: 1pt; font-si=
ze: initial; text-align: initial; background-color: rgb(255, 255, 255);"></=
div><br><div id=3D"_originalContent" style=3D""><div dir=3D"ltr"><div class=
=3D"gmail_extra">Is 2D truly essential to this container?</div><div class=
=3D"gmail_extra"><br></div><div class=3D"gmail_extra">I wonder whether it m=
ight not be ultimately more useful to enable N-dimensional tables by buildi=
ng a dimension abstraction / adaptor. Then your adaptor would focus o=
n adding to vectors and lists the missing semantics and functionality of be=
having as a dimension.<br></div><div class=3D"gmail_extra"><ul><li>Is a dim=
ension homogeneous (<i>i.e.</i> do all of its elements have identical =
shape / cardinality)? If yes then:</li></ul><ul><ul><li>Can its eleme=
nts be "reshaped"?</li></ul></ul><ul><li>Can a dimension be sparse? I=
f yes then<br></li><ul><li>How is logical indexing implemented?</li><li>How=
is mapping from logical to physical indexing represented?</li><li>What are=
the semantics of indexing to a non-existent element?</li></ul></ul><div>Id=
eally a client could answer each question as either yes or no ona dimension=
by dimension basis and thereby choose varying degrees of efficiency versus=
flexibility.</div><div><br></div><div>/john</div><div><br></div></div></di=
v>
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAJnXXojNQ-2PDP3r1agdAKrFYNBxPDy1ztcA=
SrHKJ2x6xqcf2g%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJnXXojNQ-2P=
DP3r1agdAKrFYNBxPDy1ztcASrHKJ2x6xqcf2g%40mail.gmail.com</a>.<br>
<br><!--end of _originalContent --></div></body></html>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/20160420144427.4911184.59623.10028%40=
gmail.com?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.com=
/a/isocpp.org/d/msgid/std-proposals/20160420144427.4911184.59623.10028%40gm=
ail.com</a>.<br />
.
Author: allsey87@gmail.com
Date: Wed, 20 Apr 2016 08:03:29 -0700 (PDT)
Raw View
------=_Part_643_438268001.1461164609940
Content-Type: multipart/alternative;
boundary="----=_Part_644_1125070306.1461164609940"
------=_Part_644_1125070306.1461164609940
Content-Type: text/plain; charset=UTF-8
Hi John,
I think as a starting point trying to implement an adaptor that provides 2D
access to a 1D container (such as list or vector) will suffice. If there is
enough interest, and assuming it doesn't overcomplicate the adaptor, we
could then generalise the adaptor into more dimensions.
In my mind, dimensions can have different cardinality, i.e. a table with
three rows, and two columns. All elements are of type T (fixed) which is
the first argument to the table adaptor's template. For the moment, I would
not consider sparse dimensions, although if there is enough interest, this
could be added later on - although I suspect it would be better to have
such a concept in a different adaptor/proposal, perhaps for a sparse_table<>
On Wednesday, 20 April 2016 16:21:57 UTC+2, John Yates wrote:
>
> Is 2D truly essential to this container?
>
> I wonder whether it might not be ultimately more useful to enable
> N-dimensional tables by building a dimension abstraction / adaptor. Then
> your adaptor would focus on adding to vectors and lists the missing
> semantics and functionality of behaving as a dimension.
>
> - Is a dimension homogeneous (*i.e.* do all of its elements have
> identical shape / cardinality)? If yes then:
>
>
> - Can its elements be "reshaped"?
>
>
> - Can a dimension be sparse? If yes then
> - How is logical indexing implemented?
> - How is mapping from logical to physical indexing represented?
> - What are the semantics of indexing to a non-existent element?
>
> Ideally a client could answer each question as either yes or no ona
> dimension by dimension basis and thereby choose varying degrees of
> efficiency versus flexibility.
>
> /john
>
>
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/83e8c40b-c9f2-427d-a20d-5bcb5025c813%40isocpp.org.
------=_Part_644_1125070306.1461164609940
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Hi John,<br><br>I think as a starting point trying to impl=
ement an adaptor that provides 2D access to a 1D container (such as list or=
vector) will suffice. If there is enough interest, and assuming it doesn&#=
39;t overcomplicate the adaptor, we could then generalise the adaptor into =
more dimensions.<br><br>In my mind, dimensions can have different cardinali=
ty, i.e. a table with three rows, and two columns. All elements are of type=
T (fixed) which is the first argument to the table adaptor's template.=
For the moment, I would not consider sparse dimensions, although if there =
is enough interest, this could be added later on - although I suspect it wo=
uld be better to have such a concept in a different adaptor/proposal, perha=
ps for a sparse_table<><br><br>On Wednesday, 20 April 2016 16:21:57 U=
TC+2, John Yates wrote:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr"><div>Is 2D truly essential to this container?</div><div><br></di=
v><div>I wonder whether it might not be ultimately more useful to enable N-=
dimensional tables by building a dimension abstraction / adaptor.=C2=A0 The=
n your adaptor would focus on adding to vectors and lists the missing seman=
tics and functionality of behaving as a dimension.<br></div><div><ul><li>Is=
a dimension homogeneous (<i>i.e.</i>=C2=A0do all of its elements have iden=
tical shape / cardinality)?=C2=A0 If yes then:</li></ul><ul><ul><li>Can its=
elements be "reshaped"?</li></ul></ul><ul><li>Can a dimension be=
sparse?=C2=A0 If yes then<br></li><ul><li>How is logical indexing implemen=
ted?</li><li>How is mapping from logical to physical indexing represented?<=
/li><li>What are the semantics of indexing to a non-existent element?</li><=
/ul></ul><div>Ideally a client could answer each question as either yes or =
no ona dimension by dimension basis and thereby choose varying degrees of e=
fficiency versus flexibility.</div><div><br></div><div>/john</div><div><br>=
</div></div></div>
</blockquote></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/83e8c40b-c9f2-427d-a20d-5bcb5025c813%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/83e8c40b-c9f2-427d-a20d-5bcb5025c813=
%40isocpp.org</a>.<br />
------=_Part_644_1125070306.1461164609940--
------=_Part_643_438268001.1461164609940--
.
Author: allsey87@gmail.com
Date: Wed, 20 Apr 2016 09:03:22 -0700 (PDT)
Raw View
------=_Part_29_88942857.1461168202702
Content-Type: multipart/alternative;
boundary="----=_Part_30_1273586745.1461168202702"
------=_Part_30_1273586745.1461168202702
Content-Type: text/plain; charset=UTF-8
Although, if digress for a moment, using a very similar adaptor to what I
am describing with a std::map<unsigned int, value_type> where the key is
the index of dimension 1, plus the number of elements of dimension 1
multiplied by the index of dimension 2 and so forth, would allow one to
quickly realise a sparse_table<>. Although... every time you change the
cardinality of one of the dimensions, you would need to recalculate all
keys and rebuild the map, which isn't so elegant. Either way, I would
propose leaving the concept of a sparse_table<> aside at least until we
have a working implementation of a table<> adaptor.
On Wednesday, 20 April 2016 16:21:57 UTC+2, John Yates wrote:
>
> Is 2D truly essential to this container?
>
> I wonder whether it might not be ultimately more useful to enable
> N-dimensional tables by building a dimension abstraction / adaptor. Then
> your adaptor would focus on adding to vectors and lists the missing
> semantics and functionality of behaving as a dimension.
>
> - Is a dimension homogeneous (*i.e.* do all of its elements have
> identical shape / cardinality)? If yes then:
>
>
> - Can its elements be "reshaped"?
>
>
> - Can a dimension be sparse? If yes then
> - How is logical indexing implemented?
> - How is mapping from logical to physical indexing represented?
> - What are the semantics of indexing to a non-existent element?
>
> Ideally a client could answer each question as either yes or no ona
> dimension by dimension basis and thereby choose varying degrees of
> efficiency versus flexibility.
>
> /john
>
>
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/118af229-5207-4c17-ba92-54fc7547f00b%40isocpp.org.
------=_Part_30_1273586745.1461168202702
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Although, if digress for a moment, using a very similar ad=
aptor to what I am describing with a std::map<unsigned int, value_type&g=
t; where the key is the index of dimension 1, plus the number of elements o=
f dimension 1 multiplied by the index of dimension 2 and so forth, would al=
low one to quickly realise a sparse_table<>. Although... every time y=
ou change the cardinality of one of the dimensions, you would need to recal=
culate all keys and rebuild the map, which isn't so elegant. Either way=
, I would propose leaving the concept of a sparse_table<> aside at le=
ast until we have a working implementation of a table<> adaptor.<br><=
br>On Wednesday, 20 April 2016 16:21:57 UTC+2, John Yates wrote:<blockquot=
e class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: =
1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>Is 2D truly essent=
ial to this container?</div><div><br></div><div>I wonder whether it might n=
ot be ultimately more useful to enable N-dimensional tables by building a d=
imension abstraction / adaptor.=C2=A0 Then your adaptor would focus on addi=
ng to vectors and lists the missing semantics and functionality of behaving=
as a dimension.<br></div><div><ul><li>Is a dimension homogeneous (<i>i.e.<=
/i>=C2=A0do all of its elements have identical shape / cardinality)?=C2=A0 =
If yes then:</li></ul><ul><ul><li>Can its elements be "reshaped"?=
</li></ul></ul><ul><li>Can a dimension be sparse?=C2=A0 If yes then<br></li=
><ul><li>How is logical indexing implemented?</li><li>How is mapping from l=
ogical to physical indexing represented?</li><li>What are the semantics of =
indexing to a non-existent element?</li></ul></ul><div>Ideally a client cou=
ld answer each question as either yes or no ona dimension by dimension basi=
s and thereby choose varying degrees of efficiency versus flexibility.</div=
><div><br></div><div>/john</div><div><br></div></div></div>
</blockquote></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/118af229-5207-4c17-ba92-54fc7547f00b%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/118af229-5207-4c17-ba92-54fc7547f00b=
%40isocpp.org</a>.<br />
------=_Part_30_1273586745.1461168202702--
------=_Part_29_88942857.1461168202702--
.
Author: Magnus Fromreide <magfr@lysator.liu.se>
Date: Wed, 20 Apr 2016 22:50:15 +0200
Raw View
On Wed, Apr 20, 2016 at 06:04:37AM -0700, allsey87@gmail.com wrote:
> Hi Tony, Hi Magnus
>
> I find Magnus's idea of specifying the table as an adaptor (using std::list
> or std::vector as the container) very attractive. This way the user could
> select the underlying container based on their application specific
> performance requirements:
I do not claim that idea as mine, we already *almost* have it in the library
in the form of std::valarray.
Also note that I required the container to be RandomIterable, so std::list is
out but you could use a std::deque.
/MF
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/20160420205015.GB892%40noemi.bahnhof.se.
.
Author: allsey87@gmail.com
Date: Thu, 21 Apr 2016 00:57:58 -0700 (PDT)
Raw View
------=_Part_92_84434221.1461225478662
Content-Type: multipart/alternative;
boundary="----=_Part_93_1011426713.1461225478662"
------=_Part_93_1011426713.1461225478662
Content-Type: text/plain; charset=UTF-8
On Wednesday, 20 April 2016 22:50:20 UTC+2, Magnus Fromreide wrote:
> Also note that I required the container to be RandomIterable, so std::list
> is
> out but you could use a std::deque.
>
I don't see why the underlying container would have to be RandomIterable
not just ForwardIterable. The stride iterator for the columns could just be
implemented using std::advance which automatically selects operator++ or
operator+ depending to the capabilities of the iterator.
I'm not sure whether it is plausible from an implementation standpoint, but
I think it would be nice if the characteristics of the underlying
container's iterability would also apply to the column and row iterators.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e092f6e1-3d5d-487c-8fb3-e27314be9d9f%40isocpp.org.
------=_Part_93_1011426713.1461225478662
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Wednesday, 20 April 2016 22:50:20 UTC+2, Magnus Fromrei=
de wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Also note that I=
required the container to be RandomIterable, so std::list is
<br>out but you could use a std::deque.
<br></blockquote><div><br>I don't see why the underlying container woul=
d have to be RandomIterable not just ForwardIterable. The stride iterator f=
or the columns could just be implemented using std::advance which automatic=
ally selects operator++ or operator+ depending to the capabilities of the i=
terator.<br><br>I'm not sure whether it is plausible from an implementa=
tion standpoint, but I think it would be nice if the characteristics of the=
underlying container's iterability would also apply to the column and =
row iterators.<br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/e092f6e1-3d5d-487c-8fb3-e27314be9d9f%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/e092f6e1-3d5d-487c-8fb3-e27314be9d9f=
%40isocpp.org</a>.<br />
------=_Part_93_1011426713.1461225478662--
------=_Part_92_84434221.1461225478662--
.
Author: =?UTF-8?Q?Klaim_=2D_Jo=C3=ABl_Lamotte?= <mjklaim@gmail.com>
Date: Sat, 23 Apr 2016 22:17:18 +0200
Raw View
--001a11442b1a5be91405312ca107
Content-Type: text/plain; charset=UTF-8
(sorry I didn't have the time to read all the discussions, I'll just get to
the points I think important)
Overall I like the core idea. However:
On 15 April 2016 at 12:25, <allsey87@gmail.com> wrote:
> The aim of this container would be to represent graphs, tables, and small
> to medium size matrices.
With this aim in mind, I suggest that you make sure that you define the API
to allow an implementation which uses 2d blocks subdivision of the table.
That is, if you have a table of Thing of 100 columns and 100 rows, it can
be managed internally as
static const size_t block_size = block_rows * block_cols; // determined
by some context-dependent algorithm which take into account memory layout
and object size
using block = std::array<Thing, block_size>; // each block is a 2D
array of values, corresponding to a patch of the complete table
flat_map< block_pos, unique_ptr<block> >; // block_pos can be generated
from the position of a slot in the table
It would
- limit the cache issues of a list implementation when going though
elements one by one;
- it would let still allow somewhat fast lookup from a slot position;
- it would limit allocations, compared to list, but still allow dynamic
expansion without copy/move like vectors
- if you give access to blocks, maybe there are ways for algorithms to
optimize work to avoid cache issues - but I didn't try so I'm not sure;
- it avoids growth issues that you could get with vectors when the table
become massive;
I believe that some tools like Photoshop work with this kind of table of
picture patches (with different levels of details) and it helps for a lot
of things.
Another suggestion I would consider important would be to provide these
variants of the idea:
1. a table with compile-time size;
2. a table with construction-time fixed size;
3. a table that can grow it size dynamically;
Theorically 2 and 3 can be the same (like std::vector) but in practice they
should not allow the same operations (like the need for vectors of fixed
max sizes).
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOU91ONBUizSRH8FUdJKMnu-PqhVKkekc_C-G_ZDrhKvxVy_pg%40mail.gmail.com.
--001a11442b1a5be91405312ca107
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra">(sorry I didn't have the ti=
me to read all the discussions, I'll just get to the points I think imp=
ortant)</div><div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra=
">Overall I like the core idea. However:</div><div class=3D"gmail_extra"><b=
r><div class=3D"gmail_quote">On 15 April 2016 at 12:25, <span dir=3D"ltr">=
<<a href=3D"mailto:allsey87@gmail.com" target=3D"_blank">allsey87@gmail.=
com</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,2=
04);border-left-style:solid;padding-left:1ex"><span style=3D"font-family:&#=
39;courier new',monospace">The aim of this container would be to r</spa=
n><span style=3D"font-family:'courier new',monospace"><span style=
=3D"font-family:'courier new',monospace">epresent graphs, tables, a=
nd small to medium size matrices. </span></span></blockquote></div><br>With=
this aim in mind, I suggest that you make sure that you define the API to =
allow an implementation which uses 2d blocks subdivision of the table.</div=
><div class=3D"gmail_extra">That is, if you have a table of Thing of 100 co=
lumns and 100 rows, it can be managed internally as</div><div class=3D"gmai=
l_extra"><br></div><div class=3D"gmail_extra">=C2=A0 =C2=A0 static const si=
ze_t block_size =3D block_rows * block_cols; // determined by some context-=
dependent algorithm which take into account memory layout and object size</=
div><div class=3D"gmail_extra">=C2=A0 =C2=A0 using block =3D std::array<=
Thing, block_size>; // each block is a 2D array of values, corresponding=
to a patch of the complete table</div><div class=3D"gmail_extra">=C2=A0 =
=C2=A0 flat_map< block_pos, unique_ptr<block> >; // block_pos c=
an be generated from the position of a slot in the table</div><div class=3D=
"gmail_extra"><br></div><div class=3D"gmail_extra">It would</div><div class=
=3D"gmail_extra">=C2=A0 - limit the cache issues of a list implementation w=
hen going though elements one by one;</div><div class=3D"gmail_extra">=C2=
=A0 - it would let still allow somewhat fast lookup from a slot position;</=
div><div class=3D"gmail_extra">=C2=A0 - it would limit allocations, compare=
d to list, but still allow dynamic expansion without copy/move like vectors=
</div><div class=3D"gmail_extra">=C2=A0 - if you give access to blocks, may=
be there are ways for algorithms to optimize work to avoid cache issues - b=
ut I didn't try so I'm not sure;</div><div class=3D"gmail_extra">=
=C2=A0 - it avoids growth issues that you could get with vectors when the t=
able become massive;</div><div class=3D"gmail_extra"><br></div><div class=
=3D"gmail_extra">I believe that some tools like Photoshop work with this ki=
nd of table of picture patches (with different levels of details) and it he=
lps for a lot of things.</div><div class=3D"gmail_extra"><br></div><div cla=
ss=3D"gmail_extra">Another suggestion I would consider important would be t=
o provide these variants of the idea:</div><div class=3D"gmail_extra">=C2=
=A01. a table with compile-time size;</div><div class=3D"gmail_extra">=C2=
=A02. a table with construction-time fixed size;</div><div class=3D"gmail_e=
xtra">=C2=A03. a table that can grow it size dynamically;</div><div class=
=3D"gmail_extra"><br></div><div class=3D"gmail_extra">Theorically 2 and 3 c=
an be the same (like std::vector) but in practice they should not allow the=
same operations (like the need for vectors of fixed max sizes).</div><div =
class=3D"gmail_extra"><br></div><div class=3D"gmail_extra"><br></div><div c=
lass=3D"gmail_extra"><br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAOU91ONBUizSRH8FUdJKMnu-PqhVKkekc_C-=
G_ZDrhKvxVy_pg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOU91ONBUizSRH8F=
UdJKMnu-PqhVKkekc_C-G_ZDrhKvxVy_pg%40mail.gmail.com</a>.<br />
--001a11442b1a5be91405312ca107--
.
Author: allsey87@gmail.com
Date: Thu, 28 Apr 2016 01:41:23 -0700 (PDT)
Raw View
------=_Part_189_1050687022.1461832883634
Content-Type: multipart/alternative;
boundary="----=_Part_190_744885707.1461832883634"
------=_Part_190_744885707.1461832883634
Content-Type: text/plain; charset=UTF-8
Hi,
With this aim in mind, I suggest that you make sure that you define the API
> to allow an implementation which uses 2d blocks subdivision of the table.
> That is, if you have a table of Thing of 100 columns and 100 rows, it can
> be managed internally as
>
The ideas you have mentioned are interesting and worthwhile investigating.
I would suggest the following approach: first a very simple prototype and
test bench is developed that allows us to determine a functional API for
the table, such that we can ensure good usability and correctness. From
here we can start optimising the implementation, looking at what is
possible in terms of time complexity and cache performance. We can then
feed these results back into the proposal as constraints on the
implementation (e.g. operation X when using container Y as the adaptor must
be O(Z) or better etc)
Michael
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/9fda39d6-7c6f-4993-9fca-275c2f26ccf7%40isocpp.org.
------=_Part_190_744885707.1461832883634
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Hi,<br><br><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr"><div>With this aim in mind, I suggest that you make sure tha=
t you define the API to allow an implementation which uses 2d blocks subdiv=
ision of the table.</div><div>That is, if you have a table of Thing of 100 =
columns and 100 rows, it can be managed internally as</div></div></blockquo=
te><div><br>The ideas you have mentioned are interesting and worthwhile inv=
estigating. I would suggest the following approach: first a very simple pro=
totype and test bench is developed that allows us to determine a functional=
API for the table, such that we can ensure good usability and correctness.=
From here we can start optimising the implementation, looking at what is p=
ossible in terms of time complexity and cache performance. We can then feed=
these results back into the proposal as constraints on the implementation =
(e.g. operation X when using container Y as the adaptor must be O(Z) or bet=
ter etc)<br><br>Michael<br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/9fda39d6-7c6f-4993-9fca-275c2f26ccf7%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/9fda39d6-7c6f-4993-9fca-275c2f26ccf7=
%40isocpp.org</a>.<br />
------=_Part_190_744885707.1461832883634--
------=_Part_189_1050687022.1461832883634--
.
Author: Feng Wang <c0xt30a@gmail.com>
Date: Fri, 1 Jul 2016 08:31:46 -0700 (PDT)
Raw View
------=_Part_2235_347442037.1467387106928
Content-Type: multipart/alternative;
boundary="----=_Part_2236_1755109892.1467387106928"
------=_Part_2236_1755109892.1467387106928
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Hi,
I am doing numeric computation thus heavily using matrix in C++. I would=20
like to provide some suggestions based on my home-made matrix library:
+ Homogeneous interface as vector, list, ..., providing similar interfaces=
=20
like size, clear, swap, resize, and similar constructor=20
template< typename T, tyepname Alloc =3D std::allocator<T> >=20
struct matrix;
+ add more iterators, for diagonal and off-diagonal elements for ~matrix m~=
=20
and ~index~ as matrix is a 2D object, and in numeric process such as=20
decompositions and transformations the elements in a specific row, column=
=20
or diagonal is specially interested
- normal iterators
* m.begin(), m.end, m.rbegin(), m.rend(), m.cbegin(), m.cend(),=20
m.crbegin(), m.crend()
- column iterators
* m.col_begin(index), m.col_end(index), m.col_rbegin(index),=20
m.col_rend(index), m.col_cbegin(index), m.col_cend(index),=20
m.col_crbegin(index), m.col_crend(index)
- row iterators
* m.row_begin(index), m.row_end(index), m.row_rbegin(index),=20
m.row_rend(index), m.row_cbegin(index), m.row_cend(index),=20
m.row_crbegin(index), m.row_crend(index)
- diag iterators
* m.diag_begin(index), m.diag_end(index), m.diag_rbegin(index),=20
m.diag_rend(index), m.diag_cbegin(index), m.diag_cend(index),=20
m.diag_crbegin(index), m.diag_crend(index)
- diag iterators
* m.diag_begin(index), m.diag_end(index), m.diag_rbegin(index),=20
m.diag_rend(index), m.diag_cbegin(index), m.diag_cend(index),=20
m.diag_crbegin(index), m.diag_crend(index)
- anti-diag/cross-diag iterators
* m.anti_diag_begin(index), m.anti_diag_end(index),=20
m.anti_diag_rbegin(index), m.anti_diag_rend(index),=20
m.anti_diag_cbegin(index), m.anti_diag_cend(index),=20
m.anti_diag_crbegin(index), m.anti_diag_crend(index)
+ Numeric algorithms [refer to linear algebra category of matlab at=20
http://de.mathworks.com/help/matlab/linear-algebra.html], it is even better=
=20
to have a Matlab colone in C++
+ decompositions
- lu
- svd
- cholesky
- qr
- eigenvalue
- ...
+ special functions=20
- det
- norm
- sin
- cos
- exp
- pow
- fft
- ifft
- ...
+ linear equations
=20
+ normal operators, such as =3D, +=3D, +, -=3D, -, *=3D, *, /=3D, /, ..=
..
=20
Best regards,
Feng
=E5=9C=A8 2016=E5=B9=B44=E6=9C=8815=E6=97=A5=E6=98=9F=E6=9C=9F=E4=BA=94 UTC=
+2=E4=B8=8B=E5=8D=8812:38:01=EF=BC=8Calls...@gmail.com=E5=86=99=E9=81=93=EF=
=BC=9A
>
> Hi Everyone,
>
> I'm considering implementing a new container called either std::table or=
=20
> std::matrix. The data structure would be similar to std::list as elements=
=20
> would be linked together through pointers/iterators. The aim of this data=
=20
> structure is *not* to create a high performance matrix, that tries to sol=
ve=20
> every single problem. There are always trade-offs in the design of=20
> matrices, and for high performance situations, it is probably better to=
=20
> use, e.g. in computer vision, opencv's Mat class. Keeping this in mind,=
=20
> conceptually the table/matrix that I am proposing would like this:
>
>
> | std::begin(col) | std::begin(col) |
> | --------------- | --------------- | --------------- | ------------- |
> | std::begin(row) | element 0,0 | element 0,1 | std::end(row) |
> | std::begin(row) | element 1,0 | element 1,1 | std::end(row) |
> | std::begin(row) | element 2,0 | element 2,1 | std::end(row) |
> | --------------- | --------------- | --------------- | ------------- |
> | std::end(col) | std::end(col) |
>
>
> In this design, two bidirectional (or forward) iterators are kept in each=
=20
> element for iterating across the rows and columns. I would imagine simila=
r=20
> to a std::list, that this would enable the removing/adding of rows/column=
s=20
> without invalidating other row/column/element iterators, and also avoid=
=20
> moving all elements when a row/column is deleted.
>
> The motivation for using this layout over a=20
> std::vector<std::vector<double> > (vector inside a vector) is that the=20
> vector inside a vector approach can be unsafe and prone to bugs. I have=
=20
> just written the code for removing/adding rows/columns for the vector=20
> inside a vector approach, and while it is ok for the first dimension,=20
> working in the second dimension is painful. Not to mention, one has to=20
> constantly check if the table/matrix is well formed (i.e. equal number of=
=20
> elements in each row/column)
>
> The aim of this container would be to represent graphs, tables, and small=
=20
> to medium size matrices. I would like to also draw attention to the fact,=
=20
> that although syntax to access matrix elements in most libraries often=20
> appears as either my_matrix.at(2,3) or my_matrix[2][3], the actual access=
=20
> to the data is not often random, but rather linear across a given column =
or=20
> row (consider matrix multiplication). Furthermore, assuming all memory fo=
r=20
> the matrix is allocated once dynamically in the constructor, the=20
> performance for doing e.g. multiplication of two matrices would be=20
> reasonable since all elements should make there way into the higher level=
s=20
> of the cache after the first miss.
>
> From a user stand point, I would like the following sorts of operations t=
o=20
> be possible:
>
> /* 1. construction / use of initialization list */
> std::table<double> my_table(3,2) =3D {
> 11, 12,
> 21, 22,
> 31, 32
> };
>
> std::cout << my_table.size(); // 6
>
> // element-wise iteration - important notes 1. random access iterators no=
t=20
> supported, 2. individual elements can not be erased
> for(auto el : my_table) {
> std::cout << el << std::end;
> }
> // or
> for(auto it_el =3D std::begin(my_table); it_el !=3D std::end(my_table);=
=20
> it_el++) {
> std::cout << *it_el << std::end;
> }
>
> /* 2. copy all values, column by column into a std::vector */
> std::vector<double> vector_values;
>
> for(const auto& col : my_table.get_cols()) {
> vector_values.insert(std::end(vector_values), std::begin(col),=20
> std::end(col));
> }
>
> /* 3. set all elements to forty two */
> for(auto& row : my_table.get_rows()) {
> for(auto& el : row) {
> el =3D 42.0f;
> }
> }
>
> /* 4. insert elements from a list or vector */
> // the type of iterator returned from std::end(my_table.get_rows()) or=20
> std::end(my_table.get_cols()) determines the orientation */
> std::list<double> list_values =3D {
> 42, 21;
> };
> // may throw exception if dimension mismatch, or alternatively=20
> truncate/default construct missing elements */
> my_table.insert(std::end(my_table.get_rows()), std::begin(list_values),=
=20
> std::end(list_values));
>
> /* 5. algorithms / erase-remove idiom applied to columns */
> // note since we work with columns and rows in matrices, remove(_if) is=
=20
> extended to remove(_if)_any, remove(_if)_all, remove_if_none
>
> my_table.erase( std::remove_if_none( std::begin(my_table.get_cols()),=20
> std::begin(my_table.get_cols()), [] (double el) { return (el =3D=3D 42);}=
),=20
> std::end(my_table.get_cols));
>
> /* 6. add row at beginning of table */
> my_table.add_row(std::begin(my_table.get_rows()));
>
> Any thoughts or counter proposals? Reasons why this is a bad idea?
>
>
>
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/77c22fd8-0fd2-47a3-9408-f0eacde9d1e8%40isocpp.or=
g.
------=_Part_2236_1755109892.1467387106928
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Hi,</div><div><br></div><div>I am doing numeric compu=
tation thus heavily using matrix in C++. I would like to provide some sugge=
stions based on my home-made matrix library:</div><div><br></div><div>+ Hom=
ogeneous interface as vector, list, ..., providing similar interfaces like =
size, clear, swap, resize, and similar constructor=C2=A0</div><div><br></di=
v><div>=C2=A0 =C2=A0 template< typename T, tyepname Alloc =3D std::alloc=
ator<T> >=C2=A0</div><div>=C2=A0 =C2=A0 struct matrix;</div><div><=
br></div><div>+ add more iterators, for diagonal and off-diagonal elements =
for ~matrix m~ and ~index~ as matrix is a 2D object, and in numeric process=
such as decompositions and transformations the elements in a specific row,=
column or diagonal is specially interested</div><div>=C2=A0 =C2=A0 - norma=
l iterators</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 * m.begin(), m.end, m.rbe=
gin(), m.rend(), m.cbegin(), m.cend(), m.crbegin(), m.crend()</div><div>=C2=
=A0 =C2=A0 - column iterators</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 * m.col=
_begin(index), m.col_end(index), m.col_rbegin(index), m.col_rend(index), m.=
col_cbegin(index), m.col_cend(index), m.col_crbegin(index), m.col_crend(ind=
ex)</div><div>=C2=A0 =C2=A0 - row iterators</div><div>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 * m.row_begin(index), m.row_end(index), m.row_rbegin(index), m.row_r=
end(index), m.row_cbegin(index), m.row_cend(index), m.row_crbegin(index), m=
..row_crend(index)</div><div>=C2=A0 =C2=A0 - diag iterators</div><div>=C2=A0=
=C2=A0 =C2=A0 =C2=A0* m.diag_begin(index), m.diag_end(index), m.diag_rbegi=
n(index), m.diag_rend(index), m.diag_cbegin(index), m.diag_cend(index), m.d=
iag_crbegin(index), m.diag_crend(index)</div><div><div>=C2=A0 =C2=A0 - diag=
iterators</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0* m.diag_begin(index), m.di=
ag_end(index), m.diag_rbegin(index), m.diag_rend(index), m.diag_cbegin(inde=
x), m.diag_cend(index), m.diag_crbegin(index), m.diag_crend(index)</div></d=
iv><div><div>=C2=A0 =C2=A0 - anti-diag/cross-diag iterators</div><div>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0* m.anti_diag_begin(index), m.anti_diag_end(index),=
m.anti_diag_rbegin(index), m.anti_diag_rend(index), m.anti_diag_cbegin(ind=
ex), m.anti_diag_cend(index), m.anti_diag_crbegin(index), m.anti_diag_crend=
(index)</div></div><div><br></div><div>+ Numeric algorithms [refer to linea=
r algebra category of matlab at http://de.mathworks.com/help/matlab/linear-=
algebra.html], it is even better to have a Matlab colone in C++</div><div>=
=C2=A0 =C2=A0 + decompositions</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 - lu</=
div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 - svd</div><div>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 - cholesky</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 - qr</div><div>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 - eigenvalue</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0=
- ...</div><div>=C2=A0 =C2=A0 + special functions=C2=A0</div><div>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 - det</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 - norm</di=
v><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 - sin</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 - cos</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 - exp</div><div>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 - pow</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 - fft</div><d=
iv>=C2=A0 =C2=A0 =C2=A0 =C2=A0 - ifft</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0=
- ...</div><div><br></div><div>=C2=A0 =C2=A0 + linear equations</div><div>=
=C2=A0 =C2=A0=C2=A0</div><div>=C2=A0 =C2=A0 + normal operators, such as =3D=
, +=3D, +, -=3D, -, *=3D, *, /=3D, /, ...</div><div><br></div><div>=C2=A0=
=C2=A0 =C2=A0</div><div>Best regards,</div><div>Feng</div><div><br></div><b=
r><br>=E5=9C=A8 2016=E5=B9=B44=E6=9C=8815=E6=97=A5=E6=98=9F=E6=9C=9F=E4=BA=
=94 UTC+2=E4=B8=8B=E5=8D=8812:38:01=EF=BC=8Calls...@gmail.com=E5=86=99=E9=
=81=93=EF=BC=9A<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr=
"><span style=3D"font-family:courier new,monospace">Hi Everyone,<br><br>I&#=
39;m considering implementing a new container called either std::table or s=
td::matrix. The data structure would be similar to std::list as elements wo=
uld be linked together through pointers/iterators. The aim of this data str=
ucture is *not* to create a high performance matrix, that tries to solve ev=
ery single problem. There are always trade-offs in the design of matrices, =
and for high performance situations, it is probably better to use, e.g. in =
computer vision, opencv's Mat class. Keeping this in mind, conceptually=
the table/matrix that I am proposing would like this:<br><br><br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 | std::begin(col) | std::begin(col) |<br>| -------------=
-- | --------------- | --------------- | ------------- |<br>| std::begin(ro=
w) | element 0,0=C2=A0=C2=A0=C2=A0=C2=A0 | element 0,1=C2=A0=C2=A0=C2=A0=C2=
=A0 | std::end(row) |<br>| std::begin(row) | element 1,0=C2=A0=C2=A0=C2=A0=
=C2=A0 | element 1,1=C2=A0=C2=A0=C2=A0=C2=A0 | std::end(row) |<br>| std::be=
gin(row) | element 2,0=C2=A0=C2=A0=C2=A0=C2=A0 | element 2,1=C2=A0=C2=A0=C2=
=A0=C2=A0 | std::end(row) |<br>| --------------- | --------------- | ------=
--------- | ------------- |<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | std::end(col=
)=C2=A0=C2=A0 | std::end(col)=C2=A0=C2=A0 |<br><br><br>In this design, two =
bidirectional (or forward) iterators are kept in each element for iterating=
across the rows and columns. I would imagine similar to a std::list, that =
this would enable the removing/adding of rows/columns without invalidating =
other row/column/element iterators, and also avoid moving all elements when=
a row/column is deleted.<br><br>The motivation for using this layout over =
a std::vector<std::vector<<wbr>double> > (vector inside a vecto=
r) is that the vector inside a vector approach can be unsafe and prone to b=
ugs. I have just written the code for removing/adding rows/columns for the =
vector inside a vector approach, and while it is ok for the first dimension=
, working in the second dimension is painful. Not to mention, one has to co=
nstantly check if the table/matrix is well formed (i.e. equal number of ele=
ments in each row/column)<br><br>The aim of this container would be to repr=
esent graphs, tables, and small to medium size matrices. I would like to al=
so draw attention to the fact, that although syntax to access matrix elemen=
ts in most libraries often appears as either <a href=3D"http://my_matrix.at=
" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'http:/=
/www.google.com/url?q\x3dhttp%3A%2F%2Fmy_matrix.at\x26sa\x3dD\x26sntz\x3d1\=
x26usg\x3dAFQjCNELNLrmwHRR1FRqJ4aLsXP6ZgrUSw';return true;" onclick=3D"=
this.href=3D'http://www.google.com/url?q\x3dhttp%3A%2F%2Fmy_matrix.at\x=
26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNELNLrmwHRR1FRqJ4aLsXP6ZgrUSw';re=
turn true;">my_matrix.at</a>(2,3) or my_matrix[2][3], the actual access to =
the data is not often random, but rather linear across a given column or ro=
w (consider matrix multiplication). Furthermore, assuming all memory for th=
e matrix is allocated once dynamically in the constructor, the performance =
for doing e.g. multiplication of two matrices would be reasonable since all=
elements should make there way into the higher levels of the cache after t=
he first miss.<br><br>From a user stand point, I would like the following s=
orts of operations to be possible:<br><br>/* 1. construction / use of initi=
alization list */<br>std::table<double> my_table(3,2) =3D {<br>=C2=A0=
=C2=A0 11, 12,<br>=C2=A0=C2=A0 21, 22,<br>=C2=A0=C2=A0 31, 32<br>};<br><br>=
std::cout << my_table.size(); // 6<br><br>// element-wise iteration -=
important notes 1. random access iterators not supported, 2. individual el=
ements can not be erased<br>for(auto el : my_table) {<br>=C2=A0=C2=A0 std::=
cout << el << std::end;<br>}<br>// or<br>for(auto it_el =3D std=
::begin(my_table); it_el !=3D std::end(my_table); it_el++) {<br>=C2=A0=C2=
=A0 std::cout << *it_el << std::end;<br>}<br><br>/* 2. copy all=
values, column by column into a std::vector */<br>std::vector<double>=
; vector_values;<br><br>for(const auto& col : my_table.get_cols()) {<br=
>=C2=A0=C2=A0 vector_values.insert(std::end(<wbr>vector_values), std::begin=
(col), std::end(col));<br>}<br><br>/* 3. set all elements to forty two */<b=
r>for(auto& row : my_table.get_rows()) {<br>=C2=A0=C2=A0 for(auto& =
el : row) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 el =3D 42.0f;<br>=C2=A0=C2=A0=
}<br>}<br><br>/* 4. insert elements from a list or vector */<br>// the typ=
e of iterator returned from std::end(my_table.get_rows()) or std::end(my_ta=
ble.get_cols()) determines the orientation */<br>std::list<double> li=
st_values =3D {<br>=C2=A0=C2=A0 42, 21;<br>};<br>// may throw exception if =
dimension mismatch, or alternatively truncate/default construct missing ele=
ments */<br>my_table.insert(std::end(my_<wbr>table.get_rows()), std::begin(=
list_values), std::end(list_values));<br><br>/* 5. algorithms / erase-remov=
e idiom applied to columns */<br>// note since we work with columns and row=
s in matrices, remove(_if) is extended to=C2=A0 remove(_if)_any, remove(_if=
)_all, remove_if_none<br><br>my_table.erase( std::remove_if_none( std::begi=
n(my_table.get_cols()<wbr>), std::begin(my_table.get_cols()<wbr>), [] (doub=
le el) { return (el =3D=3D 42);} ), std::end(my_table.get_cols));<br><br>/*=
6. add row at beginning of table */<br>my_table.add_row(std::begin(<wbr>my=
_table.get_rows()));<br><br>Any thoughts or counter proposals? Reasons why =
this is a bad idea?<br><br><br></span></div></blockquote></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/77c22fd8-0fd2-47a3-9408-f0eacde9d1e8%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/77c22fd8-0fd2-47a3-9408-f0eacde9d1e8=
%40isocpp.org</a>.<br />
------=_Part_2236_1755109892.1467387106928--
------=_Part_2235_347442037.1467387106928--
.
Author: Vishal Oza <vickoza@gmail.com>
Date: Fri, 1 Jul 2016 14:52:43 -0700 (PDT)
Raw View
------=_Part_4103_2081362081.1467409963945
Content-Type: multipart/alternative;
boundary="----=_Part_4104_734112642.1467409963945"
------=_Part_4104_734112642.1467409963945
Content-Type: text/plain; charset=UTF-8
I was thinking about something thing but not as a linked data structures
but as a vector of element as the size of the array is not known at
compiler time but I think there is no reason to change the size of the
Matrix at run-time after you have created the Matrix. the stopping point I
have is trying to get operator[] to take two element without using a pair
or tuple. also I an modif
On Friday, April 15, 2016 at 5:38:01 AM UTC-5, alls...@gmail.com wrote:
>
> Hi Everyone,
>
> I'm considering implementing a new container called either std::table or
> std::matrix. The data structure would be similar to std::list as elements
> would be linked together through pointers/iterators. The aim of this data
> structure is *not* to create a high performance matrix, that tries to solve
> every single problem. There are always trade-offs in the design of
> matrices, and for high performance situations, it is probably better to
> use, e.g. in computer vision, opencv's Mat class. Keeping this in mind,
> conceptually the table/matrix that I am proposing would like this:
>
>
> | std::begin(col) | std::begin(col) |
> | --------------- | --------------- | --------------- | ------------- |
> | std::begin(row) | element 0,0 | element 0,1 | std::end(row) |
> | std::begin(row) | element 1,0 | element 1,1 | std::end(row) |
> | std::begin(row) | element 2,0 | element 2,1 | std::end(row) |
> | --------------- | --------------- | --------------- | ------------- |
> | std::end(col) | std::end(col) |
>
>
> In this design, two bidirectional (or forward) iterators are kept in each
> element for iterating across the rows and columns. I would imagine similar
> to a std::list, that this would enable the removing/adding of rows/columns
> without invalidating other row/column/element iterators, and also avoid
> moving all elements when a row/column is deleted.
>
> The motivation for using this layout over a
> std::vector<std::vector<double> > (vector inside a vector) is that the
> vector inside a vector approach can be unsafe and prone to bugs. I have
> just written the code for removing/adding rows/columns for the vector
> inside a vector approach, and while it is ok for the first dimension,
> working in the second dimension is painful. Not to mention, one has to
> constantly check if the table/matrix is well formed (i.e. equal number of
> elements in each row/column)
>
> The aim of this container would be to represent graphs, tables, and small
> to medium size matrices. I would like to also draw attention to the fact,
> that although syntax to access matrix elements in most libraries often
> appears as either my_matrix.at(2,3) or my_matrix[2][3], the actual access
> to the data is not often random, but rather linear across a given column or
> row (consider matrix multiplication). Furthermore, assuming all memory for
> the matrix is allocated once dynamically in the constructor, the
> performance for doing e.g. multiplication of two matrices would be
> reasonable since all elements should make there way into the higher levels
> of the cache after the first miss.
>
> From a user stand point, I would like the following sorts of operations to
> be possible:
>
> /* 1. construction / use of initialization list */
> std::table<double> my_table(3,2) = {
> 11, 12,
> 21, 22,
> 31, 32
> };
>
> std::cout << my_table.size(); // 6
>
> // element-wise iteration - important notes 1. random access iterators not
> supported, 2. individual elements can not be erased
> for(auto el : my_table) {
> std::cout << el << std::end;
> }
> // or
> for(auto it_el = std::begin(my_table); it_el != std::end(my_table);
> it_el++) {
> std::cout << *it_el << std::end;
> }
>
> /* 2. copy all values, column by column into a std::vector */
> std::vector<double> vector_values;
>
> for(const auto& col : my_table.get_cols()) {
> vector_values.insert(std::end(vector_values), std::begin(col),
> std::end(col));
> }
>
> /* 3. set all elements to forty two */
> for(auto& row : my_table.get_rows()) {
> for(auto& el : row) {
> el = 42.0f;
> }
> }
>
> /* 4. insert elements from a list or vector */
> // the type of iterator returned from std::end(my_table.get_rows()) or
> std::end(my_table.get_cols()) determines the orientation */
> std::list<double> list_values = {
> 42, 21;
> };
> // may throw exception if dimension mismatch, or alternatively
> truncate/default construct missing elements */
> my_table.insert(std::end(my_table.get_rows()), std::begin(list_values),
> std::end(list_values));
>
> /* 5. algorithms / erase-remove idiom applied to columns */
> // note since we work with columns and rows in matrices, remove(_if) is
> extended to remove(_if)_any, remove(_if)_all, remove_if_none
>
> my_table.erase( std::remove_if_none( std::begin(my_table.get_cols()),
> std::begin(my_table.get_cols()), [] (double el) { return (el == 42);} ),
> std::end(my_table.get_cols));
>
> /* 6. add row at beginning of table */
> my_table.add_row(std::begin(my_table.get_rows()));
>
> Any thoughts or counter proposals? Reasons why this is a bad idea?
>
>
>
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a48359b7-febf-4b85-8a55-9009f6a7da99%40isocpp.org.
------=_Part_4104_734112642.1467409963945
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I was thinking about something thing but not as a linked d=
ata structures but as a vector of element as the size of the array is not k=
nown at compiler time but I think there is no reason to change the size of =
the Matrix at run-time after you have created the Matrix. the stopping poin=
t I have is trying to get operator[] to take two element without using a pa=
ir or tuple. also I an modif=C2=A0<br><br>On Friday, April 15, 2016 at 5:38=
:01 AM UTC-5, alls...@gmail.com wrote:<blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left=
: 1ex;"><div dir=3D"ltr"><span style=3D"font-family:courier new,monospace">=
Hi Everyone,<br><br>I'm considering implementing a new container called=
either std::table or std::matrix. The data structure would be similar to s=
td::list as elements would be linked together through pointers/iterators. T=
he aim of this data structure is *not* to create a high performance matrix,=
that tries to solve every single problem. There are always trade-offs in t=
he design of matrices, and for high performance situations, it is probably =
better to use, e.g. in computer vision, opencv's Mat class. Keeping thi=
s in mind, conceptually the table/matrix that I am proposing would like thi=
s:<br><br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | std::begin(col) | std::begin(c=
ol) |<br>| --------------- | --------------- | --------------- | ----------=
--- |<br>| std::begin(row) | element 0,0=C2=A0=C2=A0=C2=A0=C2=A0 | element =
0,1=C2=A0=C2=A0=C2=A0=C2=A0 | std::end(row) |<br>| std::begin(row) | elemen=
t 1,0=C2=A0=C2=A0=C2=A0=C2=A0 | element 1,1=C2=A0=C2=A0=C2=A0=C2=A0 | std::=
end(row) |<br>| std::begin(row) | element 2,0=C2=A0=C2=A0=C2=A0=C2=A0 | ele=
ment 2,1=C2=A0=C2=A0=C2=A0=C2=A0 | std::end(row) |<br>| --------------- | -=
-------------- | --------------- | ------------- |<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 | std::end(col)=C2=A0=C2=A0 | std::end(col)=C2=A0=C2=A0 |<br><br><br=
>In this design, two bidirectional (or forward) iterators are kept in each =
element for iterating across the rows and columns. I would imagine similar =
to a std::list, that this would enable the removing/adding of rows/columns =
without invalidating other row/column/element iterators, and also avoid mov=
ing all elements when a row/column is deleted.<br><br>The motivation for us=
ing this layout over a std::vector<std::vector<<wbr>double> > (=
vector inside a vector) is that the vector inside a vector approach can be =
unsafe and prone to bugs. I have just written the code for removing/adding =
rows/columns for the vector inside a vector approach, and while it is ok fo=
r the first dimension, working in the second dimension is painful. Not to m=
ention, one has to constantly check if the table/matrix is well formed (i.e=
.. equal number of elements in each row/column)<br><br>The aim of this conta=
iner would be to represent graphs, tables, and small to medium size matrice=
s. I would like to also draw attention to the fact, that although syntax to=
access matrix elements in most libraries often appears as either <a href=
=3D"http://my_matrix.at" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"=
this.href=3D'http://www.google.com/url?q\x3dhttp%3A%2F%2Fmy_matrix.at\x=
26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNELNLrmwHRR1FRqJ4aLsXP6ZgrUSw';re=
turn true;" onclick=3D"this.href=3D'http://www.google.com/url?q\x3dhttp=
%3A%2F%2Fmy_matrix.at\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNELNLrmwHRR1FR=
qJ4aLsXP6ZgrUSw';return true;">my_matrix.at</a>(2,3) or my_matrix[2][3]=
, the actual access to the data is not often random, but rather linear acro=
ss a given column or row (consider matrix multiplication). Furthermore, ass=
uming all memory for the matrix is allocated once dynamically in the constr=
uctor, the performance for doing e.g. multiplication of two matrices would =
be reasonable since all elements should make there way into the higher leve=
ls of the cache after the first miss.<br><br>From a user stand point, I wou=
ld like the following sorts of operations to be possible:<br><br>/* 1. cons=
truction / use of initialization list */<br>std::table<double> my_tab=
le(3,2) =3D {<br>=C2=A0=C2=A0 11, 12,<br>=C2=A0=C2=A0 21, 22,<br>=C2=A0=C2=
=A0 31, 32<br>};<br><br>std::cout << my_table.size(); // 6<br><br>// =
element-wise iteration - important notes 1. random access iterators not sup=
ported, 2. individual elements can not be erased<br>for(auto el : my_table)=
{<br>=C2=A0=C2=A0 std::cout << el << std::end;<br>}<br>// or<b=
r>for(auto it_el =3D std::begin(my_table); it_el !=3D std::end(my_table); i=
t_el++) {<br>=C2=A0=C2=A0 std::cout << *it_el << std::end;<br>}=
<br><br>/* 2. copy all values, column by column into a std::vector */<br>st=
d::vector<double> vector_values;<br><br>for(const auto& col : my_=
table.get_cols()) {<br>=C2=A0=C2=A0 vector_values.insert(std::end(<wbr>vect=
or_values), std::begin(col), std::end(col));<br>}<br><br>/* 3. set all elem=
ents to forty two */<br>for(auto& row : my_table.get_rows()) {<br>=C2=
=A0=C2=A0 for(auto& el : row) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 el =
=3D 42.0f;<br>=C2=A0=C2=A0 }<br>}<br><br>/* 4. insert elements from a list =
or vector */<br>// the type of iterator returned from std::end(my_table.get=
_rows()) or std::end(my_table.get_cols()) determines the orientation */<br>=
std::list<double> list_values =3D {<br>=C2=A0=C2=A0 42, 21;<br>};<br>=
// may throw exception if dimension mismatch, or alternatively truncate/def=
ault construct missing elements */<br>my_table.insert(std::end(my_<wbr>tabl=
e.get_rows()), std::begin(list_values), std::end(list_values));<br><br>/* 5=
.. algorithms / erase-remove idiom applied to columns */<br>// note since we=
work with columns and rows in matrices, remove(_if) is extended to=C2=A0 r=
emove(_if)_any, remove(_if)_all, remove_if_none<br><br>my_table.erase( std:=
:remove_if_none( std::begin(my_table.get_cols()<wbr>), std::begin(my_table.=
get_cols()<wbr>), [] (double el) { return (el =3D=3D 42);} ), std::end(my_t=
able.get_cols));<br><br>/* 6. add row at beginning of table */<br>my_table.=
add_row(std::begin(<wbr>my_table.get_rows()));<br><br>Any thoughts or count=
er proposals? Reasons why this is a bad idea?<br><br><br></span></div></blo=
ckquote></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/a48359b7-febf-4b85-8a55-9009f6a7da99%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a48359b7-febf-4b85-8a55-9009f6a7da99=
%40isocpp.org</a>.<br />
------=_Part_4104_734112642.1467409963945--
------=_Part_4103_2081362081.1467409963945--
.