I am writing a c++ function to compute marginal PDFs (Probability density functions). This basically means that I get multi dimensional data (PDF) defined along a grid of a number of variables. I want to integrate the data over an undefined number of dimensions to keep the function general.
The dimension of the PDF can be arbitrary and the dimension of the marginal PDF can also be arbitrary. It is not possible to define the order of the dimensions of the input data, so I send a vector to the function, which says which variables need to be kept. The other variables need to be integrated.
So for example: No of variables: 5(a,b,c,d,e) , PDF data dimension 5, compute marginal PDF of (a,c,d). This means the variables/dimensions 0,2,3 need to be kept and the others need to be integrated out (by a definite integral). so: PDF[a][b][c][d][e] -> MARGPDF[a][c][d] (which contains other values) for every [a][c][d] I need to perform an action on the data in the other dimensions [b][e]. I can do this by making a view, however I don't now how I can do this dynamically. By dynamic I mean that I want that the number of dimensions and which dimensions are kept are free to choose.
Basically, what I want is to create a view of all the values in the dimensions b and e and do this for each (loop) value of a,c,d. However, I want the function to be general such that the input can be any multi array and the output variables will be free to choose. So it could also be: PDF[a][b][c][d] -> MARGPDF[c] or PDF[a][b][c][d][e][f] -> MARGPDF[b][d].
I've had the following idea: I sort the PDF multi array by dimension, such that I can create a view of the last number of dimensions, so: PDF[a][b][c][d][e] becomes PDF[a][c][d][b][e] . Then I loop over each a,c,d and create a view of the remaining 2 dimensions b and e. I perform a calculation using this view and save the value to MARGPDF[a][c][d].
What I need to know to perform such an operation is: How can I switch the order of the dimensions/indices of a boost::multi_array ? How can I create a view when the dimensions are free? Or do you have any other idea to accomplish the same thing?
The start of my code is provided below:
template<class DataType, int Dimension, int ReducedDimension>
boost::multi_array<DataType, ReducedDimension> ComputeMarginalPDF(boost::multi_array<DataType, Dimension> PDF,
std::vector< std::vector<DataType> > Variables , std::vector<int> VarsToKeep ){
// check input dimensions
if (VarsToKeep.size() != ReducedDimension ){
std::cout << "Dimensions do not match" << std::endl;
}
std::vector< std::vector<double> > NewVariables(0) ;
// Construct reduced array with proper dimensions
typedef boost::multi_array< DataType , ReducedDimension > ReducedArray ;
boost::array< ReducedArray::index , ReducedDimension > dimensions;
// get dimensions from array and insert into dimensions ;
// set Marginal PDF dimensions
for(int i = 0 ; i < VarsToKeep.size() ; i++){
dimensions[i] = PDF.shape()[ VarsToKeep[i] ] ;
NewVariables.push_back( Variables[ VarsToKeep[i] ] );
}
ReducedArray Marginal(dimensions) ;
// to be filled with code
I hope I am not to confusing. Any suggestions to improve the questions are welcome.