/** Calculate Gershgorin bounds for a dense matrix. * * \ingroup gershgorin_group * * \param A The matrix * returns maxeval Calculated max value * returns maxminusmin Calculated max-min value */ void *TYPED_FUNC( bml_gershgorin_dense) ( const bml_matrix_dense_t * A) { REAL_T radius, dvalue, absham; int N = A->N; REAL_T *A_matrix = A->matrix; double emin = 100000000000.0; double emax = -100000000000.0; double *eval = bml_allocate_memory(sizeof(double) * 2); #pragma omp parallel for default(none) shared(N, A_matrix) private(absham, radius, dvalue) reduction(max:emax) reduction(min:emin) for (int i = 0; i < N; i++) { radius = 0.0; for (int j = 0; j < N; j++) { absham = ABS(A_matrix[ROWMAJOR(i, j, N, N)]); radius += (double) absham; } dvalue = A_matrix[ROWMAJOR(i, i, N, N)]; radius -= ABS(dvalue); emax = (emax > REAL_PART(dvalue + radius) ? emax : REAL_PART(dvalue + radius)); emin = (emin < REAL_PART(dvalue - radius) ? emin : REAL_PART(dvalue - radius)); } eval[0] = emax; eval[1] = emax - emin; return eval; }
/** Matrix multiply. * * \f$ X^{2} \leftarrow X \, X \f$ * * \ingroup multiply_group * * \param X Matrix X * \param X2 Matrix X2 * \param threshold Used for sparse multiply */ void *TYPED_FUNC( bml_multiply_x2_ellpack) ( const bml_matrix_ellpack_t * X, bml_matrix_ellpack_t * X2, const double threshold) { int X_N = X->N; int X_M = X->M; int *X_index = X->index; int *X_nnz = X->nnz; int X2_N = X2->N; int X2_M = X2->M; int *X2_index = X2->index; int *X2_nnz = X2->nnz; int ix[X_N], jx[X_N]; REAL_T x[X_N]; REAL_T traceX = 0.0; REAL_T traceX2 = 0.0; REAL_T *X_value = (REAL_T *) X->value; REAL_T *X2_value = (REAL_T *) X2->value; double *trace = bml_allocate_memory(sizeof(double) * 2); memset(ix, 0, X_N * sizeof(int)); memset(jx, 0, X_N * sizeof(int)); memset(x, 0.0, X_N * sizeof(REAL_T)); #pragma omp parallel for \ default(none) \ firstprivate(ix, jx, x) \ shared(X_N, X_M, X_index, X_nnz, X_value) \ shared(X2_N, X2_M, X2_index, X2_nnz, X2_value) \ reduction(+: traceX, traceX2) for (int i = 0; i < X_N; i++) // CALCULATES THRESHOLDED X^2 { int l = 0; for (int jp = 0; jp < X_nnz[i]; jp++) { REAL_T a = X_value[ROWMAJOR(i, jp, X_N, X_M)]; int j = X_index[ROWMAJOR(i, jp, X_N, X_M)]; if (j == i) { traceX = traceX + a; } for (int kp = 0; kp < X_nnz[j]; kp++) { int k = X_index[ROWMAJOR(j, kp, X_N, X_M)]; if (ix[k] == 0) { x[k] = 0.0; //X2_index[ROWMAJOR(i, l, N, M)] = k; jx[l] = k; ix[k] = i + 1; l++; } // TEMPORARY STORAGE VECTOR LENGTH FULL N x[k] = x[k] + a * X_value[ROWMAJOR(j, kp, X_N, X_M)]; } } // Check for number of non-zeroes per row exceeded if (l > X2_M) { LOG_ERROR("Number of non-zeroes per row > M, Increase M\n"); } int ll = 0; for (int j = 0; j < l; j++) { //int jp = X2_index[ROWMAJOR(i, j, N, M)]; int jp = jx[j]; REAL_T xtmp = x[jp]; // The diagonal elements are stored in the first column if (jp == i) { traceX2 = traceX2 + xtmp; X2_value[ROWMAJOR(i, ll, X2_N, X2_M)] = xtmp; X2_index[ROWMAJOR(i, ll, X2_N, X2_M)] = jp; ll++; } else if (is_above_threshold(xtmp, threshold)) { X2_value[ROWMAJOR(i, ll, X2_N, X2_M)] = xtmp; X2_index[ROWMAJOR(i, ll, X2_N, X2_M)] = jp; ll++; } ix[jp] = 0; x[jp] = 0.0; } X2_nnz[i] = ll; } trace[0] = traceX; trace[1] = traceX2; return trace; }