static void _display_histograms(int n_steps, cs_real_t var_min, cs_real_t var_max, cs_real_t min, cs_real_t max, cs_gnum_t count[]) { int i, j; double var_step; #if defined(HAVE_MPI) if (cs_glob_n_ranks > 1) { cs_gnum_t _g_count[10]; cs_gnum_t *g_count = _g_count; MPI_Allreduce(count, g_count, n_steps, CS_MPI_GNUM, MPI_SUM, cs_glob_mpi_comm); for (i = 0; i < n_steps; i++) count[i] = g_count[i]; } #endif /* Print base min, max, and increment */ bft_printf(_(" minimum value = %10.5e\n"), (double)min); bft_printf(_(" maximum value = %10.5e\n\n"), (double)max); var_step = CS_ABS(var_max - var_min) / n_steps; if (CS_ABS(var_max - var_min) > 0.) { /* Number of elements in each subdivision */ for (i = 0, j = 1; i < n_steps - 1; i++, j++) bft_printf(" %3d : [ %10.5e ; %10.5e [ = %10llu\n", i+1, var_min + i*var_step, var_min + j*var_step, (unsigned long long)(count[i])); bft_printf(" %3d : [ %10.5e ; %10.5e ] = %10llu\n", n_steps, var_min + (n_steps - 1)*var_step, var_max, (unsigned long long)(count[n_steps - 1])); } }
static void _int_face_histogram(const cs_mesh_t *mesh, const cs_real_t var[], cs_real_t min, cs_real_t max, cs_real_t n_min, cs_real_t n_max) { cs_lnum_t i; int j, k; cs_real_t step; cs_gnum_t count[8]; const int n_steps = 8; assert(sizeof(double) == sizeof(cs_real_t)); /* Define axis subdivisions */ for (j = 0; j < n_steps; j++) count[j] = 0; if (CS_ABS(max - min) > 0.) { step = CS_ABS(max - min) / n_steps; /* Loop on faces */ for (i = 0; i < mesh->n_i_faces; i++) { if (mesh->i_face_cells[i][0] >= mesh->n_cells) continue; /* Associated subdivision */ for (j = 0, k = 1; k < n_steps; j++, k++) { if (var[i] < min + k*step) break; } count[j] += 1; } } _display_histograms(n_steps, min, max, n_min, n_max, count); }
static void _histogram(cs_lnum_t n_vals, const cs_real_t var[], cs_real_t min, cs_real_t max, cs_real_t n_min, cs_real_t n_max) { cs_lnum_t i; int j, k; cs_real_t step; cs_gnum_t count[10]; const int n_steps = 10; assert (sizeof(double) == sizeof(cs_real_t)); /* Define axis subdivisions */ for (j = 0; j < n_steps; j++) count[j] = 0; if (CS_ABS(max - min) > 0.) { step = CS_ABS(max - min) / n_steps; /* Loop on values */ for (i = 0; i < n_vals; i++) { /* Associated subdivision */ for (j = 0, k = 1; k < n_steps; j++, k++) { if (var[i] < min + k*step) break; } count[j] += 1; } } _display_histograms(n_steps, min, max, n_min, n_max, count); }
/* sparse Cholesky update/downdate, L*L' + sigma*w*w' (sigma = +1 or -1) */ CS_INT cs_updown (cs *L, CS_INT sigma, const cs *C, const CS_INT *parent) { CS_INT n, p, f, j, *Lp, *Li, *Cp, *Ci ; CS_ENTRY *Lx, *Cx, alpha, gamma, w1, w2, *w ; double beta = 1, beta2 = 1, delta ; #ifdef CS_COMPLEX cs_complex_t phase ; #endif if (!CS_CSC (L) || !CS_CSC (C) || !parent) return (0) ; /* check inputs */ Lp = L->p ; Li = L->i ; Lx = L->x ; n = L->n ; Cp = C->p ; Ci = C->i ; Cx = C->x ; if ((p = Cp [0]) >= Cp [1]) return (1) ; /* return if C empty */ w = cs_malloc (n, sizeof (CS_ENTRY)) ; /* get workspace */ if (!w) return (0) ; /* out of memory */ f = Ci [p] ; for ( ; p < Cp [1] ; p++) f = CS_MIN (f, Ci [p]) ; /* f = min (find (C)) */ for (j = f ; j != -1 ; j = parent [j]) w [j] = 0 ; /* clear workspace w */ for (p = Cp [0] ; p < Cp [1] ; p++) w [Ci [p]] = Cx [p] ; /* w = C */ for (j = f ; j != -1 ; j = parent [j]) /* walk path f up to root */ { p = Lp [j] ; alpha = w [j] / Lx [p] ; /* alpha = w(j) / L(j,j) */ beta2 = beta*beta + sigma*alpha*CS_CONJ(alpha) ; if (beta2 <= 0) break ; /* not positive definite */ beta2 = sqrt (beta2) ; delta = (sigma > 0) ? (beta / beta2) : (beta2 / beta) ; gamma = sigma * CS_CONJ(alpha) / (beta2 * beta) ; Lx [p] = delta * Lx [p] + ((sigma > 0) ? (gamma * w [j]) : 0) ; beta = beta2 ; #ifdef CS_COMPLEX phase = CS_ABS (Lx [p]) / Lx [p] ; /* phase = abs(L(j,j))/L(j,j)*/ Lx [p] *= phase ; /* L(j,j) = L(j,j) * phase */ #endif for (p++ ; p < Lp [j+1] ; p++) { w1 = w [Li [p]] ; w [Li [p]] = w2 = w1 - alpha * Lx [p] ; Lx [p] = delta * Lx [p] + gamma * ((sigma > 0) ? w1 : w2) ; #ifdef CS_COMPLEX Lx [p] *= phase ; /* L(i,j) = L(i,j) * phase */ #endif } } cs_free (w) ; return (beta2 > 0) ; }
/* [L,U,pinv]=lu(A, [q lnz unz]). lnz and unz can be guess */ csn *cs_lu (const cs *A, const css *S, double tol) { cs *L, *U ; csn *N ; CS_ENTRY pivot, *Lx, *Ux, *x ; double a, t ; CS_INT *Lp, *Li, *Up, *Ui, *pinv, *xi, *q, n, ipiv, k, top, p, i, col, lnz,unz; if (!CS_CSC (A) || !S) return (NULL) ; /* check inputs */ n = A->n ; q = S->q ; lnz = S->lnz ; unz = S->unz ; x = cs_malloc (n, sizeof (CS_ENTRY)) ; /* get CS_ENTRY workspace */ xi = cs_malloc (2*n, sizeof (CS_INT)) ; /* get CS_INT workspace */ N = cs_calloc (1, sizeof (csn)) ; /* allocate result */ if (!x || !xi || !N) return (cs_ndone (N, NULL, xi, x, 0)) ; N->L = L = cs_spalloc (n, n, lnz, 1, 0) ; /* allocate result L */ N->U = U = cs_spalloc (n, n, unz, 1, 0) ; /* allocate result U */ N->pinv = pinv = cs_malloc (n, sizeof (CS_INT)) ; /* allocate result pinv */ if (!L || !U || !pinv) return (cs_ndone (N, NULL, xi, x, 0)) ; Lp = L->p ; Up = U->p ; for (i = 0 ; i < n ; i++) x [i] = 0 ; /* clear workspace */ for (i = 0 ; i < n ; i++) pinv [i] = -1 ; /* no rows pivotal yet */ for (k = 0 ; k <= n ; k++) Lp [k] = 0 ; /* no cols of L yet */ lnz = unz = 0 ; for (k = 0 ; k < n ; k++) /* compute L(:,k) and U(:,k) */ { /* --- Triangular solve --------------------------------------------- */ Lp [k] = lnz ; /* L(:,k) starts here */ Up [k] = unz ; /* U(:,k) starts here */ if ((lnz + n > L->nzmax && !cs_sprealloc (L, 2*L->nzmax + n)) || (unz + n > U->nzmax && !cs_sprealloc (U, 2*U->nzmax + n))) { return (cs_ndone (N, NULL, xi, x, 0)) ; } Li = L->i ; Lx = L->x ; Ui = U->i ; Ux = U->x ; col = q ? (q [k]) : k ; top = cs_spsolve (L, A, col, xi, x, pinv, 1) ; /* x = L\A(:,col) */ /* --- Find pivot --------------------------------------------------- */ ipiv = -1 ; a = -1 ; for (p = top ; p < n ; p++) { i = xi [p] ; /* x(i) is nonzero */ if (pinv [i] < 0) /* row i is not yet pivotal */ { if ((t = CS_ABS (x [i])) > a) { a = t ; /* largest pivot candidate so far */ ipiv = i ; } } else /* x(i) is the entry U(pinv[i],k) */ { Ui [unz] = pinv [i] ; Ux [unz++] = x [i] ; } } if (ipiv == -1 || a <= 0) return (cs_ndone (N, NULL, xi, x, 0)) ; if (pinv [col] < 0 && CS_ABS (x [col]) >= a*tol) ipiv = col ; /* --- Divide by pivot ---------------------------------------------- */ pivot = x [ipiv] ; /* the chosen pivot */ Ui [unz] = k ; /* last entry in U(:,k) is U(k,k) */ Ux [unz++] = pivot ; pinv [ipiv] = k ; /* ipiv is the kth pivot row */ Li [lnz] = ipiv ; /* first entry in L(:,k) is L(k,k) = 1 */ Lx [lnz++] = 1 ; for (p = top ; p < n ; p++) /* L(k+1:n,k) = x / pivot */ { i = xi [p] ; if (pinv [i] < 0) /* x(i) is an entry in L(:,k) */ { Li [lnz] = i ; /* save unpermuted row in L */ Lx [lnz++] = x [i] / pivot ; /* scale pivot column */ } x [i] = 0 ; /* x [0..n-1] = 0 for next k */ } } /* --- Finalize L and U ------------------------------------------------- */ Lp [n] = lnz ; Up [n] = unz ; Li = L->i ; /* fix row indices of L for final pinv */ for (p = 0 ; p < lnz ; p++) Li [p] = pinv [Li [p]] ; cs_sprealloc (L, 0) ; /* remove extra space from L and U */ cs_sprealloc (U, 0) ; return (cs_ndone (N, NULL, xi, x, 1)) ; /* success */ }