简体   繁体   中英

passing several boost multi_array from function

I have a bunch of 3d arrays generated using boost::multi_array in a function. I would not want to use all these arrays in another code of mine is there any way to do this?

When I had a 2d case what I did was

typedef boost::numeric::ublas::matrix<double> fils;
boost::array<fils,5> filter1(unsigned width, unsigned height)
{
    matrix<double>l,m,n,o,p;
    //perform other steps//
    boost::array<fils,5> t={l,m,n,o,p};
    return t;
}

main.cpp

int main()
{
    boost::array<fils,5> z;
    z= t(w,h);
}

for the 2d case this method works fine. I now want to do the same with a 3D case where

typedef boost::multi_array<double,3>x;
boost::array<x,12>x1(unsigned w,unsigned h,unsigned s)
{
    typedef boost::multi_array<double,3>M;
    typedef M::index Mi;
    m l(boost::extents[w][h][s]),m(boost::extents[w][h][s]),n(boost::extents[w][h][s]),o(boost::extents[w][h][s]);
    //perform steps//
}

how do I get the matrices l,m,n,o,p so that I can use them as source in other bits of code.

In my opinion the most elegant solution is to declare a 4-D multi_array like so :

typedef boost::multi_array<double,4> FloatArray4D;
typedef M::index Mi;

function create4dArray()
{
    FloatArray4D returnValue(boost::extents[w][h][s][4]);
    // Populate the array as you please here is an example.
    for (int i = 0; i < 4; i++) {
       for (int j = 0; j < w; j++) {
           for (int k = 0; k < h; k++) {
               for (int x = 0; x < s; x++) {
                   returnValue[j][k][x][i] = i+j*10+k*100+x*1000;
                }
            }
        }
    }
    return returnValue;
}

Then you can access the subarray by indexing on the last coordinate. It might be more efficient to index them by the first coordinate (in terms of localization of the data) but I don't know the implementation details of boost::multi_array (can someone weight in on this in comments ?)

To extract a view (no-copy) of your 3-D data from the 4-D multi_array created you can use this :

typedef boost::multi_array_types::index_range range;
FloatArray4D::index_gen indices;

FloatArray4D my4DArray = create4dArray();

// Create a new view with 3 dimentions (corresponding to your l) fixing the 4th dimention to 0

FloatArray4D::array_view<3>::type l = [indices[range()][range()][range()][0];

then you can use l as if it was your 3-D array.

PS: NEVER name something x or M , especially not a type. Yes long names are a pain to type, but get a decent text editor with auto-completion and it won't be a problem. Knowing what an object is by its name however, will always be great. It improves readability, for you and for anyone else who has to read your code.

Also do not typedef inside a function. If you want to define a custom type do it in a header file that is shared. You don't want to have to declare that type everywhere. And actually don't overuse typedef, only use it if it improves readability.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM