On Thu, Aug 13, 2009 at 6:36 AM, Alle Meije Wink wrote:
Dear OverMind
Hope I'm not making this thread too long, I've tried to search the archives
but did not get further than browsing.
After looking at different options, your idea of wrapping the different
dimensions/dimensionalities in a struct sounds like the best idea, and
closest to the type of data and problems I'm dealing with.
Would you have a few more clues (maybe code, maybe URLs) as to how to shape
this? I had a look at
http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern but that
is a very broad description. As I understand it, the struct that
encapsulates the possible dimensionalities and the CRTP class refer to the
same solution? Or are they different things?
Thanks!
Alle Meije
Date: Fri, 7 Aug 2009 18:09:11 -0600
From: OvermindDL1
Subject: Re: [Boost-users] question about multi_array use
You could always just wrap up each of the possible dimensions in a
struct that can handle the (de)serialization and everything too,
perhaps use crtp to put identical functionality in a non-virtual base
class.
On Fri, Aug 7, 2009 at 2:04 PM, Anton Daneyko wrote:
Hello,
I might be wrong, but it seems the answer is "no you can't do that",
because
the dimensionality is a template parameter multi_array and
multi_array are different types. However I would like to hear
some
else' opinion as well.
Regards,
Anton Daneyko.
On Fri, Aug 7, 2009 at 3:48 PM, Alle Meije Wink
wrote:
Hello,
I would like to use the multi_array container to handle imaging data.
The
image data can be anything up to 8-dimensional (usually up to 4) and
dimension information is found in records that accompany the binary
data.
Would it be possible to create an image class that takes the
dimensionality and extents list as parameters, so that images of all
dimensionalities can be treated as one class?
For example, could the dimensionality be passed as a size_t argument?
What I understand from the multi_array paper is that the extents list
would only be required whan the array is initialised.
Bit busy currently so no real-code to test with, but I might have pseudo-code.
Hmm, I just (saved out first and) cut a large paragraph I was writing
because I just came up with another idea.
Why not use Boost.Variant stuffed with all possible types of matrices?
A simple templated visitor could handle them all for any operations
you want, and it optimizes out quite well. If you are worried about
memory use you could wrap each matrix in the variant in a
boost::recursive_variant so that it is dynamically allocated as
necessary as well. Perhaps something like this:
typedef boost::variant
>
,boost::recursive_variant< multi_array >
,boost::recursive_variant< multi_array >
,boost::recursive_variant< multi_array >
,boost::recursive_variant< multi_array >
,boost::recursive_variant< multi_array >
,boost::recursive_variant< multi_array >
> multi_array_variant_2_to_8_t;
And of course you could template it so you could specify the int type
in a template parameter as well.
Then make a variant for each of your operations, something along the
lines of this for an equal test for example:
class multi_array_variant_dotproduct_compare_equality
: public boost::static_visitor<bool>
{
public:
template
bool operator()( const T &, const U & ) const
{
return false; // different dimensions will always test unequal
}
template <typename T>
bool operator()( const T & lhs, const T & rhs ) const
{
return lhs==rhs;
}
}
And you could probably template it all (maybe using fusion) so most of
of your tests could be generated for simple things like == and so
forth.
Then probably wrap it all up in a pretty class for ease of use, like
this for a beginning shell:
class multi_array_2to8
{
protected:
typedef boost::variant
,boost::recursive_variant< multi_array >
,boost::recursive_variant< multi_array >
,boost::recursive_variant< multi_array >
,boost::recursive_variant< multi_array >
,boost::recursive_variant< multi_array >
,boost::recursive_variant< multi_array >
> multi_array_variant_t;
multi_array_variant_t _multi_array_variant;
/* snip stuff */
protected: // visitors
class multi_array_variant_dotproduct_compare_equality
: public boost::static_visitor<bool>
{
public:
template
bool operator()( const T &, const U & ) const
{
return false; // different dimensions will always be unequal
}
template <typename T>
bool operator()( const T & lhs, const T & rhs ) const
{
return lhs==rhs;
}
}
/* snip more stuff */
public: // op tests
bool operator==(multi_array_2to8 const &rhs) const
{
return boost::apply_visitor
(multi_array_variant_dotproduct_compare_equality()
,_multi_array_variant
,rhs._multi_array_variant
);
}
/* snip the rest of the stuff */
}
For initially filling a vector would probably require a visitor using
fusion, or 7 visitors, fusion's invoke sounds a lot easier though, and
could simplify a few other visitors too, and use using fusion (and
maybe crtp, depending on how you build it) would reduce the necessary
code a lot as well.
If you are still interested in my other way, I can try to remember
what I was thinking and finish the paragraph I was doing, but that
above seems better overall...
For now though, sleep, and since I am tired enough that the screen is
blurry, I make no remarks on my above coding quality, hopefully it
works as-is, but consider it pseudo-code otherwise.