57template<
bool row_,
typename Value_,
typename Index_,
typename StoredValue_,
typename StoredIndex_,
typename TempIndex_,
typename Parser_>
58std::shared_ptr<tatami::Matrix<Value_, Index_> > load_sparse_matrix_basic(Parser_& parser, eminem::Field field,
size_t NR,
size_t NC,
size_t NL) {
59 std::vector<typename std::conditional<row_, TempIndex_, StoredIndex_>::type> rows;
60 std::vector<typename std::conditional<!row_, TempIndex_, StoredIndex_>::type> columns;
61 rows.reserve(NL), columns.reserve(NL);
62 std::vector<StoredValue_> values;
65 if (field == eminem::Field::INTEGER) {
66 parser.scan_integer([&](
size_t r,
size_t c,
int v) ->
void {
68 rows.push_back(r - 1);
69 columns.push_back(c - 1);
72 }
else if (field == eminem::Field::REAL || field == eminem::Field::DOUBLE) {
73 parser.scan_real([&](
size_t r,
size_t c,
double v) ->
void {
75 rows.push_back(r - 1);
76 columns.push_back(c - 1);
80 throw std::runtime_error(
"unsupported Matrix Market field type");
84 std::vector<StoredIndex_> indices;
86 indices.swap(columns);
91 return std::shared_ptr<tatami::Matrix<Value_, Index_> >(
93 NR, NC, std::move(values), std::move(indices), std::move(ptr), row_,
false
98template<
bool row_,
typename Value_,
typename Index_,
typename StoredValue_,
typename StoredIndex_,
typename TempIndex_,
typename Parser_>
99std::shared_ptr<tatami::Matrix<Value_, Index_> > load_sparse_matrix_data(Parser_& parser, eminem::Field field,
size_t NR,
size_t NC,
size_t NL) {
100 if constexpr(std::is_same<StoredValue_, Automatic>::value) {
101 if (field == eminem::Field::REAL || field == eminem::Field::DOUBLE) {
102 return load_sparse_matrix_basic<row_, Value_, Index_, double, StoredIndex_, TempIndex_>(parser, field, NR, NC, NL);
104 if (field != eminem::Field::INTEGER) {
105 throw std::runtime_error(
"unsupported Matrix Market field type");
107 return load_sparse_matrix_basic<row_, Value_, Index_, int, StoredIndex_, TempIndex_>(parser, field, NR, NC, NL);
109 return load_sparse_matrix_basic<row_, Value_, Index_, StoredValue_, StoredIndex_, TempIndex_>(parser, field, NR, NC, NL);
113template<
bool row_,
typename Value_,
typename Index_,
typename StoredValue_,
typename StoredIndex_,
typename TempIndex_,
typename Parser_>
114std::shared_ptr<tatami::Matrix<Value_, Index_> > load_sparse_matrix_index(Parser_& parser, eminem::Field field,
size_t NR,
size_t NC,
size_t NL) {
115 if constexpr(std::is_same<StoredIndex_, Automatic>::value) {
117 constexpr size_t limit8 = std::numeric_limits<uint8_t>::max(), limit16 = std::numeric_limits<uint16_t>::max();
118 size_t target = (row_ ? NC : NR);
120 if (target <= limit8) {
121 return load_sparse_matrix_data<row_, Value_, Index_, StoredValue_, uint8_t, TempIndex_>(parser, field, NR, NC, NL);
122 }
else if (target <= limit16) {
123 return load_sparse_matrix_data<row_, Value_, Index_, StoredValue_, uint16_t, TempIndex_>(parser, field, NR, NC, NL);
125 return load_sparse_matrix_data<row_, Value_, Index_, StoredValue_, uint32_t, TempIndex_>(parser, field, NR, NC, NL);
129 return load_sparse_matrix_data<row_, Value_, Index_, StoredValue_, StoredIndex_, TempIndex_>(parser, field, NR, NC, NL);
133template<
bool row_,
typename Value_,
typename Index_,
typename StoredValue_,
typename Parser_>
134std::shared_ptr<tatami::Matrix<Value_, Index_> > load_dense_matrix_basic(Parser_& parser, eminem::Field field,
size_t NR,
size_t NC) {
135 std::vector<StoredValue_> values;
137 values.resize(NR * NC);
139 values.reserve(NR * NC);
142 if (field == eminem::Field::INTEGER) {
143 parser.scan_integer([&](
size_t r,
size_t c,
int v) ->
void {
145 values[(r - 1) * NC + (c - 1)] = v;
151 }
else if (field == eminem::Field::REAL || field == eminem::Field::DOUBLE) {
152 parser.scan_real([&](
size_t r,
size_t c,
double v) ->
void {
154 values[(r - 1) * NC + (c - 1)] = v;
161 throw std::runtime_error(
"unsupported Matrix Market field type");
164 return std::shared_ptr<tatami::Matrix<Value_, Index_> >(
169template<
bool row_,
bool parallel_,
typename Value_,
typename Index_,
typename StoredValue_,
typename StoredIndex_>
171 eminem::Parser<parallel_> parser(&reader);
172 parser.scan_preamble();
174 const auto& banner = parser.get_banner();
175 auto field = banner.field;
176 auto format = banner.format;
177 size_t NR = parser.get_nrows(), NC = parser.get_ncols(), NL = parser.get_nlines();
179 if (format == eminem::Format::COORDINATE) {
181 constexpr size_t limit8 = std::numeric_limits<uint8_t>::max(), limit16 = std::numeric_limits<uint16_t>::max();
182 auto primary = (row_ ? NR : NC);
184 if (primary <= limit8) {
185 return load_sparse_matrix_index<row_, Value_, Index_, StoredValue_, StoredIndex_, uint8_t>(parser, field, NR, NC, NL);
186 }
else if (primary <= limit16) {
187 return load_sparse_matrix_index<row_, Value_, Index_, StoredValue_, StoredIndex_, uint16_t>(parser, field, NR, NC, NL);
189 return load_sparse_matrix_index<row_, Value_, Index_, StoredValue_, StoredIndex_, uint32_t>(parser, field, NR, NC, NL);
193 if constexpr(std::is_same<StoredValue_, Automatic>::value) {
194 if (field == eminem::Field::REAL || field == eminem::Field::DOUBLE) {
195 return load_dense_matrix_basic<row_, Value_, Index_, double>(parser, field, NR, NC);
197 if (field != eminem::Field::INTEGER) {
198 throw std::runtime_error(
"unsupported Matrix Market field type");
200 return load_dense_matrix_basic<row_, Value_, Index_, int>(parser, field, NR, NC);
203 return load_dense_matrix_basic<row_, Value_, Index_, StoredValue_>(parser, field, NR, NC);
230template<
typename Value_,
typename Index_,
typename StoredValue_ = Automatic,
typename StoredIndex_ = Automatic>
234 return internal::load_matrix<true, true, Value_, Index_, StoredValue_, StoredIndex_>(reader);
236 return internal::load_matrix<true, false, Value_, Index_, StoredValue_, StoredIndex_>(reader);
240 return internal::load_matrix<false, true, Value_, Index_, StoredValue_, StoredIndex_>(reader);
242 return internal::load_matrix<false, false, Value_, Index_, StoredValue_, StoredIndex_>(reader);
261template<
typename Value_,
typename Index_,
typename StoredValue_ = Automatic,
typename StoredIndex_ = Automatic>
264 return load_matrix<Value_, Index_, StoredValue_, StoredIndex_>(reader, options);
267#if __has_include("zlib.h")
282template<
typename Value_,
typename Index_,
typename StoredValue_ = Automatic,
typename StoredIndex_ = Automatic>
285 return load_matrix<Value_, Index_, StoredValue_, StoredIndex_>(reader, options);
301template<
typename Value_,
typename Index_,
typename StoredValue_ = Automatic,
typename StoredIndex_ = Automatic>
304 return load_matrix<Value_, Index_, StoredValue_, StoredIndex_>(reader, options);
323template<
typename Value_,
typename Index_,
typename StoredValue_ = Automatic,
typename StoredIndex_ = Automatic>
326 return load_matrix<Value_, Index_, StoredValue_, StoredIndex_>(reader, options);
329#if __has_include("zlib.h")
345template<
typename Value_,
typename Index_,
typename StoredValue_ = Automatic,
typename StoredIndex_ = Automatic>
348 return load_matrix<Value_, Index_, StoredValue_, StoredIndex_>(reader, options);
365template<
typename Value_,
typename Index_,
typename StoredValue_ = Automatic,
typename StoredIndex_ = Automatic>
368 return load_matrix<Value_, Index_, StoredValue_, StoredIndex_>(reader, options);