#ifndef IOBIND_UBLAS_MATRIX_POLICY_HPP
#define IOBIND_UBLAS_MATRIX_POLICY_HPP
#include <string>
#include <sstream>
#include <iobind/policy.hpp>
#include <iobind/sequence_policy.hpp>
#include <iobind/pair_parser.hpp>
#include <iobind/data_policy_property.hpp>
#include <iobind/dimension_policy_property.hpp>
#include <iobind/ublas_dimension_policy.hpp>
#include <iobind/item_policy_property.hpp>
#include <iobind/dimension_decorators_property.hpp>
#include <iobind/item_decorators_property.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/banded.hpp>
namespace iobind{
namespace detail{
template<
typename DimensionPolicy,
typename DataPolicy,
typename MatrixDimensionPolicy
>
class ublas_matrix_to_string_policy:
public property::dimension_policy_property<DimensionPolicy>,
public property::data_policy_property<DataPolicy>,
public MatrixDimensionPolicy
{
public:
typedef property::dimension_policy_property<DimensionPolicy> dimension_policy_property_type;
typedef property::data_policy_property<DataPolicy> data_policy_property_type;
typedef std::string return_type;
typedef std::string const& string_param_type;
explicit ublas_matrix_to_string_policy(
dimension_policy_param_type dimension_policy_,
data_policy_param_type data_policy_
)
:
dimension_policy_property_type(dimension_policy_),
data_policy_property_type(data_policy_)
{};
template<typename Matrix>
return_type encode(Matrix const& matrix_) const
{
std::ostringstream output;
std::vector<size_t> dims;
fill_dimensions(matrix_, dims);
// output size and elements
output<<get_dimension_policy().encode(dims.begin(), dims.end());
output<<get_data_policy().encode(
matrix_.data().begin(),
matrix_.data().end()
);
return output.str();
};
};
template<
typename Matrix,
typename ItemPolicy,
typename ResizePolicy,
typename BuildDataPolicy
>
class ublas_matrix_from_string_policy:
public property::item_policy_property<ItemPolicy>,
public property::item_decorators_property,
public property::dimension_decorators_property,
public ResizePolicy,
public BuildDataPolicy
{
public:
typedef property::item_policy_property<ItemPolicy> item_policy_property_type;
typedef property::item_decorators_property item_decorators_property_type;
typedef property::dimension_decorators_property dimension_decorators_property_type;
typedef Matrix matrix_type;
typedef matrix_type return_type;
typedef std::pair<matrix_type::size_type,matrix_type::size_type> matrix_size_type;
typedef std::pair<matrix_type::size_type, matrix_type::value_type> matrix_item_type;
typedef std::string string_type;
typedef string_type const& string_param_type;
explicit ublas_matrix_from_string_policy(
item_policy_param_type item_policy_,
string_param_type dimension_begin_,
string_param_type dimension_delimiter_,
string_param_type dimension_end_,
string_param_type items_begin_,
string_param_type items_delimiter_,
string_param_type items_end_
)
:
item_policy_property_type( item_policy_),
dimension_decorators_property_type(dimension_begin_, dimension_delimiter_, dimension_end_),
item_decorators_property_type(items_begin_, items_delimiter_, items_end_)
{};
return_type encode( string_param_type string_) const
{
matrix_type m;
std::vector<matrix_type::size_type> dims;
boost::spirit::parse_info<> info = parser::build_sequence_from_string(
string_,
dims,
from_string<matrix_type::size_type>(),
get_dimension_begin(),
get_dimension_delimiter(),
get_dimension_end()
);
// check if match
if (!info.hit)
{
std::cerr
<<"ublas_matrix_from_string_policy: could not find dimensions of matrix"
<<std::endl;
return matrix_type();
};
// if right number of dims
if (!resize(m,dims))
{
std::cerr<<"ublas_matrix_from_string_policy: invalid dimensions"<<std::endl;
return matrix_type();
}
if (info.full)
{
std::cerr<<"ublas_matrix_from_string_policy: found dimensions but no data?"<<std::endl;
return matrix_type();
}
assert( info.length < string_.size() );
size_t index=make_sequence_from_string(
string_.c_str() + info.length,
m.data(),
get_item_policy(),
get_items_begin(),
get_items_delimiter(),
get_items_end()
);
if ( index != m.data().size() )
{
std::cerr<<"ublas_banded_matrix_from_string: data is not compatible with matrix dimensions"<<std::endl
<<"nb of data: "<<m.data().size()<<", found "<<index<<std::endl;
return matrix_type();
}
return m;
};
};
}; //detail
template<
typename DimensionPolicy,
typename DataPolicy,
typename MatrixDimensionPolicy
>
class ublas_matrix_to_string :
public detail::policy_cons<
detail::ublas_matrix_to_string_policy<DimensionPolicy,DataPolicy,MatrixDimensionPolicy> ,
detail::identity_policy >
{
public:
typedef DimensionPolicy const& dimension_policy_const_reference;
typedef DataPolicy const& data_policy_const_reference;
typedef ublas_matrix_to_string<DimensionPolicy,DataPolicy,MatrixDimensionPolicy> type;
typedef detail::ublas_matrix_to_string_policy<DimensionPolicy,DataPolicy,MatrixDimensionPolicy>
ublas_matrix_to_string_policy_type;
typedef detail::policy_cons<
ublas_matrix_to_string_policy_type ,
detail::identity_policy
> policy_type;
typedef policy_type::head_type::string_param_type string_param_type;
explicit ublas_matrix_to_string(
dimension_policy_const_reference dimension_policy_ ,
data_policy_const_reference data_policy_
)
: policy_type(
ublas_matrix_to_string_policy_type(
dimension_policy_,
data_policy_
),
detail::identity_policy()
)
{};
// replaces the ineer policy
template<typename P>
ublas_matrix_to_string< DimensionPolicy, P,MatrixDimensionPolicy >
change_data_policy( P const& data_policy_) const
{
return ublas_matrix_to_string< DimensionPolicy,P,MatrixDimensionPolicy >(
get_head().get_dimension_policy(),
data_policy_
);
};
template<typename P >
ublas_matrix_to_string< DimensionPolicy, P,MatrixDimensionPolicy>
operator << ( P const& data_policy_) const
{
return change_data_policy(data_policy_);
};
// replaces the ineer policy
template<typename P>
ublas_matrix_to_string< P, DataPolicy,MatrixDimensionPolicy >
change_dimension_policy( P const& dimension_policy_) const
{
return ublas_matrix_to_string< P, DataPolicy,MatrixDimensionPolicy >(
dimension_policy_,
get_head().get_data_policy()
);
};
// replaces the ineer policy
template<typename P>
ublas_matrix_to_string<P, DataPolicy, MatrixDimensionPolicy >
operator >> ( P const& dimension_policy_) const
{
return change_dimension_policy(dimension_policy_);
};
template<typename P>
ublas_matrix_to_string<DimensionPolicy, DataPolicy, P>
change_matrix_sizer( P const& dummy_) const
{
return ublas_matrix_to_string<DimensionPolicy, DataPolicy, P>(
get_head().get_dimension_policy()
get_head().get_data_policy()
);
}
};
typedef ublas_matrix_to_string<
sequence_to_string_p_type,
sequence_to_string_p_type,
detail::fill_dimensions_matrix2
> ublas_matrix_to_string_p_type;
const ublas_matrix_to_string_p_type
ublas_matrix_to_string_p =
ublas_matrix_to_string_p_type(sequence_to_string_p, sequence_to_string_p);
template<
typename Matrix,
typename ItemPolicy,
typename ResizePolicy,
typename BuildDataPolicy
>
class ublas_matrix_from_string :
public detail::policy_cons<
detail::ublas_matrix_from_string_policy<Matrix,ItemPolicy,ResizePolicy,BuildDataPolicy>,
detail::identity_policy
>
{
public:
typedef detail::ublas_matrix_from_string_policy<Matrix,ItemPolicy,ResizePolicy,BuildDataPolicy>
ublas_matrix_from_string_policy_type;
typedef detail::policy_cons< ublas_matrix_from_string_policy_type,detail::identity_policy > policy_type;
typedef ItemPolicy const& item_policy_param_type;
typedef std::string const& string_param_type;
typedef ublas_matrix_from_string<Matrix,ItemPolicy,ResizePolicy,BuildDataPolicy> type;
explicit ublas_matrix_from_string(
item_policy_param_type item_policy_,
string_param_type dimension_begin_="(",
string_param_type dimension_delimiter_ =",",
string_param_type dimension_end_ = ")",
string_param_type items_begin_ = "(",
string_param_type items_delimiter_ = ",",
string_param_type items_end_ = ")"
)
: policy_type(
ublas_matrix_from_string_policy_type(
item_policy_,
dimension_begin_,
dimension_delimiter_,
dimension_end_,
items_begin_,
items_delimiter_,
items_end_
),
detail::identity_policy()
)
{};
// set items decorators
type set_dimension_decorators(
string_param_type begin_,
string_param_type delimiter_,
string_param_type end_
) const
{
return type(
get_head().get_item_policy(),
begin_,
delimiter_,
end_,
get_head().get_items_begin(),
get_head().get_items_delimiter(),
get_head().get_items_end()
);
};
// set items decorators
type set_item_decorators(
string_param_type begin_,
string_param_type delimiter_,
string_param_type end_
) const
{
return type(
get_head().get_item_policy(),
get_head().get_dimension_begin(),
get_head().get_dimension_delimiter(),
get_head().get_dimension_end(),
begin_,
delimiter_,
end_
);
};
// replace the container type
template<typename M>
ublas_matrix_from_string<M,ItemPolicy,ResizePolicy,BuildDataPolicy>
change_matrix_type( M const& dummy_matrix) const
{
return ublas_matrix_from_string<M,ItemPolicy,ResizePolicy,BuildDataPolicy>(
get_head().get_item_policy(),
get_head().get_dimension_begin(),
get_head().get_dimension_delimiter(),
get_head().get_dimension_end(),
get_head().get_items_begin(),
get_head().get_items_delimiter(),
get_head().get_items_end()
);
};
template<typename M>
ublas_matrix_from_string<M,ItemPolicy,ResizePolicy,BuildDataPolicy> operator%( M const& dummy_matrix) const
{
return change_matrix_type(dummy_matrix);
};
// change the item policy
template<typename P>
ublas_matrix_from_string< Matrix, P, ResizePolicy,BuildDataPolicy >
change_item_policy( P const& item_policy_) const
{
return ublas_matrix_from_string< Matrix,P, ResizePolicy,BuildDataPolicy >(
item_policy_,
get_head().get_dimension_begin(),
get_head().get_dimension_delimiter(),
get_head().get_dimension_end(),
get_head().get_items_begin(),
get_head().get_items_delimiter(),
get_head().get_items_end()
);
};
// replaces the item policy
template<typename P>
ublas_matrix_from_string< Matrix, P, ResizePolicy,BuildDataPolicy >
operator <<( P const& item_policy_) const
{
return change_item_policy(item_policy_);
};
template<typename P>
ublas_matrix_from_string< Matrix, ItemPolicy, P,BuildDataPolicy >
change_resize_policy( P const& resize_policy_) const
{
return ublas_matrix_from_string< Matrix,ItemPolicy,P,BuildDataPolicy >(
get_head().get_item_policy(),
get_head().get_dimension_begin(),
get_head().get_dimension_delimiter(),
get_head().get_dimension_end(),
get_head().get_items_begin(),
get_head().get_items_delimiter(),
get_head().get_items_end()
);
};
template<typename P>
ublas_matrix_from_string< Matrix, ItemPolicy, ResizePolicy,P>
change_build_data_policy( P const& build_data_policy_) const
{
return ublas_matrix_from_string<Matrix, ItemPolicy, ResizePolicy,P>(
get_head().get_item_policy(),
get_head().get_dimension_begin(),
get_head().get_dimension_delimiter(),
get_head().get_dimension_end(),
get_head().get_items_begin(),
get_head().get_items_delimiter(),
get_head().get_items_end()
);
};
};
typedef ublas_matrix_from_string<
boost::numeric::ublas::matrix<double>,
from_string<double>,
detail::resize2_matrix,
parser::sequence_from_string_filler
> ublas_matrix_from_string_p_type;
const ublas_matrix_from_string_p_type ublas_matrix_from_string_p=
ublas_matrix_from_string_p_type( from_string<double>() );
}; // iobind
#endif