170 qWarning(
"[FiffSparseMatrix::fiff_get_float_sparse_matrix] wrong data type!");
179 qWarning(
"[FiffSparseMatrix::fiff_get_float_sparse_matrix] wrong # of dimensions!");
195 qWarning(
"[FiffSparseMatrix::fiff_get_float_sparse_matrix] Incomprehensible sparse matrix coding");
198 if (tag->size() != correct_size) {
199 qWarning(
"[FiffSparseMatrix::fiff_get_float_sparse_matrix] wrong data size!");
205 auto res = std::make_unique<FiffSparseMatrix>();
211 const float* src_data =
reinterpret_cast<const float*
>(tag->data());
212 const int* src_inds =
reinterpret_cast<const int*
>(src_data +
nz);
213 const int* src_ptrs = src_inds +
nz;
216 res->data = Eigen::Map<const Eigen::VectorXf>(src_data,
nz);
217 res->inds = Eigen::Map<const Eigen::VectorXi>(src_inds,
nz);
218 res->ptrs = Eigen::Map<const Eigen::VectorXi>(src_ptrs, ptrs_count);
229 for (j = 0,
nz = 0; j < nrow; j++)
233 qWarning(
"[FiffSparseMatrix::create_sparse_rcs] No nonzero elements specified.");
237 auto sparse = std::make_unique<FiffSparseMatrix>();
242 sparse->data = Eigen::VectorXf::Zero(
nz);
243 sparse->inds = Eigen::VectorXi::Zero(
nz);
244 sparse->ptrs = Eigen::VectorXi::Zero(nrow + 1);
246 for (j = 0,
nz = 0; j < nrow; j++) {
248 for (k = 0; k < nnz[j]; k++) {
251 ind = sparse->inds[
nz] = colindex[j][k];
252 if (ind < 0 || ind >= ncol) {
253 qWarning(
"[FiffSparseMatrix::create_sparse_rcs] Column index out of range");
257 sparse->data[
nz] = vals[j][k];
259 sparse->data[
nz] = 0.0;
262 sparse->ptrs[j] = ptr;
264 sparse->ptrs[nrow] =
nz;
265 for (j = nrow-1; j >= 0; j--)
266 if (sparse->ptrs[j] < 0)
267 sparse->ptrs[j] = sparse->ptrs[j+1];
279 qWarning(
"[FiffSparseMatrix::mne_add_upper_triangle_rcs] input must be in RCS format");
282 if (this->
m != this->
n) {
283 qWarning(
"[FiffSparseMatrix::mne_add_upper_triangle_rcs] input must be square");
288 std::vector<int> nnz_vec(this->
m);
289 std::vector<std::vector<int>> colindex(this->
m);
290 std::vector<std::vector<float>> vals(this->
m);
292 for (
int i = 0; i < this->
m; i++) {
293 nnz_vec[i] = this->
ptrs[i+1] - this->
ptrs[i];
294 if (nnz_vec[i] > 0) {
295 colindex[i].resize(nnz_vec[i]);
296 vals[i].resize(nnz_vec[i]);
297 for (
int j = this->ptrs[i], k = 0; j < this->ptrs[i+1]; j++, k++) {
298 vals[i][k] = this->
data[j];
299 colindex[i][k] = this->
inds[j];
305 std::vector<int> nadd(this->m, 0);
306 for (
int i = 0; i < this->m; i++)
307 for (
int j = this->
ptrs[i]; j < this->
ptrs[i+1]; j++)
308 nadd[this->
inds[j]]++;
311 for (
int i = 0; i < this->m; i++) {
312 colindex[i].resize(nnz_vec[i] + nadd[i]);
313 vals[i].resize(nnz_vec[i] + nadd[i]);
315 for (
int i = 0; i < this->m; i++)
316 for (
int j = this->ptrs[i]; j < this->ptrs[i+1]; j++) {
317 int row = this->
inds[j];
318 colindex[row][nnz_vec[row]] = i;
319 vals[row][nnz_vec[row]] = this->
data[j];
324 std::vector<int*> ci_ptrs(this->m);
325 std::vector<float*> val_ptrs(this->m);
326 for (
int i = 0; i < this->m; i++) {
327 ci_ptrs[i] = colindex[i].data();
328 val_ptrs[i] = vals[i].data();
331 return create_sparse_rcs(this->m, this->
n, nnz_vec.data(), ci_ptrs.data(), val_ptrs.data());
339 return Eigen::SparseMatrix<double>();
341 typedef Eigen::Triplet<double> T;
342 std::vector<T> tripletList;
343 tripletList.reserve(
nz);
346 for (
int row = 0; row <
m; ++row) {
347 for (
int j =
ptrs[row]; j <
ptrs[row + 1]; ++j) {
348 tripletList.push_back(T(row,
inds[j],
static_cast<double>(
data[j])));
352 for (
int col = 0; col <
n; ++col) {
353 for (
int j =
ptrs[col]; j <
ptrs[col + 1]; ++j) {
354 tripletList.push_back(T(
inds[j], col,
static_cast<double>(
data[j])));
358 qWarning(
"[FiffSparseMatrix::toEigenSparse] Unknown coding type: %d",
coding);
359 return Eigen::SparseMatrix<double>();
362 Eigen::SparseMatrix<double> result(
m,
n);
363 result.setFromTriplets(tripletList.begin(), tripletList.end());
372 if (mat.nonZeros() == 0) {
382 result.
data = Eigen::VectorXf::Zero(result.
nz);
383 result.
inds = Eigen::VectorXi::Zero(result.
nz);
384 result.
ptrs = Eigen::VectorXi::Zero(result.
m + 1);
387 typedef Eigen::Triplet<double> T;
388 std::vector<T> triplets;
389 triplets.reserve(mat.nonZeros());
390 for (
int k = 0; k < mat.outerSize(); ++k) {
391 for (Eigen::SparseMatrix<double>::InnerIterator it(mat, k); it; ++it) {
392 triplets.push_back(T(it.row(), it.col(), it.value()));
395 std::sort(triplets.begin(), triplets.end(),
396 [](
const T& a,
const T& b) {
397 return a.row() < b.row() || (a.row() == b.row() && a.col() < b.col());
403 for (
const auto& t : triplets) {
404 while (row < t.row()) {
405 result.
ptrs[++row] = idx;
407 result.
data[idx] =
static_cast<float>(t.value());
408 result.
inds[idx] =
static_cast<int>(t.col());
411 while (row < result.
m) {
412 result.
ptrs[++row] = idx;