Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #3601 > unrolled thread
| Started by | jacob navia <jacob@spamsink.net> |
|---|---|
| First post | 2011-04-13 23:44 +0200 |
| Last post | 2011-04-15 14:23 -0700 |
| Articles | 16 — 3 participants |
Back to article view | Back to comp.lang.c++
Understanding ValArray slices jacob navia <jacob@spamsink.net> - 2011-04-13 23:44 +0200
Re: Understanding ValArray slices Ian Collins <ian-news@hotmail.com> - 2011-04-14 09:50 +1200
Re: Understanding ValArray slices jacob navia <jacob@spamsink.net> - 2011-04-14 00:22 +0200
Re: Understanding ValArray slices gwowen <gwowen@gmail.com> - 2011-04-14 01:59 -0700
Re: Understanding ValArray slices jacob navia <jacob@spamsink.net> - 2011-04-14 14:48 +0200
Re: Understanding ValArray slices gwowen <gwowen@gmail.com> - 2011-04-14 09:53 -0700
Re: Understanding ValArray slices jacob navia <jacob@spamsink.net> - 2011-04-14 22:50 +0200
Re: Understanding ValArray slices jacob navia <jacob@spamsink.net> - 2011-04-14 22:51 +0200
Re: Understanding ValArray slices gwowen <gwowen@gmail.com> - 2011-04-14 22:47 -0700
Re: Understanding ValArray slices jacob navia <jacob@spamsink.net> - 2011-04-15 22:19 +0200
Re: Understanding ValArray slices Ian Collins <ian-news@hotmail.com> - 2011-04-16 08:21 +1200
Re: Understanding ValArray slices gwowen <gwowen@gmail.com> - 2011-04-15 14:13 -0700
Re: Understanding ValArray slices jacob navia <jacob@spamsink.net> - 2011-04-15 23:24 +0200
Re: Understanding ValArray slices gwowen <gwowen@gmail.com> - 2011-04-15 23:05 -0700
Re: Understanding ValArray slices jacob navia <jacob@spamsink.net> - 2011-04-16 12:00 +0200
Re: Understanding ValArray slices gwowen <gwowen@gmail.com> - 2011-04-15 14:23 -0700
| From | jacob navia <jacob@spamsink.net> |
|---|---|
| Date | 2011-04-13 23:44 +0200 |
| Subject | Understanding ValArray slices |
| Message-ID | <io55g6$66o$1@speranza.aioe.org> |
Hi I have some trouble understanding what are the ValArray slices classes. Are they just like pointers in the sense that they do not copy the data but just select it? Or are they arrays of their own with their own data. Or do they produce an array of indices? ValArray classes aren't even mentioned in the C++ Primer book (Lippman et al) not are they mentioned in the one of Plaugher. The only docs are some scanty web pages and the standard, what is not that easy to understand. Thanks in advance for some short tutorial or a pointer to one. jacob
[toc] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-04-14 09:50 +1200 |
| Message-ID | <90mk5cFeeiU8@mid.individual.net> |
| In reply to | #3601 |
On 04/14/11 09:44 AM, jacob navia wrote: > Hi > > I have some trouble understanding what are the ValArray slices classes. > > Are they just like pointers in the sense that they do not copy the data > but just select it? They a a collection of indices into a valarray. > Or are they arrays of their own with their own data. > > Or do they produce an array of indices? Yes. > ValArray classes aren't even mentioned in the C++ Primer book (Lippman > et al) not are they mentioned in the one of Plaugher. The only docs are > some scanty web pages and the standard, what is not that easy to > understand. > > Thanks in advance for some short tutorial or a pointer to one. The standard (and excellent) reference is "The C++ Standard Library" by Nicolai M. Josuttis. -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | jacob navia <jacob@spamsink.net> |
|---|---|
| Date | 2011-04-14 00:22 +0200 |
| Message-ID | <io57nd$b6s$1@speranza.aioe.org> |
| In reply to | #3608 |
Le 13/04/11 23:50, Ian Collins a écrit : > On 04/14/11 09:44 AM, jacob navia wrote: >> Or do they produce an array of indices? > > Yes. > Thanks, I see now how this works. The problem is that it would be more efficient to pass directly the stride specs instead of allocating the indices array. I will see how I implement this. Thanks again Ian
[toc] | [prev] | [next] | [standalone]
| From | gwowen <gwowen@gmail.com> |
|---|---|
| Date | 2011-04-14 01:59 -0700 |
| Message-ID | <0cfb9f27-e357-4df0-8524-c6f5da967d44@k3g2000prl.googlegroups.com> |
| In reply to | #3615 |
On Apr 13, 11:22 pm, jacob navia <ja...@spamsink.net> wrote:
> Thanks, I see now how this works. The problem is that
> it would be more efficient to pass directly the
> stride specs instead of allocating the indices array. I will
> see how I implement this.
I think Ian and you are talking at slight cross-purposes.
slices do not themselves, need to store an array of indices, but
rather just the start,end and stride passed at construction time. All
the heavy lifting can be done in the overloaded
valarray::operator[slice], and no intermediate array-of-indices need
creating.
In inefficient semi-pseudo code
valarray<T> valarray::operator[] (slice ...) {
valarray<T> retval(size.size());
size_t retidx = 0;
for(size_t idx = slice.start(); idx < slice.end(); idx +=
slice.stride()){
retval[retidx] = *this[idx];
retidx += 1;
}
}
Of course, one could implement them as generating an array of indices
at construction time, but I doubt that implementations do this. The
fact that operator[] is defined as operating on slice, rather than
const slice& suggests that in the intended implementation slices are
easily copyable.
[toc] | [prev] | [next] | [standalone]
| From | jacob navia <jacob@spamsink.net> |
|---|---|
| Date | 2011-04-14 14:48 +0200 |
| Message-ID | <io6qf5$ncl$1@speranza.aioe.org> |
| In reply to | #3647 |
Le 14/04/11 10:59, gwowen a écrit :
> On Apr 13, 11:22 pm, jacob navia<ja...@spamsink.net> wrote:
>
>> Thanks, I see now how this works. The problem is that
>> it would be more efficient to pass directly the
>> stride specs instead of allocating the indices array. I will
>> see how I implement this.
>
> I think Ian and you are talking at slight cross-purposes.
>
> slices do not themselves, need to store an array of indices, but
> rather just the start,end and stride passed at construction time. All
> the heavy lifting can be done in the overloaded
> valarray::operator[slice], and no intermediate array-of-indices need
> creating.
>
> In inefficient semi-pseudo code
>
> valarray<T> valarray::operator[] (slice ...) {
> valarray<T> retval(size.size());
> size_t retidx = 0;
> for(size_t idx = slice.start(); idx< slice.end(); idx +=
> slice.stride()){
> retval[retidx] = *this[idx];
> retidx += 1;
> }
> }
>
> Of course, one could implement them as generating an array of indices
> at construction time, but I doubt that implementations do this. The
> fact that operator[] is defined as operating on slice, rather than
> const slice& suggests that in the intended implementation slices are
> easily copyable.
OK, this means that in my implementation
MultiplyWith(ValArray *, ValArray*)
would multiply two arrays of the same length
MutiplyWithScalar(ValArray *array,ElementType m)
would multiply an array by a single number and
MultiplyWithSlice(ValArray *array, size_t start, size_t size, size_t
increment, ValArray *multiplicand)
would multiply using the described slice. The multiplicand should have
exactly "size" elements (i.e. as much elements as the slice describes)
[toc] | [prev] | [next] | [standalone]
| From | gwowen <gwowen@gmail.com> |
|---|---|
| Date | 2011-04-14 09:53 -0700 |
| Message-ID | <01b3d7b2-ba1c-439b-8524-babd0fcdb598@x37g2000prb.googlegroups.com> |
| In reply to | #3668 |
On Apr 14, 1:48 pm, jacob navia <ja...@spamsink.net> wrote: > Le 14/04/11 10:59, gwowen a crit : > MultiplyWithSlice(ValArray *array, size_t start, size_t size, size_t > increment, ValArray *multiplicand) > > would multiply using the described slice. The multiplicand should have > exactly "size" elements (i.e. as much elements as the slice describes) I'm not sure, I'm afraid. Would this be an "in place" multiplication, or would MultiplyWithSlice() return a new object/pointer to a new object? There's a good example on how to use valarray slices on the MSDN http://msdn.microsoft.com/en-us/library/5hky5878%28v=vs.80%29.aspx Essentially, the only (standardised) use of a slice object is an argument to valarray::operator[] which returns a valarray object whose size is that of the slice, containing selected elements of the initial valarray - without modifiying the initial array. Think of it like the std::string::substr() function, but selecting evenly letters rather than a substring. std::string str = "abcdefghijklmnopqrstu"; std::string fragment = str.subtst(1,8); // fragment = "bcdefghi" // if strings were sliceable std::string::slice slc(0,8,2); // fragment = str[slc]; // fragment = "acegikmo"
[toc] | [prev] | [next] | [standalone]
| From | jacob navia <jacob@spamsink.net> |
|---|---|
| Date | 2011-04-14 22:50 +0200 |
| Message-ID | <io7mmh$22l$1@speranza.aioe.org> |
| In reply to | #3703 |
Le 14/04/11 18:53, gwowen a écrit :
> On Apr 14, 1:48 pm, jacob navia<ja...@spamsink.net> wrote:
>> Le 14/04/11 10:59, gwowen a crit :
>
>> MultiplyWithSlice(ValArray *array, size_t start, size_t size, size_t
>> increment, ValArray *multiplicand)
>>
>> would multiply using the described slice. The multiplicand should have
>> exactly "size" elements (i.e. as much elements as the slice describes)
>
> I'm not sure, I'm afraid. Would this be an "in place" multiplication,
> or would MultiplyWithSlice() return a new object/pointer to a new
> object?
All the functions of the library are in place functions for the left
argument
Multiply(left,right) means left += right
This allows to build an "accumulator" kind of software in RPN
that is easy to generate and use. You can then express complicated
formulas in that notation without allocating intermediate results.
>
> There's a good example on how to use valarray slices on the MSDN
> http://msdn.microsoft.com/en-us/library/5hky5878%28v=vs.80%29.aspx
> Essentially, the only (standardised) use of a slice object is an
> argument to valarray::operator[] which returns a valarray object whose
> size is that of the slice, containing selected elements of the initial
> valarray - without modifiying the initial array. Think of it like the
> std::string::substr() function, but selecting evenly letters rather
> than a substring.
I am not sure it is necessary to have a slice object. If I add 3
arguments to the slice functions it would be the same...
Another (maybe beter) possibility is that ALL functions take
a "slice" argument that defults to
{0,length(ValArray),1} i.e. 0,1,2... length(ValArray)
A function SetSlice(ValArray,start,length,increment) would set a
slice into the array to other values than the default ones, making
that ALL functions would work on the slice automatically.
To take out the slice you would call ReSetSlice(ValArray);
This has the advantage of having less functions and reusing
maybe the same code to work on a slice ithout any
modifications.
>
> std::string str = "abcdefghijklmnopqrstu";
> std::string fragment = str.subtst(1,8); // fragment = "bcdefghi"
>
> // if strings were sliceable
> std::string::slice slc(0,8,2); //
> fragment = str[slc]; // fragment = "acegikmo"
Yes, I see.
Thanks for your input.
[toc] | [prev] | [next] | [standalone]
| From | jacob navia <jacob@spamsink.net> |
|---|---|
| Date | 2011-04-14 22:51 +0200 |
| Message-ID | <io7mok$22l$2@speranza.aioe.org> |
| In reply to | #3720 |
Le 14/04/11 22:50, jacob navia a écrit : > > Multiply(left,right) means left += right > Of course NOT! Multiply(left,right) means left *= right Sorry :-)
[toc] | [prev] | [next] | [standalone]
| From | gwowen <gwowen@gmail.com> |
|---|---|
| Date | 2011-04-14 22:47 -0700 |
| Message-ID | <068fc503-45d6-441e-b1c6-db9594166418@j17g2000vbr.googlegroups.com> |
| In reply to | #3720 |
On Apr 14, 9:50 pm, jacob navia <ja...@spamsink.net> wrote: > Le 14/04/11 18:53, gwowen a crit : > > > On Apr 14, 1:48 pm, jacob navia<ja...@spamsink.net> wrote: > >> Le 14/04/11 10:59, gwowen a crit : > > >> MultiplyWithSlice(ValArray *array, size_t start, size_t size, size_t > >> increment, ValArray *multiplicand) > > >> would multiply using the described slice. The multiplicand should have > >> exactly "size" elements (i.e. as much elements as the slice describes) > > > I'm not sure, I'm afraid. Would this be an "in place" multiplication, > > or would MultiplyWithSlice() return a new object/pointer to a new > > object? > > All the functions of the library are in place functions for the left > argument Right, ok. In which case, yes, everything you say after is right. The only slight gotcha I can see is that with multiply functions with slices will, of course, result in the left hand operand getting resized, but this is also true for standard matrix multiplication. On a tangent, I can imagine an implementation that provides and easily- sliceable valarray that stores the the start,stride,size and reindexes on the fly, in operator[]. Combined with copy-on-write semantics you'd get cheap slicing, at the cost of an extra multiply-and-add during indexing. If you slice often (writing a multigrid elliptic PDE solver, for example) this might be a considerable win... Anyway I'm rambling...
[toc] | [prev] | [next] | [standalone]
| From | jacob navia <jacob@spamsink.net> |
|---|---|
| Date | 2011-04-15 22:19 +0200 |
| Message-ID | <ioa97l$2g7$1@speranza.aioe.org> |
| In reply to | #3733 |
Le 15/04/11 07:47, gwowen a écrit : > On a tangent, I can imagine an implementation that provides and easily- > sliceable valarray that stores the the start,stride,size and reindexes > on the fly, in operator[]. I am doing exactly that.
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-04-16 08:21 +1200 |
| Message-ID | <90rnmpFojcU5@mid.individual.net> |
| In reply to | #3793 |
On 04/16/11 08:19 AM, jacob navia wrote: > Le 15/04/11 07:47, gwowen a écrit : > >> On a tangent, I can imagine an implementation that provides and easily- >> sliceable valarray that stores the the start,stride,size and reindexes >> on the fly, in operator[]. > > I am doing exactly that. In C? -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | gwowen <gwowen@gmail.com> |
|---|---|
| Date | 2011-04-15 14:13 -0700 |
| Message-ID | <f2d1ca7b-ff8d-4390-b9e4-650b80fa60b5@w9g2000prg.googlegroups.com> |
| In reply to | #3794 |
On Apr 15, 9:21 pm, Ian Collins <ian-n...@hotmail.com> wrote: > In C? Jacob's C compiler comes with many extensions to standard C - operator overloading being one of them.
[toc] | [prev] | [next] | [standalone]
| From | jacob navia <jacob@spamsink.net> |
|---|---|
| Date | 2011-04-15 23:24 +0200 |
| Message-ID | <ioad1i$bkd$1@speranza.aioe.org> |
| In reply to | #3794 |
Le 15/04/11 22:21, Ian Collins a écrit : > On 04/16/11 08:19 AM, jacob navia wrote: >> Le 15/04/11 07:47, gwowen a écrit : >> >>> On a tangent, I can imagine an implementation that provides and easily- >>> sliceable valarray that stores the the start,stride,size and reindexes >>> on the fly, in operator[]. >> >> I am doing exactly that. > > In C? > For instance: int Multiply(ValArray *left,ValArray *right); This will multiply left *= right. You can set a Slice into a ValArray with: int SetSlice(ValArray *a,size_t start,size_t length,size_t increment); From now on, all operations will only use the slice in the array until you reset it with int ResetSlice(ValArray *array); Yes, in C and the main version is in C90, I do not use even my own extensions to get maximum portability. In lcc win you will be able to use the overloaded operators, but not in the versions I will present to the C standards committee. You can read the docs and download the source code from http://code.google.com/p/ccl/
[toc] | [prev] | [next] | [standalone]
| From | gwowen <gwowen@gmail.com> |
|---|---|
| Date | 2011-04-15 23:05 -0700 |
| Message-ID | <57bbf3a5-3bba-4be1-9c3c-cc627bca542d@v31g2000vbs.googlegroups.com> |
| In reply to | #3801 |
On Apr 15, 10:24 pm, jacob navia <ja...@spamsink.net> wrote: > For instance: > > int Multiply(ValArray *left,ValArray *right); Is there a reason the second pointer isn't "const" (or are you just saving typing for these examples)?
[toc] | [prev] | [next] | [standalone]
| From | jacob navia <jacob@spamsink.net> |
|---|---|
| Date | 2011-04-16 12:00 +0200 |
| Message-ID | <iobpbr$4mo$1@speranza.aioe.org> |
| In reply to | #3816 |
Le 16/04/11 08:05, gwowen a écrit : > On Apr 15, 10:24 pm, jacob navia<ja...@spamsink.net> wrote: > >> For instance: >> >> int Multiply(ValArray *left,ValArray *right); > > Is there a reason the second pointer isn't "const" (or are you just > saving typing for these examples)? You are right. The second argument should be const Thanks.
[toc] | [prev] | [next] | [standalone]
| From | gwowen <gwowen@gmail.com> |
|---|---|
| Date | 2011-04-15 14:23 -0700 |
| Message-ID | <57d7068a-4f46-4054-a590-4c1e0510974b@e26g2000vbz.googlegroups.com> |
| In reply to | #3793 |
On Apr 15, 9:19 pm, jacob navia <ja...@spamsink.net> wrote: > Le 15/04/11 07:47, gwowen a crit : > > > On a tangent, I can imagine an implementation that provides and easily- > > sliceable valarray that stores the the start,stride,size and reindexes > > on the fly, in operator[]. > > I am doing exactly that. I think Matlab does it too - some of the slicing and selection operators are incredibly quick - until you have to modify the results, when all that deferred copying catches up with you. It definitely works for them, because Matlab is such a good tool for visualising slices of high dimensional arrays, and since a) Matlab is clearly inspired by Fortran and b) Fortran arrays have variable bounds and strides anyway, I think this must be almost-standard in Fortran.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c++
csiph-web