This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Initializing a Matrix or Array from std::string

Tags: None
(comma "," separated)
Manhigh
Registered Member
Posts
10
Karma
0
OS
Is there any standard way of doing this right now? It seems like it would be logical to tokenize a string consisting of a series of numbers with delimiters given by the user. I'm going to need to implement this and want to make sure I'm not reinventing the wheel.

IOFormat seems to be strictly for output, and I'm not sure using it to parse input would be a good idea (wouldn't want extraneous spaces to cause a failure). I'm thinking something like:

s = "3242.25 252.2525 252.0 7356. 232462.26 2452.";

Loading a 1D array or vector should have dynamic capability, based on the number of elements in the string.

Eigen::VectorXd x = Eigen::VectorXd::FromString(s," ",...)

Loading an array or matrix of a particular shape should have some sort of graceful failure mode.

Eigen::MatrixXd x = Eigen::MatrixXd::FromString(1,1,s," ",...) // Fails, too many elements in the string for a 1x1 matrix

Other standard creation options should also be available (row major vs column major, etc) If there's interest in this (and it does not yet exist) I'd be willing to contribute whatever I come up with.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
This discussion came up several times, but the problem is that it is impossible to provide a general solution because the expectations are much too different from one use case to another. Nevertheless, feel free to post your solution here, might be useful to others.
Manhigh
Registered Member
Posts
10
Karma
0
OS
In the interest of posting this here in case its useful to others, here's my solution. It uses boost, so it's probably not a favorable solution in general. In my application this is in no way a bottleneck, so I spent no time trying to optimize the performance. Nevertheless, if you need a way of quickly loading data from a string to a vector of doubles (which can then be mapped via Eigen) here you go:

Code: Select all
#include <vector>
#include <string>

#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/lexical_cast.hpp>

/*! Given a string consisting of a series of doubles with some
*  delimiter, return an Eigen::VectorXd populated with those
*  doubles, in the same order as they are given in the string.
*
*  \param vec A double vector to be populated with the results
*  \param str A string to be parsed as a series of doubles.
*  \param delim Delimiters of the text (a typical default is " ," for comma and space-delimited text
*
*/
void str_to_dvector(std::vector<double>& vec, std::string str, std::string delim) {
    std::vector<std::string> strvec;

    boost::algorithm::trim_if( str, boost::algorithm::is_any_of(delim));
    boost::algorithm::split(strvec,str,boost::algorithm::is_any_of(delim), boost::algorithm::token_compress_on);

    vec.clear();
    vec.resize( strvec.size() );
    for( unsigned int i=0; i<strvec.size(); i++) {
        vec[i] = boost::lexical_cast<double>(strvec[i]);
    }
}


Bookmarks



Who is online

Registered users: Bing [Bot], claydoh, Google [Bot], rblackwell, Yahoo [Bot]