• C++ Programming for Financial Engineering
    Highly recommended by thousands of MFE students. Covers essential C++ topics with applications to financial engineering. Learn more Join!
    Python for Finance with Intro to Data Science
    Gain practical understanding of Python to read, understand, and write professional Python code for your first day on the job. Learn more Join!
    An Intuition-Based Options Primer for FE
    Ideal for entry level positions interviews and graduate studies, specializing in options trading arbitrage and options valuation models. Learn more Join!

Matrix input

Joined
11/14/06
Messages
80
Points
16
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]
 
indention is lost

Yes, I can't seem to do anything about this. I think the web software drops whitespace to keep the post size down. Is there a way to make stuff inside really be treated WYSIWYG?
 
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
 
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.
 
Back
Top