smttsp
smttsp

Reputation: 4191

Efficient way of converting matlab matrix to array in c++

I have a Matlab code which I should convert to c++. In one file there are a lot of matrices and I want to convert them to arrays(or vectors). I need efficient way of converting those matrices.

f = [   -.000212080863  .000358589677   .002178236305   ...
        -.004159358782  -.010131117538  .023408156762   ...
        .028168029062   -.091920010549  -.052043163216  ...
        .421566206729   .774289603740   .437991626228   ...
        -.062035963906  -.105574208706  .041289208741   ...
        .032683574283   -.019761779012  -.009164231153  ...
        .006764185419   .002433373209   -.001662863769  ...
        -.000638131296  .000302259520   .000140541149   ...
        -.000041340484  -.000021315014  .000003734597   ...
        .000002063806   -.000000167408  -.000000095158  ];

I tried things like this but all my trials give some errors.

int* first;
first = new int[5];
first = {1,2,3,4,5};

Note: I can put commas and change [ to { manually.

Thanks,

Upvotes: 1

Views: 3001

Answers (3)

ogni42
ogni42

Reputation: 1276

If your compiler supports it, you could also use an initializer list

vector<double> f{ -.000212080863, .000358589677, ...} // replace elipses with other numerical values

This will give you the advantage that you vector size is not stack limited. Keep in mind that matlab uses column order for matrices, so you need to take care when converting those.

Upvotes: 0

Stefano Falasca
Stefano Falasca

Reputation: 9097

You can use something like this:

PMatrix MatrixData::factory(string parser){
    typedef boost::tokenizer<boost::char_separator<char> > tokenizer;

    // Verifica formattazione matrice

    if (!((parser[0]=='{' && parser[parser.size()-1] == '}')||(parser[0]=='[' && parser[parser.size()-1] == ']')))
        assert( (std::cout<<"Wrong matrix structure"<<std::endl, 0) );

     // Verifica struttura matrice

    boost::char_separator<char> row_sep("[]{};");
    boost::char_separator<char> col_sep(",");
    unsigned int row_number,col_number;

    tokenizer::iterator rowtok_iter;
    tokenizer::iterator coltok_iter;

    row_number = 0;
    tokenizer rowtokens(parser, row_sep);
    for (rowtok_iter = rowtokens.begin();rowtok_iter != rowtokens.end(); ++rowtok_iter)
        row_number++;

    col_number = 0;
    tokenizer coltokens(*rowtokens.begin(), col_sep);
    col_number = std::distance(coltokens.begin(),coltokens.end());

    //cout << row_number << " rows and " << col_number << " columns" << endl;

    unsigned int active_row_col_number;
    double* values = new double[col_number*row_number];
    unsigned int i = 0;

    for (rowtok_iter = rowtokens.begin();rowtok_iter != rowtokens.end(); ++rowtok_iter){
        active_row_col_number = 0;
        tokenizer coltokens1(*rowtok_iter, col_sep);
        for (coltok_iter = coltokens1.begin();coltok_iter != coltokens1.end();++coltok_iter){
            active_row_col_number++;
            values[i]=strtod(coltok_iter->c_str(),0);
            i++;
        }   
        if (active_row_col_number!=col_number)
             assert( (std::cout<<"Wrong matrix structure 1"<<std::endl, 0) );
    }   
    PMatrix ret = MatrixData::factory(row_number,col_number,values);
    delete[] values;
    return ret;
}

which directly parses a Matlab-formatted matrix from a string and puts the result into "values".

This is not the cleanest code you can imagine, but it can be cleaned up. It's using boost::tokenizer, as you can see. Hope it helps.

Upvotes: 1

Mats Petersson
Mats Petersson

Reputation: 129374

If the value is constant (as in, you are happy to recompile for each time you want to change the values), then you can do:

double f[] = {  -.000212080863,  .000358589677,   .002178236305,   ... };

(Note the addition of commas, and curly brackets instead of square ones).

If the values are changing, then you want to use a vector<double> f;, clean up the input a bit and use something like:

ifstream infile("numbers.txt"); 
while(infile >> value) 
{ 
   f.push_back(value); 
}

Upvotes: 2

Related Questions