'indexed' multi arrays?

In a recent project I've been working on, we had need for something that I'm calling (for lack of a better, more inspired name ;) an 'indexed' multi array. Essentially, we wanted something like a boost multi_array but that also allowed indexing along each dimension using some kind of indexing function. For example, along one dimension the indexing function may except a string as input and use a map to return an integer index, while along some other dimension the real line may be cut into non-overlapping intervals and a double value is looked up returning the index of the interval it belongs to. We looked at various solutions, but in the end rolled our own based off of the boost multi_array and a new concept of an 'indexer'. Is this something that anybody else would see as useful? I hope my explanation was sufficiently clear ;) Cheers, Chris Hamilton

Hi Chris, On Dec 20, 2007 9:47 PM, Chris Hamilton <chamilton@cs.dal.ca> wrote:
In a recent project I've been working on, we had need for something that I'm calling (for lack of a better, more inspired name ;) an 'indexed' multi array. Essentially, we wanted something like a boost multi_array but that also allowed indexing along each dimension using some kind of indexing function. For example, along one dimension the indexing function may except a string as input and use a map to return an integer index, while along some other dimension the real line may be cut into non-overlapping intervals and a double value is looked up returning the index of the interval it belongs to.
We looked at various solutions, but in the end rolled our own based off of the boost multi_array and a new concept of an 'indexer'.
Is this something that anybody else would see as useful? I hope my explanation was sufficiently clear ;)
I definitely think this would be useful, but more in the line of a general utility that allows me to create an input iterator that's based on a function object. Something like boost::make_function_output_iterator(...) only boost::make_function_input_iterator(...). I'm guessing, you might have a generic function that returns an iterator from a container. You might argue that it would be good to wrap your container in such a way that you have: std::list<std::string> cities; // contain the list of cities currently_unnamed_wrapper<unsigned int, std::list<std::string> > city_finder(cities); std::list<std::string>::iterator city_iterator = city_finder[zip_code]; std::cout << *city_iterator << std::endl; Is this similar to what you've already implemented? -- Dean Michael C. Berris Software Engineer, Friendster, Inc. [http://cplusplus-soup.blogspot.com/] [mikhailberis@gmail.com] [+63 928 7291459] [+1 408 4049523]

I definitely think this would be useful, but more in the line of a general utility that allows me to create an input iterator that's based on a function object. Something like boost::make_function_output_iterator(...) only boost::make_function_input_iterator(...).
I'm guessing, you might have a generic function that returns an iterator from a container. You might argue that it would be good to wrap your container in such a way that you have:
std::list<std::string> cities; // contain the list of cities currently_unnamed_wrapper<unsigned int, std::list<std::string> > city_finder(cities); std::list<std::string>::iterator city_iterator = city_finder[zip_code]; std::cout << *city_iterator << std::endl;
Is this similar to what you've already implemented?
Not at all at this point. For simplicity, I defined an 'Indexer' concept, which implements the following functions: int lookup( const T& key ) const; size_t size() const; (plus some other callback type stuff to be discussed later) These are passed to the 'LookupTable' class as template arguments, using a trick similar to the 'tuple' class, and currently supporting up to 10 dimensions. The generated object then looks and feels like a multi_array, but extended with 'operator()' which does lookups based on key, rather than index. So, access to a two dimensional array with the first dimension indexed using strings and the second using doubles would be like: a("string")(1.0) I made the 'indexers' accessible through the LookupTable object through a templated 'indexer<>' function. Since the indexers define the shape of the array, it only makes sense that the shape be changed through them. Thus, there's a callback mechanism (through friendly base classes) that allows the indexer to inform the underlying array of any shape changes (ie: remove indices n..n+k from dimension m, ...) The whole function output iterator seems maybe 'too external', in that it doesn't create a tight connection between the container indexing a dimension and the underlying multi array; how to keep them in sync? Chris

In message <476A7273.2000900@cs.dal.ca>, Chris Hamilton <chamilton@cs.dal.ca> writes
In a recent project I've been working on, we had need for something that I'm calling (for lack of a better, more inspired name ;) an 'indexed' multi array. Essentially, we wanted something like a boost multi_array but that also allowed indexing along each dimension using some kind of indexing function.
This looks interesting to me.
For example, along one dimension the indexing function may except a string as input and use a map to return an integer index, while along some other dimension the real line may be cut into non-overlapping intervals and a double value is looked up returning the index of the interval it belongs to.
And this too, in its own right. How do you deal with the issue of limited precision in doubles? E.g. a value that is a corner case for just being in range for one index, or possibly another if these ranges are meant to have no 'gap' (e.g. [d1, d2), [d2, d3))? Or possibly the value used is just in or out of a range, but the relevant epsilon could take it either way? Regards, Alec -- Alec Ross

Alec Ross wrote:
In message <476A7273.2000900@cs.dal.ca>, Chris Hamilton <chamilton@cs.dal.ca> writes
In a recent project I've been working on, we had need for something that I'm calling (for lack of a better, more inspired name ;) an 'indexed' multi array. Essentially, we wanted something like a boost multi_array but that also allowed indexing along each dimension using some kind of indexing function.
This looks interesting to me.
For example, along one dimension the indexing function may except a string as input and use a map to return an integer index, while along some other dimension the real line may be cut into non-overlapping intervals and a double value is looked up returning the index of the interval it belongs to.
And this too, in its own right. How do you deal with the issue of limited precision in doubles? E.g. a value that is a corner case for just being in range for one index, or possibly another if these ranges are meant to have no 'gap' (e.g. [d1, d2), [d2, d3))? Or possibly the value used is just in or out of a range, but the relevant epsilon could take it either way?
That's something that I didn't address whatsoever at this point. However, it would always be possible to add some sort of 'epsilon' logic to the 'Intervals' indexer (as I've called it currently). I'm not sure there's a generic appropriate behaviour and I imagine it's very likely application specific. Chris
participants (3)
-
Alec Ross
-
Chris Hamilton
-
Dean Michael Berris