29 double inline real(
double x)
34 double inline imag(
double x)
39 double inline real(std::complex<double> x)
44 double inline imag(std::complex<double> x)
49 template<
typename Scalar>
52 register int lo = 0, hi = Alen - 1, mid;
60 else if (idx > Ai[mid])
75 template<
typename Scalar>
80 template<
typename Scalar>
87 template<
typename Scalar>
93 template<
typename Scalar>
96 for (
unsigned int i = 0; i < this->nnz; i++)
100 template<
typename Scalar>
104 Ap = malloc_with_check<CSMatrix<Scalar>,
int>(this->size + 1,
this);
105 int aisize = this->get_num_indices();
106 Ai = malloc_with_check<CSMatrix<Scalar>,
int>(aisize,
this);
111 for (i = 0; i < this->size; i++)
114 pos += this->sort_and_store_indices(&this->pages[i], Ai + pos, Ai + aisize);
116 Ap[this->size] = pos;
118 free_with_check(this->pages);
119 free_with_check(this->next_pages);
121 nnz = Ap[this->size];
126 template<
typename Scalar>
129 Ax = calloc_with_check<CSMatrix<Scalar>, Scalar>(nnz,
this);
132 template<
typename Scalar>
141 template<
typename Scalar>
144 for (
int i = 0; i < Ap[n + 1] - Ap[n]; i++)
145 Ax[Ap[n] + i] = Scalar(0);
148 template<
typename Scalar>
151 memset(Ax, 0,
sizeof(Scalar)* nnz);
154 template<
typename Scalar>
160 template<
typename Scalar>
163 return nnz / (double)(this->size * this->size);
166 template<
typename Scalar>
171 this->Ap = malloc_with_check<CSMatrix<Scalar>,
int>(this->size + 1,
this);
172 this->Ai = malloc_with_check<CSMatrix<Scalar>,
int>(nnz,
this);
173 this->Ax = malloc_with_check<CSMatrix<Scalar>, Scalar>(nnz,
this);
174 memcpy(this->Ap, ap, (this->size + 1) *
sizeof(
int));
175 memcpy(this->Ai, ai, this->nnz *
sizeof(
int));
176 memcpy(this->Ax, ax, this->nnz *
sizeof(Scalar));
179 template<
typename Scalar>
184 int* tempAp = malloc_with_check<CSMatrix<Scalar>,
int>(this->size + 1,
this);
185 int* tempAi = malloc_with_check<CSMatrix<Scalar>,
int>(nnz,
this);
186 Scalar* tempAx = malloc_with_check<CSMatrix<Scalar>, Scalar>(nnz,
this);
189 for (
int target_row = 0; target_row < this->size; target_row++)
191 tempAp[target_row] = run_i;
192 for (
int src_column = 0; src_column < this->size; src_column++)
194 for (
int src_row = this->Ap[src_column]; src_row < this->Ap[src_column + 1]; src_row++)
196 if (this->Ai[src_row] == target_row)
198 tempAi[run_i] = src_column;
199 tempAx[run_i++] = this->Ax[src_row];
205 tempAp[this->size] = this->nnz;
206 memcpy(this->Ai, tempAi,
sizeof(
int)* nnz);
207 memcpy(this->Ap, tempAp,
sizeof(
int)* (this->size + 1));
208 memcpy(this->Ax, tempAx,
sizeof(Scalar)* nnz);
209 free_with_check(tempAi);
210 free_with_check(tempAx);
211 free_with_check(tempAp);
214 template<
typename Scalar>
220 template<
typename Scalar>
226 template<
typename Scalar>
232 template<
typename Scalar>
235 if ((this->get_size() < offset_i + mat->
get_size()) || (this->get_size() < offset_j + mat->
get_size()))
245 for (
unsigned short i = 0; i < csMatrix->
get_size(); i++)
247 int index = csMatrix->
Ap[i];
248 for (
int j = 0; j < csMatrix->
Ap[i + 1] - index; j++)
250 this->add(offset_i + csMatrix->
Ai[index + j], offset_j + i, csMatrix->
Ax[index + j]);
262 int pos = find_position(Ai + Ap[n], Ap[n + 1] - Ap[n], m);
266 this->info(
"CSMatrix<Scalar>::add(): i = %d, j = %d.", m, n);
271 Ax[Ap[n] + pos] += v;
276 void CSMatrix<std::complex<double> >::add(
unsigned int m,
unsigned int n, std::complex<double> v)
281 int pos = find_position(Ai + Ap[n], Ap[n + 1] - Ap[n], m);
285 this->info(
"CSMatrix<Scalar>::add(): i = %d, j = %d.", m, n);
289 #pragma omp critical (CSMatrixAdd)
290 Ax[Ap[n] + pos] += v;
294 template<
typename Scalar>
298 int mid = find_position(Ai + Ap[n], Ap[n + 1] - Ap[n], m);
303 return Ax[Ap[n] + mid];
306 template<
typename Scalar>
311 template<
typename Scalar>
316 template<
typename Scalar>
328 void CSCMatrix<std::complex<double> >::add(
unsigned int m,
unsigned int n, std::complex<double> v)
330 CSMatrix<std::complex<double> >::add(m, n, v);
333 template<
typename Scalar>
339 template<
typename Scalar>
342 if (!vector_out_initialized)
343 vector_out = malloc_with_check<Scalar>(this->size);
344 memset(vector_out, 0,
sizeof(Scalar)* this->size);
346 for (
int i = 0; i < this->size; i++)
348 for (
int j = 0; j < this->Ap[i + 1] - this->Ap[i]; j++)
349 vector_out[this->Ai[this->Ap[i] + j]] += this->Ax[this->Ap[i] + j] * vector_in[i];
354 static int i_coordinate(
int i,
int j,
bool invert)
362 static int j_coordinate(
int i,
int j,
bool invert)
370 template<
typename Scalar>
377 FILE* file = fopen(filename,
"w");
381 fprintf(file,
"%%%%MatrixMarket matrix coordinate real general\n");
383 fprintf(file,
"%%%%MatrixMarket matrix coordinate complex general\n");
385 fprintf(file,
"%d %d %d\n", this->size, this->size, this->nnz);
388 this->switch_orientation();
389 for (
unsigned int j = 0; j < this->size; j++)
391 for (
int i = Ap[j]; i < Ap[j + 1]; i++)
393 Hermes::Helpers::fprint_coordinate_num(file, i_coordinate(Ai[i] + 1, j + 1, invert_storage), j_coordinate(Ai[i] + 1, j + 1, invert_storage), Ax[i], number_format);
398 this->switch_orientation();
408 sparse.nzmax = this->nnz;
410 this->switch_orientation();
412 sparse.nir = this->nnz;
413 sparse.ir = this->Ai;
414 sparse.njc = this->size + 1;
415 sparse.jc = (
int *)this->Ap;
416 sparse.ndata = this->nnz;
419 dims[0] = this->size;
420 dims[1] = this->size;
422 mat_t *mat = Mat_CreateVer(filename,
"", MAT_FT_MAT5);
427 double* Ax_re =
nullptr;
428 double* Ax_im =
nullptr;
434 matvar = Mat_VarCreate(var_name, MAT_C_SPARSE, MAT_T_DOUBLE, 2, dims, &sparse, MAT_F_DONT_COPY_DATA);
439 Ax_re = malloc_with_check<CSMatrix<Scalar>,
double>(this->nnz,
this);
440 Ax_im = malloc_with_check<CSMatrix<Scalar>,
double>(this->nnz,
this);
441 struct mat_complex_split_t z = { Ax_re, Ax_im };
443 for (
int i = 0; i < this->nnz; i++)
445 Ax_re[i] = ((std::complex<double>)(this->Ax[i])).real();
446 Ax_im[i] = ((std::complex<double>)(this->Ax[i])).imag();
449 matvar = Mat_VarCreate(var_name, MAT_C_SPARSE, MAT_T_DOUBLE, 2, dims, &sparse, MAT_F_DONT_COPY_DATA | MAT_F_COMPLEX);
454 Mat_VarWrite(mat, matvar, MAT_COMPRESSION_ZLIB);
458 this->switch_orientation();
459 free_with_check(Ax_re);
460 free_with_check(Ax_im);
471 FILE* file = fopen(filename,
"w");
476 this->switch_orientation();
477 for (
unsigned int j = 0; j < this->size; j++)
479 for (
int i = Ap[j]; i < Ap[j + 1]; i++)
481 Helpers::fprint_coordinate_num(file, i_coordinate(Ai[i], j, invert_storage), j_coordinate(Ai[i], j, invert_storage), Ax[i], number_format);
486 this->switch_orientation();
492 case EXPORT_FORMAT_MATLAB_SIMPLE:
494 FILE* file = fopen(filename,
"w");
496 this->switch_orientation();
497 fprintf(file,
"%% Size: %dx%d\n%% Nonzeros: %d\ntemp = zeros(%d, 3);\ntemp =[\n",
498 this->size, this->size, nnz, nnz);
499 for (
unsigned int j = 0; j < this->size; j++)
500 for (
int i = Ap[j]; i < Ap[j + 1]; i++)
502 fprintf(file,
"%d %d ", Ai[i] + 1, j + 1);
503 Hermes::Helpers::fprint_num(file, Ax[i], number_format);
506 fprintf(file,
"];\n");
508 this->switch_orientation();
513 case EXPORT_FORMAT_BSON:
520 bson_append_int(&bw,
"size", this->size);
522 bson_append_int(&bw,
"nnz", this->nnz);
525 this->switch_orientation();
527 bson_append_start_array(&bw,
"Ap");
528 for (
unsigned int i = 0; i < this->size; i++)
529 bson_append_int(&bw,
"p", this->Ap[i]);
530 bson_append_finish_array(&bw);
532 bson_append_start_array(&bw,
"Ai");
533 for (
unsigned int i = 0; i < this->nnz; i++)
534 bson_append_int(&bw,
"i", this->Ai[i]);
535 bson_append_finish_array(&bw);
537 bson_append_start_array(&bw,
"Ax");
538 for (
unsigned int i = 0; i < this->nnz; i++)
539 bson_append_double(&bw,
"x", real(this->Ax[i]));
540 bson_append_finish_array(&bw);
544 bson_append_start_array(&bw,
"Ax-imag");
545 for (
unsigned int i = 0; i < this->nnz; i++)
546 bson_append_double(&bw,
"x-i", imag(this->Ax[i]));
547 bson_append_finish_array(&bw);
549 bson_append_finish_array(&bw);
552 this->switch_orientation();
559 fpw = fopen(filename,
"wb");
560 const char *dataw = (
const char *)bson_data(&bw);
561 fwrite(dataw, bson_size(&bw), 1, fpw);
571 template<
typename Scalar>
577 template<
typename Scalar>
583 template<
typename Scalar>
599 matfp = Mat_Open(filename, MAT_ACC_RDONLY);
604 matvar = Mat_VarRead(matfp, var_name);
608 mat_sparse_t *sparse = (mat_sparse_t *)matvar->data;
610 this->nnz = sparse->nir;
612 this->Ai = malloc_with_check<CSMatrix<Scalar>,
int>(this->nnz,
this);
613 this->size = sparse->njc;
614 this->Ap = malloc_with_check<CSMatrix<Scalar>,
int>(this->size + 1,
this);
616 void* data =
nullptr;
621 std::complex<double>* complex_data = malloc_with_check<CSMatrix<Scalar>, std::complex<double> >(this->nnz,
this);
622 double* real_array = (
double*)((mat_complex_split_t*)sparse->data)->Re;
623 double* imag_array = (
double*)((mat_complex_split_t*)sparse->data)->Im;
624 for (
int i = 0; i < this->nnz; i++)
625 complex_data[i] = std::complex<double>(real_array[i], imag_array[i]);
626 data = (
void*)complex_data;
628 memcpy(this->Ax, data, this->nnz *
sizeof(Scalar));
630 free_with_check(data);
631 memcpy(this->Ap, sparse->jc, this->size *
sizeof(
int));
632 this->Ap[this->size] = this->nnz;
633 memcpy(this->Ai, sparse->ir, this->nnz *
sizeof(
int));
636 this->switch_orientation();
653 case EXPORT_FORMAT_BSON:
656 fpr = fopen(filename,
"rb");
659 fseek(fpr, 0, SEEK_END);
660 int size = ftell(fpr);
664 char *datar = malloc_with_check<char>(size);
665 fread(datar, size, 1, fpr);
669 bson_init_finished_data(&br, datar, 0);
673 bson_find(&it, &br,
"size");
674 this->size = bson_iterator_int(&it);
675 bson_find(&it, &br,
"nnz");
676 this->nnz = bson_iterator_int(&it);
678 this->Ap = malloc_with_check<CSMatrix<Scalar>,
int>(this->size + 1,
this);
679 this->Ai = malloc_with_check<CSMatrix<Scalar>,
int>(nnz,
this);
680 this->Ax = malloc_with_check<CSMatrix<Scalar>, Scalar>(nnz,
this);
683 bson_iterator it_coeffs;
684 bson_find(&it_coeffs, &br,
"Ap");
685 bson_iterator_subobject_init(&it_coeffs, &sub, 0);
686 bson_iterator_init(&it, &sub);
688 while (bson_iterator_next(&it))
689 this->Ap[index_coeff++] = bson_iterator_int(&it);
690 this->Ap[this->size] = this->nnz;
692 bson_find(&it_coeffs, &br,
"Ai");
693 bson_iterator_subobject_init(&it_coeffs, &sub, 0);
694 bson_iterator_init(&it, &sub);
696 while (bson_iterator_next(&it))
697 this->Ai[index_coeff++] = bson_iterator_int(&it);
699 bson_find(&it_coeffs, &br,
"Ax");
700 bson_iterator_subobject_init(&it_coeffs, &sub, 0);
701 bson_iterator_init(&it, &sub);
703 while (bson_iterator_next(&it))
704 this->Ax[index_coeff++] = bson_iterator_double(&it);
708 bson_find(&it_coeffs, &br,
"Ax-imag");
709 bson_iterator_subobject_init(&it_coeffs, &sub, 0);
710 bson_iterator_init(&it, &sub);
712 while (bson_iterator_next(&it))
713 ((std::complex<double>)this->Ax[index_coeff++]).imag(bson_iterator_double(&it));
717 this->switch_orientation();
720 free_with_check(datar);
727 template<
typename Scalar>
733 template<
typename Scalar>
739 template<
typename Scalar>
743 new_matrix->
create(this->get_size(), this->get_nnz(), this->get_Ap(), this->get_Ai(), this->get_Ax());
747 template<
typename Scalar>
752 template<
typename Scalar>
757 template<
typename Scalar>
769 void CSRMatrix<std::complex<double> >::add(
unsigned int m,
unsigned int n, std::complex<double> v)
771 CSMatrix<std::complex<double> >::add(n, m, v);
774 template<
typename Scalar>
780 template<
typename Scalar>
787 final_page = final_page->
next;
792 final_page = final_page->
next;
794 final_page->
idx[final_page->
count++] = col;
797 this->pages[row].idx[this->pages[row].count++] = col;
800 template<
typename Scalar>
804 new_matrix->
create(this->get_size(), this->get_nnz(), this->get_Ap(), this->get_Ai(), this->get_Ax());
virtual unsigned int get_size() const
void switch_orientation()
Switches CSR / CSC arrays.
General namespace for the Hermes library.
void import_from_file(const char *filename, const char *var_name, MatrixExportFormat fmt, bool invert_storage=false)
Exception interface Basically a std::exception, but with a constructor with string and with print_msg...
General CSR Matrix class. (can be used in umfpack, in that case use the CSCMatrix subclass...
virtual void add(unsigned int m, unsigned int n, Scalar v)
int * Ap
Index to Ax/Ai, where each column / row starts.
T ** new_matrix(unsigned int m, unsigned int n=0)
File containing common definitions, and basic global enums etc. for HermesCommon. ...
static int find_position(int *Ai, int Alen, unsigned int idx)
Finds the correct position to insert / retrieve elements.
void multiply_with_vector(Scalar *vector_in, Scalar *&vector_out, bool vector_out_initialized) const
Multiply with a vector.
General (abstract) sparse matrix representation in Hermes.
SparseMatrix< Scalar > * duplicate() const
Duplicates a matrix (including allocation).
MatrixExportFormat
Format of file matrix and vector output.
virtual void add_as_block(unsigned int i, unsigned int j, SparseMatrix< Scalar > *mat)
Basic cs (Compressed sparse) matrix classes and operations.
Plain ascii file lines contains row column and value.
virtual void zero()
Utility method.
virtual void add(unsigned int m, unsigned int n, Scalar v)
virtual void export_to_file(const char *filename, const char *var_name, MatrixExportFormat fmt, char *number_format="%lf")
General CSC Matrix class. (can be used in umfpack, in that case use the CSCMatrix subclass...
IO exception. Internal. Exception occurs when something fails to be written to / read from the disk...
void create(unsigned int size, unsigned int nnz, int *ap, int *ai, Scalar *ax)
int idx[PAGE_SIZE]
buffer for storing indices
virtual void set_row_zero(unsigned int n)
Utility method.
virtual Scalar get(unsigned int Ai_data_index, unsigned int Ai_index) const
void export_to_file(const char *filename, const char *var_name, MatrixExportFormat fmt, char *number_format="%lf")
virtual Scalar get(unsigned int m, unsigned int n) const
void import_from_file(const char *filename, const char *var_name, MatrixExportFormat fmt)
int * Ai
Row / Column indices of values in Ax.
SparseMatrix< Scalar > * duplicate() const
Duplicates a matrix (including allocation).
unsigned char count
number of indices stored
void multiply_with_Scalar(Scalar value)
Multiplies matrix with a Scalar.
Structure for storing indices in sparse matrix.
virtual double get_fill_in() const
Utility method.
virtual Scalar get(unsigned int m, unsigned int n) const
Method is not overriden and should be.
virtual void import_from_file(const char *filename, const char *var_name, MatrixExportFormat fmt)
General CS Matrix class. Either row- or column- specific (see subclassses).
CSCMatrix()
Default constructor.
void export_to_file(const char *filename, const char *var_name, MatrixExportFormat fmt, char *number_format="%lf", bool invert_storage=false)
virtual void add_as_block(unsigned int i, unsigned int j, SparseMatrix< Scalar > *mat)
virtual void pre_add_ij(unsigned int row, unsigned int col)
Page * next
pointer to next page
Matrix Market which can be read by pysparse library.
CSMatrix()
Default constructor.
virtual void free()
Utility method.
virtual unsigned int get_nnz() const
Utility method.
virtual void alloc()
Allocate utility storage (row, column indices, etc.).
CSRMatrix()
Default constructor.
virtual void add(unsigned int Ai_data_index, unsigned int Ai_index, Scalar v)