171 qWarning(
"[FiffSparseMatrix::fiff_get_float_sparse_matrix] wrong data type!");
180 qWarning(
"[FiffSparseMatrix::fiff_get_float_sparse_matrix] wrong # of dimensions!");
196 qWarning(
"[FiffSparseMatrix::fiff_get_float_sparse_matrix] Incomprehensible sparse matrix coding");
199 if (tag->size() != correct_size) {
200 qWarning(
"[FiffSparseMatrix::fiff_get_float_sparse_matrix] wrong data size!");
206 auto res = std::make_unique<FiffSparseMatrix>();
212 const float* src_data =
reinterpret_cast<const float*
>(tag->data());
213 const int* src_inds =
reinterpret_cast<const int*
>(src_data +
nz);
214 const int* src_ptrs = src_inds +
nz;
217 res->data = Eigen::Map<const Eigen::VectorXf>(src_data,
nz);
218 res->inds = Eigen::Map<const Eigen::VectorXi>(src_inds,
nz);
219 res->ptrs = Eigen::Map<const Eigen::VectorXi>(src_ptrs, ptrs_count);
230 for (j = 0,
nz = 0; j < nrow; j++)
234 qWarning(
"[FiffSparseMatrix::create_sparse_rcs] No nonzero elements specified.");
238 auto sparse = std::make_unique<FiffSparseMatrix>();
243 sparse->data = Eigen::VectorXf::Zero(
nz);
244 sparse->inds = Eigen::VectorXi::Zero(
nz);
245 sparse->ptrs = Eigen::VectorXi::Zero(nrow + 1);
247 for (j = 0,
nz = 0; j < nrow; j++) {
249 for (k = 0; k < nnz[j]; k++) {
252 ind = sparse->inds[
nz] = colindex[j][k];
253 if (ind < 0 || ind >= ncol) {
254 qWarning(
"[FiffSparseMatrix::create_sparse_rcs] Column index out of range");
258 sparse->data[
nz] = vals[j][k];
260 sparse->data[
nz] = 0.0;
263 sparse->ptrs[j] = ptr;
265 sparse->ptrs[nrow] =
nz;
266 for (j = nrow-1; j >= 0; j--)
267 if (sparse->ptrs[j] < 0)
268 sparse->ptrs[j] = sparse->ptrs[j+1];
280 qWarning(
"[FiffSparseMatrix::mne_add_upper_triangle_rcs] input must be in RCS format");
283 if (this->
m != this->
n) {
284 qWarning(
"[FiffSparseMatrix::mne_add_upper_triangle_rcs] input must be square");
289 std::vector<int> nnz_vec(this->
m);
290 std::vector<std::vector<int>> colindex(this->
m);
291 std::vector<std::vector<float>> vals(this->
m);
293 for (
int i = 0; i < this->
m; i++) {
294 nnz_vec[i] = this->
ptrs[i+1] - this->
ptrs[i];
295 if (nnz_vec[i] > 0) {
296 colindex[i].resize(nnz_vec[i]);
297 vals[i].resize(nnz_vec[i]);
298 for (
int j = this->ptrs[i], k = 0; j < this->ptrs[i+1]; j++, k++) {
299 vals[i][k] = this->
data[j];
300 colindex[i][k] = this->
inds[j];
306 std::vector<int> nadd(this->m, 0);
307 for (
int i = 0; i < this->m; i++)
308 for (
int j = this->
ptrs[i]; j < this->
ptrs[i+1]; j++)
309 nadd[this->
inds[j]]++;
312 for (
int i = 0; i < this->m; i++) {
313 colindex[i].resize(nnz_vec[i] + nadd[i]);
314 vals[i].resize(nnz_vec[i] + nadd[i]);
316 for (
int i = 0; i < this->m; i++)
317 for (
int j = this->ptrs[i]; j < this->ptrs[i+1]; j++) {
318 int row = this->
inds[j];
319 colindex[row][nnz_vec[row]] = i;
320 vals[row][nnz_vec[row]] = this->
data[j];
325 std::vector<int*> ci_ptrs(this->m);
326 std::vector<float*> val_ptrs(this->m);
327 for (
int i = 0; i < this->m; i++) {
328 ci_ptrs[i] = colindex[i].data();
329 val_ptrs[i] = vals[i].data();
332 return create_sparse_rcs(this->m, this->
n, nnz_vec.data(), ci_ptrs.data(), val_ptrs.data());
340 return Eigen::SparseMatrix<double>();
342 using T = Eigen::Triplet<double>;
343 std::vector<T> tripletList;
344 tripletList.reserve(
nz);
347 for (
int row = 0; row <
m; ++row) {
348 for (
int j =
ptrs[row]; j <
ptrs[row + 1]; ++j) {
349 tripletList.push_back(T(row,
inds[j],
static_cast<double>(
data[j])));
353 for (
int col = 0; col <
n; ++col) {
354 for (
int j =
ptrs[col]; j <
ptrs[col + 1]; ++j) {
355 tripletList.push_back(T(
inds[j], col,
static_cast<double>(
data[j])));
359 qWarning(
"[FiffSparseMatrix::toEigenSparse] Unknown coding type: %d",
coding);
360 return Eigen::SparseMatrix<double>();
363 Eigen::SparseMatrix<double> result(
m,
n);
364 result.setFromTriplets(tripletList.begin(), tripletList.end());
373 if (mat.nonZeros() == 0) {
383 result.
data = Eigen::VectorXf::Zero(result.
nz);
384 result.
inds = Eigen::VectorXi::Zero(result.
nz);
385 result.
ptrs = Eigen::VectorXi::Zero(result.
m + 1);
388 using T = Eigen::Triplet<double>;
389 std::vector<T> triplets;
390 triplets.reserve(mat.nonZeros());
391 for (
int k = 0; k < mat.outerSize(); ++k) {
392 for (Eigen::SparseMatrix<double>::InnerIterator it(mat, k); it; ++it) {
393 triplets.push_back(T(it.row(), it.col(), it.value()));
396 std::sort(triplets.begin(), triplets.end(),
397 [](
const T& a,
const T& b) {
398 return a.row() < b.row() || (a.row() == b.row() && a.col() < b.col());
404 for (
const auto& t : triplets) {
405 while (row < t.row()) {
406 result.
ptrs[++row] = idx;
408 result.
data[idx] =
static_cast<float>(t.value());
409 result.
inds[idx] =
static_cast<int>(t.col());
412 while (row < result.
m) {
413 result.
ptrs[++row] = idx;
424 qWarning(
"[FiffSparseMatrix::pickLowerTriangleRcs] input must be in RCS format");
428 qWarning(
"[FiffSparseMatrix::pickLowerTriangleRcs] input must be square");
432 std::vector<int> nnz_vec(
m);
433 std::vector<std::vector<int>> colindex(
m);
434 std::vector<std::vector<float>> vals(
m);
436 for (
int i = 0; i <
m; i++) {
439 colindex[i].resize(count);
440 vals[i].resize(count);
442 for (
int j =
ptrs[i]; j <
ptrs[i+1]; j++) {
444 vals[i][k] =
data[j];
445 colindex[i][k] =
inds[j];
455 std::vector<int*> ci_ptrs(
m);
456 std::vector<float*> val_ptrs(
m);
457 for (
int i = 0; i <
m; i++) {
458 ci_ptrs[i] = colindex[i].empty() ? nullptr : colindex[i].data();
459 val_ptrs[i] = vals[i].empty() ? nullptr : vals[i].data();