45 #define MALLOC_18(x,t) (t *)malloc((x)*sizeof(t))
47 #define REALLOC_18(x,y,t) (t *)((x == NULL) ? malloc((y)*sizeof(t)) : realloc((x),(y)*sizeof(t)))
49 #define FREE_18(x) if ((char *)(x) != NULL) free((char *)(x))
55 using namespace Eigen;
56 using namespace FIFFLIB;
57 using namespace FIFFLIB;
65 fiff_int_t fiff_type_base(fiff_int_t type)
67 return type & FIFFTS_BASE_MASK;
70 fiff_int_t fiff_type_fundamental(fiff_int_t type)
72 return type & FIFFTS_FS_MASK;
75 fiff_int_t fiff_type_matrix_coding(fiff_int_t type)
77 return type & FIFFTS_MC_MASK;
90 unsigned int tsize = tag->size();
94 if (tag->data() == NULL) {
95 qCritical(
"fiff_get_matrix_dims: no data available!");
98 if (fiff_type_fundamental(tag->type) != FIFFTS_FS_MATRIX) {
99 qCritical(
"fiff_get_matrix_dims: tag does not contain a matrix!");
102 if (tsize <
sizeof(fiff_int_t)) {
103 qCritical(
"fiff_get_matrix_dims: too small matrix data!");
109 ndim = *((fiff_int_t *)((fiff_byte_t *)(tag->data())+tag->size()-
sizeof(fiff_int_t)));
110 if (ndim <= 0 || ndim > FIFFC_MATRIX_MAX_DIM) {
111 qCritical(
"fiff_get_matrix_dims: unreasonable # of dimensions!");
114 if (fiff_type_matrix_coding(tag->type) == FIFFTS_MC_DENSE) {
115 if (tsize < (ndim+1)*
sizeof(fiff_int_t)) {
116 qCritical(
"fiff_get_matrix_dims: too small matrix data!");
119 res = MALLOC_18(ndim+1,
int);
121 dims = ((fiff_int_t *)((fiff_byte_t *)(tag->data())+tag->size())) - ndim - 1;
122 for (
k = 0;
k < ndim;
k++)
125 else if (fiff_type_matrix_coding(tag->type) == FIFFTS_MC_CCS ||
126 fiff_type_matrix_coding(tag->type) == FIFFTS_MC_RCS) {
127 if (tsize < (ndim+2)*
sizeof(fiff_int_t)) {
128 qCritical(
"fiff_get_matrix_sparse_dims: too small matrix data!");
131 res = MALLOC_18(ndim+2,
int);
133 dims = ((fiff_int_t *)((fiff_byte_t *)(tag->data())+tag->size())) - ndim - 1;
134 for (
k = 0;
k < ndim;
k++)
136 res[ndim+1] = dims[-1];
139 qCritical(
"fiff_get_matrix_dims: unknown matrix coding.");
149 FiffSparseMatrix::FiffSparseMatrix()
171 if (mat.
coding == FIFFTS_MC_CCS) {
172 size = mat.
nz*(
sizeof(FIFFLIB::fiff_float_t) +
sizeof(FIFFLIB::fiff_int_t)) +
173 (mat.
n+1)*(
sizeof(FIFFLIB::fiff_int_t));
175 if (mat.
coding == FIFFTS_MC_RCS) {
176 size = mat.
nz*(
sizeof(FIFFLIB::fiff_float_t) +
sizeof(FIFFLIB::fiff_int_t)) +
177 (mat.
m+1)*(
sizeof(FIFFLIB::fiff_int_t));
180 printf(
"Illegal sparse matrix storage type: %d",mat.
coding);
183 this->
data = (
float *)malloc(size);
199 fiff_int_t *FiffSparseMatrix::fiff_get_matrix_sparse_dims(
FiffTag::SPtr &tag)
201 return fiff_get_matrix_dims(tag);
213 if ( fiff_type_fundamental(tag->type) != FIFFT_MATRIX ||
214 fiff_type_base(tag->type) != FIFFT_FLOAT ||
215 (fiff_type_matrix_coding(tag->type) != FIFFTS_MC_CCS &&
216 fiff_type_matrix_coding(tag->type) != FIFFTS_MC_RCS) ) {
217 printf(
"fiff_get_float_ccs_matrix: wrong data type!");
221 if ((dims = fiff_get_matrix_sparse_dims(tag)) == NULL)
225 printf(
"fiff_get_float_sparse_matrix: wrong # of dimensions!");
233 coding = fiff_type_matrix_coding(tag->type);
234 if (
coding == FIFFTS_MC_CCS)
235 correct_size =
nz*(
sizeof(fiff_float_t) +
sizeof(fiff_int_t)) +
236 (
n+1+dims[0]+2)*(
sizeof(fiff_int_t));
237 else if (
coding == FIFFTS_MC_RCS)
238 correct_size =
nz*(
sizeof(fiff_float_t) +
sizeof(fiff_int_t)) +
239 (
m+1+dims[0]+2)*(
sizeof(fiff_int_t));
241 printf(
"fiff_get_float_sparse_matrix: Incomprehensible sparse matrix coding");
244 if (tag->size() != correct_size) {
245 printf(
"fiff_get_float_sparse_matrix: wrong data size!");
256 res->
data = MALLOC_18(correct_size,
float);
257 memcpy (res->
data,(
float*)tag->data(),correct_size);
269 FiffSparseMatrix *FiffSparseMatrix::create_sparse_rcs(
int nrow,
int ncol,
int *nnz,
int **colindex,
float **vals)
273 int j,
k,
nz,ptr,size,ind;
274 int stor_type = FIFFTS_MC_RCS;
276 for (j = 0,
nz = 0; j < nrow; j++)
280 printf(
"No nonzero elements specified.");
283 if (stor_type == FIFFTS_MC_RCS) {
284 size =
nz*(
sizeof(fiff_float_t) +
sizeof(fiff_int_t)) +
285 (nrow+1)*(
sizeof(fiff_int_t));
288 printf(
"Illegal sparse matrix storage type: %d",stor_type);
292 sparse->
coding = stor_type;
296 sparse->
data = (
float *)malloc(size);
300 for (j = 0,
nz = 0; j < nrow; j++) {
302 for (
k = 0;
k < nnz[j];
k++) {
305 ind = sparse->
inds[
nz] = colindex[j][
k];
306 if (ind < 0 || ind >= ncol) {
307 printf(
"Column index out of range in mne_create_sparse_rcs");
316 sparse->
ptrs[j] = ptr;
319 for (j = nrow-1; j >= 0; j--)
320 if (sparse->
ptrs[j] < 0)
321 sparse->
ptrs[j] = sparse->
ptrs[j+1];
339 int **colindex = NULL;
345 if (this->coding != FIFFTS_MC_RCS) {
346 printf(
"The input matrix to mne_add_upper_triangle_rcs must be in RCS format");
349 if (this->m != this->n) {
350 printf(
"The input matrix to mne_add_upper_triangle_rcs must be square");
353 nnz = MALLOC_18(this->m,
int);
354 colindex = MALLOC_18(this->m,
int *);
355 vals = MALLOC_18(this->m,
float *);
356 for (i = 0; i < this->
m; i++) {
357 nnz[i] = this->
ptrs[i+1] - this->
ptrs[i];
359 colindex[i] = MALLOC_18(nnz[i],
int);
360 vals[i] = MALLOC_18(nnz[i],
float);
361 for (j = this->ptrs[i],
k = 0; j < this->ptrs[i+1]; j++,
k++) {
362 vals[i][
k] = this->
data[j];
363 colindex[i][
k] = this->
inds[j];
374 nadd = MALLOC_18(this->m,
int);
375 for (i = 0; i < this->
m; i++)
377 for (i = 0; i < this->
m; i++)
378 for (j = this->ptrs[i]; j < this->ptrs[i+1]; j++)
379 nadd[this->
inds[j]]++;
380 for (i = 0; i < this->
m; i++) {
381 colindex[i] = REALLOC_18(colindex[i],nnz[i]+nadd[i],
int);
382 vals[i] = REALLOC_18(vals[i],nnz[i]+nadd[i],
float);
384 for (i = 0; i < this->
m; i++)
385 for (j = this->ptrs[i]; j < this->ptrs[i+1]; j++) {
387 colindex[row][nnz[row]] = i;
388 vals[row][nnz[row]] = this->
data[j];
391 res = create_sparse_rcs(this->m,this->n,nnz,colindex,vals);
394 for (i = 0; i < this->
m; i++) {
395 FREE_18(colindex[i]);