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 | |