| 1 | #include "general.h" |
| 2 | #include "SparseMatrix.h" |
| 3 | #include "spring_electrical.h" |
| 4 | #include "post_process.h" |
| 5 | #include "stress_model.h" |
| 6 | |
| 7 | void stress_model_core(int dim, SparseMatrix B, real **x, int edge_len_weighted, int maxit_sm, real tol, int *flag){ |
| 8 | int m; |
| 9 | SparseStressMajorizationSmoother sm; |
| 10 | real lambda = 0; |
| 11 | /*int maxit_sm = 1000, i; tol = 0.001*/ |
| 12 | int i; |
| 13 | SparseMatrix A = B; |
| 14 | |
| 15 | if (!SparseMatrix_is_symmetric(A, FALSE) || A->type != MATRIX_TYPE_REAL){ |
| 16 | if (A->type == MATRIX_TYPE_REAL){ |
| 17 | A = SparseMatrix_symmetrize(A, FALSE); |
| 18 | A = SparseMatrix_remove_diagonal(A); |
| 19 | } else { |
| 20 | A = SparseMatrix_get_real_adjacency_matrix_symmetrized(A); |
| 21 | } |
| 22 | } |
| 23 | A = SparseMatrix_remove_diagonal(A); |
| 24 | |
| 25 | *flag = 0; |
| 26 | m = A->m; |
| 27 | if (!x) { |
| 28 | *x = MALLOC(sizeof(real)*m*dim); |
| 29 | srand(123); |
| 30 | for (i = 0; i < dim*m; i++) (*x)[i] = drand(); |
| 31 | } |
| 32 | |
| 33 | if (edge_len_weighted){ |
| 34 | sm = SparseStressMajorizationSmoother_new(A, dim, lambda, *x, WEIGHTING_SCHEME_SQR_DIST, TRUE);/* do not under weight the long distances */ |
| 35 | //sm = SparseStressMajorizationSmoother_new(A, dim, lambda, *x, WEIGHTING_SCHEME_INV_DIST, TRUE);/* do not under weight the long distances */ |
| 36 | } else { |
| 37 | sm = SparseStressMajorizationSmoother_new(A, dim, lambda, *x, WEIGHTING_SCHEME_NONE, TRUE);/* weight the long distances */ |
| 38 | } |
| 39 | |
| 40 | if (!sm) { |
| 41 | *flag = -1; |
| 42 | goto RETURN; |
| 43 | } |
| 44 | |
| 45 | |
| 46 | sm->tol_cg = 0.1; /* we found that there is no need to solve the Laplacian accurately */ |
| 47 | sm->scheme = SM_SCHEME_STRESS; |
| 48 | SparseStressMajorizationSmoother_smooth(sm, dim, *x, maxit_sm, tol); |
| 49 | for (i = 0; i < dim*m; i++) { |
| 50 | (*x)[i] /= sm->scaling; |
| 51 | } |
| 52 | SparseStressMajorizationSmoother_delete(sm); |
| 53 | |
| 54 | RETURN: |
| 55 | if (A != B) SparseMatrix_delete(A); |
| 56 | |
| 57 | } |
| 58 | |
| 59 | |
| 60 | #ifdef GVIEWER |
| 61 | #include "gviewer.h" |
| 62 | #include "get_ps.h" |
| 63 | struct stress_model_data { |
| 64 | int dim; |
| 65 | SparseMatrix D; |
| 66 | real **x; |
| 67 | int edge_len_weighted; |
| 68 | int maxit_sm; |
| 69 | real tol; |
| 70 | int *flag; |
| 71 | }; |
| 72 | |
| 73 | void stress_model_gv(void* data){ |
| 74 | struct stress_model_data* d; |
| 75 | |
| 76 | d = (struct stress_model_data*) data; |
| 77 | return stress_model_core(d->dim, d->D, d->x, d->edge_len_weighted, d->maxit_sm, d->tol, d->flag); |
| 78 | } |
| 79 | void stress_model(int dim, SparseMatrix A, SparseMatrix D, real **x, int edge_len_weighted, int maxit_sm, real tol, int *flag){ |
| 80 | struct stress_model_data data = {dim, D, x, edge_len_weighted, maxit_sm, tol, flag}; |
| 81 | |
| 82 | int argcc = 1; |
| 83 | char **argvv; |
| 84 | |
| 85 | if (!Gviewer) return stress_model_core(dim, D, x, edge_len_weighted, maxit_sm, tol, flag); |
| 86 | argcc = 1; |
| 87 | argvv = malloc(sizeof(char*)*argcc); |
| 88 | argvv[0] = malloc(sizeof(char)); |
| 89 | argvv[0][0] = '1'; |
| 90 | // gviewer_init(&argcc, argvv, 0.1, 20, 60, 2*1010, 2*770, A, dim, *x, &(data), stress_model_gv); |
| 91 | gviewer_set_edge_color_scheme(COLOR_SCHEME_NO); |
| 92 | gviewer_toggle_bgcolor(); |
| 93 | gviewer_init(&argcc, argvv, 0.1, 20, 60, 720, 720, A, dim, *x, &(data), stress_model_gv); |
| 94 | free(argvv); |
| 95 | |
| 96 | } |
| 97 | #else |
| 98 | void stress_model(int dim, SparseMatrix A, SparseMatrix D, real **x, int edge_len_weighted, int maxit_sm, real tol, int *flag){ |
| 99 | stress_model_core(dim, D, x, edge_len_weighted, maxit_sm, tol, flag); |
| 100 | } |
| 101 | #endif |
| 102 | |
| 103 | |