Matrix input

Here's another approach to the problem of how to efficiently input a matrix to your code. This follows on from the thread on the LA refresher forum. This allows you to do the cut and paste thing like Barney sugggested, or to input the data from a file (suitably-named to avoid confusion down the line).

There's nothing wrong with the approaches suggested on the other thread, this is just an alternative that uses the I/O streams in the C++ standard libary a little differently.

One irritating thing here is that if using the console to input the values, you have to type Ctrl-Z as the last line of your input to indicate EOF to the C++ library code. Not sure how to get around that, but I only used this mode for testing anyway. This code is also brittle as heck but works OK with the inputs from Dan.

The matrix code I am using is in Boost::numerics::ublas (sorry Eddie), hence the use of templates e.g. matrix<double>.

C++:
[SIZE=2]matrix<[/SIZE][SIZE=2][COLOR=#0000ff]double[/COLOR][/SIZE][SIZE=2]> data = readMatrix(cin); [/SIZE][SIZE=2][COLOR=#008000]// read from the console[/COLOR][/SIZE]
[SIZE=2]matrix<[/SIZE][SIZE=2][COLOR=#0000ff]double[/COLOR][/SIZE][SIZE=2]> A = readMatrix([/SIZE][SIZE=2][COLOR=#800000]"LARefresher\\hw2a.txt"[/COLOR][/SIZE][SIZE=2]); [/SIZE][SIZE=2][COLOR=#008000]// read from file[/COLOR][/SIZE]
Here's the actual reader code:

C++:
[SIZE=2][COLOR=#008000]// Read matrix elements from an input stream. Assumes well-formed data, line by line,[/COLOR][/SIZE]
[SIZE=2][COLOR=#008000]// terminated by CtrlZ (if from screen) or EOF (if from file)[/COLOR][/SIZE]
[SIZE=2]matrix<[/SIZE][SIZE=2][COLOR=#0000ff]double[/COLOR][/SIZE][SIZE=2]> readMatrix(istream &data)[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2]std::vector<[/SIZE][SIZE=2][COLOR=#0000ff]double[/COLOR][/SIZE][SIZE=2]> rowValues;[/SIZE]
[SIZE=2]std::vector<std::vector<[/SIZE][SIZE=2][COLOR=#0000ff]double[/COLOR][/SIZE][SIZE=2]> > rows;[/SIZE]
[SIZE=2][COLOR=#0000ff]while[/COLOR][/SIZE][SIZE=2] ([/SIZE][SIZE=2][COLOR=#0000ff]true[/COLOR][/SIZE][SIZE=2])[/SIZE]
[SIZE=2]{[/SIZE]
     [SIZE=2][COLOR=#0000ff]char[/COLOR][/SIZE][SIZE=2] line[256];[/SIZE]
     [SIZE=2]data.getline(line, [/SIZE][SIZE=2][COLOR=#0000ff]sizeof[/COLOR][/SIZE][SIZE=2](line));[/SIZE]
[SIZE=2][COLOR=#0000ff]if[/COLOR][/SIZE][SIZE=2] (data.fail() || data.eof())[/SIZE]
[SIZE=2]{[/SIZE]
     [SIZE=2][COLOR=#0000ff]break[/COLOR][/SIZE][SIZE=2];[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2]istrstream doubles(line);[/SIZE]
[SIZE=2][COLOR=#0000ff]while[/COLOR][/SIZE][SIZE=2] (!doubles.fail() && !doubles.eof())[/SIZE]
[SIZE=2]{[/SIZE]
    [SIZE=2]ws(doubles);[/SIZE]
    [SIZE=2][COLOR=#0000ff]double[/COLOR][/SIZE][SIZE=2] element;[/SIZE]
    [SIZE=2]doubles >> element;[/SIZE]
[SIZE=2][COLOR=#0000ff]if[/COLOR][/SIZE][SIZE=2] (doubles.fail())[/SIZE]
[SIZE=2]{[/SIZE]
      [SIZE=2]cerr << [/SIZE][SIZE=2][COLOR=#800000]"malformed input line ("[/COLOR][/SIZE][SIZE=2] << string(line) << [/SIZE][SIZE=2][COLOR=#800000]")"[/COLOR][/SIZE][SIZE=2] << endl;[/SIZE]
[SIZE=2]}[/SIZE]
 
[SIZE=2]rowValues.push_back(element);[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2]rows.push_back(rowValues);[/SIZE]
[SIZE=2]rowValues.clear();[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2][COLOR=#008000]// Reset input stream state[/COLOR][/SIZE]
[SIZE=2]data.clear();[/SIZE]
[SIZE=2]matrix<[/SIZE][SIZE=2][COLOR=#0000ff]double[/COLOR][/SIZE][SIZE=2]> m(rows.size(), rows.front().size());[/SIZE]
[SIZE=2]std::vector<std::vector<[/SIZE][SIZE=2][COLOR=#0000ff]double[/COLOR][/SIZE][SIZE=2]> >::const_iterator rowData = rows.begin();[/SIZE]
[SIZE=2]Dimension next(0);[/SIZE]
[SIZE=2][COLOR=#0000ff]while[/COLOR][/SIZE][SIZE=2] (rowData != rows.end())[/SIZE]
[SIZE=2]{[/SIZE]
     [SIZE=2]matrix_row<matrix<[/SIZE][SIZE=2][COLOR=#0000ff]double[/COLOR][/SIZE][SIZE=2]> > mri (row(m, next));[/SIZE]
     [SIZE=2]std::vector<[/SIZE][SIZE=2][COLOR=#0000ff]double[/COLOR][/SIZE][SIZE=2]>::const_iterator nextData = rowData->begin();[/SIZE]
     [SIZE=2]matrix_row<matrix<[/SIZE][SIZE=2][COLOR=#0000ff]double[/COLOR][/SIZE][SIZE=2]> >::iterator matrixData = mri.begin();[/SIZE]
[SIZE=2][COLOR=#0000ff]while[/COLOR][/SIZE][SIZE=2] (nextData != rowData->end())[/SIZE]
[SIZE=2]{[/SIZE]
     [SIZE=2]*matrixData = *nextData;[/SIZE]
     [SIZE=2]++matrixData;[/SIZE]
     [SIZE=2]++nextData;[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2]++rowData;[/SIZE]
[SIZE=2]++next;[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2]cout << m;[/SIZE]
[SIZE=2][COLOR=#0000ff]return[/COLOR][/SIZE][SIZE=2] m;[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2]matrix<[/SIZE][SIZE=2][COLOR=#0000ff]double[/COLOR][/SIZE][SIZE=2]> readMatrix(string filename)[/SIZE]
[SIZE=2]{[/SIZE]
    [SIZE=2]ifstream myFile;[/SIZE]
    [SIZE=2]myFile.open(filename.c_str());[/SIZE]
[SIZE=2][COLOR=#0000ff]if[/COLOR][/SIZE][SIZE=2] (!myFile.fail())[/SIZE]
[SIZE=2]{[/SIZE]
    [SIZE=2][COLOR=#0000ff]return[/COLOR][/SIZE][SIZE=2] readMatrix(myFile);[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2][COLOR=#0000ff]else[/COLOR][/SIZE]
[SIZE=2]{[/SIZE]
    [SIZE=2]cerr << [/SIZE][SIZE=2][COLOR=#800000]"cannot open file: ("[/COLOR][/SIZE][SIZE=2] << filename << [/SIZE][SIZE=2][COLOR=#800000]")"[/COLOR][/SIZE][SIZE=2] << endl;[/SIZE]
[SIZE=2][COLOR=#0000ff]throw[/COLOR][/SIZE][SIZE=2][COLOR=#800000]"cannot open file"[/COLOR][/SIZE][SIZE=2];[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2]}[/SIZE]
 
Ok, I manually edited your post to see if the indentation work. let's see
C++:
[SIZE=2][COLOR=#008000]// Read matrix elements from an input stream. Assumes well-formed data, line by line,[/COLOR][/SIZE]
[SIZE=2][COLOR=#008000]// terminated by CtrlZ (if from screen) or EOF (if from file)[/COLOR][/SIZE]
[SIZE=2]matrix<[/SIZE][SIZE=2][COLOR=#0000ff]double[/COLOR][/SIZE][SIZE=2]> readMatrix(istream &data)[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2]std::vector<[/SIZE][SIZE=2][COLOR=#0000ff]double[/COLOR][/SIZE][SIZE=2]> rowValues;[/SIZE]
[SIZE=2]std::vector<std::vector<[/SIZE][SIZE=2][COLOR=#0000ff]double[/COLOR][/SIZE][SIZE=2]> > rows;[/SIZE]
[SIZE=2][COLOR=#0000ff]while[/COLOR][/SIZE][SIZE=2] ([/SIZE][SIZE=2][COLOR=#0000ff]true[/COLOR][/SIZE][SIZE=2])[/SIZE]
[SIZE=2]{[/SIZE]
     [SIZE=2][COLOR=#0000ff]char[/COLOR][/SIZE][SIZE=2] line[256];[/SIZE]
     [SIZE=2]data.getline(line, [/SIZE][SIZE=2][COLOR=#0000ff]sizeof[/COLOR][/SIZE][SIZE=2](line));[/SIZE]
[SIZE=2][COLOR=#0000ff]if[/COLOR][/SIZE][SIZE=2] (data.fail() || data.eof())[/SIZE]
[SIZE=2]{[/SIZE]
     [SIZE=2][COLOR=#0000ff]break[/COLOR][/SIZE][SIZE=2];[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2]istrstream doubles(line);[/SIZE]
[SIZE=2][COLOR=#0000ff]while[/COLOR][/SIZE][SIZE=2] (!doubles.fail() && !doubles.eof())[/SIZE]
[SIZE=2]{[/SIZE]
    [SIZE=2]ws(doubles);[/SIZE]
    [SIZE=2][COLOR=#0000ff]double[/COLOR][/SIZE][SIZE=2] element;[/SIZE]
    [SIZE=2]doubles >> element;[/SIZE]
[SIZE=2][COLOR=#0000ff]if[/COLOR][/SIZE][SIZE=2] (doubles.fail())[/SIZE]
[SIZE=2]{[/SIZE]
      [SIZE=2]cerr << [/SIZE][SIZE=2][COLOR=#800000]"malformed input line ("[/COLOR][/SIZE][SIZE=2] << string(line) << [/SIZE][SIZE=2][COLOR=#800000]")"[/COLOR][/SIZE][SIZE=2] << endl;[/SIZE]
[SIZE=2]}[/SIZE]
Ok, it seems like I can copy and paste your code OK. when I copy your post above, there seems to be some weird block around your code which I guess is coming from the IDE you used. if I copy and paste from another IDE, the indentation is fine but the color is lost.

Will do some more testing. It should be true WYSIWYG
 

alain

Older and Wiser
Hi Steve,

Nice piece of code. I read in a previous post that you are using uBlas from Boost. I installed it again using the installer and I also tried to install the bindings to ATLAS. Have you tried it? Any luck? ATLAS comes with all the routines that you might need in Linear Algebra.
 
Hi Steve,

Nice piece of code. I read in a previous post that you are using uBlas from Boost. I installed it again using the installer and I also tried to install the bindings to ATLAS. Have you tried it? Any luck? ATLAS comes with all the routines that you might need in Linear Algebra.

Nope I am just using the Boost headers right now. Did not want to get into an area where I am too tempted to just use existing code ;-) If I need truly ultimate perf down the line, I will try one of the optimized lower layer libs.

As it is, I am finding uBlas code (and my own Cholesky code modeled on their programming metaphors) runs anywhere from 2-10 times faster than equivalent for loops coded to use the uBlas structs.
 
Top