| 1 | /* $Id$Revision: */ | 
|---|
| 2 | /* vim:set shiftwidth=4 ts=8: */ | 
|---|
| 3 |  | 
|---|
| 4 | /************************************************************************* | 
|---|
| 5 | * Copyright (c) 2011 AT&T Intellectual Property | 
|---|
| 6 | * All rights reserved. This program and the accompanying materials | 
|---|
| 7 | * are made available under the terms of the Eclipse Public License v1.0 | 
|---|
| 8 | * which accompanies this distribution, and is available at | 
|---|
| 9 | * http://www.eclipse.org/legal/epl-v10.html | 
|---|
| 10 | * | 
|---|
| 11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ | 
|---|
| 12 | *************************************************************************/ | 
|---|
| 13 | #ifndef SPARSEMATRIX_H | 
|---|
| 14 | #define  SPARSEMATRIX_H | 
|---|
| 15 |  | 
|---|
| 16 | #include <general.h> | 
|---|
| 17 | #include <stdio.h> | 
|---|
| 18 |  | 
|---|
| 19 | #define SYMMETRY_EPSILON 0.0000001 | 
|---|
| 20 | enum {FORMAT_CSC, FORMAT_CSR, FORMAT_COORD}; | 
|---|
| 21 | enum {UNMASKED = -10, MASKED = 1}; | 
|---|
| 22 | enum {MATRIX_PATTERN_SYMMETRIC = 1<<0, MATRIX_SYMMETRIC = 1<<1, MATRIX_SKEW = 1<<2, MATRIX_HERMITIAN = 1<<3, MATRIX_UNDIRECTED = 1<<4}; | 
|---|
| 23 | enum {BIPARTITE_RECT = 0, BIPARTITE_PATTERN_UNSYM, BIPARTITE_UNSYM, BIPARTITE_ALWAYS}; | 
|---|
| 24 |  | 
|---|
| 25 |  | 
|---|
| 26 | struct SparseMatrix_struct { | 
|---|
| 27 | int m; /* row dimension */ | 
|---|
| 28 | int n; /* column dimension */ | 
|---|
| 29 | int nz;/* The actual length used is nz, for CSR/CSC matrix this is the same as ia[n] */ | 
|---|
| 30 | int nzmax; /* the current length of ja and a (if exists) allocated.*/ | 
|---|
| 31 | int type; /* whether it is real/complex matrix, or pattern only */ | 
|---|
| 32 | int *ia; /* row pointer for CSR format, or row indices for coordinate format. 0-based */ | 
|---|
| 33 | int *ja; /* column indices. 0-based */ | 
|---|
| 34 | void *a; /* entry values. If NULL, pattern matrix */ | 
|---|
| 35 | int format;/* whether it is CSR, CSC, COORD. By default it is in CSR format */ | 
|---|
| 36 | int property; /* pattern_symmetric/symmetric/skew/hermitian*/ | 
|---|
| 37 | int size;/* size of each entry. This allows for general matrix where each entry is, say, a matrix itself */ | 
|---|
| 38 | }; | 
|---|
| 39 |  | 
|---|
| 40 | typedef struct SparseMatrix_struct* SparseMatrix; | 
|---|
| 41 |  | 
|---|
| 42 | enum {MATRIX_TYPE_REAL = 1<<0, MATRIX_TYPE_COMPLEX = 1<<1, MATRIX_TYPE_INTEGER = 1<<2, MATRIX_TYPE_PATTERN = 1<<3, MATRIX_TYPE_UNKNOWN = 1<<4}; | 
|---|
| 43 |  | 
|---|
| 44 | /* SparseMatrix_general is more general and allow elements to be | 
|---|
| 45 | any data structure, not just real/int/complex etc */ | 
|---|
| 46 | SparseMatrix SparseMatrix_new(int m, int n, int nz, int type, int format); | 
|---|
| 47 | SparseMatrix SparseMatrix_general_new(int m, int n, int nz, int type, size_t sz, int format); | 
|---|
| 48 |  | 
|---|
| 49 | /* this version sum repeated entries */ | 
|---|
| 50 | SparseMatrix SparseMatrix_from_coordinate_format(SparseMatrix A); | 
|---|
| 51 | /* what_to_sum is SUM_REPEATED_NONE, SUM_REPEATED_ALL, SUM_REPEATED_REAL_PART, SUM_REPEATED_IMAGINARY_PART, SUM_IMGINARY_KEEP_LAST_REAL*/ | 
|---|
| 52 | SparseMatrix SparseMatrix_from_coordinate_format_not_compacted(SparseMatrix A, int what_to_sum); | 
|---|
| 53 |  | 
|---|
| 54 | SparseMatrix SparseMatrix_from_coordinate_arrays(int nz, int m, int n, int *irn, int *jcn, void *val, int type, size_t sz); | 
|---|
| 55 | SparseMatrix SparseMatrix_from_coordinate_arrays_not_compacted(int nz, int m, int n, int *irn, int *jcn, void *val, int type, size_t sz, int what_to_sum); | 
|---|
| 56 |  | 
|---|
| 57 |  | 
|---|
| 58 | void SparseMatrix_print(char *, SparseMatrix A);/*print to stdout in Mathematica format*/ | 
|---|
| 59 |  | 
|---|
| 60 | void SparseMatrix_export(FILE *f, SparseMatrix A);/* export into MM format except the header */ | 
|---|
| 61 |  | 
|---|
| 62 | SparseMatrix SparseMatrix_import_binary(char *name); | 
|---|
| 63 | SparseMatrix SparseMatrix_import_binary_fp(FILE *f);/* import into a preopenned file */ | 
|---|
| 64 |  | 
|---|
| 65 | void SparseMatrix_export_binary(char *name, SparseMatrix A, int *flag); | 
|---|
| 66 | void SparseMatrix_export_binary_fp(FILE *f, SparseMatrix A);/* export binary into a file preopened */ | 
|---|
| 67 |  | 
|---|
| 68 | void SparseMatrix_delete(SparseMatrix A); | 
|---|
| 69 |  | 
|---|
| 70 | SparseMatrix SparseMatrix_add(SparseMatrix A, SparseMatrix B); | 
|---|
| 71 | SparseMatrix SparseMatrix_multiply(SparseMatrix A, SparseMatrix B); | 
|---|
| 72 | SparseMatrix SparseMatrix_multiply3(SparseMatrix A, SparseMatrix B, SparseMatrix C); | 
|---|
| 73 |  | 
|---|
| 74 | /* For complex matrix: | 
|---|
| 75 | if what_to_sum = SUM_REPEATED_REAL_PART, we find entries {i,j,x + i y} and sum the x's if {i,j,Round(y)} are the same | 
|---|
| 76 | if what_to_sum = SUM_REPEATED_IMAGINARY_PART, we find entries {i,j,x + i y} and sum the y's if {i,j,Round(x)} are the same | 
|---|
| 77 | For other matrix, what_to_sum = SUM_REPEATED_REAL_PART is the same as what_to_sum = SUM_REPEATED_IMAGINARY_PART | 
|---|
| 78 | or what_to_sum = SUM_REPEATED_ALL | 
|---|
| 79 | if what_to_sum = SUM_IMGINARY_KEEP_LAST_REAL, we merge {i,j,R1,I1} and {i,j,R2,I2} into {i,j,R1+R2,I2}. Useful if I1 and I2 are time stamps, | 
|---|
| 80 | .   and we use this to indicate that a user watched R1+R2 seconds, last watch is I2. | 
|---|
| 81 | */ | 
|---|
| 82 | enum {SUM_REPEATED_NONE = 0, SUM_REPEATED_ALL, SUM_REPEATED_REAL_PART, SUM_REPEATED_IMAGINARY_PART, SUM_IMGINARY_KEEP_LAST_REAL}; | 
|---|
| 83 | SparseMatrix SparseMatrix_sum_repeat_entries(SparseMatrix A, int what_to_sum); | 
|---|
| 84 | SparseMatrix SparseMatrix_coordinate_form_add_entries(SparseMatrix A, int nentries, int *irn, int *jcn, void *val); | 
|---|
| 85 | int SparseMatrix_is_symmetric(SparseMatrix A, int test_pattern_symmetry_only); | 
|---|
| 86 | SparseMatrix SparseMatrix_transpose(SparseMatrix A); | 
|---|
| 87 | SparseMatrix SparseMatrix_symmetrize(SparseMatrix A, int pattern_symmetric_only); | 
|---|
| 88 | SparseMatrix SparseMatrix_symmetrize_nodiag(SparseMatrix A, int pattern_symmetric_only); | 
|---|
| 89 | void SparseMatrix_multiply_vector(SparseMatrix A, real *v, real **res, int transposed);/* if v = NULL, v is assumed to be {1,1,...,1}*/ | 
|---|
| 90 | SparseMatrix SparseMatrix_remove_diagonal(SparseMatrix A); | 
|---|
| 91 | SparseMatrix SparseMatrix_remove_upper(SparseMatrix A);/* remove diag and upper diag */ | 
|---|
| 92 | SparseMatrix SparseMatrix_divide_row_by_degree(SparseMatrix A); | 
|---|
| 93 | SparseMatrix SparseMatrix_get_real_adjacency_matrix_symmetrized(SparseMatrix A);  /* symmetric, all entries to 1, diaginal removed */ | 
|---|
| 94 | SparseMatrix SparseMatrix_normalize_to_rowsum1(SparseMatrix A);/* for real only! */ | 
|---|
| 95 | void SparseMatrix_multiply_dense(SparseMatrix A, int ATranspose, real *v, int vTransposed, real **res, int res_transpose, int dim); | 
|---|
| 96 | SparseMatrix SparseMatrix_apply_fun(SparseMatrix A, double (*fun)(double x));/* for real only! */ | 
|---|
| 97 | SparseMatrix SparseMatrix_apply_fun_general(SparseMatrix A, void (*fun)(int i, int j, int n, double *x));/* for real and complex (n=2) */ | 
|---|
| 98 | SparseMatrix SparseMatrix_copy(SparseMatrix A); | 
|---|
| 99 | int SparseMatrix_has_diagonal(SparseMatrix A); | 
|---|
| 100 | SparseMatrix SparseMatrix_normalize_by_row(SparseMatrix A);/* divide by max of each row */ | 
|---|
| 101 | SparseMatrix SparseMatrix_crop(SparseMatrix A, real epsilon);/*remove any entry <= epsilon*/ | 
|---|
| 102 | SparseMatrix SparseMatrix_scaled_by_vector(SparseMatrix A, real *v, int apply_to_row); | 
|---|
| 103 | SparseMatrix SparseMatrix_multiply_by_scaler(SparseMatrix A, real s); | 
|---|
| 104 | SparseMatrix SparseMatrix_make_undirected(SparseMatrix A);/* make it strictly low diag only, and set flag to undirected */ | 
|---|
| 105 | int SparseMatrix_connectedQ(SparseMatrix A); | 
|---|
| 106 | real SparseMatrix_pseudo_diameter_only(SparseMatrix A); | 
|---|
| 107 | real SparseMatrix_pseudo_diameter_weighted(SparseMatrix A0, int root, int aggressive, int *end1, int *end2, int *connectedQ); /* assume real distances, unsymmetric matrix ill be symmetrized */ | 
|---|
| 108 | real SparseMatrix_pseudo_diameter_unweighted(SparseMatrix A0, int root, int aggressive, int *end1, int *end2, int *connectedQ); /* assume unit edge length, unsymmetric matrix ill be symmetrized */ | 
|---|
| 109 | void SparseMatrix_level_sets(SparseMatrix A, int root, int *nlevel, int **levelset_ptr, int **levelset, int **mask, int reintialize_mask); | 
|---|
| 110 | void SparseMatrix_level_sets_khops(int khops, SparseMatrix A, int root, int *nlevel, int **levelset_ptr, int **levelset, int **mask, int reintialize_mask); | 
|---|
| 111 | void SparseMatrix_weakly_connected_components(SparseMatrix A0, int *ncomp, int **comps, int **comps_ptr); | 
|---|
| 112 | void SparseMatrix_decompose_to_supervariables(SparseMatrix A, int *ncluster, int **cluster, int **clusterp); | 
|---|
| 113 | SparseMatrix SparseMatrix_get_submatrix(SparseMatrix A, int nrow, int ncol, int *rindices, int *cindices); | 
|---|
| 114 | SparseMatrix SparseMatrix_exclude_submatrix(SparseMatrix A, int nrow, int ncol, int *rindices, int *cindices); | 
|---|
| 115 |  | 
|---|
| 116 | SparseMatrix SparseMatrix_get_augmented(SparseMatrix A); | 
|---|
| 117 |  | 
|---|
| 118 | /* bipartite_options: | 
|---|
| 119 | BIPARTITE_RECT -- turn rectangular matrix into square), | 
|---|
| 120 | BIPARTITE_PATTERN_UNSYM -- pattern unsummetric as bipartite | 
|---|
| 121 | BIPARTITE_UNSYM -- unsymmetric as square | 
|---|
| 122 | BIPARTITE_ALWAYS -- always as square | 
|---|
| 123 | */ | 
|---|
| 124 | SparseMatrix SparseMatrix_to_square_matrix(SparseMatrix A, int bipartite_options); | 
|---|
| 125 |  | 
|---|
| 126 | SparseMatrix SparseMatrix_largest_component(SparseMatrix A); | 
|---|
| 127 |  | 
|---|
| 128 | /* columns with <= threhold entries are deleted */ | 
|---|
| 129 | SparseMatrix SparseMatrix_delete_empty_columns(SparseMatrix A, int **new2old, int *nnew, int inplace); | 
|---|
| 130 | SparseMatrix SparseMatrix_delete_sparse_columns(SparseMatrix A, int threshold, int **new2old, int *nnew, int inplace); | 
|---|
| 131 |  | 
|---|
| 132 | SparseMatrix SparseMatrix_sort(SparseMatrix A); | 
|---|
| 133 |  | 
|---|
| 134 | SparseMatrix SparseMatrix_set_entries_to_real_one(SparseMatrix A); | 
|---|
| 135 |  | 
|---|
| 136 | SparseMatrix SparseMatrix_complement(SparseMatrix A, int undirected); | 
|---|
| 137 |  | 
|---|
| 138 | int SparseMatrix_k_centers(SparseMatrix D, int weighted, int K, int root, | 
|---|
| 139 | int **centers, int centering, real **dist); | 
|---|
| 140 |  | 
|---|
| 141 | int SparseMatrix_k_centers_user(SparseMatrix D, int weighted, int K, | 
|---|
| 142 | int *centers_user, int centering, real **dist); | 
|---|
| 143 |  | 
|---|
| 144 | SparseMatrix SparseMatrix_distance_matrix_k_centers(int K, SparseMatrix D, int weighted); | 
|---|
| 145 |  | 
|---|
| 146 | int SparseMatrix_distance_matrix(SparseMatrix A, int weighted,  real **dist_matrix); | 
|---|
| 147 | SparseMatrix SparseMatrix_distance_matrix_khops(int khops, SparseMatrix A, int weighted); | 
|---|
| 148 | SparseMatrix SparseMatrix_distance_matrix_k_centers(int K, SparseMatrix D, int weighted); | 
|---|
| 149 |  | 
|---|
| 150 | void SparseMatrix_kcoreness(SparseMatrix A, int **coreness);/* assign coreness to each node */ | 
|---|
| 151 | void SparseMatrix_kcore_decomposition(SparseMatrix A, int *coreness_max0, int **coreness_ptr0, int **coreness_list0);/* return the decomposition */ | 
|---|
| 152 |  | 
|---|
| 153 | void SparseMatrix_khairness(SparseMatrix A, int **hairness);/* assign hairness to each node */ | 
|---|
| 154 | void SparseMatrix_khair_decomposition(SparseMatrix A, int *hairness_max0, int **hairness_ptr0, int **hairness_list0);/* return the decomposition */ | 
|---|
| 155 |  | 
|---|
| 156 | SparseMatrix SparseMatrix_from_dense(int m, int n, real *x); | 
|---|
| 157 |  | 
|---|
| 158 | void SparseMatrix_page_rank(SparseMatrix A, real teleport_probablity, int weighted, real epsilon, real **page_rank); | 
|---|
| 159 |  | 
|---|
| 160 |  | 
|---|
| 161 | #define SparseMatrix_set_undirected(A) set_flag((A)->property, MATRIX_UNDIRECTED) | 
|---|
| 162 | #define SparseMatrix_set_symmetric(A) set_flag((A)->property, MATRIX_SYMMETRIC) | 
|---|
| 163 | #define SparseMatrix_set_pattern_symmetric(A) set_flag((A)->property, MATRIX_PATTERN_SYMMETRIC) | 
|---|
| 164 | #define SparseMatrix_set_skew(A) set_flag((A)->property, MATRIX_SKEW) | 
|---|
| 165 | #define SparseMatrix_set_hemitian(A) set_flag((A)->property, MATRIX_HERMITIAN) | 
|---|
| 166 |  | 
|---|
| 167 |  | 
|---|
| 168 | #define SparseMatrix_clear_undirected(A) clear_flag((A)->property, MATRIX_UNDIRECTED) | 
|---|
| 169 | #define SparseMatrix_clear_symmetric(A) clear_flag((A)->property, MATRIX_SYMMETRIC) | 
|---|
| 170 | #define SparseMatrix_clear_pattern_symmetric(A) clear_flag((A)->property, MATRIX_PATTERN_SYMMETRIC) | 
|---|
| 171 | #define SparseMatrix_clear_skew(A) clear_flag((A)->property, MATRIX_SKEW) | 
|---|
| 172 | #define SparseMatrix_clear_hemitian(A) clear_flag((A)->property, MATRIX_HERMITIAN) | 
|---|
| 173 |  | 
|---|
| 174 |  | 
|---|
| 175 | #define SparseMatrix_known_undirected(A) test_flag((A)->property, MATRIX_UNDIRECTED) | 
|---|
| 176 | #define SparseMatrix_known_symmetric(A) test_flag((A)->property, MATRIX_SYMMETRIC) | 
|---|
| 177 | #define SparseMatrix_known_strucural_symmetric(A) test_flag((A)->property, MATRIX_PATTERN_SYMMETRIC) | 
|---|
| 178 | #define SparseMatrix_known_skew(A) test_flag((A)->property, MATRIX_SKEW) | 
|---|
| 179 | #define SparseMatrix_known_hemitian(A) test_flag((A)->property, MATRIX_HERMITIAN) | 
|---|
| 180 |  | 
|---|
| 181 |  | 
|---|
| 182 |  | 
|---|
| 183 |  | 
|---|
| 184 | #endif | 
|---|
| 185 |  | 
|---|