65 unsigned int tsize = tag->size();
69 if (tag->data() ==
nullptr) {
70 qCritical(
"fiff_get_matrix_dims: no data available!");
74 qCritical(
"fiff_get_matrix_dims: tag does not contain a matrix!");
78 qCritical(
"fiff_get_matrix_dims: too small matrix data!");
86 qCritical(
"fiff_get_matrix_dims: unreasonable # of dimensions!");
91 qCritical(
"fiff_get_matrix_dims: too small matrix data!");
94 std::vector<int> res(ndim + 1);
97 for (
int k = 0; k < ndim; k++)
102 if (tsize < (ndim + 2) *
sizeof(
fiff_int_t)) {
103 qCritical(
"fiff_get_matrix_sparse_dims: too small matrix data!");
106 std::vector<int> res(ndim + 2);
109 for (
int k = 0; k < ndim; k++)
110 res[k + 1] = dims[k];
111 res[ndim + 1] = dims[-1];
114 qCritical(
"fiff_get_matrix_dims: unknown matrix coding.");
133, m_eigen(std::move(mat))
149 int cod, correct_size;
155 qWarning(
"[FiffSparseMatrix::fiff_get_float_sparse_matrix] wrong data type!");
164 qWarning(
"[FiffSparseMatrix::fiff_get_float_sparse_matrix] wrong # of dimensions!");
180 qWarning(
"[FiffSparseMatrix::fiff_get_float_sparse_matrix] Incomprehensible sparse matrix coding");
183 if (tag->size() != correct_size) {
184 qWarning(
"[FiffSparseMatrix::fiff_get_float_sparse_matrix] wrong data size!");
190 const float* src_data =
reinterpret_cast<const float*
>(tag->data());
191 const int* src_inds =
reinterpret_cast<const int*
>(src_data + nz);
192 const int* src_ptrs = src_inds + nz;
198 bool valid = m >= 0 && n >= 0 && nz >= 0 && src_ptrs[0] == 0 && src_ptrs[nOuter] == nz;
199 for (
int k = 0; valid && k < nOuter; ++k)
200 valid = src_ptrs[k] <= src_ptrs[k + 1];
201 for (
int j = 0; valid && j < nz; ++j)
202 valid = src_inds[j] >= 0 && src_inds[j] < nInner;
204 qWarning(
"[FiffSparseMatrix::fiff_get_float_sparse_matrix] index or pointer outside the matrix!");
208 using T = Eigen::Triplet<float>;
209 std::vector<T> triplets;
210 triplets.reserve(nz);
213 for (
int row = 0; row < m; ++row) {
214 for (
int j = src_ptrs[row]; j < src_ptrs[row + 1]; ++j) {
215 triplets.push_back(T(row, src_inds[j], src_data[j]));
219 for (
int col = 0; col < n; ++col) {
220 for (
int j = src_ptrs[col]; j < src_ptrs[col + 1]; ++j) {
221 triplets.push_back(T(src_inds[j], col, src_data[j]));
226 Eigen::SparseMatrix<float> eigenMat(m, n);
227 eigenMat.setFromTriplets(triplets.begin(), triplets.end());
228 eigenMat.makeCompressed();
230 auto res = std::make_unique<FiffSparseMatrix>(std::move(eigenMat), cod);
240 for (j = 0, totalNz = 0; j < nrow; j++)
241 totalNz = totalNz + nnz[j];
244 qWarning(
"[FiffSparseMatrix::create_sparse_rcs] No nonzero elements specified.");
248 using T = Eigen::Triplet<float>;
249 std::vector<T> triplets;
250 triplets.reserve(totalNz);
252 for (j = 0; j < nrow; j++) {
253 for (k = 0; k < nnz[j]; k++) {
254 int col = colindex[j][k];
255 if (col < 0 || col >= ncol) {
256 qWarning(
"[FiffSparseMatrix::create_sparse_rcs] Column index out of range");
259 float val = vals ? vals[j][k] : 0.0f;
260 triplets.push_back(T(j, col, val));
264 Eigen::SparseMatrix<float> eigenMat(nrow, ncol);
265 eigenMat.setFromTriplets(triplets.begin(), triplets.end());
266 eigenMat.makeCompressed();
268 return std::make_unique<FiffSparseMatrix>(std::move(eigenMat),
FIFFTS_MC_RCS);
281 if (nRows != nCols) {
282 qWarning(
"[FiffSparseMatrix::mne_add_upper_triangle_rcs] input must be square");
287 Eigen::SparseMatrix<float> full = m_eigen + Eigen::SparseMatrix<float>(m_eigen.transpose());
290 for (
int k = 0; k < full.outerSize(); ++k) {
291 for (Eigen::SparseMatrix<float>::InnerIterator it(full, k); it; ++it) {
292 if (it.row() == it.col()) {
294 it.valueRef() = 0.5f * it.value();
299 full.makeCompressed();
300 return std::make_unique<FiffSparseMatrix>(std::move(full),
FIFFTS_MC_RCS);
308 if (mat.nonZeros() == 0)
312 result.m_eigen = mat.cast<
float>();
313 result.m_eigen.makeCompressed();
322 if (mat.nonZeros() == 0)
326 result.m_eigen = mat;
327 result.m_eigen.makeCompressed();
338 if (nRows != nCols) {
339 qWarning(
"[FiffSparseMatrix::pickLowerTriangleRcs] input must be square");
343 using T = Eigen::Triplet<float>;
344 std::vector<T> triplets;
345 triplets.reserve(m_eigen.nonZeros());
347 for (
int k = 0; k < m_eigen.outerSize(); ++k) {
348 for (Eigen::SparseMatrix<float>::InnerIterator it(m_eigen, k); it; ++it) {
349 if (it.row() >= it.col()) {
350 triplets.push_back(T(it.row(), it.col(), it.value()));
355 Eigen::SparseMatrix<float> lower(nRows, nCols);
356 lower.setFromTriplets(triplets.begin(), triplets.end());
357 lower.makeCompressed();
359 return std::make_unique<FiffSparseMatrix>(std::move(lower),
FIFFTS_MC_RCS);
FIFF tag-kind, block-kind and type-code numerical definitions, authoritative for FIFFLIB.
constexpr auto FIFFTS_MC_DENSE
constexpr auto FIFFTS_MC_RCS
constexpr auto FIFFTS_FS_MATRIX
constexpr auto FIFFTS_MC_MASK
constexpr auto FIFFTS_MC_CCS
constexpr auto FIFFC_MATRIX_MAX_DIM
constexpr auto FIFFT_FLOAT
constexpr auto FIFFTS_FS_MASK
constexpr auto FIFFTS_BASE_MASK
fiff_int_t fiff_type_base(fiff_int_t type)
std::vector< int > fiff_get_matrix_dims(const FiffTag::UPtr &tag)
fiff_int_t fiff_type_matrix_coding(fiff_int_t type)
fiff_int_t fiff_type_fundamental(fiff_int_t type)
FIFF sparse matrix: column / row-compressed sparse storage backed by Eigen::SparseMatrix.
Primitive scalar typedefs and forward-compatible aliases backing the FIFF type system.
FIFF file I/O, in-memory data structures and high-level readers/writers.
unsigned char fiff_byte_t
static FiffSparseMatrix fromEigenSparse(const Eigen::SparseMatrix< double > &mat)
static std::vector< int > fiff_get_matrix_sparse_dims(const FIFFLIB::FiffTag::UPtr &tag)
FiffSparseMatrix::UPtr pickLowerTriangleRcs() const
static FiffSparseMatrix::UPtr create_sparse_rcs(int nrow, int ncol, int *nnz, int **colindex, float **vals)
static FiffSparseMatrix::UPtr fiff_get_float_sparse_matrix(const FIFFLIB::FiffTag::UPtr &tag)
std::unique_ptr< FiffSparseMatrix > UPtr
FiffSparseMatrix::UPtr mne_add_upper_triangle_rcs()
FIFFLIB::fiff_int_t coding
std::unique_ptr< FiffTag > UPtr