Commit 3f2a0c2b authored by Davis King's avatar Davis King

Added an operator>> for matrix objects which allows you to read in

ASCII matrices using the format used by operator<<.
parent 010f87a6
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "matrix/matrix_la.h" #include "matrix/matrix_la.h"
#include "matrix/symmetric_matrix_cache.h" #include "matrix/symmetric_matrix_cache.h"
#include "matrix/matrix_conv.h" #include "matrix/matrix_conv.h"
#include "matrix/matrix_read_from_istream.h"
#ifdef DLIB_USE_BLAS #ifdef DLIB_USE_BLAS
#include "matrix/matrix_blas_bindings.h" #include "matrix/matrix_blas_bindings.h"
......
...@@ -1786,6 +1786,22 @@ namespace dlib ...@@ -1786,6 +1786,22 @@ namespace dlib
return out; return out;
} }
/*
template <
typename T,
long NR,
long NC,
typename MM,
typename L
>
std::istream& operator>> (
std::istream& in,
matrix<T,NR,NC,MM,L>& m
);
This function is defined inside the matrix_read_from_istream.h file.
*/
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
......
...@@ -703,6 +703,34 @@ namespace dlib ...@@ -703,6 +703,34 @@ namespace dlib
- returns out - returns out
!*/ !*/
template <
typename T,
long NR,
long NC,
typename MM,
typename L
>
std::istream& operator>> (
std::istream& in,
matrix<T,NR,NC,MM,L>& m
);
/*!
ensures
- Tries to read a matrix from the given input stream and store it into #m.
- The format expected is the text format output by the above operator<<().
That is, the format should be a grid of text such as:
2 3 4
5 2 6
- The separation between numbers can be any number of whitespace characters or
commas.
- The matrix data is assumed to end upon the first blank line or end-of-file,
whichever comes first. This means you can create an input stream with
multiple matrices in it by separating them with empty lines.
- returns in.
- If there was a formatting error or something which prevents the input data
from being parsed into a matrix then #in.fail() == true.
!*/
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename EXP> template <typename EXP>
......
// Copyright (C) 2013 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_MATRIx_READ_FROM_ISTREAM_H___
#define DLIB_MATRIx_READ_FROM_ISTREAM_H___
#include "matrix.h"
#include <vector>
#include <iostream>
namespace dlib
{
// ----------------------------------------------------------------------------------------
namespace impl
{
inline bool next_is_whitespace (
std::istream& in
)
{
return in.peek() == '\n' ||
in.peek() == ' ' ||
in.peek() == ',' ||
in.peek() == '\t' ||
in.peek() == '\r';
}
}
template <typename T, long NR, long NC, typename MM, typename L>
std::istream& operator>> (
std::istream& in,
matrix<T,NR,NC,MM,L>& m
)
{
using namespace dlib::impl;
long num_rows = 0;
std::vector<T> buf;
buf.reserve(100);
// eat any leading whitespace
while (next_is_whitespace(in))
in.get();
bool at_start_of_line = true;
bool stop = false;
while(!stop && in.peek() != EOF)
{
T temp;
in >> temp;
if (!in)
return in;
buf.push_back(temp);
if (at_start_of_line)
{
at_start_of_line = false;
++num_rows;
}
// Eat next block of whitespace but also note if we hit the start of the next
// line.
int last_ch = 'a'; // set last_ch to anything other than '\n'
while (next_is_whitespace(in))
{
if (last_ch == '\n' && in.peek() == '\n')
{
stop = true;
break;
}
last_ch = in.get();
if (last_ch == '\n')
at_start_of_line = true;
}
}
// It's an error for there to not be any matrix data in the input stream
if (num_rows == 0)
{
in.clear(in.rdstate() | std::ios::failbit);
return in;
}
const long num_cols = buf.size()/num_rows;
// It's also an error if the sizes don't make sense.
if (num_rows*num_cols != (long)buf.size() ||
(NR != 0 && NR != num_rows) ||
(NC != 0 && NC != num_cols))
{
in.clear(in.rdstate() | std::ios::failbit);
return in;
}
m = reshape(mat(buf),num_rows, buf.size()/num_rows);
if (in.eof())
{
// Clear the eof and fail bits since this is caused by peeking at the EOF.
// But in the current case, we have successfully read the matrix.
in.clear(in.rdstate() & (~(std::ios::eofbit | std::ios::failbit)));
}
return in;
}
}
// ----------------------------------------------------------------------------------------
#endif // DLIB_MATRIx_READ_FROM_ISTREAM_H___
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment